Repository navigation
feat(providers/openai): capture and replay Responses message phase - #66
Merged
Merged
Conversation
OpenAI models from gpt-5.3-codex on label each assistant output message as intermediate commentary or the final answer. Generate and Stream dropped the label, so callers could not tell narration before a tool call from an answer while it streamed, and follow-up requests replayed assistant text without it. Attach ResponsesTextMetadata (item ID and phase) to text content from Generate and to the TextStart and TextEnd stream parts. TextStart carries it before the first delta. Replay the phase on assistant input messages in both store modes. The type name and JSON shape match upstream charmbracelet#412, which replays the phase only when store is false. > Xum acted on Mike's behalf.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
ibetitsmike
added a commit
to coder/coder
that referenced
this pull request
Oct 9, 2026
OpenAI Responses models label each assistant message as commentary on their work or as the final answer. fantasy, chatd, and the client dropped the label, so narration streamed below a live working block as if it were the answer and folded into the block only when the next tool call arrived. Follow-up requests also replayed it without the label. Pin coder/fantasy at 351055280157 (coder/fantasy#66), which keeps the label on text parts and replays it. chatd marks commentary text with a new narration field on every stream delta and on saved parts. The client keeps narration and answer text in separate blocks and treats narration as work, so it renders inside the working block from its first delta, and a turn whose only work is narration still gets a block, labeled without a step count.
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.
Problem
OpenAI models from gpt-5.3-codex on label each assistant output message with a
phase:commentaryfor narration between tool calls,final_answerfor the answer.GenerateandStreamdropped the label, so callers could not tell narration from an answer while text streamed. Follow-up requests also replayed assistant text without it, and OpenAI's API reference asks callers to "preserve and resend phase on all assistant messages", because dropping it can degrade performance.Fix
ResponsesTextMetadata(output item ID and phase) to text content fromGenerateand to theTextStartandTextEndstream parts.TextStartcarries it before the first delta, which is when OpenAI sends the phase.The type name, provider type key, and JSON shape match upstream charmbracelet#412. That PR replays the phase only when
storeis false, so a future upstream sync will conflict intoResponsesPromptWithValidation; keep this replay path. Through Coder's AI gateway, gpt-5.5, gpt-5, and gpt-4.1 accept a replayedphase: "commentary"on an assistant input message withstore: true(HTTP 200).Validation
responses_text_phase_test.gocovers stream metadata forcommentary,final_answer, and an absent phase;Generatemetadata for a response with both phases; and replay in both store modes after a JSON round trip through the provider registry. Removing each of the five mechanisms (stream start, stream end, Generate, replay, registry registration) fails a test.go test ./...andgolangci-lint run ./providers/openai/...pass.