@ai-sdk/google 4.0.0-beta.4 → 4.0.0-beta.40
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 +279 -4
- package/README.md +2 -0
- package/dist/index.d.ts +85 -26
- package/dist/index.js +1524 -469
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +62 -19
- package/dist/internal/index.js +1135 -361
- package/dist/internal/index.js.map +1 -1
- package/docs/15-google-generative-ai.mdx +36 -3
- package/package.json +9 -12
- package/src/convert-google-generative-ai-usage.ts +9 -2
- package/src/convert-to-google-generative-ai-messages.ts +329 -50
- package/src/google-generative-ai-embedding-model.ts +64 -15
- package/src/google-generative-ai-embedding-options.ts +24 -0
- package/src/google-generative-ai-files.ts +228 -0
- package/src/google-generative-ai-image-model.ts +39 -15
- package/src/google-generative-ai-language-model.ts +557 -146
- package/src/google-generative-ai-options.ts +25 -2
- package/src/google-generative-ai-prompt.ts +48 -4
- package/src/google-generative-ai-video-model.ts +7 -7
- package/src/google-generative-ai-video-settings.ts +1 -0
- package/src/google-json-accumulator.ts +336 -0
- package/src/google-prepare-tools.ts +65 -9
- package/src/google-provider.ts +31 -18
- package/src/index.ts +1 -0
- package/src/map-google-generative-ai-finish-reason.ts +2 -2
- package/dist/index.d.mts +0 -368
- package/dist/index.mjs +0 -2482
- package/dist/index.mjs.map +0 -1
- package/dist/internal/index.d.mts +0 -284
- package/dist/internal/index.mjs +0 -1706
- package/dist/internal/index.mjs.map +0 -1
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
LanguageModelV4,
|
|
3
|
+
LanguageModelV4CallOptions,
|
|
4
|
+
LanguageModelV4Content,
|
|
5
|
+
LanguageModelV4FinishReason,
|
|
6
|
+
LanguageModelV4GenerateResult,
|
|
7
|
+
LanguageModelV4Source,
|
|
8
|
+
LanguageModelV4StreamPart,
|
|
9
|
+
LanguageModelV4StreamResult,
|
|
10
|
+
JSONObject,
|
|
11
|
+
SharedV4ProviderMetadata,
|
|
12
|
+
SharedV4Warning,
|
|
12
13
|
} from '@ai-sdk/provider';
|
|
13
14
|
import {
|
|
14
15
|
combineHeaders,
|
|
@@ -17,12 +18,18 @@ import {
|
|
|
17
18
|
FetchFunction,
|
|
18
19
|
generateId,
|
|
19
20
|
InferSchema,
|
|
21
|
+
isCustomReasoning,
|
|
20
22
|
lazySchema,
|
|
23
|
+
mapReasoningToProviderBudget,
|
|
24
|
+
mapReasoningToProviderEffort,
|
|
21
25
|
parseProviderOptions,
|
|
22
26
|
ParseResult,
|
|
23
27
|
postJsonToApi,
|
|
24
28
|
Resolvable,
|
|
25
29
|
resolve,
|
|
30
|
+
serializeModelOptions,
|
|
31
|
+
WORKFLOW_SERIALIZE,
|
|
32
|
+
WORKFLOW_DESERIALIZE,
|
|
26
33
|
zodSchema,
|
|
27
34
|
} from '@ai-sdk/provider-utils';
|
|
28
35
|
import { z } from 'zod/v4';
|
|
@@ -37,32 +44,48 @@ import { googleFailedResponseHandler } from './google-error';
|
|
|
37
44
|
import {
|
|
38
45
|
GoogleGenerativeAIModelId,
|
|
39
46
|
googleLanguageModelOptions,
|
|
47
|
+
VertexServiceTierMap,
|
|
40
48
|
} from './google-generative-ai-options';
|
|
41
|
-
import {
|
|
49
|
+
import { GoogleGenerativeAIProviderMetadata } from './google-generative-ai-prompt';
|
|
42
50
|
import { prepareTools } from './google-prepare-tools';
|
|
51
|
+
import { GoogleJSONAccumulator, PartialArg } from './google-json-accumulator';
|
|
43
52
|
import { mapGoogleGenerativeAIFinishReason } from './map-google-generative-ai-finish-reason';
|
|
44
53
|
|
|
45
54
|
type GoogleGenerativeAIConfig = {
|
|
46
55
|
provider: string;
|
|
47
56
|
baseURL: string;
|
|
48
|
-
headers
|
|
57
|
+
headers?: Resolvable<Record<string, string | undefined>>;
|
|
49
58
|
fetch?: FetchFunction;
|
|
50
59
|
generateId: () => string;
|
|
51
60
|
|
|
52
61
|
/**
|
|
53
62
|
* The supported URLs for the model.
|
|
54
63
|
*/
|
|
55
|
-
supportedUrls?: () =>
|
|
64
|
+
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
56
65
|
};
|
|
57
66
|
|
|
58
|
-
export class GoogleGenerativeAILanguageModel implements
|
|
59
|
-
readonly specificationVersion = '
|
|
67
|
+
export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
|
|
68
|
+
readonly specificationVersion = 'v4';
|
|
60
69
|
|
|
61
70
|
readonly modelId: GoogleGenerativeAIModelId;
|
|
62
71
|
|
|
63
72
|
private readonly config: GoogleGenerativeAIConfig;
|
|
64
73
|
private readonly generateId: () => string;
|
|
65
74
|
|
|
75
|
+
static [WORKFLOW_SERIALIZE](model: GoogleGenerativeAILanguageModel) {
|
|
76
|
+
return serializeModelOptions({
|
|
77
|
+
modelId: model.modelId,
|
|
78
|
+
config: model.config,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
83
|
+
modelId: string;
|
|
84
|
+
config: GoogleGenerativeAIConfig;
|
|
85
|
+
}) {
|
|
86
|
+
return new GoogleGenerativeAILanguageModel(options.modelId, options.config);
|
|
87
|
+
}
|
|
88
|
+
|
|
66
89
|
constructor(
|
|
67
90
|
modelId: GoogleGenerativeAIModelId,
|
|
68
91
|
config: GoogleGenerativeAIConfig,
|
|
@@ -80,22 +103,26 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
80
103
|
return this.config.supportedUrls?.() ?? {};
|
|
81
104
|
}
|
|
82
105
|
|
|
83
|
-
private async getArgs(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
private async getArgs(
|
|
107
|
+
{
|
|
108
|
+
prompt,
|
|
109
|
+
maxOutputTokens,
|
|
110
|
+
temperature,
|
|
111
|
+
topP,
|
|
112
|
+
topK,
|
|
113
|
+
frequencyPenalty,
|
|
114
|
+
presencePenalty,
|
|
115
|
+
stopSequences,
|
|
116
|
+
responseFormat,
|
|
117
|
+
seed,
|
|
118
|
+
tools,
|
|
119
|
+
toolChoice,
|
|
120
|
+
reasoning,
|
|
121
|
+
providerOptions,
|
|
122
|
+
}: LanguageModelV4CallOptions,
|
|
123
|
+
{ isStreaming = false }: { isStreaming?: boolean } = {},
|
|
124
|
+
) {
|
|
125
|
+
const warnings: SharedV4Warning[] = [];
|
|
99
126
|
|
|
100
127
|
const providerOptionsName = this.config.provider.includes('vertex')
|
|
101
128
|
? 'vertex'
|
|
@@ -115,12 +142,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
115
142
|
}
|
|
116
143
|
|
|
117
144
|
// Add warning if Vertex rag tools are used with a non-Vertex Google provider
|
|
145
|
+
const isVertexProvider = this.config.provider.startsWith('google.vertex.');
|
|
146
|
+
|
|
118
147
|
if (
|
|
119
148
|
tools?.some(
|
|
120
149
|
tool =>
|
|
121
150
|
tool.type === 'provider' && tool.id === 'google.vertex_rag_store',
|
|
122
151
|
) &&
|
|
123
|
-
!
|
|
152
|
+
!isVertexProvider
|
|
124
153
|
) {
|
|
125
154
|
warnings.push({
|
|
126
155
|
type: 'other',
|
|
@@ -131,11 +160,32 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
131
160
|
});
|
|
132
161
|
}
|
|
133
162
|
|
|
163
|
+
if (googleOptions?.streamFunctionCallArguments && !isVertexProvider) {
|
|
164
|
+
warnings.push({
|
|
165
|
+
type: 'other',
|
|
166
|
+
message:
|
|
167
|
+
"'streamFunctionCallArguments' is only supported on the Vertex AI API " +
|
|
168
|
+
'and will be ignored with the current Google provider ' +
|
|
169
|
+
`(${this.config.provider}). See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#streaming-fc`,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Vertex API requires another service tier format.
|
|
174
|
+
let sanitizedServiceTier: string | undefined = googleOptions?.serviceTier;
|
|
175
|
+
if (googleOptions?.serviceTier && isVertexProvider) {
|
|
176
|
+
sanitizedServiceTier = VertexServiceTierMap[googleOptions.serviceTier];
|
|
177
|
+
}
|
|
178
|
+
|
|
134
179
|
const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
|
|
180
|
+
const supportsFunctionResponseParts = this.modelId.startsWith('gemini-3');
|
|
135
181
|
|
|
136
182
|
const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
|
|
137
183
|
prompt,
|
|
138
|
-
{
|
|
184
|
+
{
|
|
185
|
+
isGemmaModel,
|
|
186
|
+
providerOptionsName,
|
|
187
|
+
supportsFunctionResponseParts,
|
|
188
|
+
},
|
|
139
189
|
);
|
|
140
190
|
|
|
141
191
|
const {
|
|
@@ -148,6 +198,39 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
148
198
|
modelId: this.modelId,
|
|
149
199
|
});
|
|
150
200
|
|
|
201
|
+
const resolvedThinking = resolveThinkingConfig({
|
|
202
|
+
reasoning,
|
|
203
|
+
modelId: this.modelId,
|
|
204
|
+
warnings,
|
|
205
|
+
});
|
|
206
|
+
const thinkingConfig =
|
|
207
|
+
googleOptions?.thinkingConfig || resolvedThinking
|
|
208
|
+
? { ...resolvedThinking, ...googleOptions?.thinkingConfig }
|
|
209
|
+
: undefined;
|
|
210
|
+
|
|
211
|
+
const streamFunctionCallArguments =
|
|
212
|
+
isStreaming && isVertexProvider
|
|
213
|
+
? (googleOptions?.streamFunctionCallArguments ?? false)
|
|
214
|
+
: undefined;
|
|
215
|
+
|
|
216
|
+
const toolConfig =
|
|
217
|
+
googleToolConfig ||
|
|
218
|
+
streamFunctionCallArguments ||
|
|
219
|
+
googleOptions?.retrievalConfig
|
|
220
|
+
? {
|
|
221
|
+
...googleToolConfig,
|
|
222
|
+
...(streamFunctionCallArguments && {
|
|
223
|
+
functionCallingConfig: {
|
|
224
|
+
...googleToolConfig?.functionCallingConfig,
|
|
225
|
+
streamFunctionCallArguments: true as const,
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
228
|
+
...(googleOptions?.retrievalConfig && {
|
|
229
|
+
retrievalConfig: googleOptions.retrievalConfig,
|
|
230
|
+
}),
|
|
231
|
+
}
|
|
232
|
+
: undefined;
|
|
233
|
+
|
|
151
234
|
return {
|
|
152
235
|
args: {
|
|
153
236
|
generationConfig: {
|
|
@@ -179,7 +262,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
179
262
|
|
|
180
263
|
// provider options:
|
|
181
264
|
responseModalities: googleOptions?.responseModalities,
|
|
182
|
-
thinkingConfig
|
|
265
|
+
thinkingConfig,
|
|
183
266
|
...(googleOptions?.mediaResolution && {
|
|
184
267
|
mediaResolution: googleOptions.mediaResolution,
|
|
185
268
|
}),
|
|
@@ -191,14 +274,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
191
274
|
systemInstruction: isGemmaModel ? undefined : systemInstruction,
|
|
192
275
|
safetySettings: googleOptions?.safetySettings,
|
|
193
276
|
tools: googleTools,
|
|
194
|
-
toolConfig
|
|
195
|
-
? {
|
|
196
|
-
...googleToolConfig,
|
|
197
|
-
retrievalConfig: googleOptions.retrievalConfig,
|
|
198
|
-
}
|
|
199
|
-
: googleToolConfig,
|
|
277
|
+
toolConfig,
|
|
200
278
|
cachedContent: googleOptions?.cachedContent,
|
|
201
279
|
labels: googleOptions?.labels,
|
|
280
|
+
serviceTier: sanitizedServiceTier,
|
|
202
281
|
},
|
|
203
282
|
warnings: [...warnings, ...toolWarnings],
|
|
204
283
|
providerOptionsName,
|
|
@@ -206,12 +285,12 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
206
285
|
}
|
|
207
286
|
|
|
208
287
|
async doGenerate(
|
|
209
|
-
options:
|
|
210
|
-
): Promise<
|
|
288
|
+
options: LanguageModelV4CallOptions,
|
|
289
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
211
290
|
const { args, warnings, providerOptionsName } = await this.getArgs(options);
|
|
212
291
|
|
|
213
292
|
const mergedHeaders = combineHeaders(
|
|
214
|
-
await resolve(this.config.headers),
|
|
293
|
+
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
215
294
|
options.headers,
|
|
216
295
|
);
|
|
217
296
|
|
|
@@ -232,7 +311,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
232
311
|
});
|
|
233
312
|
|
|
234
313
|
const candidate = response.candidates[0];
|
|
235
|
-
const content: Array<
|
|
314
|
+
const content: Array<LanguageModelV4Content> = [];
|
|
236
315
|
|
|
237
316
|
// map ordered parts to content:
|
|
238
317
|
const parts = candidate.content?.parts ?? [];
|
|
@@ -241,6 +320,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
241
320
|
|
|
242
321
|
// Associates a code execution result with its preceding call.
|
|
243
322
|
let lastCodeExecutionToolCallId: string | undefined;
|
|
323
|
+
// Associates a server-side tool response with its preceding call (tool combination).
|
|
324
|
+
let lastServerToolCallId: string | undefined;
|
|
244
325
|
|
|
245
326
|
// Build content array from all parts
|
|
246
327
|
for (const part of parts) {
|
|
@@ -289,7 +370,11 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
289
370
|
providerMetadata: thoughtSignatureMetadata,
|
|
290
371
|
});
|
|
291
372
|
}
|
|
292
|
-
} else if (
|
|
373
|
+
} else if (
|
|
374
|
+
'functionCall' in part &&
|
|
375
|
+
part.functionCall.name != null &&
|
|
376
|
+
part.functionCall.args != null
|
|
377
|
+
) {
|
|
293
378
|
content.push({
|
|
294
379
|
type: 'tool-call' as const,
|
|
295
380
|
toolCallId: this.config.generateId(),
|
|
@@ -307,21 +392,68 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
307
392
|
const hasThought = part.thought === true;
|
|
308
393
|
const hasThoughtSignature = !!part.thoughtSignature;
|
|
309
394
|
content.push({
|
|
310
|
-
type: 'file'
|
|
395
|
+
type: hasThought ? 'reasoning-file' : 'file',
|
|
311
396
|
data: part.inlineData.data,
|
|
312
397
|
mediaType: part.inlineData.mimeType,
|
|
313
|
-
providerMetadata:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
398
|
+
providerMetadata: hasThoughtSignature
|
|
399
|
+
? {
|
|
400
|
+
[providerOptionsName]: {
|
|
401
|
+
thoughtSignature: part.thoughtSignature,
|
|
402
|
+
},
|
|
403
|
+
}
|
|
404
|
+
: undefined,
|
|
405
|
+
});
|
|
406
|
+
} else if ('toolCall' in part && part.toolCall) {
|
|
407
|
+
const toolCallId = part.toolCall.id ?? this.config.generateId();
|
|
408
|
+
lastServerToolCallId = toolCallId;
|
|
409
|
+
content.push({
|
|
410
|
+
type: 'tool-call',
|
|
411
|
+
toolCallId,
|
|
412
|
+
toolName: `server:${part.toolCall.toolType}`,
|
|
413
|
+
input: JSON.stringify(part.toolCall.args ?? {}),
|
|
414
|
+
providerExecuted: true,
|
|
415
|
+
dynamic: true,
|
|
416
|
+
providerMetadata: part.thoughtSignature
|
|
417
|
+
? {
|
|
418
|
+
[providerOptionsName]: {
|
|
419
|
+
thoughtSignature: part.thoughtSignature,
|
|
420
|
+
serverToolCallId: toolCallId,
|
|
421
|
+
serverToolType: part.toolCall.toolType,
|
|
422
|
+
},
|
|
423
|
+
}
|
|
424
|
+
: {
|
|
425
|
+
[providerOptionsName]: {
|
|
426
|
+
serverToolCallId: toolCallId,
|
|
427
|
+
serverToolType: part.toolCall.toolType,
|
|
428
|
+
},
|
|
429
|
+
},
|
|
324
430
|
});
|
|
431
|
+
} else if ('toolResponse' in part && part.toolResponse) {
|
|
432
|
+
const responseToolCallId =
|
|
433
|
+
lastServerToolCallId ??
|
|
434
|
+
part.toolResponse.id ??
|
|
435
|
+
this.config.generateId();
|
|
436
|
+
content.push({
|
|
437
|
+
type: 'tool-result',
|
|
438
|
+
toolCallId: responseToolCallId,
|
|
439
|
+
toolName: `server:${part.toolResponse.toolType}`,
|
|
440
|
+
result: (part.toolResponse.response ?? {}) as JSONObject,
|
|
441
|
+
providerMetadata: part.thoughtSignature
|
|
442
|
+
? {
|
|
443
|
+
[providerOptionsName]: {
|
|
444
|
+
thoughtSignature: part.thoughtSignature,
|
|
445
|
+
serverToolCallId: responseToolCallId,
|
|
446
|
+
serverToolType: part.toolResponse.toolType,
|
|
447
|
+
},
|
|
448
|
+
}
|
|
449
|
+
: {
|
|
450
|
+
[providerOptionsName]: {
|
|
451
|
+
serverToolCallId: responseToolCallId,
|
|
452
|
+
serverToolType: part.toolResponse.toolType,
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
lastServerToolCallId = undefined;
|
|
325
457
|
}
|
|
326
458
|
}
|
|
327
459
|
|
|
@@ -355,7 +487,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
355
487
|
urlContextMetadata: candidate.urlContextMetadata ?? null,
|
|
356
488
|
safetyRatings: candidate.safetyRatings ?? null,
|
|
357
489
|
usageMetadata: usageMetadata ?? null,
|
|
358
|
-
|
|
490
|
+
finishMessage: candidate.finishMessage ?? null,
|
|
491
|
+
serviceTier: response.serviceTier ?? null,
|
|
492
|
+
} satisfies GoogleGenerativeAIProviderMetadata,
|
|
359
493
|
},
|
|
360
494
|
request: { body: args },
|
|
361
495
|
response: {
|
|
@@ -367,12 +501,15 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
367
501
|
}
|
|
368
502
|
|
|
369
503
|
async doStream(
|
|
370
|
-
options:
|
|
371
|
-
): Promise<
|
|
372
|
-
const { args, warnings, providerOptionsName } = await this.getArgs(
|
|
504
|
+
options: LanguageModelV4CallOptions,
|
|
505
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
506
|
+
const { args, warnings, providerOptionsName } = await this.getArgs(
|
|
507
|
+
options,
|
|
508
|
+
{ isStreaming: true },
|
|
509
|
+
);
|
|
373
510
|
|
|
374
511
|
const headers = combineHeaders(
|
|
375
|
-
await resolve(this.config.headers),
|
|
512
|
+
this.config.headers ? await resolve(this.config.headers) : undefined,
|
|
376
513
|
options.headers,
|
|
377
514
|
);
|
|
378
515
|
|
|
@@ -388,14 +525,15 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
388
525
|
fetch: this.config.fetch,
|
|
389
526
|
});
|
|
390
527
|
|
|
391
|
-
let finishReason:
|
|
528
|
+
let finishReason: LanguageModelV4FinishReason = {
|
|
392
529
|
unified: 'other',
|
|
393
530
|
raw: undefined,
|
|
394
531
|
};
|
|
395
532
|
let usage: GoogleGenerativeAIUsageMetadata | undefined = undefined;
|
|
396
|
-
let providerMetadata:
|
|
533
|
+
let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
|
|
397
534
|
let lastGroundingMetadata: GroundingMetadataSchema | null = null;
|
|
398
535
|
let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
|
|
536
|
+
let serviceTier: string | null = null;
|
|
399
537
|
|
|
400
538
|
const generateId = this.config.generateId;
|
|
401
539
|
let hasToolCalls = false;
|
|
@@ -409,12 +547,21 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
409
547
|
const emittedSourceUrls = new Set<string>();
|
|
410
548
|
// Associates a code execution result with its preceding call.
|
|
411
549
|
let lastCodeExecutionToolCallId: string | undefined;
|
|
550
|
+
// Associates a server-side tool response with its preceding call (tool combination).
|
|
551
|
+
let lastServerToolCallId: string | undefined;
|
|
552
|
+
|
|
553
|
+
const activeStreamingToolCalls: Array<{
|
|
554
|
+
toolCallId: string;
|
|
555
|
+
toolName: string;
|
|
556
|
+
accumulator: GoogleJSONAccumulator;
|
|
557
|
+
providerMetadata?: SharedV4ProviderMetadata;
|
|
558
|
+
}> = [];
|
|
412
559
|
|
|
413
560
|
return {
|
|
414
561
|
stream: response.pipeThrough(
|
|
415
562
|
new TransformStream<
|
|
416
563
|
ParseResult<ChunkSchema>,
|
|
417
|
-
|
|
564
|
+
LanguageModelV4StreamPart
|
|
418
565
|
>({
|
|
419
566
|
start(controller) {
|
|
420
567
|
controller.enqueue({ type: 'stream-start', warnings });
|
|
@@ -438,6 +585,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
438
585
|
usage = usageMetadata;
|
|
439
586
|
}
|
|
440
587
|
|
|
588
|
+
if (value.serviceTier != null) {
|
|
589
|
+
serviceTier = value.serviceTier;
|
|
590
|
+
}
|
|
591
|
+
|
|
441
592
|
const candidate = value.candidates?.[0];
|
|
442
593
|
|
|
443
594
|
// sometimes the API returns an empty candidates array
|
|
@@ -598,60 +749,213 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
598
749
|
|
|
599
750
|
const hasThought = part.thought === true;
|
|
600
751
|
const hasThoughtSignature = !!part.thoughtSignature;
|
|
601
|
-
const fileMeta =
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
: {}),
|
|
609
|
-
},
|
|
610
|
-
}
|
|
611
|
-
: undefined;
|
|
752
|
+
const fileMeta = hasThoughtSignature
|
|
753
|
+
? {
|
|
754
|
+
[providerOptionsName]: {
|
|
755
|
+
thoughtSignature: part.thoughtSignature,
|
|
756
|
+
},
|
|
757
|
+
}
|
|
758
|
+
: undefined;
|
|
612
759
|
controller.enqueue({
|
|
613
|
-
type: 'file',
|
|
760
|
+
type: hasThought ? 'reasoning-file' : 'file',
|
|
614
761
|
mediaType: part.inlineData.mimeType,
|
|
615
762
|
data: part.inlineData.data,
|
|
616
763
|
providerMetadata: fileMeta,
|
|
617
764
|
});
|
|
765
|
+
} else if ('toolCall' in part && part.toolCall) {
|
|
766
|
+
const toolCallId = part.toolCall.id ?? generateId();
|
|
767
|
+
lastServerToolCallId = toolCallId;
|
|
768
|
+
const serverMeta = {
|
|
769
|
+
[providerOptionsName]: {
|
|
770
|
+
...(part.thoughtSignature
|
|
771
|
+
? { thoughtSignature: part.thoughtSignature }
|
|
772
|
+
: {}),
|
|
773
|
+
serverToolCallId: toolCallId,
|
|
774
|
+
serverToolType: part.toolCall.toolType,
|
|
775
|
+
},
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
controller.enqueue({
|
|
779
|
+
type: 'tool-call',
|
|
780
|
+
toolCallId,
|
|
781
|
+
toolName: `server:${part.toolCall.toolType}`,
|
|
782
|
+
input: JSON.stringify(part.toolCall.args ?? {}),
|
|
783
|
+
providerExecuted: true,
|
|
784
|
+
dynamic: true,
|
|
785
|
+
providerMetadata: serverMeta,
|
|
786
|
+
});
|
|
787
|
+
} else if ('toolResponse' in part && part.toolResponse) {
|
|
788
|
+
const responseToolCallId =
|
|
789
|
+
lastServerToolCallId ??
|
|
790
|
+
part.toolResponse.id ??
|
|
791
|
+
generateId();
|
|
792
|
+
const serverMeta = {
|
|
793
|
+
[providerOptionsName]: {
|
|
794
|
+
...(part.thoughtSignature
|
|
795
|
+
? { thoughtSignature: part.thoughtSignature }
|
|
796
|
+
: {}),
|
|
797
|
+
serverToolCallId: responseToolCallId,
|
|
798
|
+
serverToolType: part.toolResponse.toolType,
|
|
799
|
+
},
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
controller.enqueue({
|
|
803
|
+
type: 'tool-result',
|
|
804
|
+
toolCallId: responseToolCallId,
|
|
805
|
+
toolName: `server:${part.toolResponse.toolType}`,
|
|
806
|
+
result: (part.toolResponse.response ?? {}) as JSONObject,
|
|
807
|
+
providerMetadata: serverMeta,
|
|
808
|
+
});
|
|
809
|
+
lastServerToolCallId = undefined;
|
|
618
810
|
}
|
|
619
811
|
}
|
|
620
812
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
813
|
+
// Handle streaming and complete function calls
|
|
814
|
+
for (const part of parts) {
|
|
815
|
+
if (!('functionCall' in part)) continue;
|
|
816
|
+
|
|
817
|
+
const providerMeta = part.thoughtSignature
|
|
818
|
+
? {
|
|
819
|
+
[providerOptionsName]: {
|
|
820
|
+
thoughtSignature: part.thoughtSignature,
|
|
821
|
+
},
|
|
822
|
+
}
|
|
823
|
+
: undefined;
|
|
824
|
+
|
|
825
|
+
const isStreamingChunk =
|
|
826
|
+
part.functionCall.partialArgs != null ||
|
|
827
|
+
(part.functionCall.name != null &&
|
|
828
|
+
part.functionCall.willContinue === true);
|
|
829
|
+
const isTerminalChunk =
|
|
830
|
+
part.functionCall.name == null &&
|
|
831
|
+
part.functionCall.args == null &&
|
|
832
|
+
part.functionCall.partialArgs == null &&
|
|
833
|
+
part.functionCall.willContinue == null;
|
|
834
|
+
const isCompleteCall =
|
|
835
|
+
part.functionCall.name != null &&
|
|
836
|
+
part.functionCall.args != null &&
|
|
837
|
+
part.functionCall.partialArgs == null;
|
|
838
|
+
|
|
839
|
+
if (isStreamingChunk) {
|
|
840
|
+
if (
|
|
841
|
+
part.functionCall.name != null &&
|
|
842
|
+
part.functionCall.willContinue === true
|
|
843
|
+
) {
|
|
844
|
+
const toolCallId = generateId();
|
|
845
|
+
const accumulator = new GoogleJSONAccumulator();
|
|
846
|
+
activeStreamingToolCalls.push({
|
|
847
|
+
toolCallId,
|
|
848
|
+
toolName: part.functionCall.name,
|
|
849
|
+
accumulator,
|
|
850
|
+
providerMetadata: providerMeta,
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
controller.enqueue({
|
|
854
|
+
type: 'tool-input-start',
|
|
855
|
+
id: toolCallId,
|
|
856
|
+
toolName: part.functionCall.name,
|
|
857
|
+
providerMetadata: providerMeta,
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
if (part.functionCall.partialArgs != null) {
|
|
861
|
+
const { textDelta } = accumulator.processPartialArgs(
|
|
862
|
+
part.functionCall.partialArgs as PartialArg[],
|
|
863
|
+
);
|
|
864
|
+
if (textDelta.length > 0) {
|
|
865
|
+
controller.enqueue({
|
|
866
|
+
type: 'tool-input-delta',
|
|
867
|
+
id: toolCallId,
|
|
868
|
+
delta: textDelta,
|
|
869
|
+
providerMetadata: providerMeta,
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
} else if (
|
|
874
|
+
part.functionCall.partialArgs != null &&
|
|
875
|
+
activeStreamingToolCalls.length > 0
|
|
876
|
+
) {
|
|
877
|
+
const active =
|
|
878
|
+
activeStreamingToolCalls[
|
|
879
|
+
activeStreamingToolCalls.length - 1
|
|
880
|
+
];
|
|
881
|
+
const { textDelta } = active.accumulator.processPartialArgs(
|
|
882
|
+
part.functionCall.partialArgs as PartialArg[],
|
|
883
|
+
);
|
|
884
|
+
if (textDelta.length > 0) {
|
|
885
|
+
controller.enqueue({
|
|
886
|
+
type: 'tool-input-delta',
|
|
887
|
+
id: active.toolCallId,
|
|
888
|
+
delta: textDelta,
|
|
889
|
+
providerMetadata: providerMeta,
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
} else if (
|
|
894
|
+
isTerminalChunk &&
|
|
895
|
+
activeStreamingToolCalls.length > 0
|
|
896
|
+
) {
|
|
897
|
+
const active = activeStreamingToolCalls.pop()!;
|
|
898
|
+
const { finalJSON, closingDelta } =
|
|
899
|
+
active.accumulator.finalize();
|
|
900
|
+
|
|
901
|
+
if (closingDelta.length > 0) {
|
|
902
|
+
controller.enqueue({
|
|
903
|
+
type: 'tool-input-delta',
|
|
904
|
+
id: active.toolCallId,
|
|
905
|
+
delta: closingDelta,
|
|
906
|
+
providerMetadata: active.providerMetadata,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
controller.enqueue({
|
|
911
|
+
type: 'tool-input-end',
|
|
912
|
+
id: active.toolCallId,
|
|
913
|
+
providerMetadata: active.providerMetadata,
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
controller.enqueue({
|
|
917
|
+
type: 'tool-call',
|
|
918
|
+
toolCallId: active.toolCallId,
|
|
919
|
+
toolName: active.toolName,
|
|
920
|
+
input: finalJSON,
|
|
921
|
+
providerMetadata: active.providerMetadata,
|
|
922
|
+
});
|
|
923
|
+
|
|
924
|
+
hasToolCalls = true;
|
|
925
|
+
} else if (isCompleteCall) {
|
|
926
|
+
const toolCallId = generateId();
|
|
927
|
+
const toolName = part.functionCall.name!;
|
|
928
|
+
const args =
|
|
929
|
+
typeof part.functionCall.args === 'string'
|
|
930
|
+
? part.functionCall.args
|
|
931
|
+
: JSON.stringify(part.functionCall.args ?? {});
|
|
626
932
|
|
|
627
|
-
if (toolCallDeltas != null) {
|
|
628
|
-
for (const toolCall of toolCallDeltas) {
|
|
629
933
|
controller.enqueue({
|
|
630
934
|
type: 'tool-input-start',
|
|
631
|
-
id:
|
|
632
|
-
toolName
|
|
633
|
-
providerMetadata:
|
|
935
|
+
id: toolCallId,
|
|
936
|
+
toolName,
|
|
937
|
+
providerMetadata: providerMeta,
|
|
634
938
|
});
|
|
635
939
|
|
|
636
940
|
controller.enqueue({
|
|
637
941
|
type: 'tool-input-delta',
|
|
638
|
-
id:
|
|
639
|
-
delta:
|
|
640
|
-
providerMetadata:
|
|
942
|
+
id: toolCallId,
|
|
943
|
+
delta: args,
|
|
944
|
+
providerMetadata: providerMeta,
|
|
641
945
|
});
|
|
642
946
|
|
|
643
947
|
controller.enqueue({
|
|
644
948
|
type: 'tool-input-end',
|
|
645
|
-
id:
|
|
646
|
-
providerMetadata:
|
|
949
|
+
id: toolCallId,
|
|
950
|
+
providerMetadata: providerMeta,
|
|
647
951
|
});
|
|
648
952
|
|
|
649
953
|
controller.enqueue({
|
|
650
954
|
type: 'tool-call',
|
|
651
|
-
toolCallId
|
|
652
|
-
toolName
|
|
653
|
-
input:
|
|
654
|
-
providerMetadata:
|
|
955
|
+
toolCallId,
|
|
956
|
+
toolName,
|
|
957
|
+
input: args,
|
|
958
|
+
providerMetadata: providerMeta,
|
|
655
959
|
});
|
|
656
960
|
|
|
657
961
|
hasToolCalls = true;
|
|
@@ -674,16 +978,11 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
674
978
|
groundingMetadata: lastGroundingMetadata,
|
|
675
979
|
urlContextMetadata: lastUrlContextMetadata,
|
|
676
980
|
safetyRatings: candidate.safetyRatings ?? null,
|
|
677
|
-
|
|
981
|
+
usageMetadata: usageMetadata ?? null,
|
|
982
|
+
finishMessage: candidate.finishMessage ?? null,
|
|
983
|
+
serviceTier,
|
|
984
|
+
} satisfies GoogleGenerativeAIProviderMetadata,
|
|
678
985
|
};
|
|
679
|
-
if (usageMetadata != null) {
|
|
680
|
-
(
|
|
681
|
-
providerMetadata[providerOptionsName] as Record<
|
|
682
|
-
string,
|
|
683
|
-
unknown
|
|
684
|
-
>
|
|
685
|
-
).usageMetadata = usageMetadata;
|
|
686
|
-
}
|
|
687
986
|
}
|
|
688
987
|
},
|
|
689
988
|
|
|
@@ -716,39 +1015,107 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
716
1015
|
}
|
|
717
1016
|
}
|
|
718
1017
|
|
|
719
|
-
function
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
1018
|
+
function isGemini3Model(modelId: string): boolean {
|
|
1019
|
+
return /gemini-3[\.\-]/i.test(modelId) || /gemini-3$/i.test(modelId);
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function getMaxOutputTokensForGemini25Model(): number {
|
|
1023
|
+
return 65536;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
function getMaxThinkingTokensForGemini25Model(modelId: string): number {
|
|
1027
|
+
const id = modelId.toLowerCase();
|
|
1028
|
+
if (id.includes('2.5-pro') || id.includes('gemini-3-pro-image')) {
|
|
1029
|
+
return 32768;
|
|
1030
|
+
}
|
|
1031
|
+
return 24576;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
type GoogleThinkingConfig = NonNullable<
|
|
1035
|
+
InferSchema<typeof googleLanguageModelOptions>['thinkingConfig']
|
|
1036
|
+
>;
|
|
1037
|
+
|
|
1038
|
+
function resolveThinkingConfig({
|
|
1039
|
+
reasoning,
|
|
1040
|
+
modelId,
|
|
1041
|
+
warnings,
|
|
723
1042
|
}: {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
}) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
1043
|
+
reasoning: LanguageModelV4CallOptions['reasoning'];
|
|
1044
|
+
modelId: string;
|
|
1045
|
+
warnings: SharedV4Warning[];
|
|
1046
|
+
}): Omit<GoogleThinkingConfig, 'includeThoughts'> | undefined {
|
|
1047
|
+
if (!isCustomReasoning(reasoning)) {
|
|
1048
|
+
return undefined;
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
if (isGemini3Model(modelId) && !modelId.includes('gemini-3-pro-image')) {
|
|
1052
|
+
return resolveGemini3ThinkingConfig({ reasoning, warnings });
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
return resolveGemini25ThinkingConfig({ reasoning, modelId, warnings });
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
function resolveGemini3ThinkingConfig({
|
|
1059
|
+
reasoning,
|
|
1060
|
+
warnings,
|
|
1061
|
+
}: {
|
|
1062
|
+
reasoning: Exclude<
|
|
1063
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
1064
|
+
'provider-default' | undefined
|
|
735
1065
|
>;
|
|
1066
|
+
warnings: SharedV4Warning[];
|
|
1067
|
+
}): Pick<GoogleThinkingConfig, 'thinkingLevel'> | undefined {
|
|
1068
|
+
if (reasoning === 'none') {
|
|
1069
|
+
// It's not possible to fully disable thinking with Gemini 3.
|
|
1070
|
+
return { thinkingLevel: 'minimal' };
|
|
1071
|
+
}
|
|
736
1072
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
:
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1073
|
+
const thinkingLevel = mapReasoningToProviderEffort({
|
|
1074
|
+
reasoning,
|
|
1075
|
+
effortMap: {
|
|
1076
|
+
minimal: 'minimal',
|
|
1077
|
+
low: 'low',
|
|
1078
|
+
medium: 'medium',
|
|
1079
|
+
high: 'high',
|
|
1080
|
+
xhigh: 'high',
|
|
1081
|
+
},
|
|
1082
|
+
warnings,
|
|
1083
|
+
});
|
|
1084
|
+
|
|
1085
|
+
if (thinkingLevel == null) {
|
|
1086
|
+
return undefined;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
return { thinkingLevel };
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
function resolveGemini25ThinkingConfig({
|
|
1093
|
+
reasoning,
|
|
1094
|
+
modelId,
|
|
1095
|
+
warnings,
|
|
1096
|
+
}: {
|
|
1097
|
+
reasoning: Exclude<
|
|
1098
|
+
LanguageModelV4CallOptions['reasoning'],
|
|
1099
|
+
'provider-default' | undefined
|
|
1100
|
+
>;
|
|
1101
|
+
modelId: string;
|
|
1102
|
+
warnings: SharedV4Warning[];
|
|
1103
|
+
}): Pick<GoogleThinkingConfig, 'thinkingBudget'> | undefined {
|
|
1104
|
+
if (reasoning === 'none') {
|
|
1105
|
+
return { thinkingBudget: 0 };
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
const thinkingBudget = mapReasoningToProviderBudget({
|
|
1109
|
+
reasoning,
|
|
1110
|
+
maxOutputTokens: getMaxOutputTokensForGemini25Model(),
|
|
1111
|
+
maxReasoningBudget: getMaxThinkingTokensForGemini25Model(modelId),
|
|
1112
|
+
minReasoningBudget: 0,
|
|
1113
|
+
warnings,
|
|
1114
|
+
});
|
|
1115
|
+
if (thinkingBudget == null) {
|
|
1116
|
+
return undefined;
|
|
1117
|
+
}
|
|
1118
|
+
return { thinkingBudget };
|
|
752
1119
|
}
|
|
753
1120
|
|
|
754
1121
|
function extractSources({
|
|
@@ -757,12 +1124,12 @@ function extractSources({
|
|
|
757
1124
|
}: {
|
|
758
1125
|
groundingMetadata: GroundingMetadataSchema | undefined | null;
|
|
759
1126
|
generateId: () => string;
|
|
760
|
-
}): undefined |
|
|
1127
|
+
}): undefined | LanguageModelV4Source[] {
|
|
761
1128
|
if (!groundingMetadata?.groundingChunks) {
|
|
762
1129
|
return undefined;
|
|
763
1130
|
}
|
|
764
1131
|
|
|
765
|
-
const sources:
|
|
1132
|
+
const sources: LanguageModelV4Source[] = [];
|
|
766
1133
|
|
|
767
1134
|
for (const chunk of groundingMetadata.groundingChunks) {
|
|
768
1135
|
if (chunk.web != null) {
|
|
@@ -928,6 +1295,15 @@ export const getGroundingMetadataSchema = () =>
|
|
|
928
1295
|
.nullish(),
|
|
929
1296
|
});
|
|
930
1297
|
|
|
1298
|
+
const partialArgSchema = z.object({
|
|
1299
|
+
jsonPath: z.string(),
|
|
1300
|
+
stringValue: z.string().nullish(),
|
|
1301
|
+
numberValue: z.number().nullish(),
|
|
1302
|
+
boolValue: z.boolean().nullish(),
|
|
1303
|
+
nullValue: z.unknown().nullish(),
|
|
1304
|
+
willContinue: z.boolean().nullish(),
|
|
1305
|
+
});
|
|
1306
|
+
|
|
931
1307
|
const getContentSchema = () =>
|
|
932
1308
|
z.object({
|
|
933
1309
|
parts: z
|
|
@@ -936,8 +1312,10 @@ const getContentSchema = () =>
|
|
|
936
1312
|
// note: order matters since text can be fully empty
|
|
937
1313
|
z.object({
|
|
938
1314
|
functionCall: z.object({
|
|
939
|
-
name: z.string(),
|
|
940
|
-
args: z.unknown(),
|
|
1315
|
+
name: z.string().nullish(),
|
|
1316
|
+
args: z.unknown().nullish(),
|
|
1317
|
+
partialArgs: z.array(partialArgSchema).nullish(),
|
|
1318
|
+
willContinue: z.boolean().nullish(),
|
|
941
1319
|
}),
|
|
942
1320
|
thoughtSignature: z.string().nullish(),
|
|
943
1321
|
}),
|
|
@@ -949,6 +1327,22 @@ const getContentSchema = () =>
|
|
|
949
1327
|
thought: z.boolean().nullish(),
|
|
950
1328
|
thoughtSignature: z.string().nullish(),
|
|
951
1329
|
}),
|
|
1330
|
+
z.object({
|
|
1331
|
+
toolCall: z.object({
|
|
1332
|
+
toolType: z.string(),
|
|
1333
|
+
args: z.unknown().nullish(),
|
|
1334
|
+
id: z.string(),
|
|
1335
|
+
}),
|
|
1336
|
+
thoughtSignature: z.string().nullish(),
|
|
1337
|
+
}),
|
|
1338
|
+
z.object({
|
|
1339
|
+
toolResponse: z.object({
|
|
1340
|
+
toolType: z.string(),
|
|
1341
|
+
response: z.unknown().nullish(),
|
|
1342
|
+
id: z.string(),
|
|
1343
|
+
}),
|
|
1344
|
+
thoughtSignature: z.string().nullish(),
|
|
1345
|
+
}),
|
|
952
1346
|
z.object({
|
|
953
1347
|
executableCode: z
|
|
954
1348
|
.object({
|
|
@@ -982,6 +1376,15 @@ const getSafetyRatingSchema = () =>
|
|
|
982
1376
|
blocked: z.boolean().nullish(),
|
|
983
1377
|
});
|
|
984
1378
|
|
|
1379
|
+
const tokenDetailsSchema = z
|
|
1380
|
+
.array(
|
|
1381
|
+
z.object({
|
|
1382
|
+
modality: z.string(),
|
|
1383
|
+
tokenCount: z.number(),
|
|
1384
|
+
}),
|
|
1385
|
+
)
|
|
1386
|
+
.nullish();
|
|
1387
|
+
|
|
985
1388
|
const usageSchema = z.object({
|
|
986
1389
|
cachedContentTokenCount: z.number().nullish(),
|
|
987
1390
|
thoughtsTokenCount: z.number().nullish(),
|
|
@@ -990,6 +1393,9 @@ const usageSchema = z.object({
|
|
|
990
1393
|
totalTokenCount: z.number().nullish(),
|
|
991
1394
|
// https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
|
|
992
1395
|
trafficType: z.string().nullish(),
|
|
1396
|
+
// https://ai.google.dev/api/generate-content#Modality
|
|
1397
|
+
promptTokensDetails: tokenDetailsSchema,
|
|
1398
|
+
candidatesTokensDetails: tokenDetailsSchema,
|
|
993
1399
|
});
|
|
994
1400
|
|
|
995
1401
|
// https://ai.google.dev/api/generate-content#UrlRetrievalMetadata
|
|
@@ -1012,6 +1418,7 @@ const responseSchema = lazySchema(() =>
|
|
|
1012
1418
|
z.object({
|
|
1013
1419
|
content: getContentSchema().nullish().or(z.object({}).strict()),
|
|
1014
1420
|
finishReason: z.string().nullish(),
|
|
1421
|
+
finishMessage: z.string().nullish(),
|
|
1015
1422
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1016
1423
|
groundingMetadata: getGroundingMetadataSchema().nullish(),
|
|
1017
1424
|
urlContextMetadata: getUrlContextMetadataSchema().nullish(),
|
|
@@ -1024,21 +1431,15 @@ const responseSchema = lazySchema(() =>
|
|
|
1024
1431
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1025
1432
|
})
|
|
1026
1433
|
.nullish(),
|
|
1434
|
+
serviceTier: z.string().nullish(),
|
|
1027
1435
|
}),
|
|
1028
1436
|
),
|
|
1029
1437
|
);
|
|
1030
1438
|
|
|
1031
|
-
type ContentSchema = NonNullable<
|
|
1032
|
-
InferSchema<typeof responseSchema>['candidates'][number]['content']
|
|
1033
|
-
>;
|
|
1034
1439
|
export type GroundingMetadataSchema = NonNullable<
|
|
1035
1440
|
InferSchema<typeof responseSchema>['candidates'][number]['groundingMetadata']
|
|
1036
1441
|
>;
|
|
1037
1442
|
|
|
1038
|
-
type GroundingChunkSchema = NonNullable<
|
|
1039
|
-
GroundingMetadataSchema['groundingChunks']
|
|
1040
|
-
>[number];
|
|
1041
|
-
|
|
1042
1443
|
export type UrlContextMetadataSchema = NonNullable<
|
|
1043
1444
|
InferSchema<typeof responseSchema>['candidates'][number]['urlContextMetadata']
|
|
1044
1445
|
>;
|
|
@@ -1047,6 +1448,14 @@ export type SafetyRatingSchema = NonNullable<
|
|
|
1047
1448
|
InferSchema<typeof responseSchema>['candidates'][number]['safetyRatings']
|
|
1048
1449
|
>[number];
|
|
1049
1450
|
|
|
1451
|
+
export type PromptFeedbackSchema = NonNullable<
|
|
1452
|
+
InferSchema<typeof responseSchema>['promptFeedback']
|
|
1453
|
+
>;
|
|
1454
|
+
|
|
1455
|
+
export type UsageMetadataSchema = NonNullable<
|
|
1456
|
+
InferSchema<typeof responseSchema>['usageMetadata']
|
|
1457
|
+
>;
|
|
1458
|
+
|
|
1050
1459
|
// limited version of the schema, focussed on what is needed for the implementation
|
|
1051
1460
|
// this approach limits breakages when the API changes and increases efficiency
|
|
1052
1461
|
const chunkSchema = lazySchema(() =>
|
|
@@ -1057,6 +1466,7 @@ const chunkSchema = lazySchema(() =>
|
|
|
1057
1466
|
z.object({
|
|
1058
1467
|
content: getContentSchema().nullish(),
|
|
1059
1468
|
finishReason: z.string().nullish(),
|
|
1469
|
+
finishMessage: z.string().nullish(),
|
|
1060
1470
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1061
1471
|
groundingMetadata: getGroundingMetadataSchema().nullish(),
|
|
1062
1472
|
urlContextMetadata: getUrlContextMetadataSchema().nullish(),
|
|
@@ -1070,6 +1480,7 @@ const chunkSchema = lazySchema(() =>
|
|
|
1070
1480
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1071
1481
|
})
|
|
1072
1482
|
.nullish(),
|
|
1483
|
+
serviceTier: z.string().nullish(),
|
|
1073
1484
|
}),
|
|
1074
1485
|
),
|
|
1075
1486
|
);
|