@ai-sdk/gateway 4.0.0-beta.11 → 4.0.0-beta.111
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/CHANGELOG.md +762 -4
- package/dist/index.d.ts +449 -42
- package/dist/index.js +1554 -397
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +534 -61
- package/package.json +14 -14
- package/src/errors/as-gateway-error.ts +2 -1
- package/src/errors/create-gateway-error.ts +17 -3
- package/src/errors/gateway-authentication-error.ts +8 -5
- package/src/errors/gateway-error.ts +8 -0
- package/src/errors/gateway-failed-dependency-error.ts +35 -0
- package/src/errors/gateway-forbidden-error.ts +34 -0
- package/src/errors/gateway-response-error.ts +1 -1
- package/src/errors/index.ts +2 -0
- package/src/errors/parse-auth-method.ts +1 -2
- package/src/gateway-config.ts +1 -1
- package/src/gateway-embedding-model-settings.ts +1 -0
- package/src/gateway-embedding-model.ts +62 -15
- package/src/gateway-fetch-metadata.ts +51 -38
- package/src/gateway-generation-info.ts +149 -0
- package/src/gateway-headers.ts +3 -0
- package/src/gateway-image-model-settings.ts +8 -1
- package/src/gateway-image-model.ts +46 -21
- package/src/gateway-language-model-settings.ts +45 -26
- package/src/gateway-language-model.ts +72 -42
- package/src/gateway-model-entry.ts +15 -3
- package/src/gateway-provider-options.ts +50 -78
- package/src/gateway-provider.ts +296 -35
- package/src/gateway-realtime-auth.ts +126 -0
- package/src/gateway-realtime-model-settings.ts +1 -0
- package/src/gateway-realtime-model.ts +118 -0
- package/src/gateway-reranking-model-settings.ts +7 -0
- package/src/gateway-reranking-model.ts +142 -0
- package/src/gateway-speech-model-settings.ts +1 -0
- package/src/gateway-speech-model.ts +145 -0
- package/src/gateway-spend-report.ts +193 -0
- package/src/gateway-tools.ts +10 -0
- package/src/gateway-transcription-model-settings.ts +1 -0
- package/src/gateway-transcription-model.ts +155 -0
- package/src/gateway-video-model-settings.ts +4 -0
- package/src/gateway-video-model.ts +29 -19
- package/src/index.ts +30 -5
- package/src/tool/exa-search.ts +352 -0
- package/src/tool/parallel-search.ts +10 -11
- package/src/tool/perplexity-search.ts +10 -11
- package/dist/index.d.mts +0 -602
- package/dist/index.mjs +0 -1539
- package/dist/index.mjs.map +0 -1
package/docs/00-ai-gateway.mdx
CHANGED
|
@@ -29,7 +29,7 @@ For most use cases, you can use the AI Gateway directly with a model string:
|
|
|
29
29
|
import { generateText } from 'ai';
|
|
30
30
|
|
|
31
31
|
const { text } = await generateText({
|
|
32
|
-
model: 'openai/gpt-5',
|
|
32
|
+
model: 'openai/gpt-5.4',
|
|
33
33
|
prompt: 'Hello world',
|
|
34
34
|
});
|
|
35
35
|
```
|
|
@@ -39,7 +39,7 @@ const { text } = await generateText({
|
|
|
39
39
|
import { generateText, gateway } from 'ai';
|
|
40
40
|
|
|
41
41
|
const { text } = await generateText({
|
|
42
|
-
model: gateway('openai/gpt-5'),
|
|
42
|
+
model: gateway('openai/gpt-5.4'),
|
|
43
43
|
prompt: 'Hello world',
|
|
44
44
|
});
|
|
45
45
|
```
|
|
@@ -61,7 +61,7 @@ import { gateway } from 'ai';
|
|
|
61
61
|
|
|
62
62
|
You may want to create a custom provider instance when you need to:
|
|
63
63
|
|
|
64
|
-
- Set custom configuration options (API key, base URL, headers)
|
|
64
|
+
- Set custom configuration options (API key, Vercel access token, base URL, headers)
|
|
65
65
|
- Use the provider in a [provider registry](/docs/ai-sdk-core/provider-management)
|
|
66
66
|
- Wrap the provider with [middleware](/docs/ai-sdk-core/middleware)
|
|
67
67
|
- Use different settings for different parts of your application
|
|
@@ -80,12 +80,19 @@ You can use the following optional settings to customize the AI Gateway provider
|
|
|
80
80
|
|
|
81
81
|
- **baseURL** _string_
|
|
82
82
|
|
|
83
|
-
Use a different URL prefix for API calls. The default prefix is `https://ai-gateway.vercel.sh/
|
|
83
|
+
Use a different URL prefix for API calls. The default prefix is `https://ai-gateway.vercel.sh/v4/ai`.
|
|
84
84
|
|
|
85
85
|
- **apiKey** _string_
|
|
86
86
|
|
|
87
|
-
API key that is being sent using the `Authorization`
|
|
88
|
-
the `AI_GATEWAY_API_KEY` environment variable.
|
|
87
|
+
API key or Vercel access token that is being sent using the `Authorization`
|
|
88
|
+
header. It defaults to the `AI_GATEWAY_API_KEY` environment variable.
|
|
89
|
+
Supports AI Gateway API keys, Vercel personal access tokens, and Vercel app
|
|
90
|
+
access tokens.
|
|
91
|
+
|
|
92
|
+
- **teamIdOrSlug** _string_
|
|
93
|
+
|
|
94
|
+
Vercel team ID or slug used to scope model requests when authenticating with
|
|
95
|
+
multi-team Vercel access tokens.
|
|
89
96
|
|
|
90
97
|
- **headers** _Record<string,string>_
|
|
91
98
|
|
|
@@ -104,7 +111,7 @@ You can use the following optional settings to customize the AI Gateway provider
|
|
|
104
111
|
|
|
105
112
|
## Authentication
|
|
106
113
|
|
|
107
|
-
The Gateway provider supports
|
|
114
|
+
The Gateway provider supports the following authentication methods:
|
|
108
115
|
|
|
109
116
|
### API Key Authentication
|
|
110
117
|
|
|
@@ -124,15 +131,37 @@ const gateway = createGateway({
|
|
|
124
131
|
});
|
|
125
132
|
```
|
|
126
133
|
|
|
134
|
+
### Vercel Access Token Authentication for Model Requests
|
|
135
|
+
|
|
136
|
+
For dynamic runtime authentication of model requests, pass a Vercel personal
|
|
137
|
+
access token or Vercel app access token to a custom Gateway provider instance:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { createGateway } from 'ai';
|
|
141
|
+
|
|
142
|
+
const gateway = createGateway({
|
|
143
|
+
apiKey: 'your_vercel_access_token_here',
|
|
144
|
+
teamIdOrSlug: 'your-team', // required for multi-team tokens
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`apiKey` takes precedence over `AI_GATEWAY_API_KEY` and OIDC.
|
|
149
|
+
|
|
150
|
+
<Note>
|
|
151
|
+
Vercel access tokens with `teamIdOrSlug` are supported for model requests.
|
|
152
|
+
Gateway helper methods such as `getCredits`, `getSpendReport`, and
|
|
153
|
+
`getGenerationInfo` require an AI Gateway API key or OIDC authentication.
|
|
154
|
+
</Note>
|
|
155
|
+
|
|
127
156
|
### OIDC Authentication (Vercel Deployments)
|
|
128
157
|
|
|
129
|
-
When deployed to Vercel, the AI Gateway provider supports authenticating
|
|
130
|
-
tokens](https://vercel.com/docs/oidc)
|
|
158
|
+
When deployed to Vercel, the AI Gateway provider supports authenticating model
|
|
159
|
+
requests using [OIDC (OpenID Connect) tokens](https://vercel.com/docs/oidc)
|
|
160
|
+
without API Keys.
|
|
131
161
|
|
|
132
162
|
#### How OIDC Authentication Works
|
|
133
163
|
|
|
134
164
|
1. **In Production/Preview Deployments**:
|
|
135
|
-
|
|
136
165
|
- OIDC authentication is automatically handled
|
|
137
166
|
- No manual configuration needed
|
|
138
167
|
- Tokens are automatically obtained and refreshed
|
|
@@ -147,8 +176,8 @@ tokens](https://vercel.com/docs/oidc) without API Keys.
|
|
|
147
176
|
- You'll need to run `vercel env pull` again to refresh the token before it expires
|
|
148
177
|
|
|
149
178
|
<Note>
|
|
150
|
-
If an API
|
|
151
|
-
always be used, even if invalid.
|
|
179
|
+
If an API key or Vercel access token is present (either passed directly or via
|
|
180
|
+
environment), it will always be used instead of OIDC, even if invalid.
|
|
152
181
|
</Note>
|
|
153
182
|
|
|
154
183
|
Read more about using OIDC tokens in the [Vercel AI Gateway docs](https://vercel.com/docs/ai-gateway#using-the-ai-gateway-with-a-vercel-oidc-token).
|
|
@@ -159,6 +188,8 @@ You can connect your own provider credentials to use with Vercel AI Gateway. Thi
|
|
|
159
188
|
|
|
160
189
|
To set up BYOK, add your provider credentials in your Vercel team's AI Gateway settings. Once configured, AI Gateway automatically uses your credentials. No code changes are needed.
|
|
161
190
|
|
|
191
|
+
For providers like Azure where you can use custom deployment names, you can configure model mappings to map gateway model slugs to your deployment names. See [model mappings](https://vercel.com/docs/ai-gateway/byok#model-mappings) for details.
|
|
192
|
+
|
|
162
193
|
Learn more in the [BYOK documentation](https://vercel.com/docs/ai-gateway/byok).
|
|
163
194
|
|
|
164
195
|
## Language Models
|
|
@@ -169,13 +200,111 @@ You can create language models using a provider instance. The first argument is
|
|
|
169
200
|
import { generateText } from 'ai';
|
|
170
201
|
|
|
171
202
|
const { text } = await generateText({
|
|
172
|
-
model: 'openai/gpt-5',
|
|
203
|
+
model: 'openai/gpt-5.4',
|
|
173
204
|
prompt: 'Explain quantum computing in simple terms',
|
|
174
205
|
});
|
|
175
206
|
```
|
|
176
207
|
|
|
177
208
|
AI Gateway language models can also be used in the `streamText` function and support structured data generation with [`Output`](/docs/reference/ai-sdk-core/output) (see [AI SDK Core](/docs/ai-sdk-core)).
|
|
178
209
|
|
|
210
|
+
## Reranking Models
|
|
211
|
+
|
|
212
|
+
You can create reranking models using the `rerankingModel` method on the provider instance:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
import { rerank } from 'ai';
|
|
216
|
+
import { gateway } from '@ai-sdk/gateway';
|
|
217
|
+
|
|
218
|
+
const { ranking } = await rerank({
|
|
219
|
+
model: gateway.rerankingModel('cohere/rerank-v3.5'),
|
|
220
|
+
query: 'What is the capital of France?',
|
|
221
|
+
documents: [
|
|
222
|
+
'Paris is the capital of France.',
|
|
223
|
+
'Berlin is the capital of Germany.',
|
|
224
|
+
'Madrid is the capital of Spain.',
|
|
225
|
+
],
|
|
226
|
+
topN: 2,
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
console.log(ranking);
|
|
230
|
+
// [
|
|
231
|
+
// { originalIndex: 0, score: 0.89, document: 'Paris is the capital of France.' },
|
|
232
|
+
// { originalIndex: 2, score: 0.15, document: 'Madrid is the capital of Spain.' },
|
|
233
|
+
// ]
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Reranking models are useful for improving search results in retrieval-augmented generation (RAG) pipelines by re-scoring candidate documents after an initial retrieval step.
|
|
237
|
+
|
|
238
|
+
## Realtime Models
|
|
239
|
+
|
|
240
|
+
<Note type="warning">
|
|
241
|
+
Realtime support is experimental and the API may change in patch releases.
|
|
242
|
+
</Note>
|
|
243
|
+
|
|
244
|
+
You can create realtime models for bidirectional audio/text WebSocket sessions using the `experimental_realtime` method on the provider instance. The first argument is the model ID in the format `creator/model-name`:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import { gateway } from '@ai-sdk/gateway';
|
|
248
|
+
|
|
249
|
+
const model = gateway.experimental_realtime('openai/gpt-realtime-2');
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The Gateway normalizes realtime the same way it normalizes every other modality: your client speaks the [normalized AI SDK realtime protocol](/docs/ai-sdk-core/realtime) and the Gateway translates to and from the upstream provider server-side. This means the same client code works regardless of which provider backs the model.
|
|
253
|
+
|
|
254
|
+
Gateway realtime v0 is server-side only. Calling `gateway.experimental_realtime()` in a browser throws an error. `getToken()` returns the Gateway auth token resolved by the provider (`apiKey`, `AI_GATEWAY_API_KEY`, or Vercel OIDC token), so do not expose it to browser clients.
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import { gateway } from '@ai-sdk/gateway';
|
|
258
|
+
|
|
259
|
+
// Server-side only. Do not return this token to browser clients.
|
|
260
|
+
const token = await gateway.experimental_realtime.getToken({
|
|
261
|
+
model: 'openai/gpt-realtime-2',
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
<Note>
|
|
266
|
+
Gateway realtime v0 does not mint a provider-style short-lived client secret.
|
|
267
|
+
Gateway-minted ephemeral secrets are planned as future work; browser support
|
|
268
|
+
should wait for that flow.
|
|
269
|
+
</Note>
|
|
270
|
+
|
|
271
|
+
<Note>
|
|
272
|
+
The Gateway WebSocket route transports auth via the versioned
|
|
273
|
+
`Sec-WebSocket-Protocol` subprotocol and the model id via the `?ai-model-id=`
|
|
274
|
+
query - the WebSocket transport of the `Authorization` and `ai-model-id`
|
|
275
|
+
headers the HTTP routes use. Subprotocol values must fit the WebSocket token
|
|
276
|
+
grammar, and the complete `Sec-WebSocket-Protocol` header should stay compact
|
|
277
|
+
(under an 8 KiB safe header budget).
|
|
278
|
+
</Note>
|
|
279
|
+
|
|
280
|
+
### Provider Options
|
|
281
|
+
|
|
282
|
+
Gateway [provider options](#gateway-provider-options) — `tags`, `user`, `byok`, compliance flags, and so on — are set under `providerOptions.gateway` in the **session configuration**, mirroring how they ride the request body on the non-realtime routes. Include them in the session configuration you send to the Gateway, and the Gateway applies them server-side:
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
286
|
+
|
|
287
|
+
const gatewayOptions: GatewayProviderOptions = {
|
|
288
|
+
tags: ['cooking-coach', 'v2'],
|
|
289
|
+
user: 'user-123',
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const sessionConfig = {
|
|
293
|
+
instructions: 'You are a concise voice assistant.',
|
|
294
|
+
providerOptions: { gateway: gatewayOptions },
|
|
295
|
+
};
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The `GatewayProviderOptions` type is exported from `@ai-sdk/gateway` for stable client-facing fields. The type also accepts service-owned option keys so the Gateway service can add or change server-side options without requiring an SDK release for every schema change. Runtime validation is owned by the Gateway service.
|
|
299
|
+
|
|
300
|
+
<Note>
|
|
301
|
+
Provider options are sent in the first `session.update` frame (after the
|
|
302
|
+
socket opens), so connect-time options such as `byok` and quota selection
|
|
303
|
+
require a Gateway that resolves them from that frame. Routing knobs like
|
|
304
|
+
`order` / `only` do not apply to realtime, where the Gateway selects the
|
|
305
|
+
WebSocket-capable provider.
|
|
306
|
+
</Note>
|
|
307
|
+
|
|
179
308
|
## Available Models
|
|
180
309
|
|
|
181
310
|
The AI Gateway supports models from OpenAI, Anthropic, Google, Meta, xAI, Mistral, DeepSeek, Amazon Bedrock, Cohere, Perplexity, Alibaba, and other providers.
|
|
@@ -215,7 +344,7 @@ availableModels.models.forEach(model => {
|
|
|
215
344
|
|
|
216
345
|
// Use any discovered model with plain string
|
|
217
346
|
const { text } = await generateText({
|
|
218
|
-
model: availableModels.models[0].id, // e.g., 'openai/gpt-
|
|
347
|
+
model: availableModels.models[0].id, // e.g., 'openai/gpt-5.4'
|
|
219
348
|
prompt: 'Hello world',
|
|
220
349
|
});
|
|
221
350
|
```
|
|
@@ -238,6 +367,86 @@ The `getCredits()` method returns your team's credit information based on the au
|
|
|
238
367
|
- **balance** _number_ - Your team's current available credit balance
|
|
239
368
|
- **total_used** _number_ - Total credits consumed by your team
|
|
240
369
|
|
|
370
|
+
## Generation Lookup
|
|
371
|
+
|
|
372
|
+
Look up detailed information about a specific generation by its ID, including cost, token usage, latency, and provider details. Generation IDs are available in `providerMetadata.gateway.generationId` on both `generateText` and `streamText` responses.
|
|
373
|
+
|
|
374
|
+
When streaming, the generation ID is injected on the first content chunk, so you can capture it early in the stream without waiting for completion. This is especially useful in cases where a network interruption or mid-stream error could prevent you from receiving the final response — since the gateway records the final status server-side, you can use the generation ID to look up the results (including cost, token usage, and finish reason) later via `getGenerationInfo()`.
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
import { gateway, generateText } from 'ai';
|
|
378
|
+
|
|
379
|
+
// Make a request
|
|
380
|
+
const result = await generateText({
|
|
381
|
+
model: gateway('anthropic/claude-sonnet-4'),
|
|
382
|
+
prompt: 'Explain quantum entanglement briefly',
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// Get the generation ID from provider metadata
|
|
386
|
+
const generationId = result.providerMetadata?.gateway?.generationId;
|
|
387
|
+
|
|
388
|
+
// Look up detailed generation info
|
|
389
|
+
const generation = await gateway.getGenerationInfo({ id: generationId });
|
|
390
|
+
|
|
391
|
+
console.log(`Model: ${generation.model}`);
|
|
392
|
+
console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
|
|
393
|
+
console.log(`Latency: ${generation.latency}ms`);
|
|
394
|
+
console.log(`Prompt tokens: ${generation.promptTokens}`);
|
|
395
|
+
console.log(`Completion tokens: ${generation.completionTokens}`);
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
With `streamText`, you can capture the generation ID from the first chunk via `stream`:
|
|
399
|
+
|
|
400
|
+
```ts
|
|
401
|
+
import { gateway, streamText } from 'ai';
|
|
402
|
+
|
|
403
|
+
const result = streamText({
|
|
404
|
+
model: gateway('anthropic/claude-sonnet-4'),
|
|
405
|
+
prompt: 'Explain quantum entanglement briefly',
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
let generationId: string | undefined;
|
|
409
|
+
|
|
410
|
+
for await (const part of result.stream) {
|
|
411
|
+
if (!generationId && part.providerMetadata?.gateway?.generationId) {
|
|
412
|
+
generationId = part.providerMetadata.gateway.generationId as string;
|
|
413
|
+
console.log(`Generation ID (early): ${generationId}`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Look up cost and usage after the stream completes
|
|
418
|
+
if (generationId) {
|
|
419
|
+
const generation = await gateway.getGenerationInfo({ id: generationId });
|
|
420
|
+
console.log(`Cost: $${generation.totalCost.toFixed(6)}`);
|
|
421
|
+
console.log(`Finish reason: ${generation.finishReason}`);
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
The `getGenerationInfo()` method accepts:
|
|
426
|
+
|
|
427
|
+
- **id** _string_ - The generation ID to look up (format: `gen_<ulid>`, required)
|
|
428
|
+
|
|
429
|
+
It returns a `GatewayGenerationInfo` object with the following fields:
|
|
430
|
+
|
|
431
|
+
- **id** _string_ - The generation ID
|
|
432
|
+
- **totalCost** _number_ - Total cost in USD
|
|
433
|
+
- **upstreamInferenceCost** _number_ - Upstream inference cost in USD (relevant for BYOK)
|
|
434
|
+
- **usage** _number_ - Usage cost in USD (same as totalCost)
|
|
435
|
+
- **createdAt** _string_ - ISO 8601 timestamp when the generation was created
|
|
436
|
+
- **model** _string_ - Model identifier used
|
|
437
|
+
- **isByok** _boolean_ - Whether Bring Your Own Key credentials were used
|
|
438
|
+
- **providerName** _string_ - The provider that served this generation
|
|
439
|
+
- **streamed** _boolean_ - Whether streaming was used
|
|
440
|
+
- **finishReason** _string_ - Finish reason (e.g. `'stop'`)
|
|
441
|
+
- **latency** _number_ - Time to first token in milliseconds
|
|
442
|
+
- **generationTime** _number_ - Total generation time in milliseconds
|
|
443
|
+
- **promptTokens** _number_ - Number of prompt tokens
|
|
444
|
+
- **completionTokens** _number_ - Number of completion tokens
|
|
445
|
+
- **reasoningTokens** _number_ - Reasoning tokens used (if applicable)
|
|
446
|
+
- **cachedTokens** _number_ - Cached tokens used (if applicable)
|
|
447
|
+
- **cacheCreationTokens** _number_ - Cache creation input tokens
|
|
448
|
+
- **billableWebSearchCalls** _number_ - Number of billable web search calls
|
|
449
|
+
|
|
241
450
|
## Examples
|
|
242
451
|
|
|
243
452
|
### Basic Text Generation
|
|
@@ -246,7 +455,7 @@ The `getCredits()` method returns your team's credit information based on the au
|
|
|
246
455
|
import { generateText } from 'ai';
|
|
247
456
|
|
|
248
457
|
const { text } = await generateText({
|
|
249
|
-
model: 'anthropic/claude-sonnet-4',
|
|
458
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
250
459
|
prompt: 'Write a haiku about programming',
|
|
251
460
|
});
|
|
252
461
|
|
|
@@ -259,7 +468,7 @@ console.log(text);
|
|
|
259
468
|
import { streamText } from 'ai';
|
|
260
469
|
|
|
261
470
|
const { textStream } = await streamText({
|
|
262
|
-
model: 'openai/gpt-5',
|
|
471
|
+
model: 'openai/gpt-5.4',
|
|
263
472
|
prompt: 'Explain the benefits of serverless architecture',
|
|
264
473
|
});
|
|
265
474
|
|
|
@@ -297,13 +506,13 @@ const { text } = await generateText({
|
|
|
297
506
|
Some providers offer tools that are executed by the provider itself, such as [OpenAI's web search tool](/providers/ai-sdk-providers/openai#web-search-tool). To use these tools through AI Gateway, import the provider to access the tool definitions:
|
|
298
507
|
|
|
299
508
|
```ts
|
|
300
|
-
import { generateText,
|
|
509
|
+
import { generateText, isStepCount } from 'ai';
|
|
301
510
|
import { openai } from '@ai-sdk/openai';
|
|
302
511
|
|
|
303
512
|
const result = await generateText({
|
|
304
|
-
model: 'openai/gpt-5-mini',
|
|
513
|
+
model: 'openai/gpt-5.4-mini',
|
|
305
514
|
prompt: 'What is the Vercel AI Gateway?',
|
|
306
|
-
stopWhen:
|
|
515
|
+
stopWhen: isStepCount(10),
|
|
307
516
|
tools: {
|
|
308
517
|
web_search: openai.tools.webSearch({}),
|
|
309
518
|
},
|
|
@@ -330,7 +539,7 @@ The Perplexity Search tool enables models to search the web using [Perplexity's
|
|
|
330
539
|
import { gateway, generateText } from 'ai';
|
|
331
540
|
|
|
332
541
|
const result = await generateText({
|
|
333
|
-
model: 'openai/gpt-5-nano',
|
|
542
|
+
model: 'openai/gpt-5.4-nano',
|
|
334
543
|
prompt: 'Search for news about AI regulations in January 2025.',
|
|
335
544
|
tools: {
|
|
336
545
|
perplexity_search: gateway.tools.perplexitySearch(),
|
|
@@ -348,7 +557,7 @@ You can also configure the search with optional parameters:
|
|
|
348
557
|
import { gateway, generateText } from 'ai';
|
|
349
558
|
|
|
350
559
|
const result = await generateText({
|
|
351
|
-
model: 'openai/gpt-5-nano',
|
|
560
|
+
model: 'openai/gpt-5.4-nano',
|
|
352
561
|
prompt:
|
|
353
562
|
'Search for news about AI regulations from the first week of January 2025.',
|
|
354
563
|
tools: {
|
|
@@ -402,14 +611,14 @@ The tool works with both `generateText` and `streamText`:
|
|
|
402
611
|
import { gateway, streamText } from 'ai';
|
|
403
612
|
|
|
404
613
|
const result = streamText({
|
|
405
|
-
model: 'openai/gpt-5-nano',
|
|
614
|
+
model: 'openai/gpt-5.4-nano',
|
|
406
615
|
prompt: 'Search for the latest news about AI regulations.',
|
|
407
616
|
tools: {
|
|
408
617
|
perplexity_search: gateway.tools.perplexitySearch(),
|
|
409
618
|
},
|
|
410
619
|
});
|
|
411
620
|
|
|
412
|
-
for await (const part of result.
|
|
621
|
+
for await (const part of result.stream) {
|
|
413
622
|
switch (part.type) {
|
|
414
623
|
case 'text-delta':
|
|
415
624
|
process.stdout.write(part.text);
|
|
@@ -424,6 +633,93 @@ for await (const part of result.fullStream) {
|
|
|
424
633
|
}
|
|
425
634
|
```
|
|
426
635
|
|
|
636
|
+
#### Exa Search
|
|
637
|
+
|
|
638
|
+
The Exa Search tool enables models to search the web using [Exa's Search API](https://exa.ai/docs/reference/search-api-guide-for-coding-agents). This tool is executed by the AI Gateway and returns token-efficient web excerpts for agent workflows.
|
|
639
|
+
|
|
640
|
+
```ts
|
|
641
|
+
import { gateway, generateText } from 'ai';
|
|
642
|
+
|
|
643
|
+
const result = await generateText({
|
|
644
|
+
model: 'openai/gpt-5.4-nano',
|
|
645
|
+
prompt:
|
|
646
|
+
'Find the latest AI regulation updates and summarize the key changes.',
|
|
647
|
+
tools: {
|
|
648
|
+
exa_search: gateway.tools.exaSearch(),
|
|
649
|
+
},
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
console.log(result.text);
|
|
653
|
+
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
|
|
654
|
+
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
You can also configure the search with optional parameters:
|
|
658
|
+
|
|
659
|
+
```ts
|
|
660
|
+
import { gateway, generateText } from 'ai';
|
|
661
|
+
|
|
662
|
+
const result = await generateText({
|
|
663
|
+
model: 'openai/gpt-5.4-nano',
|
|
664
|
+
prompt: 'Find recent AI regulation news from trusted sources.',
|
|
665
|
+
tools: {
|
|
666
|
+
exa_search: gateway.tools.exaSearch({
|
|
667
|
+
type: 'fast',
|
|
668
|
+
numResults: 5,
|
|
669
|
+
category: 'news',
|
|
670
|
+
includeDomains: ['reuters.com', 'bbc.com', 'nytimes.com'],
|
|
671
|
+
contents: {
|
|
672
|
+
highlights: true,
|
|
673
|
+
maxAgeHours: 24,
|
|
674
|
+
},
|
|
675
|
+
}),
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
console.log(result.text);
|
|
680
|
+
console.log('Tool calls:', JSON.stringify(result.toolCalls, null, 2));
|
|
681
|
+
console.log('Tool results:', JSON.stringify(result.toolResults, null, 2));
|
|
682
|
+
```
|
|
683
|
+
|
|
684
|
+
The Exa Search tool supports the following optional configuration options:
|
|
685
|
+
|
|
686
|
+
- **type** _'auto' | 'fast' | 'instant'_
|
|
687
|
+
|
|
688
|
+
Search mode. `'auto'` is the default balance of speed and quality.
|
|
689
|
+
|
|
690
|
+
- **numResults** _number_
|
|
691
|
+
|
|
692
|
+
Maximum number of results to return (1-100, default: 10).
|
|
693
|
+
|
|
694
|
+
- **category** _'company' | 'people' | 'research paper' | 'news' | 'personal site' | 'financial report'_
|
|
695
|
+
|
|
696
|
+
Focus results on a specific content type.
|
|
697
|
+
|
|
698
|
+
- **includeDomains** / **excludeDomains** _string[]_
|
|
699
|
+
|
|
700
|
+
Restrict or exclude search results by domain.
|
|
701
|
+
|
|
702
|
+
- **startPublishedDate** / **endPublishedDate** _string_
|
|
703
|
+
|
|
704
|
+
Filter results by ISO 8601 publication date.
|
|
705
|
+
|
|
706
|
+
- **contents** _object_
|
|
707
|
+
|
|
708
|
+
Control result extraction and freshness:
|
|
709
|
+
- `text` - Return full page text, optionally capped with `maxCharacters`
|
|
710
|
+
- `highlights` - Return token-efficient excerpts
|
|
711
|
+
- `maxAgeHours` - Control cached content freshness
|
|
712
|
+
- `livecrawlTimeout` - Livecrawl timeout in milliseconds
|
|
713
|
+
- `subpages` / `subpageTarget` - Crawl related subpages
|
|
714
|
+
- `extras.links` / `extras.imageLinks` - Extract links from pages
|
|
715
|
+
|
|
716
|
+
The tool works with both `generateText` and `streamText`.
|
|
717
|
+
|
|
718
|
+
This initial Gateway integration supports Exa's plain Search modes and
|
|
719
|
+
token-efficient content controls. Deep synthesis modes and generated summaries
|
|
720
|
+
are intentionally not exposed yet because they have separate pricing from
|
|
721
|
+
standard Search.
|
|
722
|
+
|
|
427
723
|
#### Parallel Search
|
|
428
724
|
|
|
429
725
|
The Parallel Search tool enables models to search the web using [Parallel AI's Search API](https://docs.parallel.ai/api-reference/search-beta/search). This tool is optimized for LLM consumption, returning relevant excerpts from web pages that can replace multiple keyword searches with a single call.
|
|
@@ -432,7 +728,7 @@ The Parallel Search tool enables models to search the web using [Parallel AI's S
|
|
|
432
728
|
import { gateway, generateText } from 'ai';
|
|
433
729
|
|
|
434
730
|
const result = await generateText({
|
|
435
|
-
model: 'openai/gpt-5-nano',
|
|
731
|
+
model: 'openai/gpt-5.4-nano',
|
|
436
732
|
prompt: 'Research the latest developments in quantum computing.',
|
|
437
733
|
tools: {
|
|
438
734
|
parallel_search: gateway.tools.parallelSearch(),
|
|
@@ -450,7 +746,7 @@ You can also configure the search with optional parameters:
|
|
|
450
746
|
import { gateway, generateText } from 'ai';
|
|
451
747
|
|
|
452
748
|
const result = await generateText({
|
|
453
|
-
model: 'openai/gpt-5-nano',
|
|
749
|
+
model: 'openai/gpt-5.4-nano',
|
|
454
750
|
prompt: 'Find detailed information about TypeScript 5.0 features.',
|
|
455
751
|
tools: {
|
|
456
752
|
parallel_search: gateway.tools.parallelSearch({
|
|
@@ -476,7 +772,6 @@ The Parallel Search tool supports the following optional configuration options:
|
|
|
476
772
|
- **mode** _'one-shot' | 'agentic'_
|
|
477
773
|
|
|
478
774
|
Mode preset for different use cases:
|
|
479
|
-
|
|
480
775
|
- `'one-shot'` - Comprehensive results with longer excerpts for single-response answers (default)
|
|
481
776
|
- `'agentic'` - Concise, token-efficient results optimized for multi-step agentic workflows
|
|
482
777
|
|
|
@@ -487,7 +782,6 @@ The Parallel Search tool supports the following optional configuration options:
|
|
|
487
782
|
- **sourcePolicy** _object_
|
|
488
783
|
|
|
489
784
|
Source policy for controlling which domains to include/exclude:
|
|
490
|
-
|
|
491
785
|
- `includeDomains` - List of domains to include in search results
|
|
492
786
|
- `excludeDomains` - List of domains to exclude from search results
|
|
493
787
|
- `afterDate` - Only include results published after this date (ISO 8601 format)
|
|
@@ -495,14 +789,12 @@ The Parallel Search tool supports the following optional configuration options:
|
|
|
495
789
|
- **excerpts** _object_
|
|
496
790
|
|
|
497
791
|
Excerpt configuration for controlling result length:
|
|
498
|
-
|
|
499
792
|
- `maxCharsPerResult` - Maximum characters per result
|
|
500
793
|
- `maxCharsTotal` - Maximum total characters across all results
|
|
501
794
|
|
|
502
795
|
- **fetchPolicy** _object_
|
|
503
796
|
|
|
504
797
|
Fetch policy for controlling content freshness:
|
|
505
|
-
|
|
506
798
|
- `maxAgeSeconds` - Maximum age in seconds for cached content (set to 0 for always fresh)
|
|
507
799
|
|
|
508
800
|
The tool works with both `generateText` and `streamText`:
|
|
@@ -511,14 +803,14 @@ The tool works with both `generateText` and `streamText`:
|
|
|
511
803
|
import { gateway, streamText } from 'ai';
|
|
512
804
|
|
|
513
805
|
const result = streamText({
|
|
514
|
-
model: 'openai/gpt-5-nano',
|
|
806
|
+
model: 'openai/gpt-5.4-nano',
|
|
515
807
|
prompt: 'Research the latest AI safety guidelines.',
|
|
516
808
|
tools: {
|
|
517
809
|
parallel_search: gateway.tools.parallelSearch(),
|
|
518
810
|
},
|
|
519
811
|
});
|
|
520
812
|
|
|
521
|
-
for await (const part of result.
|
|
813
|
+
for await (const part of result.stream) {
|
|
522
814
|
switch (part.type) {
|
|
523
815
|
case 'text-delta':
|
|
524
816
|
process.stdout.write(part.text);
|
|
@@ -533,22 +825,24 @@ for await (const part of result.fullStream) {
|
|
|
533
825
|
}
|
|
534
826
|
```
|
|
535
827
|
|
|
536
|
-
###
|
|
828
|
+
### Custom Reporting
|
|
829
|
+
|
|
830
|
+
Track usage per end-user and categorize requests with tags, then query the data through the reporting API.
|
|
537
831
|
|
|
538
|
-
|
|
832
|
+
#### Usage Tracking with User and Tags
|
|
539
833
|
|
|
540
834
|
```ts
|
|
541
|
-
import type {
|
|
835
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
542
836
|
import { generateText } from 'ai';
|
|
543
837
|
|
|
544
838
|
const { text } = await generateText({
|
|
545
|
-
model: 'openai/gpt-5',
|
|
839
|
+
model: 'openai/gpt-5.4',
|
|
546
840
|
prompt: 'Summarize this document...',
|
|
547
841
|
providerOptions: {
|
|
548
842
|
gateway: {
|
|
549
843
|
user: 'user-abc-123', // Track usage for this specific end-user
|
|
550
844
|
tags: ['document-summary', 'premium-feature'], // Categorize for reporting
|
|
551
|
-
} satisfies
|
|
845
|
+
} satisfies GatewayProviderOptions,
|
|
552
846
|
},
|
|
553
847
|
});
|
|
554
848
|
```
|
|
@@ -559,6 +853,77 @@ This allows you to:
|
|
|
559
853
|
- Filter and analyze spending by feature or use case using tags
|
|
560
854
|
- Track which users or features are driving the most AI usage
|
|
561
855
|
|
|
856
|
+
#### Querying Spend Reports
|
|
857
|
+
|
|
858
|
+
Use the `getSpendReport()` method to query usage data programmatically. The reporting API is only available for Vercel Pro and Enterprise plans. For pricing, see the [Custom Reporting docs](https://vercel.com/docs/ai-gateway/capabilities/custom-reporting).
|
|
859
|
+
|
|
860
|
+
```ts
|
|
861
|
+
import { gateway } from 'ai';
|
|
862
|
+
|
|
863
|
+
const report = await gateway.getSpendReport({
|
|
864
|
+
startDate: '2026-03-01',
|
|
865
|
+
endDate: '2026-03-25',
|
|
866
|
+
groupBy: 'model',
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
for (const row of report.results) {
|
|
870
|
+
console.log(`${row.model}: $${row.totalCost.toFixed(4)}`);
|
|
871
|
+
}
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
The `getSpendReport()` method accepts the following parameters:
|
|
875
|
+
|
|
876
|
+
- **startDate** _string_ - Start date in `YYYY-MM-DD` format (inclusive, required)
|
|
877
|
+
- **endDate** _string_ - End date in `YYYY-MM-DD` format (inclusive, required)
|
|
878
|
+
- **groupBy** _string_ - Aggregation dimension: `'day'` (default), `'user'`, `'model'`, `'tag'`, `'provider'`, or `'credential_type'`
|
|
879
|
+
- **datePart** _string_ - Time granularity when `groupBy` is `'day'`: `'day'` or `'hour'`
|
|
880
|
+
- **userId** _string_ - Filter to a specific user
|
|
881
|
+
- **model** _string_ - Filter to a specific model (e.g. `'anthropic/claude-sonnet-4.5'`)
|
|
882
|
+
- **provider** _string_ - Filter to a specific provider (e.g. `'anthropic'`)
|
|
883
|
+
- **credentialType** _string_ - Filter by `'byok'` or `'system'` credentials
|
|
884
|
+
- **tags** _string[]_ - Filter to requests matching these tags
|
|
885
|
+
|
|
886
|
+
Each row in `results` contains a grouping field (matching your `groupBy` choice) and metrics:
|
|
887
|
+
|
|
888
|
+
- **totalCost** _number_ - Total cost in USD
|
|
889
|
+
- **marketCost** _number_ - Market cost in USD
|
|
890
|
+
- **inputTokens** _number_ - Number of input tokens
|
|
891
|
+
- **outputTokens** _number_ - Number of output tokens
|
|
892
|
+
- **cachedInputTokens** _number_ - Number of cached input tokens
|
|
893
|
+
- **cacheCreationInputTokens** _number_ - Number of cache creation input tokens
|
|
894
|
+
- **reasoningTokens** _number_ - Number of reasoning tokens
|
|
895
|
+
- **requestCount** _number_ - Number of requests
|
|
896
|
+
|
|
897
|
+
You can combine tracking and querying to analyze spend by tags you defined:
|
|
898
|
+
|
|
899
|
+
```ts
|
|
900
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
901
|
+
import { gateway, streamText } from 'ai';
|
|
902
|
+
|
|
903
|
+
// 1. Make requests with tags
|
|
904
|
+
const result = streamText({
|
|
905
|
+
model: gateway('anthropic/claude-haiku-4.5'),
|
|
906
|
+
prompt: 'Summarize this quarter's results',
|
|
907
|
+
providerOptions: {
|
|
908
|
+
gateway: {
|
|
909
|
+
tags: ['team:finance', 'feature:summaries'],
|
|
910
|
+
} satisfies GatewayProviderOptions,
|
|
911
|
+
},
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
// 2. Later, query spend filtered by those tags
|
|
915
|
+
const report = await gateway.getSpendReport({
|
|
916
|
+
startDate: '2026-03-01',
|
|
917
|
+
endDate: '2026-03-31',
|
|
918
|
+
groupBy: 'tag',
|
|
919
|
+
tags: ['team:finance'],
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
for (const row of report.results) {
|
|
923
|
+
console.log(`${row.tag}: $${row.totalCost.toFixed(4)} (${row.requestCount} requests)`);
|
|
924
|
+
}
|
|
925
|
+
```
|
|
926
|
+
|
|
562
927
|
## Provider Options
|
|
563
928
|
|
|
564
929
|
The AI Gateway provider accepts provider options that control routing behavior and provider-specific configurations.
|
|
@@ -568,17 +933,17 @@ The AI Gateway provider accepts provider options that control routing behavior a
|
|
|
568
933
|
You can use the `gateway` key in `providerOptions` to control how AI Gateway routes requests:
|
|
569
934
|
|
|
570
935
|
```ts
|
|
571
|
-
import type {
|
|
936
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
572
937
|
import { generateText } from 'ai';
|
|
573
938
|
|
|
574
939
|
const { text } = await generateText({
|
|
575
|
-
model: 'anthropic/claude-sonnet-4',
|
|
940
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
576
941
|
prompt: 'Explain quantum computing',
|
|
577
942
|
providerOptions: {
|
|
578
943
|
gateway: {
|
|
579
944
|
order: ['vertex', 'anthropic'], // Try Vertex AI first, then Anthropic
|
|
580
945
|
only: ['vertex', 'anthropic'], // Only use these providers
|
|
581
|
-
} satisfies
|
|
946
|
+
} satisfies GatewayProviderOptions,
|
|
582
947
|
},
|
|
583
948
|
});
|
|
584
949
|
```
|
|
@@ -597,11 +962,24 @@ The following gateway provider options are available:
|
|
|
597
962
|
|
|
598
963
|
Example: `only: ['anthropic', 'vertex']` will only allow routing to Anthropic or Vertex AI.
|
|
599
964
|
|
|
965
|
+
- **sort** _'cost' | 'ttft' | 'tps'_
|
|
966
|
+
|
|
967
|
+
Sorts available providers by a performance or cost metric before routing. The gateway will try the best-scoring provider first and fall back through the rest in sorted order. If unspecified, providers are ordered using the gateway's default system ranking.
|
|
968
|
+
- `'cost'` — lowest cost first
|
|
969
|
+
- `'ttft'` — lowest time-to-first-token first
|
|
970
|
+
- `'tps'` — highest tokens-per-second first
|
|
971
|
+
|
|
972
|
+
When combined with `order`, the user-specified providers are promoted to the front while remaining providers follow the sorted order.
|
|
973
|
+
|
|
974
|
+
Example: `sort: 'ttft'` will route to the provider with the fastest time-to-first-token.
|
|
975
|
+
|
|
976
|
+
When `sort` is active, the response's `providerMetadata.gateway.routing.sort` object contains the sort option used, the resulting execution order, per-provider metric values, and any providers that were deprioritized.
|
|
977
|
+
|
|
600
978
|
- **models** _string[]_
|
|
601
979
|
|
|
602
980
|
Specifies fallback models to use when the primary model fails or is unavailable. The gateway will try the primary model first (specified in the `model` parameter), then try each model in this array in order until one succeeds.
|
|
603
981
|
|
|
604
|
-
Example: `models: ['openai/gpt-5-nano', 'gemini-
|
|
982
|
+
Example: `models: ['openai/gpt-5.4-nano', 'gemini-3-flash-preview']` will try the fallback models in order if the primary model fails.
|
|
605
983
|
|
|
606
984
|
- **user** _string_
|
|
607
985
|
|
|
@@ -621,15 +999,29 @@ The following gateway provider options are available:
|
|
|
621
999
|
|
|
622
1000
|
Each provider can have multiple credentials (tried in order). The structure is a record where keys are provider slugs and values are arrays of credential objects.
|
|
623
1001
|
|
|
624
|
-
|
|
1002
|
+
Each credential can optionally include a `modelMappings` array to map AI Gateway model slugs to your deployment names (for example, custom Azure deployment names). If a BYOK request fails, the gateway falls back to system credentials using the default model name.
|
|
625
1003
|
|
|
1004
|
+
Examples:
|
|
626
1005
|
- Single provider: `byok: { 'anthropic': [{ apiKey: 'sk-ant-...' }] }`
|
|
627
1006
|
- Multiple credentials: `byok: { 'vertex': [{ project: 'proj-1', googleCredentials: { privateKey: '...', clientEmail: '...' } }, { project: 'proj-2', googleCredentials: { privateKey: '...', clientEmail: '...' } }] }`
|
|
628
1007
|
- Multiple providers: `byok: { 'anthropic': [{ apiKey: '...' }], 'bedrock': [{ accessKeyId: '...', secretAccessKey: '...' }] }`
|
|
1008
|
+
- With model mappings: `byok: { 'azure': [{ apiKey: '...', resourceName: '...', modelMappings: [{ gatewayModelSlug: 'openai/gpt-5.4-nano', customModelId: 'my-deployment' }] }] }`
|
|
629
1009
|
|
|
630
1010
|
- **zeroDataRetention** _boolean_
|
|
631
1011
|
|
|
632
|
-
Restricts routing
|
|
1012
|
+
Restricts routing to providers with zero data retention agreements with Vercel for AI Gateway. BYOK credentials are skipped by default, since your provider agreements differ from Vercel's. When this filter is on, AI Gateway routes only to providers Vercel has ZDR agreements with for the model. If you have BYOK keys marked as ZDR, those keys are tried first, then AI Gateway falls back to its system credentials. You are responsible for the accuracy of that marking. Applies to both account-wide and request-level ZDR. The request fails if no ZDR-eligible credentials are available. Request-level ZDR is only available for Vercel Pro and Enterprise plans.
|
|
1013
|
+
|
|
1014
|
+
- **disallowPromptTraining** _boolean_
|
|
1015
|
+
|
|
1016
|
+
Restricts routing to providers that have agreements with Vercel for AI Gateway to not use prompts for model training. When using BYOK credentials, this filter is not applied. If BYOK credentials fail and the request falls back to system credentials, only providers that do not train on prompt data will be used. If there are no providers available for the model that disallow prompt training, the request will fail.
|
|
1017
|
+
|
|
1018
|
+
- **hipaaCompliant** _boolean_
|
|
1019
|
+
|
|
1020
|
+
Restricts routing to models and tools from providers that have signed a BAA with Vercel for the use of AI Gateway (requires Vercel HIPAA BAA add on). BYOK credentials are skipped when `hipaaCompliant` is set to `true` to ensure that requests are only routed to providers that support HIPAA compliance.
|
|
1021
|
+
|
|
1022
|
+
- **quotaEntityId** _string_
|
|
1023
|
+
|
|
1024
|
+
The unique identifier for the entity against which quota is tracked. Used for quota management and enforcement purposes.
|
|
633
1025
|
|
|
634
1026
|
- **providerTimeouts** _object_
|
|
635
1027
|
|
|
@@ -639,20 +1031,46 @@ The following gateway provider options are available:
|
|
|
639
1031
|
|
|
640
1032
|
For full details, see [Provider Timeouts](https://vercel.com/docs/ai-gateway/models-and-providers/provider-timeouts).
|
|
641
1033
|
|
|
1034
|
+
- **serviceTier** _'flex' | 'priority'_
|
|
1035
|
+
|
|
1036
|
+
Unified service tier intent. The gateway translates it into whichever
|
|
1037
|
+
per-provider option each provider expects, and overrides any tier
|
|
1038
|
+
also set in the per-provider options. Leave unset for provider
|
|
1039
|
+
default. See the [OpenAI](/providers/ai-sdk-providers/openai),
|
|
1040
|
+
[Google Generative AI](/providers/ai-sdk-providers/google-generative-ai),
|
|
1041
|
+
and [Google Vertex AI](/providers/ai-sdk-providers/google-vertex)
|
|
1042
|
+
provider docs for tier semantics, model availability, and graceful
|
|
1043
|
+
downgrade behavior on each provider.
|
|
1044
|
+
|
|
1045
|
+
```ts
|
|
1046
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
1047
|
+
import { generateText } from 'ai';
|
|
1048
|
+
|
|
1049
|
+
const { text } = await generateText({
|
|
1050
|
+
model: 'openai/gpt-5-mini',
|
|
1051
|
+
prompt: 'Hello',
|
|
1052
|
+
providerOptions: {
|
|
1053
|
+
gateway: {
|
|
1054
|
+
serviceTier: 'priority',
|
|
1055
|
+
} satisfies GatewayProviderOptions,
|
|
1056
|
+
},
|
|
1057
|
+
});
|
|
1058
|
+
```
|
|
1059
|
+
|
|
642
1060
|
You can combine these options to have fine-grained control over routing and tracking:
|
|
643
1061
|
|
|
644
1062
|
```ts
|
|
645
|
-
import type {
|
|
1063
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
646
1064
|
import { generateText } from 'ai';
|
|
647
1065
|
|
|
648
1066
|
const { text } = await generateText({
|
|
649
|
-
model: 'anthropic/claude-sonnet-4',
|
|
1067
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
650
1068
|
prompt: 'Write a haiku about programming',
|
|
651
1069
|
providerOptions: {
|
|
652
1070
|
gateway: {
|
|
653
1071
|
order: ['vertex'], // Prefer Vertex AI
|
|
654
1072
|
only: ['anthropic', 'vertex'], // Only allow these providers
|
|
655
|
-
} satisfies
|
|
1073
|
+
} satisfies GatewayProviderOptions,
|
|
656
1074
|
},
|
|
657
1075
|
});
|
|
658
1076
|
```
|
|
@@ -662,43 +1080,98 @@ const { text } = await generateText({
|
|
|
662
1080
|
The `models` option enables automatic fallback to alternative models when the primary model fails:
|
|
663
1081
|
|
|
664
1082
|
```ts
|
|
665
|
-
import type {
|
|
1083
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
666
1084
|
import { generateText } from 'ai';
|
|
667
1085
|
|
|
668
1086
|
const { text } = await generateText({
|
|
669
|
-
model: 'openai/gpt-
|
|
1087
|
+
model: 'openai/gpt-5.4', // Primary model
|
|
670
1088
|
prompt: 'Write a TypeScript haiku',
|
|
671
1089
|
providerOptions: {
|
|
672
1090
|
gateway: {
|
|
673
|
-
models: ['openai/gpt-5-nano', 'gemini-
|
|
674
|
-
} satisfies
|
|
1091
|
+
models: ['openai/gpt-5.4-nano', 'gemini-3-flash-preview'], // Fallback models
|
|
1092
|
+
} satisfies GatewayProviderOptions,
|
|
675
1093
|
},
|
|
676
1094
|
});
|
|
677
1095
|
|
|
678
1096
|
// This will:
|
|
679
|
-
// 1. Try openai/gpt-
|
|
680
|
-
// 2. If it fails, try openai/gpt-5-nano
|
|
681
|
-
// 3. If that fails, try gemini-
|
|
1097
|
+
// 1. Try openai/gpt-5.4 first
|
|
1098
|
+
// 2. If it fails, try openai/gpt-5.4-nano
|
|
1099
|
+
// 3. If that fails, try gemini-3-flash-preview
|
|
682
1100
|
// 4. Return the result from the first model that succeeds
|
|
683
1101
|
```
|
|
684
1102
|
|
|
685
1103
|
#### Zero Data Retention Example
|
|
686
1104
|
|
|
687
|
-
Set `zeroDataRetention` to true to
|
|
688
|
-
that have zero data retention policies. When `zeroDataRetention` is `false` or not
|
|
689
|
-
specified, there is no enforcement of restricting routing.
|
|
1105
|
+
Set `zeroDataRetention` to true to route requests to providers with zero data retention agreements with Vercel for AI Gateway. BYOK credentials are skipped by default, since your provider agreements differ from Vercel's. When this filter is on, AI Gateway routes only to providers Vercel has ZDR agreements with for the model. If you have BYOK keys marked as ZDR, those keys are tried first, then AI Gateway falls back to its system credentials. You are responsible for the accuracy of that marking. Applies to both account-wide and request-level ZDR. The request fails if no ZDR-eligible credentials are available. When `zeroDataRetention` is `false` or not specified, there is no enforcement of restricting routing. Request-level ZDR is only available for Vercel Pro and Enterprise plans.
|
|
690
1106
|
|
|
691
1107
|
```ts
|
|
692
|
-
import type {
|
|
1108
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
693
1109
|
import { generateText } from 'ai';
|
|
694
1110
|
|
|
695
1111
|
const { text } = await generateText({
|
|
696
|
-
model: 'anthropic/claude-sonnet-4.
|
|
1112
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
697
1113
|
prompt: 'Analyze this sensitive document...',
|
|
698
1114
|
providerOptions: {
|
|
699
1115
|
gateway: {
|
|
700
1116
|
zeroDataRetention: true,
|
|
701
|
-
} satisfies
|
|
1117
|
+
} satisfies GatewayProviderOptions,
|
|
1118
|
+
},
|
|
1119
|
+
});
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
#### Disallow Prompt Training Example
|
|
1123
|
+
|
|
1124
|
+
Set `disallowPromptTraining` to true to route requests to providers that have agreements with Vercel for AI Gateway to not use prompts for model training. When using BYOK credentials, this filter is not applied. If BYOK credentials fail and the request falls back to system credentials, only providers that do not train on prompt data will be used. If there are no providers available for the model that disallow prompt training, the request will fail. When `disallowPromptTraining` is `false` or not specified, there is no enforcement of restricting routing.
|
|
1125
|
+
|
|
1126
|
+
```ts
|
|
1127
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
1128
|
+
import { generateText } from 'ai';
|
|
1129
|
+
|
|
1130
|
+
const { text } = await generateText({
|
|
1131
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
1132
|
+
prompt: 'Analyze this proprietary business data...',
|
|
1133
|
+
providerOptions: {
|
|
1134
|
+
gateway: {
|
|
1135
|
+
disallowPromptTraining: true,
|
|
1136
|
+
} satisfies GatewayProviderOptions,
|
|
1137
|
+
},
|
|
1138
|
+
});
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
#### HIPAA Compliance Example
|
|
1142
|
+
|
|
1143
|
+
Set `hipaaCompliant` to true to route requests only to models or tools by providers that have signed a BAA with Vercel for the use of AI Gateway. If the model or tool does not have a HIPAA-compliant provider, the request will fail. When `hipaaCompliant` is `false` or not specified, there is no enforcement of restricting routing. BYOK credentials are skipped when `hipaaCompliant` is set to `true` to ensure that requests are only routed to providers that support HIPAA compliance.
|
|
1144
|
+
|
|
1145
|
+
```ts
|
|
1146
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
1147
|
+
import { generateText } from 'ai';
|
|
1148
|
+
|
|
1149
|
+
const { text } = await generateText({
|
|
1150
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
1151
|
+
prompt: 'Analyze this patient data...',
|
|
1152
|
+
providerOptions: {
|
|
1153
|
+
gateway: {
|
|
1154
|
+
hipaaCompliant: true,
|
|
1155
|
+
} satisfies GatewayProviderOptions,
|
|
1156
|
+
},
|
|
1157
|
+
});
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
#### Quota Entity ID Example
|
|
1161
|
+
|
|
1162
|
+
Set `quotaEntityId` to track and enforce quota against a specific entity. This is useful for multi-tenant applications where you need to manage quota at the entity level (e.g., per organization or team).
|
|
1163
|
+
|
|
1164
|
+
```ts
|
|
1165
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
1166
|
+
import { generateText } from 'ai';
|
|
1167
|
+
|
|
1168
|
+
const { text } = await generateText({
|
|
1169
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
1170
|
+
prompt: 'Summarize this report...',
|
|
1171
|
+
providerOptions: {
|
|
1172
|
+
gateway: {
|
|
1173
|
+
quotaEntityId: 'org-123',
|
|
1174
|
+
} satisfies GatewayProviderOptions,
|
|
702
1175
|
},
|
|
703
1176
|
});
|
|
704
1177
|
```
|
|
@@ -709,16 +1182,16 @@ When using provider-specific options through AI Gateway, use the actual provider
|
|
|
709
1182
|
|
|
710
1183
|
```ts
|
|
711
1184
|
import type { AnthropicLanguageModelOptions } from '@ai-sdk/anthropic';
|
|
712
|
-
import type {
|
|
1185
|
+
import type { GatewayProviderOptions } from '@ai-sdk/gateway';
|
|
713
1186
|
import { generateText } from 'ai';
|
|
714
1187
|
|
|
715
1188
|
const { text } = await generateText({
|
|
716
|
-
model: 'anthropic/claude-sonnet-4',
|
|
1189
|
+
model: 'anthropic/claude-sonnet-4.6',
|
|
717
1190
|
prompt: 'Explain quantum computing',
|
|
718
1191
|
providerOptions: {
|
|
719
1192
|
gateway: {
|
|
720
1193
|
order: ['vertex', 'anthropic'],
|
|
721
|
-
} satisfies
|
|
1194
|
+
} satisfies GatewayProviderOptions,
|
|
722
1195
|
anthropic: {
|
|
723
1196
|
thinking: { type: 'enabled', budgetTokens: 12000 },
|
|
724
1197
|
} satisfies AnthropicLanguageModelOptions,
|