@ai-sdk/google 3.0.67 → 3.0.68

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.
@@ -0,0 +1,466 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ /*
9
+ * Zod schemas for the Gemini Interactions API wire format.
10
+ *
11
+ * Helpers are defined as factories (invoked only inside the exported
12
+ * `lazySchema(() => ...)` callbacks) so no `z.object(...)` / `z.union(...)`
13
+ * runs at module import. Schemas are intentionally narrow on the fields the
14
+ * SDK consumes (text + thought) and lenient (`loose()` / `unknown`) on the
15
+ * rest, so subsequent additions can widen without breaking the basic path.
16
+ */
17
+
18
+ const tokenByModalitySchema = () =>
19
+ z
20
+ .object({
21
+ modality: z.string().nullish(),
22
+ tokens: z.number().nullish(),
23
+ })
24
+ .loose();
25
+
26
+ const usageSchema = () =>
27
+ z
28
+ .object({
29
+ total_input_tokens: z.number().nullish(),
30
+ total_output_tokens: z.number().nullish(),
31
+ total_thought_tokens: z.number().nullish(),
32
+ total_cached_tokens: z.number().nullish(),
33
+ total_tool_use_tokens: z.number().nullish(),
34
+ total_tokens: z.number().nullish(),
35
+ input_tokens_by_modality: z.array(tokenByModalitySchema()).nullish(),
36
+ output_tokens_by_modality: z.array(tokenByModalitySchema()).nullish(),
37
+ cached_tokens_by_modality: z.array(tokenByModalitySchema()).nullish(),
38
+ tool_use_tokens_by_modality: z.array(tokenByModalitySchema()).nullish(),
39
+ grounding_tool_count: z
40
+ .array(
41
+ z
42
+ .object({
43
+ type: z.string().nullish(),
44
+ count: z.number().nullish(),
45
+ })
46
+ .loose(),
47
+ )
48
+ .nullish(),
49
+ })
50
+ .loose();
51
+
52
+ export type GoogleInteractionsUsage = z.infer<ReturnType<typeof usageSchema>>;
53
+
54
+ const interactionStatusSchema = () =>
55
+ z.enum([
56
+ 'in_progress',
57
+ 'requires_action',
58
+ 'completed',
59
+ 'failed',
60
+ 'cancelled',
61
+ 'incomplete',
62
+ ]);
63
+
64
+ const annotationSchema = () => {
65
+ const urlCitation = z
66
+ .object({
67
+ type: z.literal('url_citation'),
68
+ url: z.string().nullish(),
69
+ title: z.string().nullish(),
70
+ start_index: z.number().nullish(),
71
+ end_index: z.number().nullish(),
72
+ })
73
+ .loose();
74
+
75
+ const fileCitation = z
76
+ .object({
77
+ type: z.literal('file_citation'),
78
+ file_name: z.string().nullish(),
79
+ document_uri: z.string().nullish(),
80
+ source: z.string().nullish(),
81
+ page_number: z.number().nullish(),
82
+ media_id: z.string().nullish(),
83
+ start_index: z.number().nullish(),
84
+ end_index: z.number().nullish(),
85
+ custom_metadata: z.record(z.string(), z.unknown()).nullish(),
86
+ })
87
+ .loose();
88
+
89
+ const placeCitation = z
90
+ .object({
91
+ type: z.literal('place_citation'),
92
+ name: z.string().nullish(),
93
+ url: z.string().nullish(),
94
+ place_id: z.string().nullish(),
95
+ start_index: z.number().nullish(),
96
+ end_index: z.number().nullish(),
97
+ })
98
+ .loose();
99
+
100
+ return z.union([
101
+ urlCitation,
102
+ fileCitation,
103
+ placeCitation,
104
+ z.object({ type: z.string() }).loose(),
105
+ ]);
106
+ };
107
+
108
+ const thoughtSummaryItemSchema = () =>
109
+ z
110
+ .object({
111
+ type: z.string(),
112
+ text: z.string().nullish(),
113
+ data: z.string().nullish(),
114
+ mime_type: z.string().nullish(),
115
+ })
116
+ .loose();
117
+
118
+ /*
119
+ * Catch-all content block schema. Specific variants (`text`, `thought`,
120
+ * `function_call`, built-in tool call/result) are narrowly typed; unknown
121
+ * block types fall through `loose()`.
122
+ */
123
+ const contentBlockSchema = () => {
124
+ const textContent = z
125
+ .object({
126
+ type: z.literal('text'),
127
+ text: z.string(),
128
+ annotations: z.array(annotationSchema()).nullish(),
129
+ })
130
+ .loose();
131
+
132
+ const thoughtContent = z
133
+ .object({
134
+ type: z.literal('thought'),
135
+ signature: z.string().nullish(),
136
+ summary: z.array(thoughtSummaryItemSchema()).nullish(),
137
+ })
138
+ .loose();
139
+
140
+ const functionCallContent = z
141
+ .object({
142
+ type: z.literal('function_call'),
143
+ id: z.string(),
144
+ name: z.string(),
145
+ arguments: z.record(z.string(), z.unknown()).nullish(),
146
+ signature: z.string().nullish(),
147
+ })
148
+ .loose();
149
+
150
+ const imageContent = z
151
+ .object({
152
+ type: z.literal('image'),
153
+ data: z.string().nullish(),
154
+ mime_type: z.string().nullish(),
155
+ resolution: z.enum(['low', 'medium', 'high', 'ultra_high']).nullish(),
156
+ uri: z.string().nullish(),
157
+ })
158
+ .loose();
159
+
160
+ const builtinToolCall = z
161
+ .object({
162
+ type: z.enum([
163
+ 'google_search_call',
164
+ 'code_execution_call',
165
+ 'url_context_call',
166
+ 'file_search_call',
167
+ 'google_maps_call',
168
+ 'mcp_server_tool_call',
169
+ ]),
170
+ id: z.string(),
171
+ arguments: z.record(z.string(), z.unknown()).nullish(),
172
+ name: z.string().nullish(),
173
+ server_name: z.string().nullish(),
174
+ search_type: z.string().nullish(),
175
+ signature: z.string().nullish(),
176
+ })
177
+ .loose();
178
+
179
+ const builtinToolResult = z
180
+ .object({
181
+ type: z.enum([
182
+ 'google_search_result',
183
+ 'code_execution_result',
184
+ 'url_context_result',
185
+ 'file_search_result',
186
+ 'google_maps_result',
187
+ 'mcp_server_tool_result',
188
+ ]),
189
+ call_id: z.string(),
190
+ result: z.unknown().nullish(),
191
+ is_error: z.boolean().nullish(),
192
+ name: z.string().nullish(),
193
+ server_name: z.string().nullish(),
194
+ signature: z.string().nullish(),
195
+ })
196
+ .loose();
197
+
198
+ return z.union([
199
+ textContent,
200
+ imageContent,
201
+ thoughtContent,
202
+ functionCallContent,
203
+ builtinToolCall,
204
+ builtinToolResult,
205
+ z.object({ type: z.string() }).loose(),
206
+ ]);
207
+ };
208
+
209
+ export type GoogleInteractionsContentBlock = z.infer<
210
+ ReturnType<typeof contentBlockSchema>
211
+ >;
212
+
213
+ export const googleInteractionsResponseSchema = lazySchema(() =>
214
+ zodSchema(
215
+ z
216
+ .object({
217
+ /*
218
+ * `id` is omitted from the response body when `store: false` (fully
219
+ * stateless mode) — there is no server-side interaction record for the
220
+ * client to reference. `nullish` lets the schema accept that shape.
221
+ */
222
+ id: z.string().nullish(),
223
+ created: z.string().nullish(),
224
+ updated: z.string().nullish(),
225
+ status: interactionStatusSchema(),
226
+ model: z.string().nullish(),
227
+ agent: z.string().nullish(),
228
+ outputs: z.array(contentBlockSchema()).nullish(),
229
+ usage: usageSchema().nullish(),
230
+ service_tier: z.string().nullish(),
231
+ previous_interaction_id: z.string().nullish(),
232
+ response_modalities: z.array(z.string()).nullish(),
233
+ })
234
+ .loose(),
235
+ ),
236
+ );
237
+
238
+ export type GoogleInteractionsResponse = InferSchema<
239
+ typeof googleInteractionsResponseSchema
240
+ >;
241
+
242
+ export const googleInteractionsEventSchema = lazySchema(() =>
243
+ zodSchema(
244
+ (() => {
245
+ const status = interactionStatusSchema();
246
+ const annotation = annotationSchema();
247
+ const thoughtSummaryItem = thoughtSummaryItemSchema();
248
+
249
+ const interactionStartEvent = z
250
+ .object({
251
+ event_type: z.literal('interaction.start'),
252
+ event_id: z.string().nullish(),
253
+ interaction: z
254
+ .object({
255
+ /*
256
+ * `id` is omitted when `store: false` (fully stateless mode);
257
+ * see the matching note on `googleInteractionsResponseSchema.id`.
258
+ */
259
+ id: z.string().nullish(),
260
+ created: z.string().nullish(),
261
+ model: z.string().nullish(),
262
+ agent: z.string().nullish(),
263
+ status: status.nullish(),
264
+ })
265
+ .loose(),
266
+ })
267
+ .loose();
268
+
269
+ const contentStartEvent = z
270
+ .object({
271
+ event_type: z.literal('content.start'),
272
+ event_id: z.string().nullish(),
273
+ index: z.number(),
274
+ content: contentBlockSchema(),
275
+ })
276
+ .loose();
277
+
278
+ const contentDeltaText = z
279
+ .object({
280
+ type: z.literal('text'),
281
+ text: z.string(),
282
+ })
283
+ .loose();
284
+
285
+ const contentDeltaThoughtSummary = z
286
+ .object({
287
+ type: z.literal('thought_summary'),
288
+ content: thoughtSummaryItem.nullish(),
289
+ })
290
+ .loose();
291
+
292
+ const contentDeltaThoughtSignature = z
293
+ .object({
294
+ type: z.literal('thought_signature'),
295
+ signature: z.string().nullish(),
296
+ })
297
+ .loose();
298
+
299
+ /*
300
+ * `function_call` content deltas carry the entire call (id + name +
301
+ * arguments) — there is no per-token argument streaming. See js-genai
302
+ * `src/interactions/resources/interactions.ts` `ContentDelta.FunctionCall`.
303
+ */
304
+ const contentDeltaFunctionCall = z
305
+ .object({
306
+ type: z.literal('function_call'),
307
+ id: z.string(),
308
+ name: z.string(),
309
+ arguments: z.record(z.string(), z.unknown()).nullish(),
310
+ signature: z.string().nullish(),
311
+ })
312
+ .loose();
313
+
314
+ const contentDeltaTextAnnotation = z
315
+ .object({
316
+ type: z.literal('text_annotation'),
317
+ annotations: z.array(annotation).nullish(),
318
+ })
319
+ .loose();
320
+
321
+ /*
322
+ * `image` content deltas carry the entire image payload (`data` base64 +
323
+ * `mime_type`, or `uri`) — there is no per-byte streaming. See js-genai
324
+ * `src/interactions/resources/interactions.ts` `ContentDelta.Image`.
325
+ */
326
+ const contentDeltaImage = z
327
+ .object({
328
+ type: z.literal('image'),
329
+ data: z.string().nullish(),
330
+ mime_type: z.string().nullish(),
331
+ resolution: z.enum(['low', 'medium', 'high', 'ultra_high']).nullish(),
332
+ uri: z.string().nullish(),
333
+ })
334
+ .loose();
335
+
336
+ /*
337
+ * Built-in tool call deltas mirror the same shape as their content-block
338
+ * counterparts (full payload per delta -- there is no per-token streaming
339
+ * of arguments). Result deltas carry the populated `result` payload.
340
+ */
341
+ const contentDeltaBuiltinToolCall = z
342
+ .object({
343
+ type: z.enum([
344
+ 'google_search_call',
345
+ 'code_execution_call',
346
+ 'url_context_call',
347
+ 'file_search_call',
348
+ 'google_maps_call',
349
+ 'mcp_server_tool_call',
350
+ ]),
351
+ id: z.string(),
352
+ arguments: z.record(z.string(), z.unknown()).nullish(),
353
+ name: z.string().nullish(),
354
+ server_name: z.string().nullish(),
355
+ search_type: z.string().nullish(),
356
+ signature: z.string().nullish(),
357
+ })
358
+ .loose();
359
+
360
+ const contentDeltaBuiltinToolResult = z
361
+ .object({
362
+ type: z.enum([
363
+ 'google_search_result',
364
+ 'code_execution_result',
365
+ 'url_context_result',
366
+ 'file_search_result',
367
+ 'google_maps_result',
368
+ 'mcp_server_tool_result',
369
+ ]),
370
+ call_id: z.string(),
371
+ result: z.unknown().nullish(),
372
+ is_error: z.boolean().nullish(),
373
+ name: z.string().nullish(),
374
+ server_name: z.string().nullish(),
375
+ signature: z.string().nullish(),
376
+ })
377
+ .loose();
378
+
379
+ const contentDeltaUnknown = z.object({ type: z.string() }).loose();
380
+
381
+ const contentDeltaUnion = z.union([
382
+ contentDeltaText,
383
+ contentDeltaImage,
384
+ contentDeltaThoughtSummary,
385
+ contentDeltaThoughtSignature,
386
+ contentDeltaFunctionCall,
387
+ contentDeltaTextAnnotation,
388
+ contentDeltaBuiltinToolCall,
389
+ contentDeltaBuiltinToolResult,
390
+ contentDeltaUnknown,
391
+ ]);
392
+
393
+ const contentDeltaEvent = z
394
+ .object({
395
+ event_type: z.literal('content.delta'),
396
+ event_id: z.string().nullish(),
397
+ index: z.number(),
398
+ delta: contentDeltaUnion,
399
+ })
400
+ .loose();
401
+
402
+ const contentStopEvent = z
403
+ .object({
404
+ event_type: z.literal('content.stop'),
405
+ event_id: z.string().nullish(),
406
+ index: z.number(),
407
+ })
408
+ .loose();
409
+
410
+ const interactionStatusUpdateEvent = z
411
+ .object({
412
+ event_type: z.literal('interaction.status_update'),
413
+ event_id: z.string().nullish(),
414
+ interaction_id: z.string().nullish(),
415
+ status,
416
+ })
417
+ .loose();
418
+
419
+ const interactionCompleteEvent = z
420
+ .object({
421
+ event_type: z.literal('interaction.complete'),
422
+ event_id: z.string().nullish(),
423
+ interaction: z
424
+ .object({
425
+ id: z.string().nullish(),
426
+ status: status.nullish(),
427
+ usage: usageSchema().nullish(),
428
+ service_tier: z.string().nullish(),
429
+ })
430
+ .loose(),
431
+ })
432
+ .loose();
433
+
434
+ const errorEvent = z
435
+ .object({
436
+ event_type: z.literal('error'),
437
+ event_id: z.string().nullish(),
438
+ error: z
439
+ .object({
440
+ code: z.string().nullish(),
441
+ message: z.string().nullish(),
442
+ })
443
+ .loose()
444
+ .nullish(),
445
+ })
446
+ .loose();
447
+
448
+ const unknownEvent = z.object({ event_type: z.string() }).loose();
449
+
450
+ return z.union([
451
+ interactionStartEvent,
452
+ contentStartEvent,
453
+ contentDeltaEvent,
454
+ contentStopEvent,
455
+ interactionStatusUpdateEvent,
456
+ interactionCompleteEvent,
457
+ errorEvent,
458
+ unknownEvent,
459
+ ]);
460
+ })(),
461
+ ),
462
+ );
463
+
464
+ export type GoogleInteractionsEvent = InferSchema<
465
+ typeof googleInteractionsEventSchema
466
+ >;
@@ -0,0 +1,136 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ /**
9
+ * Type-only union of Gemini model IDs that the Interactions API accepts via
10
+ * `model:`. Mirrors `Model` from `googleapis/js-genai`
11
+ * `src/interactions/resources/interactions.ts`.
12
+ *
13
+ * Kept as a separate type from `GoogleModelId` even though most IDs overlap;
14
+ * the two surfaces (`:generateContent` vs `/interactions`) are independent and
15
+ * may diverge over time.
16
+ */
17
+ export type GoogleInteractionsModelId =
18
+ | 'gemini-2.5-computer-use-preview-10-2025'
19
+ | 'gemini-2.5-flash'
20
+ | 'gemini-2.5-flash-image'
21
+ | 'gemini-2.5-flash-lite'
22
+ | 'gemini-2.5-flash-lite-preview-09-2025'
23
+ | 'gemini-2.5-flash-native-audio-preview-12-2025'
24
+ | 'gemini-2.5-flash-preview-09-2025'
25
+ | 'gemini-2.5-flash-preview-tts'
26
+ | 'gemini-2.5-pro'
27
+ | 'gemini-2.5-pro-preview-tts'
28
+ | 'gemini-3-flash-preview'
29
+ | 'gemini-3-pro-image-preview'
30
+ | 'gemini-3-pro-preview'
31
+ | 'gemini-3.1-pro-preview'
32
+ | 'gemini-3.1-flash-image-preview'
33
+ | 'gemini-3.1-flash-lite-preview'
34
+ | 'gemini-3.1-flash-tts-preview'
35
+ | 'lyria-3-clip-preview'
36
+ | 'lyria-3-pro-preview'
37
+ | (string & {});
38
+
39
+ /**
40
+ * Provider-options schema for `google.interactions(...)` calls. Read from the
41
+ * shared `providerOptions.google.*` namespace (per PRD); per-call options that
42
+ * the AI SDK doesn't natively expose live here.
43
+ *
44
+ * All fields are `.nullish()` per the existing google provider convention.
45
+ */
46
+ export const googleInteractionsLanguageModelOptions = lazySchema(() =>
47
+ zodSchema(
48
+ z.object({
49
+ previousInteractionId: z.string().nullish(),
50
+ store: z.boolean().nullish(),
51
+
52
+ agent: z.string().nullish(),
53
+ agentConfig: z
54
+ .union([
55
+ z
56
+ .object({
57
+ type: z.literal('dynamic'),
58
+ })
59
+ .loose(),
60
+ z.object({
61
+ type: z.literal('deep-research'),
62
+ thinkingSummaries: z.enum(['auto', 'none']).nullish(),
63
+ visualization: z.enum(['off', 'auto']).nullish(),
64
+ collaborativePlanning: z.boolean().nullish(),
65
+ }),
66
+ ])
67
+ .nullish(),
68
+
69
+ thinkingLevel: z.enum(['minimal', 'low', 'medium', 'high']).nullish(),
70
+ thinkingSummaries: z.enum(['auto', 'none']).nullish(),
71
+ imageConfig: z
72
+ .object({
73
+ aspectRatio: z
74
+ .enum([
75
+ '1:1',
76
+ '2:3',
77
+ '3:2',
78
+ '3:4',
79
+ '4:3',
80
+ '4:5',
81
+ '5:4',
82
+ '9:16',
83
+ '16:9',
84
+ '21:9',
85
+ '1:8',
86
+ '8:1',
87
+ '1:4',
88
+ '4:1',
89
+ ])
90
+ .nullish(),
91
+ imageSize: z.enum(['1K', '2K', '4K', '512']).nullish(),
92
+ })
93
+ .nullish(),
94
+ mediaResolution: z
95
+ .enum(['low', 'medium', 'high', 'ultra_high'])
96
+ .nullish(),
97
+
98
+ responseModalities: z
99
+ .array(z.enum(['text', 'image', 'audio', 'video', 'document']))
100
+ .nullish(),
101
+ serviceTier: z.enum(['flex', 'standard', 'priority']).nullish(),
102
+
103
+ /**
104
+ * Alternative to AI SDK `system` message. If both are set, the AI SDK
105
+ * `system` message wins and a warning is emitted.
106
+ */
107
+ systemInstruction: z.string().nullish(),
108
+
109
+ /**
110
+ * Per-block signature for round-tripping `thought.signature` and
111
+ * `function_call.signature` blocks. Set by the SDK on output reasoning /
112
+ * tool-call parts; passed back unchanged on input parts so the API
113
+ * accepts the prior turn.
114
+ */
115
+ signature: z.string().nullish(),
116
+
117
+ /**
118
+ * Set by the SDK on output assistant messages. The converter uses it to
119
+ * decide which messages to drop when compacting under
120
+ * `previousInteractionId`.
121
+ */
122
+ interactionId: z.string().nullish(),
123
+
124
+ /**
125
+ * Maximum time, in milliseconds, to poll a background interaction (agent
126
+ * call) before giving up. Defaults to 30 minutes. Long-running agents
127
+ * such as deep research can take tens of minutes — increase if needed.
128
+ */
129
+ pollingTimeoutMs: z.number().int().positive().nullish(),
130
+ }),
131
+ ),
132
+ );
133
+
134
+ export type GoogleLanguageModelInteractionsOptions = InferSchema<
135
+ typeof googleInteractionsLanguageModelOptions
136
+ >;