mirror of
https://github.com/openai/codex.git
synced 2026-09-11 20:36:49 +00:00
## What changed - Remove the legacy `shell_command` handler and runtime, leaving `exec_command` and `write_stdin` as the shell execution tools. - Treat legacy `shell_command` model metadata as `unified_exec`, and normalize legacy user opt-outs so they do not disable command execution. Managed feature requirements and `shell_tool` can still disable it. - Preserve shell approvals, sandboxing, zsh-fork support, and output truncation through the unified execution path. ## Testing - Cover legacy configuration and model-metadata compatibility. - Exercise unified shell execution, approvals, truncation, and `apply_patch` serialization across the app-server and core test suites. GitOrigin-RevId: 5c2fd6164fc3519cdae4944cb9db276b8467311c
129 lines
4.3 KiB
Rust
129 lines
4.3 KiB
Rust
use core_test_support::responses;
|
|
use serde_json::json;
|
|
use std::path::Path;
|
|
|
|
pub fn create_command_execution_sse_response(
|
|
command: Vec<String>,
|
|
workdir: Option<&Path>,
|
|
timeout_ms: Option<u64>,
|
|
call_id: &str,
|
|
) -> anyhow::Result<String> {
|
|
let command_str = shlex::try_join(command.iter().map(String::as_str))?;
|
|
let mut arguments = json!({
|
|
"cmd": command_str,
|
|
"workdir": workdir.map(|w| w.to_string_lossy()),
|
|
});
|
|
if let Some(timeout_ms) = timeout_ms {
|
|
arguments["yield_time_ms"] = json!(timeout_ms);
|
|
}
|
|
let tool_call_arguments = serde_json::to_string(&arguments)?;
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_function_call(call_id, "exec_command", &tool_call_arguments),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_escalated_command_execution_sse_response(
|
|
command: Vec<String>,
|
|
workdir: Option<&Path>,
|
|
timeout_ms: Option<u64>,
|
|
call_id: &str,
|
|
) -> anyhow::Result<String> {
|
|
let command_str = shlex::try_join(command.iter().map(String::as_str))?;
|
|
let tool_call_arguments = serde_json::to_string(&json!({
|
|
"cmd": command_str,
|
|
"workdir": workdir.map(|w| w.to_string_lossy()),
|
|
"yield_time_ms": timeout_ms,
|
|
"sandbox_permissions": "require_escalated",
|
|
"justification": "Test approval request."
|
|
}))?;
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_function_call(call_id, "exec_command", &tool_call_arguments),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_final_assistant_message_sse_response(message: &str) -> anyhow::Result<String> {
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_assistant_message("msg-1", message),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_apply_patch_sse_response(
|
|
patch_content: &str,
|
|
call_id: &str,
|
|
) -> anyhow::Result<String> {
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_apply_patch_exec_command_call_via_heredoc(call_id, patch_content),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_exec_command_sse_response(call_id: &str) -> anyhow::Result<String> {
|
|
let (cmd, args) = if cfg!(windows) {
|
|
("cmd.exe", vec!["/d", "/c", "echo hi"])
|
|
} else {
|
|
("/bin/sh", vec!["-c", "echo hi"])
|
|
};
|
|
let command = std::iter::once(cmd.to_string())
|
|
.chain(args.into_iter().map(str::to_string))
|
|
.collect::<Vec<_>>();
|
|
let tool_call_arguments = serde_json::to_string(&json!({
|
|
"cmd": command.join(" "),
|
|
"yield_time_ms": 500
|
|
}))?;
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_function_call(call_id, "exec_command", &tool_call_arguments),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_request_user_input_sse_response(call_id: &str) -> anyhow::Result<String> {
|
|
let tool_call_arguments = serde_json::to_string(&json!({
|
|
"questions": [{
|
|
"id": "confirm_path",
|
|
"header": "Confirm",
|
|
"question": "Proceed with the plan?",
|
|
"options": [{
|
|
"label": "Yes (Recommended)",
|
|
"description": "Continue the current plan."
|
|
}, {
|
|
"label": "No",
|
|
"description": "Stop and revisit the approach."
|
|
}]
|
|
}]
|
|
}))?;
|
|
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_function_call(call_id, "request_user_input", &tool_call_arguments),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|
|
|
|
pub fn create_request_permissions_sse_response(call_id: &str) -> anyhow::Result<String> {
|
|
let tool_call_arguments = serde_json::to_string(&json!({
|
|
"reason": "Select a workspace root",
|
|
"permissions": {
|
|
"file_system": {
|
|
"write": [
|
|
".",
|
|
"../shared"
|
|
]
|
|
}
|
|
}
|
|
}))?;
|
|
|
|
Ok(responses::sse(vec![
|
|
responses::ev_response_created("resp-1"),
|
|
responses::ev_function_call(call_id, "request_permissions", &tool_call_arguments),
|
|
responses::ev_completed("resp-1"),
|
|
]))
|
|
}
|