Forward standalone assistant output to realtime - #27319
Conversation
There was a problem hiding this comment.
💡 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".
772f20c to
b5290d3
Compare
There was a problem hiding this comment.
💡 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".
e74db69 to
6db8125
Compare
There was a problem hiding this comment.
💡 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".
| output_text: truncate_realtime_text_to_token_budget( | ||
| &output_text, | ||
| REALTIME_ASSISTANT_OUTPUT_TOKEN_BUDGET, | ||
| ), |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
hmm is this actually p0?
7c2165b to
7afe0da
Compare
7afe0da to
f5d7eac
Compare
| if self.conversation.running_state().await.is_none() | ||
| || self.conversation.active_handoff_id().await.is_none() | ||
| { | ||
| if self.conversation.running_state().await.is_none() { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
approving to unblock. Let's add a todo to clean up
|
/merge |
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
conversation.handoff.appendwith a stable synthetic handoff ID[BACKEND]conversation.item.createmessage items, then enqueueresponse.createso the frontend model respondsTest plan