Skip to content

feat: show provider usage limits with /usage-limits - #9875

Open
chrisdeeming wants to merge 18 commits into
pingdotgg:mainfrom
chrisdeeming:t3code/add-provider-usage-limits-command
Open

feat: show provider usage limits with /usage-limits#9875
chrisdeeming wants to merge 18 commits into
pingdotgg:mainfrom
chrisdeeming:t3code/add-provider-usage-limits-command

Conversation

@chrisdeeming

@chrisdeeming chrisdeeming commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • Adds a /usage-limits slash command. It is offered only for providers that appear under Usage → Limits. Sending it opens the current model's limits above the composer, built from the same snapshot as the Usage page. Nothing is posted to the thread and no turn starts.
  • Web renders it as a composer notice: the Usage page rows one size down, plus banked reset credits and the redeem action. It dismisses with the notice control, on the next send, or when the thread or model changes.
  • Mobile renders it as a card in the slot above the composer, using the Usage page's account block in a dense variant with the same reset-credit control.
  • The server advertises the command in each provider's slash-command catalog when limits exist for that provider.
  • Usage → Limits fixes that surfaced while building this: every window now shows its own reset countdown instead of collapsing matching ones into one, mobile bar fills above 70% were transparent because the color tokens did not exist, and the redeem button reads "Use reset" on both platforms.

Why

Checking how much quota is left meant leaving the thread for Usage → Limits. A limits snapshot goes stale as soon as the next turn runs, so it belongs in the transient slot above the composer rather than in durable thread history.

UI Changes

Note

Since producing the videos below, the feature has been changed to not require sending /usage-limits as a message. Clicking it in the slash command menu instantly displays the usage limits.

Web, Claude:

claude_usage_web.webm

Web, Codex with a banked reset credit:

codex_usage_web.webm

iOS, Claude:

claude_usage_ios.mov

iOS, Codex with a banked reset credit:

codex_usage_ios.mov

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Built with Claude Fable 5.1 in Claude Code via T3 Code.

Note

Add /usage-limits command to show provider usage limits in chat composer

  • Adds shared command recognition, coverage predicates, report collection, and catalog decoration logic in usageLimits.ts, plus a new UsageLimitsReport contract in providerUsageLimits.ts
  • Server's subscribeServerConfig stream in ws.ts injects the /usage-limits slash command into provider catalogs only for clients that opt in via a new capability flag in the subscription payload
  • Web and mobile connection runtimes enable the usage-limits command capability; ChatView.tsx intercepts a standalone /usage-limits prompt and opens a local report panel instead of starting a turn
  • ChatComposer.tsx clears the command trigger and invokes the callback when /usage-limits is selected from the menu
  • Mobile gets a new ComposerUsageLimits docked card and compact/dense modes for AccountLimits, ResetCredits, and WindowRow; WindowRow bar colors now use explicit red (≥90%) and amber (70–89%) instead of semantic classes
  • Risk: WindowRow in UsageLimitsSection.tsx switches from semantic destructive/warning color classes to hardcoded red/amber, which may not match theme overrides; LimitWindows in UsageLimits.tsx no longer suppresses repeated reset countdowns for windows sharing a reset time

Macroscope summarized f370809.


Note

Medium Risk
Touches WebSocket server config streaming and capability-gated catalog mutation; incorrect opt-in handling could advertise or hide the command for the wrong clients, but auth and turn dispatch are unchanged.

Overview
Adds a /usage-limits composer command that opens provider quota locally from the same snapshots as Usage → Limits—no agent turn and nothing posted to the thread. It is offered only when Limits has data for the selected provider.

Server & clients: Subscribers opt in with usageLimitsCommand on subscribeServerConfig; the server then injects the slash command into provider catalogs via shared withUsageLimitsCommands, and republishes when limit-source coverage changes (not on every quota tick). Older clients that do not opt in keep unmodified catalogs so they would still send the command to the provider.

Web & mobile: Thread composers intercept a standalone /usage-limits (typed or from the menu) and show a docked panel above the composer; new task on mobile blocks with guidance to use a thread or Settings. Panels track live limit data, dismiss on close, and auto-close when the thread/model/turn changes or a message is sent. Shared collectProviderUsageLimits builds the UsageLimitsReport; usage UI pieces gain compact/dense variants and small fixes (per-window reset labels, mobile bar colors).

Reviewed by Cursor Bugbot for commit f370809. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Sep 5, 2026
Comment thread apps/mobile/src/features/threads/ThreadDetailScreen.tsx Outdated
Comment thread apps/web/src/components/ChatView.tsx Outdated
Comment thread apps/server/src/ws.ts
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch from 06d70f7 to 0884697 Compare September 5, 2026 02:53
Comment thread apps/mobile/src/features/threads/ThreadComposer.tsx Outdated
Comment thread packages/shared/src/usageLimits.ts Outdated
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch from 2d91b6d to e560039 Compare September 5, 2026 03:22
@chrisdeeming
chrisdeeming marked this pull request as ready for review September 5, 2026 03:52

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread packages/shared/src/usageLimits.ts
Comment thread apps/web/src/components/chat/ComposerUsageLimits.tsx
@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a default-enabled, cross-platform /usage-limits capability spanning provider catalogs, WebSocket streaming, shared contracts, and web/mobile composer state and UI. Its broad runtime surface, plus unresolved command-routing and stale-data risks, warrants human review.

Not approved because:

  • 3 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch from e560039 to ea91dea Compare September 5, 2026 04:03
Comment thread apps/web/src/components/ChatView.tsx Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/server/src/ws.ts
Comment thread apps/mobile/src/features/threads/ThreadDetailScreen.tsx Outdated
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch 2 times, most recently from a9ce673 to 124fcf8 Compare September 5, 2026 04:18
Comment thread apps/web/src/components/chat/ComposerUsageLimits.tsx Outdated
Comment thread apps/server/src/ws.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread apps/server/src/ws.ts Outdated
Comment thread apps/mobile/src/features/threads/ComposerUsageLimits.tsx
Comment thread apps/web/src/components/ChatView.tsx Outdated
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch 3 times, most recently from cb0a604 to 0674340 Compare September 5, 2026 05:05
Comment thread apps/mobile/src/features/threads/ThreadDetailScreen.tsx Outdated
Comment thread packages/shared/src/usageLimits.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d841ed6. Configure here.

Comment thread apps/web/src/components/ChatView.tsx Outdated
}
isPreparingWorktree={isPreparingWorktree}
bannerItems={composerBannerItems}
onUsageLimitsCommand={

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium components/ChatView.tsx:8097

When /usage-limits is selected while the composer has an attachment or terminal/element context, ChatComposer treats it as an action-only command, removes the command text, and opens the limits panel; the non-prompt content is therefore left unsent. onUsageLimitsCommand is passed whenever limits are offered, unlike the typed-command path, which excludes composerHasNonPromptContent. Only provide this action callback when the composer contains no non-prompt content so the command remains sendable with its attachment or context.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/ChatView.tsx around line 8097:

When `/usage-limits` is selected while the composer has an attachment or terminal/element context, `ChatComposer` treats it as an action-only command, removes the command text, and opens the limits panel; the non-prompt content is therefore left unsent. `onUsageLimitsCommand` is passed whenever limits are offered, unlike the typed-command path, which excludes `composerHasNonPromptContent`. Only provide this action callback when the composer contains no non-prompt content so the command remains sendable with its attachment or context.

@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch 5 times, most recently from 2951d44 to 1898482 Compare September 5, 2026 06:25
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch 2 times, most recently from f42f194 to b684981 Compare September 5, 2026 06:30
Sending /usage-limits in a thread opens the current model's limits above
the composer, built from the same snapshot as Usage > Limits. The command
resolves in the client without starting a turn, so nothing is written to
the thread; the panel closes on dismiss or the next send.

Web renders it as a composer notice so it stacks under warnings and uses
the standard dismiss. Mobile docks an opaque card in the approval slot.
The server only advertises the command for providers present in Limits.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Review follow-ups for /usage-limits: drop the snapshot when the thread or
model changes, keep it hidden rather than dropped while the provider list
is unavailable, clear it only when a message actually leaves, clear it
when a later request has nothing to show, let submissions carrying
attachments or contexts send as prompts, and report a usage-limit source
that failed to read even though it has no accounts left to match.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Seed the provider status stream with the current providers so a usage
limit source refresh reaches clients before any provider change, with a
test. Tie the /usage-limits snapshot to the turn and clear it once an
approval or question is answered, since the agent then spends quota.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
The /usage-limits panel now reads provider data at render, so a redeemed
reset credit or refreshed probe shows through instead of a frozen
snapshot. Mobile New Task no longer offers the command and refuses to
send it, since only the thread composer can answer it.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Choosing /usage-limits from the composer menu opens the panel at once
instead of leaving the command in the draft to be sent. Typing it out and
sending still works as a fallback.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Compare provider status pairings against the snapshot the client holds
instead of dropping the first one, so a refresh between snapshot and
subscription still goes out. A usage-limit source that failed to read
now counts for every driver, so its error reaches the panel. Only a
successful approval or answer clears the panel, and New Task lets a
prompt with attachments through.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Native accounts in the panel show their instance id when they share a
driver and have no display name. A response that resolves after
navigating away clears only the originating thread's panel. The catalog
republish comparator now lives in shared, counts a failed source as
covering every driver, and is tested.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
A report with no accounts, such as a failed hub and no native windows,
now renders its own heading row with the close control.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
A send can outlast a navigation while attachments upload, so it clears
only the originating thread's limits panel instead of whatever is open.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Only a delivered approval or answer resumes the agent, so a failed reply
leaves the snapshot in place.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Source-backed rows showed only the hub kind, so two accounts from one
hub were indistinguishable. They now carry the hub and account id.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Ownership was a prefix match on a composite key; thread ids may contain
the delimiter, so the panel now stores its thread key and compares it.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
A send that fails before the turn starts spends no quota, so it leaves
the panel in place. Both the composer and plan follow-up paths clear
after a successful start.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
The command name is only T3's where Limits has data for the selected
provider; elsewhere a provider's own command of that name is sent
through untouched, on the menu, on send, and in New Task. The panel key
now includes any pending approval or question, so an answer from any
client closes it, which also retires the local response wrappers. The
web key stays hidden rather than dropped while a server thread is not
yet loaded.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Clients that handle the command locally say so on the config
subscription; the server injects it into provider catalogs only for
them. An older client, which would send the injected command to the
provider as a prompt, never sees it. The one-shot config fetch stays
without it.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
The menu handler and the send intercept now require an available panel
key, so a reconnect or loading thread leaves the text in the composer.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
Picking /usage-limits with attachments or contexts aboard inserts the
command text instead, so it sends as a prompt, matching the typed path.

Model: Claude Fable 5.1. Harness: Claude Code in T3 Code.
@chrisdeeming
chrisdeeming force-pushed the t3code/add-provider-usage-limits-command branch from b684981 to f370809 Compare September 5, 2026 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant