From 875b8467214ee2b84c8c743d141f095f9eacae5c Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Thu, 14 May 2026 12:43:40 -0700 Subject: [PATCH] Remove core OverrideTurnContext op --- codex-rs/core/src/session/handlers.rs | 57 ---------------- codex-rs/core/src/session/tests.rs | 42 ++---------- .../tests/suite/collaboration_instructions.rs | 39 +++++++---- codex-rs/core/tests/suite/compact.rs | 3 +- codex-rs/core/tests/suite/compact_remote.rs | 6 +- .../core/tests/suite/compact_resume_fork.rs | 3 +- codex-rs/core/tests/suite/model_overrides.rs | 10 +-- codex-rs/core/tests/suite/model_switching.rs | 9 ++- .../core/tests/suite/model_visible_layout.rs | 3 +- codex-rs/core/tests/suite/override_updates.rs | 17 ++--- .../core/tests/suite/permissions_messages.rs | 12 ++-- codex-rs/core/tests/suite/personality.rs | 12 ++-- codex-rs/core/tests/suite/prompt_caching.rs | 6 +- codex-rs/core/tests/suite/remote_models.rs | 6 +- codex-rs/core/tests/suite/resume.rs | 3 +- codex-rs/core/tests/suite/review.rs | 3 +- codex-rs/docs/protocol_v1.md | 2 +- codex-rs/memories/write/src/startup_tests.rs | 3 +- codex-rs/protocol/src/protocol.rs | 65 ------------------- 19 files changed, 93 insertions(+), 208 deletions(-) diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 33d4ead581..e2f850d13f 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -81,19 +81,6 @@ pub async fn realtime_conversation_list_voices(sess: &Session, sub_id: String) { .await; } -pub async fn override_turn_context(sess: &Session, sub_id: String, updates: SessionSettingsUpdate) { - if let Err(err) = sess.update_settings(updates).await { - sess.send_event_raw(Event { - id: sub_id, - msg: EventMsg::Error(ErrorEvent { - message: err.to_string(), - codex_error_info: Some(CodexErrorInfo::BadRequest), - }), - }) - .await; - } -} - pub async fn user_input_or_turn(sess: &Arc, sub_id: String, op: Op) { user_input_or_turn_inner( sess, @@ -723,50 +710,6 @@ pub(super) async fn submission_loop( realtime_conversation_list_voices(&sess, sub.id.clone()).await; false } - Op::OverrideTurnContext { - cwd, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - windows_sandbox_level, - model, - effort, - summary, - service_tier, - collaboration_mode, - personality, - } => { - let collaboration_mode = if let Some(collab_mode) = collaboration_mode { - collab_mode - } else { - let state = sess.state.lock().await; - state.session_configuration.collaboration_mode.with_updates( - model.clone(), - effort, - /*developer_instructions*/ None, - ) - }; - override_turn_context( - &sess, - sub.id.clone(), - SessionSettingsUpdate { - cwd, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - windows_sandbox_level, - collaboration_mode: Some(collaboration_mode), - reasoning_summary: summary, - service_tier, - personality, - ..Default::default() - }, - ) - .await; - false - } Op::UserInput { .. } => { user_input_or_turn(&sess, sub.id.clone(), sub.op).await; false diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 2c03e75a80..c906ed0f29 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -2256,24 +2256,6 @@ async fn fork_startup_context_then_first_turn_diff_snapshot() -> anyhow::Result< developer_instructions: Some("Fork turn collaboration instructions.".to_string()), }, }; - forked - .thread - .submit(Op::OverrideTurnContext { - cwd: None, - approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, - sandbox_policy: None, - permission_profile: None, - windows_sandbox_level: None, - model: None, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(collaboration_mode), - personality: None, - }) - .await?; - forked .thread .submit(Op::UserInput { @@ -2284,7 +2266,11 @@ async fn fork_startup_context_then_first_turn_diff_snapshot() -> anyhow::Result< }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + turn_context: TurnContextOverrides { + approval_policy: Some(AskForApproval::Never), + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -5206,24 +5192,6 @@ fn submission_dispatch_span_uses_debug_for_realtime_audio() { #[test] fn op_kind_for_input_and_context_ops() { - assert_eq!( - Op::OverrideTurnContext { - cwd: None, - approval_policy: None, - approvals_reviewer: None, - sandbox_policy: None, - permission_profile: None, - windows_sandbox_level: None, - model: None, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, - } - .kind(), - "override_turn_context" - ); assert_eq!( Op::UserInput { environments: None, diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 727f5d135e..a18959a393 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -124,12 +124,13 @@ async fn user_input_includes_collaboration_instructions_after_override() -> Resu let collab_text = "collab instructions"; let collaboration_mode = collab_mode_with_instructions(Some(collab_text)); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -286,12 +287,13 @@ async fn override_then_next_turn_uses_updated_collaboration_instructions() -> Re let collaboration_mode = collab_mode_with_instructions(Some(collab_text)); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -342,12 +344,13 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu let turn_mode = collab_mode_with_instructions(Some(turn_text)); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -418,12 +421,13 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> let second_text = "second instructions"; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -449,12 +453,13 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -509,12 +514,13 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { let collab_text = "same instructions"; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -540,12 +546,13 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -599,12 +606,13 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang let plan_text = "plan mode instructions"; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -633,12 +641,13 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -696,12 +705,13 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() let collab_text = "mode-stable instructions"; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -730,12 +740,13 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -799,12 +810,13 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { let collab_text = "resume instructions"; initial .codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -869,12 +881,13 @@ async fn empty_collaboration_instructions_are_ignored() -> Result<()> { let current_model = test.session_configured.model.clone(); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index 7fa5cdf40e..08f6eef832 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -3284,12 +3284,13 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; } codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(PathBuf::from(PRETURN_CONTEXT_DIFF_CWD)), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 1f5f661f05..11ab20a5ad 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -2774,12 +2774,13 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_including_incoming_us for user in ["USER_ONE", "USER_TWO", "USER_THREE"] { if user == "USER_THREE" { codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(PathBuf::from(PRETURN_CONTEXT_DIFF_CWD)), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -2892,12 +2893,13 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(next_model.to_string()), effort: None, diff --git a/codex-rs/core/tests/suite/compact_resume_fork.rs b/codex-rs/core/tests/suite/compact_resume_fork.rs index 06cf5c357a..49f108d044 100644 --- a/codex-rs/core/tests/suite/compact_resume_fork.rs +++ b/codex-rs/core/tests/suite/compact_resume_fork.rs @@ -549,12 +549,13 @@ async fn snapshot_rollback_followup_turn_trims_context_updates() -> Result<()> { let override_cwd = config.cwd.join(PRETURN_CONTEXT_DIFF_CWD); std::fs::create_dir_all(&override_cwd)?; conversation - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(override_cwd.to_path_buf()), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/model_overrides.rs b/codex-rs/core/tests/suite/model_overrides.rs index 9f8835f19f..e904654b4b 100644 --- a/codex-rs/core/tests/suite/model_overrides.rs +++ b/codex-rs/core/tests/suite/model_overrides.rs @@ -9,7 +9,7 @@ use pretty_assertions::assert_eq; const CONFIG_TOML: &str = "config.toml"; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn override_turn_context_does_not_persist_when_config_exists() { +async fn turn_context_update_does_not_persist_when_config_exists() { let server = start_mock_server().await; let initial_contents = "model = \"gpt-4o\"\n"; let mut builder = test_codex() @@ -25,12 +25,13 @@ async fn override_turn_context_does_not_persist_when_config_exists() { let config_path = test.home.path().join(CONFIG_TOML); codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some("o3".to_string()), effort: Some(Some(ReasoningEffort::High)), @@ -52,7 +53,7 @@ async fn override_turn_context_does_not_persist_when_config_exists() { } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn override_turn_context_does_not_create_config_file() { +async fn turn_context_update_does_not_create_config_file() { let server = start_mock_server().await; let mut builder = test_codex(); let test = builder.build(&server).await.expect("create conversation"); @@ -64,12 +65,13 @@ async fn override_turn_context_does_not_create_config_file() { ); codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some("o3".to_string()), effort: Some(Some(ReasoningEffort::Medium)), diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index 9c9c4580d7..978308f2cb 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -166,12 +166,13 @@ async fn model_change_appends_model_instructions_developer_message() -> Result<( wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(next_model.to_string()), effort: None, @@ -246,12 +247,13 @@ async fn model_and_personality_change_only_appends_model_instructions() -> Resul wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(next_model.to_string()), effort: None, @@ -993,12 +995,13 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result< wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(smaller_model_slug.to_string()), effort: None, diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 2b275a97f5..664e05fbec 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -521,12 +521,13 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - fs::create_dir_all(&resume_override_cwd)?; resumed .codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(resume_override_cwd), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some("gpt-5.2".to_string()), effort: None, diff --git a/codex-rs/core/tests/suite/override_updates.rs b/codex-rs/core/tests/suite/override_updates.rs index d0e949947a..bc92b178af 100644 --- a/codex-rs/core/tests/suite/override_updates.rs +++ b/codex-rs/core/tests/suite/override_updates.rs @@ -24,8 +24,7 @@ fn collab_mode_with_instructions(instructions: Option<&str>) -> CollaborationMod } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn override_turn_context_without_user_turn_does_not_record_permissions_update() -> Result<()> -{ +async fn turn_context_update_without_user_turn_does_not_record_permissions_update() -> Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; @@ -35,12 +34,13 @@ async fn override_turn_context_without_user_turn_does_not_record_permissions_upd let test = builder.build(&server).await?; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -64,8 +64,7 @@ async fn override_turn_context_without_user_turn_does_not_record_permissions_upd } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn override_turn_context_without_user_turn_does_not_record_environment_update() -> Result<()> -{ +async fn turn_context_update_without_user_turn_does_not_record_environment_update() -> Result<()> { skip_if_no_network!(Ok(())); let server = start_mock_server().await; @@ -73,12 +72,13 @@ async fn override_turn_context_without_user_turn_does_not_record_environment_upd let new_cwd = TempDir::new()?; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(new_cwd.path().to_path_buf()), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -102,7 +102,7 @@ async fn override_turn_context_without_user_turn_does_not_record_environment_upd } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn override_turn_context_without_user_turn_does_not_record_collaboration_update() -> Result<()> +async fn turn_context_update_without_user_turn_does_not_record_collaboration_update() -> Result<()> { skip_if_no_network!(Ok(())); @@ -112,12 +112,13 @@ async fn override_turn_context_without_user_turn_does_not_record_collaboration_u let collaboration_mode = collab_mode_with_instructions(Some(collab_text)); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/permissions_messages.rs b/codex-rs/core/tests/suite/permissions_messages.rs index d22b37a843..13faecedf1 100644 --- a/codex-rs/core/tests/suite/permissions_messages.rs +++ b/codex-rs/core/tests/suite/permissions_messages.rs @@ -104,12 +104,13 @@ async fn permissions_message_added_on_override_change() -> Result<()> { wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -241,12 +242,13 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -332,12 +334,13 @@ async fn resume_replays_permissions_messages() -> Result<()> { initial .codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -441,12 +444,13 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { initial .codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 5ae0d1bd2a..9e8ddbf4fa 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -337,12 +337,13 @@ async fn user_turn_personality_some_adds_update_message() -> anyhow::Result<()> wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -421,12 +422,13 @@ async fn user_turn_personality_same_value_does_not_add_update_message() -> anyho wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -518,12 +520,13 @@ async fn user_turn_personality_skips_if_feature_disabled() -> anyhow::Result<()> wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, @@ -767,12 +770,13 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 17c57c39df..0a107b0cf1 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -443,12 +443,13 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an .to_legacy_sandbox_policy(config.cwd.as_path()) .expect("workspace profile should have legacy projection"); codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile: Some(permission_profile), + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: Some(Some(ReasoningEffort::High)), @@ -530,12 +531,13 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul }; codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: Some(AskForApproval::Never), approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some("gpt-5.4".to_string()), effort: Some(Some(ReasoningEffort::Low)), diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index aa976c3aa1..799775fbf3 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -639,12 +639,13 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { assert_eq!(model_info.shell_type, ConfigShellToolType::UnifiedExec); codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(REMOTE_MODEL_SLUG.to_string()), effort: None, @@ -899,12 +900,13 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { wait_for_model_available(&models_manager, model).await; codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some(model.to_string()), effort: None, diff --git a/codex-rs/core/tests/suite/resume.rs b/codex-rs/core/tests/suite/resume.rs index 29a8f4ff7a..c9d0bb0760 100644 --- a/codex-rs/core/tests/suite/resume.rs +++ b/codex-rs/core/tests/suite/resume.rs @@ -425,12 +425,13 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu let resumed = resume_builder.resume(&server, home, rollout_path).await?; resumed .codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: Some("gpt-5.4".to_string()), effort: None, diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 57467a1007..bdc1fe7540 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -790,12 +790,13 @@ async fn review_uses_overridden_cwd_for_base_branch_merge_base() { .await; codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: Some(repo_path.to_path_buf()), approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/docs/protocol_v1.md b/codex-rs/docs/protocol_v1.md index d18aa669ca..44b767dfa1 100644 --- a/codex-rs/docs/protocol_v1.md +++ b/codex-rs/docs/protocol_v1.md @@ -70,7 +70,7 @@ For complete documentation of the `Op` and `EventMsg` variants, refer to [protoc - `Op::Interrupt` – Interrupts a running turn - `Op::ExecApproval` – Approve or deny code execution - `Op::UserInputAnswer` – Provide answers for a `request_user_input` tool call - - `Op::UserTurn` and `Op::OverrideTurnContext` accept an optional `personality` override that updates the model’s communication style + - `Op::UserTurn` and `Op::UserInputWithTurnContext` accept an optional `personality` override that updates the model’s communication style Valid `personality` values are `friendly`, `pragmatic`, and `none`. When `none` is selected, the personality placeholder is replaced with an empty string. diff --git a/codex-rs/memories/write/src/startup_tests.rs b/codex-rs/memories/write/src/startup_tests.rs index 4fcb1d409b..cd48b6a1d7 100644 --- a/codex-rs/memories/write/src/startup_tests.rs +++ b/codex-rs/memories/write/src/startup_tests.rs @@ -243,12 +243,13 @@ async fn memories_startup_phase1_uses_live_thread_service_tier() -> anyhow::Resu assert_eq!(test.config.service_tier, None); test.codex - .submit(Op::OverrideTurnContext { + .update_turn_context_overrides(codex_core::CodexThreadTurnContextOverrides { cwd: None, approval_policy: None, approvals_reviewer: None, sandbox_policy: None, permission_profile: None, + active_permission_profile: None, windows_sandbox_level: None, model: None, effort: None, diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index c241ceda60..6a4c539385 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -524,70 +524,6 @@ pub enum Op { communication: InterAgentCommunication, }, - /// Override parts of the persistent turn context for subsequent turns. - /// - /// All fields are optional; when omitted, the existing value is preserved. - /// This does not enqueue any input – it only updates defaults used for - /// turns that rely on persistent session-level context (for example, - /// [`Op::UserInput`]). - OverrideTurnContext { - /// Updated `cwd` for sandbox/tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - cwd: Option, - - /// Updated command approval policy. - #[serde(skip_serializing_if = "Option::is_none")] - approval_policy: Option, - - /// Updated approval reviewer for future approval prompts. - #[serde(skip_serializing_if = "Option::is_none")] - approvals_reviewer: Option, - - /// Updated sandbox policy for tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - sandbox_policy: Option, - - /// Updated permissions profile for tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - permission_profile: Option, - - /// Updated Windows sandbox mode for tool execution. - #[serde(skip_serializing_if = "Option::is_none")] - windows_sandbox_level: Option, - - /// Updated model slug. When set, the model info is derived - /// automatically. - #[serde(skip_serializing_if = "Option::is_none")] - model: Option, - - /// Updated reasoning effort (honored only for reasoning-capable models). - /// - /// Use `Some(Some(_))` to set a specific effort, `Some(None)` to clear - /// the effort, or `None` to leave the existing value unchanged. - #[serde(skip_serializing_if = "Option::is_none")] - effort: Option>, - - /// Updated reasoning summary preference (honored only for reasoning-capable models). - #[serde(skip_serializing_if = "Option::is_none")] - summary: Option, - - /// Updated service tier preference for future turns. - /// - /// Use `Some(Some(_))` to set a specific tier, `Some(None)` to clear the - /// preference, or `None` to leave the existing value unchanged. - #[serde(skip_serializing_if = "Option::is_none")] - service_tier: Option>, - - /// EXPERIMENTAL - set a pre-set collaboration mode. - /// Takes precedence over model, effort, and developer instructions if set. - #[serde(skip_serializing_if = "Option::is_none")] - collaboration_mode: Option, - - /// Updated personality preference. - #[serde(skip_serializing_if = "Option::is_none")] - personality: Option, - }, - /// Approve a command execution ExecApproval { /// The id of the submission we are approving @@ -776,7 +712,6 @@ impl Op { Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", Self::UserInput { .. } => "user_input", Self::InterAgentCommunication { .. } => "inter_agent_communication", - Self::OverrideTurnContext { .. } => "override_turn_context", Self::ExecApproval { .. } => "exec_approval", Self::PatchApproval { .. } => "patch_approval", Self::ResolveElicitation { .. } => "resolve_elicitation",