diff --git a/codex-rs/app-server/tests/common/models_cache.rs b/codex-rs/app-server/tests/common/models_cache.rs index 8233b1b29..2a0c10a27 100644 --- a/codex-rs/app-server/tests/common/models_cache.rs +++ b/codex-rs/app-server/tests/common/models_cache.rs @@ -47,6 +47,7 @@ fn preset_to_info(preset: &ModelPreset, priority: i32) -> ModelInfo { context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), diff --git a/codex-rs/codex-api/tests/models_integration.rs b/codex-rs/codex-api/tests/models_integration.rs index 4ee606989..5f421dc1a 100644 --- a/codex-rs/codex-api/tests/models_integration.rs +++ b/codex-rs/codex-api/tests/models_integration.rs @@ -93,6 +93,7 @@ async fn models_client_hits_models_endpoint() { context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), diff --git a/codex-rs/core/tests/suite/auto_review.rs b/codex-rs/core/tests/suite/auto_review.rs index 5fe1cbc2f..7dae7c4c6 100644 --- a/codex-rs/core/tests/suite/auto_review.rs +++ b/codex-rs/core/tests/suite/auto_review.rs @@ -256,6 +256,7 @@ fn remote_model_with_auto_review_override(slug: &str, review_model: &str) -> Mod context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), } diff --git a/codex-rs/core/tests/suite/model_switching.rs b/codex-rs/core/tests/suite/model_switching.rs index d176b5bc2..22363eabe 100644 --- a/codex-rs/core/tests/suite/model_switching.rs +++ b/codex-rs/core/tests/suite/model_switching.rs @@ -136,6 +136,7 @@ fn test_model_info( context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), } @@ -957,6 +958,7 @@ async fn model_switch_to_smaller_model_updates_token_context_window() -> Result< context_window: Some(large_context_window), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent, experimental_supported_tools: Vec::new(), }; diff --git a/codex-rs/core/tests/suite/models_cache_ttl.rs b/codex-rs/core/tests/suite/models_cache_ttl.rs index b343c4bba..5103f8212 100644 --- a/codex-rs/core/tests/suite/models_cache_ttl.rs +++ b/codex-rs/core/tests/suite/models_cache_ttl.rs @@ -365,6 +365,7 @@ fn test_remote_model(slug: &str, priority: i32) -> ModelInfo { context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), diff --git a/codex-rs/core/tests/suite/personality.rs b/codex-rs/core/tests/suite/personality.rs index 06c2fc41f..a58e5f20f 100644 --- a/codex-rs/core/tests/suite/personality.rs +++ b/codex-rs/core/tests/suite/personality.rs @@ -587,6 +587,7 @@ async fn remote_model_friendly_personality_instructions_with_feature() -> anyhow context_window: Some(128_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), @@ -701,6 +702,7 @@ async fn user_turn_personality_remote_model_template_includes_update_message() - context_window: Some(128_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index dc8df93c9..b3fc9b9db 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -499,6 +499,7 @@ async fn remote_models_remote_model_uses_unified_exec() -> Result<()> { context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), }; @@ -751,6 +752,7 @@ async fn remote_models_apply_remote_base_instructions() -> Result<()> { context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), }; @@ -1237,6 +1239,7 @@ fn test_remote_model_with_policy( context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), } diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 9f3fc16c3..7f0493ea8 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -1499,6 +1499,7 @@ async fn stdio_image_responses_are_sanitized_for_text_only_model() -> anyhow::Re context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: vec![InputModality::Text], diff --git a/codex-rs/core/tests/suite/spawn_agent_description.rs b/codex-rs/core/tests/suite/spawn_agent_description.rs index ba29b4f00..30aab8926 100644 --- a/codex-rs/core/tests/suite/spawn_agent_description.rs +++ b/codex-rs/core/tests/suite/spawn_agent_description.rs @@ -84,6 +84,7 @@ fn test_model_info( context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), } diff --git a/codex-rs/core/tests/suite/view_image.rs b/codex-rs/core/tests/suite/view_image.rs index 02fa6984b..240f386ec 100644 --- a/codex-rs/core/tests/suite/view_image.rs +++ b/codex-rs/core/tests/suite/view_image.rs @@ -1470,6 +1470,7 @@ async fn view_image_tool_returns_unsupported_message_for_text_only_model() -> an context_window: Some(272_000), max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), }; diff --git a/codex-rs/models-manager/src/model_info.rs b/codex-rs/models-manager/src/model_info.rs index 81a5c6e5e..566953dfc 100644 --- a/codex-rs/models-manager/src/model_info.rs +++ b/codex-rs/models-manager/src/model_info.rs @@ -94,6 +94,7 @@ pub fn model_info_from_slug(slug: &str) -> ModelInfo { context_window: Some(272_000), max_context_window: Some(272_000), auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: default_input_modalities(), diff --git a/codex-rs/protocol/src/openai_models.rs b/codex-rs/protocol/src/openai_models.rs index 1553ef343..5b95fee29 100644 --- a/codex-rs/protocol/src/openai_models.rs +++ b/codex-rs/protocol/src/openai_models.rs @@ -389,6 +389,9 @@ pub struct ModelInfo { /// context window when available. #[serde(default, skip_serializing_if = "Option::is_none")] pub auto_compact_token_limit: Option, + /// Opaque identifier for compaction-compatible model configurations. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub comp_hash: Option, /// Percentage of the context window considered usable for inputs, after /// reserving headroom for system prompts, tool overhead, and model output. #[serde(default = "default_effective_context_window_percent")] @@ -671,6 +674,7 @@ mod tests { context_window: None, max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: vec![], input_modalities: default_input_modalities(), @@ -940,6 +944,7 @@ mod tests { assert_eq!(model.web_search_tool_type, WebSearchToolType::Text); assert!(!model.supports_search_tool); assert!(!model.use_responses_lite); + assert_eq!(model.comp_hash, None); assert_eq!(model.auto_review_model_override, None); assert_eq!(model.tool_mode, None); } diff --git a/codex-rs/tools/src/tool_config_tests.rs b/codex-rs/tools/src/tool_config_tests.rs index 0e3917d69..7a4738772 100644 --- a/codex-rs/tools/src/tool_config_tests.rs +++ b/codex-rs/tools/src/tool_config_tests.rs @@ -39,6 +39,7 @@ fn model_with_shell_type(shell_type: ConfigShellToolType) -> ModelInfo { context_window: None, max_context_window: None, auto_compact_token_limit: None, + comp_hash: None, effective_context_window_percent: 95, experimental_supported_tools: Vec::new(), input_modalities: codex_protocol::openai_models::default_input_modalities(),