cascade-ai 0.48.0 → 0.49.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/README.md +26 -5
- package/dist/cli.cjs +1904 -55
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1904 -55
- package/dist/cli.js.map +1 -1
- package/dist/desktop-core.cjs +1841 -51
- package/dist/index.cjs +1841 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -0
- package/dist/index.d.ts +87 -0
- package/dist/index.js +1841 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -238,8 +238,1660 @@ var init_audit_logger = __esm({
|
|
|
238
238
|
}
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
// src/core/router/pricing-data.json
|
|
242
|
+
var pricing_data_default = {
|
|
243
|
+
entries: [
|
|
244
|
+
{
|
|
245
|
+
model: "claude-opus-5",
|
|
246
|
+
provider: "anthropic",
|
|
247
|
+
modality: "text",
|
|
248
|
+
currency: "USD",
|
|
249
|
+
asOf: "2026-07-27",
|
|
250
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
251
|
+
provenance: "vendor-pricing-page",
|
|
252
|
+
tiers: [
|
|
253
|
+
{
|
|
254
|
+
inputPer1m: 5,
|
|
255
|
+
outputPer1m: 25,
|
|
256
|
+
cachedInputPer1m: 0.5,
|
|
257
|
+
cacheWritePer1m: 6.25,
|
|
258
|
+
reasoningOutputPer1m: 25
|
|
259
|
+
}
|
|
260
|
+
],
|
|
261
|
+
batchMultiplier: 0.5,
|
|
262
|
+
contextWindow: 1e6
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
model: "claude-opus-4-8",
|
|
266
|
+
provider: "anthropic",
|
|
267
|
+
modality: "text",
|
|
268
|
+
currency: "USD",
|
|
269
|
+
asOf: "2026-07-27",
|
|
270
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
271
|
+
provenance: "vendor-pricing-page",
|
|
272
|
+
tiers: [
|
|
273
|
+
{
|
|
274
|
+
inputPer1m: 5,
|
|
275
|
+
outputPer1m: 25,
|
|
276
|
+
cachedInputPer1m: 0.5,
|
|
277
|
+
cacheWritePer1m: 6.25,
|
|
278
|
+
reasoningOutputPer1m: 25
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
batchMultiplier: 0.5,
|
|
282
|
+
contextWindow: 1e6
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
model: "claude-opus-4-7",
|
|
286
|
+
provider: "anthropic",
|
|
287
|
+
modality: "text",
|
|
288
|
+
currency: "USD",
|
|
289
|
+
asOf: "2026-07-27",
|
|
290
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
291
|
+
provenance: "vendor-pricing-page",
|
|
292
|
+
tiers: [
|
|
293
|
+
{
|
|
294
|
+
inputPer1m: 5,
|
|
295
|
+
outputPer1m: 25,
|
|
296
|
+
cachedInputPer1m: 0.5,
|
|
297
|
+
cacheWritePer1m: 6.25,
|
|
298
|
+
reasoningOutputPer1m: 25
|
|
299
|
+
}
|
|
300
|
+
],
|
|
301
|
+
batchMultiplier: 0.5,
|
|
302
|
+
contextWindow: 1e6
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
model: "claude-opus-4-6",
|
|
306
|
+
provider: "anthropic",
|
|
307
|
+
modality: "text",
|
|
308
|
+
currency: "USD",
|
|
309
|
+
asOf: "2026-07-27",
|
|
310
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
311
|
+
provenance: "vendor-pricing-page",
|
|
312
|
+
tiers: [
|
|
313
|
+
{
|
|
314
|
+
inputPer1m: 5,
|
|
315
|
+
outputPer1m: 25,
|
|
316
|
+
cachedInputPer1m: 0.5,
|
|
317
|
+
cacheWritePer1m: 6.25,
|
|
318
|
+
reasoningOutputPer1m: 25
|
|
319
|
+
}
|
|
320
|
+
],
|
|
321
|
+
batchMultiplier: 0.5,
|
|
322
|
+
contextWindow: 1e6
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
model: "claude-opus-4-5",
|
|
326
|
+
provider: "anthropic",
|
|
327
|
+
modality: "text",
|
|
328
|
+
currency: "USD",
|
|
329
|
+
asOf: "2026-07-27",
|
|
330
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
331
|
+
provenance: "vendor-pricing-page",
|
|
332
|
+
tiers: [
|
|
333
|
+
{
|
|
334
|
+
inputPer1m: 5,
|
|
335
|
+
outputPer1m: 25,
|
|
336
|
+
cachedInputPer1m: 0.5,
|
|
337
|
+
cacheWritePer1m: 6.25,
|
|
338
|
+
reasoningOutputPer1m: 25
|
|
339
|
+
}
|
|
340
|
+
],
|
|
341
|
+
batchMultiplier: 0.5,
|
|
342
|
+
contextWindow: 2e5
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
model: "claude-opus-4-1",
|
|
346
|
+
provider: "anthropic",
|
|
347
|
+
modality: "text",
|
|
348
|
+
currency: "USD",
|
|
349
|
+
asOf: "2026-07-27",
|
|
350
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
351
|
+
provenance: "vendor-pricing-page",
|
|
352
|
+
tiers: [
|
|
353
|
+
{
|
|
354
|
+
inputPer1m: 15,
|
|
355
|
+
outputPer1m: 75,
|
|
356
|
+
cachedInputPer1m: 1.5,
|
|
357
|
+
cacheWritePer1m: 18.75,
|
|
358
|
+
reasoningOutputPer1m: 75
|
|
359
|
+
}
|
|
360
|
+
],
|
|
361
|
+
batchMultiplier: 0.5,
|
|
362
|
+
contextWindow: 2e5,
|
|
363
|
+
notes: "Deprecated by Anthropic; priced for historical/cost-reporting accuracy."
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
model: "claude-opus-4",
|
|
367
|
+
provider: "anthropic",
|
|
368
|
+
modality: "text",
|
|
369
|
+
currency: "USD",
|
|
370
|
+
asOf: "2026-07-27",
|
|
371
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
372
|
+
provenance: "vendor-pricing-page",
|
|
373
|
+
tiers: [
|
|
374
|
+
{
|
|
375
|
+
inputPer1m: 15,
|
|
376
|
+
outputPer1m: 75,
|
|
377
|
+
cachedInputPer1m: 1.5,
|
|
378
|
+
cacheWritePer1m: 18.75,
|
|
379
|
+
reasoningOutputPer1m: 75
|
|
380
|
+
}
|
|
381
|
+
],
|
|
382
|
+
batchMultiplier: 0.5,
|
|
383
|
+
contextWindow: 2e5,
|
|
384
|
+
notes: "Retired except on Google Cloud; priced for historical/cost-reporting accuracy."
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
model: "claude-sonnet-5",
|
|
388
|
+
provider: "anthropic",
|
|
389
|
+
modality: "text",
|
|
390
|
+
currency: "USD",
|
|
391
|
+
asOf: "2026-07-27",
|
|
392
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
393
|
+
provenance: "vendor-pricing-page",
|
|
394
|
+
tiers: [
|
|
395
|
+
{
|
|
396
|
+
inputPer1m: 2,
|
|
397
|
+
outputPer1m: 10,
|
|
398
|
+
cachedInputPer1m: 0.2,
|
|
399
|
+
cacheWritePer1m: 2.5,
|
|
400
|
+
reasoningOutputPer1m: 10
|
|
401
|
+
}
|
|
402
|
+
],
|
|
403
|
+
batchMultiplier: 0.5,
|
|
404
|
+
contextWindow: 1e6,
|
|
405
|
+
notes: "Introductory pricing through 2026-08-31. Standard pricing of $3/$15 per 1M takes effect 2026-09-01 \u2014 re-check this entry then."
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
model: "claude-sonnet-4-6",
|
|
409
|
+
provider: "anthropic",
|
|
410
|
+
modality: "text",
|
|
411
|
+
currency: "USD",
|
|
412
|
+
asOf: "2026-07-27",
|
|
413
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
414
|
+
provenance: "vendor-pricing-page",
|
|
415
|
+
tiers: [
|
|
416
|
+
{
|
|
417
|
+
inputPer1m: 3,
|
|
418
|
+
outputPer1m: 15,
|
|
419
|
+
cachedInputPer1m: 0.3,
|
|
420
|
+
cacheWritePer1m: 3.75,
|
|
421
|
+
reasoningOutputPer1m: 15
|
|
422
|
+
}
|
|
423
|
+
],
|
|
424
|
+
batchMultiplier: 0.5,
|
|
425
|
+
contextWindow: 1e6
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
model: "claude-sonnet-4-5",
|
|
429
|
+
provider: "anthropic",
|
|
430
|
+
modality: "text",
|
|
431
|
+
currency: "USD",
|
|
432
|
+
asOf: "2026-07-27",
|
|
433
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
434
|
+
provenance: "vendor-pricing-page",
|
|
435
|
+
tiers: [
|
|
436
|
+
{
|
|
437
|
+
maxInputTokens: 2e5,
|
|
438
|
+
inputPer1m: 3,
|
|
439
|
+
outputPer1m: 15,
|
|
440
|
+
cachedInputPer1m: 0.3,
|
|
441
|
+
cacheWritePer1m: 3.75,
|
|
442
|
+
reasoningOutputPer1m: 15
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
inputPer1m: 6,
|
|
446
|
+
outputPer1m: 22.5,
|
|
447
|
+
cachedInputPer1m: 0.6,
|
|
448
|
+
cacheWritePer1m: 7.5,
|
|
449
|
+
reasoningOutputPer1m: 22.5
|
|
450
|
+
}
|
|
451
|
+
],
|
|
452
|
+
batchMultiplier: 0.5,
|
|
453
|
+
contextWindow: 2e5,
|
|
454
|
+
notes: "Long-context (>200K) premium applies to the 1M-context beta. Base rates from the Anthropic pricing page; the >200K tier from the litellm catalog (Anthropic does not tabulate it on the pricing page)."
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
model: "claude-sonnet-4",
|
|
458
|
+
provider: "anthropic",
|
|
459
|
+
modality: "text",
|
|
460
|
+
currency: "USD",
|
|
461
|
+
asOf: "2026-07-27",
|
|
462
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
463
|
+
provenance: "vendor-pricing-page",
|
|
464
|
+
tiers: [
|
|
465
|
+
{
|
|
466
|
+
inputPer1m: 3,
|
|
467
|
+
outputPer1m: 15,
|
|
468
|
+
cachedInputPer1m: 0.3,
|
|
469
|
+
cacheWritePer1m: 3.75,
|
|
470
|
+
reasoningOutputPer1m: 15
|
|
471
|
+
}
|
|
472
|
+
],
|
|
473
|
+
batchMultiplier: 0.5,
|
|
474
|
+
contextWindow: 2e5
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
model: "claude-haiku-4-5",
|
|
478
|
+
provider: "anthropic",
|
|
479
|
+
modality: "text",
|
|
480
|
+
currency: "USD",
|
|
481
|
+
asOf: "2026-07-27",
|
|
482
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
483
|
+
provenance: "vendor-pricing-page",
|
|
484
|
+
tiers: [
|
|
485
|
+
{
|
|
486
|
+
inputPer1m: 1,
|
|
487
|
+
outputPer1m: 5,
|
|
488
|
+
cachedInputPer1m: 0.1,
|
|
489
|
+
cacheWritePer1m: 1.25,
|
|
490
|
+
reasoningOutputPer1m: 5
|
|
491
|
+
}
|
|
492
|
+
],
|
|
493
|
+
batchMultiplier: 0.5,
|
|
494
|
+
contextWindow: 2e5
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
model: "claude-haiku-3-5",
|
|
498
|
+
provider: "anthropic",
|
|
499
|
+
modality: "text",
|
|
500
|
+
currency: "USD",
|
|
501
|
+
asOf: "2026-07-27",
|
|
502
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
503
|
+
provenance: "vendor-pricing-page",
|
|
504
|
+
tiers: [
|
|
505
|
+
{
|
|
506
|
+
inputPer1m: 0.8,
|
|
507
|
+
outputPer1m: 4,
|
|
508
|
+
cachedInputPer1m: 0.08,
|
|
509
|
+
cacheWritePer1m: 1,
|
|
510
|
+
reasoningOutputPer1m: 4
|
|
511
|
+
}
|
|
512
|
+
],
|
|
513
|
+
batchMultiplier: 0.5,
|
|
514
|
+
contextWindow: 2e5
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
model: "gpt-5.6-sol",
|
|
518
|
+
provider: "openai",
|
|
519
|
+
aliases: [
|
|
520
|
+
"gpt-5.6"
|
|
521
|
+
],
|
|
522
|
+
modality: "text",
|
|
523
|
+
currency: "USD",
|
|
524
|
+
asOf: "2026-07-27",
|
|
525
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
526
|
+
provenance: "litellm-catalog",
|
|
527
|
+
tiers: [
|
|
528
|
+
{
|
|
529
|
+
maxInputTokens: 272e3,
|
|
530
|
+
inputPer1m: 5,
|
|
531
|
+
outputPer1m: 30,
|
|
532
|
+
cachedInputPer1m: 0.5,
|
|
533
|
+
cacheWritePer1m: 6.25
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
inputPer1m: 10,
|
|
537
|
+
outputPer1m: 45,
|
|
538
|
+
cachedInputPer1m: 1,
|
|
539
|
+
cacheWritePer1m: 12.5
|
|
540
|
+
}
|
|
541
|
+
],
|
|
542
|
+
batchMultiplier: 0.5,
|
|
543
|
+
contextWindow: 105e4
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
model: "gpt-5.6-terra",
|
|
547
|
+
provider: "openai",
|
|
548
|
+
modality: "text",
|
|
549
|
+
currency: "USD",
|
|
550
|
+
asOf: "2026-07-27",
|
|
551
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
552
|
+
provenance: "litellm-catalog",
|
|
553
|
+
tiers: [
|
|
554
|
+
{
|
|
555
|
+
maxInputTokens: 272e3,
|
|
556
|
+
inputPer1m: 2.5,
|
|
557
|
+
outputPer1m: 15,
|
|
558
|
+
cachedInputPer1m: 0.25,
|
|
559
|
+
cacheWritePer1m: 3.125
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
inputPer1m: 5,
|
|
563
|
+
outputPer1m: 22.5,
|
|
564
|
+
cachedInputPer1m: 0.5,
|
|
565
|
+
cacheWritePer1m: 6.25
|
|
566
|
+
}
|
|
567
|
+
],
|
|
568
|
+
batchMultiplier: 0.5,
|
|
569
|
+
contextWindow: 105e4
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
model: "gpt-5.6-luna",
|
|
573
|
+
provider: "openai",
|
|
574
|
+
modality: "text",
|
|
575
|
+
currency: "USD",
|
|
576
|
+
asOf: "2026-07-27",
|
|
577
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
578
|
+
provenance: "litellm-catalog",
|
|
579
|
+
tiers: [
|
|
580
|
+
{
|
|
581
|
+
maxInputTokens: 272e3,
|
|
582
|
+
inputPer1m: 1,
|
|
583
|
+
outputPer1m: 6,
|
|
584
|
+
cachedInputPer1m: 0.1,
|
|
585
|
+
cacheWritePer1m: 1.25
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
inputPer1m: 2,
|
|
589
|
+
outputPer1m: 9,
|
|
590
|
+
cachedInputPer1m: 0.2,
|
|
591
|
+
cacheWritePer1m: 2.5
|
|
592
|
+
}
|
|
593
|
+
],
|
|
594
|
+
batchMultiplier: 0.5,
|
|
595
|
+
contextWindow: 105e4
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
model: "gpt-5.5",
|
|
599
|
+
provider: "openai",
|
|
600
|
+
modality: "text",
|
|
601
|
+
currency: "USD",
|
|
602
|
+
asOf: "2026-07-27",
|
|
603
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
604
|
+
provenance: "litellm-catalog",
|
|
605
|
+
tiers: [
|
|
606
|
+
{
|
|
607
|
+
maxInputTokens: 272e3,
|
|
608
|
+
inputPer1m: 5,
|
|
609
|
+
outputPer1m: 30,
|
|
610
|
+
cachedInputPer1m: 0.5
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
inputPer1m: 10,
|
|
614
|
+
outputPer1m: 45,
|
|
615
|
+
cachedInputPer1m: 1
|
|
616
|
+
}
|
|
617
|
+
],
|
|
618
|
+
batchMultiplier: 0.5,
|
|
619
|
+
contextWindow: 105e4
|
|
620
|
+
},
|
|
621
|
+
{
|
|
622
|
+
model: "gpt-5.4",
|
|
623
|
+
provider: "openai",
|
|
624
|
+
modality: "text",
|
|
625
|
+
currency: "USD",
|
|
626
|
+
asOf: "2026-07-27",
|
|
627
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
628
|
+
provenance: "litellm-catalog",
|
|
629
|
+
tiers: [
|
|
630
|
+
{
|
|
631
|
+
maxInputTokens: 272e3,
|
|
632
|
+
inputPer1m: 2.5,
|
|
633
|
+
outputPer1m: 15,
|
|
634
|
+
cachedInputPer1m: 0.25
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
inputPer1m: 5,
|
|
638
|
+
outputPer1m: 22.5,
|
|
639
|
+
cachedInputPer1m: 0.5
|
|
640
|
+
}
|
|
641
|
+
],
|
|
642
|
+
batchMultiplier: 0.5,
|
|
643
|
+
contextWindow: 105e4
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
model: "gpt-5.4-mini",
|
|
647
|
+
provider: "openai",
|
|
648
|
+
modality: "text",
|
|
649
|
+
currency: "USD",
|
|
650
|
+
asOf: "2026-07-27",
|
|
651
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
652
|
+
provenance: "litellm-catalog",
|
|
653
|
+
tiers: [
|
|
654
|
+
{
|
|
655
|
+
inputPer1m: 0.75,
|
|
656
|
+
outputPer1m: 4.5,
|
|
657
|
+
cachedInputPer1m: 0.075
|
|
658
|
+
}
|
|
659
|
+
],
|
|
660
|
+
batchMultiplier: 0.5,
|
|
661
|
+
contextWindow: 105e4
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
model: "gpt-5",
|
|
665
|
+
provider: "openai",
|
|
666
|
+
modality: "text",
|
|
667
|
+
currency: "USD",
|
|
668
|
+
asOf: "2026-07-27",
|
|
669
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
670
|
+
provenance: "litellm-catalog",
|
|
671
|
+
tiers: [
|
|
672
|
+
{
|
|
673
|
+
inputPer1m: 1.25,
|
|
674
|
+
outputPer1m: 10,
|
|
675
|
+
cachedInputPer1m: 0.125
|
|
676
|
+
}
|
|
677
|
+
],
|
|
678
|
+
contextWindow: 272e3
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
model: "gpt-5-mini",
|
|
682
|
+
provider: "openai",
|
|
683
|
+
modality: "text",
|
|
684
|
+
currency: "USD",
|
|
685
|
+
asOf: "2026-07-27",
|
|
686
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
687
|
+
provenance: "litellm-catalog",
|
|
688
|
+
tiers: [
|
|
689
|
+
{
|
|
690
|
+
inputPer1m: 0.25,
|
|
691
|
+
outputPer1m: 2,
|
|
692
|
+
cachedInputPer1m: 0.025
|
|
693
|
+
}
|
|
694
|
+
],
|
|
695
|
+
contextWindow: 272e3
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
model: "gpt-5-nano",
|
|
699
|
+
provider: "openai",
|
|
700
|
+
modality: "text",
|
|
701
|
+
currency: "USD",
|
|
702
|
+
asOf: "2026-07-27",
|
|
703
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
704
|
+
provenance: "litellm-catalog",
|
|
705
|
+
tiers: [
|
|
706
|
+
{
|
|
707
|
+
inputPer1m: 0.05,
|
|
708
|
+
outputPer1m: 0.4,
|
|
709
|
+
cachedInputPer1m: 5e-3
|
|
710
|
+
}
|
|
711
|
+
],
|
|
712
|
+
contextWindow: 272e3
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
model: "gpt-4.1",
|
|
716
|
+
provider: "openai",
|
|
717
|
+
modality: "text",
|
|
718
|
+
currency: "USD",
|
|
719
|
+
asOf: "2026-07-27",
|
|
720
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
721
|
+
provenance: "litellm-catalog",
|
|
722
|
+
tiers: [
|
|
723
|
+
{
|
|
724
|
+
inputPer1m: 2,
|
|
725
|
+
outputPer1m: 8,
|
|
726
|
+
cachedInputPer1m: 0.5
|
|
727
|
+
}
|
|
728
|
+
],
|
|
729
|
+
batchMultiplier: 0.5,
|
|
730
|
+
contextWindow: 1047576
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
model: "gpt-4.1-mini",
|
|
734
|
+
provider: "openai",
|
|
735
|
+
modality: "text",
|
|
736
|
+
currency: "USD",
|
|
737
|
+
asOf: "2026-07-27",
|
|
738
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
739
|
+
provenance: "litellm-catalog",
|
|
740
|
+
tiers: [
|
|
741
|
+
{
|
|
742
|
+
inputPer1m: 0.4,
|
|
743
|
+
outputPer1m: 1.6,
|
|
744
|
+
cachedInputPer1m: 0.1
|
|
745
|
+
}
|
|
746
|
+
],
|
|
747
|
+
batchMultiplier: 0.5,
|
|
748
|
+
contextWindow: 1047576
|
|
749
|
+
},
|
|
750
|
+
{
|
|
751
|
+
model: "gpt-4.1-nano",
|
|
752
|
+
provider: "openai",
|
|
753
|
+
modality: "text",
|
|
754
|
+
currency: "USD",
|
|
755
|
+
asOf: "2026-07-27",
|
|
756
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
757
|
+
provenance: "litellm-catalog",
|
|
758
|
+
tiers: [
|
|
759
|
+
{
|
|
760
|
+
inputPer1m: 0.1,
|
|
761
|
+
outputPer1m: 0.4,
|
|
762
|
+
cachedInputPer1m: 0.025
|
|
763
|
+
}
|
|
764
|
+
],
|
|
765
|
+
batchMultiplier: 0.5,
|
|
766
|
+
contextWindow: 1047576
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
model: "gpt-4o",
|
|
770
|
+
provider: "openai",
|
|
771
|
+
modality: "text",
|
|
772
|
+
currency: "USD",
|
|
773
|
+
asOf: "2026-07-27",
|
|
774
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
775
|
+
provenance: "litellm-catalog",
|
|
776
|
+
tiers: [
|
|
777
|
+
{
|
|
778
|
+
inputPer1m: 2.5,
|
|
779
|
+
outputPer1m: 10,
|
|
780
|
+
cachedInputPer1m: 1.25
|
|
781
|
+
}
|
|
782
|
+
],
|
|
783
|
+
batchMultiplier: 0.5,
|
|
784
|
+
contextWindow: 128e3
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
model: "gpt-4o-mini",
|
|
788
|
+
provider: "openai",
|
|
789
|
+
modality: "text",
|
|
790
|
+
currency: "USD",
|
|
791
|
+
asOf: "2026-07-27",
|
|
792
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
793
|
+
provenance: "litellm-catalog",
|
|
794
|
+
tiers: [
|
|
795
|
+
{
|
|
796
|
+
inputPer1m: 0.15,
|
|
797
|
+
outputPer1m: 0.6,
|
|
798
|
+
cachedInputPer1m: 0.075
|
|
799
|
+
}
|
|
800
|
+
],
|
|
801
|
+
batchMultiplier: 0.5,
|
|
802
|
+
contextWindow: 128e3
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
model: "gpt-5.5",
|
|
806
|
+
provider: "azure",
|
|
807
|
+
region: "global",
|
|
808
|
+
modality: "text",
|
|
809
|
+
currency: "USD",
|
|
810
|
+
asOf: "2026-07-27",
|
|
811
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
812
|
+
provenance: "litellm-catalog",
|
|
813
|
+
tiers: [
|
|
814
|
+
{
|
|
815
|
+
maxInputTokens: 272e3,
|
|
816
|
+
inputPer1m: 5,
|
|
817
|
+
outputPer1m: 30,
|
|
818
|
+
cachedInputPer1m: 0.5
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
inputPer1m: 10,
|
|
822
|
+
outputPer1m: 45,
|
|
823
|
+
cachedInputPer1m: 1
|
|
824
|
+
}
|
|
825
|
+
],
|
|
826
|
+
contextWindow: 105e4
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
model: "gpt-5.5",
|
|
830
|
+
provider: "azure",
|
|
831
|
+
region: "us",
|
|
832
|
+
modality: "text",
|
|
833
|
+
currency: "USD",
|
|
834
|
+
asOf: "2026-07-27",
|
|
835
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
836
|
+
provenance: "litellm-catalog",
|
|
837
|
+
tiers: [
|
|
838
|
+
{
|
|
839
|
+
maxInputTokens: 272e3,
|
|
840
|
+
inputPer1m: 5.5,
|
|
841
|
+
outputPer1m: 33,
|
|
842
|
+
cachedInputPer1m: 0.55
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
inputPer1m: 11,
|
|
846
|
+
outputPer1m: 49.5,
|
|
847
|
+
cachedInputPer1m: 1.1
|
|
848
|
+
}
|
|
849
|
+
],
|
|
850
|
+
contextWindow: 105e4
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
model: "gpt-5.5",
|
|
854
|
+
provider: "azure",
|
|
855
|
+
region: "eu",
|
|
856
|
+
modality: "text",
|
|
857
|
+
currency: "USD",
|
|
858
|
+
asOf: "2026-07-27",
|
|
859
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
860
|
+
provenance: "litellm-catalog",
|
|
861
|
+
tiers: [
|
|
862
|
+
{
|
|
863
|
+
maxInputTokens: 272e3,
|
|
864
|
+
inputPer1m: 5.5,
|
|
865
|
+
outputPer1m: 33,
|
|
866
|
+
cachedInputPer1m: 0.55
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
inputPer1m: 11,
|
|
870
|
+
outputPer1m: 49.5,
|
|
871
|
+
cachedInputPer1m: 1.1
|
|
872
|
+
}
|
|
873
|
+
],
|
|
874
|
+
contextWindow: 105e4
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
model: "gpt-5.4",
|
|
878
|
+
provider: "azure",
|
|
879
|
+
region: "global",
|
|
880
|
+
modality: "text",
|
|
881
|
+
currency: "USD",
|
|
882
|
+
asOf: "2026-07-27",
|
|
883
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
884
|
+
provenance: "litellm-catalog",
|
|
885
|
+
tiers: [
|
|
886
|
+
{
|
|
887
|
+
maxInputTokens: 272e3,
|
|
888
|
+
inputPer1m: 2.5,
|
|
889
|
+
outputPer1m: 15,
|
|
890
|
+
cachedInputPer1m: 0.25
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
inputPer1m: 5,
|
|
894
|
+
outputPer1m: 22.5,
|
|
895
|
+
cachedInputPer1m: 0.5
|
|
896
|
+
}
|
|
897
|
+
],
|
|
898
|
+
contextWindow: 105e4
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
model: "gpt-5.4",
|
|
902
|
+
provider: "azure",
|
|
903
|
+
region: "us",
|
|
904
|
+
modality: "text",
|
|
905
|
+
currency: "USD",
|
|
906
|
+
asOf: "2026-07-27",
|
|
907
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
908
|
+
provenance: "litellm-catalog",
|
|
909
|
+
tiers: [
|
|
910
|
+
{
|
|
911
|
+
inputPer1m: 2.75,
|
|
912
|
+
outputPer1m: 16.5,
|
|
913
|
+
cachedInputPer1m: 0.28
|
|
914
|
+
}
|
|
915
|
+
],
|
|
916
|
+
contextWindow: 105e4
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
model: "gpt-5.4",
|
|
920
|
+
provider: "azure",
|
|
921
|
+
region: "eu",
|
|
922
|
+
modality: "text",
|
|
923
|
+
currency: "USD",
|
|
924
|
+
asOf: "2026-07-27",
|
|
925
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
926
|
+
provenance: "litellm-catalog",
|
|
927
|
+
tiers: [
|
|
928
|
+
{
|
|
929
|
+
inputPer1m: 2.75,
|
|
930
|
+
outputPer1m: 16.5,
|
|
931
|
+
cachedInputPer1m: 0.28
|
|
932
|
+
}
|
|
933
|
+
],
|
|
934
|
+
contextWindow: 105e4
|
|
935
|
+
},
|
|
936
|
+
{
|
|
937
|
+
model: "gpt-5.6-terra",
|
|
938
|
+
provider: "azure",
|
|
939
|
+
region: "global",
|
|
940
|
+
modality: "text",
|
|
941
|
+
currency: "USD",
|
|
942
|
+
asOf: "2026-07-27",
|
|
943
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
944
|
+
provenance: "litellm-catalog",
|
|
945
|
+
tiers: [
|
|
946
|
+
{
|
|
947
|
+
maxInputTokens: 272e3,
|
|
948
|
+
inputPer1m: 2.5,
|
|
949
|
+
outputPer1m: 15,
|
|
950
|
+
cachedInputPer1m: 0.25
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
inputPer1m: 5,
|
|
954
|
+
outputPer1m: 22.5,
|
|
955
|
+
cachedInputPer1m: 0.5
|
|
956
|
+
}
|
|
957
|
+
],
|
|
958
|
+
contextWindow: 105e4
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
model: "gpt-5.6-terra",
|
|
962
|
+
provider: "azure",
|
|
963
|
+
region: "eu",
|
|
964
|
+
modality: "text",
|
|
965
|
+
currency: "USD",
|
|
966
|
+
asOf: "2026-07-27",
|
|
967
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
968
|
+
provenance: "litellm-catalog",
|
|
969
|
+
tiers: [
|
|
970
|
+
{
|
|
971
|
+
maxInputTokens: 272e3,
|
|
972
|
+
inputPer1m: 2.75,
|
|
973
|
+
outputPer1m: 16.5,
|
|
974
|
+
cachedInputPer1m: 0.275
|
|
975
|
+
},
|
|
976
|
+
{
|
|
977
|
+
inputPer1m: 5.5,
|
|
978
|
+
outputPer1m: 24.75,
|
|
979
|
+
cachedInputPer1m: 0.55
|
|
980
|
+
}
|
|
981
|
+
],
|
|
982
|
+
contextWindow: 105e4
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
model: "gpt-5",
|
|
986
|
+
provider: "azure",
|
|
987
|
+
region: "global",
|
|
988
|
+
modality: "text",
|
|
989
|
+
currency: "USD",
|
|
990
|
+
asOf: "2026-07-27",
|
|
991
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
992
|
+
provenance: "litellm-catalog",
|
|
993
|
+
tiers: [
|
|
994
|
+
{
|
|
995
|
+
inputPer1m: 1.25,
|
|
996
|
+
outputPer1m: 10,
|
|
997
|
+
cachedInputPer1m: 0.125
|
|
998
|
+
}
|
|
999
|
+
],
|
|
1000
|
+
contextWindow: 272e3
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
model: "gpt-5-mini",
|
|
1004
|
+
provider: "azure",
|
|
1005
|
+
region: "global",
|
|
1006
|
+
modality: "text",
|
|
1007
|
+
currency: "USD",
|
|
1008
|
+
asOf: "2026-07-27",
|
|
1009
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1010
|
+
provenance: "litellm-catalog",
|
|
1011
|
+
tiers: [
|
|
1012
|
+
{
|
|
1013
|
+
inputPer1m: 0.25,
|
|
1014
|
+
outputPer1m: 2,
|
|
1015
|
+
cachedInputPer1m: 0.025
|
|
1016
|
+
}
|
|
1017
|
+
],
|
|
1018
|
+
contextWindow: 272e3
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
model: "gpt-5-nano",
|
|
1022
|
+
provider: "azure",
|
|
1023
|
+
region: "global",
|
|
1024
|
+
modality: "text",
|
|
1025
|
+
currency: "USD",
|
|
1026
|
+
asOf: "2026-07-27",
|
|
1027
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1028
|
+
provenance: "litellm-catalog",
|
|
1029
|
+
tiers: [
|
|
1030
|
+
{
|
|
1031
|
+
inputPer1m: 0.05,
|
|
1032
|
+
outputPer1m: 0.4,
|
|
1033
|
+
cachedInputPer1m: 5e-3
|
|
1034
|
+
}
|
|
1035
|
+
],
|
|
1036
|
+
contextWindow: 272e3
|
|
1037
|
+
},
|
|
1038
|
+
{
|
|
1039
|
+
model: "gpt-4.1",
|
|
1040
|
+
provider: "azure",
|
|
1041
|
+
region: "global",
|
|
1042
|
+
modality: "text",
|
|
1043
|
+
currency: "USD",
|
|
1044
|
+
asOf: "2026-07-27",
|
|
1045
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1046
|
+
provenance: "litellm-catalog",
|
|
1047
|
+
tiers: [
|
|
1048
|
+
{
|
|
1049
|
+
inputPer1m: 2,
|
|
1050
|
+
outputPer1m: 8,
|
|
1051
|
+
cachedInputPer1m: 0.5
|
|
1052
|
+
}
|
|
1053
|
+
],
|
|
1054
|
+
batchMultiplier: 0.5,
|
|
1055
|
+
contextWindow: 1047576
|
|
1056
|
+
},
|
|
1057
|
+
{
|
|
1058
|
+
model: "gpt-4o",
|
|
1059
|
+
provider: "azure",
|
|
1060
|
+
region: "global",
|
|
1061
|
+
modality: "text",
|
|
1062
|
+
currency: "USD",
|
|
1063
|
+
asOf: "2026-07-27",
|
|
1064
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1065
|
+
provenance: "litellm-catalog",
|
|
1066
|
+
tiers: [
|
|
1067
|
+
{
|
|
1068
|
+
inputPer1m: 2.5,
|
|
1069
|
+
outputPer1m: 10,
|
|
1070
|
+
cachedInputPer1m: 1.25
|
|
1071
|
+
}
|
|
1072
|
+
],
|
|
1073
|
+
contextWindow: 128e3
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
model: "gpt-4o-mini",
|
|
1077
|
+
provider: "azure",
|
|
1078
|
+
region: "global",
|
|
1079
|
+
modality: "text",
|
|
1080
|
+
currency: "USD",
|
|
1081
|
+
asOf: "2026-07-27",
|
|
1082
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1083
|
+
provenance: "litellm-catalog",
|
|
1084
|
+
tiers: [
|
|
1085
|
+
{
|
|
1086
|
+
inputPer1m: 0.165,
|
|
1087
|
+
outputPer1m: 0.66,
|
|
1088
|
+
cachedInputPer1m: 0.075
|
|
1089
|
+
}
|
|
1090
|
+
],
|
|
1091
|
+
contextWindow: 128e3,
|
|
1092
|
+
notes: "Azure charges $0.165/$0.66 per 1M for gpt-4o-mini vs $0.15/$0.60 on OpenAI \u2014 same model, different price."
|
|
1093
|
+
},
|
|
1094
|
+
{
|
|
1095
|
+
model: "gemini-3.1-pro",
|
|
1096
|
+
provider: "gemini",
|
|
1097
|
+
aliases: [
|
|
1098
|
+
"gemini-3.1-pro-preview"
|
|
1099
|
+
],
|
|
1100
|
+
modality: "text",
|
|
1101
|
+
currency: "USD",
|
|
1102
|
+
asOf: "2026-07-27",
|
|
1103
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1104
|
+
provenance: "vendor-pricing-page",
|
|
1105
|
+
tiers: [
|
|
1106
|
+
{
|
|
1107
|
+
maxInputTokens: 2e5,
|
|
1108
|
+
inputPer1m: 2,
|
|
1109
|
+
outputPer1m: 12,
|
|
1110
|
+
cachedInputPer1m: 0.2,
|
|
1111
|
+
reasoningOutputPer1m: 12
|
|
1112
|
+
},
|
|
1113
|
+
{
|
|
1114
|
+
inputPer1m: 4,
|
|
1115
|
+
outputPer1m: 18,
|
|
1116
|
+
cachedInputPer1m: 0.4,
|
|
1117
|
+
reasoningOutputPer1m: 18
|
|
1118
|
+
}
|
|
1119
|
+
],
|
|
1120
|
+
batchMultiplier: 0.5,
|
|
1121
|
+
contextWindow: 1048576,
|
|
1122
|
+
notes: "Long-context tier: $2/$12 per 1M up to 200K prompt tokens, $4/$18 above it."
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
model: "gemini-3-pro",
|
|
1126
|
+
provider: "gemini",
|
|
1127
|
+
aliases: [
|
|
1128
|
+
"gemini-3-pro-preview"
|
|
1129
|
+
],
|
|
1130
|
+
modality: "text",
|
|
1131
|
+
currency: "USD",
|
|
1132
|
+
asOf: "2026-07-27",
|
|
1133
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1134
|
+
provenance: "vendor-pricing-page",
|
|
1135
|
+
tiers: [
|
|
1136
|
+
{
|
|
1137
|
+
maxInputTokens: 2e5,
|
|
1138
|
+
inputPer1m: 2,
|
|
1139
|
+
outputPer1m: 12,
|
|
1140
|
+
cachedInputPer1m: 0.2,
|
|
1141
|
+
reasoningOutputPer1m: 12
|
|
1142
|
+
},
|
|
1143
|
+
{
|
|
1144
|
+
inputPer1m: 4,
|
|
1145
|
+
outputPer1m: 18,
|
|
1146
|
+
cachedInputPer1m: 0.4,
|
|
1147
|
+
reasoningOutputPer1m: 18
|
|
1148
|
+
}
|
|
1149
|
+
],
|
|
1150
|
+
batchMultiplier: 0.5,
|
|
1151
|
+
contextWindow: 1048576
|
|
1152
|
+
},
|
|
1153
|
+
{
|
|
1154
|
+
model: "gemini-3.6-flash",
|
|
1155
|
+
provider: "gemini",
|
|
1156
|
+
modality: "text",
|
|
1157
|
+
currency: "USD",
|
|
1158
|
+
asOf: "2026-07-27",
|
|
1159
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1160
|
+
provenance: "vendor-pricing-page",
|
|
1161
|
+
tiers: [
|
|
1162
|
+
{
|
|
1163
|
+
inputPer1m: 1.5,
|
|
1164
|
+
outputPer1m: 7.5,
|
|
1165
|
+
cachedInputPer1m: 0.15,
|
|
1166
|
+
reasoningOutputPer1m: 7.5
|
|
1167
|
+
}
|
|
1168
|
+
],
|
|
1169
|
+
batchMultiplier: 0.5,
|
|
1170
|
+
contextWindow: 1048576,
|
|
1171
|
+
notes: "Released 2026-07-21. Output pricing dropped ~17% from Gemini 3.5 Flash ($9.00 -> $7.50 per 1M); input unchanged."
|
|
1172
|
+
},
|
|
1173
|
+
{
|
|
1174
|
+
model: "gemini-3.5-flash",
|
|
1175
|
+
provider: "gemini",
|
|
1176
|
+
modality: "text",
|
|
1177
|
+
currency: "USD",
|
|
1178
|
+
asOf: "2026-07-27",
|
|
1179
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1180
|
+
provenance: "vendor-pricing-page",
|
|
1181
|
+
tiers: [
|
|
1182
|
+
{
|
|
1183
|
+
inputPer1m: 1.5,
|
|
1184
|
+
outputPer1m: 9,
|
|
1185
|
+
cachedInputPer1m: 0.15,
|
|
1186
|
+
reasoningOutputPer1m: 9
|
|
1187
|
+
}
|
|
1188
|
+
],
|
|
1189
|
+
batchMultiplier: 0.5,
|
|
1190
|
+
contextWindow: 1048576
|
|
1191
|
+
},
|
|
1192
|
+
{
|
|
1193
|
+
model: "gemini-3.5-flash-lite",
|
|
1194
|
+
provider: "gemini",
|
|
1195
|
+
modality: "text",
|
|
1196
|
+
currency: "USD",
|
|
1197
|
+
asOf: "2026-07-27",
|
|
1198
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1199
|
+
provenance: "litellm-catalog",
|
|
1200
|
+
tiers: [
|
|
1201
|
+
{
|
|
1202
|
+
inputPer1m: 0.3,
|
|
1203
|
+
outputPer1m: 2.5,
|
|
1204
|
+
cachedInputPer1m: 0.03,
|
|
1205
|
+
reasoningOutputPer1m: 2.5
|
|
1206
|
+
}
|
|
1207
|
+
],
|
|
1208
|
+
batchMultiplier: 0.5,
|
|
1209
|
+
contextWindow: 1048576
|
|
1210
|
+
},
|
|
1211
|
+
{
|
|
1212
|
+
model: "gemini-3.1-flash-lite",
|
|
1213
|
+
provider: "gemini",
|
|
1214
|
+
modality: "text",
|
|
1215
|
+
currency: "USD",
|
|
1216
|
+
asOf: "2026-07-27",
|
|
1217
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite",
|
|
1218
|
+
provenance: "litellm-catalog",
|
|
1219
|
+
tiers: [
|
|
1220
|
+
{
|
|
1221
|
+
inputPer1m: 0.25,
|
|
1222
|
+
outputPer1m: 1.5,
|
|
1223
|
+
cachedInputPer1m: 0.025,
|
|
1224
|
+
reasoningOutputPer1m: 1.5
|
|
1225
|
+
}
|
|
1226
|
+
],
|
|
1227
|
+
batchMultiplier: 0.5,
|
|
1228
|
+
contextWindow: 1048576
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
model: "gemini-3-flash",
|
|
1232
|
+
provider: "gemini",
|
|
1233
|
+
aliases: [
|
|
1234
|
+
"gemini-3-flash-preview"
|
|
1235
|
+
],
|
|
1236
|
+
modality: "text",
|
|
1237
|
+
currency: "USD",
|
|
1238
|
+
asOf: "2026-07-27",
|
|
1239
|
+
source: "https://ai.google.dev/pricing/gemini-3",
|
|
1240
|
+
provenance: "litellm-catalog",
|
|
1241
|
+
tiers: [
|
|
1242
|
+
{
|
|
1243
|
+
inputPer1m: 0.5,
|
|
1244
|
+
outputPer1m: 3,
|
|
1245
|
+
cachedInputPer1m: 0.05,
|
|
1246
|
+
reasoningOutputPer1m: 3
|
|
1247
|
+
}
|
|
1248
|
+
],
|
|
1249
|
+
contextWindow: 1048576
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
model: "gemini-2.5-pro",
|
|
1253
|
+
provider: "gemini",
|
|
1254
|
+
modality: "text",
|
|
1255
|
+
currency: "USD",
|
|
1256
|
+
asOf: "2026-07-27",
|
|
1257
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1258
|
+
provenance: "litellm-catalog",
|
|
1259
|
+
tiers: [
|
|
1260
|
+
{
|
|
1261
|
+
maxInputTokens: 2e5,
|
|
1262
|
+
inputPer1m: 1.25,
|
|
1263
|
+
outputPer1m: 10,
|
|
1264
|
+
cachedInputPer1m: 0.125
|
|
1265
|
+
},
|
|
1266
|
+
{
|
|
1267
|
+
inputPer1m: 2.5,
|
|
1268
|
+
outputPer1m: 15,
|
|
1269
|
+
cachedInputPer1m: 0.25
|
|
1270
|
+
}
|
|
1271
|
+
],
|
|
1272
|
+
contextWindow: 1048576
|
|
1273
|
+
},
|
|
1274
|
+
{
|
|
1275
|
+
model: "gemini-2.5-flash",
|
|
1276
|
+
provider: "gemini",
|
|
1277
|
+
modality: "text",
|
|
1278
|
+
currency: "USD",
|
|
1279
|
+
asOf: "2026-07-27",
|
|
1280
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-preview",
|
|
1281
|
+
provenance: "litellm-catalog",
|
|
1282
|
+
tiers: [
|
|
1283
|
+
{
|
|
1284
|
+
inputPer1m: 0.3,
|
|
1285
|
+
outputPer1m: 2.5,
|
|
1286
|
+
cachedInputPer1m: 0.03,
|
|
1287
|
+
reasoningOutputPer1m: 2.5
|
|
1288
|
+
}
|
|
1289
|
+
],
|
|
1290
|
+
contextWindow: 1048576
|
|
1291
|
+
},
|
|
1292
|
+
{
|
|
1293
|
+
model: "gemini-2.5-flash-lite",
|
|
1294
|
+
provider: "gemini",
|
|
1295
|
+
modality: "text",
|
|
1296
|
+
currency: "USD",
|
|
1297
|
+
asOf: "2026-07-27",
|
|
1298
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-lite",
|
|
1299
|
+
provenance: "litellm-catalog",
|
|
1300
|
+
tiers: [
|
|
1301
|
+
{
|
|
1302
|
+
inputPer1m: 0.1,
|
|
1303
|
+
outputPer1m: 0.4,
|
|
1304
|
+
cachedInputPer1m: 0.01,
|
|
1305
|
+
reasoningOutputPer1m: 0.4
|
|
1306
|
+
}
|
|
1307
|
+
],
|
|
1308
|
+
contextWindow: 1048576
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
model: "gemini-2.0-flash",
|
|
1312
|
+
provider: "gemini",
|
|
1313
|
+
modality: "text",
|
|
1314
|
+
currency: "USD",
|
|
1315
|
+
asOf: "2026-07-27",
|
|
1316
|
+
source: "https://ai.google.dev/pricing#2_0flash",
|
|
1317
|
+
provenance: "litellm-catalog",
|
|
1318
|
+
tiers: [
|
|
1319
|
+
{
|
|
1320
|
+
inputPer1m: 0.1,
|
|
1321
|
+
outputPer1m: 0.4,
|
|
1322
|
+
cachedInputPer1m: 0.025
|
|
1323
|
+
}
|
|
1324
|
+
],
|
|
1325
|
+
contextWindow: 1048576,
|
|
1326
|
+
notes: "Gemini Developer API price. Vertex AI lists $0.15/$0.60 per 1M for the same model \u2014 see the vertex entry."
|
|
1327
|
+
},
|
|
1328
|
+
{
|
|
1329
|
+
model: "gemini-2.0-flash-lite",
|
|
1330
|
+
provider: "gemini",
|
|
1331
|
+
modality: "text",
|
|
1332
|
+
currency: "USD",
|
|
1333
|
+
asOf: "2026-07-27",
|
|
1334
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite",
|
|
1335
|
+
provenance: "litellm-catalog",
|
|
1336
|
+
tiers: [
|
|
1337
|
+
{
|
|
1338
|
+
inputPer1m: 0.075,
|
|
1339
|
+
outputPer1m: 0.3,
|
|
1340
|
+
cachedInputPer1m: 0.01875
|
|
1341
|
+
}
|
|
1342
|
+
],
|
|
1343
|
+
contextWindow: 1048576
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
model: "gemini-2.0-flash",
|
|
1347
|
+
provider: "vertex",
|
|
1348
|
+
modality: "text",
|
|
1349
|
+
currency: "USD",
|
|
1350
|
+
asOf: "2026-07-27",
|
|
1351
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1352
|
+
provenance: "vendor-pricing-page",
|
|
1353
|
+
tiers: [
|
|
1354
|
+
{
|
|
1355
|
+
inputPer1m: 0.15,
|
|
1356
|
+
outputPer1m: 0.6
|
|
1357
|
+
}
|
|
1358
|
+
],
|
|
1359
|
+
batchMultiplier: 0.5,
|
|
1360
|
+
notes: "Vertex AI lists $0.15/$0.60 per 1M; the Gemini Developer API lists $0.10/$0.40 for the same model."
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
model: "gemini-3.1-pro",
|
|
1364
|
+
provider: "vertex",
|
|
1365
|
+
aliases: [
|
|
1366
|
+
"gemini-3.1-pro-preview"
|
|
1367
|
+
],
|
|
1368
|
+
modality: "text",
|
|
1369
|
+
currency: "USD",
|
|
1370
|
+
asOf: "2026-07-27",
|
|
1371
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1372
|
+
provenance: "vendor-pricing-page",
|
|
1373
|
+
tiers: [
|
|
1374
|
+
{
|
|
1375
|
+
maxInputTokens: 2e5,
|
|
1376
|
+
inputPer1m: 2,
|
|
1377
|
+
outputPer1m: 12,
|
|
1378
|
+
cachedInputPer1m: 0.2,
|
|
1379
|
+
reasoningOutputPer1m: 12
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
inputPer1m: 4,
|
|
1383
|
+
outputPer1m: 18,
|
|
1384
|
+
cachedInputPer1m: 0.4,
|
|
1385
|
+
reasoningOutputPer1m: 18
|
|
1386
|
+
}
|
|
1387
|
+
],
|
|
1388
|
+
batchMultiplier: 0.5,
|
|
1389
|
+
contextWindow: 1048576
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
model: "gemini-3.6-flash",
|
|
1393
|
+
provider: "vertex",
|
|
1394
|
+
modality: "text",
|
|
1395
|
+
currency: "USD",
|
|
1396
|
+
asOf: "2026-07-27",
|
|
1397
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1398
|
+
provenance: "vendor-pricing-page",
|
|
1399
|
+
tiers: [
|
|
1400
|
+
{
|
|
1401
|
+
inputPer1m: 1.5,
|
|
1402
|
+
outputPer1m: 7.5,
|
|
1403
|
+
cachedInputPer1m: 0.15,
|
|
1404
|
+
reasoningOutputPer1m: 7.5
|
|
1405
|
+
}
|
|
1406
|
+
],
|
|
1407
|
+
batchMultiplier: 0.5,
|
|
1408
|
+
contextWindow: 1048576
|
|
1409
|
+
},
|
|
1410
|
+
{
|
|
1411
|
+
model: "gemini-2.5-pro",
|
|
1412
|
+
provider: "vertex",
|
|
1413
|
+
modality: "text",
|
|
1414
|
+
currency: "USD",
|
|
1415
|
+
asOf: "2026-07-27",
|
|
1416
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1417
|
+
provenance: "vendor-pricing-page",
|
|
1418
|
+
tiers: [
|
|
1419
|
+
{
|
|
1420
|
+
maxInputTokens: 2e5,
|
|
1421
|
+
inputPer1m: 1.25,
|
|
1422
|
+
outputPer1m: 10,
|
|
1423
|
+
cachedInputPer1m: 0.13
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
inputPer1m: 2.5,
|
|
1427
|
+
outputPer1m: 15,
|
|
1428
|
+
cachedInputPer1m: 0.25
|
|
1429
|
+
}
|
|
1430
|
+
],
|
|
1431
|
+
batchMultiplier: 0.5,
|
|
1432
|
+
contextWindow: 1048576
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
model: "gemini-2.5-flash",
|
|
1436
|
+
provider: "vertex",
|
|
1437
|
+
modality: "text",
|
|
1438
|
+
currency: "USD",
|
|
1439
|
+
asOf: "2026-07-27",
|
|
1440
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1441
|
+
provenance: "vendor-pricing-page",
|
|
1442
|
+
tiers: [
|
|
1443
|
+
{
|
|
1444
|
+
inputPer1m: 0.3,
|
|
1445
|
+
outputPer1m: 2.5,
|
|
1446
|
+
cachedInputPer1m: 0.03,
|
|
1447
|
+
reasoningOutputPer1m: 2.5
|
|
1448
|
+
}
|
|
1449
|
+
],
|
|
1450
|
+
batchMultiplier: 0.5,
|
|
1451
|
+
contextWindow: 1048576
|
|
1452
|
+
},
|
|
1453
|
+
{
|
|
1454
|
+
model: "claude-sonnet-4-6",
|
|
1455
|
+
provider: "openrouter",
|
|
1456
|
+
modality: "text",
|
|
1457
|
+
currency: "USD",
|
|
1458
|
+
asOf: "2026-07-27",
|
|
1459
|
+
source: "https://openrouter.ai/anthropic/claude-sonnet-4.6",
|
|
1460
|
+
provenance: "litellm-catalog",
|
|
1461
|
+
tiers: [
|
|
1462
|
+
{
|
|
1463
|
+
maxInputTokens: 2e5,
|
|
1464
|
+
inputPer1m: 3,
|
|
1465
|
+
outputPer1m: 15,
|
|
1466
|
+
cachedInputPer1m: 0.3,
|
|
1467
|
+
cacheWritePer1m: 3.75
|
|
1468
|
+
},
|
|
1469
|
+
{
|
|
1470
|
+
inputPer1m: 6,
|
|
1471
|
+
outputPer1m: 22.5,
|
|
1472
|
+
cachedInputPer1m: 0.6,
|
|
1473
|
+
cacheWritePer1m: 7.5
|
|
1474
|
+
}
|
|
1475
|
+
],
|
|
1476
|
+
contextWindow: 1e6
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
model: "claude-haiku-4-5",
|
|
1480
|
+
provider: "openrouter",
|
|
1481
|
+
modality: "text",
|
|
1482
|
+
currency: "USD",
|
|
1483
|
+
asOf: "2026-07-27",
|
|
1484
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1485
|
+
provenance: "litellm-catalog",
|
|
1486
|
+
tiers: [
|
|
1487
|
+
{
|
|
1488
|
+
inputPer1m: 1,
|
|
1489
|
+
outputPer1m: 5,
|
|
1490
|
+
cachedInputPer1m: 0.1,
|
|
1491
|
+
cacheWritePer1m: 1.25
|
|
1492
|
+
}
|
|
1493
|
+
],
|
|
1494
|
+
contextWindow: 2e5
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
model: "gpt-5",
|
|
1498
|
+
provider: "openrouter",
|
|
1499
|
+
modality: "text",
|
|
1500
|
+
currency: "USD",
|
|
1501
|
+
asOf: "2026-07-27",
|
|
1502
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1503
|
+
provenance: "litellm-catalog",
|
|
1504
|
+
tiers: [
|
|
1505
|
+
{
|
|
1506
|
+
inputPer1m: 1.25,
|
|
1507
|
+
outputPer1m: 10,
|
|
1508
|
+
cachedInputPer1m: 0.125
|
|
1509
|
+
}
|
|
1510
|
+
],
|
|
1511
|
+
contextWindow: 272e3
|
|
1512
|
+
},
|
|
1513
|
+
{
|
|
1514
|
+
model: "gpt-5-mini",
|
|
1515
|
+
provider: "openrouter",
|
|
1516
|
+
modality: "text",
|
|
1517
|
+
currency: "USD",
|
|
1518
|
+
asOf: "2026-07-27",
|
|
1519
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1520
|
+
provenance: "litellm-catalog",
|
|
1521
|
+
tiers: [
|
|
1522
|
+
{
|
|
1523
|
+
inputPer1m: 0.25,
|
|
1524
|
+
outputPer1m: 2,
|
|
1525
|
+
cachedInputPer1m: 0.025
|
|
1526
|
+
}
|
|
1527
|
+
],
|
|
1528
|
+
contextWindow: 272e3
|
|
1529
|
+
},
|
|
1530
|
+
{
|
|
1531
|
+
model: "gemini-3.1-pro",
|
|
1532
|
+
provider: "openrouter",
|
|
1533
|
+
aliases: [
|
|
1534
|
+
"gemini-3.1-pro-preview"
|
|
1535
|
+
],
|
|
1536
|
+
modality: "text",
|
|
1537
|
+
currency: "USD",
|
|
1538
|
+
asOf: "2026-07-27",
|
|
1539
|
+
source: "https://openrouter.ai/google/gemini-3.1-pro-preview",
|
|
1540
|
+
provenance: "litellm-catalog",
|
|
1541
|
+
tiers: [
|
|
1542
|
+
{
|
|
1543
|
+
maxInputTokens: 2e5,
|
|
1544
|
+
inputPer1m: 2,
|
|
1545
|
+
outputPer1m: 12,
|
|
1546
|
+
cachedInputPer1m: 0.2
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
inputPer1m: 4,
|
|
1550
|
+
outputPer1m: 18,
|
|
1551
|
+
cachedInputPer1m: 0.4,
|
|
1552
|
+
cacheWritePer1m: 0.25
|
|
1553
|
+
}
|
|
1554
|
+
],
|
|
1555
|
+
contextWindow: 1048576
|
|
1556
|
+
},
|
|
1557
|
+
{
|
|
1558
|
+
model: "text-embedding-3-small",
|
|
1559
|
+
provider: "openai",
|
|
1560
|
+
modality: "embedding",
|
|
1561
|
+
currency: "USD",
|
|
1562
|
+
asOf: "2026-07-27",
|
|
1563
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1564
|
+
provenance: "litellm-catalog",
|
|
1565
|
+
tiers: [
|
|
1566
|
+
{
|
|
1567
|
+
inputPer1m: 0.02,
|
|
1568
|
+
outputPer1m: 0
|
|
1569
|
+
}
|
|
1570
|
+
],
|
|
1571
|
+
batchMultiplier: 0.5,
|
|
1572
|
+
contextWindow: 8191
|
|
1573
|
+
},
|
|
1574
|
+
{
|
|
1575
|
+
model: "text-embedding-3-large",
|
|
1576
|
+
provider: "openai",
|
|
1577
|
+
modality: "embedding",
|
|
1578
|
+
currency: "USD",
|
|
1579
|
+
asOf: "2026-07-27",
|
|
1580
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1581
|
+
provenance: "litellm-catalog",
|
|
1582
|
+
tiers: [
|
|
1583
|
+
{
|
|
1584
|
+
inputPer1m: 0.13,
|
|
1585
|
+
outputPer1m: 0
|
|
1586
|
+
}
|
|
1587
|
+
],
|
|
1588
|
+
batchMultiplier: 0.5,
|
|
1589
|
+
contextWindow: 8191
|
|
1590
|
+
},
|
|
1591
|
+
{
|
|
1592
|
+
model: "gemini-embedding-001",
|
|
1593
|
+
provider: "gemini",
|
|
1594
|
+
modality: "embedding",
|
|
1595
|
+
currency: "USD",
|
|
1596
|
+
asOf: "2026-07-27",
|
|
1597
|
+
source: "https://ai.google.dev/gemini-api/docs/embeddings#model-versions",
|
|
1598
|
+
provenance: "litellm-catalog",
|
|
1599
|
+
tiers: [
|
|
1600
|
+
{
|
|
1601
|
+
inputPer1m: 0.15,
|
|
1602
|
+
outputPer1m: 0
|
|
1603
|
+
}
|
|
1604
|
+
],
|
|
1605
|
+
contextWindow: 2048
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
model: "dall-e-3",
|
|
1609
|
+
provider: "openai",
|
|
1610
|
+
modality: "image",
|
|
1611
|
+
currency: "USD",
|
|
1612
|
+
asOf: "2026-07-27",
|
|
1613
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1614
|
+
provenance: "litellm-catalog",
|
|
1615
|
+
rates: [
|
|
1616
|
+
{
|
|
1617
|
+
unit: "per_image",
|
|
1618
|
+
amount: 0.04,
|
|
1619
|
+
variant: "1024x1024 standard"
|
|
1620
|
+
}
|
|
1621
|
+
]
|
|
1622
|
+
},
|
|
1623
|
+
{
|
|
1624
|
+
model: "gemini-3-pro-image",
|
|
1625
|
+
provider: "gemini",
|
|
1626
|
+
modality: "image",
|
|
1627
|
+
currency: "USD",
|
|
1628
|
+
asOf: "2026-07-27",
|
|
1629
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1630
|
+
provenance: "litellm-catalog",
|
|
1631
|
+
rates: [
|
|
1632
|
+
{
|
|
1633
|
+
unit: "per_image",
|
|
1634
|
+
amount: 0.134,
|
|
1635
|
+
variant: "default output resolution"
|
|
1636
|
+
}
|
|
1637
|
+
],
|
|
1638
|
+
notes: "Google bills image output per output-token ($120 per 1M image output tokens); $0.134/image is that rate applied to one default-resolution image. Cost per image therefore varies with resolution."
|
|
1639
|
+
},
|
|
1640
|
+
{
|
|
1641
|
+
model: "imagen-4.0-generate-001",
|
|
1642
|
+
provider: "vertex",
|
|
1643
|
+
modality: "image",
|
|
1644
|
+
currency: "USD",
|
|
1645
|
+
asOf: "2026-07-27",
|
|
1646
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1647
|
+
provenance: "litellm-catalog",
|
|
1648
|
+
rates: [
|
|
1649
|
+
{
|
|
1650
|
+
unit: "per_image",
|
|
1651
|
+
amount: 0.04
|
|
1652
|
+
}
|
|
1653
|
+
]
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
model: "veo-3.1-generate-001",
|
|
1657
|
+
provider: "gemini",
|
|
1658
|
+
modality: "video",
|
|
1659
|
+
currency: "USD",
|
|
1660
|
+
asOf: "2026-07-27",
|
|
1661
|
+
source: "https://ai.google.dev/gemini-api/docs/video",
|
|
1662
|
+
provenance: "litellm-catalog",
|
|
1663
|
+
rates: [
|
|
1664
|
+
{
|
|
1665
|
+
unit: "per_second",
|
|
1666
|
+
amount: 0.4
|
|
1667
|
+
}
|
|
1668
|
+
]
|
|
1669
|
+
},
|
|
1670
|
+
{
|
|
1671
|
+
model: "veo-3.1-generate-001",
|
|
1672
|
+
provider: "vertex",
|
|
1673
|
+
modality: "video",
|
|
1674
|
+
currency: "USD",
|
|
1675
|
+
asOf: "2026-07-27",
|
|
1676
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo",
|
|
1677
|
+
provenance: "litellm-catalog",
|
|
1678
|
+
rates: [
|
|
1679
|
+
{
|
|
1680
|
+
unit: "per_second",
|
|
1681
|
+
amount: 0.4
|
|
1682
|
+
}
|
|
1683
|
+
]
|
|
1684
|
+
},
|
|
1685
|
+
{
|
|
1686
|
+
model: "tts-1",
|
|
1687
|
+
provider: "openai",
|
|
1688
|
+
modality: "speech",
|
|
1689
|
+
currency: "USD",
|
|
1690
|
+
asOf: "2026-07-27",
|
|
1691
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1692
|
+
provenance: "litellm-catalog",
|
|
1693
|
+
rates: [
|
|
1694
|
+
{
|
|
1695
|
+
unit: "per_character",
|
|
1696
|
+
amount: 15e-6
|
|
1697
|
+
}
|
|
1698
|
+
],
|
|
1699
|
+
notes: "$15 per 1M characters."
|
|
1700
|
+
},
|
|
1701
|
+
{
|
|
1702
|
+
model: "tts-1-hd",
|
|
1703
|
+
provider: "openai",
|
|
1704
|
+
modality: "speech",
|
|
1705
|
+
currency: "USD",
|
|
1706
|
+
asOf: "2026-07-27",
|
|
1707
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1708
|
+
provenance: "litellm-catalog",
|
|
1709
|
+
rates: [
|
|
1710
|
+
{
|
|
1711
|
+
unit: "per_character",
|
|
1712
|
+
amount: 3e-5
|
|
1713
|
+
}
|
|
1714
|
+
],
|
|
1715
|
+
notes: "$30 per 1M characters."
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
model: "whisper-1",
|
|
1719
|
+
provider: "openai",
|
|
1720
|
+
modality: "transcription",
|
|
1721
|
+
currency: "USD",
|
|
1722
|
+
asOf: "2026-07-27",
|
|
1723
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1724
|
+
provenance: "litellm-catalog",
|
|
1725
|
+
rates: [
|
|
1726
|
+
{
|
|
1727
|
+
unit: "per_audio_minute",
|
|
1728
|
+
amount: 6e-3
|
|
1729
|
+
}
|
|
1730
|
+
],
|
|
1731
|
+
notes: "litellm records $0.0001 per audio second; $0.006/minute is that rate x 60."
|
|
1732
|
+
}
|
|
1733
|
+
]
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
// src/core/router/pricing.ts
|
|
1737
|
+
var DATASET = pricing_data_default;
|
|
1738
|
+
function normalizeForPricing(id) {
|
|
1739
|
+
let s = id.trim().toLowerCase();
|
|
1740
|
+
s = s.replace(/^models\//, "");
|
|
1741
|
+
const slash = s.lastIndexOf("/");
|
|
1742
|
+
if (slash !== -1) s = s.slice(slash + 1);
|
|
1743
|
+
const tag = s.search(/[:@]/);
|
|
1744
|
+
if (tag !== -1) s = s.slice(0, tag);
|
|
1745
|
+
s = s.replace(/-latest$/, "");
|
|
1746
|
+
s = s.replace(/-preview(?:-\d{2}-\d{2})?$/, "");
|
|
1747
|
+
s = s.replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
1748
|
+
s = s.replace(/-\d{8}$/, "");
|
|
1749
|
+
s = s.replace(/-preview$/, "");
|
|
1750
|
+
return s;
|
|
1751
|
+
}
|
|
1752
|
+
function indexKey(model, provider, region) {
|
|
1753
|
+
return `${provider}|${normalizeForPricing(model)}|${region ?? ""}`;
|
|
1754
|
+
}
|
|
1755
|
+
var INDEX = /* @__PURE__ */ new Map();
|
|
1756
|
+
for (const entry of DATASET.entries) {
|
|
1757
|
+
for (const name of [entry.model, ...entry.aliases ?? []]) {
|
|
1758
|
+
const withRegion = indexKey(name, entry.provider, entry.region);
|
|
1759
|
+
if (!INDEX.has(withRegion)) INDEX.set(withRegion, entry);
|
|
1760
|
+
const bare = indexKey(name, entry.provider);
|
|
1761
|
+
const existing = INDEX.get(bare);
|
|
1762
|
+
if (!existing || existing.region && existing.region !== "global" && entry.region === "global") {
|
|
1763
|
+
INDEX.set(bare, entry);
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
function findPricing(modelId, provider, opts = {}) {
|
|
1768
|
+
const ids = [modelId, opts.baseModelId].filter((x) => !!x);
|
|
1769
|
+
const providers = [provider, ...opts.fallbackProviders ?? []];
|
|
1770
|
+
for (const p of providers) {
|
|
1771
|
+
for (const id of ids) {
|
|
1772
|
+
const hit = (opts.region ? INDEX.get(indexKey(id, p, opts.region)) : void 0) ?? INDEX.get(indexKey(id, p));
|
|
1773
|
+
if (hit) return { entry: hit, matchedProvider: p, viaFallback: p !== provider };
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
return null;
|
|
1777
|
+
}
|
|
1778
|
+
function tierFor(entry, inputTokens = 0) {
|
|
1779
|
+
const tiers = entry.tiers;
|
|
1780
|
+
if (!tiers?.length) return null;
|
|
1781
|
+
for (const t of tiers) {
|
|
1782
|
+
if (t.maxInputTokens === void 0 || inputTokens <= t.maxInputTokens) return t;
|
|
1783
|
+
}
|
|
1784
|
+
return tiers[tiers.length - 1] ?? null;
|
|
1785
|
+
}
|
|
1786
|
+
var PER_1M_TO_PER_1K = 1 / 1e3;
|
|
1787
|
+
function tokenRatesPer1k(entry, opts = {}) {
|
|
1788
|
+
const tier = tierFor(entry, opts.inputTokens ?? 0);
|
|
1789
|
+
if (!tier) return null;
|
|
1790
|
+
const mult = (opts.batch ? entry.batchMultiplier ?? 1 : 1) * PER_1M_TO_PER_1K;
|
|
1791
|
+
const out = {
|
|
1792
|
+
input: tier.inputPer1m * mult,
|
|
1793
|
+
output: tier.outputPer1m * mult
|
|
1794
|
+
};
|
|
1795
|
+
if (tier.cachedInputPer1m !== void 0) out.cachedInput = tier.cachedInputPer1m * mult;
|
|
1796
|
+
if (tier.cacheWritePer1m !== void 0) out.cacheWrite = tier.cacheWritePer1m * mult;
|
|
1797
|
+
if (tier.reasoningOutputPer1m !== void 0) out.reasoningOutput = tier.reasoningOutputPer1m * mult;
|
|
1798
|
+
return out;
|
|
1799
|
+
}
|
|
1800
|
+
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"]);
|
|
1801
|
+
function isLoopbackOrPrivateHost(url) {
|
|
1802
|
+
if (!url) return false;
|
|
1803
|
+
try {
|
|
1804
|
+
const host = new URL(url).hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
1805
|
+
if (LOOPBACK_HOSTS.has(host) || LOOPBACK_HOSTS.has(`[${host}]`)) return true;
|
|
1806
|
+
if (host.endsWith(".local")) return true;
|
|
1807
|
+
if (/^127\./.test(host)) return true;
|
|
1808
|
+
if (/^10\./.test(host)) return true;
|
|
1809
|
+
if (/^192\.168\./.test(host)) return true;
|
|
1810
|
+
if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true;
|
|
1811
|
+
return false;
|
|
1812
|
+
} catch {
|
|
1813
|
+
return false;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
function isLocalEndpoint(cfg) {
|
|
1817
|
+
if (typeof cfg.local === "boolean") return cfg.local;
|
|
1818
|
+
if (cfg.type === "ollama") return true;
|
|
1819
|
+
if (cfg.type === "openai-compatible") return isLoopbackOrPrivateHost(cfg.baseUrl);
|
|
1820
|
+
return false;
|
|
1821
|
+
}
|
|
1822
|
+
var UNKNOWN = { input: 0, output: 0, unknown: true, free: false };
|
|
1823
|
+
var FREE = { input: 0, output: 0, unknown: false, free: true };
|
|
1824
|
+
function resolvePricing(model, opts = {}) {
|
|
1825
|
+
if (model.isLocal) return FREE;
|
|
1826
|
+
const fallbackProviders = model.provider === "azure" ? ["openai"] : model.provider === "gemini" ? ["vertex"] : [];
|
|
1827
|
+
const match = findPricing(model.id, model.provider, {
|
|
1828
|
+
region: opts.region,
|
|
1829
|
+
baseModelId: model.baseModelId,
|
|
1830
|
+
fallbackProviders
|
|
1831
|
+
});
|
|
1832
|
+
if (!match) return UNKNOWN;
|
|
1833
|
+
const rates = tokenRatesPer1k(match.entry, { inputTokens: opts.inputTokens, batch: opts.batch });
|
|
1834
|
+
if (!rates) return UNKNOWN;
|
|
1835
|
+
return {
|
|
1836
|
+
input: rates.input,
|
|
1837
|
+
output: rates.output,
|
|
1838
|
+
unknown: false,
|
|
1839
|
+
free: false,
|
|
1840
|
+
entry: match.entry,
|
|
1841
|
+
...match.viaFallback ? { estimatedFromProvider: match.matchedProvider } : {}
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
function withResolvedPricing(model, opts = {}) {
|
|
1845
|
+
const p = resolvePricing(model, opts);
|
|
1846
|
+
return {
|
|
1847
|
+
...model,
|
|
1848
|
+
inputCostPer1kTokens: p.input,
|
|
1849
|
+
outputCostPer1kTokens: p.output,
|
|
1850
|
+
...p.unknown ? { pricingUnknown: true } : { pricingUnknown: false }
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
function isPricingUnknown(model) {
|
|
1854
|
+
return model.pricingUnknown === true && !model.isLocal;
|
|
1855
|
+
}
|
|
1856
|
+
var BLENDED_COST_CEILING = 0.05;
|
|
1857
|
+
function blendedCostPer1k(model) {
|
|
1858
|
+
if (isPricingUnknown(model)) return BLENDED_COST_CEILING;
|
|
1859
|
+
return model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
|
|
1860
|
+
}
|
|
1861
|
+
var DISAGREEMENT_THRESHOLD = 0.02;
|
|
1862
|
+
function reconcilePrice(model, live) {
|
|
1863
|
+
const baseline = resolvePricing(model);
|
|
1864
|
+
const liveIsZero = !(live.input > 0) && !(live.output > 0);
|
|
1865
|
+
if (liveIsZero && !model.isLocal) {
|
|
1866
|
+
return { input: baseline.input, output: baseline.output, accepted: false };
|
|
1867
|
+
}
|
|
1868
|
+
if (baseline.unknown || !baseline.entry) {
|
|
1869
|
+
return { input: live.input, output: live.output, accepted: true };
|
|
1870
|
+
}
|
|
1871
|
+
const dsBlend = baseline.input + baseline.output * 2;
|
|
1872
|
+
const liveBlend = live.input + live.output * 2;
|
|
1873
|
+
const ratio = dsBlend > 0 ? liveBlend / dsBlend : Number.POSITIVE_INFINITY;
|
|
1874
|
+
const material = dsBlend > 0 && Math.abs(ratio - 1) > DISAGREEMENT_THRESHOLD;
|
|
1875
|
+
return {
|
|
1876
|
+
input: live.input,
|
|
1877
|
+
output: live.output,
|
|
1878
|
+
accepted: true,
|
|
1879
|
+
...material ? {
|
|
1880
|
+
disagreement: {
|
|
1881
|
+
modelId: model.id,
|
|
1882
|
+
provider: model.provider,
|
|
1883
|
+
dataset: { input: baseline.input, output: baseline.output },
|
|
1884
|
+
live: { input: live.input, output: live.output },
|
|
1885
|
+
ratio: Math.round(ratio * 1e3) / 1e3,
|
|
1886
|
+
datasetAsOf: baseline.entry.asOf,
|
|
1887
|
+
datasetSource: baseline.entry.source
|
|
1888
|
+
}
|
|
1889
|
+
} : {}
|
|
1890
|
+
};
|
|
1891
|
+
}
|
|
1892
|
+
|
|
241
1893
|
// src/constants.ts
|
|
242
|
-
var CASCADE_VERSION = "0.
|
|
1894
|
+
var CASCADE_VERSION = "0.49.0";
|
|
243
1895
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
244
1896
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
245
1897
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -588,6 +2240,13 @@ var MODELS = {
|
|
|
588
2240
|
for (const _m of Object.values(MODELS)) {
|
|
589
2241
|
if (_m.supportsToolUse === void 0) _m.supportsToolUse = !_m.isLocal;
|
|
590
2242
|
}
|
|
2243
|
+
for (const _m of Object.values(MODELS)) {
|
|
2244
|
+
const priced = resolvePricing(_m);
|
|
2245
|
+
if (priced.unknown || priced.free || priced.estimatedFromProvider) continue;
|
|
2246
|
+
_m.inputCostPer1kTokens = priced.input;
|
|
2247
|
+
_m.outputCostPer1kTokens = priced.output;
|
|
2248
|
+
_m.pricingUnknown = false;
|
|
2249
|
+
}
|
|
591
2250
|
var T1_MODEL_PRIORITY = [
|
|
592
2251
|
"gpt-5.5",
|
|
593
2252
|
"gpt-5.4",
|
|
@@ -678,21 +2337,49 @@ var PROVIDER_DISPLAY_NAMES = {
|
|
|
678
2337
|
|
|
679
2338
|
// src/utils/cost.ts
|
|
680
2339
|
function resolveModelPricing(model) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
2340
|
+
if (model.isLocal) return { input: 0, output: 0, unknown: false };
|
|
2341
|
+
if (model.inputCostPer1kTokens > 0 || model.outputCostPer1kTokens > 0) {
|
|
2342
|
+
return {
|
|
2343
|
+
input: model.inputCostPer1kTokens,
|
|
2344
|
+
output: model.outputCostPer1kTokens,
|
|
2345
|
+
unknown: false
|
|
2346
|
+
};
|
|
2347
|
+
}
|
|
2348
|
+
const fromDataset = resolvePricing(model);
|
|
2349
|
+
if (!fromDataset.unknown) {
|
|
2350
|
+
return {
|
|
2351
|
+
input: fromDataset.input,
|
|
2352
|
+
output: fromDataset.output,
|
|
2353
|
+
unknown: false,
|
|
2354
|
+
...fromDataset.estimatedFromProvider ? { estimatedFromProvider: fromDataset.estimatedFromProvider } : {}
|
|
2355
|
+
};
|
|
2356
|
+
}
|
|
2357
|
+
if (model.id) {
|
|
684
2358
|
const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
|
|
685
|
-
if (known) {
|
|
686
|
-
|
|
687
|
-
|
|
2359
|
+
if (known && (known.inputCostPer1kTokens > 0 || known.outputCostPer1kTokens > 0)) {
|
|
2360
|
+
return {
|
|
2361
|
+
input: known.inputCostPer1kTokens,
|
|
2362
|
+
output: known.outputCostPer1kTokens,
|
|
2363
|
+
unknown: false
|
|
2364
|
+
};
|
|
688
2365
|
}
|
|
689
2366
|
}
|
|
690
|
-
return { input, output };
|
|
2367
|
+
return { input: 0, output: 0, unknown: true };
|
|
691
2368
|
}
|
|
692
2369
|
function calculateCost(inputTokens, outputTokens, model) {
|
|
693
2370
|
const { input, output } = resolveModelPricing(model);
|
|
694
2371
|
return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
|
|
695
2372
|
}
|
|
2373
|
+
function buildTokenUsage(inputTokens, outputTokens, model) {
|
|
2374
|
+
const { input, output, unknown } = resolveModelPricing(model);
|
|
2375
|
+
return {
|
|
2376
|
+
inputTokens,
|
|
2377
|
+
outputTokens,
|
|
2378
|
+
totalTokens: inputTokens + outputTokens,
|
|
2379
|
+
estimatedCostUsd: inputTokens / 1e3 * input + outputTokens / 1e3 * output,
|
|
2380
|
+
...unknown ? { costUnknown: true } : {}
|
|
2381
|
+
};
|
|
2382
|
+
}
|
|
696
2383
|
|
|
697
2384
|
// src/providers/base.ts
|
|
698
2385
|
var BaseProvider = class {
|
|
@@ -712,12 +2399,7 @@ var BaseProvider = class {
|
|
|
712
2399
|
return calculateCost(inputTokens, outputTokens, this.model);
|
|
713
2400
|
}
|
|
714
2401
|
makeUsage(inputTokens, outputTokens) {
|
|
715
|
-
return
|
|
716
|
-
inputTokens,
|
|
717
|
-
outputTokens,
|
|
718
|
-
totalTokens: inputTokens + outputTokens,
|
|
719
|
-
estimatedCostUsd: this.estimateCost(inputTokens, outputTokens)
|
|
720
|
-
};
|
|
2402
|
+
return buildTokenUsage(inputTokens, outputTokens, this.model);
|
|
721
2403
|
}
|
|
722
2404
|
};
|
|
723
2405
|
|
|
@@ -886,7 +2568,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
886
2568
|
return data.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
887
2569
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "anthropic");
|
|
888
2570
|
if (known) return known;
|
|
889
|
-
return {
|
|
2571
|
+
return withResolvedPricing({
|
|
890
2572
|
id: m.id,
|
|
891
2573
|
name: m.display_name || m.id,
|
|
892
2574
|
provider: "anthropic",
|
|
@@ -897,7 +2579,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
897
2579
|
maxOutputTokens: 8e3,
|
|
898
2580
|
supportsStreaming: true,
|
|
899
2581
|
isLocal: false
|
|
900
|
-
};
|
|
2582
|
+
});
|
|
901
2583
|
});
|
|
902
2584
|
} catch {
|
|
903
2585
|
return Object.values(MODELS).filter((m) => m.provider === "anthropic");
|
|
@@ -1101,7 +2783,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
1101
2783
|
return response.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
1102
2784
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "openai");
|
|
1103
2785
|
if (known) return known;
|
|
1104
|
-
return {
|
|
2786
|
+
return withResolvedPricing({
|
|
1105
2787
|
id: m.id,
|
|
1106
2788
|
name: m.id,
|
|
1107
2789
|
provider: "openai",
|
|
@@ -1112,7 +2794,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
1112
2794
|
maxOutputTokens: 4e3,
|
|
1113
2795
|
supportsStreaming: true,
|
|
1114
2796
|
isLocal: false
|
|
1115
|
-
};
|
|
2797
|
+
});
|
|
1116
2798
|
});
|
|
1117
2799
|
} catch {
|
|
1118
2800
|
return Object.values(MODELS).filter((m) => m.provider === "openai");
|
|
@@ -1208,6 +2890,10 @@ function azureModelForDeployment(cfg) {
|
|
|
1208
2890
|
const baseModelId = cfg.model?.trim() || inferAzureBaseModel(id) || void 0;
|
|
1209
2891
|
const base = baseModelId ? MODELS[baseModelId] : void 0;
|
|
1210
2892
|
if (base) {
|
|
2893
|
+
const azurePrice = resolvePricing(
|
|
2894
|
+
{ id, provider: "azure", isLocal: false, baseModelId },
|
|
2895
|
+
{ region: cfg.region }
|
|
2896
|
+
);
|
|
1211
2897
|
return {
|
|
1212
2898
|
...base,
|
|
1213
2899
|
id,
|
|
@@ -1216,7 +2902,12 @@ function azureModelForDeployment(cfg) {
|
|
|
1216
2902
|
provider: "azure",
|
|
1217
2903
|
baseModelId,
|
|
1218
2904
|
// real identity for benchmark + live pricing
|
|
1219
|
-
supportsToolUse: base.supportsToolUse ?? true
|
|
2905
|
+
supportsToolUse: base.supportsToolUse ?? true,
|
|
2906
|
+
...azurePrice.unknown ? {} : {
|
|
2907
|
+
inputCostPer1kTokens: azurePrice.input,
|
|
2908
|
+
outputCostPer1kTokens: azurePrice.output,
|
|
2909
|
+
pricingUnknown: false
|
|
2910
|
+
}
|
|
1220
2911
|
};
|
|
1221
2912
|
}
|
|
1222
2913
|
return {
|
|
@@ -1379,7 +3070,7 @@ var GeminiProvider = class extends BaseProvider {
|
|
|
1379
3070
|
(km) => km.id === id && km.provider === "gemini"
|
|
1380
3071
|
);
|
|
1381
3072
|
if (known) return known;
|
|
1382
|
-
return {
|
|
3073
|
+
return withResolvedPricing({
|
|
1383
3074
|
id,
|
|
1384
3075
|
name: m.displayName || id,
|
|
1385
3076
|
provider: "gemini",
|
|
@@ -1390,7 +3081,7 @@ var GeminiProvider = class extends BaseProvider {
|
|
|
1390
3081
|
maxOutputTokens: m.outputTokenLimit || 8e3,
|
|
1391
3082
|
supportsStreaming: true,
|
|
1392
3083
|
isLocal: false
|
|
1393
|
-
};
|
|
3084
|
+
});
|
|
1394
3085
|
});
|
|
1395
3086
|
} catch {
|
|
1396
3087
|
return Object.values(MODELS).filter((m) => m.provider === "gemini");
|
|
@@ -1737,9 +3428,10 @@ var OllamaProvider = class extends BaseProvider {
|
|
|
1737
3428
|
return supportedKeywords.some((k) => name.includes(k)) && isChatModel(name);
|
|
1738
3429
|
});
|
|
1739
3430
|
const shows = await Promise.all(entries.map((m) => this.showModel(m.name)));
|
|
3431
|
+
const local = isLocalEndpoint({ ...this.config, type: "ollama" });
|
|
1740
3432
|
return entries.map((m, i) => {
|
|
1741
3433
|
const show = shows[i];
|
|
1742
|
-
return {
|
|
3434
|
+
return withResolvedPricing({
|
|
1743
3435
|
id: m.name,
|
|
1744
3436
|
name: m.name,
|
|
1745
3437
|
provider: "ollama",
|
|
@@ -1749,10 +3441,10 @@ var OllamaProvider = class extends BaseProvider {
|
|
|
1749
3441
|
outputCostPer1kTokens: 0,
|
|
1750
3442
|
maxOutputTokens: 4e3,
|
|
1751
3443
|
supportsStreaming: true,
|
|
1752
|
-
isLocal:
|
|
3444
|
+
isLocal: local,
|
|
1753
3445
|
supportsToolUse: show?.tools ?? isToolCapable(m.name),
|
|
1754
3446
|
minSizeB: this.parseSizeB(m.details?.parameter_size)
|
|
1755
|
-
};
|
|
3447
|
+
});
|
|
1756
3448
|
});
|
|
1757
3449
|
} catch {
|
|
1758
3450
|
return [];
|
|
@@ -1855,7 +3547,8 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
|
1855
3547
|
}).filter((x) => typeof x === "string" && x.length > 0);
|
|
1856
3548
|
if (ids.length === 0) return [this.model];
|
|
1857
3549
|
const chatIds = ids.filter((id) => isChatModel(id));
|
|
1858
|
-
|
|
3550
|
+
const local = isLocalEndpoint(this.config);
|
|
3551
|
+
return (chatIds.length ? chatIds : ids).map((id) => withResolvedPricing({
|
|
1859
3552
|
id,
|
|
1860
3553
|
name: id,
|
|
1861
3554
|
provider: "openai-compatible",
|
|
@@ -1865,7 +3558,7 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
|
1865
3558
|
outputCostPer1kTokens: 0,
|
|
1866
3559
|
maxOutputTokens: 4e3,
|
|
1867
3560
|
supportsStreaming: true,
|
|
1868
|
-
isLocal:
|
|
3561
|
+
isLocal: local
|
|
1869
3562
|
}));
|
|
1870
3563
|
}
|
|
1871
3564
|
async isAvailable() {
|
|
@@ -2080,7 +3773,7 @@ var ModelSelector = class {
|
|
|
2080
3773
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
2081
3774
|
}
|
|
2082
3775
|
if (providerStr && this.availableProviders.has(providerStr)) {
|
|
2083
|
-
const dynamicModel = {
|
|
3776
|
+
const dynamicModel = withResolvedPricing({
|
|
2084
3777
|
id: actualId,
|
|
2085
3778
|
name: actualId,
|
|
2086
3779
|
provider: providerStr,
|
|
@@ -2091,7 +3784,7 @@ var ModelSelector = class {
|
|
|
2091
3784
|
maxOutputTokens: 8e3,
|
|
2092
3785
|
supportsStreaming: true,
|
|
2093
3786
|
isLocal: providerStr === "ollama"
|
|
2094
|
-
};
|
|
3787
|
+
});
|
|
2095
3788
|
this.addDynamicModel(dynamicModel);
|
|
2096
3789
|
return dynamicModel;
|
|
2097
3790
|
}
|
|
@@ -2483,6 +4176,8 @@ var LiveDataProvider = class {
|
|
|
2483
4176
|
snapshot = null;
|
|
2484
4177
|
prices = /* @__PURE__ */ new Map();
|
|
2485
4178
|
capabilities = /* @__PURE__ */ new Map();
|
|
4179
|
+
/** Dataset-vs-live price mismatches, deduped by `provider:modelId`. */
|
|
4180
|
+
disagreements = /* @__PURE__ */ new Map();
|
|
2486
4181
|
source = "bundled";
|
|
2487
4182
|
fetchedAt = 0;
|
|
2488
4183
|
loaded = false;
|
|
@@ -2636,14 +4331,45 @@ var LiveDataProvider = class {
|
|
|
2636
4331
|
/**
|
|
2637
4332
|
* Returns a price-corrected copy of each model when live pricing is known,
|
|
2638
4333
|
* leaving the original untouched (so the shared catalog is never mutated).
|
|
4334
|
+
*
|
|
4335
|
+
* Reconciliation policy (see reconcilePrice in pricing.ts): the bundled
|
|
4336
|
+
* dataset is the authoritative baseline, and a live quote overrides it
|
|
4337
|
+
* because it is fresher by construction — but the disagreement is RECORDED,
|
|
4338
|
+
* not swallowed. A dataset/live mismatch is the best signal available that
|
|
4339
|
+
* the committed prices have gone stale, so it must be visible rather than
|
|
4340
|
+
* silently resolved in either direction. A live quote of $0 for a non-local
|
|
4341
|
+
* model is rejected outright: that is the very failure mode this change
|
|
4342
|
+
* exists to prevent, and a marketplace's free-tier alias must never zero out
|
|
4343
|
+
* the price of the paid model Cascade is actually calling.
|
|
2639
4344
|
*/
|
|
2640
4345
|
applyLivePricing(models) {
|
|
2641
4346
|
return models.map((m) => {
|
|
2642
4347
|
const p = this.getLivePrice(m.baseModelId ?? m.id);
|
|
2643
4348
|
if (!p) return m;
|
|
2644
|
-
|
|
4349
|
+
const reconciled = reconcilePrice(m, p);
|
|
4350
|
+
if (reconciled.disagreement) this.recordDisagreement(reconciled.disagreement);
|
|
4351
|
+
if (!reconciled.accepted) return m;
|
|
4352
|
+
return {
|
|
4353
|
+
...m,
|
|
4354
|
+
inputCostPer1kTokens: reconciled.input,
|
|
4355
|
+
outputCostPer1kTokens: reconciled.output,
|
|
4356
|
+
pricingUnknown: false
|
|
4357
|
+
};
|
|
2645
4358
|
});
|
|
2646
4359
|
}
|
|
4360
|
+
recordDisagreement(d) {
|
|
4361
|
+
const key = `${d.provider}:${d.modelId}`;
|
|
4362
|
+
if (this.disagreements.has(key)) return;
|
|
4363
|
+
this.disagreements.set(key, d);
|
|
4364
|
+
}
|
|
4365
|
+
/**
|
|
4366
|
+
* Dataset-vs-live price mismatches seen this session, newest-model-first
|
|
4367
|
+
* insertion order. Surfaced by `cascade models --verbose`; a non-empty list
|
|
4368
|
+
* means src/core/router/pricing-data.json is probably due a refresh.
|
|
4369
|
+
*/
|
|
4370
|
+
getPriceDisagreements() {
|
|
4371
|
+
return [...this.disagreements.values()];
|
|
4372
|
+
}
|
|
2647
4373
|
/** Current capability facts for a model id, or null when unknown. */
|
|
2648
4374
|
getCapability(modelId) {
|
|
2649
4375
|
return this.capabilities.get(normalizeModelId2(modelId)) ?? null;
|
|
@@ -2840,7 +4566,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
2840
4566
|
tokensByTier: {},
|
|
2841
4567
|
inputTokensByTier: {},
|
|
2842
4568
|
outputTokensByTier: {},
|
|
2843
|
-
costByFeature: {}
|
|
4569
|
+
costByFeature: {},
|
|
4570
|
+
untrackedCostCalls: 0,
|
|
4571
|
+
untrackedCostModels: []
|
|
2844
4572
|
};
|
|
2845
4573
|
tierModels = /* @__PURE__ */ new Map();
|
|
2846
4574
|
/**
|
|
@@ -3190,7 +4918,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3190
4918
|
`Model ${model.id} inference timed out after ${cloudTimeoutMs}ms`
|
|
3191
4919
|
);
|
|
3192
4920
|
}
|
|
3193
|
-
const
|
|
4921
|
+
const corrected = buildTokenUsage(
|
|
3194
4922
|
result.usage.inputTokens,
|
|
3195
4923
|
result.usage.outputTokens,
|
|
3196
4924
|
model
|
|
@@ -3199,7 +4927,8 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3199
4927
|
...result,
|
|
3200
4928
|
usage: {
|
|
3201
4929
|
...result.usage,
|
|
3202
|
-
estimatedCostUsd:
|
|
4930
|
+
estimatedCostUsd: corrected.estimatedCostUsd,
|
|
4931
|
+
...corrected.costUnknown ? { costUnknown: true } : { costUnknown: void 0 }
|
|
3203
4932
|
}
|
|
3204
4933
|
};
|
|
3205
4934
|
if (!result || typeof result.content !== "string" || !result.usage) {
|
|
@@ -3386,7 +5115,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3386
5115
|
tokensByTier: { ...this.stats.tokensByTier },
|
|
3387
5116
|
inputTokensByTier: { ...this.stats.inputTokensByTier },
|
|
3388
5117
|
outputTokensByTier: { ...this.stats.outputTokensByTier },
|
|
3389
|
-
costByFeature: { ...this.stats.costByFeature }
|
|
5118
|
+
costByFeature: { ...this.stats.costByFeature },
|
|
5119
|
+
untrackedCostCalls: this.stats.untrackedCostCalls,
|
|
5120
|
+
untrackedCostModels: [...this.stats.untrackedCostModels]
|
|
3390
5121
|
};
|
|
3391
5122
|
}
|
|
3392
5123
|
/**
|
|
@@ -3437,7 +5168,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3437
5168
|
tokensByTier: {},
|
|
3438
5169
|
inputTokensByTier: {},
|
|
3439
5170
|
outputTokensByTier: {},
|
|
3440
|
-
costByFeature: {}
|
|
5171
|
+
costByFeature: {},
|
|
5172
|
+
untrackedCostCalls: 0,
|
|
5173
|
+
untrackedCostModels: []
|
|
3441
5174
|
};
|
|
3442
5175
|
this.sessionCostUsd = 0;
|
|
3443
5176
|
this.budgetState = "ok";
|
|
@@ -3622,6 +5355,18 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
3622
5355
|
if (featureTag) {
|
|
3623
5356
|
this.stats.costByFeature[featureTag] = (this.stats.costByFeature[featureTag] ?? 0) + usage.estimatedCostUsd;
|
|
3624
5357
|
}
|
|
5358
|
+
if (usage.costUnknown) {
|
|
5359
|
+
this.stats.untrackedCostCalls += 1;
|
|
5360
|
+
if (!this.stats.untrackedCostModels.includes(model.id)) {
|
|
5361
|
+
this.stats.untrackedCostModels.push(model.id);
|
|
5362
|
+
const capped = this.config?.budget?.maxCostPerRunUsd != null || this.config?.budget?.sessionBudgetUsd != null;
|
|
5363
|
+
this.emit("cost:untracked", {
|
|
5364
|
+
modelId: model.id,
|
|
5365
|
+
provider: model.provider,
|
|
5366
|
+
reason: capped ? `No published price for ${model.provider}:${model.id}. Its spend is not counted toward your cost budget \u2014 the token cap still applies. Add it to the pricing dataset, or set the provider's \`local: true\` if this endpoint really is free.` : `No published price for ${model.provider}:${model.id}. Cost for this model is reported as "not tracked" rather than $0.00.`
|
|
5367
|
+
});
|
|
5368
|
+
}
|
|
5369
|
+
}
|
|
3625
5370
|
this.runTokens += usage.totalTokens;
|
|
3626
5371
|
this.runCostUsd += usage.estimatedCostUsd;
|
|
3627
5372
|
this.updateBudgetState();
|
|
@@ -9129,7 +10874,18 @@ var ProviderConfigSchema = zod.z.object({
|
|
|
9129
10874
|
apiVersion: zod.z.string().optional(),
|
|
9130
10875
|
model: zod.z.string().optional(),
|
|
9131
10876
|
authToken: zod.z.string().optional(),
|
|
9132
|
-
credentialSource: zod.z.string().optional()
|
|
10877
|
+
credentialSource: zod.z.string().optional(),
|
|
10878
|
+
/**
|
|
10879
|
+
* "This endpoint is self-hosted, so inference genuinely costs $0."
|
|
10880
|
+
* Only meaningful for `ollama` and `openai-compatible`. Unset ⇒ inferred:
|
|
10881
|
+
* ollama is local, openai-compatible is local when its baseUrl is
|
|
10882
|
+
* loopback/LAN. Set it explicitly to override — e.g. `false` for an Ollama
|
|
10883
|
+
* instance you rent, `true` for a llama.cpp box on your own LAN reached by
|
|
10884
|
+
* hostname.
|
|
10885
|
+
*/
|
|
10886
|
+
local: zod.z.boolean().optional(),
|
|
10887
|
+
/** Region for providers whose price varies by region (Azure: global | us | eu | …). */
|
|
10888
|
+
region: zod.z.string().optional()
|
|
9133
10889
|
});
|
|
9134
10890
|
var ModelOverridesSchema = zod.z.object({
|
|
9135
10891
|
t1: zod.z.string().optional(),
|
|
@@ -9715,8 +11471,8 @@ var TaskAnalyzer = class {
|
|
|
9715
11471
|
}
|
|
9716
11472
|
costEfficiency(model, complexity) {
|
|
9717
11473
|
if (this.tracker) return this.tracker.costEfficiencyScore(model, complexity);
|
|
9718
|
-
const blended = model
|
|
9719
|
-
const normalised = Math.min(1, blended /
|
|
11474
|
+
const blended = blendedCostPer1k(model);
|
|
11475
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
9720
11476
|
const complexityWeight = (6 - complexity) / 5;
|
|
9721
11477
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
9722
11478
|
}
|
|
@@ -9851,8 +11607,8 @@ var ModelPerformanceTracker = class {
|
|
|
9851
11607
|
* normalised over $0.05 blended as the "expensive" ceiling.
|
|
9852
11608
|
*/
|
|
9853
11609
|
costEfficiencyScore(model, complexity) {
|
|
9854
|
-
const blended = model
|
|
9855
|
-
const normalised = Math.min(1, blended /
|
|
11610
|
+
const blended = blendedCostPer1k(model);
|
|
11611
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
9856
11612
|
const complexityWeight = (6 - complexity) / 5;
|
|
9857
11613
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
9858
11614
|
}
|
|
@@ -12695,7 +14451,11 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12695
14451
|
inputTokens: 0,
|
|
12696
14452
|
outputTokens: 0,
|
|
12697
14453
|
totalTokens: stats.totalTokens,
|
|
12698
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
14454
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
14455
|
+
// At least one call ran on a model with no known price, so its spend is
|
|
14456
|
+
// missing from the total above. Say so rather than letting the caller
|
|
14457
|
+
// present an undercount as the final figure.
|
|
14458
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12699
14459
|
},
|
|
12700
14460
|
t2Results,
|
|
12701
14461
|
durationMs,
|
|
@@ -12765,7 +14525,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12765
14525
|
inputTokens: 0,
|
|
12766
14526
|
outputTokens: 0,
|
|
12767
14527
|
totalTokens: stats2.totalTokens,
|
|
12768
|
-
estimatedCostUsd: stats2.totalCostUsd
|
|
14528
|
+
estimatedCostUsd: stats2.totalCostUsd,
|
|
14529
|
+
...stats2.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12769
14530
|
},
|
|
12770
14531
|
t2Results: [],
|
|
12771
14532
|
durationMs: Date.now() - startMs,
|
|
@@ -12789,7 +14550,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12789
14550
|
inputTokens: result.usage?.inputTokens ?? 0,
|
|
12790
14551
|
outputTokens: result.usage?.outputTokens ?? 0,
|
|
12791
14552
|
totalTokens: stats.totalTokens,
|
|
12792
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
14553
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
14554
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12793
14555
|
},
|
|
12794
14556
|
t2Results: [],
|
|
12795
14557
|
durationMs: Date.now() - startMs,
|
|
@@ -14573,7 +16335,10 @@ var DashboardServer = class {
|
|
|
14573
16335
|
this.socket.broadcast("cost:update", {
|
|
14574
16336
|
sessionId,
|
|
14575
16337
|
totalTokens: result.usage.totalTokens,
|
|
14576
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
16338
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
16339
|
+
// True when a model with no known price was used: the total above is
|
|
16340
|
+
// an undercount, and the UI must not present it as the full spend.
|
|
16341
|
+
costUnknown: result.usage.costUnknown === true
|
|
14577
16342
|
});
|
|
14578
16343
|
this.throttledBroadcast("workspace");
|
|
14579
16344
|
} catch (err) {
|
|
@@ -14886,7 +16651,8 @@ var DashboardServer = class {
|
|
|
14886
16651
|
this.socket.broadcast("cost:update", {
|
|
14887
16652
|
sessionId,
|
|
14888
16653
|
totalTokens: result.usage.totalTokens,
|
|
14889
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
16654
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
16655
|
+
costUnknown: result.usage.costUnknown === true
|
|
14890
16656
|
});
|
|
14891
16657
|
this.throttledBroadcast("workspace");
|
|
14892
16658
|
} catch (err) {
|
|
@@ -15428,7 +17194,8 @@ ${prompt}`;
|
|
|
15428
17194
|
this.socket.broadcast("cost:update", {
|
|
15429
17195
|
sessionId,
|
|
15430
17196
|
totalTokens: result.usage.totalTokens,
|
|
15431
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
17197
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
17198
|
+
costUnknown: result.usage.costUnknown === true
|
|
15432
17199
|
});
|
|
15433
17200
|
this.socket.broadcastToRoom(`session:${sessionId}`, "session:complete", { sessionId, result });
|
|
15434
17201
|
this.throttledBroadcast("workspace");
|
|
@@ -15984,12 +17751,19 @@ var CloudClient = class _CloudClient {
|
|
|
15984
17751
|
);
|
|
15985
17752
|
await openUrl(authorizeUrl);
|
|
15986
17753
|
const code = await listener.waitForCode;
|
|
15987
|
-
|
|
15988
|
-
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
15992
|
-
|
|
17754
|
+
let res;
|
|
17755
|
+
try {
|
|
17756
|
+
res = await fetch(this.url("/api/native/token"), {
|
|
17757
|
+
method: "POST",
|
|
17758
|
+
headers: { "Content-Type": "application/json" },
|
|
17759
|
+
body: JSON.stringify({ code, code_verifier: verifier })
|
|
17760
|
+
});
|
|
17761
|
+
} catch (err) {
|
|
17762
|
+
throw new Error(
|
|
17763
|
+
`Signed in, but could not reach Cascade at ${this.serverUrl} to finish. Check your connection and that the server URL is correct. (${err instanceof Error ? err.message : String(err)})`
|
|
17764
|
+
);
|
|
17765
|
+
}
|
|
17766
|
+
if (!res.ok) throw new Error(await loginFailureMessage(res, this.serverUrl));
|
|
15993
17767
|
const tokens = await res.json();
|
|
15994
17768
|
return await this.finishLogin(tokens);
|
|
15995
17769
|
} finally {
|
|
@@ -16163,6 +17937,22 @@ function sleep(ms, signal) {
|
|
|
16163
17937
|
}, { once: true });
|
|
16164
17938
|
});
|
|
16165
17939
|
}
|
|
17940
|
+
async function loginFailureMessage(res, serverUrl) {
|
|
17941
|
+
const body = await res.text().catch(() => "");
|
|
17942
|
+
let apiError = "";
|
|
17943
|
+
try {
|
|
17944
|
+
apiError = String(JSON.parse(body).error ?? "");
|
|
17945
|
+
} catch {
|
|
17946
|
+
}
|
|
17947
|
+
if (apiError === "invalid_grant") {
|
|
17948
|
+
return "Sign-in expired before it completed \u2014 the code is single-use and short-lived, and restarting the server during sign-in also invalidates it. Please try again.";
|
|
17949
|
+
}
|
|
17950
|
+
if (apiError) return `Sign-in failed: ${apiError} (HTTP ${res.status}).`;
|
|
17951
|
+
if (res.status === 404 || /<html/i.test(body)) {
|
|
17952
|
+
return `Signed in, but ${serverUrl} did not answer the Cascade API (HTTP ${res.status}). If this host was recently pointed at a new server, DNS may still be propagating.`;
|
|
17953
|
+
}
|
|
17954
|
+
return `Sign-in could not be completed (HTTP ${res.status}). Please try again.`;
|
|
17955
|
+
}
|
|
16166
17956
|
function base64url(buf) {
|
|
16167
17957
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
16168
17958
|
}
|