ai-sdk-provider-env 0.2.0 → 0.4.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/README.md +69 -240
- package/dist/index.cjs +154 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +139 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +139 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +154 -40
- package/dist/index.mjs.map +1 -1
- package/llms.txt +180 -0
- package/package.json +11 -25
package/README.md
CHANGED
|
@@ -1,60 +1,38 @@
|
|
|
1
|
-
> [中文](./README_zh.md)
|
|
1
|
+
> [For AI agent (llms.txt)](./llms.txt) | [中文](./README_zh.md)
|
|
2
2
|
|
|
3
3
|
# ai-sdk-provider-env
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Environment-variable-driven provider for [Vercel AI SDK](https://sdk.vercel.ai/). Switch AI providers and models without code changes.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/ai-sdk-provider-env)
|
|
8
8
|
[](./LICENSE)
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
Using multiple AI providers with Vercel AI SDK means importing each SDK, configuring API keys and base URLs, and wiring everything together — per provider, per project. Switching providers requires code changes.
|
|
13
|
-
|
|
14
|
-
`ai-sdk-provider-env` eliminates this boilerplate. Define provider configurations through environment variables, resolve them at runtime. Add a new provider by setting env vars, switch models by changing a string — no code changes needed.
|
|
15
|
-
|
|
16
|
-
## Features
|
|
17
|
-
|
|
18
|
-
- Resolve provider config (base URL, API key, compatibility mode) from environment variables automatically
|
|
19
|
-
- Built-in presets for popular providers, so you only need to set an API key
|
|
20
|
-
- Supports OpenAI, Anthropic, Google Gemini, and any OpenAI-compatible API
|
|
21
|
-
- Implements `ProviderV3`, plugs directly into `createProviderRegistry`
|
|
22
|
-
- Provider instances are cached, no redundant initialization
|
|
23
|
-
- Fully customizable: custom fetch, env-based headers, custom separator, code-based configs
|
|
24
|
-
|
|
25
|
-
## Installation
|
|
10
|
+
## Quick Start
|
|
26
11
|
|
|
27
12
|
```bash
|
|
28
13
|
pnpm add ai-sdk-provider-env
|
|
29
14
|
```
|
|
30
15
|
|
|
31
|
-
Install provider SDKs as needed:
|
|
32
|
-
|
|
33
16
|
```bash
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
pnpm add @ai-sdk/google # for Google AI Studio (Gemini)
|
|
37
|
-
pnpm add @ai-sdk/openai-compatible # for generic OpenAI-compatible APIs
|
|
17
|
+
# .env
|
|
18
|
+
OPENAI_API_KEY=sk-xxx
|
|
38
19
|
```
|
|
39
20
|
|
|
40
|
-
## Quick Start
|
|
41
|
-
|
|
42
21
|
```ts
|
|
43
|
-
import {
|
|
22
|
+
import { generateText } from 'ai'
|
|
44
23
|
import { envProvider } from 'ai-sdk-provider-env'
|
|
45
24
|
|
|
46
|
-
const
|
|
47
|
-
env: envProvider(),
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
// Use a preset: only API_KEY is required
|
|
51
|
-
// OPENAI_API_KEY=sk-xxx (OPENAI_PRESET=openai is optional — auto-detected)
|
|
52
|
-
const model = registry.languageModel('env:openai/gpt-4o')
|
|
25
|
+
const provider = envProvider()
|
|
53
26
|
|
|
54
|
-
const { text } = await generateText({
|
|
27
|
+
const { text } = await generateText({
|
|
28
|
+
model: provider.languageModel('openai/gpt-4o'),
|
|
29
|
+
prompt: 'Hello!',
|
|
30
|
+
})
|
|
55
31
|
```
|
|
56
32
|
|
|
57
|
-
|
|
33
|
+
The config set name `openai` auto-matches the built-in preset — only an API key is needed.
|
|
34
|
+
|
|
35
|
+
Any [valid](#environment-variables) env var prefix becomes a config set. Two endpoints, zero code changes:
|
|
58
36
|
|
|
59
37
|
```bash
|
|
60
38
|
# .env
|
|
@@ -66,235 +44,86 @@ SMART_API_KEY=key-smart
|
|
|
66
44
|
```
|
|
67
45
|
|
|
68
46
|
```ts
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
prompt: 'Write a story',
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
const review = await generateText({
|
|
75
|
-
model: registry.languageModel('env:smart/gpt-4o'),
|
|
76
|
-
prompt: `Review this: ${draft.text}`,
|
|
77
|
-
})
|
|
47
|
+
provider.languageModel('fast/llama-3-8b')
|
|
48
|
+
provider.languageModel('smart/gpt-4o')
|
|
78
49
|
```
|
|
79
50
|
|
|
80
|
-
## Environment
|
|
51
|
+
## Environment Variables
|
|
81
52
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
With the default separator `_`, a config set reads these variables (`[MYAI]` = your config set name, uppercased):
|
|
85
|
-
|
|
86
|
-
| Variable | Required | Description |
|
|
87
|
-
|---|---|---|
|
|
88
|
-
| `[MYAI]_API_KEY` | Yes | API key |
|
|
89
|
-
| `[MYAI]_BASE_URL` | Yes (unless preset is set or auto-detected) | API base URL |
|
|
90
|
-
| `[MYAI]_PRESET` | No | Built-in preset name (e.g. `openai`) |
|
|
91
|
-
| `[MYAI]_COMPATIBLE` | No | Compatibility mode (default: `openai-compatible`) |
|
|
92
|
-
| `[MYAI]_HEADERS` | No | Custom HTTP headers (JSON format) |
|
|
53
|
+
Model ID format: `{configSet}/{modelId}`. The config set maps to an uppercased env var prefix.
|
|
93
54
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
**Compatibility modes:**
|
|
97
|
-
|
|
98
|
-
| Value | Behavior |
|
|
99
|
-
|---|---|
|
|
100
|
-
| `openai` | Uses `@ai-sdk/openai` |
|
|
101
|
-
| `anthropic` | Uses `@ai-sdk/anthropic` |
|
|
102
|
-
| `gemini` | Uses `@ai-sdk/google` |
|
|
103
|
-
| `openai-compatible` | Uses `@ai-sdk/openai-compatible` with the config set name as the provider name (default) |
|
|
104
|
-
|
|
105
|
-
## Built-in Presets
|
|
106
|
-
|
|
107
|
-
| Preset name | Base URL | Compatible |
|
|
108
|
-
|---|---|---|
|
|
109
|
-
| `openai` | `https://api.openai.com/v1` | `openai` |
|
|
110
|
-
| `anthropic` | `https://api.anthropic.com` | `anthropic` |
|
|
111
|
-
| `google` | `https://generativelanguage.googleapis.com/v1beta` | `gemini` |
|
|
112
|
-
| `deepseek` | `https://api.deepseek.com` | `openai-compatible` |
|
|
113
|
-
| `zhipu` | `https://open.bigmodel.cn/api/paas/v4` | `openai-compatible` |
|
|
114
|
-
| `groq` | `https://api.groq.com/openai/v1` | `openai-compatible` |
|
|
115
|
-
| `together` | `https://api.together.xyz/v1` | `openai-compatible` |
|
|
116
|
-
| `fireworks` | `https://api.fireworks.ai/inference/v1` | `openai-compatible` |
|
|
117
|
-
| `mistral` | `https://api.mistral.ai/v1` | `openai-compatible` |
|
|
118
|
-
| `moonshot` | `https://api.moonshot.cn/v1` | `openai-compatible` |
|
|
119
|
-
| `perplexity` | `https://api.perplexity.ai` | `openai-compatible` |
|
|
120
|
-
| `openrouter` | `https://openrouter.ai/api/v1` | `openai-compatible` |
|
|
121
|
-
| `siliconflow` | `https://api.siliconflow.cn/v1` | `openai-compatible` |
|
|
122
|
-
|
|
123
|
-
## Preset Auto-Detect
|
|
124
|
-
|
|
125
|
-
`presetAutoDetect` is enabled by default. When the config set name exactly matches a built-in preset name, the preset is applied automatically — no `_PRESET` env var needed. Only an API key is required:
|
|
55
|
+
Config set names must match `[A-Za-z_][A-Za-z0-9_-]*` — ASCII letters, digits, underscores, and hyphens. **Hyphens are automatically normalized to underscores** for env var lookup:
|
|
126
56
|
|
|
127
57
|
```bash
|
|
128
|
-
#
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```ts
|
|
133
|
-
const provider = envProvider()
|
|
134
|
-
|
|
135
|
-
// Works — openrouter preset auto-detected from config set name
|
|
136
|
-
const model = provider.languageModel('openrouter/some-model')
|
|
58
|
+
# Config set "my-api" → reads MY_API_* env vars
|
|
59
|
+
MY_API_BASE_URL=https://api.example.com/v1
|
|
60
|
+
MY_API_API_KEY=sk-xxx
|
|
137
61
|
```
|
|
138
62
|
|
|
139
|
-
Explicit `_PRESET` and `_BASE_URL` env vars always take precedence over auto-detect. To disable this behavior:
|
|
140
|
-
|
|
141
63
|
```ts
|
|
142
|
-
|
|
64
|
+
provider.languageModel('my-api/some-model') // reads MY_API_* env vars
|
|
65
|
+
provider.languageModel('my_api/some-model') // same env vars
|
|
143
66
|
```
|
|
144
67
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
### `envProvider(options?)`
|
|
148
|
-
|
|
149
|
-
Returns a `ProviderV3` instance.
|
|
150
|
-
|
|
151
|
-
```ts
|
|
152
|
-
import { envProvider } from 'ai-sdk-provider-env'
|
|
153
|
-
|
|
154
|
-
const provider = envProvider(options)
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Options** (`EnvProviderOptions`):
|
|
158
|
-
|
|
159
|
-
| Option | Type | Default | Description |
|
|
160
|
-
|---|---|---|---|
|
|
161
|
-
| `separator` | `string` | `'_'` | Separator between the prefix and the variable name |
|
|
162
|
-
| `configs` | `Record<string, ConfigSetEntry>` | `undefined` | Explicit config sets (takes precedence over env vars) |
|
|
163
|
-
| `defaults` | `EnvProviderDefaults` | `undefined` | Global defaults applied to all providers (can be overridden per config set) |
|
|
164
|
-
| `presetAutoDetect` | `boolean` | `true` | Auto-apply a built-in preset when the config set name matches. Set to `false` to require explicit `_PRESET` configuration. |
|
|
165
|
-
|
|
166
|
-
**`EnvProviderDefaults`:**
|
|
167
|
-
|
|
168
|
-
| Option | Type | Default | Description |
|
|
169
|
-
|---|---|---|---|
|
|
170
|
-
| `fetch` | `typeof globalThis.fetch` | `undefined` | Custom fetch implementation passed to all created providers |
|
|
171
|
-
| `headers` | `Record<string, string>` | `undefined` | Default HTTP headers for all providers (overridden by config-set headers) |
|
|
172
|
-
|
|
173
|
-
**`ConfigSetEntry`:**
|
|
68
|
+
> For config set names outside these rules (e.g. Unicode, dots), use the [`configs` option](./docs/advanced.md#code-based-configs) instead.
|
|
174
69
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
**Model ID format:**
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
{configSet}/{modelId}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Examples: `openai/gpt-4o`, `anthropic/claude-sonnet-4-20250514`, `myapi/some-model`.
|
|
192
|
-
|
|
193
|
-
## Advanced Usage
|
|
194
|
-
|
|
195
|
-
### Custom separator
|
|
196
|
-
|
|
197
|
-
If single underscores conflict with your naming scheme, use double underscores or any other string:
|
|
198
|
-
|
|
199
|
-
```ts
|
|
200
|
-
const provider = envProvider({ separator: '__' })
|
|
201
|
-
|
|
202
|
-
// Now reads: OPENAI__BASE_URL, OPENAI__API_KEY, OPENAI__PRESET, OPENAI__COMPATIBLE
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Code-based configs
|
|
206
|
-
|
|
207
|
-
Skip env vars entirely and pass config directly. This takes the highest precedence:
|
|
208
|
-
|
|
209
|
-
```ts
|
|
210
|
-
const provider = envProvider({
|
|
211
|
-
configs: {
|
|
212
|
-
openai: {
|
|
213
|
-
baseURL: 'https://api.openai.com/v1',
|
|
214
|
-
apiKey: process.env.OPENAI_KEY!,
|
|
215
|
-
compatible: 'openai',
|
|
216
|
-
},
|
|
217
|
-
claude: {
|
|
218
|
-
baseURL: 'https://api.anthropic.com',
|
|
219
|
-
apiKey: process.env.ANTHROPIC_KEY!,
|
|
220
|
-
compatible: 'anthropic',
|
|
221
|
-
},
|
|
222
|
-
deepseek: {
|
|
223
|
-
preset: 'deepseek',
|
|
224
|
-
apiKey: process.env.DEEPSEEK_KEY!,
|
|
225
|
-
},
|
|
226
|
-
},
|
|
227
|
-
})
|
|
228
|
-
|
|
229
|
-
const model = provider.languageModel('openai/gpt-4o')
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Custom fetch
|
|
233
|
-
|
|
234
|
-
Pass a custom fetch implementation to all providers. Useful for proxies, logging, or test mocks:
|
|
70
|
+
| Variable | Required | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `{PREFIX}_API_KEY` | Yes | API key |
|
|
73
|
+
| `{PREFIX}_BASE_URL` | Unless preset matches | API base URL |
|
|
74
|
+
| `{PREFIX}_PRESET` | No | Built-in preset name (e.g. `openai`) |
|
|
75
|
+
| `{PREFIX}_COMPATIBLE` | No | `openai` · `anthropic` · `gemini` · `openai-compatible` (default) |
|
|
76
|
+
| `{PREFIX}_HEADERS` | No | Custom HTTP headers (JSON) |
|
|
235
77
|
|
|
236
|
-
|
|
237
|
-
const provider = envProvider({ defaults: { fetch: myCustomFetch } })
|
|
238
|
-
```
|
|
78
|
+
When `_PRESET` is set or [auto-detected](#built-in-presets), `_BASE_URL` and `_COMPATIBLE` fall back to preset defaults.
|
|
239
79
|
|
|
240
|
-
###
|
|
80
|
+
### Compatibility modes
|
|
241
81
|
|
|
242
|
-
|
|
82
|
+
| Value | SDK | Fallback |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `openai` | `@ai-sdk/openai` | `@ai-sdk/openai-compatible` if not installed |
|
|
85
|
+
| `anthropic` | `@ai-sdk/anthropic` | None |
|
|
86
|
+
| `gemini` | `@ai-sdk/google` | None |
|
|
87
|
+
| `openai-compatible` | `@ai-sdk/openai-compatible` (default) | — |
|
|
243
88
|
|
|
244
|
-
|
|
245
|
-
const provider = envProvider({
|
|
246
|
-
defaults: {
|
|
247
|
-
headers: { 'X-App-Name': 'my-app', 'X-Request-Source': 'server' },
|
|
248
|
-
},
|
|
249
|
-
})
|
|
250
|
-
```
|
|
89
|
+
Install provider SDKs as needed: `pnpm add @ai-sdk/openai @ai-sdk/anthropic @ai-sdk/google`
|
|
251
90
|
|
|
252
|
-
|
|
91
|
+
## Built-in Presets
|
|
253
92
|
|
|
254
|
-
|
|
93
|
+
When the config set name matches a preset, it auto-applies — only `_API_KEY` is needed:
|
|
255
94
|
|
|
256
95
|
```bash
|
|
257
|
-
|
|
96
|
+
DEEPSEEK_API_KEY=sk-xxx # config set "deepseek" matches the preset
|
|
258
97
|
```
|
|
259
98
|
|
|
260
|
-
These headers are merged into every request made by that config set's provider. When combined with `defaults.headers`, config-set headers take precedence for the same key.
|
|
261
|
-
|
|
262
|
-
### Using with `createProviderRegistry`
|
|
263
|
-
|
|
264
|
-
`envProvider()` implements `ProviderV3`, so it works directly with `createProviderRegistry`:
|
|
265
|
-
|
|
266
99
|
```ts
|
|
267
|
-
|
|
268
|
-
import { envProvider } from 'ai-sdk-provider-env'
|
|
269
|
-
|
|
270
|
-
const registry = createProviderRegistry({
|
|
271
|
-
env: envProvider(),
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
// Language model
|
|
275
|
-
const model = registry.languageModel('env:openai/gpt-4o')
|
|
276
|
-
|
|
277
|
-
// Embedding model
|
|
278
|
-
const embedder = registry.embeddingModel('env:openai/text-embedding-3-small')
|
|
279
|
-
|
|
280
|
-
// Image model
|
|
281
|
-
const imageModel = registry.imageModel('env:openai/dall-e-3')
|
|
282
|
-
|
|
283
|
-
const { text } = await generateText({
|
|
284
|
-
model,
|
|
285
|
-
prompt: 'Hello!',
|
|
286
|
-
})
|
|
100
|
+
provider.languageModel('deepseek/deepseek-chat') // just works
|
|
287
101
|
```
|
|
288
102
|
|
|
289
|
-
|
|
103
|
+
| Preset | Base URL | Compatible |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `openai` | `https://api.openai.com/v1` | `openai` |
|
|
106
|
+
| `anthropic` | `https://api.anthropic.com` | `anthropic` |
|
|
107
|
+
| `google` | `https://generativelanguage.googleapis.com/v1beta` | `gemini` |
|
|
108
|
+
| `deepseek` | `https://api.deepseek.com` | `openai-compatible` |
|
|
109
|
+
| `groq` | `https://api.groq.com/openai/v1` | `openai-compatible` |
|
|
110
|
+
| `together` | `https://api.together.xyz/v1` | `openai-compatible` |
|
|
111
|
+
| `fireworks` | `https://api.fireworks.ai/inference/v1` | `openai-compatible` |
|
|
112
|
+
| `mistral` | `https://api.mistral.ai/v1` | `openai-compatible` |
|
|
113
|
+
| `moonshot` | `https://api.moonshot.ai/v1` | `openai-compatible` |
|
|
114
|
+
| `moonshot-china` | `https://api.moonshot.cn/v1` | `openai-compatible` |
|
|
115
|
+
| `perplexity` | `https://api.perplexity.ai` | `openai-compatible` |
|
|
116
|
+
| `openrouter` | `https://openrouter.ai/api/v1` | `openai-compatible` |
|
|
117
|
+
| `siliconflow` | `https://api.siliconflow.com/v1` | `openai-compatible` |
|
|
118
|
+
| `siliconflow-china` | `https://api.siliconflow.cn/v1` | `openai-compatible` |
|
|
119
|
+
| `xai` | `https://api.x.ai/v1` | `openai-compatible` |
|
|
120
|
+
| `zai` | `https://api.z.ai/api/paas/v4` | `openai-compatible` |
|
|
121
|
+
| `zhipu` | `https://open.bigmodel.cn/api/paas/v4` | `openai-compatible` |
|
|
290
122
|
|
|
291
|
-
|
|
123
|
+
To disable auto-detection: `envProvider({ presetAutoDetect: false })`. See [Advanced Usage](./docs/advanced.md#preset-auto-detect) for details.
|
|
292
124
|
|
|
293
|
-
|
|
294
|
-
import { createOpenAI } from '@ai-sdk/openai'
|
|
125
|
+
## Documentation
|
|
295
126
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
})
|
|
300
|
-
```
|
|
127
|
+
- **[API Reference](./docs/api-reference.md)** — `envProvider()` options, types, model ID format
|
|
128
|
+
- **[Advanced Usage](./docs/advanced.md)** — Code-based configs, custom fetch/headers, custom separator, provider registry
|
|
129
|
+
- **[Bundler Usage](./docs/bundler.md)** — For `bun build`, `vite build`, and other bundlers
|