This commit is contained in:
Charles Cunningham
2026-01-25 17:20:42 -08:00
parent 123cb25c36
commit 22f47b3285
4 changed files with 35 additions and 28 deletions

View File

@@ -1091,8 +1091,6 @@ pub struct ExecRunParams {
pub model: Option<String>,
pub model_provider: Option<String>,
pub cwd: Option<String>,
pub approval_policy: Option<AskForApproval>,
pub sandbox_policy: Option<SandboxPolicy>,
pub effort: Option<ReasoningEffort>,
pub summary: Option<ReasoningSummary>,
pub collaboration_mode: Option<CollaborationMode>,

View File

@@ -380,9 +380,7 @@ Run a single turn to completion without subscribing to streamed turn/item events
"type": "text",
"text": "Generate a concise thread title",
"textElements": []
}],
"approvalPolicy": "never", // optional
"sandboxPolicy": { "type": "readOnly" } // optional
}]
} }
{ "id": 31, "result": {
"threadId": "thread-123",
@@ -397,6 +395,7 @@ Notes:
- `exec/run` is best for one-off utilities (for example, generating a title) where you just need the final result.
- `exec/run` always runs ephemerally, so it does not create a rollout and will not appear in `thread/list`.
- `exec/run` forces `approvalPolicy: "never"` and a read-only sandbox.
- Use `turn/start` when you want streaming events, intermediate items, or a long-lived thread.
### Example: One-off command execution

View File

@@ -1398,25 +1398,40 @@ impl CodexMessageProcessor {
return;
}
if let Some(policy) = params.sandbox_policy.as_ref() {
let requested_policy = policy.clone().to_core();
if let Err(err) = self.config.sandbox_policy.can_set(&requested_policy) {
let error = JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!("invalid sandbox policy: {err}"),
data: None,
};
self.outgoing.send_error(request_id, error).await;
return;
}
if let Err(err) = self
.config
.approval_policy
.can_set(&codex_protocol::protocol::AskForApproval::Never)
{
let error = JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!("invalid approval policy: {err}"),
data: None,
};
self.outgoing.send_error(request_id, error).await;
return;
}
if let Err(err) = self
.config
.sandbox_policy
.can_set(&codex_protocol::protocol::SandboxPolicy::ReadOnly)
{
let error = JSONRPCErrorError {
code: INVALID_REQUEST_ERROR_CODE,
message: format!("invalid sandbox policy: {err}"),
data: None,
};
self.outgoing.send_error(request_id, error).await;
return;
}
let mut typesafe_overrides = self.build_thread_config_overrides(
params.model,
params.model_provider,
params.cwd,
params.approval_policy,
None,
Some(codex_app_server_protocol::AskForApproval::Never),
Some(codex_app_server_protocol::SandboxMode::ReadOnly),
params.base_instructions,
params.developer_instructions,
params.personality,
@@ -1458,8 +1473,8 @@ impl CodexMessageProcessor {
let thread_ids_to_skip_listener_attachment =
self.thread_ids_to_skip_listener_attachment.clone();
let thread_id_for_turn = thread_id.clone();
let thread_id_for_remove = thread_id.clone();
let thread_id_for_turn = thread_id;
let thread_id_for_remove = thread_id;
thread_ids_to_skip_listener_attachment
.lock()
.await
@@ -1468,17 +1483,16 @@ impl CodexMessageProcessor {
let response_result: Result<ExecRunResponse, JSONRPCErrorError> = async {
let has_turn_overrides = params.effort.is_some()
|| params.summary.is_some()
|| params.collaboration_mode.is_some()
|| params.sandbox_policy.is_some();
|| params.collaboration_mode.is_some();
if has_turn_overrides {
let _ = thread
.submit(Op::OverrideTurnContext {
cwd: None,
approval_policy: None,
sandbox_policy: params.sandbox_policy.map(|policy| policy.to_core()),
sandbox_policy: None,
model: None,
effort: params.effort.map(Some),
summary: params.summary.clone(),
summary: params.summary,
collaboration_mode: params.collaboration_mode.clone(),
personality: None,
})

View File

@@ -40,8 +40,6 @@ async fn exec_run_completes_turn_and_returns_final_message() -> Result<()> {
model: None,
model_provider: None,
cwd: None,
approval_policy: None,
sandbox_policy: None,
effort: None,
summary: None,
collaboration_mode: None,
@@ -88,8 +86,6 @@ async fn exec_run_rejects_empty_input() -> Result<()> {
model: None,
model_provider: None,
cwd: None,
approval_policy: None,
sandbox_policy: None,
effort: None,
summary: None,
collaboration_mode: None,