Skip to content

feat(chat): outcome on terminal frames and useAgentChat onTurnEnd - #2378

Merged
threepointone merged 2 commits into
mainfrom
feat/2280-turn-end-outcome
Sep 26, 2026
Merged

threepointone merged 2 commits into
mainfrom
feat/2280-turn-end-outcome

Conversation

@threepointone

@threepointone threepointone commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up to #2365 for #2280. Apps no longer need to read raw WebSocket frames to settle optimistic sends.

Wire: terminal cf_agent_use_chat_response frames carry outcome: completed, error, aborted, skipped, or recovering. Before this, a skipped or cancelled request looked the same as a completed one. When outcome is absent (older servers), clients treat the turn as error if this frame or an earlier one had error, and as completed otherwise.

  • ai-chat: skipped requests, in-band error done, both abort exits, recovery-scheduled close.
  • Think: skipped/stale requests, the non-resumable done, recovery-scheduled closes, the main streaming terminal.

React: useAgentChat({ onTurnEnd }) fires once per ended request with { requestId, messageIds, outcome, error, replay }. This covers this tab, other connections, and replays. It is deduped per request and never fires for recovering, because the successor request reports the same messageIds. ChatTurnEndEvent and ChatTurnOutcome are exported from agents/chat/react, @cloudflare/ai-chat/react, and @cloudflare/think/react.

Docs: new "Settle sends when a turn ends" section. "Correlate terminal frames with sent messages" is updated for outcome.

Tests cover the outcome at each server site in ai-chat and Think, plus a hook test with completed, error, skipped, recovering, successor, duplicate replay, and replayed error.

Made with Cursor


Devin Review

)

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

changeset-bot Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e7970f9

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

This PR includes changesets to release 4 packages
Name Type
agents Minor
@cloudflare/think Minor
@cloudflare/ai-chat Minor
@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

@agent-think

agent-think Bot commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

✅ agents import sizes: no significant changes (c5b605be → e7970f91, workflow run)

devin-ai-integration[bot]

This comment was marked as resolved.

@pkg-pr-new

pkg-pr-new Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

agents

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

@cloudflare/ai-chat

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

@cloudflare/codemode

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

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: e7970f9

…dedupe

Co-authored-by: Cursor <cursoragent@cursor.com>
@threepointone
threepointone merged commit dbf170c into main Sep 26, 2026
18 of 19 checks passed
@threepointone
threepointone deleted the feat/2280-turn-end-outcome branch September 26, 2026 08:16
@github-actions github-actions Bot mentioned this pull request Sep 26, 2026
tombeckenham added a commit to tombeckenham/agents-tom that referenced this pull request Oct 7, 2026
Brings react-agui.tsx level with the legacy hook in agents/chat/react,
which received these through the upstream merge:

- cloudflare#2344 the server snapshot heals a diverged observed assistant
- cloudflare#2348 an observer skips replayed continuation frames it already applied
- cloudflare#2361 onToolCall fires only after the stream ends
- cloudflare#2378 onTurnEnd fires once per ended request
- cloudflare#2383 turns settle across replay, resume and observers (held and
  recovering requests, the resume:false idle probe)
- cloudflare#2496 streaming protection is released when the socket closes
- cloudflare#2394 follow the socket when the agent name changes
- cloudflare#2403 the tool-result cleanup no longer dispatches per chunk
- cloudflare#2039 keep an optimistic send the reconnect transcript omits

The last three had no failing test: their upstream tests are ported into
react-tests (the address-change one against a fake of useAgent's pending
socket, since this package has no test worker) and failed before the fix.

restoreBufferedSends, MAX_REMEMBERED_ENDED_TURNS and
isSocketAddressPending are exported from agents/chat/react so the two
hooks share them.
tombeckenham added a commit to tombeckenham/agents-tom that referenced this pull request Oct 7, 2026
…ge ids and per-event seq

Ports the server half of upstream cloudflare#2334, cloudflare#2365, cloudflare#2378, cloudflare#2383 and cloudflare#2348 into
AGUIChatAgent. An in-band RUN_ERROR now marks its stream errored when the body
ends (a settled stream cannot be re-marked, which had broken cloudflare#1575's errored
replay) and rides an error frame the client transport still delivers as an event.
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.

2 participants