llm-strings 1.0.0 → 1.1.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 +87 -12
  2. package/dist/chunk-6P5GSSNW.js +176 -0
  3. package/dist/chunk-6P5GSSNW.js.map +1 -0
  4. package/dist/chunk-FCEV23OT.js +37 -0
  5. package/dist/chunk-FCEV23OT.js.map +1 -0
  6. package/dist/chunk-MGWGNZDJ.cjs +116 -0
  7. package/dist/chunk-MGWGNZDJ.cjs.map +1 -0
  8. package/dist/chunk-MPIHGH6L.js +116 -0
  9. package/dist/chunk-MPIHGH6L.js.map +1 -0
  10. package/dist/chunk-N6NVBE43.cjs +37 -0
  11. package/dist/chunk-N6NVBE43.cjs.map +1 -0
  12. package/dist/chunk-NSCBY4VD.cjs +370 -0
  13. package/dist/chunk-NSCBY4VD.cjs.map +1 -0
  14. package/dist/chunk-RR3VXIW2.cjs +176 -0
  15. package/dist/chunk-RR3VXIW2.cjs.map +1 -0
  16. package/dist/chunk-RSUXM42X.cjs +180 -0
  17. package/dist/chunk-RSUXM42X.cjs.map +1 -0
  18. package/dist/chunk-UYMVUTLV.js +180 -0
  19. package/dist/chunk-UYMVUTLV.js.map +1 -0
  20. package/dist/chunk-XID353H7.js +370 -0
  21. package/dist/chunk-XID353H7.js.map +1 -0
  22. package/dist/index.cjs +46 -811
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +5 -140
  25. package/dist/index.d.ts +5 -140
  26. package/dist/index.js +29 -753
  27. package/dist/index.js.map +1 -1
  28. package/dist/normalize.cjs +8 -0
  29. package/dist/normalize.cjs.map +1 -0
  30. package/dist/normalize.d.cts +33 -0
  31. package/dist/normalize.d.ts +33 -0
  32. package/dist/normalize.js +8 -0
  33. package/dist/normalize.js.map +1 -0
  34. package/dist/parse.cjs +9 -0
  35. package/dist/parse.cjs.map +1 -0
  36. package/dist/parse.d.cts +32 -0
  37. package/dist/parse.d.ts +32 -0
  38. package/dist/parse.js +9 -0
  39. package/dist/parse.js.map +1 -0
  40. package/dist/provider-core-BUaKKLpd.d.cts +53 -0
  41. package/dist/provider-core-BUaKKLpd.d.ts +53 -0
  42. package/dist/providers.cjs +41 -0
  43. package/dist/providers.cjs.map +1 -0
  44. package/dist/providers.d.cts +34 -0
  45. package/dist/providers.d.ts +34 -0
  46. package/dist/providers.js +41 -0
  47. package/dist/providers.js.map +1 -0
  48. package/dist/validate.cjs +10 -0
  49. package/dist/validate.cjs.map +1 -0
  50. package/dist/validate.d.cts +21 -0
  51. package/dist/validate.d.ts +21 -0
  52. package/dist/validate.js +10 -0
  53. package/dist/validate.js.map +1 -0
  54. package/package.json +33 -1
package/dist/index.js CHANGED
@@ -1,756 +1,30 @@
1
- // src/parse.ts
2
- function parse(connectionString) {
3
- const url = new URL(connectionString);
4
- if (url.protocol !== "llm:") {
5
- throw new Error(
6
- `Invalid scheme: expected "llm://", got "${url.protocol}//"`
7
- );
8
- }
9
- const host = url.hostname;
10
- const model = url.pathname.replace(/^\//, "");
11
- const label = url.username || void 0;
12
- const apiKey = url.password || void 0;
13
- const params = {};
14
- for (const [key, value] of url.searchParams) {
15
- params[key] = value;
16
- }
17
- return {
18
- raw: connectionString,
19
- host,
20
- model,
21
- label,
22
- apiKey,
23
- params
24
- };
25
- }
26
- function build(config) {
27
- const auth = config.label || config.apiKey ? `${config.label ?? ""}${config.apiKey ? `:${config.apiKey}` : ""}@` : "";
28
- const query = new URLSearchParams(config.params).toString();
29
- const qs = query ? `?${query}` : "";
30
- return `llm://${auth}${config.host}/${config.model}${qs}`;
31
- }
32
-
33
- // src/providers.ts
34
- function detectProvider(host) {
35
- if (host.includes("openrouter")) return "openrouter";
36
- if (host.includes("gateway.ai.vercel")) return "vercel";
37
- if (host.includes("amazonaws") || host.includes("bedrock")) return "bedrock";
38
- if (host.includes("openai")) return "openai";
39
- if (host.includes("anthropic") || host.includes("claude")) return "anthropic";
40
- if (host.includes("googleapis") || host.includes("google")) return "google";
41
- if (host.includes("mistral")) return "mistral";
42
- if (host.includes("cohere")) return "cohere";
43
- return void 0;
44
- }
45
- var ALIASES = {
46
- // temperature
47
- temp: "temperature",
48
- // max_tokens
49
- max: "max_tokens",
50
- max_out: "max_tokens",
51
- max_output: "max_tokens",
52
- max_output_tokens: "max_tokens",
53
- max_completion_tokens: "max_tokens",
54
- maxOutputTokens: "max_tokens",
55
- maxTokens: "max_tokens",
56
- // top_p
57
- topp: "top_p",
58
- topP: "top_p",
59
- nucleus: "top_p",
60
- // top_k
61
- topk: "top_k",
62
- topK: "top_k",
63
- // frequency_penalty
64
- freq: "frequency_penalty",
65
- freq_penalty: "frequency_penalty",
66
- frequencyPenalty: "frequency_penalty",
67
- repetition_penalty: "frequency_penalty",
68
- // presence_penalty
69
- pres: "presence_penalty",
70
- pres_penalty: "presence_penalty",
71
- presencePenalty: "presence_penalty",
72
- // stop
73
- stop_sequences: "stop",
74
- stopSequences: "stop",
75
- stop_sequence: "stop",
76
- // seed
77
- random_seed: "seed",
78
- randomSeed: "seed",
79
- // n (completions count)
80
- candidateCount: "n",
81
- candidate_count: "n",
82
- num_completions: "n",
83
- // effort / reasoning
84
- reasoning_effort: "effort",
85
- reasoning: "effort",
86
- // cache
87
- cache_control: "cache",
88
- cacheControl: "cache",
89
- cachePoint: "cache",
90
- cache_point: "cache"
91
- };
92
- var PROVIDER_PARAMS = {
93
- openai: {
94
- temperature: "temperature",
95
- max_tokens: "max_tokens",
96
- top_p: "top_p",
97
- frequency_penalty: "frequency_penalty",
98
- presence_penalty: "presence_penalty",
99
- stop: "stop",
100
- n: "n",
101
- seed: "seed",
102
- stream: "stream",
103
- effort: "reasoning_effort"
104
- },
105
- anthropic: {
106
- temperature: "temperature",
107
- max_tokens: "max_tokens",
108
- top_p: "top_p",
109
- top_k: "top_k",
110
- stop: "stop_sequences",
111
- stream: "stream",
112
- effort: "effort",
113
- cache: "cache_control",
114
- cache_ttl: "cache_ttl"
115
- },
116
- google: {
117
- temperature: "temperature",
118
- max_tokens: "maxOutputTokens",
119
- top_p: "topP",
120
- top_k: "topK",
121
- frequency_penalty: "frequencyPenalty",
122
- presence_penalty: "presencePenalty",
123
- stop: "stopSequences",
124
- n: "candidateCount",
125
- stream: "stream",
126
- seed: "seed",
127
- responseMimeType: "responseMimeType",
128
- responseSchema: "responseSchema"
129
- },
130
- mistral: {
131
- temperature: "temperature",
132
- max_tokens: "max_tokens",
133
- top_p: "top_p",
134
- frequency_penalty: "frequency_penalty",
135
- presence_penalty: "presence_penalty",
136
- stop: "stop",
137
- n: "n",
138
- seed: "random_seed",
139
- stream: "stream",
140
- safe_prompt: "safe_prompt",
141
- min_tokens: "min_tokens"
142
- },
143
- cohere: {
144
- temperature: "temperature",
145
- max_tokens: "max_tokens",
146
- top_p: "p",
147
- top_k: "k",
148
- frequency_penalty: "frequency_penalty",
149
- presence_penalty: "presence_penalty",
150
- stop: "stop_sequences",
151
- stream: "stream",
152
- seed: "seed"
153
- },
154
- bedrock: {
155
- // Bedrock Converse API uses camelCase
156
- temperature: "temperature",
157
- max_tokens: "maxTokens",
158
- top_p: "topP",
159
- top_k: "topK",
160
- // Claude models via additionalModelRequestFields
161
- stop: "stopSequences",
162
- stream: "stream",
163
- cache: "cache_control",
164
- cache_ttl: "cache_ttl"
165
- },
166
- openrouter: {
167
- // OpenAI-compatible API with extra routing params
168
- temperature: "temperature",
169
- max_tokens: "max_tokens",
170
- top_p: "top_p",
171
- top_k: "top_k",
172
- frequency_penalty: "frequency_penalty",
173
- presence_penalty: "presence_penalty",
174
- stop: "stop",
175
- n: "n",
176
- seed: "seed",
177
- stream: "stream",
178
- effort: "reasoning_effort"
179
- },
180
- vercel: {
181
- // OpenAI-compatible gateway
182
- temperature: "temperature",
183
- max_tokens: "max_tokens",
184
- top_p: "top_p",
185
- top_k: "top_k",
186
- frequency_penalty: "frequency_penalty",
187
- presence_penalty: "presence_penalty",
188
- stop: "stop",
189
- n: "n",
190
- seed: "seed",
191
- stream: "stream",
192
- effort: "reasoning_effort"
193
- }
194
- };
195
- var PARAM_SPECS = {
196
- openai: {
197
- temperature: { type: "number", min: 0, max: 2 },
198
- max_tokens: { type: "number", min: 1 },
199
- top_p: { type: "number", min: 0, max: 1 },
200
- frequency_penalty: { type: "number", min: -2, max: 2 },
201
- presence_penalty: { type: "number", min: -2, max: 2 },
202
- stop: { type: "string" },
203
- n: { type: "number", min: 1 },
204
- seed: { type: "number" },
205
- stream: { type: "boolean" },
206
- reasoning_effort: {
207
- type: "string",
208
- values: ["none", "minimal", "low", "medium", "high", "xhigh"]
209
- }
210
- },
211
- anthropic: {
212
- temperature: { type: "number", min: 0, max: 1 },
213
- max_tokens: { type: "number", min: 1 },
214
- top_p: { type: "number", min: 0, max: 1 },
215
- top_k: { type: "number", min: 0 },
216
- stop_sequences: { type: "string" },
217
- stream: { type: "boolean" },
218
- effort: { type: "string", values: ["low", "medium", "high", "max"] },
219
- cache_control: { type: "string", values: ["ephemeral"] },
220
- cache_ttl: { type: "string", values: ["5m", "1h"] }
221
- },
222
- google: {
223
- temperature: { type: "number", min: 0, max: 2 },
224
- maxOutputTokens: { type: "number", min: 1 },
225
- topP: { type: "number", min: 0, max: 1 },
226
- topK: { type: "number", min: 0 },
227
- frequencyPenalty: { type: "number", min: -2, max: 2 },
228
- presencePenalty: { type: "number", min: -2, max: 2 },
229
- stopSequences: { type: "string" },
230
- candidateCount: { type: "number", min: 1 },
231
- stream: { type: "boolean" },
232
- seed: { type: "number" },
233
- responseMimeType: { type: "string" },
234
- responseSchema: { type: "string" }
235
- },
236
- mistral: {
237
- temperature: { type: "number", min: 0, max: 1 },
238
- max_tokens: { type: "number", min: 1 },
239
- top_p: { type: "number", min: 0, max: 1 },
240
- frequency_penalty: { type: "number", min: -2, max: 2 },
241
- presence_penalty: { type: "number", min: -2, max: 2 },
242
- stop: { type: "string" },
243
- n: { type: "number", min: 1 },
244
- random_seed: { type: "number" },
245
- stream: { type: "boolean" },
246
- safe_prompt: { type: "boolean" },
247
- min_tokens: { type: "number", min: 0 }
248
- },
249
- cohere: {
250
- temperature: { type: "number", min: 0, max: 1 },
251
- max_tokens: { type: "number", min: 1 },
252
- p: { type: "number", min: 0, max: 1 },
253
- k: { type: "number", min: 0, max: 500 },
254
- frequency_penalty: { type: "number", min: 0, max: 1 },
255
- presence_penalty: { type: "number", min: 0, max: 1 },
256
- stop_sequences: { type: "string" },
257
- stream: { type: "boolean" },
258
- seed: { type: "number" }
259
- },
260
- bedrock: {
261
- // Converse API inferenceConfig params
262
- temperature: { type: "number", min: 0, max: 1 },
263
- maxTokens: { type: "number", min: 1 },
264
- topP: { type: "number", min: 0, max: 1 },
265
- topK: { type: "number", min: 0 },
266
- stopSequences: { type: "string" },
267
- stream: { type: "boolean" },
268
- cache_control: { type: "string", values: ["ephemeral"] },
269
- cache_ttl: { type: "string", values: ["5m", "1h"] }
270
- },
271
- openrouter: {
272
- // Loose validation — proxies to many providers with varying ranges
273
- temperature: { type: "number", min: 0, max: 2 },
274
- max_tokens: { type: "number", min: 1 },
275
- top_p: { type: "number", min: 0, max: 1 },
276
- top_k: { type: "number", min: 0 },
277
- frequency_penalty: { type: "number", min: -2, max: 2 },
278
- presence_penalty: { type: "number", min: -2, max: 2 },
279
- stop: { type: "string" },
280
- n: { type: "number", min: 1 },
281
- seed: { type: "number" },
282
- stream: { type: "boolean" },
283
- reasoning_effort: {
284
- type: "string",
285
- values: ["none", "minimal", "low", "medium", "high", "xhigh"]
286
- }
287
- },
288
- vercel: {
289
- // Loose validation — proxies to many providers with varying ranges
290
- temperature: { type: "number", min: 0, max: 2 },
291
- max_tokens: { type: "number", min: 1 },
292
- top_p: { type: "number", min: 0, max: 1 },
293
- top_k: { type: "number", min: 0 },
294
- frequency_penalty: { type: "number", min: -2, max: 2 },
295
- presence_penalty: { type: "number", min: -2, max: 2 },
296
- stop: { type: "string" },
297
- n: { type: "number", min: 1 },
298
- seed: { type: "number" },
299
- stream: { type: "boolean" },
300
- reasoning_effort: {
301
- type: "string",
302
- values: ["none", "minimal", "low", "medium", "high", "xhigh"]
303
- }
304
- }
305
- };
306
- function isReasoningModel(model) {
307
- const name = model.includes("/") ? model.split("/").pop() : model;
308
- return /^o[134]/.test(name);
309
- }
310
- function canHostOpenAIModels(provider) {
311
- return provider === "openai" || provider === "openrouter" || provider === "vercel";
312
- }
313
- var REASONING_MODEL_UNSUPPORTED = /* @__PURE__ */ new Set([
314
- "temperature",
315
- "top_p",
316
- "frequency_penalty",
317
- "presence_penalty",
318
- "n"
319
- ]);
320
- function detectBedrockModelFamily(model) {
321
- const parts = model.split(".");
322
- let prefix = parts[0];
323
- if (["us", "eu", "apac", "global"].includes(prefix) && parts.length > 1) {
324
- prefix = parts[1];
325
- }
326
- const families = [
327
- "anthropic",
328
- "meta",
329
- "amazon",
330
- "mistral",
331
- "cohere",
332
- "ai21"
333
- ];
334
- return families.find((f) => prefix === f);
335
- }
336
- function bedrockSupportsCaching(model) {
337
- const family = detectBedrockModelFamily(model);
338
- if (family === "anthropic") return true;
339
- if (family === "amazon" && model.includes("nova")) return true;
340
- return false;
341
- }
342
- var CACHE_VALUES = {
343
- openai: void 0,
344
- // OpenAI auto-caches; no explicit param
345
- anthropic: "ephemeral",
346
- google: void 0,
347
- // Google uses explicit caching API, not a param
348
- mistral: void 0,
349
- cohere: void 0,
350
- bedrock: "ephemeral",
351
- // Supported for Claude models on Bedrock
352
- openrouter: void 0,
353
- // Depends on underlying provider
354
- vercel: void 0
355
- // Depends on underlying provider
356
- };
357
- var CACHE_TTLS = {
358
- openai: void 0,
359
- anthropic: ["5m", "1h"],
360
- google: void 0,
361
- mistral: void 0,
362
- cohere: void 0,
363
- bedrock: ["5m", "1h"],
364
- // Claude on Bedrock uses same TTLs as direct Anthropic
365
- openrouter: void 0,
366
- vercel: void 0
367
- };
368
- var DURATION_RE = /^\d+[mh]$/;
369
- var PROVIDER_META = [
370
- { id: "openai", name: "OpenAI", host: "api.openai.com", color: "#10a37f" },
371
- { id: "anthropic", name: "Anthropic", host: "api.anthropic.com", color: "#e8956a" },
372
- { id: "google", name: "Google", host: "generativelanguage.googleapis.com", color: "#4285f4" },
373
- { id: "mistral", name: "Mistral", host: "api.mistral.ai", color: "#ff7000" },
374
- { id: "cohere", name: "Cohere", host: "api.cohere.com", color: "#39594d" },
375
- { id: "bedrock", name: "Bedrock", host: "bedrock-runtime.us-east-1.amazonaws.com", color: "#ff9900" },
376
- { id: "openrouter", name: "OpenRouter", host: "openrouter.ai", color: "#818cf8" },
377
- { id: "vercel", name: "Vercel", host: "gateway.ai.vercel.app", color: "#ededed" }
378
- ];
379
- var MODELS = {
380
- openai: [
381
- "gpt-5.2",
382
- "gpt-5.2-pro",
383
- "gpt-4.1",
384
- "gpt-4.1-mini",
385
- "gpt-4.1-nano",
386
- "o3",
387
- "o3-mini",
388
- "o4-mini",
389
- "o1-pro"
390
- ],
391
- anthropic: [
392
- "claude-opus-4-6",
393
- "claude-sonnet-4-6",
394
- "claude-sonnet-4-5",
395
- "claude-haiku-4-5"
396
- ],
397
- google: [
398
- "gemini-3-pro-preview",
399
- "gemini-3-flash-preview",
400
- "gemini-2.5-pro",
401
- "gemini-2.5-flash"
402
- ],
403
- mistral: [
404
- "mistral-large-latest",
405
- "mistral-medium-latest",
406
- "mistral-small-latest",
407
- "codestral-latest",
408
- "magistral-medium-latest"
409
- ],
410
- cohere: [
411
- "command-a-03-2025",
412
- "command-r-plus-08-2024",
413
- "command-r-08-2024",
414
- "command-r7b-12-2024"
415
- ],
416
- bedrock: [
417
- "anthropic.claude-opus-4-6-v1",
418
- "anthropic.claude-sonnet-4-6-v1",
419
- "anthropic.claude-haiku-4-5-v1",
420
- "amazon.nova-pro-v1",
421
- "amazon.nova-lite-v1",
422
- "meta.llama3-70b-instruct-v1:0"
423
- ],
424
- openrouter: [
425
- "openai/gpt-5.2",
426
- "anthropic/claude-opus-4-6",
427
- "google/gemini-2.5-pro",
428
- "mistral/mistral-large-latest"
429
- ],
430
- vercel: [
431
- "openai/gpt-5.2",
432
- "anthropic/claude-opus-4-6",
433
- "google/gemini-2.5-pro",
434
- "google/gemini-3-pro-preview",
435
- "google/gemini-3-flash-preview",
436
- "mistral/mistral-large-latest",
437
- "qwen/qwen2.5-pro"
438
- ]
439
- };
440
- var CANONICAL_PARAM_SPECS = {
441
- openai: {
442
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
443
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
444
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
445
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
446
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
447
- stop: { type: "string", default: "", description: "Stop sequences" },
448
- n: { type: "number", min: 1, default: 1, description: "Completions count" },
449
- seed: { type: "number", default: "", description: "Random seed" },
450
- stream: { type: "boolean", default: false, description: "Stream response" },
451
- effort: { type: "enum", values: ["none", "minimal", "low", "medium", "high", "xhigh"], default: "medium", description: "Reasoning effort" }
452
- },
453
- anthropic: {
454
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
455
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
456
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
457
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
458
- stop: { type: "string", default: "", description: "Stop sequences" },
459
- stream: { type: "boolean", default: false, description: "Stream response" },
460
- effort: { type: "enum", values: ["low", "medium", "high", "max"], default: "medium", description: "Thinking effort" },
461
- cache: { type: "enum", values: ["ephemeral"], default: "ephemeral", description: "Cache control" },
462
- cache_ttl: { type: "enum", values: ["5m", "1h"], default: "5m", description: "Cache TTL" }
463
- },
464
- google: {
465
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
466
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
467
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
468
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
469
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
470
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
471
- stop: { type: "string", default: "", description: "Stop sequences" },
472
- n: { type: "number", min: 1, default: 1, description: "Candidate count" },
473
- stream: { type: "boolean", default: false, description: "Stream response" },
474
- seed: { type: "number", default: "", description: "Random seed" }
475
- },
476
- mistral: {
477
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
478
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
479
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
480
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
481
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
482
- stop: { type: "string", default: "", description: "Stop sequences" },
483
- n: { type: "number", min: 1, default: 1, description: "Completions count" },
484
- seed: { type: "number", default: "", description: "Random seed" },
485
- stream: { type: "boolean", default: false, description: "Stream response" },
486
- safe_prompt: { type: "boolean", default: false, description: "Enable safe prompt" },
487
- min_tokens: { type: "number", min: 0, default: 0, description: "Minimum tokens" }
488
- },
489
- cohere: {
490
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
491
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
492
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling (p)" },
493
- top_k: { type: "number", min: 0, max: 500, default: 40, description: "Top-K sampling (k)" },
494
- frequency_penalty: { type: "number", min: 0, max: 1, default: 0, description: "Penalize frequent tokens" },
495
- presence_penalty: { type: "number", min: 0, max: 1, default: 0, description: "Penalize repeated topics" },
496
- stop: { type: "string", default: "", description: "Stop sequences" },
497
- stream: { type: "boolean", default: false, description: "Stream response" },
498
- seed: { type: "number", default: "", description: "Random seed" }
499
- },
500
- bedrock: {
501
- temperature: { type: "number", min: 0, max: 1, default: 0.7, description: "Controls randomness" },
502
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
503
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
504
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
505
- stop: { type: "string", default: "", description: "Stop sequences" },
506
- stream: { type: "boolean", default: false, description: "Stream response" },
507
- cache: { type: "enum", values: ["ephemeral"], default: "ephemeral", description: "Cache control" },
508
- cache_ttl: { type: "enum", values: ["5m", "1h"], default: "5m", description: "Cache TTL" }
509
- },
510
- openrouter: {
511
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
512
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
513
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
514
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
515
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
516
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
517
- stop: { type: "string", default: "", description: "Stop sequences" },
518
- n: { type: "number", min: 1, default: 1, description: "Completions count" },
519
- seed: { type: "number", default: "", description: "Random seed" },
520
- stream: { type: "boolean", default: false, description: "Stream response" },
521
- effort: { type: "enum", values: ["none", "minimal", "low", "medium", "high", "xhigh"], default: "medium", description: "Reasoning effort" }
522
- },
523
- vercel: {
524
- temperature: { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" },
525
- max_tokens: { type: "number", min: 1, default: 4096, description: "Maximum output tokens" },
526
- top_p: { type: "number", min: 0, max: 1, default: 1, description: "Nucleus sampling" },
527
- top_k: { type: "number", min: 0, default: 40, description: "Top-K sampling" },
528
- frequency_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize frequent tokens" },
529
- presence_penalty: { type: "number", min: -2, max: 2, default: 0, description: "Penalize repeated topics" },
530
- stop: { type: "string", default: "", description: "Stop sequences" },
531
- n: { type: "number", min: 1, default: 1, description: "Completions count" },
532
- seed: { type: "number", default: "", description: "Random seed" },
533
- stream: { type: "boolean", default: false, description: "Stream response" },
534
- effort: { type: "enum", values: ["none", "minimal", "low", "medium", "high", "xhigh"], default: "medium", description: "Reasoning effort" }
535
- }
536
- };
537
-
538
- // src/normalize.ts
539
- function normalize(config, options = {}) {
540
- const provider = detectProvider(config.host);
541
- const changes = [];
542
- const params = {};
543
- for (const [rawKey, value] of Object.entries(config.params)) {
544
- let key = rawKey;
545
- if (ALIASES[key]) {
546
- const canonical = ALIASES[key];
547
- if (options.verbose) {
548
- changes.push({
549
- from: key,
550
- to: canonical,
551
- value,
552
- reason: `alias: "${key}" \u2192 "${canonical}"`
553
- });
554
- }
555
- key = canonical;
556
- }
557
- if (key === "cache" && provider) {
558
- let cacheValue = CACHE_VALUES[provider];
559
- if (provider === "bedrock" && !bedrockSupportsCaching(config.model)) {
560
- cacheValue = void 0;
561
- }
562
- if (!cacheValue) {
563
- if (options.verbose) {
564
- changes.push({
565
- from: "cache",
566
- to: "(dropped)",
567
- value,
568
- reason: `${provider} does not use a cache param for this model (caching is automatic or unsupported)`
569
- });
570
- }
571
- continue;
572
- }
573
- const isBool = value === "true" || value === "1" || value === "yes";
574
- const isDuration = DURATION_RE.test(value);
575
- if (isBool || isDuration) {
576
- const providerKey = PROVIDER_PARAMS[provider]?.["cache"] ?? "cache";
577
- if (options.verbose) {
578
- changes.push({
579
- from: "cache",
580
- to: providerKey,
581
- value: cacheValue,
582
- reason: `cache=${value} \u2192 ${providerKey}=${cacheValue} for ${provider}`
583
- });
584
- }
585
- params[providerKey] = cacheValue;
586
- if (isDuration && CACHE_TTLS[provider]) {
587
- if (options.verbose) {
588
- changes.push({
589
- from: "cache",
590
- to: "cache_ttl",
591
- value,
592
- reason: `cache=${value} \u2192 cache_ttl=${value} for ${provider}`
593
- });
594
- }
595
- params["cache_ttl"] = value;
596
- }
597
- continue;
598
- }
599
- }
600
- if (provider && PROVIDER_PARAMS[provider]) {
601
- const providerKey = PROVIDER_PARAMS[provider][key];
602
- if (providerKey && providerKey !== key) {
603
- if (options.verbose) {
604
- changes.push({
605
- from: key,
606
- to: providerKey,
607
- value,
608
- reason: `${provider} uses "${providerKey}" instead of "${key}"`
609
- });
610
- }
611
- key = providerKey;
612
- }
613
- }
614
- if (provider && canHostOpenAIModels(provider) && isReasoningModel(config.model) && key === "max_tokens") {
615
- if (options.verbose) {
616
- changes.push({
617
- from: "max_tokens",
618
- to: "max_completion_tokens",
619
- value,
620
- reason: "OpenAI reasoning models use max_completion_tokens instead of max_tokens"
621
- });
622
- }
623
- key = "max_completion_tokens";
624
- }
625
- params[key] = value;
626
- }
627
- return {
628
- config: { ...config, params },
629
- provider,
630
- changes
631
- };
632
- }
633
-
634
- // src/validate.ts
635
- function validate(connectionString, options = {}) {
636
- const parsed = parse(connectionString);
637
- const { config, provider } = normalize(parsed);
638
- const issues = [];
639
- if (!provider) {
640
- issues.push({
641
- param: "host",
642
- value: config.host,
643
- message: `Unknown provider for host "${config.host}". Validation skipped.`,
644
- severity: options.strict ? "error" : "warning"
645
- });
646
- return issues;
647
- }
648
- const specs = PARAM_SPECS[provider];
649
- const knownParams = new Set(Object.values(PROVIDER_PARAMS[provider]));
650
- for (const [key, value] of Object.entries(config.params)) {
651
- if (canHostOpenAIModels(provider) && isReasoningModel(config.model) && REASONING_MODEL_UNSUPPORTED.has(key)) {
652
- issues.push({
653
- param: key,
654
- value,
655
- message: `"${key}" is not supported by OpenAI reasoning model "${config.model}". Use "reasoning_effort" instead of temperature for controlling output.`,
656
- severity: "error"
657
- });
658
- continue;
659
- }
660
- if (provider === "bedrock") {
661
- const family = detectBedrockModelFamily(config.model);
662
- if (key === "topK" && family && family !== "anthropic" && family !== "cohere" && family !== "mistral") {
663
- issues.push({
664
- param: key,
665
- value,
666
- message: `"topK" is not supported by ${family} models on Bedrock.`,
667
- severity: "error"
668
- });
669
- continue;
670
- }
671
- if (key === "cache_control" && !bedrockSupportsCaching(config.model)) {
672
- issues.push({
673
- param: key,
674
- value,
675
- message: `Prompt caching is only supported for Anthropic Claude and Amazon Nova models on Bedrock, not ${family ?? "unknown"} models.`,
676
- severity: "error"
677
- });
678
- continue;
679
- }
680
- }
681
- if (!knownParams.has(key) && !specs[key]) {
682
- issues.push({
683
- param: key,
684
- value,
685
- message: `Unknown param "${key}" for ${provider}.`,
686
- severity: options.strict ? "error" : "warning"
687
- });
688
- continue;
689
- }
690
- const spec = specs[key];
691
- if (!spec) continue;
692
- if ((provider === "anthropic" || provider === "bedrock" && detectBedrockModelFamily(config.model) === "anthropic") && (key === "temperature" || key === "top_p" || key === "topP")) {
693
- const otherKey = key === "temperature" ? provider === "bedrock" ? "topP" : "top_p" : "temperature";
694
- if (key === "temperature" && config.params[otherKey] !== void 0) {
695
- issues.push({
696
- param: key,
697
- value,
698
- message: `Cannot specify both "temperature" and "${otherKey}" for Anthropic models.`,
699
- severity: "error"
700
- });
701
- }
702
- }
703
- if (spec.type === "number") {
704
- const num = Number(value);
705
- if (isNaN(num)) {
706
- issues.push({
707
- param: key,
708
- value,
709
- message: `"${key}" should be a number, got "${value}".`,
710
- severity: "error"
711
- });
712
- continue;
713
- }
714
- if (spec.min !== void 0 && num < spec.min) {
715
- issues.push({
716
- param: key,
717
- value,
718
- message: `"${key}" must be >= ${spec.min}, got ${num}.`,
719
- severity: "error"
720
- });
721
- }
722
- if (spec.max !== void 0 && num > spec.max) {
723
- issues.push({
724
- param: key,
725
- value,
726
- message: `"${key}" must be <= ${spec.max}, got ${num}.`,
727
- severity: "error"
728
- });
729
- }
730
- }
731
- if (spec.type === "boolean") {
732
- if (!["true", "false", "0", "1"].includes(value)) {
733
- issues.push({
734
- param: key,
735
- value,
736
- message: `"${key}" should be a boolean (true/false), got "${value}".`,
737
- severity: "error"
738
- });
739
- }
740
- }
741
- if (spec.type === "string" && spec.values) {
742
- if (!spec.values.includes(value)) {
743
- issues.push({
744
- param: key,
745
- value,
746
- message: `"${key}" must be one of [${spec.values.join(", ")}], got "${value}".`,
747
- severity: "error"
748
- });
749
- }
750
- }
751
- }
752
- return issues;
753
- }
1
+ import {
2
+ CANONICAL_PARAM_SPECS,
3
+ MODELS,
4
+ PROVIDER_META
5
+ } from "./chunk-6P5GSSNW.js";
6
+ import {
7
+ validate
8
+ } from "./chunk-UYMVUTLV.js";
9
+ import {
10
+ normalize
11
+ } from "./chunk-MPIHGH6L.js";
12
+ import {
13
+ build,
14
+ parse
15
+ } from "./chunk-FCEV23OT.js";
16
+ import {
17
+ ALIASES,
18
+ PARAM_SPECS,
19
+ PROVIDER_PARAMS,
20
+ REASONING_MODEL_UNSUPPORTED,
21
+ canHostOpenAIModels,
22
+ detectBedrockModelFamily,
23
+ detectGatewaySubProvider,
24
+ detectProvider,
25
+ isGatewayProvider,
26
+ isReasoningModel
27
+ } from "./chunk-XID353H7.js";
754
28
  export {
755
29
  ALIASES,
756
30
  CANONICAL_PARAM_SPECS,
@@ -762,7 +36,9 @@ export {
762
36
  build,
763
37
  canHostOpenAIModels,
764
38
  detectBedrockModelFamily,
39
+ detectGatewaySubProvider,
765
40
  detectProvider,
41
+ isGatewayProvider,
766
42
  isReasoningModel,
767
43
  normalize,
768
44
  parse,