in codex-rs/tui/src/chatwidget/rate_limits.rs [169:284]
fn on_rate_limit_snapshot_from(
&mut self,
snapshot: Option<RateLimitSnapshot>,
source: RateLimitSnapshotSource,
) {
if let Some(mut snapshot) = snapshot {
let limit_id = snapshot
.limit_id
.clone()
.unwrap_or_else(|| "codex".to_string());
let limit_label = snapshot
.limit_name
.clone()
.unwrap_or_else(|| limit_id.clone());
if snapshot.credits.is_none() {
snapshot.credits = self
.rate_limit_snapshots_by_limit_id
.get(&limit_id)
.and_then(|display| display.credits.as_ref())
.map(|credits| CreditsSnapshot {
has_credits: credits.has_credits,
unlimited: credits.unlimited,
balance: credits.balance.clone(),
});
}
let preserved_individual_limit =
if matches!(source, RateLimitSnapshotSource::RollingUpdate)
&& snapshot.individual_limit.is_none()
{
self.rate_limit_snapshots_by_limit_id
.get(&limit_id)
.and_then(|display| display.individual_limit.clone())
} else {
None
};
self.plan_type = snapshot.plan_type.or(self.plan_type);
let is_codex_limit = limit_id.eq_ignore_ascii_case("codex");
if is_codex_limit
&& let Some(rate_limit_reached_type) = snapshot.rate_limit_reached_type
{
self.codex_rate_limit_reached_type = Some(rate_limit_reached_type);
}
let warnings = if is_codex_limit {
self.rate_limit_warnings.take_warnings(
snapshot
.secondary
.as_ref()
.map(|window| f64::from(window.used_percent)),
snapshot
.secondary
.as_ref()
.and_then(|window| window.window_duration_mins),
snapshot
.primary
.as_ref()
.map(|window| f64::from(window.used_percent)),
snapshot
.primary
.as_ref()
.and_then(|window| window.window_duration_mins),
)
} else {
vec![]
};
let high_usage = is_codex_limit
&& (snapshot
.secondary
.as_ref()
.map(|w| f64::from(w.used_percent) >= RATE_LIMIT_SWITCH_PROMPT_THRESHOLD)
.unwrap_or(false)
|| snapshot
.primary
.as_ref()
.map(|w| f64::from(w.used_percent) >= RATE_LIMIT_SWITCH_PROMPT_THRESHOLD)
.unwrap_or(false));
let has_workspace_credits = snapshot
.credits
.as_ref()
.map(|credits| credits.has_credits)
.unwrap_or(false);
if high_usage
&& !has_workspace_credits
&& !self.rate_limit_switch_prompt_hidden()
&& self.current_model() != NUDGE_MODEL_SLUG
&& !matches!(
self.rate_limit_switch_prompt,
RateLimitSwitchPromptState::Shown
)
{
self.rate_limit_switch_prompt = RateLimitSwitchPromptState::Pending;
}
let mut display =
rate_limit_snapshot_display_for_limit(&snapshot, limit_label, Local::now());
if display.individual_limit.is_none() {
display.individual_limit = preserved_individual_limit;
}
self.rate_limit_snapshots_by_limit_id
.insert(limit_id, display);
if !warnings.is_empty() {
for warning in warnings {
self.add_to_history(history_cell::new_warning_event(warning));
}
self.request_redraw();
}
} else {
self.rate_limit_snapshots_by_limit_id.clear();
self.codex_rate_limit_reached_type = None;
}
self.refresh_status_line();
}