@ai-sdk/gateway 4.0.64 → 4.0.67
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 +29 -0
- package/dist/index.d.ts +18 -7
- package/dist/index.js +39 -95
- package/dist/index.js.map +1 -1
- package/docs/00-ai-gateway.mdx +8 -2
- package/package.json +2 -2
- package/src/gateway-language-model-batch.ts +27 -126
- package/src/gateway-language-model-settings.ts +4 -6
- package/src/gateway-video-model-settings.ts +1 -0
- package/src/tool/tako-search.ts +25 -10
package/docs/00-ai-gateway.mdx
CHANGED
|
@@ -207,6 +207,12 @@ const { text } = await generateText({
|
|
|
207
207
|
|
|
208
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)).
|
|
209
209
|
|
|
210
|
+
When an upstream provider reports a well-formed error after streaming has
|
|
211
|
+
started, AI SDK Core exposes it as a
|
|
212
|
+
[`StreamProviderError`](/docs/reference/ai-sdk-errors/ai-stream-provider-error).
|
|
213
|
+
Use its `type`, `code`, `statusCode`, and `isRetryable` metadata to classify
|
|
214
|
+
the failure without inspecting the Gateway's serialized error payload.
|
|
215
|
+
|
|
210
216
|
## Text Batches
|
|
211
217
|
|
|
212
218
|
<Note type="warning">
|
|
@@ -1017,9 +1023,9 @@ The Tako Search tool supports these optional configuration options:
|
|
|
1017
1023
|
- **includeContents** _boolean_ - Inline each page's extracted full text in `content`. **articleContentMaxChars** caps it, defaulting to 30,000 characters (maximum 1,000,000).
|
|
1018
1024
|
- **sources.data** _object_ - Configure data results:
|
|
1019
1025
|
- **count** _number_ - Maximum data results, 1-20. Defaults to 5.
|
|
1020
|
-
- **includeContents** _boolean_ - Inline each card's underlying rows in `content.dataset` as typed, unit-labeled columns.
|
|
1026
|
+
- **includeContents** _boolean_ - Inline each card's underlying rows in `content.dataset` as typed, unit-labeled columns. This adds a data surcharge based on the row count and dataset source. To estimate cost, first search with `includeContents: false` and inspect `cards.content.export_pricing`. Because this applies to every returned card, use `count` and `maxRows` to control cost.
|
|
1021
1027
|
- **contentFormat** _'json_compact' | 'json_records' | 'csv' | 'card_json'_ - Serialization for inlined card data. Defaults to `'json_compact'`.
|
|
1022
|
-
- **maxRows** _number_ - Row cap
|
|
1028
|
+
- **maxRows** _number_ - Row cap per result. Omit to use the allowance in `cards.content.export_pricing`. A data surcharge applies per 1,000 exported rows; lower values reduce cost.
|
|
1023
1029
|
- **nodeIds** _string[]_ - Data Graph node IDs to prioritize. Up to 20.
|
|
1024
1030
|
- **strict** _boolean_ - Only return cards matching `nodeIds`. Requires at least one `nodeIds` value.
|
|
1025
1031
|
- **location** _object_ - End-user `{ latitude, longitude }` coordinates for localized results.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/gateway",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "4.0.
|
|
4
|
+
"version": "4.0.67",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ai-sdk/provider": "4.0.8",
|
|
34
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
34
|
+
"@ai-sdk/provider-utils": "5.0.32",
|
|
35
35
|
"@vercel/oidc": "3.2.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
APICallError,
|
|
3
2
|
type Experimental_BatchLanguageModelV4 as BatchLanguageModelV4,
|
|
4
3
|
type Experimental_BatchV4ItemResult as BatchV4ItemResult,
|
|
5
4
|
type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
|
|
@@ -15,9 +14,10 @@ import {
|
|
|
15
14
|
combineHeaders,
|
|
16
15
|
convertAsyncIteratorToReadableStream,
|
|
17
16
|
createJsonErrorResponseHandler,
|
|
17
|
+
createJsonLinesResponseHandler,
|
|
18
18
|
createJsonResponseHandler,
|
|
19
19
|
getErrorMessage,
|
|
20
|
-
|
|
20
|
+
normalizeBatchRequestCounts,
|
|
21
21
|
postJsonToApi,
|
|
22
22
|
resolve,
|
|
23
23
|
WORKFLOW_SERIALIZE,
|
|
@@ -190,7 +190,7 @@ export class GatewayBatchLanguageModel
|
|
|
190
190
|
: undefined;
|
|
191
191
|
|
|
192
192
|
try {
|
|
193
|
-
const { value:
|
|
193
|
+
const { value: lines } = await postJsonToApi({
|
|
194
194
|
url: this.getBatchUrl('results'),
|
|
195
195
|
headers: combineHeaders(
|
|
196
196
|
resolvedHeaders,
|
|
@@ -199,28 +199,9 @@ export class GatewayBatchLanguageModel
|
|
|
199
199
|
await resolve(this.config.o11yHeaders),
|
|
200
200
|
),
|
|
201
201
|
body: { batchId },
|
|
202
|
-
successfulResponseHandler:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
requestBodyValues,
|
|
206
|
-
}: {
|
|
207
|
-
url: string;
|
|
208
|
-
requestBodyValues: unknown;
|
|
209
|
-
response: Response;
|
|
210
|
-
}) => {
|
|
211
|
-
if (response.body == null) {
|
|
212
|
-
throw new APICallError({
|
|
213
|
-
message: 'Batch results response body is empty',
|
|
214
|
-
url,
|
|
215
|
-
requestBodyValues,
|
|
216
|
-
statusCode: response.status,
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
return {
|
|
220
|
-
value: response.body,
|
|
221
|
-
responseHeaders: Object.fromEntries([...response.headers]),
|
|
222
|
-
};
|
|
223
|
-
},
|
|
202
|
+
successfulResponseHandler: createJsonLinesResponseHandler(
|
|
203
|
+
gatewayBatchItemResultLineSchema,
|
|
204
|
+
),
|
|
224
205
|
failedResponseHandler: createJsonErrorResponseHandler({
|
|
225
206
|
errorSchema: z.any(),
|
|
226
207
|
errorToMessage: data => getErrorMessage(data) ?? 'unknown error',
|
|
@@ -230,7 +211,7 @@ export class GatewayBatchLanguageModel
|
|
|
230
211
|
});
|
|
231
212
|
|
|
232
213
|
return convertAsyncIteratorToReadableStream(
|
|
233
|
-
|
|
214
|
+
convertGatewayBatchResultLines(lines),
|
|
234
215
|
);
|
|
235
216
|
} catch (error) {
|
|
236
217
|
if (isAbortOrTimeoutError(error)) {
|
|
@@ -342,7 +323,12 @@ function convertGatewayBatchStatus(body: {
|
|
|
342
323
|
expiresAt?: string | null;
|
|
343
324
|
providerMetadata?: Record<string, Record<string, unknown>> | null;
|
|
344
325
|
}): BatchV4Status {
|
|
345
|
-
const requestCounts =
|
|
326
|
+
const requestCounts = normalizeBatchRequestCounts({
|
|
327
|
+
total: body.requestCounts?.total,
|
|
328
|
+
pending: body.requestCounts?.pending,
|
|
329
|
+
completed: body.requestCounts?.completed,
|
|
330
|
+
failed: body.requestCounts?.failed,
|
|
331
|
+
});
|
|
346
332
|
|
|
347
333
|
return {
|
|
348
334
|
status: body.status,
|
|
@@ -367,112 +353,27 @@ function convertGatewayBatchStatus(body: {
|
|
|
367
353
|
}
|
|
368
354
|
|
|
369
355
|
/**
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* full set is present rather than fabricating zeros.
|
|
373
|
-
*/
|
|
374
|
-
function convertGatewayBatchRequestCounts(
|
|
375
|
-
counts:
|
|
376
|
-
| {
|
|
377
|
-
total?: number | null;
|
|
378
|
-
pending?: number | null;
|
|
379
|
-
completed?: number | null;
|
|
380
|
-
failed?: number | null;
|
|
381
|
-
}
|
|
382
|
-
| null
|
|
383
|
-
| undefined,
|
|
384
|
-
): BatchV4Status['requestCounts'] | undefined {
|
|
385
|
-
if (
|
|
386
|
-
counts == null ||
|
|
387
|
-
typeof counts.total !== 'number' ||
|
|
388
|
-
typeof counts.pending !== 'number' ||
|
|
389
|
-
typeof counts.completed !== 'number' ||
|
|
390
|
-
typeof counts.failed !== 'number'
|
|
391
|
-
) {
|
|
392
|
-
return undefined;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
return {
|
|
396
|
-
total: counts.total,
|
|
397
|
-
pending: counts.pending,
|
|
398
|
-
completed: counts.completed,
|
|
399
|
-
failed: counts.failed,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* Incremental NDJSON line splitter for the batch results stream: buffers
|
|
405
|
-
* partial lines across chunks and flushes a trailing line without a final
|
|
406
|
-
* newline. Each non-empty line is one `BatchV4ItemResult` JSON object.
|
|
356
|
+
* Converts the minimally validated Gateway batch result lines. The Gateway
|
|
357
|
+
* already sanitizes the complete result objects server-side.
|
|
407
358
|
*
|
|
408
|
-
* @
|
|
409
|
-
* @yields One minimally-validated `BatchV4ItemResult` per non-empty line.
|
|
359
|
+
* @yields Each Gateway batch item result.
|
|
410
360
|
*/
|
|
411
|
-
async function*
|
|
412
|
-
|
|
361
|
+
async function* convertGatewayBatchResultLines(
|
|
362
|
+
lines: AsyncIterable<unknown>,
|
|
413
363
|
): AsyncGenerator<BatchV4ItemResult<LanguageModelV4GenerateResult>> {
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
if (done) {
|
|
424
|
-
finished = true;
|
|
425
|
-
buffer += decoder.decode();
|
|
426
|
-
break;
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
buffer += decoder.decode(value, { stream: true });
|
|
430
|
-
|
|
431
|
-
let lineEnd = buffer.indexOf('\n');
|
|
432
|
-
while (lineEnd !== -1) {
|
|
433
|
-
const line = buffer.slice(0, lineEnd).replace(/\r$/, '');
|
|
434
|
-
buffer = buffer.slice(lineEnd + 1);
|
|
435
|
-
|
|
436
|
-
if (line.trim().length > 0) {
|
|
437
|
-
yield await parseGatewayBatchResultLine(line);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
lineEnd = buffer.indexOf('\n');
|
|
364
|
+
for await (const line of lines) {
|
|
365
|
+
const item = line as BatchV4ItemResult<LanguageModelV4GenerateResult>;
|
|
366
|
+
|
|
367
|
+
// JSON carries `response.timestamp` as an ISO string; core expects a Date.
|
|
368
|
+
if (item.status === 'succeeded') {
|
|
369
|
+
const response = item.result?.response;
|
|
370
|
+
if (response !== undefined && typeof response.timestamp === 'string') {
|
|
371
|
+
response.timestamp = new Date(response.timestamp);
|
|
441
372
|
}
|
|
442
373
|
}
|
|
443
374
|
|
|
444
|
-
|
|
445
|
-
if (finalLine.trim().length > 0) {
|
|
446
|
-
yield await parseGatewayBatchResultLine(finalLine);
|
|
447
|
-
}
|
|
448
|
-
} finally {
|
|
449
|
-
if (!finished) {
|
|
450
|
-
await reader.cancel().catch(() => {});
|
|
451
|
-
}
|
|
452
|
-
reader.releaseLock();
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
async function parseGatewayBatchResultLine(
|
|
457
|
-
line: string,
|
|
458
|
-
): Promise<BatchV4ItemResult<LanguageModelV4GenerateResult>> {
|
|
459
|
-
// Minimal validation (id + status); items pass through otherwise — the
|
|
460
|
-
// Gateway already sanitizes them server-side.
|
|
461
|
-
const parsed = await parseJSON({
|
|
462
|
-
text: line,
|
|
463
|
-
schema: gatewayBatchItemResultLineSchema,
|
|
464
|
-
});
|
|
465
|
-
const item =
|
|
466
|
-
parsed as unknown as BatchV4ItemResult<LanguageModelV4GenerateResult>;
|
|
467
|
-
// JSON carries `response.timestamp` as an ISO string; core expects a Date
|
|
468
|
-
// (`GeneratedFile`-style consumers call `.toISOString()`).
|
|
469
|
-
if (item.status === 'succeeded') {
|
|
470
|
-
const response = item.result?.response;
|
|
471
|
-
if (response !== undefined && typeof response.timestamp === 'string') {
|
|
472
|
-
response.timestamp = new Date(response.timestamp);
|
|
473
|
-
}
|
|
375
|
+
yield item;
|
|
474
376
|
}
|
|
475
|
-
return item;
|
|
476
377
|
}
|
|
477
378
|
|
|
478
379
|
const gatewayBatchItemResultLineSchema = z
|
|
@@ -47,7 +47,6 @@ export type GatewayModelId =
|
|
|
47
47
|
| 'anthropic/claude-sonnet-4.6'
|
|
48
48
|
| 'anthropic/claude-sonnet-5'
|
|
49
49
|
| 'arcee-ai/trinity-large-thinking'
|
|
50
|
-
| 'arcee-ai/trinity-mini'
|
|
51
50
|
| 'bytedance/seed-1.6'
|
|
52
51
|
| 'bytedance/seed-1.8'
|
|
53
52
|
| 'cohere/command-a'
|
|
@@ -103,13 +102,13 @@ export type GatewayModelId =
|
|
|
103
102
|
| 'minimax/minimax-m2.5'
|
|
104
103
|
| 'minimax/minimax-m2.5-highspeed'
|
|
105
104
|
| 'minimax/minimax-m2.7'
|
|
105
|
+
| 'minimax/minimax-m2.7-free'
|
|
106
106
|
| 'minimax/minimax-m2.7-highspeed'
|
|
107
107
|
| 'minimax/minimax-m3'
|
|
108
|
+
| 'minimax/minimax-m3-free'
|
|
108
109
|
| 'mistral/codestral'
|
|
109
110
|
| 'mistral/devstral-2'
|
|
110
111
|
| 'mistral/devstral-small-2'
|
|
111
|
-
| 'mistral/magistral-medium'
|
|
112
|
-
| 'mistral/magistral-small'
|
|
113
112
|
| 'mistral/ministral-14b'
|
|
114
113
|
| 'mistral/ministral-3b'
|
|
115
114
|
| 'mistral/ministral-8b'
|
|
@@ -133,7 +132,6 @@ export type GatewayModelId =
|
|
|
133
132
|
| 'nvidia/nemotron-3-super-120b-a12b'
|
|
134
133
|
| 'nvidia/nemotron-3-ultra-550b-a55b'
|
|
135
134
|
| 'nvidia/nemotron-3.5-lightning'
|
|
136
|
-
| 'nvidia/nemotron-3.5-lightning-free'
|
|
137
135
|
| 'nvidia/nemotron-nano-12b-v2-vl'
|
|
138
136
|
| 'nvidia/nemotron-nano-9b-v2'
|
|
139
137
|
| 'openai/gpt-3.5-turbo'
|
|
@@ -148,7 +146,6 @@ export type GatewayModelId =
|
|
|
148
146
|
| 'openai/gpt-4o-fast'
|
|
149
147
|
| 'openai/gpt-4o-mini'
|
|
150
148
|
| 'openai/gpt-4o-mini-fast'
|
|
151
|
-
| 'openai/gpt-4o-mini-search-preview'
|
|
152
149
|
| 'openai/gpt-5'
|
|
153
150
|
| 'openai/gpt-5-codex'
|
|
154
151
|
| 'openai/gpt-5-fast'
|
|
@@ -184,10 +181,10 @@ export type GatewayModelId =
|
|
|
184
181
|
| 'openai/gpt-5.6-terra-fast'
|
|
185
182
|
| 'openai/gpt-oss-120b'
|
|
186
183
|
| 'openai/gpt-oss-20b'
|
|
184
|
+
| 'openai/gpt-oss-safeguard-120b'
|
|
187
185
|
| 'openai/gpt-oss-safeguard-20b'
|
|
188
186
|
| 'openai/o1'
|
|
189
187
|
| 'openai/o3'
|
|
190
|
-
| 'openai/o3-deep-research'
|
|
191
188
|
| 'openai/o3-fast'
|
|
192
189
|
| 'openai/o3-mini'
|
|
193
190
|
| 'openai/o3-pro'
|
|
@@ -235,5 +232,6 @@ export type GatewayModelId =
|
|
|
235
232
|
| 'zai/glm-5.2'
|
|
236
233
|
| 'zai/glm-5.2-fast'
|
|
237
234
|
| 'zai/glm-5.3'
|
|
235
|
+
| 'zai/glm-5.3-flash'
|
|
238
236
|
| 'zai/glm-5v-turbo'
|
|
239
237
|
| (string & {});
|
package/src/tool/tako-search.ts
CHANGED
|
@@ -14,15 +14,28 @@ export type TakoContentFormat =
|
|
|
14
14
|
| 'json_records';
|
|
15
15
|
|
|
16
16
|
export interface TakoDataSourceConfig {
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* Maximum number of data results to return (1-20). When includeContents is
|
|
19
|
+
* true, each additional result adds its own data surcharge.
|
|
20
|
+
*/
|
|
18
21
|
count?: number;
|
|
19
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Inline rows for each data result. This adds a data surcharge based on row
|
|
24
|
+
* count and dataset source. To estimate cost, search with includeContents
|
|
25
|
+
* disabled and inspect cards.content.export_pricing. This applies to every
|
|
26
|
+
* returned card; limit sources.data.count and sources.data.maxRows to control
|
|
27
|
+
* cost.
|
|
28
|
+
*/
|
|
20
29
|
includeContents?: boolean;
|
|
21
30
|
/** Requested delivery mode for card data. Search cards are always inlined. */
|
|
22
31
|
mode?: 'inline' | 'url';
|
|
23
32
|
/** Serialization for inlined card data. */
|
|
24
33
|
contentFormat?: TakoContentFormat;
|
|
25
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Maximum rows to inline per result. Omit to use the allowance in
|
|
36
|
+
* cards.content.export_pricing. A data surcharge applies per 1,000 exported
|
|
37
|
+
* rows; lower values reduce cost.
|
|
38
|
+
*/
|
|
26
39
|
maxRows?: number;
|
|
27
40
|
/** Data Graph node IDs to prioritize. */
|
|
28
41
|
nodeIds?: string[];
|
|
@@ -190,7 +203,6 @@ export interface TakoCard {
|
|
|
190
203
|
relevance?: 'High' | 'Low' | 'Medium' | null;
|
|
191
204
|
content?: TakoResultContent | null;
|
|
192
205
|
exportable?: boolean;
|
|
193
|
-
relevance_score?: number | null;
|
|
194
206
|
nodes?: Array<{
|
|
195
207
|
id: string;
|
|
196
208
|
type: 'entity' | 'metric';
|
|
@@ -215,7 +227,6 @@ export interface TakoWebResult {
|
|
|
215
227
|
source_name?: string | null;
|
|
216
228
|
publish_date?: string | null;
|
|
217
229
|
content?: TakoResultContent | null;
|
|
218
|
-
citation_number?: number | null;
|
|
219
230
|
}
|
|
220
231
|
|
|
221
232
|
export interface TakoSearchResponse {
|
|
@@ -254,11 +265,15 @@ const takoDataSourceInputSchema = z.object({
|
|
|
254
265
|
count: z
|
|
255
266
|
.number()
|
|
256
267
|
.optional()
|
|
257
|
-
.describe(
|
|
268
|
+
.describe(
|
|
269
|
+
'Maximum number of data results to return (1-20). When include_contents is true, each additional result adds its own data surcharge.',
|
|
270
|
+
),
|
|
258
271
|
include_contents: z
|
|
259
272
|
.boolean()
|
|
260
273
|
.optional()
|
|
261
|
-
.describe(
|
|
274
|
+
.describe(
|
|
275
|
+
'Inline rows for each data result. This adds a data surcharge based on row count and dataset source. To estimate cost, search with include_contents disabled and inspect cards.content.export_pricing. This applies to every returned card; limit sources.data.count and sources.data.max_rows to control cost.',
|
|
276
|
+
),
|
|
262
277
|
mode: z
|
|
263
278
|
.enum(['inline', 'url'])
|
|
264
279
|
.optional()
|
|
@@ -272,7 +287,9 @@ const takoDataSourceInputSchema = z.object({
|
|
|
272
287
|
max_rows: z
|
|
273
288
|
.number()
|
|
274
289
|
.optional()
|
|
275
|
-
.describe(
|
|
290
|
+
.describe(
|
|
291
|
+
'Maximum rows to inline per result. Omit to use the allowance in cards.content.export_pricing. A data surcharge applies per 1,000 exported rows; lower values reduce cost.',
|
|
292
|
+
),
|
|
276
293
|
node_ids: z
|
|
277
294
|
.array(z.string())
|
|
278
295
|
.optional()
|
|
@@ -493,7 +510,6 @@ const takoCardSchema = z
|
|
|
493
510
|
relevance: z.enum(['High', 'Low', 'Medium']).nullish(),
|
|
494
511
|
content: takoResultContentSchema.nullish(),
|
|
495
512
|
exportable: z.boolean().optional(),
|
|
496
|
-
relevance_score: z.number().nullish(),
|
|
497
513
|
nodes: z
|
|
498
514
|
.array(
|
|
499
515
|
z.object({
|
|
@@ -525,7 +541,6 @@ const takoWebResultSchema = z
|
|
|
525
541
|
source_name: z.string().nullish(),
|
|
526
542
|
publish_date: z.string().nullish(),
|
|
527
543
|
content: takoResultContentSchema.nullish(),
|
|
528
|
-
citation_number: z.number().nullish(),
|
|
529
544
|
})
|
|
530
545
|
.passthrough();
|
|
531
546
|
|