llm-strings 1.3.0 → 1.5.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.
- package/LICENSE +21 -0
- package/README.md +339 -339
- package/dist/ai-sdk.cjs +1146 -117
- package/dist/ai-sdk.d.cts +1 -1
- package/dist/ai-sdk.d.ts +1 -1
- package/dist/ai-sdk.js +95 -58
- package/dist/{chunk-7HE4RH6X.js → chunk-4BE457QA.js} +16 -29
- package/dist/{chunk-TQJ2ABCT.js → chunk-6HQOCOQI.js} +1 -2
- package/dist/{chunk-NZR5DUX5.js → chunk-7Z7DCLZN.js} +14 -3
- package/dist/{chunk-OCJX4QFJ.js → chunk-PCJDQTOV.js} +520 -76
- package/dist/index.cjs +542 -95
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -5
- package/dist/normalize.cjs +1065 -63
- package/dist/normalize.d.cts +1 -1
- package/dist/normalize.d.ts +1 -1
- package/dist/normalize.js +2 -3
- package/dist/parse.cjs +1075 -1
- package/dist/parse.d.cts +4 -4
- package/dist/parse.d.ts +4 -4
- package/dist/parse.js +2 -3
- package/dist/{provider-core-B934MuhJ.d.cts → provider-core-B1GMszQP.d.cts} +2 -3
- package/dist/{provider-core-B934MuhJ.d.ts → provider-core-B1GMszQP.d.ts} +2 -3
- package/dist/providers.cjs +542 -697
- package/dist/providers.d.cts +3 -8
- package/dist/providers.d.ts +3 -8
- package/dist/providers.js +25 -624
- package/dist/validate.cjs +542 -95
- package/dist/validate.d.cts +1 -1
- package/dist/validate.d.ts +1 -1
- package/dist/validate.js +4 -5
- package/package.json +16 -2
- package/dist/ai-sdk.cjs.map +0 -1
- package/dist/ai-sdk.js.map +0 -1
- package/dist/chunk-7HE4RH6X.js.map +0 -1
- package/dist/chunk-NZR5DUX5.js.map +0 -1
- package/dist/chunk-OCJX4QFJ.js.map +0 -1
- package/dist/chunk-TQJ2ABCT.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/normalize.cjs.map +0 -1
- package/dist/normalize.js.map +0 -1
- package/dist/parse.cjs.map +0 -1
- package/dist/parse.js.map +0 -1
- package/dist/providers.cjs.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/validate.cjs.map +0 -1
- package/dist/validate.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,25 +8,47 @@
|
|
|
8
8
|
[](https://github.com/justsml/llm-strings/blob/main/LICENSE)
|
|
9
9
|
[](https://www.typescriptlang.org/)
|
|
10
10
|
[](https://www.npmjs.com/package/llm-strings)
|
|
11
|
+
[](https://nodejs.org/)
|
|
12
|
+
|
|
13
|
+
**Parse, normalize, validate, and build portable `llm://` URLs across AI providers.**
|
|
14
|
+
|
|
15
|
+
[Install](#install) · [Quick Start](#quick-start) · [Examples](#examples) · [Supported Providers](#supported-providers) · [API](#api-reference)
|
|
11
16
|
|
|
12
17
|
</div>
|
|
13
18
|
|
|
14
19
|
---
|
|
15
20
|
|
|
16
|
-

|
|
17
22
|
|
|
18
23
|
```ini
|
|
19
|
-
llm://
|
|
20
|
-
llm://
|
|
21
|
-
llm://bedrock
|
|
22
|
-
llm://
|
|
24
|
+
llm://openai/gpt-5.5?effort=medium&maxTokens=2000
|
|
25
|
+
llm://anthropic/claude-opus-4-8?cache=5m&effort=max
|
|
26
|
+
llm://bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.5&max=4096
|
|
27
|
+
llm://openrouter/anthropic/claude-sonnet-4-5?temp=0.7&max=2000
|
|
23
28
|
```
|
|
24
29
|
|
|
25
|
-
Every LLM provider invented
|
|
30
|
+
Every LLM provider invented slightly different names for the same knobs:
|
|
31
|
+
`max_tokens` vs `maxOutputTokens` vs `maxTokens`, `top_p` vs `topP` vs `p`,
|
|
32
|
+
`stop` vs `stop_sequences` vs `stopSequences`.
|
|
33
|
+
|
|
34
|
+
**llm-strings** gives you one portable format for model configuration. Put the
|
|
35
|
+
whole config in an env var, normalize it to the provider's API shape, validate
|
|
36
|
+
it before you spend tokens, and build UI controls from the same metadata.
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
Based on the [LLM Connection Strings](https://danlevy.net/llm-connection-strings/)
|
|
39
|
+
proposal by Dan Levy. See the [draft IETF RFC for `llm://`](https://datatracker.ietf.org/doc/html/draft-levy-llm-uri-scheme-00).
|
|
28
40
|
|
|
29
|
-
|
|
41
|
+
## Why developers use it
|
|
42
|
+
|
|
43
|
+
- **One config string** for host, model, credentials, and generation params.
|
|
44
|
+
- **Provider-native output** from provider-agnostic input like `temp=0.7&max=2000`.
|
|
45
|
+
- **Early validation** for ranges, mutual exclusions, Bedrock model-family
|
|
46
|
+
rules, and OpenAI reasoning-family normalization.
|
|
47
|
+
- **Short aliases** like `openai`, `anthropic`, `google`, `bedrock`, `groq`, and
|
|
48
|
+
`openrouter`, with env overrides for private or regional endpoints.
|
|
49
|
+
- **AI SDK providerOptions** generation for provider-specific settings.
|
|
50
|
+
- **Zero runtime dependencies**, ESM + CJS, full TypeScript declarations, and
|
|
51
|
+
sub-path imports for smaller bundles.
|
|
30
52
|
|
|
31
53
|
## Install
|
|
32
54
|
|
|
@@ -34,164 +56,87 @@ Based on the [LLM Connection Strings](https://danlevy.net/llm-connection-strings
|
|
|
34
56
|
npm install llm-strings
|
|
35
57
|
```
|
|
36
58
|
|
|
37
|
-
## Quick Start
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
import { parse, normalize, validate, build } from "llm-strings";
|
|
41
|
-
|
|
42
|
-
// Parse a connection string into structured config
|
|
43
|
-
const config = parse("llm://api.openai.com/gpt-5.2?temp=0.7&max=2000");
|
|
44
|
-
// → { host: "api.openai.com", model: "gpt-5.2", params: { temp: "0.7", max: "2000" } }
|
|
45
|
-
|
|
46
|
-
// Normalize aliases and map to the provider's actual API param names
|
|
47
|
-
const { config: normalized, provider } = normalize(config);
|
|
48
|
-
// → params: { temperature: "0.7", max_tokens: "2000" }, provider: "openai"
|
|
49
|
-
|
|
50
|
-
// Validate against provider specs (returns [] if valid)
|
|
51
|
-
const issues = validate("llm://api.openai.com/gpt-5.2?temp=3.0");
|
|
52
|
-
// → [{ param: "temperature", message: '"temperature" must be <= 2, got 3', severity: "error" }]
|
|
53
|
-
|
|
54
|
-
// Build a connection string from a config object
|
|
55
|
-
const str = build({
|
|
56
|
-
host: "api.openai.com",
|
|
57
|
-
model: "gpt-5.2",
|
|
58
|
-
params: { temperature: "0.7" },
|
|
59
|
-
});
|
|
60
|
-
// → "llm://api.openai.com/gpt-5.2?temperature=0.7"
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Why Connection Strings?
|
|
64
|
-
|
|
65
|
-
You already use them for databases: `postgres://user:pass@host/db`. They're compact, portable, and easy to pass through environment variables. LLM configs deserve the same treatment.
|
|
66
|
-
|
|
67
|
-
**Store your entire model config in one env var:**
|
|
68
|
-
|
|
69
59
|
```bash
|
|
70
|
-
|
|
60
|
+
pnpm add llm-strings
|
|
71
61
|
```
|
|
72
62
|
|
|
73
|
-
**Switch providers by changing a string, not refactoring code:**
|
|
74
|
-
|
|
75
63
|
```bash
|
|
76
|
-
|
|
77
|
-
LLM_URL="llm://api.openai.com/gpt-5.2?temp=0.7&max=2000"
|
|
78
|
-
|
|
79
|
-
# Tuesday: Anthropic
|
|
80
|
-
LLM_URL="llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&max=2000"
|
|
81
|
-
|
|
82
|
-
# Wednesday: Bedrock in production
|
|
83
|
-
LLM_URL="llm://bedrock-runtime.us-east-1.amazonaws.com/anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.7&max=2000"
|
|
64
|
+
yarn add llm-strings
|
|
84
65
|
```
|
|
85
66
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
## Benefits
|
|
89
|
-
|
|
90
|
-
- **One format, every provider** — Write `temp=0.7&max=2000` once. Normalization maps it to `temperature`, `max_tokens`, `maxOutputTokens`, `maxTokens`, or whatever your provider calls it.
|
|
91
|
-
- **Catch mistakes early** — `validate()` checks types, ranges, and provider-specific rules before you burn tokens on a bad request.
|
|
92
|
-
- **Zero dependencies** — Pure TypeScript. No runtime baggage.
|
|
93
|
-
- **Portable config** — Fits in an env var, a CLI flag, a config file, or a database column.
|
|
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.
|
|
96
|
-
|
|
97
|
-
## Format
|
|
98
|
-
|
|
99
|
-
```ini
|
|
100
|
-
llm://[label[:apiKey]@]host/model[?params]
|
|
67
|
+
```bash
|
|
68
|
+
bun add llm-strings
|
|
101
69
|
```
|
|
102
70
|
|
|
103
|
-
|
|
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` |
|
|
110
|
-
|
|
111
|
-
## Examples
|
|
112
|
-
|
|
113
|
-
### Switching between providers
|
|
114
|
-
|
|
115
|
-
Write portable params, let `normalize()` translate them:
|
|
71
|
+
## Quick Start
|
|
116
72
|
|
|
117
73
|
```ts
|
|
118
|
-
import {
|
|
119
|
-
|
|
120
|
-
// Same logical config, different providers
|
|
121
|
-
const strings = [
|
|
122
|
-
"llm://api.openai.com/gpt-5.2?temp=0.7&max=2000&top_p=0.9",
|
|
123
|
-
"llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&max=2000&top_p=0.9",
|
|
124
|
-
"llm://generativelanguage.googleapis.com/gemini-3-flash-preview?temp=0.7&max=2000&top_p=0.9",
|
|
125
|
-
];
|
|
126
|
-
|
|
127
|
-
for (const str of strings) {
|
|
128
|
-
const { config, provider } = normalize(parse(str));
|
|
129
|
-
console.log(`${provider}:`, config.params);
|
|
130
|
-
}
|
|
131
|
-
// openai: { temperature: "0.7", max_tokens: "2000", top_p: "0.9" }
|
|
132
|
-
// anthropic: { temperature: "0.7", max_tokens: "2000", top_p: "0.9" }
|
|
133
|
-
// google: { temperature: "0.7", maxOutputTokens: "2000", topP: "0.9" }
|
|
134
|
-
```
|
|
74
|
+
import { build, normalize, parse, validate } from "llm-strings";
|
|
135
75
|
|
|
136
|
-
|
|
76
|
+
const input = "llm://openai/gpt-4o?temp=0.7&max=2000&topp=0.9";
|
|
137
77
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
78
|
+
const parsed = parse(input);
|
|
79
|
+
// {
|
|
80
|
+
// raw: "llm://openai/gpt-4o?temp=0.7&max=2000&topp=0.9",
|
|
81
|
+
// host: "api.openai.com",
|
|
82
|
+
// hostAlias: "openai",
|
|
83
|
+
// model: "gpt-4o",
|
|
84
|
+
// params: { temp: "0.7", max: "2000", topp: "0.9" }
|
|
85
|
+
// }
|
|
142
86
|
|
|
143
|
-
const { config, provider } = normalize(
|
|
87
|
+
const { config, provider } = normalize(parsed);
|
|
88
|
+
// provider: "openai"
|
|
89
|
+
// config.params: { temperature: "0.7", max_tokens: "2000", top_p: "0.9" }
|
|
90
|
+
|
|
91
|
+
const issues = validate("llm://anthropic/claude-sonnet-4-5?temp=0.7&top_p=0.9");
|
|
92
|
+
// [
|
|
93
|
+
// {
|
|
94
|
+
// param: "temperature",
|
|
95
|
+
// value: "0.7",
|
|
96
|
+
// severity: "error",
|
|
97
|
+
// message: "Cannot specify both \"temperature\" and \"top_p\" for Anthropic models."
|
|
98
|
+
// }
|
|
99
|
+
// ]
|
|
144
100
|
|
|
145
|
-
|
|
146
|
-
|
|
101
|
+
const url = build({
|
|
102
|
+
host: "anthropic",
|
|
103
|
+
model: "claude-sonnet-4-5",
|
|
104
|
+
params: { temp: "0.7", max: "4096" },
|
|
105
|
+
});
|
|
106
|
+
// "llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&max=4096"
|
|
147
107
|
```
|
|
148
108
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Set env overrides to point an alias at a regional or private endpoint:
|
|
109
|
+
## Format
|
|
152
110
|
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
LLM_STRINGS_BEDROCK_HOST="bedrock-runtime.us-west-2.amazonaws.com"
|
|
111
|
+
```ini
|
|
112
|
+
llm://[label[:apiKey]@]host/model[?params]
|
|
156
113
|
```
|
|
157
114
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
115
|
+
| Part | Required | Description | Example |
|
|
116
|
+
| -------- | -------- | --------------------------------- | -------------------------- |
|
|
117
|
+
| `label` | No | App name or environment label | `worker` |
|
|
118
|
+
| `apiKey` | No | API key in the password position | `sk-proj-abc123` |
|
|
119
|
+
| `host` | Yes | Provider host or short alias | `api.openai.com`, `openai` |
|
|
120
|
+
| `model` | Yes | Model name, route, or provider ID | `gpt-5.5` |
|
|
121
|
+
| `params` | No | Query-string generation settings | `effort=medium&max=2000` |
|
|
161
122
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
```ts
|
|
165
|
-
import { validate } from "llm-strings";
|
|
123
|
+
Connection strings can include secrets, so treat values containing `apiKey` like
|
|
124
|
+
credentials: store them in secret managers or env vars, and avoid logging them.
|
|
166
125
|
|
|
167
|
-
|
|
168
|
-
const issues = validate(
|
|
169
|
-
"llm://api.anthropic.com/claude-sonnet-4-5?temp=0.7&top_p=0.9",
|
|
170
|
-
);
|
|
126
|
+
## Examples
|
|
171
127
|
|
|
172
|
-
|
|
173
|
-
console.error(`[${issue.severity}] ${issue.param}: ${issue.message}`);
|
|
174
|
-
}
|
|
175
|
-
// [error] temperature: Cannot specify both "temperature" and "top_p" for Anthropic models.
|
|
176
|
-
```
|
|
128
|
+
### One env var for your model config
|
|
177
129
|
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
const issues = validate("llm://api.openai.com/o3?temp=0.7&max=2000");
|
|
181
|
-
// [error] temperature: "temperature" is not supported by OpenAI reasoning model "o3".
|
|
182
|
-
// Use "reasoning_effort" instead of temperature for controlling output.
|
|
130
|
+
```bash
|
|
131
|
+
LLM_URL="llm://worker:sk-proj-abc123@openai/gpt-4o?temp=0.7&max=2000"
|
|
183
132
|
```
|
|
184
133
|
|
|
185
|
-
### Environment-driven config
|
|
186
|
-
|
|
187
134
|
```ts
|
|
188
|
-
import {
|
|
135
|
+
import { normalize, parse } from "llm-strings";
|
|
189
136
|
|
|
190
|
-
// One env var holds the entire config
|
|
191
137
|
const { config, provider } = normalize(parse(process.env.LLM_URL!));
|
|
192
138
|
|
|
193
|
-
|
|
194
|
-
const response = await fetch(`https://${config.host}/v1/chat/completions`, {
|
|
139
|
+
await fetch(`https://${config.host}/v1/chat/completions`, {
|
|
195
140
|
method: "POST",
|
|
196
141
|
headers: {
|
|
197
142
|
Authorization: `Bearer ${config.apiKey}`,
|
|
@@ -201,156 +146,215 @@ const response = await fetch(`https://${config.host}/v1/chat/completions`, {
|
|
|
201
146
|
model: config.model,
|
|
202
147
|
messages: [{ role: "user", content: "Hello!" }],
|
|
203
148
|
...Object.fromEntries(
|
|
204
|
-
Object.entries(config.params).map(([
|
|
149
|
+
Object.entries(config.params).map(([key, value]) => [
|
|
150
|
+
key,
|
|
151
|
+
Number.isNaN(Number(value)) ? value : Number(value),
|
|
152
|
+
]),
|
|
205
153
|
),
|
|
206
154
|
}),
|
|
207
155
|
});
|
|
156
|
+
|
|
157
|
+
console.log(provider); // "openai"
|
|
208
158
|
```
|
|
209
159
|
|
|
210
|
-
###
|
|
160
|
+
### Switch providers without changing app code
|
|
211
161
|
|
|
212
|
-
|
|
213
|
-
|
|
162
|
+
```bash
|
|
163
|
+
# OpenAI
|
|
164
|
+
LLM_URL="llm://openai/gpt-4o?temp=0.7&max=2000"
|
|
214
165
|
|
|
215
|
-
|
|
216
|
-
|
|
166
|
+
# Anthropic
|
|
167
|
+
LLM_URL="llm://anthropic/claude-sonnet-4-5?temp=0.7&max=2000"
|
|
217
168
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
);
|
|
169
|
+
# Google
|
|
170
|
+
LLM_URL="llm://google/gemini-3.5-flash?temp=0.7&max=2000"
|
|
221
171
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// cacheControl: { type: "ephemeral", ttl: "1h" },
|
|
225
|
-
// effort: "max"
|
|
226
|
-
// }
|
|
227
|
-
// }
|
|
172
|
+
# Bedrock
|
|
173
|
+
LLM_URL="llm://bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0?temp=0.7&max=2000"
|
|
228
174
|
```
|
|
229
175
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
176
|
+
```ts
|
|
177
|
+
import { normalize, parse } from "llm-strings";
|
|
178
|
+
|
|
179
|
+
for (const value of [
|
|
180
|
+
"llm://openai/gpt-4o?temp=0.7&max=2000",
|
|
181
|
+
"llm://anthropic/claude-sonnet-4-5?temp=0.7&max=2000",
|
|
182
|
+
"llm://google/gemini-3.5-flash?temp=0.7&max=2000",
|
|
183
|
+
]) {
|
|
184
|
+
const { config, provider } = normalize(parse(value));
|
|
185
|
+
console.log(provider, config.params);
|
|
186
|
+
}
|
|
235
187
|
|
|
236
|
-
|
|
188
|
+
// openai { temperature: "0.7", max_tokens: "2000" }
|
|
189
|
+
// anthropic { temperature: "0.7", max_tokens: "2000" }
|
|
190
|
+
// google { temperature: "0.7", maxOutputTokens: "2000" }
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Resolve short host aliases
|
|
237
194
|
|
|
238
195
|
```ts
|
|
239
|
-
import {
|
|
196
|
+
import { normalize, parse } from "llm-strings";
|
|
240
197
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
parse("llm://api.anthropic.com/claude-sonnet-4-5?max=4096&cache=true"),
|
|
198
|
+
const { config, provider } = normalize(
|
|
199
|
+
parse("llm://groq/llama-3.3-70b?max=1000"),
|
|
244
200
|
);
|
|
245
|
-
// → params: { max_tokens: "4096", cache_control: "ephemeral" }
|
|
246
201
|
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
);
|
|
251
|
-
// → params: { max_tokens: "4096", cache_control: "ephemeral", cache_ttl: "5m" }
|
|
202
|
+
config.host; // "api.groq.com"
|
|
203
|
+
provider; // "groq"
|
|
204
|
+
```
|
|
252
205
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
);
|
|
259
|
-
// → params: { cache_control: "ephemeral", cache_ttl: "1h" }
|
|
206
|
+
Override any alias at deploy time:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
LLM_STRINGS_OPENAI_HOST="regional.openai.example.com"
|
|
210
|
+
LLM_STRINGS_BEDROCK_HOST="https://bedrock-runtime.us-west-2.amazonaws.com/model"
|
|
260
211
|
```
|
|
261
212
|
|
|
262
|
-
|
|
213
|
+
The alternate form `LLM_STRINGS_HOST_OPENAI` is also supported. Overrides may
|
|
214
|
+
include a scheme or path; only the host portion is used.
|
|
263
215
|
|
|
264
|
-
|
|
216
|
+
### Validate before calling the provider
|
|
265
217
|
|
|
266
218
|
```ts
|
|
267
|
-
import {
|
|
268
|
-
|
|
269
|
-
const { changes } = normalize(
|
|
270
|
-
parse(
|
|
271
|
-
"llm://generativelanguage.googleapis.com/gemini-3-flash-preview?temp=0.7&max=2000&topp=0.9",
|
|
272
|
-
),
|
|
273
|
-
{ verbose: true },
|
|
274
|
-
);
|
|
219
|
+
import { validate } from "llm-strings";
|
|
275
220
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
// temp → temperature (alias: "temp" → "temperature")
|
|
280
|
-
// max → max_tokens (alias: "max" → "max_tokens")
|
|
281
|
-
// max_tokens → maxOutputTokens (google uses "maxOutputTokens" instead of "max_tokens")
|
|
282
|
-
// topp → top_p (alias: "topp" → "top_p")
|
|
283
|
-
// top_p → topP (google uses "topP" instead of "top_p")
|
|
284
|
-
```
|
|
221
|
+
validate("llm://openai/gpt-4o?temp=3.0");
|
|
222
|
+
// [{ param: "temperature", message: "\"temperature\" must be <= 2, got 3", ... }]
|
|
285
223
|
|
|
286
|
-
|
|
224
|
+
validate("llm://openai/gpt-5.5?temp=0.7&max=2000");
|
|
225
|
+
// [] — temperature is a known unsupported reasoning-family param, so normalize() drops it
|
|
287
226
|
|
|
288
|
-
|
|
289
|
-
|
|
227
|
+
validate("llm://fal/fal-ai/flux-pro?future_model_param=1");
|
|
228
|
+
// [] — unknown params pass through by default for model-specific schemas
|
|
290
229
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
model: "gpt-5.2",
|
|
294
|
-
label: "my-app",
|
|
295
|
-
apiKey: "sk-proj-abc123",
|
|
296
|
-
params: { temperature: "0.7", max_tokens: "2000", stream: "true" },
|
|
297
|
-
});
|
|
298
|
-
// → "llm://my-app:sk-proj-abc123@api.openai.com/gpt-5.2?temperature=0.7&max_tokens=2000&stream=true"
|
|
230
|
+
validate("llm://fal/fal-ai/flux-pro?future_model_param=1", { strict: true });
|
|
231
|
+
// [{ param: "future_model_param", severity: "error", message: "Unknown param..." }]
|
|
299
232
|
```
|
|
300
233
|
|
|
301
|
-
###
|
|
234
|
+
### See exactly what changed
|
|
302
235
|
|
|
303
236
|
```ts
|
|
304
|
-
import {
|
|
305
|
-
import { detectBedrockModelFamily } from "llm-strings/providers";
|
|
237
|
+
import { normalize, parse } from "llm-strings";
|
|
306
238
|
|
|
307
|
-
const
|
|
308
|
-
"llm://
|
|
239
|
+
const { changes } = normalize(
|
|
240
|
+
parse("llm://google/gemini-3.5-flash?temp=0.7&max=2000&topp=0.9"),
|
|
241
|
+
{ verbose: true },
|
|
309
242
|
);
|
|
310
243
|
|
|
311
|
-
|
|
312
|
-
|
|
244
|
+
for (const change of changes) {
|
|
245
|
+
console.log(`${change.from} -> ${change.to} (${change.reason})`);
|
|
246
|
+
}
|
|
313
247
|
|
|
314
|
-
|
|
315
|
-
//
|
|
316
|
-
//
|
|
248
|
+
// temp -> temperature (alias: "temp" -> "temperature")
|
|
249
|
+
// max -> max_tokens (alias: "max" -> "max_tokens")
|
|
250
|
+
// max_tokens -> maxOutputTokens (google uses "maxOutputTokens" instead of "max_tokens")
|
|
251
|
+
// topp -> top_p (alias: "topp" -> "top_p")
|
|
252
|
+
// top_p -> topP (google uses "topP" instead of "top_p")
|
|
317
253
|
```
|
|
318
254
|
|
|
319
|
-
###
|
|
255
|
+
### Build AI SDK providerOptions
|
|
256
|
+
|
|
257
|
+
The AI SDK adapter lives on a separate sub-path so you only load it when you
|
|
258
|
+
need it:
|
|
320
259
|
|
|
321
260
|
```ts
|
|
322
|
-
|
|
261
|
+
const { createAiSdkProviderOptions } = await import("llm-strings/ai-sdk");
|
|
323
262
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
parse("llm://openrouter.ai/anthropic/claude-sonnet-4-5?temp=0.7&max=2000"),
|
|
263
|
+
const { providerOptions } = createAiSdkProviderOptions(
|
|
264
|
+
"llm://anthropic/claude-sonnet-4-5?cache=1h&effort=max",
|
|
327
265
|
);
|
|
328
|
-
// → params: { temperature: "0.7", max_tokens: "2000" }
|
|
329
266
|
|
|
330
|
-
//
|
|
331
|
-
|
|
332
|
-
//
|
|
333
|
-
//
|
|
267
|
+
// {
|
|
268
|
+
// anthropic: {
|
|
269
|
+
// cacheControl: { type: "ephemeral", ttl: "1h" },
|
|
270
|
+
// effort: "max"
|
|
271
|
+
// }
|
|
272
|
+
// }
|
|
334
273
|
```
|
|
335
274
|
|
|
336
|
-
|
|
275
|
+
Common generation settings like temperature, top-p, and max output tokens
|
|
276
|
+
belong on the AI SDK call itself. The helper emits provider-specific options
|
|
277
|
+
such as Anthropic cache control, Bedrock cache points, OpenAI reasoning options,
|
|
278
|
+
Mistral `safePrompt`, OpenRouter routing, and Vercel AI Gateway routing,
|
|
279
|
+
including options such as `order`, `sort=ttft`, and `caching=auto`.
|
|
280
|
+
|
|
281
|
+
### Build provider-aware UIs
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { CANONICAL_PARAM_SPECS, PROVIDER_META } from "llm-strings/providers";
|
|
337
285
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
| OpenAI | `api.openai.com` | snake_case |
|
|
341
|
-
| Anthropic | `api.anthropic.com` | snake_case |
|
|
342
|
-
| Google | `generativelanguage.googleapis.com` | camelCase |
|
|
343
|
-
| Mistral | `api.mistral.ai` | snake_case |
|
|
344
|
-
| Cohere | `api.cohere.com` | snake_case |
|
|
345
|
-
| AWS Bedrock | `bedrock-runtime.{region}.amazonaws.com` | camelCase |
|
|
346
|
-
| OpenRouter | `openrouter.ai` | snake_case |
|
|
347
|
-
| Vercel AI | `gateway.ai.vercel.app` | snake_case |
|
|
286
|
+
PROVIDER_META.map(({ id, name, host, color }) => ({ id, name, host, color }));
|
|
287
|
+
// [{ id: "openai", name: "OpenAI", host: "api.openai.com", color: "#10a37f" }, ...]
|
|
348
288
|
|
|
349
|
-
|
|
289
|
+
CANONICAL_PARAM_SPECS.anthropic.temperature;
|
|
290
|
+
// {
|
|
291
|
+
// type: "number",
|
|
292
|
+
// min: 0,
|
|
293
|
+
// max: 1,
|
|
294
|
+
// default: 0.7,
|
|
295
|
+
// description: "Controls randomness"
|
|
296
|
+
// }
|
|
297
|
+
```
|
|
350
298
|
|
|
351
|
-
##
|
|
299
|
+
## Supported Providers
|
|
352
300
|
|
|
353
|
-
|
|
301
|
+
`llm-strings` ships provider detection, host aliases, metadata, and parameter
|
|
302
|
+
normalization for the major LLM provider shapes. Chat-compatible providers get
|
|
303
|
+
canonical parameter mapping and validation; media and audio providers are
|
|
304
|
+
available for detection, metadata, aliases, and flexible AI SDK providerOptions.
|
|
305
|
+
|
|
306
|
+
| Category | Providers |
|
|
307
|
+
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
308
|
+
| Core chat + reasoning | OpenAI, Azure OpenAI, Anthropic, Google AI Studio, Google Vertex AI, Mistral, Cohere, AWS Bedrock, OpenRouter, Vercel AI Gateway |
|
|
309
|
+
| OpenAI-compatible APIs | xAI, Groq, DeepInfra, Together.ai, Fireworks, DeepSeek, Moonshot AI, Perplexity, Alibaba DashScope, Cerebras, Baseten, Hugging Face |
|
|
310
|
+
| Media, audio, and flexible | Fal, Black Forest Labs, Replicate, Prodia, Luma, ByteDance, Kling AI, ElevenLabs, AssemblyAI, Deepgram, Gladia, LMNT, Hume, Rev.ai |
|
|
311
|
+
| Extra aliases and endpoints | `aistudio`, `vertex`, `grok`, `bfl`, `dashscope`, `alibabacloud`, `togetherai`, `fireworksai`, `moonshot`, `wandb`, `weightsandbiases`, `baidu`, `qianfan`, `venice`, `parasail`, `novita`, `atlascloud`, `xiaomi`, `minimax` |
|
|
312
|
+
|
|
313
|
+
### Provider table
|
|
314
|
+
|
|
315
|
+
| Provider ID | Default host | Param style |
|
|
316
|
+
| ------------------- | ----------------------------------------- | ----------------- |
|
|
317
|
+
| `openai` | `api.openai.com` | snake_case |
|
|
318
|
+
| `azure` | `models.inference.ai.azure.com` | OpenAI-compatible |
|
|
319
|
+
| `anthropic` | `api.anthropic.com` | snake_case |
|
|
320
|
+
| `google` | `generativelanguage.googleapis.com` | camelCase |
|
|
321
|
+
| `google-vertex` | `aiplatform.googleapis.com` | camelCase |
|
|
322
|
+
| `mistral` | `api.mistral.ai` | snake_case |
|
|
323
|
+
| `cohere` | `api.cohere.com` | mixed |
|
|
324
|
+
| `bedrock` | `bedrock-runtime.us-east-1.amazonaws.com` | camelCase |
|
|
325
|
+
| `openrouter` | `openrouter.ai` | OpenAI-compatible |
|
|
326
|
+
| `vercel` | `gateway.ai.vercel.app` | OpenAI-compatible |
|
|
327
|
+
| `xai` | `api.x.ai` | OpenAI-compatible |
|
|
328
|
+
| `groq` | `api.groq.com` | OpenAI-compatible |
|
|
329
|
+
| `fal` | `fal.run` | flexible |
|
|
330
|
+
| `deepinfra` | `api.deepinfra.com` | OpenAI-compatible |
|
|
331
|
+
| `black-forest-labs` | `api.bfl.ai` | flexible |
|
|
332
|
+
| `together` | `api.together.xyz` | OpenAI-compatible |
|
|
333
|
+
| `fireworks` | `api.fireworks.ai` | OpenAI-compatible |
|
|
334
|
+
| `deepseek` | `api.deepseek.com` | OpenAI-compatible |
|
|
335
|
+
| `moonshotai` | `api.moonshot.ai` | OpenAI-compatible |
|
|
336
|
+
| `perplexity` | `api.perplexity.ai` | OpenAI-compatible |
|
|
337
|
+
| `alibaba` | `dashscope-intl.aliyuncs.com` | OpenAI-compatible |
|
|
338
|
+
| `cerebras` | `api.cerebras.ai` | OpenAI-compatible |
|
|
339
|
+
| `replicate` | `api.replicate.com` | flexible |
|
|
340
|
+
| `prodia` | `api.prodia.com` | flexible |
|
|
341
|
+
| `luma` | `api.lumalabs.ai` | flexible |
|
|
342
|
+
| `bytedance` | `ark.cn-beijing.volces.com` | flexible |
|
|
343
|
+
| `kling` | `api.klingai.com` | flexible |
|
|
344
|
+
| `elevenlabs` | `api.elevenlabs.io` | flexible |
|
|
345
|
+
| `assemblyai` | `api.assemblyai.com` | flexible |
|
|
346
|
+
| `deepgram` | `api.deepgram.com` | flexible |
|
|
347
|
+
| `gladia` | `api.gladia.io` | flexible |
|
|
348
|
+
| `lmnt` | `api.lmnt.com` | flexible |
|
|
349
|
+
| `hume` | `api.hume.ai` | flexible |
|
|
350
|
+
| `revai` | `api.rev.ai` | flexible |
|
|
351
|
+
| `baseten` | `api.baseten.co` | OpenAI-compatible |
|
|
352
|
+
| `huggingface` | `api-inference.huggingface.co` | OpenAI-compatible |
|
|
353
|
+
|
|
354
|
+
## Shorthand aliases
|
|
355
|
+
|
|
356
|
+
Use short, memorable query params. `normalize()` expands them first, then maps
|
|
357
|
+
them to provider-native names.
|
|
354
358
|
|
|
355
359
|
| Shorthand | Canonical |
|
|
356
360
|
| ------------------------------------------------------------------------------------------------------------ | ------------------- |
|
|
@@ -366,21 +370,48 @@ Use these shortcuts in your connection strings — they expand automatically dur
|
|
|
366
370
|
| `reasoning`, `reasoning_effort` | `effort` |
|
|
367
371
|
| `cache_control`, `cacheControl`, `cachePoint`, `cache_point` | `cache` |
|
|
368
372
|
|
|
369
|
-
##
|
|
373
|
+
## Prompt caching
|
|
370
374
|
|
|
371
|
-
|
|
375
|
+
```ts
|
|
376
|
+
import { normalize, parse } from "llm-strings";
|
|
377
|
+
|
|
378
|
+
normalize(parse("llm://anthropic/claude-sonnet-4-5?max=4096&cache=true")).config
|
|
379
|
+
.params;
|
|
380
|
+
// { max_tokens: "4096", cache_control: "ephemeral" }
|
|
381
|
+
|
|
382
|
+
normalize(parse("llm://anthropic/claude-sonnet-4-5?max=4096&cache=5m")).config
|
|
383
|
+
.params;
|
|
384
|
+
// { max_tokens: "4096", cache_control: "ephemeral", cache_ttl: "5m" }
|
|
385
|
+
|
|
386
|
+
normalize(
|
|
387
|
+
parse("llm://bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0?cache=1h"),
|
|
388
|
+
).config.params;
|
|
389
|
+
// { cache_control: "ephemeral", cache_ttl: "1h" }
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Caching currently normalizes for Anthropic and supported Bedrock models. For
|
|
393
|
+
Anthropic, `cache=5m` and `cache=1h` are both supported. For Bedrock, support is
|
|
394
|
+
model-family specific and currently covers Claude and Amazon Nova models. For
|
|
395
|
+
providers where caching is automatic, unsupported, or provider-specific in a way
|
|
396
|
+
that should not be represented as a generation param, `cache` is dropped during
|
|
397
|
+
normalization.
|
|
398
|
+
|
|
399
|
+
## Sub-path imports
|
|
372
400
|
|
|
373
401
|
```ts
|
|
374
|
-
import {
|
|
402
|
+
import { build, parse } from "llm-strings/parse";
|
|
375
403
|
import { normalize } from "llm-strings/normalize";
|
|
376
404
|
import { validate } from "llm-strings/validate";
|
|
405
|
+
import { createAiSdkProviderOptions } from "llm-strings/ai-sdk";
|
|
377
406
|
import {
|
|
378
|
-
detectProvider,
|
|
379
|
-
resolveHostAlias,
|
|
380
407
|
ALIASES,
|
|
408
|
+
CANONICAL_PARAM_SPECS,
|
|
381
409
|
HOST_ALIASES,
|
|
382
|
-
PROVIDER_PARAMS,
|
|
383
410
|
PARAM_SPECS,
|
|
411
|
+
PROVIDER_META,
|
|
412
|
+
PROVIDER_PARAMS,
|
|
413
|
+
detectProvider,
|
|
414
|
+
resolveHostAlias,
|
|
384
415
|
} from "llm-strings/providers";
|
|
385
416
|
```
|
|
386
417
|
|
|
@@ -390,151 +421,120 @@ All sub-paths ship ESM + CJS with full type declarations.
|
|
|
390
421
|
|
|
391
422
|
### `parse(connectionString): LlmConnectionConfig`
|
|
392
423
|
|
|
393
|
-
Parses an `llm://` connection string into
|
|
424
|
+
Parses an `llm://` connection string into structured config. Throws when the
|
|
425
|
+
scheme is not `llm://`.
|
|
394
426
|
|
|
395
427
|
### `build(config): string`
|
|
396
428
|
|
|
397
|
-
|
|
429
|
+
Builds an `llm://` connection string from a config object. This is the inverse
|
|
430
|
+
of `parse()`.
|
|
398
431
|
|
|
399
432
|
### `normalize(config, options?): NormalizeResult`
|
|
400
433
|
|
|
401
|
-
Normalizes
|
|
434
|
+
Normalizes params for the detected provider:
|
|
402
435
|
|
|
403
|
-
1. Expands shorthand aliases
|
|
404
|
-
2. Maps to provider-specific
|
|
405
|
-
|
|
406
|
-
|
|
436
|
+
1. Expands shorthand aliases such as `temp` -> `temperature`.
|
|
437
|
+
2. Maps canonical names to provider-specific names such as `max_tokens` ->
|
|
438
|
+
`maxOutputTokens` for Google.
|
|
439
|
+
3. Normalizes cache values such as `cache=5m` -> `cache_control=ephemeral` and
|
|
440
|
+
`cache_ttl=5m`.
|
|
441
|
+
4. Adjusts OpenAI reasoning-family params such as `max_tokens` ->
|
|
442
|
+
`max_completion_tokens` and drops known unsupported sampling params.
|
|
407
443
|
|
|
408
|
-
Pass `{ verbose: true }` to get a
|
|
444
|
+
Pass `{ verbose: true }` to get a `changes` array that documents each
|
|
445
|
+
transformation.
|
|
409
446
|
|
|
410
447
|
### `validate(connectionString, options?): ValidationIssue[]`
|
|
411
448
|
|
|
412
|
-
Parses, normalizes, and validates a connection string
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
-
|
|
416
|
-
|
|
417
|
-
- Reasoning model restrictions (no `temperature` on o1/o3/o4)
|
|
418
|
-
- Bedrock model family constraints (`topK` only for Claude/Cohere/Mistral)
|
|
419
|
-
|
|
420
|
-
Pass `{ strict: true }` to promote warnings (unknown provider, unknown params) to errors:
|
|
421
|
-
|
|
422
|
-
```ts
|
|
423
|
-
validate("llm://custom-api.com/my-model?temp=0.5", { strict: true });
|
|
424
|
-
// → [{ severity: "error", message: "Unknown provider …" }]
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
### `detectProvider(host): Provider | undefined`
|
|
428
|
-
|
|
429
|
-
Identifies the provider from a hostname string.
|
|
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
|
-
|
|
435
|
-
### `detectBedrockModelFamily(model): BedrockModelFamily | undefined`
|
|
436
|
-
|
|
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.
|
|
438
|
-
|
|
439
|
-
### `detectGatewaySubProvider(model): Provider | undefined`
|
|
440
|
-
|
|
441
|
-
Extracts the underlying provider from a gateway model string (e.g. `"anthropic/claude-sonnet-4-5"` → `"anthropic"`). Returns `undefined` for unknown prefixes or models without a `/`.
|
|
442
|
-
|
|
443
|
-
### `isReasoningModel(model): boolean`
|
|
444
|
-
|
|
445
|
-
Returns `true` for OpenAI reasoning models (o1, o3, o4 families). Handles gateway prefixes like `"openai/o3"`.
|
|
449
|
+
Parses, normalizes, and validates a connection string. Returns `[]` when the
|
|
450
|
+
config is valid. Checks include type correctness, numeric ranges, enum values,
|
|
451
|
+
unknown providers, Anthropic `temperature` + `top_p` mutual exclusion,
|
|
452
|
+
OpenAI reasoning-family normalization, and Bedrock model-family rules. Unknown
|
|
453
|
+
params are allowed by default so new model-specific schemas can pass through.
|
|
446
454
|
|
|
447
|
-
|
|
455
|
+
Pass `{ strict: true }` to report unknown providers or unknown params as
|
|
456
|
+
errors.
|
|
448
457
|
|
|
449
|
-
|
|
458
|
+
### `createAiSdkProviderOptions(input, options?): AiSdkProviderOptionsResult`
|
|
450
459
|
|
|
451
|
-
|
|
460
|
+
Creates AI SDK `providerOptions` from a string, parsed config, or normalize
|
|
461
|
+
result. Import from `llm-strings/ai-sdk`.
|
|
452
462
|
|
|
453
|
-
|
|
463
|
+
### Provider helpers
|
|
454
464
|
|
|
455
|
-
|
|
465
|
+
Import from `llm-strings/providers`:
|
|
456
466
|
|
|
457
|
-
|
|
467
|
+
| Export | Description |
|
|
468
|
+
| ------------------------------- | ------------------------------------------------------------------------------------- |
|
|
469
|
+
| `detectProvider(host)` | Detects provider from hostname. |
|
|
470
|
+
| `resolveHostAlias(host)` | Expands aliases and applies `LLM_STRINGS_*_HOST` overrides. |
|
|
471
|
+
| `detectBedrockModelFamily()` | Detects Anthropic, Meta, Amazon, Mistral, Cohere, or AI21 Bedrock families. |
|
|
472
|
+
| `detectGatewaySubProvider()` | Extracts provider prefix from gateway models like `anthropic/claude...`. |
|
|
473
|
+
| `isReasoningModel(model)` | Detects OpenAI GPT-5 and o-series reasoning models, including gateway-prefixed names. |
|
|
474
|
+
| `isGatewayProvider(provider)` | Returns true for `openrouter` and `vercel`. |
|
|
475
|
+
| `canHostOpenAIModels(provider)` | Returns true for providers that need OpenAI reasoning-model checks. |
|
|
476
|
+
| `bedrockSupportsCaching(model)` | Returns true for Bedrock Claude and Nova prompt caching support. |
|
|
458
477
|
|
|
459
478
|
### Constants
|
|
460
479
|
|
|
461
|
-
| Export | Description
|
|
462
|
-
| ----------------------------- |
|
|
463
|
-
| `ALIASES` | Shorthand
|
|
464
|
-
| `HOST_ALIASES` | Short provider host aliases
|
|
465
|
-
| `PROVIDER_PARAMS` | Canonical
|
|
466
|
-
| `PARAM_SPECS` | Validation rules
|
|
467
|
-
| `REASONING_MODEL_UNSUPPORTED` |
|
|
468
|
-
| `PROVIDER_META` |
|
|
469
|
-
| `
|
|
470
|
-
| `CANONICAL_PARAM_SPECS` | Canonical param specs per provider with descriptions — useful for building UIs |
|
|
480
|
+
| Export | Description |
|
|
481
|
+
| ----------------------------- | ------------------------------------------------------------------------------- |
|
|
482
|
+
| `ALIASES` | Shorthand -> canonical param name mapping. |
|
|
483
|
+
| `HOST_ALIASES` | Short provider host aliases -> canonical API hosts. |
|
|
484
|
+
| `PROVIDER_PARAMS` | Canonical -> provider-specific param names, per provider. |
|
|
485
|
+
| `PARAM_SPECS` | Validation rules keyed by provider-specific param name. |
|
|
486
|
+
| `REASONING_MODEL_UNSUPPORTED` | Canonical params unsupported by OpenAI reasoning models. |
|
|
487
|
+
| `PROVIDER_META` | Provider metadata for UI integrations. |
|
|
488
|
+
| `CANONICAL_PARAM_SPECS` | Canonical param specs per provider, useful for building forms and settings UIs. |
|
|
471
489
|
|
|
472
490
|
## TypeScript
|
|
473
491
|
|
|
474
|
-
Full type definitions ship with the package:
|
|
475
|
-
|
|
476
492
|
```ts
|
|
477
|
-
// Core types from the main entry
|
|
478
493
|
import type {
|
|
479
494
|
LlmConnectionConfig,
|
|
480
|
-
NormalizeResult,
|
|
481
495
|
NormalizeChange,
|
|
482
496
|
NormalizeOptions,
|
|
497
|
+
NormalizeResult,
|
|
483
498
|
ValidateOptions,
|
|
484
499
|
ValidationIssue,
|
|
485
500
|
} from "llm-strings";
|
|
486
501
|
|
|
487
|
-
// Provider types from the providers sub-path
|
|
488
502
|
import type {
|
|
489
|
-
Provider,
|
|
490
503
|
BedrockModelFamily,
|
|
504
|
+
CanonicalParamSpec,
|
|
491
505
|
ParamSpec,
|
|
506
|
+
Provider,
|
|
492
507
|
ProviderMeta,
|
|
493
|
-
CanonicalParamSpec,
|
|
494
508
|
} from "llm-strings/providers";
|
|
495
509
|
```
|
|
496
510
|
|
|
497
|
-
##
|
|
498
|
-
|
|
499
|
-
The library exports metadata useful for building UIs — provider names, brand colors, suggested models, and canonical parameter specs:
|
|
511
|
+
## Development
|
|
500
512
|
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
} from "llm-strings/providers";
|
|
507
|
-
|
|
508
|
-
// Provider display info
|
|
509
|
-
PROVIDER_META.forEach((p) => console.log(`${p.name}: ${p.host} (${p.color})`));
|
|
510
|
-
// OpenAI: api.openai.com (#10a37f)
|
|
511
|
-
// Anthropic: api.anthropic.com (#e8956a)
|
|
512
|
-
// ...
|
|
513
|
-
|
|
514
|
-
// Suggested models per provider
|
|
515
|
-
MODELS.openai; // → ["gpt-5.2", "gpt-5.2-pro", "gpt-4.1", "gpt-4.1-mini", ...]
|
|
516
|
-
MODELS.anthropic; // → ["claude-opus-4-6", "claude-sonnet-4-6", "claude-sonnet-4-5", ...]
|
|
517
|
-
|
|
518
|
-
// Canonical param specs — useful for building config forms
|
|
519
|
-
CANONICAL_PARAM_SPECS.openai.temperature;
|
|
520
|
-
// → { type: "number", min: 0, max: 2, default: 0.7, description: "Controls randomness" }
|
|
521
|
-
|
|
522
|
-
CANONICAL_PARAM_SPECS.anthropic.effort;
|
|
523
|
-
// → { type: "enum", values: ["low", "medium", "high", "max"], default: "medium", description: "Thinking effort" }
|
|
513
|
+
```bash
|
|
514
|
+
pnpm install
|
|
515
|
+
pnpm test
|
|
516
|
+
pnpm run build
|
|
517
|
+
pnpm run lint
|
|
524
518
|
```
|
|
525
519
|
|
|
520
|
+
This package is intentionally small: pure TypeScript, zero runtime dependencies,
|
|
521
|
+
and focused tests for parsing, normalization, validation, provider metadata,
|
|
522
|
+
Bedrock behavior, gateway behavior, and AI SDK providerOptions.
|
|
523
|
+
|
|
526
524
|
## Contributing
|
|
527
525
|
|
|
528
|
-
|
|
526
|
+
Issues and pull requests are welcome. Good contributions include new provider
|
|
527
|
+
aliases, provider-specific validation rules, improved normalization mappings,
|
|
528
|
+
AI SDK providerOptions coverage, docs fixes, and real-world edge cases.
|
|
529
529
|
|
|
530
530
|
## License
|
|
531
531
|
|
|
532
|
-
MIT
|
|
532
|
+
MIT © Dan Levy
|
|
533
533
|
|
|
534
534
|
---
|
|
535
535
|
|
|
536
536
|
<div align="center">
|
|
537
537
|
|
|
538
|
-
**[
|
|
538
|
+
**[Read the spec](https://danlevy.net/llm-connection-strings/) · [Report a bug](https://github.com/justsml/llm-strings/issues) · [Request a feature](https://github.com/justsml/llm-strings/issues)**
|
|
539
539
|
|
|
540
540
|
</div>
|