Context
The Codex usage indicator (#847) reads rate-limit data from `session.metadata.codexUsage`, which is populated by `normalizeCodexUsage` in `cli/src/codex/utils/codexUsage.ts`.
`normalizeCodexUsage` only extracts rate-limit data when it is piggy-backed on a `thread/tokenUsage/updated` event. The codex app-server also emits a separate `account/rateLimits/updated` event when subscription windows reset or when credits are added / spent, but `appServerEventConverter.ts` currently drops those:
```ts
// cli/src/codex/utils/appServerEventConverter.ts
case 'thread/tokenUsage/updated':
return makeTokenCountEvent(payload)
// account/rateLimits/updated is not handled - falls through, dropped
```
Impact
The indicator only updates rate-limit state when the user sends a turn. A user who blew their weekly window 4 hours ago and is waiting for it to reset will see stale '100%' on the gauge until they send a turn that triggers a token_count event - by which point they're already trying to send and getting blocked.
Fix shape
Two options:
-
Handle account/rateLimits/updated: add a converter that produces a synthetic token_count-shaped payload carrying only the rate-limit deltas, so `normalizeCodexUsage` can consume it without restructuring. The resulting `CodexUsage` patch keeps the existing fields and just refreshes `rateLimits`.
-
Split rate-limit extraction: extract rate-limit parsing into its own normalizer that can be called independently of token-count payloads. Cleaner but bigger refactor.
Option 1 is the minimum useful fix - one converter case plus a token_count payload synth.
Related
Context
The Codex usage indicator (#847) reads rate-limit data from `session.metadata.codexUsage`, which is populated by `normalizeCodexUsage` in `cli/src/codex/utils/codexUsage.ts`.
`normalizeCodexUsage` only extracts rate-limit data when it is piggy-backed on a `thread/tokenUsage/updated` event. The codex app-server also emits a separate `account/rateLimits/updated` event when subscription windows reset or when credits are added / spent, but `appServerEventConverter.ts` currently drops those:
```ts
// cli/src/codex/utils/appServerEventConverter.ts
case 'thread/tokenUsage/updated':
return makeTokenCountEvent(payload)
// account/rateLimits/updated is not handled - falls through, dropped
```
Impact
The indicator only updates rate-limit state when the user sends a turn. A user who blew their weekly window 4 hours ago and is waiting for it to reset will see stale '100%' on the gauge until they send a turn that triggers a token_count event - by which point they're already trying to send and getting blocked.
Fix shape
Two options:
Handle account/rateLimits/updated: add a converter that produces a synthetic token_count-shaped payload carrying only the rate-limit deltas, so `normalizeCodexUsage` can consume it without restructuring. The resulting `CodexUsage` patch keeps the existing fields and just refreshes `rateLimits`.
Split rate-limit extraction: extract rate-limit parsing into its own normalizer that can be called independently of token-count payloads. Cleaner but bigger refactor.
Option 1 is the minimum useful fix - one converter case plus a token_count payload synth.
Related