@ai-sdk/xai 4.0.53 → 4.0.55
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/CHANGELOG.md +18 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +121 -81
- package/dist/index.js.map +1 -1
- package/docs/01-xai.mdx +21 -12
- package/package.json +3 -3
- package/src/responses/xai-responses-language-model.ts +43 -28
- package/src/{responses/xai-responses-batch.ts → xai-batch.ts} +93 -74
- package/src/xai-provider.ts +25 -6
package/docs/01-xai.mdx
CHANGED
|
@@ -641,27 +641,37 @@ import { xai } from '@ai-sdk/xai';
|
|
|
641
641
|
import {
|
|
642
642
|
experimental_getBatchResults as getBatchResults,
|
|
643
643
|
experimental_getBatchStatus as getBatchStatus,
|
|
644
|
-
|
|
644
|
+
experimental_startBatch as startBatch,
|
|
645
645
|
} from 'ai';
|
|
646
646
|
import { setTimeout } from 'node:timers/promises';
|
|
647
647
|
|
|
648
|
-
const model =
|
|
648
|
+
const model = 'grok-4.3';
|
|
649
649
|
|
|
650
|
-
const batch = await
|
|
651
|
-
|
|
650
|
+
const batch = await startBatch({
|
|
651
|
+
provider: xai,
|
|
652
652
|
requests: [
|
|
653
|
-
{
|
|
654
|
-
|
|
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
|
+
},
|
|
655
665
|
],
|
|
656
666
|
});
|
|
657
667
|
|
|
658
668
|
let status = batch.status;
|
|
659
669
|
while (status === 'pending') {
|
|
660
670
|
await setTimeout(60_000);
|
|
661
|
-
({ status } = await getBatchStatus({
|
|
671
|
+
({ status } = await getBatchStatus({ provider: xai, batch }));
|
|
662
672
|
}
|
|
663
673
|
|
|
664
|
-
for await (const item of getBatchResults({
|
|
674
|
+
for await (const item of getBatchResults({ provider: xai, batch })) {
|
|
665
675
|
if (item.status === 'succeeded') {
|
|
666
676
|
console.log(item.id, item.text);
|
|
667
677
|
} else {
|
|
@@ -670,14 +680,13 @@ for await (const item of getBatchResults({ model, batch })) {
|
|
|
670
680
|
}
|
|
671
681
|
```
|
|
672
682
|
|
|
673
|
-
`
|
|
683
|
+
`startBatch` returns a serializable batch reference. Persist this reference
|
|
674
684
|
to check the batch status or retrieve its results from another process. Results
|
|
675
685
|
can arrive in a different order from the input requests, so match each result by
|
|
676
686
|
its `id`.
|
|
677
687
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
the batch APIs.
|
|
688
|
+
Each request specifies its `type` and `model`. xAI supports using different
|
|
689
|
+
text models within the same batch.
|
|
681
690
|
|
|
682
691
|
<Note>
|
|
683
692
|
The xAI Batch API does not support per-batch webhooks. When you provide a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/xai",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.55",
|
|
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.
|
|
33
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
32
|
+
"@ai-sdk/provider": "4.0.11",
|
|
33
|
+
"@ai-sdk/provider-utils": "5.0.37"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@ai-sdk/test-server": "2.0.1",
|
|
@@ -139,6 +139,15 @@ function isRetryableStatusCode(statusCode: number): boolean {
|
|
|
139
139
|
);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
export const xaiResponsesSupportedUrls: Record<string, RegExp[]> = {
|
|
143
|
+
'image/*': [/^https?:\/\/.*$/],
|
|
144
|
+
// xAI's Responses API accepts non-image documents (PDF, plain text, CSV, etc.) as
|
|
145
|
+
// `{ type: 'input_file', file_url }`. Keeping these URLs intact here lets them pass
|
|
146
|
+
// through to the converter instead of being downloaded to bytes by the SDK.
|
|
147
|
+
'application/pdf': [/^https?:\/\/.*$/],
|
|
148
|
+
'text/*': [/^https?:\/\/.*$/],
|
|
149
|
+
};
|
|
150
|
+
|
|
142
151
|
export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
143
152
|
readonly specificationVersion = 'v4';
|
|
144
153
|
|
|
@@ -169,31 +178,30 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
169
178
|
return this.config.provider;
|
|
170
179
|
}
|
|
171
180
|
|
|
172
|
-
readonly supportedUrls
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}: LanguageModelV4CallOptions) {
|
|
181
|
+
readonly supportedUrls = xaiResponsesSupportedUrls;
|
|
182
|
+
|
|
183
|
+
static async prepareRequest({
|
|
184
|
+
modelId,
|
|
185
|
+
options: {
|
|
186
|
+
prompt,
|
|
187
|
+
maxOutputTokens,
|
|
188
|
+
temperature,
|
|
189
|
+
topP,
|
|
190
|
+
topK,
|
|
191
|
+
frequencyPenalty,
|
|
192
|
+
presencePenalty,
|
|
193
|
+
stopSequences,
|
|
194
|
+
seed,
|
|
195
|
+
responseFormat,
|
|
196
|
+
providerOptions,
|
|
197
|
+
tools,
|
|
198
|
+
toolChoice,
|
|
199
|
+
reasoning,
|
|
200
|
+
},
|
|
201
|
+
}: {
|
|
202
|
+
modelId: XaiResponsesModelId;
|
|
203
|
+
options: LanguageModelV4CallOptions;
|
|
204
|
+
}) {
|
|
197
205
|
const warnings: SharedV4Warning[] = [];
|
|
198
206
|
|
|
199
207
|
const options =
|
|
@@ -276,7 +284,7 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
276
284
|
|
|
277
285
|
let resolvedReasoningEffort = options.reasoningEffort;
|
|
278
286
|
if (resolvedReasoningEffort == null && isCustomReasoning(reasoning)) {
|
|
279
|
-
if (!supportsReasoningEffort(
|
|
287
|
+
if (!supportsReasoningEffort(modelId)) {
|
|
280
288
|
warnings.push({
|
|
281
289
|
type: 'unsupported',
|
|
282
290
|
feature: 'reasoning',
|
|
@@ -292,7 +300,7 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
292
300
|
low: 'low',
|
|
293
301
|
medium: 'medium',
|
|
294
302
|
high: 'high',
|
|
295
|
-
xhigh:
|
|
303
|
+
xhigh: modelId === 'grok-4.6' ? 'xhigh' : 'high',
|
|
296
304
|
},
|
|
297
305
|
warnings,
|
|
298
306
|
});
|
|
@@ -300,7 +308,7 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
300
308
|
}
|
|
301
309
|
|
|
302
310
|
const baseArgs: Record<string, unknown> = {
|
|
303
|
-
model:
|
|
311
|
+
model: modelId,
|
|
304
312
|
input,
|
|
305
313
|
logprobs:
|
|
306
314
|
options.logprobs === true || options.topLogprobs != null
|
|
@@ -370,6 +378,13 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
370
378
|
};
|
|
371
379
|
}
|
|
372
380
|
|
|
381
|
+
private getArgs(options: LanguageModelV4CallOptions) {
|
|
382
|
+
return XaiResponsesLanguageModel.prepareRequest({
|
|
383
|
+
modelId: this.modelId,
|
|
384
|
+
options,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
|
|
373
388
|
async doGenerate(
|
|
374
389
|
options: LanguageModelV4CallOptions,
|
|
375
390
|
): Promise<LanguageModelV4GenerateResult> {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InvalidArgumentError,
|
|
3
|
-
type
|
|
3
|
+
type Experimental_BatchV4 as BatchV4,
|
|
4
4
|
type Experimental_BatchV4Error as BatchV4Error,
|
|
5
5
|
type Experimental_BatchV4ItemResult as BatchV4ItemResult,
|
|
6
6
|
type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
|
|
7
|
-
type Experimental_BatchV4StartOptions as BatchV4StartOptions,
|
|
8
7
|
type Experimental_BatchV4StartResult as BatchV4StartResult,
|
|
9
8
|
type Experimental_BatchV4Status as BatchV4Status,
|
|
9
|
+
type Experimental_TextBatchV4Request as TextBatchV4Request,
|
|
10
|
+
type Experimental_TextBatchV4ItemResult as TextBatchV4ItemResult,
|
|
11
|
+
type Experimental_BatchV4StartOptions as BatchV4StartOptions,
|
|
10
12
|
type LanguageModelV4Content,
|
|
11
13
|
type LanguageModelV4GenerateResult,
|
|
12
14
|
type SharedV4ProviderMetadata,
|
|
@@ -20,37 +22,54 @@ import {
|
|
|
20
22
|
getFromApi,
|
|
21
23
|
lazySchema,
|
|
22
24
|
normalizeBatchRequestCounts,
|
|
25
|
+
parseProviderOptions,
|
|
23
26
|
postFormDataToApi,
|
|
24
27
|
postJsonToApi,
|
|
25
28
|
safeValidateTypes,
|
|
26
|
-
WORKFLOW_DESERIALIZE,
|
|
27
|
-
WORKFLOW_SERIALIZE,
|
|
28
29
|
zodSchema,
|
|
29
30
|
type InferSchema,
|
|
30
31
|
} from '@ai-sdk/provider-utils';
|
|
31
32
|
import { z } from 'zod/v4';
|
|
32
|
-
import { convertXaiChatUsage } from '
|
|
33
|
-
import { getResponseMetadata } from '
|
|
34
|
-
import { mapXaiFinishReason } from '
|
|
33
|
+
import { convertXaiChatUsage } from './convert-xai-chat-usage';
|
|
34
|
+
import { getResponseMetadata } from './get-response-metadata';
|
|
35
|
+
import { mapXaiFinishReason } from './map-xai-finish-reason';
|
|
35
36
|
import {
|
|
36
37
|
xaiChatResponseSchema,
|
|
37
38
|
type XaiChatResponse,
|
|
38
|
-
} from '
|
|
39
|
-
import { xaiFailedResponseHandler } from '
|
|
40
|
-
import { xaiFilesResponseSchema } from '
|
|
39
|
+
} from './xai-chat-language-model';
|
|
40
|
+
import { xaiFailedResponseHandler } from './xai-error';
|
|
41
|
+
import { xaiFilesResponseSchema } from './files/xai-files-api';
|
|
41
42
|
import {
|
|
42
43
|
XaiResponsesLanguageModel,
|
|
44
|
+
xaiResponsesSupportedUrls,
|
|
43
45
|
type XaiResponsesConfig,
|
|
44
|
-
} from './xai-responses-language-model';
|
|
45
|
-
import type { XaiResponsesModelId } from './xai-responses-language-model-options';
|
|
46
|
+
} from './responses/xai-responses-language-model';
|
|
47
|
+
import type { XaiResponsesModelId } from './responses/xai-responses-language-model-options';
|
|
46
48
|
|
|
47
49
|
const xaiBatchEndpoint = '/v1/responses';
|
|
48
50
|
const xaiBatchName = 'ai-sdk-text-batch';
|
|
49
51
|
const xaiBatchResultsPageSize = 1000;
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
const xaiBatchProviderOptionsSchema = lazySchema(() =>
|
|
54
|
+
zodSchema(
|
|
55
|
+
z.object({
|
|
56
|
+
/**
|
|
57
|
+
* TTL in seconds for the uploaded batch input file, measured from
|
|
58
|
+
* upload time. xAI accepts integers between 3600 (1 hour) and
|
|
59
|
+
* 2592000 (30 days) inclusive. Without it the file has no expiry.
|
|
60
|
+
*/
|
|
61
|
+
inputFileExpiresAfter: z
|
|
62
|
+
.number()
|
|
63
|
+
.int()
|
|
64
|
+
.min(3600)
|
|
65
|
+
.max(2_592_000)
|
|
66
|
+
.optional(),
|
|
67
|
+
}),
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
type XaiBatchModelIds = { readonly text: XaiResponsesModelId };
|
|
72
|
+
type XaiBatchRequest = TextBatchV4Request<XaiResponsesModelId>;
|
|
54
73
|
|
|
55
74
|
type XaiBatchPreparedRequest = {
|
|
56
75
|
body: unknown;
|
|
@@ -116,18 +135,22 @@ const xaiBatchResultsPageSchema = lazySchema(() =>
|
|
|
116
135
|
),
|
|
117
136
|
);
|
|
118
137
|
|
|
119
|
-
class
|
|
138
|
+
export class XaiBatch implements BatchV4<XaiBatchModelIds> {
|
|
139
|
+
readonly specificationVersion = 'v4' as const;
|
|
140
|
+
readonly provider: string;
|
|
141
|
+
readonly supportedUrls = xaiResponsesSupportedUrls;
|
|
142
|
+
|
|
120
143
|
constructor(
|
|
121
144
|
private readonly options: {
|
|
145
|
+
provider: string;
|
|
122
146
|
config: XaiResponsesConfig;
|
|
123
|
-
prepareRequest: (
|
|
124
|
-
request: XaiBatchRequest,
|
|
125
|
-
) => PromiseLike<XaiBatchPreparedRequest>;
|
|
126
147
|
},
|
|
127
|
-
) {
|
|
148
|
+
) {
|
|
149
|
+
this.provider = options.provider;
|
|
150
|
+
}
|
|
128
151
|
|
|
129
|
-
async
|
|
130
|
-
options: BatchV4StartOptions<
|
|
152
|
+
async doStartBatch(
|
|
153
|
+
options: BatchV4StartOptions<XaiBatchModelIds>,
|
|
131
154
|
): Promise<BatchV4StartResult> {
|
|
132
155
|
const fileParts: string[] = [];
|
|
133
156
|
const warnings: BatchV4StartResult['warnings'] =
|
|
@@ -144,8 +167,14 @@ class XaiResponsesBatch {
|
|
|
144
167
|
},
|
|
145
168
|
];
|
|
146
169
|
|
|
170
|
+
const batchOptions = await parseProviderOptions({
|
|
171
|
+
provider: 'xai',
|
|
172
|
+
providerOptions: options.providerOptions,
|
|
173
|
+
schema: xaiBatchProviderOptionsSchema,
|
|
174
|
+
});
|
|
175
|
+
|
|
147
176
|
for (const request of options.requests) {
|
|
148
|
-
const preparedRequest = await this.
|
|
177
|
+
const preparedRequest = await this.prepareRequest(request);
|
|
149
178
|
|
|
150
179
|
fileParts.push(
|
|
151
180
|
JSON.stringify({
|
|
@@ -166,6 +195,14 @@ class XaiResponsesBatch {
|
|
|
166
195
|
const file = new Blob(fileParts, { type: 'application/jsonl' });
|
|
167
196
|
fileParts.length = 0;
|
|
168
197
|
const formData = new FormData();
|
|
198
|
+
// xAI rejects uploads where expires_after arrives after the file part,
|
|
199
|
+
// so all fields precede the file.
|
|
200
|
+
if (batchOptions?.inputFileExpiresAfter != null) {
|
|
201
|
+
formData.append(
|
|
202
|
+
'expires_after',
|
|
203
|
+
String(batchOptions.inputFileExpiresAfter),
|
|
204
|
+
);
|
|
205
|
+
}
|
|
169
206
|
formData.append('file', file, filename);
|
|
170
207
|
|
|
171
208
|
const headers = combineHeaders(
|
|
@@ -203,19 +240,31 @@ class XaiResponsesBatch {
|
|
|
203
240
|
return {
|
|
204
241
|
batchId: batch.batch_id,
|
|
205
242
|
...convertXaiBatchStatus(batch),
|
|
243
|
+
providerMetadata: {
|
|
244
|
+
xai: {
|
|
245
|
+
inputFileId: uploadedFile.id,
|
|
246
|
+
...(uploadedFile.expires_at != null
|
|
247
|
+
? {
|
|
248
|
+
inputFileExpiresAt: new Date(
|
|
249
|
+
uploadedFile.expires_at * 1000,
|
|
250
|
+
).toISOString(),
|
|
251
|
+
}
|
|
252
|
+
: {}),
|
|
253
|
+
},
|
|
254
|
+
},
|
|
206
255
|
warnings,
|
|
207
256
|
};
|
|
208
257
|
}
|
|
209
258
|
|
|
210
|
-
async
|
|
259
|
+
async doGetBatchStatus(
|
|
211
260
|
options: BatchV4OperationOptions,
|
|
212
261
|
): Promise<BatchV4Status> {
|
|
213
262
|
return convertXaiBatchStatus(await this.retrieveBatch(options));
|
|
214
263
|
}
|
|
215
264
|
|
|
216
|
-
async
|
|
265
|
+
async doGetBatchResults(
|
|
217
266
|
options: BatchV4OperationOptions,
|
|
218
|
-
): Promise<ReadableStream<BatchV4ItemResult
|
|
267
|
+
): Promise<ReadableStream<BatchV4ItemResult>> {
|
|
219
268
|
const batch = await this.retrieveBatch(options);
|
|
220
269
|
if (convertXaiBatchStatus(batch).status === 'pending') {
|
|
221
270
|
throw new InvalidArgumentError({
|
|
@@ -249,7 +298,7 @@ class XaiResponsesBatch {
|
|
|
249
298
|
|
|
250
299
|
private async *iterateBatchResults(
|
|
251
300
|
options: BatchV4OperationOptions,
|
|
252
|
-
): AsyncGenerator<BatchV4ItemResult
|
|
301
|
+
): AsyncGenerator<BatchV4ItemResult> {
|
|
253
302
|
let paginationToken: string | undefined;
|
|
254
303
|
|
|
255
304
|
do {
|
|
@@ -287,7 +336,7 @@ class XaiResponsesBatch {
|
|
|
287
336
|
|
|
288
337
|
private async convertBatchResult(
|
|
289
338
|
result: XaiBatchResult,
|
|
290
|
-
): Promise<
|
|
339
|
+
): Promise<TextBatchV4ItemResult> {
|
|
291
340
|
const error = result.batch_result?.error;
|
|
292
341
|
if (
|
|
293
342
|
(result.error_message?.length ?? 0) > 0 ||
|
|
@@ -296,6 +345,7 @@ class XaiResponsesBatch {
|
|
|
296
345
|
) {
|
|
297
346
|
const convertedError = convertXaiBatchError(result);
|
|
298
347
|
return {
|
|
348
|
+
type: 'text',
|
|
299
349
|
id: result.batch_request_id,
|
|
300
350
|
status: isXaiCancellationError(error?.code) ? 'cancelled' : 'failed',
|
|
301
351
|
error: convertedError,
|
|
@@ -317,11 +367,13 @@ class XaiResponsesBatch {
|
|
|
317
367
|
const conversion = convertXaiChatBatchResponse(validation.value);
|
|
318
368
|
return conversion.success
|
|
319
369
|
? {
|
|
370
|
+
type: 'text',
|
|
320
371
|
id: result.batch_request_id,
|
|
321
372
|
status: 'succeeded',
|
|
322
373
|
result: conversion.result,
|
|
323
374
|
}
|
|
324
375
|
: {
|
|
376
|
+
type: 'text',
|
|
325
377
|
id: result.batch_request_id,
|
|
326
378
|
status: 'failed',
|
|
327
379
|
error: conversion.error,
|
|
@@ -331,51 +383,19 @@ class XaiResponsesBatch {
|
|
|
331
383
|
return invalidXaiBatchResult(result.batch_request_id);
|
|
332
384
|
}
|
|
333
385
|
|
|
334
|
-
private
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
{
|
|
343
|
-
private readonly batch: XaiResponsesBatch;
|
|
344
|
-
|
|
345
|
-
static [WORKFLOW_SERIALIZE](model: XaiResponsesLanguageModel) {
|
|
346
|
-
return XaiResponsesLanguageModel[WORKFLOW_SERIALIZE](model);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
static [WORKFLOW_DESERIALIZE](options: {
|
|
350
|
-
modelId: XaiResponsesModelId;
|
|
351
|
-
config: XaiResponsesConfig;
|
|
352
|
-
}) {
|
|
353
|
-
return new XaiResponsesBatchLanguageModel(options.modelId, options.config);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
constructor(modelId: XaiResponsesModelId, config: XaiResponsesConfig) {
|
|
357
|
-
super(modelId, config);
|
|
358
|
-
this.batch = new XaiResponsesBatch({
|
|
359
|
-
config,
|
|
360
|
-
prepareRequest: async request => {
|
|
361
|
-
const { args: body, warnings } = await this.getArgs(request.options);
|
|
362
|
-
return { body, warnings };
|
|
363
|
-
},
|
|
364
|
-
});
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
experimental_doStartBatch(
|
|
368
|
-
options: Parameters<BatchLanguageModelV4['experimental_doStartBatch']>[0],
|
|
369
|
-
) {
|
|
370
|
-
return this.batch.startBatch(options);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
experimental_doGetBatchStatus(options: BatchV4OperationOptions) {
|
|
374
|
-
return this.batch.getBatchStatus(options);
|
|
386
|
+
private async prepareRequest(
|
|
387
|
+
request: XaiBatchRequest,
|
|
388
|
+
): Promise<XaiBatchPreparedRequest> {
|
|
389
|
+
const { args: body, warnings } =
|
|
390
|
+
await XaiResponsesLanguageModel.prepareRequest({
|
|
391
|
+
modelId: request.modelId,
|
|
392
|
+
options: request.options,
|
|
393
|
+
});
|
|
394
|
+
return { body, warnings };
|
|
375
395
|
}
|
|
376
396
|
|
|
377
|
-
|
|
378
|
-
return this.
|
|
397
|
+
private getUrl(path: string) {
|
|
398
|
+
return `${this.options.config.baseURL ?? 'https://api.x.ai/v1'}${path}`;
|
|
379
399
|
}
|
|
380
400
|
}
|
|
381
401
|
|
|
@@ -455,10 +475,9 @@ function isXaiCancellationError(code: string | number | null | undefined) {
|
|
|
455
475
|
);
|
|
456
476
|
}
|
|
457
477
|
|
|
458
|
-
function invalidXaiBatchResult(
|
|
459
|
-
id: string,
|
|
460
|
-
): BatchV4ItemResult<LanguageModelV4GenerateResult> {
|
|
478
|
+
function invalidXaiBatchResult(id: string): TextBatchV4ItemResult {
|
|
461
479
|
return {
|
|
480
|
+
type: 'text',
|
|
462
481
|
id,
|
|
463
482
|
status: 'failed',
|
|
464
483
|
error: {
|
package/src/xai-provider.ts
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
type Experimental_RealtimeFactoryV4 as RealtimeFactoryV4,
|
|
3
3
|
type Experimental_RealtimeFactoryV4GetTokenOptions as RealtimeFactoryV4GetTokenOptions,
|
|
4
4
|
type Experimental_VideoModelV4,
|
|
5
|
-
type
|
|
5
|
+
type Experimental_BatchV4 as BatchV4,
|
|
6
6
|
type FilesV4,
|
|
7
7
|
type ImageModelV4,
|
|
8
8
|
type LanguageModelV4,
|
|
@@ -23,7 +23,8 @@ import { XaiChatLanguageModel } from './xai-chat-language-model';
|
|
|
23
23
|
import type { XaiChatModelId } from './xai-chat-language-model-options';
|
|
24
24
|
import { XaiImageModel } from './xai-image-model';
|
|
25
25
|
import type { XaiImageModelId } from './xai-image-settings';
|
|
26
|
-
import {
|
|
26
|
+
import { XaiBatch } from './xai-batch';
|
|
27
|
+
import { XaiResponsesLanguageModel } from './responses/xai-responses-language-model';
|
|
27
28
|
import type { XaiResponsesModelId } from './responses/xai-responses-language-model-options';
|
|
28
29
|
import { XaiRealtimeModel } from './realtime/xai-realtime-model';
|
|
29
30
|
import { xaiTools } from './tool';
|
|
@@ -35,12 +36,12 @@ import { XaiSpeechModel } from './xai-speech-model';
|
|
|
35
36
|
import { XaiTranscriptionModel } from './xai-transcription-model';
|
|
36
37
|
|
|
37
38
|
export interface XaiProvider extends ProviderV4 {
|
|
38
|
-
(modelId: XaiResponsesModelId):
|
|
39
|
+
(modelId: XaiResponsesModelId): LanguageModelV4;
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Creates an Xai language model for text generation.
|
|
42
43
|
*/
|
|
43
|
-
languageModel(modelId: XaiResponsesModelId):
|
|
44
|
+
languageModel(modelId: XaiResponsesModelId): LanguageModelV4;
|
|
44
45
|
|
|
45
46
|
/**
|
|
46
47
|
* Creates an Xai chat model for text generation.
|
|
@@ -50,7 +51,12 @@ export interface XaiProvider extends ProviderV4 {
|
|
|
50
51
|
/**
|
|
51
52
|
* Creates an Xai responses model for text generation.
|
|
52
53
|
*/
|
|
53
|
-
responses: (modelId: XaiResponsesModelId) =>
|
|
54
|
+
responses: (modelId: XaiResponsesModelId) => LanguageModelV4;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Returns a BatchV4 interface for processing batches with xAI.
|
|
58
|
+
*/
|
|
59
|
+
experimental_batch(): BatchV4<{ text: XaiResponsesModelId }>;
|
|
54
60
|
|
|
55
61
|
/**
|
|
56
62
|
* Creates an Xai image model for image generation.
|
|
@@ -167,7 +173,7 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider {
|
|
|
167
173
|
};
|
|
168
174
|
|
|
169
175
|
const createResponsesLanguageModel = (modelId: XaiResponsesModelId) => {
|
|
170
|
-
return new
|
|
176
|
+
return new XaiResponsesLanguageModel(modelId, {
|
|
171
177
|
provider: 'xai.responses',
|
|
172
178
|
baseURL,
|
|
173
179
|
headers: getHeaders,
|
|
@@ -249,6 +255,18 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider {
|
|
|
249
255
|
fetch: options.fetch,
|
|
250
256
|
});
|
|
251
257
|
|
|
258
|
+
const createBatch = () =>
|
|
259
|
+
new XaiBatch({
|
|
260
|
+
provider: 'xai.batch',
|
|
261
|
+
config: {
|
|
262
|
+
provider: 'xai.responses',
|
|
263
|
+
baseURL,
|
|
264
|
+
headers: getHeaders,
|
|
265
|
+
generateId,
|
|
266
|
+
fetch: options.fetch,
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
|
|
252
270
|
const provider = (modelId: XaiResponsesModelId) =>
|
|
253
271
|
createResponsesLanguageModel(modelId);
|
|
254
272
|
|
|
@@ -270,6 +288,7 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider {
|
|
|
270
288
|
provider.transcriptionModel = createTranscriptionModel;
|
|
271
289
|
provider.transcription = createTranscriptionModel;
|
|
272
290
|
provider.files = createFiles;
|
|
291
|
+
provider.experimental_batch = createBatch;
|
|
273
292
|
provider.tools = xaiTools;
|
|
274
293
|
|
|
275
294
|
return provider;
|