price-table re-sync — deepseek-v4.1-flash and 173 price corrections from pi-ai 0.87.1

Costs were rendering '—' for tonight's extraction runs. Root cause: the
pi family bump (df1328e, 0.85.1 -> 0.87.1) added deepseek-v4.1-flash to
the shipped catalogs, but scripts/sync-pricing.ts was never re-run after
it — src/core/prices.ts was still the 2026-09-25 generation. The design
itself is sound and matches the owner's expectation: nothing stores
dollars; records keep tokens + model string; callCost infers at read
time from PRICES[model]. So the re-sync retroactively re-prices every
run the moment the entry lands.

- npx tsx scripts/sync-pricing.ts: 1495 keys (+314/-173 lines);
  openrouter:deepseek/deepseek-v4.1-flash = 0.15/0.6/0.003 (matches the
  catalog the picker serves)
- glm-5.3-flash price drift (0.075/0.25 -> 0.15/0.5, cacheRead 0.015 ->
  0.05): four pinned-cost tests re-derived (usage, cost-summary via
  callCost, activity-dock, stats-bar)
- prices.ts header: dropped the false bare-slug-legacy claim (the table
  has zero bare keys; sync emits provider-qualified only) and noted the
  forgetting-the-sync failure mode
This commit is contained in:
amosblomqvist
2026-09-29 04:30:15 +03:00
parent 5707672a09
commit 82503446c8
4 changed files with 333 additions and 188 deletions
+320 -177
View File
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -70,9 +70,9 @@ describe("activity dock pure layer", () => {
}, },
}); });
const blob = toBlobs({ jobs: [priced], extractions: [] })[0]!; const blob = toBlobs({ jobs: [priced], extractions: [] })[0]!;
// (10000-5000)/1e6*0.075 + 5000/1e6*0.015 + 1000/1e6*0.25 = 0.0007 // (10000-5000)/1e6*0.15 + 5000/1e6*0.05 + 1000/1e6*0.5 = 0.0015
// (pi-ai catalog prices) // (pi-ai catalog prices — glm-5.3-flash drifted in pi-ai 0.87.1)
assert.ok(blob.cost !== null && blob.cost > 0.0006 && blob.cost < 0.0008); assert.ok(blob.cost !== null && blob.cost > 0.0014 && blob.cost < 0.0016);
const absent = toBlobs({ jobs: [job()], extractions: [] })[0]!; const absent = toBlobs({ jobs: [job()], extractions: [] })[0]!;
assert.equal(absent.cost, null); assert.equal(absent.cost, null);
}); });
@@ -243,7 +243,8 @@ describe("activity section render", () => {
}} }}
/>, />,
); );
// two identical priced jobs → 2 × $0.001 = $0.0020 total (pi prices) // two identical priced jobs → 2 × $0.002 = $0.0040 total (pi prices,
assert.match(html, /activity-total-cost[^>]*>\$0\.0020</); // glm-5.3-flash drifted in pi-ai 0.87.1)
assert.match(html, /activity-total-cost[^>]*>\$0\.0040</);
}); });
}); });
+3 -3
View File
@@ -57,9 +57,9 @@ describe("stats bar", () => {
// catalog join lands with the UI chunk), so the meter renders // catalog join lands with the UI chunk), so the meter renders
// USAGE-ONLY (owner amendment: never a fallback window). // USAGE-ONLY (owner amendment: never a fallback window).
assert.match(html, /data-testid="stats-context">11k</); assert.match(html, /data-testid="stats-context">11k</);
// pi catalog price 0.075/0.25 per 1M: each turn 10k×0.075 + 1k×0.25 // pi catalog price 0.15/0.5 per 1M (drifted in pi-ai 0.87.1):
// = $0.001 → two = $0.0020 // each turn 10k×0.15 + 1k×0.5 = $0.002 → two = $0.0040
assert.match(html, /data-testid="stats-cost">\$0\.0020</); assert.match(html, /data-testid="stats-cost">\$0\.0040</);
// model button label: SSR (record fetch not run yet) reads "—" — // model button label: SSR (record fetch not run yet) reads "—" —
// the strong slot arrives client-side via GET /api/settings; the // the strong slot arrives client-side via GET /api/settings; the
// turn log below still folds the ACTUAL models billed // turn log below still folds the ACTUAL models billed
+4 -3
View File
@@ -42,9 +42,10 @@ test("sumSteps folds steps; absent stays absent until a value appears", () => {
test("callCost: glm-5.3-flash math — fresh input, cached read, output", () => { test("callCost: glm-5.3-flash math — fresh input, cached read, output", () => {
const cost = callCost(call({ inputTokens: 100_000, outputTokens: 20_000, cacheReadTokens: 10_000 }), "openrouter:z-ai/glm-5.3-flash"); const cost = callCost(call({ inputTokens: 100_000, outputTokens: 20_000, cacheReadTokens: 10_000 }), "openrouter:z-ai/glm-5.3-flash");
assert.ok(cost !== null); assert.ok(cost !== null);
// fresh 90k @ $0.075/M + cached 10k @ $0.015/M + output 20k @ $0.25/M // fresh 90k @ $0.15/M + cached 10k @ $0.05/M + output 20k @ $0.5/M
// (pi-ai catalog prices — regenerated tables, scripts/sync-pricing) // (pi-ai catalog prices — regenerated tables, scripts/sync-pricing;
assert.ok(Math.abs(cost! - (0.00675 + 0.00015 + 0.005)) < 1e-9); // prices drifted in pi-ai 0.87.1, owner's cost fix 2026-09-29)
assert.ok(Math.abs(cost! - (0.0135 + 0.0005 + 0.01)) < 1e-9);
}); });
test("callCost: cache writes bill at the cacheWrite rate", () => { test("callCost: cache writes bill at the cacheWrite rate", () => {