@ai-sdk/google 3.0.135 → 3.0.137

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.
@@ -360,6 +360,14 @@ and long coding or agentic tasks.
360
360
  - Complex requests can run for several minutes. Make sure your HTTP client
361
361
  allows read timeouts of at least 15 to 20 minutes.
362
362
 
363
+ **Grounding across requests.** When a response is continued automatically,
364
+ `providerMetadata.google.groundingMetadataPerRequest` contains the grounding
365
+ metadata from each request, in order. An entry is `null` if that request did
366
+ not return grounding metadata. This preserves earlier Search results even if
367
+ the final request returns none, and keeps citation indices scoped to their
368
+ original request. The existing `groundingMetadata` field keeps its current
369
+ behavior; use the per-request array when inspecting a continued response.
370
+
363
371
  **Usage across requests.** Each continued request re-sends the prompt plus all
364
372
  output so far as input, so its prompt token count includes everything
365
373
  generated before it. `usage` is the sum of all requests, which matches what
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "3.0.135",
3
+ "version": "3.0.137",
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",
@@ -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
  );
@@ -428,11 +428,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
428
428
  // the prompt plus all output so far as input, so the first request's
429
429
  // prompt token count is kept separately for context window checks.
430
430
  const continuedParts: ContentPartSchema[] = [];
431
+ const groundingMetadataPerRequest: Array<GroundingMetadataSchema | null> =
432
+ [];
431
433
  let continuedUsageMetadata: GoogleGenerativeAIUsageMetadata | undefined;
432
434
  const firstPromptTokenCount = response.usageMetadata?.promptTokenCount;
433
435
 
434
436
  while (true) {
435
437
  const candidate = response.candidates?.[0];
438
+ groundingMetadataPerRequest.push(candidate?.groundingMetadata ?? null);
436
439
  const continuationToken =
437
440
  candidate?.finishReason === 'CONTINUATION'
438
441
  ? candidate.continuationToken
@@ -642,6 +645,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
642
645
  [providerOptionsName]: {
643
646
  promptFeedback: response.promptFeedback ?? null,
644
647
  groundingMetadata: candidate?.groundingMetadata ?? null,
648
+ ...(groundingMetadataPerRequest.length > 1
649
+ ? { groundingMetadataPerRequest }
650
+ : {}),
645
651
  urlContextMetadata: candidate?.urlContextMetadata ?? null,
646
652
  safetyRatings: candidate?.safetyRatings ?? null,
647
653
  usageMetadata: usageMetadata ?? null,
@@ -695,6 +701,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
695
701
  const { responseHeaders, value: firstResponse } =
696
702
  await streamGenerateContent(args);
697
703
 
704
+ const groundingMetadataPerRequest: Array<GroundingMetadataSchema | null> =
705
+ [];
706
+ let requestGroundingMetadata: GroundingMetadataSchema | null = null;
707
+
698
708
  // Gemini 4 long decode: when a stream reaches the per-request cap while
699
709
  // `maxOutputTokens` budget remains, its last chunk finishes with
700
710
  // `CONTINUATION`. Resend the same request with the continuation token and
@@ -703,12 +713,22 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
703
713
  stream: firstResponse,
704
714
  getContinuationToken: chunk => {
705
715
  const candidate = chunk.candidates?.[0];
716
+ if (candidate?.groundingMetadata != null) {
717
+ requestGroundingMetadata = candidate.groundingMetadata;
718
+ }
706
719
  return candidate?.finishReason === 'CONTINUATION'
707
720
  ? (candidate.continuationToken ?? undefined)
708
721
  : undefined;
709
722
  },
710
- continueStream: async continuationToken =>
711
- (await streamGenerateContent({ ...args, continuationToken })).value,
723
+ continueStream: async continuationToken => {
724
+ const { value } = await streamGenerateContent({
725
+ ...args,
726
+ continuationToken,
727
+ });
728
+ groundingMetadataPerRequest.push(requestGroundingMetadata);
729
+ requestGroundingMetadata = null;
730
+ return value;
731
+ },
712
732
  });
713
733
 
714
734
  let finishReason: LanguageModelV3FinishReason = {
@@ -1293,6 +1313,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
1293
1313
  [providerOptionsName]: {
1294
1314
  promptFeedback,
1295
1315
  groundingMetadata: lastGroundingMetadata,
1316
+ ...(groundingMetadataPerRequest.length > 0
1317
+ ? {
1318
+ groundingMetadataPerRequest: [
1319
+ ...groundingMetadataPerRequest,
1320
+ requestGroundingMetadata,
1321
+ ],
1322
+ }
1323
+ : {}),
1296
1324
  urlContextMetadata: lastUrlContextMetadata,
1297
1325
  safetyRatings: lastSafetyRatings,
1298
1326
  usageMetadata: usage ?? null,
@@ -1545,14 +1573,15 @@ export const getGroundingMetadataSchema = () =>
1545
1573
  .nullish(),
1546
1574
  });
1547
1575
 
1548
- const partialArgSchema = z.object({
1549
- jsonPath: z.string(),
1550
- stringValue: z.string().nullish(),
1551
- numberValue: z.number().nullish(),
1552
- boolValue: z.boolean().nullish(),
1553
- nullValue: z.unknown().nullish(),
1554
- willContinue: z.boolean().nullish(),
1555
- });
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
+ });
1556
1585
 
1557
1586
  const getContentSchema = () =>
1558
1587
  z.object({
@@ -1565,7 +1594,7 @@ const getContentSchema = () =>
1565
1594
  id: z.string().nullish(),
1566
1595
  name: z.string().nullish(),
1567
1596
  args: z.unknown().nullish(),
1568
- partialArgs: z.array(partialArgSchema).nullish(),
1597
+ partialArgs: z.array(partialArgSchema()).nullish(),
1569
1598
  willContinue: z.boolean().nullish(),
1570
1599
  }),
1571
1600
  thoughtSignature: z.string().nullish(),
@@ -1627,35 +1656,37 @@ const getSafetyRatingSchema = () =>
1627
1656
  blocked: z.boolean().nullish(),
1628
1657
  });
1629
1658
 
1630
- const tokenDetailsSchema = z
1631
- .array(
1632
- z
1633
- .object({
1634
- modality: z.string(),
1635
- tokenCount: z.number(),
1636
- })
1637
- .catchall(z.json()),
1638
- )
1639
- .nullish();
1640
-
1641
- const usageSchema = z
1642
- .object({
1643
- cachedContentTokenCount: z.number().nullish(),
1644
- thoughtsTokenCount: z.number().nullish(),
1645
- promptTokenCount: z.number().nullish(),
1646
- candidatesTokenCount: z.number().nullish(),
1647
- toolUsePromptTokenCount: z.number().nullish(),
1648
- totalTokenCount: z.number().nullish(),
1649
- // https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
1650
- trafficType: z.string().nullish(),
1651
- serviceTier: z.string().nullish(),
1652
- // https://ai.google.dev/api/generate-content#Modality
1653
- promptTokensDetails: tokenDetailsSchema,
1654
- cacheTokensDetails: tokenDetailsSchema,
1655
- candidatesTokensDetails: tokenDetailsSchema,
1656
- toolUsePromptTokensDetails: tokenDetailsSchema,
1657
- })
1658
- .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());
1659
1690
 
1660
1691
  // https://ai.google.dev/api/generate-content#UrlRetrievalMetadata
1661
1692
  export const getUrlContextMetadataSchema = () =>
@@ -1687,7 +1718,7 @@ const responseSchema = lazySchema(() =>
1687
1718
  }),
1688
1719
  )
1689
1720
  .nullish(),
1690
- usageMetadata: usageSchema.nullish(),
1721
+ usageMetadata: usageSchema().nullish(),
1691
1722
  promptFeedback: z
1692
1723
  .object({
1693
1724
  blockReason: z.string().nullish(),
@@ -1751,7 +1782,7 @@ const chunkSchema = lazySchema(() =>
1751
1782
  }),
1752
1783
  )
1753
1784
  .nullish(),
1754
- usageMetadata: usageSchema.nullish(),
1785
+ usageMetadata: usageSchema().nullish(),
1755
1786
  promptFeedback: z
1756
1787
  .object({
1757
1788
  blockReason: z.string().nullish(),
@@ -74,6 +74,8 @@ export type GoogleGenerativeAIUsageMetadata = UsageMetadataSchema;
74
74
  export interface GoogleGenerativeAIProviderMetadata {
75
75
  promptFeedback: GoogleGenerativeAIPromptFeedback | null;
76
76
  groundingMetadata: GoogleGenerativeAIGroundingMetadata | null;
77
+ /** Grounding from each automatically continued request, in request order. */
78
+ groundingMetadataPerRequest?: Array<GoogleGenerativeAIGroundingMetadata | null>;
77
79
  urlContextMetadata: GoogleGenerativeAIUrlContextMetadata | null;
78
80
  safetyRatings: GoogleGenerativeAISafetyRating[] | null;
79
81
  usageMetadata: GoogleGenerativeAIUsageMetadata | null;
@@ -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
+ );