fix(api-server): forward Codex commentary in streaming SSE endpoint - #67613
Open
webtecnica wants to merge 1 commit into
Open
fix(api-server): forward Codex commentary in streaming SSE endpoint#67613webtecnica wants to merge 1 commit into
webtecnica wants to merge 1 commit into
Conversation
Wire interim_assistant_callback through APIServerAdapter._create_agent() and _run_agent() so Codex commentary (phase=commentary) is forwarded to API Server streaming clients. Add SSE event to the Hermes session stream endpoint, gated behind display.show_commentary (defaults to true). Fixes NousResearch#67580
Collaborator
Duplicate of #67593: both wire |
teknium1
reviewed
Jul 19, 2026
teknium1
left a comment
Contributor
There was a problem hiding this comment.
Thanks for tracing the existing callback boundary and keeping commentary separate from final response content.
Problems
- The new callback ignores
already_streamed(gateway/platforms/api_server.py:2572in this diff). Core can call this callback withalready_streamed=Truewhen the same visible text already went through normal deltas (run_agent.py:4893-4900), so this would duplicate commentary in the session stream. /v1/responsesstreaming still calls_run_agentwithout an interim callback on current main (gateway/platforms/api_server.py:3841-3853). The linked issue describes API Server streaming endpoints, and this supported stream would remain silent.- This adds a public SSE event but changes neither regression tests nor the documented session-stream event contract (
website/docs/user-guide/features/api-server.md:346).
Suggested changes
- Drop
already_streamed=Trueevents and add regression coverage for duplicate suppression, final-content separation, and the config gate. - Extend the Responses stream with a distinct
phase="commentary"message item, then document both stream contracts.
Automated hermes-sweeper review.
| @@ -2568,11 +2570,27 @@ def _tool_progress(event_type: str, tool_name: str = None, preview: str = None, | |||
| event_name = event_type.replace("tool.", "tool.") | |||
| _enqueue(event_name, {"message_id": message_id, "tool_name": tool_name, "preview": preview, "args": args}) | |||
|
|
|||
Contributor
There was a problem hiding this comment.
Honor already_streamed here. Core invokes this callback with already_streamed=True when the same visible text was already sent through the delta stream (run_agent.py:4893-4900); emitting it again as assistant.commentary duplicates client-visible narration.
1 task
13 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wire
interim_assistant_callbackthroughAPIServerAdapter._create_agent()and_run_agent()so Codex commentary (phase=commentary) is forwarded to API Server streaming clients.Add
assistant.commentarySSE event to the Hermes session stream endpoint (POST /api/sessions/{session_id}/chat/stream), gated behinddisplay.show_commentary(defaults totrue).Fixes #67580
Problem
When Hermes uses the
openai-codexbackend through API Server, Codex can generate user-facing progress messages as assistant output items withphase="commentary". Hermes preserves those items incodex_message_items, but API Server streaming clients do not receive them.Long-running, tool-heavy turns remain silent until the final answer. The user cannot tell whether the agent is making progress, stalled, or has misunderstood the task.
Root Cause
APIServerAdapter._create_agent()forwardsstream_delta_callback,tool_progress_callback,tool_start_callback, andtool_complete_callbacktoAIAgent, but it does not accept or forwardinterim_assistant_callback._run_agent()has the same omission. The Hermes session SSE handler wires assistant deltas and tool progress without a commentary path.The core commentary behavior was added in #66115 and defaults to visible, but
gateway/platforms/api_server.pywas not part of that callback wiring.Changes
_create_agent(): Addedinterim_assistant_callback=Noneparameter and passes it toAIAgent()_run_agent(): Addedinterim_assistant_callback=Noneparameter and forwards it to_create_agent()_handle_session_chat_stream(): Added_commentarycallback that emitsassistant.commentarySSE events withmessage_id,text, andalready_streamedfields. Gated behinddisplay.show_commentaryconfig.Safety
phase="analysis"/ raw chain-of-thought / reasoning summaries are NOT exposed through this pathassistant.completedcontentdisplay.show_commentary: falsepreserves the quiet behavior (no commentary events emitted)/v1/chat/completionsdelta content is unaffected (commentary does not go intochoices[].delta.content)