From 377b251d595209501ab057ae9f2e3ccd7cd3f417 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Fri, 24 Oct 2025 13:32:54 -0700 Subject: [PATCH] tests --- codex-rs/core/src/context_manager/manager.rs | 14 +++-- .../core/src/context_manager/truncation.rs | 61 +++++++++++++++++-- codex-rs/core/src/tools/context.rs | 50 +-------------- codex-rs/core/src/tools/mod.rs | 6 -- 4 files changed, 64 insertions(+), 67 deletions(-) diff --git a/codex-rs/core/src/context_manager/manager.rs b/codex-rs/core/src/context_manager/manager.rs index 4df513fbc9..4fa3e95f7b 100644 --- a/codex-rs/core/src/context_manager/manager.rs +++ b/codex-rs/core/src/context_manager/manager.rs @@ -390,8 +390,8 @@ fn is_api_message(message: &ResponseItem) -> bool { #[cfg(test)] mod tests { use super::*; - use crate::context_manager::truncation::CONTEXT_OUTPUT_MAX_BYTES; - use crate::context_manager::truncation::CONTEXT_OUTPUT_TRUNCATION_NOTICE; + use crate::context_manager::truncation::TELEMETRY_PREVIEW_MAX_BYTES; + use crate::context_manager::truncation::TELEMETRY_PREVIEW_TRUNCATION_NOTICE; use codex_protocol::models::ContentItem; use codex_protocol::models::FunctionCallOutputPayload; use codex_protocol::models::LocalShellAction; @@ -468,7 +468,7 @@ mod tests { #[test] fn record_items_truncates_function_call_output() { let mut h = ContextManager::new(); - let long_content = "a".repeat(CONTEXT_OUTPUT_MAX_BYTES + 32); + let long_content = "a".repeat(TELEMETRY_PREVIEW_MAX_BYTES + 32); let item = ResponseItem::FunctionCallOutput { call_id: "call-long".to_string(), output: FunctionCallOutputPayload { @@ -484,7 +484,9 @@ mod tests { panic!("expected FunctionCallOutput variant"); }; assert!( - output.content.ends_with(CONTEXT_OUTPUT_TRUNCATION_NOTICE), + output + .content + .ends_with(TELEMETRY_PREVIEW_TRUNCATION_NOTICE), "truncated content should end with notice" ); assert!( @@ -496,7 +498,7 @@ mod tests { #[test] fn record_items_truncates_custom_tool_output() { let mut h = ContextManager::new(); - let long_content = "b".repeat(CONTEXT_OUTPUT_MAX_BYTES + 64); + let long_content = "b".repeat(TELEMETRY_PREVIEW_MAX_BYTES + 64); let item = ResponseItem::CustomToolCallOutput { call_id: "custom-long".to_string(), output: long_content.clone(), @@ -509,7 +511,7 @@ mod tests { panic!("expected CustomToolCallOutput variant"); }; assert!( - output.ends_with(CONTEXT_OUTPUT_TRUNCATION_NOTICE), + output.ends_with(TELEMETRY_PREVIEW_TRUNCATION_NOTICE), "truncated output should end with notice" ); assert!( diff --git a/codex-rs/core/src/context_manager/truncation.rs b/codex-rs/core/src/context_manager/truncation.rs index 18847810b1..5ed30bc9b6 100644 --- a/codex-rs/core/src/context_manager/truncation.rs +++ b/codex-rs/core/src/context_manager/truncation.rs @@ -7,14 +7,16 @@ pub(crate) struct TruncationConfig { pub truncation_notice: &'static str, } -pub(crate) const CONTEXT_OUTPUT_MAX_BYTES: usize = 8 * 1024; // 8 KiB -pub(crate) const CONTEXT_OUTPUT_MAX_LINES: usize = 256; -pub(crate) const CONTEXT_OUTPUT_TRUNCATION_NOTICE: &str = "[... output truncated ...]"; +// Telemetry preview limits: keep log events smaller than model budgets. +pub(crate) const TELEMETRY_PREVIEW_MAX_BYTES: usize = 2 * 1024; // 2 KiB +pub(crate) const TELEMETRY_PREVIEW_MAX_LINES: usize = 64; // lines +pub(crate) const TELEMETRY_PREVIEW_TRUNCATION_NOTICE: &str = + "[... telemetry preview truncated ...]"; pub(crate) const CONTEXT_OUTPUT_TRUNCATION: TruncationConfig = TruncationConfig { - max_bytes: CONTEXT_OUTPUT_MAX_BYTES, - max_lines: CONTEXT_OUTPUT_MAX_LINES, - truncation_notice: CONTEXT_OUTPUT_TRUNCATION_NOTICE, + max_bytes: TELEMETRY_PREVIEW_MAX_BYTES, + max_lines: TELEMETRY_PREVIEW_MAX_LINES, + truncation_notice: TELEMETRY_PREVIEW_TRUNCATION_NOTICE, }; pub(crate) fn truncate_with_config(content: &str, config: TruncationConfig) -> String { @@ -107,4 +109,51 @@ mod tests { assert!(truncated.lines().count() <= 3); assert!(truncated.contains("[notice]")); } + + #[test] + fn telemetry_preview_returns_original_within_limits() { + let content = "short output"; + let config = TruncationConfig { + max_bytes: TELEMETRY_PREVIEW_MAX_BYTES, + max_lines: TELEMETRY_PREVIEW_MAX_LINES, + truncation_notice: TELEMETRY_PREVIEW_TRUNCATION_NOTICE, + }; + assert_eq!(truncate_with_config(content, config), content); + } + + #[test] + fn telemetry_preview_truncates_by_bytes() { + let config = TruncationConfig { + max_bytes: TELEMETRY_PREVIEW_MAX_BYTES, + max_lines: TELEMETRY_PREVIEW_MAX_LINES, + truncation_notice: TELEMETRY_PREVIEW_TRUNCATION_NOTICE, + }; + let content = "x".repeat(TELEMETRY_PREVIEW_MAX_BYTES + 8); + let preview = truncate_with_config(&content, config); + + assert!(preview.contains(TELEMETRY_PREVIEW_TRUNCATION_NOTICE)); + assert!( + preview.len() + <= TELEMETRY_PREVIEW_MAX_BYTES + TELEMETRY_PREVIEW_TRUNCATION_NOTICE.len() + 1 + ); + } + + #[test] + fn telemetry_preview_truncates_by_lines() { + let config = TruncationConfig { + max_bytes: TELEMETRY_PREVIEW_MAX_BYTES, + max_lines: TELEMETRY_PREVIEW_MAX_LINES, + truncation_notice: TELEMETRY_PREVIEW_TRUNCATION_NOTICE, + }; + let content = (0..(TELEMETRY_PREVIEW_MAX_LINES + 5)) + .map(|idx| format!("line {idx}")) + .collect::>() + .join("\n"); + + let preview = truncate_with_config(&content, config); + let lines: Vec<&str> = preview.lines().collect(); + + assert!(lines.len() <= TELEMETRY_PREVIEW_MAX_LINES + 1); + assert_eq!(lines.last(), Some(&TELEMETRY_PREVIEW_TRUNCATION_NOTICE)); + } } diff --git a/codex-rs/core/src/tools/context.rs b/codex-rs/core/src/tools/context.rs index 8900c13e45..dda6260938 100644 --- a/codex-rs/core/src/tools/context.rs +++ b/codex-rs/core/src/tools/context.rs @@ -1,10 +1,5 @@ use crate::codex::Session; use crate::codex::TurnContext; -use crate::context_manager::truncation::TruncationConfig; -use crate::context_manager::truncation::truncate_with_config; -use crate::tools::TELEMETRY_PREVIEW_MAX_BYTES; -use crate::tools::TELEMETRY_PREVIEW_MAX_LINES; -use crate::tools::TELEMETRY_PREVIEW_TRUNCATION_NOTICE; use crate::turn_diff_tracker::TurnDiffTracker; use codex_otel::otel_event_manager::OtelEventManager; use codex_protocol::models::FunctionCallOutputPayload; @@ -77,7 +72,7 @@ pub enum ToolOutput { impl ToolOutput { pub fn log_preview(&self) -> String { match self { - ToolOutput::Function { content, .. } => telemetry_preview(content), + ToolOutput::Function { content, .. } => content.clone(), ToolOutput::Mcp { result } => format!("{result:?}"), } } @@ -112,17 +107,6 @@ impl ToolOutput { } } -fn telemetry_preview(content: &str) -> String { - truncate_with_config( - content, - TruncationConfig { - max_bytes: TELEMETRY_PREVIEW_MAX_BYTES, - max_lines: TELEMETRY_PREVIEW_MAX_LINES, - truncation_notice: TELEMETRY_PREVIEW_TRUNCATION_NOTICE, - }, - ) -} - #[cfg(test)] mod tests { use super::*; @@ -168,38 +152,6 @@ mod tests { other => panic!("expected FunctionCallOutput, got {other:?}"), } } - - #[test] - fn telemetry_preview_returns_original_within_limits() { - let content = "short output"; - assert_eq!(telemetry_preview(content), content); - } - - #[test] - fn telemetry_preview_truncates_by_bytes() { - let content = "x".repeat(TELEMETRY_PREVIEW_MAX_BYTES + 8); - let preview = telemetry_preview(&content); - - assert!(preview.contains(TELEMETRY_PREVIEW_TRUNCATION_NOTICE)); - assert!( - preview.len() - <= TELEMETRY_PREVIEW_MAX_BYTES + TELEMETRY_PREVIEW_TRUNCATION_NOTICE.len() + 1 - ); - } - - #[test] - fn telemetry_preview_truncates_by_lines() { - let content = (0..(TELEMETRY_PREVIEW_MAX_LINES + 5)) - .map(|idx| format!("line {idx}")) - .collect::>() - .join("\n"); - - let preview = telemetry_preview(&content); - let lines: Vec<&str> = preview.lines().collect(); - - assert!(lines.len() <= TELEMETRY_PREVIEW_MAX_LINES + 1); - assert_eq!(lines.last(), Some(&TELEMETRY_PREVIEW_TRUNCATION_NOTICE)); - } } #[derive(Clone, Debug)] diff --git a/codex-rs/core/src/tools/mod.rs b/codex-rs/core/src/tools/mod.rs index f22d064b51..edb333915e 100644 --- a/codex-rs/core/src/tools/mod.rs +++ b/codex-rs/core/src/tools/mod.rs @@ -22,12 +22,6 @@ pub(crate) const MODEL_FORMAT_HEAD_LINES: usize = MODEL_FORMAT_MAX_LINES / 2; pub(crate) const MODEL_FORMAT_TAIL_LINES: usize = MODEL_FORMAT_MAX_LINES - MODEL_FORMAT_HEAD_LINES; // 128 pub(crate) const MODEL_FORMAT_HEAD_BYTES: usize = MODEL_FORMAT_MAX_BYTES / 2; -// Telemetry preview limits: keep log events smaller than model budgets. -pub(crate) const TELEMETRY_PREVIEW_MAX_BYTES: usize = 2 * 1024; // 2 KiB -pub(crate) const TELEMETRY_PREVIEW_MAX_LINES: usize = 64; // lines -pub(crate) const TELEMETRY_PREVIEW_TRUNCATION_NOTICE: &str = - "[... telemetry preview truncated ...]"; - /// Format the combined exec output for sending back to the model. /// Includes exit code and duration metadata; truncates large bodies safely. pub fn format_exec_output_for_model(exec_output: &ExecToolCallOutput) -> String {