Allowance-based plans: what /usage shows you now, and what happens at the limit

Running out of quota is annoying. Not knowing how much is left is worse. You are mid-deadline, the last reply was fine, and the next one is refused: limit reached. Which limit? Today’s or this month’s? Is the large-model allowance a separate bucket? When does it come back? Those answers used to live in a web dashboard. PR #142308, merged on October 22, 2026, moves them into the terminal.
Two different ways to pay
Hermes grew up on a credit balance: top up, spend down, stop at zero. Some subscriptions instead run on usage windows — a day, a week, a month, plus a separate allowance for large models. That is not a balance you drain; it is a quota that refills.
The difference decides the interface. A balance is one number; a quota is a set of gauges. So this change does not model plans in Hermes at all. It draws what the server sends.
As many bars as the server sends
Allowances arrive from two places with the same shape:
usage_window.gaugesin the Portal account snapshot;- the
x-nous-credits-window-gaugesresponse header, which also rides on the 402 refusal.
Each gauge carries a scope that says what a full one blocks:
scope: all— blocks every paid model (day, week, month, and any allowance added later can use this scope);scope: top_tier— blocks only the models the gateway marks top tier.
A free model is never blocked; it draws on nothing. That rule sits at the top of agent/plan_limits.py, because the picker’s “used up” note, the limit card’s suggestion and the one-tap switch button all have to agree — one rule, one source.
A comment in agent/usage_gauges.py is worth quoting: Hermes keeps its own words only for ids it knows (they are translated and fitted to each surface); any other id shows the server’s label. A new allowance on the server needs no Hermes release.
What /usage looks like now
/usage was already the “how much has this session cost” command — tokens, estimated cost, context window, duration, and an account-limits section when the provider exposes one. On a window plan it now shows one bar per allowance, with percent used and time to reset.
In the Desktop app the same data appears under Settings → Billing as gauges, next to a Keep going on credits switch: once an allowance runs out, may top-up credits take over? That switch is the same account setting as the Portal’s Billing → Topup toggle — the Desktop is just another entrance to it. Changing it needs Remote Spending (billing:manage) on that terminal; without it the click starts the approval itself, the switch holds the requested position, and the change applies once approved. No refuse, verify, click-again loop.
The model pickers get price tags back
On a window plan every listed model is included, so a per-token price would be noise. Instead each row carries one word: Free, Small, Medium, Large. The gateway sends the word per caller as usage_level on /v1/models; Hermes only translates it.
Around it:
- Recommended models come first; the CLI picker splits the list into “Recommended” and “Other models”, while messaging pickers just order recommended first;
- When an allowance is used up the picker says so once and shows when it resets; blocked models are dimmed where the platform supports dimming;
- Choosing a
Largemodel gives a one-time notice that it uses more of the monthly large-model allowance.
Every other account — credit-grant, pay-as-you-go, free tier — gets nothing from this module. Their code paths are unchanged.
At the limit, three answers instead of one
The refusal used to be a generic “usage limit reached”. It now says which allowance ran out, when it resets, and what still works: up to two models from the plan’s recommended list that can still run. Platforms that already have buttons render them as buttons; everything else gets a sentence.
One design decision is worth copying into any agent product: Hermes never switches models on its own. A usage-window limit does not walk the fallback chain — the fallback chain exists for “this provider is down”, not for “you exceeded your plan”. You either pick an available model or wait for the reset.
Two channel-specific details: messaging platforms point at the Portal instead of /topup (a chat button could spend the room owner’s money), and with a credential pool only the refused model is benched until the reset — not the whole credential. The other models on that key keep working.
Compatibility and boundaries
From the PR:
- Without a window plan, every code path is the same as before;
- usage-window response headers and refusal codes are honoured only on Nous routes, so another upstream cannot trigger this UI;
- additive only: no existing config, API or CLI behaviour is removed.
Release status
PR #142308 merged to main on October 22, 2026 — over 200 files, across the CLI, TUI, gateway and Desktop. The latest release is still v0.22.4 from October 21, so this is main-only until the next release reaches the stable channel.
To keep the neighbours straight: /usage reset redeems banked Codex resets (see that post), Resetwatch is a third-party Desktop plugin that puts remaining quota for 14 platforms on one screen (see that post), and this change is the official support for allowance-based plans themselves. For the rest of the model picker’s behaviour, the hermes model reference covers the flags.