diff --git a/codex-rs/app-server/src/codex_message_processor.rs b/codex-rs/app-server/src/codex_message_processor.rs index ac7e608500..daac6a019d 100644 --- a/codex-rs/app-server/src/codex_message_processor.rs +++ b/codex-rs/app-server/src/codex_message_processor.rs @@ -341,8 +341,11 @@ use codex_protocol::dynamic_tools::DynamicToolSpec as CoreDynamicToolSpec; use codex_protocol::error::CodexErr; use codex_protocol::error::Result as CodexResult; use codex_protocol::items::TurnItem; +use codex_protocol::models::PermissionProfile; use codex_protocol::models::ResponseItem; +use codex_protocol::models::SandboxEnforcement; use codex_protocol::permissions::FileSystemSandboxPolicy; +use codex_protocol::permissions::NetworkSandboxPolicy; use codex_protocol::protocol::AgentStatus; use codex_protocol::protocol::ConversationAudioParams; use codex_protocol::protocol::ConversationStartParams; @@ -361,6 +364,7 @@ use codex_protocol::protocol::ReviewDelivery as CoreReviewDelivery; use codex_protocol::protocol::ReviewRequest; use codex_protocol::protocol::ReviewTarget as CoreReviewTarget; use codex_protocol::protocol::RolloutItem; +use codex_protocol::protocol::SandboxPolicy as CoreSandboxPolicy; use codex_protocol::protocol::SessionConfiguredEvent; use codex_protocol::protocol::SessionMetaLine; use codex_protocol::protocol::TurnEnvironmentSelection; @@ -6666,6 +6670,19 @@ impl CodexMessageProcessor { } else { (None, None) }; + let permission_profile_for_validation = + if permission_profile.is_some() || sandbox_policy.is_none() { + permission_profile.clone() + } else { + let snapshot = thread.config_snapshot().await; + sandbox_policy.as_ref().map(|sandbox_policy| { + permission_profile_from_legacy_turn_sandbox_policy( + &snapshot, + sandbox_policy, + cwd.as_deref(), + ) + }) + }; let model = params.model; let effort = params.effort.map(Some); let summary = params.summary; @@ -6681,9 +6698,9 @@ impl CodexMessageProcessor { cwd: cwd.clone(), approval_policy, approvals_reviewer, - sandbox_policy: sandbox_policy.clone(), - permission_profile: permission_profile.clone(), + permission_profile: permission_profile_for_validation, active_permission_profile: active_permission_profile.clone(), + clear_active_permission_profile: sandbox_policy.is_some(), windows_sandbox_level: None, model: model.clone(), effort, @@ -9568,6 +9585,27 @@ fn apply_permission_profile_selection_to_config_overrides( )); } +fn permission_profile_from_legacy_turn_sandbox_policy( + snapshot: &ThreadConfigSnapshot, + sandbox_policy: &CoreSandboxPolicy, + cwd: Option<&Path>, +) -> PermissionProfile { + let sandbox_cwd = cwd.unwrap_or(snapshot.cwd.as_path()); + let configured_file_system_sandbox_policy = + snapshot.permission_profile.file_system_sandbox_policy(); + let file_system_sandbox_policy = + FileSystemSandboxPolicy::from_legacy_sandbox_policy_preserving_deny_entries( + sandbox_policy, + sandbox_cwd, + &configured_file_system_sandbox_policy, + ); + PermissionProfile::from_runtime_permissions_with_enforcement( + SandboxEnforcement::from_legacy_sandbox_policy(sandbox_policy), + &file_system_sandbox_policy, + NetworkSandboxPolicy::from(sandbox_policy), + ) +} + fn thread_response_sandbox_policy( permission_profile: &codex_protocol::models::PermissionProfile, cwd: &Path, diff --git a/codex-rs/core/src/codex_thread.rs b/codex-rs/core/src/codex_thread.rs index 47092cdeb0..b66f64fcd6 100644 --- a/codex-rs/core/src/codex_thread.rs +++ b/codex-rs/core/src/codex_thread.rs @@ -24,7 +24,6 @@ use codex_protocol::openai_models::ReasoningEffort; use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::Event; use codex_protocol::protocol::Op; -use codex_protocol::protocol::SandboxPolicy; use codex_protocol::protocol::SessionSource; use codex_protocol::protocol::Submission; use codex_protocol::protocol::ThreadMemoryMode; @@ -63,9 +62,9 @@ pub struct CodexThreadTurnContextOverrides { pub cwd: Option, pub approval_policy: Option, pub approvals_reviewer: Option, - pub sandbox_policy: Option, pub permission_profile: Option, pub active_permission_profile: Option, + pub clear_active_permission_profile: bool, pub windows_sandbox_level: Option, pub model: Option, pub effort: Option>, @@ -214,9 +213,9 @@ impl CodexThread { cwd, approval_policy, approvals_reviewer, - sandbox_policy, permission_profile, active_permission_profile, + clear_active_permission_profile, windows_sandbox_level, model, effort, @@ -234,19 +233,6 @@ impl CodexThread { .await .with_updates(model, effort, /*developer_instructions*/ None) }; - let clear_active_permission_profile = - permission_profile.is_none() && sandbox_policy.is_some(); - let permission_profile = match (permission_profile, sandbox_policy.as_ref()) { - (Some(permission_profile), _) => Some(permission_profile), - (None, Some(sandbox_policy)) => Some( - self.codex - .session - .permission_profile_from_legacy_sandbox_update(sandbox_policy, cwd.as_deref()) - .await, - ), - (None, None) => None, - }; - let updates = SessionSettingsUpdate { cwd, approval_policy,