diff --git a/codex-rs/core/src/tools/orchestrator.rs b/codex-rs/core/src/tools/orchestrator.rs index bdc4e3aff70..38aac5c1edf 100644 --- a/codex-rs/core/src/tools/orchestrator.rs +++ b/codex-rs/core/src/tools/orchestrator.rs @@ -98,9 +98,9 @@ impl ToolOrchestrator { "sandbox denied and no retry".to_string(), )); } - // Under `Never`, do not retry without sandbox; surface a concise message + // Under `Never` or `OnRequest`, do not retry without sandbox; surface a concise message // derived from the actual output (platform-agnostic). - if matches!(approval_policy, AskForApproval::Never) { + if !tool.wants_no_sandbox_approval(approval_policy) { let msg = build_never_denied_message_from_output(output.as_ref()); return Err(ToolError::SandboxDenied(msg)); } diff --git a/codex-rs/core/src/tools/runtimes/apply_patch.rs b/codex-rs/core/src/tools/runtimes/apply_patch.rs index eb1cda4e5b2..18abbfee4a4 100644 --- a/codex-rs/core/src/tools/runtimes/apply_patch.rs +++ b/codex-rs/core/src/tools/runtimes/apply_patch.rs @@ -17,6 +17,7 @@ use crate::tools::sandboxing::ToolCtx; use crate::tools::sandboxing::ToolError; use crate::tools::sandboxing::ToolRuntime; use crate::tools::sandboxing::with_cached_approval; +use codex_protocol::protocol::AskForApproval; use codex_protocol::protocol::ReviewDecision; use futures::future::BoxFuture; use std::collections::HashMap; @@ -127,6 +128,10 @@ impl Approvable for ApplyPatchRuntime { .await }) } + + fn wants_no_sandbox_approval(&self, policy: AskForApproval) -> bool { + !matches!(policy, AskForApproval::Never) + } } impl ToolRuntime for ApplyPatchRuntime { diff --git a/codex-rs/core/src/tools/sandboxing.rs b/codex-rs/core/src/tools/sandboxing.rs index 7c4d65ca800..0dd7a99f470 100644 --- a/codex-rs/core/src/tools/sandboxing.rs +++ b/codex-rs/core/src/tools/sandboxing.rs @@ -121,6 +121,11 @@ pub(crate) trait Approvable { } } + /// Decide we can request an approval for no-sandbox execution. + fn wants_no_sandbox_approval(&self, policy: AskForApproval) -> bool { + !matches!(policy, AskForApproval::Never | AskForApproval::OnRequest) + } + fn start_approval_async<'a>( &'a mut self, req: &'a Req,