Add Luna Reserve usage fallback to the TUI (#42372)

## Why

When ordinary included usage is exhausted, eligible users need a way to keep working with the backend-provided Luna Reserve quota and return to their previous model once ordinary usage recovers.

## What changed

- Automatically switch eligible TUI tasks to Luna Reserve after an authoritative account usage read, preserving the prior model and reasoning effort per task.
- Restrict model selection while on Reserve to its supported reasoning levels, keep queued turns on the accepted model, and restore the saved model after a fresh read confirms recovery.
- Surface Reserve usage in the composer and `/status`, and expose `normalModelSlug` in app-server rate-limit snapshots so clients can use the associated model's display metadata without changing the request model.
- Poll account limits more frequently near exhaustion and retain compatibility with app servers that only accept the legacy null request parameters.

## Testing

- Added coverage for Reserve entry, queued-turn handling, task reconstruction, recovery authorization, account changes, model selection, usage rendering, and banner dismissal.

GitOrigin-RevId: 46a435e9531051f8cec3f6a46c4b9f7cfa479747
This commit is contained in:
dhruvgupta-oai authored and copyberry committed 2026-09-02 21:50:51 +00:00
1 parent 76f47103fe
commit 5037919777
76 files changed
+1907 -135

No files matched your search

+6
View File
@@ -4506,6 +4506,7 @@ async fn set_rate_limits_retains_previous_credits() {
let initial = RateLimitSnapshot {
limit_id: None,
limit_name: None,
normal_model_slug: None,
primary: Some(RateLimitWindow {
used_percent: 10.0,
window_minutes: Some(15),
@@ -4527,6 +4528,7 @@ async fn set_rate_limits_retains_previous_credits() {
let update = RateLimitSnapshot {
limit_id: Some("codex_other".to_string()),
limit_name: Some("codex_other".to_string()),
normal_model_slug: None,
primary: Some(RateLimitWindow {
used_percent: 40.0,
window_minutes: Some(30),
@@ -4550,6 +4552,7 @@ async fn set_rate_limits_retains_previous_credits() {
Some(RateLimitSnapshot {
limit_id: Some("codex_other".to_string()),
limit_name: Some("codex_other".to_string()),
normal_model_slug: None,
primary: update.primary.clone(),
secondary: update.secondary,
credits: initial.credits,
@@ -4622,6 +4625,7 @@ async fn set_rate_limits_updates_plan_type_when_present() {
let initial = RateLimitSnapshot {
limit_id: None,
limit_name: None,
normal_model_slug: None,
primary: Some(RateLimitWindow {
used_percent: 15.0,
window_minutes: Some(20),
@@ -4647,6 +4651,7 @@ async fn set_rate_limits_updates_plan_type_when_present() {
let update = RateLimitSnapshot {
limit_id: None,
limit_name: None,
normal_model_slug: None,
primary: Some(RateLimitWindow {
used_percent: 35.0,
window_minutes: Some(25),
@@ -4666,6 +4671,7 @@ async fn set_rate_limits_updates_plan_type_when_present() {
Some(RateLimitSnapshot {
limit_id: Some("codex".to_string()),
limit_name: None,
normal_model_slug: None,
primary: update.primary,
secondary: update.secondary,
credits: initial.credits,