From 4d3a5dc799f75e035fbf983dae299a70eea7af72 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Mon, 13 Apr 2026 23:56:26 -0700 Subject: [PATCH] Avoid realtime final answer progress echo --- codex-rs/core/src/codex.rs | 18 ++++++++++++++---- codex-rs/core/src/realtime_conversation.rs | 19 ++++++++++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/codex-rs/core/src/codex.rs b/codex-rs/core/src/codex.rs index 2fd36376dd..d8eb660c44 100644 --- a/codex-rs/core/src/codex.rs +++ b/codex-rs/core/src/codex.rs @@ -107,6 +107,7 @@ use codex_protocol::items::UserMessageItem; use codex_protocol::items::build_hook_prompt_message; use codex_protocol::mcp::CallToolResult; use codex_protocol::models::BaseInstructions; +use codex_protocol::models::MessagePhase; use codex_protocol::models::PermissionProfile; use codex_protocol::models::format_allow_prefixes; use codex_protocol::openai_models::ModelInfo; @@ -2935,10 +2936,14 @@ impl Session { } async fn maybe_clear_realtime_handoff_for_event(&self, msg: &EventMsg) { - if !matches!(msg, EventMsg::TurnComplete(_)) { + let EventMsg::TurnComplete(event) = msg else { return; - } - if let Err(err) = self.conversation.handoff_complete().await { + }; + if let Err(err) = self + .conversation + .handoff_complete(event.last_agent_message.clone()) + .await + { debug!("failed to finalize realtime handoff output: {err}"); } self.conversation.clear_active_handoff().await; @@ -7349,7 +7354,12 @@ fn realtime_text_for_event(msg: &EventMsg) -> Option { match msg { EventMsg::AgentMessage(event) => Some(event.message.clone()), EventMsg::ItemCompleted(event) => match &event.item { - TurnItem::AgentMessage(item) => Some(agent_message_text(item)), + TurnItem::AgentMessage(item) + if item.phase.as_ref() != Some(&MessagePhase::FinalAnswer) => + { + Some(agent_message_text(item)) + } + TurnItem::AgentMessage(_) => None, _ => None, }, EventMsg::Error(_) diff --git a/codex-rs/core/src/realtime_conversation.rs b/codex-rs/core/src/realtime_conversation.rs index 8200ba4908..70d75e64e0 100644 --- a/codex-rs/core/src/realtime_conversation.rs +++ b/codex-rs/core/src/realtime_conversation.rs @@ -448,7 +448,10 @@ impl RealtimeConversationManager { Ok(()) } - pub(crate) async fn handoff_complete(&self) -> CodexResult<()> { + pub(crate) async fn handoff_complete( + &self, + final_output_text: Option, + ) -> CodexResult<()> { let handoff = { let guard = self.state.lock().await; guard.as_ref().map(|state| state.handoff.clone()) @@ -464,10 +467,20 @@ impl RealtimeConversationManager { let Some(handoff_id) = handoff.active_handoff.lock().await.clone() else { return Ok(()); }; - let Some(output_text) = handoff.last_output_text.lock().await.clone() else { - return Ok(()); + let output_text = match final_output_text { + Some(output_text) => output_text, + None => { + let Some(output_text) = handoff.last_output_text.lock().await.clone() else { + return Ok(()); + }; + output_text + } }; + if output_text.is_empty() { + return Ok(()); + } + handoff .output_tx .send(HandoffOutput::FinalUpdate {