diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index d86c636d8..ab6364304 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -203,6 +203,18 @@ 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. +pub fn turn_permission_fields( + permission_profile: PermissionProfile, + cwd: &Path, +) -> (SandboxPolicy, Option) { + let sandbox_policy = permission_profile + .to_legacy_sandbox_policy(cwd) + .unwrap_or_else(|_| SandboxPolicy::new_read_only_policy()); + (sandbox_policy, Some(permission_profile)) +} + pub struct TestCodexBuilder { config_mutators: Vec>, auth: CodexAuth, @@ -710,9 +722,8 @@ impl TestCodex { service_tier: Option>, environments: Option>, ) -> Result<()> { - let sandbox_policy = permission_profile - .to_legacy_sandbox_policy(self.config.cwd.as_path()) - .unwrap_or_else(|_| SandboxPolicy::new_read_only_policy()); + let (sandbox_policy, permission_profile) = + turn_permission_fields(permission_profile, self.config.cwd.as_path()); let session_model = self.session_configured.model.clone(); self.codex .submit(Op::UserTurn { @@ -726,7 +737,7 @@ impl TestCodex { approval_policy, approvals_reviewer: None, sandbox_policy, - permission_profile: Some(permission_profile), + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/image_rollout.rs b/codex-rs/core/tests/suite/image_rollout.rs index 18ebe0fb0..f819e1cfd 100644 --- a/codex-rs/core/tests/suite/image_rollout.rs +++ b/codex-rs/core/tests/suite/image_rollout.rs @@ -1,13 +1,13 @@ use anyhow::Context; use codex_protocol::models::ContentItem; use codex_protocol::models::DEFAULT_IMAGE_DETAIL; +use codex_protocol::models::PermissionProfile; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; use codex_protocol::protocol::RolloutItem; use codex_protocol::protocol::RolloutLine; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses; use core_test_support::responses::ev_assistant_message; @@ -18,6 +18,7 @@ use core_test_support::responses::start_mock_server; use core_test_support::skip_if_no_network; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use image::ImageBuffer; use image::Rgba; @@ -108,6 +109,8 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu responses::mount_sse_once(&server, 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 { @@ -125,8 +128,8 @@ async fn copy_paste_local_image_persists_rollout_request_shape() -> anyhow::Resu cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, @@ -196,6 +199,8 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> responses::mount_sse_once(&server, 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 { @@ -213,8 +218,8 @@ async fn drag_drop_image_persists_rollout_request_shape() -> anyhow::Result<()> cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/json_result.rs b/codex-rs/core/tests/suite/json_result.rs index 01783a365..c4ce8ac90 100644 --- a/codex-rs/core/tests/suite/json_result.rs +++ b/codex-rs/core/tests/suite/json_result.rs @@ -1,14 +1,15 @@ #![cfg(not(target_os = "windows"))] +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses; use core_test_support::skip_if_no_network; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use pretty_assertions::assert_eq; use responses::ev_assistant_message; @@ -69,6 +70,8 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { responses::mount_sse_once_match(&server, match_json_text_param, sse1).await; let TestCodex { codex, cwd, .. } = test_codex().build(&server).await?; + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, cwd.path()); // 1) Normal user input – should hit server once. codex @@ -82,8 +85,8 @@ async fn codex_returns_json_result(model: String) -> anyhow::Result<()> { cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/live_reload.rs b/codex-rs/core/tests/suite/live_reload.rs index 25206a6fd..c422073e4 100644 --- a/codex-rs/core/tests/suite/live_reload.rs +++ b/codex-rs/core/tests/suite/live_reload.rs @@ -8,10 +8,10 @@ use std::time::Duration; use anyhow::Result; use codex_config::config_toml::ProjectConfig; use codex_protocol::config_types::TrustLevel; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses; use core_test_support::responses::ResponsesRequest; @@ -19,6 +19,7 @@ use core_test_support::responses::mount_sse_sequence; use core_test_support::responses::start_mock_server; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use tokio::time::timeout; @@ -46,6 +47,8 @@ fn contains_skill_body(request: &ResponsesRequest, skill_body: &str) -> bool { async fn submit_skill_turn(test: &TestCodex, skill_path: PathBuf, prompt: &str) -> 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, @@ -63,8 +66,8 @@ async fn submit_skill_turn(test: &TestCodex, skill_path: PathBuf, prompt: &str) cwd: test.cwd_path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index 8eb8fca8a..e2688afc9 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -9,6 +9,7 @@ use codex_login::CodexAuth; use codex_models_manager::client_version_to_whole; use codex_models_manager::manager::RefreshStrategy; use codex_protocol::config_types::ReasoningSummary; +use codex_protocol::models::PermissionProfile; use codex_protocol::openai_models::ConfigShellToolType; use codex_protocol::openai_models::ModelInfo; use codex_protocol::openai_models::ModelVisibility; @@ -19,7 +20,6 @@ use codex_protocol::openai_models::TruncationPolicyConfig; use codex_protocol::openai_models::default_input_modalities; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses; use core_test_support::responses::ev_assistant_message; @@ -28,6 +28,7 @@ use core_test_support::responses::ev_response_created; use core_test_support::responses::sse; use core_test_support::responses::sse_response; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use pretty_assertions::assert_eq; use serde::Deserialize; @@ -87,6 +88,8 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { sse_response(response_body).insert_header("X-Models-Etag", ETAG), ) .await; + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, test.cwd_path()); codex .submit(Op::UserTurn { @@ -99,8 +102,8 @@ async fn renews_cache_ttl_on_matching_models_etag() -> Result<()> { cwd: test.cwd_path().to_path_buf(), approval_policy: codex_protocol::protocol::AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: test.session_configured.model.clone(), effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index cfe9ba8fc..b582a2abc 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -3,11 +3,11 @@ use std::sync::Arc; use codex_core::CodexThread; use codex_protocol::AgentPath; use codex_protocol::items::TurnItem; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InterAgentCommunication; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::context_snapshot; use core_test_support::context_snapshot::ContextSnapshotOptions; @@ -25,6 +25,7 @@ use core_test_support::streaming_sse::StreamingSseServer; use core_test_support::streaming_sse::start_streaming_sse_server; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use pretty_assertions::assert_eq; use serde_json::Value; @@ -108,6 +109,8 @@ async fn submit_user_input(codex: &CodexThread, text: &str) { } 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, @@ -119,8 +122,8 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { cwd: test.config.cwd.to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: test.session_configured.model.clone(), effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 7814f4936..c82a5a167 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -6,10 +6,10 @@ use codex_features::Feature; use codex_protocol::config_types::CollaborationMode; use codex_protocol::config_types::ModeKind; use codex_protocol::config_types::Settings; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::request_user_input::RequestUserInputAnswer; use codex_protocol::request_user_input::RequestUserInputResponse; use codex_protocol::user_input::UserInput; @@ -24,6 +24,7 @@ use core_test_support::responses::start_mock_server; use core_test_support::skip_if_no_network; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use core_test_support::wait_for_event_match; use pretty_assertions::assert_eq; @@ -128,6 +129,8 @@ 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 { @@ -140,8 +143,8 @@ async fn request_user_input_round_trip_for_mode(mode: ModeKind) -> anyhow::Resul cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, @@ -248,6 +251,8 @@ where let session_model = session_configured.model.clone(); let collaboration_mode = build_mode(session_model.clone()); + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex .submit(Op::UserTurn { @@ -260,8 +265,8 @@ where cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index 1edaefb78..ab5e46299 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -9,9 +9,9 @@ use codex_exec_server::ExecServerRuntimePaths; use codex_exec_server::ExecutorFileSystem; use codex_login::CodexAuth; use codex_models_manager::collaboration_mode_presets::CollaborationModesConfig; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionSource; use codex_protocol::user_input::UserInput; use codex_utils_absolute_path::AbsolutePathBuf; @@ -24,6 +24,7 @@ use core_test_support::responses::sse; use core_test_support::responses::start_mock_server; use core_test_support::skip_if_no_network; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use pretty_assertions::assert_eq; use std::fs; use std::path::Path; @@ -97,6 +98,8 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { .await; let session_model = test.session_configured.model.clone(); + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, test.config.cwd.as_path()); test.codex .submit(Op::UserTurn { environments: None, @@ -114,8 +117,8 @@ async fn user_turn_includes_skill_instructions() -> Result<()> { cwd: test.config.cwd.to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index a0ee7b114..47282c283 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -5,10 +5,10 @@ use std::fs; use std::time::Duration; use std::time::Instant; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses::ev_assistant_message; use core_test_support::responses::ev_completed; @@ -24,6 +24,7 @@ use core_test_support::streaming_sse::StreamingSseChunk; use core_test_support::streaming_sse::start_streaming_sse_server; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use core_test_support::wait_for_event; use pretty_assertions::assert_eq; use serde_json::Value; @@ -32,6 +33,8 @@ use tokio::sync::oneshot; async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::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 { @@ -44,8 +47,8 @@ async fn run_turn(test: &TestCodex, prompt: &str) -> anyhow::Result<()> { cwd: test.cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, @@ -352,6 +355,8 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an .await?; 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, @@ -363,8 +368,8 @@ async fn shell_tools_start_before_response_completed_when_stream_delayed() -> an cwd: test.cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_model, effort: None, summary: None, diff --git a/codex-rs/core/tests/suite/websocket_fallback.rs b/codex-rs/core/tests/suite/websocket_fallback.rs index dbe2e3c6d..f073ce7ab 100644 --- a/codex-rs/core/tests/suite/websocket_fallback.rs +++ b/codex-rs/core/tests/suite/websocket_fallback.rs @@ -1,9 +1,9 @@ use anyhow::Result; use codex_model_provider_info::WireApi; +use codex_protocol::models::PermissionProfile; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::user_input::UserInput; use core_test_support::responses; use core_test_support::responses::ev_completed; @@ -14,6 +14,7 @@ use core_test_support::responses::sse; use core_test_support::skip_if_no_network; use core_test_support::test_codex::TestCodex; use core_test_support::test_codex::test_codex; +use core_test_support::test_codex::turn_permission_fields; use pretty_assertions::assert_eq; use tokio::time::Duration; use tokio::time::timeout; @@ -147,6 +148,8 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result cwd, .. } = builder.build(&server).await?; + let (sandbox_policy, permission_profile) = + turn_permission_fields(PermissionProfile::Disabled, cwd.path()); codex .submit(Op::UserTurn { @@ -159,8 +162,8 @@ async fn websocket_fallback_hides_first_websocket_retry_stream_error() -> Result cwd: cwd.path().to_path_buf(), approval_policy: AskForApproval::Never, approvals_reviewer: None, - sandbox_policy: SandboxPolicy::DangerFullAccess, - permission_profile: None, + sandbox_policy, + permission_profile, model: session_configured.model.clone(), effort: None, summary: None,