llm-strings 1.1.1 → 1.2.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 (54) hide show
  1. package/README.md +117 -45
  2. package/dist/ai-sdk.cjs +831 -0
  3. package/dist/ai-sdk.cjs.map +1 -0
  4. package/dist/ai-sdk.d.cts +27 -0
  5. package/dist/ai-sdk.d.ts +27 -0
  6. package/dist/ai-sdk.js +465 -0
  7. package/dist/ai-sdk.js.map +1 -0
  8. package/dist/{chunk-MPIHGH6L.js → chunk-2ARD4TFU.js} +5 -4
  9. package/dist/chunk-2ARD4TFU.js.map +1 -0
  10. package/dist/{chunk-FCEV23OT.js → chunk-BCOUH7LH.js} +9 -3
  11. package/dist/chunk-BCOUH7LH.js.map +1 -0
  12. package/dist/{chunk-UYMVUTLV.js → chunk-RPXK2A7O.js} +5 -9
  13. package/dist/chunk-RPXK2A7O.js.map +1 -0
  14. package/dist/{chunk-XID353H7.js → chunk-W4NIQY7M.js} +412 -52
  15. package/dist/chunk-W4NIQY7M.js.map +1 -0
  16. package/dist/index.cjs +1032 -12
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +9 -4
  21. package/dist/normalize.cjs +370 -4
  22. package/dist/normalize.cjs.map +1 -1
  23. package/dist/normalize.d.cts +1 -1
  24. package/dist/normalize.d.ts +1 -1
  25. package/dist/normalize.js +2 -2
  26. package/dist/parse.cjs +129 -5
  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.ts → provider-core-BiAl8MCV.d.cts} +20 -1
  32. package/dist/{provider-core-DinpG40u.d.cts → provider-core-BiAl8MCV.d.ts} +20 -1
  33. package/dist/providers.cjs +1145 -90
  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 +379 -60
  38. package/dist/providers.js.map +1 -1
  39. package/dist/validate.cjs +1017 -6
  40. package/dist/validate.cjs.map +1 -1
  41. package/dist/validate.js +4 -4
  42. package/package.json +13 -2
  43. package/dist/chunk-FCEV23OT.js.map +0 -1
  44. package/dist/chunk-MGWGNZDJ.cjs +0 -116
  45. package/dist/chunk-MGWGNZDJ.cjs.map +0 -1
  46. package/dist/chunk-MPIHGH6L.js.map +0 -1
  47. package/dist/chunk-N6NVBE43.cjs +0 -37
  48. package/dist/chunk-N6NVBE43.cjs.map +0 -1
  49. package/dist/chunk-NSCBY4VD.cjs +0 -370
  50. package/dist/chunk-NSCBY4VD.cjs.map +0 -1
  51. package/dist/chunk-RSUXM42X.cjs +0 -180
  52. package/dist/chunk-RSUXM42X.cjs.map +0 -1
  53. package/dist/chunk-UYMVUTLV.js.map +0 -1
  54. package/dist/chunk-XID353H7.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,18 +1,1038 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
2
19
 
3
- var _chunkRSUXM42Xcjs = require('./chunk-RSUXM42X.cjs');
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ HOST_ALIASES: () => HOST_ALIASES,
24
+ build: () => build,
25
+ normalize: () => normalize,
26
+ parse: () => parse,
27
+ resolveHostAlias: () => resolveHostAlias,
28
+ validate: () => validate
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
4
31
 
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
+ anthropic: "api.anthropic.com",
39
+ google: "generativelanguage.googleapis.com",
40
+ aistudio: "generativelanguage.googleapis.com",
41
+ mistral: "api.mistral.ai",
42
+ cohere: "api.cohere.com",
43
+ bedrock: "bedrock-runtime.us-east-1.amazonaws.com",
44
+ openrouter: "openrouter.ai",
45
+ vercel: "gateway.ai.vercel.app",
46
+ alibaba: "dashscope-intl.aliyuncs.com",
47
+ alibabacloud: "dashscope-intl.aliyuncs.com",
48
+ dashscope: "dashscope-intl.aliyuncs.com",
49
+ fireworks: "api.fireworks.ai",
50
+ fireworksai: "api.fireworks.ai",
51
+ venice: "api.venice.ai",
52
+ parasail: "api.parasail.io",
53
+ deepinfra: "api.deepinfra.com",
54
+ atlascloud: "api.atlascloud.ai",
55
+ novita: "api.novita.ai",
56
+ novitaai: "api.novita.ai",
57
+ grok: "api.x.ai",
58
+ xai: "api.x.ai",
59
+ wandb: "api.inference.wandb.ai",
60
+ weightsandbiases: "api.inference.wandb.ai",
61
+ baidu: "qianfan.baidubce.com",
62
+ qianfan: "qianfan.baidubce.com",
63
+ vertex: "aiplatform.googleapis.com",
64
+ xiaomi: "api.xiaomimimo.com",
65
+ minimax: "api.minimax.io"
66
+ };
67
+ function readProcessEnv() {
68
+ return typeof process !== "undefined" && process.env ? process.env : {};
69
+ }
70
+ function normalizeHostValue(value) {
71
+ const trimmed = value.trim();
72
+ if (!trimmed) return trimmed;
73
+ try {
74
+ if (trimmed.includes("://")) {
75
+ return new URL(trimmed).host;
76
+ }
77
+ } catch {
78
+ }
79
+ return trimmed.replace(/^\/\//, "").split("/")[0] ?? trimmed;
80
+ }
81
+ function envHostOverride(alias, env) {
82
+ const upper = alias.toUpperCase();
83
+ const override = env[`LLM_STRINGS_${upper}_HOST`] ?? env[`LLM_STRINGS_HOST_${upper}`];
84
+ return override?.trim() ? override : void 0;
85
+ }
86
+ function resolveHostAlias(host, env = readProcessEnv()) {
87
+ const normalizedHost = host.toLowerCase();
88
+ if (!hasOwn(HOST_ALIASES, normalizedHost)) {
89
+ return { host };
90
+ }
91
+ const alias = normalizedHost;
92
+ const override = envHostOverride(alias, env);
93
+ return {
94
+ host: normalizeHostValue(override ?? HOST_ALIASES[alias]),
95
+ alias
96
+ };
97
+ }
98
+ function providerFromHostAlias(alias) {
99
+ const normalizedAlias = alias.toLowerCase();
100
+ if (hasOwn(PROVIDER_PARAMS, normalizedAlias)) {
101
+ return normalizedAlias;
102
+ }
103
+ return void 0;
104
+ }
105
+ function detectProvider(host) {
106
+ host = host.toLowerCase();
107
+ if (host.includes("openrouter")) return "openrouter";
108
+ if (host.includes("gateway.ai.vercel")) return "vercel";
109
+ if (host.includes("amazonaws") || host.includes("bedrock")) return "bedrock";
110
+ if (host.includes("openai")) return "openai";
111
+ if (host.includes("anthropic") || host.includes("claude")) return "anthropic";
112
+ if (host.includes("googleapis") || host.includes("google")) return "google";
113
+ if (host.includes("mistral")) return "mistral";
114
+ if (host.includes("cohere")) return "cohere";
115
+ return void 0;
116
+ }
117
+ var ALIASES = {
118
+ // temperature
119
+ temp: "temperature",
120
+ // max_tokens
121
+ max: "max_tokens",
122
+ max_out: "max_tokens",
123
+ max_output: "max_tokens",
124
+ max_output_tokens: "max_tokens",
125
+ max_completion_tokens: "max_tokens",
126
+ maxOutputTokens: "max_tokens",
127
+ maxTokens: "max_tokens",
128
+ // top_p
129
+ topp: "top_p",
130
+ topP: "top_p",
131
+ nucleus: "top_p",
132
+ // top_k
133
+ topk: "top_k",
134
+ topK: "top_k",
135
+ // frequency_penalty
136
+ freq: "frequency_penalty",
137
+ freq_penalty: "frequency_penalty",
138
+ frequencyPenalty: "frequency_penalty",
139
+ repetition_penalty: "frequency_penalty",
140
+ // presence_penalty
141
+ pres: "presence_penalty",
142
+ pres_penalty: "presence_penalty",
143
+ presencePenalty: "presence_penalty",
144
+ // stop
145
+ stop_sequences: "stop",
146
+ stopSequences: "stop",
147
+ stop_sequence: "stop",
148
+ // seed
149
+ random_seed: "seed",
150
+ randomSeed: "seed",
151
+ // n (completions count)
152
+ candidateCount: "n",
153
+ candidate_count: "n",
154
+ num_completions: "n",
155
+ // effort / reasoning
156
+ reasoning_effort: "effort",
157
+ reasoning: "effort",
158
+ // cache
159
+ cache_control: "cache",
160
+ cacheControl: "cache",
161
+ cachePoint: "cache",
162
+ cache_point: "cache"
163
+ };
164
+ var PROVIDER_PARAMS = {
165
+ openai: {
166
+ temperature: "temperature",
167
+ max_tokens: "max_tokens",
168
+ top_p: "top_p",
169
+ frequency_penalty: "frequency_penalty",
170
+ presence_penalty: "presence_penalty",
171
+ stop: "stop",
172
+ n: "n",
173
+ seed: "seed",
174
+ stream: "stream",
175
+ effort: "reasoning_effort"
176
+ },
177
+ anthropic: {
178
+ temperature: "temperature",
179
+ max_tokens: "max_tokens",
180
+ top_p: "top_p",
181
+ top_k: "top_k",
182
+ stop: "stop_sequences",
183
+ stream: "stream",
184
+ effort: "effort",
185
+ cache: "cache_control",
186
+ cache_ttl: "cache_ttl"
187
+ },
188
+ google: {
189
+ temperature: "temperature",
190
+ max_tokens: "maxOutputTokens",
191
+ top_p: "topP",
192
+ top_k: "topK",
193
+ frequency_penalty: "frequencyPenalty",
194
+ presence_penalty: "presencePenalty",
195
+ stop: "stopSequences",
196
+ n: "candidateCount",
197
+ stream: "stream",
198
+ seed: "seed",
199
+ responseMimeType: "responseMimeType",
200
+ responseSchema: "responseSchema"
201
+ },
202
+ mistral: {
203
+ temperature: "temperature",
204
+ max_tokens: "max_tokens",
205
+ top_p: "top_p",
206
+ frequency_penalty: "frequency_penalty",
207
+ presence_penalty: "presence_penalty",
208
+ stop: "stop",
209
+ n: "n",
210
+ seed: "random_seed",
211
+ stream: "stream",
212
+ safe_prompt: "safe_prompt",
213
+ min_tokens: "min_tokens"
214
+ },
215
+ cohere: {
216
+ temperature: "temperature",
217
+ max_tokens: "max_tokens",
218
+ top_p: "p",
219
+ top_k: "k",
220
+ frequency_penalty: "frequency_penalty",
221
+ presence_penalty: "presence_penalty",
222
+ stop: "stop_sequences",
223
+ stream: "stream",
224
+ seed: "seed"
225
+ },
226
+ bedrock: {
227
+ // Bedrock Converse API uses camelCase
228
+ temperature: "temperature",
229
+ max_tokens: "maxTokens",
230
+ top_p: "topP",
231
+ top_k: "topK",
232
+ // Claude models via additionalModelRequestFields
233
+ stop: "stopSequences",
234
+ stream: "stream",
235
+ cache: "cache_control",
236
+ cache_ttl: "cache_ttl"
237
+ },
238
+ openrouter: {
239
+ // OpenAI-compatible API with extra routing params
240
+ temperature: "temperature",
241
+ max_tokens: "max_tokens",
242
+ top_p: "top_p",
243
+ top_k: "top_k",
244
+ frequency_penalty: "frequency_penalty",
245
+ presence_penalty: "presence_penalty",
246
+ stop: "stop",
247
+ n: "n",
248
+ seed: "seed",
249
+ stream: "stream",
250
+ effort: "reasoning_effort"
251
+ },
252
+ vercel: {
253
+ // OpenAI-compatible gateway
254
+ temperature: "temperature",
255
+ max_tokens: "max_tokens",
256
+ top_p: "top_p",
257
+ top_k: "top_k",
258
+ frequency_penalty: "frequency_penalty",
259
+ presence_penalty: "presence_penalty",
260
+ stop: "stop",
261
+ n: "n",
262
+ seed: "seed",
263
+ stream: "stream",
264
+ effort: "reasoning_effort"
265
+ }
266
+ };
267
+ var PARAM_SPECS = {
268
+ openai: {
269
+ temperature: {
270
+ type: "number",
271
+ min: 0,
272
+ max: 2,
273
+ default: 0.7,
274
+ description: "Controls randomness"
275
+ },
276
+ max_tokens: {
277
+ type: "number",
278
+ min: 1,
279
+ default: 4096,
280
+ description: "Maximum output tokens"
281
+ },
282
+ top_p: {
283
+ type: "number",
284
+ min: 0,
285
+ max: 1,
286
+ default: 1,
287
+ description: "Nucleus sampling"
288
+ },
289
+ frequency_penalty: {
290
+ type: "number",
291
+ min: -2,
292
+ max: 2,
293
+ default: 0,
294
+ description: "Penalize frequent tokens"
295
+ },
296
+ presence_penalty: {
297
+ type: "number",
298
+ min: -2,
299
+ max: 2,
300
+ default: 0,
301
+ description: "Penalize repeated topics"
302
+ },
303
+ stop: { type: "string", description: "Stop sequences" },
304
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
305
+ seed: { type: "number", description: "Random seed" },
306
+ stream: { type: "boolean", default: false, description: "Stream response" },
307
+ reasoning_effort: {
308
+ type: "string",
309
+ values: ["none", "minimal", "low", "medium", "high", "xhigh"],
310
+ default: "medium",
311
+ description: "Reasoning effort"
312
+ }
313
+ },
314
+ anthropic: {
315
+ temperature: {
316
+ type: "number",
317
+ min: 0,
318
+ max: 1,
319
+ default: 0.7,
320
+ description: "Controls randomness"
321
+ },
322
+ max_tokens: {
323
+ type: "number",
324
+ min: 1,
325
+ default: 4096,
326
+ description: "Maximum output tokens"
327
+ },
328
+ top_p: {
329
+ type: "number",
330
+ min: 0,
331
+ max: 1,
332
+ default: 1,
333
+ description: "Nucleus sampling"
334
+ },
335
+ top_k: {
336
+ type: "number",
337
+ min: 0,
338
+ default: 40,
339
+ description: "Top-K sampling"
340
+ },
341
+ stop_sequences: { type: "string", description: "Stop sequences" },
342
+ stream: { type: "boolean", default: false, description: "Stream response" },
343
+ effort: {
344
+ type: "string",
345
+ values: ["low", "medium", "high", "max"],
346
+ default: "medium",
347
+ description: "Thinking effort"
348
+ },
349
+ cache_control: {
350
+ type: "string",
351
+ values: ["ephemeral"],
352
+ default: "ephemeral",
353
+ description: "Cache control"
354
+ },
355
+ cache_ttl: {
356
+ type: "string",
357
+ values: ["5m", "1h"],
358
+ default: "5m",
359
+ description: "Cache TTL"
360
+ }
361
+ },
362
+ google: {
363
+ temperature: {
364
+ type: "number",
365
+ min: 0,
366
+ max: 2,
367
+ default: 0.7,
368
+ description: "Controls randomness"
369
+ },
370
+ maxOutputTokens: {
371
+ type: "number",
372
+ min: 1,
373
+ default: 4096,
374
+ description: "Maximum output tokens"
375
+ },
376
+ topP: {
377
+ type: "number",
378
+ min: 0,
379
+ max: 1,
380
+ default: 1,
381
+ description: "Nucleus sampling"
382
+ },
383
+ topK: {
384
+ type: "number",
385
+ min: 0,
386
+ default: 40,
387
+ description: "Top-K sampling"
388
+ },
389
+ frequencyPenalty: {
390
+ type: "number",
391
+ min: -2,
392
+ max: 2,
393
+ default: 0,
394
+ description: "Penalize frequent tokens"
395
+ },
396
+ presencePenalty: {
397
+ type: "number",
398
+ min: -2,
399
+ max: 2,
400
+ default: 0,
401
+ description: "Penalize repeated topics"
402
+ },
403
+ stopSequences: { type: "string", description: "Stop sequences" },
404
+ candidateCount: {
405
+ type: "number",
406
+ min: 1,
407
+ default: 1,
408
+ description: "Candidate count"
409
+ },
410
+ stream: { type: "boolean", default: false, description: "Stream response" },
411
+ seed: { type: "number", description: "Random seed" },
412
+ responseMimeType: { type: "string", description: "Response MIME type" },
413
+ responseSchema: { type: "string", description: "Response schema" }
414
+ },
415
+ mistral: {
416
+ temperature: {
417
+ type: "number",
418
+ min: 0,
419
+ max: 1,
420
+ default: 0.7,
421
+ description: "Controls randomness"
422
+ },
423
+ max_tokens: {
424
+ type: "number",
425
+ min: 1,
426
+ default: 4096,
427
+ description: "Maximum output tokens"
428
+ },
429
+ top_p: {
430
+ type: "number",
431
+ min: 0,
432
+ max: 1,
433
+ default: 1,
434
+ description: "Nucleus sampling"
435
+ },
436
+ frequency_penalty: {
437
+ type: "number",
438
+ min: -2,
439
+ max: 2,
440
+ default: 0,
441
+ description: "Penalize frequent tokens"
442
+ },
443
+ presence_penalty: {
444
+ type: "number",
445
+ min: -2,
446
+ max: 2,
447
+ default: 0,
448
+ description: "Penalize repeated topics"
449
+ },
450
+ stop: { type: "string", description: "Stop sequences" },
451
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
452
+ random_seed: { type: "number", description: "Random seed" },
453
+ stream: { type: "boolean", default: false, description: "Stream response" },
454
+ safe_prompt: {
455
+ type: "boolean",
456
+ default: false,
457
+ description: "Enable safe prompt"
458
+ },
459
+ min_tokens: {
460
+ type: "number",
461
+ min: 0,
462
+ default: 0,
463
+ description: "Minimum tokens"
464
+ }
465
+ },
466
+ cohere: {
467
+ temperature: {
468
+ type: "number",
469
+ min: 0,
470
+ max: 1,
471
+ default: 0.7,
472
+ description: "Controls randomness"
473
+ },
474
+ max_tokens: {
475
+ type: "number",
476
+ min: 1,
477
+ default: 4096,
478
+ description: "Maximum output tokens"
479
+ },
480
+ p: {
481
+ type: "number",
482
+ min: 0,
483
+ max: 1,
484
+ default: 1,
485
+ description: "Nucleus sampling (p)"
486
+ },
487
+ k: {
488
+ type: "number",
489
+ min: 0,
490
+ max: 500,
491
+ default: 40,
492
+ description: "Top-K sampling (k)"
493
+ },
494
+ frequency_penalty: {
495
+ type: "number",
496
+ min: 0,
497
+ max: 1,
498
+ default: 0,
499
+ description: "Penalize frequent tokens"
500
+ },
501
+ presence_penalty: {
502
+ type: "number",
503
+ min: 0,
504
+ max: 1,
505
+ default: 0,
506
+ description: "Penalize repeated topics"
507
+ },
508
+ stop_sequences: { type: "string", description: "Stop sequences" },
509
+ stream: { type: "boolean", default: false, description: "Stream response" },
510
+ seed: { type: "number", description: "Random seed" }
511
+ },
512
+ bedrock: {
513
+ // Converse API inferenceConfig params
514
+ temperature: {
515
+ type: "number",
516
+ min: 0,
517
+ max: 1,
518
+ default: 0.7,
519
+ description: "Controls randomness"
520
+ },
521
+ maxTokens: {
522
+ type: "number",
523
+ min: 1,
524
+ default: 4096,
525
+ description: "Maximum output tokens"
526
+ },
527
+ topP: {
528
+ type: "number",
529
+ min: 0,
530
+ max: 1,
531
+ default: 1,
532
+ description: "Nucleus sampling"
533
+ },
534
+ topK: {
535
+ type: "number",
536
+ min: 0,
537
+ default: 40,
538
+ description: "Top-K sampling"
539
+ },
540
+ stopSequences: { type: "string", description: "Stop sequences" },
541
+ stream: { type: "boolean", default: false, description: "Stream response" },
542
+ cache_control: {
543
+ type: "string",
544
+ values: ["ephemeral"],
545
+ default: "ephemeral",
546
+ description: "Cache control"
547
+ },
548
+ cache_ttl: {
549
+ type: "string",
550
+ values: ["5m", "1h"],
551
+ default: "5m",
552
+ description: "Cache TTL"
553
+ }
554
+ },
555
+ openrouter: {
556
+ // Loose validation — proxies to many providers with varying ranges
557
+ temperature: {
558
+ type: "number",
559
+ min: 0,
560
+ max: 2,
561
+ default: 0.7,
562
+ description: "Controls randomness"
563
+ },
564
+ max_tokens: {
565
+ type: "number",
566
+ min: 1,
567
+ default: 4096,
568
+ description: "Maximum output tokens"
569
+ },
570
+ top_p: {
571
+ type: "number",
572
+ min: 0,
573
+ max: 1,
574
+ default: 1,
575
+ description: "Nucleus sampling"
576
+ },
577
+ top_k: {
578
+ type: "number",
579
+ min: 0,
580
+ default: 40,
581
+ description: "Top-K sampling"
582
+ },
583
+ frequency_penalty: {
584
+ type: "number",
585
+ min: -2,
586
+ max: 2,
587
+ default: 0,
588
+ description: "Penalize frequent tokens"
589
+ },
590
+ presence_penalty: {
591
+ type: "number",
592
+ min: -2,
593
+ max: 2,
594
+ default: 0,
595
+ description: "Penalize repeated topics"
596
+ },
597
+ stop: { type: "string", description: "Stop sequences" },
598
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
599
+ seed: { type: "number", description: "Random seed" },
600
+ stream: { type: "boolean", default: false, description: "Stream response" },
601
+ reasoning_effort: {
602
+ type: "string",
603
+ values: ["none", "minimal", "low", "medium", "high", "xhigh"],
604
+ default: "medium",
605
+ description: "Reasoning effort"
606
+ }
607
+ },
608
+ vercel: {
609
+ // Loose validation — proxies to many providers with varying ranges
610
+ temperature: {
611
+ type: "number",
612
+ min: 0,
613
+ max: 2,
614
+ default: 0.7,
615
+ description: "Controls randomness"
616
+ },
617
+ max_tokens: {
618
+ type: "number",
619
+ min: 1,
620
+ default: 4096,
621
+ description: "Maximum output tokens"
622
+ },
623
+ top_p: {
624
+ type: "number",
625
+ min: 0,
626
+ max: 1,
627
+ default: 1,
628
+ description: "Nucleus sampling"
629
+ },
630
+ top_k: {
631
+ type: "number",
632
+ min: 0,
633
+ default: 40,
634
+ description: "Top-K sampling"
635
+ },
636
+ frequency_penalty: {
637
+ type: "number",
638
+ min: -2,
639
+ max: 2,
640
+ default: 0,
641
+ description: "Penalize frequent tokens"
642
+ },
643
+ presence_penalty: {
644
+ type: "number",
645
+ min: -2,
646
+ max: 2,
647
+ default: 0,
648
+ description: "Penalize repeated topics"
649
+ },
650
+ stop: { type: "string", description: "Stop sequences" },
651
+ n: { type: "number", min: 1, default: 1, description: "Completions count" },
652
+ seed: { type: "number", description: "Random seed" },
653
+ stream: { type: "boolean", default: false, description: "Stream response" },
654
+ reasoning_effort: {
655
+ type: "string",
656
+ values: ["none", "minimal", "low", "medium", "high", "xhigh"],
657
+ default: "medium",
658
+ description: "Reasoning effort"
659
+ }
660
+ }
661
+ };
662
+ function isReasoningModel(model) {
663
+ const name = model.includes("/") ? model.split("/").pop() : model;
664
+ return /^o[134]/.test(name);
665
+ }
666
+ function canHostOpenAIModels(provider) {
667
+ return provider === "openai" || provider === "openrouter" || provider === "vercel";
668
+ }
669
+ function isGatewayProvider(provider) {
670
+ return provider === "openrouter" || provider === "vercel";
671
+ }
672
+ function detectGatewaySubProvider(model) {
673
+ const slash = model.indexOf("/");
674
+ if (slash < 1) return void 0;
675
+ const prefix = model.slice(0, slash);
676
+ const direct = [
677
+ "openai",
678
+ "anthropic",
679
+ "google",
680
+ "mistral",
681
+ "cohere"
682
+ ];
683
+ return direct.find((p) => p === prefix);
684
+ }
685
+ var REASONING_MODEL_UNSUPPORTED = /* @__PURE__ */ new Set([
686
+ "temperature",
687
+ "top_p",
688
+ "frequency_penalty",
689
+ "presence_penalty",
690
+ "n"
691
+ ]);
692
+ function detectBedrockModelFamily(model) {
693
+ const parts = model.split(".");
694
+ let prefix = parts[0];
695
+ if (["us", "eu", "apac", "global"].includes(prefix) && parts.length > 1) {
696
+ prefix = parts[1];
697
+ }
698
+ const families = [
699
+ "anthropic",
700
+ "meta",
701
+ "amazon",
702
+ "mistral",
703
+ "cohere",
704
+ "ai21"
705
+ ];
706
+ return families.find((f) => prefix === f);
707
+ }
708
+ function bedrockSupportsCaching(model) {
709
+ const family = detectBedrockModelFamily(model);
710
+ if (family === "anthropic") return true;
711
+ if (family === "amazon" && model.includes("nova")) return true;
712
+ return false;
713
+ }
714
+ var CACHE_VALUES = {
715
+ openai: void 0,
716
+ // OpenAI auto-caches; no explicit param
717
+ anthropic: "ephemeral",
718
+ google: void 0,
719
+ // Google uses explicit caching API, not a param
720
+ mistral: void 0,
721
+ cohere: void 0,
722
+ bedrock: "ephemeral",
723
+ // Supported for Claude models on Bedrock
724
+ openrouter: void 0,
725
+ // Depends on underlying provider
726
+ vercel: void 0
727
+ // Depends on underlying provider
728
+ };
729
+ var CACHE_TTLS = {
730
+ openai: void 0,
731
+ anthropic: ["5m", "1h"],
732
+ google: void 0,
733
+ mistral: void 0,
734
+ cohere: void 0,
735
+ bedrock: ["5m", "1h"],
736
+ // Claude on Bedrock uses same TTLs as direct Anthropic
737
+ openrouter: void 0,
738
+ vercel: void 0
739
+ };
740
+ var DURATION_RE = /^\d+[mh]$/;
5
741
 
6
- var _chunkMGWGNZDJcjs = require('./chunk-MGWGNZDJ.cjs');
742
+ // src/parse.ts
743
+ function parse(connectionString) {
744
+ const url = new URL(connectionString);
745
+ if (url.protocol !== "llm:") {
746
+ throw new Error(
747
+ `Invalid scheme: expected "llm://", got "${url.protocol}//"`
748
+ );
749
+ }
750
+ const { host, alias: hostAlias } = resolveHostAlias(url.host);
751
+ const model = url.pathname.replace(/^\//, "");
752
+ const label = url.username || void 0;
753
+ const apiKey = url.password || void 0;
754
+ const params = {};
755
+ for (const [key, value] of url.searchParams) {
756
+ params[key] = value;
757
+ }
758
+ return {
759
+ raw: connectionString,
760
+ host,
761
+ hostAlias,
762
+ model,
763
+ label,
764
+ apiKey,
765
+ params
766
+ };
767
+ }
768
+ function build(config) {
769
+ const { host } = resolveHostAlias(config.host);
770
+ const auth = config.label || config.apiKey ? `${config.label ?? ""}${config.apiKey ? `:${config.apiKey}` : ""}@` : "";
771
+ const query = new URLSearchParams(config.params).toString();
772
+ const qs = query ? `?${query}` : "";
773
+ return `llm://${auth}${host}/${config.model}${qs}`;
774
+ }
7
775
 
776
+ // src/normalize.ts
777
+ function normalize(config, options = {}) {
778
+ const provider = (config.hostAlias ? providerFromHostAlias(config.hostAlias) : void 0) ?? detectProvider(config.host);
779
+ const subProvider = provider && isGatewayProvider(provider) ? detectGatewaySubProvider(config.model) : void 0;
780
+ const changes = [];
781
+ const params = {};
782
+ for (const [rawKey, value] of Object.entries(config.params)) {
783
+ let key = rawKey;
784
+ if (ALIASES[key]) {
785
+ const canonical = ALIASES[key];
786
+ if (options.verbose) {
787
+ changes.push({
788
+ from: key,
789
+ to: canonical,
790
+ value,
791
+ reason: `alias: "${key}" \u2192 "${canonical}"`
792
+ });
793
+ }
794
+ key = canonical;
795
+ }
796
+ if (key === "cache" && provider) {
797
+ let cacheValue = CACHE_VALUES[provider];
798
+ if (provider === "bedrock" && !bedrockSupportsCaching(config.model)) {
799
+ cacheValue = void 0;
800
+ }
801
+ if (!cacheValue) {
802
+ if (options.verbose) {
803
+ changes.push({
804
+ from: "cache",
805
+ to: "(dropped)",
806
+ value,
807
+ reason: `${provider} does not use a cache param for this model (caching is automatic or unsupported)`
808
+ });
809
+ }
810
+ continue;
811
+ }
812
+ const isBool = value === "true" || value === "1" || value === "yes";
813
+ const isDuration = DURATION_RE.test(value);
814
+ if (isBool || isDuration) {
815
+ const providerKey = PROVIDER_PARAMS[provider]?.["cache"] ?? "cache";
816
+ if (options.verbose) {
817
+ changes.push({
818
+ from: "cache",
819
+ to: providerKey,
820
+ value: cacheValue,
821
+ reason: `cache=${value} \u2192 ${providerKey}=${cacheValue} for ${provider}`
822
+ });
823
+ }
824
+ params[providerKey] = cacheValue;
825
+ if (isDuration && CACHE_TTLS[provider]) {
826
+ if (options.verbose) {
827
+ changes.push({
828
+ from: "cache",
829
+ to: "cache_ttl",
830
+ value,
831
+ reason: `cache=${value} \u2192 cache_ttl=${value} for ${provider}`
832
+ });
833
+ }
834
+ params["cache_ttl"] = value;
835
+ }
836
+ continue;
837
+ }
838
+ }
839
+ if (provider && PROVIDER_PARAMS[provider]) {
840
+ const providerKey = PROVIDER_PARAMS[provider][key];
841
+ if (providerKey && providerKey !== key) {
842
+ if (options.verbose) {
843
+ changes.push({
844
+ from: key,
845
+ to: providerKey,
846
+ value,
847
+ reason: `${provider} uses "${providerKey}" instead of "${key}"`
848
+ });
849
+ }
850
+ key = providerKey;
851
+ }
852
+ }
853
+ if (provider && canHostOpenAIModels(provider) && isReasoningModel(config.model) && key === "max_tokens") {
854
+ if (options.verbose) {
855
+ changes.push({
856
+ from: "max_tokens",
857
+ to: "max_completion_tokens",
858
+ value,
859
+ reason: "OpenAI reasoning models use max_completion_tokens instead of max_tokens"
860
+ });
861
+ }
862
+ key = "max_completion_tokens";
863
+ }
864
+ params[key] = value;
865
+ }
866
+ return {
867
+ config: { ...config, params },
868
+ provider,
869
+ subProvider,
870
+ changes
871
+ };
872
+ }
8
873
 
9
-
10
- var _chunkN6NVBE43cjs = require('./chunk-N6NVBE43.cjs');
11
- require('./chunk-NSCBY4VD.cjs');
12
-
13
-
14
-
15
-
16
-
17
- exports.build = _chunkN6NVBE43cjs.build; exports.normalize = _chunkMGWGNZDJcjs.normalize; exports.parse = _chunkN6NVBE43cjs.parse; exports.validate = _chunkRSUXM42Xcjs.validate;
874
+ // src/validate.ts
875
+ function buildReverseParamMap(provider) {
876
+ const map = {};
877
+ for (const [canonical, specific] of Object.entries(
878
+ PROVIDER_PARAMS[provider]
879
+ )) {
880
+ map[specific] = canonical;
881
+ }
882
+ return map;
883
+ }
884
+ function lookupSubProviderSpec(gatewayParamName, gatewayReverseMap, subProvider) {
885
+ const canonical = gatewayReverseMap[gatewayParamName] ?? gatewayParamName;
886
+ const subProviderKey = PROVIDER_PARAMS[subProvider]?.[canonical];
887
+ if (!subProviderKey) return { spec: void 0, canonical };
888
+ return { spec: PARAM_SPECS[subProvider]?.[subProviderKey], canonical };
889
+ }
890
+ function buildSubProviderKnownParams(gateway, subProvider) {
891
+ const known = /* @__PURE__ */ new Set();
892
+ const subProviderCanonicals = new Set(
893
+ Object.keys(PROVIDER_PARAMS[subProvider])
894
+ );
895
+ for (const [canonical, gatewaySpecific] of Object.entries(
896
+ PROVIDER_PARAMS[gateway]
897
+ )) {
898
+ if (subProviderCanonicals.has(canonical)) {
899
+ known.add(gatewaySpecific);
900
+ }
901
+ }
902
+ return known;
903
+ }
904
+ function validate(connectionString, options = {}) {
905
+ const parsed = parse(connectionString);
906
+ const { config, provider, subProvider } = normalize(parsed);
907
+ const issues = [];
908
+ if (!provider) {
909
+ issues.push({
910
+ param: "host",
911
+ value: config.host,
912
+ message: `Unknown provider for host "${config.host}". Validation skipped.`,
913
+ severity: options.strict ? "error" : "warning"
914
+ });
915
+ return issues;
916
+ }
917
+ const effectiveProvider = subProvider ?? provider;
918
+ const specs = PARAM_SPECS[effectiveProvider];
919
+ const gatewayReverseMap = subProvider ? buildReverseParamMap(provider) : void 0;
920
+ const knownParams = subProvider ? buildSubProviderKnownParams(provider, subProvider) : new Set(Object.values(PROVIDER_PARAMS[provider]));
921
+ for (const [key, value] of Object.entries(config.params)) {
922
+ if (canHostOpenAIModels(provider) && isReasoningModel(config.model) && REASONING_MODEL_UNSUPPORTED.has(key)) {
923
+ issues.push({
924
+ param: key,
925
+ value,
926
+ message: `"${key}" is not supported by OpenAI reasoning model "${config.model}". Use "reasoning_effort" instead of temperature for controlling output.`,
927
+ severity: "error"
928
+ });
929
+ continue;
930
+ }
931
+ if (provider === "bedrock") {
932
+ const family = detectBedrockModelFamily(config.model);
933
+ if (key === "topK" && family && family !== "anthropic" && family !== "cohere" && family !== "mistral") {
934
+ issues.push({
935
+ param: key,
936
+ value,
937
+ message: `"topK" is not supported by ${family} models on Bedrock.`,
938
+ severity: "error"
939
+ });
940
+ continue;
941
+ }
942
+ if (key === "cache_control" && !bedrockSupportsCaching(config.model)) {
943
+ issues.push({
944
+ param: key,
945
+ value,
946
+ message: `Prompt caching is only supported for Anthropic Claude and Amazon Nova models on Bedrock, not ${family ?? "unknown"} models.`,
947
+ severity: "error"
948
+ });
949
+ continue;
950
+ }
951
+ }
952
+ if (!knownParams.has(key) && !specs[key]) {
953
+ issues.push({
954
+ param: key,
955
+ value,
956
+ message: `Unknown param "${key}" for ${effectiveProvider}.`,
957
+ severity: options.strict ? "error" : "warning"
958
+ });
959
+ continue;
960
+ }
961
+ let spec = specs[key];
962
+ if (subProvider && gatewayReverseMap && !spec) {
963
+ const result = lookupSubProviderSpec(key, gatewayReverseMap, subProvider);
964
+ spec = result.spec;
965
+ }
966
+ if (!spec) continue;
967
+ if ((effectiveProvider === "anthropic" || provider === "bedrock" && detectBedrockModelFamily(config.model) === "anthropic") && (key === "temperature" || key === "top_p" || key === "topP")) {
968
+ const otherKey = key === "temperature" ? provider === "bedrock" ? "topP" : "top_p" : "temperature";
969
+ if (key === "temperature" && config.params[otherKey] !== void 0) {
970
+ issues.push({
971
+ param: key,
972
+ value,
973
+ message: `Cannot specify both "temperature" and "${otherKey}" for Anthropic models.`,
974
+ severity: "error"
975
+ });
976
+ }
977
+ }
978
+ if (spec.type === "number") {
979
+ const num = Number(value);
980
+ if (isNaN(num)) {
981
+ issues.push({
982
+ param: key,
983
+ value,
984
+ message: `"${key}" should be a number, got "${value}".`,
985
+ severity: "error"
986
+ });
987
+ continue;
988
+ }
989
+ if (spec.min !== void 0 && num < spec.min) {
990
+ issues.push({
991
+ param: key,
992
+ value,
993
+ message: `"${key}" must be >= ${spec.min}, got ${num}.`,
994
+ severity: "error"
995
+ });
996
+ }
997
+ if (spec.max !== void 0 && num > spec.max) {
998
+ issues.push({
999
+ param: key,
1000
+ value,
1001
+ message: `"${key}" must be <= ${spec.max}, got ${num}.`,
1002
+ severity: "error"
1003
+ });
1004
+ }
1005
+ }
1006
+ if (spec.type === "boolean") {
1007
+ if (!["true", "false", "0", "1"].includes(value)) {
1008
+ issues.push({
1009
+ param: key,
1010
+ value,
1011
+ message: `"${key}" should be a boolean (true/false), got "${value}".`,
1012
+ severity: "error"
1013
+ });
1014
+ }
1015
+ }
1016
+ if (spec.type === "string" && spec.values) {
1017
+ if (!spec.values.includes(value)) {
1018
+ issues.push({
1019
+ param: key,
1020
+ value,
1021
+ message: `"${key}" must be one of [${spec.values.join(", ")}], got "${value}".`,
1022
+ severity: "error"
1023
+ });
1024
+ }
1025
+ }
1026
+ }
1027
+ return issues;
1028
+ }
1029
+ // Annotate the CommonJS export names for ESM import in node:
1030
+ 0 && (module.exports = {
1031
+ HOST_ALIASES,
1032
+ build,
1033
+ normalize,
1034
+ parse,
1035
+ resolveHostAlias,
1036
+ validate
1037
+ });
18
1038
  //# sourceMappingURL=index.cjs.map