@ai-sdk/xai 4.0.55 → 4.0.57

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/docs/01-xai.mdx CHANGED
@@ -625,65 +625,16 @@ The following provider options are available:
625
625
  tools with client-side function tools in the same request.
626
626
  </Note>
627
627
 
628
- ## Text Batches
628
+ ## Batch
629
629
 
630
630
  <Note type="warning">
631
- Text batch support is experimental and the API may change in patch releases.
631
+ Batch support is experimental and the API may change in patch releases.
632
632
  </Note>
633
633
 
634
- The xAI provider supports asynchronous text generation through the
635
- [Batch API](https://docs.x.ai/developers/advanced-api-usage/batch-api). Use the
636
- experimental text batch APIs to start a batch, poll its status, and stream its
637
- results:
638
-
639
- ```ts
640
- import { xai } from '@ai-sdk/xai';
641
- import {
642
- experimental_getBatchResults as getBatchResults,
643
- experimental_getBatchStatus as getBatchStatus,
644
- experimental_startBatch as startBatch,
645
- } from 'ai';
646
- import { setTimeout } from 'node:timers/promises';
647
-
648
- const model = 'grok-4.3';
649
-
650
- const batch = await startBatch({
651
- provider: xai,
652
- requests: [
653
- {
654
- id: 'capital-france',
655
- type: 'text',
656
- model,
657
- prompt: 'What is the capital of France?',
658
- },
659
- {
660
- id: 'capital-germany',
661
- type: 'text',
662
- model: 'grok-4.20-non-reasoning',
663
- prompt: 'What is the capital of Germany?',
664
- },
665
- ],
666
- });
667
-
668
- let status = batch.status;
669
- while (status === 'pending') {
670
- await setTimeout(60_000);
671
- ({ status } = await getBatchStatus({ provider: xai, batch }));
672
- }
673
-
674
- for await (const item of getBatchResults({ provider: xai, batch })) {
675
- if (item.status === 'succeeded') {
676
- console.log(item.id, item.text);
677
- } else {
678
- console.error(item.id, item.error);
679
- }
680
- }
681
- ```
682
-
683
- `startBatch` returns a serializable batch reference. Persist this reference
684
- to check the batch status or retrieve its results from another process. Results
685
- can arrive in a different order from the input requests, so match each result by
686
- its `id`.
634
+ The xAI provider supports asynchronous text generation through the [Batch
635
+ API](https://docs.x.ai/developers/advanced-api-usage/batch-api). Pass the xAI
636
+ provider to the AI SDK's [Batch](/docs/ai-sdk-core/batch) API
637
+ for the complete workflow, including polling, persistence, and result handling.
687
638
 
688
639
  Each request specifies its `type` and `model`. xAI supports using different
689
640
  text models within the same batch.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/xai",
3
- "version": "4.0.55",
3
+ "version": "4.0.57",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,8 +29,8 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.11",
33
- "@ai-sdk/provider-utils": "5.0.37"
32
+ "@ai-sdk/provider": "4.0.13",
33
+ "@ai-sdk/provider-utils": "5.0.39"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@ai-sdk/test-server": "2.0.1",
package/src/xai-batch.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  import {
2
2
  InvalidArgumentError,
3
3
  type Experimental_BatchV4 as BatchV4,
4
+ type Experimental_BatchV4CancelResult as BatchV4CancelResult,
4
5
  type Experimental_BatchV4Error as BatchV4Error,
5
6
  type Experimental_BatchV4ItemResult as BatchV4ItemResult,
7
+ type Experimental_BatchV4ListOptions as BatchV4ListOptions,
8
+ type Experimental_BatchV4ListResult as BatchV4ListResult,
6
9
  type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
7
10
  type Experimental_BatchV4StartResult as BatchV4StartResult,
8
11
  type Experimental_BatchV4Status as BatchV4Status,
@@ -80,26 +83,27 @@ type XaiBatchResponseConversion =
80
83
  | { success: true; result: LanguageModelV4GenerateResult }
81
84
  | { success: false; error: BatchV4Error };
82
85
 
86
+ const xaiBatchResponseZodSchema = () =>
87
+ z.object({
88
+ batch_id: z.string(),
89
+ name: z.string().nullish(),
90
+ create_time: z.string().nullish(),
91
+ expire_time: z.string().nullish(),
92
+ cancel_time: z.string().nullish(),
93
+ cancel_by_xai_message: z.string().nullish(),
94
+ state: z
95
+ .object({
96
+ num_requests: z.number().nullish(),
97
+ num_pending: z.number().nullish(),
98
+ num_success: z.number().nullish(),
99
+ num_error: z.number().nullish(),
100
+ num_cancelled: z.number().nullish(),
101
+ })
102
+ .nullish(),
103
+ });
104
+
83
105
  const xaiBatchResponseSchema = lazySchema(() =>
84
- zodSchema(
85
- z.object({
86
- batch_id: z.string(),
87
- name: z.string().nullish(),
88
- create_time: z.string().nullish(),
89
- expire_time: z.string().nullish(),
90
- cancel_time: z.string().nullish(),
91
- cancel_by_xai_message: z.string().nullish(),
92
- state: z
93
- .object({
94
- num_requests: z.number().nullish(),
95
- num_pending: z.number().nullish(),
96
- num_success: z.number().nullish(),
97
- num_error: z.number().nullish(),
98
- num_cancelled: z.number().nullish(),
99
- })
100
- .nullish(),
101
- }),
102
- ),
106
+ zodSchema(xaiBatchResponseZodSchema()),
103
107
  );
104
108
 
105
109
  type XaiBatchResponse = InferSchema<typeof xaiBatchResponseSchema>;
@@ -135,6 +139,15 @@ const xaiBatchResultsPageSchema = lazySchema(() =>
135
139
  ),
136
140
  );
137
141
 
142
+ const xaiBatchListResponseSchema = lazySchema(() =>
143
+ zodSchema(
144
+ z.object({
145
+ batches: z.array(xaiBatchResponseZodSchema()),
146
+ pagination_token: z.string().nullish(),
147
+ }),
148
+ ),
149
+ );
150
+
138
151
  export class XaiBatch implements BatchV4<XaiBatchModelIds> {
139
152
  readonly specificationVersion = 'v4' as const;
140
153
  readonly provider: string;
@@ -262,6 +275,58 @@ export class XaiBatch implements BatchV4<XaiBatchModelIds> {
262
275
  return convertXaiBatchStatus(await this.retrieveBatch(options));
263
276
  }
264
277
 
278
+ async doCancelBatch(
279
+ options: BatchV4OperationOptions,
280
+ ): Promise<BatchV4CancelResult> {
281
+ await postJsonToApi({
282
+ url: this.getUrl(
283
+ `/batches/${encodeURIComponent(options.batchId)}:cancel`,
284
+ ),
285
+ headers: combineHeaders(this.options.config.headers?.(), options.headers),
286
+ body: {},
287
+ failedResponseHandler: xaiFailedResponseHandler,
288
+ successfulResponseHandler: createJsonResponseHandler(
289
+ xaiBatchResponseSchema,
290
+ ),
291
+ abortSignal: options.abortSignal,
292
+ fetch: this.options.config.fetch,
293
+ });
294
+
295
+ return {};
296
+ }
297
+
298
+ async doListBatches(options: BatchV4ListOptions): Promise<BatchV4ListResult> {
299
+ const url = new URL(this.getUrl('/batches'));
300
+ if (options.limit != null) {
301
+ url.searchParams.set('limit', String(options.limit));
302
+ }
303
+ if (options.cursor != null) {
304
+ url.searchParams.set('pagination_token', options.cursor);
305
+ }
306
+
307
+ const { value: page } = await getFromApi({
308
+ url: url.toString(),
309
+ headers: combineHeaders(this.options.config.headers?.(), options.headers),
310
+ failedResponseHandler: xaiFailedResponseHandler,
311
+ successfulResponseHandler: createJsonResponseHandler(
312
+ xaiBatchListResponseSchema,
313
+ ),
314
+ abortSignal: options.abortSignal,
315
+ fetch: this.options.config.fetch,
316
+ validateUrl: false,
317
+ });
318
+
319
+ return {
320
+ batches: page.batches.map(batch => ({
321
+ batchId: batch.batch_id,
322
+ ...convertXaiBatchStatus(batch),
323
+ })),
324
+ ...(page.pagination_token != null
325
+ ? { nextCursor: page.pagination_token }
326
+ : {}),
327
+ };
328
+ }
329
+
265
330
  async doGetBatchResults(
266
331
  options: BatchV4OperationOptions,
267
332
  ): Promise<ReadableStream<BatchV4ItemResult>> {