@ai-sdk/google 4.0.0-beta.1 → 4.0.0-beta.10

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,4 +1,4 @@
1
- import { LanguageModelV3Usage } from '@ai-sdk/provider';
1
+ import { LanguageModelV4Usage } from '@ai-sdk/provider';
2
2
 
3
3
  export type GoogleGenerativeAIUsageMetadata = {
4
4
  promptTokenCount?: number | null;
@@ -11,7 +11,7 @@ export type GoogleGenerativeAIUsageMetadata = {
11
11
 
12
12
  export function convertGoogleGenerativeAIUsage(
13
13
  usage: GoogleGenerativeAIUsageMetadata | undefined | null,
14
- ): LanguageModelV3Usage {
14
+ ): LanguageModelV4Usage {
15
15
  if (usage == null) {
16
16
  return {
17
17
  inputTokens: {
@@ -1,5 +1,5 @@
1
1
  import {
2
- LanguageModelV3Prompt,
2
+ LanguageModelV4Prompt,
3
3
  UnsupportedFunctionalityError,
4
4
  } from '@ai-sdk/provider';
5
5
  import {
@@ -10,7 +10,7 @@ import {
10
10
  import { convertToBase64 } from '@ai-sdk/provider-utils';
11
11
 
12
12
  export function convertToGoogleGenerativeAIMessages(
13
- prompt: LanguageModelV3Prompt,
13
+ prompt: LanguageModelV4Prompt,
14
14
  options?: { isGemmaModel?: boolean; providerOptionsName?: string },
15
15
  ): GoogleGenerativeAIPrompt {
16
16
  const systemInstructionParts: Array<{ text: string }> = [];
@@ -125,6 +125,9 @@ export function convertToGoogleGenerativeAIMessages(
125
125
  mimeType: part.mediaType,
126
126
  data: convertToBase64(part.data),
127
127
  },
128
+ ...(providerOpts?.thought === true
129
+ ? { thought: true }
130
+ : {}),
128
131
  thoughtSignature,
129
132
  };
130
133
  }
@@ -1,5 +1,5 @@
1
1
  import {
2
- EmbeddingModelV3,
2
+ EmbeddingModelV4,
3
3
  TooManyEmbeddingValuesForCallError,
4
4
  } from '@ai-sdk/provider';
5
5
  import {
@@ -26,8 +26,8 @@ type GoogleGenerativeAIEmbeddingConfig = {
26
26
  fetch?: FetchFunction;
27
27
  };
28
28
 
29
- export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
30
- readonly specificationVersion = 'v3';
29
+ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV4 {
30
+ readonly specificationVersion = 'v4';
31
31
  readonly modelId: GoogleGenerativeAIEmbeddingModelId;
32
32
  readonly maxEmbeddingsPerCall = 2048;
33
33
  readonly supportsParallelCalls = true;
@@ -50,8 +50,8 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
50
50
  headers,
51
51
  abortSignal,
52
52
  providerOptions,
53
- }: Parameters<EmbeddingModelV3['doEmbed']>[0]): Promise<
54
- Awaited<ReturnType<EmbeddingModelV3['doEmbed']>>
53
+ }: Parameters<EmbeddingModelV4['doEmbed']>[0]): Promise<
54
+ Awaited<ReturnType<EmbeddingModelV4['doEmbed']>>
55
55
  > {
56
56
  // Parse provider options
57
57
  const googleOptions = await parseProviderOptions({
@@ -74,8 +74,26 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
74
74
  headers,
75
75
  );
76
76
 
77
- // For single embeddings, use the single endpoint (ratelimits, etc.)
77
+ const multimodalContent = googleOptions?.content;
78
+
79
+ if (
80
+ multimodalContent != null &&
81
+ multimodalContent.length !== values.length
82
+ ) {
83
+ throw new Error(
84
+ `The number of multimodal content entries (${multimodalContent.length}) must match the number of values (${values.length}).`,
85
+ );
86
+ }
87
+
88
+ // For single embeddings, use the single endpoint
78
89
  if (values.length === 1) {
90
+ const valueParts = multimodalContent?.[0];
91
+ const textPart = values[0] ? [{ text: values[0] }] : [];
92
+ const parts =
93
+ valueParts != null
94
+ ? [...textPart, ...valueParts]
95
+ : [{ text: values[0] }];
96
+
79
97
  const {
80
98
  responseHeaders,
81
99
  value: response,
@@ -86,7 +104,7 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
86
104
  body: {
87
105
  model: `models/${this.modelId}`,
88
106
  content: {
89
- parts: [{ text: values[0] }],
107
+ parts,
90
108
  },
91
109
  outputDimensionality: googleOptions?.outputDimensionality,
92
110
  taskType: googleOptions?.taskType,
@@ -107,6 +125,7 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
107
125
  };
108
126
  }
109
127
 
128
+ // For multiple values, use the batch endpoint
110
129
  const {
111
130
  responseHeaders,
112
131
  value: response,
@@ -115,12 +134,22 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
115
134
  url: `${this.config.baseURL}/models/${this.modelId}:batchEmbedContents`,
116
135
  headers: mergedHeaders,
117
136
  body: {
118
- requests: values.map(value => ({
119
- model: `models/${this.modelId}`,
120
- content: { role: 'user', parts: [{ text: value }] },
121
- outputDimensionality: googleOptions?.outputDimensionality,
122
- taskType: googleOptions?.taskType,
123
- })),
137
+ requests: values.map((value, index) => {
138
+ const valueParts = multimodalContent?.[index];
139
+ const textPart = value ? [{ text: value }] : [];
140
+ return {
141
+ model: `models/${this.modelId}`,
142
+ content: {
143
+ role: 'user',
144
+ parts:
145
+ valueParts != null
146
+ ? [...textPart, ...valueParts]
147
+ : [{ text: value }],
148
+ },
149
+ outputDimensionality: googleOptions?.outputDimensionality,
150
+ taskType: googleOptions?.taskType,
151
+ };
152
+ }),
124
153
  },
125
154
  failedResponseHandler: googleFailedResponseHandler,
126
155
  successfulResponseHandler: createJsonResponseHandler(
@@ -7,8 +7,19 @@ import { z } from 'zod/v4';
7
7
 
8
8
  export type GoogleGenerativeAIEmbeddingModelId =
9
9
  | 'gemini-embedding-001'
10
+ | 'gemini-embedding-2-preview'
10
11
  | (string & {});
11
12
 
13
+ const googleEmbeddingContentPartSchema = z.union([
14
+ z.object({ text: z.string() }),
15
+ z.object({
16
+ inlineData: z.object({
17
+ mimeType: z.string(),
18
+ data: z.string(),
19
+ }),
20
+ }),
21
+ ]);
22
+
12
23
  export const googleEmbeddingModelOptions = lazySchema(() =>
13
24
  zodSchema(
14
25
  z.object({
@@ -42,6 +53,19 @@ export const googleEmbeddingModelOptions = lazySchema(() =>
42
53
  'CODE_RETRIEVAL_QUERY',
43
54
  ])
44
55
  .optional(),
56
+
57
+ /**
58
+ * Optional. Per-value multimodal content parts for embedding non-text
59
+ * content (images, video, PDF, audio). Each entry corresponds to the
60
+ * embedding value at the same index and its parts are merged with the
61
+ * text value in the request. Use `null` for entries that are text-only.
62
+ *
63
+ * The array length must match the number of values being embedded. In
64
+ * the case of a single embedding, the array length must be 1.
65
+ */
66
+ content: z
67
+ .array(z.array(googleEmbeddingContentPartSchema).min(1).nullable())
68
+ .optional(),
45
69
  }),
46
70
  ),
47
71
  );
@@ -1,7 +1,7 @@
1
1
  import {
2
- ImageModelV3,
3
- LanguageModelV3Prompt,
4
- SharedV3Warning,
2
+ ImageModelV4,
3
+ LanguageModelV4Prompt,
4
+ SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
7
  combineHeaders,
@@ -37,8 +37,8 @@ interface GoogleGenerativeAIImageModelConfig {
37
37
  };
38
38
  }
39
39
 
40
- export class GoogleGenerativeAIImageModel implements ImageModelV3 {
41
- readonly specificationVersion = 'v3';
40
+ export class GoogleGenerativeAIImageModel implements ImageModelV4 {
41
+ readonly specificationVersion = 'v4';
42
42
 
43
43
  get maxImagesPerCall(): number {
44
44
  if (this.settings.maxImagesPerCall != null) {
@@ -63,8 +63,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
63
63
  ) {}
64
64
 
65
65
  async doGenerate(
66
- options: Parameters<ImageModelV3['doGenerate']>[0],
67
- ): Promise<Awaited<ReturnType<ImageModelV3['doGenerate']>>> {
66
+ options: Parameters<ImageModelV4['doGenerate']>[0],
67
+ ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
68
68
  // Gemini image models use the language model API internally
69
69
  if (isGeminiModel(this.modelId)) {
70
70
  return this.doGenerateGemini(options);
@@ -73,8 +73,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
73
73
  }
74
74
 
75
75
  private async doGenerateImagen(
76
- options: Parameters<ImageModelV3['doGenerate']>[0],
77
- ): Promise<Awaited<ReturnType<ImageModelV3['doGenerate']>>> {
76
+ options: Parameters<ImageModelV4['doGenerate']>[0],
77
+ ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
78
78
  const {
79
79
  prompt,
80
80
  n = 1,
@@ -87,7 +87,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
87
87
  files,
88
88
  mask,
89
89
  } = options;
90
- const warnings: Array<SharedV3Warning> = [];
90
+ const warnings: Array<SharedV4Warning> = [];
91
91
 
92
92
  // Imagen API endpoints do not support image editing
93
93
  if (files != null && files.length > 0) {
@@ -181,8 +181,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
181
181
  }
182
182
 
183
183
  private async doGenerateGemini(
184
- options: Parameters<ImageModelV3['doGenerate']>[0],
185
- ): Promise<Awaited<ReturnType<ImageModelV3['doGenerate']>>> {
184
+ options: Parameters<ImageModelV4['doGenerate']>[0],
185
+ ): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
186
186
  const {
187
187
  prompt,
188
188
  n,
@@ -195,7 +195,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
195
195
  files,
196
196
  mask,
197
197
  } = options;
198
- const warnings: Array<SharedV3Warning> = [];
198
+ const warnings: Array<SharedV4Warning> = [];
199
199
 
200
200
  // Gemini does not support mask-based inpainting
201
201
  if (mask != null) {
@@ -253,7 +253,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
253
253
  }
254
254
  }
255
255
 
256
- const languageModelPrompt: LanguageModelV3Prompt = [
256
+ const languageModelPrompt: LanguageModelV4Prompt = [
257
257
  { role: 'user', content: userContent },
258
258
  ];
259
259
 
@@ -1,14 +1,14 @@
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
+ SharedV4ProviderMetadata,
11
+ SharedV4Warning,
12
12
  } from '@ai-sdk/provider';
13
13
  import {
14
14
  combineHeaders,
@@ -38,7 +38,10 @@ import {
38
38
  GoogleGenerativeAIModelId,
39
39
  googleLanguageModelOptions,
40
40
  } from './google-generative-ai-options';
41
- import { GoogleGenerativeAIContentPart } from './google-generative-ai-prompt';
41
+ import {
42
+ GoogleGenerativeAIContentPart,
43
+ GoogleGenerativeAIProviderMetadata,
44
+ } from './google-generative-ai-prompt';
42
45
  import { prepareTools } from './google-prepare-tools';
43
46
  import { mapGoogleGenerativeAIFinishReason } from './map-google-generative-ai-finish-reason';
44
47
 
@@ -52,11 +55,11 @@ type GoogleGenerativeAIConfig = {
52
55
  /**
53
56
  * The supported URLs for the model.
54
57
  */
55
- supportedUrls?: () => LanguageModelV3['supportedUrls'];
58
+ supportedUrls?: () => LanguageModelV4['supportedUrls'];
56
59
  };
57
60
 
58
- export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
59
- readonly specificationVersion = 'v3';
61
+ export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
62
+ readonly specificationVersion = 'v4';
60
63
 
61
64
  readonly modelId: GoogleGenerativeAIModelId;
62
65
 
@@ -94,8 +97,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
94
97
  tools,
95
98
  toolChoice,
96
99
  providerOptions,
97
- }: LanguageModelV3CallOptions) {
98
- const warnings: SharedV3Warning[] = [];
100
+ }: LanguageModelV4CallOptions) {
101
+ const warnings: SharedV4Warning[] = [];
99
102
 
100
103
  const providerOptionsName = this.config.provider.includes('vertex')
101
104
  ? 'vertex'
@@ -206,8 +209,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
206
209
  }
207
210
 
208
211
  async doGenerate(
209
- options: LanguageModelV3CallOptions,
210
- ): Promise<LanguageModelV3GenerateResult> {
212
+ options: LanguageModelV4CallOptions,
213
+ ): Promise<LanguageModelV4GenerateResult> {
211
214
  const { args, warnings, providerOptionsName } = await this.getArgs(options);
212
215
 
213
216
  const mergedHeaders = combineHeaders(
@@ -232,7 +235,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
232
235
  });
233
236
 
234
237
  const candidate = response.candidates[0];
235
- const content: Array<LanguageModelV3Content> = [];
238
+ const content: Array<LanguageModelV4Content> = [];
236
239
 
237
240
  // map ordered parts to content:
238
241
  const parts = candidate.content?.parts ?? [];
@@ -304,17 +307,23 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
304
307
  : undefined,
305
308
  });
306
309
  } else if ('inlineData' in part) {
310
+ const hasThought = part.thought === true;
311
+ const hasThoughtSignature = !!part.thoughtSignature;
307
312
  content.push({
308
313
  type: 'file' as const,
309
314
  data: part.inlineData.data,
310
315
  mediaType: part.inlineData.mimeType,
311
- providerMetadata: part.thoughtSignature
312
- ? {
313
- [providerOptionsName]: {
314
- thoughtSignature: part.thoughtSignature,
315
- },
316
- }
317
- : undefined,
316
+ providerMetadata:
317
+ hasThought || hasThoughtSignature
318
+ ? {
319
+ [providerOptionsName]: {
320
+ ...(hasThought ? { thought: true } : {}),
321
+ ...(hasThoughtSignature
322
+ ? { thoughtSignature: part.thoughtSignature }
323
+ : {}),
324
+ },
325
+ }
326
+ : undefined,
318
327
  });
319
328
  }
320
329
  }
@@ -349,7 +358,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
349
358
  urlContextMetadata: candidate.urlContextMetadata ?? null,
350
359
  safetyRatings: candidate.safetyRatings ?? null,
351
360
  usageMetadata: usageMetadata ?? null,
352
- },
361
+ finishMessage: candidate.finishMessage ?? null,
362
+ } satisfies GoogleGenerativeAIProviderMetadata,
353
363
  },
354
364
  request: { body: args },
355
365
  response: {
@@ -361,8 +371,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
361
371
  }
362
372
 
363
373
  async doStream(
364
- options: LanguageModelV3CallOptions,
365
- ): Promise<LanguageModelV3StreamResult> {
374
+ options: LanguageModelV4CallOptions,
375
+ ): Promise<LanguageModelV4StreamResult> {
366
376
  const { args, warnings, providerOptionsName } = await this.getArgs(options);
367
377
 
368
378
  const headers = combineHeaders(
@@ -382,12 +392,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
382
392
  fetch: this.config.fetch,
383
393
  });
384
394
 
385
- let finishReason: LanguageModelV3FinishReason = {
395
+ let finishReason: LanguageModelV4FinishReason = {
386
396
  unified: 'other',
387
397
  raw: undefined,
388
398
  };
389
399
  let usage: GoogleGenerativeAIUsageMetadata | undefined = undefined;
390
- let providerMetadata: SharedV3ProviderMetadata | undefined = undefined;
400
+ let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
401
+ let lastGroundingMetadata: GroundingMetadataSchema | null = null;
402
+ let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
391
403
 
392
404
  const generateId = this.config.generateId;
393
405
  let hasToolCalls = false;
@@ -406,7 +418,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
406
418
  stream: response.pipeThrough(
407
419
  new TransformStream<
408
420
  ParseResult<ChunkSchema>,
409
- LanguageModelV3StreamPart
421
+ LanguageModelV4StreamPart
410
422
  >({
411
423
  start(controller) {
412
424
  controller.enqueue({ type: 'stream-start', warnings });
@@ -439,6 +451,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
439
451
 
440
452
  const content = candidate.content;
441
453
 
454
+ if (candidate.groundingMetadata != null) {
455
+ lastGroundingMetadata = candidate.groundingMetadata;
456
+ }
457
+ if (candidate.urlContextMetadata != null) {
458
+ lastUrlContextMetadata = candidate.urlContextMetadata;
459
+ }
460
+
442
461
  const sources = extractSources({
443
462
  groundingMetadata: candidate.groundingMetadata,
444
463
  generateId,
@@ -581,19 +600,24 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
581
600
  currentReasoningBlockId = null;
582
601
  }
583
602
 
584
- // Process file parts inline to preserve order with text
585
- const thoughtSignatureMetadata = part.thoughtSignature
586
- ? {
587
- [providerOptionsName]: {
588
- thoughtSignature: part.thoughtSignature,
589
- },
590
- }
591
- : undefined;
603
+ const hasThought = part.thought === true;
604
+ const hasThoughtSignature = !!part.thoughtSignature;
605
+ const fileMeta =
606
+ hasThought || hasThoughtSignature
607
+ ? {
608
+ [providerOptionsName]: {
609
+ ...(hasThought ? { thought: true } : {}),
610
+ ...(hasThoughtSignature
611
+ ? { thoughtSignature: part.thoughtSignature }
612
+ : {}),
613
+ },
614
+ }
615
+ : undefined;
592
616
  controller.enqueue({
593
617
  type: 'file',
594
618
  mediaType: part.inlineData.mimeType,
595
619
  data: part.inlineData.data,
596
- providerMetadata: thoughtSignatureMetadata,
620
+ providerMetadata: fileMeta,
597
621
  });
598
622
  }
599
623
  }
@@ -651,19 +675,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
651
675
  providerMetadata = {
652
676
  [providerOptionsName]: {
653
677
  promptFeedback: value.promptFeedback ?? null,
654
- groundingMetadata: candidate.groundingMetadata ?? null,
655
- urlContextMetadata: candidate.urlContextMetadata ?? null,
678
+ groundingMetadata: lastGroundingMetadata,
679
+ urlContextMetadata: lastUrlContextMetadata,
656
680
  safetyRatings: candidate.safetyRatings ?? null,
657
- },
681
+ usageMetadata: usageMetadata ?? null,
682
+ finishMessage: candidate.finishMessage ?? null,
683
+ } satisfies GoogleGenerativeAIProviderMetadata,
658
684
  };
659
- if (usageMetadata != null) {
660
- (
661
- providerMetadata[providerOptionsName] as Record<
662
- string,
663
- unknown
664
- >
665
- ).usageMetadata = usageMetadata;
666
- }
667
685
  }
668
686
  },
669
687
 
@@ -737,12 +755,12 @@ function extractSources({
737
755
  }: {
738
756
  groundingMetadata: GroundingMetadataSchema | undefined | null;
739
757
  generateId: () => string;
740
- }): undefined | LanguageModelV3Source[] {
758
+ }): undefined | LanguageModelV4Source[] {
741
759
  if (!groundingMetadata?.groundingChunks) {
742
760
  return undefined;
743
761
  }
744
762
 
745
- const sources: LanguageModelV3Source[] = [];
763
+ const sources: LanguageModelV4Source[] = [];
746
764
 
747
765
  for (const chunk of groundingMetadata.groundingChunks) {
748
766
  if (chunk.web != null) {
@@ -926,6 +944,7 @@ const getContentSchema = () =>
926
944
  mimeType: z.string(),
927
945
  data: z.string(),
928
946
  }),
947
+ thought: z.boolean().nullish(),
929
948
  thoughtSignature: z.string().nullish(),
930
949
  }),
931
950
  z.object({
@@ -991,6 +1010,7 @@ const responseSchema = lazySchema(() =>
991
1010
  z.object({
992
1011
  content: getContentSchema().nullish().or(z.object({}).strict()),
993
1012
  finishReason: z.string().nullish(),
1013
+ finishMessage: z.string().nullish(),
994
1014
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
995
1015
  groundingMetadata: getGroundingMetadataSchema().nullish(),
996
1016
  urlContextMetadata: getUrlContextMetadataSchema().nullish(),
@@ -1026,6 +1046,14 @@ export type SafetyRatingSchema = NonNullable<
1026
1046
  InferSchema<typeof responseSchema>['candidates'][number]['safetyRatings']
1027
1047
  >[number];
1028
1048
 
1049
+ export type PromptFeedbackSchema = NonNullable<
1050
+ InferSchema<typeof responseSchema>['promptFeedback']
1051
+ >;
1052
+
1053
+ export type UsageMetadataSchema = NonNullable<
1054
+ InferSchema<typeof responseSchema>['usageMetadata']
1055
+ >;
1056
+
1029
1057
  // limited version of the schema, focussed on what is needed for the implementation
1030
1058
  // this approach limits breakages when the API changes and increases efficiency
1031
1059
  const chunkSchema = lazySchema(() =>
@@ -1036,6 +1064,7 @@ const chunkSchema = lazySchema(() =>
1036
1064
  z.object({
1037
1065
  content: getContentSchema().nullish(),
1038
1066
  finishReason: z.string().nullish(),
1067
+ finishMessage: z.string().nullish(),
1039
1068
  safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
1040
1069
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1041
1070
  urlContextMetadata: getUrlContextMetadataSchema().nullish(),
@@ -1,6 +1,8 @@
1
1
  import {
2
2
  GroundingMetadataSchema,
3
+ PromptFeedbackSchema,
3
4
  UrlContextMetadataSchema,
5
+ UsageMetadataSchema,
4
6
  } from './google-generative-ai-language-model';
5
7
  import { type SafetyRatingSchema } from './google-generative-ai-language-model';
6
8
 
@@ -31,8 +33,15 @@ export type GoogleGenerativeAIUrlContextMetadata = UrlContextMetadataSchema;
31
33
 
32
34
  export type GoogleGenerativeAISafetyRating = SafetyRatingSchema;
33
35
 
36
+ export type GoogleGenerativeAIPromptFeedback = PromptFeedbackSchema;
37
+
38
+ export type GoogleGenerativeAIUsageMetadata = UsageMetadataSchema;
39
+
34
40
  export interface GoogleGenerativeAIProviderMetadata {
41
+ promptFeedback: GoogleGenerativeAIPromptFeedback | null;
35
42
  groundingMetadata: GoogleGenerativeAIGroundingMetadata | null;
36
43
  urlContextMetadata: GoogleGenerativeAIUrlContextMetadata | null;
37
44
  safetyRatings: GoogleGenerativeAISafetyRating[] | null;
45
+ usageMetadata: GoogleGenerativeAIUsageMetadata | null;
46
+ finishMessage: string | null;
38
47
  }
@@ -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',
@@ -1,6 +1,6 @@
1
1
  import {
2
- LanguageModelV3CallOptions,
3
- SharedV3Warning,
2
+ LanguageModelV4CallOptions,
3
+ SharedV4Warning,
4
4
  UnsupportedFunctionalityError,
5
5
  } from '@ai-sdk/provider';
6
6
  import { convertJSONSchemaToOpenAPISchema } from './convert-json-schema-to-openapi-schema';
@@ -11,8 +11,8 @@ export function prepareTools({
11
11
  toolChoice,
12
12
  modelId,
13
13
  }: {
14
- tools: LanguageModelV3CallOptions['tools'];
15
- toolChoice?: LanguageModelV3CallOptions['toolChoice'];
14
+ tools: LanguageModelV4CallOptions['tools'];
15
+ toolChoice?: LanguageModelV4CallOptions['toolChoice'];
16
16
  modelId: GoogleGenerativeAIModelId;
17
17
  }): {
18
18
  tools:
@@ -35,12 +35,12 @@ export function prepareTools({
35
35
  allowedFunctionNames?: string[];
36
36
  };
37
37
  };
38
- toolWarnings: SharedV3Warning[];
38
+ toolWarnings: SharedV4Warning[];
39
39
  } {
40
40
  // when the tools array is empty, change it to undefined to prevent errors:
41
41
  tools = tools?.length ? tools : undefined;
42
42
 
43
- const toolWarnings: SharedV3Warning[] = [];
43
+ const toolWarnings: SharedV4Warning[] = [];
44
44
 
45
45
  const isLatest = (
46
46
  [