## Why
Synchronous auth header construction could silently return no credentials when managed authentication became unavailable. Callers need an error to avoid sending requests with missing or partial authentication.
## What changed
- Make `AuthProvider::add_auth_headers`, `to_auth_headers`, and auth header telemetry fallible, and propagate failures through request and WebSocket setup.
- Return a transient error when managed authentication is unavailable, and preserve network policy denials through auth error conversion.
- Retry transient MCP authentication errors while treating build errors and policy denials as terminal.
- Cancel local MCP event streams before resolving authentication so cleanup still works when credentials become unavailable.
## Testing
Add regression coverage for rejected partial authentication, async header resolution, terminal auth errors without sending requests, managed account changes, MCP retry classification, and local stream cancellation after authentication becomes unavailable.
GitOrigin-RevId: 39d981e232cba1e302de502a2fa6239101114ed1
## What changed
Add optional `native_usage_usd_micros` fields to thread usage totals and breakdown groups, and carry backend values through the client alongside existing credit and USD estimates. Missing or null native amounts remain `None`, while explicit zero amounts remain `Some(0)`.
## Testing
Add coverage for native totals and group amounts, mixed batches with legacy responses, and the distinction between missing, null, and zero native group amounts.
GitOrigin-RevId: 53891fc95807138e2eccb99d4cda1520b857dba4
## What changed
- Make Summary the initial Analytics tab, showing profile identity, token totals, streaks, activity insights, and most-used plugins and skills.
- Move daily, weekly, and cumulative token activity charts into Summary. Replace the usage menu's separate views with “View analytics”; `/usage weekly` and the other explicit modes open Summary with the requested view, while reopening from the menu retains navigation.
- Load account profiles independently of other reports, preserve missing values separately from zero, and reject responses when the active account changes. Refresh retries profile failures.
- Adapt Summary to narrow terminals and compact large chart totals and axis labels. Show the account email without its ID in the Analytics header.
- Flush queued transcript history before opening an overlay so startup output stays in the transcript.
## Testing
Add profile decoding and account identity tests, Summary layout and navigation snapshots, refresh and cancellation coverage, and regression tests for retained navigation and transcript history when opening Analytics.
GitOrigin-RevId: 6dbe6c4c98209000d8b4bc18a4e01b98fab5991a
## Why
Consumer analytics lacked a per-chat view of allowance usage and balance credit debits.
## What changed
- Add a Top chats panel for up to 100 local chats active in the past 30 days, including discovered descendants and excluding archived roots.
- Show weekly and five-hour usage as percentages of current full limits, plus balance credits including adjustments. Preserve exact credit decimals and distinguish missing values from zero.
- Support cycling sort metrics with `s`, a top-five dashboard summary, and expandable model, reasoning effort, and speed breakdowns.
- Query task usage through `query_v2` with bounded, disjoint descendant groups. Retain partial and unavailable rows, hide titles when usage is unavailable, and report ranking coverage and freshness.
## Testing
Add backend and TUI tests covering decimal precision, request and response validation, paginated archived descendants, unavailable responses, metric selection, title hiding, and top-five rendering.
GitOrigin-RevId: b8f233166576389c8212bb97eceb7c6be7f5f51d
## What changed
- Add consumer plan usage history behind `analytics_plan_history`, disabled by default, fetching seven days of five-hour and weekly allowance periods.
- Show period usage percentages with expandable breakdowns by feature, model, surface, or turn start, plus snapshot freshness and incomplete coverage indicators.
- Preserve unknown usage separately from zero and handle an unavailable history endpoint without blocking other analytics reports.
## Testing
Add backend and TUI tests for unavailable endpoints, response validation, feature and account gating, account changes during requests, period navigation, snapshot resets, and narrow and wide layouts.
GitOrigin-RevId: 7bea87a3407730b18040d7dda7e7dd0afe67fb2e
## What changed
- Show local chats active in the past 30 days, ranked by estimated lifetime credits, for supported Business and Enterprise plans. Exclude archived chats and subagents.
- Add expandable model, reasoning effort, and speed breakdowns, optional zero-credit groups, and dollar estimates when supplied by the backend.
- Load estimates in bounded batches of up to 100 distinct threads, retaining available results when some estimates are unavailable. Hide chat titles without a returned estimate and distinguish missing usage from zero.
## Testing
Add coverage for batch validation, partial failures, request limits, pagination and ranking, plan eligibility, title visibility, and responsive table navigation and details.
GitOrigin-RevId: 783b960a780f4e0fd39f57e2fa78fb31b3090c44
## What changed
Add `Client::get_account_analytics` with public `AnalyticsReport`, `AnalyticsResponse`, and analytics models for token usage, credits, workspace messages, plugins, and skills. Select report-specific routes and query parameters for both `api/codex` and `wham` paths.
Preserve backend attribution, optional amounts, and signed credit values. Keep string values open for forward compatibility, and return a generic decoding error without including the response body.
## Testing
Add HTTP contract tests covering report routing and decoding, plugin query parameters, signed credit events, new string values, and rejection of mismatched response shapes without exposing the body in the error.
GitOrigin-RevId: 196ff7f49c3f9d8a029398d09af14449c5d04207
## 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
## What changed
- Accept optional `account/rateLimits/read` capabilities for Luna Reserve support
and lightweight background polling while preserving omitted and `null` params.
- Forward the Luna Reserve capability only for eligible ChatGPT sessions, and let
lightweight polls skip the separate reset-credit detail request.
- Return the backend's `ordinaryUsageAllowed` decision only when its account and
user identity match the active session.
## Testing
- Cover capability defaults, eligible and restricted authentication modes,
lightweight polling, identity filtering, and backend permission handling.
GitOrigin-RevId: f407a3ae1e70e411fdf245f072a16e453f59cd87
## What changed
- Query workspace-visible turn estimates for ChatGPT-authenticated sessions through the appropriate Codex or ChatGPT endpoint.
- Track completed response IDs and emit `codex.turn.cost_microusd` only when the estimate is nonnegative, visible, and covers every observed response.
- Keep error response bodies out of turn-cost worker logs.
## Testing
- Cover both endpoint styles, nullable estimates, settlement validation, exact micro-USD conversion, and response-ID tracking.
- Add an app-server integration test that verifies a settled ChatGPT turn reaches the OTLP metrics exporter with its turn, conversation, and auth-mode attributes.
GitOrigin-RevId: 6ae3f8df729fad52984a0c6efafd8c96c7214e55
## What changed
- Carry optional backend-owned banner and account identity data through
`account/rateLimits/read`, filtering banners that do not match the authenticated
account and user.
- Render supported rate-limit notices above the composer with actions for usage,
credits, resets, owner notifications, and plan management while preserving the
existing fallback UI for absent or unsupported banners.
- Refresh usage after limit errors, reject stale responses, and keep queued input
paused until recovery completes. When instructed by the banner, switch to the
first available fallback model without changing unrelated thread settings.
## Testing
- Add protocol, banner parsing and rendering, CTA, identity filtering, refresh
ordering, fallback-model, account-change, and queued-input recovery coverage.
GitOrigin-RevId: e03d75a82e425deb87f4b120a71cf2286c0ef6cc
## What changed
- Route turn-cost queries for non-OpenAI providers through the configured
provider endpoint and authentication, while retaining the existing OpenAI
API-key path and excluding Amazon Bedrock.
- Observe turns only when their model provider matches the worker's provider.
- Retry custom-provider authentication failures during periodic availability
probes and ensure client authentication takes precedence over provider
headers.
## Testing
- Add coverage for provider matching, custom-provider authentication retries,
ChatGPT-auth rejection, and header precedence.
GitOrigin-RevId: 04a7b28e8e3e18a510ae6fface5193af40d114c0
## What changed
- Track app-server turn lifecycle events for OpenAI API-key sessions when OTLP telemetry export is enabled.
- Query the turn-cost endpoint after completed or aborted turns and emit `codex.turn_cost` with the estimated USD cost, interruption state, model, speed, and reasoning effort.
- Preserve provider organization and project headers, wait for all observed responses to be priced, and retry pending or transiently failed queries with bounded tracking.
- Re-probe availability after authentication changes and shut the worker down with other app-server background tasks.
## Testing
- Cover late API-key login, transient probe failures, telemetry after thread removal, and turns with multiple responses.
- Verify turn-cost requests use API-key authentication and provider scope headers and deserialize priced response data.
GitOrigin-RevId: a303162a54798b554fcb2e9e2b372e1cf9f49f39
## What changed
- Add `Client::get_thread_usage` for querying authoritative estimated credit
and dollar usage for a thread across both supported backend path styles.
- Expose usage totals and optional model, reasoning effort, speed, and token
breakdowns through `ThreadUsage` and `ThreadUsageBreakdownGroup`.
- Reject responses that do not include the requested thread.
## Testing
- Cover endpoint paths, request serialization, complete and partial usage
responses, and mismatched thread IDs.
GitOrigin-RevId: 16c83590b2c804e0182b4493cf2aa39206029c77
## Why
Backend-backed features need to use the same outbound routing configuration as the rest of Codex.
## What changed
- Build the backend client on a route-aware client pool supplied by `HttpClientFactory`.
- Pass the configured factory through app-server account requests, cloud config loading, cloud tasks, and memory rate-limit checks.
- Preserve task query encoding, authentication headers, JSON request bodies, and ChatGPT cookie handling during the migration.
## Testing
- Add backend-client tests for proxy-policy propagation, task query encoding, bearer authentication, and JSON request bodies.
GitOrigin-RevId: c17d162e0dce9cec758df7cdeecf982207c6512b
## Why
Supported clients currently receive only a reset-credit count from
`account/rateLimits/read`. The redemption UI and other app-server
clients need each available credit's expiry and ID so they can explain
what will expire and consume the credit a user selected. This
information belongs on the existing rate-limit read surface rather than
a second app-server list RPC that clients would need to coordinate.
## What changed
- extend `rateLimitResetCredits` on `account/rateLimits/read` with
nullable `credits` detail rows
- fetch usage and reset-credit details concurrently; if the detail
request fails, times out, or cannot be parsed, preserve the usage
response and return `credits: null`
- expose each credit's ID, reset type, status, grant time, expiry time,
title, and description
- add an optional nullable `creditId` to
`account/rateLimitResetCredit/consume`; omitting it preserves the
existing automatic-selection behavior
- forward a selected credit ID to the Codex backend and update the
app-server documentation and generated schemas
The TUI consumer is stacked in #30488.
## Validation
- `just test -p codex-app-server-protocol` (251 passed)
- `just test -p codex-backend-client` (16 passed)
- `just test -p codex-app-server rate_limit` (18 passed)
Part of #29618.
## Why
Codex users can earn personal rate-limit reset credits, but app-server
clients do not currently have an API for reading or redeeming them. This
adds the backend and protocol foundation used by the `/usage` TUI flow
in #28154.
## What changed
- Extend `account/rateLimits/read` with a nullable
`rateLimitResetCredits` summary sourced from the existing usage
response.
- Add backend-client and app-server support for consuming a reset with a
caller-generated idempotency key. A UUID is recommended, and clients
reuse the same key when retrying the same logical reset.
- Return only the consume `outcome`; clients refetch
`account/rateLimits/read` for updated window state.
- Document the response field and each consume outcome, and regenerate
the JSON and TypeScript schema fixtures.
- Clarify in `AGENTS.md` that new app-server string enum values use
camelCase on the wire.
- Update the existing TUI response fixture for the expanded protocol
shape.
- Add coverage for authentication, response mapping, backend failures,
consume outcomes, and request timeout behavior.
## Validation
- `just test -p codex-app-server-protocol` — 231 passed.
- `just test -p codex-backend-client` — 14 passed.
- Focused `codex-app-server` reset-credit tests — 5 passed.
- Focused `codex-tui` protocol response fixture test — passed.
- `just fix -p codex-backend-client -p codex-app-server-protocol -p
codex-app-server` — passed.
- `just fmt` — passed.