diff --git a/codex-rs/core/src/client_common.rs b/codex-rs/core/src/client_common.rs index 5a361062..d30da519 100644 --- a/codex-rs/core/src/client_common.rs +++ b/codex-rs/core/src/client_common.rs @@ -159,12 +159,16 @@ fn build_structured_output(parsed: &ExecOutputJson) -> String { parsed.metadata.duration_seconds )); + let mut output = parsed.output.clone(); if let Some(total_lines) = extract_total_output_lines(&parsed.output) { sections.push(format!("Total output lines: {total_lines}")); + if let Some(stripped) = strip_total_output_header(&output) { + output = stripped.to_string(); + } } sections.push("Output:".to_string()); - sections.push(parsed.output.clone()); + sections.push(output); sections.join("\n") } @@ -177,6 +181,13 @@ fn extract_total_output_lines(output: &str) -> Option { total_segment.parse::().ok() } +fn strip_total_output_header(output: &str) -> Option<&str> { + let after_prefix = output.strip_prefix("Total output lines: ")?; + let (_, remainder) = after_prefix.split_once('\n')?; + let remainder = remainder.strip_prefix('\n').unwrap_or(remainder); + Some(remainder) +} + #[derive(Debug)] pub enum ResponseEvent { Created, diff --git a/codex-rs/core/tests/suite/shell_serialization.rs b/codex-rs/core/tests/suite/shell_serialization.rs index 4e29215f..67fc2786 100644 --- a/codex-rs/core/tests/suite/shell_serialization.rs +++ b/codex-rs/core/tests/suite/shell_serialization.rs @@ -255,17 +255,17 @@ async fn shell_output_reserializes_truncated_content() -> Result<()> { Wall time: [0-9]+(?:\.[0-9]+)? seconds Total output lines: 400 Output: -Total output lines: 400 - 1 2 3 4 5 6 -.*\[\.{3} omitted \d+ of 400 lines \.{3}\] +.* +\[\.{3} omitted \d+ of 400 lines \.{3}\] -.*\n396 +.* +396 397 398 399 diff --git a/codex-rs/core/tests/suite/tools.rs b/codex-rs/core/tests/suite/tools.rs index e57cd0a5..08826a1a 100644 --- a/codex-rs/core/tests/suite/tools.rs +++ b/codex-rs/core/tests/suite/tools.rs @@ -516,7 +516,6 @@ async fn shell_sandbox_denied_truncates_error_output() -> Result<()> { Wall time: [0-9]+(?:\.[0-9]+)? seconds Total output lines: \d+ Output: -Total output lines: \d+ failed in sandbox: .*?(?:Operation not permitted|Permission denied|Read-only file system).*? \[\.{3} omitted \d+ of \d+ lines \.{3}\] @@ -601,7 +600,6 @@ execution error: .*$"#; Wall time: [0-9]+(?:\.[0-9]+)? seconds Total output lines: \d+ Output: -Total output lines: \d+ execution error: .*$"#; let spawn_error_regex = Regex::new(spawn_error_pattern)?;