Skip to content

🔌 refactor: Drive the Resumable Stream Through the ChatTransport - #16378

Merged
berry-13 merged 2 commits into
canaryfrom
berry-13/chat-transport-resumable
Sep 25, 2026
Merged

berry-13 merged 2 commits into
canaryfrom
berry-13/chat-transport-resumable

Conversation

@berry-13

@berry-13 berry-13 commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The resumable stream is the path every non-Assistants chat takes, but useResumableSSE still opened sse.js itself and parsed frames inline, so the app's real streaming path bypassed the ChatTransport that #16335 and #16336 introduced. This routes it through the transport, behaviour-preserving, so stream state can move out of the hooks next.

ChatTransport gains reconnectToStream, the counterpart of the AI SDK method of that name, implemented on the sse.js transport. It attaches with a GET, refreshes the token once per attachment on a 401 (a second 401 goes to the hook's bounded reconnect ladder), reports a cancel the caller did not issue (a backgrounded or frozen tab) as a dropped connection with status 0, and exposes closed for the foreground reattach check. useResumableSSE now consumes normalized ChatEvents. Resume cursors, job ids, steer and queue bookkeeping, abort and cleanup stay where they were, and the step handler is untouched. The hook shrinks by 48 lines.

Type of change

  • Refactor

Testing

Tested environments/configuration:

  • Chromium (Playwright) against lc backend and frontend on this branch, Anthropic endpoint (claude-sonnet-4-6)
  • Normal turn: streamed and finalized.
  • Stop mid-stream: abort endpoint called, partial response persisted after reload.
  • Reconnect mid-run: __killNetwork dropped the stream and it reattached with resume=true; the backend logged the disconnect and a resumed subscription one second later, and events kept arriving.
  • Queued turn sent during a run: auto-sent after FINAL under a new generation epoch.
  • Steer during a run without a tool boundary: 202, handed back in pendingSteers on FINAL, converted to a queued turn and sent.
  • Not exercised live: a real user-agent cancel (Chromium offline emulation does not sever an open stream) and a steer injected mid-run (needs a tool-calling agent); both are covered by the specs.

Automated tests:

  • cd client && npx jest hooks/SSE data-provider/SSE: 16 suites, 482 tests pass (all existing specs unchanged, 13 new)
  • Added reconnectToStream tests in sse.spec.ts: GET headers, resume snapshot framing, server error vs HTTP status, user-agent cancel, caller abort, body end, 401 refresh, second 401 and failed refresh, plain-text server error, abort during refresh
  • cd client && npm run typecheck, cd packages/data-provider && npx tsc --noEmit: clean
  • npx eslint, npx prettier --check, node scripts/sort-imports.mts --check on touched files: clean

Screenshots / recordings

No user-facing change

Risk / compatibility

No wire format change. The resume path previously refreshed the token on every 401 without a cap; it now refreshes once per attachment and lets the reconnect ladder bound the rest. A body that ends without a terminal frame is still only recovered on the next foreground, as before; that is tracked separately in berry-13#144.

Checklist

  • I reviewed my own changes
  • Relevant tests have been added or updated
  • Existing relevant tests pass
  • The change does not introduce new warnings or errors
  • Required documentation PR: N/A

Add reconnectToStream to ChatTransport and the sse.js transport: a GET
attach with request headers, a token refresh on every 401, a cancel the
caller did not issue reported as a dropped connection (status 0), and a
closed flag for the foreground check. useResumableSSE now consumes
normalized ChatEvents instead of opening sse.js and parsing frames
itself; resume, steer and queue bookkeeping are unchanged.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-25T19:24:40.533562Z 82901a1 New commits
🔒 Security Review ✅ Completed 2026-09-25T19:03:52.860519Z 1619f8f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Refresh the token once per attachment and report a second 401, so the
hook's reconnect budget bounds a stream that keeps answering 401. A
server-written error event that is not JSON keeps its raw text instead
of reading as a dropped connection.
@berry-13
berry-13 merged commit df01dba into canary Sep 25, 2026
33 checks passed
@berry-13
berry-13 deleted the berry-13/chat-transport-resumable branch September 25, 2026 19:54
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