Repository navigation
turnpike 0.3.0
Prices carry time. prices.json used to be a snapshot of now, so every refresh repriced all of history — DeepSeek's August increase (~2.5x blended on a real workload) would have under-reported new calls until models.dev caught up, then retroactively inflated a month of old ones the instant it did. The table is now a price history: each call is priced at the rates in force when it was made.
prices pull appends a dated revision rather than replacing what's there, stamped with the pull time — if you know the real date, edit effective_from and the next pull leaves it alone. Providers that bill by the clock get a recurring UTC off_peak window. Base rates always hold the undiscounted price, so a window you forget to write overcharges you on paper rather than hiding spend — the same bias as turnpike's refusal to report a confident $0.
That makes prices.json the only record of your price history, so it's treated as your data rather than a cache: a pull keeps the previous copy at prices.json.bak and swaps the new one in by rename, and a table it can't parse is an error that leaves the file untouched. A revision only has to state what changed — anything it omits it inherits from the base entry, so a hand-written revision can't quietly delete pricing it didn't mention.
Pre-existing tables have neither field, so they load and price identically.
turnpike stats --by-tool. Every call now records how its identity was learned, so --by-tool can group each one under its single best identity — the declared x-turnpike-client header when the caller sends one, otherwise the observed calling process, falling back to the User-Agent. One column per call instead of three you have to reconcile by hand. The new column forward-migrates onto existing databases; old rows keep the historical client-then-process order.
check has a fourth exit code. 3 is unknown — nothing is broken, turnpike just can't vouch for the number yet (no calls recorded, or some have no price). Previously that collapsed into 2 alongside a typo'd --budget and corrupt data, which meant "go investigate" and "wait for a price table" were the same signal:
turnpike check --budget 50/day -q
case $? in
0) ;; # under budget
1) ntfy send "LLM budget blown" ;; # at/over — the actionable alert
3) ;; # unknown — no data yet, or a price gap; not an error
*) exit $? ;; # 2: something's actually broken
esacIf you branch on check's exit code, this is the one thing to look at when upgrading.
Install: cargo install turnpike (crates.io) or cargo install --path . from a clone.
Full changelog: v0.2.0...v0.3.0