@ai-sdk/google 3.0.139 → 3.0.141
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 +20 -0
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +661 -552
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +657 -545
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.js +623 -514
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +626 -514
- package/dist/internal/index.mjs.map +1 -1
- package/docs/15-google-generative-ai.mdx +32 -12
- package/package.json +2 -2
- package/src/convert-to-google-generative-ai-messages.ts +71 -10
- package/src/google-error.ts +46 -6
- package/src/google-generative-ai-language-model.ts +43 -16
- package/src/google-generative-ai-prompt.ts +21 -2
- package/src/index.ts +4 -1
- package/src/interactions/prepare-google-interactions-tools.ts +7 -4
|
@@ -447,12 +447,12 @@ Things to keep in mind:
|
|
|
447
447
|
|
|
448
448
|
#### Long decode with the Interactions API
|
|
449
449
|
|
|
450
|
-
With the [Interactions API](#interactions-api),
|
|
451
|
-
`background: true
|
|
452
|
-
continuation is needed, and `usage` covers all requests. Set an
|
|
453
|
-
`maxOutputTokens` above 65,536
|
|
454
|
-
|
|
455
|
-
|
|
450
|
+
With the [Interactions API](#interactions-api), the AI SDK currently requires
|
|
451
|
+
`background: true` for long decode. The server runs every request itself, so no
|
|
452
|
+
client-side continuation is needed, and `usage` covers all requests. Set an
|
|
453
|
+
explicit `maxOutputTokens` above 65,536 and keep `store` enabled (the default).
|
|
454
|
+
The provider polls the interaction (or streams it, reconnecting when the
|
|
455
|
+
connection drops) until it finishes.
|
|
456
456
|
|
|
457
457
|
```ts
|
|
458
458
|
import { google } from '@ai-sdk/google';
|
|
@@ -471,10 +471,14 @@ const result = await generateText({
|
|
|
471
471
|
});
|
|
472
472
|
```
|
|
473
473
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
474
|
+
Foreground client-side continuation is not yet supported by the AI SDK.
|
|
475
|
+
If you do not set `maxOutputTokens`, non-streaming calls (`generateText`)
|
|
476
|
+
default to 32,768 tokens and streaming calls (`streamText`) to 65,536 tokens.
|
|
477
|
+
An interaction that reaches its limit finishes with `length`. Long decode is
|
|
478
|
+
not available with the Vertex AI Interactions API.
|
|
479
|
+
|
|
480
|
+
The token budget includes both thinking and output tokens. To retain the previous
|
|
481
|
+
64K budget for a non-streaming call, set `maxOutputTokens: 65_536` explicitly.
|
|
478
482
|
|
|
479
483
|
### File Inputs
|
|
480
484
|
|
|
@@ -505,7 +509,14 @@ const result = await generateText({
|
|
|
505
509
|
});
|
|
506
510
|
```
|
|
507
511
|
|
|
508
|
-
You can also use YouTube URLs directly
|
|
512
|
+
You can also use YouTube URLs directly. Pass `videoMetadata` through
|
|
513
|
+
`providerOptions.google` on a video file part to clip a segment or control the
|
|
514
|
+
frame rate. This also works with inline video data and uploaded file URLs.
|
|
515
|
+
The metadata supports these optional fields:
|
|
516
|
+
|
|
517
|
+
- `startOffset` (string): Start time as a duration in seconds, e.g. `'60s'` or `'3.5s'`.
|
|
518
|
+
- `endOffset` (string): End time in the same duration format.
|
|
519
|
+
- `fps` (number): Frames per second in the range `(0, 24]`. The default is `1`.
|
|
509
520
|
|
|
510
521
|
```ts
|
|
511
522
|
import { google } from '@ai-sdk/google';
|
|
@@ -519,12 +530,21 @@ const result = await generateText({
|
|
|
519
530
|
content: [
|
|
520
531
|
{
|
|
521
532
|
type: 'text',
|
|
522
|
-
text: 'Summarize this video',
|
|
533
|
+
text: 'Summarize this part of the video',
|
|
523
534
|
},
|
|
524
535
|
{
|
|
525
536
|
type: 'file',
|
|
526
537
|
data: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
|
|
527
538
|
mediaType: 'video/mp4',
|
|
539
|
+
providerOptions: {
|
|
540
|
+
google: {
|
|
541
|
+
videoMetadata: {
|
|
542
|
+
startOffset: '60s',
|
|
543
|
+
endOffset: '600s',
|
|
544
|
+
fps: 1,
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
},
|
|
528
548
|
},
|
|
529
549
|
],
|
|
530
550
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.141",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@ai-sdk/provider": "3.0.19",
|
|
40
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
40
|
+
"@ai-sdk/provider-utils": "4.0.64"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "20.17.24",
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type JSONValue,
|
|
2
3
|
UnsupportedFunctionalityError,
|
|
3
4
|
type LanguageModelV3Prompt,
|
|
4
5
|
type SharedV3Warning,
|
|
5
6
|
} from '@ai-sdk/provider';
|
|
6
7
|
import {
|
|
8
|
+
stringifyWithBigIntAndCycles,
|
|
7
9
|
convertToBase64,
|
|
8
10
|
isUrlSupported,
|
|
9
11
|
secureJsonParse,
|
|
10
12
|
} from '@ai-sdk/provider-utils';
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
import {
|
|
14
|
+
googleVideoMetadataSchema,
|
|
15
|
+
type GoogleGenerativeAIContent,
|
|
16
|
+
type GoogleGenerativeAIContentPart,
|
|
17
|
+
type GoogleGenerativeAIFunctionResponsePart,
|
|
18
|
+
type GoogleGenerativeAIPrompt,
|
|
16
19
|
} from './google-generative-ai-prompt';
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -34,6 +37,7 @@ type GoogleProviderOptions = {
|
|
|
34
37
|
thoughtSignature?: unknown;
|
|
35
38
|
serverToolCallId?: unknown;
|
|
36
39
|
serverToolType?: unknown;
|
|
40
|
+
videoMetadata?: unknown;
|
|
37
41
|
};
|
|
38
42
|
|
|
39
43
|
function getGoogleProviderOptions(
|
|
@@ -103,6 +107,42 @@ function convertUrlToolResultPart(
|
|
|
103
107
|
: undefined;
|
|
104
108
|
}
|
|
105
109
|
|
|
110
|
+
function serializeFunctionResponseContent(
|
|
111
|
+
value: JSONValue,
|
|
112
|
+
): JSONValue | string {
|
|
113
|
+
// Keep Google's structured response for ordinary JSON, but normalize values
|
|
114
|
+
// that would otherwise fail when the final request body is serialized.
|
|
115
|
+
return containsNonJsonValue(value)
|
|
116
|
+
? secureJsonParse(stringifyWithBigIntAndCycles(value))
|
|
117
|
+
: value;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function containsNonJsonValue(
|
|
121
|
+
value: unknown,
|
|
122
|
+
ancestors = new Set<object>(),
|
|
123
|
+
): boolean {
|
|
124
|
+
if (typeof value === 'bigint') {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (typeof value !== 'object' || value === null) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
if (typeof (value as { toJSON?: unknown }).toJSON === 'function') {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
if (ancestors.has(value)) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
ancestors.add(value);
|
|
137
|
+
try {
|
|
138
|
+
return Object.values(value).some(item =>
|
|
139
|
+
containsNonJsonValue(item, ancestors),
|
|
140
|
+
);
|
|
141
|
+
} finally {
|
|
142
|
+
ancestors.delete(value);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
106
146
|
/*
|
|
107
147
|
* Appends tool result content parts to the message using the functionResponse
|
|
108
148
|
* format with support for multimodal parts (e.g. inline images/files alongside
|
|
@@ -149,12 +189,12 @@ function appendToolResultParts(
|
|
|
149
189
|
if (functionResponsePart != null) {
|
|
150
190
|
functionResponseParts.push(functionResponsePart);
|
|
151
191
|
} else {
|
|
152
|
-
responseTextParts.push(
|
|
192
|
+
responseTextParts.push(stringifyWithBigIntAndCycles(contentPart));
|
|
153
193
|
}
|
|
154
194
|
break;
|
|
155
195
|
}
|
|
156
196
|
default: {
|
|
157
|
-
responseTextParts.push(
|
|
197
|
+
responseTextParts.push(stringifyWithBigIntAndCycles(contentPart));
|
|
158
198
|
break;
|
|
159
199
|
}
|
|
160
200
|
}
|
|
@@ -232,7 +272,7 @@ function appendLegacyToolResultParts(
|
|
|
232
272
|
break;
|
|
233
273
|
}
|
|
234
274
|
default:
|
|
235
|
-
parts.push({ text:
|
|
275
|
+
parts.push({ text: stringifyWithBigIntAndCycles(contentPart) });
|
|
236
276
|
break;
|
|
237
277
|
}
|
|
238
278
|
}
|
|
@@ -313,6 +353,14 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
313
353
|
// default to image/jpeg for unknown image/* types
|
|
314
354
|
const mediaType =
|
|
315
355
|
part.mediaType === 'image/*' ? 'image/jpeg' : part.mediaType;
|
|
356
|
+
const rawVideoMetadata = getGoogleProviderOptions(
|
|
357
|
+
part.providerOptions,
|
|
358
|
+
providerOptionsName,
|
|
359
|
+
)?.videoMetadata;
|
|
360
|
+
const videoMetadata =
|
|
361
|
+
rawVideoMetadata == null
|
|
362
|
+
? undefined
|
|
363
|
+
: googleVideoMetadataSchema.parse(rawVideoMetadata);
|
|
316
364
|
|
|
317
365
|
parts.push(
|
|
318
366
|
part.data instanceof URL
|
|
@@ -325,12 +373,14 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
325
373
|
? part.originalUrl
|
|
326
374
|
: part.data.toString(),
|
|
327
375
|
},
|
|
376
|
+
...(videoMetadata != null ? { videoMetadata } : {}),
|
|
328
377
|
}
|
|
329
378
|
: {
|
|
330
379
|
inlineData: {
|
|
331
380
|
mimeType: mediaType,
|
|
332
381
|
data: convertToBase64(part.data),
|
|
333
382
|
},
|
|
383
|
+
...(videoMetadata != null ? { videoMetadata } : {}),
|
|
334
384
|
},
|
|
335
385
|
);
|
|
336
386
|
|
|
@@ -450,7 +500,7 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
450
500
|
? { id: part.toolCallId }
|
|
451
501
|
: {}),
|
|
452
502
|
name: part.toolName,
|
|
453
|
-
args: part.input,
|
|
503
|
+
args: parseToolCallInput(part.input),
|
|
454
504
|
},
|
|
455
505
|
thoughtSignature: effectiveThoughtSignature,
|
|
456
506
|
};
|
|
@@ -567,7 +617,7 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
567
617
|
content:
|
|
568
618
|
output.type === 'execution-denied'
|
|
569
619
|
? (output.reason ?? 'Tool call execution denied.')
|
|
570
|
-
: output.value,
|
|
620
|
+
: serializeFunctionResponseContent(output.value),
|
|
571
621
|
},
|
|
572
622
|
},
|
|
573
623
|
});
|
|
@@ -621,3 +671,14 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
621
671
|
contents,
|
|
622
672
|
};
|
|
623
673
|
}
|
|
674
|
+
|
|
675
|
+
function parseToolCallInput(input: unknown): unknown {
|
|
676
|
+
if (typeof input !== 'string') {
|
|
677
|
+
return input;
|
|
678
|
+
}
|
|
679
|
+
try {
|
|
680
|
+
return secureJsonParse(input);
|
|
681
|
+
} catch {
|
|
682
|
+
return input;
|
|
683
|
+
}
|
|
684
|
+
}
|
package/src/google-error.ts
CHANGED
|
@@ -6,15 +6,18 @@ import {
|
|
|
6
6
|
} from '@ai-sdk/provider-utils';
|
|
7
7
|
import { z } from 'zod/v4';
|
|
8
8
|
|
|
9
|
+
export const getGoogleErrorSchema = () =>
|
|
10
|
+
z.object({
|
|
11
|
+
code: z.number().nullable(),
|
|
12
|
+
message: z.string(),
|
|
13
|
+
status: z.string(),
|
|
14
|
+
details: z.array(z.unknown()).nullish(),
|
|
15
|
+
});
|
|
16
|
+
|
|
9
17
|
const googleErrorDataSchema = lazySchema(() =>
|
|
10
18
|
zodSchema(
|
|
11
19
|
z.object({
|
|
12
|
-
error:
|
|
13
|
-
code: z.number().nullable(),
|
|
14
|
-
message: z.string(),
|
|
15
|
-
status: z.string(),
|
|
16
|
-
details: z.array(z.unknown()).nullish(),
|
|
17
|
-
}),
|
|
20
|
+
error: getGoogleErrorSchema(),
|
|
18
21
|
}),
|
|
19
22
|
),
|
|
20
23
|
);
|
|
@@ -25,3 +28,40 @@ export const googleFailedResponseHandler = createJsonErrorResponseHandler({
|
|
|
25
28
|
errorSchema: googleErrorDataSchema,
|
|
26
29
|
errorToMessage: data => data.error.message,
|
|
27
30
|
});
|
|
31
|
+
|
|
32
|
+
// Google RPC status names can be sent without a numeric HTTP error code.
|
|
33
|
+
export function mapGoogleErrorStatusToHttpStatusCode(
|
|
34
|
+
status: string,
|
|
35
|
+
): number | undefined {
|
|
36
|
+
switch (status) {
|
|
37
|
+
case 'CANCELLED':
|
|
38
|
+
return 499;
|
|
39
|
+
case 'INVALID_ARGUMENT':
|
|
40
|
+
case 'FAILED_PRECONDITION':
|
|
41
|
+
case 'OUT_OF_RANGE':
|
|
42
|
+
return 400;
|
|
43
|
+
case 'DEADLINE_EXCEEDED':
|
|
44
|
+
return 504;
|
|
45
|
+
case 'NOT_FOUND':
|
|
46
|
+
return 404;
|
|
47
|
+
case 'ALREADY_EXISTS':
|
|
48
|
+
case 'ABORTED':
|
|
49
|
+
return 409;
|
|
50
|
+
case 'PERMISSION_DENIED':
|
|
51
|
+
return 403;
|
|
52
|
+
case 'UNAUTHENTICATED':
|
|
53
|
+
return 401;
|
|
54
|
+
case 'RESOURCE_EXHAUSTED':
|
|
55
|
+
return 429;
|
|
56
|
+
case 'UNIMPLEMENTED':
|
|
57
|
+
return 501;
|
|
58
|
+
case 'UNKNOWN':
|
|
59
|
+
case 'INTERNAL':
|
|
60
|
+
case 'DATA_LOSS':
|
|
61
|
+
return 500;
|
|
62
|
+
case 'UNAVAILABLE':
|
|
63
|
+
return 503;
|
|
64
|
+
default:
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import {
|
|
2
|
+
APICallError,
|
|
3
|
+
type LanguageModelV3,
|
|
4
|
+
type LanguageModelV3CallOptions,
|
|
5
|
+
type LanguageModelV3Content,
|
|
6
|
+
type LanguageModelV3FinishReason,
|
|
7
|
+
type LanguageModelV3GenerateResult,
|
|
8
|
+
type LanguageModelV3Source,
|
|
9
|
+
type LanguageModelV3StreamPart,
|
|
10
|
+
type LanguageModelV3StreamResult,
|
|
11
|
+
type JSONObject,
|
|
12
|
+
type SharedV3ProviderMetadata,
|
|
13
|
+
type SharedV3Warning,
|
|
13
14
|
} from '@ai-sdk/provider';
|
|
14
15
|
import {
|
|
15
16
|
combineHeaders,
|
|
@@ -37,7 +38,11 @@ import { convertJSONSchemaToOpenAPISchema } from './convert-json-schema-to-opena
|
|
|
37
38
|
import { convertToGoogleGenerativeAIMessages } from './convert-to-google-generative-ai-messages';
|
|
38
39
|
import { downloadToolResultFiles } from './download-tool-result-files';
|
|
39
40
|
import { getModelPath } from './get-model-path';
|
|
40
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
getGoogleErrorSchema,
|
|
43
|
+
googleFailedResponseHandler,
|
|
44
|
+
mapGoogleErrorStatusToHttpStatusCode,
|
|
45
|
+
} from './google-error';
|
|
41
46
|
import {
|
|
42
47
|
googleLanguageModelOptions,
|
|
43
48
|
type GoogleGenerativeAIModelId,
|
|
@@ -684,11 +689,12 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
684
689
|
extraHeaders,
|
|
685
690
|
);
|
|
686
691
|
|
|
692
|
+
const url = `${this.config.baseURL}/${getModelPath(
|
|
693
|
+
this.modelId,
|
|
694
|
+
)}:streamGenerateContent?alt=sse`;
|
|
687
695
|
const streamGenerateContent = (body: typeof args) =>
|
|
688
696
|
postJsonToApi({
|
|
689
|
-
url
|
|
690
|
-
this.modelId,
|
|
691
|
-
)}:streamGenerateContent?alt=sse`,
|
|
697
|
+
url,
|
|
692
698
|
headers,
|
|
693
699
|
body,
|
|
694
700
|
failedResponseHandler: googleFailedResponseHandler,
|
|
@@ -829,6 +835,26 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
829
835
|
|
|
830
836
|
const value = chunk.value;
|
|
831
837
|
|
|
838
|
+
if (value.error != null) {
|
|
839
|
+
finishReason = { unified: 'error', raw: undefined };
|
|
840
|
+
const error = value.error;
|
|
841
|
+
controller.enqueue({
|
|
842
|
+
type: 'error',
|
|
843
|
+
error: new APICallError({
|
|
844
|
+
message: error.message,
|
|
845
|
+
url,
|
|
846
|
+
requestBodyValues: args,
|
|
847
|
+
statusCode:
|
|
848
|
+
error.code ??
|
|
849
|
+
mapGoogleErrorStatusToHttpStatusCode(error.status),
|
|
850
|
+
responseHeaders,
|
|
851
|
+
responseBody: JSON.stringify({ error }),
|
|
852
|
+
data: error,
|
|
853
|
+
}),
|
|
854
|
+
});
|
|
855
|
+
return;
|
|
856
|
+
}
|
|
857
|
+
|
|
832
858
|
if (!hasEmittedResponseMetadata && value.responseId != null) {
|
|
833
859
|
hasEmittedResponseMetadata = true;
|
|
834
860
|
controller.enqueue({
|
|
@@ -1768,6 +1794,7 @@ export type UsageMetadataSchema = NonNullable<
|
|
|
1768
1794
|
const chunkSchema = lazySchema(() =>
|
|
1769
1795
|
zodSchema(
|
|
1770
1796
|
z.object({
|
|
1797
|
+
error: getGoogleErrorSchema().nullish(),
|
|
1771
1798
|
responseId: z.string().nullish(),
|
|
1772
1799
|
candidates: z
|
|
1773
1800
|
.array(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { z } from 'zod/v4';
|
|
1
2
|
import {
|
|
2
3
|
type GroundingMetadataSchema,
|
|
3
4
|
type PromptFeedbackSchema,
|
|
@@ -20,9 +21,24 @@ export type GoogleGenerativeAIContent = {
|
|
|
20
21
|
parts: Array<GoogleGenerativeAIContentPart>;
|
|
21
22
|
};
|
|
22
23
|
|
|
24
|
+
export const googleVideoMetadataSchema = z.object({
|
|
25
|
+
/** Start offset as a duration in seconds, e.g. `'3.5s'`. */
|
|
26
|
+
startOffset: z.string().optional(),
|
|
27
|
+
/** End offset as a duration in seconds, e.g. `'10s'`. */
|
|
28
|
+
endOffset: z.string().optional(),
|
|
29
|
+
/** Frames per second in the range (0, 24]. Defaults to 1. */
|
|
30
|
+
fps: z.number().gt(0).max(24).optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/** Metadata for preprocessing video file parts. */
|
|
34
|
+
export type GoogleVideoMetadata = z.infer<typeof googleVideoMetadataSchema>;
|
|
35
|
+
|
|
23
36
|
export type GoogleGenerativeAIContentPart =
|
|
24
37
|
| { text: string; thought?: boolean; thoughtSignature?: string }
|
|
25
|
-
| {
|
|
38
|
+
| {
|
|
39
|
+
inlineData: { mimeType: string; data: string };
|
|
40
|
+
videoMetadata?: GoogleVideoMetadata;
|
|
41
|
+
}
|
|
26
42
|
| {
|
|
27
43
|
functionCall: { id?: string; name: string; args: unknown };
|
|
28
44
|
thoughtSignature?: string;
|
|
@@ -35,7 +51,10 @@ export type GoogleGenerativeAIContentPart =
|
|
|
35
51
|
parts?: Array<GoogleGenerativeAIFunctionResponsePart>;
|
|
36
52
|
};
|
|
37
53
|
}
|
|
38
|
-
| {
|
|
54
|
+
| {
|
|
55
|
+
fileData: { mimeType: string; fileUri: string };
|
|
56
|
+
videoMetadata?: GoogleVideoMetadata;
|
|
57
|
+
}
|
|
39
58
|
| {
|
|
40
59
|
toolCall: {
|
|
41
60
|
toolType: string;
|
package/src/index.ts
CHANGED
|
@@ -4,7 +4,10 @@ export type {
|
|
|
4
4
|
/** @deprecated Use `GoogleLanguageModelOptions` instead. */
|
|
5
5
|
GoogleLanguageModelOptions as GoogleGenerativeAIProviderOptions,
|
|
6
6
|
} from './google-generative-ai-options';
|
|
7
|
-
export type {
|
|
7
|
+
export type {
|
|
8
|
+
GoogleGenerativeAIProviderMetadata,
|
|
9
|
+
GoogleVideoMetadata,
|
|
10
|
+
} from './google-generative-ai-prompt';
|
|
8
11
|
export type {
|
|
9
12
|
GoogleImageModelOptions,
|
|
10
13
|
/** @deprecated Use `GoogleImageModelOptions` instead. */
|
|
@@ -39,7 +39,7 @@ export type PrepareGoogleInteractionsToolsResult = {
|
|
|
39
39
|
* `toolChoice` shapes:
|
|
40
40
|
* - `'auto'` -> `'auto'`
|
|
41
41
|
* - `'required'` -> `'any'`
|
|
42
|
-
* - `'none'` -> `
|
|
42
|
+
* - `'none'` -> omit all tools and `tool_choice`
|
|
43
43
|
* - `{ type: 'tool', toolName }` -> `{ allowed_tools: { mode: 'validated', tools: [name] } }`
|
|
44
44
|
* (Interactions `AllowedTools.tools` is an `Array<string>` of function
|
|
45
45
|
* names, not tool descriptors -- see `src/interactions/resources/interactions.ts`
|
|
@@ -54,6 +54,12 @@ export function prepareGoogleInteractionsTools({
|
|
|
54
54
|
}): PrepareGoogleInteractionsToolsResult {
|
|
55
55
|
const toolWarnings: Array<SharedV3Warning> = [];
|
|
56
56
|
|
|
57
|
+
// The API's tool_choice only controls function tools. Omit all tools to
|
|
58
|
+
// disable provider-executed tools as well.
|
|
59
|
+
if (toolChoice?.type === 'none') {
|
|
60
|
+
return { tools: undefined, toolChoice: undefined, toolWarnings };
|
|
61
|
+
}
|
|
62
|
+
|
|
57
63
|
const normalized = tools?.length ? tools : undefined;
|
|
58
64
|
|
|
59
65
|
if (normalized == null) {
|
|
@@ -223,9 +229,6 @@ export function prepareGoogleInteractionsTools({
|
|
|
223
229
|
case 'required':
|
|
224
230
|
mappedToolChoice = 'any';
|
|
225
231
|
break;
|
|
226
|
-
case 'none':
|
|
227
|
-
mappedToolChoice = 'none';
|
|
228
|
-
break;
|
|
229
232
|
case 'tool':
|
|
230
233
|
mappedToolChoice = {
|
|
231
234
|
allowed_tools: {
|