docs(chat): add startIndex to GET /api/chat/{chatId}/stream - #286
Conversation
The resume endpoint is documented but has no way to say WHERE to resume from, so a reconnecting client can only replay the turn from chunk zero. Adds the optional `startIndex` query parameter (integer, minimum 0) and the 400 returned when it is present but not a non-negative integer. This is the contract for the api route that implements it (chat#1923). A long turn's SSE stream can end before the run does — reproduced on prod 2026-08-02, where the stream closed at ~123s while the workflow ran on to completion and the UI froze at 6 of 13 iterations. `startIndex` is what lets the client reconnect without duplicating or skipping chunks. Refs recoupable/chat#1923 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe OpenAPI specification adds an optional ChangesChat stream resume
Estimated code review effort: 2 (Simple) | ~5 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Verified locally against a Mintlify dev server
|
origin/main |
this PR | |
|---|---|---|
| params | ['chatId'] |
['chatId', 'startIndex'] |
| responses | ['200','204','401','403','404'] |
['200','204','400','401','403','404'] |
Results
| Check | Result |
|---|---|
| Page builds and serves | ✅ HTTP 200 at /api-reference/chat/workflow-stream |
| Title from existing frontmatter | ✅ "Resume Chat Stream" |
| Query Parameters section appears | ✅ new section, startIndex integer |
| Description prose + inline code | ✅ renders, paragraphs preserved |
| Response tabs | ✅ 200 / 400 / 401 / 403 / 404 |
| 400 body schema | ✅ ChatStreamErrorResponse $ref resolves |
| Sidebar entry | ✅ already present under Streaming → "Resume Chat Stream" |
| Diff shape | ✅ 20 insertions, 0 deletions |
| JSON validity | ✅ parses; params and responses resolve as above |
Two notes on what is not shown
204 has no response tab. Mintlify only tabs responses that carry content, and a 204 No Content has none by definition. It is present in the spec (see the table above) and unchanged by this PR — the absence of a tab is correct rendering, not a dropped response.
llms.txt was not verified. The local dev server returns the SPA shell for /llms.txt rather than generated text; it is produced at deploy time. The nav entry it derives from (api-reference/chat/workflow-stream in docs.json, line 66) already exists and is unchanged, so no nav work was needed here — but I did not observe the generated output and am not claiming it.


Contract for the resume route in chat#1923. Docs-first: this lands before the api PR that implements it.
The gap
GET /api/chat/{chatId}/streamis already documented (api-reference/chat/workflow-stream.mdx, spec block inapi-reference/openapi/research.json) and cross-referenced fromPOST /api/chat,POST /api/chat/runsandGET /api/chat/runs/{runId}. What it lacks is any way to say where to resume from — so a reconnecting client can only replay the whole turn from chunk zero.Worth flagging for whoever picks up the api side: the endpoint is documented but not implemented.
api/app/api/chat/[chatId]/contains onlystop/. This is documented-but-missing drift, not the usual reverse.What this adds
startIndexinteger,minimum: 0— zero-based index of the first chunk to return. Omit for a fresh reader (page load, or watching a headlessPOST /api/chat/runsrun for the first time).400startIndexpresent but not a non-negative integer. Reuses the existingChatStreamErrorResponseschema.Documented responses are now
200 / 204 / 400 / 401 / 403 / 404.Why it's needed
Reproduced on prod 2026-08-02 (chat#1923): a long turn's SSE stream ended at ~123 s with a clean
[DONE]and nofinishchunk while the workflow ran on to completion. The client received 6 of 13 iterations and froze; everything after was generated and persisted but never delivered. The Workflow SDK documentsgetReadable({ startIndex })as "useful for reconnecting after timeouts or network interruptions", and upstreamvercel-labs/open-agentsships exactly this parameter on its equivalent route.Verification
20 insertions(+), 0 deletions(-).json.dumps(json.load(f), indent=2)does not round-trip this file byte-for-byte (165,132 → 165,567 bytes), so a rewrite would have produced a large spurious diff.[chatId(path,string), startIndex(query,integer)], responses to[200, 204, 400, 401, 403, 404].api-reference/chat/workflow-streamis already present indocs.jsonnav (line 66), so no nav change is needed.Merge order
docs → api → chat. This PR first; the api route is written against it, and the chat client reconnect depends on the route.
🤖 Generated with Claude Code
Summary by cubic
Adds
startIndextoGET /api/chat/{chatId}/streamso clients can resume SSE from a specific chunk instead of replaying the whole turn. Aligns the streaming contract with chat#1923.startIndexquery param (integer,minimum: 0): zero-based index of the first chunk to return. Omit to stream from the beginning.400whenstartIndexis provided but not a non-negative integer (usesChatStreamErrorResponse).200,204,400,401,403,404.Written for commit 6fed74c. Summary will update on new commits.