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.js
CHANGED
|
@@ -192,8 +192,1660 @@ var init_audit_logger = __esm({
|
|
|
192
192
|
}
|
|
193
193
|
});
|
|
194
194
|
|
|
195
|
+
// src/core/router/pricing-data.json
|
|
196
|
+
var pricing_data_default = {
|
|
197
|
+
entries: [
|
|
198
|
+
{
|
|
199
|
+
model: "claude-opus-5",
|
|
200
|
+
provider: "anthropic",
|
|
201
|
+
modality: "text",
|
|
202
|
+
currency: "USD",
|
|
203
|
+
asOf: "2026-07-27",
|
|
204
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
205
|
+
provenance: "vendor-pricing-page",
|
|
206
|
+
tiers: [
|
|
207
|
+
{
|
|
208
|
+
inputPer1m: 5,
|
|
209
|
+
outputPer1m: 25,
|
|
210
|
+
cachedInputPer1m: 0.5,
|
|
211
|
+
cacheWritePer1m: 6.25,
|
|
212
|
+
reasoningOutputPer1m: 25
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
batchMultiplier: 0.5,
|
|
216
|
+
contextWindow: 1e6
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
model: "claude-opus-4-8",
|
|
220
|
+
provider: "anthropic",
|
|
221
|
+
modality: "text",
|
|
222
|
+
currency: "USD",
|
|
223
|
+
asOf: "2026-07-27",
|
|
224
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
225
|
+
provenance: "vendor-pricing-page",
|
|
226
|
+
tiers: [
|
|
227
|
+
{
|
|
228
|
+
inputPer1m: 5,
|
|
229
|
+
outputPer1m: 25,
|
|
230
|
+
cachedInputPer1m: 0.5,
|
|
231
|
+
cacheWritePer1m: 6.25,
|
|
232
|
+
reasoningOutputPer1m: 25
|
|
233
|
+
}
|
|
234
|
+
],
|
|
235
|
+
batchMultiplier: 0.5,
|
|
236
|
+
contextWindow: 1e6
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
model: "claude-opus-4-7",
|
|
240
|
+
provider: "anthropic",
|
|
241
|
+
modality: "text",
|
|
242
|
+
currency: "USD",
|
|
243
|
+
asOf: "2026-07-27",
|
|
244
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
245
|
+
provenance: "vendor-pricing-page",
|
|
246
|
+
tiers: [
|
|
247
|
+
{
|
|
248
|
+
inputPer1m: 5,
|
|
249
|
+
outputPer1m: 25,
|
|
250
|
+
cachedInputPer1m: 0.5,
|
|
251
|
+
cacheWritePer1m: 6.25,
|
|
252
|
+
reasoningOutputPer1m: 25
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
batchMultiplier: 0.5,
|
|
256
|
+
contextWindow: 1e6
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
model: "claude-opus-4-6",
|
|
260
|
+
provider: "anthropic",
|
|
261
|
+
modality: "text",
|
|
262
|
+
currency: "USD",
|
|
263
|
+
asOf: "2026-07-27",
|
|
264
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
265
|
+
provenance: "vendor-pricing-page",
|
|
266
|
+
tiers: [
|
|
267
|
+
{
|
|
268
|
+
inputPer1m: 5,
|
|
269
|
+
outputPer1m: 25,
|
|
270
|
+
cachedInputPer1m: 0.5,
|
|
271
|
+
cacheWritePer1m: 6.25,
|
|
272
|
+
reasoningOutputPer1m: 25
|
|
273
|
+
}
|
|
274
|
+
],
|
|
275
|
+
batchMultiplier: 0.5,
|
|
276
|
+
contextWindow: 1e6
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
model: "claude-opus-4-5",
|
|
280
|
+
provider: "anthropic",
|
|
281
|
+
modality: "text",
|
|
282
|
+
currency: "USD",
|
|
283
|
+
asOf: "2026-07-27",
|
|
284
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
285
|
+
provenance: "vendor-pricing-page",
|
|
286
|
+
tiers: [
|
|
287
|
+
{
|
|
288
|
+
inputPer1m: 5,
|
|
289
|
+
outputPer1m: 25,
|
|
290
|
+
cachedInputPer1m: 0.5,
|
|
291
|
+
cacheWritePer1m: 6.25,
|
|
292
|
+
reasoningOutputPer1m: 25
|
|
293
|
+
}
|
|
294
|
+
],
|
|
295
|
+
batchMultiplier: 0.5,
|
|
296
|
+
contextWindow: 2e5
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
model: "claude-opus-4-1",
|
|
300
|
+
provider: "anthropic",
|
|
301
|
+
modality: "text",
|
|
302
|
+
currency: "USD",
|
|
303
|
+
asOf: "2026-07-27",
|
|
304
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
305
|
+
provenance: "vendor-pricing-page",
|
|
306
|
+
tiers: [
|
|
307
|
+
{
|
|
308
|
+
inputPer1m: 15,
|
|
309
|
+
outputPer1m: 75,
|
|
310
|
+
cachedInputPer1m: 1.5,
|
|
311
|
+
cacheWritePer1m: 18.75,
|
|
312
|
+
reasoningOutputPer1m: 75
|
|
313
|
+
}
|
|
314
|
+
],
|
|
315
|
+
batchMultiplier: 0.5,
|
|
316
|
+
contextWindow: 2e5,
|
|
317
|
+
notes: "Deprecated by Anthropic; priced for historical/cost-reporting accuracy."
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
model: "claude-opus-4",
|
|
321
|
+
provider: "anthropic",
|
|
322
|
+
modality: "text",
|
|
323
|
+
currency: "USD",
|
|
324
|
+
asOf: "2026-07-27",
|
|
325
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
326
|
+
provenance: "vendor-pricing-page",
|
|
327
|
+
tiers: [
|
|
328
|
+
{
|
|
329
|
+
inputPer1m: 15,
|
|
330
|
+
outputPer1m: 75,
|
|
331
|
+
cachedInputPer1m: 1.5,
|
|
332
|
+
cacheWritePer1m: 18.75,
|
|
333
|
+
reasoningOutputPer1m: 75
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
batchMultiplier: 0.5,
|
|
337
|
+
contextWindow: 2e5,
|
|
338
|
+
notes: "Retired except on Google Cloud; priced for historical/cost-reporting accuracy."
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
model: "claude-sonnet-5",
|
|
342
|
+
provider: "anthropic",
|
|
343
|
+
modality: "text",
|
|
344
|
+
currency: "USD",
|
|
345
|
+
asOf: "2026-07-27",
|
|
346
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
347
|
+
provenance: "vendor-pricing-page",
|
|
348
|
+
tiers: [
|
|
349
|
+
{
|
|
350
|
+
inputPer1m: 2,
|
|
351
|
+
outputPer1m: 10,
|
|
352
|
+
cachedInputPer1m: 0.2,
|
|
353
|
+
cacheWritePer1m: 2.5,
|
|
354
|
+
reasoningOutputPer1m: 10
|
|
355
|
+
}
|
|
356
|
+
],
|
|
357
|
+
batchMultiplier: 0.5,
|
|
358
|
+
contextWindow: 1e6,
|
|
359
|
+
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."
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
model: "claude-sonnet-4-6",
|
|
363
|
+
provider: "anthropic",
|
|
364
|
+
modality: "text",
|
|
365
|
+
currency: "USD",
|
|
366
|
+
asOf: "2026-07-27",
|
|
367
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
368
|
+
provenance: "vendor-pricing-page",
|
|
369
|
+
tiers: [
|
|
370
|
+
{
|
|
371
|
+
inputPer1m: 3,
|
|
372
|
+
outputPer1m: 15,
|
|
373
|
+
cachedInputPer1m: 0.3,
|
|
374
|
+
cacheWritePer1m: 3.75,
|
|
375
|
+
reasoningOutputPer1m: 15
|
|
376
|
+
}
|
|
377
|
+
],
|
|
378
|
+
batchMultiplier: 0.5,
|
|
379
|
+
contextWindow: 1e6
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
model: "claude-sonnet-4-5",
|
|
383
|
+
provider: "anthropic",
|
|
384
|
+
modality: "text",
|
|
385
|
+
currency: "USD",
|
|
386
|
+
asOf: "2026-07-27",
|
|
387
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
388
|
+
provenance: "vendor-pricing-page",
|
|
389
|
+
tiers: [
|
|
390
|
+
{
|
|
391
|
+
maxInputTokens: 2e5,
|
|
392
|
+
inputPer1m: 3,
|
|
393
|
+
outputPer1m: 15,
|
|
394
|
+
cachedInputPer1m: 0.3,
|
|
395
|
+
cacheWritePer1m: 3.75,
|
|
396
|
+
reasoningOutputPer1m: 15
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
inputPer1m: 6,
|
|
400
|
+
outputPer1m: 22.5,
|
|
401
|
+
cachedInputPer1m: 0.6,
|
|
402
|
+
cacheWritePer1m: 7.5,
|
|
403
|
+
reasoningOutputPer1m: 22.5
|
|
404
|
+
}
|
|
405
|
+
],
|
|
406
|
+
batchMultiplier: 0.5,
|
|
407
|
+
contextWindow: 2e5,
|
|
408
|
+
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)."
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
model: "claude-sonnet-4",
|
|
412
|
+
provider: "anthropic",
|
|
413
|
+
modality: "text",
|
|
414
|
+
currency: "USD",
|
|
415
|
+
asOf: "2026-07-27",
|
|
416
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
417
|
+
provenance: "vendor-pricing-page",
|
|
418
|
+
tiers: [
|
|
419
|
+
{
|
|
420
|
+
inputPer1m: 3,
|
|
421
|
+
outputPer1m: 15,
|
|
422
|
+
cachedInputPer1m: 0.3,
|
|
423
|
+
cacheWritePer1m: 3.75,
|
|
424
|
+
reasoningOutputPer1m: 15
|
|
425
|
+
}
|
|
426
|
+
],
|
|
427
|
+
batchMultiplier: 0.5,
|
|
428
|
+
contextWindow: 2e5
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
model: "claude-haiku-4-5",
|
|
432
|
+
provider: "anthropic",
|
|
433
|
+
modality: "text",
|
|
434
|
+
currency: "USD",
|
|
435
|
+
asOf: "2026-07-27",
|
|
436
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
437
|
+
provenance: "vendor-pricing-page",
|
|
438
|
+
tiers: [
|
|
439
|
+
{
|
|
440
|
+
inputPer1m: 1,
|
|
441
|
+
outputPer1m: 5,
|
|
442
|
+
cachedInputPer1m: 0.1,
|
|
443
|
+
cacheWritePer1m: 1.25,
|
|
444
|
+
reasoningOutputPer1m: 5
|
|
445
|
+
}
|
|
446
|
+
],
|
|
447
|
+
batchMultiplier: 0.5,
|
|
448
|
+
contextWindow: 2e5
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
model: "claude-haiku-3-5",
|
|
452
|
+
provider: "anthropic",
|
|
453
|
+
modality: "text",
|
|
454
|
+
currency: "USD",
|
|
455
|
+
asOf: "2026-07-27",
|
|
456
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
457
|
+
provenance: "vendor-pricing-page",
|
|
458
|
+
tiers: [
|
|
459
|
+
{
|
|
460
|
+
inputPer1m: 0.8,
|
|
461
|
+
outputPer1m: 4,
|
|
462
|
+
cachedInputPer1m: 0.08,
|
|
463
|
+
cacheWritePer1m: 1,
|
|
464
|
+
reasoningOutputPer1m: 4
|
|
465
|
+
}
|
|
466
|
+
],
|
|
467
|
+
batchMultiplier: 0.5,
|
|
468
|
+
contextWindow: 2e5
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
model: "gpt-5.6-sol",
|
|
472
|
+
provider: "openai",
|
|
473
|
+
aliases: [
|
|
474
|
+
"gpt-5.6"
|
|
475
|
+
],
|
|
476
|
+
modality: "text",
|
|
477
|
+
currency: "USD",
|
|
478
|
+
asOf: "2026-07-27",
|
|
479
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
480
|
+
provenance: "litellm-catalog",
|
|
481
|
+
tiers: [
|
|
482
|
+
{
|
|
483
|
+
maxInputTokens: 272e3,
|
|
484
|
+
inputPer1m: 5,
|
|
485
|
+
outputPer1m: 30,
|
|
486
|
+
cachedInputPer1m: 0.5,
|
|
487
|
+
cacheWritePer1m: 6.25
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
inputPer1m: 10,
|
|
491
|
+
outputPer1m: 45,
|
|
492
|
+
cachedInputPer1m: 1,
|
|
493
|
+
cacheWritePer1m: 12.5
|
|
494
|
+
}
|
|
495
|
+
],
|
|
496
|
+
batchMultiplier: 0.5,
|
|
497
|
+
contextWindow: 105e4
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
model: "gpt-5.6-terra",
|
|
501
|
+
provider: "openai",
|
|
502
|
+
modality: "text",
|
|
503
|
+
currency: "USD",
|
|
504
|
+
asOf: "2026-07-27",
|
|
505
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
506
|
+
provenance: "litellm-catalog",
|
|
507
|
+
tiers: [
|
|
508
|
+
{
|
|
509
|
+
maxInputTokens: 272e3,
|
|
510
|
+
inputPer1m: 2.5,
|
|
511
|
+
outputPer1m: 15,
|
|
512
|
+
cachedInputPer1m: 0.25,
|
|
513
|
+
cacheWritePer1m: 3.125
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
inputPer1m: 5,
|
|
517
|
+
outputPer1m: 22.5,
|
|
518
|
+
cachedInputPer1m: 0.5,
|
|
519
|
+
cacheWritePer1m: 6.25
|
|
520
|
+
}
|
|
521
|
+
],
|
|
522
|
+
batchMultiplier: 0.5,
|
|
523
|
+
contextWindow: 105e4
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
model: "gpt-5.6-luna",
|
|
527
|
+
provider: "openai",
|
|
528
|
+
modality: "text",
|
|
529
|
+
currency: "USD",
|
|
530
|
+
asOf: "2026-07-27",
|
|
531
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
532
|
+
provenance: "litellm-catalog",
|
|
533
|
+
tiers: [
|
|
534
|
+
{
|
|
535
|
+
maxInputTokens: 272e3,
|
|
536
|
+
inputPer1m: 1,
|
|
537
|
+
outputPer1m: 6,
|
|
538
|
+
cachedInputPer1m: 0.1,
|
|
539
|
+
cacheWritePer1m: 1.25
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
inputPer1m: 2,
|
|
543
|
+
outputPer1m: 9,
|
|
544
|
+
cachedInputPer1m: 0.2,
|
|
545
|
+
cacheWritePer1m: 2.5
|
|
546
|
+
}
|
|
547
|
+
],
|
|
548
|
+
batchMultiplier: 0.5,
|
|
549
|
+
contextWindow: 105e4
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
model: "gpt-5.5",
|
|
553
|
+
provider: "openai",
|
|
554
|
+
modality: "text",
|
|
555
|
+
currency: "USD",
|
|
556
|
+
asOf: "2026-07-27",
|
|
557
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
558
|
+
provenance: "litellm-catalog",
|
|
559
|
+
tiers: [
|
|
560
|
+
{
|
|
561
|
+
maxInputTokens: 272e3,
|
|
562
|
+
inputPer1m: 5,
|
|
563
|
+
outputPer1m: 30,
|
|
564
|
+
cachedInputPer1m: 0.5
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
inputPer1m: 10,
|
|
568
|
+
outputPer1m: 45,
|
|
569
|
+
cachedInputPer1m: 1
|
|
570
|
+
}
|
|
571
|
+
],
|
|
572
|
+
batchMultiplier: 0.5,
|
|
573
|
+
contextWindow: 105e4
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
model: "gpt-5.4",
|
|
577
|
+
provider: "openai",
|
|
578
|
+
modality: "text",
|
|
579
|
+
currency: "USD",
|
|
580
|
+
asOf: "2026-07-27",
|
|
581
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
582
|
+
provenance: "litellm-catalog",
|
|
583
|
+
tiers: [
|
|
584
|
+
{
|
|
585
|
+
maxInputTokens: 272e3,
|
|
586
|
+
inputPer1m: 2.5,
|
|
587
|
+
outputPer1m: 15,
|
|
588
|
+
cachedInputPer1m: 0.25
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
inputPer1m: 5,
|
|
592
|
+
outputPer1m: 22.5,
|
|
593
|
+
cachedInputPer1m: 0.5
|
|
594
|
+
}
|
|
595
|
+
],
|
|
596
|
+
batchMultiplier: 0.5,
|
|
597
|
+
contextWindow: 105e4
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
model: "gpt-5.4-mini",
|
|
601
|
+
provider: "openai",
|
|
602
|
+
modality: "text",
|
|
603
|
+
currency: "USD",
|
|
604
|
+
asOf: "2026-07-27",
|
|
605
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
606
|
+
provenance: "litellm-catalog",
|
|
607
|
+
tiers: [
|
|
608
|
+
{
|
|
609
|
+
inputPer1m: 0.75,
|
|
610
|
+
outputPer1m: 4.5,
|
|
611
|
+
cachedInputPer1m: 0.075
|
|
612
|
+
}
|
|
613
|
+
],
|
|
614
|
+
batchMultiplier: 0.5,
|
|
615
|
+
contextWindow: 105e4
|
|
616
|
+
},
|
|
617
|
+
{
|
|
618
|
+
model: "gpt-5",
|
|
619
|
+
provider: "openai",
|
|
620
|
+
modality: "text",
|
|
621
|
+
currency: "USD",
|
|
622
|
+
asOf: "2026-07-27",
|
|
623
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
624
|
+
provenance: "litellm-catalog",
|
|
625
|
+
tiers: [
|
|
626
|
+
{
|
|
627
|
+
inputPer1m: 1.25,
|
|
628
|
+
outputPer1m: 10,
|
|
629
|
+
cachedInputPer1m: 0.125
|
|
630
|
+
}
|
|
631
|
+
],
|
|
632
|
+
contextWindow: 272e3
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
model: "gpt-5-mini",
|
|
636
|
+
provider: "openai",
|
|
637
|
+
modality: "text",
|
|
638
|
+
currency: "USD",
|
|
639
|
+
asOf: "2026-07-27",
|
|
640
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
641
|
+
provenance: "litellm-catalog",
|
|
642
|
+
tiers: [
|
|
643
|
+
{
|
|
644
|
+
inputPer1m: 0.25,
|
|
645
|
+
outputPer1m: 2,
|
|
646
|
+
cachedInputPer1m: 0.025
|
|
647
|
+
}
|
|
648
|
+
],
|
|
649
|
+
contextWindow: 272e3
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
model: "gpt-5-nano",
|
|
653
|
+
provider: "openai",
|
|
654
|
+
modality: "text",
|
|
655
|
+
currency: "USD",
|
|
656
|
+
asOf: "2026-07-27",
|
|
657
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
658
|
+
provenance: "litellm-catalog",
|
|
659
|
+
tiers: [
|
|
660
|
+
{
|
|
661
|
+
inputPer1m: 0.05,
|
|
662
|
+
outputPer1m: 0.4,
|
|
663
|
+
cachedInputPer1m: 5e-3
|
|
664
|
+
}
|
|
665
|
+
],
|
|
666
|
+
contextWindow: 272e3
|
|
667
|
+
},
|
|
668
|
+
{
|
|
669
|
+
model: "gpt-4.1",
|
|
670
|
+
provider: "openai",
|
|
671
|
+
modality: "text",
|
|
672
|
+
currency: "USD",
|
|
673
|
+
asOf: "2026-07-27",
|
|
674
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
675
|
+
provenance: "litellm-catalog",
|
|
676
|
+
tiers: [
|
|
677
|
+
{
|
|
678
|
+
inputPer1m: 2,
|
|
679
|
+
outputPer1m: 8,
|
|
680
|
+
cachedInputPer1m: 0.5
|
|
681
|
+
}
|
|
682
|
+
],
|
|
683
|
+
batchMultiplier: 0.5,
|
|
684
|
+
contextWindow: 1047576
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
model: "gpt-4.1-mini",
|
|
688
|
+
provider: "openai",
|
|
689
|
+
modality: "text",
|
|
690
|
+
currency: "USD",
|
|
691
|
+
asOf: "2026-07-27",
|
|
692
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
693
|
+
provenance: "litellm-catalog",
|
|
694
|
+
tiers: [
|
|
695
|
+
{
|
|
696
|
+
inputPer1m: 0.4,
|
|
697
|
+
outputPer1m: 1.6,
|
|
698
|
+
cachedInputPer1m: 0.1
|
|
699
|
+
}
|
|
700
|
+
],
|
|
701
|
+
batchMultiplier: 0.5,
|
|
702
|
+
contextWindow: 1047576
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
model: "gpt-4.1-nano",
|
|
706
|
+
provider: "openai",
|
|
707
|
+
modality: "text",
|
|
708
|
+
currency: "USD",
|
|
709
|
+
asOf: "2026-07-27",
|
|
710
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
711
|
+
provenance: "litellm-catalog",
|
|
712
|
+
tiers: [
|
|
713
|
+
{
|
|
714
|
+
inputPer1m: 0.1,
|
|
715
|
+
outputPer1m: 0.4,
|
|
716
|
+
cachedInputPer1m: 0.025
|
|
717
|
+
}
|
|
718
|
+
],
|
|
719
|
+
batchMultiplier: 0.5,
|
|
720
|
+
contextWindow: 1047576
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
model: "gpt-4o",
|
|
724
|
+
provider: "openai",
|
|
725
|
+
modality: "text",
|
|
726
|
+
currency: "USD",
|
|
727
|
+
asOf: "2026-07-27",
|
|
728
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
729
|
+
provenance: "litellm-catalog",
|
|
730
|
+
tiers: [
|
|
731
|
+
{
|
|
732
|
+
inputPer1m: 2.5,
|
|
733
|
+
outputPer1m: 10,
|
|
734
|
+
cachedInputPer1m: 1.25
|
|
735
|
+
}
|
|
736
|
+
],
|
|
737
|
+
batchMultiplier: 0.5,
|
|
738
|
+
contextWindow: 128e3
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
model: "gpt-4o-mini",
|
|
742
|
+
provider: "openai",
|
|
743
|
+
modality: "text",
|
|
744
|
+
currency: "USD",
|
|
745
|
+
asOf: "2026-07-27",
|
|
746
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
747
|
+
provenance: "litellm-catalog",
|
|
748
|
+
tiers: [
|
|
749
|
+
{
|
|
750
|
+
inputPer1m: 0.15,
|
|
751
|
+
outputPer1m: 0.6,
|
|
752
|
+
cachedInputPer1m: 0.075
|
|
753
|
+
}
|
|
754
|
+
],
|
|
755
|
+
batchMultiplier: 0.5,
|
|
756
|
+
contextWindow: 128e3
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
model: "gpt-5.5",
|
|
760
|
+
provider: "azure",
|
|
761
|
+
region: "global",
|
|
762
|
+
modality: "text",
|
|
763
|
+
currency: "USD",
|
|
764
|
+
asOf: "2026-07-27",
|
|
765
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
766
|
+
provenance: "litellm-catalog",
|
|
767
|
+
tiers: [
|
|
768
|
+
{
|
|
769
|
+
maxInputTokens: 272e3,
|
|
770
|
+
inputPer1m: 5,
|
|
771
|
+
outputPer1m: 30,
|
|
772
|
+
cachedInputPer1m: 0.5
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
inputPer1m: 10,
|
|
776
|
+
outputPer1m: 45,
|
|
777
|
+
cachedInputPer1m: 1
|
|
778
|
+
}
|
|
779
|
+
],
|
|
780
|
+
contextWindow: 105e4
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
model: "gpt-5.5",
|
|
784
|
+
provider: "azure",
|
|
785
|
+
region: "us",
|
|
786
|
+
modality: "text",
|
|
787
|
+
currency: "USD",
|
|
788
|
+
asOf: "2026-07-27",
|
|
789
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
790
|
+
provenance: "litellm-catalog",
|
|
791
|
+
tiers: [
|
|
792
|
+
{
|
|
793
|
+
maxInputTokens: 272e3,
|
|
794
|
+
inputPer1m: 5.5,
|
|
795
|
+
outputPer1m: 33,
|
|
796
|
+
cachedInputPer1m: 0.55
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
inputPer1m: 11,
|
|
800
|
+
outputPer1m: 49.5,
|
|
801
|
+
cachedInputPer1m: 1.1
|
|
802
|
+
}
|
|
803
|
+
],
|
|
804
|
+
contextWindow: 105e4
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
model: "gpt-5.5",
|
|
808
|
+
provider: "azure",
|
|
809
|
+
region: "eu",
|
|
810
|
+
modality: "text",
|
|
811
|
+
currency: "USD",
|
|
812
|
+
asOf: "2026-07-27",
|
|
813
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
814
|
+
provenance: "litellm-catalog",
|
|
815
|
+
tiers: [
|
|
816
|
+
{
|
|
817
|
+
maxInputTokens: 272e3,
|
|
818
|
+
inputPer1m: 5.5,
|
|
819
|
+
outputPer1m: 33,
|
|
820
|
+
cachedInputPer1m: 0.55
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
inputPer1m: 11,
|
|
824
|
+
outputPer1m: 49.5,
|
|
825
|
+
cachedInputPer1m: 1.1
|
|
826
|
+
}
|
|
827
|
+
],
|
|
828
|
+
contextWindow: 105e4
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
model: "gpt-5.4",
|
|
832
|
+
provider: "azure",
|
|
833
|
+
region: "global",
|
|
834
|
+
modality: "text",
|
|
835
|
+
currency: "USD",
|
|
836
|
+
asOf: "2026-07-27",
|
|
837
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
838
|
+
provenance: "litellm-catalog",
|
|
839
|
+
tiers: [
|
|
840
|
+
{
|
|
841
|
+
maxInputTokens: 272e3,
|
|
842
|
+
inputPer1m: 2.5,
|
|
843
|
+
outputPer1m: 15,
|
|
844
|
+
cachedInputPer1m: 0.25
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
inputPer1m: 5,
|
|
848
|
+
outputPer1m: 22.5,
|
|
849
|
+
cachedInputPer1m: 0.5
|
|
850
|
+
}
|
|
851
|
+
],
|
|
852
|
+
contextWindow: 105e4
|
|
853
|
+
},
|
|
854
|
+
{
|
|
855
|
+
model: "gpt-5.4",
|
|
856
|
+
provider: "azure",
|
|
857
|
+
region: "us",
|
|
858
|
+
modality: "text",
|
|
859
|
+
currency: "USD",
|
|
860
|
+
asOf: "2026-07-27",
|
|
861
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
862
|
+
provenance: "litellm-catalog",
|
|
863
|
+
tiers: [
|
|
864
|
+
{
|
|
865
|
+
inputPer1m: 2.75,
|
|
866
|
+
outputPer1m: 16.5,
|
|
867
|
+
cachedInputPer1m: 0.28
|
|
868
|
+
}
|
|
869
|
+
],
|
|
870
|
+
contextWindow: 105e4
|
|
871
|
+
},
|
|
872
|
+
{
|
|
873
|
+
model: "gpt-5.4",
|
|
874
|
+
provider: "azure",
|
|
875
|
+
region: "eu",
|
|
876
|
+
modality: "text",
|
|
877
|
+
currency: "USD",
|
|
878
|
+
asOf: "2026-07-27",
|
|
879
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
880
|
+
provenance: "litellm-catalog",
|
|
881
|
+
tiers: [
|
|
882
|
+
{
|
|
883
|
+
inputPer1m: 2.75,
|
|
884
|
+
outputPer1m: 16.5,
|
|
885
|
+
cachedInputPer1m: 0.28
|
|
886
|
+
}
|
|
887
|
+
],
|
|
888
|
+
contextWindow: 105e4
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
model: "gpt-5.6-terra",
|
|
892
|
+
provider: "azure",
|
|
893
|
+
region: "global",
|
|
894
|
+
modality: "text",
|
|
895
|
+
currency: "USD",
|
|
896
|
+
asOf: "2026-07-27",
|
|
897
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
898
|
+
provenance: "litellm-catalog",
|
|
899
|
+
tiers: [
|
|
900
|
+
{
|
|
901
|
+
maxInputTokens: 272e3,
|
|
902
|
+
inputPer1m: 2.5,
|
|
903
|
+
outputPer1m: 15,
|
|
904
|
+
cachedInputPer1m: 0.25
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
inputPer1m: 5,
|
|
908
|
+
outputPer1m: 22.5,
|
|
909
|
+
cachedInputPer1m: 0.5
|
|
910
|
+
}
|
|
911
|
+
],
|
|
912
|
+
contextWindow: 105e4
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
model: "gpt-5.6-terra",
|
|
916
|
+
provider: "azure",
|
|
917
|
+
region: "eu",
|
|
918
|
+
modality: "text",
|
|
919
|
+
currency: "USD",
|
|
920
|
+
asOf: "2026-07-27",
|
|
921
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
922
|
+
provenance: "litellm-catalog",
|
|
923
|
+
tiers: [
|
|
924
|
+
{
|
|
925
|
+
maxInputTokens: 272e3,
|
|
926
|
+
inputPer1m: 2.75,
|
|
927
|
+
outputPer1m: 16.5,
|
|
928
|
+
cachedInputPer1m: 0.275
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
inputPer1m: 5.5,
|
|
932
|
+
outputPer1m: 24.75,
|
|
933
|
+
cachedInputPer1m: 0.55
|
|
934
|
+
}
|
|
935
|
+
],
|
|
936
|
+
contextWindow: 105e4
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
model: "gpt-5",
|
|
940
|
+
provider: "azure",
|
|
941
|
+
region: "global",
|
|
942
|
+
modality: "text",
|
|
943
|
+
currency: "USD",
|
|
944
|
+
asOf: "2026-07-27",
|
|
945
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
946
|
+
provenance: "litellm-catalog",
|
|
947
|
+
tiers: [
|
|
948
|
+
{
|
|
949
|
+
inputPer1m: 1.25,
|
|
950
|
+
outputPer1m: 10,
|
|
951
|
+
cachedInputPer1m: 0.125
|
|
952
|
+
}
|
|
953
|
+
],
|
|
954
|
+
contextWindow: 272e3
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
model: "gpt-5-mini",
|
|
958
|
+
provider: "azure",
|
|
959
|
+
region: "global",
|
|
960
|
+
modality: "text",
|
|
961
|
+
currency: "USD",
|
|
962
|
+
asOf: "2026-07-27",
|
|
963
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
964
|
+
provenance: "litellm-catalog",
|
|
965
|
+
tiers: [
|
|
966
|
+
{
|
|
967
|
+
inputPer1m: 0.25,
|
|
968
|
+
outputPer1m: 2,
|
|
969
|
+
cachedInputPer1m: 0.025
|
|
970
|
+
}
|
|
971
|
+
],
|
|
972
|
+
contextWindow: 272e3
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
model: "gpt-5-nano",
|
|
976
|
+
provider: "azure",
|
|
977
|
+
region: "global",
|
|
978
|
+
modality: "text",
|
|
979
|
+
currency: "USD",
|
|
980
|
+
asOf: "2026-07-27",
|
|
981
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
982
|
+
provenance: "litellm-catalog",
|
|
983
|
+
tiers: [
|
|
984
|
+
{
|
|
985
|
+
inputPer1m: 0.05,
|
|
986
|
+
outputPer1m: 0.4,
|
|
987
|
+
cachedInputPer1m: 5e-3
|
|
988
|
+
}
|
|
989
|
+
],
|
|
990
|
+
contextWindow: 272e3
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
model: "gpt-4.1",
|
|
994
|
+
provider: "azure",
|
|
995
|
+
region: "global",
|
|
996
|
+
modality: "text",
|
|
997
|
+
currency: "USD",
|
|
998
|
+
asOf: "2026-07-27",
|
|
999
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1000
|
+
provenance: "litellm-catalog",
|
|
1001
|
+
tiers: [
|
|
1002
|
+
{
|
|
1003
|
+
inputPer1m: 2,
|
|
1004
|
+
outputPer1m: 8,
|
|
1005
|
+
cachedInputPer1m: 0.5
|
|
1006
|
+
}
|
|
1007
|
+
],
|
|
1008
|
+
batchMultiplier: 0.5,
|
|
1009
|
+
contextWindow: 1047576
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
model: "gpt-4o",
|
|
1013
|
+
provider: "azure",
|
|
1014
|
+
region: "global",
|
|
1015
|
+
modality: "text",
|
|
1016
|
+
currency: "USD",
|
|
1017
|
+
asOf: "2026-07-27",
|
|
1018
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1019
|
+
provenance: "litellm-catalog",
|
|
1020
|
+
tiers: [
|
|
1021
|
+
{
|
|
1022
|
+
inputPer1m: 2.5,
|
|
1023
|
+
outputPer1m: 10,
|
|
1024
|
+
cachedInputPer1m: 1.25
|
|
1025
|
+
}
|
|
1026
|
+
],
|
|
1027
|
+
contextWindow: 128e3
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
model: "gpt-4o-mini",
|
|
1031
|
+
provider: "azure",
|
|
1032
|
+
region: "global",
|
|
1033
|
+
modality: "text",
|
|
1034
|
+
currency: "USD",
|
|
1035
|
+
asOf: "2026-07-27",
|
|
1036
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1037
|
+
provenance: "litellm-catalog",
|
|
1038
|
+
tiers: [
|
|
1039
|
+
{
|
|
1040
|
+
inputPer1m: 0.165,
|
|
1041
|
+
outputPer1m: 0.66,
|
|
1042
|
+
cachedInputPer1m: 0.075
|
|
1043
|
+
}
|
|
1044
|
+
],
|
|
1045
|
+
contextWindow: 128e3,
|
|
1046
|
+
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."
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
model: "gemini-3.1-pro",
|
|
1050
|
+
provider: "gemini",
|
|
1051
|
+
aliases: [
|
|
1052
|
+
"gemini-3.1-pro-preview"
|
|
1053
|
+
],
|
|
1054
|
+
modality: "text",
|
|
1055
|
+
currency: "USD",
|
|
1056
|
+
asOf: "2026-07-27",
|
|
1057
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1058
|
+
provenance: "vendor-pricing-page",
|
|
1059
|
+
tiers: [
|
|
1060
|
+
{
|
|
1061
|
+
maxInputTokens: 2e5,
|
|
1062
|
+
inputPer1m: 2,
|
|
1063
|
+
outputPer1m: 12,
|
|
1064
|
+
cachedInputPer1m: 0.2,
|
|
1065
|
+
reasoningOutputPer1m: 12
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
inputPer1m: 4,
|
|
1069
|
+
outputPer1m: 18,
|
|
1070
|
+
cachedInputPer1m: 0.4,
|
|
1071
|
+
reasoningOutputPer1m: 18
|
|
1072
|
+
}
|
|
1073
|
+
],
|
|
1074
|
+
batchMultiplier: 0.5,
|
|
1075
|
+
contextWindow: 1048576,
|
|
1076
|
+
notes: "Long-context tier: $2/$12 per 1M up to 200K prompt tokens, $4/$18 above it."
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
model: "gemini-3-pro",
|
|
1080
|
+
provider: "gemini",
|
|
1081
|
+
aliases: [
|
|
1082
|
+
"gemini-3-pro-preview"
|
|
1083
|
+
],
|
|
1084
|
+
modality: "text",
|
|
1085
|
+
currency: "USD",
|
|
1086
|
+
asOf: "2026-07-27",
|
|
1087
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1088
|
+
provenance: "vendor-pricing-page",
|
|
1089
|
+
tiers: [
|
|
1090
|
+
{
|
|
1091
|
+
maxInputTokens: 2e5,
|
|
1092
|
+
inputPer1m: 2,
|
|
1093
|
+
outputPer1m: 12,
|
|
1094
|
+
cachedInputPer1m: 0.2,
|
|
1095
|
+
reasoningOutputPer1m: 12
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
inputPer1m: 4,
|
|
1099
|
+
outputPer1m: 18,
|
|
1100
|
+
cachedInputPer1m: 0.4,
|
|
1101
|
+
reasoningOutputPer1m: 18
|
|
1102
|
+
}
|
|
1103
|
+
],
|
|
1104
|
+
batchMultiplier: 0.5,
|
|
1105
|
+
contextWindow: 1048576
|
|
1106
|
+
},
|
|
1107
|
+
{
|
|
1108
|
+
model: "gemini-3.6-flash",
|
|
1109
|
+
provider: "gemini",
|
|
1110
|
+
modality: "text",
|
|
1111
|
+
currency: "USD",
|
|
1112
|
+
asOf: "2026-07-27",
|
|
1113
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1114
|
+
provenance: "vendor-pricing-page",
|
|
1115
|
+
tiers: [
|
|
1116
|
+
{
|
|
1117
|
+
inputPer1m: 1.5,
|
|
1118
|
+
outputPer1m: 7.5,
|
|
1119
|
+
cachedInputPer1m: 0.15,
|
|
1120
|
+
reasoningOutputPer1m: 7.5
|
|
1121
|
+
}
|
|
1122
|
+
],
|
|
1123
|
+
batchMultiplier: 0.5,
|
|
1124
|
+
contextWindow: 1048576,
|
|
1125
|
+
notes: "Released 2026-07-21. Output pricing dropped ~17% from Gemini 3.5 Flash ($9.00 -> $7.50 per 1M); input unchanged."
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
model: "gemini-3.5-flash",
|
|
1129
|
+
provider: "gemini",
|
|
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
|
+
inputPer1m: 1.5,
|
|
1138
|
+
outputPer1m: 9,
|
|
1139
|
+
cachedInputPer1m: 0.15,
|
|
1140
|
+
reasoningOutputPer1m: 9
|
|
1141
|
+
}
|
|
1142
|
+
],
|
|
1143
|
+
batchMultiplier: 0.5,
|
|
1144
|
+
contextWindow: 1048576
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
model: "gemini-3.5-flash-lite",
|
|
1148
|
+
provider: "gemini",
|
|
1149
|
+
modality: "text",
|
|
1150
|
+
currency: "USD",
|
|
1151
|
+
asOf: "2026-07-27",
|
|
1152
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1153
|
+
provenance: "litellm-catalog",
|
|
1154
|
+
tiers: [
|
|
1155
|
+
{
|
|
1156
|
+
inputPer1m: 0.3,
|
|
1157
|
+
outputPer1m: 2.5,
|
|
1158
|
+
cachedInputPer1m: 0.03,
|
|
1159
|
+
reasoningOutputPer1m: 2.5
|
|
1160
|
+
}
|
|
1161
|
+
],
|
|
1162
|
+
batchMultiplier: 0.5,
|
|
1163
|
+
contextWindow: 1048576
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
model: "gemini-3.1-flash-lite",
|
|
1167
|
+
provider: "gemini",
|
|
1168
|
+
modality: "text",
|
|
1169
|
+
currency: "USD",
|
|
1170
|
+
asOf: "2026-07-27",
|
|
1171
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite",
|
|
1172
|
+
provenance: "litellm-catalog",
|
|
1173
|
+
tiers: [
|
|
1174
|
+
{
|
|
1175
|
+
inputPer1m: 0.25,
|
|
1176
|
+
outputPer1m: 1.5,
|
|
1177
|
+
cachedInputPer1m: 0.025,
|
|
1178
|
+
reasoningOutputPer1m: 1.5
|
|
1179
|
+
}
|
|
1180
|
+
],
|
|
1181
|
+
batchMultiplier: 0.5,
|
|
1182
|
+
contextWindow: 1048576
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
model: "gemini-3-flash",
|
|
1186
|
+
provider: "gemini",
|
|
1187
|
+
aliases: [
|
|
1188
|
+
"gemini-3-flash-preview"
|
|
1189
|
+
],
|
|
1190
|
+
modality: "text",
|
|
1191
|
+
currency: "USD",
|
|
1192
|
+
asOf: "2026-07-27",
|
|
1193
|
+
source: "https://ai.google.dev/pricing/gemini-3",
|
|
1194
|
+
provenance: "litellm-catalog",
|
|
1195
|
+
tiers: [
|
|
1196
|
+
{
|
|
1197
|
+
inputPer1m: 0.5,
|
|
1198
|
+
outputPer1m: 3,
|
|
1199
|
+
cachedInputPer1m: 0.05,
|
|
1200
|
+
reasoningOutputPer1m: 3
|
|
1201
|
+
}
|
|
1202
|
+
],
|
|
1203
|
+
contextWindow: 1048576
|
|
1204
|
+
},
|
|
1205
|
+
{
|
|
1206
|
+
model: "gemini-2.5-pro",
|
|
1207
|
+
provider: "gemini",
|
|
1208
|
+
modality: "text",
|
|
1209
|
+
currency: "USD",
|
|
1210
|
+
asOf: "2026-07-27",
|
|
1211
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1212
|
+
provenance: "litellm-catalog",
|
|
1213
|
+
tiers: [
|
|
1214
|
+
{
|
|
1215
|
+
maxInputTokens: 2e5,
|
|
1216
|
+
inputPer1m: 1.25,
|
|
1217
|
+
outputPer1m: 10,
|
|
1218
|
+
cachedInputPer1m: 0.125
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
inputPer1m: 2.5,
|
|
1222
|
+
outputPer1m: 15,
|
|
1223
|
+
cachedInputPer1m: 0.25
|
|
1224
|
+
}
|
|
1225
|
+
],
|
|
1226
|
+
contextWindow: 1048576
|
|
1227
|
+
},
|
|
1228
|
+
{
|
|
1229
|
+
model: "gemini-2.5-flash",
|
|
1230
|
+
provider: "gemini",
|
|
1231
|
+
modality: "text",
|
|
1232
|
+
currency: "USD",
|
|
1233
|
+
asOf: "2026-07-27",
|
|
1234
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-preview",
|
|
1235
|
+
provenance: "litellm-catalog",
|
|
1236
|
+
tiers: [
|
|
1237
|
+
{
|
|
1238
|
+
inputPer1m: 0.3,
|
|
1239
|
+
outputPer1m: 2.5,
|
|
1240
|
+
cachedInputPer1m: 0.03,
|
|
1241
|
+
reasoningOutputPer1m: 2.5
|
|
1242
|
+
}
|
|
1243
|
+
],
|
|
1244
|
+
contextWindow: 1048576
|
|
1245
|
+
},
|
|
1246
|
+
{
|
|
1247
|
+
model: "gemini-2.5-flash-lite",
|
|
1248
|
+
provider: "gemini",
|
|
1249
|
+
modality: "text",
|
|
1250
|
+
currency: "USD",
|
|
1251
|
+
asOf: "2026-07-27",
|
|
1252
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-lite",
|
|
1253
|
+
provenance: "litellm-catalog",
|
|
1254
|
+
tiers: [
|
|
1255
|
+
{
|
|
1256
|
+
inputPer1m: 0.1,
|
|
1257
|
+
outputPer1m: 0.4,
|
|
1258
|
+
cachedInputPer1m: 0.01,
|
|
1259
|
+
reasoningOutputPer1m: 0.4
|
|
1260
|
+
}
|
|
1261
|
+
],
|
|
1262
|
+
contextWindow: 1048576
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
model: "gemini-2.0-flash",
|
|
1266
|
+
provider: "gemini",
|
|
1267
|
+
modality: "text",
|
|
1268
|
+
currency: "USD",
|
|
1269
|
+
asOf: "2026-07-27",
|
|
1270
|
+
source: "https://ai.google.dev/pricing#2_0flash",
|
|
1271
|
+
provenance: "litellm-catalog",
|
|
1272
|
+
tiers: [
|
|
1273
|
+
{
|
|
1274
|
+
inputPer1m: 0.1,
|
|
1275
|
+
outputPer1m: 0.4,
|
|
1276
|
+
cachedInputPer1m: 0.025
|
|
1277
|
+
}
|
|
1278
|
+
],
|
|
1279
|
+
contextWindow: 1048576,
|
|
1280
|
+
notes: "Gemini Developer API price. Vertex AI lists $0.15/$0.60 per 1M for the same model \u2014 see the vertex entry."
|
|
1281
|
+
},
|
|
1282
|
+
{
|
|
1283
|
+
model: "gemini-2.0-flash-lite",
|
|
1284
|
+
provider: "gemini",
|
|
1285
|
+
modality: "text",
|
|
1286
|
+
currency: "USD",
|
|
1287
|
+
asOf: "2026-07-27",
|
|
1288
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite",
|
|
1289
|
+
provenance: "litellm-catalog",
|
|
1290
|
+
tiers: [
|
|
1291
|
+
{
|
|
1292
|
+
inputPer1m: 0.075,
|
|
1293
|
+
outputPer1m: 0.3,
|
|
1294
|
+
cachedInputPer1m: 0.01875
|
|
1295
|
+
}
|
|
1296
|
+
],
|
|
1297
|
+
contextWindow: 1048576
|
|
1298
|
+
},
|
|
1299
|
+
{
|
|
1300
|
+
model: "gemini-2.0-flash",
|
|
1301
|
+
provider: "vertex",
|
|
1302
|
+
modality: "text",
|
|
1303
|
+
currency: "USD",
|
|
1304
|
+
asOf: "2026-07-27",
|
|
1305
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1306
|
+
provenance: "vendor-pricing-page",
|
|
1307
|
+
tiers: [
|
|
1308
|
+
{
|
|
1309
|
+
inputPer1m: 0.15,
|
|
1310
|
+
outputPer1m: 0.6
|
|
1311
|
+
}
|
|
1312
|
+
],
|
|
1313
|
+
batchMultiplier: 0.5,
|
|
1314
|
+
notes: "Vertex AI lists $0.15/$0.60 per 1M; the Gemini Developer API lists $0.10/$0.40 for the same model."
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
model: "gemini-3.1-pro",
|
|
1318
|
+
provider: "vertex",
|
|
1319
|
+
aliases: [
|
|
1320
|
+
"gemini-3.1-pro-preview"
|
|
1321
|
+
],
|
|
1322
|
+
modality: "text",
|
|
1323
|
+
currency: "USD",
|
|
1324
|
+
asOf: "2026-07-27",
|
|
1325
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1326
|
+
provenance: "vendor-pricing-page",
|
|
1327
|
+
tiers: [
|
|
1328
|
+
{
|
|
1329
|
+
maxInputTokens: 2e5,
|
|
1330
|
+
inputPer1m: 2,
|
|
1331
|
+
outputPer1m: 12,
|
|
1332
|
+
cachedInputPer1m: 0.2,
|
|
1333
|
+
reasoningOutputPer1m: 12
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
inputPer1m: 4,
|
|
1337
|
+
outputPer1m: 18,
|
|
1338
|
+
cachedInputPer1m: 0.4,
|
|
1339
|
+
reasoningOutputPer1m: 18
|
|
1340
|
+
}
|
|
1341
|
+
],
|
|
1342
|
+
batchMultiplier: 0.5,
|
|
1343
|
+
contextWindow: 1048576
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
model: "gemini-3.6-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: 1.5,
|
|
1356
|
+
outputPer1m: 7.5,
|
|
1357
|
+
cachedInputPer1m: 0.15,
|
|
1358
|
+
reasoningOutputPer1m: 7.5
|
|
1359
|
+
}
|
|
1360
|
+
],
|
|
1361
|
+
batchMultiplier: 0.5,
|
|
1362
|
+
contextWindow: 1048576
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
model: "gemini-2.5-pro",
|
|
1366
|
+
provider: "vertex",
|
|
1367
|
+
modality: "text",
|
|
1368
|
+
currency: "USD",
|
|
1369
|
+
asOf: "2026-07-27",
|
|
1370
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1371
|
+
provenance: "vendor-pricing-page",
|
|
1372
|
+
tiers: [
|
|
1373
|
+
{
|
|
1374
|
+
maxInputTokens: 2e5,
|
|
1375
|
+
inputPer1m: 1.25,
|
|
1376
|
+
outputPer1m: 10,
|
|
1377
|
+
cachedInputPer1m: 0.13
|
|
1378
|
+
},
|
|
1379
|
+
{
|
|
1380
|
+
inputPer1m: 2.5,
|
|
1381
|
+
outputPer1m: 15,
|
|
1382
|
+
cachedInputPer1m: 0.25
|
|
1383
|
+
}
|
|
1384
|
+
],
|
|
1385
|
+
batchMultiplier: 0.5,
|
|
1386
|
+
contextWindow: 1048576
|
|
1387
|
+
},
|
|
1388
|
+
{
|
|
1389
|
+
model: "gemini-2.5-flash",
|
|
1390
|
+
provider: "vertex",
|
|
1391
|
+
modality: "text",
|
|
1392
|
+
currency: "USD",
|
|
1393
|
+
asOf: "2026-07-27",
|
|
1394
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1395
|
+
provenance: "vendor-pricing-page",
|
|
1396
|
+
tiers: [
|
|
1397
|
+
{
|
|
1398
|
+
inputPer1m: 0.3,
|
|
1399
|
+
outputPer1m: 2.5,
|
|
1400
|
+
cachedInputPer1m: 0.03,
|
|
1401
|
+
reasoningOutputPer1m: 2.5
|
|
1402
|
+
}
|
|
1403
|
+
],
|
|
1404
|
+
batchMultiplier: 0.5,
|
|
1405
|
+
contextWindow: 1048576
|
|
1406
|
+
},
|
|
1407
|
+
{
|
|
1408
|
+
model: "claude-sonnet-4-6",
|
|
1409
|
+
provider: "openrouter",
|
|
1410
|
+
modality: "text",
|
|
1411
|
+
currency: "USD",
|
|
1412
|
+
asOf: "2026-07-27",
|
|
1413
|
+
source: "https://openrouter.ai/anthropic/claude-sonnet-4.6",
|
|
1414
|
+
provenance: "litellm-catalog",
|
|
1415
|
+
tiers: [
|
|
1416
|
+
{
|
|
1417
|
+
maxInputTokens: 2e5,
|
|
1418
|
+
inputPer1m: 3,
|
|
1419
|
+
outputPer1m: 15,
|
|
1420
|
+
cachedInputPer1m: 0.3,
|
|
1421
|
+
cacheWritePer1m: 3.75
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
inputPer1m: 6,
|
|
1425
|
+
outputPer1m: 22.5,
|
|
1426
|
+
cachedInputPer1m: 0.6,
|
|
1427
|
+
cacheWritePer1m: 7.5
|
|
1428
|
+
}
|
|
1429
|
+
],
|
|
1430
|
+
contextWindow: 1e6
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
model: "claude-haiku-4-5",
|
|
1434
|
+
provider: "openrouter",
|
|
1435
|
+
modality: "text",
|
|
1436
|
+
currency: "USD",
|
|
1437
|
+
asOf: "2026-07-27",
|
|
1438
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1439
|
+
provenance: "litellm-catalog",
|
|
1440
|
+
tiers: [
|
|
1441
|
+
{
|
|
1442
|
+
inputPer1m: 1,
|
|
1443
|
+
outputPer1m: 5,
|
|
1444
|
+
cachedInputPer1m: 0.1,
|
|
1445
|
+
cacheWritePer1m: 1.25
|
|
1446
|
+
}
|
|
1447
|
+
],
|
|
1448
|
+
contextWindow: 2e5
|
|
1449
|
+
},
|
|
1450
|
+
{
|
|
1451
|
+
model: "gpt-5",
|
|
1452
|
+
provider: "openrouter",
|
|
1453
|
+
modality: "text",
|
|
1454
|
+
currency: "USD",
|
|
1455
|
+
asOf: "2026-07-27",
|
|
1456
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1457
|
+
provenance: "litellm-catalog",
|
|
1458
|
+
tiers: [
|
|
1459
|
+
{
|
|
1460
|
+
inputPer1m: 1.25,
|
|
1461
|
+
outputPer1m: 10,
|
|
1462
|
+
cachedInputPer1m: 0.125
|
|
1463
|
+
}
|
|
1464
|
+
],
|
|
1465
|
+
contextWindow: 272e3
|
|
1466
|
+
},
|
|
1467
|
+
{
|
|
1468
|
+
model: "gpt-5-mini",
|
|
1469
|
+
provider: "openrouter",
|
|
1470
|
+
modality: "text",
|
|
1471
|
+
currency: "USD",
|
|
1472
|
+
asOf: "2026-07-27",
|
|
1473
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1474
|
+
provenance: "litellm-catalog",
|
|
1475
|
+
tiers: [
|
|
1476
|
+
{
|
|
1477
|
+
inputPer1m: 0.25,
|
|
1478
|
+
outputPer1m: 2,
|
|
1479
|
+
cachedInputPer1m: 0.025
|
|
1480
|
+
}
|
|
1481
|
+
],
|
|
1482
|
+
contextWindow: 272e3
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
model: "gemini-3.1-pro",
|
|
1486
|
+
provider: "openrouter",
|
|
1487
|
+
aliases: [
|
|
1488
|
+
"gemini-3.1-pro-preview"
|
|
1489
|
+
],
|
|
1490
|
+
modality: "text",
|
|
1491
|
+
currency: "USD",
|
|
1492
|
+
asOf: "2026-07-27",
|
|
1493
|
+
source: "https://openrouter.ai/google/gemini-3.1-pro-preview",
|
|
1494
|
+
provenance: "litellm-catalog",
|
|
1495
|
+
tiers: [
|
|
1496
|
+
{
|
|
1497
|
+
maxInputTokens: 2e5,
|
|
1498
|
+
inputPer1m: 2,
|
|
1499
|
+
outputPer1m: 12,
|
|
1500
|
+
cachedInputPer1m: 0.2
|
|
1501
|
+
},
|
|
1502
|
+
{
|
|
1503
|
+
inputPer1m: 4,
|
|
1504
|
+
outputPer1m: 18,
|
|
1505
|
+
cachedInputPer1m: 0.4,
|
|
1506
|
+
cacheWritePer1m: 0.25
|
|
1507
|
+
}
|
|
1508
|
+
],
|
|
1509
|
+
contextWindow: 1048576
|
|
1510
|
+
},
|
|
1511
|
+
{
|
|
1512
|
+
model: "text-embedding-3-small",
|
|
1513
|
+
provider: "openai",
|
|
1514
|
+
modality: "embedding",
|
|
1515
|
+
currency: "USD",
|
|
1516
|
+
asOf: "2026-07-27",
|
|
1517
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1518
|
+
provenance: "litellm-catalog",
|
|
1519
|
+
tiers: [
|
|
1520
|
+
{
|
|
1521
|
+
inputPer1m: 0.02,
|
|
1522
|
+
outputPer1m: 0
|
|
1523
|
+
}
|
|
1524
|
+
],
|
|
1525
|
+
batchMultiplier: 0.5,
|
|
1526
|
+
contextWindow: 8191
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
model: "text-embedding-3-large",
|
|
1530
|
+
provider: "openai",
|
|
1531
|
+
modality: "embedding",
|
|
1532
|
+
currency: "USD",
|
|
1533
|
+
asOf: "2026-07-27",
|
|
1534
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1535
|
+
provenance: "litellm-catalog",
|
|
1536
|
+
tiers: [
|
|
1537
|
+
{
|
|
1538
|
+
inputPer1m: 0.13,
|
|
1539
|
+
outputPer1m: 0
|
|
1540
|
+
}
|
|
1541
|
+
],
|
|
1542
|
+
batchMultiplier: 0.5,
|
|
1543
|
+
contextWindow: 8191
|
|
1544
|
+
},
|
|
1545
|
+
{
|
|
1546
|
+
model: "gemini-embedding-001",
|
|
1547
|
+
provider: "gemini",
|
|
1548
|
+
modality: "embedding",
|
|
1549
|
+
currency: "USD",
|
|
1550
|
+
asOf: "2026-07-27",
|
|
1551
|
+
source: "https://ai.google.dev/gemini-api/docs/embeddings#model-versions",
|
|
1552
|
+
provenance: "litellm-catalog",
|
|
1553
|
+
tiers: [
|
|
1554
|
+
{
|
|
1555
|
+
inputPer1m: 0.15,
|
|
1556
|
+
outputPer1m: 0
|
|
1557
|
+
}
|
|
1558
|
+
],
|
|
1559
|
+
contextWindow: 2048
|
|
1560
|
+
},
|
|
1561
|
+
{
|
|
1562
|
+
model: "dall-e-3",
|
|
1563
|
+
provider: "openai",
|
|
1564
|
+
modality: "image",
|
|
1565
|
+
currency: "USD",
|
|
1566
|
+
asOf: "2026-07-27",
|
|
1567
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1568
|
+
provenance: "litellm-catalog",
|
|
1569
|
+
rates: [
|
|
1570
|
+
{
|
|
1571
|
+
unit: "per_image",
|
|
1572
|
+
amount: 0.04,
|
|
1573
|
+
variant: "1024x1024 standard"
|
|
1574
|
+
}
|
|
1575
|
+
]
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
model: "gemini-3-pro-image",
|
|
1579
|
+
provider: "gemini",
|
|
1580
|
+
modality: "image",
|
|
1581
|
+
currency: "USD",
|
|
1582
|
+
asOf: "2026-07-27",
|
|
1583
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1584
|
+
provenance: "litellm-catalog",
|
|
1585
|
+
rates: [
|
|
1586
|
+
{
|
|
1587
|
+
unit: "per_image",
|
|
1588
|
+
amount: 0.134,
|
|
1589
|
+
variant: "default output resolution"
|
|
1590
|
+
}
|
|
1591
|
+
],
|
|
1592
|
+
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."
|
|
1593
|
+
},
|
|
1594
|
+
{
|
|
1595
|
+
model: "imagen-4.0-generate-001",
|
|
1596
|
+
provider: "vertex",
|
|
1597
|
+
modality: "image",
|
|
1598
|
+
currency: "USD",
|
|
1599
|
+
asOf: "2026-07-27",
|
|
1600
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1601
|
+
provenance: "litellm-catalog",
|
|
1602
|
+
rates: [
|
|
1603
|
+
{
|
|
1604
|
+
unit: "per_image",
|
|
1605
|
+
amount: 0.04
|
|
1606
|
+
}
|
|
1607
|
+
]
|
|
1608
|
+
},
|
|
1609
|
+
{
|
|
1610
|
+
model: "veo-3.1-generate-001",
|
|
1611
|
+
provider: "gemini",
|
|
1612
|
+
modality: "video",
|
|
1613
|
+
currency: "USD",
|
|
1614
|
+
asOf: "2026-07-27",
|
|
1615
|
+
source: "https://ai.google.dev/gemini-api/docs/video",
|
|
1616
|
+
provenance: "litellm-catalog",
|
|
1617
|
+
rates: [
|
|
1618
|
+
{
|
|
1619
|
+
unit: "per_second",
|
|
1620
|
+
amount: 0.4
|
|
1621
|
+
}
|
|
1622
|
+
]
|
|
1623
|
+
},
|
|
1624
|
+
{
|
|
1625
|
+
model: "veo-3.1-generate-001",
|
|
1626
|
+
provider: "vertex",
|
|
1627
|
+
modality: "video",
|
|
1628
|
+
currency: "USD",
|
|
1629
|
+
asOf: "2026-07-27",
|
|
1630
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo",
|
|
1631
|
+
provenance: "litellm-catalog",
|
|
1632
|
+
rates: [
|
|
1633
|
+
{
|
|
1634
|
+
unit: "per_second",
|
|
1635
|
+
amount: 0.4
|
|
1636
|
+
}
|
|
1637
|
+
]
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
model: "tts-1",
|
|
1641
|
+
provider: "openai",
|
|
1642
|
+
modality: "speech",
|
|
1643
|
+
currency: "USD",
|
|
1644
|
+
asOf: "2026-07-27",
|
|
1645
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1646
|
+
provenance: "litellm-catalog",
|
|
1647
|
+
rates: [
|
|
1648
|
+
{
|
|
1649
|
+
unit: "per_character",
|
|
1650
|
+
amount: 15e-6
|
|
1651
|
+
}
|
|
1652
|
+
],
|
|
1653
|
+
notes: "$15 per 1M characters."
|
|
1654
|
+
},
|
|
1655
|
+
{
|
|
1656
|
+
model: "tts-1-hd",
|
|
1657
|
+
provider: "openai",
|
|
1658
|
+
modality: "speech",
|
|
1659
|
+
currency: "USD",
|
|
1660
|
+
asOf: "2026-07-27",
|
|
1661
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1662
|
+
provenance: "litellm-catalog",
|
|
1663
|
+
rates: [
|
|
1664
|
+
{
|
|
1665
|
+
unit: "per_character",
|
|
1666
|
+
amount: 3e-5
|
|
1667
|
+
}
|
|
1668
|
+
],
|
|
1669
|
+
notes: "$30 per 1M characters."
|
|
1670
|
+
},
|
|
1671
|
+
{
|
|
1672
|
+
model: "whisper-1",
|
|
1673
|
+
provider: "openai",
|
|
1674
|
+
modality: "transcription",
|
|
1675
|
+
currency: "USD",
|
|
1676
|
+
asOf: "2026-07-27",
|
|
1677
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1678
|
+
provenance: "litellm-catalog",
|
|
1679
|
+
rates: [
|
|
1680
|
+
{
|
|
1681
|
+
unit: "per_audio_minute",
|
|
1682
|
+
amount: 6e-3
|
|
1683
|
+
}
|
|
1684
|
+
],
|
|
1685
|
+
notes: "litellm records $0.0001 per audio second; $0.006/minute is that rate x 60."
|
|
1686
|
+
}
|
|
1687
|
+
]
|
|
1688
|
+
};
|
|
1689
|
+
|
|
1690
|
+
// src/core/router/pricing.ts
|
|
1691
|
+
var DATASET = pricing_data_default;
|
|
1692
|
+
function normalizeForPricing(id) {
|
|
1693
|
+
let s = id.trim().toLowerCase();
|
|
1694
|
+
s = s.replace(/^models\//, "");
|
|
1695
|
+
const slash = s.lastIndexOf("/");
|
|
1696
|
+
if (slash !== -1) s = s.slice(slash + 1);
|
|
1697
|
+
const tag = s.search(/[:@]/);
|
|
1698
|
+
if (tag !== -1) s = s.slice(0, tag);
|
|
1699
|
+
s = s.replace(/-latest$/, "");
|
|
1700
|
+
s = s.replace(/-preview(?:-\d{2}-\d{2})?$/, "");
|
|
1701
|
+
s = s.replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
1702
|
+
s = s.replace(/-\d{8}$/, "");
|
|
1703
|
+
s = s.replace(/-preview$/, "");
|
|
1704
|
+
return s;
|
|
1705
|
+
}
|
|
1706
|
+
function indexKey(model, provider, region) {
|
|
1707
|
+
return `${provider}|${normalizeForPricing(model)}|${region ?? ""}`;
|
|
1708
|
+
}
|
|
1709
|
+
var INDEX = /* @__PURE__ */ new Map();
|
|
1710
|
+
for (const entry of DATASET.entries) {
|
|
1711
|
+
for (const name of [entry.model, ...entry.aliases ?? []]) {
|
|
1712
|
+
const withRegion = indexKey(name, entry.provider, entry.region);
|
|
1713
|
+
if (!INDEX.has(withRegion)) INDEX.set(withRegion, entry);
|
|
1714
|
+
const bare = indexKey(name, entry.provider);
|
|
1715
|
+
const existing = INDEX.get(bare);
|
|
1716
|
+
if (!existing || existing.region && existing.region !== "global" && entry.region === "global") {
|
|
1717
|
+
INDEX.set(bare, entry);
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
function findPricing(modelId, provider, opts = {}) {
|
|
1722
|
+
const ids = [modelId, opts.baseModelId].filter((x) => !!x);
|
|
1723
|
+
const providers = [provider, ...opts.fallbackProviders ?? []];
|
|
1724
|
+
for (const p of providers) {
|
|
1725
|
+
for (const id of ids) {
|
|
1726
|
+
const hit = (opts.region ? INDEX.get(indexKey(id, p, opts.region)) : void 0) ?? INDEX.get(indexKey(id, p));
|
|
1727
|
+
if (hit) return { entry: hit, matchedProvider: p, viaFallback: p !== provider };
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
return null;
|
|
1731
|
+
}
|
|
1732
|
+
function tierFor(entry, inputTokens = 0) {
|
|
1733
|
+
const tiers = entry.tiers;
|
|
1734
|
+
if (!tiers?.length) return null;
|
|
1735
|
+
for (const t of tiers) {
|
|
1736
|
+
if (t.maxInputTokens === void 0 || inputTokens <= t.maxInputTokens) return t;
|
|
1737
|
+
}
|
|
1738
|
+
return tiers[tiers.length - 1] ?? null;
|
|
1739
|
+
}
|
|
1740
|
+
var PER_1M_TO_PER_1K = 1 / 1e3;
|
|
1741
|
+
function tokenRatesPer1k(entry, opts = {}) {
|
|
1742
|
+
const tier = tierFor(entry, opts.inputTokens ?? 0);
|
|
1743
|
+
if (!tier) return null;
|
|
1744
|
+
const mult = (opts.batch ? entry.batchMultiplier ?? 1 : 1) * PER_1M_TO_PER_1K;
|
|
1745
|
+
const out = {
|
|
1746
|
+
input: tier.inputPer1m * mult,
|
|
1747
|
+
output: tier.outputPer1m * mult
|
|
1748
|
+
};
|
|
1749
|
+
if (tier.cachedInputPer1m !== void 0) out.cachedInput = tier.cachedInputPer1m * mult;
|
|
1750
|
+
if (tier.cacheWritePer1m !== void 0) out.cacheWrite = tier.cacheWritePer1m * mult;
|
|
1751
|
+
if (tier.reasoningOutputPer1m !== void 0) out.reasoningOutput = tier.reasoningOutputPer1m * mult;
|
|
1752
|
+
return out;
|
|
1753
|
+
}
|
|
1754
|
+
var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"]);
|
|
1755
|
+
function isLoopbackOrPrivateHost(url) {
|
|
1756
|
+
if (!url) return false;
|
|
1757
|
+
try {
|
|
1758
|
+
const host = new URL(url).hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
1759
|
+
if (LOOPBACK_HOSTS.has(host) || LOOPBACK_HOSTS.has(`[${host}]`)) return true;
|
|
1760
|
+
if (host.endsWith(".local")) return true;
|
|
1761
|
+
if (/^127\./.test(host)) return true;
|
|
1762
|
+
if (/^10\./.test(host)) return true;
|
|
1763
|
+
if (/^192\.168\./.test(host)) return true;
|
|
1764
|
+
if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true;
|
|
1765
|
+
return false;
|
|
1766
|
+
} catch {
|
|
1767
|
+
return false;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
function isLocalEndpoint(cfg) {
|
|
1771
|
+
if (typeof cfg.local === "boolean") return cfg.local;
|
|
1772
|
+
if (cfg.type === "ollama") return true;
|
|
1773
|
+
if (cfg.type === "openai-compatible") return isLoopbackOrPrivateHost(cfg.baseUrl);
|
|
1774
|
+
return false;
|
|
1775
|
+
}
|
|
1776
|
+
var UNKNOWN = { input: 0, output: 0, unknown: true, free: false };
|
|
1777
|
+
var FREE = { input: 0, output: 0, unknown: false, free: true };
|
|
1778
|
+
function resolvePricing(model, opts = {}) {
|
|
1779
|
+
if (model.isLocal) return FREE;
|
|
1780
|
+
const fallbackProviders = model.provider === "azure" ? ["openai"] : model.provider === "gemini" ? ["vertex"] : [];
|
|
1781
|
+
const match = findPricing(model.id, model.provider, {
|
|
1782
|
+
region: opts.region,
|
|
1783
|
+
baseModelId: model.baseModelId,
|
|
1784
|
+
fallbackProviders
|
|
1785
|
+
});
|
|
1786
|
+
if (!match) return UNKNOWN;
|
|
1787
|
+
const rates = tokenRatesPer1k(match.entry, { inputTokens: opts.inputTokens, batch: opts.batch });
|
|
1788
|
+
if (!rates) return UNKNOWN;
|
|
1789
|
+
return {
|
|
1790
|
+
input: rates.input,
|
|
1791
|
+
output: rates.output,
|
|
1792
|
+
unknown: false,
|
|
1793
|
+
free: false,
|
|
1794
|
+
entry: match.entry,
|
|
1795
|
+
...match.viaFallback ? { estimatedFromProvider: match.matchedProvider } : {}
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
function withResolvedPricing(model, opts = {}) {
|
|
1799
|
+
const p = resolvePricing(model, opts);
|
|
1800
|
+
return {
|
|
1801
|
+
...model,
|
|
1802
|
+
inputCostPer1kTokens: p.input,
|
|
1803
|
+
outputCostPer1kTokens: p.output,
|
|
1804
|
+
...p.unknown ? { pricingUnknown: true } : { pricingUnknown: false }
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
function isPricingUnknown(model) {
|
|
1808
|
+
return model.pricingUnknown === true && !model.isLocal;
|
|
1809
|
+
}
|
|
1810
|
+
var BLENDED_COST_CEILING = 0.05;
|
|
1811
|
+
function blendedCostPer1k(model) {
|
|
1812
|
+
if (isPricingUnknown(model)) return BLENDED_COST_CEILING;
|
|
1813
|
+
return model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
|
|
1814
|
+
}
|
|
1815
|
+
var DISAGREEMENT_THRESHOLD = 0.02;
|
|
1816
|
+
function reconcilePrice(model, live) {
|
|
1817
|
+
const baseline = resolvePricing(model);
|
|
1818
|
+
const liveIsZero = !(live.input > 0) && !(live.output > 0);
|
|
1819
|
+
if (liveIsZero && !model.isLocal) {
|
|
1820
|
+
return { input: baseline.input, output: baseline.output, accepted: false };
|
|
1821
|
+
}
|
|
1822
|
+
if (baseline.unknown || !baseline.entry) {
|
|
1823
|
+
return { input: live.input, output: live.output, accepted: true };
|
|
1824
|
+
}
|
|
1825
|
+
const dsBlend = baseline.input + baseline.output * 2;
|
|
1826
|
+
const liveBlend = live.input + live.output * 2;
|
|
1827
|
+
const ratio = dsBlend > 0 ? liveBlend / dsBlend : Number.POSITIVE_INFINITY;
|
|
1828
|
+
const material = dsBlend > 0 && Math.abs(ratio - 1) > DISAGREEMENT_THRESHOLD;
|
|
1829
|
+
return {
|
|
1830
|
+
input: live.input,
|
|
1831
|
+
output: live.output,
|
|
1832
|
+
accepted: true,
|
|
1833
|
+
...material ? {
|
|
1834
|
+
disagreement: {
|
|
1835
|
+
modelId: model.id,
|
|
1836
|
+
provider: model.provider,
|
|
1837
|
+
dataset: { input: baseline.input, output: baseline.output },
|
|
1838
|
+
live: { input: live.input, output: live.output },
|
|
1839
|
+
ratio: Math.round(ratio * 1e3) / 1e3,
|
|
1840
|
+
datasetAsOf: baseline.entry.asOf,
|
|
1841
|
+
datasetSource: baseline.entry.source
|
|
1842
|
+
}
|
|
1843
|
+
} : {}
|
|
1844
|
+
};
|
|
1845
|
+
}
|
|
1846
|
+
|
|
195
1847
|
// src/constants.ts
|
|
196
|
-
var CASCADE_VERSION = "0.
|
|
1848
|
+
var CASCADE_VERSION = "0.49.0";
|
|
197
1849
|
var CASCADE_CONFIG_DIR = ".cascade";
|
|
198
1850
|
var CASCADE_MD_FILE = "CASCADE.md";
|
|
199
1851
|
var CASCADE_IGNORE_FILE = ".cascadeignore";
|
|
@@ -542,6 +2194,13 @@ var MODELS = {
|
|
|
542
2194
|
for (const _m of Object.values(MODELS)) {
|
|
543
2195
|
if (_m.supportsToolUse === void 0) _m.supportsToolUse = !_m.isLocal;
|
|
544
2196
|
}
|
|
2197
|
+
for (const _m of Object.values(MODELS)) {
|
|
2198
|
+
const priced = resolvePricing(_m);
|
|
2199
|
+
if (priced.unknown || priced.free || priced.estimatedFromProvider) continue;
|
|
2200
|
+
_m.inputCostPer1kTokens = priced.input;
|
|
2201
|
+
_m.outputCostPer1kTokens = priced.output;
|
|
2202
|
+
_m.pricingUnknown = false;
|
|
2203
|
+
}
|
|
545
2204
|
var T1_MODEL_PRIORITY = [
|
|
546
2205
|
"gpt-5.5",
|
|
547
2206
|
"gpt-5.4",
|
|
@@ -632,21 +2291,49 @@ var PROVIDER_DISPLAY_NAMES = {
|
|
|
632
2291
|
|
|
633
2292
|
// src/utils/cost.ts
|
|
634
2293
|
function resolveModelPricing(model) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
2294
|
+
if (model.isLocal) return { input: 0, output: 0, unknown: false };
|
|
2295
|
+
if (model.inputCostPer1kTokens > 0 || model.outputCostPer1kTokens > 0) {
|
|
2296
|
+
return {
|
|
2297
|
+
input: model.inputCostPer1kTokens,
|
|
2298
|
+
output: model.outputCostPer1kTokens,
|
|
2299
|
+
unknown: false
|
|
2300
|
+
};
|
|
2301
|
+
}
|
|
2302
|
+
const fromDataset = resolvePricing(model);
|
|
2303
|
+
if (!fromDataset.unknown) {
|
|
2304
|
+
return {
|
|
2305
|
+
input: fromDataset.input,
|
|
2306
|
+
output: fromDataset.output,
|
|
2307
|
+
unknown: false,
|
|
2308
|
+
...fromDataset.estimatedFromProvider ? { estimatedFromProvider: fromDataset.estimatedFromProvider } : {}
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
if (model.id) {
|
|
638
2312
|
const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
|
|
639
|
-
if (known) {
|
|
640
|
-
|
|
641
|
-
|
|
2313
|
+
if (known && (known.inputCostPer1kTokens > 0 || known.outputCostPer1kTokens > 0)) {
|
|
2314
|
+
return {
|
|
2315
|
+
input: known.inputCostPer1kTokens,
|
|
2316
|
+
output: known.outputCostPer1kTokens,
|
|
2317
|
+
unknown: false
|
|
2318
|
+
};
|
|
642
2319
|
}
|
|
643
2320
|
}
|
|
644
|
-
return { input, output };
|
|
2321
|
+
return { input: 0, output: 0, unknown: true };
|
|
645
2322
|
}
|
|
646
2323
|
function calculateCost(inputTokens, outputTokens, model) {
|
|
647
2324
|
const { input, output } = resolveModelPricing(model);
|
|
648
2325
|
return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
|
|
649
2326
|
}
|
|
2327
|
+
function buildTokenUsage(inputTokens, outputTokens, model) {
|
|
2328
|
+
const { input, output, unknown } = resolveModelPricing(model);
|
|
2329
|
+
return {
|
|
2330
|
+
inputTokens,
|
|
2331
|
+
outputTokens,
|
|
2332
|
+
totalTokens: inputTokens + outputTokens,
|
|
2333
|
+
estimatedCostUsd: inputTokens / 1e3 * input + outputTokens / 1e3 * output,
|
|
2334
|
+
...unknown ? { costUnknown: true } : {}
|
|
2335
|
+
};
|
|
2336
|
+
}
|
|
650
2337
|
|
|
651
2338
|
// src/providers/base.ts
|
|
652
2339
|
var BaseProvider = class {
|
|
@@ -666,12 +2353,7 @@ var BaseProvider = class {
|
|
|
666
2353
|
return calculateCost(inputTokens, outputTokens, this.model);
|
|
667
2354
|
}
|
|
668
2355
|
makeUsage(inputTokens, outputTokens) {
|
|
669
|
-
return
|
|
670
|
-
inputTokens,
|
|
671
|
-
outputTokens,
|
|
672
|
-
totalTokens: inputTokens + outputTokens,
|
|
673
|
-
estimatedCostUsd: this.estimateCost(inputTokens, outputTokens)
|
|
674
|
-
};
|
|
2356
|
+
return buildTokenUsage(inputTokens, outputTokens, this.model);
|
|
675
2357
|
}
|
|
676
2358
|
};
|
|
677
2359
|
|
|
@@ -840,7 +2522,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
840
2522
|
return data.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
841
2523
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "anthropic");
|
|
842
2524
|
if (known) return known;
|
|
843
|
-
return {
|
|
2525
|
+
return withResolvedPricing({
|
|
844
2526
|
id: m.id,
|
|
845
2527
|
name: m.display_name || m.id,
|
|
846
2528
|
provider: "anthropic",
|
|
@@ -851,7 +2533,7 @@ var AnthropicProvider = class extends BaseProvider {
|
|
|
851
2533
|
maxOutputTokens: 8e3,
|
|
852
2534
|
supportsStreaming: true,
|
|
853
2535
|
isLocal: false
|
|
854
|
-
};
|
|
2536
|
+
});
|
|
855
2537
|
});
|
|
856
2538
|
} catch {
|
|
857
2539
|
return Object.values(MODELS).filter((m) => m.provider === "anthropic");
|
|
@@ -1055,7 +2737,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
1055
2737
|
return response.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
1056
2738
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "openai");
|
|
1057
2739
|
if (known) return known;
|
|
1058
|
-
return {
|
|
2740
|
+
return withResolvedPricing({
|
|
1059
2741
|
id: m.id,
|
|
1060
2742
|
name: m.id,
|
|
1061
2743
|
provider: "openai",
|
|
@@ -1066,7 +2748,7 @@ var OpenAIProvider = class extends BaseProvider {
|
|
|
1066
2748
|
maxOutputTokens: 4e3,
|
|
1067
2749
|
supportsStreaming: true,
|
|
1068
2750
|
isLocal: false
|
|
1069
|
-
};
|
|
2751
|
+
});
|
|
1070
2752
|
});
|
|
1071
2753
|
} catch {
|
|
1072
2754
|
return Object.values(MODELS).filter((m) => m.provider === "openai");
|
|
@@ -1162,6 +2844,10 @@ function azureModelForDeployment(cfg) {
|
|
|
1162
2844
|
const baseModelId = cfg.model?.trim() || inferAzureBaseModel(id) || void 0;
|
|
1163
2845
|
const base = baseModelId ? MODELS[baseModelId] : void 0;
|
|
1164
2846
|
if (base) {
|
|
2847
|
+
const azurePrice = resolvePricing(
|
|
2848
|
+
{ id, provider: "azure", isLocal: false, baseModelId },
|
|
2849
|
+
{ region: cfg.region }
|
|
2850
|
+
);
|
|
1165
2851
|
return {
|
|
1166
2852
|
...base,
|
|
1167
2853
|
id,
|
|
@@ -1170,7 +2856,12 @@ function azureModelForDeployment(cfg) {
|
|
|
1170
2856
|
provider: "azure",
|
|
1171
2857
|
baseModelId,
|
|
1172
2858
|
// real identity for benchmark + live pricing
|
|
1173
|
-
supportsToolUse: base.supportsToolUse ?? true
|
|
2859
|
+
supportsToolUse: base.supportsToolUse ?? true,
|
|
2860
|
+
...azurePrice.unknown ? {} : {
|
|
2861
|
+
inputCostPer1kTokens: azurePrice.input,
|
|
2862
|
+
outputCostPer1kTokens: azurePrice.output,
|
|
2863
|
+
pricingUnknown: false
|
|
2864
|
+
}
|
|
1174
2865
|
};
|
|
1175
2866
|
}
|
|
1176
2867
|
return {
|
|
@@ -1333,7 +3024,7 @@ var GeminiProvider = class extends BaseProvider {
|
|
|
1333
3024
|
(km) => km.id === id && km.provider === "gemini"
|
|
1334
3025
|
);
|
|
1335
3026
|
if (known) return known;
|
|
1336
|
-
return {
|
|
3027
|
+
return withResolvedPricing({
|
|
1337
3028
|
id,
|
|
1338
3029
|
name: m.displayName || id,
|
|
1339
3030
|
provider: "gemini",
|
|
@@ -1344,7 +3035,7 @@ var GeminiProvider = class extends BaseProvider {
|
|
|
1344
3035
|
maxOutputTokens: m.outputTokenLimit || 8e3,
|
|
1345
3036
|
supportsStreaming: true,
|
|
1346
3037
|
isLocal: false
|
|
1347
|
-
};
|
|
3038
|
+
});
|
|
1348
3039
|
});
|
|
1349
3040
|
} catch {
|
|
1350
3041
|
return Object.values(MODELS).filter((m) => m.provider === "gemini");
|
|
@@ -1691,9 +3382,10 @@ var OllamaProvider = class extends BaseProvider {
|
|
|
1691
3382
|
return supportedKeywords.some((k) => name.includes(k)) && isChatModel(name);
|
|
1692
3383
|
});
|
|
1693
3384
|
const shows = await Promise.all(entries.map((m) => this.showModel(m.name)));
|
|
3385
|
+
const local = isLocalEndpoint({ ...this.config, type: "ollama" });
|
|
1694
3386
|
return entries.map((m, i) => {
|
|
1695
3387
|
const show = shows[i];
|
|
1696
|
-
return {
|
|
3388
|
+
return withResolvedPricing({
|
|
1697
3389
|
id: m.name,
|
|
1698
3390
|
name: m.name,
|
|
1699
3391
|
provider: "ollama",
|
|
@@ -1703,10 +3395,10 @@ var OllamaProvider = class extends BaseProvider {
|
|
|
1703
3395
|
outputCostPer1kTokens: 0,
|
|
1704
3396
|
maxOutputTokens: 4e3,
|
|
1705
3397
|
supportsStreaming: true,
|
|
1706
|
-
isLocal:
|
|
3398
|
+
isLocal: local,
|
|
1707
3399
|
supportsToolUse: show?.tools ?? isToolCapable(m.name),
|
|
1708
3400
|
minSizeB: this.parseSizeB(m.details?.parameter_size)
|
|
1709
|
-
};
|
|
3401
|
+
});
|
|
1710
3402
|
});
|
|
1711
3403
|
} catch {
|
|
1712
3404
|
return [];
|
|
@@ -1809,7 +3501,8 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
|
1809
3501
|
}).filter((x) => typeof x === "string" && x.length > 0);
|
|
1810
3502
|
if (ids.length === 0) return [this.model];
|
|
1811
3503
|
const chatIds = ids.filter((id) => isChatModel(id));
|
|
1812
|
-
|
|
3504
|
+
const local = isLocalEndpoint(this.config);
|
|
3505
|
+
return (chatIds.length ? chatIds : ids).map((id) => withResolvedPricing({
|
|
1813
3506
|
id,
|
|
1814
3507
|
name: id,
|
|
1815
3508
|
provider: "openai-compatible",
|
|
@@ -1819,7 +3512,7 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
|
1819
3512
|
outputCostPer1kTokens: 0,
|
|
1820
3513
|
maxOutputTokens: 4e3,
|
|
1821
3514
|
supportsStreaming: true,
|
|
1822
|
-
isLocal:
|
|
3515
|
+
isLocal: local
|
|
1823
3516
|
}));
|
|
1824
3517
|
}
|
|
1825
3518
|
async isAvailable() {
|
|
@@ -2034,7 +3727,7 @@ var ModelSelector = class {
|
|
|
2034
3727
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
2035
3728
|
}
|
|
2036
3729
|
if (providerStr && this.availableProviders.has(providerStr)) {
|
|
2037
|
-
const dynamicModel = {
|
|
3730
|
+
const dynamicModel = withResolvedPricing({
|
|
2038
3731
|
id: actualId,
|
|
2039
3732
|
name: actualId,
|
|
2040
3733
|
provider: providerStr,
|
|
@@ -2045,7 +3738,7 @@ var ModelSelector = class {
|
|
|
2045
3738
|
maxOutputTokens: 8e3,
|
|
2046
3739
|
supportsStreaming: true,
|
|
2047
3740
|
isLocal: providerStr === "ollama"
|
|
2048
|
-
};
|
|
3741
|
+
});
|
|
2049
3742
|
this.addDynamicModel(dynamicModel);
|
|
2050
3743
|
return dynamicModel;
|
|
2051
3744
|
}
|
|
@@ -2437,6 +4130,8 @@ var LiveDataProvider = class {
|
|
|
2437
4130
|
snapshot = null;
|
|
2438
4131
|
prices = /* @__PURE__ */ new Map();
|
|
2439
4132
|
capabilities = /* @__PURE__ */ new Map();
|
|
4133
|
+
/** Dataset-vs-live price mismatches, deduped by `provider:modelId`. */
|
|
4134
|
+
disagreements = /* @__PURE__ */ new Map();
|
|
2440
4135
|
source = "bundled";
|
|
2441
4136
|
fetchedAt = 0;
|
|
2442
4137
|
loaded = false;
|
|
@@ -2590,14 +4285,45 @@ var LiveDataProvider = class {
|
|
|
2590
4285
|
/**
|
|
2591
4286
|
* Returns a price-corrected copy of each model when live pricing is known,
|
|
2592
4287
|
* leaving the original untouched (so the shared catalog is never mutated).
|
|
4288
|
+
*
|
|
4289
|
+
* Reconciliation policy (see reconcilePrice in pricing.ts): the bundled
|
|
4290
|
+
* dataset is the authoritative baseline, and a live quote overrides it
|
|
4291
|
+
* because it is fresher by construction — but the disagreement is RECORDED,
|
|
4292
|
+
* not swallowed. A dataset/live mismatch is the best signal available that
|
|
4293
|
+
* the committed prices have gone stale, so it must be visible rather than
|
|
4294
|
+
* silently resolved in either direction. A live quote of $0 for a non-local
|
|
4295
|
+
* model is rejected outright: that is the very failure mode this change
|
|
4296
|
+
* exists to prevent, and a marketplace's free-tier alias must never zero out
|
|
4297
|
+
* the price of the paid model Cascade is actually calling.
|
|
2593
4298
|
*/
|
|
2594
4299
|
applyLivePricing(models) {
|
|
2595
4300
|
return models.map((m) => {
|
|
2596
4301
|
const p = this.getLivePrice(m.baseModelId ?? m.id);
|
|
2597
4302
|
if (!p) return m;
|
|
2598
|
-
|
|
4303
|
+
const reconciled = reconcilePrice(m, p);
|
|
4304
|
+
if (reconciled.disagreement) this.recordDisagreement(reconciled.disagreement);
|
|
4305
|
+
if (!reconciled.accepted) return m;
|
|
4306
|
+
return {
|
|
4307
|
+
...m,
|
|
4308
|
+
inputCostPer1kTokens: reconciled.input,
|
|
4309
|
+
outputCostPer1kTokens: reconciled.output,
|
|
4310
|
+
pricingUnknown: false
|
|
4311
|
+
};
|
|
2599
4312
|
});
|
|
2600
4313
|
}
|
|
4314
|
+
recordDisagreement(d) {
|
|
4315
|
+
const key = `${d.provider}:${d.modelId}`;
|
|
4316
|
+
if (this.disagreements.has(key)) return;
|
|
4317
|
+
this.disagreements.set(key, d);
|
|
4318
|
+
}
|
|
4319
|
+
/**
|
|
4320
|
+
* Dataset-vs-live price mismatches seen this session, newest-model-first
|
|
4321
|
+
* insertion order. Surfaced by `cascade models --verbose`; a non-empty list
|
|
4322
|
+
* means src/core/router/pricing-data.json is probably due a refresh.
|
|
4323
|
+
*/
|
|
4324
|
+
getPriceDisagreements() {
|
|
4325
|
+
return [...this.disagreements.values()];
|
|
4326
|
+
}
|
|
2601
4327
|
/** Current capability facts for a model id, or null when unknown. */
|
|
2602
4328
|
getCapability(modelId) {
|
|
2603
4329
|
return this.capabilities.get(normalizeModelId2(modelId)) ?? null;
|
|
@@ -2794,7 +4520,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
2794
4520
|
tokensByTier: {},
|
|
2795
4521
|
inputTokensByTier: {},
|
|
2796
4522
|
outputTokensByTier: {},
|
|
2797
|
-
costByFeature: {}
|
|
4523
|
+
costByFeature: {},
|
|
4524
|
+
untrackedCostCalls: 0,
|
|
4525
|
+
untrackedCostModels: []
|
|
2798
4526
|
};
|
|
2799
4527
|
tierModels = /* @__PURE__ */ new Map();
|
|
2800
4528
|
/**
|
|
@@ -3144,7 +4872,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3144
4872
|
`Model ${model.id} inference timed out after ${cloudTimeoutMs}ms`
|
|
3145
4873
|
);
|
|
3146
4874
|
}
|
|
3147
|
-
const
|
|
4875
|
+
const corrected = buildTokenUsage(
|
|
3148
4876
|
result.usage.inputTokens,
|
|
3149
4877
|
result.usage.outputTokens,
|
|
3150
4878
|
model
|
|
@@ -3153,7 +4881,8 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3153
4881
|
...result,
|
|
3154
4882
|
usage: {
|
|
3155
4883
|
...result.usage,
|
|
3156
|
-
estimatedCostUsd:
|
|
4884
|
+
estimatedCostUsd: corrected.estimatedCostUsd,
|
|
4885
|
+
...corrected.costUnknown ? { costUnknown: true } : { costUnknown: void 0 }
|
|
3157
4886
|
}
|
|
3158
4887
|
};
|
|
3159
4888
|
if (!result || typeof result.content !== "string" || !result.usage) {
|
|
@@ -3340,7 +5069,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3340
5069
|
tokensByTier: { ...this.stats.tokensByTier },
|
|
3341
5070
|
inputTokensByTier: { ...this.stats.inputTokensByTier },
|
|
3342
5071
|
outputTokensByTier: { ...this.stats.outputTokensByTier },
|
|
3343
|
-
costByFeature: { ...this.stats.costByFeature }
|
|
5072
|
+
costByFeature: { ...this.stats.costByFeature },
|
|
5073
|
+
untrackedCostCalls: this.stats.untrackedCostCalls,
|
|
5074
|
+
untrackedCostModels: [...this.stats.untrackedCostModels]
|
|
3344
5075
|
};
|
|
3345
5076
|
}
|
|
3346
5077
|
/**
|
|
@@ -3391,7 +5122,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3391
5122
|
tokensByTier: {},
|
|
3392
5123
|
inputTokensByTier: {},
|
|
3393
5124
|
outputTokensByTier: {},
|
|
3394
|
-
costByFeature: {}
|
|
5125
|
+
costByFeature: {},
|
|
5126
|
+
untrackedCostCalls: 0,
|
|
5127
|
+
untrackedCostModels: []
|
|
3395
5128
|
};
|
|
3396
5129
|
this.sessionCostUsd = 0;
|
|
3397
5130
|
this.budgetState = "ok";
|
|
@@ -3576,6 +5309,18 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter {
|
|
|
3576
5309
|
if (featureTag) {
|
|
3577
5310
|
this.stats.costByFeature[featureTag] = (this.stats.costByFeature[featureTag] ?? 0) + usage.estimatedCostUsd;
|
|
3578
5311
|
}
|
|
5312
|
+
if (usage.costUnknown) {
|
|
5313
|
+
this.stats.untrackedCostCalls += 1;
|
|
5314
|
+
if (!this.stats.untrackedCostModels.includes(model.id)) {
|
|
5315
|
+
this.stats.untrackedCostModels.push(model.id);
|
|
5316
|
+
const capped = this.config?.budget?.maxCostPerRunUsd != null || this.config?.budget?.sessionBudgetUsd != null;
|
|
5317
|
+
this.emit("cost:untracked", {
|
|
5318
|
+
modelId: model.id,
|
|
5319
|
+
provider: model.provider,
|
|
5320
|
+
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.`
|
|
5321
|
+
});
|
|
5322
|
+
}
|
|
5323
|
+
}
|
|
3579
5324
|
this.runTokens += usage.totalTokens;
|
|
3580
5325
|
this.runCostUsd += usage.estimatedCostUsd;
|
|
3581
5326
|
this.updateBudgetState();
|
|
@@ -9083,7 +10828,18 @@ var ProviderConfigSchema = z.object({
|
|
|
9083
10828
|
apiVersion: z.string().optional(),
|
|
9084
10829
|
model: z.string().optional(),
|
|
9085
10830
|
authToken: z.string().optional(),
|
|
9086
|
-
credentialSource: z.string().optional()
|
|
10831
|
+
credentialSource: z.string().optional(),
|
|
10832
|
+
/**
|
|
10833
|
+
* "This endpoint is self-hosted, so inference genuinely costs $0."
|
|
10834
|
+
* Only meaningful for `ollama` and `openai-compatible`. Unset ⇒ inferred:
|
|
10835
|
+
* ollama is local, openai-compatible is local when its baseUrl is
|
|
10836
|
+
* loopback/LAN. Set it explicitly to override — e.g. `false` for an Ollama
|
|
10837
|
+
* instance you rent, `true` for a llama.cpp box on your own LAN reached by
|
|
10838
|
+
* hostname.
|
|
10839
|
+
*/
|
|
10840
|
+
local: z.boolean().optional(),
|
|
10841
|
+
/** Region for providers whose price varies by region (Azure: global | us | eu | …). */
|
|
10842
|
+
region: z.string().optional()
|
|
9087
10843
|
});
|
|
9088
10844
|
var ModelOverridesSchema = z.object({
|
|
9089
10845
|
t1: z.string().optional(),
|
|
@@ -9669,8 +11425,8 @@ var TaskAnalyzer = class {
|
|
|
9669
11425
|
}
|
|
9670
11426
|
costEfficiency(model, complexity) {
|
|
9671
11427
|
if (this.tracker) return this.tracker.costEfficiencyScore(model, complexity);
|
|
9672
|
-
const blended = model
|
|
9673
|
-
const normalised = Math.min(1, blended /
|
|
11428
|
+
const blended = blendedCostPer1k(model);
|
|
11429
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
9674
11430
|
const complexityWeight = (6 - complexity) / 5;
|
|
9675
11431
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
9676
11432
|
}
|
|
@@ -9805,8 +11561,8 @@ var ModelPerformanceTracker = class {
|
|
|
9805
11561
|
* normalised over $0.05 blended as the "expensive" ceiling.
|
|
9806
11562
|
*/
|
|
9807
11563
|
costEfficiencyScore(model, complexity) {
|
|
9808
|
-
const blended = model
|
|
9809
|
-
const normalised = Math.min(1, blended /
|
|
11564
|
+
const blended = blendedCostPer1k(model);
|
|
11565
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
9810
11566
|
const complexityWeight = (6 - complexity) / 5;
|
|
9811
11567
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
9812
11568
|
}
|
|
@@ -12649,7 +14405,11 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12649
14405
|
inputTokens: 0,
|
|
12650
14406
|
outputTokens: 0,
|
|
12651
14407
|
totalTokens: stats.totalTokens,
|
|
12652
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
14408
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
14409
|
+
// At least one call ran on a model with no known price, so its spend is
|
|
14410
|
+
// missing from the total above. Say so rather than letting the caller
|
|
14411
|
+
// present an undercount as the final figure.
|
|
14412
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12653
14413
|
},
|
|
12654
14414
|
t2Results,
|
|
12655
14415
|
durationMs,
|
|
@@ -12719,7 +14479,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12719
14479
|
inputTokens: 0,
|
|
12720
14480
|
outputTokens: 0,
|
|
12721
14481
|
totalTokens: stats2.totalTokens,
|
|
12722
|
-
estimatedCostUsd: stats2.totalCostUsd
|
|
14482
|
+
estimatedCostUsd: stats2.totalCostUsd,
|
|
14483
|
+
...stats2.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12723
14484
|
},
|
|
12724
14485
|
t2Results: [],
|
|
12725
14486
|
durationMs: Date.now() - startMs,
|
|
@@ -12743,7 +14504,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
12743
14504
|
inputTokens: result.usage?.inputTokens ?? 0,
|
|
12744
14505
|
outputTokens: result.usage?.outputTokens ?? 0,
|
|
12745
14506
|
totalTokens: stats.totalTokens,
|
|
12746
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
14507
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
14508
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
12747
14509
|
},
|
|
12748
14510
|
t2Results: [],
|
|
12749
14511
|
durationMs: Date.now() - startMs,
|
|
@@ -14527,7 +16289,10 @@ var DashboardServer = class {
|
|
|
14527
16289
|
this.socket.broadcast("cost:update", {
|
|
14528
16290
|
sessionId,
|
|
14529
16291
|
totalTokens: result.usage.totalTokens,
|
|
14530
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
16292
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
16293
|
+
// True when a model with no known price was used: the total above is
|
|
16294
|
+
// an undercount, and the UI must not present it as the full spend.
|
|
16295
|
+
costUnknown: result.usage.costUnknown === true
|
|
14531
16296
|
});
|
|
14532
16297
|
this.throttledBroadcast("workspace");
|
|
14533
16298
|
} catch (err) {
|
|
@@ -14840,7 +16605,8 @@ var DashboardServer = class {
|
|
|
14840
16605
|
this.socket.broadcast("cost:update", {
|
|
14841
16606
|
sessionId,
|
|
14842
16607
|
totalTokens: result.usage.totalTokens,
|
|
14843
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
16608
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
16609
|
+
costUnknown: result.usage.costUnknown === true
|
|
14844
16610
|
});
|
|
14845
16611
|
this.throttledBroadcast("workspace");
|
|
14846
16612
|
} catch (err) {
|
|
@@ -15382,7 +17148,8 @@ ${prompt}`;
|
|
|
15382
17148
|
this.socket.broadcast("cost:update", {
|
|
15383
17149
|
sessionId,
|
|
15384
17150
|
totalTokens: result.usage.totalTokens,
|
|
15385
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
17151
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
17152
|
+
costUnknown: result.usage.costUnknown === true
|
|
15386
17153
|
});
|
|
15387
17154
|
this.socket.broadcastToRoom(`session:${sessionId}`, "session:complete", { sessionId, result });
|
|
15388
17155
|
this.throttledBroadcast("workspace");
|
|
@@ -15938,12 +17705,19 @@ var CloudClient = class _CloudClient {
|
|
|
15938
17705
|
);
|
|
15939
17706
|
await openUrl(authorizeUrl);
|
|
15940
17707
|
const code = await listener.waitForCode;
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
17708
|
+
let res;
|
|
17709
|
+
try {
|
|
17710
|
+
res = await fetch(this.url("/api/native/token"), {
|
|
17711
|
+
method: "POST",
|
|
17712
|
+
headers: { "Content-Type": "application/json" },
|
|
17713
|
+
body: JSON.stringify({ code, code_verifier: verifier })
|
|
17714
|
+
});
|
|
17715
|
+
} catch (err) {
|
|
17716
|
+
throw new Error(
|
|
17717
|
+
`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)})`
|
|
17718
|
+
);
|
|
17719
|
+
}
|
|
17720
|
+
if (!res.ok) throw new Error(await loginFailureMessage(res, this.serverUrl));
|
|
15947
17721
|
const tokens = await res.json();
|
|
15948
17722
|
return await this.finishLogin(tokens);
|
|
15949
17723
|
} finally {
|
|
@@ -16117,6 +17891,22 @@ function sleep(ms, signal) {
|
|
|
16117
17891
|
}, { once: true });
|
|
16118
17892
|
});
|
|
16119
17893
|
}
|
|
17894
|
+
async function loginFailureMessage(res, serverUrl) {
|
|
17895
|
+
const body = await res.text().catch(() => "");
|
|
17896
|
+
let apiError = "";
|
|
17897
|
+
try {
|
|
17898
|
+
apiError = String(JSON.parse(body).error ?? "");
|
|
17899
|
+
} catch {
|
|
17900
|
+
}
|
|
17901
|
+
if (apiError === "invalid_grant") {
|
|
17902
|
+
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.";
|
|
17903
|
+
}
|
|
17904
|
+
if (apiError) return `Sign-in failed: ${apiError} (HTTP ${res.status}).`;
|
|
17905
|
+
if (res.status === 404 || /<html/i.test(body)) {
|
|
17906
|
+
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.`;
|
|
17907
|
+
}
|
|
17908
|
+
return `Sign-in could not be completed (HTTP ${res.status}). Please try again.`;
|
|
17909
|
+
}
|
|
16120
17910
|
function base64url(buf) {
|
|
16121
17911
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
16122
17912
|
}
|