diff --git a/codex-rs/core/config.schema.json b/codex-rs/core/config.schema.json index 672562886..689538102 100644 --- a/codex-rs/core/config.schema.json +++ b/codex-rs/core/config.schema.json @@ -616,11 +616,19 @@ "additionalProperties": false, "description": "Memories settings loaded from config.toml.", "properties": { + "consolidation_model": { + "description": "Model used for memory consolidation.", + "type": "string" + }, + "extract_model": { + "description": "Model used for thread summarisation.", + "type": "string" + }, "generate_memories": { "description": "When `false`, newly created threads are stored with `memory_mode = \"disabled\"` in the state DB.", "type": "boolean" }, - "max_raw_memories_for_global": { + "max_raw_memories_for_consolidation": { "description": "Maximum number of recent raw memories retained for global consolidation.", "format": "uint", "minimum": 0.0, @@ -651,14 +659,6 @@ "description": "When `true`, web searches and MCP tool calls mark the thread `memory_mode` as `\"polluted\"`.", "type": "boolean" }, - "phase_1_model": { - "description": "Model used for thread summarisation.", - "type": "string" - }, - "phase_2_model": { - "description": "Model used for memory consolidation.", - "type": "string" - }, "use_memories": { "description": "When `false`, skip injecting memory usage instructions into developer prompts.", "type": "boolean" diff --git a/codex-rs/core/src/config/mod.rs b/codex-rs/core/src/config/mod.rs index 93f928faf..b5520a2f0 100644 --- a/codex-rs/core/src/config/mod.rs +++ b/codex-rs/core/src/config/mod.rs @@ -2508,13 +2508,13 @@ persistence = "none" no_memories_if_mcp_or_web_search = true generate_memories = false use_memories = false -max_raw_memories_for_global = 512 +max_raw_memories_for_consolidation = 512 max_unused_days = 21 max_rollout_age_days = 42 max_rollouts_per_startup = 9 min_rollout_idle_hours = 24 -phase_1_model = "gpt-5-mini" -phase_2_model = "gpt-5" +extract_model = "gpt-5-mini" +consolidation_model = "gpt-5" "#; let memories_cfg = toml::from_str::(memories).expect("TOML deserialization should succeed"); @@ -2523,13 +2523,13 @@ phase_2_model = "gpt-5" no_memories_if_mcp_or_web_search: Some(true), generate_memories: Some(false), use_memories: Some(false), - max_raw_memories_for_global: Some(512), + max_raw_memories_for_consolidation: Some(512), max_unused_days: Some(21), max_rollout_age_days: Some(42), max_rollouts_per_startup: Some(9), min_rollout_idle_hours: Some(24), - phase_1_model: Some("gpt-5-mini".to_string()), - phase_2_model: Some("gpt-5".to_string()), + extract_model: Some("gpt-5-mini".to_string()), + consolidation_model: Some("gpt-5".to_string()), }), memories_cfg.memories ); @@ -2546,13 +2546,13 @@ phase_2_model = "gpt-5" no_memories_if_mcp_or_web_search: true, generate_memories: false, use_memories: false, - max_raw_memories_for_global: 512, + max_raw_memories_for_consolidation: 512, max_unused_days: 21, max_rollout_age_days: 42, max_rollouts_per_startup: 9, min_rollout_idle_hours: 24, - phase_1_model: Some("gpt-5-mini".to_string()), - phase_2_model: Some("gpt-5".to_string()), + extract_model: Some("gpt-5-mini".to_string()), + consolidation_model: Some("gpt-5".to_string()), } ); } diff --git a/codex-rs/core/src/config/types.rs b/codex-rs/core/src/config/types.rs index 469405c8f..39b56ee4a 100644 --- a/codex-rs/core/src/config/types.rs +++ b/codex-rs/core/src/config/types.rs @@ -26,7 +26,7 @@ pub const DEFAULT_OTEL_ENVIRONMENT: &str = "dev"; pub const DEFAULT_MEMORIES_MAX_ROLLOUTS_PER_STARTUP: usize = 16; pub const DEFAULT_MEMORIES_MAX_ROLLOUT_AGE_DAYS: i64 = 30; pub const DEFAULT_MEMORIES_MIN_ROLLOUT_IDLE_HOURS: i64 = 6; -pub const DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL: usize = 256; +pub const DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 256; pub const DEFAULT_MEMORIES_MAX_UNUSED_DAYS: i64 = 30; #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema)] @@ -378,7 +378,7 @@ pub struct MemoriesToml { /// When `false`, skip injecting memory usage instructions into developer prompts. pub use_memories: Option, /// Maximum number of recent raw memories retained for global consolidation. - pub max_raw_memories_for_global: Option, + pub max_raw_memories_for_consolidation: Option, /// Maximum number of days since a memory was last used before it becomes ineligible for phase 2 selection. pub max_unused_days: Option, /// Maximum age of the threads used for memories. @@ -388,9 +388,9 @@ pub struct MemoriesToml { /// Minimum idle time between last thread activity and memory creation (hours). > 12h recommended. pub min_rollout_idle_hours: Option, /// Model used for thread summarisation. - pub phase_1_model: Option, + pub extract_model: Option, /// Model used for memory consolidation. - pub phase_2_model: Option, + pub consolidation_model: Option, } /// Effective memories settings after defaults are applied. @@ -399,13 +399,13 @@ pub struct MemoriesConfig { pub no_memories_if_mcp_or_web_search: bool, pub generate_memories: bool, pub use_memories: bool, - pub max_raw_memories_for_global: usize, + pub max_raw_memories_for_consolidation: usize, pub max_unused_days: i64, pub max_rollout_age_days: i64, pub max_rollouts_per_startup: usize, pub min_rollout_idle_hours: i64, - pub phase_1_model: Option, - pub phase_2_model: Option, + pub extract_model: Option, + pub consolidation_model: Option, } impl Default for MemoriesConfig { @@ -414,13 +414,13 @@ impl Default for MemoriesConfig { no_memories_if_mcp_or_web_search: false, generate_memories: true, use_memories: true, - max_raw_memories_for_global: DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + max_raw_memories_for_consolidation: DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, max_unused_days: DEFAULT_MEMORIES_MAX_UNUSED_DAYS, max_rollout_age_days: DEFAULT_MEMORIES_MAX_ROLLOUT_AGE_DAYS, max_rollouts_per_startup: DEFAULT_MEMORIES_MAX_ROLLOUTS_PER_STARTUP, min_rollout_idle_hours: DEFAULT_MEMORIES_MIN_ROLLOUT_IDLE_HOURS, - phase_1_model: None, - phase_2_model: None, + extract_model: None, + consolidation_model: None, } } } @@ -434,9 +434,9 @@ impl From for MemoriesConfig { .unwrap_or(defaults.no_memories_if_mcp_or_web_search), generate_memories: toml.generate_memories.unwrap_or(defaults.generate_memories), use_memories: toml.use_memories.unwrap_or(defaults.use_memories), - max_raw_memories_for_global: toml - .max_raw_memories_for_global - .unwrap_or(defaults.max_raw_memories_for_global) + max_raw_memories_for_consolidation: toml + .max_raw_memories_for_consolidation + .unwrap_or(defaults.max_raw_memories_for_consolidation) .min(4096), max_unused_days: toml .max_unused_days @@ -454,8 +454,8 @@ impl From for MemoriesConfig { .min_rollout_idle_hours .unwrap_or(defaults.min_rollout_idle_hours) .clamp(1, 48), - phase_1_model: toml.phase_1_model, - phase_2_model: toml.phase_2_model, + extract_model: toml.extract_model, + consolidation_model: toml.consolidation_model, } } } diff --git a/codex-rs/core/src/memories/phase1.rs b/codex-rs/core/src/memories/phase1.rs index d2fb6d11f..fd6d4ed64 100644 --- a/codex-rs/core/src/memories/phase1.rs +++ b/codex-rs/core/src/memories/phase1.rs @@ -193,7 +193,7 @@ async fn claim_startup_jobs( async fn build_request_context(session: &Arc, config: &Config) -> RequestContext { let model_name = config .memories - .phase_1_model + .extract_model .clone() .unwrap_or(phase_one::MODEL.to_string()); let model = session diff --git a/codex-rs/core/src/memories/phase2.rs b/codex-rs/core/src/memories/phase2.rs index fb6e99d2d..ff13e4f64 100644 --- a/codex-rs/core/src/memories/phase2.rs +++ b/codex-rs/core/src/memories/phase2.rs @@ -52,7 +52,7 @@ pub(super) async fn run(session: &Arc, config: Arc) { return; }; let root = memory_root(&config.codex_home); - let max_raw_memories = config.memories.max_raw_memories_for_global; + let max_raw_memories = config.memories.max_raw_memories_for_consolidation; let max_unused_days = config.memories.max_unused_days; // 1. Claim the job. @@ -294,7 +294,7 @@ mod agent { agent_config.model = Some( config .memories - .phase_2_model + .consolidation_model .clone() .unwrap_or(phase_two::MODEL.to_string()), ); diff --git a/codex-rs/core/src/memories/storage.rs b/codex-rs/core/src/memories/storage.rs index 1410c4e73..68f75a095 100644 --- a/codex-rs/core/src/memories/storage.rs +++ b/codex-rs/core/src/memories/storage.rs @@ -13,21 +13,21 @@ use crate::memories::rollout_summaries_dir; pub(super) async fn rebuild_raw_memories_file_from_memories( root: &Path, memories: &[Stage1Output], - max_raw_memories_for_global: usize, + max_raw_memories_for_consolidation: usize, ) -> std::io::Result<()> { ensure_layout(root).await?; - rebuild_raw_memories_file(root, memories, max_raw_memories_for_global).await + rebuild_raw_memories_file(root, memories, max_raw_memories_for_consolidation).await } /// Syncs canonical rollout summary files from DB-backed stage-1 output rows. pub(super) async fn sync_rollout_summaries_from_memories( root: &Path, memories: &[Stage1Output], - max_raw_memories_for_global: usize, + max_raw_memories_for_consolidation: usize, ) -> std::io::Result<()> { ensure_layout(root).await?; - let retained = retained_memories(memories, max_raw_memories_for_global); + let retained = retained_memories(memories, max_raw_memories_for_consolidation); let keep = retained .iter() .map(rollout_summary_file_stem) @@ -62,9 +62,9 @@ pub(super) async fn sync_rollout_summaries_from_memories( async fn rebuild_raw_memories_file( root: &Path, memories: &[Stage1Output], - max_raw_memories_for_global: usize, + max_raw_memories_for_consolidation: usize, ) -> std::io::Result<()> { - let retained = retained_memories(memories, max_raw_memories_for_global); + let retained = retained_memories(memories, max_raw_memories_for_consolidation); let mut body = String::from("# Raw Memories\n\n"); if retained.is_empty() { @@ -155,9 +155,9 @@ async fn write_rollout_summary_for_thread( fn retained_memories( memories: &[Stage1Output], - max_raw_memories_for_global: usize, + max_raw_memories_for_consolidation: usize, ) -> &[Stage1Output] { - &memories[..memories.len().min(max_raw_memories_for_global)] + &memories[..memories.len().min(max_raw_memories_for_consolidation)] } fn raw_memories_format_error(err: std::fmt::Error) -> std::io::Error { diff --git a/codex-rs/core/src/memories/tests.rs b/codex-rs/core/src/memories/tests.rs index 62cef7eae..0ebc0b8f1 100644 --- a/codex-rs/core/src/memories/tests.rs +++ b/codex-rs/core/src/memories/tests.rs @@ -1,6 +1,6 @@ use super::storage::rebuild_raw_memories_file_from_memories; use super::storage::sync_rollout_summaries_from_memories; -use crate::config::types::DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL; +use crate::config::types::DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION; use crate::memories::ensure_layout; use crate::memories::memory_root; use crate::memories::raw_memories_file; @@ -95,14 +95,14 @@ async fn sync_rollout_summaries_and_raw_memories_file_keeps_latest_memories_only sync_rollout_summaries_from_memories( &root, &memories, - DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, ) .await .expect("sync rollout summaries"); rebuild_raw_memories_file_from_memories( &root, &memories, - DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, ) .await .expect("rebuild raw memories"); @@ -201,7 +201,7 @@ async fn sync_rollout_summaries_uses_timestamp_hash_and_sanitized_slug_filename( sync_rollout_summaries_from_memories( &root, &memories, - DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, ) .await .expect("sync rollout summaries"); @@ -304,14 +304,14 @@ task_outcome: success sync_rollout_summaries_from_memories( &root, &memories, - DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, ) .await .expect("sync rollout summaries"); rebuild_raw_memories_file_from_memories( &root, &memories, - DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_GLOBAL, + DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION, ) .await .expect("rebuild raw memories"); diff --git a/codex-rs/core/tests/suite/memories.rs b/codex-rs/core/tests/suite/memories.rs index fce663cf9..80e2d6ff6 100644 --- a/codex-rs/core/tests/suite/memories.rs +++ b/codex-rs/core/tests/suite/memories.rs @@ -168,7 +168,7 @@ async fn web_search_pollution_moves_selected_thread_into_removed_phase2_inputs() let mut initial_builder = test_codex().with_home(home.clone()).with_config(|config| { config.features.enable(Feature::Sqlite); config.features.enable(Feature::MemoryTool); - config.memories.max_raw_memories_for_global = 1; + config.memories.max_raw_memories_for_consolidation = 1; config.memories.no_memories_if_mcp_or_web_search = true; }); let initial = initial_builder.build(&server).await?; @@ -234,7 +234,7 @@ async fn web_search_pollution_moves_selected_thread_into_removed_phase2_inputs() let mut resumed_builder = test_codex().with_home(home.clone()).with_config(|config| { config.features.enable(Feature::Sqlite); config.features.enable(Feature::MemoryTool); - config.memories.max_raw_memories_for_global = 1; + config.memories.max_raw_memories_for_consolidation = 1; config.memories.no_memories_if_mcp_or_web_search = true; }); let resumed = resumed_builder @@ -313,7 +313,7 @@ async fn build_test_codex(server: &wiremock::MockServer, home: Arc) -> let mut builder = test_codex().with_home(home).with_config(|config| { config.features.enable(Feature::Sqlite); config.features.enable(Feature::MemoryTool); - config.memories.max_raw_memories_for_global = 1; + config.memories.max_raw_memories_for_consolidation = 1; }); builder.build(server).await }