From 664ee075402402fe38dc82e68d513920a49642a0 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Tue, 23 Sep 2025 09:15:16 -0700 Subject: [PATCH] Rate limits warning (#4075) Only show the highest warning rate. Change the warning threshold --- codex-rs/tui/src/chatwidget.rs | 16 +++++++---- codex-rs/tui/src/chatwidget/tests.rs | 43 +++++++++++----------------- 2 files changed, 27 insertions(+), 32 deletions(-) diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 02580a79..b665d525 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -118,7 +118,7 @@ struct RunningCommand { parsed_cmd: Vec, } -const RATE_LIMIT_WARNING_THRESHOLDS: [f64; 3] = [50.0, 75.0, 90.0]; +const RATE_LIMIT_WARNING_THRESHOLDS: [f64; 3] = [75.0, 90.0, 95.0]; #[derive(Default)] struct RateLimitWarningState { @@ -134,24 +134,30 @@ impl RateLimitWarningState { ) -> Vec { let mut warnings = Vec::new(); + let mut highest_secondary: Option = None; while self.secondary_index < RATE_LIMIT_WARNING_THRESHOLDS.len() && secondary_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.secondary_index] { - let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.secondary_index]; + highest_secondary = Some(RATE_LIMIT_WARNING_THRESHOLDS[self.secondary_index]); + self.secondary_index += 1; + } + if let Some(threshold) = highest_secondary { warnings.push(format!( "Heads up, you've used over {threshold:.0}% of your weekly limit. Run /status for a breakdown." )); - self.secondary_index += 1; } + let mut highest_primary: Option = None; while self.primary_index < RATE_LIMIT_WARNING_THRESHOLDS.len() && primary_used_percent >= RATE_LIMIT_WARNING_THRESHOLDS[self.primary_index] { - let threshold = RATE_LIMIT_WARNING_THRESHOLDS[self.primary_index]; + highest_primary = Some(RATE_LIMIT_WARNING_THRESHOLDS[self.primary_index]); + self.primary_index += 1; + } + if let Some(threshold) = highest_primary { warnings.push(format!( "Heads up, you've used over {threshold:.0}% of your 5h limit. Run /status for a breakdown." )); - self.primary_index += 1; } warnings diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs index 960a25a0..2d90b240 100644 --- a/codex-rs/tui/src/chatwidget/tests.rs +++ b/codex-rs/tui/src/chatwidget/tests.rs @@ -392,33 +392,22 @@ fn rate_limit_warnings_emit_thresholds() { warnings.extend(state.take_warnings(95.0, 10.0)); assert_eq!( - warnings.len(), - 6, - "expected one warning per threshold per limit" - ); - assert!( - warnings - .iter() - .any(|w| w.contains("Heads up, you've used over 50% of your 5h limit.")), - "expected hourly 50% warning (new copy)" - ); - assert!( - warnings - .iter() - .any(|w| w.contains("Heads up, you've used over 50% of your weekly limit.")), - "expected weekly 50% warning (new copy)" - ); - assert!( - warnings - .iter() - .any(|w| w.contains("Heads up, you've used over 90% of your 5h limit.")), - "expected hourly 90% warning (new copy)" - ); - assert!( - warnings - .iter() - .any(|w| w.contains("Heads up, you've used over 90% of your weekly limit.")), - "expected weekly 90% warning (new copy)" + warnings, + vec![ + String::from( + "Heads up, you've used over 75% of your 5h limit. Run /status for a breakdown." + ), + String::from( + "Heads up, you've used over 75% of your weekly limit. Run /status for a breakdown.", + ), + String::from( + "Heads up, you've used over 95% of your 5h limit. Run /status for a breakdown." + ), + String::from( + "Heads up, you've used over 95% of your weekly limit. Run /status for a breakdown.", + ), + ], + "expected one warning per limit for the highest crossed threshold" ); }