Why Hermes Reported Your Run Cost $0.00

You finish a long agent run, glance at the status bar and read the Cost row: $0.00. Or n/a. You were on your own OpenAI key the whole time, the run clearly moved tens of thousands of tokens, and the number in front of you says the session was free. Either it really was free, or Hermes had no idea what it cost — and until this week there was no way to tell those two apart.
That ambiguity is gone for the most common setup. A run that talks straight to a first-party API — OpenAI, xAI, Anthropic, Google, DeepSeek — is now priced even when the model is missing from Hermes’ bundled table, and the row stops pretending a real spend was zero (#120441, salvaging #56625; plus #120517 for Anthropic).
Three places a price can come from
Every cost figure Hermes prints goes through one resolution function, get_pricing_entry. It walks a short ladder and takes the first rung that answers:
- A subscription route is not priced at all. If the billing route says the model is included in a plan (
openai-codex,xai-oauth), the entry is a fixed “included” marker. Nothing is charged per token, so nothing is estimated. - OpenRouter keeps its own path, because the router publishes live per-model prices with the catalog it serves.
- The bundled price table — a snapshot shipped with Hermes — answers for the mainstream models.
- The provider’s own
/modelsendpoint is asked next, when you configured a base URL that exposes pricing metadata. - New: the vendor’s list price via models.dev, when the first four rungs are silent.
Rung five is the interesting one, and it is deliberately narrow. It only fires when your billing route points at the vendor itself:
| Billing route | Trusted host |
|---|---|
openai |
openai.com |
xai |
x.ai |
anthropic |
anthropic.com |
google |
googleapis.com |
deepseek |
deepseek.com |
xiaomi |
xiaomimimo.com |
No base URL at all counts as trusted too, since that means the provider’s own default endpoint.
Why a relay or a proxy stays unpriced
Here is the part worth internalising before you trust any cost number: the same model id can be billed at a different rate depending on who serves it.
A proxy, a relay or a custom endpoint can serve gpt-5-nano at a markup, a discount, or a flat subscription fee. The vendor’s list price would then be a confident lie. So the fallback checks the origin it is about to price: it must be https on port 443, and the host must be that vendor’s domain or a subdomain of it. Anything else returns nothing and the session keeps its honest unknown.
That reads as n/a in the status bar rather than a made-up dollar figure, and the CLI documentation now spells out exactly which sources feed the row: the bundled official price table first, then the provider’s /models listing, with models.dev filling the gap only for a direct first-party API.
Reading what you actually spent
- The status bar Cost row is the at-a-glance estimate (
n/awhen unknown or genuinely zero-priced). /usageopens the detailed breakdown, including input versus output tokens and cache read/write categories.hermes insightsrolls token and cost analytics up across sessions, which is what you want when you are deciding whether a model is worth keeping for a given job.
Two status words carry real meaning, so it is worth knowing which one you are looking at. An estimated cost means Hermes found a rate card and multiplied it by the tokens it counted. unknown means there was no rate card it was willing to apply — not that the run was free.
The estimation itself is arithmetic on numbers Hermes already has. The fallback reads model metadata from the in-process or on-disk cache rather than dialling out mid-turn, so a direct-API session does not pay a network round trip to learn its own price.
Small runs no longer round down to $0.00
There is a second, older trap in the same display: cheap models. A short run on a small model can legitimately cost a fraction of a cent, and a two-decimal format renders that as $0.00 — indistinguishable from “unpriced”. Costs below one cent are now rendered at four decimal places, so you see $0.0046 instead of a flat zero.
What is still an estimate
Be clear about what you are looking at: these are list prices times counted tokens, not your invoice. If your account has negotiated rates, committed-use discounts, or a different cache policy, the vendor’s bill will differ. The estimates are there to answer “is this model ten times more expensive than that one?” — a question they answer well — not to predict your monthly statement to the cent.
For the numbers from the original fix: a direct openai-api run on gpt-5-nano (19,750 input / 109 output tokens) used to record cost_status=unknown, estimated_cost_usd=0.0 and now records $0.0010266; a direct xai run on grok-4.3 (21,157 in / 156 out) went from unknown, 0.0 to $0.02637205. Both reconcile by hand against the vendor’s published rates.
The follow-up round also aligned Anthropic fast mode with the current Claude documentation, so the mode you select is the mode that gets reported.
Where this is shipping
Both changes landed on main after the v0.21.4 tag, so they are not in a release yet — a hermes update that pulls main, or the next tagged release, is when they arrive. There is nothing to configure: if you route to a first-party API, the fallback applies on its own, and the Cost row in the CLI reference now names its three sources so you can check the behaviour yourself.
If you do route through a relay for cost reasons, keep an eye on this: n/a on a relay is deliberate, and it is the one case where Hermes would rather say nothing than guess. For a broader look at what the status bar tracks, our status bar metrics guide walks through each row, and the provider plugin hooks guide covers the per-model capability data that the same metadata cache exposes to plugins. Subscription users should read the Claude subscription provider guide first — those routes are intentionally unpriced.