Skip to content

feat(providers/openai): capture and replay Responses message phase - #66

Merged
ibetitsmike merged 1 commit into
coder_2_33from
mike/openai-responses-phase
Oct 9, 2026
Merged

ibetitsmike merged 1 commit into
coder_2_33from
mike/openai-responses-phase

Conversation

@ibetitsmike

Copy link
Copy Markdown

Problem

OpenAI models from gpt-5.3-codex on label each assistant output message with a phase: commentary for narration between tool calls, final_answer for the answer. Generate and Stream dropped 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

  • Attach ResponsesTextMetadata (output item ID and phase) to text content from Generate and to the TextStart and TextEnd stream parts. TextStart carries it before the first delta, which is when OpenAI sends the phase.
  • Replay the phase on assistant input messages in both store modes. Messages without a phase replay unchanged.

The type name, provider type key, and JSON shape match upstream charmbracelet#412. That PR replays the phase only when store is false, so a future upstream sync will conflict in toResponsesPromptWithValidation; keep this replay path. Through Coder's AI gateway, gpt-5.5, gpt-5, and gpt-4.1 accept a replayed phase: "commentary" on an assistant input message with store: true (HTTP 200).

Validation

  • responses_text_phase_test.go covers stream metadata for commentary, final_answer, and an absent phase; Generate metadata 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 ./... and golangci-lint run ./providers/openai/... pass.
  • fix: fold web searches, answer reasoning, and OpenAI narration into working blocks coder#30529 consumes this to keep narration inside the chat UI's working block while it streams.

Xum acted on Mike's (@ibetitsmike) behalf to create this PR.

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.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 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-10-09T16:31:12.620315Z 2855b2d 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.

@ibetitsmike
ibetitsmike merged commit 3510552 into coder_2_33 Oct 9, 2026
6 of 7 checks passed
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.
ibetitsmike added a commit that referenced this pull request Oct 11, 2026
Picks up #66 (Responses message phase). The only conflict was the
assistant text replay in toResponsesPromptWithValidation: keep #66's
phase replay and this branch's canReferenceWebSearch flag.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant