llm-strings 1.3.0 → 1.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -339
  3. package/dist/ai-sdk.cjs +1146 -117
  4. package/dist/ai-sdk.d.cts +1 -1
  5. package/dist/ai-sdk.d.ts +1 -1
  6. package/dist/ai-sdk.js +95 -58
  7. package/dist/{chunk-7HE4RH6X.js → chunk-4BE457QA.js} +16 -29
  8. package/dist/{chunk-TQJ2ABCT.js → chunk-6HQOCOQI.js} +1 -2
  9. package/dist/{chunk-NZR5DUX5.js → chunk-7Z7DCLZN.js} +14 -3
  10. package/dist/{chunk-OCJX4QFJ.js → chunk-PCJDQTOV.js} +520 -76
  11. package/dist/index.cjs +542 -95
  12. package/dist/index.d.cts +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +4 -5
  15. package/dist/normalize.cjs +1065 -63
  16. package/dist/normalize.d.cts +1 -1
  17. package/dist/normalize.d.ts +1 -1
  18. package/dist/normalize.js +2 -3
  19. package/dist/parse.cjs +1075 -1
  20. package/dist/parse.d.cts +4 -4
  21. package/dist/parse.d.ts +4 -4
  22. package/dist/parse.js +2 -3
  23. package/dist/{provider-core-B934MuhJ.d.cts → provider-core-B1GMszQP.d.cts} +2 -3
  24. package/dist/{provider-core-B934MuhJ.d.ts → provider-core-B1GMszQP.d.ts} +2 -3
  25. package/dist/providers.cjs +542 -697
  26. package/dist/providers.d.cts +3 -8
  27. package/dist/providers.d.ts +3 -8
  28. package/dist/providers.js +25 -624
  29. package/dist/validate.cjs +542 -95
  30. package/dist/validate.d.cts +1 -1
  31. package/dist/validate.d.ts +1 -1
  32. package/dist/validate.js +4 -5
  33. package/package.json +16 -2
  34. package/dist/ai-sdk.cjs.map +0 -1
  35. package/dist/ai-sdk.js.map +0 -1
  36. package/dist/chunk-7HE4RH6X.js.map +0 -1
  37. package/dist/chunk-NZR5DUX5.js.map +0 -1
  38. package/dist/chunk-OCJX4QFJ.js.map +0 -1
  39. package/dist/chunk-TQJ2ABCT.js.map +0 -1
  40. package/dist/index.cjs.map +0 -1
  41. package/dist/index.js.map +0 -1
  42. package/dist/normalize.cjs.map +0 -1
  43. package/dist/normalize.js.map +0 -1
  44. package/dist/parse.cjs.map +0 -1
  45. package/dist/parse.js.map +0 -1
  46. package/dist/providers.cjs.map +0 -1
  47. package/dist/providers.js.map +0 -1
  48. package/dist/validate.cjs.map +0 -1
  49. package/dist/validate.js.map +0 -1
package/dist/ai-sdk.cjs CHANGED
@@ -139,44 +139,92 @@ function providerFromHostAlias(alias) {
139
139
  }
140
140
  return void 0;
141
141
  }
142
+ function canonicalHostName(host) {
143
+ return normalizeHostValue(host).toLowerCase().split(":")[0] ?? host;
144
+ }
145
+ function hostMatches(host, ...domains) {
146
+ return domains.some((domain) => {
147
+ const normalizedDomain = domain.toLowerCase();
148
+ return host === normalizedDomain || host.endsWith(`.${normalizedDomain}`);
149
+ });
150
+ }
151
+ function hostHasLabel(host, ...labels) {
152
+ const hostLabels = host.split(".");
153
+ return labels.some((label) => hostLabels.includes(label.toLowerCase()));
154
+ }
155
+ function hostHasLabelPrefix(host, ...prefixes) {
156
+ const hostLabels = host.split(".");
157
+ return prefixes.some(
158
+ (prefix) => hostLabels.some((label) => label.startsWith(prefix.toLowerCase()))
159
+ );
160
+ }
161
+ var MODEL_FAMILY_DELIMITERS = /* @__PURE__ */ new Set(["-", "."]);
162
+ function normalizeModelForMatching(model) {
163
+ return model.trim().toLowerCase();
164
+ }
165
+ function modelLeafName(model) {
166
+ const normalized = normalizeModelForMatching(model);
167
+ const slash = normalized.lastIndexOf("/");
168
+ return slash >= 0 ? normalized.slice(slash + 1) : normalized;
169
+ }
170
+ function modelMatchesFamily(model, family) {
171
+ const name = modelLeafName(model);
172
+ const normalizedFamily = normalizeModelForMatching(family);
173
+ if (!name || !normalizedFamily) return false;
174
+ if (name === normalizedFamily) return true;
175
+ const delimiter = name[normalizedFamily.length];
176
+ return name.startsWith(normalizedFamily) && delimiter !== void 0 && MODEL_FAMILY_DELIMITERS.has(delimiter);
177
+ }
142
178
  function detectProvider(host) {
143
- host = host.toLowerCase();
144
- if (host.includes("openrouter")) return "openrouter";
145
- if (host.includes("gateway.ai.vercel")) return "vercel";
146
- if (host.includes("amazonaws") || host.includes("bedrock")) return "bedrock";
147
- if (host.includes("aiplatform.googleapis")) return "google-vertex";
148
- if (host.includes("api.x.ai")) return "xai";
149
- if (host.includes("groq")) return "groq";
150
- if (host.includes("fal.run") || host.includes("fal.ai")) return "fal";
151
- if (host.includes("deepinfra")) return "deepinfra";
152
- if (host.includes("bfl.ai")) return "black-forest-labs";
153
- if (host.includes("together")) return "together";
154
- if (host.includes("fireworks")) return "fireworks";
155
- if (host.includes("deepseek")) return "deepseek";
156
- if (host.includes("moonshot")) return "moonshotai";
157
- if (host.includes("perplexity")) return "perplexity";
158
- if (host.includes("dashscope") || host.includes("aliyuncs")) return "alibaba";
159
- if (host.includes("cerebras")) return "cerebras";
160
- if (host.includes("replicate")) return "replicate";
161
- if (host.includes("prodia")) return "prodia";
162
- if (host.includes("lumalabs") || host.includes("luma")) return "luma";
163
- if (host.includes("volces") || host.includes("bytedance")) return "bytedance";
164
- if (host.includes("kling")) return "kling";
165
- if (host.includes("elevenlabs")) return "elevenlabs";
166
- if (host.includes("assemblyai")) return "assemblyai";
167
- if (host.includes("deepgram")) return "deepgram";
168
- if (host.includes("gladia")) return "gladia";
169
- if (host.includes("lmnt")) return "lmnt";
170
- if (host.includes("hume")) return "hume";
171
- if (host.includes("rev.ai")) return "revai";
172
- if (host.includes("baseten")) return "baseten";
173
- if (host.includes("huggingface")) return "huggingface";
174
- if (host.includes("azure")) return "azure";
175
- if (host.includes("openai")) return "openai";
176
- if (host.includes("anthropic") || host.includes("claude")) return "anthropic";
177
- if (host.includes("googleapis") || host.includes("google")) return "google";
178
- if (host.includes("mistral")) return "mistral";
179
- if (host.includes("cohere")) return "cohere";
179
+ host = canonicalHostName(host);
180
+ if (hostMatches(host, "openrouter", "openrouter.ai")) return "openrouter";
181
+ if (hostMatches(host, "vercel", "gateway.ai.vercel.app", "gateway.ai.vercel.sh")) {
182
+ return "vercel";
183
+ }
184
+ if (hostMatches(host, "bedrock", "amazonaws.com") || hostHasLabelPrefix(host, "bedrock")) {
185
+ return "bedrock";
186
+ }
187
+ if (hostMatches(host, "aiplatform.googleapis.com")) return "google-vertex";
188
+ if (hostMatches(host, "xai", "x.ai", "api.x.ai")) return "xai";
189
+ if (hostMatches(host, "groq", "groq.com", "api.groq.com")) return "groq";
190
+ if (hostMatches(host, "fal", "fal.run", "fal.ai")) return "fal";
191
+ if (hostMatches(host, "deepinfra", "deepinfra.com")) return "deepinfra";
192
+ if (hostMatches(host, "bfl", "bfl.ai", "api.bfl.ai")) {
193
+ return "black-forest-labs";
194
+ }
195
+ if (hostMatches(host, "together", "together.xyz")) return "together";
196
+ if (hostMatches(host, "fireworks", "fireworks.ai")) return "fireworks";
197
+ if (hostMatches(host, "deepseek", "deepseek.com")) return "deepseek";
198
+ if (hostMatches(host, "moonshot", "moonshot.ai")) return "moonshotai";
199
+ if (hostMatches(host, "perplexity", "perplexity.ai")) return "perplexity";
200
+ if (hostMatches(host, "alibaba", "aliyuncs.com") || hostHasLabelPrefix(host, "dashscope")) {
201
+ return "alibaba";
202
+ }
203
+ if (hostMatches(host, "cerebras", "cerebras.ai")) return "cerebras";
204
+ if (hostMatches(host, "replicate", "replicate.com")) return "replicate";
205
+ if (hostMatches(host, "prodia", "prodia.com")) return "prodia";
206
+ if (hostMatches(host, "luma", "lumalabs.ai")) return "luma";
207
+ if (hostMatches(host, "bytedance", "volces.com") || hostHasLabel(host, "bytedance")) {
208
+ return "bytedance";
209
+ }
210
+ if (hostMatches(host, "kling", "klingai.com")) return "kling";
211
+ if (hostMatches(host, "elevenlabs", "elevenlabs.io")) return "elevenlabs";
212
+ if (hostMatches(host, "assemblyai", "assemblyai.com")) return "assemblyai";
213
+ if (hostMatches(host, "deepgram", "deepgram.com")) return "deepgram";
214
+ if (hostMatches(host, "gladia", "gladia.io")) return "gladia";
215
+ if (hostMatches(host, "lmnt", "lmnt.com")) return "lmnt";
216
+ if (hostMatches(host, "hume", "hume.ai")) return "hume";
217
+ if (hostMatches(host, "revai", "rev.ai")) return "revai";
218
+ if (hostMatches(host, "baseten", "baseten.co")) return "baseten";
219
+ if (hostMatches(host, "huggingface", "huggingface.co")) return "huggingface";
220
+ if (hostMatches(host, "azure", "azure.com")) return "azure";
221
+ if (hostMatches(host, "openai", "openai.com")) return "openai";
222
+ if (hostMatches(host, "anthropic", "anthropic.com", "claude.ai")) {
223
+ return "anthropic";
224
+ }
225
+ if (hostMatches(host, "google", "googleapis.com")) return "google";
226
+ if (hostMatches(host, "mistral", "mistral.ai")) return "mistral";
227
+ if (hostMatches(host, "cohere", "cohere.com")) return "cohere";
180
228
  return void 0;
181
229
  }
182
230
  var ALIASES = {
@@ -219,7 +267,10 @@ var ALIASES = {
219
267
  num_completions: "n",
220
268
  // effort / reasoning
221
269
  reasoning_effort: "effort",
270
+ reasoningEffort: "effort",
222
271
  reasoning: "effort",
272
+ thinking_effort: "effort",
273
+ thinkingEffort: "effort",
223
274
  // cache
224
275
  cache_control: "cache",
225
276
  cacheControl: "cache",
@@ -229,6 +280,7 @@ var ALIASES = {
229
280
  var OPENAI_COMPATIBLE_PARAMS = {
230
281
  temperature: "temperature",
231
282
  max_tokens: "max_tokens",
283
+ max_completion_tokens: "max_completion_tokens",
232
284
  top_p: "top_p",
233
285
  top_k: "top_k",
234
286
  frequency_penalty: "frequency_penalty",
@@ -239,6 +291,90 @@ var OPENAI_COMPATIBLE_PARAMS = {
239
291
  stream: "stream",
240
292
  effort: "reasoning_effort"
241
293
  };
294
+ var COMMON_IMAGE_PARAMS = {
295
+ prompt: "prompt",
296
+ negative_prompt: "negative_prompt",
297
+ seed: "seed",
298
+ image_size: "image_size",
299
+ aspect_ratio: "aspect_ratio",
300
+ output_format: "output_format",
301
+ width: "width",
302
+ height: "height"
303
+ };
304
+ var FAL_PARAMS = {
305
+ ...COMMON_IMAGE_PARAMS,
306
+ num_images: "num_images",
307
+ enable_safety_checker: "enable_safety_checker",
308
+ enable_safety_checks: "enable_safety_checks",
309
+ enable_prompt_expansion: "enable_prompt_expansion",
310
+ expand_prompt: "expand_prompt"
311
+ };
312
+ var REPLICATE_PARAMS = {
313
+ ...COMMON_IMAGE_PARAMS,
314
+ input: "input",
315
+ version: "version",
316
+ num_outputs: "num_outputs",
317
+ num_inference_steps: "num_inference_steps",
318
+ guidance_scale: "guidance_scale",
319
+ stream: "stream",
320
+ webhook: "webhook",
321
+ webhook_events_filter: "webhook_events_filter"
322
+ };
323
+ var PRODIA_PARAMS = {
324
+ ...COMMON_IMAGE_PARAMS,
325
+ model: "model",
326
+ style_preset: "style_preset",
327
+ steps: "steps",
328
+ cfg_scale: "cfg_scale",
329
+ upscale: "upscale",
330
+ sampler: "sampler",
331
+ type: "type",
332
+ config: "config",
333
+ price: "price"
334
+ };
335
+ var LUMA_PARAMS = {
336
+ prompt: "prompt",
337
+ model: "model",
338
+ aspect_ratio: "aspect_ratio",
339
+ keyframes: "keyframes",
340
+ loop: "loop",
341
+ duration: "duration",
342
+ type: "type",
343
+ image_ref: "image_ref",
344
+ video: "video",
345
+ source: "source"
346
+ };
347
+ var OPENROUTER_ROUTING_PARAMS = {
348
+ provider: "provider",
349
+ order: "order",
350
+ "provider.order": "provider.order",
351
+ only: "only",
352
+ "provider.only": "provider.only",
353
+ ignore: "ignore",
354
+ "provider.ignore": "provider.ignore",
355
+ allow_fallbacks: "allow_fallbacks",
356
+ "provider.allow_fallbacks": "provider.allow_fallbacks",
357
+ require_parameters: "require_parameters",
358
+ "provider.require_parameters": "provider.require_parameters",
359
+ data_collection: "data_collection",
360
+ "provider.data_collection": "provider.data_collection",
361
+ zdr: "zdr",
362
+ "provider.zdr": "provider.zdr",
363
+ enforce_distillable_text: "enforce_distillable_text",
364
+ "provider.enforce_distillable_text": "provider.enforce_distillable_text",
365
+ quantizations: "quantizations",
366
+ "provider.quantizations": "provider.quantizations",
367
+ sort: "sort",
368
+ "provider.sort": "provider.sort",
369
+ preferred_min_throughput: "preferred_min_throughput",
370
+ "provider.preferred_min_throughput": "provider.preferred_min_throughput",
371
+ preferred_max_latency: "preferred_max_latency",
372
+ "provider.preferred_max_latency": "provider.preferred_max_latency",
373
+ max_price: "max_price",
374
+ "provider.max_price": "provider.max_price",
375
+ transforms: "transforms",
376
+ plugins: "plugins"
377
+ };
242
378
  var GOOGLE_COMPATIBLE_PARAMS = {
243
379
  temperature: "temperature",
244
380
  max_tokens: "maxOutputTokens",
@@ -257,6 +393,7 @@ var PROVIDER_PARAMS = {
257
393
  openai: {
258
394
  temperature: "temperature",
259
395
  max_tokens: "max_tokens",
396
+ max_completion_tokens: "max_completion_tokens",
260
397
  top_p: "top_p",
261
398
  frequency_penalty: "frequency_penalty",
262
399
  presence_penalty: "presence_penalty",
@@ -333,6 +470,7 @@ var PROVIDER_PARAMS = {
333
470
  // OpenAI-compatible API with extra routing params
334
471
  temperature: "temperature",
335
472
  max_tokens: "max_tokens",
473
+ max_completion_tokens: "max_completion_tokens",
336
474
  top_p: "top_p",
337
475
  top_k: "top_k",
338
476
  frequency_penalty: "frequency_penalty",
@@ -341,12 +479,14 @@ var PROVIDER_PARAMS = {
341
479
  n: "n",
342
480
  seed: "seed",
343
481
  stream: "stream",
344
- effort: "reasoning_effort"
482
+ effort: "reasoning_effort",
483
+ ...OPENROUTER_ROUTING_PARAMS
345
484
  },
346
485
  vercel: {
347
486
  // OpenAI-compatible gateway
348
487
  temperature: "temperature",
349
488
  max_tokens: "max_tokens",
489
+ max_completion_tokens: "max_completion_tokens",
350
490
  top_p: "top_p",
351
491
  top_k: "top_k",
352
492
  frequency_penalty: "frequency_penalty",
@@ -359,7 +499,7 @@ var PROVIDER_PARAMS = {
359
499
  },
360
500
  xai: OPENAI_COMPATIBLE_PARAMS,
361
501
  groq: OPENAI_COMPATIBLE_PARAMS,
362
- fal: {},
502
+ fal: FAL_PARAMS,
363
503
  deepinfra: OPENAI_COMPATIBLE_PARAMS,
364
504
  "black-forest-labs": {},
365
505
  together: OPENAI_COMPATIBLE_PARAMS,
@@ -369,9 +509,9 @@ var PROVIDER_PARAMS = {
369
509
  perplexity: OPENAI_COMPATIBLE_PARAMS,
370
510
  alibaba: OPENAI_COMPATIBLE_PARAMS,
371
511
  cerebras: OPENAI_COMPATIBLE_PARAMS,
372
- replicate: {},
373
- prodia: {},
374
- luma: {},
512
+ replicate: REPLICATE_PARAMS,
513
+ prodia: PRODIA_PARAMS,
514
+ luma: LUMA_PARAMS,
375
515
  bytedance: {},
376
516
  kling: {},
377
517
  elevenlabs: {},
@@ -384,12 +524,842 @@ var PROVIDER_PARAMS = {
384
524
  baseten: OPENAI_COMPATIBLE_PARAMS,
385
525
  huggingface: OPENAI_COMPATIBLE_PARAMS
386
526
  };
527
+ var REASONING_EFFORT_VALUES = [
528
+ "none",
529
+ "minimal",
530
+ "low",
531
+ "medium",
532
+ "high",
533
+ "xhigh",
534
+ "max"
535
+ ];
536
+ var OPENAI_COMPATIBLE_PARAM_SPECS = {
537
+ temperature: {
538
+ type: "number",
539
+ min: 0,
540
+ max: 2,
541
+ default: 0.7,
542
+ description: "Controls randomness"
543
+ },
544
+ max_tokens: {
545
+ type: "number",
546
+ min: 1,
547
+ default: 4096,
548
+ description: "Maximum output tokens"
549
+ },
550
+ max_completion_tokens: {
551
+ type: "number",
552
+ min: 1,
553
+ default: 4096,
554
+ description: "Maximum completion tokens (reasoning models)"
555
+ },
556
+ top_p: {
557
+ type: "number",
558
+ min: 0,
559
+ max: 1,
560
+ default: 1,
561
+ description: "Nucleus sampling"
562
+ },
563
+ top_k: {
564
+ type: "number",
565
+ min: 0,
566
+ default: 40,
567
+ description: "Top-K sampling"
568
+ },
569
+ frequency_penalty: {
570
+ type: "number",
571
+ min: -2,
572
+ max: 2,
573
+ default: 0,
574
+ description: "Penalize frequent tokens"
575
+ },
576
+ presence_penalty: {
577
+ type: "number",
578
+ min: -2,
579
+ max: 2,
580
+ default: 0,
581
+ description: "Penalize repeated topics"
582
+ },
583
+ stop: { type: "string", description: "Stop sequences" },
584
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
585
+ seed: { type: "number", description: "Random seed" },
586
+ stream: { type: "boolean", default: false, description: "Stream response" },
587
+ reasoning_effort: {
588
+ type: "string",
589
+ values: REASONING_EFFORT_VALUES,
590
+ default: "medium",
591
+ description: "Reasoning effort"
592
+ }
593
+ };
594
+ var OPENROUTER_ROUTING_PARAM_SPECS = {
595
+ provider: { type: "string", description: "Provider routing preferences" },
596
+ order: { type: "string", description: "Provider order" },
597
+ "provider.order": { type: "string", description: "Provider order" },
598
+ only: { type: "string", description: "Provider allowlist" },
599
+ "provider.only": { type: "string", description: "Provider allowlist" },
600
+ ignore: { type: "string", description: "Provider blocklist" },
601
+ "provider.ignore": { type: "string", description: "Provider blocklist" },
602
+ allow_fallbacks: {
603
+ type: "boolean",
604
+ default: true,
605
+ description: "Allow fallback providers"
606
+ },
607
+ "provider.allow_fallbacks": {
608
+ type: "boolean",
609
+ default: true,
610
+ description: "Allow fallback providers"
611
+ },
612
+ require_parameters: {
613
+ type: "boolean",
614
+ default: false,
615
+ description: "Only route to providers that support all request params"
616
+ },
617
+ "provider.require_parameters": {
618
+ type: "boolean",
619
+ default: false,
620
+ description: "Only route to providers that support all request params"
621
+ },
622
+ data_collection: {
623
+ type: "string",
624
+ values: ["allow", "deny"],
625
+ default: "allow",
626
+ description: "Provider data collection policy"
627
+ },
628
+ "provider.data_collection": {
629
+ type: "string",
630
+ values: ["allow", "deny"],
631
+ default: "allow",
632
+ description: "Provider data collection policy"
633
+ },
634
+ zdr: {
635
+ type: "boolean",
636
+ description: "Require zero data retention providers"
637
+ },
638
+ "provider.zdr": {
639
+ type: "boolean",
640
+ description: "Require zero data retention providers"
641
+ },
642
+ enforce_distillable_text: {
643
+ type: "boolean",
644
+ description: "Require providers that allow text distillation"
645
+ },
646
+ "provider.enforce_distillable_text": {
647
+ type: "boolean",
648
+ description: "Require providers that allow text distillation"
649
+ },
650
+ quantizations: {
651
+ type: "string",
652
+ description: "Allowed provider quantization levels"
653
+ },
654
+ "provider.quantizations": {
655
+ type: "string",
656
+ description: "Allowed provider quantization levels"
657
+ },
658
+ sort: {
659
+ type: "string",
660
+ values: ["price", "throughput", "latency", "cost", "ttft", "tps"],
661
+ description: "Provider sort strategy"
662
+ },
663
+ "provider.sort": {
664
+ type: "string",
665
+ values: ["price", "throughput", "latency", "cost", "ttft", "tps"],
666
+ description: "Provider sort strategy"
667
+ },
668
+ preferred_min_throughput: {
669
+ type: "number",
670
+ min: 0,
671
+ description: "Preferred minimum provider throughput"
672
+ },
673
+ "provider.preferred_min_throughput": {
674
+ type: "number",
675
+ min: 0,
676
+ description: "Preferred minimum provider throughput"
677
+ },
678
+ preferred_max_latency: {
679
+ type: "number",
680
+ min: 0,
681
+ description: "Preferred maximum provider latency"
682
+ },
683
+ "provider.preferred_max_latency": {
684
+ type: "number",
685
+ min: 0,
686
+ description: "Preferred maximum provider latency"
687
+ },
688
+ max_price: {
689
+ type: "string",
690
+ description: "Maximum provider price filter"
691
+ },
692
+ "provider.max_price": {
693
+ type: "string",
694
+ description: "Maximum provider price filter"
695
+ },
696
+ transforms: {
697
+ type: "string",
698
+ description: "Legacy OpenRouter message transforms"
699
+ },
700
+ plugins: {
701
+ type: "string",
702
+ description: "OpenRouter request plugins"
703
+ }
704
+ };
705
+ var FAL_PARAM_SPECS = {
706
+ prompt: { type: "string", description: "Prompt" },
707
+ negative_prompt: { type: "string", description: "Negative prompt" },
708
+ seed: { type: "number", description: "Random seed" },
709
+ num_images: {
710
+ type: "number",
711
+ min: 1,
712
+ description: "Number of images to generate"
713
+ },
714
+ image_size: { type: "string", description: "Output image size" },
715
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
716
+ enable_safety_checker: {
717
+ type: "boolean",
718
+ description: "Enable safety checker"
719
+ },
720
+ enable_safety_checks: {
721
+ type: "boolean",
722
+ description: "Enable safety checker"
723
+ },
724
+ enable_prompt_expansion: {
725
+ type: "boolean",
726
+ description: "Enable prompt expansion"
727
+ },
728
+ expand_prompt: {
729
+ type: "boolean",
730
+ description: "Enable prompt expansion"
731
+ },
732
+ output_format: {
733
+ type: "string",
734
+ values: ["jpeg", "jpg", "png", "webp", "gif"],
735
+ description: "Output image format"
736
+ },
737
+ width: { type: "number", min: 1, description: "Image width" },
738
+ height: { type: "number", min: 1, description: "Image height" }
739
+ };
740
+ var REPLICATE_PARAM_SPECS = {
741
+ prompt: { type: "string", description: "Prompt" },
742
+ negative_prompt: { type: "string", description: "Negative prompt" },
743
+ input: { type: "string", description: "Model input object" },
744
+ version: { type: "string", description: "Model version" },
745
+ seed: { type: "number", description: "Random seed" },
746
+ num_outputs: {
747
+ type: "number",
748
+ min: 1,
749
+ description: "Number of outputs to generate"
750
+ },
751
+ num_inference_steps: {
752
+ type: "number",
753
+ min: 1,
754
+ description: "Number of inference steps"
755
+ },
756
+ guidance_scale: {
757
+ type: "number",
758
+ min: 0,
759
+ description: "Guidance scale"
760
+ },
761
+ image_size: { type: "string", description: "Output image size" },
762
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
763
+ output_format: { type: "string", description: "Output format" },
764
+ width: { type: "number", min: 1, description: "Image width" },
765
+ height: { type: "number", min: 1, description: "Image height" },
766
+ stream: { type: "boolean", description: "Request streaming output" },
767
+ webhook: { type: "string", description: "Webhook URL" },
768
+ webhook_events_filter: {
769
+ type: "string",
770
+ description: "Webhook events filter"
771
+ }
772
+ };
773
+ var PRODIA_PARAM_SPECS = {
774
+ model: { type: "string", description: "Model name" },
775
+ prompt: { type: "string", description: "Prompt" },
776
+ negative_prompt: { type: "string", description: "Negative prompt" },
777
+ style_preset: { type: "string", description: "Style preset" },
778
+ steps: { type: "number", min: 1, description: "Generation steps" },
779
+ cfg_scale: { type: "number", min: 0, description: "CFG scale" },
780
+ seed: { type: "number", description: "Random seed" },
781
+ upscale: { type: "boolean", description: "Enable 2x upscale" },
782
+ sampler: { type: "string", description: "Sampler" },
783
+ width: { type: "number", min: 1, max: 1024, description: "Image width" },
784
+ height: { type: "number", min: 1, max: 1024, description: "Image height" },
785
+ image_size: { type: "string", description: "Output image size" },
786
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
787
+ output_format: { type: "string", description: "Output format" },
788
+ type: { type: "string", description: "Prodia v2 job type" },
789
+ config: { type: "string", description: "Prodia v2 job config" },
790
+ price: { type: "boolean", description: "Include Prodia v2 job price" }
791
+ };
792
+ var LUMA_PARAM_SPECS = {
793
+ prompt: { type: "string", description: "Prompt" },
794
+ model: { type: "string", description: "Model name" },
795
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
796
+ keyframes: { type: "string", description: "Generation keyframes" },
797
+ loop: { type: "boolean", description: "Generate a looping video" },
798
+ duration: { type: "string", description: "Generation duration" },
799
+ type: { type: "string", description: "Generation type" },
800
+ image_ref: { type: "string", description: "Image reference" },
801
+ video: { type: "string", description: "Video options" },
802
+ source: { type: "string", description: "Source generation or media" }
803
+ };
804
+ var GOOGLE_COMPATIBLE_PARAM_SPECS = {
805
+ temperature: {
806
+ type: "number",
807
+ min: 0,
808
+ max: 2,
809
+ default: 0.7,
810
+ description: "Controls randomness"
811
+ },
812
+ maxOutputTokens: {
813
+ type: "number",
814
+ min: 1,
815
+ default: 4096,
816
+ description: "Maximum output tokens"
817
+ },
818
+ topP: {
819
+ type: "number",
820
+ min: 0,
821
+ max: 1,
822
+ default: 1,
823
+ description: "Nucleus sampling"
824
+ },
825
+ topK: {
826
+ type: "number",
827
+ min: 0,
828
+ default: 40,
829
+ description: "Top-K sampling"
830
+ },
831
+ frequencyPenalty: {
832
+ type: "number",
833
+ min: -2,
834
+ max: 2,
835
+ default: 0,
836
+ description: "Penalize frequent tokens"
837
+ },
838
+ presencePenalty: {
839
+ type: "number",
840
+ min: -2,
841
+ max: 2,
842
+ default: 0,
843
+ description: "Penalize repeated topics"
844
+ },
845
+ stopSequences: { type: "string", description: "Stop sequences" },
846
+ candidateCount: {
847
+ type: "number",
848
+ min: 1,
849
+ default: 1,
850
+ description: "Candidate count"
851
+ },
852
+ stream: { type: "boolean", default: false, description: "Stream response" },
853
+ seed: { type: "number", description: "Random seed" },
854
+ responseMimeType: { type: "string", description: "Response MIME type" },
855
+ responseSchema: { type: "string", description: "Response schema" }
856
+ };
857
+ var PARAM_SPECS = {
858
+ openai: {
859
+ temperature: {
860
+ type: "number",
861
+ min: 0,
862
+ max: 2,
863
+ default: 0.7,
864
+ description: "Controls randomness"
865
+ },
866
+ max_tokens: {
867
+ type: "number",
868
+ min: 1,
869
+ default: 4096,
870
+ description: "Maximum output tokens"
871
+ },
872
+ max_completion_tokens: {
873
+ type: "number",
874
+ min: 1,
875
+ default: 4096,
876
+ description: "Maximum completion tokens (reasoning models)"
877
+ },
878
+ top_p: {
879
+ type: "number",
880
+ min: 0,
881
+ max: 1,
882
+ default: 1,
883
+ description: "Nucleus sampling"
884
+ },
885
+ frequency_penalty: {
886
+ type: "number",
887
+ min: -2,
888
+ max: 2,
889
+ default: 0,
890
+ description: "Penalize frequent tokens"
891
+ },
892
+ presence_penalty: {
893
+ type: "number",
894
+ min: -2,
895
+ max: 2,
896
+ default: 0,
897
+ description: "Penalize repeated topics"
898
+ },
899
+ stop: { type: "string", description: "Stop sequences" },
900
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
901
+ seed: { type: "number", description: "Random seed" },
902
+ stream: { type: "boolean", default: false, description: "Stream response" },
903
+ reasoning_effort: {
904
+ type: "string",
905
+ values: REASONING_EFFORT_VALUES,
906
+ default: "medium",
907
+ description: "Reasoning effort"
908
+ }
909
+ },
910
+ azure: OPENAI_COMPATIBLE_PARAM_SPECS,
911
+ anthropic: {
912
+ temperature: {
913
+ type: "number",
914
+ min: 0,
915
+ max: 1,
916
+ default: 0.7,
917
+ description: "Controls randomness"
918
+ },
919
+ max_tokens: {
920
+ type: "number",
921
+ min: 1,
922
+ default: 4096,
923
+ description: "Maximum output tokens"
924
+ },
925
+ top_p: {
926
+ type: "number",
927
+ min: 0,
928
+ max: 1,
929
+ default: 1,
930
+ description: "Nucleus sampling"
931
+ },
932
+ top_k: {
933
+ type: "number",
934
+ min: 0,
935
+ default: 40,
936
+ description: "Top-K sampling"
937
+ },
938
+ stop_sequences: { type: "string", description: "Stop sequences" },
939
+ stream: { type: "boolean", default: false, description: "Stream response" },
940
+ effort: {
941
+ type: "string",
942
+ values: REASONING_EFFORT_VALUES,
943
+ default: "low",
944
+ description: "Thinking effort"
945
+ },
946
+ cache_control: {
947
+ type: "string",
948
+ values: ["ephemeral"],
949
+ default: "ephemeral",
950
+ description: "Cache control"
951
+ },
952
+ cache_ttl: {
953
+ type: "string",
954
+ values: ["5m", "1h"],
955
+ default: "5m",
956
+ description: "Cache TTL"
957
+ }
958
+ },
959
+ google: {
960
+ temperature: {
961
+ type: "number",
962
+ min: 0,
963
+ max: 2,
964
+ default: 0.7,
965
+ description: "Controls randomness"
966
+ },
967
+ maxOutputTokens: {
968
+ type: "number",
969
+ min: 1,
970
+ default: 4096,
971
+ description: "Maximum output tokens"
972
+ },
973
+ topP: {
974
+ type: "number",
975
+ min: 0,
976
+ max: 1,
977
+ default: 1,
978
+ description: "Nucleus sampling"
979
+ },
980
+ topK: {
981
+ type: "number",
982
+ min: 0,
983
+ default: 40,
984
+ description: "Top-K sampling"
985
+ },
986
+ frequencyPenalty: {
987
+ type: "number",
988
+ min: -2,
989
+ max: 2,
990
+ default: 0,
991
+ description: "Penalize frequent tokens"
992
+ },
993
+ presencePenalty: {
994
+ type: "number",
995
+ min: -2,
996
+ max: 2,
997
+ default: 0,
998
+ description: "Penalize repeated topics"
999
+ },
1000
+ stopSequences: { type: "string", description: "Stop sequences" },
1001
+ candidateCount: {
1002
+ type: "number",
1003
+ min: 1,
1004
+ default: 1,
1005
+ description: "Candidate count"
1006
+ },
1007
+ stream: { type: "boolean", default: false, description: "Stream response" },
1008
+ seed: { type: "number", description: "Random seed" },
1009
+ responseMimeType: { type: "string", description: "Response MIME type" },
1010
+ responseSchema: { type: "string", description: "Response schema" }
1011
+ },
1012
+ "google-vertex": GOOGLE_COMPATIBLE_PARAM_SPECS,
1013
+ mistral: {
1014
+ temperature: {
1015
+ type: "number",
1016
+ min: 0,
1017
+ max: 1,
1018
+ default: 0.7,
1019
+ description: "Controls randomness"
1020
+ },
1021
+ max_tokens: {
1022
+ type: "number",
1023
+ min: 1,
1024
+ default: 4096,
1025
+ description: "Maximum output tokens"
1026
+ },
1027
+ top_p: {
1028
+ type: "number",
1029
+ min: 0,
1030
+ max: 1,
1031
+ default: 1,
1032
+ description: "Nucleus sampling"
1033
+ },
1034
+ frequency_penalty: {
1035
+ type: "number",
1036
+ min: -2,
1037
+ max: 2,
1038
+ default: 0,
1039
+ description: "Penalize frequent tokens"
1040
+ },
1041
+ presence_penalty: {
1042
+ type: "number",
1043
+ min: -2,
1044
+ max: 2,
1045
+ default: 0,
1046
+ description: "Penalize repeated topics"
1047
+ },
1048
+ stop: { type: "string", description: "Stop sequences" },
1049
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
1050
+ random_seed: { type: "number", description: "Random seed" },
1051
+ stream: { type: "boolean", default: false, description: "Stream response" },
1052
+ safe_prompt: {
1053
+ type: "boolean",
1054
+ default: false,
1055
+ description: "Enable safe prompt"
1056
+ },
1057
+ min_tokens: {
1058
+ type: "number",
1059
+ min: 0,
1060
+ default: 0,
1061
+ description: "Minimum tokens"
1062
+ }
1063
+ },
1064
+ cohere: {
1065
+ temperature: {
1066
+ type: "number",
1067
+ min: 0,
1068
+ max: 1,
1069
+ default: 0.7,
1070
+ description: "Controls randomness"
1071
+ },
1072
+ max_tokens: {
1073
+ type: "number",
1074
+ min: 1,
1075
+ default: 4096,
1076
+ description: "Maximum output tokens"
1077
+ },
1078
+ p: {
1079
+ type: "number",
1080
+ min: 0,
1081
+ max: 1,
1082
+ default: 1,
1083
+ description: "Nucleus sampling (p)"
1084
+ },
1085
+ k: {
1086
+ type: "number",
1087
+ min: 0,
1088
+ max: 500,
1089
+ default: 40,
1090
+ description: "Top-K sampling (k)"
1091
+ },
1092
+ frequency_penalty: {
1093
+ type: "number",
1094
+ min: 0,
1095
+ max: 1,
1096
+ default: 0,
1097
+ description: "Penalize frequent tokens"
1098
+ },
1099
+ presence_penalty: {
1100
+ type: "number",
1101
+ min: 0,
1102
+ max: 1,
1103
+ default: 0,
1104
+ description: "Penalize repeated topics"
1105
+ },
1106
+ stop_sequences: { type: "string", description: "Stop sequences" },
1107
+ stream: { type: "boolean", default: false, description: "Stream response" },
1108
+ seed: { type: "number", description: "Random seed" }
1109
+ },
1110
+ bedrock: {
1111
+ // Converse API inferenceConfig params
1112
+ temperature: {
1113
+ type: "number",
1114
+ min: 0,
1115
+ max: 1,
1116
+ default: 0.7,
1117
+ description: "Controls randomness"
1118
+ },
1119
+ maxTokens: {
1120
+ type: "number",
1121
+ min: 1,
1122
+ default: 4096,
1123
+ description: "Maximum output tokens"
1124
+ },
1125
+ topP: {
1126
+ type: "number",
1127
+ min: 0,
1128
+ max: 1,
1129
+ default: 1,
1130
+ description: "Nucleus sampling"
1131
+ },
1132
+ topK: {
1133
+ type: "number",
1134
+ min: 0,
1135
+ default: 40,
1136
+ description: "Top-K sampling"
1137
+ },
1138
+ stopSequences: { type: "string", description: "Stop sequences" },
1139
+ stream: { type: "boolean", default: false, description: "Stream response" },
1140
+ cache_control: {
1141
+ type: "string",
1142
+ values: ["ephemeral"],
1143
+ default: "ephemeral",
1144
+ description: "Cache control"
1145
+ },
1146
+ cache_ttl: {
1147
+ type: "string",
1148
+ values: ["5m", "1h"],
1149
+ default: "5m",
1150
+ description: "Cache TTL"
1151
+ }
1152
+ },
1153
+ openrouter: {
1154
+ // Loose validation — proxies to many providers with varying ranges
1155
+ temperature: {
1156
+ type: "number",
1157
+ min: 0,
1158
+ max: 2,
1159
+ default: 0.7,
1160
+ description: "Controls randomness"
1161
+ },
1162
+ max_tokens: {
1163
+ type: "number",
1164
+ min: 1,
1165
+ default: 4096,
1166
+ description: "Maximum output tokens"
1167
+ },
1168
+ max_completion_tokens: {
1169
+ type: "number",
1170
+ min: 1,
1171
+ default: 4096,
1172
+ description: "Maximum completion tokens (reasoning models)"
1173
+ },
1174
+ top_p: {
1175
+ type: "number",
1176
+ min: 0,
1177
+ max: 1,
1178
+ default: 1,
1179
+ description: "Nucleus sampling"
1180
+ },
1181
+ top_k: {
1182
+ type: "number",
1183
+ min: 0,
1184
+ default: 40,
1185
+ description: "Top-K sampling"
1186
+ },
1187
+ frequency_penalty: {
1188
+ type: "number",
1189
+ min: -2,
1190
+ max: 2,
1191
+ default: 0,
1192
+ description: "Penalize frequent tokens"
1193
+ },
1194
+ presence_penalty: {
1195
+ type: "number",
1196
+ min: -2,
1197
+ max: 2,
1198
+ default: 0,
1199
+ description: "Penalize repeated topics"
1200
+ },
1201
+ stop: { type: "string", description: "Stop sequences" },
1202
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
1203
+ seed: { type: "number", description: "Random seed" },
1204
+ stream: { type: "boolean", default: false, description: "Stream response" },
1205
+ reasoning_effort: {
1206
+ type: "string",
1207
+ values: REASONING_EFFORT_VALUES,
1208
+ default: "medium",
1209
+ description: "Reasoning effort"
1210
+ },
1211
+ ...OPENROUTER_ROUTING_PARAM_SPECS
1212
+ },
1213
+ vercel: {
1214
+ // Loose validation — proxies to many providers with varying ranges
1215
+ temperature: {
1216
+ type: "number",
1217
+ min: 0,
1218
+ max: 2,
1219
+ default: 0.7,
1220
+ description: "Controls randomness"
1221
+ },
1222
+ max_tokens: {
1223
+ type: "number",
1224
+ min: 1,
1225
+ default: 4096,
1226
+ description: "Maximum output tokens"
1227
+ },
1228
+ max_completion_tokens: {
1229
+ type: "number",
1230
+ min: 1,
1231
+ default: 4096,
1232
+ description: "Maximum completion tokens (reasoning models)"
1233
+ },
1234
+ top_p: {
1235
+ type: "number",
1236
+ min: 0,
1237
+ max: 1,
1238
+ default: 1,
1239
+ description: "Nucleus sampling"
1240
+ },
1241
+ top_k: {
1242
+ type: "number",
1243
+ min: 0,
1244
+ default: 40,
1245
+ description: "Top-K sampling"
1246
+ },
1247
+ frequency_penalty: {
1248
+ type: "number",
1249
+ min: -2,
1250
+ max: 2,
1251
+ default: 0,
1252
+ description: "Penalize frequent tokens"
1253
+ },
1254
+ presence_penalty: {
1255
+ type: "number",
1256
+ min: -2,
1257
+ max: 2,
1258
+ default: 0,
1259
+ description: "Penalize repeated topics"
1260
+ },
1261
+ stop: { type: "string", description: "Stop sequences" },
1262
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
1263
+ seed: { type: "number", description: "Random seed" },
1264
+ stream: { type: "boolean", default: false, description: "Stream response" },
1265
+ reasoning_effort: {
1266
+ type: "string",
1267
+ values: REASONING_EFFORT_VALUES,
1268
+ default: "medium",
1269
+ description: "Reasoning effort"
1270
+ },
1271
+ order: { type: "string", description: "Gateway provider order" },
1272
+ only: { type: "string", description: "Gateway provider allowlist" },
1273
+ models: { type: "string", description: "Gateway fallback models" },
1274
+ tags: { type: "string", description: "Gateway usage tags" },
1275
+ sort: {
1276
+ type: "string",
1277
+ values: ["cost", "ttft", "tps"],
1278
+ description: "Gateway provider sort strategy"
1279
+ },
1280
+ caching: {
1281
+ type: "string",
1282
+ values: ["auto"],
1283
+ description: "Gateway automatic caching strategy"
1284
+ },
1285
+ user: { type: "string", description: "Gateway usage user identifier" },
1286
+ byok: { type: "string", description: "Gateway BYOK credentials" },
1287
+ zero_data_retention: {
1288
+ type: "boolean",
1289
+ description: "Gateway zero data retention routing"
1290
+ },
1291
+ zeroDataRetention: {
1292
+ type: "boolean",
1293
+ description: "Gateway zero data retention routing"
1294
+ },
1295
+ disallow_prompt_training: {
1296
+ type: "boolean",
1297
+ description: "Gateway prompt training opt-out routing"
1298
+ },
1299
+ disallowPromptTraining: {
1300
+ type: "boolean",
1301
+ description: "Gateway prompt training opt-out routing"
1302
+ },
1303
+ hipaa_compliant: {
1304
+ type: "boolean",
1305
+ description: "Gateway HIPAA-compliant routing"
1306
+ },
1307
+ hipaaCompliant: {
1308
+ type: "boolean",
1309
+ description: "Gateway HIPAA-compliant routing"
1310
+ },
1311
+ quota_entity_id: {
1312
+ type: "string",
1313
+ description: "Gateway quota entity identifier"
1314
+ },
1315
+ quotaEntityId: {
1316
+ type: "string",
1317
+ description: "Gateway quota entity identifier"
1318
+ },
1319
+ provider_timeouts: {
1320
+ type: "string",
1321
+ description: "Gateway provider timeouts"
1322
+ },
1323
+ providerTimeouts: {
1324
+ type: "string",
1325
+ description: "Gateway provider timeouts"
1326
+ }
1327
+ },
1328
+ xai: OPENAI_COMPATIBLE_PARAM_SPECS,
1329
+ groq: OPENAI_COMPATIBLE_PARAM_SPECS,
1330
+ fal: FAL_PARAM_SPECS,
1331
+ deepinfra: OPENAI_COMPATIBLE_PARAM_SPECS,
1332
+ "black-forest-labs": {},
1333
+ together: OPENAI_COMPATIBLE_PARAM_SPECS,
1334
+ fireworks: OPENAI_COMPATIBLE_PARAM_SPECS,
1335
+ deepseek: OPENAI_COMPATIBLE_PARAM_SPECS,
1336
+ moonshotai: OPENAI_COMPATIBLE_PARAM_SPECS,
1337
+ perplexity: OPENAI_COMPATIBLE_PARAM_SPECS,
1338
+ alibaba: OPENAI_COMPATIBLE_PARAM_SPECS,
1339
+ cerebras: OPENAI_COMPATIBLE_PARAM_SPECS,
1340
+ replicate: REPLICATE_PARAM_SPECS,
1341
+ prodia: PRODIA_PARAM_SPECS,
1342
+ luma: LUMA_PARAM_SPECS,
1343
+ bytedance: {},
1344
+ kling: {},
1345
+ elevenlabs: {},
1346
+ assemblyai: {},
1347
+ deepgram: {},
1348
+ gladia: {},
1349
+ lmnt: {},
1350
+ hume: {},
1351
+ revai: {},
1352
+ baseten: OPENAI_COMPATIBLE_PARAM_SPECS,
1353
+ huggingface: OPENAI_COMPATIBLE_PARAM_SPECS
1354
+ };
387
1355
  function isReasoningModel(model) {
388
- const name = model.includes("/") ? model.split("/").pop() : model;
389
- return /^o[134]/.test(name);
1356
+ const name = modelLeafName(model);
1357
+ const oSeries = name.match(/^o\d+/)?.[0];
1358
+ const gptSeries = name.match(/^gpt-[5-9]/)?.[0];
1359
+ return (oSeries ? modelMatchesFamily(name, oSeries) : false) || (gptSeries ? modelMatchesFamily(name, gptSeries) : false);
390
1360
  }
391
1361
  function canHostOpenAIModels(provider) {
392
- return provider === "openai" || provider === "openrouter" || provider === "vercel";
1362
+ return provider === "openai" || provider === "azure" || provider === "openrouter" || provider === "vercel";
393
1363
  }
394
1364
  function isGatewayProvider(provider) {
395
1365
  return provider === "openrouter" || provider === "vercel";
@@ -397,22 +1367,27 @@ function isGatewayProvider(provider) {
397
1367
  function detectGatewaySubProvider(model) {
398
1368
  const slash = model.indexOf("/");
399
1369
  if (slash < 1) return void 0;
400
- const prefix = model.slice(0, slash);
401
- const direct = [
402
- "openai",
403
- "anthropic",
404
- "google",
405
- "mistral",
406
- "cohere"
407
- ];
408
- return direct.find((p) => p === prefix);
1370
+ const prefix = normalizeModelForMatching(model.slice(0, slash));
1371
+ const direct = {
1372
+ openai: "openai",
1373
+ anthropic: "anthropic",
1374
+ google: "google",
1375
+ vertex: "google",
1376
+ "google-vertex": "google",
1377
+ mistral: "mistral",
1378
+ cohere: "cohere"
1379
+ };
1380
+ return direct[prefix];
409
1381
  }
1382
+ var REASONING_MODEL_UNSUPPORTED = /* @__PURE__ */ new Set([
1383
+ "temperature",
1384
+ "top_p",
1385
+ "top_k",
1386
+ "frequency_penalty",
1387
+ "presence_penalty",
1388
+ "n"
1389
+ ]);
410
1390
  function detectBedrockModelFamily(model) {
411
- const parts = model.split(".");
412
- let prefix = parts[0];
413
- if (["us", "eu", "apac", "global"].includes(prefix) && parts.length > 1) {
414
- prefix = parts[1];
415
- }
416
1391
  const families = [
417
1392
  "anthropic",
418
1393
  "meta",
@@ -421,12 +1396,18 @@ function detectBedrockModelFamily(model) {
421
1396
  "cohere",
422
1397
  "ai21"
423
1398
  ];
424
- return families.find((f) => prefix === f);
1399
+ const parts = modelLeafName(model).split(".");
1400
+ return families.find((family) => parts.includes(family));
425
1401
  }
426
1402
  function bedrockSupportsCaching(model) {
427
1403
  const family = detectBedrockModelFamily(model);
428
1404
  if (family === "anthropic") return true;
429
- if (family === "amazon" && model.includes("nova")) return true;
1405
+ if (family === "amazon") {
1406
+ const parts = modelLeafName(model).split(".");
1407
+ const amazonIndex = parts.indexOf("amazon");
1408
+ const modelName = amazonIndex >= 0 ? parts[amazonIndex + 1] : void 0;
1409
+ return modelName ? modelMatchesFamily(modelName, "nova") : false;
1410
+ }
430
1411
  return false;
431
1412
  }
432
1413
  var CACHE_VALUES = {
@@ -511,9 +1492,9 @@ var CACHE_TTLS = {
511
1492
  baseten: void 0,
512
1493
  huggingface: void 0
513
1494
  };
514
- var DURATION_RE = /^\d+[mh]$/;
515
1495
 
516
1496
  // src/normalize.ts
1497
+ var DURATION_RE = /^\d+[mh]$/;
517
1498
  function normalize(config, options = {}) {
518
1499
  const provider = (config.hostAlias ? providerFromHostAlias(config.hostAlias) : void 0) ?? detectProvider(config.host);
519
1500
  const subProvider = provider && isGatewayProvider(provider) ? detectGatewaySubProvider(config.model) : void 0;
@@ -601,6 +1582,17 @@ function normalize(config, options = {}) {
601
1582
  }
602
1583
  key = "max_completion_tokens";
603
1584
  }
1585
+ if (provider && canHostOpenAIModels(provider) && isReasoningModel(config.model) && REASONING_MODEL_UNSUPPORTED.has(key)) {
1586
+ if (options.verbose) {
1587
+ changes.push({
1588
+ from: key,
1589
+ to: "(dropped)",
1590
+ value,
1591
+ reason: `${provider} reasoning model "${config.model}" does not support "${key}"`
1592
+ });
1593
+ }
1594
+ continue;
1595
+ }
604
1596
  params[key] = value;
605
1597
  }
606
1598
  return {
@@ -1009,6 +2001,7 @@ function addGatewayOption(options, key, value) {
1009
2001
  };
1010
2002
  const directKeys = /* @__PURE__ */ new Set([
1011
2003
  "sort",
2004
+ "caching",
1012
2005
  "user",
1013
2006
  "zeroDataRetention",
1014
2007
  "disallowPromptTraining",
@@ -1032,10 +2025,63 @@ function addGatewayOption(options, key, value) {
1032
2025
  }
1033
2026
  function addOpenRouterOption(options, key, value) {
1034
2027
  const target = "openrouter";
2028
+ const providerKey = key.startsWith("provider.") ? key.slice(9) : key;
2029
+ const providerListKeys = /* @__PURE__ */ new Set([
2030
+ "order",
2031
+ "only",
2032
+ "ignore",
2033
+ "quantizations"
2034
+ ]);
2035
+ const providerObjectKeys = /* @__PURE__ */ new Set([
2036
+ "provider",
2037
+ "sort",
2038
+ "preferred_min_throughput",
2039
+ "preferred_max_latency",
2040
+ "max_price"
2041
+ ]);
2042
+ const providerScalarKeys = /* @__PURE__ */ new Set([
2043
+ "allow_fallbacks",
2044
+ "require_parameters",
2045
+ "data_collection",
2046
+ "zdr",
2047
+ "enforce_distillable_text"
2048
+ ]);
1035
2049
  if (key === "models") {
1036
2050
  setProviderOption(options, target, "models", parseStringList(value));
1037
2051
  return;
1038
2052
  }
2053
+ if (key === "transforms") {
2054
+ setProviderOption(options, target, "transforms", parseStringList(value));
2055
+ return;
2056
+ }
2057
+ if (key === "plugins") {
2058
+ const parsed = parseJson(value);
2059
+ setProviderOption(
2060
+ options,
2061
+ target,
2062
+ "plugins",
2063
+ Array.isArray(parsed) ? parsed : parseStringList(value)
2064
+ );
2065
+ return;
2066
+ }
2067
+ if (key.startsWith("provider.") || providerListKeys.has(providerKey) || providerScalarKeys.has(providerKey) || providerObjectKeys.has(providerKey)) {
2068
+ if (providerKey === "provider") {
2069
+ mergeObjectOption(options, target, "provider", value);
2070
+ return;
2071
+ }
2072
+ const current = options[target]?.provider;
2073
+ const providerOptions = current && typeof current === "object" && !Array.isArray(current) ? { ...current } : {};
2074
+ if (providerListKeys.has(providerKey)) {
2075
+ providerOptions[providerKey] = parseStringList(value);
2076
+ } else if (providerObjectKeys.has(providerKey)) {
2077
+ const parsed = parseJson(value);
2078
+ providerOptions[providerKey] = parsed !== void 0 ? parsed : typedValue(value);
2079
+ } else {
2080
+ providerOptions[providerKey] = typedValue(value);
2081
+ }
2082
+ setProviderOption(options, target, "provider", providerOptions);
2083
+ return;
2084
+ }
1039
2085
  if (key === "reasoning") {
1040
2086
  mergeObjectOption(options, target, "reasoning", value);
1041
2087
  return;
@@ -1077,65 +2123,49 @@ function addOpenRouterOption(options, key, value) {
1077
2123
  function addFlexibleProviderOption(options, target, key, value) {
1078
2124
  setProviderOption(options, target, key, typedValue(value));
1079
2125
  }
2126
+ var PROVIDER_OPTION_HANDLERS = {
2127
+ openai: addOpenAiOption,
2128
+ azure: (options, key, value) => addOpenAiOption(options, key, value, "azure"),
2129
+ anthropic: addAnthropicOption,
2130
+ google: addGoogleOption,
2131
+ "google-vertex": (options, key, value) => addGoogleOption(options, key, value, "vertex"),
2132
+ mistral: addMistralOption,
2133
+ cohere: addCohereOption,
2134
+ bedrock: addBedrockOption,
2135
+ openrouter: addOpenRouterOption,
2136
+ xai: (options, key, value) => addOpenAiOption(options, key, value, "xai"),
2137
+ groq: (options, key, value) => addOpenAiOption(options, key, value, "groq"),
2138
+ fal: (options, key, value) => addFlexibleProviderOption(options, "fal", key, value),
2139
+ deepinfra: (options, key, value) => addOpenAiOption(options, key, value, "deepinfra"),
2140
+ "black-forest-labs": (options, key, value) => addFlexibleProviderOption(options, "blackForestLabs", key, value),
2141
+ together: (options, key, value) => addOpenAiOption(options, key, value, "together"),
2142
+ fireworks: (options, key, value) => addOpenAiOption(options, key, value, "fireworks"),
2143
+ deepseek: (options, key, value) => addOpenAiOption(options, key, value, "deepseek"),
2144
+ moonshotai: (options, key, value) => addOpenAiOption(options, key, value, "moonshotai"),
2145
+ perplexity: (options, key, value) => addOpenAiOption(options, key, value, "perplexity"),
2146
+ alibaba: (options, key, value) => addOpenAiOption(options, key, value, "alibaba"),
2147
+ cerebras: (options, key, value) => addOpenAiOption(options, key, value, "cerebras"),
2148
+ replicate: (options, key, value) => addFlexibleProviderOption(options, "replicate", key, value),
2149
+ prodia: (options, key, value) => addFlexibleProviderOption(options, "prodia", key, value),
2150
+ luma: (options, key, value) => addFlexibleProviderOption(options, "luma", key, value),
2151
+ bytedance: (options, key, value) => addFlexibleProviderOption(options, "bytedance", key, value),
2152
+ kling: (options, key, value) => addFlexibleProviderOption(options, "kling", key, value),
2153
+ elevenlabs: (options, key, value) => addFlexibleProviderOption(options, "elevenlabs", key, value),
2154
+ assemblyai: (options, key, value) => addFlexibleProviderOption(options, "assemblyai", key, value),
2155
+ deepgram: (options, key, value) => addFlexibleProviderOption(options, "deepgram", key, value),
2156
+ gladia: (options, key, value) => addFlexibleProviderOption(options, "gladia", key, value),
2157
+ lmnt: (options, key, value) => addFlexibleProviderOption(options, "lmnt", key, value),
2158
+ hume: (options, key, value) => addFlexibleProviderOption(options, "hume", key, value),
2159
+ revai: (options, key, value) => addFlexibleProviderOption(options, "revai", key, value),
2160
+ baseten: (options, key, value) => addOpenAiOption(options, key, value, "baseten"),
2161
+ huggingface: (options, key, value) => addOpenAiOption(options, key, value, "huggingface")
2162
+ };
1080
2163
  function addProviderSpecificOption(options, provider, key, value, includeGatewayOptions) {
1081
2164
  if (provider === "vercel") {
1082
2165
  if (includeGatewayOptions) addGatewayOption(options, key, value);
1083
2166
  return;
1084
2167
  }
1085
- if (provider === "openai") addOpenAiOption(options, key, value);
1086
- if (provider === "azure") addOpenAiOption(options, key, value, "azure");
1087
- if (provider === "anthropic") addAnthropicOption(options, key, value);
1088
- if (provider === "google") addGoogleOption(options, key, value);
1089
- if (provider === "google-vertex")
1090
- addGoogleOption(options, key, value, "vertex");
1091
- if (provider === "mistral") addMistralOption(options, key, value);
1092
- if (provider === "cohere") addCohereOption(options, key, value);
1093
- if (provider === "bedrock") addBedrockOption(options, key, value);
1094
- if (provider === "openrouter") addOpenRouterOption(options, key, value);
1095
- if (provider === "xai") addOpenAiOption(options, key, value, "xai");
1096
- if (provider === "groq") addOpenAiOption(options, key, value, "groq");
1097
- if (provider === "fal") addFlexibleProviderOption(options, "fal", key, value);
1098
- if (provider === "deepinfra")
1099
- addOpenAiOption(options, key, value, "deepinfra");
1100
- if (provider === "black-forest-labs")
1101
- addFlexibleProviderOption(options, "blackForestLabs", key, value);
1102
- if (provider === "together") addOpenAiOption(options, key, value, "together");
1103
- if (provider === "fireworks")
1104
- addOpenAiOption(options, key, value, "fireworks");
1105
- if (provider === "deepseek") addOpenAiOption(options, key, value, "deepseek");
1106
- if (provider === "moonshotai")
1107
- addOpenAiOption(options, key, value, "moonshotai");
1108
- if (provider === "perplexity")
1109
- addOpenAiOption(options, key, value, "perplexity");
1110
- if (provider === "alibaba") addOpenAiOption(options, key, value, "alibaba");
1111
- if (provider === "cerebras") addOpenAiOption(options, key, value, "cerebras");
1112
- if (provider === "replicate")
1113
- addFlexibleProviderOption(options, "replicate", key, value);
1114
- if (provider === "prodia")
1115
- addFlexibleProviderOption(options, "prodia", key, value);
1116
- if (provider === "luma")
1117
- addFlexibleProviderOption(options, "luma", key, value);
1118
- if (provider === "bytedance")
1119
- addFlexibleProviderOption(options, "bytedance", key, value);
1120
- if (provider === "kling")
1121
- addFlexibleProviderOption(options, "kling", key, value);
1122
- if (provider === "elevenlabs")
1123
- addFlexibleProviderOption(options, "elevenlabs", key, value);
1124
- if (provider === "assemblyai")
1125
- addFlexibleProviderOption(options, "assemblyai", key, value);
1126
- if (provider === "deepgram")
1127
- addFlexibleProviderOption(options, "deepgram", key, value);
1128
- if (provider === "gladia")
1129
- addFlexibleProviderOption(options, "gladia", key, value);
1130
- if (provider === "lmnt")
1131
- addFlexibleProviderOption(options, "lmnt", key, value);
1132
- if (provider === "hume")
1133
- addFlexibleProviderOption(options, "hume", key, value);
1134
- if (provider === "revai")
1135
- addFlexibleProviderOption(options, "revai", key, value);
1136
- if (provider === "baseten") addOpenAiOption(options, key, value, "baseten");
1137
- if (provider === "huggingface")
1138
- addOpenAiOption(options, key, value, "huggingface");
2168
+ PROVIDER_OPTION_HANDLERS[provider](options, key, value);
1139
2169
  }
1140
2170
  function createAiSdkProviderOptions(configOrResult, options = {}) {
1141
2171
  const normalized = typeof configOrResult === "string" ? normalize(parse(configOrResult), options) : "changes" in configOrResult && "subProvider" in configOrResult ? configOrResult : normalize(configOrResult, options);
@@ -1174,4 +2204,3 @@ function createAiSdkProviderOptions(configOrResult, options = {}) {
1174
2204
  0 && (module.exports = {
1175
2205
  createAiSdkProviderOptions
1176
2206
  });
1177
- //# sourceMappingURL=ai-sdk.cjs.map