ai 6.0.178 → 6.0.182
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 +30 -0
- package/README.md +1 -1
- package/dist/index.js +82 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +79 -20
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +86 -18
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +86 -18
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/prompt/convert-to-language-model-prompt.ts +101 -27
- package/src/ui/validate-ui-messages.ts +2 -2
- package/src/util/retry-with-exponential-backoff.ts +10 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.182",
|
|
4
4
|
"description": "AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@opentelemetry/api": "^1.9.0",
|
|
48
|
-
"@ai-sdk/gateway": "3.0.
|
|
48
|
+
"@ai-sdk/gateway": "3.0.114",
|
|
49
49
|
"@ai-sdk/provider": "3.0.10",
|
|
50
50
|
"@ai-sdk/provider-utils": "4.0.27"
|
|
51
51
|
},
|
|
@@ -25,7 +25,10 @@ import {
|
|
|
25
25
|
createDefaultDownloadFunction,
|
|
26
26
|
type DownloadFunction,
|
|
27
27
|
} from '../util/download/download-function';
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
convertDataContentToBase64String,
|
|
30
|
+
convertToLanguageModelV3DataContent,
|
|
31
|
+
} from './data-content';
|
|
29
32
|
import { InvalidMessageRoleError } from './invalid-message-role-error';
|
|
30
33
|
import type { StandardizedPrompt } from './standardize-prompt';
|
|
31
34
|
import { asArray } from '../util/as-array';
|
|
@@ -283,7 +286,10 @@ export function convertToLanguageModelMessage({
|
|
|
283
286
|
type: 'tool-result' as const,
|
|
284
287
|
toolCallId: part.toolCallId,
|
|
285
288
|
toolName: part.toolName,
|
|
286
|
-
output: mapToolResultOutput(
|
|
289
|
+
output: mapToolResultOutput({
|
|
290
|
+
output: part.output,
|
|
291
|
+
downloadedAssets,
|
|
292
|
+
}),
|
|
287
293
|
providerOptions,
|
|
288
294
|
};
|
|
289
295
|
}
|
|
@@ -309,7 +315,10 @@ export function convertToLanguageModelMessage({
|
|
|
309
315
|
type: 'tool-result' as const,
|
|
310
316
|
toolCallId: part.toolCallId,
|
|
311
317
|
toolName: part.toolName,
|
|
312
|
-
output: mapToolResultOutput(
|
|
318
|
+
output: mapToolResultOutput({
|
|
319
|
+
output: part.output,
|
|
320
|
+
downloadedAssets,
|
|
321
|
+
}),
|
|
313
322
|
providerOptions: part.providerOptions,
|
|
314
323
|
};
|
|
315
324
|
}
|
|
@@ -344,28 +353,59 @@ async function downloadAssets(
|
|
|
344
353
|
): Promise<
|
|
345
354
|
Record<string, { mediaType: string | undefined; data: Uint8Array }>
|
|
346
355
|
> {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
.
|
|
355
|
-
(
|
|
356
|
-
part.type === 'image' || part.type === 'file'
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (typeof data === 'string') {
|
|
364
|
-
try {
|
|
365
|
-
data = new URL(data);
|
|
366
|
-
} catch (ignored) {}
|
|
356
|
+
type DownloadableFile = {
|
|
357
|
+
mediaType: string | undefined;
|
|
358
|
+
data: DataContent | URL;
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
const downloadableFiles: DownloadableFile[] = [];
|
|
362
|
+
for (const message of messages) {
|
|
363
|
+
if (message.role === 'user' && Array.isArray(message.content)) {
|
|
364
|
+
for (const part of message.content) {
|
|
365
|
+
if (part.type === 'image' || part.type === 'file') {
|
|
366
|
+
downloadableFiles.push({
|
|
367
|
+
data: part.type === 'image' ? part.image : part.data,
|
|
368
|
+
mediaType:
|
|
369
|
+
part.mediaType ?? (part.type === 'image' ? 'image/*' : undefined),
|
|
370
|
+
});
|
|
371
|
+
}
|
|
367
372
|
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (message.role === 'tool' || message.role === 'assistant') {
|
|
376
|
+
if (!Array.isArray(message.content)) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
for (const part of message.content) {
|
|
381
|
+
if (part.type !== 'tool-result') {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
368
384
|
|
|
385
|
+
if (part.output.type !== 'content') {
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
for (const contentPart of part.output.value) {
|
|
390
|
+
if (
|
|
391
|
+
contentPart.type === 'image-url' ||
|
|
392
|
+
contentPart.type === 'file-url'
|
|
393
|
+
) {
|
|
394
|
+
downloadableFiles.push({
|
|
395
|
+
data: new URL(contentPart.url),
|
|
396
|
+
mediaType:
|
|
397
|
+
contentPart.type === 'image-url' ? 'image/*' : undefined,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const plannedDownloads = downloadableFiles
|
|
406
|
+
.map(part => {
|
|
407
|
+
const mediaType = part.mediaType;
|
|
408
|
+
const { data } = convertToLanguageModelV3DataContent(part.data);
|
|
369
409
|
return { mediaType, data };
|
|
370
410
|
})
|
|
371
411
|
|
|
@@ -383,7 +423,6 @@ async function downloadAssets(
|
|
|
383
423
|
supportedUrls,
|
|
384
424
|
}),
|
|
385
425
|
}));
|
|
386
|
-
|
|
387
426
|
// download in parallel:
|
|
388
427
|
const downloadedFiles = await download(plannedDownloads);
|
|
389
428
|
|
|
@@ -492,9 +531,16 @@ function convertPartToLanguageModelPart(
|
|
|
492
531
|
}
|
|
493
532
|
}
|
|
494
533
|
|
|
495
|
-
function mapToolResultOutput(
|
|
496
|
-
output
|
|
497
|
-
|
|
534
|
+
function mapToolResultOutput({
|
|
535
|
+
output,
|
|
536
|
+
downloadedAssets,
|
|
537
|
+
}: {
|
|
538
|
+
output: ToolResultOutput;
|
|
539
|
+
downloadedAssets: Record<
|
|
540
|
+
string,
|
|
541
|
+
{ mediaType: string | undefined; data: Uint8Array }
|
|
542
|
+
>;
|
|
543
|
+
}): LanguageModelV3ToolResultOutput {
|
|
498
544
|
if (output.type !== 'content') {
|
|
499
545
|
return output;
|
|
500
546
|
}
|
|
@@ -502,6 +548,34 @@ function mapToolResultOutput(
|
|
|
502
548
|
return {
|
|
503
549
|
type: 'content',
|
|
504
550
|
value: output.value.map(item => {
|
|
551
|
+
if (item.type === 'image-url') {
|
|
552
|
+
const downloadedFile = downloadedAssets[new URL(item.url).toString()];
|
|
553
|
+
if (downloadedFile) {
|
|
554
|
+
return {
|
|
555
|
+
type: 'image-data' as const,
|
|
556
|
+
data: convertDataContentToBase64String(downloadedFile.data),
|
|
557
|
+
mediaType: downloadedFile.mediaType ?? 'image/*',
|
|
558
|
+
providerOptions: item.providerOptions,
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return item;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (item.type === 'file-url') {
|
|
566
|
+
const downloadedFile = downloadedAssets[new URL(item.url).toString()];
|
|
567
|
+
if (downloadedFile) {
|
|
568
|
+
return {
|
|
569
|
+
type: 'file-data' as const,
|
|
570
|
+
data: convertDataContentToBase64String(downloadedFile.data),
|
|
571
|
+
mediaType: downloadedFile.mediaType ?? 'application/octet-stream',
|
|
572
|
+
providerOptions: item.providerOptions,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return item;
|
|
577
|
+
}
|
|
578
|
+
|
|
505
579
|
if (item.type !== 'media') {
|
|
506
580
|
return item;
|
|
507
581
|
}
|
|
@@ -168,7 +168,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
168
168
|
toolCallId: z.string(),
|
|
169
169
|
toolMetadata: toolMetadataSchema.optional(),
|
|
170
170
|
state: z.literal('output-error'),
|
|
171
|
-
input: z.unknown(),
|
|
171
|
+
input: z.unknown().optional(),
|
|
172
172
|
rawInput: z.unknown().optional(),
|
|
173
173
|
providerExecuted: z.boolean().optional(),
|
|
174
174
|
output: z.never().optional(),
|
|
@@ -282,7 +282,7 @@ const uiMessagesSchema = lazySchema(() =>
|
|
|
282
282
|
toolMetadata: toolMetadataSchema.optional(),
|
|
283
283
|
state: z.literal('output-error'),
|
|
284
284
|
providerExecuted: z.boolean().optional(),
|
|
285
|
-
input: z.unknown(),
|
|
285
|
+
input: z.unknown().optional(),
|
|
286
286
|
rawInput: z.unknown().optional(),
|
|
287
287
|
output: z.never().optional(),
|
|
288
288
|
errorText: z.string(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { APICallError } from '@ai-sdk/provider';
|
|
2
|
+
import { GatewayError } from '@ai-sdk/gateway';
|
|
2
3
|
import { delay, getErrorMessage, isAbortError } from '@ai-sdk/provider-utils';
|
|
3
4
|
import { RetryError } from './retry-error';
|
|
4
5
|
|
|
@@ -10,10 +11,14 @@ function getRetryDelayInMs({
|
|
|
10
11
|
error,
|
|
11
12
|
exponentialBackoffDelay,
|
|
12
13
|
}: {
|
|
13
|
-
error: APICallError;
|
|
14
|
+
error: APICallError | GatewayError;
|
|
14
15
|
exponentialBackoffDelay: number;
|
|
15
16
|
}): number {
|
|
16
|
-
const headers = error
|
|
17
|
+
const headers = APICallError.isInstance(error)
|
|
18
|
+
? error.responseHeaders
|
|
19
|
+
: APICallError.isInstance(error.cause)
|
|
20
|
+
? (error.cause as APICallError).responseHeaders
|
|
21
|
+
: undefined;
|
|
17
22
|
|
|
18
23
|
if (!headers) return exponentialBackoffDelay;
|
|
19
24
|
|
|
@@ -117,13 +122,13 @@ async function _retryWithExponentialBackoff<OUTPUT>(
|
|
|
117
122
|
|
|
118
123
|
if (
|
|
119
124
|
error instanceof Error &&
|
|
120
|
-
APICallError.isInstance(error) &&
|
|
121
|
-
|
|
125
|
+
((APICallError.isInstance(error) && error.isRetryable === true) ||
|
|
126
|
+
(GatewayError.isInstance(error) && error.isRetryable === true)) &&
|
|
122
127
|
tryNumber <= maxRetries
|
|
123
128
|
) {
|
|
124
129
|
await delay(
|
|
125
130
|
getRetryDelayInMs({
|
|
126
|
-
error,
|
|
131
|
+
error: error as APICallError | GatewayError,
|
|
127
132
|
exponentialBackoffDelay: delayInMs,
|
|
128
133
|
}),
|
|
129
134
|
{ abortSignal },
|