A provider that serves a model the catalogue does not list, or lists at the
wrong size, has a window and a reply limit magpie cannot know: both fall
back to whatever the catalogue says about the model's maker, which for such
a provider is nothing at all.
magpie model context relay-a/gpt-5.5 262144
magpie model output relay-a/gpt-5.5 131072
magpie model context 'relay-a/*' 200000
magpie model output relay-a/gpt-5.5 --reset
Both are looked for in the same order as each other: this model, then
`<provider id>/*`, then the provider's own list, then the catalogue. A
model's own value wins over its provider's. The reply limit is new; the
window is not — `Provider.Contexts` has been there, with a `"*"` of its own,
settable through `magpie provider set <id> context.<model>=`, and this
reuses it rather than shadowing it.
That reuse is the point rather than a detail. A context is a routing input
and not only a number agents are shown: at 95% of a held member's window a
request moves to a member that takes more, so two sources of truth would
mean the gateway routing on one number while agents are told another.
`magpie model context` is a second way to set the same field, not a second
field.
Both reach the agents. Pi keeps a model's window and reply limit in its own
models.json, OpenCode keeps its limit, and Crush, Droid, Cline, Qoder and
Zcode keep their own; an agent reads those files when it starts, so a limit
set here that never reaches them is a limit that does not take effect.
`magpie provider set` has always told the agents, and this behaves the same
way rather than introducing a second, quieter path. The test asserts each
setter reaches them exactly once — the two paths differ (one saves the
provider file, the other settings and then says so) and that difference is
worth pinning. An end-to-end pass confirms it: with a Pi models.json in
place, `magpie model context relay-a/sol 999999` writes `contextWindow:
999999` into `providers.magpie.models`.
A `0` is refused rather than read as a reset, naming `--reset`; a mistyped
model id is refused the way `magpie model name` refuses the same id; a reset
says what is actually in force instead of claiming to be back to the
vendor's list while a provider-wide value still applies; and
`magpie model context <provider>/*` reports that value rather than saying
the provider serves no such model. Validation happens where the entry is
written, so one hand-edited bad key cannot stop a theme or a window size
from saving, and #288's walk moves these on a provider rename without a
line here.
Magpie reports models.dev's list price for every call. That is the right
number for a vendor's own key and the wrong one for a provider that
resells or exposes a model at a different tariff, and it leaves a model the
catalogue does not list with no cost at all — a provider's own /models
gives ids, not economics.
magpie model price relay-a/gpt-5.5 0.12,1.20,0.01,0.15
magpie model price relay-a/* 0.12,1.20,0.01,0.15
magpie model price relay-a/gpt-5.5 --reset
magpie model prices
Absolute USD per million tokens. All four parts are required: a price
missing one would understate the rest of every call, and a hand-edited file
that left a part out would bill it at zero, so each part is a pointer and
the setter refuses a price that is negative, NaN or infinite, naming the
part at fault. Zero stays distinct throughout — a model served at no cost
has a price, not the absence of one. A `<provider>/*` entry covers every
model of that provider and an exact entry wins over it; --reset removes
only the exact entry and says so when a provider-wide one is still in
force.
The order a price is looked for in is the price for this model, then
`<provider>/*`, then the provider's own catalogue, then models.dev for the
maker. A price is a provider's tariff, not the model's: the same model
through two providers has two prices, and each keeps its own. A provider is
resolved by its id, or by an id it was renamed from, and never by its
display name — Find answers those too, and a record naming one was counted
at another provider's price.
provider.EffectivePrice is the one lookup every cost caller shares, so the
usage ledger and a session's totals both go through it, and a session
naming a model bare is still priced at its maker's list price, which is a
different question from what one provider charges. catalog.PriceOf and
PricedBy keep returning the models.dev price for anything wanting an
unbiased number. The background-task pickers (draw, search, vision) still
rank by catalogue price: they choose which model answers, not what a call
is reported to cost.
Unlike every other per-model preference this does not call
catalog.Touched. What a call costs is not what an agent picks a model by,
and the model lists magpie keeps in the agents' own files are not its to
rewrite over a number in a cost report. A rename moves the prices with it
through the walk #288 adds, so nothing here has to say so, and an id
recorded before a rename still resolves.
Validation happens where the entry is written, not in Save: one hand-edited
bad price in the file must not make saving a theme or a window size fail. A
price for a model the provider does not serve is refused the way
`magpie model name` refuses the same id, since it is a price that never
applies and nothing reports it as dead; a removal is exempt, so an entry
left for a model that has since gone can still be taken away.