From 30f6ab237205d2c55de9651fb2f04eab8ee3103e Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 13:19:04 -0700 Subject: [PATCH 01/15] Consolidate core input ops --- .../src/request_processors/turn_processor.rs | 35 +-- codex-rs/core/src/agent/control_tests.rs | 3 + codex-rs/core/src/codex_delegate.rs | 1 + codex-rs/core/src/guardian/review_session.rs | 37 ++- codex-rs/core/src/session/handlers.rs | 176 ++++-------- codex-rs/core/src/session/mod.rs | 1 + codex-rs/core/src/session/tests.rs | 68 ++--- .../src/tools/handlers/multi_agents_tests.rs | 1 + codex-rs/core/tests/common/test_codex.rs | 38 +-- codex-rs/core/tests/suite/abort_tasks.rs | 5 + codex-rs/core/tests/suite/apply_patch_cli.rs | 35 ++- codex-rs/core/tests/suite/approvals.rs | 70 +++-- codex-rs/core/tests/suite/client.rs | 110 +++++--- .../core/tests/suite/client_websockets.rs | 2 + codex-rs/core/tests/suite/code_mode.rs | 35 ++- .../tests/suite/collaboration_instructions.rs | 122 +++++---- codex-rs/core/tests/suite/compact.rs | 66 ++++- codex-rs/core/tests/suite/compact_remote.rs | 53 ++++ .../core/tests/suite/compact_remote_parity.rs | 1 + .../core/tests/suite/compact_resume_fork.rs | 1 + codex-rs/core/tests/suite/exec_policy.rs | 72 +++-- codex-rs/core/tests/suite/fork_thread.rs | 2 + codex-rs/core/tests/suite/hooks.rs | 2 + codex-rs/core/tests/suite/image_rollout.rs | 70 +++-- codex-rs/core/tests/suite/items.rs | 39 ++- codex-rs/core/tests/suite/json_result.rs | 35 ++- .../core/tests/suite/mcp_turn_metadata.rs | 38 ++- codex-rs/core/tests/suite/model_switching.rs | 35 ++- .../core/tests/suite/model_visible_layout.rs | 178 +++++++----- codex-rs/core/tests/suite/models_cache_ttl.rs | 35 ++- .../core/tests/suite/models_etag_responses.rs | 35 ++- codex-rs/core/tests/suite/otel.rs | 22 ++ codex-rs/core/tests/suite/pending_input.rs | 38 ++- .../core/tests/suite/permissions_messages.rs | 15 ++ codex-rs/core/tests/suite/personality.rs | 35 ++- codex-rs/core/tests/suite/plugins.rs | 3 + codex-rs/core/tests/suite/prompt_caching.rs | 185 ++++++++----- codex-rs/core/tests/suite/quota_exceeded.rs | 1 + .../core/tests/suite/realtime_conversation.rs | 3 + codex-rs/core/tests/suite/remote_env.rs | 35 ++- codex-rs/core/tests/suite/remote_models.rs | 253 +++++++++++------- .../core/tests/suite/request_compression.rs | 2 + .../core/tests/suite/request_permissions.rs | 35 ++- .../tests/suite/request_permissions_tool.rs | 35 ++- .../core/tests/suite/request_user_input.rs | 113 ++++---- .../suite/responses_api_proxy_headers.rs | 35 ++- codex-rs/core/tests/suite/resume.rs | 7 + codex-rs/core/tests/suite/review.rs | 1 + codex-rs/core/tests/suite/rmcp_client.rs | 35 ++- .../tests/suite/safety_check_downgrade.rs | 35 ++- codex-rs/core/tests/suite/search_tool.rs | 4 + codex-rs/core/tests/suite/shell_snapshot.rs | 140 ++++++---- codex-rs/core/tests/suite/skill_approval.rs | 35 ++- codex-rs/core/tests/suite/skills.rs | 35 ++- codex-rs/core/tests/suite/sqlite_state.rs | 35 ++- .../suite/stream_error_allows_next_turn.rs | 2 + .../core/tests/suite/stream_no_completed.rs | 1 + codex-rs/core/tests/suite/tool_harness.rs | 175 +++++++----- codex-rs/core/tests/suite/tool_parallelism.rs | 70 +++-- codex-rs/core/tests/suite/truncation.rs | 35 ++- codex-rs/core/tests/suite/unified_exec.rs | 246 ++++++++++------- .../core/tests/suite/user_notification.rs | 1 + codex-rs/core/tests/suite/user_shell_cmd.rs | 35 ++- codex-rs/core/tests/suite/view_image.rs | 35 ++- .../core/tests/suite/websocket_fallback.rs | 35 ++- codex-rs/core/tests/suite/window_headers.rs | 1 + codex-rs/mcp-server/src/codex_tool_runner.rs | 2 + codex-rs/memories/write/src/runtime.rs | 1 + codex-rs/protocol/src/protocol.rs | 245 ++++++----------- codex-rs/thread-manager-sample/src/main.rs | 1 + 70 files changed, 2067 insertions(+), 1356 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 54fc0383e44b..26de2644ef07 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -505,26 +505,28 @@ impl TurnRequestProcessor { // Start the turn by submitting the user input. Return its submission id as turn_id. let turn_op = if has_any_overrides { - Op::UserInputWithTurnContext { + Op::UserInput { items: mapped_items, environments: environment_selections, final_output_json_schema: params.output_schema, responsesapi_client_metadata: params.responsesapi_client_metadata, - cwd, - workspace_roots: runtime_workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level: None, - model, - effort, - summary, - service_tier, - collaboration_mode, - personality, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd, + workspace_roots: runtime_workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level: None, + model, + effort, + summary, + service_tier, + collaboration_mode, + personality, + }, } } else { Op::UserInput { @@ -532,6 +534,7 @@ impl TurnRequestProcessor { environments: environment_selections, final_output_json_schema: params.output_schema, responsesapi_client_metadata: params.responsesapi_client_metadata, + turn_context: Default::default(), } }; let turn_id = self diff --git a/codex-rs/core/src/agent/control_tests.rs b/codex-rs/core/src/agent/control_tests.rs index b95aad4489fd..abf9fd9b87aa 100644 --- a/codex-rs/core/src/agent/control_tests.rs +++ b/codex-rs/core/src/agent/control_tests.rs @@ -442,6 +442,7 @@ async fn send_input_submits_user_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness @@ -589,6 +590,7 @@ async fn spawn_agent_creates_thread_and_sends_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness @@ -737,6 +739,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 493771e28c80..d7c6abdd70c0 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -192,6 +192,7 @@ pub(crate) async fn run_codex_thread_one_shot( items: input, final_output_json_schema, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index afb5882a69bc..0c6358c0acda 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -706,22 +706,31 @@ async fn run_review_on_session( let submit_result = run_before_review_deadline( deadline, params.external_cancel.as_ref(), - Box::pin(review_session.codex.submit(Op::UserTurn { - environments: None, + Box::pin(review_session.codex.submit(Op::UserInput { items: prompt_items.items, - #[allow(deprecated)] - cwd: params.parent_turn.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: legacy_sandbox_policy, - permission_profile: Some(guardian_permission_profile), - model: params.model.clone(), - effort: params.reasoning_effort, - summary: Some(params.reasoning_summary), - service_tier: None, + environments: None, final_output_json_schema: Some(params.schema.clone()), - collaboration_mode: None, - personality: params.personality, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + #[allow(deprecated)] + cwd: Some(params.parent_turn.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(legacy_sandbox_policy), + permission_profile: Some(guardian_permission_profile), + summary: Some(params.reasoning_summary), + service_tier: None, + personality: params.personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: params.model.clone(), + reasoning_effort: params.reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, })), ) .await; diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index a26b9bb3f6fe..33d4ead58120 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -43,14 +43,12 @@ use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::ThreadRolledBackEvent; use codex_protocol::protocol::TurnAbortReason; +use codex_protocol::protocol::TurnContextOverrides; use codex_protocol::protocol::WarningEvent; use codex_protocol::request_permissions::RequestPermissionsResponse; use codex_protocol::request_user_input::RequestUserInputResponse; use crate::context_manager::is_user_turn_boundary; -use codex_protocol::config_types::CollaborationMode; -use codex_protocol::config_types::ModeKind; -use codex_protocol::config_types::Settings; use codex_protocol::dynamic_tools::DynamicToolResponse; use codex_protocol::items::UserMessageItem; use codex_protocol::mcp::RequestId as ProtocolRequestId; @@ -113,126 +111,22 @@ pub(super) async fn user_input_or_turn_inner( mirror_user_text_to_realtime: Option<()>, ) { let (items, updates, responsesapi_client_metadata) = match op { - Op::UserTurn { - cwd, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - model, - effort, - summary, - service_tier, - final_output_json_schema, + Op::UserInput { items, - collaboration_mode, - personality, environments, - } => { - let collaboration_mode = collaboration_mode.or_else(|| { - Some(CollaborationMode { - mode: ModeKind::Default, - settings: Settings { - model: model.clone(), - reasoning_effort: effort, - developer_instructions: None, - }, - }) - }); - ( - items, - SessionSettingsUpdate { - cwd: Some(cwd), - approval_policy: Some(approval_policy), - approvals_reviewer, - sandbox_policy: Some(sandbox_policy), - workspace_roots: None, - profile_workspace_roots: None, - permission_profile, - active_permission_profile: None, - windows_sandbox_level: None, - collaboration_mode, - reasoning_summary: summary, - service_tier, - final_output_json_schema: Some(final_output_json_schema), - environments, - personality, - app_server_client_name: None, - app_server_client_version: None, - }, - None, - ) - } - Op::UserInputWithTurnContext { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - model, - effort, - summary, - service_tier, final_output_json_schema, - items, responsesapi_client_metadata, - collaboration_mode, - personality, - environments, + turn_context, } => { - let collaboration_mode = if let Some(collab_mode) = collaboration_mode { - Some(collab_mode) + let mut updates = if turn_context == TurnContextOverrides::default() { + SessionSettingsUpdate::default() } else { - let state = sess.state.lock().await; - Some( - state - .session_configuration - .collaboration_mode - .with_updates(model, effort, /*developer_instructions*/ None), - ) + turn_context_settings_update(sess, turn_context).await }; - ( - items, - SessionSettingsUpdate { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - collaboration_mode, - reasoning_summary: summary, - service_tier, - final_output_json_schema: Some(final_output_json_schema), - environments, - personality, - app_server_client_name: None, - app_server_client_version: None, - }, - responsesapi_client_metadata, - ) + updates.final_output_json_schema = Some(final_output_json_schema); + updates.environments = environments; + (items, updates, responsesapi_client_metadata) } - Op::UserInput { - items, - environments, - final_output_json_schema, - responsesapi_client_metadata, - } => ( - items, - SessionSettingsUpdate { - final_output_json_schema: Some(final_output_json_schema), - environments, - ..Default::default() - }, - responsesapi_client_metadata, - ), _ => unreachable!(), }; @@ -289,6 +183,54 @@ pub(super) async fn user_input_or_turn_inner( } } +async fn turn_context_settings_update( + sess: &Session, + turn_context: TurnContextOverrides, +) -> SessionSettingsUpdate { + let TurnContextOverrides { + cwd, + workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level, + model, + effort, + summary, + service_tier, + collaboration_mode, + personality, + } = turn_context; + let collaboration_mode = if let Some(collaboration_mode) = collaboration_mode { + collaboration_mode + } else { + let state = sess.state.lock().await; + state + .session_configuration + .collaboration_mode + .with_updates(model, effort, /*developer_instructions*/ None) + }; + SessionSettingsUpdate { + cwd, + workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level, + collaboration_mode: Some(collaboration_mode), + reasoning_summary: summary, + service_tier, + personality, + ..Default::default() + } +} + async fn mirror_user_text_to_realtime(sess: &Arc, items: &[UserInput]) { let text = UserMessageItem::new(items).message(); if text.is_empty() { @@ -825,9 +767,7 @@ pub(super) async fn submission_loop( .await; false } - Op::UserInput { .. } - | Op::UserInputWithTurnContext { .. } - | Op::UserTurn { .. } => { + Op::UserInput { .. } => { user_input_or_turn(&sess, sub.id.clone(), sub.op).await; false } diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index d67e79f79417..9a78242222ae 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -1096,6 +1096,7 @@ impl Session { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, /*mirror_user_text_to_realtime*/ None, ) diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index bb858999e48c..2c03e75a80ac 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -2220,6 +2220,7 @@ 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(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2283,6 +2284,7 @@ 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(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -5203,7 +5205,7 @@ fn submission_dispatch_span_uses_debug_for_realtime_audio() { } #[test] -fn op_kind_distinguishes_turn_ops() { +fn op_kind_for_input_and_context_ops() { assert_eq!( Op::OverrideTurnContext { cwd: None, @@ -5228,35 +5230,11 @@ fn op_kind_distinguishes_turn_ops() { items: vec![], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), } .kind(), "user_input" ); - assert_eq!( - Op::UserInputWithTurnContext { - environments: None, - items: vec![], - final_output_json_schema: None, - responsesapi_client_metadata: None, - cwd: None, - workspace_roots: None, - profile_workspace_roots: 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, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, - } - .kind(), - "user_input_with_turn_context" - ); } #[tokio::test] @@ -5267,24 +5245,33 @@ async fn user_turn_updates_approvals_reviewer() { handlers::user_input_or_turn( &session, "sub-1".to_string(), - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: "hello".to_string(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: turn_context.model_info.slug.clone(), - effort: config.model_reasoning_effort, - summary: config.model_reasoning_summary, - service_tier: None, + environments: None, final_output_json_schema: None, - collaboration_mode: None, - personality: config.personality, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: config.model_reasoning_summary, + service_tier: None, + personality: config.personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: turn_context.model_info.slug.clone(), + reasoning_effort: config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }, ) .await; @@ -8335,6 +8322,7 @@ async fn active_goal_continuation_runs_again_after_no_tool_turn() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -8439,6 +8427,7 @@ async fn pending_request_user_input_does_not_spawn_extra_goal_continuation() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -8863,6 +8852,7 @@ async fn completed_goal_accounts_current_turn_tokens_before_tool_response() -> a }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index 0044bf852247..c0c001690734 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -2470,6 +2470,7 @@ async fn send_input_accepts_structured_items() { ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }; let captured = manager .captured_ops() diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index 947111d3fc9a..f0a22a31aeef 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -198,8 +198,7 @@ pub enum ShellModelOutput { // UnifiedExec has its own set of tests } -/// Returns the permission fields required by `Op::UserTurn` for tests that -/// construct the op directly. +/// Returns the permission fields required by test turn-context overrides. pub fn turn_permission_fields( permission_profile: PermissionProfile, cwd: &Path, @@ -762,24 +761,33 @@ impl TestCodex { turn_permission_fields(permission_profile, self.config.cwd.as_path()); let session_model = self.session_configured.model.clone(); self.codex - .submit(Op::UserTurn { - environments, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: environments, final_output_json_schema: None, - cwd: self.config.cwd.to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(self.config.cwd.to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile: permission_profile, + summary: None, + service_tier: service_tier, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/abort_tasks.rs b/codex-rs/core/tests/suite/abort_tasks.rs index c81a1c2f68ac..fd2c06aef3be 100644 --- a/codex-rs/core/tests/suite/abort_tasks.rs +++ b/codex-rs/core/tests/suite/abort_tasks.rs @@ -53,6 +53,7 @@ async fn interrupt_long_running_tool_emits_turn_aborted() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -109,6 +110,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -129,6 +131,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -211,6 +214,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -231,6 +235,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index 9185b8a7bd47..c2c8cc51a7d8 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -84,24 +84,33 @@ async fn submit_without_wait_with_turn_permissions( let test = harness.test(); let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: harness.cwd().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(harness.cwd().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index 5045755e3225..04a6e405bfc0 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -644,24 +644,33 @@ async fn submit_turn( let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2578,24 +2587,33 @@ async fn matched_prefix_rule_runs_unsandboxed_under_zsh_fork() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run allowed touch under zsh fork".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 42bacb9bdc5f..d05450684c40 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -392,6 +392,7 @@ async fn resume_includes_initial_messages_and_sends_prior_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -757,6 +758,7 @@ async fn includes_session_id_thread_id_and_model_headers_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -967,6 +969,7 @@ async fn includes_base_instructions_override_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1023,6 +1026,7 @@ async fn chatgpt_auth_sends_correct_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1146,6 +1150,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1184,6 +1189,7 @@ async fn includes_user_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1271,6 +1277,7 @@ async fn includes_apps_guidance_as_developer_message_for_chatgpt_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1333,6 +1340,7 @@ async fn omits_apps_guidance_for_api_key_auth_even_when_feature_enabled() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1391,6 +1399,7 @@ async fn omits_apps_guidance_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1432,6 +1441,7 @@ async fn omits_environment_context_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1488,6 +1498,7 @@ async fn skills_append_to_developer_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1570,6 +1581,7 @@ async fn skills_use_aliases_in_developer_message_under_budget_pressure() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1630,6 +1642,7 @@ async fn includes_configured_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1671,6 +1684,7 @@ async fn includes_no_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1713,6 +1727,7 @@ async fn includes_default_reasoning_effort_in_request_when_defined_by_model_info }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1743,12 +1758,7 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re sse(vec![ev_response_created("resp1"), ev_completed("resp1")]), ) .await; - let TestCodex { - codex, - config, - session_configured, - .. - } = test_codex().with_model("gpt-5.4").build(&server).await?; + let TestCodex { codex, config, .. } = test_codex().with_model("gpt-5.4").build(&server).await?; let collaboration_mode = CollaborationMode { mode: ModeKind::Default, @@ -1760,28 +1770,30 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re }; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: session_configured.model.clone(), - effort: Some(ReasoningEffort::Low), - summary: Some( - config - .model_reasoning_summary - .unwrap_or(ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some( + config + .model_reasoning_summary + .unwrap_or(ReasoningSummary::Auto), + ), + service_tier: None, + personality: None, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; @@ -1826,6 +1838,7 @@ async fn configured_reasoning_summary_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1882,24 +1895,33 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() .await?; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: session_configured.model, - effort: None, - summary: Some(ReasoningSummary::Concise), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some(ReasoningSummary::Concise), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_configured.model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await .unwrap(); @@ -1945,6 +1967,7 @@ async fn reasoning_summary_is_omitted_when_disabled() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2003,6 +2026,7 @@ async fn reasoning_summary_none_overrides_model_catalog_default() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2041,6 +2065,7 @@ async fn includes_default_verbosity_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2088,6 +2113,7 @@ async fn configured_verbosity_not_sent_for_models_without_support() -> anyhow::R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2134,6 +2160,7 @@ async fn configured_verbosity_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2185,6 +2212,7 @@ async fn includes_developer_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2480,6 +2508,7 @@ async fn token_count_includes_rate_limits_snapshot() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2618,6 +2647,7 @@ async fn usage_limit_error_emits_rate_limit_event() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -2694,6 +2724,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2708,6 +2739,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2792,6 +2824,7 @@ async fn incomplete_response_emits_content_filter_error_message() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2902,6 +2935,7 @@ async fn azure_overrides_assign_properties_used_for_responses_url() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2990,6 +3024,7 @@ async fn env_var_overrides_loaded_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3046,6 +3081,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3061,6 +3097,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3076,6 +3113,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index a14ee6518fa6..3ae5be3e904b 100755 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -1208,6 +1208,7 @@ async fn responses_websocket_usage_limit_error_emits_rate_limit_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -1296,6 +1297,7 @@ async fn responses_websocket_invalid_request_error_with_status_is_forwarded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting invalid request events"); diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index f117631c4acb..0da293534f59 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -2588,24 +2588,33 @@ text( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "use exec to inspect and call hidden tools".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 5ce115cdaff8..727f5d135e85 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -86,6 +86,7 @@ async fn no_collaboration_instructions_by_default() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -148,6 +149,7 @@ async fn user_input_includes_collaboration_instructions_after_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -176,28 +178,30 @@ async fn collaboration_instructions_added_on_user_turn() -> Result<()> { let collaboration_mode = collab_mode_with_instructions(Some(collab_text)); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + service_tier: None, + personality: None, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -228,28 +232,30 @@ async fn collaboration_instructions_omitted_when_disabled() -> Result<()> { let collaboration_mode = collab_mode_with_instructions(Some("turn instructions")); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + service_tier: None, + personality: None, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -305,6 +311,7 @@ async fn override_then_next_turn_uses_updated_collaboration_instructions() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -352,28 +359,30 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu .await?; test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(turn_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + service_tier: None, + personality: None, + collaboration_mode: Some(turn_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -434,6 +443,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -464,6 +474,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -523,6 +534,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -553,6 +565,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -614,6 +627,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -647,6 +661,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -709,6 +724,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -742,6 +758,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -808,6 +825,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -823,6 +841,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -882,6 +901,7 @@ async fn empty_collaboration_instructions_are_ignored() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index be3423a85ead..7fa5cdf40e22 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -88,24 +88,33 @@ fn ev_shell_command_call(call_id: &str, command: &str) -> serde_json::Value { fn disabled_permission_user_turn(text: impl Into, cwd: PathBuf, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } @@ -386,6 +395,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -410,6 +420,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -586,6 +597,7 @@ async fn manual_pre_compact_block_decision_does_not_block_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -658,6 +670,7 @@ async fn compact_hooks_respect_matchers_and_post_runs_after_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -727,6 +740,7 @@ async fn manual_compact_uses_custom_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -873,6 +887,7 @@ async fn manual_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1038,6 +1053,7 @@ async fn multiple_auto_compact_per_task_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -1509,6 +1525,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1524,6 +1541,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1539,6 +1557,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1709,6 +1728,7 @@ async fn auto_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1789,6 +1809,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1803,6 +1824,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1817,6 +1839,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2250,6 +2273,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2264,6 +2288,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2278,6 +2303,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2366,6 +2392,7 @@ async fn manual_compact_retries_after_context_window_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2469,6 +2496,7 @@ async fn manual_compact_non_context_failure_retries_then_emits_task_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -2563,6 +2591,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2580,6 +2609,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2597,6 +2627,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2760,6 +2791,7 @@ async fn auto_compact_allows_multiple_attempts_when_interleaved_with_other_turn_ }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2864,6 +2896,7 @@ async fn snapshot_request_shape_mid_turn_continuation_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3063,6 +3096,7 @@ async fn auto_compact_counts_encrypted_reasoning_before_last_user() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3181,6 +3215,7 @@ async fn auto_compact_runs_when_reasoning_header_clears_between_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3242,6 +3277,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -3281,6 +3317,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -3469,6 +3506,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user"); @@ -3483,6 +3521,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit second user"); @@ -3555,6 +3594,7 @@ async fn snapshot_request_shape_manual_compact_without_previous_user_messages() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit follow-up user input"); diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 15197042fae8..1f5f661f053b 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -326,6 +326,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -342,6 +343,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -516,6 +518,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -535,6 +538,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -548,6 +552,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -567,6 +572,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -580,6 +586,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -747,6 +754,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -763,6 +771,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -856,6 +865,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -872,6 +882,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -962,6 +973,7 @@ async fn remote_compact_filters_deferred_dynamic_tools() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -1033,6 +1045,7 @@ async fn remote_compact_runs_automatically() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1113,6 +1126,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1126,6 +1140,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1243,6 +1258,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1256,6 +1272,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1275,6 +1292,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1374,6 +1392,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1387,6 +1406,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1480,6 +1500,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1496,6 +1517,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1586,6 +1608,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1602,6 +1625,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1672,6 +1696,7 @@ async fn remote_manual_compact_emits_context_compaction_items() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1752,6 +1777,7 @@ async fn remote_manual_compact_failure_emits_task_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1835,6 +1861,7 @@ async fn remote_compact_persists_replacement_history_in_rollout() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -1977,6 +2004,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -1994,6 +2022,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2018,6 +2047,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2113,6 +2143,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2129,6 +2160,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2200,6 +2232,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2213,6 +2246,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2279,6 +2313,7 @@ async fn remote_request_uses_custom_experimental_realtime_start_instructions() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2339,6 +2374,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2354,6 +2390,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2428,6 +2465,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2444,6 +2482,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2526,6 +2565,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2541,6 +2581,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2631,6 +2672,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2660,6 +2702,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2756,6 +2799,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_including_incoming_us }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2842,6 +2886,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2871,6 +2916,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2989,6 +3035,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3002,6 +3049,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; let error_message = wait_for_event_match(&codex, |event| match event { @@ -3086,6 +3134,7 @@ async fn snapshot_request_shape_remote_mid_turn_continuation_compaction() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3163,6 +3212,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_summary_only_reinject }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3248,6 +3298,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3264,6 +3315,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3345,6 +3397,7 @@ async fn snapshot_request_shape_remote_manual_compact_without_previous_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact_remote_parity.rs b/codex-rs/core/tests/suite/compact_remote_parity.rs index 32c13b0b27c4..c465480558b0 100644 --- a/codex-rs/core/tests/suite/compact_remote_parity.rs +++ b/codex-rs/core/tests/suite/compact_remote_parity.rs @@ -606,6 +606,7 @@ async fn submit_user_input(codex: &codex_core::CodexThread, items: Vec, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user turn"); diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index 3f6c9cfdc08f..02267b54d628 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -46,24 +46,35 @@ async fn submit_user_turn( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: collaboration_mode.or({ + Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }) + }), + ..Default::default() + }, }) .await?; Ok(()) @@ -126,24 +137,33 @@ async fn execpolicy_blocks_shell_invocation() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run shell command".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/fork_thread.rs b/codex-rs/core/tests/suite/fork_thread.rs index 37456dce631e..75256ae786d2 100644 --- a/codex-rs/core/tests/suite/fork_thread.rs +++ b/codex-rs/core/tests/suite/fork_thread.rs @@ -57,6 +57,7 @@ async fn fork_thread_twice_drops_to_first_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -180,6 +181,7 @@ async fn fork_thread_from_history_does_not_require_source_rollout_path() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/hooks.rs b/codex-rs/core/tests/suite/hooks.rs index 53649afff849..8eda28354e94 100644 --- a/codex-rs/core/tests/suite/hooks.rs +++ b/codex-rs/core/tests/suite/hooks.rs @@ -1440,6 +1440,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1458,6 +1459,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; } diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 3404edbb1e9e..6e692e19681c 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -113,8 +113,7 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::LocalImage { path: abs_path.clone(), @@ -125,18 +124,28 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu text_elements: Vec::new(), }, ], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -204,8 +213,7 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::Image { image_url: image_url.clone(), @@ -216,18 +224,28 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> text_elements: Vec::new(), }, ], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 65087a1fe79a..de30306c5792 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -44,30 +44,32 @@ use std::path::PathBuf; fn disabled_plan_turn( text: &str, - model: String, + _model: String, collaboration_mode: CollaborationMode, ) -> anyhow::Result { let cwd = std::env::current_dir()?; let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); - Ok(Op::UserTurn { - environments: None, + Ok(Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(collaboration_mode), - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) } @@ -121,6 +123,7 @@ async fn user_message_item_is_emitted() -> anyhow::Result<()> { items: vec![expected_input.clone()], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -179,6 +182,7 @@ async fn assistant_message_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -239,6 +243,7 @@ async fn reasoning_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -300,6 +305,7 @@ async fn web_search_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -379,6 +385,7 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -465,6 +472,7 @@ async fn image_generation_call_event_is_emitted_when_image_save_fails() -> anyho }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -520,6 +528,7 @@ async fn agent_message_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1103,6 +1112,7 @@ async fn reasoning_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1157,6 +1167,7 @@ async fn reasoning_raw_content_delta_respects_flag() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index c4ce8ac90827..91b83fbd0060 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -75,24 +75,33 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { // 1) Normal user input – should hit server once. codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello world".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: Some(serde_json::from_str(SCHEMA)?), - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 17fe33dc8ba1..3ea70a10c620 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -64,27 +64,39 @@ async fn submit_user_turn( approval_policy: AskForApproval, collaboration_mode: Option, ) -> Result<()> { + let session_model = test.session_configured.model.clone(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: collaboration_mode.or({ + Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }) + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index adce6e36ebb8..9c9c4580d704 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -42,21 +42,30 @@ use wiremock::MockServer; fn read_only_user_turn(test: &TestCodex, items: Vec, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items, + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 7ae148788ef8..2b275a97f58e 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -117,24 +117,33 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { turn_permission_fields(PermissionProfile::read_only(), first_turn_cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "first turn".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: first_turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: first_sandbox_policy, - permission_profile: first_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(first_turn_cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(first_sandbox_policy), + permission_profile: first_permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -147,24 +156,33 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { preturn_context_diff_cwd.as_path(), ); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "second turn with context updates".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: preturn_context_diff_cwd, - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: None, - sandbox_policy: second_sandbox_policy, - permission_profile: second_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: Some(Personality::Friendly), + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(preturn_context_diff_cwd), + approval_policy: Some(AskForApproval::OnRequest), + approvals_reviewer: None, + sandbox_policy: Some(second_sandbox_policy), + permission_profile: second_permission_profile, + summary: None, + service_tier: None, + personality: Some(Personality::Friendly), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -230,24 +248,33 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R turn_permission_fields(PermissionProfile::read_only(), cwd_one.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "first turn in agents_one".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_one.clone(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: first_sandbox_policy, - permission_profile: first_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_one.clone()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(first_sandbox_policy), + permission_profile: first_permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -258,24 +285,33 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R let (second_sandbox_policy, second_permission_profile) = turn_permission_fields(PermissionProfile::read_only(), cwd_two.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "second turn in agents_two".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_two, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: second_sandbox_policy, - permission_profile: second_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_two), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(second_sandbox_policy), + permission_profile: second_permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -344,6 +380,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -376,24 +413,33 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul ); resumed .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "resume and change personality".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: resume_override_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: resumed.session_configured.model.clone(), - effort: resumed.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: Some(Personality::Friendly), + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(resume_override_cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: Some(Personality::Friendly), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: resumed.session_configured.model.clone(), + reasoning_effort: resumed.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&resumed.codex, |event| { @@ -451,6 +497,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -499,6 +546,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 8463ee1cf167..ffe06c114596 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -92,24 +92,33 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { turn_permission_fields(PermissionProfile::Disabled, test.cwd_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hi".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: codex_protocol::protocol::AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(codex_protocol::protocol::AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index 346c503c2579..979d3dafa0c7 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -104,24 +104,33 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch .await; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please run a tool".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/otel.rs b/codex-rs/core/tests/suite/otel.rs index 03692ac547ac..31477f0d3a76 100644 --- a/codex-rs/core/tests/suite/otel.rs +++ b/codex-rs/core/tests/suite/otel.rs @@ -122,6 +122,7 @@ async fn responses_api_emits_api_request_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -167,6 +168,7 @@ async fn process_sse_emits_tracing_for_output_item() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -212,6 +214,7 @@ async fn process_sse_emits_failed_event_on_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -258,6 +261,7 @@ async fn process_sse_records_failed_event_when_stream_closes_without_completed() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -324,6 +328,7 @@ async fn process_sse_failed_event_records_response_error_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -388,6 +393,7 @@ async fn process_sse_failed_event_logs_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -439,6 +445,7 @@ async fn process_sse_failed_event_logs_missing_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -499,6 +506,7 @@ async fn process_sse_failed_event_logs_response_completed_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -553,6 +561,7 @@ async fn process_sse_emits_completed_telemetry() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -631,6 +640,7 @@ async fn turn_and_completed_response_spans_record_token_usage() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -718,6 +728,7 @@ async fn handle_responses_span_records_response_kind_and_tool_name() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -811,6 +822,7 @@ async fn record_responses_sets_span_fields_for_response_events() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -899,6 +911,7 @@ async fn handle_response_item_records_tool_result_for_custom_tool_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -974,6 +987,7 @@ async fn handle_response_item_records_tool_result_for_function_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1050,6 +1064,7 @@ async fn handle_response_item_records_tool_result_for_shell_command_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1158,6 +1173,7 @@ async fn handle_shell_command_autoapprove_from_config_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1212,6 +1228,7 @@ async fn handle_shell_command_user_approved_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1281,6 +1298,7 @@ async fn handle_shell_command_user_approved_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1350,6 +1368,7 @@ async fn handle_sandbox_error_user_approves_retry_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1419,6 +1438,7 @@ async fn handle_shell_command_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1488,6 +1508,7 @@ async fn handle_sandbox_error_user_approves_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1558,6 +1579,7 @@ async fn handle_sandbox_error_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index 62851c515d59..a3c9a5ebfa95 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -103,6 +103,7 @@ async fn submit_user_input(codex: &CodexThread, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap_or_else(|err| panic!("submit user input: {err}")); @@ -112,24 +113,33 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await .unwrap_or_else(|err| panic!("submit user turn: {err}")); @@ -285,6 +295,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -303,6 +314,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/permissions_messages.rs b/codex-rs/core/tests/suite/permissions_messages.rs index c4f1bef968a6..d22b37a8437d 100644 --- a/codex-rs/core/tests/suite/permissions_messages.rs +++ b/codex-rs/core/tests/suite/permissions_messages.rs @@ -58,6 +58,7 @@ async fn permissions_message_sent_once_on_start() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -97,6 +98,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -127,6 +129,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -172,6 +175,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -185,6 +189,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -230,6 +235,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -260,6 +266,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -318,6 +325,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -350,6 +358,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -365,6 +374,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -424,6 +434,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -456,6 +467,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -477,6 +489,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -512,6 +525,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -572,6 +586,7 @@ async fn permissions_message_includes_writable_roots() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 09eb61fa69a9..5ae0d1bd2a4d 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -60,24 +60,33 @@ fn read_only_text_turn_with_personality( ) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/plugins.rs b/codex-rs/core/tests/suite/plugins.rs index 7b10db025915..f2b9cfeba9de 100644 --- a/codex-rs/core/tests/suite/plugins.rs +++ b/codex-rs/core/tests/suite/plugins.rs @@ -227,6 +227,7 @@ async fn capability_sections_render_in_developer_message_in_order() -> Result<() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -305,6 +306,7 @@ async fn explicit_plugin_mentions_inject_plugin_guidance() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -386,6 +388,7 @@ async fn explicit_plugin_mentions_track_plugin_used_analytics() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index f887131eef95..17c57c39df34 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -153,6 +153,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -166,6 +167,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -249,6 +251,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -262,6 +265,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -326,6 +330,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -339,6 +344,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -421,6 +427,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -462,6 +469,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -547,6 +555,7 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -700,6 +709,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -716,24 +726,33 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, new_cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: new_cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: "o3".to_string(), - effort: Some(ReasoningEffort::High), - summary: Some(ReasoningSummary::Detailed), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(new_cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Detailed), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: "o3".to_string(), + reasoning_effort: Some(ReasoningEffort::High), + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -830,47 +849,65 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a let default_summary = config.model_reasoning_summary; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 1".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model.clone(), - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(default_sandbox_policy.clone()), + permission_profile: None, + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model.clone(), + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model.clone(), - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(default_sandbox_policy.clone()), + permission_profile: None, + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model.clone(), + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -959,24 +996,33 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu let default_summary = config.model_reasoning_summary; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 1".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model, - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(default_sandbox_policy.clone()), + permission_profile: None, + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model, + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -984,24 +1030,33 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, default_cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: "o3".to_string(), - effort: Some(ReasoningEffort::High), - summary: Some(ReasoningSummary::Detailed), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Detailed), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: "o3".to_string(), + reasoning_effort: Some(ReasoningEffort::High), + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/quota_exceeded.rs b/codex-rs/core/tests/suite/quota_exceeded.rs index 4c0677e69a58..d93fc6c95614 100644 --- a/codex-rs/core/tests/suite/quota_exceeded.rs +++ b/codex-rs/core/tests/suite/quota_exceeded.rs @@ -48,6 +48,7 @@ async fn quota_exceeded_emits_single_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 31d30d824ee3..39ae60f4117b 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -2168,6 +2168,7 @@ async fn conversation_user_text_turn_is_sent_to_realtime_when_active() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2302,6 +2303,7 @@ async fn conversation_user_text_turn_is_capped_when_mirrored_to_realtime() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -3497,6 +3499,7 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index e19379ffc8c2..30e95f551d74 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -67,24 +67,33 @@ async fn submit_turn_with_approval_and_environments( environments: Vec, ) -> Result<()> { test.codex - .submit(Op::UserTurn { - environments: Some(environments), + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: Some(environments), final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::OnRequest), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index d1caf2483657..aa976c3aa159 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -154,24 +154,33 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: requested_model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -232,24 +241,33 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: requested_model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -309,24 +327,33 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: requested_model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -399,24 +426,33 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check model slug".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: requested_model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -460,28 +496,37 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check namespaced model metadata".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: requested_model.to_string(), - effort: None, - summary: Some( - config - .model_reasoning_summary - .unwrap_or(ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: None, + sandbox_policy: Some(config.legacy_sandbox_policy()), + permission_profile: None, + summary: Some( + config + .model_reasoning_summary + .unwrap_or(ReasoningSummary::Auto), + ), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: requested_model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -633,24 +678,33 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run call".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: REMOTE_MODEL_SLUG.to_string(), - effort: None, - summary: Some(ReasoningSummary::Auto), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Auto), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: REMOTE_MODEL_SLUG.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -865,24 +919,33 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello remote".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: model.to_string(), - effort: None, - summary: Some(ReasoningSummary::Auto), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Auto), + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: model.to_string(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/request_compression.rs b/codex-rs/core/tests/suite/request_compression.rs index fddb18f15bfb..f86b7ffafba5 100644 --- a/codex-rs/core/tests/suite/request_compression.rs +++ b/codex-rs/core/tests/suite/request_compression.rs @@ -47,6 +47,7 @@ async fn request_body_is_zstd_compressed_for_codex_backend_when_enabled() -> any }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -96,6 +97,7 @@ async fn request_body_is_not_compressed_for_api_key_auth_even_when_enabled() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index 0463ea3e2b06..c1022665e4b0 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -188,24 +188,33 @@ async fn submit_turn( ) -> Result<()> { let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index cb1324396677..d8fc5aa440ef 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -142,24 +142,33 @@ async fn submit_turn( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 6ddd9d0b5e71..9f4b95bf3599 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -132,36 +132,37 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul ]); let second_mock = responses::mount_sse_once(&server, second_response).await; - let session_model = session_configured.model.clone(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(CollaborationMode { - mode, - settings: Settings { - model: session_configured.model.clone(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(CollaborationMode { + mode, + settings: Settings { + model: session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -282,31 +283,33 @@ async fn request_user_input_interrupt_emits_deferred_token_count() -> anyhow::Re let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(CollaborationMode { - mode: ModeKind::Plan, - settings: Settings { - model: session_configured.model, - reasoning_effort: None, - developer_instructions: None, - }, - }), - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(CollaborationMode { + mode: ModeKind::Plan, + settings: Settings { + model: session_configured.model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -388,24 +391,26 @@ where turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(collaboration_mode), - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs index 09e99f78c300..fa193e728633 100644 --- a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs +++ b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs @@ -130,24 +130,33 @@ async fn submit_turn_with_timeout(test: &TestCodex, prompt: &str) -> Result<()> let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::workspace_write(), cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::OnRequest), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/resume.rs b/codex-rs/core/tests/suite/resume.rs index 3211d336e55b..29a8f4ff7ad0 100644 --- a/codex-rs/core/tests/suite/resume.rs +++ b/codex-rs/core/tests/suite/resume.rs @@ -93,6 +93,7 @@ async fn resume_includes_initial_messages_from_rollout_events() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -178,6 +179,7 @@ async fn resume_includes_initial_messages_from_reasoning_events() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -267,6 +269,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -309,6 +312,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -326,6 +330,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -398,6 +403,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -444,6 +450,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 3611df6a6aaf..57467a100710 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -684,6 +684,7 @@ async fn review_history_surfaces_in_parent_session() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 7ead0364dcc4..cbbd4725edb0 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -105,24 +105,33 @@ fn read_only_user_turn_with_model( let cwd = fixture.cwd.path().to_path_buf(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), cwd.as_path()); - Op::UserTurn { + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/safety_check_downgrade.rs b/codex-rs/core/tests/suite/safety_check_downgrade.rs index c937d49ad48b..1bd31fb486fe 100644 --- a/codex-rs/core/tests/suite/safety_check_downgrade.rs +++ b/codex-rs/core/tests/suite/safety_check_downgrade.rs @@ -37,24 +37,33 @@ const CYBER_POLICY_MESSAGE: &str = fn disabled_text_turn(test: &TestCodex, text: &str) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: REQUESTED_MODEL.to_string(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: REQUESTED_MODEL.to_string(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/search_tool.rs b/codex-rs/core/tests/suite/search_tool.rs index 69dc74dce347..6c0d3ce17b90 100644 --- a/codex-rs/core/tests/suite/search_tool.rs +++ b/codex-rs/core/tests/suite/search_tool.rs @@ -494,6 +494,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -804,6 +805,7 @@ async fn tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1111,6 +1113,7 @@ async fn tool_search_surfaced_mcp_tool_errors_are_returned_to_model() -> Result< }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1430,6 +1433,7 @@ async fn tool_search_matches_dynamic_tools_by_name_description_namespace_and_sch }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index 49ef4956cde4..e36d4a15ba99 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -159,24 +159,33 @@ async fn run_snapshot_command_with_options( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run unified exec with shell snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -254,24 +263,33 @@ async fn run_shell_command_snapshot_with_options( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run shell_command with shell snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -329,24 +347,33 @@ async fn run_tool_turn_on_harness( let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -567,24 +594,33 @@ async fn shell_command_snapshot_still_intercepts_apply_patch() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "apply patch via shell_command with snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.clone(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.clone()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/skill_approval.rs b/codex-rs/core/tests/suite/skill_approval.rs index 72244d534e25..6329b9967785 100644 --- a/codex-rs/core/tests/suite/skill_approval.rs +++ b/codex-rs/core/tests/suite/skill_approval.rs @@ -46,24 +46,33 @@ async fn submit_turn_with_policies( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.cwd_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index 6434f9c5332b..394019fee4cb 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -74,8 +74,7 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::Text { text: "please use $demo".to_string(), @@ -86,18 +85,28 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { path: skill_path.clone(), }, ], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index ab0b4c27ead4..bdaa09e527c6 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -405,24 +405,33 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result< turn_permission_fields(PermissionProfile::read_only(), cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "call the rmcp echo tool".to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { diff --git a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs index af861412616a..673fc63526fd 100644 --- a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs +++ b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs @@ -101,6 +101,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -122,6 +123,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/stream_no_completed.rs b/codex-rs/core/tests/suite/stream_no_completed.rs index 30574718f20e..841851562cf0 100644 --- a/codex-rs/core/tests/suite/stream_no_completed.rs +++ b/codex-rs/core/tests/suite/stream_no_completed.rs @@ -83,6 +83,7 @@ async fn retries_on_early_close() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index 38843f2d83a1..9a9d66054f92 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -102,24 +102,33 @@ async fn shell_command_tool_executes_command_and_streams_output() -> anyhow::Res turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please run the shell command".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -178,24 +187,33 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please update the plan".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -264,24 +282,33 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please update the plan".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -360,24 +387,33 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<() turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please apply a patch".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -493,24 +529,33 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please apply a patch".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index 47282c283d29..d5f8f63eaa27 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -37,24 +37,33 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -358,24 +367,33 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "stream delayed completion".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index 447bca673169..361a18dba18b 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -515,24 +515,33 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> { fixture .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "call the rmcp image tool".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: fixture.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile: Some(permission_profile), - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(fixture.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile: Some(permission_profile), + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index 92b8aa904780..bad92384cc11 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -190,24 +190,33 @@ async fn submit_unified_exec_turn( let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -274,24 +283,33 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { let session_model = test.session_configured.model.clone(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "apply patch via unified exec".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(SandboxPolicy::DangerFullAccess), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2116,24 +2134,33 @@ async fn unified_exec_keeps_long_running_session_after_turn_end() -> Result<()> let session_model = session_configured.model.clone(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "keep unified exec process after turn end".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(SandboxPolicy::DangerFullAccess), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2211,24 +2238,33 @@ async fn unified_exec_interrupt_preserves_long_running_session() -> Result<()> { let session_model = session_configured.model.clone(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "interrupt long-running unified exec".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(SandboxPolicy::DangerFullAccess), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2685,25 +2721,33 @@ async fn unified_exec_runs_under_sandbox() -> Result<()> { let session_model = session_configured.model.clone(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "summarize large output".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - // Important! - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2801,24 +2845,33 @@ async fn unified_exec_enforces_glob_deny_read_policy() -> Result<()> { let session_model = session_configured.model.clone(); let read_only_policy = SandboxPolicy::new_read_only_policy(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "read the fixture files".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: read_only_policy, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(read_only_policy), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2931,24 +2984,33 @@ async fn unified_exec_python_prompt_under_seatbelt() -> Result<()> { let session_model = session_configured.model.clone(); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "start python under seatbelt".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), + permission_profile: None, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/user_notification.rs b/codex-rs/core/tests/suite/user_notification.rs index 5fe08789f438..7e0210fc7770 100644 --- a/codex-rs/core/tests/suite/user_notification.rs +++ b/codex-rs/core/tests/suite/user_notification.rs @@ -64,6 +64,7 @@ mv "${tmp_path}" "${payload_path}""#, }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index 4fe3586d7fec..acbe4167bc6a 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -174,24 +174,33 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> fixture .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run model shell command".to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: fixture.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: fixture.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index d78e8761fdbb..60d7fdb4b320 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -72,21 +72,30 @@ const VIEW_IMAGE_TURN_COMPLETE_TIMEOUT: Duration = Duration::from_secs(30); fn disabled_user_turn(test: &TestCodex, items: Vec, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items, + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index f073ce7ab87f..1133c29a5896 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -152,24 +152,33 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + turn_context: codex_protocol::protocol::TurnContextOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + approvals_reviewer: None, + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: None, + service_tier: None, + personality: None, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/window_headers.rs b/codex-rs/core/tests/suite/window_headers.rs index d0e207d9639a..f823d9db7e65 100644 --- a/codex-rs/core/tests/suite/window_headers.rs +++ b/codex-rs/core/tests/suite/window_headers.rs @@ -112,6 +112,7 @@ async fn submit_user_turn(codex: &Arc, text: &str) -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/mcp-server/src/codex_tool_runner.rs b/codex-rs/mcp-server/src/codex_tool_runner.rs index 9e3ac1bae961..a38fbf6b55c2 100644 --- a/codex-rs/mcp-server/src/codex_tool_runner.rs +++ b/codex-rs/mcp-server/src/codex_tool_runner.rs @@ -116,6 +116,7 @@ pub async fn run_codex_tool_session( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, trace: None, }; @@ -165,6 +166,7 @@ pub async fn run_codex_tool_session_reply( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await { diff --git a/codex-rs/memories/write/src/runtime.rs b/codex-rs/memories/write/src/runtime.rs index 18b1bd6db1ac..0bd301709b07 100644 --- a/codex-rs/memories/write/src/runtime.rs +++ b/codex-rs/memories/write/src/runtime.rs @@ -261,6 +261,7 @@ impl MemoryStartupContext { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await { diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 94753780cb17..c241ceda6095 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -396,6 +396,80 @@ pub struct ConversationTextParams { pub text: String, } +/// Persistent turn-context overrides that can be applied before user input. +#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, JsonSchema)] +pub struct TurnContextOverrides { + /// Updated `cwd` for sandbox/tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub cwd: Option, + + /// Updated runtime workspace roots used to materialize symbolic + /// `:workspace_roots` filesystem permissions. + #[serde(skip_serializing_if = "Option::is_none")] + pub workspace_roots: Option>, + + /// Updated profile-defined workspace roots for status summaries and + /// per-turn config reconstruction. + #[serde(skip_serializing_if = "Option::is_none")] + pub profile_workspace_roots: Option>, + + /// Updated command approval policy. + #[serde(skip_serializing_if = "Option::is_none")] + pub approval_policy: Option, + + /// Updated approval reviewer for future approval prompts. + #[serde(skip_serializing_if = "Option::is_none")] + pub approvals_reviewer: Option, + + /// Updated sandbox policy for tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub sandbox_policy: Option, + + /// Updated permissions profile for tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub permission_profile: Option, + + /// Named or built-in profile that produced `permission_profile`, if the + /// update selected a profile rather than supplying raw permissions. + #[serde(skip_serializing_if = "Option::is_none")] + pub active_permission_profile: Option, + + /// Updated Windows sandbox mode for tool execution. + #[serde(skip_serializing_if = "Option::is_none")] + pub windows_sandbox_level: Option, + + /// Updated model slug. When set, the model info is derived automatically. + #[serde(skip_serializing_if = "Option::is_none")] + pub 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")] + pub effort: Option>, + + /// Updated reasoning summary preference (honored only for reasoning-capable models). + #[serde(skip_serializing_if = "Option::is_none")] + pub 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")] + pub 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")] + pub collaboration_mode: Option, + + /// Updated personality preference. + #[serde(skip_serializing_if = "Option::is_none")] + pub personality: Option, +} + /// Submission operation #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] @@ -425,10 +499,7 @@ pub enum Op { /// Request the list of voices supported by realtime conversation streams. RealtimeConversationListVoices, - /// Legacy user input. - /// - /// Prefer [`Op::UserTurn`] so the caller provides full turn context - /// (cwd/approval/sandbox/model/etc.) for each turn. + /// User input, optionally with turn-context overrides applied first. UserInput { /// User input items, see `InputItem` items: Vec, @@ -441,163 +512,10 @@ pub enum Op { /// Optional turn-scoped Responses API `client_metadata`. #[serde(default, skip_serializing_if = "Option::is_none")] responsesapi_client_metadata: Option>, - }, - - /// Similar to [`Op::UserInput`], but first applies persistent turn-context - /// overrides in the same queued operation. This preserves submission order - /// and prevents the input from starting if the overrides are rejected. - UserInputWithTurnContext { - /// User input items, see `InputItem` - items: Vec, - /// Optional turn-scoped environment selections. - #[serde(default, skip_serializing_if = "Option::is_none")] - environments: Option>, - /// Optional JSON Schema used to constrain the final assistant message for this turn. - #[serde(skip_serializing_if = "Option::is_none")] - final_output_json_schema: Option, - /// Optional turn-scoped Responses API `client_metadata`. - #[serde(default, skip_serializing_if = "Option::is_none")] - responsesapi_client_metadata: Option>, - - /// Updated `cwd` for sandbox/tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - cwd: Option, - - /// Updated runtime workspace roots used to materialize symbolic - /// `:workspace_roots` filesystem permissions. - #[serde(skip_serializing_if = "Option::is_none")] - workspace_roots: Option>, - - /// Updated profile-defined workspace roots for status summaries and - /// per-turn config reconstruction. - #[serde(skip_serializing_if = "Option::is_none")] - profile_workspace_roots: 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, - - /// Named or built-in profile that produced `permission_profile`, if - /// the update selected a profile rather than supplying raw - /// permissions. - #[serde(skip_serializing_if = "Option::is_none")] - active_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, - }, - /// Similar to [`Op::UserInput`], but contains additional context required - /// for a turn of a [`crate::codex_thread::CodexThread`]. - UserTurn { - /// User input items, see `InputItem` - items: Vec, - - /// `cwd` to use with the [`SandboxPolicy`] and potentially tool calls - /// such as `local_shell`. - cwd: PathBuf, - - /// Policy to use for command approval. - approval_policy: AskForApproval, - - /// Reviewer to use for approval requests raised during this turn. - /// - /// When omitted, the session keeps the current setting - approvals_reviewer: Option, - - /// Policy to use for tool calls such as `local_shell`. - sandbox_policy: SandboxPolicy, - - /// Full permissions profile to use for tool calls such as `local_shell`. - /// - /// When omitted, `sandbox_policy` is used as a legacy compatibility - /// projection. - #[serde(default, skip_serializing_if = "Option::is_none")] - permission_profile: Option, - - /// Must be a valid model slug for the configured client session - /// associated with this conversation. - model: String, - - /// Will only be honored if the model is configured to use reasoning. - #[serde(skip_serializing_if = "Option::is_none")] - effort: Option, - - /// Will only be honored if the model is configured to use reasoning. - /// - /// When omitted, the session keeps the current setting (which allows core to - /// fall back to the selected model's default on new sessions). - #[serde(default, skip_serializing_if = "Option::is_none")] - summary: Option, - - /// Optional service tier override for this turn. - /// - /// Use `Some(Some(_))` to set a specific tier for this turn, `Some(None)` to - /// explicitly clear the tier for this turn, or `None` to keep the existing - /// session preference. - #[serde(default, skip_serializing_if = "Option::is_none")] - service_tier: Option>, - - // The JSON schema to use for the final assistant message - final_output_json_schema: 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, - - /// Optional personality override for this turn. - #[serde(skip_serializing_if = "Option::is_none")] - personality: Option, - - /// Optional turn-scoped environments. - #[serde(default, skip_serializing_if = "Option::is_none")] - environments: Option>, + /// Persistent turn-context overrides to apply before the input. + #[serde(default, flatten)] + turn_context: TurnContextOverrides, }, /// Inter-agent communication that should be recorded as assistant history @@ -790,6 +708,7 @@ impl From> for Op { items: value, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: TurnContextOverrides::default(), } } } @@ -856,8 +775,6 @@ impl Op { Self::RealtimeConversationClose => "realtime_conversation_close", Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", Self::UserInput { .. } => "user_input", - Self::UserInputWithTurnContext { .. } => "user_input_with_turn_context", - Self::UserTurn { .. } => "user_turn", Self::InterAgentCommunication { .. } => "inter_agent_communication", Self::OverrideTurnContext { .. } => "override_turn_context", Self::ExecApproval { .. } => "exec_approval", @@ -5032,6 +4949,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5051,6 +4969,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), } ); @@ -5072,6 +4991,7 @@ mod tests { items: Vec::new(), final_output_json_schema: Some(schema.clone()), responsesapi_client_metadata: None, + turn_context: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5097,6 +5017,7 @@ mod tests { "fiber_run_id".to_string(), "fiber-123".to_string(), )])), + turn_context: Default::default(), }; let json_op = serde_json::to_value(&op)?; diff --git a/codex-rs/thread-manager-sample/src/main.rs b/codex-rs/thread-manager-sample/src/main.rs index 8a168bad138c..14564de778fd 100644 --- a/codex-rs/thread-manager-sample/src/main.rs +++ b/codex-rs/thread-manager-sample/src/main.rs @@ -293,6 +293,7 @@ async fn run_turn(thread: &CodexThread, thread_id: &str, prompt: String) -> anyh environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .context("submit user input")?; From e1b60da6fc8032ed770b2a5b9e64710926bc7ecc Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 13:51:13 -0700 Subject: [PATCH 02/15] Fix clippy field shorthand in core tests --- codex-rs/core/tests/common/test_codex.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index f0a22a31aeef..f11b86e2de4b 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -766,7 +766,7 @@ impl TestCodex { text: prompt.into(), text_elements: Vec::new(), }], - environments: environments, + environments, final_output_json_schema: None, responsesapi_client_metadata: None, turn_context: codex_protocol::protocol::TurnContextOverrides { @@ -774,9 +774,9 @@ impl TestCodex { approval_policy: Some(approval_policy), approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), - permission_profile: permission_profile, + permission_profile, summary: None, - service_tier: service_tier, + service_tier, personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, From 3b1b54ace7c49e65c159eb19dc7039c96780c183 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 14:16:20 -0700 Subject: [PATCH 03/15] Add turn context to UserInput --- .../src/request_processors/turn_processor.rs | 1 + codex-rs/core/src/agent/control_tests.rs | 3 + codex-rs/core/src/codex_delegate.rs | 1 + codex-rs/core/src/session/handlers.rs | 69 +++++++++++++-- codex-rs/core/src/session/mod.rs | 1 + codex-rs/core/src/session/tests.rs | 6 ++ .../src/tools/handlers/multi_agents_tests.rs | 1 + codex-rs/core/tests/suite/abort_tasks.rs | 5 ++ codex-rs/core/tests/suite/client.rs | 32 +++++++ .../core/tests/suite/client_websockets.rs | 2 + .../tests/suite/collaboration_instructions.rs | 14 +++ codex-rs/core/tests/suite/compact.rs | 31 +++++++ codex-rs/core/tests/suite/compact_remote.rs | 53 +++++++++++ .../core/tests/suite/compact_remote_parity.rs | 1 + .../core/tests/suite/compact_resume_fork.rs | 1 + codex-rs/core/tests/suite/fork_thread.rs | 2 + codex-rs/core/tests/suite/hooks.rs | 2 + codex-rs/core/tests/suite/items.rs | 9 ++ .../core/tests/suite/model_visible_layout.rs | 3 + codex-rs/core/tests/suite/otel.rs | 22 +++++ codex-rs/core/tests/suite/pending_input.rs | 3 + .../core/tests/suite/permissions_messages.rs | 15 ++++ codex-rs/core/tests/suite/plugins.rs | 3 + codex-rs/core/tests/suite/prompt_caching.rs | 10 +++ codex-rs/core/tests/suite/quota_exceeded.rs | 1 + .../core/tests/suite/realtime_conversation.rs | 3 + .../core/tests/suite/request_compression.rs | 2 + codex-rs/core/tests/suite/resume.rs | 7 ++ codex-rs/core/tests/suite/review.rs | 1 + codex-rs/core/tests/suite/search_tool.rs | 4 + .../suite/stream_error_allows_next_turn.rs | 2 + .../core/tests/suite/stream_no_completed.rs | 1 + .../core/tests/suite/user_notification.rs | 1 + codex-rs/core/tests/suite/window_headers.rs | 1 + codex-rs/mcp-server/src/codex_tool_runner.rs | 2 + codex-rs/memories/write/src/runtime.rs | 1 + codex-rs/protocol/src/protocol.rs | 88 ++++++++++++++++++- codex-rs/thread-manager-sample/src/main.rs | 1 + 38 files changed, 392 insertions(+), 13 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 54fc0383e44b..9895d9aad8c9 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -532,6 +532,7 @@ impl TurnRequestProcessor { environments: environment_selections, final_output_json_schema: params.output_schema, responsesapi_client_metadata: params.responsesapi_client_metadata, + turn_context: Default::default(), } }; let turn_id = self diff --git a/codex-rs/core/src/agent/control_tests.rs b/codex-rs/core/src/agent/control_tests.rs index b95aad4489fd..abf9fd9b87aa 100644 --- a/codex-rs/core/src/agent/control_tests.rs +++ b/codex-rs/core/src/agent/control_tests.rs @@ -442,6 +442,7 @@ async fn send_input_submits_user_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness @@ -589,6 +590,7 @@ async fn spawn_agent_creates_thread_and_sends_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness @@ -737,6 +739,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, ); let captured = harness diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index 493771e28c80..d7c6abdd70c0 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -192,6 +192,7 @@ pub(crate) async fn run_codex_thread_one_shot( items: input, final_output_json_schema, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index a26b9bb3f6fe..212168341b37 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -43,6 +43,7 @@ use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::ThreadRolledBackEvent; use codex_protocol::protocol::TurnAbortReason; +use codex_protocol::protocol::TurnContextOverrides; use codex_protocol::protocol::WarningEvent; use codex_protocol::request_permissions::RequestPermissionsResponse; use codex_protocol::request_user_input::RequestUserInputResponse; @@ -224,15 +225,17 @@ pub(super) async fn user_input_or_turn_inner( environments, final_output_json_schema, responsesapi_client_metadata, - } => ( - items, - SessionSettingsUpdate { - final_output_json_schema: Some(final_output_json_schema), - environments, - ..Default::default() - }, - responsesapi_client_metadata, - ), + turn_context, + } => { + let mut updates = if turn_context == TurnContextOverrides::default() { + SessionSettingsUpdate::default() + } else { + turn_context_settings_update(sess, turn_context).await + }; + updates.final_output_json_schema = Some(final_output_json_schema); + updates.environments = environments; + (items, updates, responsesapi_client_metadata) + } _ => unreachable!(), }; @@ -289,6 +292,54 @@ pub(super) async fn user_input_or_turn_inner( } } +async fn turn_context_settings_update( + sess: &Session, + turn_context: TurnContextOverrides, +) -> SessionSettingsUpdate { + let TurnContextOverrides { + cwd, + workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level, + model, + effort, + summary, + service_tier, + collaboration_mode, + personality, + } = turn_context; + let collaboration_mode = if let Some(collaboration_mode) = collaboration_mode { + collaboration_mode + } else { + let state = sess.state.lock().await; + state + .session_configuration + .collaboration_mode + .with_updates(model, effort, /*developer_instructions*/ None) + }; + SessionSettingsUpdate { + cwd, + workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level, + collaboration_mode: Some(collaboration_mode), + reasoning_summary: summary, + service_tier, + personality, + ..Default::default() + } +} + async fn mirror_user_text_to_realtime(sess: &Arc, items: &[UserInput]) { let text = UserMessageItem::new(items).message(); if text.is_empty() { diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index d67e79f79417..9a78242222ae 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -1096,6 +1096,7 @@ impl Session { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, /*mirror_user_text_to_realtime*/ None, ) diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index bb858999e48c..4dbcc80b4f50 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -2220,6 +2220,7 @@ 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(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2283,6 +2284,7 @@ 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(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -5228,6 +5230,7 @@ fn op_kind_distinguishes_turn_ops() { items: vec![], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), } .kind(), "user_input" @@ -8335,6 +8338,7 @@ async fn active_goal_continuation_runs_again_after_no_tool_turn() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -8439,6 +8443,7 @@ async fn pending_request_user_input_does_not_spawn_extra_goal_continuation() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -8863,6 +8868,7 @@ async fn completed_goal_accounts_current_turn_tokens_before_tool_response() -> a }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index 0044bf852247..c0c001690734 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -2470,6 +2470,7 @@ async fn send_input_accepts_structured_items() { ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }; let captured = manager .captured_ops() diff --git a/codex-rs/core/tests/suite/abort_tasks.rs b/codex-rs/core/tests/suite/abort_tasks.rs index c81a1c2f68ac..fd2c06aef3be 100644 --- a/codex-rs/core/tests/suite/abort_tasks.rs +++ b/codex-rs/core/tests/suite/abort_tasks.rs @@ -53,6 +53,7 @@ async fn interrupt_long_running_tool_emits_turn_aborted() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -109,6 +110,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -129,6 +131,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -211,6 +214,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -231,6 +235,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 42bacb9bdc5f..3092c613726a 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -392,6 +392,7 @@ async fn resume_includes_initial_messages_and_sends_prior_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -757,6 +758,7 @@ async fn includes_session_id_thread_id_and_model_headers_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -967,6 +969,7 @@ async fn includes_base_instructions_override_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1023,6 +1026,7 @@ async fn chatgpt_auth_sends_correct_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1146,6 +1150,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1184,6 +1189,7 @@ async fn includes_user_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1271,6 +1277,7 @@ async fn includes_apps_guidance_as_developer_message_for_chatgpt_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1333,6 +1340,7 @@ async fn omits_apps_guidance_for_api_key_auth_even_when_feature_enabled() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1391,6 +1399,7 @@ async fn omits_apps_guidance_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1432,6 +1441,7 @@ async fn omits_environment_context_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1488,6 +1498,7 @@ async fn skills_append_to_developer_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1570,6 +1581,7 @@ async fn skills_use_aliases_in_developer_message_under_budget_pressure() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1630,6 +1642,7 @@ async fn includes_configured_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1671,6 +1684,7 @@ async fn includes_no_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1713,6 +1727,7 @@ async fn includes_default_reasoning_effort_in_request_when_defined_by_model_info }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1826,6 +1841,7 @@ async fn configured_reasoning_summary_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1945,6 +1961,7 @@ async fn reasoning_summary_is_omitted_when_disabled() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2003,6 +2020,7 @@ async fn reasoning_summary_none_overrides_model_catalog_default() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2041,6 +2059,7 @@ async fn includes_default_verbosity_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2088,6 +2107,7 @@ async fn configured_verbosity_not_sent_for_models_without_support() -> anyhow::R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2134,6 +2154,7 @@ async fn configured_verbosity_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2185,6 +2206,7 @@ async fn includes_developer_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2480,6 +2502,7 @@ async fn token_count_includes_rate_limits_snapshot() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2618,6 +2641,7 @@ async fn usage_limit_error_emits_rate_limit_event() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -2694,6 +2718,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2708,6 +2733,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2792,6 +2818,7 @@ async fn incomplete_response_emits_content_filter_error_message() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2902,6 +2929,7 @@ async fn azure_overrides_assign_properties_used_for_responses_url() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2990,6 +3018,7 @@ async fn env_var_overrides_loaded_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3046,6 +3075,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3061,6 +3091,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3076,6 +3107,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index a14ee6518fa6..3ae5be3e904b 100755 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -1208,6 +1208,7 @@ async fn responses_websocket_usage_limit_error_emits_rate_limit_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -1296,6 +1297,7 @@ async fn responses_websocket_invalid_request_error_with_status_is_forwarded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submission should succeed while emitting invalid request events"); diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 5ce115cdaff8..e2890c582886 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -86,6 +86,7 @@ async fn no_collaboration_instructions_by_default() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -148,6 +149,7 @@ async fn user_input_includes_collaboration_instructions_after_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -305,6 +307,7 @@ async fn override_then_next_turn_uses_updated_collaboration_instructions() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -434,6 +437,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -464,6 +468,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -523,6 +528,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -553,6 +559,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -614,6 +621,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -647,6 +655,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -709,6 +718,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -742,6 +752,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -808,6 +819,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -823,6 +835,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -882,6 +895,7 @@ async fn empty_collaboration_instructions_are_ignored() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index be3423a85ead..1ca9b49d48b6 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -386,6 +386,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -410,6 +411,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -586,6 +588,7 @@ async fn manual_pre_compact_block_decision_does_not_block_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -658,6 +661,7 @@ async fn compact_hooks_respect_matchers_and_post_runs_after_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -727,6 +731,7 @@ async fn manual_compact_uses_custom_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user turn"); @@ -873,6 +878,7 @@ async fn manual_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1038,6 +1044,7 @@ async fn multiple_auto_compact_per_task_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -1509,6 +1516,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1524,6 +1532,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1539,6 +1548,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1709,6 +1719,7 @@ async fn auto_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1789,6 +1800,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1803,6 +1815,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1817,6 +1830,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2250,6 +2264,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2264,6 +2279,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2278,6 +2294,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2366,6 +2383,7 @@ async fn manual_compact_retries_after_context_window_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2469,6 +2487,7 @@ async fn manual_compact_non_context_failure_retries_then_emits_task_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -2563,6 +2582,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2580,6 +2600,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2597,6 +2618,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2760,6 +2782,7 @@ async fn auto_compact_allows_multiple_attempts_when_interleaved_with_other_turn_ }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -2864,6 +2887,7 @@ async fn snapshot_request_shape_mid_turn_continuation_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3063,6 +3087,7 @@ async fn auto_compact_counts_encrypted_reasoning_before_last_user() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3181,6 +3206,7 @@ async fn auto_compact_runs_when_reasoning_header_clears_between_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -3242,6 +3268,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -3281,6 +3308,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user input"); @@ -3469,6 +3497,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit first user"); @@ -3483,6 +3512,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit second user"); @@ -3555,6 +3585,7 @@ async fn snapshot_request_shape_manual_compact_without_previous_user_messages() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit follow-up user input"); diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 15197042fae8..1f5f661f053b 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -326,6 +326,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -342,6 +343,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -516,6 +518,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -535,6 +538,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -548,6 +552,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -567,6 +572,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -580,6 +586,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -747,6 +754,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -763,6 +771,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -856,6 +865,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -872,6 +882,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -962,6 +973,7 @@ async fn remote_compact_filters_deferred_dynamic_tools() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -1033,6 +1045,7 @@ async fn remote_compact_runs_automatically() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1113,6 +1126,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1126,6 +1140,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1243,6 +1258,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1256,6 +1272,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1275,6 +1292,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1374,6 +1392,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1387,6 +1406,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1480,6 +1500,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1496,6 +1517,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1586,6 +1608,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1602,6 +1625,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1672,6 +1696,7 @@ async fn remote_manual_compact_emits_context_compaction_items() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1752,6 +1777,7 @@ async fn remote_manual_compact_failure_emits_task_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1835,6 +1861,7 @@ async fn remote_compact_persists_replacement_history_in_rollout() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -1977,6 +2004,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -1994,6 +2022,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2018,6 +2047,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2113,6 +2143,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2129,6 +2160,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2200,6 +2232,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2213,6 +2246,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2279,6 +2313,7 @@ async fn remote_request_uses_custom_experimental_realtime_start_instructions() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2339,6 +2374,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2354,6 +2390,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2428,6 +2465,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2444,6 +2482,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2526,6 +2565,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2541,6 +2581,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2631,6 +2672,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2660,6 +2702,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2756,6 +2799,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_including_incoming_us }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2842,6 +2886,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2871,6 +2916,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2989,6 +3035,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3002,6 +3049,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; let error_message = wait_for_event_match(&codex, |event| match event { @@ -3086,6 +3134,7 @@ async fn snapshot_request_shape_remote_mid_turn_continuation_compaction() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3163,6 +3212,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_summary_only_reinject }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3248,6 +3298,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3264,6 +3315,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3345,6 +3397,7 @@ async fn snapshot_request_shape_remote_manual_compact_without_previous_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact_remote_parity.rs b/codex-rs/core/tests/suite/compact_remote_parity.rs index 32c13b0b27c4..c465480558b0 100644 --- a/codex-rs/core/tests/suite/compact_remote_parity.rs +++ b/codex-rs/core/tests/suite/compact_remote_parity.rs @@ -606,6 +606,7 @@ async fn submit_user_input(codex: &codex_core::CodexThread, items: Vec, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .expect("submit user turn"); diff --git a/codex-rs/core/tests/suite/fork_thread.rs b/codex-rs/core/tests/suite/fork_thread.rs index 37456dce631e..75256ae786d2 100644 --- a/codex-rs/core/tests/suite/fork_thread.rs +++ b/codex-rs/core/tests/suite/fork_thread.rs @@ -57,6 +57,7 @@ async fn fork_thread_twice_drops_to_first_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -180,6 +181,7 @@ async fn fork_thread_from_history_does_not_require_source_rollout_path() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/hooks.rs b/codex-rs/core/tests/suite/hooks.rs index 53649afff849..8eda28354e94 100644 --- a/codex-rs/core/tests/suite/hooks.rs +++ b/codex-rs/core/tests/suite/hooks.rs @@ -1440,6 +1440,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1458,6 +1459,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; } diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 65087a1fe79a..9f6407b353ff 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -121,6 +121,7 @@ async fn user_message_item_is_emitted() -> anyhow::Result<()> { items: vec![expected_input.clone()], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -179,6 +180,7 @@ async fn assistant_message_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -239,6 +241,7 @@ async fn reasoning_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -300,6 +303,7 @@ async fn web_search_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -379,6 +383,7 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -465,6 +470,7 @@ async fn image_generation_call_event_is_emitted_when_image_save_fails() -> anyho }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -520,6 +526,7 @@ async fn agent_message_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1103,6 +1110,7 @@ async fn reasoning_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1157,6 +1165,7 @@ async fn reasoning_raw_content_delta_respects_flag() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 7ae148788ef8..6c0275b1326a 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -344,6 +344,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -451,6 +452,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -499,6 +501,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/otel.rs b/codex-rs/core/tests/suite/otel.rs index 03692ac547ac..31477f0d3a76 100644 --- a/codex-rs/core/tests/suite/otel.rs +++ b/codex-rs/core/tests/suite/otel.rs @@ -122,6 +122,7 @@ async fn responses_api_emits_api_request_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -167,6 +168,7 @@ async fn process_sse_emits_tracing_for_output_item() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -212,6 +214,7 @@ async fn process_sse_emits_failed_event_on_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -258,6 +261,7 @@ async fn process_sse_records_failed_event_when_stream_closes_without_completed() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -324,6 +328,7 @@ async fn process_sse_failed_event_records_response_error_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -388,6 +393,7 @@ async fn process_sse_failed_event_logs_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -439,6 +445,7 @@ async fn process_sse_failed_event_logs_missing_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -499,6 +506,7 @@ async fn process_sse_failed_event_logs_response_completed_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -553,6 +561,7 @@ async fn process_sse_emits_completed_telemetry() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -631,6 +640,7 @@ async fn turn_and_completed_response_spans_record_token_usage() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -718,6 +728,7 @@ async fn handle_responses_span_records_response_kind_and_tool_name() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -811,6 +822,7 @@ async fn record_responses_sets_span_fields_for_response_events() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -899,6 +911,7 @@ async fn handle_response_item_records_tool_result_for_custom_tool_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -974,6 +987,7 @@ async fn handle_response_item_records_tool_result_for_function_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1050,6 +1064,7 @@ async fn handle_response_item_records_tool_result_for_shell_command_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1158,6 +1173,7 @@ async fn handle_shell_command_autoapprove_from_config_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1212,6 +1228,7 @@ async fn handle_shell_command_user_approved_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1281,6 +1298,7 @@ async fn handle_shell_command_user_approved_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1350,6 +1368,7 @@ async fn handle_sandbox_error_user_approves_retry_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1419,6 +1438,7 @@ async fn handle_shell_command_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1488,6 +1508,7 @@ async fn handle_sandbox_error_user_approves_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -1558,6 +1579,7 @@ async fn handle_sandbox_error_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index 62851c515d59..ebc18a3fd8f1 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -103,6 +103,7 @@ async fn submit_user_input(codex: &CodexThread, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap_or_else(|err| panic!("submit user input: {err}")); @@ -285,6 +286,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -303,6 +305,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/permissions_messages.rs b/codex-rs/core/tests/suite/permissions_messages.rs index c4f1bef968a6..d22b37a8437d 100644 --- a/codex-rs/core/tests/suite/permissions_messages.rs +++ b/codex-rs/core/tests/suite/permissions_messages.rs @@ -58,6 +58,7 @@ async fn permissions_message_sent_once_on_start() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -97,6 +98,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -127,6 +129,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -172,6 +175,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -185,6 +189,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -230,6 +235,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -260,6 +266,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -318,6 +325,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -350,6 +358,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -365,6 +374,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -424,6 +434,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -456,6 +467,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -477,6 +489,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -512,6 +525,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -572,6 +586,7 @@ async fn permissions_message_includes_writable_roots() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/plugins.rs b/codex-rs/core/tests/suite/plugins.rs index 7b10db025915..f2b9cfeba9de 100644 --- a/codex-rs/core/tests/suite/plugins.rs +++ b/codex-rs/core/tests/suite/plugins.rs @@ -227,6 +227,7 @@ async fn capability_sections_render_in_developer_message_in_order() -> Result<() }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -305,6 +306,7 @@ async fn explicit_plugin_mentions_inject_plugin_guidance() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -386,6 +388,7 @@ async fn explicit_plugin_mentions_track_plugin_used_analytics() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index f887131eef95..b72b7fc1d0a2 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -153,6 +153,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -166,6 +167,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -249,6 +251,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -262,6 +265,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -326,6 +330,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -339,6 +344,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -421,6 +427,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -462,6 +469,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -547,6 +555,7 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -700,6 +709,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/quota_exceeded.rs b/codex-rs/core/tests/suite/quota_exceeded.rs index 4c0677e69a58..d93fc6c95614 100644 --- a/codex-rs/core/tests/suite/quota_exceeded.rs +++ b/codex-rs/core/tests/suite/quota_exceeded.rs @@ -48,6 +48,7 @@ async fn quota_exceeded_emits_single_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 31d30d824ee3..39ae60f4117b 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -2168,6 +2168,7 @@ async fn conversation_user_text_turn_is_sent_to_realtime_when_active() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -2302,6 +2303,7 @@ async fn conversation_user_text_turn_is_capped_when_mirrored_to_realtime() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -3497,6 +3499,7 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/request_compression.rs b/codex-rs/core/tests/suite/request_compression.rs index fddb18f15bfb..f86b7ffafba5 100644 --- a/codex-rs/core/tests/suite/request_compression.rs +++ b/codex-rs/core/tests/suite/request_compression.rs @@ -47,6 +47,7 @@ async fn request_body_is_zstd_compressed_for_codex_backend_when_enabled() -> any }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -96,6 +97,7 @@ async fn request_body_is_not_compressed_for_api_key_auth_even_when_enabled() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/resume.rs b/codex-rs/core/tests/suite/resume.rs index 3211d336e55b..29a8f4ff7ad0 100644 --- a/codex-rs/core/tests/suite/resume.rs +++ b/codex-rs/core/tests/suite/resume.rs @@ -93,6 +93,7 @@ async fn resume_includes_initial_messages_from_rollout_events() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -178,6 +179,7 @@ async fn resume_includes_initial_messages_from_reasoning_events() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -267,6 +269,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -309,6 +312,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -326,6 +330,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -398,6 +403,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -444,6 +450,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 3611df6a6aaf..57467a100710 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -684,6 +684,7 @@ async fn review_history_surfaces_in_parent_session() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/search_tool.rs b/codex-rs/core/tests/suite/search_tool.rs index 69dc74dce347..6c0d3ce17b90 100644 --- a/codex-rs/core/tests/suite/search_tool.rs +++ b/codex-rs/core/tests/suite/search_tool.rs @@ -494,6 +494,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -804,6 +805,7 @@ async fn tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call() - }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1111,6 +1113,7 @@ async fn tool_search_surfaced_mcp_tool_errors_are_returned_to_model() -> Result< }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; @@ -1430,6 +1433,7 @@ async fn tool_search_matches_dynamic_tools_by_name_description_namespace_and_sch }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs index af861412616a..673fc63526fd 100644 --- a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs +++ b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs @@ -101,6 +101,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); @@ -122,6 +123,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/stream_no_completed.rs b/codex-rs/core/tests/suite/stream_no_completed.rs index 30574718f20e..841851562cf0 100644 --- a/codex-rs/core/tests/suite/stream_no_completed.rs +++ b/codex-rs/core/tests/suite/stream_no_completed.rs @@ -83,6 +83,7 @@ async fn retries_on_early_close() { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/user_notification.rs b/codex-rs/core/tests/suite/user_notification.rs index 5fe08789f438..7e0210fc7770 100644 --- a/codex-rs/core/tests/suite/user_notification.rs +++ b/codex-rs/core/tests/suite/user_notification.rs @@ -64,6 +64,7 @@ mv "${tmp_path}" "${payload_path}""#, }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/window_headers.rs b/codex-rs/core/tests/suite/window_headers.rs index d0e207d9639a..f823d9db7e65 100644 --- a/codex-rs/core/tests/suite/window_headers.rs +++ b/codex-rs/core/tests/suite/window_headers.rs @@ -112,6 +112,7 @@ async fn submit_user_turn(codex: &Arc, text: &str) -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await?; wait_for_event(codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/mcp-server/src/codex_tool_runner.rs b/codex-rs/mcp-server/src/codex_tool_runner.rs index 9e3ac1bae961..a38fbf6b55c2 100644 --- a/codex-rs/mcp-server/src/codex_tool_runner.rs +++ b/codex-rs/mcp-server/src/codex_tool_runner.rs @@ -116,6 +116,7 @@ pub async fn run_codex_tool_session( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }, trace: None, }; @@ -165,6 +166,7 @@ pub async fn run_codex_tool_session_reply( }], final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await { diff --git a/codex-rs/memories/write/src/runtime.rs b/codex-rs/memories/write/src/runtime.rs index 18b1bd6db1ac..0bd301709b07 100644 --- a/codex-rs/memories/write/src/runtime.rs +++ b/codex-rs/memories/write/src/runtime.rs @@ -261,6 +261,7 @@ impl MemoryStartupContext { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await { diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 94753780cb17..a067ff699873 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -396,6 +396,80 @@ pub struct ConversationTextParams { pub text: String, } +/// Persistent turn-context overrides that can be applied before user input. +#[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, JsonSchema)] +pub struct TurnContextOverrides { + /// Updated `cwd` for sandbox/tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub cwd: Option, + + /// Updated runtime workspace roots used to materialize symbolic + /// `:workspace_roots` filesystem permissions. + #[serde(skip_serializing_if = "Option::is_none")] + pub workspace_roots: Option>, + + /// Updated profile-defined workspace roots for status summaries and + /// per-turn config reconstruction. + #[serde(skip_serializing_if = "Option::is_none")] + pub profile_workspace_roots: Option>, + + /// Updated command approval policy. + #[serde(skip_serializing_if = "Option::is_none")] + pub approval_policy: Option, + + /// Updated approval reviewer for future approval prompts. + #[serde(skip_serializing_if = "Option::is_none")] + pub approvals_reviewer: Option, + + /// Updated sandbox policy for tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub sandbox_policy: Option, + + /// Updated permissions profile for tool calls. + #[serde(skip_serializing_if = "Option::is_none")] + pub permission_profile: Option, + + /// Named or built-in profile that produced `permission_profile`, if the + /// update selected a profile rather than supplying raw permissions. + #[serde(skip_serializing_if = "Option::is_none")] + pub active_permission_profile: Option, + + /// Updated Windows sandbox mode for tool execution. + #[serde(skip_serializing_if = "Option::is_none")] + pub windows_sandbox_level: Option, + + /// Updated model slug. When set, the model info is derived automatically. + #[serde(skip_serializing_if = "Option::is_none")] + pub 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")] + pub effort: Option>, + + /// Updated reasoning summary preference (honored only for reasoning-capable models). + #[serde(skip_serializing_if = "Option::is_none")] + pub 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")] + pub 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")] + pub collaboration_mode: Option, + + /// Updated personality preference. + #[serde(skip_serializing_if = "Option::is_none")] + pub personality: Option, +} + /// Submission operation #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema)] #[serde(tag = "type", rename_all = "snake_case")] @@ -425,10 +499,7 @@ pub enum Op { /// Request the list of voices supported by realtime conversation streams. RealtimeConversationListVoices, - /// Legacy user input. - /// - /// Prefer [`Op::UserTurn`] so the caller provides full turn context - /// (cwd/approval/sandbox/model/etc.) for each turn. + /// User input, optionally with turn-context overrides applied first. UserInput { /// User input items, see `InputItem` items: Vec, @@ -441,6 +512,10 @@ pub enum Op { /// Optional turn-scoped Responses API `client_metadata`. #[serde(default, skip_serializing_if = "Option::is_none")] responsesapi_client_metadata: Option>, + + /// Persistent turn-context overrides to apply before the input. + #[serde(default, flatten)] + turn_context: TurnContextOverrides, }, /// Similar to [`Op::UserInput`], but first applies persistent turn-context @@ -790,6 +865,7 @@ impl From> for Op { items: value, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: TurnContextOverrides::default(), } } } @@ -5032,6 +5108,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5051,6 +5128,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), } ); @@ -5072,6 +5150,7 @@ mod tests { items: Vec::new(), final_output_json_schema: Some(schema.clone()), responsesapi_client_metadata: None, + turn_context: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5097,6 +5176,7 @@ mod tests { "fiber_run_id".to_string(), "fiber-123".to_string(), )])), + turn_context: Default::default(), }; let json_op = serde_json::to_value(&op)?; diff --git a/codex-rs/thread-manager-sample/src/main.rs b/codex-rs/thread-manager-sample/src/main.rs index 8a168bad138c..14564de778fd 100644 --- a/codex-rs/thread-manager-sample/src/main.rs +++ b/codex-rs/thread-manager-sample/src/main.rs @@ -293,6 +293,7 @@ async fn run_turn(thread: &CodexThread, thread_id: &str, prompt: String) -> anyh environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, + turn_context: Default::default(), }) .await .context("submit user input")?; From cb528adaceea074fbd6fe3373402fa0b41d0545e Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 14:20:00 -0700 Subject: [PATCH 04/15] Remove UserInputWithTurnContext op --- .../src/request_processors/turn_processor.rs | 26 +++--- codex-rs/core/src/session/handlers.rs | 60 +------------ codex-rs/core/src/session/tests.rs | 25 ------ codex-rs/protocol/src/protocol.rs | 90 ------------------- 4 files changed, 13 insertions(+), 188 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 9895d9aad8c9..85b5e4e5541e 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -503,13 +503,8 @@ impl TurnRequestProcessor { .map_err(|err| invalid_request(format!("invalid turn context override: {err}")))?; } - // Start the turn by submitting the user input. Return its submission id as turn_id. - let turn_op = if has_any_overrides { - Op::UserInputWithTurnContext { - items: mapped_items, - environments: environment_selections, - final_output_json_schema: params.output_schema, - responsesapi_client_metadata: params.responsesapi_client_metadata, + let turn_context = if has_any_overrides { + codex_protocol::protocol::TurnContextOverrides { cwd, workspace_roots: runtime_workspace_roots, profile_workspace_roots, @@ -527,13 +522,16 @@ impl TurnRequestProcessor { personality, } } else { - Op::UserInput { - items: mapped_items, - environments: environment_selections, - final_output_json_schema: params.output_schema, - responsesapi_client_metadata: params.responsesapi_client_metadata, - turn_context: Default::default(), - } + Default::default() + }; + + // Start the turn by submitting the user input. Return its submission id as turn_id. + let turn_op = Op::UserInput { + items: mapped_items, + environments: environment_selections, + final_output_json_schema: params.output_schema, + responsesapi_client_metadata: params.responsesapi_client_metadata, + turn_context, }; let turn_id = self .submit_core_op(&request_id, thread.as_ref(), turn_op) diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 212168341b37..e8171542e8b5 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -164,62 +164,6 @@ pub(super) async fn user_input_or_turn_inner( None, ) } - Op::UserInputWithTurnContext { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - model, - effort, - summary, - service_tier, - final_output_json_schema, - items, - responsesapi_client_metadata, - collaboration_mode, - personality, - environments, - } => { - let collaboration_mode = if let Some(collab_mode) = collaboration_mode { - Some(collab_mode) - } else { - let state = sess.state.lock().await; - Some( - state - .session_configuration - .collaboration_mode - .with_updates(model, effort, /*developer_instructions*/ None), - ) - }; - ( - items, - SessionSettingsUpdate { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - collaboration_mode, - reasoning_summary: summary, - service_tier, - final_output_json_schema: Some(final_output_json_schema), - environments, - personality, - app_server_client_name: None, - app_server_client_version: None, - }, - responsesapi_client_metadata, - ) - } Op::UserInput { items, environments, @@ -876,9 +820,7 @@ pub(super) async fn submission_loop( .await; false } - Op::UserInput { .. } - | Op::UserInputWithTurnContext { .. } - | Op::UserTurn { .. } => { + Op::UserInput { .. } | Op::UserTurn { .. } => { 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 4dbcc80b4f50..d7fcb84ab9e2 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -5235,31 +5235,6 @@ fn op_kind_distinguishes_turn_ops() { .kind(), "user_input" ); - assert_eq!( - Op::UserInputWithTurnContext { - environments: None, - items: vec![], - final_output_json_schema: None, - responsesapi_client_metadata: None, - cwd: None, - workspace_roots: None, - profile_workspace_roots: 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, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, - } - .kind(), - "user_input_with_turn_context" - ); } #[tokio::test] diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index a067ff699873..b9cb7dcfe833 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -518,95 +518,6 @@ pub enum Op { turn_context: TurnContextOverrides, }, - /// Similar to [`Op::UserInput`], but first applies persistent turn-context - /// overrides in the same queued operation. This preserves submission order - /// and prevents the input from starting if the overrides are rejected. - UserInputWithTurnContext { - /// User input items, see `InputItem` - items: Vec, - /// Optional turn-scoped environment selections. - #[serde(default, skip_serializing_if = "Option::is_none")] - environments: Option>, - /// Optional JSON Schema used to constrain the final assistant message for this turn. - #[serde(skip_serializing_if = "Option::is_none")] - final_output_json_schema: Option, - /// Optional turn-scoped Responses API `client_metadata`. - #[serde(default, skip_serializing_if = "Option::is_none")] - responsesapi_client_metadata: Option>, - - /// Updated `cwd` for sandbox/tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - cwd: Option, - - /// Updated runtime workspace roots used to materialize symbolic - /// `:workspace_roots` filesystem permissions. - #[serde(skip_serializing_if = "Option::is_none")] - workspace_roots: Option>, - - /// Updated profile-defined workspace roots for status summaries and - /// per-turn config reconstruction. - #[serde(skip_serializing_if = "Option::is_none")] - profile_workspace_roots: 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, - - /// Named or built-in profile that produced `permission_profile`, if - /// the update selected a profile rather than supplying raw - /// permissions. - #[serde(skip_serializing_if = "Option::is_none")] - active_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, - }, - /// Similar to [`Op::UserInput`], but contains additional context required /// for a turn of a [`crate::codex_thread::CodexThread`]. UserTurn { @@ -932,7 +843,6 @@ impl Op { Self::RealtimeConversationClose => "realtime_conversation_close", Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", Self::UserInput { .. } => "user_input", - Self::UserInputWithTurnContext { .. } => "user_input_with_turn_context", Self::UserTurn { .. } => "user_turn", Self::InterAgentCommunication { .. } => "inter_agent_communication", Self::OverrideTurnContext { .. } => "override_turn_context", From c6fe81d80336529591575415a4745fa42ebc48c7 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 17:23:39 -0700 Subject: [PATCH 05/15] Simplify turn context update handling --- codex-rs/core/src/session/handlers.rs | 32 +++++++++------------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 212168341b37..6d5a059f8312 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -185,20 +185,9 @@ pub(super) async fn user_input_or_turn_inner( personality, environments, } => { - let collaboration_mode = if let Some(collab_mode) = collaboration_mode { - Some(collab_mode) - } else { - let state = sess.state.lock().await; - Some( - state - .session_configuration - .collaboration_mode - .with_updates(model, effort, /*developer_instructions*/ None), - ) - }; - ( - items, - SessionSettingsUpdate { + let mut updates = turn_context_settings_update( + sess, + TurnContextOverrides { cwd, workspace_roots, profile_workspace_roots, @@ -208,17 +197,18 @@ pub(super) async fn user_input_or_turn_inner( permission_profile, active_permission_profile, windows_sandbox_level, - collaboration_mode, - reasoning_summary: summary, + model, + effort, + summary, service_tier, - final_output_json_schema: Some(final_output_json_schema), - environments, + collaboration_mode, personality, - app_server_client_name: None, - app_server_client_version: None, }, - responsesapi_client_metadata, ) + .await; + updates.final_output_json_schema = Some(final_output_json_schema); + updates.environments = environments; + (items, updates, responsesapi_client_metadata) } Op::UserInput { items, From 9d5a0e2b5d9935a5c8a681c4d75e3efe8e261d93 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 17:39:09 -0700 Subject: [PATCH 06/15] Trim redundant turn context defaults --- codex-rs/core/src/guardian/review_session.rs | 2 -- codex-rs/core/src/session/tests.rs | 2 -- codex-rs/core/tests/common/test_codex.rs | 3 -- codex-rs/core/tests/suite/apply_patch_cli.rs | 4 --- codex-rs/core/tests/suite/approvals.rs | 7 ---- codex-rs/core/tests/suite/client.rs | 8 ----- codex-rs/core/tests/suite/code_mode.rs | 4 --- .../tests/suite/collaboration_instructions.rs | 12 ------- codex-rs/core/tests/suite/compact.rs | 4 --- codex-rs/core/tests/suite/exec_policy.rs | 8 ----- codex-rs/core/tests/suite/image_rollout.rs | 8 ----- codex-rs/core/tests/suite/items.rs | 4 --- codex-rs/core/tests/suite/json_result.rs | 4 --- .../core/tests/suite/mcp_turn_metadata.rs | 4 --- codex-rs/core/tests/suite/model_switching.rs | 4 --- .../core/tests/suite/model_visible_layout.rs | 18 ---------- codex-rs/core/tests/suite/models_cache_ttl.rs | 4 --- .../core/tests/suite/models_etag_responses.rs | 4 --- codex-rs/core/tests/suite/pending_input.rs | 4 --- codex-rs/core/tests/suite/personality.rs | 3 -- codex-rs/core/tests/suite/prompt_caching.rs | 18 ---------- codex-rs/core/tests/suite/remote_env.rs | 4 --- codex-rs/core/tests/suite/remote_models.rs | 30 ---------------- .../core/tests/suite/request_permissions.rs | 4 --- .../tests/suite/request_permissions_tool.rs | 3 -- .../core/tests/suite/request_user_input.rs | 12 ------- .../suite/responses_api_proxy_headers.rs | 4 --- codex-rs/core/tests/suite/rmcp_client.rs | 4 --- .../tests/suite/safety_check_downgrade.rs | 4 --- codex-rs/core/tests/suite/shell_snapshot.rs | 16 --------- codex-rs/core/tests/suite/skill_approval.rs | 4 --- codex-rs/core/tests/suite/skills.rs | 4 --- codex-rs/core/tests/suite/sqlite_state.rs | 4 --- codex-rs/core/tests/suite/tool_harness.rs | 20 ----------- codex-rs/core/tests/suite/tool_parallelism.rs | 8 ----- codex-rs/core/tests/suite/truncation.rs | 4 --- codex-rs/core/tests/suite/unified_exec.rs | 35 ------------------- codex-rs/core/tests/suite/user_shell_cmd.rs | 4 --- codex-rs/core/tests/suite/view_image.rs | 4 --- .../core/tests/suite/websocket_fallback.rs | 4 --- 40 files changed, 301 deletions(-) diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index 0c6358c0acda..4527aa27fa47 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -715,11 +715,9 @@ async fn run_review_on_session( #[allow(deprecated)] cwd: Some(params.parent_turn.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(legacy_sandbox_policy), permission_profile: Some(guardian_permission_profile), summary: Some(params.reasoning_summary), - service_tier: None, personality: params.personality, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 2c03e75a80ac..4e55a582fae1 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -5258,9 +5258,7 @@ async fn user_turn_updates_approvals_reviewer() { approval_policy: Some(config.permissions.approval_policy.value()), approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, summary: config.model_reasoning_summary, - service_tier: None, personality: config.personality, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index f11b86e2de4b..21815694fb98 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -772,12 +772,9 @@ impl TestCodex { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(self.config.cwd.to_path_buf()), approval_policy: Some(approval_policy), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, service_tier, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index c2c8cc51a7d8..7715ec595ceb 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -95,12 +95,8 @@ async fn submit_without_wait_with_turn_permissions( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(harness.cwd().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index 04a6e405bfc0..b4c71e922a90 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -657,10 +657,6 @@ async fn submit_turn( approval_policy: Some(approval_policy), approvals_reviewer: Some(ApprovalsReviewer::User), sandbox_policy: Some(sandbox_policy), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2601,9 +2597,6 @@ async fn matched_prefix_rule_runs_unsandboxed_under_zsh_fork() -> Result<()> { approvals_reviewer: Some(ApprovalsReviewer::User), sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index d05450684c40..4ca224a0c320 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1781,16 +1781,12 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(config.cwd.to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, summary: Some( config .model_reasoning_summary .unwrap_or(ReasoningSummary::Auto), ), - service_tier: None, - personality: None, collaboration_mode: Some(collaboration_mode), ..Default::default() }, @@ -1906,12 +1902,8 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(config.cwd.to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, summary: Some(ReasoningSummary::Concise), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index 0da293534f59..61f99c50c34a 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -2599,12 +2599,8 @@ text( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 727f5d135e85..d811f8e52f02 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -189,16 +189,12 @@ async fn collaboration_instructions_added_on_user_turn() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(test.config.legacy_sandbox_policy()), - permission_profile: None, summary: Some( test.config .model_reasoning_summary .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), ), - service_tier: None, - personality: None, collaboration_mode: Some(collaboration_mode), ..Default::default() }, @@ -243,16 +239,12 @@ async fn collaboration_instructions_omitted_when_disabled() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(test.config.legacy_sandbox_policy()), - permission_profile: None, summary: Some( test.config .model_reasoning_summary .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), ), - service_tier: None, - personality: None, collaboration_mode: Some(collaboration_mode), ..Default::default() }, @@ -370,16 +362,12 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(test.config.legacy_sandbox_policy()), - permission_profile: None, summary: Some( test.config .model_reasoning_summary .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), ), - service_tier: None, - personality: None, collaboration_mode: Some(turn_mode), ..Default::default() }, diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index 7fa5cdf40e22..436e390a0bf8 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -99,12 +99,8 @@ fn disabled_permission_user_turn(text: impl Into, cwd: PathBuf, model: S turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index 02267b54d628..cf90e275e4d7 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -57,12 +57,8 @@ async fn submit_user_turn( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: collaboration_mode.or({ Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, @@ -148,12 +144,8 @@ async fn execpolicy_blocks_shell_invocation() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 6e692e19681c..c763c7b94da2 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -130,12 +130,8 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -230,12 +226,8 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index de30306c5792..8b51c771c115 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -61,12 +61,8 @@ fn disabled_plan_turn( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(collaboration_mode), ..Default::default() }, diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index 91b83fbd0060..6f932873860a 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -86,12 +86,8 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 3ea70a10c620..df3ac8259b4d 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -79,12 +79,8 @@ async fn submit_user_turn( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: collaboration_mode.or({ Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index 9c9c4580d704..f81924d95854 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -50,12 +50,8 @@ fn read_only_user_turn(test: &TestCodex, items: Vec, model: String) - turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 2b275a97f58e..39a93ed7947a 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -128,12 +128,8 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(first_turn_cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(first_sandbox_policy), permission_profile: first_permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -167,11 +163,8 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(preturn_context_diff_cwd), approval_policy: Some(AskForApproval::OnRequest), - approvals_reviewer: None, sandbox_policy: Some(second_sandbox_policy), permission_profile: second_permission_profile, - summary: None, - service_tier: None, personality: Some(Personality::Friendly), collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, @@ -259,12 +252,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_one.clone()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(first_sandbox_policy), permission_profile: first_permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -296,12 +285,8 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_two), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(second_sandbox_policy), permission_profile: second_permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -424,11 +409,8 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(resume_override_cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, personality: Some(Personality::Friendly), collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index ffe06c114596..7cf1d52e62a0 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -103,12 +103,8 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(codex_protocol::protocol::AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index 979d3dafa0c7..ece66cc496a7 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -115,12 +115,8 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index a3c9a5ebfa95..0ecc9c784b72 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -124,12 +124,8 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 5ae0d1bd2a4d..d491a2860e68 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -71,11 +71,8 @@ fn read_only_text_turn_with_personality( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, personality, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 17c57c39df34..9eeff58420b0 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -737,12 +737,9 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(new_cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Detailed), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -860,12 +857,8 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), - approvals_reviewer: None, sandbox_policy: Some(default_sandbox_policy.clone()), - permission_profile: None, summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -892,12 +885,8 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), - approvals_reviewer: None, sandbox_policy: Some(default_sandbox_policy.clone()), - permission_profile: None, summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -1007,12 +996,8 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), - approvals_reviewer: None, sandbox_policy: Some(default_sandbox_policy.clone()), - permission_profile: None, summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -1041,12 +1026,9 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Detailed), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index 30e95f551d74..37f381946bd7 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -80,10 +80,6 @@ async fn submit_turn_with_approval_and_environments( approval_policy: Some(AskForApproval::OnRequest), approvals_reviewer: Some(ApprovalsReviewer::User), sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index aa976c3aa159..2ae573f43f19 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -165,12 +165,7 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -252,12 +247,7 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -338,12 +328,7 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -437,12 +422,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -507,16 +487,12 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), - approvals_reviewer: None, sandbox_policy: Some(config.legacy_sandbox_policy()), - permission_profile: None, summary: Some( config .model_reasoning_summary .unwrap_or(ReasoningSummary::Auto), ), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -689,12 +665,9 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Auto), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -930,12 +903,9 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Auto), - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index c1022665e4b0..a7f475940b74 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -201,10 +201,6 @@ async fn submit_turn( approval_policy: Some(approval_policy), approvals_reviewer: Some(ApprovalsReviewer::User), sandbox_policy: Some(sandbox_policy), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index d8fc5aa440ef..2b4789013515 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -156,9 +156,6 @@ async fn submit_turn( approvals_reviewer, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 9f4b95bf3599..91a8cd16f9ee 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -147,12 +147,8 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(CollaborationMode { mode, settings: Settings { @@ -294,12 +290,8 @@ async fn request_user_input_interrupt_emits_deferred_token_count() -> anyhow::Re turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(CollaborationMode { mode: ModeKind::Plan, settings: Settings { @@ -402,12 +394,8 @@ where turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(collaboration_mode), ..Default::default() }, diff --git a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs index fa193e728633..9f5b649dad59 100644 --- a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs +++ b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs @@ -141,12 +141,8 @@ async fn submit_turn_with_timeout(test: &TestCodex, prompt: &str) -> Result<()> turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::OnRequest), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index cbbd4725edb0..56b00d0c8774 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -116,12 +116,8 @@ fn read_only_user_turn_with_model( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/safety_check_downgrade.rs b/codex-rs/core/tests/suite/safety_check_downgrade.rs index 1bd31fb486fe..db782654a002 100644 --- a/codex-rs/core/tests/suite/safety_check_downgrade.rs +++ b/codex-rs/core/tests/suite/safety_check_downgrade.rs @@ -48,12 +48,8 @@ fn disabled_text_turn(test: &TestCodex, text: &str) -> Op { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index e36d4a15ba99..17b29ca33193 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -170,12 +170,8 @@ async fn run_snapshot_command_with_options( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -274,12 +270,8 @@ async fn run_shell_command_snapshot_with_options( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -358,12 +350,8 @@ async fn run_tool_turn_on_harness( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -605,12 +593,8 @@ async fn shell_command_snapshot_still_intercepts_apply_patch() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.clone()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/skill_approval.rs b/codex-rs/core/tests/suite/skill_approval.rs index 6329b9967785..66747a1f05e1 100644 --- a/codex-rs/core/tests/suite/skill_approval.rs +++ b/codex-rs/core/tests/suite/skill_approval.rs @@ -57,12 +57,8 @@ async fn submit_turn_with_policies( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index 394019fee4cb..e984ecd9a69b 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -91,12 +91,8 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index bdaa09e527c6..932fce8377ef 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -416,12 +416,8 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result< turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index 9a9d66054f92..fe543efff9f7 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -113,12 +113,8 @@ async fn shell_command_tool_executes_command_and_streams_output() -> anyhow::Res turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -198,12 +194,8 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -293,12 +285,8 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -398,12 +386,8 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<() turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -540,12 +524,8 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index d5f8f63eaa27..6d3c85caf242 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -48,12 +48,8 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -378,12 +374,8 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index 361a18dba18b..75352f9ebf4c 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -526,12 +526,8 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(fixture.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile: Some(permission_profile), - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index bad92384cc11..f619c24ed480 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -201,12 +201,7 @@ async fn submit_unified_exec_turn( turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -294,12 +289,7 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(SandboxPolicy::DangerFullAccess), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2145,12 +2135,7 @@ async fn unified_exec_keeps_long_running_session_after_turn_end() -> Result<()> turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(SandboxPolicy::DangerFullAccess), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2249,12 +2234,7 @@ async fn unified_exec_interrupt_preserves_long_running_session() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(SandboxPolicy::DangerFullAccess), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2732,12 +2712,7 @@ async fn unified_exec_runs_under_sandbox() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2856,12 +2831,7 @@ async fn unified_exec_enforces_glob_deny_read_policy() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(read_only_policy), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { @@ -2995,12 +2965,7 @@ async fn unified_exec_python_prompt_under_seatbelt() -> Result<()> { turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), - permission_profile: None, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index acbe4167bc6a..0d4eed826c07 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -185,12 +185,8 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index 60d7fdb4b320..688450cb6c90 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -80,12 +80,8 @@ fn disabled_user_turn(test: &TestCodex, items: Vec, model: String) -> turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index 1133c29a5896..843e3b2e6045 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -163,12 +163,8 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result turn_context: codex_protocol::protocol::TurnContextOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), - approvals_reviewer: None, sandbox_policy: Some(sandbox_policy), permission_profile, - summary: None, - service_tier: None, - personality: None, collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { mode: codex_protocol::config_types::ModeKind::Default, settings: codex_protocol::config_types::Settings { From cd69441b5b93d6cb05e9e662990600a83c0af7bb Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 17:42:10 -0700 Subject: [PATCH 07/15] Simplify turn start context overrides --- .../src/request_processors/turn_processor.rs | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 85b5e4e5541e..a84e658b8221 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -503,26 +503,22 @@ impl TurnRequestProcessor { .map_err(|err| invalid_request(format!("invalid turn context override: {err}")))?; } - let turn_context = if has_any_overrides { - codex_protocol::protocol::TurnContextOverrides { - cwd, - workspace_roots: runtime_workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level: None, - model, - effort, - summary, - service_tier, - collaboration_mode, - personality, - } - } else { - Default::default() + let turn_context = codex_protocol::protocol::TurnContextOverrides { + cwd, + workspace_roots: runtime_workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level: None, + model, + effort, + summary, + service_tier, + collaboration_mode, + personality, }; // Start the turn by submitting the user input. Return its submission id as turn_id. From 14284fe5a76c2de3c5be852a7dcc9a3d18ab03e7 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 15:27:06 -0700 Subject: [PATCH 08/15] Rename input settings override terminology --- codex-rs/app-server/README.md | 2 +- codex-rs/app-server/src/request_processors.rs | 2 +- .../src/request_processors/turn_processor.rs | 10 +- .../app-server/tests/suite/v2/turn_start.rs | 6 +- codex-rs/core/src/agent/control_tests.rs | 6 +- codex-rs/core/src/codex_delegate.rs | 2 +- codex-rs/core/src/codex_thread.rs | 12 +- codex-rs/core/src/lib.rs | 2 +- codex-rs/core/src/session/handlers.rs | 20 ++-- codex-rs/core/src/session/mod.rs | 2 +- codex-rs/core/src/session/tests.rs | 12 +- .../src/tools/handlers/multi_agents_tests.rs | 2 +- codex-rs/core/tests/suite/abort_tasks.rs | 10 +- codex-rs/core/tests/suite/client.rs | 64 +++++------ .../core/tests/suite/client_websockets.rs | 4 +- .../tests/suite/collaboration_instructions.rs | 28 ++--- codex-rs/core/tests/suite/compact.rs | 62 +++++----- codex-rs/core/tests/suite/compact_remote.rs | 106 +++++++++--------- .../core/tests/suite/compact_remote_parity.rs | 2 +- .../core/tests/suite/compact_resume_fork.rs | 4 +- codex-rs/core/tests/suite/fork_thread.rs | 4 +- codex-rs/core/tests/suite/hooks.rs | 4 +- codex-rs/core/tests/suite/items.rs | 18 +-- .../core/tests/suite/model_visible_layout.rs | 6 +- codex-rs/core/tests/suite/otel.rs | 44 ++++---- codex-rs/core/tests/suite/pending_input.rs | 6 +- .../core/tests/suite/permissions_messages.rs | 30 ++--- codex-rs/core/tests/suite/plugins.rs | 6 +- codex-rs/core/tests/suite/prompt_caching.rs | 22 ++-- codex-rs/core/tests/suite/quota_exceeded.rs | 2 +- .../core/tests/suite/realtime_conversation.rs | 6 +- .../core/tests/suite/request_compression.rs | 4 +- codex-rs/core/tests/suite/resume.rs | 14 +-- codex-rs/core/tests/suite/review.rs | 2 +- codex-rs/core/tests/suite/search_tool.rs | 8 +- .../suite/stream_error_allows_next_turn.rs | 4 +- .../core/tests/suite/stream_no_completed.rs | 2 +- .../core/tests/suite/user_notification.rs | 2 +- codex-rs/core/tests/suite/window_headers.rs | 2 +- codex-rs/mcp-server/src/codex_tool_runner.rs | 4 +- codex-rs/memories/write/src/runtime.rs | 2 +- codex-rs/protocol/src/protocol.rs | 26 ++--- codex-rs/thread-manager-sample/src/main.rs | 2 +- 43 files changed, 292 insertions(+), 286 deletions(-) diff --git a/codex-rs/app-server/README.md b/codex-rs/app-server/README.md index 9d0a509c4c0b..89a4a3560ee5 100644 --- a/codex-rs/app-server/README.md +++ b/codex-rs/app-server/README.md @@ -831,7 +831,7 @@ Use `thread/backgroundTerminals/clean` to terminate all running background termi ### Example: Steer an active turn Use `turn/steer` to append additional user input to the currently active regular turn. This does -not emit `turn/started` and does not accept turn context overrides. +not emit `turn/started` and does not accept thread settings overrides. ```json { "method": "turn/steer", "id": 32, "params": { diff --git a/codex-rs/app-server/src/request_processors.rs b/codex-rs/app-server/src/request_processors.rs index d5853b56c557..4e77831e5ba8 100644 --- a/codex-rs/app-server/src/request_processors.rs +++ b/codex-rs/app-server/src/request_processors.rs @@ -258,7 +258,7 @@ use codex_config::ConfigLayerStack; use codex_config::loader::project_trust_key; use codex_config::types::McpServerTransportConfig; use codex_core::CodexThread; -use codex_core::CodexThreadTurnContextOverrides; +use codex_core::CodexThreadSettingsOverrides; use codex_core::ExternalGoalPreviousStatus; use codex_core::ExternalGoalSet; use codex_core::ForkSnapshot; diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 9895d9aad8c9..5ac55372106a 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -460,7 +460,7 @@ impl TurnRequestProcessor { warning.contains("Configured value for `permission_profile` is disallowed") }) { return Err(invalid_request(format!( - "invalid turn context override: {warning}" + "invalid thread settings override: {warning}" ))); } ( @@ -482,7 +482,7 @@ impl TurnRequestProcessor { // still queued together with the input below to preserve submission order. if has_any_overrides { thread - .validate_turn_context_overrides(CodexThreadTurnContextOverrides { + .validate_thread_settings_overrides(CodexThreadSettingsOverrides { cwd: cwd.clone(), workspace_roots: runtime_workspace_roots.clone(), approval_policy, @@ -500,7 +500,9 @@ impl TurnRequestProcessor { personality, }) .await - .map_err(|err| invalid_request(format!("invalid turn context override: {err}")))?; + .map_err(|err| { + invalid_request(format!("invalid thread settings override: {err}")) + })?; } // Start the turn by submitting the user input. Return its submission id as turn_id. @@ -532,7 +534,7 @@ impl TurnRequestProcessor { environments: environment_selections, final_output_json_schema: params.output_schema, responsesapi_client_metadata: params.responsesapi_client_metadata, - turn_context: Default::default(), + thread_settings: Default::default(), } }; let turn_id = self diff --git a/codex-rs/app-server/tests/suite/v2/turn_start.rs b/codex-rs/app-server/tests/suite/v2/turn_start.rs index 844d9ab1bbe1..01e535a5a402 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start.rs @@ -904,7 +904,11 @@ async fn turn_start_rejects_invalid_permission_selection_before_starting_turn() .await??; assert_eq!(err.error.code, INVALID_REQUEST_ERROR_CODE); - assert!(err.error.message.contains("invalid turn context override")); + assert!( + err.error + .message + .contains("invalid thread settings override") + ); assert!( err.error.message.contains("allowed set [ReadOnly]"), "unexpected error message: {}", diff --git a/codex-rs/core/src/agent/control_tests.rs b/codex-rs/core/src/agent/control_tests.rs index abf9fd9b87aa..3ced8630ea60 100644 --- a/codex-rs/core/src/agent/control_tests.rs +++ b/codex-rs/core/src/agent/control_tests.rs @@ -442,7 +442,7 @@ async fn send_input_submits_user_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }, ); let captured = harness @@ -590,7 +590,7 @@ async fn spawn_agent_creates_thread_and_sends_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }, ); let captured = harness @@ -739,7 +739,7 @@ async fn spawn_agent_can_fork_parent_thread_history_with_sanitized_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }, ); let captured = harness diff --git a/codex-rs/core/src/codex_delegate.rs b/codex-rs/core/src/codex_delegate.rs index d7c6abdd70c0..4ed6b2368cbf 100644 --- a/codex-rs/core/src/codex_delegate.rs +++ b/codex-rs/core/src/codex_delegate.rs @@ -192,7 +192,7 @@ pub(crate) async fn run_codex_thread_one_shot( items: input, final_output_json_schema, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/src/codex_thread.rs b/codex-rs/core/src/codex_thread.rs index 1a2d5ed710ab..e86f34742d35 100644 --- a/codex-rs/core/src/codex_thread.rs +++ b/codex-rs/core/src/codex_thread.rs @@ -80,9 +80,9 @@ impl ThreadConfigSnapshot { } } -/// Turn context overrides that app-server validates before starting a turn. +/// Thread settings overrides that app-server validates before starting a turn. #[derive(Clone, Default)] -pub struct CodexThreadTurnContextOverrides { +pub struct CodexThreadSettingsOverrides { pub cwd: Option, pub workspace_roots: Option>, pub profile_workspace_roots: Option>, @@ -255,12 +255,12 @@ impl CodexThread { .await } - /// Validate persistent turn context overrides without committing them. - pub async fn validate_turn_context_overrides( + /// Validate persistent thread settings overrides without committing them. + pub async fn validate_thread_settings_overrides( &self, - overrides: CodexThreadTurnContextOverrides, + overrides: CodexThreadSettingsOverrides, ) -> ConstraintResult<()> { - let CodexThreadTurnContextOverrides { + let CodexThreadSettingsOverrides { cwd, workspace_roots, profile_workspace_roots, diff --git a/codex-rs/core/src/lib.rs b/codex-rs/core/src/lib.rs index 325d65745f36..b18932e65f75 100644 --- a/codex-rs/core/src/lib.rs +++ b/codex-rs/core/src/lib.rs @@ -20,7 +20,7 @@ mod compact_remote; mod compact_remote_v2; mod config_lock; pub use codex_thread::CodexThread; -pub use codex_thread::CodexThreadTurnContextOverrides; +pub use codex_thread::CodexThreadSettingsOverrides; pub use codex_thread::ThreadConfigSnapshot; pub use session::turn_context::TurnContext; mod agent; diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 6d5a059f8312..066ddbe2f2eb 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -42,8 +42,8 @@ use codex_protocol::protocol::ReviewRequest; use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::ThreadMemoryMode; use codex_protocol::protocol::ThreadRolledBackEvent; +use codex_protocol::protocol::ThreadSettingsOverrides; use codex_protocol::protocol::TurnAbortReason; -use codex_protocol::protocol::TurnContextOverrides; use codex_protocol::protocol::WarningEvent; use codex_protocol::request_permissions::RequestPermissionsResponse; use codex_protocol::request_user_input::RequestUserInputResponse; @@ -185,9 +185,9 @@ pub(super) async fn user_input_or_turn_inner( personality, environments, } => { - let mut updates = turn_context_settings_update( + let mut updates = thread_settings_update( sess, - TurnContextOverrides { + ThreadSettingsOverrides { cwd, workspace_roots, profile_workspace_roots, @@ -215,12 +215,12 @@ pub(super) async fn user_input_or_turn_inner( environments, final_output_json_schema, responsesapi_client_metadata, - turn_context, + thread_settings, } => { - let mut updates = if turn_context == TurnContextOverrides::default() { + let mut updates = if thread_settings == ThreadSettingsOverrides::default() { SessionSettingsUpdate::default() } else { - turn_context_settings_update(sess, turn_context).await + thread_settings_update(sess, thread_settings).await }; updates.final_output_json_schema = Some(final_output_json_schema); updates.environments = environments; @@ -282,11 +282,11 @@ pub(super) async fn user_input_or_turn_inner( } } -async fn turn_context_settings_update( +async fn thread_settings_update( sess: &Session, - turn_context: TurnContextOverrides, + thread_settings: ThreadSettingsOverrides, ) -> SessionSettingsUpdate { - let TurnContextOverrides { + let ThreadSettingsOverrides { cwd, workspace_roots, profile_workspace_roots, @@ -302,7 +302,7 @@ async fn turn_context_settings_update( service_tier, collaboration_mode, personality, - } = turn_context; + } = thread_settings; let collaboration_mode = if let Some(collaboration_mode) = collaboration_mode { collaboration_mode } else { diff --git a/codex-rs/core/src/session/mod.rs b/codex-rs/core/src/session/mod.rs index 9a78242222ae..5af22abb71ea 100644 --- a/codex-rs/core/src/session/mod.rs +++ b/codex-rs/core/src/session/mod.rs @@ -1096,7 +1096,7 @@ impl Session { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }, /*mirror_user_text_to_realtime*/ None, ) diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 4dbcc80b4f50..7b6feea29f1b 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -2220,7 +2220,7 @@ 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(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2284,7 +2284,7 @@ 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(), + thread_settings: Default::default(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -5230,7 +5230,7 @@ fn op_kind_distinguishes_turn_ops() { items: vec![], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), } .kind(), "user_input" @@ -8338,7 +8338,7 @@ async fn active_goal_continuation_runs_again_after_no_tool_turn() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -8443,7 +8443,7 @@ async fn pending_request_user_input_does_not_spawn_extra_goal_continuation() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -8868,7 +8868,7 @@ async fn completed_goal_accounts_current_turn_tokens_before_tool_response() -> a }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs index c0c001690734..27b12dbe4e68 100644 --- a/codex-rs/core/src/tools/handlers/multi_agents_tests.rs +++ b/codex-rs/core/src/tools/handlers/multi_agents_tests.rs @@ -2470,7 +2470,7 @@ async fn send_input_accepts_structured_items() { ], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }; let captured = manager .captured_ops() diff --git a/codex-rs/core/tests/suite/abort_tasks.rs b/codex-rs/core/tests/suite/abort_tasks.rs index fd2c06aef3be..c41502a9dc9a 100644 --- a/codex-rs/core/tests/suite/abort_tasks.rs +++ b/codex-rs/core/tests/suite/abort_tasks.rs @@ -53,7 +53,7 @@ async fn interrupt_long_running_tool_emits_turn_aborted() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -110,7 +110,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -131,7 +131,7 @@ async fn interrupt_tool_records_history_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -214,7 +214,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -235,7 +235,7 @@ async fn interrupt_persists_turn_aborted_marker_in_next_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 3092c613726a..818e0eba7bdb 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -392,7 +392,7 @@ async fn resume_includes_initial_messages_and_sends_prior_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -758,7 +758,7 @@ async fn includes_session_id_thread_id_and_model_headers_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -969,7 +969,7 @@ async fn includes_base_instructions_override_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1026,7 +1026,7 @@ async fn chatgpt_auth_sends_correct_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1150,7 +1150,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1189,7 +1189,7 @@ async fn includes_user_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1277,7 +1277,7 @@ async fn includes_apps_guidance_as_developer_message_for_chatgpt_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1340,7 +1340,7 @@ async fn omits_apps_guidance_for_api_key_auth_even_when_feature_enabled() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1399,7 +1399,7 @@ async fn omits_apps_guidance_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1441,7 +1441,7 @@ async fn omits_environment_context_when_configured_off() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1498,7 +1498,7 @@ async fn skills_append_to_developer_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1581,7 +1581,7 @@ async fn skills_use_aliases_in_developer_message_under_budget_pressure() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1642,7 +1642,7 @@ async fn includes_configured_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1684,7 +1684,7 @@ async fn includes_no_effort_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1727,7 +1727,7 @@ async fn includes_default_reasoning_effort_in_request_when_defined_by_model_info }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1841,7 +1841,7 @@ async fn configured_reasoning_summary_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1961,7 +1961,7 @@ async fn reasoning_summary_is_omitted_when_disabled() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2020,7 +2020,7 @@ async fn reasoning_summary_none_overrides_model_catalog_default() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2059,7 +2059,7 @@ async fn includes_default_verbosity_in_request() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2107,7 +2107,7 @@ async fn configured_verbosity_not_sent_for_models_without_support() -> anyhow::R }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2154,7 +2154,7 @@ async fn configured_verbosity_is_sent() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2206,7 +2206,7 @@ async fn includes_developer_instructions_message_in_request() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2502,7 +2502,7 @@ async fn token_count_includes_rate_limits_snapshot() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2641,7 +2641,7 @@ async fn usage_limit_error_emits_rate_limit_event() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -2718,7 +2718,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -2733,7 +2733,7 @@ async fn context_window_error_sets_total_tokens_to_model_window() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -2818,7 +2818,7 @@ async fn incomplete_response_emits_content_filter_error_message() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -2929,7 +2929,7 @@ async fn azure_overrides_assign_properties_used_for_responses_url() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3018,7 +3018,7 @@ async fn env_var_overrides_loaded_auth() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3075,7 +3075,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3091,7 +3091,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3107,7 +3107,7 @@ async fn history_dedupes_streamed_and_final_messages_across_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index 3ae5be3e904b..feee9d42272f 100755 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -1208,7 +1208,7 @@ async fn responses_websocket_usage_limit_error_emits_rate_limit_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submission should succeed while emitting usage limit error events"); @@ -1297,7 +1297,7 @@ async fn responses_websocket_invalid_request_error_with_status_is_forwarded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submission should succeed while emitting invalid request events"); diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index e2890c582886..2b0c20ab26ea 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -86,7 +86,7 @@ async fn no_collaboration_instructions_by_default() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -149,7 +149,7 @@ async fn user_input_includes_collaboration_instructions_after_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -307,7 +307,7 @@ async fn override_then_next_turn_uses_updated_collaboration_instructions() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -437,7 +437,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -468,7 +468,7 @@ async fn collaboration_mode_update_emits_new_instruction_message() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -528,7 +528,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -559,7 +559,7 @@ async fn collaboration_mode_update_noop_does_not_append() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -621,7 +621,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -655,7 +655,7 @@ async fn collaboration_mode_update_emits_new_instruction_message_when_mode_chang }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -718,7 +718,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -752,7 +752,7 @@ async fn collaboration_mode_update_noop_does_not_append_when_mode_is_unchanged() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -819,7 +819,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -835,7 +835,7 @@ async fn resume_replays_collaboration_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -895,7 +895,7 @@ async fn empty_collaboration_instructions_are_ignored() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index 1ca9b49d48b6..d1384ff800fc 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -386,7 +386,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -411,7 +411,7 @@ async fn summarize_context_three_requests_and_instructions() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -588,7 +588,7 @@ async fn manual_pre_compact_block_decision_does_not_block_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit first user turn"); @@ -661,7 +661,7 @@ async fn compact_hooks_respect_matchers_and_post_runs_after_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit first user turn"); @@ -731,7 +731,7 @@ async fn manual_compact_uses_custom_prompt() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit first user turn"); @@ -878,7 +878,7 @@ async fn manual_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1044,7 +1044,7 @@ async fn multiple_auto_compact_per_task_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit user input"); @@ -1516,7 +1516,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1532,7 +1532,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1548,7 +1548,7 @@ async fn auto_compact_runs_after_token_limit_hit() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1719,7 +1719,7 @@ async fn auto_compact_emits_context_compaction_items() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1800,7 +1800,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1815,7 +1815,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1830,7 +1830,7 @@ async fn auto_compact_starts_after_turn_started() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2264,7 +2264,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2279,7 +2279,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2294,7 +2294,7 @@ async fn auto_compact_persists_rollout_entries() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2383,7 +2383,7 @@ async fn manual_compact_retries_after_context_window_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2487,7 +2487,7 @@ async fn manual_compact_non_context_failure_retries_then_emits_task_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit user input"); @@ -2582,7 +2582,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2600,7 +2600,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2618,7 +2618,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2782,7 +2782,7 @@ async fn auto_compact_allows_multiple_attempts_when_interleaved_with_other_turn_ }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -2887,7 +2887,7 @@ async fn snapshot_request_shape_mid_turn_continuation_compaction() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3087,7 +3087,7 @@ async fn auto_compact_counts_encrypted_reasoning_before_last_user() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3206,7 +3206,7 @@ async fn auto_compact_runs_when_reasoning_header_clears_between_turns() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -3268,7 +3268,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit user input"); @@ -3308,7 +3308,7 @@ async fn snapshot_request_shape_pre_turn_compaction_including_incoming_user_mess ], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit user input"); @@ -3497,7 +3497,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit first user"); @@ -3512,7 +3512,7 @@ async fn snapshot_request_shape_pre_turn_compaction_context_window_exceeded() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit second user"); @@ -3585,7 +3585,7 @@ async fn snapshot_request_shape_manual_compact_without_previous_user_messages() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit follow-up user input"); diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 1f5f661f053b..9db94016e6af 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -326,7 +326,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -343,7 +343,7 @@ async fn remote_compact_replaces_history_for_followups() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -518,7 +518,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -538,7 +538,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -552,7 +552,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -572,7 +572,7 @@ async fn assert_remote_manual_compact_request_parity( ], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -586,7 +586,7 @@ async fn assert_remote_manual_compact_request_parity( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -754,7 +754,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -771,7 +771,7 @@ async fn remote_compact_v2_reuses_compaction_trigger_for_followups() -> Result<( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -865,7 +865,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -882,7 +882,7 @@ async fn remote_compact_v2_accepts_additional_output_items_before_compaction() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -973,7 +973,7 @@ async fn remote_compact_filters_deferred_dynamic_tools() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_turn_complete(&codex).await; @@ -1045,7 +1045,7 @@ async fn remote_compact_runs_automatically() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1126,7 +1126,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1140,7 +1140,7 @@ async fn remote_compact_trims_function_call_history_to_fit_context_window() -> R }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1258,7 +1258,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1272,7 +1272,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1292,7 +1292,7 @@ async fn auto_remote_compact_trims_function_call_history_to_fit_context_window() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1392,7 +1392,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1406,7 +1406,7 @@ async fn auto_remote_compact_failure_stops_agent_loop() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1500,7 +1500,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1517,7 +1517,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&baseline_codex, |event| { @@ -1608,7 +1608,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1625,7 +1625,7 @@ async fn remote_compact_trim_estimate_uses_session_base_instructions() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&override_codex, |event| { @@ -1696,7 +1696,7 @@ async fn remote_manual_compact_emits_context_compaction_items() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1777,7 +1777,7 @@ async fn remote_manual_compact_failure_emits_task_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -1861,7 +1861,7 @@ async fn remote_compact_persists_replacement_history_in_rollout() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2004,7 +2004,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2022,7 +2022,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2047,7 +2047,7 @@ async fn remote_compact_and_resume_refresh_stale_developer_instructions() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2143,7 +2143,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2160,7 +2160,7 @@ async fn remote_compact_refreshes_stale_developer_instructions_without_resume() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2232,7 +2232,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2246,7 +2246,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_sta }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2313,7 +2313,7 @@ async fn remote_request_uses_custom_experimental_realtime_start_instructions() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2374,7 +2374,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2390,7 +2390,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_restates_realtime_end }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2465,7 +2465,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2482,7 +2482,7 @@ async fn snapshot_request_shape_remote_manual_compact_restates_realtime_start() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2565,7 +2565,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2581,7 +2581,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_does_not_restate_real }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2672,7 +2672,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2702,7 +2702,7 @@ async fn snapshot_request_shape_remote_compact_resume_restates_realtime_end() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2799,7 +2799,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_including_incoming_us }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2886,7 +2886,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -2916,7 +2916,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_strips_incoming_model }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3035,7 +3035,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3049,7 +3049,7 @@ async fn snapshot_request_shape_remote_pre_turn_compaction_context_window_exceed }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; let error_message = wait_for_event_match(&codex, |event| match event { @@ -3134,7 +3134,7 @@ async fn snapshot_request_shape_remote_mid_turn_continuation_compaction() -> Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3212,7 +3212,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_summary_only_reinject }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3298,7 +3298,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3315,7 +3315,7 @@ async fn snapshot_request_shape_remote_mid_turn_compaction_multi_summary_reinjec }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -3397,7 +3397,7 @@ async fn snapshot_request_shape_remote_manual_compact_without_previous_user_mess }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact_remote_parity.rs b/codex-rs/core/tests/suite/compact_remote_parity.rs index c465480558b0..ccbd427b1f5c 100644 --- a/codex-rs/core/tests/suite/compact_remote_parity.rs +++ b/codex-rs/core/tests/suite/compact_remote_parity.rs @@ -606,7 +606,7 @@ async fn submit_user_input(codex: &codex_core::CodexThread, items: Vec Resu } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] -/// Scenario: rolling back a turn that introduced persistent pre-turn context +/// Scenario: rolling back a turn that introduced persistent thread settings /// diffs should trim those context updates so the next request includes them /// only once. async fn snapshot_rollback_followup_turn_trims_context_updates() -> Result<()> { @@ -790,7 +790,7 @@ async fn user_turn(conversation: &Arc, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .expect("submit user turn"); diff --git a/codex-rs/core/tests/suite/fork_thread.rs b/codex-rs/core/tests/suite/fork_thread.rs index 75256ae786d2..68a167f79022 100644 --- a/codex-rs/core/tests/suite/fork_thread.rs +++ b/codex-rs/core/tests/suite/fork_thread.rs @@ -57,7 +57,7 @@ async fn fork_thread_twice_drops_to_first_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -181,7 +181,7 @@ async fn fork_thread_from_history_does_not_require_source_rollout_path() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/hooks.rs b/codex-rs/core/tests/suite/hooks.rs index 8eda28354e94..d7549e0e0edd 100644 --- a/codex-rs/core/tests/suite/hooks.rs +++ b/codex-rs/core/tests/suite/hooks.rs @@ -1440,7 +1440,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1459,7 +1459,7 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; } diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 9f6407b353ff..0015a418ca62 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -121,7 +121,7 @@ async fn user_message_item_is_emitted() -> anyhow::Result<()> { items: vec![expected_input.clone()], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -180,7 +180,7 @@ async fn assistant_message_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -241,7 +241,7 @@ async fn reasoning_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -303,7 +303,7 @@ async fn web_search_item_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -383,7 +383,7 @@ async fn image_generation_call_event_is_emitted() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -470,7 +470,7 @@ async fn image_generation_call_event_is_emitted_when_image_save_fails() -> anyho }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -526,7 +526,7 @@ async fn agent_message_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1110,7 +1110,7 @@ async fn reasoning_content_delta_has_item_metadata() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1165,7 +1165,7 @@ async fn reasoning_raw_content_delta_respects_flag() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 6c0275b1326a..d9c636b35f3d 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -344,7 +344,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -452,7 +452,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -501,7 +501,7 @@ async fn snapshot_model_visible_layout_resume_override_matches_rollout_model() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/otel.rs b/codex-rs/core/tests/suite/otel.rs index 31477f0d3a76..9d2df4e60e79 100644 --- a/codex-rs/core/tests/suite/otel.rs +++ b/codex-rs/core/tests/suite/otel.rs @@ -122,7 +122,7 @@ async fn responses_api_emits_api_request_event() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -168,7 +168,7 @@ async fn process_sse_emits_tracing_for_output_item() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -214,7 +214,7 @@ async fn process_sse_emits_failed_event_on_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -261,7 +261,7 @@ async fn process_sse_records_failed_event_when_stream_closes_without_completed() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -328,7 +328,7 @@ async fn process_sse_failed_event_records_response_error_message() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -393,7 +393,7 @@ async fn process_sse_failed_event_logs_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -445,7 +445,7 @@ async fn process_sse_failed_event_logs_missing_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -506,7 +506,7 @@ async fn process_sse_failed_event_logs_response_completed_parse_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -561,7 +561,7 @@ async fn process_sse_emits_completed_telemetry() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -640,7 +640,7 @@ async fn turn_and_completed_response_spans_record_token_usage() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -728,7 +728,7 @@ async fn handle_responses_span_records_response_kind_and_tool_name() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -822,7 +822,7 @@ async fn record_responses_sets_span_fields_for_response_events() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -911,7 +911,7 @@ async fn handle_response_item_records_tool_result_for_custom_tool_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -987,7 +987,7 @@ async fn handle_response_item_records_tool_result_for_function_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1064,7 +1064,7 @@ async fn handle_response_item_records_tool_result_for_shell_command_call() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1173,7 +1173,7 @@ async fn handle_shell_command_autoapprove_from_config_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1228,7 +1228,7 @@ async fn handle_shell_command_user_approved_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1298,7 +1298,7 @@ async fn handle_shell_command_user_approved_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1368,7 +1368,7 @@ async fn handle_sandbox_error_user_approves_retry_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1438,7 +1438,7 @@ async fn handle_shell_command_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1508,7 +1508,7 @@ async fn handle_sandbox_error_user_approves_for_session_records_tool_decision() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -1579,7 +1579,7 @@ async fn handle_sandbox_error_user_denies_records_tool_decision() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index ebc18a3fd8f1..d511c8f0b657 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -103,7 +103,7 @@ async fn submit_user_input(codex: &CodexThread, text: &str) { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap_or_else(|err| panic!("submit user input: {err}")); @@ -286,7 +286,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -305,7 +305,7 @@ async fn injected_user_input_triggers_follow_up_request_with_deltas() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/permissions_messages.rs b/codex-rs/core/tests/suite/permissions_messages.rs index d22b37a8437d..33d494ae450a 100644 --- a/codex-rs/core/tests/suite/permissions_messages.rs +++ b/codex-rs/core/tests/suite/permissions_messages.rs @@ -58,7 +58,7 @@ async fn permissions_message_sent_once_on_start() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -98,7 +98,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -129,7 +129,7 @@ async fn permissions_message_added_on_override_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -175,7 +175,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -189,7 +189,7 @@ async fn permissions_message_not_added_when_no_change() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -235,7 +235,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -266,7 +266,7 @@ async fn permissions_message_omitted_when_disabled() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -325,7 +325,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -358,7 +358,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -374,7 +374,7 @@ async fn resume_replays_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -434,7 +434,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -467,7 +467,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&initial.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -489,7 +489,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -525,7 +525,7 @@ async fn resume_and_fork_append_permissions_messages() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&forked.thread, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -586,7 +586,7 @@ async fn permissions_message_includes_writable_roots() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/plugins.rs b/codex-rs/core/tests/suite/plugins.rs index f2b9cfeba9de..45fdf3df0764 100644 --- a/codex-rs/core/tests/suite/plugins.rs +++ b/codex-rs/core/tests/suite/plugins.rs @@ -227,7 +227,7 @@ async fn capability_sections_render_in_developer_message_in_order() -> Result<() }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -306,7 +306,7 @@ async fn explicit_plugin_mentions_inject_plugin_guidance() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -388,7 +388,7 @@ async fn explicit_plugin_mentions_track_plugin_used_analytics() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index b72b7fc1d0a2..2023778a1127 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -153,7 +153,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -167,7 +167,7 @@ async fn prompt_tools_are_consistent_across_requests() -> anyhow::Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -251,7 +251,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -265,7 +265,7 @@ async fn gpt_5_tools_without_apply_patch_append_apply_patch_instructions() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -330,7 +330,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -344,7 +344,7 @@ async fn prefixes_context_and_instructions_once_and_consistently_across_requests }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -427,7 +427,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -469,7 +469,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -493,7 +493,7 @@ async fn overrides_turn_context_but_keeps_cached_prefix_and_key_constant() -> an }); let expected_permissions_msg = body1["input"][0].clone(); let body1_input = body1["input"].as_array().expect("input array"); - // After overriding the turn context, emit one updated permissions message. + // After overriding thread settings, emit one updated permissions message. let expected_permissions_msg_2 = body2["input"][body1_input.len()].clone(); assert_ne!( expected_permissions_msg_2, expected_permissions_msg, @@ -555,7 +555,7 @@ async fn override_before_first_turn_emits_environment_context() -> anyhow::Resul }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -709,7 +709,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/quota_exceeded.rs b/codex-rs/core/tests/suite/quota_exceeded.rs index d93fc6c95614..413855f64132 100644 --- a/codex-rs/core/tests/suite/quota_exceeded.rs +++ b/codex-rs/core/tests/suite/quota_exceeded.rs @@ -48,7 +48,7 @@ async fn quota_exceeded_emits_single_error_event() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 39ae60f4117b..232d2380b0a1 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -2168,7 +2168,7 @@ async fn conversation_user_text_turn_is_sent_to_realtime_when_active() -> Result }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -2303,7 +2303,7 @@ async fn conversation_user_text_turn_is_capped_when_mirrored_to_realtime() -> Re }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -3499,7 +3499,7 @@ async fn inbound_handoff_request_steers_active_turn() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/request_compression.rs b/codex-rs/core/tests/suite/request_compression.rs index f86b7ffafba5..2d66389d5347 100644 --- a/codex-rs/core/tests/suite/request_compression.rs +++ b/codex-rs/core/tests/suite/request_compression.rs @@ -47,7 +47,7 @@ async fn request_body_is_zstd_compressed_for_codex_backend_when_enabled() -> any }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -97,7 +97,7 @@ async fn request_body_is_not_compressed_for_api_key_auth_even_when_enabled() -> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/resume.rs b/codex-rs/core/tests/suite/resume.rs index 29a8f4ff7ad0..db6428935477 100644 --- a/codex-rs/core/tests/suite/resume.rs +++ b/codex-rs/core/tests/suite/resume.rs @@ -93,7 +93,7 @@ async fn resume_includes_initial_messages_from_rollout_events() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -179,7 +179,7 @@ async fn resume_includes_initial_messages_from_reasoning_events() -> Result<()> }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -269,7 +269,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -312,7 +312,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -330,7 +330,7 @@ async fn resume_switches_models_preserves_base_instructions() -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { @@ -403,7 +403,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; @@ -450,7 +450,7 @@ async fn resume_model_switch_is_not_duplicated_after_pre_turn_override() -> Resu }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 57467a100710..e128a189b5d0 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -684,7 +684,7 @@ async fn review_history_surfaces_in_parent_session() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/search_tool.rs b/codex-rs/core/tests/suite/search_tool.rs index 6c0d3ce17b90..5b86c6ee7d98 100644 --- a/codex-rs/core/tests/suite/search_tool.rs +++ b/codex-rs/core/tests/suite/search_tool.rs @@ -494,7 +494,7 @@ async fn tool_search_returns_deferred_tools_without_follow_up_tool_injection() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -805,7 +805,7 @@ async fn tool_search_returns_deferred_dynamic_tool_and_routes_follow_up_call() - }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1113,7 +1113,7 @@ async fn tool_search_surfaced_mcp_tool_errors_are_returned_to_model() -> Result< }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; @@ -1433,7 +1433,7 @@ async fn tool_search_matches_dynamic_tools_by_name_description_namespace_and_sch }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; diff --git a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs index 673fc63526fd..5709cdd12b89 100644 --- a/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs +++ b/codex-rs/core/tests/suite/stream_error_allows_next_turn.rs @@ -101,7 +101,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); @@ -123,7 +123,7 @@ async fn continue_after_stream_error() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/stream_no_completed.rs b/codex-rs/core/tests/suite/stream_no_completed.rs index 841851562cf0..40763960f40c 100644 --- a/codex-rs/core/tests/suite/stream_no_completed.rs +++ b/codex-rs/core/tests/suite/stream_no_completed.rs @@ -83,7 +83,7 @@ async fn retries_on_early_close() { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/user_notification.rs b/codex-rs/core/tests/suite/user_notification.rs index 7e0210fc7770..343afd8d533f 100644 --- a/codex-rs/core/tests/suite/user_notification.rs +++ b/codex-rs/core/tests/suite/user_notification.rs @@ -64,7 +64,7 @@ mv "${tmp_path}" "${payload_path}""#, }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/window_headers.rs b/codex-rs/core/tests/suite/window_headers.rs index f823d9db7e65..76fcacf7a99e 100644 --- a/codex-rs/core/tests/suite/window_headers.rs +++ b/codex-rs/core/tests/suite/window_headers.rs @@ -112,7 +112,7 @@ async fn submit_user_turn(codex: &Arc, text: &str) -> Result<()> { }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await?; wait_for_event(codex, |event| matches!(event, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/mcp-server/src/codex_tool_runner.rs b/codex-rs/mcp-server/src/codex_tool_runner.rs index a38fbf6b55c2..1898bebeeb54 100644 --- a/codex-rs/mcp-server/src/codex_tool_runner.rs +++ b/codex-rs/mcp-server/src/codex_tool_runner.rs @@ -116,7 +116,7 @@ pub async fn run_codex_tool_session( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }, trace: None, }; @@ -166,7 +166,7 @@ pub async fn run_codex_tool_session_reply( }], final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await { diff --git a/codex-rs/memories/write/src/runtime.rs b/codex-rs/memories/write/src/runtime.rs index 0bd301709b07..b1ffb2d215f7 100644 --- a/codex-rs/memories/write/src/runtime.rs +++ b/codex-rs/memories/write/src/runtime.rs @@ -261,7 +261,7 @@ impl MemoryStartupContext { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await { diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index a067ff699873..42e327093495 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -396,9 +396,9 @@ pub struct ConversationTextParams { pub text: String, } -/// Persistent turn-context overrides that can be applied before user input. +/// Persistent thread-settings overrides that can be applied before user input. #[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, JsonSchema)] -pub struct TurnContextOverrides { +pub struct ThreadSettingsOverrides { /// Updated `cwd` for sandbox/tool calls. #[serde(skip_serializing_if = "Option::is_none")] pub cwd: Option, @@ -499,7 +499,7 @@ pub enum Op { /// Request the list of voices supported by realtime conversation streams. RealtimeConversationListVoices, - /// User input, optionally with turn-context overrides applied first. + /// User input, optionally with thread-settings overrides applied first. UserInput { /// User input items, see `InputItem` items: Vec, @@ -513,12 +513,12 @@ pub enum Op { #[serde(default, skip_serializing_if = "Option::is_none")] responsesapi_client_metadata: Option>, - /// Persistent turn-context overrides to apply before the input. + /// Persistent thread-settings overrides to apply before the input. #[serde(default, flatten)] - turn_context: TurnContextOverrides, + thread_settings: ThreadSettingsOverrides, }, - /// Similar to [`Op::UserInput`], but first applies persistent turn-context + /// Similar to [`Op::UserInput`], but first applies persistent thread-settings /// overrides in the same queued operation. This preserves submission order /// and prevents the input from starting if the overrides are rejected. UserInputWithTurnContext { @@ -681,11 +681,11 @@ pub enum Op { communication: InterAgentCommunication, }, - /// Override parts of the persistent turn context for subsequent turns. + /// Override parts of the persistent thread settings 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, + /// turns that rely on persistent session-level settings (for example, /// [`Op::UserInput`]). OverrideTurnContext { /// Updated `cwd` for sandbox/tool calls. @@ -865,7 +865,7 @@ impl From> for Op { items: value, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: TurnContextOverrides::default(), + thread_settings: ThreadSettingsOverrides::default(), } } } @@ -5108,7 +5108,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5128,7 +5128,7 @@ mod tests { items: Vec::new(), final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), } ); @@ -5150,7 +5150,7 @@ mod tests { items: Vec::new(), final_output_json_schema: Some(schema.clone()), responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }; let json_op = serde_json::to_value(op)?; @@ -5176,7 +5176,7 @@ mod tests { "fiber_run_id".to_string(), "fiber-123".to_string(), )])), - turn_context: Default::default(), + thread_settings: Default::default(), }; let json_op = serde_json::to_value(&op)?; diff --git a/codex-rs/thread-manager-sample/src/main.rs b/codex-rs/thread-manager-sample/src/main.rs index 14564de778fd..8593b8a477cb 100644 --- a/codex-rs/thread-manager-sample/src/main.rs +++ b/codex-rs/thread-manager-sample/src/main.rs @@ -293,7 +293,7 @@ async fn run_turn(thread: &CodexThread, thread_id: &str, prompt: String) -> anyh environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: Default::default(), + thread_settings: Default::default(), }) .await .context("submit user input")?; From 9ad7f64d9d9f760a15aab4779433c33128c7abd8 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 16:06:51 -0700 Subject: [PATCH 09/15] Clarify thread settings model updates --- codex-rs/core/src/session/handlers.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 066ddbe2f2eb..3cacd168a7c9 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -307,6 +307,8 @@ async fn thread_settings_update( collaboration_mode } else { let state = sess.state.lock().await; + // Model and reasoning effort live in CollaborationMode settings today, so + // partial thread-settings updates refresh those fields on the active mode. state .session_configuration .collaboration_mode From 2836662ea4138d5b0ed13a01b2ee9e25192a1c7d Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 16:17:01 -0700 Subject: [PATCH 10/15] Fix thread settings field rename --- codex-rs/core/src/guardian/review_session.rs | 2 +- codex-rs/core/src/session/tests.rs | 2 +- codex-rs/core/tests/common/test_codex.rs | 2 +- codex-rs/core/tests/suite/apply_patch_cli.rs | 2 +- codex-rs/core/tests/suite/approvals.rs | 4 ++-- codex-rs/core/tests/suite/client.rs | 4 ++-- codex-rs/core/tests/suite/code_mode.rs | 2 +- .../core/tests/suite/collaboration_instructions.rs | 6 +++--- codex-rs/core/tests/suite/compact.rs | 2 +- codex-rs/core/tests/suite/exec_policy.rs | 4 ++-- codex-rs/core/tests/suite/image_rollout.rs | 4 ++-- codex-rs/core/tests/suite/items.rs | 2 +- codex-rs/core/tests/suite/json_result.rs | 2 +- codex-rs/core/tests/suite/mcp_turn_metadata.rs | 2 +- codex-rs/core/tests/suite/model_switching.rs | 2 +- codex-rs/core/tests/suite/model_visible_layout.rs | 10 +++++----- codex-rs/core/tests/suite/models_cache_ttl.rs | 2 +- codex-rs/core/tests/suite/models_etag_responses.rs | 2 +- codex-rs/core/tests/suite/pending_input.rs | 2 +- codex-rs/core/tests/suite/personality.rs | 2 +- codex-rs/core/tests/suite/prompt_caching.rs | 10 +++++----- codex-rs/core/tests/suite/remote_env.rs | 2 +- codex-rs/core/tests/suite/remote_models.rs | 14 +++++++------- codex-rs/core/tests/suite/request_permissions.rs | 2 +- .../core/tests/suite/request_permissions_tool.rs | 2 +- codex-rs/core/tests/suite/request_user_input.rs | 6 +++--- .../tests/suite/responses_api_proxy_headers.rs | 2 +- codex-rs/core/tests/suite/rmcp_client.rs | 2 +- .../core/tests/suite/safety_check_downgrade.rs | 2 +- codex-rs/core/tests/suite/shell_snapshot.rs | 8 ++++---- codex-rs/core/tests/suite/skill_approval.rs | 2 +- codex-rs/core/tests/suite/skills.rs | 2 +- codex-rs/core/tests/suite/sqlite_state.rs | 2 +- codex-rs/core/tests/suite/tool_harness.rs | 10 +++++----- codex-rs/core/tests/suite/tool_parallelism.rs | 4 ++-- codex-rs/core/tests/suite/truncation.rs | 2 +- codex-rs/core/tests/suite/unified_exec.rs | 14 +++++++------- codex-rs/core/tests/suite/user_shell_cmd.rs | 2 +- codex-rs/core/tests/suite/view_image.rs | 2 +- codex-rs/core/tests/suite/websocket_fallback.rs | 2 +- 40 files changed, 76 insertions(+), 76 deletions(-) diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index 4527aa27fa47..389373c8deb8 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -711,7 +711,7 @@ async fn run_review_on_session( environments: None, final_output_json_schema: Some(params.schema.clone()), responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { #[allow(deprecated)] cwd: Some(params.parent_turn.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index 823459fe4ba7..84d5b557faf8 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -5253,7 +5253,7 @@ async fn user_turn_updates_approvals_reviewer() { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(config.cwd.to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index 21815694fb98..559dfb07a0e9 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -769,7 +769,7 @@ impl TestCodex { environments, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(self.config.cwd.to_path_buf()), approval_policy: Some(approval_policy), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index 7715ec595ceb..24fa3cea59e0 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -92,7 +92,7 @@ async fn submit_without_wait_with_turn_permissions( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(harness.cwd().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index b4c71e922a90..f08262eb6f4b 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -652,7 +652,7 @@ async fn submit_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), approvals_reviewer: Some(ApprovalsReviewer::User), @@ -2591,7 +2591,7 @@ async fn matched_prefix_rule_runs_unsandboxed_under_zsh_fork() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), approvals_reviewer: Some(ApprovalsReviewer::User), diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index a87f78ed1714..f6731a0ea4fa 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1778,7 +1778,7 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(config.cwd.to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -1899,7 +1899,7 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(config.cwd.to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index 61f99c50c34a..0c92767cd020 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -2596,7 +2596,7 @@ text( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 6535d679242b..bd01dc4e7d95 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -186,7 +186,7 @@ async fn collaboration_instructions_added_on_user_turn() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), sandbox_policy: Some(test.config.legacy_sandbox_policy()), @@ -236,7 +236,7 @@ async fn collaboration_instructions_omitted_when_disabled() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), sandbox_policy: Some(test.config.legacy_sandbox_policy()), @@ -359,7 +359,7 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(test.config.permissions.approval_policy.value()), sandbox_policy: Some(test.config.legacy_sandbox_policy()), diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index a9c566ff9548..2c789a271de0 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -96,7 +96,7 @@ fn disabled_permission_user_turn(text: impl Into, cwd: PathBuf, model: S environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index cf90e275e4d7..f1e01c22ce7b 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -54,7 +54,7 @@ async fn submit_user_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), sandbox_policy: Some(sandbox_policy), @@ -141,7 +141,7 @@ async fn execpolicy_blocks_shell_invocation() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index c763c7b94da2..085ca96f3770 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -127,7 +127,7 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -223,7 +223,7 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 28ba41e83d93..82e01e245183 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -58,7 +58,7 @@ fn disabled_plan_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index 6f932873860a..e81d7aa82a1b 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -83,7 +83,7 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { environments: None, final_output_json_schema: Some(serde_json::from_str(SCHEMA)?), responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index df3ac8259b4d..16e6cbe37de3 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -76,7 +76,7 @@ async fn submit_user_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index f81924d95854..1c9358a8a33f 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -47,7 +47,7 @@ fn read_only_user_turn(test: &TestCodex, items: Vec, model: String) - environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 905ef64313c7..9cf83424c9c8 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -125,7 +125,7 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(first_turn_cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(first_sandbox_policy), @@ -160,7 +160,7 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(preturn_context_diff_cwd), approval_policy: Some(AskForApproval::OnRequest), sandbox_policy: Some(second_sandbox_policy), @@ -249,7 +249,7 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_one.clone()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(first_sandbox_policy), @@ -282,7 +282,7 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_two), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(second_sandbox_policy), @@ -406,7 +406,7 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(resume_override_cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 7cf1d52e62a0..3b729738df38 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -100,7 +100,7 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(codex_protocol::protocol::AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index ece66cc496a7..49f34d8644cd 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -112,7 +112,7 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index 1702d7b2cb36..b057b86171be 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -121,7 +121,7 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index d491a2860e68..8924ca2a25d3 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -68,7 +68,7 @@ fn read_only_text_turn_with_personality( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 54a59f817999..fa49f5e6cfaa 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -734,7 +734,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(new_cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -854,7 +854,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), sandbox_policy: Some(default_sandbox_policy.clone()), @@ -882,7 +882,7 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), sandbox_policy: Some(default_sandbox_policy.clone()), @@ -993,7 +993,7 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(default_approval_policy), sandbox_policy: Some(default_sandbox_policy.clone()), @@ -1023,7 +1023,7 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(default_cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index 37f381946bd7..873796ff6ced 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -75,7 +75,7 @@ async fn submit_turn_with_approval_and_environments( environments: Some(environments), final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::OnRequest), approvals_reviewer: Some(ApprovalsReviewer::User), diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index 2ae573f43f19..a5ddd7f6ff16 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -162,7 +162,7 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -244,7 +244,7 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -325,7 +325,7 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -419,7 +419,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -484,7 +484,7 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(config.permissions.approval_policy.value()), sandbox_policy: Some(config.legacy_sandbox_policy()), @@ -662,7 +662,7 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -900,7 +900,7 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index a7f475940b74..90e28c8a0ca9 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -196,7 +196,7 @@ async fn submit_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), approvals_reviewer: Some(ApprovalsReviewer::User), diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index 2b4789013515..84e101e73ae0 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -150,7 +150,7 @@ async fn submit_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(approval_policy), approvals_reviewer, diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 91a8cd16f9ee..e0ec684797de 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -144,7 +144,7 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -287,7 +287,7 @@ async fn request_user_input_interrupt_emits_deferred_token_count() -> anyhow::Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -391,7 +391,7 @@ where environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs index 9f5b649dad59..f396a825a125 100644 --- a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs +++ b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs @@ -138,7 +138,7 @@ async fn submit_turn_with_timeout(test: &TestCodex, prompt: &str) -> Result<()> environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::OnRequest), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 56b00d0c8774..7c811a88e042 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -113,7 +113,7 @@ fn read_only_user_turn_with_model( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/safety_check_downgrade.rs b/codex-rs/core/tests/suite/safety_check_downgrade.rs index db782654a002..ab985ce0f798 100644 --- a/codex-rs/core/tests/suite/safety_check_downgrade.rs +++ b/codex-rs/core/tests/suite/safety_check_downgrade.rs @@ -45,7 +45,7 @@ fn disabled_text_turn(test: &TestCodex, text: &str) -> Op { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index 17b29ca33193..14241ffafb6f 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -167,7 +167,7 @@ async fn run_snapshot_command_with_options( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -267,7 +267,7 @@ async fn run_shell_command_snapshot_with_options( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -347,7 +347,7 @@ async fn run_tool_turn_on_harness( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -590,7 +590,7 @@ async fn shell_command_snapshot_still_intercepts_apply_patch() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.clone()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/skill_approval.rs b/codex-rs/core/tests/suite/skill_approval.rs index 66747a1f05e1..ad8ad6a91a57 100644 --- a/codex-rs/core/tests/suite/skill_approval.rs +++ b/codex-rs/core/tests/suite/skill_approval.rs @@ -54,7 +54,7 @@ async fn submit_turn_with_policies( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd_path().to_path_buf()), approval_policy: Some(approval_policy), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index e984ecd9a69b..9173f60c4a7a 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -88,7 +88,7 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index 932fce8377ef..f576e55a3d02 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -413,7 +413,7 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result< environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index fe543efff9f7..2227e5b34e1e 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -110,7 +110,7 @@ async fn shell_command_tool_executes_command_and_streams_output() -> anyhow::Res environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -191,7 +191,7 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -282,7 +282,7 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -383,7 +383,7 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<() environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -521,7 +521,7 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd_path), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index 6d3c85caf242..6663991e0203 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -45,7 +45,7 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -371,7 +371,7 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index 75352f9ebf4c..be9267934d61 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -523,7 +523,7 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(fixture.cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index f619c24ed480..077d8dcf0899 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -198,7 +198,7 @@ async fn submit_unified_exec_turn( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), @@ -286,7 +286,7 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(SandboxPolicy::DangerFullAccess), @@ -2132,7 +2132,7 @@ async fn unified_exec_keeps_long_running_session_after_turn_end() -> Result<()> environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(SandboxPolicy::DangerFullAccess), @@ -2231,7 +2231,7 @@ async fn unified_exec_interrupt_preserves_long_running_session() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(SandboxPolicy::DangerFullAccess), @@ -2709,7 +2709,7 @@ async fn unified_exec_runs_under_sandbox() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), @@ -2828,7 +2828,7 @@ async fn unified_exec_enforces_glob_deny_read_policy() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(read_only_policy), @@ -2962,7 +2962,7 @@ async fn unified_exec_python_prompt_under_seatbelt() -> Result<()> { environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index 0d4eed826c07..536ee7b49593 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -182,7 +182,7 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index 688450cb6c90..e631e537c62e 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -77,7 +77,7 @@ fn disabled_user_turn(test: &TestCodex, items: Vec, model: String) -> environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(test.config.cwd.to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index 843e3b2e6045..32a6e30caff3 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -160,7 +160,7 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - turn_context: codex_protocol::protocol::TurnContextOverrides { + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { cwd: Some(cwd.path().to_path_buf()), approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), From 4939645c4468b4d6c6699a0cdce3852399aa1a25 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 16:30:08 -0700 Subject: [PATCH 11/15] Simplify thread settings test overrides --- codex-rs/core/tests/suite/prompt_caching.rs | 10 +- codex-rs/core/tests/suite/remote_models.rs | 116 ++------------------ 2 files changed, 12 insertions(+), 114 deletions(-) diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index fa49f5e6cfaa..79023ee8780f 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -739,15 +739,9 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res approval_policy: Some(AskForApproval::Never), sandbox_policy: Some(sandbox_policy), permission_profile, + model: Some("o3".to_string()), + effort: Some(Some(ReasoningEffort::High)), summary: Some(ReasoningSummary::Detailed), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: "o3".to_string(), - reasoning_effort: Some(ReasoningEffort::High), - developer_instructions: None, - }, - }), ..Default::default() }, }) diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index a5ddd7f6ff16..adc73d8a793a 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -142,9 +142,7 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -162,20 +160,7 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { - cwd: Some(cwd.path().to_path_buf()), - approval_policy: Some(config.permissions.approval_policy.value()), - sandbox_policy: Some(config.legacy_sandbox_policy()), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: requested_model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - ..Default::default() - }, + thread_settings: Default::default(), }) .await?; @@ -224,9 +209,7 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -244,20 +227,7 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { - cwd: Some(cwd.path().to_path_buf()), - approval_policy: Some(config.permissions.approval_policy.value()), - sandbox_policy: Some(config.legacy_sandbox_policy()), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: requested_model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - ..Default::default() - }, + thread_settings: Default::default(), }) .await?; @@ -306,9 +276,7 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -325,20 +293,7 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { - cwd: Some(cwd.path().to_path_buf()), - approval_policy: Some(config.permissions.approval_policy.value()), - sandbox_policy: Some(config.legacy_sandbox_policy()), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: requested_model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - ..Default::default() - }, + thread_settings: Default::default(), }) .await?; @@ -400,9 +355,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -419,20 +372,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { - cwd: Some(cwd.path().to_path_buf()), - approval_policy: Some(config.permissions.approval_policy.value()), - sandbox_policy: Some(config.legacy_sandbox_policy()), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: requested_model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - ..Default::default() - }, + thread_settings: Default::default(), }) .await?; @@ -468,9 +408,7 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_model(requested_model) .build(&server) .await?; @@ -484,25 +422,7 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() environments: None, final_output_json_schema: None, responsesapi_client_metadata: None, - thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { - cwd: Some(cwd.path().to_path_buf()), - approval_policy: Some(config.permissions.approval_policy.value()), - sandbox_policy: Some(config.legacy_sandbox_policy()), - summary: Some( - config - .model_reasoning_summary - .unwrap_or(ReasoningSummary::Auto), - ), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: requested_model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - ..Default::default() - }, + thread_settings: Default::default(), }) .await?; @@ -668,14 +588,6 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Auto), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: REMOTE_MODEL_SLUG.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), ..Default::default() }, }) @@ -906,14 +818,6 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { sandbox_policy: Some(sandbox_policy), permission_profile, summary: Some(ReasoningSummary::Auto), - collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { - mode: codex_protocol::config_types::ModeKind::Default, - settings: codex_protocol::config_types::Settings { - model: model.to_string(), - reasoning_effort: None, - developer_instructions: None, - }, - }), ..Default::default() }, }) From d58faa2abe639c48226ff1a1dcf9eeb3cc7470d5 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 16:45:25 -0700 Subject: [PATCH 12/15] Keep thread settings stack placeholder From e3fe02900030913a2ec255f526232d5c39eea0e8 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 14:20:00 -0700 Subject: [PATCH 13/15] Remove UserInputWithTurnContext op --- .../src/request_processors/turn_processor.rs | 26 +++--- codex-rs/core/src/session/handlers.rs | 50 +---------- codex-rs/core/src/session/tests.rs | 25 ------ codex-rs/protocol/src/protocol.rs | 90 ------------------- 4 files changed, 13 insertions(+), 178 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 3de4ebbcc320..90c77c645e63 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -502,13 +502,8 @@ impl TurnRequestProcessor { })?; } - // Start the turn by submitting the user input. Return its submission id as turn_id. - let turn_op = if has_any_overrides { - Op::UserInputWithTurnContext { - items: mapped_items, - environments: environment_selections, - final_output_json_schema: params.output_schema, - responsesapi_client_metadata: params.responsesapi_client_metadata, + let thread_settings = if has_any_overrides { + codex_protocol::protocol::ThreadSettingsOverrides { cwd, workspace_roots: runtime_workspace_roots, profile_workspace_roots, @@ -526,13 +521,16 @@ impl TurnRequestProcessor { personality, } } else { - Op::UserInput { - items: mapped_items, - environments: environment_selections, - final_output_json_schema: params.output_schema, - responsesapi_client_metadata: params.responsesapi_client_metadata, - thread_settings: Default::default(), - } + Default::default() + }; + + // Start the turn by submitting the user input. Return its submission id as turn_id. + let turn_op = Op::UserInput { + items: mapped_items, + environments: environment_selections, + final_output_json_schema: params.output_schema, + responsesapi_client_metadata: params.responsesapi_client_metadata, + thread_settings, }; let turn_id = self .submit_core_op(&request_id, thread.as_ref(), turn_op) diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index e684ae6f3b2e..f8a4fa29201c 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -164,52 +164,6 @@ pub(super) async fn user_input_or_turn_inner( None, ) } - Op::UserInputWithTurnContext { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - model, - effort, - summary, - service_tier, - final_output_json_schema, - items, - responsesapi_client_metadata, - collaboration_mode, - personality, - environments, - } => { - let mut updates = thread_settings_update( - sess, - ThreadSettingsOverrides { - cwd, - workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level, - model, - effort, - summary, - service_tier, - collaboration_mode, - personality, - }, - ) - .await; - updates.final_output_json_schema = Some(final_output_json_schema); - updates.environments = environments; - (items, updates, responsesapi_client_metadata) - } Op::UserInput { items, environments, @@ -872,9 +826,7 @@ pub(super) async fn submission_loop( .await; false } - Op::UserInput { .. } - | Op::UserInputWithTurnContext { .. } - | Op::UserTurn { .. } => { + Op::UserInput { .. } | Op::UserTurn { .. } => { 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 46e93b16f46c..a6d82e211d8e 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -5227,31 +5227,6 @@ fn op_kind_distinguishes_turn_ops() { .kind(), "user_input" ); - assert_eq!( - Op::UserInputWithTurnContext { - environments: None, - items: vec![], - final_output_json_schema: None, - responsesapi_client_metadata: None, - cwd: None, - workspace_roots: None, - profile_workspace_roots: 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, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, - } - .kind(), - "user_input_with_turn_context" - ); } #[tokio::test] diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index cd9078a85c11..77d862086ca8 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -518,95 +518,6 @@ pub enum Op { thread_settings: ThreadSettingsOverrides, }, - /// Similar to [`Op::UserInput`], but first applies persistent thread-settings - /// overrides in the same queued operation. This preserves submission order - /// and prevents the input from starting if the overrides are rejected. - UserInputWithTurnContext { - /// User input items, see `InputItem` - items: Vec, - /// Optional turn-scoped environment selections. - #[serde(default, skip_serializing_if = "Option::is_none")] - environments: Option>, - /// Optional JSON Schema used to constrain the final assistant message for this turn. - #[serde(skip_serializing_if = "Option::is_none")] - final_output_json_schema: Option, - /// Optional turn-scoped Responses API `client_metadata`. - #[serde(default, skip_serializing_if = "Option::is_none")] - responsesapi_client_metadata: Option>, - - /// Updated `cwd` for sandbox/tool calls. - #[serde(skip_serializing_if = "Option::is_none")] - cwd: Option, - - /// Updated runtime workspace roots used to materialize symbolic - /// `:workspace_roots` filesystem permissions. - #[serde(skip_serializing_if = "Option::is_none")] - workspace_roots: Option>, - - /// Updated profile-defined workspace roots for status summaries and - /// per-turn config reconstruction. - #[serde(skip_serializing_if = "Option::is_none")] - profile_workspace_roots: 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, - - /// Named or built-in profile that produced `permission_profile`, if - /// the update selected a profile rather than supplying raw - /// permissions. - #[serde(skip_serializing_if = "Option::is_none")] - active_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, - }, - /// Similar to [`Op::UserInput`], but contains additional context required /// for a turn of a [`crate::codex_thread::CodexThread`]. UserTurn { @@ -932,7 +843,6 @@ impl Op { Self::RealtimeConversationClose => "realtime_conversation_close", Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", Self::UserInput { .. } => "user_input", - Self::UserInputWithTurnContext { .. } => "user_input_with_turn_context", Self::UserTurn { .. } => "user_turn", Self::InterAgentCommunication { .. } => "inter_agent_communication", Self::OverrideTurnContext { .. } => "override_turn_context", From 6927359c0cb39ca79108af5ede6e548a8ae319f4 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Sat, 16 May 2026 17:42:10 -0700 Subject: [PATCH 14/15] Simplify turn start context overrides --- .../src/request_processors/turn_processor.rs | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/codex-rs/app-server/src/request_processors/turn_processor.rs b/codex-rs/app-server/src/request_processors/turn_processor.rs index 90c77c645e63..d383f64d4e0a 100644 --- a/codex-rs/app-server/src/request_processors/turn_processor.rs +++ b/codex-rs/app-server/src/request_processors/turn_processor.rs @@ -502,26 +502,22 @@ impl TurnRequestProcessor { })?; } - let thread_settings = if has_any_overrides { - codex_protocol::protocol::ThreadSettingsOverrides { - cwd, - workspace_roots: runtime_workspace_roots, - profile_workspace_roots, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - active_permission_profile, - windows_sandbox_level: None, - model, - effort, - summary, - service_tier, - collaboration_mode, - personality, - } - } else { - Default::default() + let thread_settings = codex_protocol::protocol::ThreadSettingsOverrides { + cwd, + workspace_roots: runtime_workspace_roots, + profile_workspace_roots, + approval_policy, + approvals_reviewer, + sandbox_policy, + permission_profile, + active_permission_profile, + windows_sandbox_level: None, + model, + effort, + summary, + service_tier, + collaboration_mode, + personality, }; // Start the turn by submitting the user input. Return its submission id as turn_id. From e940365cc802823a41e1a95714ad9053ede97a5d Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Mon, 18 May 2026 19:43:44 -0700 Subject: [PATCH 15/15] Remove UserTurn op --- codex-rs/core/src/guardian/review_session.rs | 35 +-- codex-rs/core/src/session/handlers.rs | 55 +---- codex-rs/core/src/session/tests.rs | 35 +-- codex-rs/core/tests/common/test_codex.rs | 42 ++-- codex-rs/core/tests/suite/apply_patch_cli.rs | 31 +-- codex-rs/core/tests/suite/approvals.rs | 63 ++--- codex-rs/core/tests/suite/client.rs | 70 +++--- codex-rs/core/tests/suite/code_mode.rs | 31 +-- .../tests/suite/collaboration_instructions.rs | 96 ++++---- codex-rs/core/tests/suite/compact.rs | 31 +-- codex-rs/core/tests/suite/exec_policy.rs | 64 ++--- codex-rs/core/tests/suite/image_rollout.rs | 62 ++--- codex-rs/core/tests/suite/items.rs | 26 +-- codex-rs/core/tests/suite/json_result.rs | 31 +-- .../core/tests/suite/mcp_turn_metadata.rs | 34 +-- codex-rs/core/tests/suite/model_switching.rs | 31 +-- .../core/tests/suite/model_visible_layout.rs | 157 +++++++------ codex-rs/core/tests/suite/models_cache_ttl.rs | 31 +-- .../core/tests/suite/models_etag_responses.rs | 31 +-- codex-rs/core/tests/suite/pending_input.rs | 31 +-- codex-rs/core/tests/suite/personality.rs | 32 +-- codex-rs/core/tests/suite/prompt_caching.rs | 153 ++++++------ codex-rs/core/tests/suite/remote_env.rs | 31 +-- codex-rs/core/tests/suite/remote_models.rs | 157 ++++--------- .../core/tests/suite/request_permissions.rs | 32 +-- .../tests/suite/request_permissions_tool.rs | 32 +-- .../core/tests/suite/request_user_input.rs | 101 ++++---- .../suite/responses_api_proxy_headers.rs | 31 +-- codex-rs/core/tests/suite/rmcp_client.rs | 31 +-- .../tests/suite/safety_check_downgrade.rs | 31 +-- codex-rs/core/tests/suite/shell_snapshot.rs | 124 +++++----- codex-rs/core/tests/suite/skill_approval.rs | 31 +-- codex-rs/core/tests/suite/skills.rs | 31 +-- codex-rs/core/tests/suite/sqlite_state.rs | 31 +-- codex-rs/core/tests/suite/tool_harness.rs | 155 +++++++------ codex-rs/core/tests/suite/tool_parallelism.rs | 62 ++--- codex-rs/core/tests/suite/truncation.rs | 31 +-- codex-rs/core/tests/suite/unified_exec.rs | 218 ++++++++++-------- codex-rs/core/tests/suite/user_shell_cmd.rs | 31 +-- codex-rs/core/tests/suite/view_image.rs | 31 +-- .../core/tests/suite/websocket_fallback.rs | 31 +-- codex-rs/protocol/src/protocol.rs | 69 ------ 42 files changed, 1289 insertions(+), 1174 deletions(-) diff --git a/codex-rs/core/src/guardian/review_session.rs b/codex-rs/core/src/guardian/review_session.rs index afb5882a69bc..389373c8deb8 100644 --- a/codex-rs/core/src/guardian/review_session.rs +++ b/codex-rs/core/src/guardian/review_session.rs @@ -706,22 +706,29 @@ async fn run_review_on_session( let submit_result = run_before_review_deadline( deadline, params.external_cancel.as_ref(), - Box::pin(review_session.codex.submit(Op::UserTurn { - environments: None, + Box::pin(review_session.codex.submit(Op::UserInput { items: prompt_items.items, - #[allow(deprecated)] - cwd: params.parent_turn.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: legacy_sandbox_policy, - permission_profile: Some(guardian_permission_profile), - model: params.model.clone(), - effort: params.reasoning_effort, - summary: Some(params.reasoning_summary), - service_tier: None, + environments: None, final_output_json_schema: Some(params.schema.clone()), - collaboration_mode: None, - personality: params.personality, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + #[allow(deprecated)] + cwd: Some(params.parent_turn.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(legacy_sandbox_policy), + permission_profile: Some(guardian_permission_profile), + summary: Some(params.reasoning_summary), + personality: params.personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: params.model.clone(), + reasoning_effort: params.reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, })), ) .await; diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index f8a4fa29201c..e01ee28f99b1 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -49,9 +49,6 @@ use codex_protocol::request_permissions::RequestPermissionsResponse; use codex_protocol::request_user_input::RequestUserInputResponse; use crate::context_manager::is_user_turn_boundary; -use codex_protocol::config_types::CollaborationMode; -use codex_protocol::config_types::ModeKind; -use codex_protocol::config_types::Settings; use codex_protocol::dynamic_tools::DynamicToolResponse; use codex_protocol::items::UserMessageItem; use codex_protocol::mcp::RequestId as ProtocolRequestId; @@ -114,56 +111,6 @@ pub(super) async fn user_input_or_turn_inner( mirror_user_text_to_realtime: Option<()>, ) { let (items, updates, responsesapi_client_metadata) = match op { - Op::UserTurn { - cwd, - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - model, - effort, - summary, - service_tier, - final_output_json_schema, - items, - collaboration_mode, - personality, - environments, - } => { - let collaboration_mode = collaboration_mode.or_else(|| { - Some(CollaborationMode { - mode: ModeKind::Default, - settings: Settings { - model: model.clone(), - reasoning_effort: effort, - developer_instructions: None, - }, - }) - }); - ( - items, - SessionSettingsUpdate { - cwd: Some(cwd), - approval_policy: Some(approval_policy), - approvals_reviewer, - sandbox_policy: Some(sandbox_policy), - workspace_roots: None, - profile_workspace_roots: None, - permission_profile, - active_permission_profile: None, - windows_sandbox_level: None, - collaboration_mode, - reasoning_summary: summary, - service_tier, - final_output_json_schema: Some(final_output_json_schema), - environments, - personality, - app_server_client_name: None, - app_server_client_version: None, - }, - None, - ) - } Op::UserInput { items, environments, @@ -826,7 +773,7 @@ pub(super) async fn submission_loop( .await; false } - Op::UserInput { .. } | Op::UserTurn { .. } => { + 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 a6d82e211d8e..4f090a8a3aa5 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -5197,7 +5197,7 @@ fn submission_dispatch_span_uses_debug_for_realtime_audio() { } #[test] -fn op_kind_distinguishes_turn_ops() { +fn op_kind_for_input_and_context_ops() { assert_eq!( Op::OverrideTurnContext { cwd: None, @@ -5237,24 +5237,31 @@ async fn user_turn_updates_approvals_reviewer() { handlers::user_input_or_turn( &session, "sub-1".to_string(), - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: "hello".to_string(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: turn_context.model_info.slug.clone(), - effort: config.model_reasoning_effort, - summary: config.model_reasoning_summary, - service_tier: None, + environments: None, final_output_json_schema: None, - collaboration_mode: None, - personality: config.personality, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + approvals_reviewer: Some(codex_config::types::ApprovalsReviewer::AutoReview), + sandbox_policy: Some(config.legacy_sandbox_policy()), + summary: config.model_reasoning_summary, + personality: config.personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: turn_context.model_info.slug.clone(), + reasoning_effort: config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }, ) .await; diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index 2007104868e9..a1ba7b8fb2ce 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -190,8 +190,14 @@ pub enum ApplyPatchModelOutput { ShellCommandViaHeredoc, } -/// Returns the permission fields required by `Op::UserTurn` for tests that -/// construct the op directly. +/// A collection of different ways the model can output an apply_patch call +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum ShellModelOutput { + ShellCommand, + // UnifiedExec has its own set of tests +} + +/// Returns the permission fields required by test thread-settings overrides. pub fn turn_permission_fields( permission_profile: PermissionProfile, cwd: &Path, @@ -754,24 +760,30 @@ impl TestCodex { turn_permission_fields(permission_profile, self.config.cwd.as_path()); let session_model = self.session_configured.model.clone(); self.codex - .submit(Op::UserTurn { - environments, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments, final_output_json_schema: None, - cwd: self.config.cwd.to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(self.config.cwd.to_path_buf()), + approval_policy: Some(approval_policy), + sandbox_policy: Some(sandbox_policy), + permission_profile, + service_tier, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index 05379517e5e4..1e325e1bb532 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -83,24 +83,29 @@ async fn submit_without_wait_with_turn_permissions( let test = harness.test(); let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: harness.cwd().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(harness.cwd().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index 5045755e3225..f08262eb6f4b 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -644,24 +644,29 @@ async fn submit_turn( let session_model = test.session_configured.model.clone(); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile: None, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2578,24 +2583,30 @@ async fn matched_prefix_rule_runs_unsandboxed_under_zsh_fork() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run allowed touch under zsh fork".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 818e0eba7bdb..f6731a0ea4fa 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -1758,12 +1758,7 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re sse(vec![ev_response_created("resp1"), ev_completed("resp1")]), ) .await; - let TestCodex { - codex, - config, - session_configured, - .. - } = test_codex().with_model("gpt-5.4").build(&server).await?; + let TestCodex { codex, config, .. } = test_codex().with_model("gpt-5.4").build(&server).await?; let collaboration_mode = CollaborationMode { mode: ModeKind::Default, @@ -1775,28 +1770,26 @@ async fn user_turn_collaboration_mode_overrides_model_and_effort() -> anyhow::Re }; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: session_configured.model.clone(), - effort: Some(ReasoningEffort::Low), - summary: Some( - config - .model_reasoning_summary - .unwrap_or(ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + sandbox_policy: Some(config.legacy_sandbox_policy()), + summary: Some( + config + .model_reasoning_summary + .unwrap_or(ReasoningSummary::Auto), + ), + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; @@ -1898,24 +1891,29 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() .await?; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: config.cwd.to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: session_configured.model, - effort: None, - summary: Some(ReasoningSummary::Concise), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(config.cwd.to_path_buf()), + approval_policy: Some(config.permissions.approval_policy.value()), + sandbox_policy: Some(config.legacy_sandbox_policy()), + summary: Some(ReasoningSummary::Concise), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_configured.model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await .unwrap(); diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index beae9e4afb23..19373b52e47c 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -2584,24 +2584,29 @@ text( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "use exec to inspect and call hidden tools".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/collaboration_instructions.rs b/codex-rs/core/tests/suite/collaboration_instructions.rs index 2b0c20ab26ea..bd01dc4e7d95 100644 --- a/codex-rs/core/tests/suite/collaboration_instructions.rs +++ b/codex-rs/core/tests/suite/collaboration_instructions.rs @@ -178,28 +178,26 @@ async fn collaboration_instructions_added_on_user_turn() -> Result<()> { let collaboration_mode = collab_mode_with_instructions(Some(collab_text)); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -230,28 +228,26 @@ async fn collaboration_instructions_omitted_when_disabled() -> Result<()> { let collaboration_mode = collab_mode_with_instructions(Some("turn instructions")); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(collaboration_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -355,28 +351,26 @@ async fn user_turn_overrides_collaboration_instructions_after_override() -> Resu .await?; test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], - cwd: test.config.cwd.to_path_buf(), - approval_policy: test.config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: test.config.legacy_sandbox_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: Some( - test.config - .model_reasoning_summary - .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: Some(turn_mode), + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(test.config.permissions.approval_policy.value()), + sandbox_policy: Some(test.config.legacy_sandbox_policy()), + summary: Some( + test.config + .model_reasoning_summary + .unwrap_or(codex_protocol::config_types::ReasoningSummary::Auto), + ), + collaboration_mode: Some(turn_mode), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index d1384ff800fc..2c789a271de0 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -88,24 +88,29 @@ fn ev_shell_command_call(call_id: &str, command: &str) -> serde_json::Value { fn disabled_permission_user_turn(text: impl Into, cwd: PathBuf, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index 3f6c9cfdc08f..f1e01c22ce7b 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -46,24 +46,31 @@ async fn submit_user_turn( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: collaboration_mode.or({ + Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }) + }), + ..Default::default() + }, }) .await?; Ok(()) @@ -126,24 +133,29 @@ async fn execpolicy_blocks_shell_invocation() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run shell command".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 3404edbb1e9e..085ca96f3770 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -113,8 +113,7 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::LocalImage { path: abs_path.clone(), @@ -125,18 +124,24 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu text_elements: Vec::new(), }, ], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -204,8 +209,7 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::Image { image_url: image_url.clone(), @@ -216,18 +220,24 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> text_elements: Vec::new(), }, ], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/items.rs b/codex-rs/core/tests/suite/items.rs index 0015a418ca62..82e01e245183 100644 --- a/codex-rs/core/tests/suite/items.rs +++ b/codex-rs/core/tests/suite/items.rs @@ -44,30 +44,28 @@ use std::path::PathBuf; fn disabled_plan_turn( text: &str, - model: String, + _model: String, collaboration_mode: CollaborationMode, ) -> anyhow::Result { let cwd = std::env::current_dir()?; let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); - Ok(Op::UserTurn { - environments: None, + Ok(Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(collaboration_mode), - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) } diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index c4ce8ac90827..e81d7aa82a1b 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -75,24 +75,29 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { // 1) Normal user input – should hit server once. codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello world".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: Some(serde_json::from_str(SCHEMA)?), - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 17fe33dc8ba1..16e6cbe37de3 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -64,27 +64,35 @@ async fn submit_user_turn( approval_policy: AskForApproval, collaboration_mode: Option, ) -> Result<()> { + let session_model = test.session_configured.model.clone(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: collaboration_mode.or({ + Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }) + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index adce6e36ebb8..1c9358a8a33f 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -42,21 +42,26 @@ use wiremock::MockServer; fn read_only_user_turn(test: &TestCodex, items: Vec, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items, + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index d9c636b35f3d..9cf83424c9c8 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -117,24 +117,29 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { turn_permission_fields(PermissionProfile::read_only(), first_turn_cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "first turn".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: first_turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: first_sandbox_policy, - permission_profile: first_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(first_turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(first_sandbox_policy), + permission_profile: first_permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -147,24 +152,30 @@ async fn snapshot_model_visible_layout_turn_overrides() -> Result<()> { preturn_context_diff_cwd.as_path(), ); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "second turn with context updates".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: preturn_context_diff_cwd, - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: None, - sandbox_policy: second_sandbox_policy, - permission_profile: second_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: Some(Personality::Friendly), + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(preturn_context_diff_cwd), + approval_policy: Some(AskForApproval::OnRequest), + sandbox_policy: Some(second_sandbox_policy), + permission_profile: second_permission_profile, + personality: Some(Personality::Friendly), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -230,24 +241,29 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R turn_permission_fields(PermissionProfile::read_only(), cwd_one.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "first turn in agents_one".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_one.clone(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: first_sandbox_policy, - permission_profile: first_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_one.clone()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(first_sandbox_policy), + permission_profile: first_permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -258,24 +274,29 @@ async fn snapshot_model_visible_layout_cwd_change_does_not_refresh_agents() -> R let (second_sandbox_policy, second_permission_profile) = turn_permission_fields(PermissionProfile::read_only(), cwd_two.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "second turn in agents_two".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_two, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy: second_sandbox_policy, - permission_profile: second_permission_profile, - model: test.session_configured.model.clone(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_two), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(second_sandbox_policy), + permission_profile: second_permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { @@ -377,24 +398,30 @@ async fn snapshot_model_visible_layout_resume_with_personality_change() -> Resul ); resumed .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "resume and change personality".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: resume_override_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: resumed.session_configured.model.clone(), - effort: resumed.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: Some(Personality::Friendly), + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(resume_override_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + personality: Some(Personality::Friendly), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: resumed.session_configured.model.clone(), + reasoning_effort: resumed.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&resumed.codex, |event| { diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 8463ee1cf167..3b729738df38 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -92,24 +92,29 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { turn_permission_fields(PermissionProfile::Disabled, test.cwd_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hi".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: codex_protocol::protocol::AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(codex_protocol::protocol::AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/models_etag_responses.rs b/codex-rs/core/tests/suite/models_etag_responses.rs index 346c503c2579..49f34d8644cd 100644 --- a/codex-rs/core/tests/suite/models_etag_responses.rs +++ b/codex-rs/core/tests/suite/models_etag_responses.rs @@ -104,24 +104,29 @@ async fn refresh_models_on_models_etag_mismatch_and_avoid_duplicate_models_fetch .await; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please run a tool".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index d511c8f0b657..b057b86171be 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -113,24 +113,29 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await .unwrap_or_else(|err| panic!("submit user turn: {err}")); diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 09eb61fa69a9..8924ca2a25d3 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -60,24 +60,30 @@ fn read_only_text_turn_with_personality( ) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + sandbox_policy: Some(sandbox_policy), + permission_profile, + personality, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 2023778a1127..accf3fb789ef 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -714,7 +714,7 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; - // Second turn using per-turn overrides via UserTurn + // Second turn using per-turn thread-settings overrides. let new_cwd = TempDir::new().unwrap(); let writable = TempDir::new().unwrap(); let permission_profile = PermissionProfile::workspace_write_with( @@ -726,24 +726,24 @@ async fn per_turn_overrides_keep_cached_prefix_and_key_constant() -> anyhow::Res let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, new_cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: new_cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: "o3".to_string(), - effort: Some(ReasoningEffort::High), - summary: Some(ReasoningSummary::Detailed), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(new_cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + model: Some("o3".to_string()), + effort: Some(Some(ReasoningEffort::High)), + summary: Some(ReasoningSummary::Detailed), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -840,47 +840,57 @@ async fn send_user_turn_with_no_changes_does_not_send_environment_context() -> a let default_summary = config.model_reasoning_summary; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 1".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model.clone(), - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + sandbox_policy: Some(default_sandbox_policy.clone()), + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model.clone(), + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model.clone(), - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + sandbox_policy: Some(default_sandbox_policy.clone()), + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model.clone(), + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -969,24 +979,29 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu let default_summary = config.model_reasoning_summary; codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 1".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: default_approval_policy, - approvals_reviewer: None, - sandbox_policy: default_sandbox_policy.clone(), - permission_profile: None, - model: default_model, - effort: default_effort, - summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(default_approval_policy), + sandbox_policy: Some(default_sandbox_policy.clone()), + summary: Some(default_summary.unwrap_or(ReasoningSummary::Auto)), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: default_model, + reasoning_effort: default_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; @@ -994,24 +1009,30 @@ async fn send_user_turn_with_changes_sends_environment_context() -> anyhow::Resu let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, default_cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello 2".into(), text_elements: Vec::new(), }], - cwd: default_cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: "o3".to_string(), - effort: Some(ReasoningEffort::High), - summary: Some(ReasoningSummary::Detailed), - service_tier: None, - collaboration_mode: None, + environments: None, final_output_json_schema: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(default_cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Detailed), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: "o3".to_string(), + reasoning_effort: Some(ReasoningEffort::High), + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&codex, |ev| matches!(ev, EventMsg::TurnComplete(_))).await; diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index e19379ffc8c2..873796ff6ced 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -67,24 +67,29 @@ async fn submit_turn_with_approval_and_environments( environments: Vec, ) -> Result<()> { test.codex - .submit(Op::UserTurn { - environments: Some(environments), + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: Some(environments), final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy: SandboxPolicy::new_read_only_policy(), - permission_profile: None, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::OnRequest), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(SandboxPolicy::new_read_only_policy()), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index d1caf2483657..adc73d8a793a 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -142,9 +142,7 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -154,24 +152,15 @@ async fn remote_models_config_context_window_override_clamps_to_max_context_wind .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: Default::default(), }) .await?; @@ -220,9 +209,7 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -232,24 +219,15 @@ async fn remote_models_config_override_above_max_uses_max_context_window() -> Re .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: Default::default(), }) .await?; @@ -298,9 +276,7 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -309,24 +285,15 @@ async fn remote_models_use_context_window_when_config_override_is_absent() -> Re .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check context window".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - permission_profile: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: Default::default(), }) .await?; @@ -388,9 +355,7 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_auth(CodexAuth::create_dummy_chatgpt_auth_for_testing()) .with_config(|config| { config.model = Some(requested_model.to_string()); @@ -399,24 +364,15 @@ async fn remote_models_long_model_slug_is_sent_with_high_reasoning() -> Result<( .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check model slug".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: requested_model.to_string(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: Default::default(), }) .await?; @@ -452,36 +408,21 @@ async fn namespaced_model_slug_uses_catalog_metadata_without_fallback_warning() ) .await; - let TestCodex { - codex, cwd, config, .. - } = test_codex() + let TestCodex { codex, .. } = test_codex() .with_model(requested_model) .build(&server) .await?; codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "check namespaced model metadata".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: config.permissions.approval_policy.value(), - approvals_reviewer: None, - sandbox_policy: config.legacy_sandbox_policy(), - permission_profile: None, - model: requested_model.to_string(), - effort: None, - summary: Some( - config - .model_reasoning_summary - .unwrap_or(ReasoningSummary::Auto), - ), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: Default::default(), }) .await?; @@ -633,24 +574,22 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run call".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: REMOTE_MODEL_SLUG.to_string(), - effort: None, - summary: Some(ReasoningSummary::Auto), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Auto), + ..Default::default() + }, }) .await?; @@ -865,24 +804,22 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello remote".into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: model.to_string(), - effort: None, - summary: Some(ReasoningSummary::Auto), - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + summary: Some(ReasoningSummary::Auto), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index cf021f29e4f9..98001046859a 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -190,24 +190,30 @@ async fn submit_turn( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer: Some(ApprovalsReviewer::User), - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer: Some(ApprovalsReviewer::User), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index cb1324396677..84e101e73ae0 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -142,24 +142,30 @@ async fn submit_turn( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy, - approvals_reviewer, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(approval_policy), + approvals_reviewer, + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 6ddd9d0b5e71..e0ec684797de 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -132,36 +132,33 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul ]); let second_mock = responses::mount_sse_once(&server, second_response).await; - let session_model = session_configured.model.clone(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(CollaborationMode { - mode, - settings: Settings { - model: session_configured.model.clone(), - reasoning_effort: None, - developer_instructions: None, - }, - }), - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(CollaborationMode { + mode, + settings: Settings { + model: session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -282,31 +279,29 @@ async fn request_user_input_interrupt_emits_deferred_token_count() -> anyhow::Re let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(CollaborationMode { - mode: ModeKind::Plan, - settings: Settings { - model: session_configured.model, - reasoning_effort: None, - developer_instructions: None, - }, - }), - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(CollaborationMode { + mode: ModeKind::Plan, + settings: Settings { + model: session_configured.model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -388,24 +383,22 @@ where turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please confirm".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: Some(collaboration_mode), - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(collaboration_mode), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs index 09e99f78c300..f396a825a125 100644 --- a/codex-rs/core/tests/suite/responses_api_proxy_headers.rs +++ b/codex-rs/core/tests/suite/responses_api_proxy_headers.rs @@ -130,24 +130,29 @@ async fn submit_turn_with_timeout(test: &TestCodex, prompt: &str) -> Result<()> let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::workspace_write(), cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::OnRequest, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::OnRequest), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 7ead0364dcc4..7c811a88e042 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -105,24 +105,29 @@ fn read_only_user_turn_with_model( let cwd = fixture.cwd.path().to_path_buf(); let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), cwd.as_path()); - Op::UserTurn { + Op::UserInput { items: vec![UserInput::Text { text: text.into(), text_elements: Vec::new(), }], - final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, environments: None, + final_output_json_schema: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/safety_check_downgrade.rs b/codex-rs/core/tests/suite/safety_check_downgrade.rs index c937d49ad48b..ab985ce0f798 100644 --- a/codex-rs/core/tests/suite/safety_check_downgrade.rs +++ b/codex-rs/core/tests/suite/safety_check_downgrade.rs @@ -37,24 +37,29 @@ const CYBER_POLICY_MESSAGE: &str = fn disabled_text_turn(test: &TestCodex, text: &str) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items: vec![UserInput::Text { text: text.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: REQUESTED_MODEL.to_string(), - effort: test.config.model_reasoning_effort, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: REQUESTED_MODEL.to_string(), + reasoning_effort: test.config.model_reasoning_effort, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index 49ef4956cde4..14241ffafb6f 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -159,24 +159,29 @@ async fn run_snapshot_command_with_options( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run unified exec with shell snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -254,24 +259,29 @@ async fn run_shell_command_snapshot_with_options( turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run shell_command with shell snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -329,24 +339,29 @@ async fn run_tool_turn_on_harness( let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -567,24 +582,29 @@ async fn shell_command_snapshot_still_intercepts_apply_patch() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, cwd.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "apply patch via shell_command with snapshot".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.clone(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.clone()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/skill_approval.rs b/codex-rs/core/tests/suite/skill_approval.rs index 72244d534e25..ad8ad6a91a57 100644 --- a/codex-rs/core/tests/suite/skill_approval.rs +++ b/codex-rs/core/tests/suite/skill_approval.rs @@ -46,24 +46,29 @@ async fn submit_turn_with_policies( let (sandbox_policy, permission_profile) = turn_permission_fields(permission_profile, test.cwd_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd_path().to_path_buf(), - approval_policy, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd_path().to_path_buf()), + approval_policy: Some(approval_policy), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; Ok(()) diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index 6434f9c5332b..9173f60c4a7a 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -74,8 +74,7 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![ UserInput::Text { text: "please use $demo".to_string(), @@ -86,18 +85,24 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { path: skill_path.clone(), }, ], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/sqlite_state.rs b/codex-rs/core/tests/suite/sqlite_state.rs index ab0b4c27ead4..f576e55a3d02 100644 --- a/codex-rs/core/tests/suite/sqlite_state.rs +++ b/codex-rs/core/tests/suite/sqlite_state.rs @@ -405,24 +405,29 @@ async fn mcp_call_marks_thread_memory_mode_polluted_when_configured() -> Result< turn_permission_fields(PermissionProfile::read_only(), cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "call the rmcp echo tool".to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: test.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: test.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; wait_for_event(&test.codex, |event| { diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index 38843f2d83a1..2227e5b34e1e 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -102,24 +102,29 @@ async fn shell_command_tool_executes_command_and_streams_output() -> anyhow::Res turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please run the shell command".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -178,24 +183,29 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please update the plan".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -264,24 +274,29 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please update the plan".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -360,24 +375,29 @@ async fn apply_patch_tool_executes_and_emits_patch_events() -> anyhow::Result<() turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please apply a patch".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -493,24 +513,29 @@ async fn apply_patch_reports_parse_diagnostics() -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, cwd_path.as_path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "please apply a patch".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd_path, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd_path), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index 47282c283d29..6663991e0203 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -37,24 +37,29 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -358,24 +363,29 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.cwd.path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "stream delayed completion".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index 447bca673169..be9267934d61 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -515,24 +515,29 @@ async fn mcp_image_output_preserves_image_and_no_text_summary() -> Result<()> { fixture .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "call the rmcp image tool".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: fixture.cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile: Some(permission_profile), - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(fixture.cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile: Some(permission_profile), + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index 6b962116af24..98755201c942 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -192,24 +192,29 @@ async fn submit_unified_exec_turn( turn_permission_fields(permission_profile, test.config.cwd.as_path()); test.codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: prompt.into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -278,24 +283,29 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { turn_permission_fields(PermissionProfile::Disabled, &cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "apply patch via unified exec".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2120,24 +2130,29 @@ async fn unified_exec_keeps_long_running_session_after_turn_end() -> Result<()> turn_permission_fields(PermissionProfile::Disabled, &turn_cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "keep unified exec process after turn end".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2218,24 +2233,29 @@ async fn unified_exec_interrupt_preserves_long_running_session() -> Result<()> { turn_permission_fields(PermissionProfile::Disabled, &turn_cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "interrupt long-running unified exec".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2685,25 +2705,29 @@ async fn unified_exec_runs_under_sandbox() -> Result<()> { turn_permission_fields(PermissionProfile::read_only(), &turn_cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "summarize large output".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - // Important! - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2803,24 +2827,29 @@ async fn unified_exec_enforces_glob_deny_read_policy() -> Result<()> { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::read_only(), &turn_cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "read the fixture files".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; @@ -2936,24 +2965,29 @@ async fn unified_exec_python_prompt_under_seatbelt() -> Result<()> { turn_permission_fields(PermissionProfile::read_only(), &turn_cwd); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "start python under seatbelt".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: turn_cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(turn_cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/user_shell_cmd.rs b/codex-rs/core/tests/suite/user_shell_cmd.rs index 4fe3586d7fec..536ee7b49593 100644 --- a/codex-rs/core/tests/suite/user_shell_cmd.rs +++ b/codex-rs/core/tests/suite/user_shell_cmd.rs @@ -174,24 +174,29 @@ async fn user_shell_command_does_not_replace_active_turn() -> anyhow::Result<()> fixture .codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "run model shell command".to_string(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd, - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: fixture.session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: fixture.session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index d78e8761fdbb..e631e537c62e 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -72,21 +72,26 @@ const VIEW_IMAGE_TURN_COMPLETE_TIMEOUT: Duration = Duration::from_secs(30); fn disabled_user_turn(test: &TestCodex, items: Vec, model: String) -> Op { let (sandbox_policy, permission_profile) = turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); - Op::UserTurn { - environments: None, + Op::UserInput { items, + environments: None, final_output_json_schema: None, - cwd: test.config.cwd.to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model, - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(test.config.cwd.to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model, + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, } } diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index f073ce7ab87f..32a6e30caff3 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -152,24 +152,29 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex - .submit(Op::UserTurn { - environments: None, + .submit(Op::UserInput { items: vec![UserInput::Text { text: "hello".into(), text_elements: Vec::new(), }], + environments: None, final_output_json_schema: None, - cwd: cwd.path().to_path_buf(), - approval_policy: AskForApproval::Never, - approvals_reviewer: None, - sandbox_policy, - permission_profile, - model: session_configured.model.clone(), - effort: None, - summary: None, - service_tier: None, - collaboration_mode: None, - personality: None, + responsesapi_client_metadata: None, + thread_settings: codex_protocol::protocol::ThreadSettingsOverrides { + cwd: Some(cwd.path().to_path_buf()), + approval_policy: Some(AskForApproval::Never), + sandbox_policy: Some(sandbox_policy), + permission_profile, + collaboration_mode: Some(codex_protocol::config_types::CollaborationMode { + mode: codex_protocol::config_types::ModeKind::Default, + settings: codex_protocol::config_types::Settings { + model: session_configured.model.clone(), + reasoning_effort: None, + developer_instructions: None, + }, + }), + ..Default::default() + }, }) .await?; diff --git a/codex-rs/protocol/src/protocol.rs b/codex-rs/protocol/src/protocol.rs index 77d862086ca8..cec929b07f09 100644 --- a/codex-rs/protocol/src/protocol.rs +++ b/codex-rs/protocol/src/protocol.rs @@ -518,74 +518,6 @@ pub enum Op { thread_settings: ThreadSettingsOverrides, }, - /// Similar to [`Op::UserInput`], but contains additional context required - /// for a turn of a [`crate::codex_thread::CodexThread`]. - UserTurn { - /// User input items, see `InputItem` - items: Vec, - - /// `cwd` to use with the [`SandboxPolicy`] and potentially tool calls - /// such as `local_shell`. - cwd: PathBuf, - - /// Policy to use for command approval. - approval_policy: AskForApproval, - - /// Reviewer to use for approval requests raised during this turn. - /// - /// When omitted, the session keeps the current setting - approvals_reviewer: Option, - - /// Policy to use for tool calls such as `local_shell`. - sandbox_policy: SandboxPolicy, - - /// Full permissions profile to use for tool calls such as `local_shell`. - /// - /// When omitted, `sandbox_policy` is used as a legacy compatibility - /// projection. - #[serde(default, skip_serializing_if = "Option::is_none")] - permission_profile: Option, - - /// Must be a valid model slug for the configured client session - /// associated with this conversation. - model: String, - - /// Will only be honored if the model is configured to use reasoning. - #[serde(skip_serializing_if = "Option::is_none")] - effort: Option, - - /// Will only be honored if the model is configured to use reasoning. - /// - /// When omitted, the session keeps the current setting (which allows core to - /// fall back to the selected model's default on new sessions). - #[serde(default, skip_serializing_if = "Option::is_none")] - summary: Option, - - /// Optional service tier override for this turn. - /// - /// Use `Some(Some(_))` to set a specific tier for this turn, `Some(None)` to - /// explicitly clear the tier for this turn, or `None` to keep the existing - /// session preference. - #[serde(default, skip_serializing_if = "Option::is_none")] - service_tier: Option>, - - // The JSON schema to use for the final assistant message - final_output_json_schema: 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, - - /// Optional personality override for this turn. - #[serde(skip_serializing_if = "Option::is_none")] - personality: Option, - - /// Optional turn-scoped environments. - #[serde(default, skip_serializing_if = "Option::is_none")] - environments: Option>, - }, - /// Inter-agent communication that should be recorded as assistant history /// while still using the normal thread submission lifecycle. InterAgentCommunication { @@ -843,7 +775,6 @@ impl Op { Self::RealtimeConversationClose => "realtime_conversation_close", Self::RealtimeConversationListVoices => "realtime_conversation_list_voices", Self::UserInput { .. } => "user_input", - Self::UserTurn { .. } => "user_turn", Self::InterAgentCommunication { .. } => "inter_agent_communication", Self::OverrideTurnContext { .. } => "override_turn_context", Self::ExecApproval { .. } => "exec_approval",