llm-strings 1.4.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.
@@ -113,44 +113,92 @@ function providerFromHostAlias(alias) {
113
113
  }
114
114
  return void 0;
115
115
  }
116
+ function canonicalHostName(host) {
117
+ return normalizeHostValue(host).toLowerCase().split(":")[0] ?? host;
118
+ }
119
+ function hostMatches(host, ...domains) {
120
+ return domains.some((domain) => {
121
+ const normalizedDomain = domain.toLowerCase();
122
+ return host === normalizedDomain || host.endsWith(`.${normalizedDomain}`);
123
+ });
124
+ }
125
+ function hostHasLabel(host, ...labels) {
126
+ const hostLabels = host.split(".");
127
+ return labels.some((label) => hostLabels.includes(label.toLowerCase()));
128
+ }
129
+ function hostHasLabelPrefix(host, ...prefixes) {
130
+ const hostLabels = host.split(".");
131
+ return prefixes.some(
132
+ (prefix) => hostLabels.some((label) => label.startsWith(prefix.toLowerCase()))
133
+ );
134
+ }
135
+ var MODEL_FAMILY_DELIMITERS = /* @__PURE__ */ new Set(["-", "."]);
136
+ function normalizeModelForMatching(model) {
137
+ return model.trim().toLowerCase();
138
+ }
139
+ function modelLeafName(model) {
140
+ const normalized = normalizeModelForMatching(model);
141
+ const slash = normalized.lastIndexOf("/");
142
+ return slash >= 0 ? normalized.slice(slash + 1) : normalized;
143
+ }
144
+ function modelMatchesFamily(model, family) {
145
+ const name = modelLeafName(model);
146
+ const normalizedFamily = normalizeModelForMatching(family);
147
+ if (!name || !normalizedFamily) return false;
148
+ if (name === normalizedFamily) return true;
149
+ const delimiter = name[normalizedFamily.length];
150
+ return name.startsWith(normalizedFamily) && delimiter !== void 0 && MODEL_FAMILY_DELIMITERS.has(delimiter);
151
+ }
116
152
  function detectProvider(host) {
117
- host = host.toLowerCase();
118
- if (host.includes("openrouter")) return "openrouter";
119
- if (host.includes("gateway.ai.vercel")) return "vercel";
120
- if (host.includes("amazonaws") || host.includes("bedrock")) return "bedrock";
121
- if (host.includes("aiplatform.googleapis")) return "google-vertex";
122
- if (host.includes("api.x.ai")) return "xai";
123
- if (host.includes("groq")) return "groq";
124
- if (host.includes("fal.run") || host.includes("fal.ai")) return "fal";
125
- if (host.includes("deepinfra")) return "deepinfra";
126
- if (host.includes("bfl.ai")) return "black-forest-labs";
127
- if (host.includes("together")) return "together";
128
- if (host.includes("fireworks")) return "fireworks";
129
- if (host.includes("deepseek")) return "deepseek";
130
- if (host.includes("moonshot")) return "moonshotai";
131
- if (host.includes("perplexity")) return "perplexity";
132
- if (host.includes("dashscope") || host.includes("aliyuncs")) return "alibaba";
133
- if (host.includes("cerebras")) return "cerebras";
134
- if (host.includes("replicate")) return "replicate";
135
- if (host.includes("prodia")) return "prodia";
136
- if (host.includes("lumalabs") || host.includes("luma")) return "luma";
137
- if (host.includes("volces") || host.includes("bytedance")) return "bytedance";
138
- if (host.includes("kling")) return "kling";
139
- if (host.includes("elevenlabs")) return "elevenlabs";
140
- if (host.includes("assemblyai")) return "assemblyai";
141
- if (host.includes("deepgram")) return "deepgram";
142
- if (host.includes("gladia")) return "gladia";
143
- if (host.includes("lmnt")) return "lmnt";
144
- if (host.includes("hume")) return "hume";
145
- if (host.includes("rev.ai")) return "revai";
146
- if (host.includes("baseten")) return "baseten";
147
- if (host.includes("huggingface")) return "huggingface";
148
- if (host.includes("azure")) return "azure";
149
- if (host.includes("openai")) return "openai";
150
- if (host.includes("anthropic") || host.includes("claude")) return "anthropic";
151
- if (host.includes("googleapis") || host.includes("google")) return "google";
152
- if (host.includes("mistral")) return "mistral";
153
- if (host.includes("cohere")) return "cohere";
153
+ host = canonicalHostName(host);
154
+ if (hostMatches(host, "openrouter", "openrouter.ai")) return "openrouter";
155
+ if (hostMatches(host, "vercel", "gateway.ai.vercel.app", "gateway.ai.vercel.sh")) {
156
+ return "vercel";
157
+ }
158
+ if (hostMatches(host, "bedrock", "amazonaws.com") || hostHasLabelPrefix(host, "bedrock")) {
159
+ return "bedrock";
160
+ }
161
+ if (hostMatches(host, "aiplatform.googleapis.com")) return "google-vertex";
162
+ if (hostMatches(host, "xai", "x.ai", "api.x.ai")) return "xai";
163
+ if (hostMatches(host, "groq", "groq.com", "api.groq.com")) return "groq";
164
+ if (hostMatches(host, "fal", "fal.run", "fal.ai")) return "fal";
165
+ if (hostMatches(host, "deepinfra", "deepinfra.com")) return "deepinfra";
166
+ if (hostMatches(host, "bfl", "bfl.ai", "api.bfl.ai")) {
167
+ return "black-forest-labs";
168
+ }
169
+ if (hostMatches(host, "together", "together.xyz")) return "together";
170
+ if (hostMatches(host, "fireworks", "fireworks.ai")) return "fireworks";
171
+ if (hostMatches(host, "deepseek", "deepseek.com")) return "deepseek";
172
+ if (hostMatches(host, "moonshot", "moonshot.ai")) return "moonshotai";
173
+ if (hostMatches(host, "perplexity", "perplexity.ai")) return "perplexity";
174
+ if (hostMatches(host, "alibaba", "aliyuncs.com") || hostHasLabelPrefix(host, "dashscope")) {
175
+ return "alibaba";
176
+ }
177
+ if (hostMatches(host, "cerebras", "cerebras.ai")) return "cerebras";
178
+ if (hostMatches(host, "replicate", "replicate.com")) return "replicate";
179
+ if (hostMatches(host, "prodia", "prodia.com")) return "prodia";
180
+ if (hostMatches(host, "luma", "lumalabs.ai")) return "luma";
181
+ if (hostMatches(host, "bytedance", "volces.com") || hostHasLabel(host, "bytedance")) {
182
+ return "bytedance";
183
+ }
184
+ if (hostMatches(host, "kling", "klingai.com")) return "kling";
185
+ if (hostMatches(host, "elevenlabs", "elevenlabs.io")) return "elevenlabs";
186
+ if (hostMatches(host, "assemblyai", "assemblyai.com")) return "assemblyai";
187
+ if (hostMatches(host, "deepgram", "deepgram.com")) return "deepgram";
188
+ if (hostMatches(host, "gladia", "gladia.io")) return "gladia";
189
+ if (hostMatches(host, "lmnt", "lmnt.com")) return "lmnt";
190
+ if (hostMatches(host, "hume", "hume.ai")) return "hume";
191
+ if (hostMatches(host, "revai", "rev.ai")) return "revai";
192
+ if (hostMatches(host, "baseten", "baseten.co")) return "baseten";
193
+ if (hostMatches(host, "huggingface", "huggingface.co")) return "huggingface";
194
+ if (hostMatches(host, "azure", "azure.com")) return "azure";
195
+ if (hostMatches(host, "openai", "openai.com")) return "openai";
196
+ if (hostMatches(host, "anthropic", "anthropic.com", "claude.ai")) {
197
+ return "anthropic";
198
+ }
199
+ if (hostMatches(host, "google", "googleapis.com")) return "google";
200
+ if (hostMatches(host, "mistral", "mistral.ai")) return "mistral";
201
+ if (hostMatches(host, "cohere", "cohere.com")) return "cohere";
154
202
  return void 0;
155
203
  }
156
204
  var ALIASES = {
@@ -193,7 +241,10 @@ var ALIASES = {
193
241
  num_completions: "n",
194
242
  // effort / reasoning
195
243
  reasoning_effort: "effort",
244
+ reasoningEffort: "effort",
196
245
  reasoning: "effort",
246
+ thinking_effort: "effort",
247
+ thinkingEffort: "effort",
197
248
  // cache
198
249
  cache_control: "cache",
199
250
  cacheControl: "cache",
@@ -203,6 +254,7 @@ var ALIASES = {
203
254
  var OPENAI_COMPATIBLE_PARAMS = {
204
255
  temperature: "temperature",
205
256
  max_tokens: "max_tokens",
257
+ max_completion_tokens: "max_completion_tokens",
206
258
  top_p: "top_p",
207
259
  top_k: "top_k",
208
260
  frequency_penalty: "frequency_penalty",
@@ -213,6 +265,90 @@ var OPENAI_COMPATIBLE_PARAMS = {
213
265
  stream: "stream",
214
266
  effort: "reasoning_effort"
215
267
  };
268
+ var COMMON_IMAGE_PARAMS = {
269
+ prompt: "prompt",
270
+ negative_prompt: "negative_prompt",
271
+ seed: "seed",
272
+ image_size: "image_size",
273
+ aspect_ratio: "aspect_ratio",
274
+ output_format: "output_format",
275
+ width: "width",
276
+ height: "height"
277
+ };
278
+ var FAL_PARAMS = {
279
+ ...COMMON_IMAGE_PARAMS,
280
+ num_images: "num_images",
281
+ enable_safety_checker: "enable_safety_checker",
282
+ enable_safety_checks: "enable_safety_checks",
283
+ enable_prompt_expansion: "enable_prompt_expansion",
284
+ expand_prompt: "expand_prompt"
285
+ };
286
+ var REPLICATE_PARAMS = {
287
+ ...COMMON_IMAGE_PARAMS,
288
+ input: "input",
289
+ version: "version",
290
+ num_outputs: "num_outputs",
291
+ num_inference_steps: "num_inference_steps",
292
+ guidance_scale: "guidance_scale",
293
+ stream: "stream",
294
+ webhook: "webhook",
295
+ webhook_events_filter: "webhook_events_filter"
296
+ };
297
+ var PRODIA_PARAMS = {
298
+ ...COMMON_IMAGE_PARAMS,
299
+ model: "model",
300
+ style_preset: "style_preset",
301
+ steps: "steps",
302
+ cfg_scale: "cfg_scale",
303
+ upscale: "upscale",
304
+ sampler: "sampler",
305
+ type: "type",
306
+ config: "config",
307
+ price: "price"
308
+ };
309
+ var LUMA_PARAMS = {
310
+ prompt: "prompt",
311
+ model: "model",
312
+ aspect_ratio: "aspect_ratio",
313
+ keyframes: "keyframes",
314
+ loop: "loop",
315
+ duration: "duration",
316
+ type: "type",
317
+ image_ref: "image_ref",
318
+ video: "video",
319
+ source: "source"
320
+ };
321
+ var OPENROUTER_ROUTING_PARAMS = {
322
+ provider: "provider",
323
+ order: "order",
324
+ "provider.order": "provider.order",
325
+ only: "only",
326
+ "provider.only": "provider.only",
327
+ ignore: "ignore",
328
+ "provider.ignore": "provider.ignore",
329
+ allow_fallbacks: "allow_fallbacks",
330
+ "provider.allow_fallbacks": "provider.allow_fallbacks",
331
+ require_parameters: "require_parameters",
332
+ "provider.require_parameters": "provider.require_parameters",
333
+ data_collection: "data_collection",
334
+ "provider.data_collection": "provider.data_collection",
335
+ zdr: "zdr",
336
+ "provider.zdr": "provider.zdr",
337
+ enforce_distillable_text: "enforce_distillable_text",
338
+ "provider.enforce_distillable_text": "provider.enforce_distillable_text",
339
+ quantizations: "quantizations",
340
+ "provider.quantizations": "provider.quantizations",
341
+ sort: "sort",
342
+ "provider.sort": "provider.sort",
343
+ preferred_min_throughput: "preferred_min_throughput",
344
+ "provider.preferred_min_throughput": "provider.preferred_min_throughput",
345
+ preferred_max_latency: "preferred_max_latency",
346
+ "provider.preferred_max_latency": "provider.preferred_max_latency",
347
+ max_price: "max_price",
348
+ "provider.max_price": "provider.max_price",
349
+ transforms: "transforms",
350
+ plugins: "plugins"
351
+ };
216
352
  var GOOGLE_COMPATIBLE_PARAMS = {
217
353
  temperature: "temperature",
218
354
  max_tokens: "maxOutputTokens",
@@ -231,6 +367,7 @@ var PROVIDER_PARAMS = {
231
367
  openai: {
232
368
  temperature: "temperature",
233
369
  max_tokens: "max_tokens",
370
+ max_completion_tokens: "max_completion_tokens",
234
371
  top_p: "top_p",
235
372
  frequency_penalty: "frequency_penalty",
236
373
  presence_penalty: "presence_penalty",
@@ -307,6 +444,7 @@ var PROVIDER_PARAMS = {
307
444
  // OpenAI-compatible API with extra routing params
308
445
  temperature: "temperature",
309
446
  max_tokens: "max_tokens",
447
+ max_completion_tokens: "max_completion_tokens",
310
448
  top_p: "top_p",
311
449
  top_k: "top_k",
312
450
  frequency_penalty: "frequency_penalty",
@@ -315,12 +453,14 @@ var PROVIDER_PARAMS = {
315
453
  n: "n",
316
454
  seed: "seed",
317
455
  stream: "stream",
318
- effort: "reasoning_effort"
456
+ effort: "reasoning_effort",
457
+ ...OPENROUTER_ROUTING_PARAMS
319
458
  },
320
459
  vercel: {
321
460
  // OpenAI-compatible gateway
322
461
  temperature: "temperature",
323
462
  max_tokens: "max_tokens",
463
+ max_completion_tokens: "max_completion_tokens",
324
464
  top_p: "top_p",
325
465
  top_k: "top_k",
326
466
  frequency_penalty: "frequency_penalty",
@@ -333,7 +473,7 @@ var PROVIDER_PARAMS = {
333
473
  },
334
474
  xai: OPENAI_COMPATIBLE_PARAMS,
335
475
  groq: OPENAI_COMPATIBLE_PARAMS,
336
- fal: {},
476
+ fal: FAL_PARAMS,
337
477
  deepinfra: OPENAI_COMPATIBLE_PARAMS,
338
478
  "black-forest-labs": {},
339
479
  together: OPENAI_COMPATIBLE_PARAMS,
@@ -343,9 +483,9 @@ var PROVIDER_PARAMS = {
343
483
  perplexity: OPENAI_COMPATIBLE_PARAMS,
344
484
  alibaba: OPENAI_COMPATIBLE_PARAMS,
345
485
  cerebras: OPENAI_COMPATIBLE_PARAMS,
346
- replicate: {},
347
- prodia: {},
348
- luma: {},
486
+ replicate: REPLICATE_PARAMS,
487
+ prodia: PRODIA_PARAMS,
488
+ luma: LUMA_PARAMS,
349
489
  bytedance: {},
350
490
  kling: {},
351
491
  elevenlabs: {},
@@ -358,6 +498,15 @@ var PROVIDER_PARAMS = {
358
498
  baseten: OPENAI_COMPATIBLE_PARAMS,
359
499
  huggingface: OPENAI_COMPATIBLE_PARAMS
360
500
  };
501
+ var REASONING_EFFORT_VALUES = [
502
+ "none",
503
+ "minimal",
504
+ "low",
505
+ "medium",
506
+ "high",
507
+ "xhigh",
508
+ "max"
509
+ ];
361
510
  var OPENAI_COMPATIBLE_PARAM_SPECS = {
362
511
  temperature: {
363
512
  type: "number",
@@ -372,6 +521,12 @@ var OPENAI_COMPATIBLE_PARAM_SPECS = {
372
521
  default: 4096,
373
522
  description: "Maximum output tokens"
374
523
  },
524
+ max_completion_tokens: {
525
+ type: "number",
526
+ min: 1,
527
+ default: 4096,
528
+ description: "Maximum completion tokens (reasoning models)"
529
+ },
375
530
  top_p: {
376
531
  type: "number",
377
532
  min: 0,
@@ -405,11 +560,221 @@ var OPENAI_COMPATIBLE_PARAM_SPECS = {
405
560
  stream: { type: "boolean", default: false, description: "Stream response" },
406
561
  reasoning_effort: {
407
562
  type: "string",
408
- values: ["none", "minimal", "low", "medium", "high", "xhigh"],
563
+ values: REASONING_EFFORT_VALUES,
409
564
  default: "medium",
410
565
  description: "Reasoning effort"
411
566
  }
412
567
  };
568
+ var OPENROUTER_ROUTING_PARAM_SPECS = {
569
+ provider: { type: "string", description: "Provider routing preferences" },
570
+ order: { type: "string", description: "Provider order" },
571
+ "provider.order": { type: "string", description: "Provider order" },
572
+ only: { type: "string", description: "Provider allowlist" },
573
+ "provider.only": { type: "string", description: "Provider allowlist" },
574
+ ignore: { type: "string", description: "Provider blocklist" },
575
+ "provider.ignore": { type: "string", description: "Provider blocklist" },
576
+ allow_fallbacks: {
577
+ type: "boolean",
578
+ default: true,
579
+ description: "Allow fallback providers"
580
+ },
581
+ "provider.allow_fallbacks": {
582
+ type: "boolean",
583
+ default: true,
584
+ description: "Allow fallback providers"
585
+ },
586
+ require_parameters: {
587
+ type: "boolean",
588
+ default: false,
589
+ description: "Only route to providers that support all request params"
590
+ },
591
+ "provider.require_parameters": {
592
+ type: "boolean",
593
+ default: false,
594
+ description: "Only route to providers that support all request params"
595
+ },
596
+ data_collection: {
597
+ type: "string",
598
+ values: ["allow", "deny"],
599
+ default: "allow",
600
+ description: "Provider data collection policy"
601
+ },
602
+ "provider.data_collection": {
603
+ type: "string",
604
+ values: ["allow", "deny"],
605
+ default: "allow",
606
+ description: "Provider data collection policy"
607
+ },
608
+ zdr: {
609
+ type: "boolean",
610
+ description: "Require zero data retention providers"
611
+ },
612
+ "provider.zdr": {
613
+ type: "boolean",
614
+ description: "Require zero data retention providers"
615
+ },
616
+ enforce_distillable_text: {
617
+ type: "boolean",
618
+ description: "Require providers that allow text distillation"
619
+ },
620
+ "provider.enforce_distillable_text": {
621
+ type: "boolean",
622
+ description: "Require providers that allow text distillation"
623
+ },
624
+ quantizations: {
625
+ type: "string",
626
+ description: "Allowed provider quantization levels"
627
+ },
628
+ "provider.quantizations": {
629
+ type: "string",
630
+ description: "Allowed provider quantization levels"
631
+ },
632
+ sort: {
633
+ type: "string",
634
+ values: ["price", "throughput", "latency", "cost", "ttft", "tps"],
635
+ description: "Provider sort strategy"
636
+ },
637
+ "provider.sort": {
638
+ type: "string",
639
+ values: ["price", "throughput", "latency", "cost", "ttft", "tps"],
640
+ description: "Provider sort strategy"
641
+ },
642
+ preferred_min_throughput: {
643
+ type: "number",
644
+ min: 0,
645
+ description: "Preferred minimum provider throughput"
646
+ },
647
+ "provider.preferred_min_throughput": {
648
+ type: "number",
649
+ min: 0,
650
+ description: "Preferred minimum provider throughput"
651
+ },
652
+ preferred_max_latency: {
653
+ type: "number",
654
+ min: 0,
655
+ description: "Preferred maximum provider latency"
656
+ },
657
+ "provider.preferred_max_latency": {
658
+ type: "number",
659
+ min: 0,
660
+ description: "Preferred maximum provider latency"
661
+ },
662
+ max_price: {
663
+ type: "string",
664
+ description: "Maximum provider price filter"
665
+ },
666
+ "provider.max_price": {
667
+ type: "string",
668
+ description: "Maximum provider price filter"
669
+ },
670
+ transforms: {
671
+ type: "string",
672
+ description: "Legacy OpenRouter message transforms"
673
+ },
674
+ plugins: {
675
+ type: "string",
676
+ description: "OpenRouter request plugins"
677
+ }
678
+ };
679
+ var FAL_PARAM_SPECS = {
680
+ prompt: { type: "string", description: "Prompt" },
681
+ negative_prompt: { type: "string", description: "Negative prompt" },
682
+ seed: { type: "number", description: "Random seed" },
683
+ num_images: {
684
+ type: "number",
685
+ min: 1,
686
+ description: "Number of images to generate"
687
+ },
688
+ image_size: { type: "string", description: "Output image size" },
689
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
690
+ enable_safety_checker: {
691
+ type: "boolean",
692
+ description: "Enable safety checker"
693
+ },
694
+ enable_safety_checks: {
695
+ type: "boolean",
696
+ description: "Enable safety checker"
697
+ },
698
+ enable_prompt_expansion: {
699
+ type: "boolean",
700
+ description: "Enable prompt expansion"
701
+ },
702
+ expand_prompt: {
703
+ type: "boolean",
704
+ description: "Enable prompt expansion"
705
+ },
706
+ output_format: {
707
+ type: "string",
708
+ values: ["jpeg", "jpg", "png", "webp", "gif"],
709
+ description: "Output image format"
710
+ },
711
+ width: { type: "number", min: 1, description: "Image width" },
712
+ height: { type: "number", min: 1, description: "Image height" }
713
+ };
714
+ var REPLICATE_PARAM_SPECS = {
715
+ prompt: { type: "string", description: "Prompt" },
716
+ negative_prompt: { type: "string", description: "Negative prompt" },
717
+ input: { type: "string", description: "Model input object" },
718
+ version: { type: "string", description: "Model version" },
719
+ seed: { type: "number", description: "Random seed" },
720
+ num_outputs: {
721
+ type: "number",
722
+ min: 1,
723
+ description: "Number of outputs to generate"
724
+ },
725
+ num_inference_steps: {
726
+ type: "number",
727
+ min: 1,
728
+ description: "Number of inference steps"
729
+ },
730
+ guidance_scale: {
731
+ type: "number",
732
+ min: 0,
733
+ description: "Guidance scale"
734
+ },
735
+ image_size: { type: "string", description: "Output image size" },
736
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
737
+ output_format: { type: "string", description: "Output format" },
738
+ width: { type: "number", min: 1, description: "Image width" },
739
+ height: { type: "number", min: 1, description: "Image height" },
740
+ stream: { type: "boolean", description: "Request streaming output" },
741
+ webhook: { type: "string", description: "Webhook URL" },
742
+ webhook_events_filter: {
743
+ type: "string",
744
+ description: "Webhook events filter"
745
+ }
746
+ };
747
+ var PRODIA_PARAM_SPECS = {
748
+ model: { type: "string", description: "Model name" },
749
+ prompt: { type: "string", description: "Prompt" },
750
+ negative_prompt: { type: "string", description: "Negative prompt" },
751
+ style_preset: { type: "string", description: "Style preset" },
752
+ steps: { type: "number", min: 1, description: "Generation steps" },
753
+ cfg_scale: { type: "number", min: 0, description: "CFG scale" },
754
+ seed: { type: "number", description: "Random seed" },
755
+ upscale: { type: "boolean", description: "Enable 2x upscale" },
756
+ sampler: { type: "string", description: "Sampler" },
757
+ width: { type: "number", min: 1, max: 1024, description: "Image width" },
758
+ height: { type: "number", min: 1, max: 1024, description: "Image height" },
759
+ image_size: { type: "string", description: "Output image size" },
760
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
761
+ output_format: { type: "string", description: "Output format" },
762
+ type: { type: "string", description: "Prodia v2 job type" },
763
+ config: { type: "string", description: "Prodia v2 job config" },
764
+ price: { type: "boolean", description: "Include Prodia v2 job price" }
765
+ };
766
+ var LUMA_PARAM_SPECS = {
767
+ prompt: { type: "string", description: "Prompt" },
768
+ model: { type: "string", description: "Model name" },
769
+ aspect_ratio: { type: "string", description: "Output aspect ratio" },
770
+ keyframes: { type: "string", description: "Generation keyframes" },
771
+ loop: { type: "boolean", description: "Generate a looping video" },
772
+ duration: { type: "string", description: "Generation duration" },
773
+ type: { type: "string", description: "Generation type" },
774
+ image_ref: { type: "string", description: "Image reference" },
775
+ video: { type: "string", description: "Video options" },
776
+ source: { type: "string", description: "Source generation or media" }
777
+ };
413
778
  var GOOGLE_COMPATIBLE_PARAM_SPECS = {
414
779
  temperature: {
415
780
  type: "number",
@@ -478,6 +843,12 @@ var PARAM_SPECS = {
478
843
  default: 4096,
479
844
  description: "Maximum output tokens"
480
845
  },
846
+ max_completion_tokens: {
847
+ type: "number",
848
+ min: 1,
849
+ default: 4096,
850
+ description: "Maximum completion tokens (reasoning models)"
851
+ },
481
852
  top_p: {
482
853
  type: "number",
483
854
  min: 0,
@@ -505,7 +876,7 @@ var PARAM_SPECS = {
505
876
  stream: { type: "boolean", default: false, description: "Stream response" },
506
877
  reasoning_effort: {
507
878
  type: "string",
508
- values: ["none", "minimal", "low", "medium", "high", "xhigh"],
879
+ values: REASONING_EFFORT_VALUES,
509
880
  default: "medium",
510
881
  description: "Reasoning effort"
511
882
  }
@@ -542,8 +913,8 @@ var PARAM_SPECS = {
542
913
  stream: { type: "boolean", default: false, description: "Stream response" },
543
914
  effort: {
544
915
  type: "string",
545
- values: ["low", "medium", "high", "max"],
546
- default: "medium",
916
+ values: REASONING_EFFORT_VALUES,
917
+ default: "low",
547
918
  description: "Thinking effort"
548
919
  },
549
920
  cache_control: {
@@ -768,6 +1139,12 @@ var PARAM_SPECS = {
768
1139
  default: 4096,
769
1140
  description: "Maximum output tokens"
770
1141
  },
1142
+ max_completion_tokens: {
1143
+ type: "number",
1144
+ min: 1,
1145
+ default: 4096,
1146
+ description: "Maximum completion tokens (reasoning models)"
1147
+ },
771
1148
  top_p: {
772
1149
  type: "number",
773
1150
  min: 0,
@@ -801,10 +1178,11 @@ var PARAM_SPECS = {
801
1178
  stream: { type: "boolean", default: false, description: "Stream response" },
802
1179
  reasoning_effort: {
803
1180
  type: "string",
804
- values: ["none", "minimal", "low", "medium", "high", "xhigh"],
1181
+ values: REASONING_EFFORT_VALUES,
805
1182
  default: "medium",
806
1183
  description: "Reasoning effort"
807
- }
1184
+ },
1185
+ ...OPENROUTER_ROUTING_PARAM_SPECS
808
1186
  },
809
1187
  vercel: {
810
1188
  // Loose validation — proxies to many providers with varying ranges
@@ -821,6 +1199,12 @@ var PARAM_SPECS = {
821
1199
  default: 4096,
822
1200
  description: "Maximum output tokens"
823
1201
  },
1202
+ max_completion_tokens: {
1203
+ type: "number",
1204
+ min: 1,
1205
+ default: 4096,
1206
+ description: "Maximum completion tokens (reasoning models)"
1207
+ },
824
1208
  top_p: {
825
1209
  type: "number",
826
1210
  min: 0,
@@ -854,14 +1238,70 @@ var PARAM_SPECS = {
854
1238
  stream: { type: "boolean", default: false, description: "Stream response" },
855
1239
  reasoning_effort: {
856
1240
  type: "string",
857
- values: ["none", "minimal", "low", "medium", "high", "xhigh"],
1241
+ values: REASONING_EFFORT_VALUES,
858
1242
  default: "medium",
859
1243
  description: "Reasoning effort"
1244
+ },
1245
+ order: { type: "string", description: "Gateway provider order" },
1246
+ only: { type: "string", description: "Gateway provider allowlist" },
1247
+ models: { type: "string", description: "Gateway fallback models" },
1248
+ tags: { type: "string", description: "Gateway usage tags" },
1249
+ sort: {
1250
+ type: "string",
1251
+ values: ["cost", "ttft", "tps"],
1252
+ description: "Gateway provider sort strategy"
1253
+ },
1254
+ caching: {
1255
+ type: "string",
1256
+ values: ["auto"],
1257
+ description: "Gateway automatic caching strategy"
1258
+ },
1259
+ user: { type: "string", description: "Gateway usage user identifier" },
1260
+ byok: { type: "string", description: "Gateway BYOK credentials" },
1261
+ zero_data_retention: {
1262
+ type: "boolean",
1263
+ description: "Gateway zero data retention routing"
1264
+ },
1265
+ zeroDataRetention: {
1266
+ type: "boolean",
1267
+ description: "Gateway zero data retention routing"
1268
+ },
1269
+ disallow_prompt_training: {
1270
+ type: "boolean",
1271
+ description: "Gateway prompt training opt-out routing"
1272
+ },
1273
+ disallowPromptTraining: {
1274
+ type: "boolean",
1275
+ description: "Gateway prompt training opt-out routing"
1276
+ },
1277
+ hipaa_compliant: {
1278
+ type: "boolean",
1279
+ description: "Gateway HIPAA-compliant routing"
1280
+ },
1281
+ hipaaCompliant: {
1282
+ type: "boolean",
1283
+ description: "Gateway HIPAA-compliant routing"
1284
+ },
1285
+ quota_entity_id: {
1286
+ type: "string",
1287
+ description: "Gateway quota entity identifier"
1288
+ },
1289
+ quotaEntityId: {
1290
+ type: "string",
1291
+ description: "Gateway quota entity identifier"
1292
+ },
1293
+ provider_timeouts: {
1294
+ type: "string",
1295
+ description: "Gateway provider timeouts"
1296
+ },
1297
+ providerTimeouts: {
1298
+ type: "string",
1299
+ description: "Gateway provider timeouts"
860
1300
  }
861
1301
  },
862
1302
  xai: OPENAI_COMPATIBLE_PARAM_SPECS,
863
1303
  groq: OPENAI_COMPATIBLE_PARAM_SPECS,
864
- fal: {},
1304
+ fal: FAL_PARAM_SPECS,
865
1305
  deepinfra: OPENAI_COMPATIBLE_PARAM_SPECS,
866
1306
  "black-forest-labs": {},
867
1307
  together: OPENAI_COMPATIBLE_PARAM_SPECS,
@@ -871,9 +1311,9 @@ var PARAM_SPECS = {
871
1311
  perplexity: OPENAI_COMPATIBLE_PARAM_SPECS,
872
1312
  alibaba: OPENAI_COMPATIBLE_PARAM_SPECS,
873
1313
  cerebras: OPENAI_COMPATIBLE_PARAM_SPECS,
874
- replicate: {},
875
- prodia: {},
876
- luma: {},
1314
+ replicate: REPLICATE_PARAM_SPECS,
1315
+ prodia: PRODIA_PARAM_SPECS,
1316
+ luma: LUMA_PARAM_SPECS,
877
1317
  bytedance: {},
878
1318
  kling: {},
879
1319
  elevenlabs: {},
@@ -887,11 +1327,13 @@ var PARAM_SPECS = {
887
1327
  huggingface: OPENAI_COMPATIBLE_PARAM_SPECS
888
1328
  };
889
1329
  function isReasoningModel(model) {
890
- const name = model.includes("/") ? model.split("/").pop() : model;
891
- return /^o[134]/.test(name);
1330
+ const name = modelLeafName(model);
1331
+ const oSeries = name.match(/^o\d+/)?.[0];
1332
+ const gptSeries = name.match(/^gpt-[5-9]/)?.[0];
1333
+ return (oSeries ? modelMatchesFamily(name, oSeries) : false) || (gptSeries ? modelMatchesFamily(name, gptSeries) : false);
892
1334
  }
893
1335
  function canHostOpenAIModels(provider) {
894
- return provider === "openai" || provider === "openrouter" || provider === "vercel";
1336
+ return provider === "openai" || provider === "azure" || provider === "openrouter" || provider === "vercel";
895
1337
  }
896
1338
  function isGatewayProvider(provider) {
897
1339
  return provider === "openrouter" || provider === "vercel";
@@ -899,29 +1341,27 @@ function isGatewayProvider(provider) {
899
1341
  function detectGatewaySubProvider(model) {
900
1342
  const slash = model.indexOf("/");
901
1343
  if (slash < 1) return void 0;
902
- const prefix = model.slice(0, slash);
903
- const direct = [
904
- "openai",
905
- "anthropic",
906
- "google",
907
- "mistral",
908
- "cohere"
909
- ];
910
- return direct.find((p) => p === prefix);
1344
+ const prefix = normalizeModelForMatching(model.slice(0, slash));
1345
+ const direct = {
1346
+ openai: "openai",
1347
+ anthropic: "anthropic",
1348
+ google: "google",
1349
+ vertex: "google",
1350
+ "google-vertex": "google",
1351
+ mistral: "mistral",
1352
+ cohere: "cohere"
1353
+ };
1354
+ return direct[prefix];
911
1355
  }
912
1356
  var REASONING_MODEL_UNSUPPORTED = /* @__PURE__ */ new Set([
913
1357
  "temperature",
914
1358
  "top_p",
1359
+ "top_k",
915
1360
  "frequency_penalty",
916
1361
  "presence_penalty",
917
1362
  "n"
918
1363
  ]);
919
1364
  function detectBedrockModelFamily(model) {
920
- const parts = model.split(".");
921
- let prefix = parts[0];
922
- if (["us", "eu", "apac", "global"].includes(prefix) && parts.length > 1) {
923
- prefix = parts[1];
924
- }
925
1365
  const families = [
926
1366
  "anthropic",
927
1367
  "meta",
@@ -930,12 +1370,18 @@ function detectBedrockModelFamily(model) {
930
1370
  "cohere",
931
1371
  "ai21"
932
1372
  ];
933
- return families.find((f) => prefix === f);
1373
+ const parts = modelLeafName(model).split(".");
1374
+ return families.find((family) => parts.includes(family));
934
1375
  }
935
1376
  function bedrockSupportsCaching(model) {
936
1377
  const family = detectBedrockModelFamily(model);
937
1378
  if (family === "anthropic") return true;
938
- if (family === "amazon" && model.includes("nova")) return true;
1379
+ if (family === "amazon") {
1380
+ const parts = modelLeafName(model).split(".");
1381
+ const amazonIndex = parts.indexOf("amazon");
1382
+ const modelName = amazonIndex >= 0 ? parts[amazonIndex + 1] : void 0;
1383
+ return modelName ? modelMatchesFamily(modelName, "nova") : false;
1384
+ }
939
1385
  return false;
940
1386
  }
941
1387
  var CACHE_VALUES = {
@@ -1020,12 +1466,12 @@ var CACHE_TTLS = {
1020
1466
  baseten: void 0,
1021
1467
  huggingface: void 0
1022
1468
  };
1023
- var DURATION_RE = /^\d+[mh]$/;
1024
1469
 
1025
1470
  export {
1026
1471
  HOST_ALIASES,
1027
1472
  resolveHostAlias,
1028
1473
  providerFromHostAlias,
1474
+ modelMatchesFamily,
1029
1475
  detectProvider,
1030
1476
  ALIASES,
1031
1477
  PROVIDER_PARAMS,
@@ -1038,6 +1484,5 @@ export {
1038
1484
  detectBedrockModelFamily,
1039
1485
  bedrockSupportsCaching,
1040
1486
  CACHE_VALUES,
1041
- CACHE_TTLS,
1042
- DURATION_RE
1487
+ CACHE_TTLS
1043
1488
  };