Repository navigation
Conversation
Clients format at most twenty fraction digits and no currency has more than four, so a wilder exponent from Claude's spend or extra_usage payload is a malformed budget: skip the row instead of scaling it to Infinity.
The spend contract wants a trimmed, non-empty currency code. Read it once for both the spend and extra_usage payloads: trim it, skip the budget when it is blank, and keep dollars as the credits default.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This change adds automatic Claude spending-budget support end to end, including a new usage contract shape, provider parsing, currency formatting, pooled-account handling, and web/mobile presentation. The behavior is additive and well tested, but its multi-surface production impact exceeds a small self-contained fix. Notes:
You can add or adjust custom eligibility rules. Learn more. |
|
Important Review skippedWe couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: pingdotgg/t3code/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (9)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review. 📝 WalkthroughWalkthroughAdds support for Claude monthly spending budgets through provider mapping, shared spend utilities, and web and mobile usage displays. Also updates usage documentation and adds tests for spend mapping, formatting, and pooled-account behavior. ChangesClaude monthly spend limits
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix · Severity of issue fixed: Low Sequence Diagram(s)sequenceDiagram
participant Claude as Claude_get_usage
participant Mapper as claudeUsageResponseToLimits
participant Window as ServerProviderUsageWindow
participant Formatter as formatSpend
participant Views as Usage_limit_views
Claude->>Mapper: rate_limits.spend and extra_usage
Mapper->>Window: valid monthly_spend window with spend details
Window->>Formatter: amounts, currency, and exponent
Formatter->>Views: formatted spend
Possibly related PRs
Suggested reviewers: Merge Risk: ⚪ Minimal · up to The reviewed monthly-budget behavior is ready to merge after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change is display-oriented and adds budget amounts to existing usage views. No new privilege or budget-enforcement operation was identified. Risk appears low, but older-client compatibility and refresh recovery are not fully established. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 21 functions across 8 files. (1 skipped: 1 unsupported.) ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Fixes #10155.
Resubmission of #10160, which was closed on 2026-09-19 while the provider layer was frozen for V2 ("If this is still an issue once V2 lands, please reopen (or open a fresh PR against the new code)"). The branch is rebuilt on the new
mainand verified there;claudeUsageLimits.tsand the usage contract came through #2829 without conflicts. One part is new since #10160: the pooled Limits card that landed onmainin the meantime now shows the amount too.Problem
Claude Enterprise accounts, and any plan with a spending budget instead of rolling quotas, answer
get_usagewithfive_hourandseven_daynull and a populatedrate_limits.spend/rate_limits.extra_usage.claudeUsageResponseToLimitsonly maps the rolling windows and the model-scoped weeklies, so the snapshot has no windows and both the Limits view and/usage-limitssay "No limits reported." for an account with an enabled monthly budget.Change
monthly_spendwindow ("Monthly spend").spendwins when enabled, otherwiseextra_usagewhenis_enabled; they describe the same budget, so one row is drawn. Rolling windows stay beside it when they exist. The percent is computed from the amounts (9.262% is not collapsed to the provider's rounded 9). A budget with an unknown used amount, a blank currency or an impossible exponent draws no row.ServerProviderUsageWindowgains an optionalspend(usedMinor,limitMinor,currency,exponent) carrying the provider's minor units unchanged. Older clients ignore it and still get the bar.formatSpendin@t3tools/shared/usageLimitsrenders$46.31 of $500.00in the budget's currency and precision. Web shows it in the usage row and bar tooltip (Limits view,/usage-limits), and on the pooled card: under the percent when one account reports the budget, and per account (segment popover, narrow legend, accessible label) when several do. Amounts from different accounts are never summed, since the pooled percent is an average. Mobile shows the amount in the row's detail line; its pooled view stays percent only.spendanddecimal_placesare read structurally: the pinned SDK typings do not havespendyet and typeextra_usagewithoutdecimal_places.Scope and approval
Accepted bug #10155 (labels
bug,accepted,via-triage). Touches the Claude usage mapper, one optional contract field, the shared formatter, and the web and mobile usage rows. Other providers are unaffected: none of them setsspend.Verification
Real web client on V2, before and after. Headless Chromium 153 at 1400×900 (one capture at 700×900) against
vp run dev,mainat e9298af versus this branch, each with its own empty state. The provider is a stand-inclaudebinary that answers the SDK'sinitializeandget_usagewith the payload from the issue (null rolling windows, USD budget 4631 of 50000 minor units), so the budget travels through the real probe, mapper, contract and client. No real account, credentials or model call.main)No reset countdown or pace marker appears for the budget in any capture.
Tests.
claudeUsageLimits.test.ts: the Enterprise payload yields the monthly window at 9.262%; theextra_usagefallback keeps the session window beside the budget; a disabled or unlimited budget, an unknown used amount, a blank currency and an out-of-range exponent draw nothing, while a reported 0 draws the zero-spend row.usageLimits.test.ts: currency and precision formatting including a codeIntldoes not know, andsingleAccountSpendfor one account, several accounts in the same and different currencies, no members, and a budget beside a rolling window. 60 tests pass. Typecheck for contracts, shared, server, web and mobile, targeted lint, format and knip are clean.Not checked: a live Enterprise account (the payload shape is the one captured in the issue), the mobile app in a simulator and the packaged desktop app (mobile is typechecked; desktop renders the web code), and currencies other than USD in a client.
Implemented with Claude Code (Claude Fable 5.1 and Claude Opus 5.5); tests, independent review and evidence capture by GPT-6 Astra via Codex.