[codex] Propagate rate limit reached type (#18227)

## Summary

First PR in the split from #17956.

- adds the core/app-server `RateLimitReachedType` shape
- maps backend `rate_limit_reached_type` into Codex rate-limit snapshots
- carries the field through app-server notifications/responses and
generated schemas
- updates existing constructors/tests for the new optional field

## Validation

- `cargo test -p codex-backend-client`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server rate_limits`
- `cargo test -p codex-tui workspace_`
- `cargo test -p codex-tui status_`
- `just fmt`
- `just fix -p codex-backend-client`
- `just fix -p codex-app-server-protocol`
- `just fix -p codex-app-server`
- `just fix -p codex-tui`
This commit is contained in:
richardopenai
2026-04-17 13:37:25 -07:00
committed by GitHub
parent f017a23835
commit 139fa8b8f2
27 changed files with 371 additions and 6 deletions
@@ -106,6 +106,7 @@ pub(super) fn snapshot(percent: f64) -> RateLimitSnapshot {
secondary: None,
credits: None,
plan_type: None,
rate_limit_reached_type: None,
}
}
@@ -235,6 +235,7 @@ async fn rate_limit_snapshot_keeps_prior_credits_when_missing_from_headers() {
balance: Some("17.5".to_string()),
}),
plan_type: None,
rate_limit_reached_type: None,
}));
let initial_balance = chat
.rate_limit_snapshots_by_limit_id
@@ -254,6 +255,7 @@ async fn rate_limit_snapshot_keeps_prior_credits_when_missing_from_headers() {
secondary: None,
credits: None,
plan_type: None,
rate_limit_reached_type: None,
}));
let display = chat
@@ -292,6 +294,7 @@ async fn rate_limit_snapshot_updates_and_retains_plan_type() {
}),
credits: None,
plan_type: Some(PlanType::Plus),
rate_limit_reached_type: None,
}));
assert_eq!(chat.plan_type, Some(PlanType::Plus));
@@ -310,6 +313,7 @@ async fn rate_limit_snapshot_updates_and_retains_plan_type() {
}),
credits: None,
plan_type: Some(PlanType::Pro),
rate_limit_reached_type: None,
}));
assert_eq!(chat.plan_type, Some(PlanType::Pro));
@@ -328,6 +332,7 @@ async fn rate_limit_snapshot_updates_and_retains_plan_type() {
}),
credits: None,
plan_type: None,
rate_limit_reached_type: None,
}));
assert_eq!(chat.plan_type, Some(PlanType::Pro));
}
@@ -351,6 +356,7 @@ async fn rate_limit_snapshots_keep_separate_entries_per_limit_id() {
balance: Some("5.00".to_string()),
}),
plan_type: Some(PlanType::Pro),
rate_limit_reached_type: None,
}));
chat.on_rate_limit_snapshot(Some(RateLimitSnapshot {
@@ -364,6 +370,7 @@ async fn rate_limit_snapshots_keep_separate_entries_per_limit_id() {
secondary: None,
credits: None,
plan_type: Some(PlanType::Pro),
rate_limit_reached_type: None,
}));
let codex = chat
@@ -416,6 +423,7 @@ async fn rate_limit_switch_prompt_skips_non_codex_limit() {
secondary: None,
credits: None,
plan_type: None,
rate_limit_reached_type: None,
}));
assert!(matches!(