@stll/ai-catalog 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,2048 +1,2 @@
1
- import * as v from "valibot";
2
- //#region src/capabilities.gen.ts
3
- /**
4
- * Offered models whose provider API accepts PDF/file content. Generated from
5
- * live input-modality metadata plus reviewed source corrections.
6
- */
7
- const MODEL_DOCUMENT_INPUT_OPTIONS = {
8
- google: [
9
- "gemini-3.8-flash",
10
- "gemini-3.7-flash",
11
- "gemini-3.6-flash",
12
- "gemini-3.5-flash-lite",
13
- "gemini-3.1-pro-preview",
14
- "gemini-3.5-flash",
15
- "gemini-3.1-flash-lite"
16
- ],
17
- openrouter: [
18
- "openai/gpt-6.1-sol",
19
- "openai/gpt-6-astra",
20
- "openai/gpt-6-sol",
21
- "openai/gpt-6-luna",
22
- "openai/gpt-5.6-sol",
23
- "openai/gpt-5.6-terra",
24
- "openai/gpt-5.6-luna",
25
- "google/gemini-3.8-flash",
26
- "google/gemini-3.7-flash",
27
- "google/gemini-3.6-flash",
28
- "google/gemini-3.5-flash-lite",
29
- "google/gemini-3.1-pro-preview",
30
- "google/gemini-3.5-flash",
31
- "google/gemini-3.1-flash-lite",
32
- "anthropic/claude-sonnet-5.5",
33
- "anthropic/claude-sonnet-5",
34
- "anthropic/claude-opus-5",
35
- "anthropic/claude-opus-4.8",
36
- "anthropic/claude-sonnet-4.6",
37
- "openai/gpt-5.5",
38
- "openai/gpt-5.4-mini"
39
- ],
40
- openai: [
41
- "gpt-6.1-sol",
42
- "gpt-6-astra",
43
- "gpt-6-sol",
44
- "gpt-6-luna",
45
- "gpt-5.6",
46
- "gpt-5.6-terra",
47
- "gpt-5.6-luna",
48
- "gpt-5.5",
49
- "gpt-5.4",
50
- "gpt-5.4-mini",
51
- "gpt-5.4-nano",
52
- "gpt-5.2"
53
- ],
54
- anthropic: [
55
- "claude-sonnet-5-5",
56
- "claude-sonnet-5",
57
- "claude-fable-5-1",
58
- "claude-fable-5",
59
- "claude-opus-5-5",
60
- "claude-opus-5",
61
- "claude-opus-4-8",
62
- "claude-opus-4-7",
63
- "claude-sonnet-4-6",
64
- "claude-opus-4-6",
65
- "claude-haiku-4-5-20251001"
66
- ],
67
- bedrock: [
68
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
69
- "us.anthropic.claude-haiku-4-5-20251001-v1:0",
70
- "us.amazon.nova-pro-v1:0",
71
- "us.amazon.nova-lite-v1:0"
72
- ],
73
- mistral: []
74
- };
75
- /**
76
- * Reasoning-effort values each offered model accepts, `null` when the
77
- * model exposes no effort-style reasoning control. A missing `"none"`
78
- * means the model's reasoning cannot be disabled; consumers must go
79
- * through `resolveReasoningEffort`.
80
- */
81
- const MODEL_REASONING_EFFORTS = {
82
- "gemini-3.8-flash": [
83
- "low",
84
- "medium",
85
- "high"
86
- ],
87
- "gemini-3.7-flash": [
88
- "low",
89
- "medium",
90
- "high"
91
- ],
92
- "gemini-3.6-flash": [
93
- "minimal",
94
- "low",
95
- "medium",
96
- "high"
97
- ],
98
- "gemini-3.5-flash-lite": [
99
- "minimal",
100
- "low",
101
- "medium",
102
- "high"
103
- ],
104
- "gemini-3.1-pro-preview": [
105
- "low",
106
- "medium",
107
- "high"
108
- ],
109
- "gemini-3.5-flash": [
110
- "minimal",
111
- "low",
112
- "medium",
113
- "high"
114
- ],
115
- "gemini-3.1-flash-lite": [
116
- "minimal",
117
- "low",
118
- "medium",
119
- "high"
120
- ],
121
- "openai/gpt-6.1-sol": [
122
- "low",
123
- "medium",
124
- "high",
125
- "xhigh",
126
- "max"
127
- ],
128
- "openai/gpt-6-astra": [
129
- "low",
130
- "medium",
131
- "high",
132
- "xhigh",
133
- "max"
134
- ],
135
- "openai/gpt-6-sol": [
136
- "none",
137
- "low",
138
- "medium",
139
- "high",
140
- "xhigh",
141
- "max"
142
- ],
143
- "openai/gpt-6-luna": [
144
- "none",
145
- "low",
146
- "medium",
147
- "high",
148
- "xhigh",
149
- "max"
150
- ],
151
- "openai/gpt-5.6-sol": [
152
- "none",
153
- "low",
154
- "medium",
155
- "high",
156
- "xhigh",
157
- "max"
158
- ],
159
- "openai/gpt-5.6-terra": [
160
- "none",
161
- "low",
162
- "medium",
163
- "high",
164
- "xhigh",
165
- "max"
166
- ],
167
- "openai/gpt-5.6-luna": [
168
- "none",
169
- "low",
170
- "medium",
171
- "high",
172
- "xhigh",
173
- "max"
174
- ],
175
- "google/gemini-3.8-flash": [
176
- "low",
177
- "medium",
178
- "high"
179
- ],
180
- "google/gemini-3.7-flash": [
181
- "low",
182
- "medium",
183
- "high"
184
- ],
185
- "google/gemini-3.6-flash": [
186
- "minimal",
187
- "low",
188
- "medium",
189
- "high"
190
- ],
191
- "google/gemini-3.5-flash-lite": [
192
- "minimal",
193
- "low",
194
- "medium",
195
- "high"
196
- ],
197
- "google/gemini-3.1-pro-preview": [
198
- "low",
199
- "medium",
200
- "high"
201
- ],
202
- "google/gemini-3.5-flash": [
203
- "minimal",
204
- "low",
205
- "medium",
206
- "high"
207
- ],
208
- "google/gemini-3.1-flash-lite": [
209
- "none",
210
- "minimal",
211
- "low",
212
- "medium",
213
- "high"
214
- ],
215
- "anthropic/claude-sonnet-5.5": [
216
- "low",
217
- "medium",
218
- "high",
219
- "xhigh",
220
- "max"
221
- ],
222
- "anthropic/claude-sonnet-5": [
223
- "none",
224
- "low",
225
- "medium",
226
- "high",
227
- "xhigh",
228
- "max"
229
- ],
230
- "anthropic/claude-opus-5": [
231
- "none",
232
- "low",
233
- "medium",
234
- "high",
235
- "xhigh",
236
- "max"
237
- ],
238
- "anthropic/claude-opus-4.8": [
239
- "none",
240
- "low",
241
- "medium",
242
- "high",
243
- "xhigh",
244
- "max"
245
- ],
246
- "anthropic/claude-sonnet-4.6": [
247
- "none",
248
- "low",
249
- "medium",
250
- "high",
251
- "max"
252
- ],
253
- "openai/gpt-5.5": [
254
- "none",
255
- "low",
256
- "medium",
257
- "high",
258
- "xhigh"
259
- ],
260
- "openai/gpt-5.4-mini": [
261
- "none",
262
- "low",
263
- "medium",
264
- "high",
265
- "xhigh"
266
- ],
267
- "gpt-6.1-sol": [
268
- "low",
269
- "medium",
270
- "high",
271
- "xhigh",
272
- "max"
273
- ],
274
- "gpt-6-astra": [
275
- "low",
276
- "medium",
277
- "high",
278
- "xhigh",
279
- "max"
280
- ],
281
- "gpt-6-sol": [
282
- "none",
283
- "low",
284
- "medium",
285
- "high",
286
- "xhigh",
287
- "max"
288
- ],
289
- "gpt-6-luna": [
290
- "none",
291
- "low",
292
- "medium",
293
- "high",
294
- "xhigh",
295
- "max"
296
- ],
297
- "gpt-5.6": [
298
- "none",
299
- "low",
300
- "medium",
301
- "high",
302
- "xhigh",
303
- "max"
304
- ],
305
- "gpt-5.6-terra": [
306
- "none",
307
- "low",
308
- "medium",
309
- "high",
310
- "xhigh",
311
- "max"
312
- ],
313
- "gpt-5.6-luna": [
314
- "none",
315
- "low",
316
- "medium",
317
- "high",
318
- "xhigh",
319
- "max"
320
- ],
321
- "gpt-5.5": [
322
- "none",
323
- "low",
324
- "medium",
325
- "high",
326
- "xhigh"
327
- ],
328
- "gpt-5.4": [
329
- "none",
330
- "low",
331
- "medium",
332
- "high",
333
- "xhigh"
334
- ],
335
- "gpt-5.4-mini": [
336
- "none",
337
- "low",
338
- "medium",
339
- "high",
340
- "xhigh"
341
- ],
342
- "gpt-5.4-nano": [
343
- "none",
344
- "low",
345
- "medium",
346
- "high",
347
- "xhigh"
348
- ],
349
- "gpt-5.2": [
350
- "none",
351
- "low",
352
- "medium",
353
- "high",
354
- "xhigh"
355
- ],
356
- "claude-sonnet-5-5": [
357
- "low",
358
- "medium",
359
- "high",
360
- "xhigh",
361
- "max"
362
- ],
363
- "claude-sonnet-5": [
364
- "none",
365
- "low",
366
- "medium",
367
- "high",
368
- "xhigh",
369
- "max"
370
- ],
371
- "claude-fable-5-1": [
372
- "low",
373
- "medium",
374
- "high",
375
- "xhigh",
376
- "max"
377
- ],
378
- "claude-fable-5": [
379
- "low",
380
- "medium",
381
- "high",
382
- "xhigh",
383
- "max"
384
- ],
385
- "claude-opus-5-5": [
386
- "low",
387
- "medium",
388
- "high",
389
- "xhigh",
390
- "max"
391
- ],
392
- "claude-opus-5": [
393
- "low",
394
- "medium",
395
- "high",
396
- "xhigh",
397
- "max"
398
- ],
399
- "claude-opus-4-8": [
400
- "low",
401
- "medium",
402
- "high",
403
- "xhigh",
404
- "max"
405
- ],
406
- "claude-opus-4-7": [
407
- "low",
408
- "medium",
409
- "high",
410
- "xhigh",
411
- "max"
412
- ],
413
- "claude-sonnet-4-6": [
414
- "low",
415
- "medium",
416
- "high",
417
- "max"
418
- ],
419
- "claude-opus-4-6": [
420
- "low",
421
- "medium",
422
- "high",
423
- "max"
424
- ],
425
- "claude-haiku-4-5-20251001": null,
426
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": null,
427
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": null,
428
- "us.amazon.nova-pro-v1:0": null,
429
- "us.amazon.nova-lite-v1:0": null,
430
- "us.amazon.nova-micro-v1:0": null,
431
- "openai.gpt-oss-120b-1:0": [
432
- "low",
433
- "medium",
434
- "high"
435
- ],
436
- "openai.gpt-oss-20b-1:0": [
437
- "low",
438
- "medium",
439
- "high"
440
- ],
441
- "mistral-large-latest": null,
442
- "mistral-medium-latest": ["none", "high"],
443
- "mistral-small-latest": ["none", "high"]
444
- };
445
- /**
446
- * Concrete provider-default effort where the upstream catalogue publishes
447
- * one. OpenRouter is the source today; null means the provider does not expose
448
- * a truthful named default, so clients must retain a separate Default choice.
449
- */
450
- const MODEL_DEFAULT_REASONING_EFFORTS = {
451
- "gemini-3.8-flash": null,
452
- "gemini-3.7-flash": null,
453
- "gemini-3.6-flash": null,
454
- "gemini-3.5-flash-lite": null,
455
- "gemini-3.1-pro-preview": null,
456
- "gemini-3.5-flash": null,
457
- "gemini-3.1-flash-lite": null,
458
- "openai/gpt-6.1-sol": "medium",
459
- "openai/gpt-6-astra": "medium",
460
- "openai/gpt-6-sol": "medium",
461
- "openai/gpt-6-luna": "medium",
462
- "openai/gpt-5.6-sol": "medium",
463
- "openai/gpt-5.6-terra": "medium",
464
- "openai/gpt-5.6-luna": "medium",
465
- "google/gemini-3.8-flash": "medium",
466
- "google/gemini-3.7-flash": "medium",
467
- "google/gemini-3.6-flash": "medium",
468
- "google/gemini-3.5-flash-lite": "minimal",
469
- "google/gemini-3.1-pro-preview": "medium",
470
- "google/gemini-3.5-flash": "medium",
471
- "google/gemini-3.1-flash-lite": "minimal",
472
- "anthropic/claude-sonnet-5.5": "high",
473
- "anthropic/claude-sonnet-5": "high",
474
- "anthropic/claude-opus-5": "high",
475
- "anthropic/claude-opus-4.8": "high",
476
- "anthropic/claude-sonnet-4.6": "medium",
477
- "openai/gpt-5.5": "medium",
478
- "openai/gpt-5.4-mini": "medium",
479
- "gpt-6.1-sol": null,
480
- "gpt-6-astra": null,
481
- "gpt-6-sol": null,
482
- "gpt-6-luna": null,
483
- "gpt-5.6": null,
484
- "gpt-5.6-terra": null,
485
- "gpt-5.6-luna": null,
486
- "gpt-5.5": null,
487
- "gpt-5.4": null,
488
- "gpt-5.4-mini": null,
489
- "gpt-5.4-nano": null,
490
- "gpt-5.2": null,
491
- "claude-sonnet-5-5": null,
492
- "claude-sonnet-5": null,
493
- "claude-fable-5-1": null,
494
- "claude-fable-5": null,
495
- "claude-opus-5-5": null,
496
- "claude-opus-5": null,
497
- "claude-opus-4-8": null,
498
- "claude-opus-4-7": null,
499
- "claude-sonnet-4-6": null,
500
- "claude-opus-4-6": null,
501
- "claude-haiku-4-5-20251001": null,
502
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": null,
503
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": null,
504
- "us.amazon.nova-pro-v1:0": null,
505
- "us.amazon.nova-lite-v1:0": null,
506
- "us.amazon.nova-micro-v1:0": null,
507
- "openai.gpt-oss-120b-1:0": null,
508
- "openai.gpt-oss-20b-1:0": null,
509
- "mistral-large-latest": null,
510
- "mistral-medium-latest": null,
511
- "mistral-small-latest": null
512
- };
513
- /**
514
- * Whether stella should emit a `temperature` sampling override.
515
- * `"omit"` covers rejected, deprecated, and accepted-but-ignored
516
- * parameters. Consumers must go through `shouldEmitTemperature`.
517
- */
518
- const MODEL_TEMPERATURE_POLICIES = {
519
- "gemini-3.8-flash": "omit",
520
- "gemini-3.7-flash": "omit",
521
- "gemini-3.6-flash": "omit",
522
- "gemini-3.5-flash-lite": "omit",
523
- "gemini-3.1-pro-preview": "emit",
524
- "gemini-3.5-flash": "emit",
525
- "gemini-3.1-flash-lite": "emit",
526
- "openai/gpt-6.1-sol": "omit",
527
- "openai/gpt-6-astra": "omit",
528
- "openai/gpt-6-sol": "omit",
529
- "openai/gpt-6-luna": "omit",
530
- "openai/gpt-5.6-sol": "omit",
531
- "openai/gpt-5.6-terra": "omit",
532
- "openai/gpt-5.6-luna": "omit",
533
- "google/gemini-3.8-flash": "omit",
534
- "google/gemini-3.7-flash": "omit",
535
- "google/gemini-3.6-flash": "omit",
536
- "google/gemini-3.5-flash-lite": "omit",
537
- "google/gemini-3.1-pro-preview": "emit",
538
- "google/gemini-3.5-flash": "emit",
539
- "google/gemini-3.1-flash-lite": "emit",
540
- "anthropic/claude-sonnet-5.5": "emit",
541
- "anthropic/claude-sonnet-5": "omit",
542
- "anthropic/claude-opus-5": "emit",
543
- "anthropic/claude-opus-4.8": "emit",
544
- "anthropic/claude-sonnet-4.6": "emit",
545
- "openai/gpt-5.5": "omit",
546
- "openai/gpt-5.4-mini": "omit",
547
- "gpt-6.1-sol": "omit",
548
- "gpt-6-astra": "omit",
549
- "gpt-6-sol": "omit",
550
- "gpt-6-luna": "omit",
551
- "gpt-5.6": "omit",
552
- "gpt-5.6-terra": "omit",
553
- "gpt-5.6-luna": "omit",
554
- "gpt-5.5": "omit",
555
- "gpt-5.4": "emit",
556
- "gpt-5.4-mini": "emit",
557
- "gpt-5.4-nano": "emit",
558
- "gpt-5.2": "emit",
559
- "claude-sonnet-5-5": "omit",
560
- "claude-sonnet-5": "omit",
561
- "claude-fable-5-1": "omit",
562
- "claude-fable-5": "omit",
563
- "claude-opus-5-5": "omit",
564
- "claude-opus-5": "omit",
565
- "claude-opus-4-8": "omit",
566
- "claude-opus-4-7": "omit",
567
- "claude-sonnet-4-6": "emit",
568
- "claude-opus-4-6": "emit",
569
- "claude-haiku-4-5-20251001": "emit",
570
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": "emit",
571
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": "emit",
572
- "us.amazon.nova-pro-v1:0": "emit",
573
- "us.amazon.nova-lite-v1:0": "emit",
574
- "us.amazon.nova-micro-v1:0": "emit",
575
- "openai.gpt-oss-120b-1:0": "emit",
576
- "openai.gpt-oss-20b-1:0": "emit",
577
- "mistral-large-latest": "emit",
578
- "mistral-medium-latest": "emit",
579
- "mistral-small-latest": "emit"
580
- };
581
- /**
582
- * The most output tokens one response of each offered model may carry
583
- * (models.dev `limit.output`). Consumers must go through
584
- * `getOutputTokenLimit`.
585
- */
586
- const MODEL_OUTPUT_TOKEN_LIMITS = {
587
- "gemini-3.8-flash": 65536,
588
- "gemini-3.7-flash": 65536,
589
- "gemini-3.6-flash": 65536,
590
- "gemini-3.5-flash-lite": 65536,
591
- "gemini-3.1-pro-preview": 65536,
592
- "gemini-3.5-flash": 65536,
593
- "gemini-3.1-flash-lite": 65536,
594
- "openai/gpt-6.1-sol": 128e3,
595
- "openai/gpt-6-astra": 128e3,
596
- "openai/gpt-6-sol": 128e3,
597
- "openai/gpt-6-luna": 128e3,
598
- "openai/gpt-5.6-sol": 128e3,
599
- "openai/gpt-5.6-terra": 128e3,
600
- "openai/gpt-5.6-luna": 128e3,
601
- "google/gemini-3.8-flash": 65536,
602
- "google/gemini-3.7-flash": 65536,
603
- "google/gemini-3.6-flash": 65536,
604
- "google/gemini-3.5-flash-lite": 65536,
605
- "google/gemini-3.1-pro-preview": 65536,
606
- "google/gemini-3.5-flash": 65536,
607
- "google/gemini-3.1-flash-lite": 65536,
608
- "anthropic/claude-sonnet-5.5": 128e3,
609
- "anthropic/claude-sonnet-5": 128e3,
610
- "anthropic/claude-opus-5": 128e3,
611
- "anthropic/claude-opus-4.8": 128e3,
612
- "anthropic/claude-sonnet-4.6": 128e3,
613
- "openai/gpt-5.5": 128e3,
614
- "openai/gpt-5.4-mini": 128e3,
615
- "gpt-6.1-sol": 128e3,
616
- "gpt-6-astra": 128e3,
617
- "gpt-6-sol": 128e3,
618
- "gpt-6-luna": 128e3,
619
- "gpt-5.6": 128e3,
620
- "gpt-5.6-terra": 128e3,
621
- "gpt-5.6-luna": 128e3,
622
- "gpt-5.5": 128e3,
623
- "gpt-5.4": 128e3,
624
- "gpt-5.4-mini": 128e3,
625
- "gpt-5.4-nano": 128e3,
626
- "gpt-5.2": 128e3,
627
- "claude-sonnet-5-5": 128e3,
628
- "claude-sonnet-5": 128e3,
629
- "claude-fable-5-1": 128e3,
630
- "claude-fable-5": 128e3,
631
- "claude-opus-5-5": 128e3,
632
- "claude-opus-5": 128e3,
633
- "claude-opus-4-8": 128e3,
634
- "claude-opus-4-7": 128e3,
635
- "claude-sonnet-4-6": 128e3,
636
- "claude-opus-4-6": 128e3,
637
- "claude-haiku-4-5-20251001": 64e3,
638
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": 64e3,
639
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": 64e3,
640
- "us.amazon.nova-pro-v1:0": 1e4,
641
- "us.amazon.nova-lite-v1:0": 1e4,
642
- "us.amazon.nova-micro-v1:0": 1e4,
643
- "openai.gpt-oss-120b-1:0": 128e3,
644
- "openai.gpt-oss-20b-1:0": 128e3,
645
- "mistral-large-latest": 262144,
646
- "mistral-medium-latest": 262144,
647
- "mistral-small-latest": 256e3
648
- };
649
- //#endregion
650
- //#region src/model-rates.gen.ts
651
- const MODEL_RATES = {
652
- "gemini-3.8-flash": {
653
- kind: "flat",
654
- inputPerMTok: 75e3,
655
- outputPerMTok: 375e3,
656
- cachedInputPerMTok: 7500
657
- },
658
- "gemini-3.7-flash": {
659
- kind: "flat",
660
- inputPerMTok: 75e3,
661
- outputPerMTok: 375e3,
662
- cachedInputPerMTok: 7500
663
- },
664
- "gemini-3.6-flash": {
665
- kind: "flat",
666
- inputPerMTok: 75e3,
667
- outputPerMTok: 375e3,
668
- cachedInputPerMTok: 7500
669
- },
670
- "gemini-3.5-flash-lite": {
671
- kind: "flat",
672
- inputPerMTok: 3e4,
673
- outputPerMTok: 25e4,
674
- cachedInputPerMTok: 3e3
675
- },
676
- "gemini-3.1-pro-preview": {
677
- kind: "input-token-tiered",
678
- inputTokenThreshold: 2e5,
679
- standard: {
680
- inputPerMTok: 2e5,
681
- outputPerMTok: 12e5,
682
- cachedInputPerMTok: 2e4
683
- },
684
- aboveThreshold: {
685
- inputPerMTok: 4e5,
686
- outputPerMTok: 18e5,
687
- cachedInputPerMTok: 4e4
688
- }
689
- },
690
- "gemini-3.5-flash": {
691
- kind: "flat",
692
- inputPerMTok: 15e4,
693
- outputPerMTok: 9e5,
694
- cachedInputPerMTok: 15e3
695
- },
696
- "gemini-3.1-flash-lite": {
697
- kind: "flat",
698
- inputPerMTok: 25e3,
699
- outputPerMTok: 15e4,
700
- cachedInputPerMTok: 2500
701
- },
702
- "gpt-6.1-sol": {
703
- kind: "input-token-tiered",
704
- inputTokenThreshold: 272e3,
705
- standard: {
706
- inputPerMTok: 2e5,
707
- outputPerMTok: 1e6,
708
- cachedInputPerMTok: 1e4,
709
- cachedWriteInputPerMTok: 25e4
710
- },
711
- aboveThreshold: {
712
- inputPerMTok: 4e5,
713
- outputPerMTok: 15e5,
714
- cachedInputPerMTok: 2e4,
715
- cachedWriteInputPerMTok: 5e5
716
- }
717
- },
718
- "gpt-6-astra": {
719
- kind: "input-token-tiered",
720
- inputTokenThreshold: 272e3,
721
- standard: {
722
- inputPerMTok: 1e6,
723
- outputPerMTok: 5e6,
724
- cachedInputPerMTok: 1e5,
725
- cachedWriteInputPerMTok: 125e4
726
- },
727
- aboveThreshold: {
728
- inputPerMTok: 2e6,
729
- outputPerMTok: 75e5,
730
- cachedInputPerMTok: 2e5,
731
- cachedWriteInputPerMTok: 25e5
732
- }
733
- },
734
- "gpt-6-sol": {
735
- kind: "input-token-tiered",
736
- inputTokenThreshold: 272e3,
737
- standard: {
738
- inputPerMTok: 2e5,
739
- outputPerMTok: 1e6,
740
- cachedInputPerMTok: 2e4,
741
- cachedWriteInputPerMTok: 25e4
742
- },
743
- aboveThreshold: {
744
- inputPerMTok: 4e5,
745
- outputPerMTok: 15e5,
746
- cachedInputPerMTok: 4e4,
747
- cachedWriteInputPerMTok: 5e5
748
- }
749
- },
750
- "gpt-6-luna": {
751
- kind: "input-token-tiered",
752
- inputTokenThreshold: 272e3,
753
- standard: {
754
- inputPerMTok: 1e4,
755
- outputPerMTok: 5e4,
756
- cachedInputPerMTok: 1e3,
757
- cachedWriteInputPerMTok: 12500
758
- },
759
- aboveThreshold: {
760
- inputPerMTok: 2e4,
761
- outputPerMTok: 75e3,
762
- cachedInputPerMTok: 2e3,
763
- cachedWriteInputPerMTok: 25e3
764
- }
765
- },
766
- "gpt-5.6": {
767
- kind: "input-token-tiered",
768
- inputTokenThreshold: 272e3,
769
- standard: {
770
- inputPerMTok: 4e5,
771
- outputPerMTok: 2e6,
772
- cachedInputPerMTok: 4e4,
773
- cachedWriteInputPerMTok: 5e5
774
- },
775
- aboveThreshold: {
776
- inputPerMTok: 8e5,
777
- outputPerMTok: 3e6,
778
- cachedInputPerMTok: 8e4,
779
- cachedWriteInputPerMTok: 1e6
780
- }
781
- },
782
- "gpt-5.6-terra": {
783
- kind: "input-token-tiered",
784
- inputTokenThreshold: 272e3,
785
- standard: {
786
- inputPerMTok: 2e5,
787
- outputPerMTok: 12e5,
788
- cachedInputPerMTok: 2e4,
789
- cachedWriteInputPerMTok: 25e4
790
- },
791
- aboveThreshold: {
792
- inputPerMTok: 4e5,
793
- outputPerMTok: 18e5,
794
- cachedInputPerMTok: 4e4,
795
- cachedWriteInputPerMTok: 5e5
796
- }
797
- },
798
- "gpt-5.6-luna": {
799
- kind: "input-token-tiered",
800
- inputTokenThreshold: 272e3,
801
- standard: {
802
- inputPerMTok: 2e4,
803
- outputPerMTok: 12e4,
804
- cachedInputPerMTok: 2e3,
805
- cachedWriteInputPerMTok: 25e3
806
- },
807
- aboveThreshold: {
808
- inputPerMTok: 4e4,
809
- outputPerMTok: 18e4,
810
- cachedInputPerMTok: 4e3,
811
- cachedWriteInputPerMTok: 5e4
812
- }
813
- },
814
- "gpt-5.5": {
815
- kind: "input-token-tiered",
816
- inputTokenThreshold: 272e3,
817
- standard: {
818
- inputPerMTok: 5e5,
819
- outputPerMTok: 3e6,
820
- cachedInputPerMTok: 5e4
821
- },
822
- aboveThreshold: {
823
- inputPerMTok: 1e6,
824
- outputPerMTok: 45e5,
825
- cachedInputPerMTok: 1e5
826
- }
827
- },
828
- "gpt-5.4": {
829
- kind: "input-token-tiered",
830
- inputTokenThreshold: 272e3,
831
- standard: {
832
- inputPerMTok: 25e4,
833
- outputPerMTok: 15e5,
834
- cachedInputPerMTok: 25e3
835
- },
836
- aboveThreshold: {
837
- inputPerMTok: 5e5,
838
- outputPerMTok: 225e4,
839
- cachedInputPerMTok: 5e4
840
- }
841
- },
842
- "gpt-5.4-mini": {
843
- kind: "flat",
844
- inputPerMTok: 75e3,
845
- outputPerMTok: 45e4,
846
- cachedInputPerMTok: 7500
847
- },
848
- "gpt-5.4-nano": {
849
- kind: "flat",
850
- inputPerMTok: 2e4,
851
- outputPerMTok: 125e3,
852
- cachedInputPerMTok: 2e3
853
- },
854
- "gpt-5.2": {
855
- kind: "flat",
856
- inputPerMTok: 175e3,
857
- outputPerMTok: 14e5,
858
- cachedInputPerMTok: 17500
859
- },
860
- "claude-sonnet-5-5": {
861
- kind: "flat",
862
- inputPerMTok: 2e5,
863
- outputPerMTok: 1e6,
864
- cachedInputPerMTok: 2e4,
865
- cachedWriteInputPerMTok: 25e4
866
- },
867
- "claude-sonnet-5": {
868
- kind: "flat",
869
- inputPerMTok: 2e5,
870
- outputPerMTok: 1e6,
871
- cachedInputPerMTok: 2e4,
872
- cachedWriteInputPerMTok: 25e4
873
- },
874
- "claude-fable-5-1": {
875
- kind: "flat",
876
- inputPerMTok: 1e6,
877
- outputPerMTok: 5e6,
878
- cachedInputPerMTok: 25e3,
879
- cachedWriteInputPerMTok: 125e4
880
- },
881
- "claude-fable-5": {
882
- kind: "flat",
883
- inputPerMTok: 1e6,
884
- outputPerMTok: 5e6,
885
- cachedInputPerMTok: 1e5,
886
- cachedWriteInputPerMTok: 125e4
887
- },
888
- "claude-opus-5-5": {
889
- kind: "flat",
890
- inputPerMTok: 4e5,
891
- outputPerMTok: 2e6,
892
- cachedInputPerMTok: 2e4,
893
- cachedWriteInputPerMTok: 5e5
894
- },
895
- "claude-opus-5": {
896
- kind: "flat",
897
- inputPerMTok: 5e5,
898
- outputPerMTok: 25e5,
899
- cachedInputPerMTok: 5e4,
900
- cachedWriteInputPerMTok: 625e3
901
- },
902
- "claude-opus-4-8": {
903
- kind: "flat",
904
- inputPerMTok: 5e5,
905
- outputPerMTok: 25e5,
906
- cachedInputPerMTok: 5e4,
907
- cachedWriteInputPerMTok: 625e3
908
- },
909
- "claude-opus-4-7": {
910
- kind: "flat",
911
- inputPerMTok: 5e5,
912
- outputPerMTok: 25e5,
913
- cachedInputPerMTok: 5e4,
914
- cachedWriteInputPerMTok: 625e3
915
- },
916
- "claude-sonnet-4-6": {
917
- kind: "flat",
918
- inputPerMTok: 3e5,
919
- outputPerMTok: 15e5,
920
- cachedInputPerMTok: 3e4,
921
- cachedWriteInputPerMTok: 375e3
922
- },
923
- "claude-opus-4-6": {
924
- kind: "flat",
925
- inputPerMTok: 5e5,
926
- outputPerMTok: 25e5,
927
- cachedInputPerMTok: 5e4,
928
- cachedWriteInputPerMTok: 625e3
929
- },
930
- "claude-haiku-4-5-20251001": {
931
- kind: "flat",
932
- inputPerMTok: 1e5,
933
- outputPerMTok: 5e5,
934
- cachedInputPerMTok: 1e4,
935
- cachedWriteInputPerMTok: 125e3
936
- },
937
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": {
938
- kind: "flat",
939
- inputPerMTok: 33e4,
940
- outputPerMTok: 165e4,
941
- cachedInputPerMTok: 33e3,
942
- cachedWriteInputPerMTok: 412500
943
- },
944
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": {
945
- kind: "flat",
946
- inputPerMTok: 11e4,
947
- outputPerMTok: 55e4,
948
- cachedInputPerMTok: 11e3,
949
- cachedWriteInputPerMTok: 137500
950
- },
951
- "us.amazon.nova-pro-v1:0": {
952
- kind: "flat",
953
- inputPerMTok: 8e4,
954
- outputPerMTok: 32e4,
955
- cachedInputPerMTok: 2e4,
956
- cachedWriteInputPerMTok: 8e4
957
- },
958
- "us.amazon.nova-lite-v1:0": {
959
- kind: "flat",
960
- inputPerMTok: 6e3,
961
- outputPerMTok: 24e3,
962
- cachedInputPerMTok: 1500,
963
- cachedWriteInputPerMTok: 6e3
964
- },
965
- "us.amazon.nova-micro-v1:0": {
966
- kind: "flat",
967
- inputPerMTok: 3500,
968
- outputPerMTok: 14e3,
969
- cachedInputPerMTok: 875,
970
- cachedWriteInputPerMTok: 3500
971
- },
972
- "openai.gpt-oss-120b-1:0": {
973
- kind: "flat",
974
- inputPerMTok: 15e3,
975
- outputPerMTok: 6e4
976
- },
977
- "openai.gpt-oss-20b-1:0": {
978
- kind: "flat",
979
- inputPerMTok: 7e3,
980
- outputPerMTok: 3e4
981
- },
982
- "mistral-large-latest": {
983
- kind: "flat",
984
- inputPerMTok: 5e4,
985
- outputPerMTok: 15e4,
986
- cachedInputPerMTok: 5e3
987
- },
988
- "mistral-medium-latest": {
989
- kind: "flat",
990
- inputPerMTok: 15e4,
991
- outputPerMTok: 75e4,
992
- cachedInputPerMTok: 15e3
993
- },
994
- "mistral-small-latest": {
995
- kind: "flat",
996
- inputPerMTok: 15e3,
997
- outputPerMTok: 6e4,
998
- cachedInputPerMTok: 1500
999
- },
1000
- "gemini-2.5-flash": {
1001
- kind: "flat",
1002
- inputPerMTok: 3e4,
1003
- outputPerMTok: 25e4,
1004
- cachedInputPerMTok: 3e3
1005
- },
1006
- "gemini-2.5-pro": {
1007
- kind: "input-token-tiered",
1008
- inputTokenThreshold: 2e5,
1009
- standard: {
1010
- inputPerMTok: 125e3,
1011
- outputPerMTok: 1e6,
1012
- cachedInputPerMTok: 12500
1013
- },
1014
- aboveThreshold: {
1015
- inputPerMTok: 25e4,
1016
- outputPerMTok: 15e5,
1017
- cachedInputPerMTok: 25e3
1018
- }
1019
- },
1020
- "gpt-4o-mini": {
1021
- kind: "flat",
1022
- inputPerMTok: 15e3,
1023
- outputPerMTok: 6e4,
1024
- cachedInputPerMTok: 7500
1025
- },
1026
- "gpt-4o": {
1027
- kind: "flat",
1028
- inputPerMTok: 25e4,
1029
- outputPerMTok: 1e6,
1030
- cachedInputPerMTok: 125e3
1031
- },
1032
- "us.deepseek.r1-v1:0": {
1033
- kind: "flat",
1034
- inputPerMTok: 135e3,
1035
- outputPerMTok: 54e4
1036
- }
1037
- };
1038
- //#endregion
1039
- //#region src/model-rate.ts
1040
- /**
1041
- * models.dev publishes USD prices per one million tokens. Stella stores the
1042
- * same rates as integer ledger units so usage arithmetic never depends on
1043
- * floating point values.
1044
- */
1045
- const MODEL_RATE_UNITS_PER_USD = 1e5;
1046
- const getStandardModelRate = (rate) => rate.kind === "flat" ? rate : rate.standard;
1047
- const resolveModelRate = (rate, inputTokens) => rate.kind === "input-token-tiered" && inputTokens > rate.inputTokenThreshold ? rate.aboveThreshold : getStandardModelRate(rate);
1048
- //#endregion
1049
- //#region src/model-rate-policy.ts
1050
- const MODELS_DEV_RATE_PROVIDER_BY_CATALOG_PROVIDER = {
1051
- google: "google",
1052
- openai: "openai",
1053
- anthropic: "anthropic",
1054
- bedrock: "amazon-bedrock",
1055
- mistral: "mistral"
1056
- };
1057
- const defineRateSourceAliases = (aliases) => aliases;
1058
- /**
1059
- * Explicit source coordinates for non-offered model IDs that remain valid in
1060
- * deployment overrides and usage attribution. Their numeric rates still come
1061
- * exclusively from models.dev.
1062
- */
1063
- const RETAINED_MODELS_DEV_RATE_ENTRIES = {
1064
- "gemini-2.5-flash": {
1065
- modelId: "gemini-2.5-flash",
1066
- provider: "google"
1067
- },
1068
- "gemini-2.5-pro": {
1069
- modelId: "gemini-2.5-pro",
1070
- provider: "google"
1071
- },
1072
- "gpt-4o-mini": {
1073
- modelId: "gpt-4o-mini",
1074
- provider: "openai"
1075
- },
1076
- "gpt-4o": {
1077
- modelId: "gpt-4o",
1078
- provider: "openai"
1079
- },
1080
- "us.deepseek.r1-v1:0": {
1081
- modelId: "us.deepseek.r1-v1:0",
1082
- provider: "amazon-bedrock"
1083
- }
1084
- };
1085
- /**
1086
- * Exact mappings where Stella uses a provider routing ID while models.dev
1087
- * publishes pricing under the corresponding base model ID. Generation rejects
1088
- * a mapping once models.dev begins publishing the Stella ID directly, so the
1089
- * map is empty whenever upstream covers every offered ID.
1090
- */
1091
- const MODELS_DEV_RATE_SOURCE_ALIASES = defineRateSourceAliases({});
1092
- //#endregion
1093
- //#region src/capabilities-overrides.ts
1094
- const CAPABILITY_OVERRIDES = {};
1095
- //#endregion
1096
- //#region src/document-input-overrides.ts
1097
- /**
1098
- * Reviewed document-input corrections for models.dev records that exist but
1099
- * under-report the provider API's file-input support. The generator rejects an
1100
- * override once upstream agrees, so sourced data takes ownership automatically.
1101
- */
1102
- const DOCUMENT_INPUT_OVERRIDES = {
1103
- "gpt-5.4-mini": {
1104
- supported: true,
1105
- reason: "2026-08-20: OpenAI Responses accepts input_file PDF content for this vision-capable model; models.dev currently omits the pdf modality"
1106
- },
1107
- "gpt-5.4-nano": {
1108
- supported: true,
1109
- reason: "2026-08-20: OpenAI Responses accepts input_file PDF content for this vision-capable model; models.dev currently omits the pdf modality"
1110
- },
1111
- "gpt-5.2": {
1112
- supported: true,
1113
- reason: "2026-08-20: OpenAI Responses accepts input_file PDF content for this vision-capable model; models.dev currently omits the pdf modality"
1114
- }
1115
- };
1116
- //#endregion
1117
- //#region src/index.ts
1118
- /**
1119
- * Canonical AI provider and model catalog.
1120
- *
1121
- * Single source of truth for every provider/model identifier stella
1122
- * offers. Imported by the API runtime
1123
- * (`apps/api/src/lib/tanstack-ai-models.ts`)
1124
- * and the BYOK settings UI (`apps/web`), so the picker can never offer
1125
- * a model the backend rejects, and vice versa.
1126
- *
1127
- * Pure data: no provider SDKs, no env access, no side effects. This is
1128
- * deliberate so scripts (the nightly upstream-validation check) and
1129
- * both apps can import it cheaply. Keep it that way. The only runtime
1130
- * dependency is valibot, used solely to construct branded types the
1131
- * same way the rest of the repo does.
1132
- *
1133
- * Model IDs go stale when providers rename or retire models. The
1134
- * nightly `model-catalog-upstream` check
1135
- * (`packages/scripts/src/model-catalog-upstream.ts`) validates every
1136
- * ID here against live provider/aggregator listings so a retired model
1137
- * fails CI instead of 400-ing a user at runtime.
1138
- */
1139
- /**
1140
- * Logical model roles. Call sites declare *what* they need, not
1141
- * *which* model to use.
1142
- *
1143
- * - fast: classification, extraction, short generation
1144
- * - chat: conversational with tool use and streaming
1145
- * - reasoning: complex multi-step legal analysis
1146
- * - pdf: native PDF/image understanding
1147
- */
1148
- const MODEL_ROLES = [
1149
- "fast",
1150
- "chat",
1151
- "reasoning",
1152
- "pdf"
1153
- ];
1154
- const TEMPERATURE_POLICIES = ["emit", "omit"];
1155
- const STREAMING_TOOL_USE_SUPPORTS = ["supported", "unsupported"];
1156
- const AI_PROVIDERS = [
1157
- "google",
1158
- "openrouter",
1159
- "openai",
1160
- "azure_foundry",
1161
- "anthropic",
1162
- "bedrock",
1163
- "mistral",
1164
- "openai_compatible",
1165
- "huggingface"
1166
- ];
1167
- const TANSTACK_AI_PROVIDERS = [
1168
- "google",
1169
- "openrouter",
1170
- "openai",
1171
- "anthropic",
1172
- "bedrock",
1173
- "mistral"
1174
- ];
1175
- const MODEL_CATALOG_PROVIDER_KIND = {
1176
- google: "first-party",
1177
- openrouter: "aggregator",
1178
- openai: "first-party",
1179
- anthropic: "first-party",
1180
- bedrock: "platform",
1181
- mistral: "first-party"
1182
- };
1183
- /**
1184
- * Runtime form of the first-party provider union. The conditional annotation
1185
- * makes adding a first-party policy without adding its discovery implementation
1186
- * a compile error.
1187
- */
1188
- const FIRST_PARTY_MODEL_PROVIDERS = [
1189
- "google",
1190
- "openai",
1191
- "anthropic",
1192
- "mistral"
1193
- ];
1194
- /**
1195
- * Provider IDs for the GPT-6.1 family, kept in one row per member like GPT-6
1196
- * below.
1197
- */
1198
- const GPT_61_MODEL_IDS = { sol: {
1199
- openai: "gpt-6.1-sol",
1200
- openrouter: "openai/gpt-6.1-sol"
1201
- } };
1202
- const GPT_61_OPENAI_MODEL_IDS = Object.values(GPT_61_MODEL_IDS).map(({ openai }) => openai);
1203
- const GPT_61_OPENROUTER_MODEL_IDS = Object.values(GPT_61_MODEL_IDS).map(({ openrouter }) => openrouter);
1204
- /**
1205
- * Provider IDs for the GPT-6 family. Like GPT-5.6 below, one row feeds both
1206
- * the OpenAI and the OpenRouter picker.
1207
- */
1208
- const GPT_6_MODEL_IDS = {
1209
- astra: {
1210
- openai: "gpt-6-astra",
1211
- openrouter: "openai/gpt-6-astra"
1212
- },
1213
- sol: {
1214
- openai: "gpt-6-sol",
1215
- openrouter: "openai/gpt-6-sol"
1216
- },
1217
- luna: {
1218
- openai: "gpt-6-luna",
1219
- openrouter: "openai/gpt-6-luna"
1220
- }
1221
- };
1222
- const GPT_6_OPENAI_MODEL_IDS = Object.values(GPT_6_MODEL_IDS).map(({ openai }) => openai);
1223
- const GPT_6_OPENROUTER_MODEL_IDS = Object.values(GPT_6_MODEL_IDS).map(({ openrouter }) => openrouter);
1224
- /**
1225
- * Provider IDs for the GPT-5.6 family. OpenAI exposes Sol through the
1226
- * `gpt-5.6` alias while OpenRouter uses the explicit `gpt-5.6-sol` ID. Keep
1227
- * both routes in one row so adding a family member cannot update one picker
1228
- * and silently omit the other.
1229
- */
1230
- const GPT_56_MODEL_IDS = {
1231
- sol: {
1232
- openai: "gpt-5.6",
1233
- openrouter: "openai/gpt-5.6-sol"
1234
- },
1235
- terra: {
1236
- openai: "gpt-5.6-terra",
1237
- openrouter: "openai/gpt-5.6-terra"
1238
- },
1239
- luna: {
1240
- openai: "gpt-5.6-luna",
1241
- openrouter: "openai/gpt-5.6-luna"
1242
- }
1243
- };
1244
- const GPT_56_OPENAI_MODEL_IDS = Object.values(GPT_56_MODEL_IDS).map(({ openai }) => openai);
1245
- const GPT_56_OPENROUTER_MODEL_IDS = Object.values(GPT_56_MODEL_IDS).map(({ openrouter }) => openrouter);
1246
- /**
1247
- * Per-role default model IDs for the BYOK-capable cloud providers.
1248
- * Shared between the instance default table (`DEFAULT_MODELS`) and the
1249
- * settings-UI default selection, so a default is defined exactly once.
1250
- */
1251
- const BYOK_DEFAULT_MODELS = {
1252
- google: {
1253
- fast: "gemini-3.8-flash",
1254
- chat: "gemini-3.8-flash",
1255
- reasoning: "gemini-3.8-flash",
1256
- pdf: "gemini-3.8-flash"
1257
- },
1258
- openrouter: {
1259
- fast: GPT_6_MODEL_IDS.luna.openrouter,
1260
- chat: GPT_6_MODEL_IDS.sol.openrouter,
1261
- reasoning: GPT_6_MODEL_IDS.sol.openrouter,
1262
- pdf: GPT_6_MODEL_IDS.sol.openrouter
1263
- },
1264
- openai: {
1265
- fast: GPT_6_MODEL_IDS.luna.openai,
1266
- chat: GPT_6_MODEL_IDS.sol.openai,
1267
- reasoning: GPT_6_MODEL_IDS.sol.openai,
1268
- pdf: GPT_6_MODEL_IDS.sol.openai
1269
- },
1270
- anthropic: {
1271
- fast: "claude-opus-5-5",
1272
- chat: "claude-opus-5-5",
1273
- reasoning: "claude-opus-5-5",
1274
- pdf: "claude-opus-5-5"
1275
- },
1276
- bedrock: {
1277
- fast: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
1278
- chat: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
1279
- reasoning: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
1280
- pdf: "us.anthropic.claude-sonnet-4-5-20250929-v1:0"
1281
- },
1282
- mistral: {
1283
- fast: "mistral-small-latest",
1284
- chat: "mistral-medium-latest",
1285
- reasoning: "mistral-medium-latest",
1286
- pdf: "mistral-large-latest"
1287
- }
1288
- };
1289
- /**
1290
- * Instance-level default model IDs per provider. Extends the BYOK
1291
- * defaults with the providers that only the instance path uses
1292
- * (custom deployments and OpenAI-compatible endpoints).
1293
- */
1294
- const DEFAULT_MODELS = {
1295
- ...BYOK_DEFAULT_MODELS,
1296
- azure_foundry: {
1297
- fast: GPT_56_MODEL_IDS.luna.openai,
1298
- chat: GPT_56_MODEL_IDS.terra.openai,
1299
- reasoning: GPT_56_MODEL_IDS.terra.openai,
1300
- pdf: GPT_56_MODEL_IDS.terra.openai
1301
- },
1302
- openai_compatible: {
1303
- fast: "default",
1304
- chat: "default",
1305
- reasoning: "default",
1306
- pdf: "default"
1307
- },
1308
- huggingface: {
1309
- fast: "speakleash/Bielik-1.5B-v3.0-Instruct",
1310
- chat: "speakleash/Bielik-11B-v2.3-Instruct",
1311
- reasoning: "speakleash/Bielik-11B-v2.3-Instruct",
1312
- pdf: "speakleash/Bielik-11B-v2.3-Instruct"
1313
- }
1314
- };
1315
- /**
1316
- * BYOK-offered model IDs per provider — the curated catalog users pick
1317
- * from in org settings, and the server-side allowlist the API enforces.
1318
- * The frontend list is not a security boundary; this is what the API
1319
- * accepts.
1320
- *
1321
- * Limited to providers the TanStack AI integration supports for BYOK.
1322
- * Providers without a first-class TanStack adapter path are intentionally
1323
- * not accepted at this boundary.
1324
- */
1325
- const BYOK_MODEL_OPTIONS = {
1326
- google: [
1327
- "gemini-3.8-flash",
1328
- "gemini-3.7-flash",
1329
- "gemini-3.6-flash",
1330
- "gemini-3.5-flash-lite",
1331
- "gemini-3.1-pro-preview",
1332
- "gemini-3.5-flash",
1333
- "gemini-3.1-flash-lite"
1334
- ],
1335
- anthropic: [
1336
- "claude-sonnet-5-5",
1337
- "claude-sonnet-5",
1338
- "claude-fable-5-1",
1339
- "claude-fable-5",
1340
- "claude-opus-5-5",
1341
- "claude-opus-5",
1342
- "claude-opus-4-8",
1343
- "claude-opus-4-7",
1344
- "claude-sonnet-4-6",
1345
- "claude-opus-4-6",
1346
- "claude-haiku-4-5-20251001"
1347
- ],
1348
- openai: [
1349
- ...GPT_61_OPENAI_MODEL_IDS,
1350
- ...GPT_6_OPENAI_MODEL_IDS,
1351
- ...GPT_56_OPENAI_MODEL_IDS,
1352
- "gpt-5.5",
1353
- "gpt-5.4",
1354
- "gpt-5.4-mini",
1355
- "gpt-5.4-nano",
1356
- "gpt-5.2"
1357
- ],
1358
- openrouter: [
1359
- ...GPT_61_OPENROUTER_MODEL_IDS,
1360
- ...GPT_6_OPENROUTER_MODEL_IDS,
1361
- ...GPT_56_OPENROUTER_MODEL_IDS,
1362
- "google/gemini-3.8-flash",
1363
- "google/gemini-3.7-flash",
1364
- "google/gemini-3.6-flash",
1365
- "google/gemini-3.5-flash-lite",
1366
- "google/gemini-3.1-pro-preview",
1367
- "google/gemini-3.5-flash",
1368
- "google/gemini-3.1-flash-lite",
1369
- "anthropic/claude-sonnet-5.5",
1370
- "anthropic/claude-sonnet-5",
1371
- "anthropic/claude-opus-5",
1372
- "anthropic/claude-opus-4.8",
1373
- "anthropic/claude-sonnet-4.6",
1374
- "openai/gpt-5.5",
1375
- "openai/gpt-5.4-mini"
1376
- ],
1377
- bedrock: [
1378
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
1379
- "us.anthropic.claude-haiku-4-5-20251001-v1:0",
1380
- "us.amazon.nova-pro-v1:0",
1381
- "us.amazon.nova-lite-v1:0",
1382
- "us.amazon.nova-micro-v1:0",
1383
- "openai.gpt-oss-120b-1:0",
1384
- "openai.gpt-oss-20b-1:0"
1385
- ],
1386
- mistral: [
1387
- "mistral-large-latest",
1388
- "mistral-medium-latest",
1389
- "mistral-small-latest"
1390
- ]
1391
- };
1392
- /**
1393
- * Presentation metadata for every offered model. Keeping this exhaustive beside
1394
- * the allowlist prevents a newly offered model from leaking a raw provider ID
1395
- * into user-facing pickers. OpenRouter entries deliberately carry their model
1396
- * creator's icon while their routing provider remains available separately.
1397
- */
1398
- const MODEL_DISPLAY_METADATA = {
1399
- "gemini-3.8-flash": {
1400
- displayName: "Gemini 3.8 Flash",
1401
- iconProvider: "google"
1402
- },
1403
- "gemini-3.7-flash": {
1404
- displayName: "Gemini 3.7 Flash",
1405
- iconProvider: "google"
1406
- },
1407
- "gemini-3.6-flash": {
1408
- displayName: "Gemini 3.6 Flash",
1409
- iconProvider: "google"
1410
- },
1411
- "gemini-3.5-flash-lite": {
1412
- displayName: "Gemini 3.5 Flash Lite",
1413
- iconProvider: "google"
1414
- },
1415
- "gemini-3.1-pro-preview": {
1416
- displayName: "Gemini 3.1 Pro Preview",
1417
- iconProvider: "google"
1418
- },
1419
- "gemini-3.5-flash": {
1420
- displayName: "Gemini 3.5 Flash",
1421
- iconProvider: "google"
1422
- },
1423
- "gemini-3.1-flash-lite": {
1424
- displayName: "Gemini 3.1 Flash Lite",
1425
- iconProvider: "google"
1426
- },
1427
- "claude-sonnet-5-5": {
1428
- displayName: "Claude Sonnet 5.5",
1429
- iconProvider: "anthropic"
1430
- },
1431
- "claude-sonnet-5": {
1432
- displayName: "Claude Sonnet 5",
1433
- iconProvider: "anthropic"
1434
- },
1435
- "claude-fable-5-1": {
1436
- displayName: "Claude Fable 5.1",
1437
- iconProvider: "anthropic"
1438
- },
1439
- "claude-fable-5": {
1440
- displayName: "Claude Fable 5",
1441
- iconProvider: "anthropic"
1442
- },
1443
- "claude-opus-5-5": {
1444
- displayName: "Claude Opus 5.5",
1445
- iconProvider: "anthropic"
1446
- },
1447
- "claude-opus-5": {
1448
- displayName: "Claude Opus 5",
1449
- iconProvider: "anthropic"
1450
- },
1451
- "claude-opus-4-8": {
1452
- displayName: "Claude Opus 4.8",
1453
- iconProvider: "anthropic"
1454
- },
1455
- "claude-opus-4-7": {
1456
- displayName: "Claude Opus 4.7",
1457
- iconProvider: "anthropic"
1458
- },
1459
- "claude-sonnet-4-6": {
1460
- displayName: "Claude Sonnet 4.6",
1461
- iconProvider: "anthropic"
1462
- },
1463
- "claude-opus-4-6": {
1464
- displayName: "Claude Opus 4.6",
1465
- iconProvider: "anthropic"
1466
- },
1467
- "claude-haiku-4-5-20251001": {
1468
- displayName: "Claude Haiku 4.5",
1469
- iconProvider: "anthropic"
1470
- },
1471
- [GPT_61_MODEL_IDS.sol.openai]: {
1472
- displayName: "GPT-6.1 Sol",
1473
- iconProvider: "openai"
1474
- },
1475
- [GPT_6_MODEL_IDS.astra.openai]: {
1476
- displayName: "GPT-6 Astra",
1477
- iconProvider: "openai"
1478
- },
1479
- [GPT_6_MODEL_IDS.sol.openai]: {
1480
- displayName: "GPT-6 Sol",
1481
- iconProvider: "openai"
1482
- },
1483
- [GPT_6_MODEL_IDS.luna.openai]: {
1484
- displayName: "GPT-6 Luna",
1485
- iconProvider: "openai"
1486
- },
1487
- [GPT_56_MODEL_IDS.sol.openai]: {
1488
- displayName: "GPT-5.6 Sol",
1489
- iconProvider: "openai"
1490
- },
1491
- [GPT_56_MODEL_IDS.terra.openai]: {
1492
- displayName: "GPT-5.6 Terra",
1493
- iconProvider: "openai"
1494
- },
1495
- [GPT_56_MODEL_IDS.luna.openai]: {
1496
- displayName: "GPT-5.6 Luna",
1497
- iconProvider: "openai"
1498
- },
1499
- "gpt-5.5": {
1500
- displayName: "GPT-5.5",
1501
- iconProvider: "openai"
1502
- },
1503
- "gpt-5.4": {
1504
- displayName: "GPT-5.4",
1505
- iconProvider: "openai"
1506
- },
1507
- "gpt-5.4-mini": {
1508
- displayName: "GPT-5.4 Mini",
1509
- iconProvider: "openai"
1510
- },
1511
- "gpt-5.4-nano": {
1512
- displayName: "GPT-5.4 Nano",
1513
- iconProvider: "openai"
1514
- },
1515
- "gpt-5.2": {
1516
- displayName: "GPT-5.2",
1517
- iconProvider: "openai"
1518
- },
1519
- [GPT_61_MODEL_IDS.sol.openrouter]: {
1520
- displayName: "GPT-6.1 Sol",
1521
- iconProvider: "openai"
1522
- },
1523
- [GPT_6_MODEL_IDS.astra.openrouter]: {
1524
- displayName: "GPT-6 Astra",
1525
- iconProvider: "openai"
1526
- },
1527
- [GPT_6_MODEL_IDS.sol.openrouter]: {
1528
- displayName: "GPT-6 Sol",
1529
- iconProvider: "openai"
1530
- },
1531
- [GPT_6_MODEL_IDS.luna.openrouter]: {
1532
- displayName: "GPT-6 Luna",
1533
- iconProvider: "openai"
1534
- },
1535
- [GPT_56_MODEL_IDS.sol.openrouter]: {
1536
- displayName: "GPT-5.6 Sol",
1537
- iconProvider: "openai"
1538
- },
1539
- [GPT_56_MODEL_IDS.luna.openrouter]: {
1540
- displayName: "GPT-5.6 Luna",
1541
- iconProvider: "openai"
1542
- },
1543
- [GPT_56_MODEL_IDS.terra.openrouter]: {
1544
- displayName: "GPT-5.6 Terra",
1545
- iconProvider: "openai"
1546
- },
1547
- "google/gemini-3.8-flash": {
1548
- displayName: "Gemini 3.8 Flash",
1549
- iconProvider: "google"
1550
- },
1551
- "google/gemini-3.7-flash": {
1552
- displayName: "Gemini 3.7 Flash",
1553
- iconProvider: "google"
1554
- },
1555
- "google/gemini-3.6-flash": {
1556
- displayName: "Gemini 3.6 Flash",
1557
- iconProvider: "google"
1558
- },
1559
- "google/gemini-3.5-flash-lite": {
1560
- displayName: "Gemini 3.5 Flash Lite",
1561
- iconProvider: "google"
1562
- },
1563
- "google/gemini-3.1-pro-preview": {
1564
- displayName: "Gemini 3.1 Pro Preview",
1565
- iconProvider: "google"
1566
- },
1567
- "google/gemini-3.5-flash": {
1568
- displayName: "Gemini 3.5 Flash",
1569
- iconProvider: "google"
1570
- },
1571
- "google/gemini-3.1-flash-lite": {
1572
- displayName: "Gemini 3.1 Flash Lite",
1573
- iconProvider: "google"
1574
- },
1575
- "anthropic/claude-sonnet-5.5": {
1576
- displayName: "Claude Sonnet 5.5",
1577
- iconProvider: "anthropic"
1578
- },
1579
- "anthropic/claude-sonnet-5": {
1580
- displayName: "Claude Sonnet 5",
1581
- iconProvider: "anthropic"
1582
- },
1583
- "anthropic/claude-opus-5": {
1584
- displayName: "Claude Opus 5",
1585
- iconProvider: "anthropic"
1586
- },
1587
- "anthropic/claude-opus-4.8": {
1588
- displayName: "Claude Opus 4.8",
1589
- iconProvider: "anthropic"
1590
- },
1591
- "anthropic/claude-sonnet-4.6": {
1592
- displayName: "Claude Sonnet 4.6",
1593
- iconProvider: "anthropic"
1594
- },
1595
- "openai/gpt-5.5": {
1596
- displayName: "GPT-5.5",
1597
- iconProvider: "openai"
1598
- },
1599
- "openai/gpt-5.4-mini": {
1600
- displayName: "GPT-5.4 Mini",
1601
- iconProvider: "openai"
1602
- },
1603
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": {
1604
- displayName: "Claude Sonnet 4.5",
1605
- iconProvider: "anthropic"
1606
- },
1607
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": {
1608
- displayName: "Claude Haiku 4.5",
1609
- iconProvider: "anthropic"
1610
- },
1611
- "us.amazon.nova-pro-v1:0": {
1612
- displayName: "Amazon Nova Pro",
1613
- iconProvider: "bedrock"
1614
- },
1615
- "us.amazon.nova-lite-v1:0": {
1616
- displayName: "Amazon Nova Lite",
1617
- iconProvider: "bedrock"
1618
- },
1619
- "us.amazon.nova-micro-v1:0": {
1620
- displayName: "Amazon Nova Micro",
1621
- iconProvider: "bedrock"
1622
- },
1623
- "openai.gpt-oss-120b-1:0": {
1624
- displayName: "GPT OSS 120B",
1625
- iconProvider: "openai"
1626
- },
1627
- "openai.gpt-oss-20b-1:0": {
1628
- displayName: "GPT OSS 20B",
1629
- iconProvider: "openai"
1630
- },
1631
- "mistral-large-latest": {
1632
- displayName: "Mistral Large",
1633
- iconProvider: "mistral"
1634
- },
1635
- "mistral-medium-latest": {
1636
- displayName: "Mistral Medium",
1637
- iconProvider: "mistral"
1638
- },
1639
- "mistral-small-latest": {
1640
- displayName: "Mistral Small",
1641
- iconProvider: "mistral"
1642
- }
1643
- };
1644
- const MODEL_DISPLAY_METADATA_BY_ID = MODEL_DISPLAY_METADATA;
1645
- const getModelDisplayMetadata = (modelId) => MODEL_DISPLAY_METADATA_BY_ID[normalizeModelCatalogId(modelId)] ?? null;
1646
- /**
1647
- * Offered models whose provider API accepts PDF/file content. Generated from
1648
- * live models.dev input modalities plus dated, reviewed source corrections;
1649
- * the nightly upstream check rejects drift.
1650
- */
1651
- const BYOK_DOCUMENT_INPUT_MODEL_OPTIONS = MODEL_DOCUMENT_INPUT_OPTIONS;
1652
- const isBYOKProviderRoleSupported = ({ provider, role }) => role !== "pdf" || BYOK_DOCUMENT_INPUT_MODEL_OPTIONS[provider].length > 0;
1653
- const isBYOKModelRoleSupported = ({ provider, modelId, role }) => {
1654
- if (role !== "pdf") return true;
1655
- return BYOK_DOCUMENT_INPUT_MODEL_OPTIONS[provider].includes(modelId);
1656
- };
1657
- /**
1658
- * Models whose provider adapter can receive a PDF `document` content part in a
1659
- * chat turn without throwing. This is a narrower, runtime question than the
1660
- * pdf ROLE (`BYOK_DOCUMENT_INPUT_MODEL_OPTIONS`, which curates model selection
1661
- * for PDF-processing flows): it only asks "will the chat stream survive this
1662
- * attachment." The Mistral text adapter maps PDF `document` parts to
1663
- * `document_url`, so its
1664
- * vision models accept PDF attachments even though Mistral is deliberately not
1665
- * offered as a pdf-role provider. Mistral's `document_url` takes PDF but NOT
1666
- * textual documents (docx/txt/csv/md), so those still gate on
1667
- * `BYOK_DOCUMENT_INPUT_MODEL_OPTIONS` (which excludes Mistral). Superset
1668
- * invariant: every pdf-role document model also accepts a PDF chat attachment.
1669
- */
1670
- const CHAT_PDF_ATTACHMENT_MODEL_OPTIONS = {
1671
- ...BYOK_DOCUMENT_INPUT_MODEL_OPTIONS,
1672
- mistral: ["mistral-medium-latest", "mistral-small-latest"]
1673
- };
1674
- const isChatPdfAttachmentModelSupported = ({ provider, modelId }) => {
1675
- return CHAT_PDF_ATTACHMENT_MODEL_OPTIONS[provider].includes(modelId);
1676
- };
1677
- /**
1678
- * Whether a model id is currently offered for this provider+role: it
1679
- * must be in the curated catalog for the provider AND satisfy the
1680
- * role's input-modality constraint (PDF needs a document-capable
1681
- * model). This is the runtime allowlist, so a model dropped by a
1682
- * catalog bump stops being valid here even though it is still a
1683
- * non-empty string in a stored org config.
1684
- */
1685
- const isOfferedBYOKModelForRole = ({ provider, modelId, role }) => {
1686
- return BYOK_MODEL_OPTIONS[provider].includes(modelId) && isBYOKModelRoleSupported({
1687
- provider,
1688
- modelId,
1689
- role
1690
- });
1691
- };
1692
- /**
1693
- * Resolve a model id that will actually work for this provider+role,
1694
- * keeping the SAME provider. Returns the caller's model unchanged when
1695
- * it is still offered; otherwise falls back to the provider's per-role
1696
- * default (`BYOK_DEFAULT_MODELS`). Returns `null` only when the
1697
- * provider has no valid model for the role at all — the sole case
1698
- * today is `mistral` + `pdf`, because the TanStack Mistral adapter
1699
- * exposes no `document` input modality, so no Mistral model (not even
1700
- * the default) can serve the PDF role.
1701
- *
1702
- * Used to auto-heal org AI configs whose pinned model was removed by a
1703
- * catalog bump, so generation resolves to a supported model instead of
1704
- * 400-ing (or forwarding a retired id to the provider).
1705
- */
1706
- const resolveWorkingBYOKModelForRole = ({ provider, modelId, role }) => {
1707
- if (isOfferedBYOKModelForRole({
1708
- provider,
1709
- modelId,
1710
- role
1711
- })) return modelId;
1712
- const fallback = BYOK_DEFAULT_MODELS[provider][role];
1713
- return isOfferedBYOKModelForRole({
1714
- provider,
1715
- modelId: fallback,
1716
- role
1717
- }) ? fallback : null;
1718
- };
1719
- /**
1720
- * Anthropic models that use the adaptive-thinking request shape
1721
- * (`thinking: { type: "adaptive" }`). Newer Claude models reject the
1722
- * legacy budget-based form, so every Opus 4.6+/Sonnet 4.6/Fable entry
1723
- * offered above must appear here or it will 400 on the reasoning role.
1724
- */
1725
- const ANTHROPIC_ADAPTIVE_THINKING_MODELS = [
1726
- "claude-sonnet-5-5",
1727
- "claude-sonnet-5",
1728
- "claude-opus-5",
1729
- "claude-sonnet-4-6",
1730
- "claude-opus-4-6",
1731
- "claude-opus-4-7",
1732
- "claude-opus-4-8",
1733
- "claude-fable-5",
1734
- "claude-fable-5-1",
1735
- "claude-opus-5-5"
1736
- ];
1737
- /**
1738
- * Canonical reasoning-effort ladder, ordered weakest to strongest.
1739
- * Union of every effort keyword the offered providers accept; no
1740
- * single model accepts all of them, which is exactly why the
1741
- * generated per-model `MODEL_REASONING_EFFORTS` exists.
1742
- */
1743
- const REASONING_EFFORTS = [
1744
- "none",
1745
- "minimal",
1746
- "low",
1747
- "medium",
1748
- "high",
1749
- "xhigh",
1750
- "max"
1751
- ];
1752
- const resolvedReasoningEffortSchema = v.pipe(v.picklist(REASONING_EFFORTS), v.brand("ResolvedReasoningEffort"));
1753
- /**
1754
- * Per-provider model served when a user's included budget is exhausted
1755
- * and no explicit selection overrides it. Falls back to each
1756
- * provider's fast-role default; providers without a first-class
1757
- * adapter path cannot serve the lane. Total over providers so a new
1758
- * provider lands with an explicit decision.
1759
- */
1760
- const FALLBACK_CHAT_MODEL_BY_PROVIDER = {
1761
- google: DEFAULT_MODELS.google.fast,
1762
- openrouter: DEFAULT_MODELS.openrouter.fast,
1763
- openai: DEFAULT_MODELS.openai.fast,
1764
- anthropic: DEFAULT_MODELS.anthropic.fast,
1765
- bedrock: DEFAULT_MODELS.bedrock.fast,
1766
- mistral: DEFAULT_MODELS.mistral.fast,
1767
- azure_foundry: null,
1768
- openai_compatible: null,
1769
- huggingface: null
1770
- };
1771
- /**
1772
- * Provider-native IDs that are exact aliases of an offered catalog ID.
1773
- * Every metadata lookup normalizes here, so instance/dev overrides cannot
1774
- * bypass rates or capabilities and duplicated alias rows cannot drift apart.
1775
- */
1776
- const MODEL_CATALOG_ID_ALIASES = {
1777
- "gpt-5.6-sol": "gpt-5.6",
1778
- "claude-opus-4.8": "claude-opus-4-8",
1779
- "claude-sonnet-5.5": "claude-sonnet-5-5",
1780
- "claude-sonnet-4.6": "claude-sonnet-4-6"
1781
- };
1782
- const MODEL_CATALOG_ID_ALIAS_TARGET_BY_ID = MODEL_CATALOG_ID_ALIASES;
1783
- const normalizeModelCatalogId = (modelId) => MODEL_CATALOG_ID_ALIAS_TARGET_BY_ID[modelId] ?? modelId;
1784
- const MODEL_TEMPERATURE_POLICY_BY_ID = MODEL_TEMPERATURE_POLICIES;
1785
- /**
1786
- * Whether stella should emit a `temperature` override for this model.
1787
- * This is deliberately stricter than provider acceptance: deprecated
1788
- * parameters that are accepted but ignored resolve to `false`. Unknown ids
1789
- * also resolve to `false` (send nothing; provider default). Callers must
1790
- * never index `MODEL_TEMPERATURE_POLICIES` directly with
1791
- * a runtime string.
1792
- */
1793
- const shouldEmitTemperature = (modelId) => MODEL_TEMPERATURE_POLICY_BY_ID[normalizeModelCatalogId(modelId)] === "emit";
1794
- const MODEL_OUTPUT_TOKEN_LIMIT_BY_ID = MODEL_OUTPUT_TOKEN_LIMITS;
1795
- /**
1796
- * The most output tokens one response of `modelId` may carry, from the
1797
- * catalog. `undefined` for an id the catalog does not list (a deployment
1798
- * override, a dev model): the catalog knows nothing about it, so callers leave
1799
- * the allowance to the provider rather than guess one. Callers must never
1800
- * index `MODEL_OUTPUT_TOKEN_LIMITS` directly with a runtime string.
1801
- */
1802
- const getOutputTokenLimit = (modelId) => MODEL_OUTPUT_TOKEN_LIMIT_BY_ID[normalizeModelCatalogId(modelId)];
1803
- /**
1804
- * Whether a model accepts tool use on a streaming request.
1805
- *
1806
- * Every tool-carrying request stella sends is a stream, and structured
1807
- * output is a forced tool call, so `"unsupported"` withdraws both: the
1808
- * provider answers such a request with a fatal stream error rather than a
1809
- * degraded result. models.dev does not publish this, so the map is
1810
- * hand-declared here rather than in the generated `capabilities.gen.ts`,
1811
- * and it is total over the offered catalog: a new model forces a decision.
1812
- *
1813
- * Consumers must go through `supportsStreamingToolUse`.
1814
- */
1815
- const MODEL_STREAMING_TOOL_USE = {
1816
- "gemini-3.8-flash": "supported",
1817
- "gemini-3.7-flash": "supported",
1818
- "gemini-3.6-flash": "supported",
1819
- "gemini-3.5-flash-lite": "supported",
1820
- "gemini-3.1-pro-preview": "supported",
1821
- "gemini-3.5-flash": "supported",
1822
- "gemini-3.1-flash-lite": "supported",
1823
- "openai/gpt-6.1-sol": "supported",
1824
- "openai/gpt-6-astra": "supported",
1825
- "openai/gpt-6-sol": "supported",
1826
- "openai/gpt-6-luna": "supported",
1827
- "openai/gpt-5.6-sol": "supported",
1828
- "openai/gpt-5.6-terra": "supported",
1829
- "openai/gpt-5.6-luna": "supported",
1830
- "google/gemini-3.8-flash": "supported",
1831
- "google/gemini-3.7-flash": "supported",
1832
- "google/gemini-3.6-flash": "supported",
1833
- "google/gemini-3.5-flash-lite": "supported",
1834
- "google/gemini-3.1-pro-preview": "supported",
1835
- "google/gemini-3.5-flash": "supported",
1836
- "google/gemini-3.1-flash-lite": "supported",
1837
- "anthropic/claude-sonnet-5.5": "supported",
1838
- "anthropic/claude-sonnet-5": "supported",
1839
- "anthropic/claude-opus-5": "supported",
1840
- "anthropic/claude-opus-4.8": "supported",
1841
- "anthropic/claude-sonnet-4.6": "supported",
1842
- "openai/gpt-5.5": "supported",
1843
- "openai/gpt-5.4-mini": "supported",
1844
- "gpt-6.1-sol": "supported",
1845
- "gpt-6-astra": "supported",
1846
- "gpt-6-sol": "supported",
1847
- "gpt-6-luna": "supported",
1848
- "gpt-5.6": "supported",
1849
- "gpt-5.6-terra": "supported",
1850
- "gpt-5.6-luna": "supported",
1851
- "gpt-5.5": "supported",
1852
- "gpt-5.4": "supported",
1853
- "gpt-5.4-mini": "supported",
1854
- "gpt-5.4-nano": "supported",
1855
- "gpt-5.2": "supported",
1856
- "claude-sonnet-5-5": "supported",
1857
- "claude-sonnet-5": "supported",
1858
- "claude-fable-5-1": "supported",
1859
- "claude-fable-5": "supported",
1860
- "claude-opus-5-5": "supported",
1861
- "claude-opus-5": "supported",
1862
- "claude-opus-4-8": "supported",
1863
- "claude-opus-4-7": "supported",
1864
- "claude-sonnet-4-6": "supported",
1865
- "claude-opus-4-6": "supported",
1866
- "claude-haiku-4-5-20251001": "supported",
1867
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": "supported",
1868
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": "supported",
1869
- "us.amazon.nova-pro-v1:0": "supported",
1870
- "us.amazon.nova-lite-v1:0": "supported",
1871
- "us.amazon.nova-micro-v1:0": "supported",
1872
- "openai.gpt-oss-120b-1:0": "supported",
1873
- "openai.gpt-oss-20b-1:0": "supported",
1874
- "mistral-large-latest": "supported",
1875
- "mistral-medium-latest": "supported",
1876
- "mistral-small-latest": "supported"
1877
- };
1878
- const MODEL_STREAMING_TOOL_USE_BY_ID = {
1879
- "gemini-2.5-flash": "supported",
1880
- "gemini-2.5-pro": "supported",
1881
- "gpt-4o-mini": "supported",
1882
- "gpt-4o": "supported",
1883
- "us.deepseek.r1-v1:0": "unsupported",
1884
- ...MODEL_STREAMING_TOOL_USE
1885
- };
1886
- /**
1887
- * Whether stella may send tools (or a structured-output schema) to this
1888
- * model on a streaming request. Unlisted ids resolve to `true`: custom
1889
- * deployments and env overrides are overwhelmingly tool-capable, and
1890
- * withdrawing tools from an uncatalogued model would silently strip the
1891
- * agent loop rather than fail where it can be seen.
1892
- */
1893
- const supportsStreamingToolUse = (modelId) => MODEL_STREAMING_TOOL_USE_BY_ID[normalizeModelCatalogId(modelId)] !== "unsupported";
1894
- const MODEL_REASONING_EFFORTS_BY_ID = MODEL_REASONING_EFFORTS;
1895
- /**
1896
- * Declared reasoning-effort values for a model ID, or `null` when the
1897
- * model has no effort control or is not catalogued (custom deployments,
1898
- * env overrides). Callers must never index `MODEL_REASONING_EFFORTS`
1899
- * directly with a runtime string.
1900
- */
1901
- const getModelReasoningEfforts = (modelId) => MODEL_REASONING_EFFORTS_BY_ID[normalizeModelCatalogId(modelId)] ?? null;
1902
- const MODEL_DEFAULT_REASONING_EFFORTS_BY_ID = MODEL_DEFAULT_REASONING_EFFORTS;
1903
- /**
1904
- * Concrete provider-default effort published for a model, or null when the
1905
- * provider exposes no named default. Unknown ids also resolve to null.
1906
- */
1907
- const getModelDefaultReasoningEffort = (modelId) => MODEL_DEFAULT_REASONING_EFFORTS_BY_ID[normalizeModelCatalogId(modelId)] ?? null;
1908
- const asResolvedReasoningEffort = (effort) => v.parse(resolvedReasoningEffortSchema, effort);
1909
- /**
1910
- * Clamp a requested reasoning effort into the target model's declared
1911
- * capability.
1912
- *
1913
- * - Unknown model or no effort control → `null` (send no effort at
1914
- * all; the provider default is the only universally safe choice).
1915
- * - Requested value supported → returned unchanged.
1916
- * - Otherwise → the supported value nearest on `REASONING_EFFORTS`,
1917
- * preferring the weaker side on ties, so a "none" request against a
1918
- * reasoning-mandatory model degrades to its weakest tier instead of
1919
- * erroring, and requests above the model's ceiling clamp down to it.
1920
- */
1921
- const resolveReasoningEffort = ({ modelId, requested }) => {
1922
- const efforts = getModelReasoningEfforts(modelId);
1923
- const weakest = efforts?.at(0);
1924
- if (efforts === null || weakest === void 0) return null;
1925
- if (efforts.includes(requested)) return asResolvedReasoningEffort(requested);
1926
- const requestedRank = REASONING_EFFORTS.indexOf(requested);
1927
- let nearest = weakest;
1928
- let nearestDistance = Number.POSITIVE_INFINITY;
1929
- for (const effort of efforts) {
1930
- const distance = Math.abs(REASONING_EFFORTS.indexOf(effort) - requestedRank);
1931
- if (distance < nearestDistance || distance === nearestDistance && REASONING_EFFORTS.indexOf(effort) < REASONING_EFFORTS.indexOf(nearest)) {
1932
- nearest = effort;
1933
- nearestDistance = distance;
1934
- }
1935
- }
1936
- return asResolvedReasoningEffort(nearest);
1937
- };
1938
- const MODEL_RATES_BY_ID = MODEL_RATES;
1939
- const OPENROUTER_UNDERLYING_MODEL_ID_BY_ID = Object.fromEntries(BYOK_MODEL_OPTIONS.openrouter.map((modelId) => [modelId, modelId.slice(modelId.indexOf("/") + 1)]));
1940
- const getModelRate = (modelId) => {
1941
- const normalizedModelId = normalizeModelCatalogId(modelId);
1942
- const exactRate = MODEL_RATES_BY_ID[normalizedModelId];
1943
- if (exactRate !== void 0) return exactRate;
1944
- const underlyingModelId = OPENROUTER_UNDERLYING_MODEL_ID_BY_ID[normalizedModelId];
1945
- return underlyingModelId === void 0 ? void 0 : MODEL_RATES_BY_ID[normalizeModelCatalogId(underlyingModelId)];
1946
- };
1947
- /**
1948
- * Documented input context-window sizes (in tokens) per model ID.
1949
- *
1950
- * Keys are the canonical model IDs stella resolves for the provider
1951
- * adapters (the same forms used in `MODEL_RATES`, `BYOK_MODEL_OPTIONS`,
1952
- * and `DEFAULT_MODELS`, including OpenRouter provider-prefixed slugs and
1953
- * AWS Bedrock IDs). Values are the providers' publicly documented input
1954
- * windows; where a provider offers a larger beta window we intentionally
1955
- * take the conservative default (e.g. Claude's standard 200K rather than
1956
- * the 1M beta) so context budgeting never overpromises.
1957
- *
1958
- * Consumers must go through `getContextWindowTokens`, which falls back to
1959
- * `DEFAULT_CONTEXT_WINDOW_TOKENS` for any unlisted ID. Unlike
1960
- * `MODEL_RATES`, the nightly `model-catalog-upstream` check does not
1961
- * validate this map, so an unknown model degrades to the conservative
1962
- * default rather than failing CI.
1963
- */
1964
- const CONTEXT_WINDOW_TOKENS = {
1965
- "gemini-2.5-flash": 1048576,
1966
- "gemini-2.5-pro": 1048576,
1967
- "gemini-3.1-flash-lite": 1048576,
1968
- "gemini-3.5-flash": 1048576,
1969
- "gemini-3.5-flash-lite": 1048576,
1970
- "gemini-3.6-flash": 1048576,
1971
- "gemini-3.7-flash": 1048576,
1972
- "gemini-3.8-flash": 1048576,
1973
- "gemini-3.1-pro-preview": 1048576,
1974
- "gpt-4o-mini": 128e3,
1975
- "gpt-4o": 128e3,
1976
- "gpt-5.2": 4e5,
1977
- "gpt-5.4-nano": 4e5,
1978
- "gpt-5.4-mini": 4e5,
1979
- "gpt-5.4": 4e5,
1980
- "gpt-5.5": 4e5,
1981
- "gpt-6.1-sol": 922e3,
1982
- "gpt-6-astra": 922e3,
1983
- "gpt-6-sol": 922e3,
1984
- "gpt-6-luna": 922e3,
1985
- "gpt-5.6": 922e3,
1986
- "gpt-5.6-luna": 922e3,
1987
- "gpt-5.6-terra": 922e3,
1988
- "claude-haiku-4-5-20251001": 2e5,
1989
- "claude-sonnet-4-6": 2e5,
1990
- "claude-sonnet-5": 1e6,
1991
- "claude-sonnet-5-5": 1e6,
1992
- "claude-opus-4-6": 2e5,
1993
- "claude-opus-4-7": 2e5,
1994
- "claude-opus-4-8": 2e5,
1995
- "claude-opus-5": 1e6,
1996
- "claude-opus-5-5": 1e6,
1997
- "claude-fable-5": 2e5,
1998
- "claude-fable-5-1": 1e6,
1999
- "mistral-small-latest": 128e3,
2000
- "mistral-large-latest": 128e3,
2001
- "mistral-medium-latest": 128e3,
2002
- "mistral-medium-3-5": 128e3,
2003
- "magistral-small-latest": 128e3,
2004
- "google/gemini-3.8-flash": 1048576,
2005
- "google/gemini-3.7-flash": 1048576,
2006
- "google/gemini-3.6-flash": 1048576,
2007
- "google/gemini-3.5-flash-lite": 1048576,
2008
- "google/gemini-3.1-pro-preview": 1048576,
2009
- "google/gemini-3.5-flash": 1048576,
2010
- "google/gemini-3.1-flash-lite": 1048576,
2011
- "anthropic/claude-sonnet-5.5": 1e6,
2012
- "anthropic/claude-sonnet-5": 1e6,
2013
- "anthropic/claude-opus-5": 1e6,
2014
- "anthropic/claude-opus-4.8": 2e5,
2015
- "anthropic/claude-sonnet-4.6": 2e5,
2016
- "openai/gpt-6.1-sol": 922e3,
2017
- "openai/gpt-6-astra": 922e3,
2018
- "openai/gpt-6-sol": 922e3,
2019
- "openai/gpt-6-luna": 922e3,
2020
- "openai/gpt-5.6-sol": 922e3,
2021
- "openai/gpt-5.6-luna": 922e3,
2022
- "openai/gpt-5.6-terra": 922e3,
2023
- "openai/gpt-5.5": 4e5,
2024
- "openai/gpt-5.4-mini": 4e5,
2025
- "us.anthropic.claude-sonnet-4-5-20250929-v1:0": 2e5,
2026
- "us.anthropic.claude-haiku-4-5-20251001-v1:0": 2e5,
2027
- "us.amazon.nova-pro-v1:0": 3e5,
2028
- "us.amazon.nova-lite-v1:0": 3e5,
2029
- "us.amazon.nova-micro-v1:0": 128e3,
2030
- "openai.gpt-oss-120b-1:0": 128e3,
2031
- "openai.gpt-oss-20b-1:0": 128e3,
2032
- "us.deepseek.r1-v1:0": 128e3
2033
- };
2034
- const CONTEXT_WINDOW_TOKENS_BY_ID = CONTEXT_WINDOW_TOKENS;
2035
- /**
2036
- * Conservative window assumed for any model ID absent from
2037
- * `CONTEXT_WINDOW_TOKENS` (custom deployments, OpenAI-compatible
2038
- * endpoints, brand-new IDs not yet catalogued).
2039
- */
2040
- const DEFAULT_CONTEXT_WINDOW_TOKENS = 128e3;
2041
- /**
2042
- * Documented input context window for a model ID, or the conservative
2043
- * default for unlisted IDs. Callers must never index
2044
- * `CONTEXT_WINDOW_TOKENS` directly.
2045
- */
2046
- const getContextWindowTokens = (modelId) => CONTEXT_WINDOW_TOKENS_BY_ID[normalizeModelCatalogId(modelId)] ?? 128e3;
2047
- //#endregion
2048
- export { AI_PROVIDERS, ANTHROPIC_ADAPTIVE_THINKING_MODELS, BYOK_DEFAULT_MODELS, BYOK_DOCUMENT_INPUT_MODEL_OPTIONS, BYOK_MODEL_OPTIONS, CAPABILITY_OVERRIDES, CHAT_PDF_ATTACHMENT_MODEL_OPTIONS, CONTEXT_WINDOW_TOKENS, DEFAULT_CONTEXT_WINDOW_TOKENS, DEFAULT_MODELS, DOCUMENT_INPUT_OVERRIDES, FALLBACK_CHAT_MODEL_BY_PROVIDER, FIRST_PARTY_MODEL_PROVIDERS, MODELS_DEV_RATE_PROVIDER_BY_CATALOG_PROVIDER, MODELS_DEV_RATE_SOURCE_ALIASES, MODEL_CATALOG_ID_ALIASES, MODEL_CATALOG_PROVIDER_KIND, MODEL_DEFAULT_REASONING_EFFORTS, MODEL_DISPLAY_METADATA, MODEL_OUTPUT_TOKEN_LIMITS, MODEL_RATES, MODEL_RATE_UNITS_PER_USD, MODEL_REASONING_EFFORTS, MODEL_ROLES, MODEL_STREAMING_TOOL_USE, MODEL_TEMPERATURE_POLICIES, REASONING_EFFORTS, RETAINED_MODELS_DEV_RATE_ENTRIES, STREAMING_TOOL_USE_SUPPORTS, TANSTACK_AI_PROVIDERS, TEMPERATURE_POLICIES, getContextWindowTokens, getModelDefaultReasoningEffort, getModelDisplayMetadata, getModelRate, getModelReasoningEfforts, getOutputTokenLimit, getStandardModelRate, isBYOKModelRoleSupported, isBYOKProviderRoleSupported, isChatPdfAttachmentModelSupported, normalizeModelCatalogId, resolveModelRate, resolveReasoningEffort, resolveWorkingBYOKModelForRole, shouldEmitTemperature, supportsStreamingToolUse };
1
+ import { A as isBYOKProviderRoleSupported, B as MODELS_DEV_RATE_PROVIDER_BY_CATALOG_PROVIDER, C as getModelDefaultReasoningEffort, D as getModelReasoningEfforts, E as getModelRate, F as shouldEmitTemperature, G as resolveModelRate, H as RETAINED_MODELS_DEV_RATE_ENTRIES, I as supportsStreamingToolUse, J as MODEL_IMAGE_INPUT_CAPABILITIES, K as MODEL_RATES, L as DOCUMENT_INPUT_OVERRIDES, M as normalizeModelCatalogId, N as resolveReasoningEffort, O as getOutputTokenLimit, P as resolveWorkingBYOKModelForRole, R as CAPABILITY_OVERRIDES, S as getContextWindowTokens, T as getModelImageInputCapability, U as MODEL_RATE_UNITS_PER_USD, V as MODELS_DEV_RATE_SOURCE_ALIASES, W as getStandardModelRate, X as MODEL_REASONING_EFFORTS, Y as MODEL_OUTPUT_TOKEN_LIMITS, Z as MODEL_TEMPERATURE_POLICIES, _ as MODEL_STREAMING_TOOL_USE, a as BYOK_MODEL_OPTIONS, b as TANSTACK_AI_PROVIDERS, c as DEFAULT_CONTEXT_WINDOW_TOKENS, d as FIRST_PARTY_MODEL_PROVIDERS, f as IMAGE_INPUT_CAPABILITIES, g as MODEL_ROLES, h as MODEL_DISPLAY_METADATA, i as BYOK_DOCUMENT_INPUT_MODEL_OPTIONS, j as isChatPdfAttachmentModelSupported, k as isBYOKModelRoleSupported, l as DEFAULT_MODELS, m as MODEL_CATALOG_PROVIDER_KIND, n as ANTHROPIC_ADAPTIVE_THINKING_MODELS, o as CHAT_PDF_ATTACHMENT_MODEL_OPTIONS, p as MODEL_CATALOG_ID_ALIASES, q as MODEL_DEFAULT_REASONING_EFFORTS, r as BYOK_DEFAULT_MODELS, s as CONTEXT_WINDOW_TOKENS, t as AI_PROVIDERS, u as FALLBACK_CHAT_MODEL_BY_PROVIDER, v as REASONING_EFFORTS, w as getModelDisplayMetadata, x as TEMPERATURE_POLICIES, y as STREAMING_TOOL_USE_SUPPORTS, z as IMAGE_INPUT_OVERRIDES } from "./src-Dn6XqN2_.js";
2
+ export { AI_PROVIDERS, ANTHROPIC_ADAPTIVE_THINKING_MODELS, BYOK_DEFAULT_MODELS, BYOK_DOCUMENT_INPUT_MODEL_OPTIONS, BYOK_MODEL_OPTIONS, CAPABILITY_OVERRIDES, CHAT_PDF_ATTACHMENT_MODEL_OPTIONS, CONTEXT_WINDOW_TOKENS, DEFAULT_CONTEXT_WINDOW_TOKENS, DEFAULT_MODELS, DOCUMENT_INPUT_OVERRIDES, FALLBACK_CHAT_MODEL_BY_PROVIDER, FIRST_PARTY_MODEL_PROVIDERS, IMAGE_INPUT_CAPABILITIES, IMAGE_INPUT_OVERRIDES, MODELS_DEV_RATE_PROVIDER_BY_CATALOG_PROVIDER, MODELS_DEV_RATE_SOURCE_ALIASES, MODEL_CATALOG_ID_ALIASES, MODEL_CATALOG_PROVIDER_KIND, MODEL_DEFAULT_REASONING_EFFORTS, MODEL_DISPLAY_METADATA, MODEL_IMAGE_INPUT_CAPABILITIES, MODEL_OUTPUT_TOKEN_LIMITS, MODEL_RATES, MODEL_RATE_UNITS_PER_USD, MODEL_REASONING_EFFORTS, MODEL_ROLES, MODEL_STREAMING_TOOL_USE, MODEL_TEMPERATURE_POLICIES, REASONING_EFFORTS, RETAINED_MODELS_DEV_RATE_ENTRIES, STREAMING_TOOL_USE_SUPPORTS, TANSTACK_AI_PROVIDERS, TEMPERATURE_POLICIES, getContextWindowTokens, getModelDefaultReasoningEffort, getModelDisplayMetadata, getModelImageInputCapability, getModelRate, getModelReasoningEfforts, getOutputTokenLimit, getStandardModelRate, isBYOKModelRoleSupported, isBYOKProviderRoleSupported, isChatPdfAttachmentModelSupported, normalizeModelCatalogId, resolveModelRate, resolveReasoningEffort, resolveWorkingBYOKModelForRole, shouldEmitTemperature, supportsStreamingToolUse };