@ai-sdk/google 4.0.0-beta.2 → 4.0.0-beta.20

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.
@@ -1,14 +1,15 @@
1
1
  import {
2
- LanguageModelV3,
3
- LanguageModelV3CallOptions,
4
- LanguageModelV3Content,
5
- LanguageModelV3FinishReason,
6
- LanguageModelV3GenerateResult,
7
- LanguageModelV3Source,
8
- LanguageModelV3StreamPart,
9
- LanguageModelV3StreamResult,
10
- SharedV3ProviderMetadata,
11
- SharedV3Warning,
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,7 +18,10 @@ 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,
@@ -38,7 +42,10 @@ import {
38
42
  GoogleGenerativeAIModelId,
39
43
  googleLanguageModelOptions,
40
44
  } from './google-generative-ai-options';
41
- import { GoogleGenerativeAIContentPart } from './google-generative-ai-prompt';
45
+ import {
46
+ GoogleGenerativeAIContentPart,
47
+ GoogleGenerativeAIProviderMetadata,
48
+ } from './google-generative-ai-prompt';
42
49
  import { prepareTools } from './google-prepare-tools';
43
50
  import { mapGoogleGenerativeAIFinishReason } from './map-google-generative-ai-finish-reason';
44
51
 
@@ -52,11 +59,11 @@ type GoogleGenerativeAIConfig = {
52
59
  /**
53
60
  * The supported URLs for the model.
54
61
  */
55
- supportedUrls?: () => LanguageModelV3['supportedUrls'];
62
+ supportedUrls?: () => LanguageModelV4['supportedUrls'];
56
63
  };
57
64
 
58
- export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
59
- readonly specificationVersion = 'v3';
65
+ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
66
+ readonly specificationVersion = 'v4';
60
67
 
61
68
  readonly modelId: GoogleGenerativeAIModelId;
62
69
 
@@ -93,9 +100,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
93
100
  seed,
94
101
  tools,
95
102
  toolChoice,
103
+ reasoning,
96
104
  providerOptions,
97
- }: LanguageModelV3CallOptions) {
98
- const warnings: SharedV3Warning[] = [];
105
+ }: LanguageModelV4CallOptions) {
106
+ const warnings: SharedV4Warning[] = [];
99
107
 
100
108
  const providerOptionsName = this.config.provider.includes('vertex')
101
109
  ? 'vertex'
@@ -132,10 +140,15 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
132
140
  }
133
141
 
134
142
  const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
143
+ const supportsFunctionResponseParts = this.modelId.startsWith('gemini-3');
135
144
 
136
145
  const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
137
146
  prompt,
138
- { isGemmaModel, providerOptionsName },
147
+ {
148
+ isGemmaModel,
149
+ providerOptionsName,
150
+ supportsFunctionResponseParts,
151
+ },
139
152
  );
140
153
 
141
154
  const {
@@ -148,6 +161,16 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
148
161
  modelId: this.modelId,
149
162
  });
150
163
 
164
+ const resolvedThinking = resolveThinkingConfig({
165
+ reasoning,
166
+ modelId: this.modelId,
167
+ warnings,
168
+ });
169
+ const thinkingConfig =
170
+ googleOptions?.thinkingConfig || resolvedThinking
171
+ ? { ...resolvedThinking, ...googleOptions?.thinkingConfig }
172
+ : undefined;
173
+
151
174
  return {
152
175
  args: {
153
176
  generationConfig: {
@@ -179,7 +202,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
179
202
 
180
203
  // provider options:
181
204
  responseModalities: googleOptions?.responseModalities,
182
- thinkingConfig: googleOptions?.thinkingConfig,
205
+ thinkingConfig,
183
206
  ...(googleOptions?.mediaResolution && {
184
207
  mediaResolution: googleOptions.mediaResolution,
185
208
  }),
@@ -199,6 +222,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
199
222
  : googleToolConfig,
200
223
  cachedContent: googleOptions?.cachedContent,
201
224
  labels: googleOptions?.labels,
225
+ serviceTier: googleOptions?.serviceTier,
202
226
  },
203
227
  warnings: [...warnings, ...toolWarnings],
204
228
  providerOptionsName,
@@ -206,8 +230,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
206
230
  }
207
231
 
208
232
  async doGenerate(
209
- options: LanguageModelV3CallOptions,
210
- ): Promise<LanguageModelV3GenerateResult> {
233
+ options: LanguageModelV4CallOptions,
234
+ ): Promise<LanguageModelV4GenerateResult> {
211
235
  const { args, warnings, providerOptionsName } = await this.getArgs(options);
212
236
 
213
237
  const mergedHeaders = combineHeaders(
@@ -232,7 +256,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
232
256
  });
233
257
 
234
258
  const candidate = response.candidates[0];
235
- const content: Array<LanguageModelV3Content> = [];
259
+ const content: Array<LanguageModelV4Content> = [];
236
260
 
237
261
  // map ordered parts to content:
238
262
  const parts = candidate.content?.parts ?? [];
@@ -241,6 +265,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
241
265
 
242
266
  // Associates a code execution result with its preceding call.
243
267
  let lastCodeExecutionToolCallId: string | undefined;
268
+ // Associates a server-side tool response with its preceding call (tool combination).
269
+ let lastServerToolCallId: string | undefined;
244
270
 
245
271
  // Build content array from all parts
246
272
  for (const part of parts) {
@@ -304,11 +330,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
304
330
  : undefined,
305
331
  });
306
332
  } else if ('inlineData' in part) {
333
+ const hasThought = part.thought === true;
334
+ const hasThoughtSignature = !!part.thoughtSignature;
307
335
  content.push({
308
- type: 'file' as const,
336
+ type: hasThought ? 'reasoning-file' : 'file',
309
337
  data: part.inlineData.data,
310
338
  mediaType: part.inlineData.mimeType,
311
- providerMetadata: part.thoughtSignature
339
+ providerMetadata: hasThoughtSignature
312
340
  ? {
313
341
  [providerOptionsName]: {
314
342
  thoughtSignature: part.thoughtSignature,
@@ -316,6 +344,57 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
316
344
  }
317
345
  : undefined,
318
346
  });
347
+ } else if ('toolCall' in part && part.toolCall) {
348
+ const toolCallId = part.toolCall.id ?? this.config.generateId();
349
+ lastServerToolCallId = toolCallId;
350
+ content.push({
351
+ type: 'tool-call',
352
+ toolCallId,
353
+ toolName: `server:${part.toolCall.toolType}`,
354
+ input: JSON.stringify(part.toolCall.args ?? {}),
355
+ providerExecuted: true,
356
+ dynamic: true,
357
+ providerMetadata: part.thoughtSignature
358
+ ? {
359
+ [providerOptionsName]: {
360
+ thoughtSignature: part.thoughtSignature,
361
+ serverToolCallId: toolCallId,
362
+ serverToolType: part.toolCall.toolType,
363
+ },
364
+ }
365
+ : {
366
+ [providerOptionsName]: {
367
+ serverToolCallId: toolCallId,
368
+ serverToolType: part.toolCall.toolType,
369
+ },
370
+ },
371
+ });
372
+ } else if ('toolResponse' in part && part.toolResponse) {
373
+ const responseToolCallId =
374
+ lastServerToolCallId ??
375
+ part.toolResponse.id ??
376
+ this.config.generateId();
377
+ content.push({
378
+ type: 'tool-result',
379
+ toolCallId: responseToolCallId,
380
+ toolName: `server:${part.toolResponse.toolType}`,
381
+ result: (part.toolResponse.response ?? {}) as JSONObject,
382
+ providerMetadata: part.thoughtSignature
383
+ ? {
384
+ [providerOptionsName]: {
385
+ thoughtSignature: part.thoughtSignature,
386
+ serverToolCallId: responseToolCallId,
387
+ serverToolType: part.toolResponse.toolType,
388
+ },
389
+ }
390
+ : {
391
+ [providerOptionsName]: {
392
+ serverToolCallId: responseToolCallId,
393
+ serverToolType: part.toolResponse.toolType,
394
+ },
395
+ },
396
+ });
397
+ lastServerToolCallId = undefined;
319
398
  }
320
399
  }
321
400
 
@@ -349,7 +428,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
349
428
  urlContextMetadata: candidate.urlContextMetadata ?? null,
350
429
  safetyRatings: candidate.safetyRatings ?? null,
351
430
  usageMetadata: usageMetadata ?? null,
352
- },
431
+ finishMessage: candidate.finishMessage ?? null,
432
+ serviceTier: response.serviceTier ?? null,
433
+ } satisfies GoogleGenerativeAIProviderMetadata,
353
434
  },
354
435
  request: { body: args },
355
436
  response: {
@@ -361,8 +442,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
361
442
  }
362
443
 
363
444
  async doStream(
364
- options: LanguageModelV3CallOptions,
365
- ): Promise<LanguageModelV3StreamResult> {
445
+ options: LanguageModelV4CallOptions,
446
+ ): Promise<LanguageModelV4StreamResult> {
366
447
  const { args, warnings, providerOptionsName } = await this.getArgs(options);
367
448
 
368
449
  const headers = combineHeaders(
@@ -382,14 +463,15 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
382
463
  fetch: this.config.fetch,
383
464
  });
384
465
 
385
- let finishReason: LanguageModelV3FinishReason = {
466
+ let finishReason: LanguageModelV4FinishReason = {
386
467
  unified: 'other',
387
468
  raw: undefined,
388
469
  };
389
470
  let usage: GoogleGenerativeAIUsageMetadata | undefined = undefined;
390
- let providerMetadata: SharedV3ProviderMetadata | undefined = undefined;
471
+ let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
391
472
  let lastGroundingMetadata: GroundingMetadataSchema | null = null;
392
473
  let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
474
+ let serviceTier: string | null = null;
393
475
 
394
476
  const generateId = this.config.generateId;
395
477
  let hasToolCalls = false;
@@ -403,12 +485,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
403
485
  const emittedSourceUrls = new Set<string>();
404
486
  // Associates a code execution result with its preceding call.
405
487
  let lastCodeExecutionToolCallId: string | undefined;
488
+ // Associates a server-side tool response with its preceding call (tool combination).
489
+ let lastServerToolCallId: string | undefined;
406
490
 
407
491
  return {
408
492
  stream: response.pipeThrough(
409
493
  new TransformStream<
410
494
  ParseResult<ChunkSchema>,
411
- LanguageModelV3StreamPart
495
+ LanguageModelV4StreamPart
412
496
  >({
413
497
  start(controller) {
414
498
  controller.enqueue({ type: 'stream-start', warnings });
@@ -432,6 +516,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
432
516
  usage = usageMetadata;
433
517
  }
434
518
 
519
+ if (value.serviceTier != null) {
520
+ serviceTier = value.serviceTier;
521
+ }
522
+
435
523
  const candidate = value.candidates?.[0];
436
524
 
437
525
  // sometimes the API returns an empty candidates array
@@ -590,8 +678,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
590
678
  currentReasoningBlockId = null;
591
679
  }
592
680
 
593
- // Process file parts inline to preserve order with text
594
- const thoughtSignatureMetadata = part.thoughtSignature
681
+ const hasThought = part.thought === true;
682
+ const hasThoughtSignature = !!part.thoughtSignature;
683
+ const fileMeta = hasThoughtSignature
595
684
  ? {
596
685
  [providerOptionsName]: {
597
686
  thoughtSignature: part.thoughtSignature,
@@ -599,11 +688,56 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
599
688
  }
600
689
  : undefined;
601
690
  controller.enqueue({
602
- type: 'file',
691
+ type: hasThought ? 'reasoning-file' : 'file',
603
692
  mediaType: part.inlineData.mimeType,
604
693
  data: part.inlineData.data,
605
- providerMetadata: thoughtSignatureMetadata,
694
+ providerMetadata: fileMeta,
606
695
  });
696
+ } else if ('toolCall' in part && part.toolCall) {
697
+ const toolCallId = part.toolCall.id ?? generateId();
698
+ lastServerToolCallId = toolCallId;
699
+ const serverMeta = {
700
+ [providerOptionsName]: {
701
+ ...(part.thoughtSignature
702
+ ? { thoughtSignature: part.thoughtSignature }
703
+ : {}),
704
+ serverToolCallId: toolCallId,
705
+ serverToolType: part.toolCall.toolType,
706
+ },
707
+ };
708
+
709
+ controller.enqueue({
710
+ type: 'tool-call',
711
+ toolCallId,
712
+ toolName: `server:${part.toolCall.toolType}`,
713
+ input: JSON.stringify(part.toolCall.args ?? {}),
714
+ providerExecuted: true,
715
+ dynamic: true,
716
+ providerMetadata: serverMeta,
717
+ });
718
+ } else if ('toolResponse' in part && part.toolResponse) {
719
+ const responseToolCallId =
720
+ lastServerToolCallId ??
721
+ part.toolResponse.id ??
722
+ generateId();
723
+ const serverMeta = {
724
+ [providerOptionsName]: {
725
+ ...(part.thoughtSignature
726
+ ? { thoughtSignature: part.thoughtSignature }
727
+ : {}),
728
+ serverToolCallId: responseToolCallId,
729
+ serverToolType: part.toolResponse.toolType,
730
+ },
731
+ };
732
+
733
+ controller.enqueue({
734
+ type: 'tool-result',
735
+ toolCallId: responseToolCallId,
736
+ toolName: `server:${part.toolResponse.toolType}`,
737
+ result: (part.toolResponse.response ?? {}) as JSONObject,
738
+ providerMetadata: serverMeta,
739
+ });
740
+ lastServerToolCallId = undefined;
607
741
  }
608
742
  }
609
743
 
@@ -663,16 +797,11 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
663
797
  groundingMetadata: lastGroundingMetadata,
664
798
  urlContextMetadata: lastUrlContextMetadata,
665
799
  safetyRatings: candidate.safetyRatings ?? null,
666
- },
800
+ usageMetadata: usageMetadata ?? null,
801
+ finishMessage: candidate.finishMessage ?? null,
802
+ serviceTier,
803
+ } satisfies GoogleGenerativeAIProviderMetadata,
667
804
  };
668
- if (usageMetadata != null) {
669
- (
670
- providerMetadata[providerOptionsName] as Record<
671
- string,
672
- unknown
673
- >
674
- ).usageMetadata = usageMetadata;
675
- }
676
805
  }
677
806
  },
678
807
 
@@ -705,6 +834,109 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
705
834
  }
706
835
  }
707
836
 
837
+ function isGemini3Model(modelId: string): boolean {
838
+ return /gemini-3[\.\-]/i.test(modelId) || /gemini-3$/i.test(modelId);
839
+ }
840
+
841
+ function getMaxOutputTokensForGemini25Model(): number {
842
+ return 65536;
843
+ }
844
+
845
+ function getMaxThinkingTokensForGemini25Model(modelId: string): number {
846
+ const id = modelId.toLowerCase();
847
+ if (id.includes('2.5-pro') || id.includes('gemini-3-pro-image')) {
848
+ return 32768;
849
+ }
850
+ return 24576;
851
+ }
852
+
853
+ type GoogleThinkingConfig = NonNullable<
854
+ InferSchema<typeof googleLanguageModelOptions>['thinkingConfig']
855
+ >;
856
+
857
+ function resolveThinkingConfig({
858
+ reasoning,
859
+ modelId,
860
+ warnings,
861
+ }: {
862
+ reasoning: LanguageModelV4CallOptions['reasoning'];
863
+ modelId: string;
864
+ warnings: SharedV4Warning[];
865
+ }): Omit<GoogleThinkingConfig, 'includeThoughts'> | undefined {
866
+ if (!isCustomReasoning(reasoning)) {
867
+ return undefined;
868
+ }
869
+
870
+ if (isGemini3Model(modelId) && !modelId.includes('gemini-3-pro-image')) {
871
+ return resolveGemini3ThinkingConfig({ reasoning, warnings });
872
+ }
873
+
874
+ return resolveGemini25ThinkingConfig({ reasoning, modelId, warnings });
875
+ }
876
+
877
+ function resolveGemini3ThinkingConfig({
878
+ reasoning,
879
+ warnings,
880
+ }: {
881
+ reasoning: Exclude<
882
+ LanguageModelV4CallOptions['reasoning'],
883
+ 'provider-default' | undefined
884
+ >;
885
+ warnings: SharedV4Warning[];
886
+ }): Pick<GoogleThinkingConfig, 'thinkingLevel'> | undefined {
887
+ if (reasoning === 'none') {
888
+ // It's not possible to fully disable thinking with Gemini 3.
889
+ return { thinkingLevel: 'minimal' };
890
+ }
891
+
892
+ const thinkingLevel = mapReasoningToProviderEffort({
893
+ reasoning,
894
+ effortMap: {
895
+ minimal: 'minimal',
896
+ low: 'low',
897
+ medium: 'medium',
898
+ high: 'high',
899
+ xhigh: 'high',
900
+ },
901
+ warnings,
902
+ });
903
+
904
+ if (thinkingLevel == null) {
905
+ return undefined;
906
+ }
907
+
908
+ return { thinkingLevel };
909
+ }
910
+
911
+ function resolveGemini25ThinkingConfig({
912
+ reasoning,
913
+ modelId,
914
+ warnings,
915
+ }: {
916
+ reasoning: Exclude<
917
+ LanguageModelV4CallOptions['reasoning'],
918
+ 'provider-default' | undefined
919
+ >;
920
+ modelId: string;
921
+ warnings: SharedV4Warning[];
922
+ }): Pick<GoogleThinkingConfig, 'thinkingBudget'> | undefined {
923
+ if (reasoning === 'none') {
924
+ return { thinkingBudget: 0 };
925
+ }
926
+
927
+ const thinkingBudget = mapReasoningToProviderBudget({
928
+ reasoning,
929
+ maxOutputTokens: getMaxOutputTokensForGemini25Model(),
930
+ maxReasoningBudget: getMaxThinkingTokensForGemini25Model(modelId),
931
+ minReasoningBudget: 0,
932
+ warnings,
933
+ });
934
+ if (thinkingBudget == null) {
935
+ return undefined;
936
+ }
937
+ return { thinkingBudget };
938
+ }
939
+
708
940
  function getToolCallsFromParts({
709
941
  parts,
710
942
  generateId,
@@ -746,12 +978,12 @@ function extractSources({
746
978
  }: {
747
979
  groundingMetadata: GroundingMetadataSchema | undefined | null;
748
980
  generateId: () => string;
749
- }): undefined | LanguageModelV3Source[] {
981
+ }): undefined | LanguageModelV4Source[] {
750
982
  if (!groundingMetadata?.groundingChunks) {
751
983
  return undefined;
752
984
  }
753
985
 
754
- const sources: LanguageModelV3Source[] = [];
986
+ const sources: LanguageModelV4Source[] = [];
755
987
 
756
988
  for (const chunk of groundingMetadata.groundingChunks) {
757
989
  if (chunk.web != null) {
@@ -935,6 +1167,23 @@ const getContentSchema = () =>
935
1167
  mimeType: z.string(),
936
1168
  data: z.string(),
937
1169
  }),
1170
+ thought: z.boolean().nullish(),
1171
+ thoughtSignature: z.string().nullish(),
1172
+ }),
1173
+ z.object({
1174
+ toolCall: z.object({
1175
+ toolType: z.string(),
1176
+ args: z.unknown().nullish(),
1177
+ id: z.string(),
1178
+ }),
1179
+ thoughtSignature: z.string().nullish(),
1180
+ }),
1181
+ z.object({
1182
+ toolResponse: z.object({
1183
+ toolType: z.string(),
1184
+ response: z.unknown().nullish(),
1185
+ id: z.string(),
1186
+ }),
938
1187
  thoughtSignature: z.string().nullish(),
939
1188
  }),
940
1189
  z.object({
@@ -1000,6 +1249,7 @@ const responseSchema = lazySchema(() =>
1000
1249
  z.object({
1001
1250
  content: getContentSchema().nullish().or(z.object({}).strict()),
1002
1251
  finishReason: z.string().nullish(),
1252
+ finishMessage: z.string().nullish(),
1003
1253
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1004
1254
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1005
1255
  urlContextMetadata: getUrlContextMetadataSchema().nullish(),
@@ -1012,6 +1262,7 @@ const responseSchema = lazySchema(() =>
1012
1262
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1013
1263
  })
1014
1264
  .nullish(),
1265
+ serviceTier: z.string().nullish(),
1015
1266
  }),
1016
1267
  ),
1017
1268
  );
@@ -1035,6 +1286,14 @@ export type SafetyRatingSchema = NonNullable<
1035
1286
  InferSchema<typeof responseSchema>['candidates'][number]['safetyRatings']
1036
1287
  >[number];
1037
1288
 
1289
+ export type PromptFeedbackSchema = NonNullable<
1290
+ InferSchema<typeof responseSchema>['promptFeedback']
1291
+ >;
1292
+
1293
+ export type UsageMetadataSchema = NonNullable<
1294
+ InferSchema<typeof responseSchema>['usageMetadata']
1295
+ >;
1296
+
1038
1297
  // limited version of the schema, focussed on what is needed for the implementation
1039
1298
  // this approach limits breakages when the API changes and increases efficiency
1040
1299
  const chunkSchema = lazySchema(() =>
@@ -1045,6 +1304,7 @@ const chunkSchema = lazySchema(() =>
1045
1304
  z.object({
1046
1305
  content: getContentSchema().nullish(),
1047
1306
  finishReason: z.string().nullish(),
1307
+ finishMessage: z.string().nullish(),
1048
1308
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1049
1309
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1050
1310
  urlContextMetadata: getUrlContextMetadataSchema().nullish(),
@@ -1058,6 +1318,7 @@ const chunkSchema = lazySchema(() =>
1058
1318
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1059
1319
  })
1060
1320
  .nullish(),
1321
+ serviceTier: z.string().nullish(),
1061
1322
  }),
1062
1323
  ),
1063
1324
  );
@@ -7,7 +7,6 @@ export type GoogleGenerativeAIModelId =
7
7
  | 'gemini-2.0-flash'
8
8
  | 'gemini-2.0-flash-001'
9
9
  | 'gemini-2.0-flash-lite'
10
- | 'gemini-2.0-flash-exp-image-generation'
11
10
  | 'gemini-2.0-flash-lite-001'
12
11
  | 'gemini-2.5-pro'
13
12
  | 'gemini-2.5-flash'
@@ -189,6 +188,17 @@ export const googleLanguageModelOptions = lazySchema(() =>
189
188
  .optional(),
190
189
  })
191
190
  .optional(),
191
+
192
+ /**
193
+ * Optional. The service tier to use for the request.
194
+ */
195
+ serviceTier: z
196
+ .enum([
197
+ 'SERVICE_TIER_STANDARD',
198
+ 'SERVICE_TIER_FLEX',
199
+ 'SERVICE_TIER_PRIORITY',
200
+ ])
201
+ .optional(),
192
202
  }),
193
203
  ),
194
204
  );
@@ -1,8 +1,10 @@
1
1
  import {
2
2
  GroundingMetadataSchema,
3
+ PromptFeedbackSchema,
3
4
  UrlContextMetadataSchema,
5
+ type SafetyRatingSchema,
6
+ UsageMetadataSchema,
4
7
  } from './google-generative-ai-language-model';
5
- import { type SafetyRatingSchema } from './google-generative-ai-language-model';
6
8
 
7
9
  export type GoogleGenerativeAIPrompt = {
8
10
  systemInstruction?: GoogleGenerativeAISystemInstruction;
@@ -22,8 +24,34 @@ export type GoogleGenerativeAIContentPart =
22
24
  | { text: string; thought?: boolean; thoughtSignature?: string }
23
25
  | { inlineData: { mimeType: string; data: string } }
24
26
  | { functionCall: { name: string; args: unknown }; thoughtSignature?: string }
25
- | { functionResponse: { name: string; response: unknown } }
26
- | { fileData: { mimeType: string; fileUri: string } };
27
+ | {
28
+ functionResponse: {
29
+ name: string;
30
+ response: unknown;
31
+ parts?: Array<GoogleGenerativeAIFunctionResponsePart>;
32
+ };
33
+ }
34
+ | { fileData: { mimeType: string; fileUri: string } }
35
+ | {
36
+ toolCall: {
37
+ toolType: string;
38
+ args?: unknown;
39
+ id: string;
40
+ };
41
+ thoughtSignature?: string;
42
+ }
43
+ | {
44
+ toolResponse: {
45
+ toolType: string;
46
+ response?: unknown;
47
+ id: string;
48
+ };
49
+ thoughtSignature?: string;
50
+ };
51
+
52
+ export type GoogleGenerativeAIFunctionResponsePart = {
53
+ inlineData: { mimeType: string; data: string };
54
+ };
27
55
 
28
56
  export type GoogleGenerativeAIGroundingMetadata = GroundingMetadataSchema;
29
57
 
@@ -31,8 +59,16 @@ export type GoogleGenerativeAIUrlContextMetadata = UrlContextMetadataSchema;
31
59
 
32
60
  export type GoogleGenerativeAISafetyRating = SafetyRatingSchema;
33
61
 
62
+ export type GoogleGenerativeAIPromptFeedback = PromptFeedbackSchema;
63
+
64
+ export type GoogleGenerativeAIUsageMetadata = UsageMetadataSchema;
65
+
34
66
  export interface GoogleGenerativeAIProviderMetadata {
67
+ promptFeedback: GoogleGenerativeAIPromptFeedback | null;
35
68
  groundingMetadata: GoogleGenerativeAIGroundingMetadata | null;
36
69
  urlContextMetadata: GoogleGenerativeAIUrlContextMetadata | null;
37
70
  safetyRatings: GoogleGenerativeAISafetyRating[] | null;
71
+ usageMetadata: GoogleGenerativeAIUsageMetadata | null;
72
+ finishMessage: string | null;
73
+ serviceTier: string | null;
38
74
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AISDKError,
3
- type Experimental_VideoModelV3,
4
- type SharedV3Warning,
3
+ type Experimental_VideoModelV4,
4
+ type SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
7
  combineHeaders,
@@ -50,8 +50,8 @@ interface GoogleGenerativeAIVideoModelConfig {
50
50
  };
51
51
  }
52
52
 
53
- export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV3 {
54
- readonly specificationVersion = 'v3';
53
+ export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV4 {
54
+ readonly specificationVersion = 'v4';
55
55
 
56
56
  get provider(): string {
57
57
  return this.config.provider;
@@ -68,10 +68,10 @@ export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV3 {
68
68
  ) {}
69
69
 
70
70
  async doGenerate(
71
- options: Parameters<Experimental_VideoModelV3['doGenerate']>[0],
72
- ): Promise<Awaited<ReturnType<Experimental_VideoModelV3['doGenerate']>>> {
71
+ options: Parameters<Experimental_VideoModelV4['doGenerate']>[0],
72
+ ): Promise<Awaited<ReturnType<Experimental_VideoModelV4['doGenerate']>>> {
73
73
  const currentDate = this.config._internal?.currentDate?.() ?? new Date();
74
- const warnings: SharedV3Warning[] = [];
74
+ const warnings: SharedV4Warning[] = [];
75
75
 
76
76
  const googleOptions = (await parseProviderOptions({
77
77
  provider: 'google',