Skip to content

Forward assistant output to realtime through handoffs - #27127

Closed
guinness-oai wants to merge 8 commits into
mainfrom
guinness/realtime-terminal-output
Closed

Forward assistant output to realtime through handoffs#27127
guinness-oai wants to merge 8 commits into
mainfrom
guinness/realtime-terminal-output

Conversation

@guinness-oai

@guinness-oai guinness-oai commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Why

Realtime voice should feel like one coherent assistant even though the frontend model and Codex orchestrator are separate agents. That requires the frontend model to hear every user-facing Codex message, including preambles and finals, whether the turn began from a realtime handoff, typed input, or a worker report.

This change gives those messages one outbound contract: each completed Codex assistant message is forwarded exactly once through conversation.handoff.append.

Stack

Builds on #27116, which removes raw user-input mirroring.

What changed

  • Forward every completed assistant message, including preambles and finals, while excluding reasoning and tool plumbing
  • Use conversation.handoff.append for both V1 and V2
  • Preserve the active handoff ID for delegated turns and use the stable fallback ID codex for turns without an active handoff
  • Cap each injected assistant item at 1,000 approximate tokens, preserving its beginning and end with a truncation marker
  • Clear active handoff state on both turn completion and turn abort so later messages cannot inherit a stale ID
  • Remove the terminal-output developer item and response.create path
  • Keep steering and noop function-call acknowledgements unchanged

Test plan

  • just test -p codex-core assistant_output_is_capped_for_realtime_context
  • just test -p codex-core conversation_sends_each_assistant_message_once
  • just test -p codex-core conversation_clears_handoff_after_turn_abort
  • just test -p codex-app-server webrtc_terminal_output_without_handoff_reaches_realtime
  • just test -p codex-app-server webrtc_v1_handoff_request_delegates_and_appends_result
  • just test -p codex-app-server webrtc_v2_background_agent_tool_call_appends_preamble_and_final

@guinness-oai
guinness-oai force-pushed the guinness/realtime-stop-input-mirror branch from 6211ecf to 3c85d78 Compare June 9, 2026 08:47
@guinness-oai
guinness-oai force-pushed the guinness/realtime-terminal-output branch from be873bc to d63806e Compare June 9, 2026 08:56
@guinness-oai
guinness-oai force-pushed the guinness/realtime-terminal-output branch from d63806e to 1775690 Compare June 9, 2026 09:26
@guinness-oai
guinness-oai force-pushed the guinness/realtime-terminal-output branch from 1775690 to a678a86 Compare June 9, 2026 16:04
Base automatically changed from guinness/realtime-stop-input-mirror to main June 9, 2026 22:20
@guinness-oai guinness-oai changed the title Route terminal Codex output to realtime Forward assistant output to realtime through handoffs Jun 10, 2026
@guinness-oai
guinness-oai marked this pull request as ready for review June 10, 2026 00:43
@guinness-oai
guinness-oai requested a review from a team as a code owner June 10, 2026 00:43

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 002f9fe228

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if output_text.trim().is_empty() {
return;
}
self.conversation.send_assistant_output(output_text).await

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Badge Cap realtime assistant output before injecting context

When a realtime conversation is open, this forwards the full AgentMessage into the realtime model context with no truncation. Long assistant outputs can exceed context/API limits; the context guidance requires hard caps on injected items and flags >1k-token items for review. guidance

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 37d2758. Every assistant item is now capped at 1,000 approximate tokens in the shared RealtimeHandoffState::assistant_output path before either active or handoff-less sideband injection. The realtime truncator also accounts for its marker when enforcing the hard cap; assistant_output_is_capped_for_realtime_context covers the bound and head/tail preservation.

Comment on lines +1123 to +1125
assistant_output
.handoff_id
.unwrap_or_else(|| DEFAULT_HANDOFF_ID.to_string()),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Drop stale realtime handoff output before appending

If a V2 assistant output is queued and the handoff is cleared or replaced before the input task drains it (for example an abort immediately after an ItemCompleted), this still sends the captured handoff_id. The removed V2 path re-read active_handoff and dropped stale progress, so stale background output can now be appended to a cancelled or different realtime handoff.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

Closing this pull request because it has had no updates for more than 14 days. If you plan to continue working on it, feel free to reopen or open a new PR.

@github-actions github-actions Bot closed this Jun 24, 2026
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.

2 participants