feat(opencode): add killswitch indicators to quota toast#38
Open
iceteaSA wants to merge 4 commits into
Open
Conversation
There was a problem hiding this comment.
1 issue found across 10 files
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Fix all with cubic | Re-trigger cubic
16c1a8b to
b6cc376
Compare
2064776 to
04b768a
Compare
04b768a to
a3fca77
Compare
a3fca77 to
4e89c5f
Compare
3fd2fbf to
930eee6
Compare
6081cc0 to
c4f8057
Compare
Contributor
Author
…reshold Self-review fixes folded in: - Token-aware fail-closed read: const mainQuota = quotaManager.getMain(auth.access) so a previous main account's cached quota can't satisfy the fail-closed check or feed the killswitch eval after a main-account switch. - Removed a stray inner 'let sessionRequestCount = 0' + unconditional increment that shadowed the process-scoped counter, which had left the active-route fallback every-N refresh reading a never-incremented counter.
Displays quota usage bar notifications via client.tui.showToast after quota data is refreshed. Shows main and fallback account usage with visual bars, percentage, and reset time. Toast variant reflects severity (info < 70%, warning >= 70%, error >= 90%).
Align the quota refresh toast with the sidebar's visual language: - Replace the emoji status dots with status words (active/idle) - Use the shared bar width and a padded percentage via a quotaLine helper - Rename the seven-day label from 1w to 7d to match the sidebar - Keep severity-driven variant color (info/warning/error)
Layer killswitch awareness onto the restyled toast (isKilled predicate, blocked status word, ksIsKilled-aware showQuotaToastFromCache). Also restores the process-scoped 'let sessionRequestCount' (a prior cascade had flipped it to const).
98bbba1 to
b520a7b
Compare
There was a problem hiding this comment.
iceteaSA has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.
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.
Adds killswitch awareness to the quota toast (the integration of #35 + #36):
blockedfor killswitch-killed accounts,active/idlefor routable ones.Retry-Aftercomputation from feat(opencode): killswitch — block requests when quota drops below threshold #35.Single file change:
packages/opencode/src/index.ts.Summary by cubic
Adds killswitch-enforced routing and an auto-showing, restyled quota toast with
active/idle/blockedindicators. Killed accounts never serve; if none are routable, we return a synthetic 429 with aRetry-Afterbased on the earliest reset across all accounts.New Features
/claude-killswitch: view/toggle and set per-account thresholds; persisted in config. UseskillswitchPassesPolicyandkillswitchRetryAfterSeconds.getRoutableFallbackAccountsfilters fallbacks by quota policy and killswitch across fallback‑first, skip‑main, retries, and the gate. Quota toast reads the sharedQuotaManagercache, shows 5h/7d bars, marksactive/idle/blocked, and auto‑shows after refreshes.Bug Fixes
Retry-Afterwhen the quota API is backed off and no cache exists.onFallbackStorageChanged).sessionRequestCountthat could skip the every‑N quota refresh.Written for commit b520a7b. Summary will update on new commits.
Greptile Summary
This PR integrates the killswitch feature (#35) with the quota toast (#36), adding killswitch-aware routing and per-account status words (
blocked/active/idle) to the quota display. It also wires up theonFallbackStorageChangedcallback so background quota refreshes update the sidebar without resetting the active account, and centralises all fallback selection throughgetRoutableFallbackAccountsso a killswitch-killed account can never serve a request.getRoutableFallbackAccountswrapsgetUsableFallbackAccountswith a killswitch policy filter and is now used by every fallback selection path (fallback-first, soft-quota skip-main, error recovery, killswitch gate itself).showQuotaToast/showQuotaToastFromCachepair renders 5h/7d bars with padded percentages, reset times, and status words; the toast fires on fresh quota fetches and after background refreshes complete.lastSidebarRoutingremembers the last explicit routing decision so background quota refreshes (refreshSidebarQuota) never clobber the active account back tomain.Confidence Score: 5/5
The killswitch gate, fallback filtering, and sidebar preservation are all correctly wired; no hard-blocking path falls through to a killed account.
All routing paths go through getRoutableFallbackAccounts, the eager quota refresh correctly re-reads mainQuota before the killswitch evaluation, and the onSuccess callback in the killswitch fallback path corrects the sidebar. The remaining findings are cosmetic display issues that do not affect routing correctness or request delivery.
packages/opencode/src/index.ts — the showQuotaToastFromCache function and the toast header reset-time computation.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Incoming fetch request] --> B{replayable && quotaRoutingEnabled?} B -- yes --> C[getMain with access token] C -- no cache --> D[refreshMain sync\nshowQuotaToastFromCache] C -- stale / N-boundary --> E[refreshMain background\nshowQuotaToastFromCache in .then] C -- fresh --> F[writeSidebarState main] D --> F E --> F B -- no --> G{failClosedOnUnknownQuota?} F --> G G -- quota backed off & no cache --> H[Return synthetic 429 failClosed] G -- ok --> I{isKillswitchEnabled?} I -- yes & needsRefresh --> J[await refreshMain + refreshAllFallbacks\nre-read mainQuota] I -- no / already fresh --> K{killswitchPassesPolicy main?} J --> K K -- passes --> L[sendWithAccessToken main] K -- killed --> M{canReplayToFallback?} M -- yes --> N[getRoutableFallbackAccounts\ntryUsableFallbackAccounts\nonSuccess: writeCurrentSidebarState fallback] M -- no --> O[killswitchRetryAfterSeconds\nReturn 429 with Retry-After] N -- response --> P[createStrippedStream response] N -- null --> O L -- success --> Q[Return response] L -- fallbackStatus --> R[tryFallbackAccounts\nkillswitch filter inside]Comments Outside Diff (1)
packages/opencode/src/index.ts, line 1918-1942 (link)When
quotaSnapshotPassesPolicyreturns false for main,preselectedFallbackAccountsis fetched fromgetUsableFallbackAccountswithout killswitch filtering and passed directly totryUsableFallbackAccounts. If a fallback is below its killswitch threshold at this point, the routed request is delivered to that account — the killswitch block below (lines 2076–2109) only runs afterward if main itself is killswitch-killed, not when main merely crossed the softer routing threshold. The same gap exists in the fallback-first path at line 1763. The fix is to filterpreselectedFallbackAccountsagainstkillswitchPassesPolicy(getFallbackQuota(a), storage, a.id)before callingtryUsableFallbackAccounts, mirroring what themainKillswitchedpath does at line 2085–2090.Reviews (11): Last reviewed commit: "Merge branch 'fix/sidebar-fallback-quota..." | Re-trigger Greptile