Skip to content

Commit cb96a38

Browse files
authored
Merge branch 'main' into fix/status-global-agents
2 parents 9d24133 + de64f5f commit cb96a38

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

+1381
-704
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/src/bash.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ pub fn try_parse_word_only_commands_sequence(tree: &Tree, src: &str) -> Option<V
7373
}
7474
}
7575

76+
// Walk uses a stack (LIFO), so re-sort by position to restore source order.
77+
command_nodes.sort_by_key(|node| node.start_byte());
78+
7679
let mut commands = Vec::new();
7780
for node in command_nodes {
7881
if let Some(words) = parse_plain_command_from_node(node, src) {
@@ -150,10 +153,10 @@ mod tests {
150153
let src = "ls && pwd; echo 'hi there' | wc -l";
151154
let cmds = parse_seq(src).unwrap();
152155
let expected: Vec<Vec<String>> = vec![
153-
vec!["wc".to_string(), "-l".to_string()],
154-
vec!["echo".to_string(), "hi there".to_string()],
155-
vec!["pwd".to_string()],
156156
vec!["ls".to_string()],
157+
vec!["pwd".to_string()],
158+
vec!["echo".to_string(), "hi there".to_string()],
159+
vec!["wc".to_string(), "-l".to_string()],
157160
];
158161
assert_eq!(cmds, expected);
159162
}

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)