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/README.md CHANGED
@@ -19,10 +19,9 @@
19
19
  llm://api.openai.com/gpt-5.2?temp=0.7&max=2000
20
20
  llm://my-app:sk-key-123@api.anthropic.com/claude-sonnet-4-5?cache=5m
21
21
  llm://bedrock-runtime.us-east-1.amazonaws.com/anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.5
22
+ llm://openai/gpt-5.2?temp=0.7&max=2000
22
23
  ```
23
24
 
24
-
25
-
26
25
  Every LLM provider invented their own parameter names. `max_tokens` vs `maxOutputTokens` vs `maxTokens`. `top_p` vs `topP` vs `p`. `stop` vs `stop_sequences` vs `stopSequences`. You write the config once, then rewrite it for every provider.
27
26
 
28
27
  **llm-strings** gives you a single, portable format. Parse it, normalize it to any provider's API, and validate it — all in one library with zero dependencies.
@@ -53,7 +52,11 @@ const issues = validate("llm://api.openai.com/gpt-5.2?temp=3.0");
53
52
  // → [{ param: "temperature", message: '"temperature" must be <= 2, got 3', severity: "error" }]
54
53
 
55
54
  // Build a connection string from a config object
56
- const str = build({ host: "api.openai.com", model: "gpt-5.2", params: { temperature: "0.7" } });
55
+ const str = build({
56
+ host: "api.openai.com",
57
+ model: "gpt-5.2",
58
+ params: { temperature: "0.7" },
59
+ });
57
60
  // → "llm://api.openai.com/gpt-5.2?temperature=0.7"
58
61
  ```
59
62
 
@@ -89,6 +92,7 @@ Your code stays the same. `normalize()` handles the parameter translation.
89
92
  - **Zero dependencies** — Pure TypeScript. No runtime baggage.
90
93
  - **Portable config** — Fits in an env var, a CLI flag, a config file, or a database column.
91
94
  - **Shorthand aliases** — Use `temp`, `max`, `topp`, `freq`, `pres` — they all expand to the right thing.
95
+ - **Short host aliases** — Use `llm://openai/...`, `llm://anthropic/...`, `llm://bedrock/...`, etc. Env overrides can redirect aliases to regional or private endpoints.
92
96
 
93
97
  ## Format
94
98
 
@@ -96,13 +100,13 @@ Your code stays the same. `normalize()` handles the parameter translation.
96
100
  llm://[label[:apiKey]@]host/model[?params]
97
101
  ```
98
102
 
99
- | Part | Required | Description | Example |
100
- | ---------- | -------- | ----------------------------------------- | ------------------------------ |
101
- | `label` | No | App name or identifier | `my-app` |
102
- | `apiKey` | No | API key (in the password position) | `sk-proj-abc123` |
103
- | `host` | Yes | Provider's API hostname | `api.openai.com` |
104
- | `model` | Yes | Model name or ID | `gpt-5.2` |
105
- | `params` | No | Key-value config (query string) | `temp=0.7&max=2000` |
103
+ | Part | Required | Description | Example |
104
+ | -------- | -------- | ---------------------------------- | -------------------------- |
105
+ | `label` | No | App name or identifier | `my-app` |
106
+ | `apiKey` | No | API key (in the password position) | `sk-proj-abc123` |
107
+ | `host` | Yes | Provider's API host or short alias | `api.openai.com`, `openai` |
108
+ | `model` | Yes | Model name or ID | `gpt-5.2` |
109
+ | `params` | No | Key-value config (query string) | `temp=0.7&max=2000` |
106
110
 
107
111
  ## Examples
108
112
 
@@ -129,6 +133,30 @@ for (const str of strings) {
129
133
  // google: { temperature: "0.7", maxOutputTokens: "2000", topP: "0.9" }
130
134
  ```
131
135
 
136
+ ### Short host aliases
137
+
138
+ Provider IDs can be used as short hostnames:
139
+
140
+ ```ts
141
+ import { parse, normalize } from "llm-strings";
142
+
143
+ const { config, provider } = normalize(parse("llm://openai/gpt-5.2?temp=0.7"));
144
+
145
+ config.host; // "api.openai.com"
146
+ provider; // "openai"
147
+ ```
148
+
149
+ Built-in aliases: `openai`, `anthropic`, `google`, `mistral`, `cohere`, `bedrock`, `openrouter`, `vercel`.
150
+
151
+ Set env overrides to point an alias at a regional or private endpoint:
152
+
153
+ ```sh
154
+ LLM_STRINGS_OPENAI_HOST="regional.openai.example.com"
155
+ LLM_STRINGS_BEDROCK_HOST="bedrock-runtime.us-west-2.amazonaws.com"
156
+ ```
157
+
158
+ The alternate form `LLM_STRINGS_HOST_OPENAI` is also supported. Overrides may include a scheme or path; only the host portion is used.
159
+
132
160
  ### Validating before calling the API
133
161
 
134
162
  Catch bad config before it hits the network:
@@ -138,7 +166,7 @@ import { validate } from "llm-strings";
138
166
 
139
167
  // Anthropic doesn't allow temperature + top_p together
140
168
  const issues = validate(
141
- "llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&top_p=0.9"
169
+ "llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&top_p=0.9",
142
170
  );
143
171
 
144
172
  for (const issue of issues) {
@@ -173,12 +201,38 @@ const response = await fetch(`https://${config.host}/v1/chat/completions`, {
173
201
  model: config.model,
174
202
  messages: [{ role: "user", content: "Hello!" }],
175
203
  ...Object.fromEntries(
176
- Object.entries(config.params).map(([k, v]) => [k, isNaN(+v) ? v : +v])
204
+ Object.entries(config.params).map(([k, v]) => [k, isNaN(+v) ? v : +v]),
177
205
  ),
178
206
  }),
179
207
  });
180
208
  ```
181
209
 
210
+ ### AI SDK providerOptions
211
+
212
+ The AI SDK adapter is available as a separate subpath so you can load it only
213
+ where you need it:
214
+
215
+ ```ts
216
+ const { createAiSdkProviderOptions } = await import("llm-strings/ai-sdk");
217
+
218
+ const { providerOptions } = createAiSdkProviderOptions(
219
+ "llm://api.anthropic.com/claude-sonnet-4-5?cache=1h&effort=max",
220
+ );
221
+
222
+ // {
223
+ // anthropic: {
224
+ // cacheControl: { type: "ephemeral", ttl: "1h" },
225
+ // effort: "max"
226
+ // }
227
+ // }
228
+ ```
229
+
230
+ Common generation settings like `temperature`, `topP`, and `maxOutputTokens`
231
+ belong on the AI SDK call itself, so this helper only emits provider-specific
232
+ configuration such as Anthropic cache control, Bedrock cache points, OpenAI
233
+ reasoning options, Mistral `safePrompt`, OpenRouter reasoning, and Vercel AI
234
+ Gateway routing options.
235
+
182
236
  ### Prompt caching (Anthropic & Bedrock)
183
237
 
184
238
  ```ts
@@ -186,21 +240,21 @@ import { parse, normalize } from "llm-strings";
186
240
 
187
241
  // cache=true → cache_control=ephemeral
188
242
  const { config } = normalize(
189
- parse("llm://api.anthropic.com/claude-sonnet-4-5?max=4096&cache=true")
243
+ parse("llm://api.anthropic.com/claude-sonnet-4-5?max=4096&cache=true"),
190
244
  );
191
245
  // → params: { max_tokens: "4096", cache_control: "ephemeral" }
192
246
 
193
247
  // cache=5m → cache_control=ephemeral + cache_ttl=5m
194
248
  const { config: withTtl } = normalize(
195
- parse("llm://api.anthropic.com/claude-sonnet-4-5?max=4096&cache=5m")
249
+ parse("llm://api.anthropic.com/claude-sonnet-4-5?max=4096&cache=5m"),
196
250
  );
197
251
  // → params: { max_tokens: "4096", cache_control: "ephemeral", cache_ttl: "5m" }
198
252
 
199
253
  // Works on Bedrock too (Claude and Nova models)
200
254
  const { config: bedrock } = normalize(
201
255
  parse(
202
- "llm://bedrock-runtime.us-east-1.amazonaws.com/anthropic.claude-sonnet-4-5-20250929-v1:0?cache=1h"
203
- )
256
+ "llm://bedrock-runtime.us-east-1.amazonaws.com/anthropic.claude-sonnet-4-5-20250929-v1:0?cache=1h",
257
+ ),
204
258
  );
205
259
  // → params: { cache_control: "ephemeral", cache_ttl: "1h" }
206
260
  ```
@@ -214,9 +268,9 @@ import { parse, normalize } from "llm-strings";
214
268
 
215
269
  const { changes } = normalize(
216
270
  parse(
217
- "llm://generativelanguage.googleapis.com/gemini-3-flash-preview?temp=0.7&max=2000&topp=0.9"
271
+ "llm://generativelanguage.googleapis.com/gemini-3-flash-preview?temp=0.7&max=2000&topp=0.9",
218
272
  ),
219
- { verbose: true }
273
+ { verbose: true },
220
274
  );
221
275
 
222
276
  for (const c of changes) {
@@ -251,7 +305,7 @@ import { parse, normalize } from "llm-strings";
251
305
  import { detectBedrockModelFamily } from "llm-strings/providers";
252
306
 
253
307
  const config = parse(
254
- "llm://bedrock-runtime.us-east-1.amazonaws.com/us.anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.5&max=4096"
308
+ "llm://bedrock-runtime.us-east-1.amazonaws.com/us.anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.5&max=4096",
255
309
  );
256
310
 
257
311
  detectBedrockModelFamily(config.model);
@@ -269,7 +323,7 @@ import { parse, normalize, validate } from "llm-strings";
269
323
 
270
324
  // OpenRouter proxies to any provider
271
325
  const { config } = normalize(
272
- parse("llm://openrouter.ai/anthropic/claude-sonnet-4-5?temp=0.7&max=2000")
326
+ parse("llm://openrouter.ai/anthropic/claude-sonnet-4-5?temp=0.7&max=2000"),
273
327
  );
274
328
  // → params: { temperature: "0.7", max_tokens: "2000" }
275
329
 
@@ -298,19 +352,19 @@ Gateways like OpenRouter and Vercel route to any upstream provider. Bedrock host
298
352
 
299
353
  Use these shortcuts in your connection strings — they expand automatically during normalization:
300
354
 
301
- | Shorthand | Canonical |
302
- | -------------------------------------------------------------------- | -------------------- |
303
- | `temp` | `temperature` |
304
- | `max`, `max_out`, `max_output`, `max_output_tokens`, `maxTokens`, `maxOutputTokens`, `max_completion_tokens` | `max_tokens` |
305
- | `topp`, `topP`, `nucleus` | `top_p` |
306
- | `topk`, `topK` | `top_k` |
307
- | `freq`, `freq_penalty`, `frequencyPenalty`, `repetition_penalty` | `frequency_penalty` |
308
- | `pres`, `pres_penalty`, `presencePenalty` | `presence_penalty` |
309
- | `stop_sequences`, `stopSequences`, `stop_sequence` | `stop` |
310
- | `random_seed`, `randomSeed` | `seed` |
311
- | `candidateCount`, `candidate_count`, `num_completions` | `n` |
312
- | `reasoning`, `reasoning_effort` | `effort` |
313
- | `cache_control`, `cacheControl`, `cachePoint`, `cache_point` | `cache` |
355
+ | Shorthand | Canonical |
356
+ | ------------------------------------------------------------------------------------------------------------ | ------------------- |
357
+ | `temp` | `temperature` |
358
+ | `max`, `max_out`, `max_output`, `max_output_tokens`, `maxTokens`, `maxOutputTokens`, `max_completion_tokens` | `max_tokens` |
359
+ | `topp`, `topP`, `nucleus` | `top_p` |
360
+ | `topk`, `topK` | `top_k` |
361
+ | `freq`, `freq_penalty`, `frequencyPenalty`, `repetition_penalty` | `frequency_penalty` |
362
+ | `pres`, `pres_penalty`, `presencePenalty` | `presence_penalty` |
363
+ | `stop_sequences`, `stopSequences`, `stop_sequence` | `stop` |
364
+ | `random_seed`, `randomSeed` | `seed` |
365
+ | `candidateCount`, `candidate_count`, `num_completions` | `n` |
366
+ | `reasoning`, `reasoning_effort` | `effort` |
367
+ | `cache_control`, `cacheControl`, `cachePoint`, `cache_point` | `cache` |
314
368
 
315
369
  ## Sub-path Imports
316
370
 
@@ -320,7 +374,14 @@ For smaller bundles, import only what you need:
320
374
  import { parse, build } from "llm-strings/parse";
321
375
  import { normalize } from "llm-strings/normalize";
322
376
  import { validate } from "llm-strings/validate";
323
- import { detectProvider, ALIASES, PROVIDER_PARAMS, PARAM_SPECS } from "llm-strings/providers";
377
+ import {
378
+ detectProvider,
379
+ resolveHostAlias,
380
+ ALIASES,
381
+ HOST_ALIASES,
382
+ PROVIDER_PARAMS,
383
+ PARAM_SPECS,
384
+ } from "llm-strings/providers";
324
385
  ```
325
386
 
326
387
  All sub-paths ship ESM + CJS with full type declarations.
@@ -367,6 +428,10 @@ validate("llm://custom-api.com/my-model?temp=0.5", { strict: true });
367
428
 
368
429
  Identifies the provider from a hostname string.
369
430
 
431
+ ### `resolveHostAlias(host): HostResolution`
432
+
433
+ Expands provider short host aliases such as `"openai"` to canonical hosts such as `"api.openai.com"`. Reads `LLM_STRINGS_<PROVIDER>_HOST` and `LLM_STRINGS_HOST_<PROVIDER>` env overrides when available.
434
+
370
435
  ### `detectBedrockModelFamily(model): BedrockModelFamily | undefined`
371
436
 
372
437
  Identifies the model family (anthropic, meta, amazon, mistral, cohere, ai21) from a Bedrock model ID. Handles cross-region (`us.`, `eu.`, `apac.`) and global inference profiles.
@@ -393,15 +458,16 @@ Returns `true` if the Bedrock model supports prompt caching (Claude and Nova mod
393
458
 
394
459
  ### Constants
395
460
 
396
- | Export | Description |
397
- | --- | --- |
398
- | `ALIASES` | Shorthand → canonical param name mapping |
399
- | `PROVIDER_PARAMS` | Canonical provider-specific param names, per provider |
400
- | `PARAM_SPECS` | Validation rules (type, min/max, enum) per provider, keyed by provider-specific param name |
401
- | `REASONING_MODEL_UNSUPPORTED` | Set of canonical params unsupported by reasoning models |
402
- | `PROVIDER_META` | Array of provider metadata (id, name, host, brand color) for UI integrations |
403
- | `MODELS` | Suggested model IDs per provider |
404
- | `CANONICAL_PARAM_SPECS` | Canonical param specs per provider with descriptions — useful for building UIs |
461
+ | Export | Description |
462
+ | ----------------------------- | ------------------------------------------------------------------------------------------ |
463
+ | `ALIASES` | Shorthand → canonical param name mapping |
464
+ | `HOST_ALIASES` | Short provider host aliases canonical API hosts |
465
+ | `PROVIDER_PARAMS` | Canonical provider-specific param names, per provider |
466
+ | `PARAM_SPECS` | Validation rules (type, min/max, enum) per provider, keyed by provider-specific param name |
467
+ | `REASONING_MODEL_UNSUPPORTED` | Set of canonical params unsupported by reasoning models |
468
+ | `PROVIDER_META` | Array of provider metadata (id, name, host, brand color) for UI integrations |
469
+ | `MODELS` | Suggested model IDs per provider |
470
+ | `CANONICAL_PARAM_SPECS` | Canonical param specs per provider with descriptions — useful for building UIs |
405
471
 
406
472
  ## TypeScript
407
473
 
@@ -433,7 +499,11 @@ import type {
433
499
  The library exports metadata useful for building UIs — provider names, brand colors, suggested models, and canonical parameter specs:
434
500
 
435
501
  ```ts
436
- import { PROVIDER_META, MODELS, CANONICAL_PARAM_SPECS } from "llm-strings/providers";
502
+ import {
503
+ PROVIDER_META,
504
+ MODELS,
505
+ CANONICAL_PARAM_SPECS,
506
+ } from "llm-strings/providers";
437
507
 
438
508
  // Provider display info
439
509
  PROVIDER_META.forEach((p) => console.log(`${p.name}: ${p.host} (${p.color})`));
@@ -442,7 +512,7 @@ PROVIDER_META.forEach((p) => console.log(`${p.name}: ${p.host} (${p.color})`));
442
512
  // ...
443
513
 
444
514
  // Suggested models per provider
445
- MODELS.openai; // → ["gpt-5.2", "gpt-5.2-pro", "gpt-4.1", "gpt-4.1-mini", ...]
515
+ MODELS.openai; // → ["gpt-5.2", "gpt-5.2-pro", "gpt-4.1", "gpt-4.1-mini", ...]
446
516
  MODELS.anthropic; // → ["claude-opus-4-6", "claude-sonnet-4-6", "claude-sonnet-4-5", ...]
447
517
 
448
518
  // Canonical param specs — useful for building config forms