[FEATURE] Expose the live subscription budget and per-task token accounting to the model, so it can plan a session instead of guessing
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Claude Code knows exactly how much of the subscription is left, how many tasks are running, and what each of them has spent. The model doing the planning knows none of it.
Related requests cover neighbouring ground: #26340 (feed token usage back to the model — but for the context window, not the subscription), #22625 (per-subagent token tracking, for the user), #48040 (aggregate sub-agent cost in the status line, for the user), #10388 (programmatic token metrics API), #38380 (usage data for hooks and scripts), #17431 (usage visibility and threshold alerts). Every one of them exposes numbers to a human or to a script. None of them puts the numbers where the planning decision is actually made.
Why this matters more than it sounds
The decisions that dominate subscription spend are made by the model, early, and irreversibly:
- whether to fan out to N subagents or do the work inline (a fan-out costs several times a single thread)
- how many agents to spawn, and on which model
- whether to start a large refactor now or checkpoint and resume after the window resets
- how much to read, how many passes to take, how much to think
Right now the model makes all of these blind. It cannot tell the difference between "70% of the weekly window left, three days to reset" and "8% left, and the binding limit is this model's own bucket". So it either over-spends — twelve agents launched twenty minutes before the window closes — or a user writes "be frugal" into CLAUDE.md and gets caution that is uncorrelated with the actual state of the budget.
The second half is worse: during a fan-out, nobody knows what the fan-out is costing until it is over. The orchestrator cannot see that one of five parallel agents is re-reading the same directory and has burned 400K tokens, because per-task accounting is not surfaced anywhere while the tasks are in flight.
What I built, and where it hits a ceiling
I run a hook that fetches /api/oauth/usage, derives burn rate and time-to-exhaustion from rolling samples, resolves the per-model weekly bucket for the active model, and injects a compact table into the model's context on SessionStart and on every prompt — session/weekly/bucket percentages, reset times, burn rate, forecast, and a zone (green/yellow/orange/red) with the binding limiter named. A companion behaviour rule turns those numbers into policy: size effort by task complexity rather than by remaining budget, prefer inline over subagents unless there is a clear net saving, cap fan-out, and checkpoint instead of starting work that will not fit the window. A PreToolUse gate denies subagent spawns in the red zone and asks for confirmation in orange.
It works, and it changed how sessions run. But the ceiling is structural, and no user-side hook can lift it:
- Account-global only. The endpoint reports subscription-level percentages. It cannot attribute spend to a task, an agent, or a phase — so the model can see that the budget is draining but not what is draining it.
- No live task accounting. There is no way to ask "what is currently running, on which model, and what has each consumed so far". By the time the numbers move, the fan-out has already happened.
- Subagents are blind. Hook injection reaches the main session. A spawned agent gets no budget signal at all, so the component most likely to over-spend is the one with the least information.
- Snapshot, not countdown. Data arrives at prompt submission. A long agentic loop can run for many minutes past that point with a stale picture.
- The signal costs tokens. Injecting a table on every prompt spends context to save context. Native exposure would be a fraction of that, or free.
- Enforcement is binary. A
PreToolUsegate can allow or deny. It cannot tell the model "you have roughly 18 minutes of headroom — do this inline and skip the fan-out", which is the useful message.
The primitive already exists one layer down
The Claude Platform API has task budgets: the caller sets a token budget for an agentic loop, and the model sees a running countdown and uses it to prioritise and finish gracefully. So "model self-regulates against a visible budget" is a solved, shipped mechanism. What is missing is wiring it to the thing that actually constrains a Claude Code user — the subscription window — and to live per-task accounting.
Proposed Solution
Surface the budget the client already tracks to the model that spends it, and attribute spend to tasks while they are running.
1. A budget block maintained by the client, not by a user hook
A compact block injected at turn boundaries, opt-in via settings:
{ "budget": { "exposeToModel": true, "detail": "compact" } }
Contents, roughly:
session 61% (resets 22:00, 2h 14m) | weekly 44% (resets Mon 18:00)
opus bucket 78% (resets Wed 09:00) | binding: opus bucket
burn 0.42 %/min -> ~92 min to session cap
Around a hundred tokens, and it replaces a hand-built hook that costs more than that to produce worse data. Detail levels (off / compact / full) let users trade tokens for precision. Per-model weekly buckets matter as much as the headline windows: when a single model's bucket is the binding limit, the correct action is to route work to another model, and that is invisible if only 5h/7d are reported.
2. Live per-task accounting, readable while tasks are in flight
A tool or context surface answering "what is running and what has it cost":
3 tasks running:
a4f1 code-reviewer haiku 4m12s in 82K out 6K cache 310K
b9c2 test-runner sonnet 2m40s in 41K out 12K cache 90K
c7e8 doc-writer haiku 50s in 12K out 2K cache 8K
completed this session: 7 tasks, 1.2M tokens total
This is #22625 and #48040 with the audience changed: those ask for the data in a CLI report and a status line, for a human, after the fact. The orchestrating model needs the same data during the run, because it is the one deciding whether to spawn a fourth agent.
3. Budget-aware planning, not just budget-aware blocking
With (1) and (2), the model can do the arithmetic it currently guesses at: a fan-out of N agents costs roughly N times a single thread; the remaining window is X; therefore scout first, size the fleet to the real work list, or defer the sweep past the reset. Today that reasoning is possible only if a user writes a rule file and feeds it numbers by hand.
4. Subagents should inherit a budget line
A one-line budget signal in the subagent's context. The component with the least information is currently the one most able to over-spend.
5. A countdown, not just a snapshot
Task-budget-style: a running figure the model sees during a long agentic loop, derived from the subscription window rather than a caller-supplied token count. Refreshing at tool-result boundaries would be enough — the point is that the number does not go stale mid-loop.
6. Configurable policy, so the behaviour rule stops being a hand-written file
Thresholds and their consequences in settings rather than prose:
{
"budget": {
"zones": { "yellow": 50, "orange": 75, "red": 90 },
"onOrange": "confirmSubagents",
"onRed": "inlineOnly"
}
}
At minimum, expose the data and let users keep writing the policy themselves — but the zone/limiter concept is general enough to be worth shipping.
7. Parity for scripts
The same payload in hook input and in a non-interactive claude usage --json (#38380), so custom status lines, CI and dashboards read one source of truth rather than reverse-engineering an undocumented endpoint.
8. Constraints
No extra API calls — the client already receives rate-limit headers and already renders /usage. Opt-in, off by default, so nobody pays context they did not ask for. Backward compatible: sessions with the setting off behave exactly as today.
9. Minimal viable version
If the full proposal is too large: ship (1) alone, opt-in, compact detail, including per-model buckets. That single block replaces the credential-reading, endpoint-polling, binary-shipping workaround that people are building today, and it is the half that changes model behaviour most.
Alternative Solutions
A usage hook (what I built). Works for the account-global picture, but requires reading the credentials file, depends on an undocumented endpoint, needs its own cache to avoid being rate-limited by the usage endpoint, ships as a cross-compiled binary to avoid imposing a runtime, spends context on every prompt, and cannot see per-task spend or reach inside subagents at all.
/usage and the status line. Both show the numbers to the human. The human is not the one deciding whether to spawn eight agents.
External monitors (ccusage, OpenTelemetry export). Good for reporting after the fact. They observe the session rather than informing it, and none of that data reaches the model.
Instructions in CLAUDE.md ("be frugal", "avoid subagents"). Uncorrelated with the actual budget state, so they are either ignored when caution is warranted or applied when there is plenty of headroom. Caution without numbers is not planning.
Per-subagent reporting (#22625) and status-line aggregation (#48040). Both deliver the accounting this proposal needs, but to a human, after the run. Adding the model as a consumer is a small delta on that work and where most of the value is.
API-level task budgets. The right mechanism, but the caller supplies a token count. Nothing connects it to the subscription window, and it is not exposed in Claude Code.
Doing nothing and letting users hit the wall. The current outcome: rate limits are discovered by being blocked mid-task, which is the most expensive possible moment to learn about them.
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
A fan-out that should not happen
The model finishes scouting and has a work list of twelve items. Under the current design it spawns twelve agents, because nothing tells it not to. With the budget block it sees that the binding limit is the Opus weekly bucket at 78% with three days to reset, and that a twelve-way fan-out on Opus is several times the cost of the same work done in a narrower sweep. It scouts, sizes the fleet to four agents on a cheap model, and reports what it deferred. The user never had to intervene.
A large task started at the wrong moment
Phase 3 of a refactor is about to begin. The session window has roughly 18 minutes of headroom at the current burn rate. Today the model starts anyway and dies mid-edit, leaving a half-applied change. With a visible forecast it writes a checkpoint — done / in flight / next / open questions — and offers to resume after the reset.
A runaway parallel task
Five agents are running. One is re-reading the same directory tree on every step and has consumed 400K tokens. Right now this is invisible until the session cost jumps at the end. With live per-task accounting the orchestrator can see the outlier while it is still running and stop it.
Model routing under a scoped bucket
The overall weekly window is at 40%, but the active model's own bucket is at 91%. The correct move is not to work less — it is to move heavy work to a model with a freer bucket. Without per-model buckets in the exposed data, that distinction cannot be made, and the model either over-restricts itself or hits a wall it could have walked around.
What this replaces
I currently get roughly the first two of these by injecting a hand-built table into every prompt from a hook that reads my OAuth credentials and polls an undocumented endpoint. The last two are not reachable from user space at all.
Additional Context
I'm running a working approximation of item (1) — a Go hook that fetches subscription usage, derives burn rate and forecast, resolves per-model weekly buckets, injects a status table into the model's context, drives the status line, and gates subagent spawns via PreToolUse — plus a behaviour rule that turns those numbers into pacing policy. Happy to share both if a reference implementation is useful; the point of this request is that the parts that matter most (per-task attribution, subagent visibility, a live countdown) are not reachable from a hook no matter how much effort goes into it.
This is deliberately narrower than #26340, which asks for context-window usage to be fed back to the model. Context and subscription budget are different constraints with different remedies: the first is solved by compaction, the second by pacing, routing and scheduling. Both are worth exposing, and neither substitutes for the other.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗