mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Stop mirroring Codex user input into realtime (#27116)
## Why The realtime frontend model and the backing Codex thread should present one coherent assistant. Raw typed messages, steers, and worker reports belong to the orchestrator; the frontend model should receive the orchestrator's user-facing result rather than a second copy of those inputs. Today normal `turn/start` input is automatically inserted into the realtime conversation, while `turn/steer` is not. Besides creating inconsistent context, this can make the frontend model react independently before Codex has produced the response it should speak. ## What changed - Remove automatic accepted-user-input mirroring into realtime - Remove the mirror-only echo-suppression flag and dead V2 prefix helper - Preserve explicit app-to-realtime text injection and FEM-to-Codex delegation - Replace the positive mirror tests and obsolete snapshots with a negative routing regression test ## Test plan - `cargo test -p codex-core conversation_user_text_turn_is_not_sent_to_realtime` - `cargo test -p codex-core conversation_startup_context_is_truncated_and_sent_once_per_start` - `cargo test -p codex-core inbound_handoff_request_starts_turn`
This commit is contained in:
committed by
GitHub
Unverified
parent
f2969f36e8
commit
cc8325f181
@@ -739,10 +739,6 @@ fn prefix_realtime_text(text: String, prefix: &str, session_kind: RealtimeSessio
|
||||
format!("{prefix}{text}")
|
||||
}
|
||||
|
||||
pub(crate) fn prefix_realtime_v2_text(text: String, prefix: &str) -> String {
|
||||
prefix_realtime_text(text, prefix, RealtimeSessionKind::V2)
|
||||
}
|
||||
|
||||
fn validate_realtime_voice(version: RealtimeWsVersion, voice: RealtimeVoice) -> CodexResult<()> {
|
||||
let voices = RealtimeVoicesList::builtin();
|
||||
let allowed = match version {
|
||||
|
||||
@@ -15,10 +15,6 @@ use crate::session::session::Session;
|
||||
use crate::session::session::SessionSettingsUpdate;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::realtime_context::REALTIME_TURN_TOKEN_BUDGET;
|
||||
use crate::realtime_context::truncate_realtime_text_to_token_budget;
|
||||
use crate::realtime_conversation::REALTIME_USER_TEXT_PREFIX;
|
||||
use crate::realtime_conversation::prefix_realtime_v2_text;
|
||||
use crate::review_prompts::resolve_review_request;
|
||||
use crate::session::spawn_review_thread;
|
||||
use crate::tasks::CompactTask;
|
||||
@@ -54,9 +50,7 @@ use codex_protocol::request_user_input::RequestUserInputResponse;
|
||||
|
||||
use crate::context_manager::is_user_turn_boundary;
|
||||
use codex_protocol::dynamic_tools::DynamicToolResponse;
|
||||
use codex_protocol::items::UserMessageItem;
|
||||
use codex_protocol::mcp::RequestId as ProtocolRequestId;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use codex_rmcp_client::ElicitationAction;
|
||||
use codex_rmcp_client::ElicitationResponse;
|
||||
use serde_json::Value;
|
||||
@@ -91,14 +85,7 @@ pub async fn user_input_or_turn(
|
||||
op: Op,
|
||||
client_user_message_id: Option<String>,
|
||||
) {
|
||||
user_input_or_turn_inner(
|
||||
sess,
|
||||
sub_id,
|
||||
op,
|
||||
/*mirror_user_text_to_realtime*/ Some(()),
|
||||
client_user_message_id,
|
||||
)
|
||||
.await;
|
||||
user_input_or_turn_inner(sess, sub_id, op, client_user_message_id).await;
|
||||
}
|
||||
|
||||
pub async fn update_thread_settings(
|
||||
@@ -196,7 +183,6 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
sess: &Arc<Session>,
|
||||
sub_id: String,
|
||||
op: Op,
|
||||
mirror_user_text_to_realtime: Option<()>,
|
||||
client_user_message_id: Option<String>,
|
||||
) {
|
||||
let Op::UserInput {
|
||||
@@ -230,7 +216,7 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
}
|
||||
sess.maybe_emit_unknown_model_warning_for_turn(current_context.as_ref())
|
||||
.await;
|
||||
let accepted_items = match sess
|
||||
match sess
|
||||
.steer_input(
|
||||
items.clone(),
|
||||
additional_context.clone(),
|
||||
@@ -242,7 +228,6 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
{
|
||||
Ok(_) => {
|
||||
current_context.session_telemetry.user_prompt(&items);
|
||||
Some(items)
|
||||
}
|
||||
Err(SteerInputError::NoActiveTurn(items)) => {
|
||||
if let Some(responsesapi_client_metadata) = responsesapi_client_metadata {
|
||||
@@ -256,7 +241,6 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
Some(sess.mcp_elicitation_reviewer()),
|
||||
)
|
||||
.await;
|
||||
let accepted_items = items.clone();
|
||||
let additional_context_input = {
|
||||
let mut state = sess.state.lock().await;
|
||||
state.additional_context.merge(additional_context)
|
||||
@@ -278,7 +262,6 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
crate::tasks::RegularTask::new(),
|
||||
)
|
||||
.await;
|
||||
Some(accepted_items)
|
||||
}
|
||||
Err(err) => {
|
||||
sess.send_event_raw(Event {
|
||||
@@ -286,33 +269,7 @@ pub(super) async fn user_input_or_turn_inner(
|
||||
msg: EventMsg::Error(err.to_error_event()),
|
||||
})
|
||||
.await;
|
||||
None
|
||||
}
|
||||
};
|
||||
if let (Some(items), Some(())) = (accepted_items, mirror_user_text_to_realtime) {
|
||||
self::mirror_user_text_to_realtime(sess, &items).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn mirror_user_text_to_realtime(sess: &Arc<Session>, items: &[UserInput]) {
|
||||
let text = UserMessageItem::new(items).message();
|
||||
if text.is_empty() {
|
||||
return;
|
||||
}
|
||||
let text = if sess.conversation.is_running_v2().await {
|
||||
prefix_realtime_v2_text(text, REALTIME_USER_TEXT_PREFIX)
|
||||
} else {
|
||||
text
|
||||
};
|
||||
let text = truncate_realtime_text_to_token_budget(&text, REALTIME_TURN_TOKEN_BUDGET);
|
||||
if text.is_empty() {
|
||||
return;
|
||||
}
|
||||
if sess.conversation.running_state().await.is_none() {
|
||||
return;
|
||||
}
|
||||
if let Err(err) = sess.conversation.text_in(text).await {
|
||||
debug!("failed to mirror user text to realtime conversation: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1132,7 +1132,6 @@ impl Session {
|
||||
additional_context: Default::default(),
|
||||
thread_settings: Default::default(),
|
||||
},
|
||||
/*mirror_user_text_to_realtime*/ None,
|
||||
/*client_user_message_id*/ None,
|
||||
)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user