feat(quota): persist per-account quota and skip out-of-quota Kiro accounts during routing#1854
Open
vuongtlt13 wants to merge 1 commit into
Open
feat(quota): persist per-account quota and skip out-of-quota Kiro accounts during routing#1854vuongtlt13 wants to merge 1 commit into
vuongtlt13 wants to merge 1 commit into
Conversation
- Persist normalized quotaInfos (+plan/message/updatedAt) onto each connection in the usage route; bundle it in /api/providers/client so the dashboard hydrates instantly from the last-known snapshot before the live refetch. - Share parseQuotaData via open-sse/services/usage/normalize.js (re-exported from the dashboard utils) so backend and frontend normalize identically. - Skip Kiro accounts that are out of quota until their resetAt during account selection (Kiro-scoped via QUOTA_DEPLETION_PROVIDERS; other providers unchanged), and log each skip to the console log (throttled per account).
bloodf
pushed a commit
to bloodf/9router
that referenced
this pull request
Jun 19, 2026
…a + skip depleted Kiro accounts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related quota improvements:
Motivation
Previously provider quota was live-fetched only and cached just in
localStorage(and that cache was never read on mount). So:resetAtvia its usage API but never surfaces it on chat errors, so the precise reset time was being thrown away.What changed
1. Persist quota onto each connection (all providers)
parseQuotaDatamoved toopen-sse/services/usage/normalize.jsand re-exported from the dashboard utils, so backend and frontend normalize identically.GET /api/usage/[connectionId]now persists the normalizedquotaInfosarray (+quotaPlan,quotaMessage,quotaUpdatedAt) onto the connection. Only overwritesquotaInfoswhen non-empty, so a transient auth/empty response can't wipe the last-good snapshot.GET /api/providers/clientbundles those fields in the connection list.ProviderLimitshydratesquotaData(andlocalStorage) from the bundled snapshot immediately, so the table shows last-known values right away; the live refetch still runs and overwrites. The loading spinner now only shows when there is no data yet.No DB migration required — connections already persist arbitrary fields in their JSON
datablob.2. Skip out-of-quota Kiro accounts during selection (Kiro-scoped)
accountFallback.js:getQuotaResetUntil()/isQuotaDepleted(), gated byQUOTA_DEPLETION_PROVIDERS = new Set(["kiro"]).total > 0) is fully used and itsresetAtis still in the future. If any bucket has room, or the reset has already passed, or there's noresetAt, the account stays usable.getProviderCredentialsfilters these out and folds theirresetAtinto theretryAfterreported when all accounts are unavailable.Scope: strictly Kiro. For every other provider
isQuotaDepleted()returnsfalse, so routing is unchanged — extend later by adding a provider toQUOTA_DEPLETION_PROVIDERS(only when itsresetAtis trustworthy).3. Observability
Each quota-based skip is logged (throttled to once per 60s per account, since selection runs per request) so it appears in
/dashboard/console-log:Testing
parseQuotaDataandgetQuotaResetUntil/isQuotaDepletedacross depleted / has-room / reset-passed / no-resetAt / multi-bucket / unlimited / non-Kiro cases.eslintclean on all touched files.Files changed
open-sse/services/usage/normalize.js(new) — sharedparseQuotaDataopen-sse/services/accountFallback.js—QUOTA_DEPLETION_PROVIDERS,getQuotaResetUntil,isQuotaDepletedsrc/sse/services/auth.js— skip depleted accounts + throttled loggingsrc/app/api/usage/[connectionId]/route.js— persist quota snapshotsrc/app/api/providers/client/route.js— bundle quota fieldssrc/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.js— instant hydrationsrc/app/(dashboard)/dashboard/usage/components/ProviderLimits/utils.js— re-exportparseQuotaData