mirror of
https://github.com/openai/codex.git
synced 2026-05-04 11:26:33 +00:00
feat: skip memory startup when Codex rate limits are low (#19990)
## Why Memory startup runs in the background after an eligible turn, but it can consume Codex backend quota at exactly the wrong time: when the user is already near a rate-limit boundary. This PR adds a guard so the memory pipeline backs off when the Codex rate-limit snapshot says the remaining budget is too low. ## What Changed - Added `memories.min_rate_limit_remaining_percent` with a default of `25`, clamped to `0..=100`, and regenerated `core/config.schema.json`. - Added `codex-rs/memories/write/src/guard.rs`, which fetches Codex backend rate limits before memory startup and skips phase 1 / phase 2 when the Codex limit is reached or either tracked window is above the configured usage ceiling. - Keeps startup best-effort: non-Codex auth or rate-limit fetch/client failures preserve the existing memory startup behavior. - Records a `codex.memory.startup` counter with `status=skipped_rate_limit` when startup is skipped. - Added config parsing/clamping coverage and guard unit tests. ## Verification - Added `codex-rs/memories/write/src/guard_tests.rs` for threshold, primary/secondary window, and reached-limit behavior. - Added config tests for TOML parsing and clamping.
This commit is contained in:
@@ -32,6 +32,7 @@ pub const DEFAULT_OTEL_ENVIRONMENT: &str = "dev";
|
||||
pub const DEFAULT_MEMORIES_MAX_ROLLOUTS_PER_STARTUP: usize = 2;
|
||||
pub const DEFAULT_MEMORIES_MAX_ROLLOUT_AGE_DAYS: i64 = 10;
|
||||
pub const DEFAULT_MEMORIES_MIN_ROLLOUT_IDLE_HOURS: i64 = 6;
|
||||
pub const DEFAULT_MEMORIES_MIN_RATE_LIMIT_REMAINING_PERCENT: i64 = 25;
|
||||
pub const DEFAULT_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 256;
|
||||
pub const DEFAULT_MEMORIES_MAX_UNUSED_DAYS: i64 = 30;
|
||||
const MIN_MEMORIES_MAX_RAW_MEMORIES_FOR_CONSOLIDATION: usize = 1;
|
||||
@@ -204,6 +205,9 @@ pub struct MemoriesToml {
|
||||
pub max_rollouts_per_startup: Option<usize>,
|
||||
/// Minimum idle time between last thread activity and memory creation (hours). > 12h recommended.
|
||||
pub min_rollout_idle_hours: Option<i64>,
|
||||
/// Minimum remaining percentage required in Codex rate-limit windows before memory startup runs.
|
||||
#[schemars(range(min = 0, max = 100))]
|
||||
pub min_rate_limit_remaining_percent: Option<i64>,
|
||||
/// Model used for thread summarisation.
|
||||
pub extract_model: Option<String>,
|
||||
/// Model used for memory consolidation.
|
||||
@@ -221,6 +225,7 @@ pub struct MemoriesConfig {
|
||||
pub max_rollout_age_days: i64,
|
||||
pub max_rollouts_per_startup: usize,
|
||||
pub min_rollout_idle_hours: i64,
|
||||
pub min_rate_limit_remaining_percent: i64,
|
||||
pub extract_model: Option<String>,
|
||||
pub consolidation_model: Option<String>,
|
||||
}
|
||||
@@ -236,6 +241,7 @@ impl Default for MemoriesConfig {
|
||||
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,
|
||||
min_rate_limit_remaining_percent: DEFAULT_MEMORIES_MIN_RATE_LIMIT_REMAINING_PERCENT,
|
||||
extract_model: None,
|
||||
consolidation_model: None,
|
||||
}
|
||||
@@ -277,6 +283,10 @@ impl From<MemoriesToml> for MemoriesConfig {
|
||||
.min_rollout_idle_hours
|
||||
.unwrap_or(defaults.min_rollout_idle_hours)
|
||||
.clamp(1, 48),
|
||||
min_rate_limit_remaining_percent: toml
|
||||
.min_rate_limit_remaining_percent
|
||||
.unwrap_or(defaults.min_rate_limit_remaining_percent)
|
||||
.clamp(0, 100),
|
||||
extract_model: toml.extract_model,
|
||||
consolidation_model: toml.consolidation_model,
|
||||
}
|
||||
|
||||
@@ -59,3 +59,30 @@ fn memories_config_clamps_count_limits_to_nonzero_values() {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn memories_config_clamps_rate_limit_remaining_threshold() {
|
||||
let config = MemoriesConfig::from(MemoriesToml {
|
||||
min_rate_limit_remaining_percent: Some(101),
|
||||
..Default::default()
|
||||
});
|
||||
assert_eq!(
|
||||
config,
|
||||
MemoriesConfig {
|
||||
min_rate_limit_remaining_percent: 100,
|
||||
..MemoriesConfig::default()
|
||||
}
|
||||
);
|
||||
|
||||
let config = MemoriesConfig::from(MemoriesToml {
|
||||
min_rate_limit_remaining_percent: Some(-1),
|
||||
..Default::default()
|
||||
});
|
||||
assert_eq!(
|
||||
config,
|
||||
MemoriesConfig {
|
||||
min_rate_limit_remaining_percent: 0,
|
||||
..MemoriesConfig::default()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user