cascade-ai 0.48.1 → 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 +23 -2
- package/dist/cli.cjs +1875 -49
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1875 -49
- package/dist/cli.js.map +1 -1
- package/dist/desktop-core.cjs +1812 -45
- package/dist/index.cjs +1812 -45
- 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 +1812 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -112,11 +112,1688 @@ var __export = (target, all) => {
|
|
|
112
112
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
+
// src/core/router/pricing-data.json
|
|
116
|
+
var pricing_data_default;
|
|
117
|
+
var init_pricing_data = __esm({
|
|
118
|
+
"src/core/router/pricing-data.json"() {
|
|
119
|
+
pricing_data_default = {
|
|
120
|
+
schemaVersion: 1,
|
|
121
|
+
generatedAt: "2026-07-27",
|
|
122
|
+
defaultCurrency: "USD",
|
|
123
|
+
note: 'Authoritative offline baseline for model pricing, keyed by model x provider (x region). All token rates are per 1,000,000 tokens in the entry currency. A live source (see live-data.ts) may override an entry when it is fresher; disagreements are recorded rather than silently accepted. Every entry must carry currency, asOf, source and provenance \u2014 a model with NO entry is priced "unknown", never $0. Regenerate with scripts/refresh-pricing.mjs.',
|
|
124
|
+
provenanceLegend: {
|
|
125
|
+
"vendor-pricing-page": "Read directly from the vendor's own published pricing page (see `source`).",
|
|
126
|
+
"litellm-catalog": "From BerriAI/litellm model_prices_and_context_window.json, which cites the vendor page per entry. Used where the vendor page refused automated access.",
|
|
127
|
+
"seed-approximation": "NOT sourced \u2014 an approximation. No entry in this file currently uses this value; it exists so an approximation can never masquerade as a measured price."
|
|
128
|
+
},
|
|
129
|
+
entries: [
|
|
130
|
+
{
|
|
131
|
+
model: "claude-opus-5",
|
|
132
|
+
provider: "anthropic",
|
|
133
|
+
modality: "text",
|
|
134
|
+
currency: "USD",
|
|
135
|
+
asOf: "2026-07-27",
|
|
136
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
137
|
+
provenance: "vendor-pricing-page",
|
|
138
|
+
tiers: [
|
|
139
|
+
{
|
|
140
|
+
inputPer1m: 5,
|
|
141
|
+
outputPer1m: 25,
|
|
142
|
+
cachedInputPer1m: 0.5,
|
|
143
|
+
cacheWritePer1m: 6.25,
|
|
144
|
+
reasoningOutputPer1m: 25
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
batchMultiplier: 0.5,
|
|
148
|
+
contextWindow: 1e6
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
model: "claude-opus-4-8",
|
|
152
|
+
provider: "anthropic",
|
|
153
|
+
modality: "text",
|
|
154
|
+
currency: "USD",
|
|
155
|
+
asOf: "2026-07-27",
|
|
156
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
157
|
+
provenance: "vendor-pricing-page",
|
|
158
|
+
tiers: [
|
|
159
|
+
{
|
|
160
|
+
inputPer1m: 5,
|
|
161
|
+
outputPer1m: 25,
|
|
162
|
+
cachedInputPer1m: 0.5,
|
|
163
|
+
cacheWritePer1m: 6.25,
|
|
164
|
+
reasoningOutputPer1m: 25
|
|
165
|
+
}
|
|
166
|
+
],
|
|
167
|
+
batchMultiplier: 0.5,
|
|
168
|
+
contextWindow: 1e6
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
model: "claude-opus-4-7",
|
|
172
|
+
provider: "anthropic",
|
|
173
|
+
modality: "text",
|
|
174
|
+
currency: "USD",
|
|
175
|
+
asOf: "2026-07-27",
|
|
176
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
177
|
+
provenance: "vendor-pricing-page",
|
|
178
|
+
tiers: [
|
|
179
|
+
{
|
|
180
|
+
inputPer1m: 5,
|
|
181
|
+
outputPer1m: 25,
|
|
182
|
+
cachedInputPer1m: 0.5,
|
|
183
|
+
cacheWritePer1m: 6.25,
|
|
184
|
+
reasoningOutputPer1m: 25
|
|
185
|
+
}
|
|
186
|
+
],
|
|
187
|
+
batchMultiplier: 0.5,
|
|
188
|
+
contextWindow: 1e6
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
model: "claude-opus-4-6",
|
|
192
|
+
provider: "anthropic",
|
|
193
|
+
modality: "text",
|
|
194
|
+
currency: "USD",
|
|
195
|
+
asOf: "2026-07-27",
|
|
196
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
197
|
+
provenance: "vendor-pricing-page",
|
|
198
|
+
tiers: [
|
|
199
|
+
{
|
|
200
|
+
inputPer1m: 5,
|
|
201
|
+
outputPer1m: 25,
|
|
202
|
+
cachedInputPer1m: 0.5,
|
|
203
|
+
cacheWritePer1m: 6.25,
|
|
204
|
+
reasoningOutputPer1m: 25
|
|
205
|
+
}
|
|
206
|
+
],
|
|
207
|
+
batchMultiplier: 0.5,
|
|
208
|
+
contextWindow: 1e6
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
model: "claude-opus-4-5",
|
|
212
|
+
provider: "anthropic",
|
|
213
|
+
modality: "text",
|
|
214
|
+
currency: "USD",
|
|
215
|
+
asOf: "2026-07-27",
|
|
216
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
217
|
+
provenance: "vendor-pricing-page",
|
|
218
|
+
tiers: [
|
|
219
|
+
{
|
|
220
|
+
inputPer1m: 5,
|
|
221
|
+
outputPer1m: 25,
|
|
222
|
+
cachedInputPer1m: 0.5,
|
|
223
|
+
cacheWritePer1m: 6.25,
|
|
224
|
+
reasoningOutputPer1m: 25
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
batchMultiplier: 0.5,
|
|
228
|
+
contextWindow: 2e5
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
model: "claude-opus-4-1",
|
|
232
|
+
provider: "anthropic",
|
|
233
|
+
modality: "text",
|
|
234
|
+
currency: "USD",
|
|
235
|
+
asOf: "2026-07-27",
|
|
236
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
237
|
+
provenance: "vendor-pricing-page",
|
|
238
|
+
tiers: [
|
|
239
|
+
{
|
|
240
|
+
inputPer1m: 15,
|
|
241
|
+
outputPer1m: 75,
|
|
242
|
+
cachedInputPer1m: 1.5,
|
|
243
|
+
cacheWritePer1m: 18.75,
|
|
244
|
+
reasoningOutputPer1m: 75
|
|
245
|
+
}
|
|
246
|
+
],
|
|
247
|
+
batchMultiplier: 0.5,
|
|
248
|
+
contextWindow: 2e5,
|
|
249
|
+
notes: "Deprecated by Anthropic; priced for historical/cost-reporting accuracy."
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
model: "claude-opus-4",
|
|
253
|
+
provider: "anthropic",
|
|
254
|
+
modality: "text",
|
|
255
|
+
currency: "USD",
|
|
256
|
+
asOf: "2026-07-27",
|
|
257
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
258
|
+
provenance: "vendor-pricing-page",
|
|
259
|
+
tiers: [
|
|
260
|
+
{
|
|
261
|
+
inputPer1m: 15,
|
|
262
|
+
outputPer1m: 75,
|
|
263
|
+
cachedInputPer1m: 1.5,
|
|
264
|
+
cacheWritePer1m: 18.75,
|
|
265
|
+
reasoningOutputPer1m: 75
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
batchMultiplier: 0.5,
|
|
269
|
+
contextWindow: 2e5,
|
|
270
|
+
notes: "Retired except on Google Cloud; priced for historical/cost-reporting accuracy."
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
model: "claude-sonnet-5",
|
|
274
|
+
provider: "anthropic",
|
|
275
|
+
modality: "text",
|
|
276
|
+
currency: "USD",
|
|
277
|
+
asOf: "2026-07-27",
|
|
278
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
279
|
+
provenance: "vendor-pricing-page",
|
|
280
|
+
tiers: [
|
|
281
|
+
{
|
|
282
|
+
inputPer1m: 2,
|
|
283
|
+
outputPer1m: 10,
|
|
284
|
+
cachedInputPer1m: 0.2,
|
|
285
|
+
cacheWritePer1m: 2.5,
|
|
286
|
+
reasoningOutputPer1m: 10
|
|
287
|
+
}
|
|
288
|
+
],
|
|
289
|
+
batchMultiplier: 0.5,
|
|
290
|
+
contextWindow: 1e6,
|
|
291
|
+
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."
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
model: "claude-sonnet-4-6",
|
|
295
|
+
provider: "anthropic",
|
|
296
|
+
modality: "text",
|
|
297
|
+
currency: "USD",
|
|
298
|
+
asOf: "2026-07-27",
|
|
299
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
300
|
+
provenance: "vendor-pricing-page",
|
|
301
|
+
tiers: [
|
|
302
|
+
{
|
|
303
|
+
inputPer1m: 3,
|
|
304
|
+
outputPer1m: 15,
|
|
305
|
+
cachedInputPer1m: 0.3,
|
|
306
|
+
cacheWritePer1m: 3.75,
|
|
307
|
+
reasoningOutputPer1m: 15
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
batchMultiplier: 0.5,
|
|
311
|
+
contextWindow: 1e6
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
model: "claude-sonnet-4-5",
|
|
315
|
+
provider: "anthropic",
|
|
316
|
+
modality: "text",
|
|
317
|
+
currency: "USD",
|
|
318
|
+
asOf: "2026-07-27",
|
|
319
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
320
|
+
provenance: "vendor-pricing-page",
|
|
321
|
+
tiers: [
|
|
322
|
+
{
|
|
323
|
+
maxInputTokens: 2e5,
|
|
324
|
+
inputPer1m: 3,
|
|
325
|
+
outputPer1m: 15,
|
|
326
|
+
cachedInputPer1m: 0.3,
|
|
327
|
+
cacheWritePer1m: 3.75,
|
|
328
|
+
reasoningOutputPer1m: 15
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
inputPer1m: 6,
|
|
332
|
+
outputPer1m: 22.5,
|
|
333
|
+
cachedInputPer1m: 0.6,
|
|
334
|
+
cacheWritePer1m: 7.5,
|
|
335
|
+
reasoningOutputPer1m: 22.5
|
|
336
|
+
}
|
|
337
|
+
],
|
|
338
|
+
batchMultiplier: 0.5,
|
|
339
|
+
contextWindow: 2e5,
|
|
340
|
+
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)."
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
model: "claude-sonnet-4",
|
|
344
|
+
provider: "anthropic",
|
|
345
|
+
modality: "text",
|
|
346
|
+
currency: "USD",
|
|
347
|
+
asOf: "2026-07-27",
|
|
348
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
349
|
+
provenance: "vendor-pricing-page",
|
|
350
|
+
tiers: [
|
|
351
|
+
{
|
|
352
|
+
inputPer1m: 3,
|
|
353
|
+
outputPer1m: 15,
|
|
354
|
+
cachedInputPer1m: 0.3,
|
|
355
|
+
cacheWritePer1m: 3.75,
|
|
356
|
+
reasoningOutputPer1m: 15
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
batchMultiplier: 0.5,
|
|
360
|
+
contextWindow: 2e5
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
model: "claude-haiku-4-5",
|
|
364
|
+
provider: "anthropic",
|
|
365
|
+
modality: "text",
|
|
366
|
+
currency: "USD",
|
|
367
|
+
asOf: "2026-07-27",
|
|
368
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
369
|
+
provenance: "vendor-pricing-page",
|
|
370
|
+
tiers: [
|
|
371
|
+
{
|
|
372
|
+
inputPer1m: 1,
|
|
373
|
+
outputPer1m: 5,
|
|
374
|
+
cachedInputPer1m: 0.1,
|
|
375
|
+
cacheWritePer1m: 1.25,
|
|
376
|
+
reasoningOutputPer1m: 5
|
|
377
|
+
}
|
|
378
|
+
],
|
|
379
|
+
batchMultiplier: 0.5,
|
|
380
|
+
contextWindow: 2e5
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
model: "claude-haiku-3-5",
|
|
384
|
+
provider: "anthropic",
|
|
385
|
+
modality: "text",
|
|
386
|
+
currency: "USD",
|
|
387
|
+
asOf: "2026-07-27",
|
|
388
|
+
source: "https://platform.claude.com/docs/en/about-claude/pricing",
|
|
389
|
+
provenance: "vendor-pricing-page",
|
|
390
|
+
tiers: [
|
|
391
|
+
{
|
|
392
|
+
inputPer1m: 0.8,
|
|
393
|
+
outputPer1m: 4,
|
|
394
|
+
cachedInputPer1m: 0.08,
|
|
395
|
+
cacheWritePer1m: 1,
|
|
396
|
+
reasoningOutputPer1m: 4
|
|
397
|
+
}
|
|
398
|
+
],
|
|
399
|
+
batchMultiplier: 0.5,
|
|
400
|
+
contextWindow: 2e5
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
model: "gpt-5.6-sol",
|
|
404
|
+
provider: "openai",
|
|
405
|
+
aliases: [
|
|
406
|
+
"gpt-5.6"
|
|
407
|
+
],
|
|
408
|
+
modality: "text",
|
|
409
|
+
currency: "USD",
|
|
410
|
+
asOf: "2026-07-27",
|
|
411
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
412
|
+
provenance: "litellm-catalog",
|
|
413
|
+
tiers: [
|
|
414
|
+
{
|
|
415
|
+
maxInputTokens: 272e3,
|
|
416
|
+
inputPer1m: 5,
|
|
417
|
+
outputPer1m: 30,
|
|
418
|
+
cachedInputPer1m: 0.5,
|
|
419
|
+
cacheWritePer1m: 6.25
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
inputPer1m: 10,
|
|
423
|
+
outputPer1m: 45,
|
|
424
|
+
cachedInputPer1m: 1,
|
|
425
|
+
cacheWritePer1m: 12.5
|
|
426
|
+
}
|
|
427
|
+
],
|
|
428
|
+
batchMultiplier: 0.5,
|
|
429
|
+
contextWindow: 105e4
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
model: "gpt-5.6-terra",
|
|
433
|
+
provider: "openai",
|
|
434
|
+
modality: "text",
|
|
435
|
+
currency: "USD",
|
|
436
|
+
asOf: "2026-07-27",
|
|
437
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
438
|
+
provenance: "litellm-catalog",
|
|
439
|
+
tiers: [
|
|
440
|
+
{
|
|
441
|
+
maxInputTokens: 272e3,
|
|
442
|
+
inputPer1m: 2.5,
|
|
443
|
+
outputPer1m: 15,
|
|
444
|
+
cachedInputPer1m: 0.25,
|
|
445
|
+
cacheWritePer1m: 3.125
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
inputPer1m: 5,
|
|
449
|
+
outputPer1m: 22.5,
|
|
450
|
+
cachedInputPer1m: 0.5,
|
|
451
|
+
cacheWritePer1m: 6.25
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
batchMultiplier: 0.5,
|
|
455
|
+
contextWindow: 105e4
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
model: "gpt-5.6-luna",
|
|
459
|
+
provider: "openai",
|
|
460
|
+
modality: "text",
|
|
461
|
+
currency: "USD",
|
|
462
|
+
asOf: "2026-07-27",
|
|
463
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
464
|
+
provenance: "litellm-catalog",
|
|
465
|
+
tiers: [
|
|
466
|
+
{
|
|
467
|
+
maxInputTokens: 272e3,
|
|
468
|
+
inputPer1m: 1,
|
|
469
|
+
outputPer1m: 6,
|
|
470
|
+
cachedInputPer1m: 0.1,
|
|
471
|
+
cacheWritePer1m: 1.25
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
inputPer1m: 2,
|
|
475
|
+
outputPer1m: 9,
|
|
476
|
+
cachedInputPer1m: 0.2,
|
|
477
|
+
cacheWritePer1m: 2.5
|
|
478
|
+
}
|
|
479
|
+
],
|
|
480
|
+
batchMultiplier: 0.5,
|
|
481
|
+
contextWindow: 105e4
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
model: "gpt-5.5",
|
|
485
|
+
provider: "openai",
|
|
486
|
+
modality: "text",
|
|
487
|
+
currency: "USD",
|
|
488
|
+
asOf: "2026-07-27",
|
|
489
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
490
|
+
provenance: "litellm-catalog",
|
|
491
|
+
tiers: [
|
|
492
|
+
{
|
|
493
|
+
maxInputTokens: 272e3,
|
|
494
|
+
inputPer1m: 5,
|
|
495
|
+
outputPer1m: 30,
|
|
496
|
+
cachedInputPer1m: 0.5
|
|
497
|
+
},
|
|
498
|
+
{
|
|
499
|
+
inputPer1m: 10,
|
|
500
|
+
outputPer1m: 45,
|
|
501
|
+
cachedInputPer1m: 1
|
|
502
|
+
}
|
|
503
|
+
],
|
|
504
|
+
batchMultiplier: 0.5,
|
|
505
|
+
contextWindow: 105e4
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
model: "gpt-5.4",
|
|
509
|
+
provider: "openai",
|
|
510
|
+
modality: "text",
|
|
511
|
+
currency: "USD",
|
|
512
|
+
asOf: "2026-07-27",
|
|
513
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
514
|
+
provenance: "litellm-catalog",
|
|
515
|
+
tiers: [
|
|
516
|
+
{
|
|
517
|
+
maxInputTokens: 272e3,
|
|
518
|
+
inputPer1m: 2.5,
|
|
519
|
+
outputPer1m: 15,
|
|
520
|
+
cachedInputPer1m: 0.25
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
inputPer1m: 5,
|
|
524
|
+
outputPer1m: 22.5,
|
|
525
|
+
cachedInputPer1m: 0.5
|
|
526
|
+
}
|
|
527
|
+
],
|
|
528
|
+
batchMultiplier: 0.5,
|
|
529
|
+
contextWindow: 105e4
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
model: "gpt-5.4-mini",
|
|
533
|
+
provider: "openai",
|
|
534
|
+
modality: "text",
|
|
535
|
+
currency: "USD",
|
|
536
|
+
asOf: "2026-07-27",
|
|
537
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
538
|
+
provenance: "litellm-catalog",
|
|
539
|
+
tiers: [
|
|
540
|
+
{
|
|
541
|
+
inputPer1m: 0.75,
|
|
542
|
+
outputPer1m: 4.5,
|
|
543
|
+
cachedInputPer1m: 0.075
|
|
544
|
+
}
|
|
545
|
+
],
|
|
546
|
+
batchMultiplier: 0.5,
|
|
547
|
+
contextWindow: 105e4
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
model: "gpt-5",
|
|
551
|
+
provider: "openai",
|
|
552
|
+
modality: "text",
|
|
553
|
+
currency: "USD",
|
|
554
|
+
asOf: "2026-07-27",
|
|
555
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
556
|
+
provenance: "litellm-catalog",
|
|
557
|
+
tiers: [
|
|
558
|
+
{
|
|
559
|
+
inputPer1m: 1.25,
|
|
560
|
+
outputPer1m: 10,
|
|
561
|
+
cachedInputPer1m: 0.125
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
contextWindow: 272e3
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
model: "gpt-5-mini",
|
|
568
|
+
provider: "openai",
|
|
569
|
+
modality: "text",
|
|
570
|
+
currency: "USD",
|
|
571
|
+
asOf: "2026-07-27",
|
|
572
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
573
|
+
provenance: "litellm-catalog",
|
|
574
|
+
tiers: [
|
|
575
|
+
{
|
|
576
|
+
inputPer1m: 0.25,
|
|
577
|
+
outputPer1m: 2,
|
|
578
|
+
cachedInputPer1m: 0.025
|
|
579
|
+
}
|
|
580
|
+
],
|
|
581
|
+
contextWindow: 272e3
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
model: "gpt-5-nano",
|
|
585
|
+
provider: "openai",
|
|
586
|
+
modality: "text",
|
|
587
|
+
currency: "USD",
|
|
588
|
+
asOf: "2026-07-27",
|
|
589
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
590
|
+
provenance: "litellm-catalog",
|
|
591
|
+
tiers: [
|
|
592
|
+
{
|
|
593
|
+
inputPer1m: 0.05,
|
|
594
|
+
outputPer1m: 0.4,
|
|
595
|
+
cachedInputPer1m: 5e-3
|
|
596
|
+
}
|
|
597
|
+
],
|
|
598
|
+
contextWindow: 272e3
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
model: "gpt-4.1",
|
|
602
|
+
provider: "openai",
|
|
603
|
+
modality: "text",
|
|
604
|
+
currency: "USD",
|
|
605
|
+
asOf: "2026-07-27",
|
|
606
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
607
|
+
provenance: "litellm-catalog",
|
|
608
|
+
tiers: [
|
|
609
|
+
{
|
|
610
|
+
inputPer1m: 2,
|
|
611
|
+
outputPer1m: 8,
|
|
612
|
+
cachedInputPer1m: 0.5
|
|
613
|
+
}
|
|
614
|
+
],
|
|
615
|
+
batchMultiplier: 0.5,
|
|
616
|
+
contextWindow: 1047576
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
model: "gpt-4.1-mini",
|
|
620
|
+
provider: "openai",
|
|
621
|
+
modality: "text",
|
|
622
|
+
currency: "USD",
|
|
623
|
+
asOf: "2026-07-27",
|
|
624
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
625
|
+
provenance: "litellm-catalog",
|
|
626
|
+
tiers: [
|
|
627
|
+
{
|
|
628
|
+
inputPer1m: 0.4,
|
|
629
|
+
outputPer1m: 1.6,
|
|
630
|
+
cachedInputPer1m: 0.1
|
|
631
|
+
}
|
|
632
|
+
],
|
|
633
|
+
batchMultiplier: 0.5,
|
|
634
|
+
contextWindow: 1047576
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
model: "gpt-4.1-nano",
|
|
638
|
+
provider: "openai",
|
|
639
|
+
modality: "text",
|
|
640
|
+
currency: "USD",
|
|
641
|
+
asOf: "2026-07-27",
|
|
642
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
643
|
+
provenance: "litellm-catalog",
|
|
644
|
+
tiers: [
|
|
645
|
+
{
|
|
646
|
+
inputPer1m: 0.1,
|
|
647
|
+
outputPer1m: 0.4,
|
|
648
|
+
cachedInputPer1m: 0.025
|
|
649
|
+
}
|
|
650
|
+
],
|
|
651
|
+
batchMultiplier: 0.5,
|
|
652
|
+
contextWindow: 1047576
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
model: "gpt-4o",
|
|
656
|
+
provider: "openai",
|
|
657
|
+
modality: "text",
|
|
658
|
+
currency: "USD",
|
|
659
|
+
asOf: "2026-07-27",
|
|
660
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
661
|
+
provenance: "litellm-catalog",
|
|
662
|
+
tiers: [
|
|
663
|
+
{
|
|
664
|
+
inputPer1m: 2.5,
|
|
665
|
+
outputPer1m: 10,
|
|
666
|
+
cachedInputPer1m: 1.25
|
|
667
|
+
}
|
|
668
|
+
],
|
|
669
|
+
batchMultiplier: 0.5,
|
|
670
|
+
contextWindow: 128e3
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
model: "gpt-4o-mini",
|
|
674
|
+
provider: "openai",
|
|
675
|
+
modality: "text",
|
|
676
|
+
currency: "USD",
|
|
677
|
+
asOf: "2026-07-27",
|
|
678
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
679
|
+
provenance: "litellm-catalog",
|
|
680
|
+
tiers: [
|
|
681
|
+
{
|
|
682
|
+
inputPer1m: 0.15,
|
|
683
|
+
outputPer1m: 0.6,
|
|
684
|
+
cachedInputPer1m: 0.075
|
|
685
|
+
}
|
|
686
|
+
],
|
|
687
|
+
batchMultiplier: 0.5,
|
|
688
|
+
contextWindow: 128e3
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
model: "gpt-5.5",
|
|
692
|
+
provider: "azure",
|
|
693
|
+
region: "global",
|
|
694
|
+
modality: "text",
|
|
695
|
+
currency: "USD",
|
|
696
|
+
asOf: "2026-07-27",
|
|
697
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
698
|
+
provenance: "litellm-catalog",
|
|
699
|
+
tiers: [
|
|
700
|
+
{
|
|
701
|
+
maxInputTokens: 272e3,
|
|
702
|
+
inputPer1m: 5,
|
|
703
|
+
outputPer1m: 30,
|
|
704
|
+
cachedInputPer1m: 0.5
|
|
705
|
+
},
|
|
706
|
+
{
|
|
707
|
+
inputPer1m: 10,
|
|
708
|
+
outputPer1m: 45,
|
|
709
|
+
cachedInputPer1m: 1
|
|
710
|
+
}
|
|
711
|
+
],
|
|
712
|
+
contextWindow: 105e4
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
model: "gpt-5.5",
|
|
716
|
+
provider: "azure",
|
|
717
|
+
region: "us",
|
|
718
|
+
modality: "text",
|
|
719
|
+
currency: "USD",
|
|
720
|
+
asOf: "2026-07-27",
|
|
721
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
722
|
+
provenance: "litellm-catalog",
|
|
723
|
+
tiers: [
|
|
724
|
+
{
|
|
725
|
+
maxInputTokens: 272e3,
|
|
726
|
+
inputPer1m: 5.5,
|
|
727
|
+
outputPer1m: 33,
|
|
728
|
+
cachedInputPer1m: 0.55
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
inputPer1m: 11,
|
|
732
|
+
outputPer1m: 49.5,
|
|
733
|
+
cachedInputPer1m: 1.1
|
|
734
|
+
}
|
|
735
|
+
],
|
|
736
|
+
contextWindow: 105e4
|
|
737
|
+
},
|
|
738
|
+
{
|
|
739
|
+
model: "gpt-5.5",
|
|
740
|
+
provider: "azure",
|
|
741
|
+
region: "eu",
|
|
742
|
+
modality: "text",
|
|
743
|
+
currency: "USD",
|
|
744
|
+
asOf: "2026-07-27",
|
|
745
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
746
|
+
provenance: "litellm-catalog",
|
|
747
|
+
tiers: [
|
|
748
|
+
{
|
|
749
|
+
maxInputTokens: 272e3,
|
|
750
|
+
inputPer1m: 5.5,
|
|
751
|
+
outputPer1m: 33,
|
|
752
|
+
cachedInputPer1m: 0.55
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
inputPer1m: 11,
|
|
756
|
+
outputPer1m: 49.5,
|
|
757
|
+
cachedInputPer1m: 1.1
|
|
758
|
+
}
|
|
759
|
+
],
|
|
760
|
+
contextWindow: 105e4
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
model: "gpt-5.4",
|
|
764
|
+
provider: "azure",
|
|
765
|
+
region: "global",
|
|
766
|
+
modality: "text",
|
|
767
|
+
currency: "USD",
|
|
768
|
+
asOf: "2026-07-27",
|
|
769
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
770
|
+
provenance: "litellm-catalog",
|
|
771
|
+
tiers: [
|
|
772
|
+
{
|
|
773
|
+
maxInputTokens: 272e3,
|
|
774
|
+
inputPer1m: 2.5,
|
|
775
|
+
outputPer1m: 15,
|
|
776
|
+
cachedInputPer1m: 0.25
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
inputPer1m: 5,
|
|
780
|
+
outputPer1m: 22.5,
|
|
781
|
+
cachedInputPer1m: 0.5
|
|
782
|
+
}
|
|
783
|
+
],
|
|
784
|
+
contextWindow: 105e4
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
model: "gpt-5.4",
|
|
788
|
+
provider: "azure",
|
|
789
|
+
region: "us",
|
|
790
|
+
modality: "text",
|
|
791
|
+
currency: "USD",
|
|
792
|
+
asOf: "2026-07-27",
|
|
793
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
794
|
+
provenance: "litellm-catalog",
|
|
795
|
+
tiers: [
|
|
796
|
+
{
|
|
797
|
+
inputPer1m: 2.75,
|
|
798
|
+
outputPer1m: 16.5,
|
|
799
|
+
cachedInputPer1m: 0.28
|
|
800
|
+
}
|
|
801
|
+
],
|
|
802
|
+
contextWindow: 105e4
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
model: "gpt-5.4",
|
|
806
|
+
provider: "azure",
|
|
807
|
+
region: "eu",
|
|
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
|
+
inputPer1m: 2.75,
|
|
816
|
+
outputPer1m: 16.5,
|
|
817
|
+
cachedInputPer1m: 0.28
|
|
818
|
+
}
|
|
819
|
+
],
|
|
820
|
+
contextWindow: 105e4
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
model: "gpt-5.6-terra",
|
|
824
|
+
provider: "azure",
|
|
825
|
+
region: "global",
|
|
826
|
+
modality: "text",
|
|
827
|
+
currency: "USD",
|
|
828
|
+
asOf: "2026-07-27",
|
|
829
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
830
|
+
provenance: "litellm-catalog",
|
|
831
|
+
tiers: [
|
|
832
|
+
{
|
|
833
|
+
maxInputTokens: 272e3,
|
|
834
|
+
inputPer1m: 2.5,
|
|
835
|
+
outputPer1m: 15,
|
|
836
|
+
cachedInputPer1m: 0.25
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
inputPer1m: 5,
|
|
840
|
+
outputPer1m: 22.5,
|
|
841
|
+
cachedInputPer1m: 0.5
|
|
842
|
+
}
|
|
843
|
+
],
|
|
844
|
+
contextWindow: 105e4
|
|
845
|
+
},
|
|
846
|
+
{
|
|
847
|
+
model: "gpt-5.6-terra",
|
|
848
|
+
provider: "azure",
|
|
849
|
+
region: "eu",
|
|
850
|
+
modality: "text",
|
|
851
|
+
currency: "USD",
|
|
852
|
+
asOf: "2026-07-27",
|
|
853
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
854
|
+
provenance: "litellm-catalog",
|
|
855
|
+
tiers: [
|
|
856
|
+
{
|
|
857
|
+
maxInputTokens: 272e3,
|
|
858
|
+
inputPer1m: 2.75,
|
|
859
|
+
outputPer1m: 16.5,
|
|
860
|
+
cachedInputPer1m: 0.275
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
inputPer1m: 5.5,
|
|
864
|
+
outputPer1m: 24.75,
|
|
865
|
+
cachedInputPer1m: 0.55
|
|
866
|
+
}
|
|
867
|
+
],
|
|
868
|
+
contextWindow: 105e4
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
model: "gpt-5",
|
|
872
|
+
provider: "azure",
|
|
873
|
+
region: "global",
|
|
874
|
+
modality: "text",
|
|
875
|
+
currency: "USD",
|
|
876
|
+
asOf: "2026-07-27",
|
|
877
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
878
|
+
provenance: "litellm-catalog",
|
|
879
|
+
tiers: [
|
|
880
|
+
{
|
|
881
|
+
inputPer1m: 1.25,
|
|
882
|
+
outputPer1m: 10,
|
|
883
|
+
cachedInputPer1m: 0.125
|
|
884
|
+
}
|
|
885
|
+
],
|
|
886
|
+
contextWindow: 272e3
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
model: "gpt-5-mini",
|
|
890
|
+
provider: "azure",
|
|
891
|
+
region: "global",
|
|
892
|
+
modality: "text",
|
|
893
|
+
currency: "USD",
|
|
894
|
+
asOf: "2026-07-27",
|
|
895
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
896
|
+
provenance: "litellm-catalog",
|
|
897
|
+
tiers: [
|
|
898
|
+
{
|
|
899
|
+
inputPer1m: 0.25,
|
|
900
|
+
outputPer1m: 2,
|
|
901
|
+
cachedInputPer1m: 0.025
|
|
902
|
+
}
|
|
903
|
+
],
|
|
904
|
+
contextWindow: 272e3
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
model: "gpt-5-nano",
|
|
908
|
+
provider: "azure",
|
|
909
|
+
region: "global",
|
|
910
|
+
modality: "text",
|
|
911
|
+
currency: "USD",
|
|
912
|
+
asOf: "2026-07-27",
|
|
913
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
914
|
+
provenance: "litellm-catalog",
|
|
915
|
+
tiers: [
|
|
916
|
+
{
|
|
917
|
+
inputPer1m: 0.05,
|
|
918
|
+
outputPer1m: 0.4,
|
|
919
|
+
cachedInputPer1m: 5e-3
|
|
920
|
+
}
|
|
921
|
+
],
|
|
922
|
+
contextWindow: 272e3
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
model: "gpt-4.1",
|
|
926
|
+
provider: "azure",
|
|
927
|
+
region: "global",
|
|
928
|
+
modality: "text",
|
|
929
|
+
currency: "USD",
|
|
930
|
+
asOf: "2026-07-27",
|
|
931
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
932
|
+
provenance: "litellm-catalog",
|
|
933
|
+
tiers: [
|
|
934
|
+
{
|
|
935
|
+
inputPer1m: 2,
|
|
936
|
+
outputPer1m: 8,
|
|
937
|
+
cachedInputPer1m: 0.5
|
|
938
|
+
}
|
|
939
|
+
],
|
|
940
|
+
batchMultiplier: 0.5,
|
|
941
|
+
contextWindow: 1047576
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
model: "gpt-4o",
|
|
945
|
+
provider: "azure",
|
|
946
|
+
region: "global",
|
|
947
|
+
modality: "text",
|
|
948
|
+
currency: "USD",
|
|
949
|
+
asOf: "2026-07-27",
|
|
950
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
951
|
+
provenance: "litellm-catalog",
|
|
952
|
+
tiers: [
|
|
953
|
+
{
|
|
954
|
+
inputPer1m: 2.5,
|
|
955
|
+
outputPer1m: 10,
|
|
956
|
+
cachedInputPer1m: 1.25
|
|
957
|
+
}
|
|
958
|
+
],
|
|
959
|
+
contextWindow: 128e3
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
model: "gpt-4o-mini",
|
|
963
|
+
provider: "azure",
|
|
964
|
+
region: "global",
|
|
965
|
+
modality: "text",
|
|
966
|
+
currency: "USD",
|
|
967
|
+
asOf: "2026-07-27",
|
|
968
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
969
|
+
provenance: "litellm-catalog",
|
|
970
|
+
tiers: [
|
|
971
|
+
{
|
|
972
|
+
inputPer1m: 0.165,
|
|
973
|
+
outputPer1m: 0.66,
|
|
974
|
+
cachedInputPer1m: 0.075
|
|
975
|
+
}
|
|
976
|
+
],
|
|
977
|
+
contextWindow: 128e3,
|
|
978
|
+
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."
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
model: "gemini-3.1-pro",
|
|
982
|
+
provider: "gemini",
|
|
983
|
+
aliases: [
|
|
984
|
+
"gemini-3.1-pro-preview"
|
|
985
|
+
],
|
|
986
|
+
modality: "text",
|
|
987
|
+
currency: "USD",
|
|
988
|
+
asOf: "2026-07-27",
|
|
989
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
990
|
+
provenance: "vendor-pricing-page",
|
|
991
|
+
tiers: [
|
|
992
|
+
{
|
|
993
|
+
maxInputTokens: 2e5,
|
|
994
|
+
inputPer1m: 2,
|
|
995
|
+
outputPer1m: 12,
|
|
996
|
+
cachedInputPer1m: 0.2,
|
|
997
|
+
reasoningOutputPer1m: 12
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
inputPer1m: 4,
|
|
1001
|
+
outputPer1m: 18,
|
|
1002
|
+
cachedInputPer1m: 0.4,
|
|
1003
|
+
reasoningOutputPer1m: 18
|
|
1004
|
+
}
|
|
1005
|
+
],
|
|
1006
|
+
batchMultiplier: 0.5,
|
|
1007
|
+
contextWindow: 1048576,
|
|
1008
|
+
notes: "Long-context tier: $2/$12 per 1M up to 200K prompt tokens, $4/$18 above it."
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
model: "gemini-3-pro",
|
|
1012
|
+
provider: "gemini",
|
|
1013
|
+
aliases: [
|
|
1014
|
+
"gemini-3-pro-preview"
|
|
1015
|
+
],
|
|
1016
|
+
modality: "text",
|
|
1017
|
+
currency: "USD",
|
|
1018
|
+
asOf: "2026-07-27",
|
|
1019
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1020
|
+
provenance: "vendor-pricing-page",
|
|
1021
|
+
tiers: [
|
|
1022
|
+
{
|
|
1023
|
+
maxInputTokens: 2e5,
|
|
1024
|
+
inputPer1m: 2,
|
|
1025
|
+
outputPer1m: 12,
|
|
1026
|
+
cachedInputPer1m: 0.2,
|
|
1027
|
+
reasoningOutputPer1m: 12
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
inputPer1m: 4,
|
|
1031
|
+
outputPer1m: 18,
|
|
1032
|
+
cachedInputPer1m: 0.4,
|
|
1033
|
+
reasoningOutputPer1m: 18
|
|
1034
|
+
}
|
|
1035
|
+
],
|
|
1036
|
+
batchMultiplier: 0.5,
|
|
1037
|
+
contextWindow: 1048576
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
model: "gemini-3.6-flash",
|
|
1041
|
+
provider: "gemini",
|
|
1042
|
+
modality: "text",
|
|
1043
|
+
currency: "USD",
|
|
1044
|
+
asOf: "2026-07-27",
|
|
1045
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1046
|
+
provenance: "vendor-pricing-page",
|
|
1047
|
+
tiers: [
|
|
1048
|
+
{
|
|
1049
|
+
inputPer1m: 1.5,
|
|
1050
|
+
outputPer1m: 7.5,
|
|
1051
|
+
cachedInputPer1m: 0.15,
|
|
1052
|
+
reasoningOutputPer1m: 7.5
|
|
1053
|
+
}
|
|
1054
|
+
],
|
|
1055
|
+
batchMultiplier: 0.5,
|
|
1056
|
+
contextWindow: 1048576,
|
|
1057
|
+
notes: "Released 2026-07-21. Output pricing dropped ~17% from Gemini 3.5 Flash ($9.00 -> $7.50 per 1M); input unchanged."
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
model: "gemini-3.5-flash",
|
|
1061
|
+
provider: "gemini",
|
|
1062
|
+
modality: "text",
|
|
1063
|
+
currency: "USD",
|
|
1064
|
+
asOf: "2026-07-27",
|
|
1065
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1066
|
+
provenance: "vendor-pricing-page",
|
|
1067
|
+
tiers: [
|
|
1068
|
+
{
|
|
1069
|
+
inputPer1m: 1.5,
|
|
1070
|
+
outputPer1m: 9,
|
|
1071
|
+
cachedInputPer1m: 0.15,
|
|
1072
|
+
reasoningOutputPer1m: 9
|
|
1073
|
+
}
|
|
1074
|
+
],
|
|
1075
|
+
batchMultiplier: 0.5,
|
|
1076
|
+
contextWindow: 1048576
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
model: "gemini-3.5-flash-lite",
|
|
1080
|
+
provider: "gemini",
|
|
1081
|
+
modality: "text",
|
|
1082
|
+
currency: "USD",
|
|
1083
|
+
asOf: "2026-07-27",
|
|
1084
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1085
|
+
provenance: "litellm-catalog",
|
|
1086
|
+
tiers: [
|
|
1087
|
+
{
|
|
1088
|
+
inputPer1m: 0.3,
|
|
1089
|
+
outputPer1m: 2.5,
|
|
1090
|
+
cachedInputPer1m: 0.03,
|
|
1091
|
+
reasoningOutputPer1m: 2.5
|
|
1092
|
+
}
|
|
1093
|
+
],
|
|
1094
|
+
batchMultiplier: 0.5,
|
|
1095
|
+
contextWindow: 1048576
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
model: "gemini-3.1-flash-lite",
|
|
1099
|
+
provider: "gemini",
|
|
1100
|
+
modality: "text",
|
|
1101
|
+
currency: "USD",
|
|
1102
|
+
asOf: "2026-07-27",
|
|
1103
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite",
|
|
1104
|
+
provenance: "litellm-catalog",
|
|
1105
|
+
tiers: [
|
|
1106
|
+
{
|
|
1107
|
+
inputPer1m: 0.25,
|
|
1108
|
+
outputPer1m: 1.5,
|
|
1109
|
+
cachedInputPer1m: 0.025,
|
|
1110
|
+
reasoningOutputPer1m: 1.5
|
|
1111
|
+
}
|
|
1112
|
+
],
|
|
1113
|
+
batchMultiplier: 0.5,
|
|
1114
|
+
contextWindow: 1048576
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
model: "gemini-3-flash",
|
|
1118
|
+
provider: "gemini",
|
|
1119
|
+
aliases: [
|
|
1120
|
+
"gemini-3-flash-preview"
|
|
1121
|
+
],
|
|
1122
|
+
modality: "text",
|
|
1123
|
+
currency: "USD",
|
|
1124
|
+
asOf: "2026-07-27",
|
|
1125
|
+
source: "https://ai.google.dev/pricing/gemini-3",
|
|
1126
|
+
provenance: "litellm-catalog",
|
|
1127
|
+
tiers: [
|
|
1128
|
+
{
|
|
1129
|
+
inputPer1m: 0.5,
|
|
1130
|
+
outputPer1m: 3,
|
|
1131
|
+
cachedInputPer1m: 0.05,
|
|
1132
|
+
reasoningOutputPer1m: 3
|
|
1133
|
+
}
|
|
1134
|
+
],
|
|
1135
|
+
contextWindow: 1048576
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
model: "gemini-2.5-pro",
|
|
1139
|
+
provider: "gemini",
|
|
1140
|
+
modality: "text",
|
|
1141
|
+
currency: "USD",
|
|
1142
|
+
asOf: "2026-07-27",
|
|
1143
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1144
|
+
provenance: "litellm-catalog",
|
|
1145
|
+
tiers: [
|
|
1146
|
+
{
|
|
1147
|
+
maxInputTokens: 2e5,
|
|
1148
|
+
inputPer1m: 1.25,
|
|
1149
|
+
outputPer1m: 10,
|
|
1150
|
+
cachedInputPer1m: 0.125
|
|
1151
|
+
},
|
|
1152
|
+
{
|
|
1153
|
+
inputPer1m: 2.5,
|
|
1154
|
+
outputPer1m: 15,
|
|
1155
|
+
cachedInputPer1m: 0.25
|
|
1156
|
+
}
|
|
1157
|
+
],
|
|
1158
|
+
contextWindow: 1048576
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
model: "gemini-2.5-flash",
|
|
1162
|
+
provider: "gemini",
|
|
1163
|
+
modality: "text",
|
|
1164
|
+
currency: "USD",
|
|
1165
|
+
asOf: "2026-07-27",
|
|
1166
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-preview",
|
|
1167
|
+
provenance: "litellm-catalog",
|
|
1168
|
+
tiers: [
|
|
1169
|
+
{
|
|
1170
|
+
inputPer1m: 0.3,
|
|
1171
|
+
outputPer1m: 2.5,
|
|
1172
|
+
cachedInputPer1m: 0.03,
|
|
1173
|
+
reasoningOutputPer1m: 2.5
|
|
1174
|
+
}
|
|
1175
|
+
],
|
|
1176
|
+
contextWindow: 1048576
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
model: "gemini-2.5-flash-lite",
|
|
1180
|
+
provider: "gemini",
|
|
1181
|
+
modality: "text",
|
|
1182
|
+
currency: "USD",
|
|
1183
|
+
asOf: "2026-07-27",
|
|
1184
|
+
source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-lite",
|
|
1185
|
+
provenance: "litellm-catalog",
|
|
1186
|
+
tiers: [
|
|
1187
|
+
{
|
|
1188
|
+
inputPer1m: 0.1,
|
|
1189
|
+
outputPer1m: 0.4,
|
|
1190
|
+
cachedInputPer1m: 0.01,
|
|
1191
|
+
reasoningOutputPer1m: 0.4
|
|
1192
|
+
}
|
|
1193
|
+
],
|
|
1194
|
+
contextWindow: 1048576
|
|
1195
|
+
},
|
|
1196
|
+
{
|
|
1197
|
+
model: "gemini-2.0-flash",
|
|
1198
|
+
provider: "gemini",
|
|
1199
|
+
modality: "text",
|
|
1200
|
+
currency: "USD",
|
|
1201
|
+
asOf: "2026-07-27",
|
|
1202
|
+
source: "https://ai.google.dev/pricing#2_0flash",
|
|
1203
|
+
provenance: "litellm-catalog",
|
|
1204
|
+
tiers: [
|
|
1205
|
+
{
|
|
1206
|
+
inputPer1m: 0.1,
|
|
1207
|
+
outputPer1m: 0.4,
|
|
1208
|
+
cachedInputPer1m: 0.025
|
|
1209
|
+
}
|
|
1210
|
+
],
|
|
1211
|
+
contextWindow: 1048576,
|
|
1212
|
+
notes: "Gemini Developer API price. Vertex AI lists $0.15/$0.60 per 1M for the same model \u2014 see the vertex entry."
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
model: "gemini-2.0-flash-lite",
|
|
1216
|
+
provider: "gemini",
|
|
1217
|
+
modality: "text",
|
|
1218
|
+
currency: "USD",
|
|
1219
|
+
asOf: "2026-07-27",
|
|
1220
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite",
|
|
1221
|
+
provenance: "litellm-catalog",
|
|
1222
|
+
tiers: [
|
|
1223
|
+
{
|
|
1224
|
+
inputPer1m: 0.075,
|
|
1225
|
+
outputPer1m: 0.3,
|
|
1226
|
+
cachedInputPer1m: 0.01875
|
|
1227
|
+
}
|
|
1228
|
+
],
|
|
1229
|
+
contextWindow: 1048576
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
model: "gemini-2.0-flash",
|
|
1233
|
+
provider: "vertex",
|
|
1234
|
+
modality: "text",
|
|
1235
|
+
currency: "USD",
|
|
1236
|
+
asOf: "2026-07-27",
|
|
1237
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1238
|
+
provenance: "vendor-pricing-page",
|
|
1239
|
+
tiers: [
|
|
1240
|
+
{
|
|
1241
|
+
inputPer1m: 0.15,
|
|
1242
|
+
outputPer1m: 0.6
|
|
1243
|
+
}
|
|
1244
|
+
],
|
|
1245
|
+
batchMultiplier: 0.5,
|
|
1246
|
+
notes: "Vertex AI lists $0.15/$0.60 per 1M; the Gemini Developer API lists $0.10/$0.40 for the same model."
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
model: "gemini-3.1-pro",
|
|
1250
|
+
provider: "vertex",
|
|
1251
|
+
aliases: [
|
|
1252
|
+
"gemini-3.1-pro-preview"
|
|
1253
|
+
],
|
|
1254
|
+
modality: "text",
|
|
1255
|
+
currency: "USD",
|
|
1256
|
+
asOf: "2026-07-27",
|
|
1257
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1258
|
+
provenance: "vendor-pricing-page",
|
|
1259
|
+
tiers: [
|
|
1260
|
+
{
|
|
1261
|
+
maxInputTokens: 2e5,
|
|
1262
|
+
inputPer1m: 2,
|
|
1263
|
+
outputPer1m: 12,
|
|
1264
|
+
cachedInputPer1m: 0.2,
|
|
1265
|
+
reasoningOutputPer1m: 12
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
inputPer1m: 4,
|
|
1269
|
+
outputPer1m: 18,
|
|
1270
|
+
cachedInputPer1m: 0.4,
|
|
1271
|
+
reasoningOutputPer1m: 18
|
|
1272
|
+
}
|
|
1273
|
+
],
|
|
1274
|
+
batchMultiplier: 0.5,
|
|
1275
|
+
contextWindow: 1048576
|
|
1276
|
+
},
|
|
1277
|
+
{
|
|
1278
|
+
model: "gemini-3.6-flash",
|
|
1279
|
+
provider: "vertex",
|
|
1280
|
+
modality: "text",
|
|
1281
|
+
currency: "USD",
|
|
1282
|
+
asOf: "2026-07-27",
|
|
1283
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1284
|
+
provenance: "vendor-pricing-page",
|
|
1285
|
+
tiers: [
|
|
1286
|
+
{
|
|
1287
|
+
inputPer1m: 1.5,
|
|
1288
|
+
outputPer1m: 7.5,
|
|
1289
|
+
cachedInputPer1m: 0.15,
|
|
1290
|
+
reasoningOutputPer1m: 7.5
|
|
1291
|
+
}
|
|
1292
|
+
],
|
|
1293
|
+
batchMultiplier: 0.5,
|
|
1294
|
+
contextWindow: 1048576
|
|
1295
|
+
},
|
|
1296
|
+
{
|
|
1297
|
+
model: "gemini-2.5-pro",
|
|
1298
|
+
provider: "vertex",
|
|
1299
|
+
modality: "text",
|
|
1300
|
+
currency: "USD",
|
|
1301
|
+
asOf: "2026-07-27",
|
|
1302
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1303
|
+
provenance: "vendor-pricing-page",
|
|
1304
|
+
tiers: [
|
|
1305
|
+
{
|
|
1306
|
+
maxInputTokens: 2e5,
|
|
1307
|
+
inputPer1m: 1.25,
|
|
1308
|
+
outputPer1m: 10,
|
|
1309
|
+
cachedInputPer1m: 0.13
|
|
1310
|
+
},
|
|
1311
|
+
{
|
|
1312
|
+
inputPer1m: 2.5,
|
|
1313
|
+
outputPer1m: 15,
|
|
1314
|
+
cachedInputPer1m: 0.25
|
|
1315
|
+
}
|
|
1316
|
+
],
|
|
1317
|
+
batchMultiplier: 0.5,
|
|
1318
|
+
contextWindow: 1048576
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
model: "gemini-2.5-flash",
|
|
1322
|
+
provider: "vertex",
|
|
1323
|
+
modality: "text",
|
|
1324
|
+
currency: "USD",
|
|
1325
|
+
asOf: "2026-07-27",
|
|
1326
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1327
|
+
provenance: "vendor-pricing-page",
|
|
1328
|
+
tiers: [
|
|
1329
|
+
{
|
|
1330
|
+
inputPer1m: 0.3,
|
|
1331
|
+
outputPer1m: 2.5,
|
|
1332
|
+
cachedInputPer1m: 0.03,
|
|
1333
|
+
reasoningOutputPer1m: 2.5
|
|
1334
|
+
}
|
|
1335
|
+
],
|
|
1336
|
+
batchMultiplier: 0.5,
|
|
1337
|
+
contextWindow: 1048576
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
model: "claude-sonnet-4-6",
|
|
1341
|
+
provider: "openrouter",
|
|
1342
|
+
modality: "text",
|
|
1343
|
+
currency: "USD",
|
|
1344
|
+
asOf: "2026-07-27",
|
|
1345
|
+
source: "https://openrouter.ai/anthropic/claude-sonnet-4.6",
|
|
1346
|
+
provenance: "litellm-catalog",
|
|
1347
|
+
tiers: [
|
|
1348
|
+
{
|
|
1349
|
+
maxInputTokens: 2e5,
|
|
1350
|
+
inputPer1m: 3,
|
|
1351
|
+
outputPer1m: 15,
|
|
1352
|
+
cachedInputPer1m: 0.3,
|
|
1353
|
+
cacheWritePer1m: 3.75
|
|
1354
|
+
},
|
|
1355
|
+
{
|
|
1356
|
+
inputPer1m: 6,
|
|
1357
|
+
outputPer1m: 22.5,
|
|
1358
|
+
cachedInputPer1m: 0.6,
|
|
1359
|
+
cacheWritePer1m: 7.5
|
|
1360
|
+
}
|
|
1361
|
+
],
|
|
1362
|
+
contextWindow: 1e6
|
|
1363
|
+
},
|
|
1364
|
+
{
|
|
1365
|
+
model: "claude-haiku-4-5",
|
|
1366
|
+
provider: "openrouter",
|
|
1367
|
+
modality: "text",
|
|
1368
|
+
currency: "USD",
|
|
1369
|
+
asOf: "2026-07-27",
|
|
1370
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1371
|
+
provenance: "litellm-catalog",
|
|
1372
|
+
tiers: [
|
|
1373
|
+
{
|
|
1374
|
+
inputPer1m: 1,
|
|
1375
|
+
outputPer1m: 5,
|
|
1376
|
+
cachedInputPer1m: 0.1,
|
|
1377
|
+
cacheWritePer1m: 1.25
|
|
1378
|
+
}
|
|
1379
|
+
],
|
|
1380
|
+
contextWindow: 2e5
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
model: "gpt-5",
|
|
1384
|
+
provider: "openrouter",
|
|
1385
|
+
modality: "text",
|
|
1386
|
+
currency: "USD",
|
|
1387
|
+
asOf: "2026-07-27",
|
|
1388
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1389
|
+
provenance: "litellm-catalog",
|
|
1390
|
+
tiers: [
|
|
1391
|
+
{
|
|
1392
|
+
inputPer1m: 1.25,
|
|
1393
|
+
outputPer1m: 10,
|
|
1394
|
+
cachedInputPer1m: 0.125
|
|
1395
|
+
}
|
|
1396
|
+
],
|
|
1397
|
+
contextWindow: 272e3
|
|
1398
|
+
},
|
|
1399
|
+
{
|
|
1400
|
+
model: "gpt-5-mini",
|
|
1401
|
+
provider: "openrouter",
|
|
1402
|
+
modality: "text",
|
|
1403
|
+
currency: "USD",
|
|
1404
|
+
asOf: "2026-07-27",
|
|
1405
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1406
|
+
provenance: "litellm-catalog",
|
|
1407
|
+
tiers: [
|
|
1408
|
+
{
|
|
1409
|
+
inputPer1m: 0.25,
|
|
1410
|
+
outputPer1m: 2,
|
|
1411
|
+
cachedInputPer1m: 0.025
|
|
1412
|
+
}
|
|
1413
|
+
],
|
|
1414
|
+
contextWindow: 272e3
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
model: "gemini-3.1-pro",
|
|
1418
|
+
provider: "openrouter",
|
|
1419
|
+
aliases: [
|
|
1420
|
+
"gemini-3.1-pro-preview"
|
|
1421
|
+
],
|
|
1422
|
+
modality: "text",
|
|
1423
|
+
currency: "USD",
|
|
1424
|
+
asOf: "2026-07-27",
|
|
1425
|
+
source: "https://openrouter.ai/google/gemini-3.1-pro-preview",
|
|
1426
|
+
provenance: "litellm-catalog",
|
|
1427
|
+
tiers: [
|
|
1428
|
+
{
|
|
1429
|
+
maxInputTokens: 2e5,
|
|
1430
|
+
inputPer1m: 2,
|
|
1431
|
+
outputPer1m: 12,
|
|
1432
|
+
cachedInputPer1m: 0.2
|
|
1433
|
+
},
|
|
1434
|
+
{
|
|
1435
|
+
inputPer1m: 4,
|
|
1436
|
+
outputPer1m: 18,
|
|
1437
|
+
cachedInputPer1m: 0.4,
|
|
1438
|
+
cacheWritePer1m: 0.25
|
|
1439
|
+
}
|
|
1440
|
+
],
|
|
1441
|
+
contextWindow: 1048576
|
|
1442
|
+
},
|
|
1443
|
+
{
|
|
1444
|
+
model: "text-embedding-3-small",
|
|
1445
|
+
provider: "openai",
|
|
1446
|
+
modality: "embedding",
|
|
1447
|
+
currency: "USD",
|
|
1448
|
+
asOf: "2026-07-27",
|
|
1449
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1450
|
+
provenance: "litellm-catalog",
|
|
1451
|
+
tiers: [
|
|
1452
|
+
{
|
|
1453
|
+
inputPer1m: 0.02,
|
|
1454
|
+
outputPer1m: 0
|
|
1455
|
+
}
|
|
1456
|
+
],
|
|
1457
|
+
batchMultiplier: 0.5,
|
|
1458
|
+
contextWindow: 8191
|
|
1459
|
+
},
|
|
1460
|
+
{
|
|
1461
|
+
model: "text-embedding-3-large",
|
|
1462
|
+
provider: "openai",
|
|
1463
|
+
modality: "embedding",
|
|
1464
|
+
currency: "USD",
|
|
1465
|
+
asOf: "2026-07-27",
|
|
1466
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1467
|
+
provenance: "litellm-catalog",
|
|
1468
|
+
tiers: [
|
|
1469
|
+
{
|
|
1470
|
+
inputPer1m: 0.13,
|
|
1471
|
+
outputPer1m: 0
|
|
1472
|
+
}
|
|
1473
|
+
],
|
|
1474
|
+
batchMultiplier: 0.5,
|
|
1475
|
+
contextWindow: 8191
|
|
1476
|
+
},
|
|
1477
|
+
{
|
|
1478
|
+
model: "gemini-embedding-001",
|
|
1479
|
+
provider: "gemini",
|
|
1480
|
+
modality: "embedding",
|
|
1481
|
+
currency: "USD",
|
|
1482
|
+
asOf: "2026-07-27",
|
|
1483
|
+
source: "https://ai.google.dev/gemini-api/docs/embeddings#model-versions",
|
|
1484
|
+
provenance: "litellm-catalog",
|
|
1485
|
+
tiers: [
|
|
1486
|
+
{
|
|
1487
|
+
inputPer1m: 0.15,
|
|
1488
|
+
outputPer1m: 0
|
|
1489
|
+
}
|
|
1490
|
+
],
|
|
1491
|
+
contextWindow: 2048
|
|
1492
|
+
},
|
|
1493
|
+
{
|
|
1494
|
+
model: "dall-e-3",
|
|
1495
|
+
provider: "openai",
|
|
1496
|
+
modality: "image",
|
|
1497
|
+
currency: "USD",
|
|
1498
|
+
asOf: "2026-07-27",
|
|
1499
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1500
|
+
provenance: "litellm-catalog",
|
|
1501
|
+
rates: [
|
|
1502
|
+
{
|
|
1503
|
+
unit: "per_image",
|
|
1504
|
+
amount: 0.04,
|
|
1505
|
+
variant: "1024x1024 standard"
|
|
1506
|
+
}
|
|
1507
|
+
]
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
model: "gemini-3-pro-image",
|
|
1511
|
+
provider: "gemini",
|
|
1512
|
+
modality: "image",
|
|
1513
|
+
currency: "USD",
|
|
1514
|
+
asOf: "2026-07-27",
|
|
1515
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing",
|
|
1516
|
+
provenance: "litellm-catalog",
|
|
1517
|
+
rates: [
|
|
1518
|
+
{
|
|
1519
|
+
unit: "per_image",
|
|
1520
|
+
amount: 0.134,
|
|
1521
|
+
variant: "default output resolution"
|
|
1522
|
+
}
|
|
1523
|
+
],
|
|
1524
|
+
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."
|
|
1525
|
+
},
|
|
1526
|
+
{
|
|
1527
|
+
model: "imagen-4.0-generate-001",
|
|
1528
|
+
provider: "vertex",
|
|
1529
|
+
modality: "image",
|
|
1530
|
+
currency: "USD",
|
|
1531
|
+
asOf: "2026-07-27",
|
|
1532
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
|
|
1533
|
+
provenance: "litellm-catalog",
|
|
1534
|
+
rates: [
|
|
1535
|
+
{
|
|
1536
|
+
unit: "per_image",
|
|
1537
|
+
amount: 0.04
|
|
1538
|
+
}
|
|
1539
|
+
]
|
|
1540
|
+
},
|
|
1541
|
+
{
|
|
1542
|
+
model: "veo-3.1-generate-001",
|
|
1543
|
+
provider: "gemini",
|
|
1544
|
+
modality: "video",
|
|
1545
|
+
currency: "USD",
|
|
1546
|
+
asOf: "2026-07-27",
|
|
1547
|
+
source: "https://ai.google.dev/gemini-api/docs/video",
|
|
1548
|
+
provenance: "litellm-catalog",
|
|
1549
|
+
rates: [
|
|
1550
|
+
{
|
|
1551
|
+
unit: "per_second",
|
|
1552
|
+
amount: 0.4
|
|
1553
|
+
}
|
|
1554
|
+
]
|
|
1555
|
+
},
|
|
1556
|
+
{
|
|
1557
|
+
model: "veo-3.1-generate-001",
|
|
1558
|
+
provider: "vertex",
|
|
1559
|
+
modality: "video",
|
|
1560
|
+
currency: "USD",
|
|
1561
|
+
asOf: "2026-07-27",
|
|
1562
|
+
source: "https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo",
|
|
1563
|
+
provenance: "litellm-catalog",
|
|
1564
|
+
rates: [
|
|
1565
|
+
{
|
|
1566
|
+
unit: "per_second",
|
|
1567
|
+
amount: 0.4
|
|
1568
|
+
}
|
|
1569
|
+
]
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
model: "tts-1",
|
|
1573
|
+
provider: "openai",
|
|
1574
|
+
modality: "speech",
|
|
1575
|
+
currency: "USD",
|
|
1576
|
+
asOf: "2026-07-27",
|
|
1577
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1578
|
+
provenance: "litellm-catalog",
|
|
1579
|
+
rates: [
|
|
1580
|
+
{
|
|
1581
|
+
unit: "per_character",
|
|
1582
|
+
amount: 15e-6
|
|
1583
|
+
}
|
|
1584
|
+
],
|
|
1585
|
+
notes: "$15 per 1M characters."
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
model: "tts-1-hd",
|
|
1589
|
+
provider: "openai",
|
|
1590
|
+
modality: "speech",
|
|
1591
|
+
currency: "USD",
|
|
1592
|
+
asOf: "2026-07-27",
|
|
1593
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1594
|
+
provenance: "litellm-catalog",
|
|
1595
|
+
rates: [
|
|
1596
|
+
{
|
|
1597
|
+
unit: "per_character",
|
|
1598
|
+
amount: 3e-5
|
|
1599
|
+
}
|
|
1600
|
+
],
|
|
1601
|
+
notes: "$30 per 1M characters."
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
model: "whisper-1",
|
|
1605
|
+
provider: "openai",
|
|
1606
|
+
modality: "transcription",
|
|
1607
|
+
currency: "USD",
|
|
1608
|
+
asOf: "2026-07-27",
|
|
1609
|
+
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
1610
|
+
provenance: "litellm-catalog",
|
|
1611
|
+
rates: [
|
|
1612
|
+
{
|
|
1613
|
+
unit: "per_audio_minute",
|
|
1614
|
+
amount: 6e-3
|
|
1615
|
+
}
|
|
1616
|
+
],
|
|
1617
|
+
notes: "litellm records $0.0001 per audio second; $0.006/minute is that rate x 60."
|
|
1618
|
+
}
|
|
1619
|
+
]
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
|
|
1624
|
+
// src/core/router/pricing.ts
|
|
1625
|
+
function normalizeForPricing(id) {
|
|
1626
|
+
let s = id.trim().toLowerCase();
|
|
1627
|
+
s = s.replace(/^models\//, "");
|
|
1628
|
+
const slash = s.lastIndexOf("/");
|
|
1629
|
+
if (slash !== -1) s = s.slice(slash + 1);
|
|
1630
|
+
const tag = s.search(/[:@]/);
|
|
1631
|
+
if (tag !== -1) s = s.slice(0, tag);
|
|
1632
|
+
s = s.replace(/-latest$/, "");
|
|
1633
|
+
s = s.replace(/-preview(?:-\d{2}-\d{2})?$/, "");
|
|
1634
|
+
s = s.replace(/-\d{4}-\d{2}-\d{2}$/, "");
|
|
1635
|
+
s = s.replace(/-\d{8}$/, "");
|
|
1636
|
+
s = s.replace(/-preview$/, "");
|
|
1637
|
+
return s;
|
|
1638
|
+
}
|
|
1639
|
+
function indexKey(model, provider, region) {
|
|
1640
|
+
return `${provider}|${normalizeForPricing(model)}|${region ?? ""}`;
|
|
1641
|
+
}
|
|
1642
|
+
function findPricing(modelId, provider, opts = {}) {
|
|
1643
|
+
const ids = [modelId, opts.baseModelId].filter((x) => !!x);
|
|
1644
|
+
const providers = [provider, ...opts.fallbackProviders ?? []];
|
|
1645
|
+
for (const p of providers) {
|
|
1646
|
+
for (const id of ids) {
|
|
1647
|
+
const hit = (opts.region ? INDEX.get(indexKey(id, p, opts.region)) : void 0) ?? INDEX.get(indexKey(id, p));
|
|
1648
|
+
if (hit) return { entry: hit, matchedProvider: p, viaFallback: p !== provider };
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return null;
|
|
1652
|
+
}
|
|
1653
|
+
function pricingDatasetMeta() {
|
|
1654
|
+
const { schemaVersion, generatedAt, defaultCurrency } = DATASET;
|
|
1655
|
+
return { schemaVersion, generatedAt, defaultCurrency };
|
|
1656
|
+
}
|
|
1657
|
+
function tierFor(entry, inputTokens = 0) {
|
|
1658
|
+
const tiers = entry.tiers;
|
|
1659
|
+
if (!tiers?.length) return null;
|
|
1660
|
+
for (const t of tiers) {
|
|
1661
|
+
if (t.maxInputTokens === void 0 || inputTokens <= t.maxInputTokens) return t;
|
|
1662
|
+
}
|
|
1663
|
+
return tiers[tiers.length - 1] ?? null;
|
|
1664
|
+
}
|
|
1665
|
+
function tokenRatesPer1k(entry, opts = {}) {
|
|
1666
|
+
const tier = tierFor(entry, opts.inputTokens ?? 0);
|
|
1667
|
+
if (!tier) return null;
|
|
1668
|
+
const mult = (opts.batch ? entry.batchMultiplier ?? 1 : 1) * PER_1M_TO_PER_1K;
|
|
1669
|
+
const out = {
|
|
1670
|
+
input: tier.inputPer1m * mult,
|
|
1671
|
+
output: tier.outputPer1m * mult
|
|
1672
|
+
};
|
|
1673
|
+
if (tier.cachedInputPer1m !== void 0) out.cachedInput = tier.cachedInputPer1m * mult;
|
|
1674
|
+
if (tier.cacheWritePer1m !== void 0) out.cacheWrite = tier.cacheWritePer1m * mult;
|
|
1675
|
+
if (tier.reasoningOutputPer1m !== void 0) out.reasoningOutput = tier.reasoningOutputPer1m * mult;
|
|
1676
|
+
return out;
|
|
1677
|
+
}
|
|
1678
|
+
function isLoopbackOrPrivateHost(url) {
|
|
1679
|
+
if (!url) return false;
|
|
1680
|
+
try {
|
|
1681
|
+
const host = new URL(url).hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
1682
|
+
if (LOOPBACK_HOSTS.has(host) || LOOPBACK_HOSTS.has(`[${host}]`)) return true;
|
|
1683
|
+
if (host.endsWith(".local")) return true;
|
|
1684
|
+
if (/^127\./.test(host)) return true;
|
|
1685
|
+
if (/^10\./.test(host)) return true;
|
|
1686
|
+
if (/^192\.168\./.test(host)) return true;
|
|
1687
|
+
if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true;
|
|
1688
|
+
return false;
|
|
1689
|
+
} catch {
|
|
1690
|
+
return false;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
function isLocalEndpoint(cfg) {
|
|
1694
|
+
if (typeof cfg.local === "boolean") return cfg.local;
|
|
1695
|
+
if (cfg.type === "ollama") return true;
|
|
1696
|
+
if (cfg.type === "openai-compatible") return isLoopbackOrPrivateHost(cfg.baseUrl);
|
|
1697
|
+
return false;
|
|
1698
|
+
}
|
|
1699
|
+
function resolvePricing(model, opts = {}) {
|
|
1700
|
+
if (model.isLocal) return FREE;
|
|
1701
|
+
const fallbackProviders = model.provider === "azure" ? ["openai"] : model.provider === "gemini" ? ["vertex"] : [];
|
|
1702
|
+
const match = findPricing(model.id, model.provider, {
|
|
1703
|
+
region: opts.region,
|
|
1704
|
+
baseModelId: model.baseModelId,
|
|
1705
|
+
fallbackProviders
|
|
1706
|
+
});
|
|
1707
|
+
if (!match) return UNKNOWN;
|
|
1708
|
+
const rates = tokenRatesPer1k(match.entry, { inputTokens: opts.inputTokens, batch: opts.batch });
|
|
1709
|
+
if (!rates) return UNKNOWN;
|
|
1710
|
+
return {
|
|
1711
|
+
input: rates.input,
|
|
1712
|
+
output: rates.output,
|
|
1713
|
+
unknown: false,
|
|
1714
|
+
free: false,
|
|
1715
|
+
entry: match.entry,
|
|
1716
|
+
...match.viaFallback ? { estimatedFromProvider: match.matchedProvider } : {}
|
|
1717
|
+
};
|
|
1718
|
+
}
|
|
1719
|
+
function withResolvedPricing(model, opts = {}) {
|
|
1720
|
+
const p = resolvePricing(model, opts);
|
|
1721
|
+
return {
|
|
1722
|
+
...model,
|
|
1723
|
+
inputCostPer1kTokens: p.input,
|
|
1724
|
+
outputCostPer1kTokens: p.output,
|
|
1725
|
+
...p.unknown ? { pricingUnknown: true } : { pricingUnknown: false }
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
function isPricingUnknown(model) {
|
|
1729
|
+
return model.pricingUnknown === true && !model.isLocal;
|
|
1730
|
+
}
|
|
1731
|
+
function blendedCostPer1k(model) {
|
|
1732
|
+
if (isPricingUnknown(model)) return BLENDED_COST_CEILING;
|
|
1733
|
+
return model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
|
|
1734
|
+
}
|
|
1735
|
+
function reconcilePrice(model, live) {
|
|
1736
|
+
const baseline = resolvePricing(model);
|
|
1737
|
+
const liveIsZero = !(live.input > 0) && !(live.output > 0);
|
|
1738
|
+
if (liveIsZero && !model.isLocal) {
|
|
1739
|
+
return { input: baseline.input, output: baseline.output, accepted: false };
|
|
1740
|
+
}
|
|
1741
|
+
if (baseline.unknown || !baseline.entry) {
|
|
1742
|
+
return { input: live.input, output: live.output, accepted: true };
|
|
1743
|
+
}
|
|
1744
|
+
const dsBlend = baseline.input + baseline.output * 2;
|
|
1745
|
+
const liveBlend = live.input + live.output * 2;
|
|
1746
|
+
const ratio = dsBlend > 0 ? liveBlend / dsBlend : Number.POSITIVE_INFINITY;
|
|
1747
|
+
const material = dsBlend > 0 && Math.abs(ratio - 1) > DISAGREEMENT_THRESHOLD;
|
|
1748
|
+
return {
|
|
1749
|
+
input: live.input,
|
|
1750
|
+
output: live.output,
|
|
1751
|
+
accepted: true,
|
|
1752
|
+
...material ? {
|
|
1753
|
+
disagreement: {
|
|
1754
|
+
modelId: model.id,
|
|
1755
|
+
provider: model.provider,
|
|
1756
|
+
dataset: { input: baseline.input, output: baseline.output },
|
|
1757
|
+
live: { input: live.input, output: live.output },
|
|
1758
|
+
ratio: Math.round(ratio * 1e3) / 1e3,
|
|
1759
|
+
datasetAsOf: baseline.entry.asOf,
|
|
1760
|
+
datasetSource: baseline.entry.source
|
|
1761
|
+
}
|
|
1762
|
+
} : {}
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
var DATASET, INDEX, PER_1M_TO_PER_1K, LOOPBACK_HOSTS, UNKNOWN, FREE, BLENDED_COST_CEILING, DISAGREEMENT_THRESHOLD;
|
|
1766
|
+
var init_pricing = __esm({
|
|
1767
|
+
"src/core/router/pricing.ts"() {
|
|
1768
|
+
init_pricing_data();
|
|
1769
|
+
DATASET = pricing_data_default;
|
|
1770
|
+
INDEX = /* @__PURE__ */ new Map();
|
|
1771
|
+
for (const entry of DATASET.entries) {
|
|
1772
|
+
for (const name of [entry.model, ...entry.aliases ?? []]) {
|
|
1773
|
+
const withRegion = indexKey(name, entry.provider, entry.region);
|
|
1774
|
+
if (!INDEX.has(withRegion)) INDEX.set(withRegion, entry);
|
|
1775
|
+
const bare = indexKey(name, entry.provider);
|
|
1776
|
+
const existing = INDEX.get(bare);
|
|
1777
|
+
if (!existing || existing.region && existing.region !== "global" && entry.region === "global") {
|
|
1778
|
+
INDEX.set(bare, entry);
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
PER_1M_TO_PER_1K = 1 / 1e3;
|
|
1783
|
+
LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"]);
|
|
1784
|
+
UNKNOWN = { input: 0, output: 0, unknown: true, free: false };
|
|
1785
|
+
FREE = { input: 0, output: 0, unknown: false, free: true };
|
|
1786
|
+
BLENDED_COST_CEILING = 0.05;
|
|
1787
|
+
DISAGREEMENT_THRESHOLD = 0.02;
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
|
|
115
1791
|
// src/constants.ts
|
|
116
1792
|
var CASCADE_VERSION, CASCADE_CONFIG_FILE, CASCADE_DB_FILE, CASCADE_DASHBOARD_SECRET_FILE, GLOBAL_CONFIG_DIR, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_CREDENTIALS_FILE, GLOBAL_RUNTIME_DB_FILE, DEFAULT_DASHBOARD_PORT, DEFAULT_CONTEXT_LIMIT, DEFAULT_AUTO_SUMMARIZE_AT, MODELS, T1_MODEL_PRIORITY, T2_MODEL_PRIORITY, T3_MODEL_PRIORITY, VISION_MODEL_PRIORITY, COMPLEXITY_T2_COUNT, THEME_NAMES, DEFAULT_THEME, OLLAMA_BASE_URL, LM_STUDIO_BASE_URL, AZURE_BASE_URL_TEMPLATE, TOOL_NAMES, DEFAULT_APPROVAL_REQUIRED;
|
|
117
1793
|
var init_constants = __esm({
|
|
118
1794
|
"src/constants.ts"() {
|
|
119
|
-
|
|
1795
|
+
init_pricing();
|
|
1796
|
+
CASCADE_VERSION = "0.49.0";
|
|
120
1797
|
CASCADE_CONFIG_FILE = ".cascade/config.json";
|
|
121
1798
|
CASCADE_DB_FILE = ".cascade/memory.db";
|
|
122
1799
|
CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
|
|
@@ -457,6 +2134,13 @@ var init_constants = __esm({
|
|
|
457
2134
|
for (const _m of Object.values(MODELS)) {
|
|
458
2135
|
if (_m.supportsToolUse === void 0) _m.supportsToolUse = !_m.isLocal;
|
|
459
2136
|
}
|
|
2137
|
+
for (const _m of Object.values(MODELS)) {
|
|
2138
|
+
const priced = resolvePricing(_m);
|
|
2139
|
+
if (priced.unknown || priced.free || priced.estimatedFromProvider) continue;
|
|
2140
|
+
_m.inputCostPer1kTokens = priced.input;
|
|
2141
|
+
_m.outputCostPer1kTokens = priced.output;
|
|
2142
|
+
_m.pricingUnknown = false;
|
|
2143
|
+
}
|
|
460
2144
|
T1_MODEL_PRIORITY = [
|
|
461
2145
|
"gpt-5.5",
|
|
462
2146
|
"gpt-5.4",
|
|
@@ -541,24 +2225,53 @@ var init_constants = __esm({
|
|
|
541
2225
|
|
|
542
2226
|
// src/utils/cost.ts
|
|
543
2227
|
function resolveModelPricing(model) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
2228
|
+
if (model.isLocal) return { input: 0, output: 0, unknown: false };
|
|
2229
|
+
if (model.inputCostPer1kTokens > 0 || model.outputCostPer1kTokens > 0) {
|
|
2230
|
+
return {
|
|
2231
|
+
input: model.inputCostPer1kTokens,
|
|
2232
|
+
output: model.outputCostPer1kTokens,
|
|
2233
|
+
unknown: false
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
const fromDataset = resolvePricing(model);
|
|
2237
|
+
if (!fromDataset.unknown) {
|
|
2238
|
+
return {
|
|
2239
|
+
input: fromDataset.input,
|
|
2240
|
+
output: fromDataset.output,
|
|
2241
|
+
unknown: false,
|
|
2242
|
+
...fromDataset.estimatedFromProvider ? { estimatedFromProvider: fromDataset.estimatedFromProvider } : {}
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
if (model.id) {
|
|
547
2246
|
const known = Object.values(MODELS).find((m) => m.id === model.id && !m.isLocal);
|
|
548
|
-
if (known) {
|
|
549
|
-
|
|
550
|
-
|
|
2247
|
+
if (known && (known.inputCostPer1kTokens > 0 || known.outputCostPer1kTokens > 0)) {
|
|
2248
|
+
return {
|
|
2249
|
+
input: known.inputCostPer1kTokens,
|
|
2250
|
+
output: known.outputCostPer1kTokens,
|
|
2251
|
+
unknown: false
|
|
2252
|
+
};
|
|
551
2253
|
}
|
|
552
2254
|
}
|
|
553
|
-
return { input, output };
|
|
2255
|
+
return { input: 0, output: 0, unknown: true };
|
|
554
2256
|
}
|
|
555
2257
|
function calculateCost(inputTokens, outputTokens, model) {
|
|
556
2258
|
const { input, output } = resolveModelPricing(model);
|
|
557
2259
|
return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
|
|
558
2260
|
}
|
|
2261
|
+
function buildTokenUsage(inputTokens, outputTokens, model) {
|
|
2262
|
+
const { input, output, unknown } = resolveModelPricing(model);
|
|
2263
|
+
return {
|
|
2264
|
+
inputTokens,
|
|
2265
|
+
outputTokens,
|
|
2266
|
+
totalTokens: inputTokens + outputTokens,
|
|
2267
|
+
estimatedCostUsd: inputTokens / 1e3 * input + outputTokens / 1e3 * output,
|
|
2268
|
+
...unknown ? { costUnknown: true } : {}
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
559
2271
|
var init_cost = __esm({
|
|
560
2272
|
"src/utils/cost.ts"() {
|
|
561
2273
|
init_constants();
|
|
2274
|
+
init_pricing();
|
|
562
2275
|
}
|
|
563
2276
|
});
|
|
564
2277
|
|
|
@@ -584,12 +2297,7 @@ var init_base = __esm({
|
|
|
584
2297
|
return calculateCost(inputTokens, outputTokens, this.model);
|
|
585
2298
|
}
|
|
586
2299
|
makeUsage(inputTokens, outputTokens) {
|
|
587
|
-
return
|
|
588
|
-
inputTokens,
|
|
589
|
-
outputTokens,
|
|
590
|
-
totalTokens: inputTokens + outputTokens,
|
|
591
|
-
estimatedCostUsd: this.estimateCost(inputTokens, outputTokens)
|
|
592
|
-
};
|
|
2300
|
+
return buildTokenUsage(inputTokens, outputTokens, this.model);
|
|
593
2301
|
}
|
|
594
2302
|
};
|
|
595
2303
|
}
|
|
@@ -665,6 +2373,7 @@ var init_anthropic = __esm({
|
|
|
665
2373
|
"src/providers/anthropic.ts"() {
|
|
666
2374
|
init_constants();
|
|
667
2375
|
init_base();
|
|
2376
|
+
init_pricing();
|
|
668
2377
|
init_model_filter();
|
|
669
2378
|
AnthropicProvider = class extends BaseProvider {
|
|
670
2379
|
client;
|
|
@@ -775,7 +2484,7 @@ var init_anthropic = __esm({
|
|
|
775
2484
|
return data.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
776
2485
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "anthropic");
|
|
777
2486
|
if (known) return known;
|
|
778
|
-
return {
|
|
2487
|
+
return withResolvedPricing({
|
|
779
2488
|
id: m.id,
|
|
780
2489
|
name: m.display_name || m.id,
|
|
781
2490
|
provider: "anthropic",
|
|
@@ -786,7 +2495,7 @@ var init_anthropic = __esm({
|
|
|
786
2495
|
maxOutputTokens: 8e3,
|
|
787
2496
|
supportsStreaming: true,
|
|
788
2497
|
isLocal: false
|
|
789
|
-
};
|
|
2498
|
+
});
|
|
790
2499
|
});
|
|
791
2500
|
} catch {
|
|
792
2501
|
return Object.values(MODELS).filter((m) => m.provider === "anthropic");
|
|
@@ -881,6 +2590,7 @@ var init_openai = __esm({
|
|
|
881
2590
|
"src/providers/openai.ts"() {
|
|
882
2591
|
init_constants();
|
|
883
2592
|
init_base();
|
|
2593
|
+
init_pricing();
|
|
884
2594
|
init_model_filter();
|
|
885
2595
|
OpenAIProvider = class extends BaseProvider {
|
|
886
2596
|
client;
|
|
@@ -1006,7 +2716,7 @@ var init_openai = __esm({
|
|
|
1006
2716
|
return response.data.filter((m) => isChatModel(m.id)).map((m) => {
|
|
1007
2717
|
const known = Object.values(MODELS).find((km) => km.id === m.id && km.provider === "openai");
|
|
1008
2718
|
if (known) return known;
|
|
1009
|
-
return {
|
|
2719
|
+
return withResolvedPricing({
|
|
1010
2720
|
id: m.id,
|
|
1011
2721
|
name: m.id,
|
|
1012
2722
|
provider: "openai",
|
|
@@ -1017,7 +2727,7 @@ var init_openai = __esm({
|
|
|
1017
2727
|
maxOutputTokens: 4e3,
|
|
1018
2728
|
supportsStreaming: true,
|
|
1019
2729
|
isLocal: false
|
|
1020
|
-
};
|
|
2730
|
+
});
|
|
1021
2731
|
});
|
|
1022
2732
|
} catch {
|
|
1023
2733
|
return Object.values(MODELS).filter((m) => m.provider === "openai");
|
|
@@ -1120,6 +2830,10 @@ function azureModelForDeployment(cfg) {
|
|
|
1120
2830
|
const baseModelId = cfg.model?.trim() || inferAzureBaseModel(id) || void 0;
|
|
1121
2831
|
const base = baseModelId ? MODELS[baseModelId] : void 0;
|
|
1122
2832
|
if (base) {
|
|
2833
|
+
const azurePrice = resolvePricing(
|
|
2834
|
+
{ id, provider: "azure", isLocal: false, baseModelId },
|
|
2835
|
+
{ region: cfg.region }
|
|
2836
|
+
);
|
|
1123
2837
|
return {
|
|
1124
2838
|
...base,
|
|
1125
2839
|
id,
|
|
@@ -1128,7 +2842,12 @@ function azureModelForDeployment(cfg) {
|
|
|
1128
2842
|
provider: "azure",
|
|
1129
2843
|
baseModelId,
|
|
1130
2844
|
// real identity for benchmark + live pricing
|
|
1131
|
-
supportsToolUse: base.supportsToolUse ?? true
|
|
2845
|
+
supportsToolUse: base.supportsToolUse ?? true,
|
|
2846
|
+
...azurePrice.unknown ? {} : {
|
|
2847
|
+
inputCostPer1kTokens: azurePrice.input,
|
|
2848
|
+
outputCostPer1kTokens: azurePrice.output,
|
|
2849
|
+
pricingUnknown: false
|
|
2850
|
+
}
|
|
1132
2851
|
};
|
|
1133
2852
|
}
|
|
1134
2853
|
return {
|
|
@@ -1151,6 +2870,7 @@ var init_azure = __esm({
|
|
|
1151
2870
|
"src/providers/azure.ts"() {
|
|
1152
2871
|
init_constants();
|
|
1153
2872
|
init_openai();
|
|
2873
|
+
init_pricing();
|
|
1154
2874
|
DEFAULT_AZURE_API_VERSION = "2024-12-01-preview";
|
|
1155
2875
|
AzureOpenAIProvider = class extends OpenAIProvider {
|
|
1156
2876
|
constructor(config, model) {
|
|
@@ -1211,6 +2931,7 @@ var init_gemini = __esm({
|
|
|
1211
2931
|
"src/providers/gemini.ts"() {
|
|
1212
2932
|
init_constants();
|
|
1213
2933
|
init_base();
|
|
2934
|
+
init_pricing();
|
|
1214
2935
|
init_model_filter();
|
|
1215
2936
|
GeminiProvider = class extends BaseProvider {
|
|
1216
2937
|
client;
|
|
@@ -1311,7 +3032,7 @@ var init_gemini = __esm({
|
|
|
1311
3032
|
(km) => km.id === id && km.provider === "gemini"
|
|
1312
3033
|
);
|
|
1313
3034
|
if (known) return known;
|
|
1314
|
-
return {
|
|
3035
|
+
return withResolvedPricing({
|
|
1315
3036
|
id,
|
|
1316
3037
|
name: m.displayName || id,
|
|
1317
3038
|
provider: "gemini",
|
|
@@ -1322,7 +3043,7 @@ var init_gemini = __esm({
|
|
|
1322
3043
|
maxOutputTokens: m.outputTokenLimit || 8e3,
|
|
1323
3044
|
supportsStreaming: true,
|
|
1324
3045
|
isLocal: false
|
|
1325
|
-
};
|
|
3046
|
+
});
|
|
1326
3047
|
});
|
|
1327
3048
|
} catch {
|
|
1328
3049
|
return Object.values(MODELS).filter((m) => m.provider === "gemini");
|
|
@@ -1528,6 +3249,7 @@ var init_ollama = __esm({
|
|
|
1528
3249
|
init_constants();
|
|
1529
3250
|
init_net();
|
|
1530
3251
|
init_base();
|
|
3252
|
+
init_pricing();
|
|
1531
3253
|
init_model_filter();
|
|
1532
3254
|
TOOL_CAPABLE_FAMILIES = [
|
|
1533
3255
|
"llama3.1",
|
|
@@ -1687,9 +3409,10 @@ var init_ollama = __esm({
|
|
|
1687
3409
|
return supportedKeywords.some((k) => name.includes(k)) && isChatModel(name);
|
|
1688
3410
|
});
|
|
1689
3411
|
const shows = await Promise.all(entries.map((m) => this.showModel(m.name)));
|
|
3412
|
+
const local = isLocalEndpoint({ ...this.config, type: "ollama" });
|
|
1690
3413
|
return entries.map((m, i) => {
|
|
1691
3414
|
const show = shows[i];
|
|
1692
|
-
return {
|
|
3415
|
+
return withResolvedPricing({
|
|
1693
3416
|
id: m.name,
|
|
1694
3417
|
name: m.name,
|
|
1695
3418
|
provider: "ollama",
|
|
@@ -1699,10 +3422,10 @@ var init_ollama = __esm({
|
|
|
1699
3422
|
outputCostPer1kTokens: 0,
|
|
1700
3423
|
maxOutputTokens: 4e3,
|
|
1701
3424
|
supportsStreaming: true,
|
|
1702
|
-
isLocal:
|
|
3425
|
+
isLocal: local,
|
|
1703
3426
|
supportsToolUse: show?.tools ?? isToolCapable(m.name),
|
|
1704
3427
|
minSizeB: this.parseSizeB(m.details?.parameter_size)
|
|
1705
|
-
};
|
|
3428
|
+
});
|
|
1706
3429
|
});
|
|
1707
3430
|
} catch {
|
|
1708
3431
|
return [];
|
|
@@ -1786,6 +3509,7 @@ var init_openai_compatible = __esm({
|
|
|
1786
3509
|
init_openai();
|
|
1787
3510
|
init_model_filter();
|
|
1788
3511
|
init_net();
|
|
3512
|
+
init_pricing();
|
|
1789
3513
|
OpenAICompatibleProvider = class extends OpenAIProvider {
|
|
1790
3514
|
constructor(config, model) {
|
|
1791
3515
|
super({ ...config, apiKey: config.apiKey ?? "not-required" }, model);
|
|
@@ -1819,7 +3543,8 @@ var init_openai_compatible = __esm({
|
|
|
1819
3543
|
}).filter((x) => typeof x === "string" && x.length > 0);
|
|
1820
3544
|
if (ids.length === 0) return [this.model];
|
|
1821
3545
|
const chatIds = ids.filter((id) => isChatModel(id));
|
|
1822
|
-
|
|
3546
|
+
const local = isLocalEndpoint(this.config);
|
|
3547
|
+
return (chatIds.length ? chatIds : ids).map((id) => withResolvedPricing({
|
|
1823
3548
|
id,
|
|
1824
3549
|
name: id,
|
|
1825
3550
|
provider: "openai-compatible",
|
|
@@ -1829,7 +3554,7 @@ var init_openai_compatible = __esm({
|
|
|
1829
3554
|
outputCostPer1kTokens: 0,
|
|
1830
3555
|
maxOutputTokens: 4e3,
|
|
1831
3556
|
supportsStreaming: true,
|
|
1832
|
-
isLocal:
|
|
3557
|
+
isLocal: local
|
|
1833
3558
|
}));
|
|
1834
3559
|
}
|
|
1835
3560
|
async isAvailable() {
|
|
@@ -3151,7 +4876,18 @@ var ProviderConfigSchema = zod.z.object({
|
|
|
3151
4876
|
apiVersion: zod.z.string().optional(),
|
|
3152
4877
|
model: zod.z.string().optional(),
|
|
3153
4878
|
authToken: zod.z.string().optional(),
|
|
3154
|
-
credentialSource: zod.z.string().optional()
|
|
4879
|
+
credentialSource: zod.z.string().optional(),
|
|
4880
|
+
/**
|
|
4881
|
+
* "This endpoint is self-hosted, so inference genuinely costs $0."
|
|
4882
|
+
* Only meaningful for `ollama` and `openai-compatible`. Unset ⇒ inferred:
|
|
4883
|
+
* ollama is local, openai-compatible is local when its baseUrl is
|
|
4884
|
+
* loopback/LAN. Set it explicitly to override — e.g. `false` for an Ollama
|
|
4885
|
+
* instance you rent, `true` for a llama.cpp box on your own LAN reached by
|
|
4886
|
+
* hostname.
|
|
4887
|
+
*/
|
|
4888
|
+
local: zod.z.boolean().optional(),
|
|
4889
|
+
/** Region for providers whose price varies by region (Azure: global | us | eu | …). */
|
|
4890
|
+
region: zod.z.string().optional()
|
|
3155
4891
|
});
|
|
3156
4892
|
var ModelOverridesSchema = zod.z.object({
|
|
3157
4893
|
t1: zod.z.string().optional(),
|
|
@@ -4000,6 +5736,7 @@ init_openai();
|
|
|
4000
5736
|
|
|
4001
5737
|
// src/core/router/selector.ts
|
|
4002
5738
|
init_constants();
|
|
5739
|
+
init_pricing();
|
|
4003
5740
|
function normalizeModelId(id) {
|
|
4004
5741
|
return id.replace(/^models\//, "").toLowerCase();
|
|
4005
5742
|
}
|
|
@@ -4201,7 +5938,7 @@ var ModelSelector = class {
|
|
|
4201
5938
|
else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
|
|
4202
5939
|
}
|
|
4203
5940
|
if (providerStr && this.availableProviders.has(providerStr)) {
|
|
4204
|
-
const dynamicModel = {
|
|
5941
|
+
const dynamicModel = withResolvedPricing({
|
|
4205
5942
|
id: actualId,
|
|
4206
5943
|
name: actualId,
|
|
4207
5944
|
provider: providerStr,
|
|
@@ -4212,7 +5949,7 @@ var ModelSelector = class {
|
|
|
4212
5949
|
maxOutputTokens: 8e3,
|
|
4213
5950
|
supportsStreaming: true,
|
|
4214
5951
|
isLocal: providerStr === "ollama"
|
|
4215
|
-
};
|
|
5952
|
+
});
|
|
4216
5953
|
this.addDynamicModel(dynamicModel);
|
|
4217
5954
|
return dynamicModel;
|
|
4218
5955
|
}
|
|
@@ -4582,6 +6319,7 @@ function computeDelegationSavings(stats, t1Model) {
|
|
|
4582
6319
|
|
|
4583
6320
|
// src/core/router/live-data.ts
|
|
4584
6321
|
init_constants();
|
|
6322
|
+
init_pricing();
|
|
4585
6323
|
var DEFAULT_SNAPSHOT_URL = "https://raw.githubusercontent.com/Varun-SV/Cascade-AI/main/src/core/router/benchmark-data.json";
|
|
4586
6324
|
var OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models";
|
|
4587
6325
|
var FETCH_TIMEOUT_MS = 8e3;
|
|
@@ -4599,6 +6337,8 @@ var LiveDataProvider = class {
|
|
|
4599
6337
|
snapshot = null;
|
|
4600
6338
|
prices = /* @__PURE__ */ new Map();
|
|
4601
6339
|
capabilities = /* @__PURE__ */ new Map();
|
|
6340
|
+
/** Dataset-vs-live price mismatches, deduped by `provider:modelId`. */
|
|
6341
|
+
disagreements = /* @__PURE__ */ new Map();
|
|
4602
6342
|
source = "bundled";
|
|
4603
6343
|
fetchedAt = 0;
|
|
4604
6344
|
loaded = false;
|
|
@@ -4752,14 +6492,45 @@ var LiveDataProvider = class {
|
|
|
4752
6492
|
/**
|
|
4753
6493
|
* Returns a price-corrected copy of each model when live pricing is known,
|
|
4754
6494
|
* leaving the original untouched (so the shared catalog is never mutated).
|
|
6495
|
+
*
|
|
6496
|
+
* Reconciliation policy (see reconcilePrice in pricing.ts): the bundled
|
|
6497
|
+
* dataset is the authoritative baseline, and a live quote overrides it
|
|
6498
|
+
* because it is fresher by construction — but the disagreement is RECORDED,
|
|
6499
|
+
* not swallowed. A dataset/live mismatch is the best signal available that
|
|
6500
|
+
* the committed prices have gone stale, so it must be visible rather than
|
|
6501
|
+
* silently resolved in either direction. A live quote of $0 for a non-local
|
|
6502
|
+
* model is rejected outright: that is the very failure mode this change
|
|
6503
|
+
* exists to prevent, and a marketplace's free-tier alias must never zero out
|
|
6504
|
+
* the price of the paid model Cascade is actually calling.
|
|
4755
6505
|
*/
|
|
4756
6506
|
applyLivePricing(models) {
|
|
4757
6507
|
return models.map((m) => {
|
|
4758
6508
|
const p = this.getLivePrice(m.baseModelId ?? m.id);
|
|
4759
6509
|
if (!p) return m;
|
|
4760
|
-
|
|
6510
|
+
const reconciled = reconcilePrice(m, p);
|
|
6511
|
+
if (reconciled.disagreement) this.recordDisagreement(reconciled.disagreement);
|
|
6512
|
+
if (!reconciled.accepted) return m;
|
|
6513
|
+
return {
|
|
6514
|
+
...m,
|
|
6515
|
+
inputCostPer1kTokens: reconciled.input,
|
|
6516
|
+
outputCostPer1kTokens: reconciled.output,
|
|
6517
|
+
pricingUnknown: false
|
|
6518
|
+
};
|
|
4761
6519
|
});
|
|
4762
6520
|
}
|
|
6521
|
+
recordDisagreement(d) {
|
|
6522
|
+
const key = `${d.provider}:${d.modelId}`;
|
|
6523
|
+
if (this.disagreements.has(key)) return;
|
|
6524
|
+
this.disagreements.set(key, d);
|
|
6525
|
+
}
|
|
6526
|
+
/**
|
|
6527
|
+
* Dataset-vs-live price mismatches seen this session, newest-model-first
|
|
6528
|
+
* insertion order. Surfaced by `cascade models --verbose`; a non-empty list
|
|
6529
|
+
* means src/core/router/pricing-data.json is probably due a refresh.
|
|
6530
|
+
*/
|
|
6531
|
+
getPriceDisagreements() {
|
|
6532
|
+
return [...this.disagreements.values()];
|
|
6533
|
+
}
|
|
4763
6534
|
/** Current capability facts for a model id, or null when unknown. */
|
|
4764
6535
|
getCapability(modelId) {
|
|
4765
6536
|
return this.capabilities.get(normalizeModelId2(modelId)) ?? null;
|
|
@@ -4956,7 +6727,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
4956
6727
|
tokensByTier: {},
|
|
4957
6728
|
inputTokensByTier: {},
|
|
4958
6729
|
outputTokensByTier: {},
|
|
4959
|
-
costByFeature: {}
|
|
6730
|
+
costByFeature: {},
|
|
6731
|
+
untrackedCostCalls: 0,
|
|
6732
|
+
untrackedCostModels: []
|
|
4960
6733
|
};
|
|
4961
6734
|
tierModels = /* @__PURE__ */ new Map();
|
|
4962
6735
|
/**
|
|
@@ -5306,7 +7079,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
5306
7079
|
`Model ${model.id} inference timed out after ${cloudTimeoutMs}ms`
|
|
5307
7080
|
);
|
|
5308
7081
|
}
|
|
5309
|
-
const
|
|
7082
|
+
const corrected = buildTokenUsage(
|
|
5310
7083
|
result.usage.inputTokens,
|
|
5311
7084
|
result.usage.outputTokens,
|
|
5312
7085
|
model
|
|
@@ -5315,7 +7088,8 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
5315
7088
|
...result,
|
|
5316
7089
|
usage: {
|
|
5317
7090
|
...result.usage,
|
|
5318
|
-
estimatedCostUsd:
|
|
7091
|
+
estimatedCostUsd: corrected.estimatedCostUsd,
|
|
7092
|
+
...corrected.costUnknown ? { costUnknown: true } : { costUnknown: void 0 }
|
|
5319
7093
|
}
|
|
5320
7094
|
};
|
|
5321
7095
|
if (!result || typeof result.content !== "string" || !result.usage) {
|
|
@@ -5502,7 +7276,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
5502
7276
|
tokensByTier: { ...this.stats.tokensByTier },
|
|
5503
7277
|
inputTokensByTier: { ...this.stats.inputTokensByTier },
|
|
5504
7278
|
outputTokensByTier: { ...this.stats.outputTokensByTier },
|
|
5505
|
-
costByFeature: { ...this.stats.costByFeature }
|
|
7279
|
+
costByFeature: { ...this.stats.costByFeature },
|
|
7280
|
+
untrackedCostCalls: this.stats.untrackedCostCalls,
|
|
7281
|
+
untrackedCostModels: [...this.stats.untrackedCostModels]
|
|
5506
7282
|
};
|
|
5507
7283
|
}
|
|
5508
7284
|
/**
|
|
@@ -5553,7 +7329,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
5553
7329
|
tokensByTier: {},
|
|
5554
7330
|
inputTokensByTier: {},
|
|
5555
7331
|
outputTokensByTier: {},
|
|
5556
|
-
costByFeature: {}
|
|
7332
|
+
costByFeature: {},
|
|
7333
|
+
untrackedCostCalls: 0,
|
|
7334
|
+
untrackedCostModels: []
|
|
5557
7335
|
};
|
|
5558
7336
|
this.sessionCostUsd = 0;
|
|
5559
7337
|
this.budgetState = "ok";
|
|
@@ -5738,6 +7516,18 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
|
|
|
5738
7516
|
if (featureTag) {
|
|
5739
7517
|
this.stats.costByFeature[featureTag] = (this.stats.costByFeature[featureTag] ?? 0) + usage.estimatedCostUsd;
|
|
5740
7518
|
}
|
|
7519
|
+
if (usage.costUnknown) {
|
|
7520
|
+
this.stats.untrackedCostCalls += 1;
|
|
7521
|
+
if (!this.stats.untrackedCostModels.includes(model.id)) {
|
|
7522
|
+
this.stats.untrackedCostModels.push(model.id);
|
|
7523
|
+
const capped = this.config?.budget?.maxCostPerRunUsd != null || this.config?.budget?.sessionBudgetUsd != null;
|
|
7524
|
+
this.emit("cost:untracked", {
|
|
7525
|
+
modelId: model.id,
|
|
7526
|
+
provider: model.provider,
|
|
7527
|
+
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.`
|
|
7528
|
+
});
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
5741
7531
|
this.runTokens += usage.totalTokens;
|
|
5742
7532
|
this.runCostUsd += usage.estimatedCostUsd;
|
|
5743
7533
|
this.updateBudgetState();
|
|
@@ -11268,6 +13058,7 @@ var noopTelemetry = {
|
|
|
11268
13058
|
};
|
|
11269
13059
|
|
|
11270
13060
|
// src/core/router/task-analyzer.ts
|
|
13061
|
+
init_pricing();
|
|
11271
13062
|
var CODE_SIGNALS = [
|
|
11272
13063
|
/\b(?:function|class|interface|async|await|import|export|const|let|var|def|return|if|else|for|while|try|catch)\b/,
|
|
11273
13064
|
/\b(?:typescript|javascript|python|rust|go|java|c\+\+|sql|bash|shell|dockerfile|kubernetes|terraform)\b/i,
|
|
@@ -11444,8 +13235,8 @@ var TaskAnalyzer = class {
|
|
|
11444
13235
|
}
|
|
11445
13236
|
costEfficiency(model, complexity) {
|
|
11446
13237
|
if (this.tracker) return this.tracker.costEfficiencyScore(model, complexity);
|
|
11447
|
-
const blended = model
|
|
11448
|
-
const normalised = Math.min(1, blended /
|
|
13238
|
+
const blended = blendedCostPer1k(model);
|
|
13239
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
11449
13240
|
const complexityWeight = (6 - complexity) / 5;
|
|
11450
13241
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
11451
13242
|
}
|
|
@@ -11460,6 +13251,9 @@ var TaskAnalyzer = class {
|
|
|
11460
13251
|
analysisCache.clear();
|
|
11461
13252
|
}
|
|
11462
13253
|
};
|
|
13254
|
+
|
|
13255
|
+
// src/core/router/model-performance-tracker.ts
|
|
13256
|
+
init_pricing();
|
|
11463
13257
|
var DEFAULT_STATS_FILE = path32__default.default.join(os10__default.default.homedir(), ".cascade", "model-perf.json");
|
|
11464
13258
|
var ModelPerformanceTracker = class {
|
|
11465
13259
|
stats = /* @__PURE__ */ new Map();
|
|
@@ -11580,8 +13374,8 @@ var ModelPerformanceTracker = class {
|
|
|
11580
13374
|
* normalised over $0.05 blended as the "expensive" ceiling.
|
|
11581
13375
|
*/
|
|
11582
13376
|
costEfficiencyScore(model, complexity) {
|
|
11583
|
-
const blended = model
|
|
11584
|
-
const normalised = Math.min(1, blended /
|
|
13377
|
+
const blended = blendedCostPer1k(model);
|
|
13378
|
+
const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
|
|
11585
13379
|
const complexityWeight = (6 - complexity) / 5;
|
|
11586
13380
|
return Math.max(0.1, 1 - normalised * complexityWeight);
|
|
11587
13381
|
}
|
|
@@ -14385,7 +16179,11 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
14385
16179
|
inputTokens: 0,
|
|
14386
16180
|
outputTokens: 0,
|
|
14387
16181
|
totalTokens: stats.totalTokens,
|
|
14388
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
16182
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
16183
|
+
// At least one call ran on a model with no known price, so its spend is
|
|
16184
|
+
// missing from the total above. Say so rather than letting the caller
|
|
16185
|
+
// present an undercount as the final figure.
|
|
16186
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
14389
16187
|
},
|
|
14390
16188
|
t2Results,
|
|
14391
16189
|
durationMs,
|
|
@@ -14455,7 +16253,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
14455
16253
|
inputTokens: 0,
|
|
14456
16254
|
outputTokens: 0,
|
|
14457
16255
|
totalTokens: stats2.totalTokens,
|
|
14458
|
-
estimatedCostUsd: stats2.totalCostUsd
|
|
16256
|
+
estimatedCostUsd: stats2.totalCostUsd,
|
|
16257
|
+
...stats2.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
14459
16258
|
},
|
|
14460
16259
|
t2Results: [],
|
|
14461
16260
|
durationMs: Date.now() - startMs,
|
|
@@ -14479,7 +16278,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial;
|
|
|
14479
16278
|
inputTokens: result.usage?.inputTokens ?? 0,
|
|
14480
16279
|
outputTokens: result.usage?.outputTokens ?? 0,
|
|
14481
16280
|
totalTokens: stats.totalTokens,
|
|
14482
|
-
estimatedCostUsd: stats.totalCostUsd
|
|
16281
|
+
estimatedCostUsd: stats.totalCostUsd,
|
|
16282
|
+
...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
|
|
14483
16283
|
},
|
|
14484
16284
|
t2Results: [],
|
|
14485
16285
|
durationMs: Date.now() - startMs,
|
|
@@ -19696,7 +21496,10 @@ var DashboardServer = class {
|
|
|
19696
21496
|
this.socket.broadcast("cost:update", {
|
|
19697
21497
|
sessionId,
|
|
19698
21498
|
totalTokens: result.usage.totalTokens,
|
|
19699
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
21499
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
21500
|
+
// True when a model with no known price was used: the total above is
|
|
21501
|
+
// an undercount, and the UI must not present it as the full spend.
|
|
21502
|
+
costUnknown: result.usage.costUnknown === true
|
|
19700
21503
|
});
|
|
19701
21504
|
this.throttledBroadcast("workspace");
|
|
19702
21505
|
} catch (err) {
|
|
@@ -20009,7 +21812,8 @@ var DashboardServer = class {
|
|
|
20009
21812
|
this.socket.broadcast("cost:update", {
|
|
20010
21813
|
sessionId,
|
|
20011
21814
|
totalTokens: result.usage.totalTokens,
|
|
20012
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
21815
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
21816
|
+
costUnknown: result.usage.costUnknown === true
|
|
20013
21817
|
});
|
|
20014
21818
|
this.throttledBroadcast("workspace");
|
|
20015
21819
|
} catch (err) {
|
|
@@ -20551,7 +22355,8 @@ ${prompt}`;
|
|
|
20551
22355
|
this.socket.broadcast("cost:update", {
|
|
20552
22356
|
sessionId,
|
|
20553
22357
|
totalTokens: result.usage.totalTokens,
|
|
20554
|
-
totalCostUsd: result.usage.estimatedCostUsd
|
|
22358
|
+
totalCostUsd: result.usage.estimatedCostUsd,
|
|
22359
|
+
costUnknown: result.usage.costUnknown === true
|
|
20555
22360
|
});
|
|
20556
22361
|
this.socket.broadcastToRoom(`session:${sessionId}`, "session:complete", { sessionId, result });
|
|
20557
22362
|
this.throttledBroadcast("workspace");
|
|
@@ -20947,6 +22752,7 @@ function makeIdentityCommand(workspacePath = process.cwd()) {
|
|
|
20947
22752
|
});
|
|
20948
22753
|
return identity;
|
|
20949
22754
|
}
|
|
22755
|
+
init_pricing();
|
|
20950
22756
|
async function modelsCommand(options = {}) {
|
|
20951
22757
|
console.log(chalk7__default.default.magenta("\n \u25C8 Cascade Models\n"));
|
|
20952
22758
|
const cm = new ConfigManager(process.cwd());
|
|
@@ -20968,17 +22774,20 @@ async function modelsCommand(options = {}) {
|
|
|
20968
22774
|
{ tier: "T3", label: "T3 Worker", color: chalk7__default.default.hex("#2DD4BF") }
|
|
20969
22775
|
];
|
|
20970
22776
|
let anyMissing = false;
|
|
22777
|
+
let anyUnpriced = false;
|
|
20971
22778
|
for (const { tier, label, color } of tiers) {
|
|
20972
22779
|
const model = router.getTierModel(tier);
|
|
20973
22780
|
if (model) {
|
|
20974
|
-
const
|
|
20975
|
-
|
|
22781
|
+
const unpriced = isPricingUnknown(model);
|
|
22782
|
+
if (unpriced) anyUnpriced = true;
|
|
22783
|
+
const costIn = unpriced ? "cost not tracked" : model.inputCostPer1kTokens === 0 ? "free" : `$${model.inputCostPer1kTokens.toFixed(4)}/1K in`;
|
|
22784
|
+
const costOut = unpriced ? "" : model.outputCostPer1kTokens === 0 ? "free" : `, $${model.outputCostPer1kTokens.toFixed(4)}/1K out`;
|
|
20976
22785
|
const ctx = model.contextWindow >= 1e6 ? `${(model.contextWindow / 1e6).toFixed(1)}M ctx` : `${(model.contextWindow / 1e3).toFixed(0)}K ctx`;
|
|
20977
22786
|
const local = model.isLocal ? chalk7__default.default.gray(" [local]") : "";
|
|
20978
22787
|
const vision = model.isVisionCapable ? chalk7__default.default.gray(" \u{1F441}") : "";
|
|
20979
22788
|
const bench = Math.round(benchmarkScore01(model, "mixed") * 100);
|
|
20980
22789
|
console.log(
|
|
20981
|
-
` ${color.bold(tier)} ${chalk7__default.default.white(col(model.name, 24))}${chalk7__default.default.gray(col(model.provider, 16))}` + (options.verbose ? `${chalk7__default.default.gray(col(ctx, 12))}${chalk7__default.default.gray(col(`bench ${bench}/100`, 14))}${chalk7__default.default.gray(`${costIn}
|
|
22790
|
+
` ${color.bold(tier)} ${chalk7__default.default.white(col(model.name, 24))}${chalk7__default.default.gray(col(model.provider, 16))}` + (options.verbose ? `${chalk7__default.default.gray(col(ctx, 12))}${chalk7__default.default.gray(col(`bench ${bench}/100`, 14))}${chalk7__default.default.gray(`${costIn}${costOut}`)}` : `${chalk7__default.default.gray(col(ctx, 10))}${chalk7__default.default.gray(`bench ${bench}/100`)}`) + local + vision
|
|
20982
22791
|
);
|
|
20983
22792
|
} else {
|
|
20984
22793
|
console.log(` ${color.bold(tier)} ${chalk7__default.default.red("No model available")} ${chalk7__default.default.gray(`(check provider config for ${label})`)}`);
|
|
@@ -20992,8 +22801,25 @@ async function modelsCommand(options = {}) {
|
|
|
20992
22801
|
const src = liveData.getDataSource();
|
|
20993
22802
|
const gen = liveData.getGeneratedAt();
|
|
20994
22803
|
const srcLabel = src === "live" ? "live (just fetched)" : src === "cache" ? "cached" : "bundled";
|
|
22804
|
+
const pricingMeta = pricingDatasetMeta();
|
|
20995
22805
|
console.log(chalk7__default.default.gray(
|
|
20996
|
-
` Benchmark data: ${srcLabel}` + (gen ? ` \xB7 updated ${gen.slice(0, 10)}` : "") + ` \xB7 pricing: ${liveData.hasLivePricing() ? "live (OpenRouter)" : "
|
|
22806
|
+
` Benchmark data: ${srcLabel}` + (gen ? ` \xB7 updated ${gen.slice(0, 10)}` : "") + ` \xB7 pricing: ${liveData.hasLivePricing() ? "live (OpenRouter)" : "dataset"} (baseline ${pricingMeta.generatedAt})`
|
|
22807
|
+
));
|
|
22808
|
+
const drift = liveData.getPriceDisagreements();
|
|
22809
|
+
if (drift.length) {
|
|
22810
|
+
console.log(chalk7__default.default.yellow(`
|
|
22811
|
+
${drift.length} model${drift.length === 1 ? "" : "s"} priced differently by the live source than by the bundled dataset:`));
|
|
22812
|
+
for (const d of drift.slice(0, 10)) {
|
|
22813
|
+
console.log(chalk7__default.default.gray(
|
|
22814
|
+
` ${d.provider}:${d.modelId} dataset $${d.dataset.input.toFixed(5)}/$${d.dataset.output.toFixed(5)} per 1K (as of ${d.datasetAsOf}) \u2192 live $${d.live.input.toFixed(5)}/$${d.live.output.toFixed(5)} (${d.ratio}\xD7)`
|
|
22815
|
+
));
|
|
22816
|
+
}
|
|
22817
|
+
console.log(chalk7__default.default.gray(" Live pricing is used. Refresh src/core/router/pricing-data.json to clear this."));
|
|
22818
|
+
}
|
|
22819
|
+
}
|
|
22820
|
+
if (anyUnpriced) {
|
|
22821
|
+
console.log(chalk7__default.default.yellow(
|
|
22822
|
+
'\n Some tiers use a model with no published price \u2014 their spend is reported as "cost not tracked", never $0.00,\n and is not counted toward a cost budget. Add the model to the pricing dataset, or set `local: true` on the\n provider if the endpoint genuinely costs nothing to run.'
|
|
20997
22823
|
));
|
|
20998
22824
|
}
|
|
20999
22825
|
if (options.verbose) {
|