cost-accounting.md
Language Markdown2.9 KB67 lines
# How Cortex counts costCortex exists to make the price of each reply visible, so the arithmetic issimple and written down here.## PricesDeepInfra publishes, for every model, a price per million tokens:`input_tokens`, `output_tokens` and, for models with prompt caching,`cache_read_tokens`. They come with the public model list(`GET https://api.deepinfra.com/v1/openai/models`, no key needed). Cortexkeeps only models tagged `chat`, refreshes the list at startup when it is morethan a day old, and stores it locally.When the list cannot be fetched (offline, or DeepInfra changes the format),Cortex falls back to `crates/cortex-core/data/pricing-snapshot.json`, a datedcopy made by `node scripts/snapshot-pricing.mjs`. The model picker then says"Prices as of DATE (offline copy)".A price above $1,000 per million, or below zero, is treated as a parsingmistake and the model is dropped rather than shown with a wrong price.Local servers (Ollama, LM Studio, llama.cpp) cost nothing.## One reply```cost = (prompt - cached) x input price+ cached x cache price (the input price if the model has none)+ completion x output price```with prices per million tokens. Money is stored as whole **nano-dollars**(10^-9 USD) in a 64-bit integer, so a month of sums never drifts the wayfloating point does. Displayed values round to four decimal places below adollar and two above; anything under $0.0001 shows as "<$0.0001".Each reply stores the prices it was billed at. A later price change neverrewrites what an old reply cost.## Where the token counts come from| `usage_source` | When | Shown as ||---|---|---|| `reported` | The provider sent a usage block (Cortex asks for one with `stream_options.include_usage`). | the numbers || `estimated` | No usage block: most local servers, a stream you stopped, an error part way. | the numbers with an **est.** badge || `none` | Refused before a single token (bad key, no credit, rate limit). | nothing; costs $0 |The estimate is about four characters per token for Latin text and one perCJK character, plus four tokens per message for the chat template and 765 perimage. It is deliberately rough and always labeled.If DeepInfra reports its own cost for a reply (`usage.estimated_cost`), Cortexstores it beside its own figure for comparison, but shows its own arithmetic.## Month to date and the budget"This month" is the sum since midnight on the first of the current month inyour local time zone. The monthly budget warns at 80% and again at 100%, inthe chat, the sidebar and the menu bar. It never blocks a send by itself; anoptional setting asks for confirmation once the budget is spent.## Before you sendThe composer shows roughly what the prompt will cost: the conversation so farplus what you have typed and attached, at the model's input price. The reply'slength is unknown until it arrives, so this is the floor, not the total.