mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
core: enable remote compaction v2 by default (#27573)
## Why Remote compaction v2 is ready to become the default for providers that already support remote compaction. Leaving it behind an under-development opt-in keeps eligible sessions on the legacy remote-compaction path. This does not broaden provider eligibility: OpenAI and Azure move to v2, while Bedrock and OSS providers retain their existing local-compaction behavior. ## What changed - Mark `remote_compaction_v2` stable and enable it by default. - Make tests that intentionally cover legacy remote compaction explicitly disable v2. - Update parity coverage so v2 exercises the production default and only legacy mode opts out. ## Verification - `just test -p codex-core auto_compact_runs_after_resume_when_token_usage_is_over_limit auto_compact_counts_encrypted_reasoning_before_last_user auto_compact_runs_when_reasoning_header_clears_between_turns responses_lite_compact_request_uses_lite_transport_contract`
This commit is contained in:
@@ -29,6 +29,7 @@ use codex_app_server_protocol::TurnStartParams;
|
||||
use codex_app_server_protocol::TurnStartResponse;
|
||||
use codex_app_server_protocol::UserInput as V2UserInput;
|
||||
use codex_config::types::AuthCredentialsStoreMode;
|
||||
use codex_features::Feature;
|
||||
use codex_protocol::models::ContentItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use core_test_support::responses;
|
||||
@@ -150,7 +151,7 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<()
|
||||
write_mock_responses_config_toml(
|
||||
codex_home.path(),
|
||||
&server.uri(),
|
||||
&BTreeMap::default(),
|
||||
&BTreeMap::from([(Feature::RemoteCompactionV2, false)]),
|
||||
REMOTE_AUTO_COMPACT_LIMIT,
|
||||
Some(true),
|
||||
"mock_provider",
|
||||
|
||||
@@ -2015,6 +2015,7 @@ async fn auto_compact_runs_after_resume_when_token_usage_is_over_limit() {
|
||||
let mut builder = test_codex().with_config(move |config| {
|
||||
set_test_compact_prompt(config);
|
||||
config.model_auto_compact_token_limit = Some(limit);
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
});
|
||||
let initial = builder.build(&server).await.unwrap();
|
||||
let home = initial.home.clone();
|
||||
@@ -2043,6 +2044,7 @@ async fn auto_compact_runs_after_resume_when_token_usage_is_over_limit() {
|
||||
let mut resume_builder = test_codex().with_config(move |config| {
|
||||
set_test_compact_prompt(config);
|
||||
config.model_auto_compact_token_limit = Some(limit);
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
});
|
||||
let resumed = resume_builder
|
||||
.resume(&server, home, rollout_path)
|
||||
@@ -4023,6 +4025,7 @@ async fn auto_compact_counts_encrypted_reasoning_before_last_user() {
|
||||
config.chatgpt_base_url = chatgpt_base_url;
|
||||
set_test_compact_prompt(config);
|
||||
config.model_auto_compact_token_limit = Some(300);
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
})
|
||||
.build(&server)
|
||||
.await
|
||||
@@ -4145,6 +4148,7 @@ async fn auto_compact_runs_when_reasoning_header_clears_between_turns() {
|
||||
.with_config(|config| {
|
||||
set_test_compact_prompt(config);
|
||||
config.model_auto_compact_token_limit = Some(300);
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
})
|
||||
.build(&server)
|
||||
.await
|
||||
|
||||
@@ -36,7 +36,7 @@ use core_test_support::responses::start_websocket_server;
|
||||
use core_test_support::skip_if_no_network;
|
||||
use core_test_support::test_codex::TestCodexBuilder;
|
||||
use core_test_support::test_codex::TestCodexHarness;
|
||||
use core_test_support::test_codex::test_codex;
|
||||
use core_test_support::test_codex::test_codex as base_test_codex;
|
||||
use core_test_support::test_path_buf;
|
||||
use core_test_support::wait_for_event;
|
||||
use core_test_support::wait_for_event_match;
|
||||
@@ -160,6 +160,12 @@ fn compacted_summary_only_output(summary: &str) -> Vec<ResponseItem> {
|
||||
}]
|
||||
}
|
||||
|
||||
fn test_codex() -> TestCodexBuilder {
|
||||
base_test_codex().with_config(|config| {
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
})
|
||||
}
|
||||
|
||||
fn remote_realtime_test_codex_builder(
|
||||
realtime_server: &responses::WebSocketTestServer,
|
||||
) -> TestCodexBuilder {
|
||||
|
||||
@@ -529,8 +529,8 @@ async fn build_harness_inner(
|
||||
if hooks {
|
||||
trust_discovered_hooks(config);
|
||||
}
|
||||
if mode == Mode::V2 {
|
||||
let _ = config.features.enable(Feature::RemoteCompactionV2);
|
||||
if mode == Mode::Legacy {
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
}
|
||||
}))
|
||||
.await
|
||||
|
||||
@@ -34,7 +34,6 @@ use core_test_support::responses::ev_function_call;
|
||||
use core_test_support::responses::ev_message_item_added;
|
||||
use core_test_support::responses::ev_output_text_delta;
|
||||
use core_test_support::responses::ev_response_created;
|
||||
use core_test_support::responses::mount_compact_json_once;
|
||||
use core_test_support::responses::mount_sse_once;
|
||||
use core_test_support::responses::mount_sse_sequence;
|
||||
use core_test_support::responses::sse;
|
||||
@@ -1441,21 +1440,32 @@ async fn resumed_thread_runs_resume_then_compact_session_start_hooks() -> Result
|
||||
let remote_summary = "remote compact summary";
|
||||
let resume_context = "remember the resumed reef";
|
||||
let compact_context = "remember the compacted reef";
|
||||
let compacted_history = vec![
|
||||
ResponseItem::Message {
|
||||
id: None,
|
||||
role: "assistant".to_string(),
|
||||
content: vec![ContentItem::OutputText {
|
||||
text: remote_summary.to_string(),
|
||||
}],
|
||||
phase: None,
|
||||
},
|
||||
ResponseItem::Compaction {
|
||||
encrypted_content: "encrypted compact summary".to_string(),
|
||||
},
|
||||
];
|
||||
let compact_mock =
|
||||
mount_compact_json_once(&server, serde_json::json!({ "output": compacted_history })).await;
|
||||
let responses_mock = mount_sse_sequence(
|
||||
&server,
|
||||
vec![
|
||||
sse(vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_assistant_message("msg-1", "hello before resume"),
|
||||
ev_completed_with_tokens("resp-1", over_limit_tokens),
|
||||
]),
|
||||
sse(vec![
|
||||
serde_json::json!({
|
||||
"type": "response.output_item.done",
|
||||
"item": {
|
||||
"type": "compaction",
|
||||
"encrypted_content": remote_summary,
|
||||
}
|
||||
}),
|
||||
ev_completed("resp-compact"),
|
||||
]),
|
||||
sse(vec![
|
||||
ev_response_created("resp-2"),
|
||||
ev_assistant_message("msg-2", "hello after resume"),
|
||||
ev_completed("resp-2"),
|
||||
]),
|
||||
],
|
||||
)
|
||||
.await;
|
||||
|
||||
let mut builder = test_codex()
|
||||
.with_pre_build_hook(move |home| {
|
||||
@@ -1479,37 +1489,19 @@ async fn resumed_thread_runs_resume_then_compact_session_start_hooks() -> Result
|
||||
.clone()
|
||||
.context("rollout path")?;
|
||||
|
||||
mount_sse_once(
|
||||
&server,
|
||||
sse(vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_assistant_message("msg-1", "hello before resume"),
|
||||
ev_completed_with_tokens("resp-1", over_limit_tokens),
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
initial.submit_turn("hello before resume").await?;
|
||||
assert!(compact_mock.requests().is_empty());
|
||||
assert_eq!(responses_mock.requests().len(), 1);
|
||||
|
||||
let mut resume_builder = test_codex().with_config(move |config| {
|
||||
config.model_auto_compact_token_limit = Some(limit);
|
||||
trust_discovered_hooks(config);
|
||||
});
|
||||
let resumed = resume_builder.resume(&server, home, rollout_path).await?;
|
||||
let follow_up = mount_sse_once(
|
||||
&server,
|
||||
sse(vec![
|
||||
ev_response_created("resp-2"),
|
||||
ev_assistant_message("msg-2", "hello after resume"),
|
||||
ev_completed("resp-2"),
|
||||
]),
|
||||
)
|
||||
.await;
|
||||
|
||||
resumed.submit_turn("hello after resume").await?;
|
||||
|
||||
assert_eq!(compact_mock.requests().len(), 1);
|
||||
let developer_messages = follow_up.single_request().message_input_texts("developer");
|
||||
let requests = responses_mock.requests();
|
||||
assert_eq!(requests.len(), 3);
|
||||
let developer_messages = requests[2].message_input_texts("developer");
|
||||
assert!(
|
||||
developer_messages
|
||||
.iter()
|
||||
|
||||
@@ -177,10 +177,14 @@ async fn responses_lite_compact_request_uses_lite_transport_contract() -> Result
|
||||
let compact_mock =
|
||||
responses::mount_compact_json_once(&server, serde_json::json!({ "output": [] })).await;
|
||||
|
||||
let mut builder = test_codex().with_model_info_override("gpt-5.4", |model_info| {
|
||||
model_info.use_responses_lite = true;
|
||||
model_info.supports_parallel_tool_calls = true;
|
||||
});
|
||||
let mut builder = test_codex()
|
||||
.with_model_info_override("gpt-5.4", |model_info| {
|
||||
model_info.use_responses_lite = true;
|
||||
model_info.supports_parallel_tool_calls = true;
|
||||
})
|
||||
.with_config(|config| {
|
||||
let _ = config.features.disable(Feature::RemoteCompactionV2);
|
||||
});
|
||||
let test = builder.build(&server).await?;
|
||||
|
||||
test.submit_turn("Compact this conversation").await?;
|
||||
|
||||
@@ -1249,8 +1249,8 @@ pub const FEATURES: &[FeatureSpec] = &[
|
||||
FeatureSpec {
|
||||
id: Feature::RemoteCompactionV2,
|
||||
key: "remote_compaction_v2",
|
||||
stage: Stage::UnderDevelopment,
|
||||
default_enabled: false,
|
||||
stage: Stage::Stable,
|
||||
default_enabled: true,
|
||||
},
|
||||
FeatureSpec {
|
||||
id: Feature::WorkspaceDependencies,
|
||||
|
||||
@@ -150,16 +150,6 @@ fn request_permissions_tool_is_under_development() {
|
||||
assert_eq!(Feature::RequestPermissionsTool.default_enabled(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_compaction_v2_is_under_development() {
|
||||
assert_eq!(Feature::RemoteCompactionV2.stage(), Stage::UnderDevelopment);
|
||||
assert_eq!(Feature::RemoteCompactionV2.default_enabled(), false);
|
||||
assert_eq!(
|
||||
feature_for_key("remote_compaction_v2"),
|
||||
Some(Feature::RemoteCompactionV2)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn terminal_resize_reflow_is_experimental_and_enabled_by_default() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user