@trazum/core 2.4.3 → 2.5.0
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/advisories.d.ts.map +1 -1
- package/dist/advisories.js +17 -10
- package/dist/advisories.js.map +1 -1
- package/dist/answer.d.ts.map +1 -1
- package/dist/answer.js +2 -1
- package/dist/answer.js.map +1 -1
- package/dist/anthropic-usage.d.ts +6 -0
- package/dist/anthropic-usage.d.ts.map +1 -1
- package/dist/anthropic-usage.js +1 -0
- package/dist/anthropic-usage.js.map +1 -1
- package/dist/billing.d.ts +20 -0
- package/dist/billing.d.ts.map +1 -0
- package/dist/billing.js +32 -0
- package/dist/billing.js.map +1 -0
- package/dist/budget.d.ts.map +1 -1
- package/dist/budget.js +18 -8
- package/dist/budget.js.map +1 -1
- package/dist/connector.d.ts +20 -1
- package/dist/connector.d.ts.map +1 -1
- package/dist/connector.js +42 -11
- package/dist/connector.js.map +1 -1
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +4 -2
- package/dist/conversation.js.map +1 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +5 -3
- package/dist/gateway.js.map +1 -1
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +7 -5
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/input-shape.d.ts.map +1 -1
- package/dist/input-shape.js +4 -2
- package/dist/input-shape.js.map +1 -1
- package/dist/ladder.d.ts.map +1 -1
- package/dist/ladder.js +2 -1
- package/dist/ladder.js.map +1 -1
- package/dist/levers.d.ts.map +1 -1
- package/dist/levers.js +5 -2
- package/dist/levers.js.map +1 -1
- package/dist/openai-usage.d.ts +18 -0
- package/dist/openai-usage.d.ts.map +1 -1
- package/dist/openai-usage.js +26 -1
- package/dist/openai-usage.js.map +1 -1
- package/dist/openrouter-activity.d.ts +6 -0
- package/dist/openrouter-activity.d.ts.map +1 -1
- package/dist/openrouter-activity.js +7 -0
- package/dist/openrouter-activity.js.map +1 -1
- package/dist/output-shape.d.ts.map +1 -1
- package/dist/output-shape.js +2 -1
- package/dist/output-shape.js.map +1 -1
- package/dist/pricing.d.ts +35 -3
- package/dist/pricing.d.ts.map +1 -1
- package/dist/pricing.js +569 -54
- package/dist/pricing.js.map +1 -1
- package/dist/receipt.d.ts +17 -0
- package/dist/receipt.d.ts.map +1 -1
- package/dist/receipt.js +10 -0
- package/dist/receipt.js.map +1 -1
- package/dist/repeats.d.ts.map +1 -1
- package/dist/repeats.js +4 -2
- package/dist/repeats.js.map +1 -1
- package/dist/reprice.d.ts +18 -2
- package/dist/reprice.d.ts.map +1 -1
- package/dist/reprice.js +34 -12
- package/dist/reprice.js.map +1 -1
- package/dist/rollup.d.ts.map +1 -1
- package/dist/rollup.js +3 -0
- package/dist/rollup.js.map +1 -1
- package/dist/savings.d.ts.map +1 -1
- package/dist/savings.js +10 -3
- package/dist/savings.js.map +1 -1
- package/dist/session-cost.d.ts.map +1 -1
- package/dist/session-cost.js +5 -2
- package/dist/session-cost.js.map +1 -1
- package/dist/session-ledger.d.ts.map +1 -1
- package/dist/session-ledger.js +12 -7
- package/dist/session-ledger.js.map +1 -1
- package/dist/truncation-retry.d.ts.map +1 -1
- package/dist/truncation-retry.js +4 -2
- package/dist/truncation-retry.js.map +1 -1
- package/dist/ttl-fit.d.ts +8 -0
- package/dist/ttl-fit.d.ts.map +1 -1
- package/dist/ttl-fit.js +25 -14
- package/dist/ttl-fit.js.map +1 -1
- package/dist/types.d.ts +24 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/usage.d.ts +31 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +79 -10
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
- package/src/advisories.ts +18 -10
- package/src/answer.ts +6 -1
- package/src/anthropic-usage.ts +7 -0
- package/src/billing.ts +37 -0
- package/src/budget.ts +18 -8
- package/src/connector.ts +58 -10
- package/src/conversation.ts +4 -2
- package/src/gateway.ts +5 -3
- package/src/guard.ts +7 -5
- package/src/index.ts +1 -1
- package/src/input-shape.ts +4 -2
- package/src/ladder.ts +2 -1
- package/src/levers.ts +5 -2
- package/src/openai-usage.ts +44 -2
- package/src/openrouter-activity.ts +13 -0
- package/src/output-shape.ts +2 -1
- package/src/pricing.ts +614 -59
- package/src/receipt.ts +23 -1
- package/src/repeats.ts +4 -2
- package/src/reprice.ts +57 -16
- package/src/rollup.ts +3 -0
- package/src/savings.ts +12 -5
- package/src/session-cost.ts +5 -2
- package/src/session-ledger.ts +18 -9
- package/src/truncation-retry.ts +4 -2
- package/src/ttl-fit.ts +39 -15
- package/src/types.ts +18 -0
- package/src/usage.ts +112 -10
package/dist/pricing.js
CHANGED
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
export const PROVIDER_REVIEWED = Object.freeze({
|
|
31
31
|
/*
|
|
32
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
|
|
34
|
-
* models were added
|
|
35
|
-
*
|
|
33
|
+
* each model's own page, read 2026-10-10. Every existing row matched and
|
|
34
|
+
* five models were added. Claude Haiku 5.5 waited for per-request pricing,
|
|
35
|
+
* because it bills by prompt length, and was added with it on 2026-10-11.
|
|
36
36
|
*/
|
|
37
37
|
anthropic: '2026-10-10',
|
|
38
38
|
/*
|
|
@@ -52,9 +52,9 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
52
52
|
* dated snapshots (`gpt-5-2025-08-07` and the mini and nano ones), which is
|
|
53
53
|
* the id a usage log usually carries, shut down on 2026-12-11 and are now
|
|
54
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)
|
|
56
|
-
*
|
|
57
|
-
*
|
|
55
|
+
* gpt-6-sol, gpt-6-luna and gpt-5.6 sol, terra and luna) waited for
|
|
56
|
+
* per-request pricing, since each doubles its rates for prompts over 272K
|
|
57
|
+
* tokens, and was added with it the same day, from each model's own page.
|
|
58
58
|
*/
|
|
59
59
|
openai: '2026-10-11',
|
|
60
60
|
/*
|
|
@@ -64,24 +64,20 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
64
64
|
* for every Gemini 2.5 and newer model, so `caching` is 'automatic' across
|
|
65
65
|
* the board; the minimums moved to 4,096 on 3.6 and 3.8 Flash and 2,048 on
|
|
66
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
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* out and the second's tier is named in its note rather than guessed.
|
|
67
|
+
* the 25% this table carried. Gemini 3.8 Flash was added, and Gemini 3.1
|
|
68
|
+
* Pro Preview on 2026-10-11 with per-request pricing, which its prompts
|
|
69
|
+
* over 200k need. 2.5 Pro's own long-context rate is named in its note.
|
|
71
70
|
*/
|
|
72
71
|
google: '2026-10-10',
|
|
73
72
|
/*
|
|
74
|
-
* platform.kimi.ai/docs/pricing/chat
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* repository does not hold. The newer models are not added: the page states
|
|
81
|
-
* no context window for any of them, and a context window this table did
|
|
82
|
-
* not read is a number it would be inventing.
|
|
73
|
+
* platform.kimi.ai/docs/pricing/chat, models and pricing/batch, read
|
|
74
|
+
* 2026-10-11 in their Markdown form; the HTML renders its tables in the
|
|
75
|
+
* browser, which is why the review of 2026-09-12 found no context window
|
|
76
|
+
* and added nothing. Kimi K3, K2.7 Code (and its high-speed variant) and
|
|
77
|
+
* K2.6 are priced now. `kimi-k2` was discontinued on 2026-05-25 by the
|
|
78
|
+
* provider's own notice, so it stays priced and is no longer recommended.
|
|
83
79
|
*/
|
|
84
|
-
moonshot: '2026-
|
|
80
|
+
moonshot: '2026-10-11',
|
|
85
81
|
/*
|
|
86
82
|
* api-docs.deepseek.com/quick_start/pricing read 2026-10-10, and the
|
|
87
83
|
* 2026-09-10 announcement (api-docs.deepseek.com/news/news260910) read
|
|
@@ -92,15 +88,14 @@ export const PROVIDER_REVIEWED = Object.freeze({
|
|
|
92
88
|
*/
|
|
93
89
|
deepseek: '2026-10-10',
|
|
94
90
|
/*
|
|
95
|
-
* docs.x.ai/
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* would understate it by half while looking exact.
|
|
91
|
+
* docs.x.ai/developers/models, each model's page and the 2026-05-15
|
|
92
|
+
* retirement notice, read 2026-10-11 in their Markdown form. Grok 4.7, 4.6,
|
|
93
|
+
* 4.5, 4.3, the 4.20 family and Build 0.1 are priced, each with the rate a
|
|
94
|
+
* request pays once its prompt reaches 200k tokens, which per-request
|
|
95
|
+
* pricing can now express. `grok-4` was retired on 2026-05-15 and its calls
|
|
96
|
+
* have billed at Grok 4.3's prices since, so it carries both periods.
|
|
102
97
|
*/
|
|
103
|
-
xai: '2026-
|
|
98
|
+
xai: '2026-10-11',
|
|
104
99
|
/*
|
|
105
100
|
* `mistral.ai/pricing`, read 2026-08-28 — by a human, because the page
|
|
106
101
|
* renders its table in the browser and serves a fetch only an FAQ example
|
|
@@ -179,6 +174,12 @@ export function multipliersFor(model, on) {
|
|
|
179
174
|
multipliersMemo.set(model, result);
|
|
180
175
|
return result;
|
|
181
176
|
}
|
|
177
|
+
/** Five minutes and an hour: Anthropic's two cache entries, and the default. */
|
|
178
|
+
const ANTHROPIC_TTL = Object.freeze({ writeMs: 5 * 60_000, longerMs: 60 * 60_000 });
|
|
179
|
+
/** How long a model's cache entries live. See `ModelPricing.cacheTtl`. */
|
|
180
|
+
export function cacheTtlOf(model) {
|
|
181
|
+
return model.cacheTtl ?? ANTHROPIC_TTL;
|
|
182
|
+
}
|
|
182
183
|
/**
|
|
183
184
|
* Mistral discounts cached input by 90% and publishes nothing else about it
|
|
184
185
|
* that can be read from here: not how caching starts, not a minimum, not a
|
|
@@ -187,6 +188,26 @@ export function multipliersFor(model, on) {
|
|
|
187
188
|
* cannot be.
|
|
188
189
|
*/
|
|
189
190
|
/** What the GPT-5 family's three rows share, from OpenAI's guide and deprecations page, read 2026-10-11. */
|
|
191
|
+
/** xAI's long-context band: a request whose prompt reaches 200,000 tokens, at the published higher rates. */
|
|
192
|
+
const GROK_LONG = (inputPerMTok, outputPerMTok) => ({
|
|
193
|
+
id: 'from-200k',
|
|
194
|
+
when: { kind: 'input-tokens-at-least', tokens: 200_000 },
|
|
195
|
+
inputPerMTok,
|
|
196
|
+
outputPerMTok,
|
|
197
|
+
});
|
|
198
|
+
/**
|
|
199
|
+
* Said on every row that caches but whose provider publishes no minimum
|
|
200
|
+
* prefix. The bill still prices its cache reads and writes, which are
|
|
201
|
+
* published; what goes quiet is the advice that needs the minimum to promise
|
|
202
|
+
* a saving, and the reader is told why rather than handed a number from
|
|
203
|
+
* nowhere. The catalogue tests hold a null minimum on a caching model to
|
|
204
|
+
* carrying this sentence, so a forgotten minimum cannot pass as a deliberate one.
|
|
205
|
+
*/
|
|
206
|
+
const NO_PUBLISHED_CACHE_MINIMUM = 'Caches automatically, but no minimum prefix length is published, so no caching advice is given for it.';
|
|
207
|
+
/** OpenAI's GPT-5.6 and later: one cache entry, living at least 30 minutes. */
|
|
208
|
+
const OPENAI_CACHE_TTL = Object.freeze({ writeMs: 30 * 60_000, longerMs: null });
|
|
209
|
+
const OPENAI_CURRENT_NOTE = 'Priced per request by prompt length: over 272,000 input tokens, 2x input and cache and 1.5x output for'
|
|
210
|
+
+ ' the whole request. Cache writes cost 1.25x input and an entry lives at least 30 minutes.';
|
|
190
211
|
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
212
|
+ ' request settings, so 1,024 here is the nearest published floor. The 2025-08-07 snapshot shuts down on'
|
|
192
213
|
+ ' 2026-12-11; OpenAI names the gpt-5.6 models as replacements.';
|
|
@@ -386,18 +407,44 @@ export const MODELS = [
|
|
|
386
407
|
capability: 'mid',
|
|
387
408
|
tier: 'sonnet',
|
|
388
409
|
},
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
410
|
+
{
|
|
411
|
+
/*
|
|
412
|
+
* The pricing page, the models overview and the prompt-caching page, read
|
|
413
|
+
* 2026-10-10. Priced by prompt length, per request: $0.10/$0.50 for a
|
|
414
|
+
* prompt up to 100,000 tokens and $0.50/$2.50 over it, where the length
|
|
415
|
+
* counts every input token the request carried, cache reads and writes
|
|
416
|
+
* included, and "each request is priced on its own". Caching is the same
|
|
417
|
+
* ratio in both bands (hits $0.01 and $0.05, writes $0.125/$0.20 and
|
|
418
|
+
* $0.625/$1), and so is batch ($0.05/$0.25, $0.25/$1.25). 1M context,
|
|
419
|
+
* 128K output, a 512-token cache minimum.
|
|
420
|
+
*
|
|
421
|
+
* It waited for the change that prices a log per request. A record that
|
|
422
|
+
* is one call carries its own prompt; a row out of a usage report sums
|
|
423
|
+
* requests, and is billed at the over-100,000 rate unless its whole
|
|
424
|
+
* prompt total is under the line, with the cheaper figure printed beside
|
|
425
|
+
* it. See `PromptSize`.
|
|
426
|
+
*/
|
|
427
|
+
id: 'claude-haiku-5-5',
|
|
428
|
+
provider: 'anthropic',
|
|
429
|
+
displayName: 'Claude Haiku 5.5',
|
|
430
|
+
inputPerMTok: 0.1,
|
|
431
|
+
outputPerMTok: 0.5,
|
|
432
|
+
contextWindow: 1_000_000,
|
|
433
|
+
cacheMinTokens: 512,
|
|
434
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 2, batch: 0.5 },
|
|
435
|
+
tiers: [
|
|
436
|
+
{
|
|
437
|
+
id: 'over-100k',
|
|
438
|
+
when: { kind: 'input-tokens-above', tokens: 100_000 },
|
|
439
|
+
inputPerMTok: 0.5,
|
|
440
|
+
outputPerMTok: 2.5,
|
|
441
|
+
},
|
|
442
|
+
],
|
|
443
|
+
capability: 'small',
|
|
444
|
+
tier: 'haiku',
|
|
445
|
+
notes: 'Priced per request by prompt length: $0.10/$0.50 up to 100,000 input tokens, cache reads'
|
|
446
|
+
+ ' and writes included, and $0.50/$2.50 over it.',
|
|
447
|
+
},
|
|
401
448
|
{
|
|
402
449
|
id: 'claude-haiku-4-5',
|
|
403
450
|
// The dated form is the canonical API id and is what a real usage log
|
|
@@ -425,6 +472,188 @@ export const MODELS = [
|
|
|
425
472
|
// guide says the minimum "varies by request settings", so it is the nearest
|
|
426
473
|
// published floor, not a promise, and each row's note says so.
|
|
427
474
|
// ------------------------------------------------------------------------
|
|
475
|
+
// GPT-5.6 and later: OpenAI's current generation.
|
|
476
|
+
//
|
|
477
|
+
// The pricing page and each model's page, read 2026-10-10 and 2026-10-11,
|
|
478
|
+
// and the prompt-caching guide. Three things set them apart from GPT-5:
|
|
479
|
+
//
|
|
480
|
+
// - **A long-context band, per request.** "Prompts with more than 272K input
|
|
481
|
+
// tokens are priced at 2x input and cache rates and 1.5x output for the
|
|
482
|
+
// full request." 272,000, the GPT-5 era's own input limit; a tier.
|
|
483
|
+
// - **Cache writes are billed**, at 1.25x the uncached input rate, and the
|
|
484
|
+
// usage object reports them (`cache_write_tokens`). Reads are 10% of input,
|
|
485
|
+
// 5% on GPT-6.1 Sol.
|
|
486
|
+
// - **An entry lives at least 30 minutes** after its last write or read, and
|
|
487
|
+
// there is no longer one to buy: `cacheTtl`.
|
|
488
|
+
//
|
|
489
|
+
// Caching is implicit by default (a breakpoint at the end of the latest
|
|
490
|
+
// eligible message) from a 1,024-token minimum. Batch and Flex are half
|
|
491
|
+
// price; Fast, Ultrafast and regional processing are other service tiers
|
|
492
|
+
// and are not priced here. Every model: 1,050,000 context, 922,000 input at
|
|
493
|
+
// most, 128,000 output.
|
|
494
|
+
// ------------------------------------------------------------------------
|
|
495
|
+
{
|
|
496
|
+
id: 'gpt-6-astra',
|
|
497
|
+
provider: 'openai',
|
|
498
|
+
displayName: 'GPT-6 Astra',
|
|
499
|
+
inputPerMTok: 10,
|
|
500
|
+
outputPerMTok: 50,
|
|
501
|
+
contextWindow: 1_050_000,
|
|
502
|
+
cacheMinTokens: 1024,
|
|
503
|
+
caching: 'automatic',
|
|
504
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
505
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
506
|
+
tiers: [
|
|
507
|
+
{
|
|
508
|
+
id: 'over-272k',
|
|
509
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
510
|
+
inputPerMTok: 20,
|
|
511
|
+
outputPerMTok: 75,
|
|
512
|
+
},
|
|
513
|
+
],
|
|
514
|
+
capability: 'frontier',
|
|
515
|
+
tier: 'frontier',
|
|
516
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
id: 'gpt-6.1-sol',
|
|
520
|
+
provider: 'openai',
|
|
521
|
+
displayName: 'GPT-6.1 Sol',
|
|
522
|
+
inputPerMTok: 2,
|
|
523
|
+
outputPerMTok: 10,
|
|
524
|
+
contextWindow: 1_050_000,
|
|
525
|
+
cacheMinTokens: 1024,
|
|
526
|
+
caching: 'automatic',
|
|
527
|
+
multipliers: { cacheRead: 0.05, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
528
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
529
|
+
tiers: [
|
|
530
|
+
{
|
|
531
|
+
id: 'over-272k',
|
|
532
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
533
|
+
inputPerMTok: 4,
|
|
534
|
+
outputPerMTok: 15,
|
|
535
|
+
},
|
|
536
|
+
],
|
|
537
|
+
capability: 'large',
|
|
538
|
+
tier: 'opus',
|
|
539
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
id: 'gpt-6-sol',
|
|
543
|
+
provider: 'openai',
|
|
544
|
+
displayName: 'GPT-6 Sol',
|
|
545
|
+
inputPerMTok: 2,
|
|
546
|
+
outputPerMTok: 10,
|
|
547
|
+
contextWindow: 1_050_000,
|
|
548
|
+
cacheMinTokens: 1024,
|
|
549
|
+
caching: 'automatic',
|
|
550
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
551
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
552
|
+
tiers: [
|
|
553
|
+
{
|
|
554
|
+
id: 'over-272k',
|
|
555
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
556
|
+
inputPerMTok: 4,
|
|
557
|
+
outputPerMTok: 15,
|
|
558
|
+
},
|
|
559
|
+
],
|
|
560
|
+
capability: 'large',
|
|
561
|
+
tier: 'opus',
|
|
562
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
id: 'gpt-6-luna',
|
|
566
|
+
provider: 'openai',
|
|
567
|
+
displayName: 'GPT-6 Luna',
|
|
568
|
+
inputPerMTok: 0.1,
|
|
569
|
+
outputPerMTok: 0.5,
|
|
570
|
+
contextWindow: 1_050_000,
|
|
571
|
+
cacheMinTokens: 1024,
|
|
572
|
+
caching: 'automatic',
|
|
573
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
574
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
575
|
+
tiers: [
|
|
576
|
+
{
|
|
577
|
+
id: 'over-272k',
|
|
578
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
579
|
+
inputPerMTok: 0.2,
|
|
580
|
+
outputPerMTok: 0.75,
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
capability: 'small',
|
|
584
|
+
tier: 'haiku',
|
|
585
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
id: 'gpt-5.6-sol',
|
|
589
|
+
provider: 'openai',
|
|
590
|
+
displayName: 'GPT-5.6 Sol',
|
|
591
|
+
inputPerMTok: 4,
|
|
592
|
+
outputPerMTok: 20,
|
|
593
|
+
contextWindow: 1_050_000,
|
|
594
|
+
cacheMinTokens: 1024,
|
|
595
|
+
caching: 'automatic',
|
|
596
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
597
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
598
|
+
tiers: [
|
|
599
|
+
{
|
|
600
|
+
id: 'over-272k',
|
|
601
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
602
|
+
inputPerMTok: 8,
|
|
603
|
+
outputPerMTok: 30,
|
|
604
|
+
},
|
|
605
|
+
],
|
|
606
|
+
capability: 'large',
|
|
607
|
+
tier: 'opus',
|
|
608
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
id: 'gpt-5.6-terra',
|
|
612
|
+
provider: 'openai',
|
|
613
|
+
displayName: 'GPT-5.6 Terra',
|
|
614
|
+
inputPerMTok: 2,
|
|
615
|
+
outputPerMTok: 12,
|
|
616
|
+
contextWindow: 1_050_000,
|
|
617
|
+
cacheMinTokens: 1024,
|
|
618
|
+
caching: 'automatic',
|
|
619
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
620
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
621
|
+
tiers: [
|
|
622
|
+
{
|
|
623
|
+
id: 'over-272k',
|
|
624
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
625
|
+
inputPerMTok: 4,
|
|
626
|
+
outputPerMTok: 18,
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
capability: 'mid',
|
|
630
|
+
tier: 'sonnet',
|
|
631
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
id: 'gpt-5.6-luna',
|
|
635
|
+
provider: 'openai',
|
|
636
|
+
displayName: 'GPT-5.6 Luna',
|
|
637
|
+
inputPerMTok: 0.2,
|
|
638
|
+
outputPerMTok: 1.2,
|
|
639
|
+
contextWindow: 1_050_000,
|
|
640
|
+
cacheMinTokens: 1024,
|
|
641
|
+
caching: 'automatic',
|
|
642
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1.25, cacheWrite1h: 1.25, batch: 0.5 },
|
|
643
|
+
cacheTtl: OPENAI_CACHE_TTL,
|
|
644
|
+
tiers: [
|
|
645
|
+
{
|
|
646
|
+
id: 'over-272k',
|
|
647
|
+
when: { kind: 'input-tokens-above', tokens: 272_000 },
|
|
648
|
+
inputPerMTok: 0.4,
|
|
649
|
+
outputPerMTok: 1.8,
|
|
650
|
+
},
|
|
651
|
+
],
|
|
652
|
+
capability: 'small',
|
|
653
|
+
tier: 'haiku',
|
|
654
|
+
notes: OPENAI_CURRENT_NOTE,
|
|
655
|
+
},
|
|
656
|
+
// ------------------------------------------------------------------------
|
|
428
657
|
{
|
|
429
658
|
id: 'gpt-5',
|
|
430
659
|
aliases: ['gpt-5-2025-08-07'],
|
|
@@ -571,9 +800,116 @@ export const MODELS = [
|
|
|
571
800
|
notes: 'Implicit caching is automatic above 4,096 tokens. Explicit caching is also billed for storage:'
|
|
572
801
|
+ ' $0.50 per 1M tokens per hour through 2026-12-31, $1.00 after.',
|
|
573
802
|
},
|
|
803
|
+
{
|
|
804
|
+
/*
|
|
805
|
+
* The pricing page, the model page and the caching page, read 2026-10-10
|
|
806
|
+
* and 2026-10-11. The model Google's own refusal of 2.5 Pro names as its
|
|
807
|
+
* replacement, and the second model here priced by prompt length: $2/$12
|
|
808
|
+
* for a prompt up to 200,000 tokens and $4/$18 over it, the cache at
|
|
809
|
+
* $0.20 and $0.40 (10% in both bands), batch $1/$6 and $2/$9 (half in
|
|
810
|
+
* both). 1,048,576 tokens in, 65,536 out, implicit caching from 4,096.
|
|
811
|
+
* The `-customtools` endpoint is "same as Gemini 3.1 Pro Preview pricing".
|
|
812
|
+
*
|
|
813
|
+
* A preview, and priced because a log carries it: Google's 2.5 Pro
|
|
814
|
+
* refusal sends every caller here.
|
|
815
|
+
*/
|
|
816
|
+
id: 'gemini-3.1-pro-preview',
|
|
817
|
+
aliases: ['gemini-3.1-pro-preview-customtools'],
|
|
818
|
+
provider: 'google',
|
|
819
|
+
displayName: 'Gemini 3.1 Pro Preview',
|
|
820
|
+
inputPerMTok: 2,
|
|
821
|
+
outputPerMTok: 12,
|
|
822
|
+
contextWindow: 1_048_576,
|
|
823
|
+
cacheMinTokens: 4096,
|
|
824
|
+
caching: 'automatic',
|
|
825
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.5 },
|
|
826
|
+
tiers: [
|
|
827
|
+
{
|
|
828
|
+
id: 'over-200k',
|
|
829
|
+
when: { kind: 'input-tokens-above', tokens: 200_000 },
|
|
830
|
+
inputPerMTok: 4,
|
|
831
|
+
outputPerMTok: 18,
|
|
832
|
+
},
|
|
833
|
+
],
|
|
834
|
+
capability: 'large',
|
|
835
|
+
tier: 'opus',
|
|
836
|
+
notes: 'Priced per request by prompt length: $2/$12 up to 200,000 input tokens and $4/$18 over it.'
|
|
837
|
+
+ ' Implicit caching is automatic above 4,096 tokens; explicit caching is also billed for storage,'
|
|
838
|
+
+ ' $4.50 per 1M tokens per hour.',
|
|
839
|
+
},
|
|
574
840
|
// ------------------------------------------------------------------------
|
|
575
841
|
// Moonshot
|
|
576
842
|
// ------------------------------------------------------------------------
|
|
843
|
+
/*
|
|
844
|
+
* platform.kimi.ai/docs/pricing/chat, models and pricing/batch, read in
|
|
845
|
+
* their Markdown form on 2026-10-11 (the HTML renders its tables in the
|
|
846
|
+
* browser, which is why the September review saw no context windows). K3
|
|
847
|
+
* bills cache writes as their own line, by TTL, like Anthropic: $3.00 for a
|
|
848
|
+
* 5-minute entry and $6.00 for an hour against a $3.00 input, and reads at
|
|
849
|
+
* $0.30. The K2 series bills no write, and reads at its own hit price. Batch
|
|
850
|
+
* is 60% of standard on K2.7 Code and K2.6 and not offered on K3 or the
|
|
851
|
+
* high-speed K2.7. No cache minimum is published for any of them.
|
|
852
|
+
*/
|
|
853
|
+
{
|
|
854
|
+
id: 'kimi-k3',
|
|
855
|
+
provider: 'moonshot',
|
|
856
|
+
displayName: 'Kimi K3',
|
|
857
|
+
inputPerMTok: 3,
|
|
858
|
+
outputPerMTok: 15,
|
|
859
|
+
contextWindow: 1_048_576,
|
|
860
|
+
cacheMinTokens: null,
|
|
861
|
+
caching: 'automatic',
|
|
862
|
+
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 2, batch: null },
|
|
863
|
+
capability: 'frontier',
|
|
864
|
+
tier: 'frontier',
|
|
865
|
+
notes: 'Cache writes are billed as their own line: 1x input for a 5-minute entry, 2x for an hour.'
|
|
866
|
+
+ ` No batch API for this model. ${NO_PUBLISHED_CACHE_MINIMUM}`,
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
id: 'kimi-k2.7-code',
|
|
870
|
+
provider: 'moonshot',
|
|
871
|
+
displayName: 'Kimi K2.7 Code',
|
|
872
|
+
inputPerMTok: 0.95,
|
|
873
|
+
outputPerMTok: 4,
|
|
874
|
+
contextWindow: 262_144,
|
|
875
|
+
cacheMinTokens: null,
|
|
876
|
+
caching: 'automatic',
|
|
877
|
+
/* $0.19 on a hit against $0.95; batch $0.57 / $2.40, 60%. */
|
|
878
|
+
multipliers: { cacheRead: 0.2, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.6 },
|
|
879
|
+
capability: 'mid',
|
|
880
|
+
tier: 'sonnet',
|
|
881
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
id: 'kimi-k2.7-code-highspeed',
|
|
885
|
+
provider: 'moonshot',
|
|
886
|
+
displayName: 'Kimi K2.7 Code (high speed)',
|
|
887
|
+
inputPerMTok: 1.9,
|
|
888
|
+
outputPerMTok: 8,
|
|
889
|
+
contextWindow: 262_144,
|
|
890
|
+
cacheMinTokens: null,
|
|
891
|
+
caching: 'automatic',
|
|
892
|
+
/* $0.38 on a hit against $1.90; no batch API for this variant. */
|
|
893
|
+
multipliers: { cacheRead: 0.2, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
894
|
+
capability: 'mid',
|
|
895
|
+
tier: 'sonnet',
|
|
896
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
id: 'kimi-k2.6',
|
|
900
|
+
provider: 'moonshot',
|
|
901
|
+
displayName: 'Kimi K2.6',
|
|
902
|
+
inputPerMTok: 0.95,
|
|
903
|
+
outputPerMTok: 4,
|
|
904
|
+
contextWindow: 262_144,
|
|
905
|
+
cacheMinTokens: null,
|
|
906
|
+
caching: 'automatic',
|
|
907
|
+
/* $0.16 on a hit against $0.95, written as the ratio so the product is the page's figure. */
|
|
908
|
+
multipliers: { cacheRead: 0.16 / 0.95, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.6 },
|
|
909
|
+
capability: 'mid',
|
|
910
|
+
tier: 'sonnet',
|
|
911
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
912
|
+
},
|
|
577
913
|
{
|
|
578
914
|
id: 'kimi-k2',
|
|
579
915
|
provider: 'moonshot',
|
|
@@ -581,13 +917,22 @@ export const MODELS = [
|
|
|
581
917
|
inputPerMTok: 0.6,
|
|
582
918
|
outputPerMTok: 2.5,
|
|
583
919
|
contextWindow: 256_000,
|
|
584
|
-
cacheMinTokens:
|
|
920
|
+
cacheMinTokens: null,
|
|
585
921
|
caching: 'automatic',
|
|
586
922
|
multipliers: { cacheRead: 0.1, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
923
|
+
/*
|
|
924
|
+
* Discontinued: "The kimi-k2 series models were officially discontinued
|
|
925
|
+
* on May 25, 2026" (the provider's model list, read 2026-10-11). Kept at
|
|
926
|
+
* its last published price, because calls in somebody's log really
|
|
927
|
+
* happened at it, and never offered as somewhere to move. Not `retired`,
|
|
928
|
+
* which records the provider refusing a request, and no key was here to
|
|
929
|
+
* send one.
|
|
930
|
+
*/
|
|
931
|
+
recommendable: false,
|
|
587
932
|
capability: 'mid',
|
|
588
933
|
tier: 'sonnet',
|
|
589
|
-
notes: '
|
|
590
|
-
+
|
|
934
|
+
notes: 'Discontinued by Moonshot on 2026-05-25; priced at the last rate it published. No batch API.'
|
|
935
|
+
+ ` ${NO_PUBLISHED_CACHE_MINIMUM}`,
|
|
591
936
|
},
|
|
592
937
|
// ------------------------------------------------------------------------
|
|
593
938
|
// DeepSeek
|
|
@@ -729,19 +1074,174 @@ export const MODELS = [
|
|
|
729
1074
|
// ------------------------------------------------------------------------
|
|
730
1075
|
// xAI
|
|
731
1076
|
// ------------------------------------------------------------------------
|
|
1077
|
+
/*
|
|
1078
|
+
* docs.x.ai/developers/models and each model's page, read in their
|
|
1079
|
+
* Markdown form on 2026-10-11. Every text model has two rates: "requests
|
|
1080
|
+
* whose prompt reaches 200k tokens are billed at the higher rate for all
|
|
1081
|
+
* tokens in the request", which is a size tier at 200,000 inclusive and is
|
|
1082
|
+
* priced per request. Cached input scales with the band; writes are not
|
|
1083
|
+
* billed; batch is a 20% discount where the model's page offers it at all.
|
|
1084
|
+
* No cache minimum is published. Aliases are the stable family names the
|
|
1085
|
+
* pages list, never the `-latest` names, which move.
|
|
1086
|
+
*/
|
|
1087
|
+
{
|
|
1088
|
+
id: 'grok-4.7',
|
|
1089
|
+
provider: 'xai',
|
|
1090
|
+
displayName: 'Grok 4.7',
|
|
1091
|
+
inputPerMTok: 2,
|
|
1092
|
+
outputPerMTok: 6,
|
|
1093
|
+
contextWindow: 500_000,
|
|
1094
|
+
cacheMinTokens: null,
|
|
1095
|
+
caching: 'automatic',
|
|
1096
|
+
multipliers: { cacheRead: 0.25, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1097
|
+
tiers: [GROK_LONG(4, 12)],
|
|
1098
|
+
capability: 'frontier',
|
|
1099
|
+
tier: 'frontier',
|
|
1100
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
id: 'grok-4.6',
|
|
1104
|
+
provider: 'xai',
|
|
1105
|
+
displayName: 'Grok 4.6',
|
|
1106
|
+
inputPerMTok: 2,
|
|
1107
|
+
outputPerMTok: 6,
|
|
1108
|
+
contextWindow: 500_000,
|
|
1109
|
+
cacheMinTokens: null,
|
|
1110
|
+
caching: 'automatic',
|
|
1111
|
+
multipliers: { cacheRead: 0.25, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1112
|
+
tiers: [GROK_LONG(4, 12)],
|
|
1113
|
+
capability: 'large',
|
|
1114
|
+
tier: 'opus',
|
|
1115
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1116
|
+
},
|
|
1117
|
+
{
|
|
1118
|
+
id: 'grok-4.5',
|
|
1119
|
+
provider: 'xai',
|
|
1120
|
+
displayName: 'Grok 4.5',
|
|
1121
|
+
inputPerMTok: 2,
|
|
1122
|
+
outputPerMTok: 6,
|
|
1123
|
+
contextWindow: 500_000,
|
|
1124
|
+
cacheMinTokens: null,
|
|
1125
|
+
caching: 'automatic',
|
|
1126
|
+
/* $0.30 cached against $2.00. */
|
|
1127
|
+
multipliers: { cacheRead: 0.15, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1128
|
+
tiers: [GROK_LONG(4, 12)],
|
|
1129
|
+
capability: 'large',
|
|
1130
|
+
tier: 'opus',
|
|
1131
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
id: 'grok-4.3',
|
|
1135
|
+
provider: 'xai',
|
|
1136
|
+
displayName: 'Grok 4.3',
|
|
1137
|
+
inputPerMTok: 1.25,
|
|
1138
|
+
outputPerMTok: 2.5,
|
|
1139
|
+
contextWindow: 1_000_000,
|
|
1140
|
+
cacheMinTokens: null,
|
|
1141
|
+
caching: 'automatic',
|
|
1142
|
+
/* $0.20 cached against $1.25; batch 20% off. */
|
|
1143
|
+
multipliers: { cacheRead: 0.16, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.8 },
|
|
1144
|
+
tiers: [GROK_LONG(2.5, 5)],
|
|
1145
|
+
capability: 'mid',
|
|
1146
|
+
tier: 'sonnet',
|
|
1147
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
id: 'grok-4.20-0309-reasoning',
|
|
1151
|
+
aliases: ['grok-4.20', 'grok-4.20-reasoning', 'grok-4.20-0309'],
|
|
1152
|
+
provider: 'xai',
|
|
1153
|
+
displayName: 'Grok 4.20 (reasoning)',
|
|
1154
|
+
inputPerMTok: 1.25,
|
|
1155
|
+
outputPerMTok: 2.5,
|
|
1156
|
+
contextWindow: 1_000_000,
|
|
1157
|
+
cacheMinTokens: null,
|
|
1158
|
+
caching: 'automatic',
|
|
1159
|
+
multipliers: { cacheRead: 0.16, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.8 },
|
|
1160
|
+
tiers: [GROK_LONG(2.5, 5)],
|
|
1161
|
+
capability: 'mid',
|
|
1162
|
+
tier: 'sonnet',
|
|
1163
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1164
|
+
},
|
|
732
1165
|
{
|
|
1166
|
+
id: 'grok-4.20-0309-non-reasoning',
|
|
1167
|
+
aliases: ['grok-4.20-non-reasoning'],
|
|
1168
|
+
provider: 'xai',
|
|
1169
|
+
displayName: 'Grok 4.20 (non-reasoning)',
|
|
1170
|
+
inputPerMTok: 1.25,
|
|
1171
|
+
outputPerMTok: 2.5,
|
|
1172
|
+
contextWindow: 1_000_000,
|
|
1173
|
+
cacheMinTokens: null,
|
|
1174
|
+
caching: 'automatic',
|
|
1175
|
+
multipliers: { cacheRead: 0.16, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.8 },
|
|
1176
|
+
tiers: [GROK_LONG(2.5, 5)],
|
|
1177
|
+
capability: 'mid',
|
|
1178
|
+
tier: 'sonnet',
|
|
1179
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1180
|
+
},
|
|
1181
|
+
{
|
|
1182
|
+
id: 'grok-4.20-multi-agent-0309',
|
|
1183
|
+
aliases: ['grok-4.20-multi-agent'],
|
|
1184
|
+
provider: 'xai',
|
|
1185
|
+
displayName: 'Grok 4.20 Multi-Agent',
|
|
1186
|
+
inputPerMTok: 1.25,
|
|
1187
|
+
outputPerMTok: 2.5,
|
|
1188
|
+
contextWindow: 1_000_000,
|
|
1189
|
+
cacheMinTokens: null,
|
|
1190
|
+
caching: 'automatic',
|
|
1191
|
+
multipliers: { cacheRead: 0.16, cacheWrite5m: 1, cacheWrite1h: 1, batch: 0.8 },
|
|
1192
|
+
tiers: [GROK_LONG(2.5, 5)],
|
|
1193
|
+
capability: 'mid',
|
|
1194
|
+
tier: 'sonnet',
|
|
1195
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
id: 'grok-build-0.1',
|
|
1199
|
+
provider: 'xai',
|
|
1200
|
+
displayName: 'Grok Build 0.1',
|
|
1201
|
+
inputPerMTok: 1,
|
|
1202
|
+
outputPerMTok: 2,
|
|
1203
|
+
contextWindow: 256_000,
|
|
1204
|
+
cacheMinTokens: null,
|
|
1205
|
+
caching: 'automatic',
|
|
1206
|
+
multipliers: { cacheRead: 0.2, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1207
|
+
tiers: [GROK_LONG(2, 4)],
|
|
1208
|
+
capability: 'mid',
|
|
1209
|
+
tier: 'sonnet',
|
|
1210
|
+
notes: NO_PUBLISHED_CACHE_MINIMUM,
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
/*
|
|
1214
|
+
* Retired on 2026-05-15 at 12:00 PT (19:00 UTC), and billed since at
|
|
1215
|
+
* Grok 4.3's prices: "requests to the retired model slugs above will
|
|
1216
|
+
* automatically redirect to grok-4.3 ... you will be billed at grok-4.3
|
|
1217
|
+
* pricing" (xAI's retirement notice, read 2026-10-11). So the id has two
|
|
1218
|
+
* periods, and a log that spans the date is billed both ways, at the
|
|
1219
|
+
* instant xAI gave. `grok-4-0709` is the dated id the notice names.
|
|
1220
|
+
*/
|
|
733
1221
|
id: 'grok-4',
|
|
1222
|
+
aliases: ['grok-4-0709'],
|
|
734
1223
|
provider: 'xai',
|
|
735
1224
|
displayName: 'Grok 4',
|
|
736
|
-
inputPerMTok:
|
|
737
|
-
outputPerMTok:
|
|
1225
|
+
inputPerMTok: 1.25,
|
|
1226
|
+
outputPerMTok: 2.5,
|
|
738
1227
|
contextWindow: 256_000,
|
|
739
|
-
cacheMinTokens:
|
|
1228
|
+
cacheMinTokens: null,
|
|
740
1229
|
caching: 'automatic',
|
|
741
|
-
multipliers: { cacheRead: 0.
|
|
1230
|
+
multipliers: { cacheRead: 0.16, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1231
|
+
tiers: [GROK_LONG(2.5, 5)],
|
|
1232
|
+
history: [
|
|
1233
|
+
{
|
|
1234
|
+
until: '2026-05-15T19:00:00Z',
|
|
1235
|
+
inputPerMTok: 3,
|
|
1236
|
+
outputPerMTok: 15,
|
|
1237
|
+
multipliers: { cacheRead: 0.25, cacheWrite5m: 1, cacheWrite1h: 1, batch: null },
|
|
1238
|
+
},
|
|
1239
|
+
],
|
|
1240
|
+
recommendable: false,
|
|
742
1241
|
capability: 'large',
|
|
743
1242
|
tier: 'opus',
|
|
744
|
-
notes: '
|
|
1243
|
+
notes: 'Retired by xAI on 2026-05-15 and redirected to Grok 4.3, whose price it bills at from then;'
|
|
1244
|
+
+ ` $3/$15 before. ${NO_PUBLISHED_CACHE_MINIMUM}`,
|
|
745
1245
|
},
|
|
746
1246
|
// ------------------------------------------------------------------------
|
|
747
1247
|
// Mistral
|
|
@@ -993,16 +1493,20 @@ function cache(model) {
|
|
|
993
1493
|
* because "this does not apply" and "nobody said" lead to different reports and
|
|
994
1494
|
* collapsing them is the oldest mistake in this repository.
|
|
995
1495
|
*/
|
|
996
|
-
function holds(when, on,
|
|
1496
|
+
function holds(when, on, size) {
|
|
997
1497
|
if (when.kind === 'utc-hours') {
|
|
998
1498
|
const day = on.getUTCDay();
|
|
999
1499
|
if (when.weekdaysOnly && (day === 0 || day === 6))
|
|
1000
1500
|
return false;
|
|
1001
1501
|
return when.hours.includes(on.getUTCHours());
|
|
1002
1502
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1503
|
+
const over = (tokens) => when.kind === 'input-tokens-at-least' ? tokens >= when.tokens : tokens > when.tokens;
|
|
1504
|
+
if (size.inputTokens !== undefined)
|
|
1505
|
+
return over(size.inputTokens);
|
|
1506
|
+
// A whole row under the line puts every request in it under the line.
|
|
1507
|
+
if (size.inputTokensAtMost !== undefined && !over(size.inputTokensAtMost))
|
|
1508
|
+
return false;
|
|
1509
|
+
return null;
|
|
1006
1510
|
}
|
|
1007
1511
|
/**
|
|
1008
1512
|
* What one call is billed at, and what decided it.
|
|
@@ -1039,7 +1543,7 @@ export function effectivePricing(model, on = new Date(), context = {}) {
|
|
|
1039
1543
|
if (model.tiers !== undefined && model.tiers.length > 0) {
|
|
1040
1544
|
const undecided = [];
|
|
1041
1545
|
for (const tier of model.tiers) {
|
|
1042
|
-
const verdict = holds(tier.when, on, context
|
|
1546
|
+
const verdict = holds(tier.when, on, context);
|
|
1043
1547
|
if (verdict === true) {
|
|
1044
1548
|
return {
|
|
1045
1549
|
inputPerMTok: tier.inputPerMTok,
|
|
@@ -1059,6 +1563,11 @@ export function effectivePricing(model, on = new Date(), context = {}) {
|
|
|
1059
1563
|
}
|
|
1060
1564
|
/* The dearest candidate, so the figure is a ceiling rather than a wish. */
|
|
1061
1565
|
const dearest = undecided.reduce((worst, tier) => tier.inputPerMTok > worst.inputPerMTok ? tier : worst);
|
|
1566
|
+
/*
|
|
1567
|
+
* And the cheapest, which is the base: every undecided condition might not
|
|
1568
|
+
* hold, and a tier is never below the base (`pricing-tiers.test.js`).
|
|
1569
|
+
*/
|
|
1570
|
+
const floor = { inputPerMTok: model.inputPerMTok, outputPerMTok: model.outputPerMTok };
|
|
1062
1571
|
const ceiling = dearest.inputPerMTok > model.inputPerMTok
|
|
1063
1572
|
? {
|
|
1064
1573
|
inputPerMTok: dearest.inputPerMTok,
|
|
@@ -1077,7 +1586,10 @@ export function effectivePricing(model, on = new Date(), context = {}) {
|
|
|
1077
1586
|
tier: {
|
|
1078
1587
|
applied: ceiling.applied,
|
|
1079
1588
|
decided: false,
|
|
1080
|
-
because:
|
|
1589
|
+
because: context.inputTokensAtMost !== undefined
|
|
1590
|
+
? `${describe(dearest.when)}, and this row sums requests without giving any one prompt's length`
|
|
1591
|
+
: `${describe(dearest.when)}, and the token count was not given`,
|
|
1592
|
+
floor,
|
|
1081
1593
|
},
|
|
1082
1594
|
};
|
|
1083
1595
|
}
|
|
@@ -1090,6 +1602,9 @@ function describe(when) {
|
|
|
1090
1602
|
if (when.kind === 'input-tokens-above') {
|
|
1091
1603
|
return `prompts over ${when.tokens.toLocaleString('en-US')} input tokens`;
|
|
1092
1604
|
}
|
|
1605
|
+
if (when.kind === 'input-tokens-at-least') {
|
|
1606
|
+
return `prompts of ${when.tokens.toLocaleString('en-US')} input tokens or more`;
|
|
1607
|
+
}
|
|
1093
1608
|
const windows = [];
|
|
1094
1609
|
let start = null;
|
|
1095
1610
|
const sorted = [...when.hours].sort((a, b) => a - b);
|