From d7bee6bf5507f8fef5666176f8486cf73dff7c82 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Wed, 20 May 2026 15:09:20 +0100 Subject: [PATCH] feat: compact v2 for OpenAI --- codex-rs/core/src/compact.rs | 10 ++++++++ codex-rs/core/src/compact_tests.rs | 41 ++++++++++++++++++++++++++++++ codex-rs/core/src/session/turn.rs | 3 ++- codex-rs/core/src/tasks/compact.rs | 4 +-- 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/codex-rs/core/src/compact.rs b/codex-rs/core/src/compact.rs index b5802268d3..290453fe32 100644 --- a/codex-rs/core/src/compact.rs +++ b/codex-rs/core/src/compact.rs @@ -22,6 +22,8 @@ use codex_analytics::CompactionStatus; use codex_analytics::CompactionStrategy; use codex_analytics::CompactionTrigger; use codex_analytics::now_unix_seconds; +use codex_features::Feature; +use codex_features::Features; use codex_protocol::error::CodexErr; use codex_protocol::error::Result as CodexResult; use codex_protocol::items::ContextCompactionItem; @@ -66,6 +68,14 @@ pub(crate) fn should_use_remote_compact_task(provider: &ModelProviderInfo) -> bo provider.supports_remote_compaction() } +pub(crate) fn should_use_remote_compact_task_v2( + provider: &ModelProviderInfo, + features: &Features, +) -> bool { + should_use_remote_compact_task(provider) + && (provider.is_openai() || features.enabled(Feature::RemoteCompactionV2)) +} + pub(crate) async fn run_inline_auto_compact_task( sess: Arc, turn_context: Arc, diff --git a/codex-rs/core/src/compact_tests.rs b/codex-rs/core/src/compact_tests.rs index 69bd95f2df..17142c7350 100644 --- a/codex-rs/core/src/compact_tests.rs +++ b/codex-rs/core/src/compact_tests.rs @@ -1,4 +1,6 @@ use super::*; +use codex_features::Feature; +use codex_features::Features; use codex_model_provider_info::ModelProviderInfo; use codex_model_provider_info::WireApi; use codex_protocol::models::DEFAULT_IMAGE_DETAIL; @@ -239,6 +241,45 @@ fn should_use_remote_compact_task_for_azure_provider() { assert!(should_use_remote_compact_task(&provider)); } + +#[test] +fn should_use_remote_compact_task_v2_defaults_for_openai_provider() { + let provider = ModelProviderInfo::create_openai_provider(/*base_url*/ None); + let features = Features::with_defaults(); + + assert!(should_use_remote_compact_task_v2(&provider, &features)); +} + +#[test] +fn should_use_remote_compact_task_v2_stays_feature_gated_for_azure_provider() { + let provider = ModelProviderInfo { + name: "Azure".into(), + base_url: Some("https://example.com/openai".into()), + env_key: Some("AZURE_OPENAI_API_KEY".into()), + env_key_instructions: None, + experimental_bearer_token: None, + auth: None, + aws: None, + wire_api: WireApi::Responses, + query_params: None, + http_headers: None, + env_http_headers: None, + request_max_retries: None, + stream_max_retries: None, + stream_idle_timeout_ms: None, + websocket_connect_timeout_ms: None, + requires_openai_auth: false, + supports_websockets: false, + }; + let mut features = Features::with_defaults(); + + assert!(!should_use_remote_compact_task_v2(&provider, &features)); + + features.enable(Feature::RemoteCompactionV2); + + assert!(should_use_remote_compact_task_v2(&provider, &features)); +} + #[tokio::test] async fn process_compacted_history_replaces_developer_messages() { let compacted_history = vec![ diff --git a/codex-rs/core/src/session/turn.rs b/codex-rs/core/src/session/turn.rs index 4ac511f4fa..0b3be35456 100644 --- a/codex-rs/core/src/session/turn.rs +++ b/codex-rs/core/src/session/turn.rs @@ -12,6 +12,7 @@ use crate::collect_explicit_skill_mentions; use crate::compact::InitialContextInjection; use crate::compact::run_inline_auto_compact_task; use crate::compact::should_use_remote_compact_task; +use crate::compact::should_use_remote_compact_task_v2; use crate::compact_remote::run_inline_remote_auto_compact_task; use crate::compact_remote_v2::run_inline_remote_auto_compact_task as run_inline_remote_auto_compact_task_v2; use crate::connectors; @@ -799,7 +800,7 @@ async fn run_auto_compact( phase: CompactionPhase, ) -> CodexResult { if should_use_remote_compact_task(turn_context.provider.info()) { - if turn_context.features.enabled(Feature::RemoteCompactionV2) { + if should_use_remote_compact_task_v2(turn_context.provider.info(), &turn_context.features) { run_inline_remote_auto_compact_task_v2( Arc::clone(sess), Arc::clone(turn_context), diff --git a/codex-rs/core/src/tasks/compact.rs b/codex-rs/core/src/tasks/compact.rs index dddf46391e..0609b35fe3 100644 --- a/codex-rs/core/src/tasks/compact.rs +++ b/codex-rs/core/src/tasks/compact.rs @@ -33,9 +33,7 @@ impl SessionTask for CompactTask { /*inc*/ 1, &[("type", "remote")], ); - if ctx - .features - .enabled(codex_features::Feature::RemoteCompactionV2) + if crate::compact::should_use_remote_compact_task_v2(ctx.provider.info(), &ctx.features) { crate::compact_remote_v2::run_remote_compact_task(session.clone(), ctx).await } else {