@ai-sdk/google 4.0.65 → 4.0.67

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.
@@ -1065,65 +1065,16 @@ The following Zod features are known to not work with Google:
1065
1065
  available provider model ID as a string if needed.
1066
1066
  </Note>
1067
1067
 
1068
- ### Text Batches
1068
+ ### Batch
1069
1069
 
1070
1070
  <Note type="warning">
1071
- Text batch support is experimental and the API may change in patch releases.
1071
+ Batch support is experimental and the API may change in patch releases.
1072
1072
  </Note>
1073
1073
 
1074
- The Google provider supports asynchronous text generation through the
1075
- [Gemini Batch API](https://ai.google.dev/gemini-api/docs/batch-api). Use the
1076
- experimental text batch APIs to start a batch, poll its status, and stream its
1077
- results:
1078
-
1079
- ```ts
1080
- import { google } from '@ai-sdk/google';
1081
- import {
1082
- experimental_getBatchResults as getBatchResults,
1083
- experimental_getBatchStatus as getBatchStatus,
1084
- experimental_startBatch as startBatch,
1085
- } from 'ai';
1086
- import { setTimeout } from 'node:timers/promises';
1087
-
1088
- const model = 'gemini-3.6-flash';
1089
-
1090
- const batch = await startBatch({
1091
- provider: google,
1092
- requests: [
1093
- {
1094
- id: 'capital-france',
1095
- type: 'text',
1096
- model,
1097
- prompt: 'What is the capital of France?',
1098
- },
1099
- {
1100
- id: 'capital-germany',
1101
- type: 'text',
1102
- model,
1103
- prompt: 'What is the capital of Germany?',
1104
- },
1105
- ],
1106
- });
1107
-
1108
- let status = batch.status;
1109
- while (status === 'pending') {
1110
- await setTimeout(60_000);
1111
- ({ status } = await getBatchStatus({ provider: google, batch }));
1112
- }
1113
-
1114
- for await (const item of getBatchResults({ provider: google, batch })) {
1115
- if (item.status === 'succeeded') {
1116
- console.log(item.id, item.text);
1117
- } else {
1118
- console.error(item.id, item.error);
1119
- }
1120
- }
1121
- ```
1122
-
1123
- `startBatch` returns a serializable batch reference. Persist this reference
1124
- to check the batch status or retrieve its results from another process. Results
1125
- can arrive in a different order from the input requests, so match each result by
1126
- its `id`.
1074
+ The Google provider supports asynchronous text generation through the [Gemini
1075
+ Batch API](https://ai.google.dev/gemini-api/docs/batch-api). Pass the Google
1076
+ provider to the AI SDK's [Batch](/docs/ai-sdk-core/batch)
1077
+ API for the complete workflow, including polling, persistence, and result handling.
1127
1078
 
1128
1079
  Each request specifies its `type` and `model`. Google requires every text
1129
1080
  request in a batch to use the same model and throws before submission when the
@@ -1134,6 +1085,11 @@ models differ.
1134
1085
  You can pass a `webhookUrl` to receive a notification when the batch reaches a terminal state:
1135
1086
 
1136
1087
  ```ts
1088
+ import { google } from '@ai-sdk/google';
1089
+ import { experimental_startBatch as startBatch } from 'ai';
1090
+
1091
+ const model = 'gemini-3.6-flash';
1092
+
1137
1093
  const batch = await startBatch({
1138
1094
  provider: google,
1139
1095
  requests: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/google",
3
- "version": "4.0.65",
3
+ "version": "4.0.67",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -35,8 +35,8 @@
35
35
  }
36
36
  },
37
37
  "dependencies": {
38
- "@ai-sdk/provider": "4.0.11",
39
- "@ai-sdk/provider-utils": "5.0.37"
38
+ "@ai-sdk/provider": "4.0.13",
39
+ "@ai-sdk/provider-utils": "5.0.39"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ai-sdk/test-server": "2.0.1",
@@ -2,8 +2,11 @@ import {
2
2
  InvalidArgumentError,
3
3
  InvalidResponseDataError,
4
4
  type Experimental_BatchV4 as BatchV4,
5
+ type Experimental_BatchV4CancelResult as BatchV4CancelResult,
5
6
  type Experimental_BatchV4Error as BatchV4Error,
6
7
  type Experimental_BatchV4ItemResult as BatchV4ItemResult,
8
+ type Experimental_BatchV4ListOptions as BatchV4ListOptions,
9
+ type Experimental_BatchV4ListResult as BatchV4ListResult,
7
10
  type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
8
11
  type Experimental_BatchV4StartResult as BatchV4StartResult,
9
12
  type Experimental_BatchV4Status as BatchV4Status,
@@ -76,26 +79,40 @@ const googleBatchOutputSchema = z.object({
76
79
  .nullish(),
77
80
  });
78
81
 
82
+ const googleBatchOperationZodSchema = () =>
83
+ z.object({
84
+ name: z.string(),
85
+ metadata: z
86
+ .object({
87
+ state: z.string().nullish(),
88
+ createTime: z.string().nullish(),
89
+ batchStats: googleBatchStatsSchema.nullish(),
90
+ output: googleBatchOutputSchema.nullish(),
91
+ })
92
+ .nullish(),
93
+ done: z.boolean().nullish(),
94
+ error: googleRpcStatusSchema.nullish(),
95
+ response: googleBatchOutputSchema.nullish(),
96
+ });
97
+
79
98
  const googleBatchOperationSchema = lazySchema(() =>
99
+ zodSchema(googleBatchOperationZodSchema()),
100
+ );
101
+
102
+ type GoogleBatchOperation = InferSchema<typeof googleBatchOperationSchema>;
103
+
104
+ const googleBatchListResponseSchema = lazySchema(() =>
80
105
  zodSchema(
81
106
  z.object({
82
- name: z.string(),
83
- metadata: z
84
- .object({
85
- state: z.string().nullish(),
86
- createTime: z.string().nullish(),
87
- batchStats: googleBatchStatsSchema.nullish(),
88
- output: googleBatchOutputSchema.nullish(),
89
- })
90
- .nullish(),
91
- done: z.boolean().nullish(),
92
- error: googleRpcStatusSchema.nullish(),
93
- response: googleBatchOutputSchema.nullish(),
107
+ operations: z.array(googleBatchOperationZodSchema()).nullish(),
108
+ nextPageToken: z.string().nullish(),
94
109
  }),
95
110
  ),
96
111
  );
97
112
 
98
- type GoogleBatchOperation = InferSchema<typeof googleBatchOperationSchema>;
113
+ const googleBatchCancelResponseSchema = lazySchema(() =>
114
+ zodSchema(z.object({})),
115
+ );
99
116
 
100
117
  const googleFileUploadResponseSchema = lazySchema(() =>
101
118
  zodSchema(
@@ -355,6 +372,54 @@ export class GoogleBatch implements BatchV4<{ readonly text: GoogleModelId }> {
355
372
  return convertGoogleBatchStatus(await this.retrieveBatch(options));
356
373
  }
357
374
 
375
+ async doCancelBatch(
376
+ options: BatchV4OperationOptions,
377
+ ): Promise<BatchV4CancelResult> {
378
+ await postJsonToApi({
379
+ url: `${this.batchConfig.baseURL}/${options.batchId}:cancel`,
380
+ headers: await this.getHeaders(options.headers),
381
+ body: {},
382
+ failedResponseHandler: googleFailedResponseHandler,
383
+ successfulResponseHandler: createJsonResponseHandler(
384
+ googleBatchCancelResponseSchema,
385
+ ),
386
+ abortSignal: options.abortSignal,
387
+ fetch: this.batchConfig.fetch,
388
+ });
389
+
390
+ return {};
391
+ }
392
+
393
+ async doListBatches(options: BatchV4ListOptions): Promise<BatchV4ListResult> {
394
+ const url = new URL(`${this.batchConfig.baseURL}/batches`);
395
+ if (options.limit != null) {
396
+ url.searchParams.set('pageSize', String(options.limit));
397
+ }
398
+ if (options.cursor != null) {
399
+ url.searchParams.set('pageToken', options.cursor);
400
+ }
401
+
402
+ const { value: page } = await getFromApi({
403
+ url: url.toString(),
404
+ headers: await this.getHeaders(options.headers),
405
+ failedResponseHandler: googleFailedResponseHandler,
406
+ successfulResponseHandler: createJsonResponseHandler(
407
+ googleBatchListResponseSchema,
408
+ ),
409
+ abortSignal: options.abortSignal,
410
+ fetch: this.batchConfig.fetch,
411
+ validateUrl: false,
412
+ });
413
+
414
+ return {
415
+ batches: (page.operations ?? []).map(operation => ({
416
+ batchId: operation.name,
417
+ ...convertGoogleBatchStatus(operation),
418
+ })),
419
+ ...(page.nextPageToken != null ? { nextCursor: page.nextPageToken } : {}),
420
+ };
421
+ }
422
+
358
423
  async doGetBatchResults(
359
424
  options: BatchV4OperationOptions,
360
425
  ): Promise<ReadableStream<BatchV4ItemResult>> {