Skip to content

fix(ai-chat,think): keep a child's stream error across eviction so reconciliation doesn't report success - #2390

Merged
threepointone merged 1 commit into
mainfrom
fix/agent-tool-error-reconciliation
Sep 28, 2026
Merged

threepointone merged 1 commit into
mainfrom
fix/agent-tool-error-reconciliation

Conversation

@threepointone

@threepointone threepointone commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to the Devin review on #2388 (comment).

Problem

When an agent-tool child (AIChatAgent or Think) fails mid-turn, it emits an error chunk and saves its assistant reply (often human-readable error text) before startAgentToolRun marks the run error. The error was only held in memory (lastErrors). If the child was evicted in that window, the row stayed running, and stale-row reconciliation saw an assistant message after the run started and sealed it completed — so the parent reported a failed task as a success.

Fix

  • interceptAgentToolBroadcast takes an optional onError(runId, body) hook, called when it captures a run's error body.
  • Both hosts use it to write the error to the still-open run row's error_message (best-effort; broadcast never throws). status is left to the finalizer.
  • _reconcileStaleAgentToolChildRun (both hosts) seals a row that carries a recorded stream error as error with that message, instead of inferring completed from assistant messages. This matches the live finalizer, which fails a run whenever a stream error was captured.
  • Think's inspection no longer surfaces error_message on a row that is still open (ai-chat already behaved this way).

Trade-off: if chat recovery later re-ran an errored turn and it succeeded, the run still reconciles as error — the same result the live path gives when an error chunk was captured.

Tests

  • agents: reports a captured error body to onError
  • ai-chat and Think: reconciles a child evicted after a stream error as error, not completed — a real startAgentToolRun streams error text then an error chunk (marker written through the real broadcast path), the lifecycle is held before finalizing, in-memory run state is dropped as an eviction would, then the run is inspected. Both fail with "completed" without the fix.
  • Existing "recovered assistant turn reconciles to completed" tests still pass.

Devin Review

…conciliation doesn't report success

Co-authored-by: Cursor <cursoragent@cursor.com>
@changeset-bot

changeset-bot Bot commented Sep 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fd1e571

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
agents Patch
@cloudflare/ai-chat Patch
@cloudflare/think Patch
@cloudflare/agent-think Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

@agent-think

agent-think Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

✅ agents import sizes: no significant changes (a8673b7c → fd1e5714, workflow run)

@pkg-pr-new

pkg-pr-new Bot commented Sep 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@2390

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@2390

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@2390

hono-agents

npm i https://pkg.pr.new/hono-agents@2390

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@2390

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@2390

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@2390

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@2390

commit: fd1e571

@threepointone
threepointone merged commit c55ec80 into main Sep 28, 2026
16 checks passed
@threepointone
threepointone deleted the fix/agent-tool-error-reconciliation branch September 28, 2026 09:25
@github-actions github-actions Bot mentioned this pull request Oct 2, 2026
brandhaug added a commit to brandhaug/b2b-saas-starter that referenced this pull request Oct 5, 2026
## pnpm-workspace.yaml (default)

## Dependency Updates

| Package | From | To | Type |
| --- | --- | --- | --- |
| `agents` | 0.24.0 | 0.25.0 | minor |

## Release Notes

<details>
<summary><b>agents</b> (0.24.0 → 0.25.0)</summary>

### Minor Changes

- [#2005](cloudflare/agents#2005)
[`c2f7672`](cloudflare/agents@c2f7672)
Thanks [@<!---->cjol](https://github.com/cjol)! - Native RPC calls to
async Agent and Think methods now start lifecycle initialization first;
address Agents by name because raw IDs from `newUniqueId()` and
`idFromString()` now fail their first async RPC. See
[Lifecycle](https://github.com/cloudflare/agents/blob/main/docs/agents/lifecycle.md).

### Patch Changes

- [#2390](cloudflare/agents#2390)
[`c55ec80`](cloudflare/agents@c55ec80)
Thanks [@<!---->threepointone](https://github.com/threepointone)! -
Report a failed agent-tool child as failed even when it was evicted
before recording the failure. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2384](cloudflare/agents#2384)
[`f904999`](cloudflare/agents@f904999)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - Fix
agent-tool chunks being duplicated or dropped on reconnect, child
re-attach, and fiber recovery. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2364](cloudflare/agents#2364)
[`5e0507e`](cloudflare/agents@5e0507e)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - Add
`eventDelivery: "terminal"` to `runAgentTool` to forward only lifecycle,
progress, and milestone events for a run. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2448](cloudflare/agents#2448)
[`54f9ca7`](cloudflare/agents@54f9ca7)
Thanks [@<!---->aron-cf](https://github.com/aron-cf)!

…[full
notes](https://github.com/cloudflare/agents/releases/tag/agents%400.25.0)

</details>

---
*This PR was auto-generated by
[catalog-update-action](https://github.com/brandhaug/catalog-update-action).*

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
brandhaug added a commit to brandhaug/b2b-saas-starter that referenced this pull request Oct 5, 2026
## pnpm-workspace.yaml (default)

## Dependency Updates

| Package | From | To | Type |
| --- | --- | --- | --- |
| `@cloudflare/ai-chat` | 0.12.0 | 0.12.1 | patch |

## Release Notes

<details>
<summary><b>@<!---->cloudflare/ai-chat</b> (0.12.0 → 0.12.1)</summary>

### Patch Changes

- [#2390](cloudflare/agents#2390)
[`c55ec80`](cloudflare/agents@c55ec80)
Thanks [@<!---->threepointone](https://github.com/threepointone)! -
Report a failed agent-tool child as failed even when it was evicted
before recording the failure. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2384](cloudflare/agents#2384)
[`f904999`](cloudflare/agents@f904999)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - Fix
agent-tool chunks being duplicated or dropped on reconnect, child
re-attach, and fiber recovery. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2364](cloudflare/agents#2364)
[`5e0507e`](cloudflare/agents@5e0507e)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - Add
`eventDelivery: "terminal"` to `runAgentTool` to forward only lifecycle,
progress, and milestone events for a run. See [Agent
tools](https://github.com/cloudflare/agents/blob/main/docs/agents/agent-tools.md).

- [#2334](cloudflare/agents#2334)
[`7f564e7`](cloudflare/agents@7f564e7)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - AI
Chat and Think send the terminal `done` frame after persisting and
broadcasting the assistant reply, so later sends are not overwritten.
See [Chat
agents](https://github.com/cloudflare/agents/blob/main/docs/agents/chat-agents.md).

- [#2352](cloudflare/agents#2352)
[`449ac27`](cloudflare/agents@449ac27)
Thanks [@<!---->threepointone](https://github.com/threepointone)! - Do
not start an automatic continuation after an

…[full
notes](https://github.com/cloudflare/agents/releases/tag/%40cloudflare/ai-chat%400.12.1)

</details>

---
*This PR was auto-generated by
[catalog-update-action](https://github.com/brandhaug/catalog-update-action).*

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
tombeckenham added a commit to tombeckenham/agents-tom that referenced this pull request Oct 7, 2026
Ports three upstream changes to the legacy AIChatAgent's agent-tool child
adapter onto AGUIChatAgent:

- cloudflare#2364: opt-in terminal-only event delivery. Runs started with
  eventDelivery: "terminal" are tracked (and persisted on the run row) so
  their chunks are stored but not broadcast, including after a restart.
- cloudflare#2384: seed a cold live sequence from the stored backlog before a tail
  attaches (replacing the post-drain realign), and
  inspectAgentToolRun(runId, { reconcile: false }).
- cloudflare#2390: record a run's stream error on its open row so a stale-row
  reconcile after eviction reports error. The engine sends no error frame
  for an in-band RUN_ERROR, so that path records it directly.

The test worker's unported() casts for _agentToolTerminalOnlyRuns and the
inspectAgentToolRun options are replaced with the real members, and its
finalize gate moves to _saveAGUIMessages, which is what the engine's
agent-tool lifecycle calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant