@trazum/core 2.4.1 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/pdf.d.ts +108 -0
- package/dist/pdf.d.ts.map +1 -0
- package/dist/pdf.js +323 -0
- package/dist/pdf.js.map +1 -0
- package/dist/pricing.d.ts +7 -6
- package/dist/pricing.d.ts.map +1 -1
- package/dist/pricing.js +368 -53
- package/dist/pricing.js.map +1 -1
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usage.d.ts +5 -1
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +14 -2
- package/dist/usage.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +4 -0
- package/src/pdf.ts +356 -0
- package/src/pricing.ts +375 -53
- package/src/types.ts +28 -0
- package/src/usage.ts +19 -3
package/dist/pricing.js
CHANGED
|
@@ -28,8 +28,13 @@
|
|
|
28
28
|
* catalogue's headline date derived as the oldest of them rather than typed.
|
|
29
29
|
*/
|
|
30
30
|
export const PROVIDER_REVIEWED = Object.freeze({
|
|
31
|
-
/*
|
|
32
|
-
|
|
31
|
+
/*
|
|
32
|
+
* platform.claude.com/docs/en/about-claude/pricing, the models overview and
|
|
33
|
+
* each model's own page, read 2026-10-10. Every existing row matched; five
|
|
34
|
+
* models were added and one (Claude Haiku 5.5) deliberately was not, see the
|
|
35
|
+
* comment above its would-be place in MODELS.
|
|
36
|
+
*/
|
|
37
|
+
anthropic: '2026-10-10',
|
|
33
38
|
/*
|
|
34
39
|
* developers.openai.com/api/docs/pricing, read 2026-08-31.
|
|
35
40
|
*
|
|
@@ -41,10 +46,30 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
41
46
|
* and priority. The standard one is the catalogue's, identified by the other
|
|
42
47
|
* three being its multiples (0.5x, 0.5x, 2x) rather than by trusting the
|
|
43
48
|
* order they appear in.
|
|
49
|
+
*
|
|
50
|
+
* Re-read 2026-10-11 with the prompt-caching guide, the GPT-5 model page and
|
|
51
|
+
* the deprecations page. GPT-5, mini and nano matched to the cent. Their
|
|
52
|
+
* dated snapshots (`gpt-5-2025-08-07` and the mini and nano ones), which is
|
|
53
|
+
* the id a usage log usually carries, shut down on 2026-12-11 and are now
|
|
54
|
+
* declared as aliases. The current generation (gpt-6-astra, gpt-6.1-sol,
|
|
55
|
+
* gpt-6-sol, gpt-6-luna and gpt-5.6 sol, terra and luna) is on the same
|
|
56
|
+
* page and not added: every one of them doubles its rates for prompts over
|
|
57
|
+
* 272K tokens, a per-request condition no log Trazum prices passes yet.
|
|
58
|
+
*/
|
|
59
|
+
openai: '2026-10-11',
|
|
60
|
+
/*
|
|
61
|
+
* ai.google.dev/gemini-api/docs/pricing, docs/caching and the model pages,
|
|
62
|
+
* read 2026-10-10. Every price matched; what changed is how caching starts
|
|
63
|
+
* and what it costs on the old models. Implicit caching is on by default
|
|
64
|
+
* for every Gemini 2.5 and newer model, so `caching` is 'automatic' across
|
|
65
|
+
* the board; the minimums moved to 4,096 on 3.6 and 3.8 Flash and 2,048 on
|
|
66
|
+
* 2.5 Flash; and the 2.5 models read the cache at 10% of input today, not
|
|
67
|
+
* the 25% this table carried. Gemini 3.8 Flash was added. Gemini 3.1 Pro
|
|
68
|
+
* Preview and 2.5 Pro's prompts over 200k are priced by prompt length per
|
|
69
|
+
* request, which nothing that prices a log passes yet, so the first is left
|
|
70
|
+
* out and the second's tier is named in its note rather than guessed.
|
|
44
71
|
*/
|
|
45
|
-
|
|
46
|
-
/* ai.google.dev/gemini-api/docs/pricing, read 2026-08-28. */
|
|
47
|
-
google: '2026-08-28',
|
|
72
|
+
google: '2026-10-10',
|
|
48
73
|
/*
|
|
49
74
|
* platform.kimi.ai/docs/pricing/chat (platform.moonshot.ai 301s there),
|
|
50
75
|
* read 2026-09-12. The page prices kimi-k3, kimi-k2.6, kimi-k2.7-code and
|
|
@@ -57,8 +82,15 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
57
82
|
* not read is a number it would be inventing.
|
|
58
83
|
*/
|
|
59
84
|
moonshot: '2026-09-12',
|
|
60
|
-
/*
|
|
61
|
-
|
|
85
|
+
/*
|
|
86
|
+
* api-docs.deepseek.com/quick_start/pricing read 2026-10-10, and the
|
|
87
|
+
* 2026-09-10 announcement (api-docs.deepseek.com/news/news260910) read
|
|
88
|
+
* 2026-10-11 for the instant: "New pricing takes effect at 04:00 UTC on
|
|
89
|
+
* Sept 10, 2026." V4 Flash was retired that day and its id now bills at
|
|
90
|
+
* the new deepseek-flash price, so the old price lives in its `history`.
|
|
91
|
+
* V4 Pro matched the page unchanged.
|
|
92
|
+
*/
|
|
93
|
+
deepseek: '2026-10-10',
|
|
62
94
|
/*
|
|
63
95
|
* docs.x.ai/docs/models, read 2026-09-12. The page prices grok-4.6, 4.5,
|
|
64
96
|
* 4.3 and the 4.20 family, each at two rates split at 200k prompt tokens;
|
|
@@ -79,7 +111,18 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
79
111
|
* servable is not the same as checking, and moving the date then would have
|
|
80
112
|
* said it was.
|
|
81
113
|
*/
|
|
82
|
-
|
|
114
|
+
/*
|
|
115
|
+
* Re-read 2026-10-11 from mistral.ai/cloud/inference/ and the model cards
|
|
116
|
+
* at mistral.ai/news/mistral-3/, /mistral-small-4/ and
|
|
117
|
+
* /vibe-remote-agents-mistral-medium-3-5/, which carry the prices in their
|
|
118
|
+
* markup (`data-prices`) and bind the `-latest` ids. Every price matched.
|
|
119
|
+
* What changed is caching: the inference page offers "Cached input tokens
|
|
120
|
+
* -90% on input token", and every one of the three cards marks its input
|
|
121
|
+
* price as carrying the cache discount. This table said Mistral had no
|
|
122
|
+
* prompt caching at all. docs.mistral.ai, where a minimum or a mechanism
|
|
123
|
+
* would be, is not reachable from here, so neither is claimed.
|
|
124
|
+
*/
|
|
125
|
+
mistral: '2026-10-11',
|
|
83
126
|
});
|
|
84
127
|
/**
|
|
85
128
|
* The catalogue's age is its oldest provider's, because a reader asking how
|
|
@@ -90,11 +133,12 @@ export const PRICING_LAST_REVIEWED = Object.values(PROVIDER_REVIEWED).reduce((ol
|
|
|
90
133
|
/**
|
|
91
134
|
* The defaults, which are Anthropic's numbers.
|
|
92
135
|
*
|
|
93
|
-
* Still exported and still
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
136
|
+
* Still exported, and still Anthropic's numbers for every model up to Opus 5
|
|
137
|
+
* and Sonnet 5, but no longer the whole story even there: Claude Fable 5.1 and
|
|
138
|
+
* Mythos 5.1 read the cache at 0.025x and Opus 5.5 and Sonnet 5.5 at 0.05x, so
|
|
139
|
+
* a model overrides any of these through `multipliers`, and anything computing
|
|
140
|
+
* a cost should go through `multipliersFor` rather than reading these
|
|
141
|
+
* directly. Using one cache-read ratio for every model invents a saving.
|
|
98
142
|
*/
|
|
99
143
|
export const COST_MULTIPLIERS = {
|
|
100
144
|
/** Cache write with a 5-minute TTL. */
|
|
@@ -115,7 +159,13 @@ export const COST_MULTIPLIERS = {
|
|
|
115
159
|
*/
|
|
116
160
|
/** Memoised for the same reason as `effectivePricing`: once per record. */
|
|
117
161
|
const multipliersMemo = new WeakMap();
|
|
118
|
-
export function multipliersFor(model) {
|
|
162
|
+
export function multipliersFor(model, on) {
|
|
163
|
+
// A dated question about a repriced model asks the period in force then.
|
|
164
|
+
if (on !== undefined && model.history !== undefined) {
|
|
165
|
+
const period = pricedAt(model, on);
|
|
166
|
+
if (period !== model)
|
|
167
|
+
return multipliersFor(period);
|
|
168
|
+
}
|
|
119
169
|
const cached = multipliersMemo.get(model);
|
|
120
170
|
if (cached !== undefined)
|
|
121
171
|
return cached;
|
|
@@ -129,7 +179,60 @@ export function multipliersFor(model) {
|
|
|
129
179
|
multipliersMemo.set(model, result);
|
|
130
180
|
return result;
|
|
131
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Mistral discounts cached input by 90% and publishes nothing else about it
|
|
184
|
+
* that can be read from here: not how caching starts, not a minimum, not a
|
|
185
|
+
* write price. Its usage reports no write tokens, so the write ratio of 1 is
|
|
186
|
+
* never multiplied by anything; it is there so the default (Anthropic's 1.25)
|
|
187
|
+
* cannot be.
|
|
188
|
+
*/
|
|
189
|
+
/** What the GPT-5 family's three rows share, from OpenAI's guide and deprecations page, read 2026-10-11. */
|
|
190
|
+
const OPENAI_GPT5_NOTE = 'Caching is automatic, with no cache_control to set. OpenAI says the minimum for models before GPT-5.6 varies by'
|
|
191
|
+
+ ' request settings, so 1,024 here is the nearest published floor. The 2025-08-07 snapshot shuts down on'
|
|
192
|
+
+ ' 2026-12-11; OpenAI names the gpt-5.6 models as replacements.';
|
|
193
|
+
const MISTRAL_CACHE_NOTE = 'Cached input costs 10% of the input price (mistral.ai/cloud/inference, read 2026-10-11). How caching starts and'
|
|
194
|
+
+ ' its minimum are not published anywhere Trazum can read, so no caching advice is given for it.';
|
|
132
195
|
export const MODELS = [
|
|
196
|
+
{
|
|
197
|
+
/*
|
|
198
|
+
* platform.claude.com/docs/en/about-claude/pricing and the Fable 5.1 model
|
|
199
|
+
* page, read 2026-10-10. The same $10/$50 as Fable 5; what moved is the
|
|
200
|
+
* cache read, $0.25 against $10 of input, a quarter of the 0.1x every
|
|
201
|
+
* earlier Claude model pays. Writes stay at 1.25x and 2x ($12.50, $20),
|
|
202
|
+
* and the Batch API halves both sides ($5/$25).
|
|
203
|
+
*/
|
|
204
|
+
id: 'claude-fable-5-1',
|
|
205
|
+
provider: 'anthropic',
|
|
206
|
+
displayName: 'Claude Fable 5.1',
|
|
207
|
+
inputPerMTok: 10,
|
|
208
|
+
outputPerMTok: 50,
|
|
209
|
+
contextWindow: 1_000_000,
|
|
210
|
+
cacheMinTokens: 512,
|
|
211
|
+
multipliers: { cacheRead: 0.025, cacheWrite5m: 1.25, cacheWrite1h: 2, batch: 0.5 },
|
|
212
|
+
capability: 'frontier',
|
|
213
|
+
tier: 'frontier',
|
|
214
|
+
notes: 'Cache hits cost 2.5% of the input price ($0.25). Requires 30-day data retention.',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
/*
|
|
218
|
+
* The same page and prices as Fable 5.1, cache read included ($0.25,
|
|
219
|
+
* 0.025x). Sold only to verified organisations, so priced for the logs that
|
|
220
|
+
* carry it and never offered as somebody's cheaper alternative.
|
|
221
|
+
*/
|
|
222
|
+
id: 'claude-mythos-5-1',
|
|
223
|
+
provider: 'anthropic',
|
|
224
|
+
displayName: 'Claude Mythos 5.1',
|
|
225
|
+
recommendable: false,
|
|
226
|
+
inputPerMTok: 10,
|
|
227
|
+
outputPerMTok: 50,
|
|
228
|
+
contextWindow: 1_000_000,
|
|
229
|
+
cacheMinTokens: 512,
|
|
230
|
+
multipliers: { cacheRead: 0.025, cacheWrite5m: 1.25, cacheWrite1h: 2, batch: 0.5 },
|
|
231
|
+
capability: 'frontier',
|
|
232
|
+
tier: 'frontier',
|
|
233
|
+
notes: 'Available only to organizations verified through Anthropic\'s verification programs.'
|
|
234
|
+
+ ' Requires 30-day data retention.',
|
|
235
|
+
},
|
|
133
236
|
{
|
|
134
237
|
id: 'claude-fable-5',
|
|
135
238
|
provider: 'anthropic',
|
|
@@ -140,7 +243,7 @@ export const MODELS = [
|
|
|
140
243
|
cacheMinTokens: 512,
|
|
141
244
|
capability: 'frontier',
|
|
142
245
|
tier: 'frontier',
|
|
143
|
-
notes: '
|
|
246
|
+
notes: 'Legacy: superseded by Claude Fable 5.1 at the same prices. Requires 30-day data retention.',
|
|
144
247
|
},
|
|
145
248
|
{
|
|
146
249
|
id: 'claude-mythos-5',
|
|
@@ -153,7 +256,27 @@ export const MODELS = [
|
|
|
153
256
|
cacheMinTokens: 512,
|
|
154
257
|
capability: 'frontier',
|
|
155
258
|
tier: 'frontier',
|
|
156
|
-
notes: 'Available only through
|
|
259
|
+
notes: 'Available only to organizations verified through Anthropic\'s verification programs.'
|
|
260
|
+
+ ' Requires 30-day data retention.',
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
/*
|
|
264
|
+
* The pricing page and the Opus 5.5 model page, read 2026-10-10. Cheaper
|
|
265
|
+
* than Opus 5 at both ends, $4/$20, and the overview now says to start
|
|
266
|
+
* there for most workloads. Cache read $0.20 is 0.05x, half the ratio of
|
|
267
|
+
* every earlier Opus; writes $5 and $8 are 1.25x and 2x; batch $2/$10.
|
|
268
|
+
*/
|
|
269
|
+
id: 'claude-opus-5-5',
|
|
270
|
+
provider: 'anthropic',
|
|
271
|
+
displayName: 'Claude Opus 5.5',
|
|
272
|
+
inputPerMTok: 4,
|
|
273
|
+
outputPerMTok: 20,
|
|
274
|
+
contextWindow: 1_000_000,
|
|
275
|
+
cacheMinTokens: 512,
|
|
276
|
+
multipliers: { cacheRead: 0.05, cacheWrite5m: 1.25, cacheWrite1h: 2, batch: 0.5 },
|
|
277
|
+
capability: 'large',
|
|
278
|
+
tier: 'opus',
|
|
279
|
+
notes: 'Cache hits cost 5% of the input price ($0.20), against 10% on Opus 5 and earlier.',
|
|
157
280
|
},
|
|
158
281
|
{
|
|
159
282
|
id: 'claude-opus-5',
|
|
@@ -200,6 +323,45 @@ export const MODELS = [
|
|
|
200
323
|
capability: 'large',
|
|
201
324
|
tier: 'opus',
|
|
202
325
|
},
|
|
326
|
+
{
|
|
327
|
+
/*
|
|
328
|
+
* Legacy and still served, and never carried here before, so every
|
|
329
|
+
* Claude Code log from late 2025 had it as an unpriced gap. The Opus 4.5
|
|
330
|
+
* model page, read 2026-10-10: model id claude-opus-4-5-20251101, alias
|
|
331
|
+
* claude-opus-4-5, 200K context, $5/$25, 4,096-token cache minimum (the
|
|
332
|
+
* prompt caching page). Like Haiku 4.5, the short alias is the id and the
|
|
333
|
+
* dated canonical form is declared, not derived.
|
|
334
|
+
*/
|
|
335
|
+
id: 'claude-opus-4-5',
|
|
336
|
+
aliases: ['claude-opus-4-5-20251101'],
|
|
337
|
+
provider: 'anthropic',
|
|
338
|
+
displayName: 'Claude Opus 4.5',
|
|
339
|
+
inputPerMTok: 5,
|
|
340
|
+
outputPerMTok: 25,
|
|
341
|
+
contextWindow: 200_000,
|
|
342
|
+
cacheMinTokens: 4096,
|
|
343
|
+
capability: 'large',
|
|
344
|
+
tier: 'opus',
|
|
345
|
+
notes: '200K context window and a 64K output cap.',
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
/*
|
|
349
|
+
* The pricing page and the Sonnet 5.5 model page, read 2026-10-10. The
|
|
350
|
+
* same $2/$10 as Sonnet 5, with the cache read at $0.10, 0.05x, where
|
|
351
|
+
* Sonnet 5 reads at $0.20. Writes $2.50 and $4; batch $1/$5.
|
|
352
|
+
*/
|
|
353
|
+
id: 'claude-sonnet-5-5',
|
|
354
|
+
provider: 'anthropic',
|
|
355
|
+
displayName: 'Claude Sonnet 5.5',
|
|
356
|
+
inputPerMTok: 2,
|
|
357
|
+
outputPerMTok: 10,
|
|
358
|
+
contextWindow: 1_000_000,
|
|
359
|
+
cacheMinTokens: 512,
|
|
360
|
+
multipliers: { cacheRead: 0.05, cacheWrite5m: 1.25, cacheWrite1h: 2, batch: 0.5 },
|
|
361
|
+
capability: 'mid',
|
|
362
|
+
tier: 'sonnet',
|
|
363
|
+
notes: 'Cache hits cost 5% of the input price ($0.10), against 10% ($0.20) on Sonnet 5.',
|
|
364
|
+
},
|
|
203
365
|
{
|
|
204
366
|
id: 'claude-sonnet-5',
|
|
205
367
|
provider: 'anthropic',
|
|
@@ -224,6 +386,18 @@ export const MODELS = [
|
|
|
224
386
|
capability: 'mid',
|
|
225
387
|
tier: 'sonnet',
|
|
226
388
|
},
|
|
389
|
+
/*
|
|
390
|
+
* Claude Haiku 5.5 is not here, on purpose, and its calls are an unpriced
|
|
391
|
+
* gap that names it. The pricing page (read 2026-10-10) prices it by prompt
|
|
392
|
+
* length: $0.10/$0.50 up to 100,000 tokens and $0.50/$2.50 above, where the
|
|
393
|
+
* length counts cache reads and writes and each request is priced on its
|
|
394
|
+
* own. A tier can say that, but nothing that prices a usage log passes one
|
|
395
|
+
* request's prompt length to `effectivePricing`: records are summed per
|
|
396
|
+
* workload, model and day before they are priced. Added today, every Haiku
|
|
397
|
+
* 5.5 call would fall to the undecided ceiling, five times the price most of
|
|
398
|
+
* them paid. It goes in with the change that prices tiered models per
|
|
399
|
+
* request, not before.
|
|
400
|
+
*/
|
|
227
401
|
{
|
|
228
402
|
id: 'claude-haiku-4-5',
|
|
229
403
|
// The dated form is the canonical API id and is what a real usage log
|
|
@@ -243,13 +417,17 @@ export const MODELS = [
|
|
|
243
417
|
// ------------------------------------------------------------------------
|
|
244
418
|
// OpenAI
|
|
245
419
|
//
|
|
246
|
-
// Caching is AUTOMATIC
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
//
|
|
420
|
+
// Caching is AUTOMATIC, with no cache_control to set, and a cached read costs
|
|
421
|
+
// a tenth of input on these three ($0.125 against $1.25). The reordering
|
|
422
|
+
// advice is identical (a prefix is a prefix), the marker advice is not, which
|
|
423
|
+
// is why `caching` and `multipliers` exist at all. The 1,024 minimum is the
|
|
424
|
+
// one OpenAI publishes for GPT-5.6 and later; for these older models its
|
|
425
|
+
// guide says the minimum "varies by request settings", so it is the nearest
|
|
426
|
+
// published floor, not a promise, and each row's note says so.
|
|
250
427
|
// ------------------------------------------------------------------------
|
|
251
428
|
{
|
|
252
429
|
id: 'gpt-5',
|
|
430
|
+
aliases: ['gpt-5-2025-08-07'],
|
|
253
431
|
provider: 'openai',
|
|
254
432
|
displayName: 'GPT-5',
|
|
255
433
|
inputPerMTok: 1.25,
|
|
@@ -260,10 +438,11 @@ export const MODELS = [
|
|
|
260
438
|
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
261
439
|
capability: 'frontier',
|
|
262
440
|
tier: 'frontier',
|
|
263
|
-
notes:
|
|
441
|
+
notes: OPENAI_GPT5_NOTE,
|
|
264
442
|
},
|
|
265
443
|
{
|
|
266
444
|
id: 'gpt-5-mini',
|
|
445
|
+
aliases: ['gpt-5-mini-2025-08-07'],
|
|
267
446
|
provider: 'openai',
|
|
268
447
|
displayName: 'GPT-5 mini',
|
|
269
448
|
inputPerMTok: 0.25,
|
|
@@ -274,9 +453,11 @@ export const MODELS = [
|
|
|
274
453
|
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
275
454
|
capability: 'mid',
|
|
276
455
|
tier: 'sonnet',
|
|
456
|
+
notes: OPENAI_GPT5_NOTE,
|
|
277
457
|
},
|
|
278
458
|
{
|
|
279
459
|
id: 'gpt-5-nano',
|
|
460
|
+
aliases: ['gpt-5-nano-2025-08-07'],
|
|
280
461
|
provider: 'openai',
|
|
281
462
|
displayName: 'GPT-5 nano',
|
|
282
463
|
inputPerMTok: 0.05,
|
|
@@ -287,6 +468,7 @@ export const MODELS = [
|
|
|
287
468
|
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
288
469
|
capability: 'small',
|
|
289
470
|
tier: 'haiku',
|
|
471
|
+
notes: OPENAI_GPT5_NOTE,
|
|
290
472
|
},
|
|
291
473
|
// ------------------------------------------------------------------------
|
|
292
474
|
// Google
|
|
@@ -299,8 +481,9 @@ export const MODELS = [
|
|
|
299
481
|
outputPerMTok: 10,
|
|
300
482
|
contextWindow: 1_048_576,
|
|
301
483
|
cacheMinTokens: 2048,
|
|
302
|
-
caching: '
|
|
303
|
-
|
|
484
|
+
caching: 'automatic',
|
|
485
|
+
/* $0.125 cached against $1.25 input for prompts up to 200k, read 2026-10-10. */
|
|
486
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
304
487
|
/* Refused on 2026-08-28: still in `GET /v1beta/models`, and a 404 to a request. */
|
|
305
488
|
retired: {
|
|
306
489
|
on: '2026-08-28',
|
|
@@ -308,7 +491,9 @@ export const MODELS = [
|
|
|
308
491
|
},
|
|
309
492
|
capability: 'large',
|
|
310
493
|
tier: 'opus',
|
|
311
|
-
notes: '
|
|
494
|
+
notes: 'Prompts over 200k tokens are billed $2.50 in and $15.00 out; this row prices every prompt at the up-to-200k rate,'
|
|
495
|
+
+ ' because no log Trazum prices says how long each prompt was. Implicit caching is automatic; explicit caching is'
|
|
496
|
+
+ ' also billed for storage per hour.',
|
|
312
497
|
},
|
|
313
498
|
{
|
|
314
499
|
id: 'gemini-2.5-flash',
|
|
@@ -317,9 +502,10 @@ export const MODELS = [
|
|
|
317
502
|
inputPerMTok: 0.3,
|
|
318
503
|
outputPerMTok: 2.5,
|
|
319
504
|
contextWindow: 1_048_576,
|
|
320
|
-
cacheMinTokens:
|
|
321
|
-
caching: '
|
|
322
|
-
|
|
505
|
+
cacheMinTokens: 2048,
|
|
506
|
+
caching: 'automatic',
|
|
507
|
+
/* $0.03 cached against $0.30 input (text), read 2026-10-10. */
|
|
508
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
323
509
|
/* Refused on 2026-08-28: still in `GET /v1beta/models`, and a 404 to a request. */
|
|
324
510
|
retired: {
|
|
325
511
|
on: '2026-08-28',
|
|
@@ -330,9 +516,10 @@ export const MODELS = [
|
|
|
330
516
|
},
|
|
331
517
|
{
|
|
332
518
|
/*
|
|
333
|
-
* Google's own error message names this as the replacement for the
|
|
334
|
-
*
|
|
335
|
-
* rates, read 2026-08-28
|
|
519
|
+
* Google's own error message names this as the replacement for the retired
|
|
520
|
+
* 2.5 Flash (the 2.5 Pro refusal names 3.1 Pro Preview), and
|
|
521
|
+
* ai.google.dev/gemini-api/docs/pricing carries the rates, read 2026-08-28
|
|
522
|
+
* and again on 2026-10-10.
|
|
336
523
|
*
|
|
337
524
|
* The introductory price has a published end date and a published successor,
|
|
338
525
|
* which is exactly what `promo` is for and is the shape the catalogue nearly
|
|
@@ -346,8 +533,8 @@ export const MODELS = [
|
|
|
346
533
|
outputPerMTok: 7.5,
|
|
347
534
|
promo: { inputPerMTok: 0.75, outputPerMTok: 3.75, until: '2026-12-31' },
|
|
348
535
|
contextWindow: 1_048_576,
|
|
349
|
-
cacheMinTokens:
|
|
350
|
-
caching: '
|
|
536
|
+
cacheMinTokens: 4096,
|
|
537
|
+
caching: 'automatic',
|
|
351
538
|
/*
|
|
352
539
|
* $0.075 against $0.75 inside the introductory window, and $0.15 against
|
|
353
540
|
* $1.50 after it: Google scales the cache price with the headline one, so
|
|
@@ -357,7 +544,31 @@ export const MODELS = [
|
|
|
357
544
|
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
358
545
|
capability: 'mid',
|
|
359
546
|
tier: 'sonnet',
|
|
360
|
-
notes: '
|
|
547
|
+
notes: 'Implicit caching is automatic above 4,096 tokens. Explicit caching is also billed for storage:'
|
|
548
|
+
+ ' $0.50 per 1M tokens per hour through 2026-12-31, $1.00 after.',
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
/*
|
|
552
|
+
* Gemini 3.8 Flash, from ai.google.dev/gemini-api/docs/pricing, its model
|
|
553
|
+
* page and docs/caching, read 2026-10-10. The same rates and the same
|
|
554
|
+
* introductory window as 3.6 Flash, published as one table each: $0.75
|
|
555
|
+
* and $3.75 through 2026-12-31, $1.50 and $7.50 from 2027-01-01, and the
|
|
556
|
+
* cache price scales with them ($0.075, then $0.15).
|
|
557
|
+
*/
|
|
558
|
+
id: 'gemini-3.8-flash',
|
|
559
|
+
provider: 'google',
|
|
560
|
+
displayName: 'Gemini 3.8 Flash',
|
|
561
|
+
inputPerMTok: 1.5,
|
|
562
|
+
outputPerMTok: 7.5,
|
|
563
|
+
promo: { inputPerMTok: 0.75, outputPerMTok: 3.75, until: '2026-12-31' },
|
|
564
|
+
contextWindow: 1_048_576,
|
|
565
|
+
cacheMinTokens: 4096,
|
|
566
|
+
caching: 'automatic',
|
|
567
|
+
/* $0.075 / $0.75 = 0.1 (and $0.15 / $1.50); batch $0.375 / $0.75 = 0.5 (and $1.875 / $3.75). */
|
|
568
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
569
|
+
capability: 'mid',
|
|
570
|
+
tier: 'sonnet',
|
|
571
|
+
notes: 'Implicit caching is automatic above 4,096 tokens. Explicit caching is also billed for storage:'
|
|
361
572
|
+ ' $0.50 per 1M tokens per hour through 2026-12-31, $1.00 after.',
|
|
362
573
|
},
|
|
363
574
|
// ------------------------------------------------------------------------
|
|
@@ -401,34 +612,95 @@ export const MODELS = [
|
|
|
401
612
|
},
|
|
402
613
|
{
|
|
403
614
|
/*
|
|
404
|
-
* DeepSeek V4 Flash,
|
|
405
|
-
* 2026-
|
|
615
|
+
* DeepSeek V4 Flash, retired on 2026-09-10. The pricing page (read
|
|
616
|
+
* 2026-10-10) says the id "is still accepted ... served by the
|
|
617
|
+
* DeepSeek-V4.1-Flash model and billed at the Flash price", so from
|
|
618
|
+
* 04:00 UTC that day it carries deepseek-flash's rates. Before that
|
|
619
|
+
* instant it billed at its own, read off the same page on 2026-08-28:
|
|
620
|
+
* $0.22/$0.66 off-peak, double at peak, $0.007 a cache hit.
|
|
406
621
|
*
|
|
407
622
|
* The base rate is off-peak because off-peak is the common case: peak is
|
|
408
623
|
* 01:00-04:00 and 06:00-10:00 UTC on weekdays, which is 35 hours of 168.
|
|
409
|
-
* The peak tier is exactly double, published as such.
|
|
624
|
+
* The peak tier is exactly double, published as such. Clock pricing began
|
|
625
|
+
* at 16:00 UTC on 2026-08-16; the flat price before it is on no page this
|
|
626
|
+
* table can read, so calls before then are priced as the first period.
|
|
627
|
+
*
|
|
628
|
+
* Not recommendable: a legacy id DeepSeek routes "temporarily". Without
|
|
629
|
+
* this, a tie on price would offer it ahead of deepseek-flash.
|
|
410
630
|
*/
|
|
411
631
|
id: 'deepseek-v4-flash',
|
|
412
632
|
provider: 'deepseek',
|
|
413
633
|
displayName: 'DeepSeek V4 Flash',
|
|
414
|
-
|
|
415
|
-
|
|
634
|
+
recommendable: false,
|
|
635
|
+
inputPerMTok: 0.15,
|
|
636
|
+
outputPerMTok: 0.6,
|
|
416
637
|
tiers: [
|
|
417
638
|
{
|
|
418
639
|
id: 'peak',
|
|
419
640
|
when: { kind: 'utc-hours', hours: [1, 2, 3, 6, 7, 8, 9], weekdaysOnly: true },
|
|
420
|
-
inputPerMTok: 0.
|
|
421
|
-
outputPerMTok: 1.
|
|
641
|
+
inputPerMTok: 0.3,
|
|
642
|
+
outputPerMTok: 1.2,
|
|
643
|
+
},
|
|
644
|
+
],
|
|
645
|
+
history: [
|
|
646
|
+
{
|
|
647
|
+
until: '2026-09-10T04:00:00Z',
|
|
648
|
+
inputPerMTok: 0.22,
|
|
649
|
+
outputPerMTok: 0.66,
|
|
650
|
+
tiers: [
|
|
651
|
+
{
|
|
652
|
+
id: 'peak',
|
|
653
|
+
when: { kind: 'utc-hours', hours: [1, 2, 3, 6, 7, 8, 9], weekdaysOnly: true },
|
|
654
|
+
inputPerMTok: 0.44,
|
|
655
|
+
outputPerMTok: 1.32,
|
|
656
|
+
},
|
|
657
|
+
],
|
|
658
|
+
/* $0.007 cache hit against $0.22 input off-peak. */
|
|
659
|
+
multipliers: { cacheRead: 0.0318, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
422
660
|
},
|
|
423
661
|
],
|
|
424
662
|
contextWindow: 1_000_000,
|
|
425
663
|
cacheMinTokens: 1024,
|
|
426
664
|
caching: 'automatic',
|
|
427
|
-
/* $0.
|
|
428
|
-
multipliers: { cacheRead: 0.
|
|
665
|
+
/* $0.003 cache hit against $0.15 input off-peak, $0.006 against $0.30 at peak. */
|
|
666
|
+
multipliers: { cacheRead: 0.02, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
429
667
|
capability: 'mid',
|
|
430
668
|
tier: 'sonnet',
|
|
431
|
-
notes: '
|
|
669
|
+
notes: 'Retired 2026-09-10: the id is still accepted, served by V4.1 Flash and billed at the deepseek-flash price.'
|
|
670
|
+
+ ' Maximum output 384K tokens. Peak excludes Chinese public holidays, which this table cannot express.',
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
/*
|
|
674
|
+
* DeepSeek V4.1 Flash, from api-docs.deepseek.com/quick_start/pricing,
|
|
675
|
+
* read 2026-10-10. Released 2026-09-10; its price took effect at 04:00
|
|
676
|
+
* UTC that day. Off-peak is the base and peak is exactly double, as
|
|
677
|
+
* published; the cache hit is 2% of input at both ($0.003 and $0.006).
|
|
678
|
+
*
|
|
679
|
+
* The cache minimum is carried from deepseek-v4-flash: DeepSeek's pages
|
|
680
|
+
* publish none for this generation, and 1,024 is the figure the earlier
|
|
681
|
+
* row was reviewed with.
|
|
682
|
+
*/
|
|
683
|
+
id: 'deepseek-flash',
|
|
684
|
+
provider: 'deepseek',
|
|
685
|
+
displayName: 'DeepSeek V4.1 Flash',
|
|
686
|
+
inputPerMTok: 0.15,
|
|
687
|
+
outputPerMTok: 0.6,
|
|
688
|
+
tiers: [
|
|
689
|
+
{
|
|
690
|
+
id: 'peak',
|
|
691
|
+
when: { kind: 'utc-hours', hours: [1, 2, 3, 6, 7, 8, 9], weekdaysOnly: true },
|
|
692
|
+
inputPerMTok: 0.3,
|
|
693
|
+
outputPerMTok: 1.2,
|
|
694
|
+
},
|
|
695
|
+
],
|
|
696
|
+
contextWindow: 1_000_000,
|
|
697
|
+
cacheMinTokens: 1024,
|
|
698
|
+
caching: 'automatic',
|
|
699
|
+
multipliers: { cacheRead: 0.02, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
700
|
+
capability: 'mid',
|
|
701
|
+
tier: 'sonnet',
|
|
702
|
+
notes: 'Maximum output 384K tokens. Peak excludes Chinese public holidays, which this table cannot express:'
|
|
703
|
+
+ ' on a weekday holiday it charges peak where DeepSeek charges off-peak.',
|
|
432
704
|
},
|
|
433
705
|
{
|
|
434
706
|
/* Same page, same clock. Pro is three times Flash at both ends. */
|
|
@@ -517,12 +789,12 @@ export const MODELS = [
|
|
|
517
789
|
inputPerMTok: 0.5,
|
|
518
790
|
outputPerMTok: 1.5,
|
|
519
791
|
contextWindow: 262_144,
|
|
520
|
-
cacheMinTokens:
|
|
521
|
-
caching: '
|
|
522
|
-
multipliers: { batch: 0.5 },
|
|
792
|
+
cacheMinTokens: null,
|
|
793
|
+
caching: 'unknown',
|
|
794
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
523
795
|
capability: 'large',
|
|
524
796
|
tier: 'opus',
|
|
525
|
-
notes:
|
|
797
|
+
notes: MISTRAL_CACHE_NOTE,
|
|
526
798
|
},
|
|
527
799
|
{
|
|
528
800
|
/*
|
|
@@ -545,11 +817,12 @@ export const MODELS = [
|
|
|
545
817
|
inputPerMTok: 1.5,
|
|
546
818
|
outputPerMTok: 7.5,
|
|
547
819
|
contextWindow: 262_144,
|
|
548
|
-
cacheMinTokens:
|
|
549
|
-
caching: '
|
|
550
|
-
multipliers: { batch: 0.5 },
|
|
820
|
+
cacheMinTokens: null,
|
|
821
|
+
caching: 'unknown',
|
|
822
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
551
823
|
capability: 'mid',
|
|
552
824
|
tier: 'sonnet',
|
|
825
|
+
notes: MISTRAL_CACHE_NOTE,
|
|
553
826
|
},
|
|
554
827
|
{
|
|
555
828
|
/* Same page, same day. `mistral-small-2603` is what the API reports. */
|
|
@@ -560,11 +833,12 @@ export const MODELS = [
|
|
|
560
833
|
inputPerMTok: 0.15,
|
|
561
834
|
outputPerMTok: 0.6,
|
|
562
835
|
contextWindow: 262_144,
|
|
563
|
-
cacheMinTokens:
|
|
564
|
-
caching: '
|
|
565
|
-
multipliers: { batch: 0.5 },
|
|
836
|
+
cacheMinTokens: null,
|
|
837
|
+
caching: 'unknown',
|
|
838
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
566
839
|
capability: 'small',
|
|
567
840
|
tier: 'haiku',
|
|
841
|
+
notes: MISTRAL_CACHE_NOTE,
|
|
568
842
|
},
|
|
569
843
|
];
|
|
570
844
|
export const DEFAULT_MODEL = 'claude-opus-5';
|
|
@@ -655,6 +929,41 @@ export function listModels() {
|
|
|
655
929
|
return [...MODELS];
|
|
656
930
|
}
|
|
657
931
|
const pricingMemo = new WeakMap();
|
|
932
|
+
/**
|
|
933
|
+
* The row as it stood at `on`: itself when the current price applies, or a
|
|
934
|
+
* frozen copy carrying the period's rates, tiers and ratios. Built once per
|
|
935
|
+
* period, so a log of a million calls does not build a million rows.
|
|
936
|
+
*/
|
|
937
|
+
const periodMemo = new WeakMap();
|
|
938
|
+
function pricedAt(model, on) {
|
|
939
|
+
const history = model.history;
|
|
940
|
+
if (history === undefined || history.length === 0)
|
|
941
|
+
return model;
|
|
942
|
+
let periods = periodMemo.get(model);
|
|
943
|
+
if (periods === undefined) {
|
|
944
|
+
periods = history.map((period) => {
|
|
945
|
+
const { history: _history, promo: _promo, tiers: _tiers, multipliers: _multipliers, ...rest } = model;
|
|
946
|
+
const row = Object.freeze({
|
|
947
|
+
...rest,
|
|
948
|
+
inputPerMTok: period.inputPerMTok,
|
|
949
|
+
outputPerMTok: period.outputPerMTok,
|
|
950
|
+
...(period.tiers !== undefined ? { tiers: period.tiers } : {}),
|
|
951
|
+
...(period.multipliers !== undefined
|
|
952
|
+
? { multipliers: period.multipliers }
|
|
953
|
+
: model.multipliers !== undefined
|
|
954
|
+
? { multipliers: model.multipliers }
|
|
955
|
+
: {}),
|
|
956
|
+
});
|
|
957
|
+
return { untilMs: new Date(period.until).getTime(), row };
|
|
958
|
+
});
|
|
959
|
+
periodMemo.set(model, periods);
|
|
960
|
+
}
|
|
961
|
+
const at = on.getTime();
|
|
962
|
+
for (const period of periods)
|
|
963
|
+
if (at < period.untilMs)
|
|
964
|
+
return period.row;
|
|
965
|
+
return model;
|
|
966
|
+
}
|
|
658
967
|
/** The two unconditional answers for one model, parsed once. */
|
|
659
968
|
function cache(model) {
|
|
660
969
|
const entry = {
|
|
@@ -712,6 +1021,12 @@ function holds(when, on, inputTokens) {
|
|
|
712
1021
|
* `pricing.test.js` fails a tiered model whose report drops it.
|
|
713
1022
|
*/
|
|
714
1023
|
export function effectivePricing(model, on = new Date(), context = {}) {
|
|
1024
|
+
/* A call before a published price change is priced as it was billed then. */
|
|
1025
|
+
if (model.history !== undefined) {
|
|
1026
|
+
const period = pricedAt(model, on);
|
|
1027
|
+
if (period !== model)
|
|
1028
|
+
return effectivePricing(period, on, context);
|
|
1029
|
+
}
|
|
715
1030
|
const memo = pricingMemo.get(model) ?? cache(model);
|
|
716
1031
|
/**
|
|
717
1032
|
* Tiers first, and a promotion never runs on top of one.
|