From daf77b845230c35c325500ff73fe72a78f3b7416 Mon Sep 17 00:00:00 2001 From: Dylan Hurd Date: Mon, 17 Nov 2025 13:05:15 -0800 Subject: [PATCH] chore(core) Update shell instructions (#6679) ## Summary Consolidates `shell` and `shell_command` tool instructions. ## Testing - [x] Updated tests, tested locally --- codex-rs/core/gpt_5_1_prompt.md | 2 - codex-rs/core/gpt_5_codex_prompt.md | 2 - codex-rs/core/src/tools/spec.rs | 74 ++++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/codex-rs/core/gpt_5_1_prompt.md b/codex-rs/core/gpt_5_1_prompt.md index 5a424dd0f6..97a3875fe5 100644 --- a/codex-rs/core/gpt_5_1_prompt.md +++ b/codex-rs/core/gpt_5_1_prompt.md @@ -318,8 +318,6 @@ For casual greetings, acknowledgements, or other one-off conversational messages When using the shell, you must adhere to the following guidelines: -- The arguments to `shell` will be passed to execvp(). -- Always set the `workdir` param when using the shell function. Do not use `cd` unless absolutely necessary. - When searching for text or files, prefer using `rg` or `rg --files` respectively because `rg` is much faster than alternatives like `grep`. (If the `rg` command is not found, then use alternatives.) - Read files in chunks with a max chunk size of 250 lines. Do not use python scripts to attempt to output larger chunks of a file. Command line output will be truncated after 10 kilobytes or 256 lines of output, regardless of the command used. diff --git a/codex-rs/core/gpt_5_codex_prompt.md b/codex-rs/core/gpt_5_codex_prompt.md index e3cbfa0f25..57d06761ba 100644 --- a/codex-rs/core/gpt_5_codex_prompt.md +++ b/codex-rs/core/gpt_5_codex_prompt.md @@ -2,8 +2,6 @@ You are Codex, based on GPT-5. You are running as a coding agent in the Codex CL ## General -- The arguments to `shell` will be passed to execvp(). Most terminal commands should be prefixed with ["bash", "-lc"]. -- Always set the `workdir` param when using the shell function. Do not use `cd` unless absolutely necessary. - When searching for text or files, prefer using `rg` or `rg --files` respectively because `rg` is much faster than alternatives like `grep`. (If the `rg` command is not found, then use alternatives.) ## Editing constraints diff --git a/codex-rs/core/src/tools/spec.rs b/codex-rs/core/src/tools/spec.rs index ab201889ad..2bd8156988 100644 --- a/codex-rs/core/src/tools/spec.rs +++ b/codex-rs/core/src/tools/spec.rs @@ -294,9 +294,26 @@ fn create_shell_tool() -> ToolSpec { }, ); + let description = if cfg!(windows) { + r#"Runs a Powershell command (Windows) and returns its output. Arguments to `shell` will be passed to CreateProcessW(). Most commands should be prefixed with ["powershell.exe", "-Command"]. + +Examples of valid command strings: + +- ls -a (show hidden): ["powershell.exe", "-Command", "Get-ChildItem -Force"] +- recursive find by name: ["powershell.exe", "-Command", "Get-ChildItem -Recurse -Filter *.py"] +- recursive grep: ["powershell.exe", "-Command", "Get-ChildItem -Path C:\\myrepo -Recurse | Select-String -Pattern 'TODO' -CaseSensitive"] +- ps aux | grep python: ["powershell.exe", "-Command", "Get-Process | Where-Object { $_.ProcessName -like '*python*' }"] +- setting an env var: ["powershell.exe", "-Command", "$env:FOO='bar'; echo $env:FOO"] +- running an inline Python script: ["powershell.exe", "-Command", "@'\\nprint('Hello, world!')\\n'@ | python -"]"# + } else { + r#"Runs a shell command and returns its output. +- The arguments to `shell` will be passed to execvp(). Most terminal commands should be prefixed with ["bash", "-lc"]. +- Always set the `workdir` param when using the shell function. Do not use `cd` unless absolutely necessary."# + }.to_string(); + ToolSpec::Function(ResponsesApiTool { name: "shell".to_string(), - description: "Runs a shell command and returns its output.".to_string(), + description, strict: false, parameters: JsonSchema::Object { properties, @@ -341,9 +358,25 @@ fn create_shell_command_tool() -> ToolSpec { }, ); + let description = if cfg!(windows) { + r#"Runs a Powershell command (Windows) and returns its output. + +Examples of valid command strings: + +- ls -a (show hidden): "Get-ChildItem -Force" +- recursive find by name: "Get-ChildItem -Recurse -Filter *.py" +- recursive grep: "Get-ChildItem -Path C:\\myrepo -Recurse | Select-String -Pattern 'TODO' -CaseSensitive" +- ps aux | grep python: "Get-Process | Where-Object { $_.ProcessName -like '*python*' }" +- setting an env var: "$env:FOO='bar'; echo $env:FOO" +- running an inline Python script: "@'\\nprint('Hello, world!')\\n'@ | python -"# + } else { + r#"Runs a shell command and returns its output. +- Always set the `workdir` param when using the shell_command function. Do not use `cd` unless absolutely necessary."# + }.to_string(); + ToolSpec::Function(ResponsesApiTool { name: "shell_command".to_string(), - description: "Runs a shell command string and returns its output.".to_string(), + description, strict: false, parameters: JsonSchema::Object { properties, @@ -1873,8 +1906,23 @@ mod tests { }; assert_eq!(name, "shell"); - let expected = "Runs a shell command and returns its output."; - assert_eq!(description, expected); + let expected = if cfg!(windows) { + r#"Runs a Powershell command (Windows) and returns its output. Arguments to `shell` will be passed to CreateProcessW(). Most commands should be prefixed with ["powershell.exe", "-Command"]. + +Examples of valid command strings: + +- ls -a (show hidden): ["powershell.exe", "-Command", "Get-ChildItem -Force"] +- recursive find by name: ["powershell.exe", "-Command", "Get-ChildItem -Recurse -Filter *.py"] +- recursive grep: ["powershell.exe", "-Command", "Get-ChildItem -Path C:\\myrepo -Recurse | Select-String -Pattern 'TODO' -CaseSensitive"] +- ps aux | grep python: ["powershell.exe", "-Command", "Get-Process | Where-Object { $_.ProcessName -like '*python*' }"] +- setting an env var: ["powershell.exe", "-Command", "$env:FOO='bar'; echo $env:FOO"] +- running an inline Python script: ["powershell.exe", "-Command", "@'\\nprint('Hello, world!')\\n'@ | python -"]"# + } else { + r#"Runs a shell command and returns its output. +- The arguments to `shell` will be passed to execvp(). Most terminal commands should be prefixed with ["bash", "-lc"]. +- Always set the `workdir` param when using the shell function. Do not use `cd` unless absolutely necessary."# + }.to_string(); + assert_eq!(description, &expected); } #[test] @@ -1888,8 +1936,22 @@ mod tests { }; assert_eq!(name, "shell_command"); - let expected = "Runs a shell command string and returns its output."; - assert_eq!(description, expected); + let expected = if cfg!(windows) { + r#"Runs a Powershell command (Windows) and returns its output. + +Examples of valid command strings: + +- ls -a (show hidden): "Get-ChildItem -Force" +- recursive find by name: "Get-ChildItem -Recurse -Filter *.py" +- recursive grep: "Get-ChildItem -Path C:\\myrepo -Recurse | Select-String -Pattern 'TODO' -CaseSensitive" +- ps aux | grep python: "Get-Process | Where-Object { $_.ProcessName -like '*python*' }" +- setting an env var: "$env:FOO='bar'; echo $env:FOO" +- running an inline Python script: "@'\\nprint('Hello, world!')\\n'@ | python -"#.to_string() + } else { + r#"Runs a shell command and returns its output. +- Always set the `workdir` param when using the shell_command function. Do not use `cd` unless absolutely necessary."#.to_string() + }; + assert_eq!(description, &expected); } #[test]