@ai-sdk/google 4.0.80 → 4.0.82
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 +17 -0
- package/dist/index.js +479 -519
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +6 -0
- package/dist/internal/index.js +342 -342
- package/dist/internal/index.js.map +1 -1
- package/docs/15-google.mdx +3 -3
- package/package.json +3 -3
- package/src/convert-to-google-messages.ts +30 -9
- package/src/download-tool-result-files.ts +20 -2
- package/src/google-language-model.ts +16 -0
- package/src/google-prompt.ts +7 -3
- package/src/interactions/convert-to-google-interactions-input.ts +2 -2
- package/src/interactions/google-interactions-prompt.ts +2 -2
package/docs/15-google.mdx
CHANGED
|
@@ -1626,7 +1626,7 @@ These parts are informational and do not require a tool response. They are
|
|
|
1626
1626
|
available from both `generateText` and `streamText`.
|
|
1627
1627
|
|
|
1628
1628
|
For static processing, use `'static'` or provide clipping and frame-rate
|
|
1629
|
-
options:
|
|
1629
|
+
options. `startOffset` and `endOffset` are measured in seconds:
|
|
1630
1630
|
|
|
1631
1631
|
```ts
|
|
1632
1632
|
const video = {
|
|
@@ -1637,8 +1637,8 @@ const video = {
|
|
|
1637
1637
|
google: {
|
|
1638
1638
|
processing: {
|
|
1639
1639
|
type: 'static',
|
|
1640
|
-
startOffset:
|
|
1641
|
-
endOffset:
|
|
1640
|
+
startOffset: 0,
|
|
1641
|
+
endOffset: 10.5,
|
|
1642
1642
|
fps: 0.5,
|
|
1643
1643
|
},
|
|
1644
1644
|
} satisfies GoogleInteractionsVideoOptions,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.82",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@ai-sdk/provider": "4.0.18",
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.49"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@ai-sdk/test-server": "2.0.
|
|
42
|
+
"@ai-sdk/test-server": "2.0.2",
|
|
43
43
|
"@types/node": "22.19.19",
|
|
44
44
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
45
45
|
"tsup": "^8.5.1",
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
convertToBase64,
|
|
10
10
|
getTopLevelMediaType,
|
|
11
11
|
isFullMediaType,
|
|
12
|
+
isUrlSupported,
|
|
12
13
|
resolveFullMediaType,
|
|
13
14
|
resolveProviderReference,
|
|
14
15
|
secureJsonParse,
|
|
@@ -52,9 +53,6 @@ function parseBase64DataUrl(
|
|
|
52
53
|
function convertUrlToolResultPart(
|
|
53
54
|
url: string,
|
|
54
55
|
): GoogleFunctionResponsePart | undefined {
|
|
55
|
-
// Per https://ai.google.dev/api/caching#FunctionResponsePart, only inline data is supported.
|
|
56
|
-
// https://docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/function-calling#functionresponsepart suggests that this
|
|
57
|
-
// may be different for Vertex, but this needs to be confirmed and further tested for both APIs.
|
|
58
56
|
const parsedDataUrl = parseBase64DataUrl(url);
|
|
59
57
|
if (parsedDataUrl == null) {
|
|
60
58
|
return undefined;
|
|
@@ -106,6 +104,7 @@ function appendToolResultParts(
|
|
|
106
104
|
>['value'],
|
|
107
105
|
toolCallId?: string,
|
|
108
106
|
includeFunctionCallIds = true,
|
|
107
|
+
supportedUrls: Record<string, RegExp[]> = {},
|
|
109
108
|
): void {
|
|
110
109
|
const functionResponseParts: GoogleFunctionResponsePart[] = [];
|
|
111
110
|
const responseTextParts: string[] = [];
|
|
@@ -125,12 +124,30 @@ function appendToolResultParts(
|
|
|
125
124
|
},
|
|
126
125
|
});
|
|
127
126
|
} else if (contentPart.data.type === 'url') {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
127
|
+
const url = contentPart.data.url.toString();
|
|
128
|
+
const convertedUrlPart = convertUrlToolResultPart(url);
|
|
129
|
+
const supportedUrl =
|
|
130
|
+
contentPart.data.url.protocol === 'gs:' &&
|
|
131
|
+
contentPart.data.originalUrl != null
|
|
132
|
+
? contentPart.data.originalUrl
|
|
133
|
+
: url;
|
|
134
|
+
|
|
135
|
+
if (convertedUrlPart != null) {
|
|
136
|
+
functionResponseParts.push(convertedUrlPart);
|
|
137
|
+
} else if (
|
|
138
|
+
isFullMediaType(contentPart.mediaType) &&
|
|
139
|
+
isUrlSupported({
|
|
140
|
+
url: supportedUrl,
|
|
141
|
+
mediaType: contentPart.mediaType,
|
|
142
|
+
supportedUrls,
|
|
143
|
+
})
|
|
144
|
+
) {
|
|
145
|
+
functionResponseParts.push({
|
|
146
|
+
fileData: {
|
|
147
|
+
mimeType: contentPart.mediaType,
|
|
148
|
+
fileUri: supportedUrl,
|
|
149
|
+
},
|
|
150
|
+
});
|
|
134
151
|
} else {
|
|
135
152
|
responseTextParts.push(JSON.stringify(contentPart));
|
|
136
153
|
}
|
|
@@ -242,6 +259,7 @@ export function convertToGoogleMessages(
|
|
|
242
259
|
providerOptionsNames?: readonly string[];
|
|
243
260
|
supportsFunctionResponseParts?: boolean;
|
|
244
261
|
includeFunctionCallIds?: boolean;
|
|
262
|
+
supportedFunctionResponseUrls?: Record<string, RegExp[]>;
|
|
245
263
|
},
|
|
246
264
|
): GooglePrompt {
|
|
247
265
|
const systemInstructionParts: Array<{ text: string }> = [];
|
|
@@ -255,6 +273,8 @@ export function convertToGoogleMessages(
|
|
|
255
273
|
const supportsFunctionResponseParts =
|
|
256
274
|
options?.supportsFunctionResponseParts ?? true;
|
|
257
275
|
const includeFunctionCallIds = options?.includeFunctionCallIds ?? true;
|
|
276
|
+
const supportedFunctionResponseUrls =
|
|
277
|
+
options?.supportedFunctionResponseUrls ?? {};
|
|
258
278
|
|
|
259
279
|
let sentinelInjected = false;
|
|
260
280
|
const missingSignatureToolNames: string[] = [];
|
|
@@ -657,6 +677,7 @@ export function convertToGoogleMessages(
|
|
|
657
677
|
output.value,
|
|
658
678
|
part.toolCallId,
|
|
659
679
|
includeFunctionCallIds,
|
|
680
|
+
supportedFunctionResponseUrls,
|
|
660
681
|
);
|
|
661
682
|
} else {
|
|
662
683
|
appendLegacyToolResultParts(
|
|
@@ -6,20 +6,23 @@ import {
|
|
|
6
6
|
detectMediaType,
|
|
7
7
|
downloadBlob,
|
|
8
8
|
isFullMediaType,
|
|
9
|
+
isUrlSupported,
|
|
9
10
|
} from '@ai-sdk/provider-utils';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* Download tool result file URLs that Vertex cannot reference directly before
|
|
14
|
+
* converting the prompt to the Google request format.
|
|
14
15
|
*/
|
|
15
16
|
export async function downloadToolResultFiles(
|
|
16
17
|
prompt: LanguageModelV4Prompt,
|
|
17
18
|
{
|
|
18
19
|
abortSignal,
|
|
19
20
|
maxBytes,
|
|
21
|
+
supportedUrls = {},
|
|
20
22
|
}: {
|
|
21
23
|
abortSignal: AbortSignal | undefined;
|
|
22
24
|
maxBytes: number;
|
|
25
|
+
supportedUrls?: Record<string, RegExp[]>;
|
|
23
26
|
},
|
|
24
27
|
): Promise<LanguageModelV4Prompt> {
|
|
25
28
|
const result: LanguageModelV4Prompt = [];
|
|
@@ -36,6 +39,7 @@ export async function downloadToolResultFiles(
|
|
|
36
39
|
output: await downloadToolResultOutput(part.output, {
|
|
37
40
|
abortSignal,
|
|
38
41
|
maxBytes,
|
|
42
|
+
supportedUrls,
|
|
39
43
|
}),
|
|
40
44
|
}
|
|
41
45
|
: part,
|
|
@@ -60,6 +64,7 @@ export async function downloadToolResultFiles(
|
|
|
60
64
|
output: await downloadToolResultOutput(part.output, {
|
|
61
65
|
abortSignal,
|
|
62
66
|
maxBytes,
|
|
67
|
+
supportedUrls,
|
|
63
68
|
}),
|
|
64
69
|
});
|
|
65
70
|
}
|
|
@@ -79,9 +84,11 @@ async function downloadToolResultOutput(
|
|
|
79
84
|
{
|
|
80
85
|
abortSignal,
|
|
81
86
|
maxBytes,
|
|
87
|
+
supportedUrls,
|
|
82
88
|
}: {
|
|
83
89
|
abortSignal: AbortSignal | undefined;
|
|
84
90
|
maxBytes: number;
|
|
91
|
+
supportedUrls: Record<string, RegExp[]>;
|
|
85
92
|
},
|
|
86
93
|
): Promise<LanguageModelV4ToolResultOutput> {
|
|
87
94
|
if (output.type !== 'content') {
|
|
@@ -96,6 +103,17 @@ async function downloadToolResultOutput(
|
|
|
96
103
|
continue;
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
if (
|
|
107
|
+
isUrlSupported({
|
|
108
|
+
url: part.data.url.toString(),
|
|
109
|
+
mediaType: part.mediaType,
|
|
110
|
+
supportedUrls,
|
|
111
|
+
})
|
|
112
|
+
) {
|
|
113
|
+
value.push(part);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
|
|
99
117
|
const blob = await downloadBlob(part.data.url.toString(), {
|
|
100
118
|
abortSignal,
|
|
101
119
|
maxBytes,
|
|
@@ -66,6 +66,14 @@ const configurableSafetySettingCategories = [
|
|
|
66
66
|
|
|
67
67
|
const gemini25ModelPattern = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
|
|
68
68
|
|
|
69
|
+
const googleCloudStorageFunctionResponseUrls = {
|
|
70
|
+
'image/png': [/^gs:\/\/.*$/],
|
|
71
|
+
'image/jpeg': [/^gs:\/\/.*$/],
|
|
72
|
+
'image/webp': [/^gs:\/\/.*$/],
|
|
73
|
+
'application/pdf': [/^gs:\/\/.*$/],
|
|
74
|
+
'text/plain': [/^gs:\/\/.*$/],
|
|
75
|
+
} satisfies Record<string, RegExp[]>;
|
|
76
|
+
|
|
69
77
|
export type GoogleLanguageModelConfig = {
|
|
70
78
|
provider: string;
|
|
71
79
|
baseURL: string;
|
|
@@ -83,6 +91,7 @@ export type GoogleLanguageModelConfig = {
|
|
|
83
91
|
*/
|
|
84
92
|
downloadToolResultFiles?: {
|
|
85
93
|
maxBytes: number;
|
|
94
|
+
supportsGoogleCloudStorageUrls?: boolean;
|
|
86
95
|
};
|
|
87
96
|
};
|
|
88
97
|
|
|
@@ -295,11 +304,17 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
295
304
|
}
|
|
296
305
|
|
|
297
306
|
const { usesGemini3Features } = getGoogleModelCapabilities(modelId);
|
|
307
|
+
const supportedFunctionResponseUrls =
|
|
308
|
+
usesGemini3Features &&
|
|
309
|
+
config.downloadToolResultFiles?.supportsGoogleCloudStorageUrls
|
|
310
|
+
? googleCloudStorageFunctionResponseUrls
|
|
311
|
+
: undefined;
|
|
298
312
|
|
|
299
313
|
const promptWithDownloadedToolResultFiles = config.downloadToolResultFiles
|
|
300
314
|
? await downloadToolResultFiles(prompt, {
|
|
301
315
|
abortSignal,
|
|
302
316
|
maxBytes: config.downloadToolResultFiles.maxBytes,
|
|
317
|
+
supportedUrls: supportedFunctionResponseUrls,
|
|
303
318
|
})
|
|
304
319
|
: prompt;
|
|
305
320
|
|
|
@@ -312,6 +327,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
312
327
|
providerOptionsNames,
|
|
313
328
|
supportsFunctionResponseParts: usesGemini3Features,
|
|
314
329
|
includeFunctionCallIds: !isVertexProvider,
|
|
330
|
+
supportedFunctionResponseUrls,
|
|
315
331
|
},
|
|
316
332
|
);
|
|
317
333
|
|
package/src/google-prompt.ts
CHANGED
|
@@ -73,9 +73,13 @@ export type GoogleContentPart =
|
|
|
73
73
|
};
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
export type GoogleFunctionResponsePart =
|
|
77
|
-
|
|
78
|
-
};
|
|
76
|
+
export type GoogleFunctionResponsePart =
|
|
77
|
+
| {
|
|
78
|
+
inlineData: { mimeType: string; data: string };
|
|
79
|
+
}
|
|
80
|
+
| {
|
|
81
|
+
fileData: { mimeType: string; fileUri: string };
|
|
82
|
+
};
|
|
79
83
|
|
|
80
84
|
export type GoogleGroundingMetadata = GroundingMetadataSchema;
|
|
81
85
|
|
|
@@ -401,10 +401,10 @@ function getVideoProcessingField({
|
|
|
401
401
|
processing: {
|
|
402
402
|
type: 'static',
|
|
403
403
|
...(typeof config.startOffset === 'number'
|
|
404
|
-
? { start_offset: config.startOffset }
|
|
404
|
+
? { start_offset: `${config.startOffset}s` }
|
|
405
405
|
: {}),
|
|
406
406
|
...(typeof config.endOffset === 'number'
|
|
407
|
-
? { end_offset: config.endOffset }
|
|
407
|
+
? { end_offset: `${config.endOffset}s` }
|
|
408
408
|
: {}),
|
|
409
409
|
...(typeof config.fps === 'number' ? { fps: config.fps } : {}),
|
|
410
410
|
},
|