Skip to content

Commit ecbd7fa

Browse files
authored
Merge branch 'main' into add-github-action-for-nix
2 parents 1b7c84c + 8595237 commit ecbd7fa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1392
-710
lines changed

codex-rs/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codex-rs/cli/src/debug_sandbox.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ async fn run_command_under_sandbox(
6464
sandbox_type: SandboxType,
6565
) -> anyhow::Result<()> {
6666
let sandbox_mode = create_sandbox_mode(full_auto);
67-
let cwd = std::env::current_dir()?;
6867
let config = Config::load_with_cli_overrides(
6968
config_overrides
7069
.parse_overrides()
@@ -75,13 +74,29 @@ async fn run_command_under_sandbox(
7574
..Default::default()
7675
},
7776
)?;
77+
78+
// In practice, this should be `std::env::current_dir()` because this CLI
79+
// does not support `--cwd`, but let's use the config value for consistency.
80+
let cwd = config.cwd.clone();
81+
// For now, we always use the same cwd for both the command and the
82+
// sandbox policy. In the future, we could add a CLI option to set them
83+
// separately.
84+
let sandbox_policy_cwd = cwd.clone();
85+
7886
let stdio_policy = StdioPolicy::Inherit;
7987
let env = create_env(&config.shell_environment_policy);
8088

8189
let mut child = match sandbox_type {
8290
SandboxType::Seatbelt => {
83-
spawn_command_under_seatbelt(command, &config.sandbox_policy, cwd, stdio_policy, env)
84-
.await?
91+
spawn_command_under_seatbelt(
92+
command,
93+
cwd,
94+
&config.sandbox_policy,
95+
sandbox_policy_cwd.as_path(),
96+
stdio_policy,
97+
env,
98+
)
99+
.await?
85100
}
86101
SandboxType::Landlock => {
87102
#[expect(clippy::expect_used)]
@@ -91,8 +106,9 @@ async fn run_command_under_sandbox(
91106
spawn_command_under_linux_sandbox(
92107
codex_linux_sandbox_exe,
93108
command,
94-
&config.sandbox_policy,
95109
cwd,
110+
&config.sandbox_policy,
111+
sandbox_policy_cwd.as_path(),
96112
stdio_policy,
97113
env,
98114
)

codex-rs/cli/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,11 @@ async fn cli_main(codex_linux_sandbox_exe: Option<PathBuf>) -> anyhow::Result<()
177177
root_config_overrides.clone(),
178178
);
179179
let usage = codex_tui::run_main(interactive, codex_linux_sandbox_exe).await?;
180-
if !usage.is_zero() {
181-
println!("{}", codex_core::protocol::FinalOutput::from(usage));
180+
if !usage.token_usage.is_zero() {
181+
println!(
182+
"{}",
183+
codex_core::protocol::FinalOutput::from(usage.token_usage)
184+
);
182185
}
183186
}
184187
Some(Subcommand::Exec(mut exec_cli)) => {

codex-rs/core/Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ name = "codex-core"
44
version = { workspace = true }
55

66
[lib]
7+
doctest = false
78
name = "codex_core"
89
path = "src/lib.rs"
9-
doctest = false
1010

1111
[lints]
1212
workspace = true
@@ -41,7 +41,12 @@ similar = "2.7.0"
4141
strum_macros = "0.27.2"
4242
tempfile = "3"
4343
thiserror = "2.0.16"
44-
time = { version = "0.3", features = ["formatting", "parsing", "local-offset", "macros"] }
44+
time = { version = "0.3", features = [
45+
"formatting",
46+
"parsing",
47+
"local-offset",
48+
"macros",
49+
] }
4550
tokio = { version = "1", features = [
4651
"io-std",
4752
"macros",

codex-rs/core/gpt_5_codex_prompt.md

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,41 @@ When using the planning tool:
2626

2727
## Codex CLI harness, sandboxing, and approvals
2828

29-
The Codex CLI harness supports several different sandboxing, and approval configurations that the user can choose from.
29+
The Codex CLI harness supports several different configurations for sandboxing and escalation approvals that the user can choose from.
3030

31-
Filesystem sandboxing defines which files can be read or written. The options are:
32-
- **read-only**: You can only read files.
33-
- **workspace-write**: You can read files. You can write to files in this folder, but not outside it.
34-
- **danger-full-access**: No filesystem sandboxing.
31+
Filesystem sandboxing defines which files can be read or written. The options for `sandbox_mode` are:
32+
- **read-only**: The sandbox only permits reading files.
33+
- **workspace-write**: The sandbox permits reading files, and editing files in `cwd` and `writable_roots`. Editing files in other directories requires approval.
34+
- **danger-full-access**: No filesystem sandboxing - all commands are permitted.
3535

36-
Network sandboxing defines whether network can be accessed without approval. Options are
36+
Network sandboxing defines whether network can be accessed without approval. Options for `network_access` are:
3737
- **restricted**: Requires approval
3838
- **enabled**: No approval needed
3939

40-
Approvals are your mechanism to get user consent to perform more privileged actions. Although they introduce friction to the user because your work is paused until the user responds, you should leverage them to accomplish your important work. Do not let these settings or the sandbox deter you from attempting to accomplish the user's task unless it is set to "never", in which case never ask for approvals.
41-
42-
Approval options are
40+
Approvals are your mechanism to get user consent to run shell commands without the sandbox. Possible configuration options for `approval_policy` are
4341
- **untrusted**: The harness will escalate most commands for user approval, apart from a limited allowlist of safe "read" commands.
4442
- **on-failure**: The harness will allow all commands to run in the sandbox (if enabled), and failures will be escalated to the user for approval to run again without the sandbox.
4543
- **on-request**: Commands will be run in the sandbox by default, and you can specify in your tool call if you want to escalate a command to run without sandboxing. (Note that this mode is not always available. If it is, you'll see parameters for it in the `shell` command description.)
4644
- **never**: This is a non-interactive mode where you may NEVER ask the user for approval to run commands. Instead, you must always persist and work around constraints to solve the task for the user. You MUST do your utmost best to finish the task and validate your work before yielding. If this mode is paired with `danger-full-access`, take advantage of it to deliver the best outcome for the user. Further, in this mode, your default testing philosophy is overridden: Even if you don't see local patterns for testing, you may add tests and scripts to validate your work. Just remove them before yielding.
4745

48-
When you are running with approvals `on-request`, and sandboxing enabled, here are scenarios where you'll need to request approval:
49-
- You need to run a command that writes to a directory that requires it (e.g. running tests that write to /tmp)
46+
When you are running with `approval_policy == on-request`, and sandboxing enabled, here are scenarios where you'll need to request approval:
47+
- You need to run a command that writes to a directory that requires it (e.g. running tests that write to /var)
5048
- You need to run a GUI app (e.g., open/xdg-open/osascript) to open browsers or files.
5149
- You are running sandboxed and need to run a command that requires network access (e.g. installing packages)
52-
- If you run a command that is important to solving the user's query, but it fails because of sandboxing, rerun the command with approval.
50+
- If you run a command that is important to solving the user's query, but it fails because of sandboxing, rerun the command with approval. ALWAYS proceed to use the `with_escalated_permissions` and `justification` parameters - do not message the user before requesting approval for the command.
5351
- You are about to take a potentially destructive action such as an `rm` or `git reset` that the user did not explicitly ask for
5452
- (for all of these, you should weigh alternative paths that do not require approval)
5553

56-
When sandboxing is set to read-only, you'll need to request approval for any command that isn't a read.
54+
When `sandbox_mode` is set to read-only, you'll need to request approval for any command that isn't a read.
5755

5856
You will be told what filesystem sandboxing, network sandboxing, and approval mode are active in a developer or user message. If you are not told about this, assume that you are running with workspace-write, network sandboxing enabled, and approval on-failure.
5957

58+
Although they introduce friction to the user because your work is paused until the user responds, you should leverage them when necessary to accomplish important work. If the completing the task requires escalated permissions, Do not let these settings or the sandbox deter you from attempting to accomplish the user's task unless it is set to "never", in which case never ask for approvals.
59+
60+
When requesting approval to execute a command that will require escalated privileges:
61+
- Provide the `with_escalated_permissions` parameter with the boolean value true
62+
- Include a short, 1 sentence explanation for why you need to enable `with_escalated_permissions` in the justification parameter
63+
6064
## Special user requests
6165

6266
- If the user makes a simple request (such as asking for the time) which you can fulfill by running a terminal command (such as `date`), you should do so.

codex-rs/core/src/client_common.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ pub struct Prompt {
3434
}
3535

3636
impl Prompt {
37-
pub(crate) fn get_full_instructions(&self, model: &ModelFamily) -> Cow<'_, str> {
37+
pub(crate) fn get_full_instructions<'a>(&'a self, model: &'a ModelFamily) -> Cow<'a, str> {
3838
let base = self
3939
.base_instructions_override
4040
.as_deref()
4141
.unwrap_or(model.base_instructions.deref());
42-
let mut sections: Vec<&str> = vec![base];
43-
4442
// When there are no custom instructions, add apply_patch_tool_instructions if:
4543
// - the model needs special instructions (4.1)
4644
// AND
@@ -54,9 +52,10 @@ impl Prompt {
5452
&& model.needs_special_apply_patch_instructions
5553
&& !is_apply_patch_tool_present
5654
{
57-
sections.push(APPLY_PATCH_TOOL_INSTRUCTIONS);
55+
Cow::Owned(format!("{base}\n{APPLY_PATCH_TOOL_INSTRUCTIONS}"))
56+
} else {
57+
Cow::Borrowed(base)
5858
}
59-
Cow::Owned(sections.join("\n"))
6059
}
6160

6261
pub(crate) fn get_formatted_input(&self) -> Vec<ResponseItem> {

0 commit comments

Comments
 (0)