@ai-sdk/google 3.0.136 → 3.0.138

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "3.0.136",
3
+ "version": "3.0.138",
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.61"
40
+ "@ai-sdk/provider-utils": "4.0.62"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -109,8 +109,18 @@ function convertJSONSchemaDefinition(
109
109
  if (nonNullTypes.length === 0) {
110
110
  // Only null type
111
111
  result.type = 'null';
112
+ } else if (nonNullTypes.length === 1) {
113
+ // A single type stays a plain node so sibling keywords (items,
114
+ // format, ...) remain valid: Gemini rejects fields beside anyOf and
115
+ // items on a non-array node.
116
+ result.type = nonNullTypes[0];
117
+ if (hasNull) {
118
+ result.nullable = true;
119
+ }
112
120
  } else {
113
- // One or more non-null types: always use anyOf
121
+ // Multiple non-null types: use anyOf. Type-specific keywords
122
+ // (items, format, ...) still land beside it, which Gemini rejects;
123
+ // splitting them per branch is not handled yet.
114
124
  result.anyOf = nonNullTypes.map(t => ({ type: t }));
115
125
  if (hasNull) {
116
126
  result.nullable = true;
@@ -10,21 +10,22 @@ export type GoogleGenerativeAIEmbeddingModelId =
10
10
  | 'gemini-embedding-2-preview'
11
11
  | (string & {});
12
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(),
13
+ const googleEmbeddingContentPartSchema = () =>
14
+ z.union([
15
+ z.object({ text: z.string() }),
16
+ z.object({
17
+ inlineData: z.object({
18
+ mimeType: z.string(),
19
+ data: z.string(),
20
+ }),
19
21
  }),
20
- }),
21
- z.object({
22
- fileData: z.object({
23
- fileUri: z.string(),
24
- mimeType: z.string(),
22
+ z.object({
23
+ fileData: z.object({
24
+ fileUri: z.string(),
25
+ mimeType: z.string(),
26
+ }),
25
27
  }),
26
- }),
27
- ]);
28
+ ]);
28
29
 
29
30
  export const googleEmbeddingModelOptions = lazySchema(() =>
30
31
  zodSchema(
@@ -70,7 +71,7 @@ export const googleEmbeddingModelOptions = lazySchema(() =>
70
71
  * the case of a single embedding, the array length must be 1.
71
72
  */
72
73
  content: z
73
- .array(z.array(googleEmbeddingContentPartSchema).min(1).nullable())
74
+ .array(z.array(googleEmbeddingContentPartSchema()).min(1).nullable())
74
75
  .optional(),
75
76
  }),
76
77
  ),
@@ -418,7 +418,7 @@ const googleImageModelOptionsSchema = lazySchema(() =>
418
418
  * dedicated escape hatch for grounding image generation the same way
419
419
  * `generateText` does.
420
420
  */
421
- googleSearch: googleSearchToolArgsBaseSchema.optional(),
421
+ googleSearch: googleSearchToolArgsBaseSchema().optional(),
422
422
  }),
423
423
  ),
424
424
  );
@@ -1573,14 +1573,15 @@ export const getGroundingMetadataSchema = () =>
1573
1573
  .nullish(),
1574
1574
  });
1575
1575
 
1576
- const partialArgSchema = z.object({
1577
- jsonPath: z.string(),
1578
- stringValue: z.string().nullish(),
1579
- numberValue: z.number().nullish(),
1580
- boolValue: z.boolean().nullish(),
1581
- nullValue: z.unknown().nullish(),
1582
- willContinue: z.boolean().nullish(),
1583
- });
1576
+ const partialArgSchema = () =>
1577
+ z.object({
1578
+ jsonPath: z.string(),
1579
+ stringValue: z.string().nullish(),
1580
+ numberValue: z.number().nullish(),
1581
+ boolValue: z.boolean().nullish(),
1582
+ nullValue: z.unknown().nullish(),
1583
+ willContinue: z.boolean().nullish(),
1584
+ });
1584
1585
 
1585
1586
  const getContentSchema = () =>
1586
1587
  z.object({
@@ -1593,7 +1594,7 @@ const getContentSchema = () =>
1593
1594
  id: z.string().nullish(),
1594
1595
  name: z.string().nullish(),
1595
1596
  args: z.unknown().nullish(),
1596
- partialArgs: z.array(partialArgSchema).nullish(),
1597
+ partialArgs: z.array(partialArgSchema()).nullish(),
1597
1598
  willContinue: z.boolean().nullish(),
1598
1599
  }),
1599
1600
  thoughtSignature: z.string().nullish(),
@@ -1655,35 +1656,37 @@ const getSafetyRatingSchema = () =>
1655
1656
  blocked: z.boolean().nullish(),
1656
1657
  });
1657
1658
 
1658
- const tokenDetailsSchema = z
1659
- .array(
1660
- z
1661
- .object({
1662
- modality: z.string(),
1663
- tokenCount: z.number(),
1664
- })
1665
- .catchall(z.json()),
1666
- )
1667
- .nullish();
1668
-
1669
- const usageSchema = z
1670
- .object({
1671
- cachedContentTokenCount: z.number().nullish(),
1672
- thoughtsTokenCount: z.number().nullish(),
1673
- promptTokenCount: z.number().nullish(),
1674
- candidatesTokenCount: z.number().nullish(),
1675
- toolUsePromptTokenCount: z.number().nullish(),
1676
- totalTokenCount: z.number().nullish(),
1677
- // https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
1678
- trafficType: z.string().nullish(),
1679
- serviceTier: z.string().nullish(),
1680
- // https://ai.google.dev/api/generate-content#Modality
1681
- promptTokensDetails: tokenDetailsSchema,
1682
- cacheTokensDetails: tokenDetailsSchema,
1683
- candidatesTokensDetails: tokenDetailsSchema,
1684
- toolUsePromptTokensDetails: tokenDetailsSchema,
1685
- })
1686
- .catchall(z.json());
1659
+ const tokenDetailsSchema = () =>
1660
+ z
1661
+ .array(
1662
+ z
1663
+ .object({
1664
+ modality: z.string(),
1665
+ tokenCount: z.number(),
1666
+ })
1667
+ .catchall(z.json()),
1668
+ )
1669
+ .nullish();
1670
+
1671
+ const usageSchema = () =>
1672
+ z
1673
+ .object({
1674
+ cachedContentTokenCount: z.number().nullish(),
1675
+ thoughtsTokenCount: z.number().nullish(),
1676
+ promptTokenCount: z.number().nullish(),
1677
+ candidatesTokenCount: z.number().nullish(),
1678
+ toolUsePromptTokenCount: z.number().nullish(),
1679
+ totalTokenCount: z.number().nullish(),
1680
+ // https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
1681
+ trafficType: z.string().nullish(),
1682
+ serviceTier: z.string().nullish(),
1683
+ // https://ai.google.dev/api/generate-content#Modality
1684
+ promptTokensDetails: tokenDetailsSchema(),
1685
+ cacheTokensDetails: tokenDetailsSchema(),
1686
+ candidatesTokensDetails: tokenDetailsSchema(),
1687
+ toolUsePromptTokensDetails: tokenDetailsSchema(),
1688
+ })
1689
+ .catchall(z.json());
1687
1690
 
1688
1691
  // https://ai.google.dev/api/generate-content#UrlRetrievalMetadata
1689
1692
  export const getUrlContextMetadataSchema = () =>
@@ -1715,7 +1718,7 @@ const responseSchema = lazySchema(() =>
1715
1718
  }),
1716
1719
  )
1717
1720
  .nullish(),
1718
- usageMetadata: usageSchema.nullish(),
1721
+ usageMetadata: usageSchema().nullish(),
1719
1722
  promptFeedback: z
1720
1723
  .object({
1721
1724
  blockReason: z.string().nullish(),
@@ -1779,7 +1782,7 @@ const chunkSchema = lazySchema(() =>
1779
1782
  }),
1780
1783
  )
1781
1784
  .nullish(),
1782
- usageMetadata: usageSchema.nullish(),
1785
+ usageMetadata: usageSchema().nullish(),
1783
1786
  promptFeedback: z
1784
1787
  .object({
1785
1788
  blockReason: z.string().nullish(),
@@ -408,36 +408,40 @@ export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV3 {
408
408
  }
409
409
  }
410
410
 
411
- const googleOperationSchema = z.object({
412
- name: z.string().nullish(),
413
- done: z.boolean().nullish(),
414
- error: z
415
- .object({
416
- code: z.number().nullish(),
417
- message: z.string(),
418
- status: z.string().nullish(),
419
- })
420
- .nullish(),
421
- response: z
422
- .object({
423
- generateVideoResponse: z
411
+ const googleOperationSchema = lazySchema(() =>
412
+ zodSchema(
413
+ z.object({
414
+ name: z.string().nullish(),
415
+ done: z.boolean().nullish(),
416
+ error: z
417
+ .object({
418
+ code: z.number().nullish(),
419
+ message: z.string(),
420
+ status: z.string().nullish(),
421
+ })
422
+ .nullish(),
423
+ response: z
424
424
  .object({
425
- generatedSamples: z
426
- .array(
427
- z.object({
428
- video: z
429
- .object({
430
- uri: z.string().nullish(),
431
- })
432
- .nullish(),
433
- }),
434
- )
425
+ generateVideoResponse: z
426
+ .object({
427
+ generatedSamples: z
428
+ .array(
429
+ z.object({
430
+ video: z
431
+ .object({
432
+ uri: z.string().nullish(),
433
+ })
434
+ .nullish(),
435
+ }),
436
+ )
437
+ .nullish(),
438
+ })
435
439
  .nullish(),
436
440
  })
437
441
  .nullish(),
438
- })
439
- .nullish(),
440
- });
442
+ }),
443
+ ),
444
+ );
441
445
 
442
446
  const googleVideoModelOptionsSchema = lazySchema(() =>
443
447
  zodSchema(
@@ -6,40 +6,43 @@ import {
6
6
  import { z } from 'zod/v4';
7
7
 
8
8
  /** Tool to retrieve knowledge from the File Search Stores. */
9
- const fileSearchArgsBaseSchema = z
10
- .object({
11
- /** The names of the file_search_stores to retrieve from.
12
- * Example: `fileSearchStores/my-file-search-store-123`
13
- */
14
- fileSearchStoreNames: z
15
- .array(z.string())
16
- .describe(
17
- 'The names of the file_search_stores to retrieve from. Example: `fileSearchStores/my-file-search-store-123`',
18
- ),
19
- /** The number of file search retrieval chunks to retrieve. */
20
- topK: z
21
- .number()
22
- .int()
23
- .positive()
24
- .describe('The number of file search retrieval chunks to retrieve.')
25
- .optional(),
9
+ const fileSearchArgsBaseSchema = () =>
10
+ z
11
+ .object({
12
+ /** The names of the file_search_stores to retrieve from.
13
+ * Example: `fileSearchStores/my-file-search-store-123`
14
+ */
15
+ fileSearchStoreNames: z
16
+ .array(z.string())
17
+ .describe(
18
+ 'The names of the file_search_stores to retrieve from. Example: `fileSearchStores/my-file-search-store-123`',
19
+ ),
20
+ /** The number of file search retrieval chunks to retrieve. */
21
+ topK: z
22
+ .number()
23
+ .int()
24
+ .positive()
25
+ .describe('The number of file search retrieval chunks to retrieve.')
26
+ .optional(),
26
27
 
27
- /** Metadata filter to apply to the file search retrieval documents.
28
- * See https://google.aip.dev/160 for the syntax of the filter expression.
29
- */
30
- metadataFilter: z
31
- .string()
32
- .describe(
33
- 'Metadata filter to apply to the file search retrieval documents. See https://google.aip.dev/160 for the syntax of the filter expression.',
34
- )
35
- .optional(),
36
- })
37
- .passthrough();
28
+ /** Metadata filter to apply to the file search retrieval documents.
29
+ * See https://google.aip.dev/160 for the syntax of the filter expression.
30
+ */
31
+ metadataFilter: z
32
+ .string()
33
+ .describe(
34
+ 'Metadata filter to apply to the file search retrieval documents. See https://google.aip.dev/160 for the syntax of the filter expression.',
35
+ )
36
+ .optional(),
37
+ })
38
+ .passthrough();
38
39
 
39
- export type GoogleFileSearchToolArgs = z.infer<typeof fileSearchArgsBaseSchema>;
40
+ export type GoogleFileSearchToolArgs = z.infer<
41
+ ReturnType<typeof fileSearchArgsBaseSchema>
42
+ >;
40
43
 
41
44
  const fileSearchArgsSchema = lazySchema(() =>
42
- zodSchema(fileSearchArgsBaseSchema),
45
+ zodSchema(fileSearchArgsBaseSchema()),
43
46
  );
44
47
 
45
48
  export const fileSearch = createProviderToolFactory<
@@ -9,30 +9,31 @@ import { z } from 'zod/v4';
9
9
  // https://ai.google.dev/api/generate-content#GroundingSupport
10
10
  // https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/grounding-with-google-search
11
11
 
12
- export const googleSearchToolArgsBaseSchema = z
13
- .object({
14
- searchTypes: z
15
- .object({
16
- webSearch: z.object({}).optional(),
17
- imageSearch: z.object({}).optional(),
18
- })
19
- .optional(),
12
+ export const googleSearchToolArgsBaseSchema = () =>
13
+ z
14
+ .object({
15
+ searchTypes: z
16
+ .object({
17
+ webSearch: z.object({}).optional(),
18
+ imageSearch: z.object({}).optional(),
19
+ })
20
+ .optional(),
20
21
 
21
- timeRangeFilter: z
22
- .object({
23
- startTime: z.string(),
24
- endTime: z.string(),
25
- })
26
- .optional(),
27
- })
28
- .passthrough();
22
+ timeRangeFilter: z
23
+ .object({
24
+ startTime: z.string(),
25
+ endTime: z.string(),
26
+ })
27
+ .optional(),
28
+ })
29
+ .passthrough();
29
30
 
30
31
  export type GoogleSearchToolArgs = z.infer<
31
- typeof googleSearchToolArgsBaseSchema
32
+ ReturnType<typeof googleSearchToolArgsBaseSchema>
32
33
  >;
33
34
 
34
35
  const googleSearchToolArgsSchema = lazySchema(() =>
35
- zodSchema(googleSearchToolArgsBaseSchema),
36
+ zodSchema(googleSearchToolArgsBaseSchema()),
36
37
  );
37
38
 
38
39
  export const googleSearch = createProviderToolFactory<{}, GoogleSearchToolArgs>(
@@ -1,3 +1,8 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
1
6
  import { z } from 'zod/v4';
2
7
 
3
8
  export type GoogleTranscriptionModelId =
@@ -11,41 +16,45 @@ export type GoogleTranscriptionModelId =
11
16
  * The live variant (`gemini-3.5-transcribe-live`) requires streaming
12
17
  * transcription, which is only available in AI SDK v7.
13
18
  */
14
- export const googleTranscriptionModelOptions = z.object({
15
- /**
16
- * BCP-47 language codes providing hints about the languages present in the
17
- * audio. If omitted or empty, defaults to automatic language detection.
18
- */
19
- languageCodes: z.array(z.string()).optional(),
19
+ export const googleTranscriptionModelOptions = lazySchema(() =>
20
+ zodSchema(
21
+ z.object({
22
+ /**
23
+ * BCP-47 language codes providing hints about the languages present in the
24
+ * audio. If omitted or empty, defaults to automatic language detection.
25
+ */
26
+ languageCodes: z.array(z.string()).optional(),
20
27
 
21
- /**
22
- * Custom vocabulary phrases, which bias the speech recognition model
23
- * toward recognizing specific terms.
24
- */
25
- customVocabulary: z.array(z.string()).optional(),
28
+ /**
29
+ * Custom vocabulary phrases, which bias the speech recognition model
30
+ * toward recognizing specific terms.
31
+ */
32
+ customVocabulary: z.array(z.string()).optional(),
26
33
 
27
- /**
28
- * Enables word-level timestamp generation.
29
- */
30
- wordTimestamp: z.boolean().optional(),
34
+ /**
35
+ * Enables word-level timestamp generation.
36
+ */
37
+ wordTimestamp: z.boolean().optional(),
31
38
 
32
- /**
33
- * Enables speaker diarization.
34
- */
35
- diarization: z.boolean().optional(),
39
+ /**
40
+ * Enables speaker diarization.
41
+ */
42
+ diarization: z.boolean().optional(),
36
43
 
37
- /**
38
- * Transcription output formatting mode.
39
- *
40
- * - `VERBATIM` (default): exact literal transcript preserving filler
41
- * words, repetitions, and false starts.
42
- * - `SMART`: cleans up and structures the transcript in real time —
43
- * disfluency removal, inline self-corrections, structured formatting
44
- * (lists, numbers, dates, paragraph breaks), and grammar/casing polish.
45
- */
46
- mode: z.enum(['SMART', 'VERBATIM']).optional(),
47
- });
44
+ /**
45
+ * Transcription output formatting mode.
46
+ *
47
+ * - `VERBATIM` (default): exact literal transcript preserving filler
48
+ * words, repetitions, and false starts.
49
+ * - `SMART`: cleans up and structures the transcript in real time —
50
+ * disfluency removal, inline self-corrections, structured formatting
51
+ * (lists, numbers, dates, paragraph breaks), and grammar/casing polish.
52
+ */
53
+ mode: z.enum(['SMART', 'VERBATIM']).optional(),
54
+ }),
55
+ ),
56
+ );
48
57
 
49
- export type GoogleTranscriptionModelOptions = z.infer<
58
+ export type GoogleTranscriptionModelOptions = InferSchema<
50
59
  typeof googleTranscriptionModelOptions
51
60
  >;
@@ -5,6 +5,8 @@ import {
5
5
  type TranscriptionModelV3,
6
6
  } from '@ai-sdk/provider';
7
7
  import {
8
+ lazySchema,
9
+ zodSchema,
8
10
  combineHeaders,
9
11
  convertToBase64,
10
12
  createJsonResponseHandler,
@@ -211,33 +213,38 @@ function parseOffsetSeconds(
211
213
  return Number.isFinite(parsed) ? parsed : undefined;
212
214
  }
213
215
 
214
- const googleInteractionsWordAnnotationSchema = z.object({
215
- type: z.string().nullish(),
216
- text: z.string().nullish(),
217
- speaker: z.string().nullish(),
218
- start_offset: z.string().nullish(),
219
- end_offset: z.string().nullish(),
220
- });
221
-
222
- const googleInteractionsTranscriptionResponseSchema = z.object({
223
- status: z.string().nullish(),
224
- steps: z
225
- .array(
226
- z.object({
227
- type: z.string().nullish(),
228
- content: z
229
- .array(
230
- z.object({
231
- type: z.string().nullish(),
232
- text: z.string().nullish(),
233
- annotations: z
234
- .array(googleInteractionsWordAnnotationSchema)
235
- .nullish(),
236
- }),
237
- )
238
- .nullish(),
239
- }),
240
- )
241
- .nullish(),
242
- usage: z.record(z.string(), z.unknown()).nullish(),
243
- });
216
+ const googleInteractionsWordAnnotationSchema = () =>
217
+ z.object({
218
+ type: z.string().nullish(),
219
+ text: z.string().nullish(),
220
+ speaker: z.string().nullish(),
221
+ start_offset: z.string().nullish(),
222
+ end_offset: z.string().nullish(),
223
+ });
224
+
225
+ const googleInteractionsTranscriptionResponseSchema = lazySchema(() =>
226
+ zodSchema(
227
+ z.object({
228
+ status: z.string().nullish(),
229
+ steps: z
230
+ .array(
231
+ z.object({
232
+ type: z.string().nullish(),
233
+ content: z
234
+ .array(
235
+ z.object({
236
+ type: z.string().nullish(),
237
+ text: z.string().nullish(),
238
+ annotations: z
239
+ .array(googleInteractionsWordAnnotationSchema())
240
+ .nullish(),
241
+ }),
242
+ )
243
+ .nullish(),
244
+ }),
245
+ )
246
+ .nullish(),
247
+ usage: z.record(z.string(), z.unknown()).nullish(),
248
+ }),
249
+ ),
250
+ );