Skip to content

fix: useChat status stays ready during stream resumption#999

Open
threepointone wants to merge 1 commit intomainfrom
fix/resume-stream-status
Open

fix: useChat status stays ready during stream resumption#999
threepointone wants to merge 1 commit intomainfrom
fix/resume-stream-status

Conversation

@threepointone
Copy link
Contributor

Problem

useChat's status stayed "ready" during stream resumption after a page refresh. This meant isLoading was false and no abort button or thinking indicator appeared during resume.

The root cause: resumed stream chunks flowed through onAgentMessagesetMessages directly, bypassing the AI SDK's transport pipeline. Since useChat never saw the chunks, it never transitioned status to "streaming".

Fix

WebSocketChatTransport.reconnectToStream() now returns a proper ReadableStream<UIMessageChunk> for resumed streams:

  1. Registers a listener for CF_AGENT_STREAM_RESUMING
  2. Sends CF_AGENT_STREAM_RESUME_REQUEST (100ms delayed to avoid double-RESUMING race with onConnect)
  3. On RESUMING received: sends ACK, returns a ReadableStream fed by replayed + live chunks
  4. On timeout (3s): returns null (no active stream)

useAgentChat changes:

  • Forwards resume option to useChat so it calls transport.reconnectToStream()
  • Guards onAgentMessage with localRequestIdsRef to skip chunks already handled by the transport
  • Removed duplicate CF_AGENT_STREAM_RESUME_REQUEST from useEffect (transport owns it now)

Testing

  • Updated existing test to verify progressive chunk processing (not batched)
  • All 239 tests pass
  • npm run check passes (typecheck + lint + format across 44 projects)

@changeset-bot
Copy link

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: 51d8c4e

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

This PR includes changesets to release 1 package
Name Type
@cloudflare/ai-chat 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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 26, 2026

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/agents@999
npm i https://pkg.pr.new/cloudflare/agents/@cloudflare/ai-chat@999
npm i https://pkg.pr.new/cloudflare/agents/@cloudflare/codemode@999
npm i https://pkg.pr.new/cloudflare/agents/hono-agents@999

commit: 51d8c4e

Implement WebSocketChatTransport.reconnectToStream() to return a proper
ReadableStream for resumed streams, and forward the resume option to
useChat. This lets the AI SDK's pipeline process resumed chunks natively,
correctly managing status, isLoading, and abort during stream resumption.

- reconnectToStream sends RESUME_REQUEST, waits for RESUMING, sends ACK,
  returns ReadableStream fed by replayed + live chunks
- 100ms delayed explicit request avoids double-RESUMING race with onConnect
- onAgentMessage guards with localRequestIdsRef to skip transport-handled
  chunks
- Removed duplicate RESUME_REQUEST from useEffect (transport owns it now)
- Updated test to verify progressive chunk processing
@threepointone threepointone force-pushed the fix/resume-stream-status branch from ebf0252 to 51d8c4e Compare February 26, 2026 15:19
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