llm-strings 1.1.2 → 1.3.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 (47) hide show
  1. package/README.md +115 -45
  2. package/dist/ai-sdk.cjs +1177 -0
  3. package/dist/ai-sdk.cjs.map +1 -0
  4. package/dist/ai-sdk.d.cts +28 -0
  5. package/dist/ai-sdk.d.ts +28 -0
  6. package/dist/ai-sdk.js +544 -0
  7. package/dist/ai-sdk.js.map +1 -0
  8. package/dist/{chunk-UYMVUTLV.js → chunk-7HE4RH6X.js} +5 -9
  9. package/dist/chunk-7HE4RH6X.js.map +1 -0
  10. package/dist/{chunk-MPIHGH6L.js → chunk-NZR5DUX5.js} +5 -4
  11. package/dist/chunk-NZR5DUX5.js.map +1 -0
  12. package/dist/chunk-OCJX4QFJ.js +1044 -0
  13. package/dist/chunk-OCJX4QFJ.js.map +1 -0
  14. package/dist/{chunk-FCEV23OT.js → chunk-TQJ2ABCT.js} +9 -3
  15. package/dist/chunk-TQJ2ABCT.js.map +1 -0
  16. package/dist/index.cjs +760 -87
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +1 -1
  19. package/dist/index.d.ts +4 -4
  20. package/dist/index.js +9 -4
  21. package/dist/normalize.cjs +176 -5
  22. package/dist/normalize.cjs.map +1 -1
  23. package/dist/normalize.d.cts +1 -1
  24. package/dist/normalize.d.ts +2 -2
  25. package/dist/normalize.js +2 -2
  26. package/dist/parse.cjs +100 -2
  27. package/dist/parse.cjs.map +1 -1
  28. package/dist/parse.d.cts +5 -1
  29. package/dist/parse.d.ts +5 -1
  30. package/dist/parse.js +2 -1
  31. package/dist/{provider-core-DinpG40u.d.cts → provider-core-B934MuhJ.d.cts} +21 -2
  32. package/dist/{provider-core-DinpG40u.d.ts → provider-core-B934MuhJ.d.ts} +21 -2
  33. package/dist/providers.cjs +1396 -114
  34. package/dist/providers.cjs.map +1 -1
  35. package/dist/providers.d.cts +2 -2
  36. package/dist/providers.d.ts +2 -2
  37. package/dist/providers.js +672 -61
  38. package/dist/providers.js.map +1 -1
  39. package/dist/validate.cjs +750 -82
  40. package/dist/validate.cjs.map +1 -1
  41. package/dist/validate.js +4 -4
  42. package/package.json +13 -3
  43. package/dist/chunk-FCEV23OT.js.map +0 -1
  44. package/dist/chunk-MPIHGH6L.js.map +0 -1
  45. package/dist/chunk-UYMVUTLV.js.map +0 -1
  46. package/dist/chunk-XID353H7.js +0 -370
  47. package/dist/chunk-XID353H7.js.map +0 -1
package/dist/validate.cjs CHANGED
@@ -24,37 +24,154 @@ __export(validate_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(validate_exports);
26
26
 
27
- // src/parse.ts
28
- function parse(connectionString) {
29
- const url = new URL(connectionString);
30
- if (url.protocol !== "llm:") {
31
- throw new Error(
32
- `Invalid scheme: expected "llm://", got "${url.protocol}//"`
33
- );
27
+ // src/provider-core.ts
28
+ function hasOwn(object, key) {
29
+ return Object.prototype.hasOwnProperty.call(object, key);
30
+ }
31
+ var HOST_ALIASES = {
32
+ openai: "api.openai.com",
33
+ azure: "models.inference.ai.azure.com",
34
+ anthropic: "api.anthropic.com",
35
+ google: "generativelanguage.googleapis.com",
36
+ "google-vertex": "aiplatform.googleapis.com",
37
+ aistudio: "generativelanguage.googleapis.com",
38
+ mistral: "api.mistral.ai",
39
+ cohere: "api.cohere.com",
40
+ bedrock: "bedrock-runtime.us-east-1.amazonaws.com",
41
+ openrouter: "openrouter.ai",
42
+ vercel: "gateway.ai.vercel.app",
43
+ alibaba: "dashscope-intl.aliyuncs.com",
44
+ alibabacloud: "dashscope-intl.aliyuncs.com",
45
+ dashscope: "dashscope-intl.aliyuncs.com",
46
+ groq: "api.groq.com",
47
+ fal: "fal.run",
48
+ fireworks: "api.fireworks.ai",
49
+ fireworksai: "api.fireworks.ai",
50
+ "black-forest-labs": "api.bfl.ai",
51
+ bfl: "api.bfl.ai",
52
+ deepseek: "api.deepseek.com",
53
+ moonshotai: "api.moonshot.ai",
54
+ moonshot: "api.moonshot.ai",
55
+ perplexity: "api.perplexity.ai",
56
+ venice: "api.venice.ai",
57
+ parasail: "api.parasail.io",
58
+ deepinfra: "api.deepinfra.com",
59
+ atlascloud: "api.atlascloud.ai",
60
+ novita: "api.novita.ai",
61
+ novitaai: "api.novita.ai",
62
+ grok: "api.x.ai",
63
+ xai: "api.x.ai",
64
+ together: "api.together.xyz",
65
+ togetherai: "api.together.xyz",
66
+ cerebras: "api.cerebras.ai",
67
+ replicate: "api.replicate.com",
68
+ prodia: "api.prodia.com",
69
+ luma: "api.lumalabs.ai",
70
+ bytedance: "ark.cn-beijing.volces.com",
71
+ kling: "api.klingai.com",
72
+ elevenlabs: "api.elevenlabs.io",
73
+ assemblyai: "api.assemblyai.com",
74
+ deepgram: "api.deepgram.com",
75
+ gladia: "api.gladia.io",
76
+ lmnt: "api.lmnt.com",
77
+ hume: "api.hume.ai",
78
+ revai: "api.rev.ai",
79
+ baseten: "api.baseten.co",
80
+ huggingface: "api-inference.huggingface.co",
81
+ wandb: "api.inference.wandb.ai",
82
+ weightsandbiases: "api.inference.wandb.ai",
83
+ baidu: "qianfan.baidubce.com",
84
+ qianfan: "qianfan.baidubce.com",
85
+ vertex: "aiplatform.googleapis.com",
86
+ xiaomi: "api.xiaomimimo.com",
87
+ minimax: "api.minimax.io"
88
+ };
89
+ var HOST_ALIAS_PROVIDERS = {
90
+ aistudio: "google",
91
+ vertex: "google-vertex",
92
+ grok: "xai",
93
+ bfl: "black-forest-labs",
94
+ moonshot: "moonshotai",
95
+ alibaba: "alibaba",
96
+ alibabacloud: "alibaba",
97
+ dashscope: "alibaba",
98
+ togetherai: "together",
99
+ fireworksai: "fireworks"
100
+ };
101
+ function readProcessEnv() {
102
+ return typeof process !== "undefined" && process.env ? process.env : {};
103
+ }
104
+ function normalizeHostValue(value) {
105
+ const trimmed = value.trim();
106
+ if (!trimmed) return trimmed;
107
+ try {
108
+ if (trimmed.includes("://")) {
109
+ return new URL(trimmed).host;
110
+ }
111
+ } catch {
34
112
  }
35
- const host = url.hostname;
36
- const model = url.pathname.replace(/^\//, "");
37
- const label = url.username || void 0;
38
- const apiKey = url.password || void 0;
39
- const params = {};
40
- for (const [key, value] of url.searchParams) {
41
- params[key] = value;
113
+ return trimmed.replace(/^\/\//, "").split("/")[0] ?? trimmed;
114
+ }
115
+ function envHostOverride(alias, env) {
116
+ const upper = alias.toUpperCase();
117
+ const override = env[`LLM_STRINGS_${upper}_HOST`] ?? env[`LLM_STRINGS_HOST_${upper}`];
118
+ return override?.trim() ? override : void 0;
119
+ }
120
+ function resolveHostAlias(host, env = readProcessEnv()) {
121
+ const normalizedHost = host.toLowerCase();
122
+ if (!hasOwn(HOST_ALIASES, normalizedHost)) {
123
+ return { host };
42
124
  }
125
+ const alias = normalizedHost;
126
+ const override = envHostOverride(alias, env);
43
127
  return {
44
- raw: connectionString,
45
- host,
46
- model,
47
- label,
48
- apiKey,
49
- params
128
+ host: normalizeHostValue(override ?? HOST_ALIASES[alias]),
129
+ alias
50
130
  };
51
131
  }
52
-
53
- // src/provider-core.ts
132
+ function providerFromHostAlias(alias) {
133
+ const normalizedAlias = alias.toLowerCase();
134
+ if (hasOwn(PROVIDER_PARAMS, normalizedAlias)) {
135
+ return normalizedAlias;
136
+ }
137
+ if (hasOwn(HOST_ALIAS_PROVIDERS, normalizedAlias)) {
138
+ return HOST_ALIAS_PROVIDERS[normalizedAlias];
139
+ }
140
+ return void 0;
141
+ }
54
142
  function detectProvider(host) {
143
+ host = host.toLowerCase();
55
144
  if (host.includes("openrouter")) return "openrouter";
56
145
  if (host.includes("gateway.ai.vercel")) return "vercel";
57
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";
58
175
  if (host.includes("openai")) return "openai";
59
176
  if (host.includes("anthropic") || host.includes("claude")) return "anthropic";
60
177
  if (host.includes("googleapis") || host.includes("google")) return "google";
@@ -109,6 +226,33 @@ var ALIASES = {
109
226
  cachePoint: "cache",
110
227
  cache_point: "cache"
111
228
  };
229
+ var OPENAI_COMPATIBLE_PARAMS = {
230
+ temperature: "temperature",
231
+ max_tokens: "max_tokens",
232
+ top_p: "top_p",
233
+ top_k: "top_k",
234
+ frequency_penalty: "frequency_penalty",
235
+ presence_penalty: "presence_penalty",
236
+ stop: "stop",
237
+ n: "n",
238
+ seed: "seed",
239
+ stream: "stream",
240
+ effort: "reasoning_effort"
241
+ };
242
+ var GOOGLE_COMPATIBLE_PARAMS = {
243
+ temperature: "temperature",
244
+ max_tokens: "maxOutputTokens",
245
+ top_p: "topP",
246
+ top_k: "topK",
247
+ frequency_penalty: "frequencyPenalty",
248
+ presence_penalty: "presencePenalty",
249
+ stop: "stopSequences",
250
+ n: "candidateCount",
251
+ stream: "stream",
252
+ seed: "seed",
253
+ responseMimeType: "responseMimeType",
254
+ responseSchema: "responseSchema"
255
+ };
112
256
  var PROVIDER_PARAMS = {
113
257
  openai: {
114
258
  temperature: "temperature",
@@ -122,6 +266,7 @@ var PROVIDER_PARAMS = {
122
266
  stream: "stream",
123
267
  effort: "reasoning_effort"
124
268
  },
269
+ azure: OPENAI_COMPATIBLE_PARAMS,
125
270
  anthropic: {
126
271
  temperature: "temperature",
127
272
  max_tokens: "max_tokens",
@@ -147,6 +292,7 @@ var PROVIDER_PARAMS = {
147
292
  responseMimeType: "responseMimeType",
148
293
  responseSchema: "responseSchema"
149
294
  },
295
+ "google-vertex": GOOGLE_COMPATIBLE_PARAMS,
150
296
  mistral: {
151
297
  temperature: "temperature",
152
298
  max_tokens: "max_tokens",
@@ -210,15 +356,175 @@ var PROVIDER_PARAMS = {
210
356
  seed: "seed",
211
357
  stream: "stream",
212
358
  effort: "reasoning_effort"
359
+ },
360
+ xai: OPENAI_COMPATIBLE_PARAMS,
361
+ groq: OPENAI_COMPATIBLE_PARAMS,
362
+ fal: {},
363
+ deepinfra: OPENAI_COMPATIBLE_PARAMS,
364
+ "black-forest-labs": {},
365
+ together: OPENAI_COMPATIBLE_PARAMS,
366
+ fireworks: OPENAI_COMPATIBLE_PARAMS,
367
+ deepseek: OPENAI_COMPATIBLE_PARAMS,
368
+ moonshotai: OPENAI_COMPATIBLE_PARAMS,
369
+ perplexity: OPENAI_COMPATIBLE_PARAMS,
370
+ alibaba: OPENAI_COMPATIBLE_PARAMS,
371
+ cerebras: OPENAI_COMPATIBLE_PARAMS,
372
+ replicate: {},
373
+ prodia: {},
374
+ luma: {},
375
+ bytedance: {},
376
+ kling: {},
377
+ elevenlabs: {},
378
+ assemblyai: {},
379
+ deepgram: {},
380
+ gladia: {},
381
+ lmnt: {},
382
+ hume: {},
383
+ revai: {},
384
+ baseten: OPENAI_COMPATIBLE_PARAMS,
385
+ huggingface: OPENAI_COMPATIBLE_PARAMS
386
+ };
387
+ var OPENAI_COMPATIBLE_PARAM_SPECS = {
388
+ temperature: {
389
+ type: "number",
390
+ min: 0,
391
+ max: 2,
392
+ default: 0.7,
393
+ description: "Controls randomness"
394
+ },
395
+ max_tokens: {
396
+ type: "number",
397
+ min: 1,
398
+ default: 4096,
399
+ description: "Maximum output tokens"
400
+ },
401
+ top_p: {
402
+ type: "number",
403
+ min: 0,
404
+ max: 1,
405
+ default: 1,
406
+ description: "Nucleus sampling"
407
+ },
408
+ top_k: {
409
+ type: "number",
410
+ min: 0,
411
+ default: 40,
412
+ description: "Top-K sampling"
413
+ },
414
+ frequency_penalty: {
415
+ type: "number",
416
+ min: -2,
417
+ max: 2,
418
+ default: 0,
419
+ description: "Penalize frequent tokens"
420
+ },
421
+ presence_penalty: {
422
+ type: "number",
423
+ min: -2,
424
+ max: 2,
425
+ default: 0,
426
+ description: "Penalize repeated topics"
427
+ },
428
+ stop: { type: "string", description: "Stop sequences" },
429
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
430
+ seed: { type: "number", description: "Random seed" },
431
+ stream: { type: "boolean", default: false, description: "Stream response" },
432
+ reasoning_effort: {
433
+ type: "string",
434
+ values: ["none", "minimal", "low", "medium", "high", "xhigh"],
435
+ default: "medium",
436
+ description: "Reasoning effort"
213
437
  }
214
438
  };
439
+ var GOOGLE_COMPATIBLE_PARAM_SPECS = {
440
+ temperature: {
441
+ type: "number",
442
+ min: 0,
443
+ max: 2,
444
+ default: 0.7,
445
+ description: "Controls randomness"
446
+ },
447
+ maxOutputTokens: {
448
+ type: "number",
449
+ min: 1,
450
+ default: 4096,
451
+ description: "Maximum output tokens"
452
+ },
453
+ topP: {
454
+ type: "number",
455
+ min: 0,
456
+ max: 1,
457
+ default: 1,
458
+ description: "Nucleus sampling"
459
+ },
460
+ topK: {
461
+ type: "number",
462
+ min: 0,
463
+ default: 40,
464
+ description: "Top-K sampling"
465
+ },
466
+ frequencyPenalty: {
467
+ type: "number",
468
+ min: -2,
469
+ max: 2,
470
+ default: 0,
471
+ description: "Penalize frequent tokens"
472
+ },
473
+ presencePenalty: {
474
+ type: "number",
475
+ min: -2,
476
+ max: 2,
477
+ default: 0,
478
+ description: "Penalize repeated topics"
479
+ },
480
+ stopSequences: { type: "string", description: "Stop sequences" },
481
+ candidateCount: {
482
+ type: "number",
483
+ min: 1,
484
+ default: 1,
485
+ description: "Candidate count"
486
+ },
487
+ stream: { type: "boolean", default: false, description: "Stream response" },
488
+ seed: { type: "number", description: "Random seed" },
489
+ responseMimeType: { type: "string", description: "Response MIME type" },
490
+ responseSchema: { type: "string", description: "Response schema" }
491
+ };
215
492
  var PARAM_SPECS = {
216
493
  openai: {
217
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
218
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
219
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
220
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
221
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
494
+ temperature: {
495
+ type: "number",
496
+ min: 0,
497
+ max: 2,
498
+ default: 0.7,
499
+ description: "Controls randomness"
500
+ },
501
+ max_tokens: {
502
+ type: "number",
503
+ min: 1,
504
+ default: 4096,
505
+ description: "Maximum output tokens"
506
+ },
507
+ top_p: {
508
+ type: "number",
509
+ min: 0,
510
+ max: 1,
511
+ default: 1,
512
+ description: "Nucleus sampling"
513
+ },
514
+ frequency_penalty: {
515
+ type: "number",
516
+ min: -2,
517
+ max: 2,
518
+ default: 0,
519
+ description: "Penalize frequent tokens"
520
+ },
521
+ presence_penalty: {
522
+ type: "number",
523
+ min: -2,
524
+ max: 2,
525
+ default: 0,
526
+ description: "Penalize repeated topics"
527
+ },
222
528
  stop: { type: "string", description: "Stop sequences" },
223
529
  n: { type: "number", min: 1, default: 1, description: "Completions count" },
224
530
  seed: { type: "number", description: "Random seed" },
@@ -230,74 +536,291 @@ var PARAM_SPECS = {
230
536
  description: "Reasoning effort"
231
537
  }
232
538
  },
539
+ azure: OPENAI_COMPATIBLE_PARAM_SPECS,
233
540
  anthropic: {
234
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
235
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
236
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
237
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
541
+ temperature: {
542
+ type: "number",
543
+ min: 0,
544
+ max: 1,
545
+ default: 0.7,
546
+ description: "Controls randomness"
547
+ },
548
+ max_tokens: {
549
+ type: "number",
550
+ min: 1,
551
+ default: 4096,
552
+ description: "Maximum output tokens"
553
+ },
554
+ top_p: {
555
+ type: "number",
556
+ min: 0,
557
+ max: 1,
558
+ default: 1,
559
+ description: "Nucleus sampling"
560
+ },
561
+ top_k: {
562
+ type: "number",
563
+ min: 0,
564
+ default: 40,
565
+ description: "Top-K sampling"
566
+ },
238
567
  stop_sequences: { type: "string", description: "Stop sequences" },
239
568
  stream: { type: "boolean", default: false, description: "Stream response" },
240
- effort: { type: "string", values: ["low", "medium", "high", "max"], default: "medium", description: "Thinking effort" },
241
- cache_control: { type: "string", values: ["ephemeral"], default: "ephemeral", description: "Cache control" },
242
- cache_ttl: { type: "string", values: ["5m", "1h"], default: "5m", description: "Cache TTL" }
569
+ effort: {
570
+ type: "string",
571
+ values: ["low", "medium", "high", "max"],
572
+ default: "medium",
573
+ description: "Thinking effort"
574
+ },
575
+ cache_control: {
576
+ type: "string",
577
+ values: ["ephemeral"],
578
+ default: "ephemeral",
579
+ description: "Cache control"
580
+ },
581
+ cache_ttl: {
582
+ type: "string",
583
+ values: ["5m", "1h"],
584
+ default: "5m",
585
+ description: "Cache TTL"
586
+ }
243
587
  },
244
588
  google: {
245
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
246
- maxOutputTokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
247
- topP: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
248
- topK: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
249
- frequencyPenalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
250
- presencePenalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
589
+ temperature: {
590
+ type: "number",
591
+ min: 0,
592
+ max: 2,
593
+ default: 0.7,
594
+ description: "Controls randomness"
595
+ },
596
+ maxOutputTokens: {
597
+ type: "number",
598
+ min: 1,
599
+ default: 4096,
600
+ description: "Maximum output tokens"
601
+ },
602
+ topP: {
603
+ type: "number",
604
+ min: 0,
605
+ max: 1,
606
+ default: 1,
607
+ description: "Nucleus sampling"
608
+ },
609
+ topK: {
610
+ type: "number",
611
+ min: 0,
612
+ default: 40,
613
+ description: "Top-K sampling"
614
+ },
615
+ frequencyPenalty: {
616
+ type: "number",
617
+ min: -2,
618
+ max: 2,
619
+ default: 0,
620
+ description: "Penalize frequent tokens"
621
+ },
622
+ presencePenalty: {
623
+ type: "number",
624
+ min: -2,
625
+ max: 2,
626
+ default: 0,
627
+ description: "Penalize repeated topics"
628
+ },
251
629
  stopSequences: { type: "string", description: "Stop sequences" },
252
- candidateCount: { type: "number", min: 1, default: 1, description: "Candidate count" },
630
+ candidateCount: {
631
+ type: "number",
632
+ min: 1,
633
+ default: 1,
634
+ description: "Candidate count"
635
+ },
253
636
  stream: { type: "boolean", default: false, description: "Stream response" },
254
637
  seed: { type: "number", description: "Random seed" },
255
638
  responseMimeType: { type: "string", description: "Response MIME type" },
256
639
  responseSchema: { type: "string", description: "Response schema" }
257
640
  },
641
+ "google-vertex": GOOGLE_COMPATIBLE_PARAM_SPECS,
258
642
  mistral: {
259
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
260
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
261
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
262
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
263
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
643
+ temperature: {
644
+ type: "number",
645
+ min: 0,
646
+ max: 1,
647
+ default: 0.7,
648
+ description: "Controls randomness"
649
+ },
650
+ max_tokens: {
651
+ type: "number",
652
+ min: 1,
653
+ default: 4096,
654
+ description: "Maximum output tokens"
655
+ },
656
+ top_p: {
657
+ type: "number",
658
+ min: 0,
659
+ max: 1,
660
+ default: 1,
661
+ description: "Nucleus sampling"
662
+ },
663
+ frequency_penalty: {
664
+ type: "number",
665
+ min: -2,
666
+ max: 2,
667
+ default: 0,
668
+ description: "Penalize frequent tokens"
669
+ },
670
+ presence_penalty: {
671
+ type: "number",
672
+ min: -2,
673
+ max: 2,
674
+ default: 0,
675
+ description: "Penalize repeated topics"
676
+ },
264
677
  stop: { type: "string", description: "Stop sequences" },
265
678
  n: { type: "number", min: 1, default: 1, description: "Completions count" },
266
679
  random_seed: { type: "number", description: "Random seed" },
267
680
  stream: { type: "boolean", default: false, description: "Stream response" },
268
- safe_prompt: { type: "boolean", default: false, description: "Enable safe prompt" },
269
- min_tokens: { type: "number", min: 0, default: 0, description: "Minimum tokens" }
681
+ safe_prompt: {
682
+ type: "boolean",
683
+ default: false,
684
+ description: "Enable safe prompt"
685
+ },
686
+ min_tokens: {
687
+ type: "number",
688
+ min: 0,
689
+ default: 0,
690
+ description: "Minimum tokens"
691
+ }
270
692
  },
271
693
  cohere: {
272
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
273
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
274
- p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling (p)" },
275
- k: { type: "number", min: 0, max: 500, default: 40, description: "Top-K sampling (k)" },
276
- frequency_penalty: { type: "number", min: 0, max: 1, default: 0, description: "Penalize frequent tokens" },
277
- presence_penalty: { type: "number", min: 0, max: 1, default: 0, description: "Penalize repeated topics" },
694
+ temperature: {
695
+ type: "number",
696
+ min: 0,
697
+ max: 1,
698
+ default: 0.7,
699
+ description: "Controls randomness"
700
+ },
701
+ max_tokens: {
702
+ type: "number",
703
+ min: 1,
704
+ default: 4096,
705
+ description: "Maximum output tokens"
706
+ },
707
+ p: {
708
+ type: "number",
709
+ min: 0,
710
+ max: 1,
711
+ default: 1,
712
+ description: "Nucleus sampling (p)"
713
+ },
714
+ k: {
715
+ type: "number",
716
+ min: 0,
717
+ max: 500,
718
+ default: 40,
719
+ description: "Top-K sampling (k)"
720
+ },
721
+ frequency_penalty: {
722
+ type: "number",
723
+ min: 0,
724
+ max: 1,
725
+ default: 0,
726
+ description: "Penalize frequent tokens"
727
+ },
728
+ presence_penalty: {
729
+ type: "number",
730
+ min: 0,
731
+ max: 1,
732
+ default: 0,
733
+ description: "Penalize repeated topics"
734
+ },
278
735
  stop_sequences: { type: "string", description: "Stop sequences" },
279
736
  stream: { type: "boolean", default: false, description: "Stream response" },
280
737
  seed: { type: "number", description: "Random seed" }
281
738
  },
282
739
  bedrock: {
283
740
  // Converse API inferenceConfig params
284
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
285
- maxTokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
286
- topP: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
287
- topK: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
741
+ temperature: {
742
+ type: "number",
743
+ min: 0,
744
+ max: 1,
745
+ default: 0.7,
746
+ description: "Controls randomness"
747
+ },
748
+ maxTokens: {
749
+ type: "number",
750
+ min: 1,
751
+ default: 4096,
752
+ description: "Maximum output tokens"
753
+ },
754
+ topP: {
755
+ type: "number",
756
+ min: 0,
757
+ max: 1,
758
+ default: 1,
759
+ description: "Nucleus sampling"
760
+ },
761
+ topK: {
762
+ type: "number",
763
+ min: 0,
764
+ default: 40,
765
+ description: "Top-K sampling"
766
+ },
288
767
  stopSequences: { type: "string", description: "Stop sequences" },
289
768
  stream: { type: "boolean", default: false, description: "Stream response" },
290
- cache_control: { type: "string", values: ["ephemeral"], default: "ephemeral", description: "Cache control" },
291
- cache_ttl: { type: "string", values: ["5m", "1h"], default: "5m", description: "Cache TTL" }
769
+ cache_control: {
770
+ type: "string",
771
+ values: ["ephemeral"],
772
+ default: "ephemeral",
773
+ description: "Cache control"
774
+ },
775
+ cache_ttl: {
776
+ type: "string",
777
+ values: ["5m", "1h"],
778
+ default: "5m",
779
+ description: "Cache TTL"
780
+ }
292
781
  },
293
782
  openrouter: {
294
783
  // Loose validation — proxies to many providers with varying ranges
295
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
296
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
297
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
298
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
299
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
300
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
784
+ temperature: {
785
+ type: "number",
786
+ min: 0,
787
+ max: 2,
788
+ default: 0.7,
789
+ description: "Controls randomness"
790
+ },
791
+ max_tokens: {
792
+ type: "number",
793
+ min: 1,
794
+ default: 4096,
795
+ description: "Maximum output tokens"
796
+ },
797
+ top_p: {
798
+ type: "number",
799
+ min: 0,
800
+ max: 1,
801
+ default: 1,
802
+ description: "Nucleus sampling"
803
+ },
804
+ top_k: {
805
+ type: "number",
806
+ min: 0,
807
+ default: 40,
808
+ description: "Top-K sampling"
809
+ },
810
+ frequency_penalty: {
811
+ type: "number",
812
+ min: -2,
813
+ max: 2,
814
+ default: 0,
815
+ description: "Penalize frequent tokens"
816
+ },
817
+ presence_penalty: {
818
+ type: "number",
819
+ min: -2,
820
+ max: 2,
821
+ default: 0,
822
+ description: "Penalize repeated topics"
823
+ },
301
824
  stop: { type: "string", description: "Stop sequences" },
302
825
  n: { type: "number", min: 1, default: 1, description: "Completions count" },
303
826
  seed: { type: "number", description: "Random seed" },
@@ -311,12 +834,46 @@ var PARAM_SPECS = {
311
834
  },
312
835
  vercel: {
313
836
  // Loose validation — proxies to many providers with varying ranges
314
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
315
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
316
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
317
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
318
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
319
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
837
+ temperature: {
838
+ type: "number",
839
+ min: 0,
840
+ max: 2,
841
+ default: 0.7,
842
+ description: "Controls randomness"
843
+ },
844
+ max_tokens: {
845
+ type: "number",
846
+ min: 1,
847
+ default: 4096,
848
+ description: "Maximum output tokens"
849
+ },
850
+ top_p: {
851
+ type: "number",
852
+ min: 0,
853
+ max: 1,
854
+ default: 1,
855
+ description: "Nucleus sampling"
856
+ },
857
+ top_k: {
858
+ type: "number",
859
+ min: 0,
860
+ default: 40,
861
+ description: "Top-K sampling"
862
+ },
863
+ frequency_penalty: {
864
+ type: "number",
865
+ min: -2,
866
+ max: 2,
867
+ default: 0,
868
+ description: "Penalize frequent tokens"
869
+ },
870
+ presence_penalty: {
871
+ type: "number",
872
+ min: -2,
873
+ max: 2,
874
+ default: 0,
875
+ description: "Penalize repeated topics"
876
+ },
320
877
  stop: { type: "string", description: "Stop sequences" },
321
878
  n: { type: "number", min: 1, default: 1, description: "Completions count" },
322
879
  seed: { type: "number", description: "Random seed" },
@@ -327,7 +884,33 @@ var PARAM_SPECS = {
327
884
  default: "medium",
328
885
  description: "Reasoning effort"
329
886
  }
330
- }
887
+ },
888
+ xai: OPENAI_COMPATIBLE_PARAM_SPECS,
889
+ groq: OPENAI_COMPATIBLE_PARAM_SPECS,
890
+ fal: {},
891
+ deepinfra: OPENAI_COMPATIBLE_PARAM_SPECS,
892
+ "black-forest-labs": {},
893
+ together: OPENAI_COMPATIBLE_PARAM_SPECS,
894
+ fireworks: OPENAI_COMPATIBLE_PARAM_SPECS,
895
+ deepseek: OPENAI_COMPATIBLE_PARAM_SPECS,
896
+ moonshotai: OPENAI_COMPATIBLE_PARAM_SPECS,
897
+ perplexity: OPENAI_COMPATIBLE_PARAM_SPECS,
898
+ alibaba: OPENAI_COMPATIBLE_PARAM_SPECS,
899
+ cerebras: OPENAI_COMPATIBLE_PARAM_SPECS,
900
+ replicate: {},
901
+ prodia: {},
902
+ luma: {},
903
+ bytedance: {},
904
+ kling: {},
905
+ elevenlabs: {},
906
+ assemblyai: {},
907
+ deepgram: {},
908
+ gladia: {},
909
+ lmnt: {},
910
+ hume: {},
911
+ revai: {},
912
+ baseten: OPENAI_COMPATIBLE_PARAM_SPECS,
913
+ huggingface: OPENAI_COMPATIBLE_PARAM_SPECS
331
914
  };
332
915
  function isReasoningModel(model) {
333
916
  const name = model.includes("/") ? model.split("/").pop() : model;
@@ -343,7 +926,13 @@ function detectGatewaySubProvider(model) {
343
926
  const slash = model.indexOf("/");
344
927
  if (slash < 1) return void 0;
345
928
  const prefix = model.slice(0, slash);
346
- const direct = ["openai", "anthropic", "google", "mistral", "cohere"];
929
+ const direct = [
930
+ "openai",
931
+ "anthropic",
932
+ "google",
933
+ "mistral",
934
+ "cohere"
935
+ ];
347
936
  return direct.find((p) => p === prefix);
348
937
  }
349
938
  var REASONING_MODEL_UNSUPPORTED = /* @__PURE__ */ new Set([
@@ -378,34 +967,117 @@ function bedrockSupportsCaching(model) {
378
967
  var CACHE_VALUES = {
379
968
  openai: void 0,
380
969
  // OpenAI auto-caches; no explicit param
970
+ azure: void 0,
381
971
  anthropic: "ephemeral",
382
972
  google: void 0,
383
973
  // Google uses explicit caching API, not a param
974
+ "google-vertex": void 0,
384
975
  mistral: void 0,
385
976
  cohere: void 0,
386
977
  bedrock: "ephemeral",
387
978
  // Supported for Claude models on Bedrock
388
979
  openrouter: void 0,
389
980
  // Depends on underlying provider
390
- vercel: void 0
981
+ vercel: void 0,
391
982
  // Depends on underlying provider
983
+ xai: void 0,
984
+ groq: void 0,
985
+ fal: void 0,
986
+ deepinfra: void 0,
987
+ "black-forest-labs": void 0,
988
+ together: void 0,
989
+ fireworks: void 0,
990
+ deepseek: void 0,
991
+ moonshotai: void 0,
992
+ perplexity: void 0,
993
+ alibaba: void 0,
994
+ cerebras: void 0,
995
+ replicate: void 0,
996
+ prodia: void 0,
997
+ luma: void 0,
998
+ bytedance: void 0,
999
+ kling: void 0,
1000
+ elevenlabs: void 0,
1001
+ assemblyai: void 0,
1002
+ deepgram: void 0,
1003
+ gladia: void 0,
1004
+ lmnt: void 0,
1005
+ hume: void 0,
1006
+ revai: void 0,
1007
+ baseten: void 0,
1008
+ huggingface: void 0
392
1009
  };
393
1010
  var CACHE_TTLS = {
394
1011
  openai: void 0,
1012
+ azure: void 0,
395
1013
  anthropic: ["5m", "1h"],
396
1014
  google: void 0,
1015
+ "google-vertex": void 0,
397
1016
  mistral: void 0,
398
1017
  cohere: void 0,
399
1018
  bedrock: ["5m", "1h"],
400
1019
  // Claude on Bedrock uses same TTLs as direct Anthropic
401
1020
  openrouter: void 0,
402
- vercel: void 0
1021
+ vercel: void 0,
1022
+ xai: void 0,
1023
+ groq: void 0,
1024
+ fal: void 0,
1025
+ deepinfra: void 0,
1026
+ "black-forest-labs": void 0,
1027
+ together: void 0,
1028
+ fireworks: void 0,
1029
+ deepseek: void 0,
1030
+ moonshotai: void 0,
1031
+ perplexity: void 0,
1032
+ alibaba: void 0,
1033
+ cerebras: void 0,
1034
+ replicate: void 0,
1035
+ prodia: void 0,
1036
+ luma: void 0,
1037
+ bytedance: void 0,
1038
+ kling: void 0,
1039
+ elevenlabs: void 0,
1040
+ assemblyai: void 0,
1041
+ deepgram: void 0,
1042
+ gladia: void 0,
1043
+ lmnt: void 0,
1044
+ hume: void 0,
1045
+ revai: void 0,
1046
+ baseten: void 0,
1047
+ huggingface: void 0
403
1048
  };
404
1049
  var DURATION_RE = /^\d+[mh]$/;
405
1050
 
1051
+ // src/parse.ts
1052
+ function parse(connectionString) {
1053
+ const url = new URL(connectionString);
1054
+ if (url.protocol !== "llm:") {
1055
+ throw new Error(
1056
+ `Invalid scheme: expected "llm://", got "${url.protocol}//"`
1057
+ );
1058
+ }
1059
+ const { host, alias: hostAlias } = resolveHostAlias(url.host);
1060
+ const model = url.pathname.replace(/^\//, "");
1061
+ const label = url.username || void 0;
1062
+ const apiKey = url.password || void 0;
1063
+ const params = {};
1064
+ for (const [key, value] of url.searchParams) {
1065
+ params[key] = value;
1066
+ }
1067
+ return {
1068
+ raw: connectionString,
1069
+ host,
1070
+ hostAlias,
1071
+ model,
1072
+ label,
1073
+ apiKey,
1074
+ params
1075
+ };
1076
+ }
1077
+
406
1078
  // src/normalize.ts
407
1079
  function normalize(config, options = {}) {
408
- const provider = detectProvider(config.host);
1080
+ const provider = (config.hostAlias ? providerFromHostAlias(config.hostAlias) : void 0) ?? detectProvider(config.host);
409
1081
  const subProvider = provider && isGatewayProvider(provider) ? detectGatewaySubProvider(config.model) : void 0;
410
1082
  const changes = [];
411
1083
  const params = {};
@@ -590,11 +1262,7 @@ function validate(connectionString, options = {}) {
590
1262
  }
591
1263
  let spec = specs[key];
592
1264
  if (subProvider && gatewayReverseMap && !spec) {
593
- const result = lookupSubProviderSpec(
594
- key,
595
- gatewayReverseMap,
596
- subProvider
597
- );
1265
+ const result = lookupSubProviderSpec(key, gatewayReverseMap, subProvider);
598
1266
  spec = result.spec;
599
1267
  }
600
1268
  if (!spec) continue;