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