fix(console): emit complete Responses-API SSE lifecycle for converted streams - #40210
fix(console): emit complete Responses-API SSE lifecycle for converted streams#40210Yuxin-Qiao wants to merge 1 commit into
Conversation
|
Thanks for working on this! I am a Codex CLI user with an OpenCode Go subscription, and I am hitting exactly the failure described in #40171: with This fix looks like exactly what the gateway needs: completing the SSE lifecycle for the chat-to-responses conversion that is already happening. It would unblock a lot of Codex users on OpenCode Go, and I would be happy to test it end-to-end once it is merged. One heads-up: the issue-compliance bot flagged that the PR description is missing the required template sections and said it would auto-close within 2 hours unless updated. @Yuxin-Qiao, could you fill in the PR description template so this stays open while it waits for review? Maintainers, this one would be great to prioritize if you have a moment. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
Thanks for the heads-up and the offer to test! I updated the PR description to follow the template, and the bot confirmed it now meets the contributing guidelines. Appreciate the context on how the missing lifecycle events break Codex CLI turns end to end. |
Issue for this PR
Closes #40171
Type of change
What does this PR do?
/v1/responses(Zen/Go gateway) synthesizes Responses-API SSE from chat-completions upstream chunks, but only emittedresponse.output_text.deltaandresponse.completed. Responses-API clients (e.g. the Codex CLI) rely onresponse.created,response.in_progress,response.output_item.added,response.content_part.addedandresponse.output_item.doneto parse a turn, so streaming turns never complete.Live capture before this change (
deepseek-v4-flash,stream: true):The fix makes the chat-to-responses stream converter stateful (
createToOpenaiChunkinpackages/console/app/src/routes/zen/util/provider/openai.ts) and emits the full lifecycle in order:response.created,response.in_progress,response.output_item.added(message),response.content_part.added,response.output_text.delta,response.output_item.done(with accumulated text),response.completed(withoutput,stop_reason,usage). Tool-call streams also getresponse.function_call_arguments.doneandresponse.output_item.done.createStreamPartConvertercreates one stateful converter per stream; upstreams that already speak Responses-API are still passed through unchanged.Note: #40011 changes the client-side model catalog only and does not touch the gateway converter, so it does not fix this issue.
How did you verify your code works?
packages/console/app/test/openaiResponsesStream.test.ts(bun:test, matching existing console tests) covering: full text-stream lifecycle ordering with a singleresponse.created, accumulated text inoutput_item.done/completed, tool-call lifecycle (function_call_arguments.done,output_item.done), stream with no visible text, and[DONE]passthrough.Screenshots / recordings
N/A (server-side gateway change).
Checklist