fix(pricing): price Claude Opus 5, correct Sonnet 5, drop retired models
Claude Opus 5 had no pricing row at all, so every token it burned was costed at $0 — the pattern list stopped at the 4.x Opus family and nothing matched `claude-opus-5`. Add it (5/25, fast mode 10/50, same shape as 4.8). Sonnet 5's launch discount expired 2026-08-31 and the discounted rate became the published standard, so the row's 3/15 standard rate started overcharging the day after. Fold 2/10 into DEFAULT_PRICING and empty DEFAULT_INTRO_PRICING; no model ships a promo today. Fable/Mythos 5.1 fell through to the `claude-fable-5%` row, which caches at $1/MTok against 5.1's $0.25 — give them their own rows. That overlap is only resolvable if the lookup prefers the more specific pattern, and `matchPricing` took `LIMIT 1` with no ORDER BY, i.e. whichever row was inserted first. Order by pattern length descending, which is what docs/DATABASE.md already claimed. (The nested REPLACE(model_pattern, '%', '%') it dropped was a no-op.) Retire Claude 3.x, Opus 4/4.1 and Sonnet 4 from the defaults. The startup top-up only ever ADDS missing rows, so removing them from DEFAULT_PRICING would leave every existing install untouched — prune them once, guarded by PRAGMA user_version (0 -> 1) so a model deliberately re-added in Settings survives later restarts. The same one-shot migration corrects the existing Sonnet 5 row. Only rates are deleted; token_usage is never touched, and Reset Defaults still restores the full current set.
This commit is contained in:
+10
-4
@@ -430,11 +430,17 @@ CREATE TABLE model_pricing (
|
||||
|
||||
Standard rates and intro rates are edited independently: the pricing update path writes intro columns only when the caller sends intro fields, so a standard-rate edit never disturbs a promo (and vice versa). Clearing `intro_until` also zeroes the intro rates.
|
||||
|
||||
**Example default rule (Claude Sonnet 5, with its launch promo):**
|
||||
**Example default rules:**
|
||||
|
||||
| Pattern | Input | Output | Intro Input | Intro Output | Intro Until |
|
||||
|---------|-------|--------|-------------|--------------|-------------|
|
||||
| `claude-sonnet-5%` | $3.00 | $15.00 | $2.00 | $10.00 | `2026-08-31` |
|
||||
| Pattern | Input | Output | Cache read | Fast in/out |
|
||||
|---------|-------|--------|------------|-------------|
|
||||
| `claude-opus-5%` | $5.00 | $25.00 | $0.50 | $10 / $50 |
|
||||
| `claude-sonnet-5%` | $2.00 | $10.00 | $0.20 | — |
|
||||
| `claude-fable-5-1%` | $10.00 | $50.00 | $0.25 | — |
|
||||
|
||||
No rule ships an intro rate today: Sonnet 5's launch promo ran through `2026-08-31` and its discounted rate became the standard one, so `DEFAULT_INTRO_PRICING` is empty. `claude-fable-5-1%` exists alongside `claude-fable-5%` only because 5.1 caches cheaper — that overlap is what the longest-pattern-first match rule above resolves.
|
||||
|
||||
**Retired models.** Claude 3.x, Opus 4/4.1 and Sonnet 4 were dropped from the defaults. Because the startup top-up only *adds* missing rows, those rows are also deleted once from existing databases, guarded by `PRAGMA user_version` (0 → 1) so a model you deliberately re-add in Settings survives later restarts. The same one-shot migration corrects the pre-existing Sonnet 5 row to its post-promo $2 / $10 standard rate. Deleting a rule never touches `token_usage` — only the rates used to price it.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user