Skip to content

Forward standalone assistant output to realtime - #27319

Merged
guinness-oai merged 2 commits into
mainfrom
guinness/realtime-handoff-append-minimal
Jun 10, 2026
Merged

Forward standalone assistant output to realtime#27319
guinness-oai merged 2 commits into
mainfrom
guinness/realtime-handoff-append-minimal

Conversation

@guinness-oai

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

Copy link
Copy Markdown
Contributor

Why

When a realtime session is open without an active frontend-model handoff, completed Codex assistant messages are currently dropped. That prevents the frontend model from hearing orchestrator preambles and final responses produced by typed turns or other non-handoff work, which makes the two models present as disconnected personas.

Active handoffs already forward each completed assistant message, including preambles. This change leaves those V1 and V2 paths intact and fills only the no-active-handoff gap.

What changed

  • Send standalone V1 assistant messages through conversation.handoff.append with a stable synthetic handoff ID
  • Send standalone V2 assistant messages as normal [BACKEND] conversation.item.create message items, then enqueue response.create so the frontend model responds
  • Preserve the existing active V1 and V2 transport and completion behavior
  • Continue excluding user messages from realtime mirroring
  • Skip empty output and cap each complete context injection, including its V2 prefix, at 1,000 tokens
  • Add end-to-end coverage for both wire formats, V2 response creation, preambles, final responses, and truncation

Test plan

  • CI

@guinness-oai
guinness-oai requested a review from a team as a code owner June 10, 2026 05:46

@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: 772f20c61b

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

Comment thread codex-rs/core/src/realtime_conversation.rs Outdated
Comment thread codex-rs/core/src/realtime_conversation.rs Outdated
@guinness-oai
guinness-oai force-pushed the guinness/realtime-handoff-append-minimal branch from 772f20c to b5290d3 Compare June 10, 2026 05:52
@guinness-oai

Copy link
Copy Markdown
Contributor Author

@codex

@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: b5290d3a05

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

Comment thread codex-rs/core/src/realtime_conversation.rs Outdated
@guinness-oai
guinness-oai force-pushed the guinness/realtime-handoff-append-minimal branch 2 times, most recently from e74db69 to 6db8125 Compare June 10, 2026 06:16
@guinness-oai

Copy link
Copy Markdown
Contributor Author

@codex

@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: 6db81257cd

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

Comment on lines +485 to +488
output_text: truncate_realtime_text_to_token_budget(
&output_text,
REALTIME_ASSISTANT_OUTPUT_TOKEN_BUDGET,
),

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 Enforce the >1k context review threshold

Standalone output without active handoff is fed back into realtime model context, but this 1,000-token budget uses the byte/4 estimator. For CJK/emoji or tokenizer-dense text it can still exceed the >1k-token manual-review threshold; use a stricter cap before forwarding. 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.

hmm is this actually p0?

Comment thread codex-rs/core/src/realtime_conversation.rs Outdated
@guinness-oai
guinness-oai force-pushed the guinness/realtime-handoff-append-minimal branch 3 times, most recently from 7c2165b to 7afe0da Compare June 10, 2026 07:06
@guinness-oai
guinness-oai force-pushed the guinness/realtime-handoff-append-minimal branch from 7afe0da to f5d7eac Compare June 10, 2026 07:13
if self.conversation.running_state().await.is_none()
|| self.conversation.active_handoff_id().await.is_none()
{
if self.conversation.running_state().await.is_none() {

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.

I am curious why not just removing || self.conversation.active_handoff_id().await.is_none()? why changes in codex-rs/codex-api/src/endpoint/realtime_websocket/methods.rs and codex-rs/core/src/realtime_conversation.rs

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.

Removing that condition is necessary, but not sufficient: handoff_out() also returns early without an active handoff. More importantly, the existing downstream path assumes a real handoff ID. V1 would otherwise emit a function-call output without a corresponding call, while V2 would drop the progress update and never request a response.

The realtime_conversation.rs changes add explicit standalone behavior: V1 sends conversation.handoff.append; V2 sends a normal message item plus response.create. The methods.rs change only exposes the existing V1 protocol event through RealtimeWebsocketWriter. The remaining bulk is E2E coverage for both contracts.

@aibrahim-oai aibrahim-oai 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.

approving to unblock. Let's add a todo to clean up

@guinness-oai
guinness-oai enabled auto-merge (squash) June 10, 2026 21:25
@guinness-oai

Copy link
Copy Markdown
Contributor Author

/merge

@guinness-oai
guinness-oai merged commit 22dd6eb into main Jun 10, 2026
54 of 55 checks passed
@guinness-oai
guinness-oai deleted the guinness/realtime-handoff-append-minimal branch June 10, 2026 21:32
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 10, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants