Skip to content

v6.4.1

Choose a tag to compare

@ndycode ndycode released this 30 Jun 07:07

Fixed

  • Local token-bucket depletion no longer leaks into persisted, cross-process state. 6.4.0 made a depleted account rotate by writing a synthetic window into rateLimitResetTimes — but that field is saved to the shared accounts file and reloaded by every process, so one process exhausting its own in-memory proactive limiter could spuriously mark a server-healthy account as rate-limited in other concurrent processes (the multi-process / PID-offset deployment this tool targets). Account selection (sticky, hybrid, round-robin) and getMinWaitTimeForFamily are now token-bucket-aware directly: a locally-depleted account is skipped in-memory with no persisted state, and an all-depleted pool waits for token refill instead of returning a spurious 503. (#183)
  • A locally-depleted account no longer accrues a server-429-style health penalty. The depletion path previously called recordRateLimit, mis-attributing a purely-local proactive throttle as an upstream rejection and deprioritizing a perfectly healthy account in hybrid scoring for hours. (#183)
  • codex-warm no longer reports a quota-exhausted account as "warmed". A 429 is now classified by reason: a quota/usage_limit 429 (the window is already spent) is surfaced as a distinct failure, while a transient tokens/concurrent 429 (window active) still counts as warmed. (#182)

Notes

  • This is a patch release that corrects a regression introduced in 6.4.0; the rotationStrategy config (#183) and codex-warm tool (#182) added in 6.4.0 are unchanged in behavior except for the fixes above. Single-process usage was unaffected by the regression — the leak only manifested across concurrent processes sharing one accounts file.
  • The local token bucket is intentionally in-memory and per-process; only real server 429s belong in the persisted rateLimitResetTimes. Selectors now consult the bucket in-memory rather than encoding local back-pressure into shared state.