Uh oh!
There was an error while loading. Please reload this page.
feat: display provider usage limits in settings - #1732
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Your free Security trial is over. An organization admin can activate Security or dismiss this notice. Comment |
Aditya190803
commented
Apr 4, 2026
For now, I’ve added two images to illustrate the UI: 1. Free tier viewThis screenshot reflects my current setup. I don’t have subscriptions to Codex or Claude Code, I’m using Copilot Pro (available to me as a student). It shows how the weekly usage limit appears in the interface. 2. Pro tier (mocked example)This second screenshot uses dummy data to demonstrate how the UI could look for users on a Pro plan (Codex or Claude Code). It includes both session-based limits and weekly limits for clarity. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:80515efa38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a substantial cross-provider usage-limit capability with new CLI/PTY probes, live runtime ingestion, shared snapshot concurrency logic, and web/mobile UI changes. Its broad production impact and several unresolved comments describing concrete runtime or display risks require human review. You can add or adjust custom eligibility rules. Learn more. |
Uh oh!
There was an error while loading. Please reload this page.
Aditya190803
commented
Apr 6, 2026
Hey @juliusmarminge, could you take a look at this PR when you get a moment? Thanks! |
Marve10s
commented
Apr 6, 2026
A few concerns after checking the code:
I can test further and commit to this PR if you're okay with it, @Aditya190803. Genuinely want to see this merged - it would be super useful |
juliusmarminge
commented
Apr 6, 2026
this is on my list to review still! Just dealing with some larger prep work so haven't had time yet. As for the "it must be more visible and sjhould be 1:1 like codex app": How often do you guys check your limits to warrant it being one click ??? I check it at most a few times a week, so hiding it in settings next to the provider status is fine! |
Marve10s
commented
Apr 6, 2026
juliusmarminge
commented
Apr 6, 2026
Yes when the single settings page gets too large we'll split it to subpages. We already did the work adding the sidebar when adding the archive |
juliusmarminge
commented
Apr 6, 2026
juliusmarminge
left a comment
There was a problem hiding this comment.
implementation seems way overcomplicated.
why cache the data? the provider check runs once per minute. we can get fresh data on every tick?
how i imaagined this working:
- extend the
checkProviderprobe in ServerProvider to include a newusageLimitsproperty. - on the auth check probes (app server / claude), extract usage data
- stream it down to client as part of the normal provider snapshot
- render the UI on settings page
given i haven't looked into exactly what's possible to probe and not, why is this PR so much more than that?
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
f9aabcd to
171df70CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
036a9b9 to
ed12bb8CompareReplay last-exit on a microtask so Terminal Manager can assign session.process first. On Windows, kill the PTY tree with taskkill so cmd.exe-launched CLI children do not leak. Co-authored-by: Cursor <cursoragent@cursor.com>
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
| if (isGrokFreeTier(provider)) { | ||
| return GROK_FREE_TIER_USAGE_MESSAGE; | ||
| } | ||
| if (!provider.usageLimits) return "Usage data unavailable"; |
There was a problem hiding this comment.
Dropped usage windows leave empty tiles
Low Severity
Forward-compatible decoding now drops invalid or unknown usage windows instead of failing the provider, which can leave usageLimits.available true with an empty windows array. providerQuotaNotice only fills the tile body when usageLimits is missing, so those snapshots render a title with no bars and no message on web and mobile.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit fdc78fb. Configure here.
| return { | ||
| models, | ||
| ...(auth ? { auth } : {}), | ||
| } satisfies GrokAcpDiscoveryResult; |
There was a problem hiding this comment.
Grok auth probe can discard models
Medium Severity
The Grok auth subscription probe still runs inside the outer ACP discovery timeout, so a slow acp.start() can leave too little budget for auth/check_subscription. When that outer timer fires, the already-built model catalog is thrown away and the provider is reported as a startup timeout instead of ready with unknown auth.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 574252c. Configure here.
| Effect.catchCause((cause) => | ||
| Cause.hasInterrupts(cause) ? Effect.failCause(cause) : Effect.succeed(Option.none()), | ||
| ), | ||
| ); |
There was a problem hiding this comment.
Codex rate-limit interrupt drops snapshot
Medium Severity
The Codex rate-limit read rethrows interrupts, so an outer probe timeout that fires during account/rateLimits/read can still fail the whole app-server snapshot. Account, models, and skills that were already fetched are then discarded as a provider timeout instead of publishing with usage degraded.
Reviewed by Cursor Bugbot for commit 574252c. Configure here.
Aditya190803
commented
Aug 27, 2026
Follow-up stacked on this PR: remaining session/weekly usage in the chat box, current provider only. Stacked PR: #8445
Settings Chat hover |
| ? window.windowDurationMins | ||
| : reported.length > 1 && index === 0 | ||
| ? CODEX_SESSION_WINDOW_DURATION_MINS | ||
| : CODEX_WEEKLY_WINDOW_DURATION_MINS; |
There was a problem hiding this comment.
Codex partials mislabeled as weekly
Medium Severity
Live Codex account.rate-limits.updated payloads reuse the full-snapshot resolver, which treats a lone duration-less primary window as weekly. Codex notifications are documented as partial, and mergeUsageLimitWindows upserts by kind, so a session-only patch can overwrite the weekly bar and leave the session bar stale during a turn.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit e6ed20c. Configure here.
derektrimm
commented
Aug 28, 2026
We hit a few landmines building the usage-limits implementation in #5739 that this PR's data paths will also cross, so passing them along to save the rediscovery:
Happy to share the test fixtures we built for these cases if useful. |
…imits # Conflicts: # apps/server/src/provider/Layers/OpenCodeProvider.ts # apps/server/src/provider/makeManagedServerProvider.ts # apps/web/src/timestampFormat.test.ts
There was a problem hiding this comment.
One finding in the in-scope web files: an empty provider tile can render when a usage snapshot decodes as available with zero windows. Everything else (bar geometry/role="progressbar"/motion-reduce matching ContextWindowMeter, locale-consistent reset formatting via timestampFormat.ts, indicatorBackground matching the page surface) is consistent with the existing system.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
There are 32 total unresolved issues (including 31 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ea3c1ce. Configure here.
| return undefined; | ||
| } | ||
| if (duration > 30 * 24 * 60) { | ||
| return "monthly"; |
There was a problem hiding this comment.
Monthly windows classified as weekly
Medium Severity
windowKindFromDuration treats a window as monthly only when duration is strictly greater than 30 days. Codex Free/Go and Cursor both stamp exactly 30 days (43200 minutes), so those windows classify as weekly. Codex then labels the bar Weekly instead of Monthly.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ea3c1ce. Configure here.
Aditya190803
commented
Aug 30, 2026
Quick update:
I wanted to make this a stacked PR, but couldn’t get that working, so I opened a new PR instead. I didn’t close this one since quite a few people are already following it. |
Aditya190803
commented
Aug 30, 2026
It is a Opt in Feature |
derektrimm
commented
Aug 30, 2026
Thanks for the update, and for how much of the earlier list you've taken on - I went back through the current diff (plus the pipeline copy in #8445) and most of it is genuinely handled now. Wanted to close the loop properly:
One perf observation on the #8445 copy of the pipeline, offered in the spirit of this repo's performance bar: every account.rate-limits.updated event currently republishes the full ServerProvider snapshot (models, skills, slash commands) to every connected client, and the dedupe guard in applyUsageLimits never gets a chance to fire - applyRuntimeUsageLimits stamps a fresh checkedAt on every event, so the value always differs even when every percentage is identical. Comparing just the window fields and keeping the previous checkedAt when nothing changed would make no-op events free on the wire. Happy to share our test fixtures for the same-kind-window and unit-mismatch cases if they'd save you time - and thanks again for pushing this feature forward, a lot of people clearly want it. |









Fixes#228.
What Changed
Added provider usage limits to the settings flow end to end for all 4 providers (Codex, Claude, Cursor, OpenCode):
Note: For OpenCode, only the official OpenCode-managed providers (OpenCode Go, OpenCode Zen) are shown.
Why
Users need a visible place to confirm provider usage limits without digging through logs or backend state. This keeps the value available across sessions and makes the current limits easy to inspect from the UI.
UI Changes
The Settings panel now shows provider usage limits in the provider section.
Checklist
Note
Medium Risk
Provider status checks now spawn PTY/CLI probes and merge live rate-limit events into published snapshots; failures degrade to “unavailable” but add complexity and timing sensitivity around concurrent refreshes.
Overview
Adds provider subscription quota data to provider snapshots and surfaces it in the mobile Usage screen, with server-side probing and live refresh so limits stay current between status checks.
Server: Each major driver (Claude, Codex, Cursor, Grok, OpenCode) now attaches
usageLimitsduring status probes—via Codex app-serveraccount/rateLimits/read, Claudeclaude --print /usage, Cursor/Grok PTY/usageTUI automation, and OpenCode Go/Zen inventory fields. OptionalPtyAdapteris threaded into Claude/Cursor/Grok driver checks so PTY-based probes work when the server layer provides it.applyUsageLimitson managed provider snapshots patches quota windows from runtimeaccount.rate-limits.updatedevents (ProviderUsageLimitsIngestionLive), with epoch merging so in-flight probes do not overwrite fresher live updates.Mobile: New Provider limits section on the usage route shows per-environment provider bars, reset dates, and notices (e.g. Grok free tier, unavailable API-key accounts).
Hygiene: Ignores
.claude-work-test/so Claude usage probe tests do not commit session files.Reviewed by Cursor Bugbot for commit ea3c1ce. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add provider usage limits display to Usage page with CLI probing and runtime ingestion
ServerProviderUsageLimitsschema to server.ts with validated usage windows (session,weekly,monthly), percent clamping to 0–100, and forward-compatible decoding that drops invalid windows instead of failing the provider/usageor TUI output: Claude (claudeUsageProbe.ts, 15s timeout), Cursor (cursorUsageProbe.ts, 25s timeout), Grok (grokTuiUsageProbe.ts, 10s timeout), Codex via app server rate-limits API (codexUsageProbe.ts), and OpenCode managed providers (openCodeUsageLimits.ts)ProviderUsageLimitsIngestionLivelayer in server.ts that subscribes toaccount.rate-limits.updatedevents, parses runtime telemetry via runtimeUsageLimits.ts, and callsapplyUsageLimitson the provider instance to patch live snapshotsapplyUsageLimits, track per-window patch epochs, and preserve live-patched usage windows across concurrent refresh and enrichmentkill()usestaskkill /T /Ffor process-tree terminationNodePtyProcessconstructor now requires aplatformargument; Windows kill behavior switched fromprocess.killtotaskkillwithprocess.killfallback. Provider snapshots now carry an optionalusageLimitsfield; invalid usage windows are silently dropped during decode rather than failing the providerMacroscope summarized ea3c1ce.