Merge branch 'etraut/next-turn-state-core' into etraut/next-turn-state-app-server

# Conflicts:
#	codex-rs/app-server/src/request_processors.rs
#	codex-rs/app-server/src/request_processors/turn_processor.rs
This commit is contained in:
Eric Traut
2026-05-16 13:31:59 -07:00
70 changed files with 1936 additions and 1214 deletions
@@ -598,7 +598,7 @@ impl TurnRequestProcessor {
// Start the turn by submitting the user input. Return its submission id as turn_id.
let turn_op = if let Some(overrides) = resolved_overrides {
Op::UserInputWithTurnContext {
Op::UserInput {
items: mapped_items,
environments: environment_selections,
final_output_json_schema: params.output_schema,
@@ -611,6 +611,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 = Uuid::now_v7().to_string();
+3
View File
@@ -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
+1
View File
@@ -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?;
+23 -14
View File
@@ -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;
+18 -79
View File
@@ -51,9 +51,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;
@@ -190,84 +187,28 @@ pub(super) async fn user_input_or_turn_inner(
mirror_user_text_to_realtime: Option<()>,
) {
let (items, updates, responsesapi_client_metadata, emit_turn_context_applied) = 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,
false,
)
}
Op::UserInputWithTurnContext {
final_output_json_schema,
items,
responsesapi_client_metadata,
environments,
turn_context,
} => {
let mut updates = 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, true)
}
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,
false,
),
turn_context,
} => {
let emit_turn_context_applied = turn_context != TurnContextOverrides::default();
let mut updates = if emit_turn_context_applied {
turn_context_settings_update(sess, turn_context).await
} else {
SessionSettingsUpdate::default()
};
updates.final_output_json_schema = Some(final_output_json_schema);
updates.environments = environments;
(
items,
updates,
responsesapi_client_metadata,
emit_turn_context_applied,
)
}
_ => unreachable!(),
};
@@ -823,9 +764,7 @@ pub(super) async fn submission_loop(
realtime_conversation_list_voices(&sess, sub.id.clone()).await;
false
}
Op::UserInput { .. }
| Op::UserInputWithTurnContext { .. }
| Op::UserTurn { .. } => {
Op::UserInput { .. } => {
user_input_or_turn(&sess, sub.id.clone(), sub.op).await;
false
}
+1
View File
@@ -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,
)
+31 -21
View File
@@ -2221,6 +2221,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;
@@ -2258,7 +2259,7 @@ async fn fork_startup_context_then_first_turn_diff_snapshot() -> anyhow::Result<
};
forked
.thread
.submit(Op::UserInputWithTurnContext {
.submit(Op::UserInput {
environments: None,
items: vec![UserInput::Text {
text: "after fork".into(),
@@ -5191,27 +5192,24 @@ 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::UserInput {
environments: None,
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,
Op::TurnContext {
turn_context: TurnContextOverrides::default(),
}
.kind(),
"user_input_with_turn_context"
"turn_context"
);
}
@@ -5223,24 +5221,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;
@@ -8291,6 +8298,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?;
@@ -8395,6 +8403,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?;
@@ -8819,6 +8828,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?;
@@ -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()
+23 -15
View File
@@ -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?;
+5
View File
@@ -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();
+22 -13
View File
@@ -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(())
+44 -26
View File
@@ -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?;
+74 -36
View File
@@ -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();
@@ -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");
+22 -13
View File
@@ -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?;
@@ -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;
@@ -138,6 +139,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;
@@ -166,28 +168,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;
@@ -218,28 +222,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;
@@ -285,6 +291,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;
@@ -322,28 +329,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;
@@ -394,6 +403,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;
@@ -414,6 +424,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;
@@ -463,6 +474,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;
@@ -483,6 +495,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;
@@ -534,6 +547,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;
@@ -557,6 +571,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;
@@ -609,6 +624,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;
@@ -632,6 +648,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;
@@ -688,6 +705,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;
@@ -703,6 +721,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;
@@ -752,6 +771,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;
+53 -13
View File
@@ -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<String>, 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");
@@ -3271,6 +3307,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");
@@ -3459,6 +3496,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");
@@ -3473,6 +3511,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");
@@ -3545,6 +3584,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");
@@ -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;
@@ -2746,6 +2789,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;
@@ -2832,6 +2876,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;
@@ -2851,6 +2896,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;
@@ -2969,6 +3015,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;
@@ -2982,6 +3029,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 {
@@ -3066,6 +3114,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;
@@ -3143,6 +3192,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;
@@ -3228,6 +3278,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;
@@ -3244,6 +3295,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;
@@ -3325,6 +3377,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;
@@ -606,6 +606,7 @@ async fn submit_user_input(codex: &codex_core::CodexThread, items: Vec<UserInput
items,
final_output_json_schema: None,
responsesapi_client_metadata: None,
turn_context: Default::default(),
})
.await?;
wait_for_turn_complete(codex).await;
@@ -781,6 +781,7 @@ async fn user_turn(conversation: &Arc<CodexThread>, text: &str) {
}],
final_output_json_schema: None,
responsesapi_client_metadata: None,
turn_context: Default::default(),
})
.await
.expect("submit user turn");
+46 -26
View File
@@ -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?;
+2
View File
@@ -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();
+2
View File
@@ -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?;
}
+44 -26
View File
@@ -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?;
+25 -14
View File
@@ -44,30 +44,32 @@ use std::path::PathBuf;
fn disabled_plan_turn(
text: &str,
model: String,
_model: String,
collaboration_mode: CollaborationMode,
) -> anyhow::Result<Op> {
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?;
+22 -13
View File
@@ -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?;
+25 -13
View File
@@ -64,27 +64,39 @@ async fn submit_user_turn(
approval_policy: AskForApproval,
collaboration_mode: Option<CollaborationMode>,
) -> 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(())
+22 -13
View File
@@ -42,21 +42,30 @@ use wiremock::MockServer;
fn read_only_user_turn(test: &TestCodex, items: Vec<UserInput>, 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()
},
}
}
+113 -65
View File
@@ -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;
@@ -490,6 +537,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| {
+22 -13
View File
@@ -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?;
@@ -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?;
+22
View File
@@ -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();
+25 -13
View File
@@ -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();
@@ -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;
@@ -117,6 +119,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;
@@ -162,6 +165,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;
@@ -175,6 +179,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;
@@ -220,6 +225,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;
@@ -240,6 +246,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;
@@ -298,6 +305,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;
@@ -320,6 +328,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;
@@ -335,6 +344,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;
@@ -394,6 +404,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;
@@ -416,6 +427,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;
@@ -437,6 +449,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;
@@ -472,6 +485,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;
@@ -532,6 +546,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;
+22 -13
View File
@@ -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()
},
}
}
+3
View File
@@ -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;
+120 -65
View File
@@ -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;
@@ -456,6 +463,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;
@@ -534,6 +542,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?;
@@ -687,6 +696,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;
@@ -703,24 +713,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;
@@ -817,47 +836,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;
@@ -946,24 +983,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;
@@ -971,24 +1017,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;
@@ -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();
@@ -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?;
+22 -13
View File
@@ -67,24 +67,33 @@ async fn submit_turn_with_approval_and_environments(
environments: Vec<TurnEnvironmentSelection>,
) -> 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?;
+158 -95
View File
@@ -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?;
@@ -623,24 +668,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?;
@@ -845,24 +899,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?;
@@ -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?;
@@ -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(())
@@ -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(())
+59 -54
View File
@@ -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?;
@@ -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?;
+7
View File
@@ -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;
@@ -434,6 +440,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| {
+1
View File
@@ -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();
+22 -13
View File
@@ -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()
},
}
}
@@ -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()
},
}
}
+4
View File
@@ -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?;
+88 -52
View File
@@ -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?;
+22 -13
View File
@@ -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(())
+22 -13
View File
@@ -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?;
+22 -13
View File
@@ -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| {
@@ -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();
@@ -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();
+110 -65
View File
@@ -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?;
+44 -26
View File
@@ -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?;
+22 -13
View File
@@ -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?;
+154 -92
View File
@@ -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?;
@@ -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;
+22 -13
View File
@@ -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?;
+22 -13
View File
@@ -72,21 +72,30 @@ const VIEW_IMAGE_TURN_COMPLETE_TIMEOUT: Duration = Duration::from_secs(30);
fn disabled_user_turn(test: &TestCodex, items: Vec<UserInput>, 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()
},
}
}
+22 -13
View File
@@ -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?;
@@ -112,6 +112,7 @@ async fn submit_user_turn(codex: &Arc<CodexThread>, 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;
@@ -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
{
+1
View File
@@ -261,6 +261,7 @@ impl MemoryStartupContext {
environments: None,
final_output_json_schema: None,
responsesapi_client_metadata: None,
turn_context: Default::default(),
})
.await
{
+7 -92
View File
@@ -500,10 +500,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<UserInput>,
@@ -516,26 +513,9 @@ pub enum Op {
/// Optional turn-scoped Responses API `client_metadata`.
#[serde(default, skip_serializing_if = "Option::is_none")]
responsesapi_client_metadata: Option<HashMap<String, String>>,
},
/// 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<UserInput>,
/// Optional turn-scoped environment selections.
#[serde(default, skip_serializing_if = "Option::is_none")]
environments: Option<Vec<TurnEnvironmentSelection>>,
/// 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<Value>,
/// Optional turn-scoped Responses API `client_metadata`.
#[serde(default, skip_serializing_if = "Option::is_none")]
responsesapi_client_metadata: Option<HashMap<String, String>>,
/// Persistent turn-context overrides to apply before the input.
#[serde(flatten)]
#[serde(default, flatten)]
turn_context: TurnContextOverrides,
},
@@ -549,74 +529,6 @@ pub enum Op {
turn_context: TurnContextOverrides,
},
/// 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<UserInput>,
/// `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<ApprovalsReviewer>,
/// 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<PermissionProfile>,
/// 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<ReasoningEffortConfig>,
/// 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<ReasoningSummaryConfig>,
/// 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<Option<String>>,
// The JSON schema to use for the final assistant message
final_output_json_schema: Option<Value>,
/// 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<CollaborationMode>,
/// Optional personality override for this turn.
#[serde(skip_serializing_if = "Option::is_none")]
personality: Option<Personality>,
/// Optional turn-scoped environments.
#[serde(default, skip_serializing_if = "Option::is_none")]
environments: Option<Vec<TurnEnvironmentSelection>>,
},
/// Inter-agent communication that should be recorded as assistant history
/// while still using the normal thread submission lifecycle.
InterAgentCommunication {
@@ -743,6 +655,7 @@ impl From<Vec<UserInput>> for Op {
items: value,
final_output_json_schema: None,
responsesapi_client_metadata: None,
turn_context: TurnContextOverrides::default(),
}
}
}
@@ -809,9 +722,7 @@ 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::TurnContext { .. } => "turn_context",
Self::UserTurn { .. } => "user_turn",
Self::InterAgentCommunication { .. } => "inter_agent_communication",
Self::ExecApproval { .. } => "exec_approval",
Self::PatchApproval { .. } => "patch_approval",
@@ -5016,6 +4927,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)?;
@@ -5035,6 +4947,7 @@ mod tests {
items: Vec::new(),
final_output_json_schema: None,
responsesapi_client_metadata: None,
turn_context: Default::default(),
}
);
@@ -5056,6 +4969,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)?;
@@ -5081,6 +4995,7 @@ mod tests {
"fiber_run_id".to_string(),
"fiber-123".to_string(),
)])),
turn_context: Default::default(),
};
let json_op = serde_json::to_value(&op)?;
@@ -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")?;