@ai-sdk/xai 4.0.57 → 4.0.58
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 +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +170 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/xai-batch.ts +196 -10
- package/src/xai-chat-language-model.ts +1 -1
- package/src/xai-provider.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-sdk/xai
|
|
2
2
|
|
|
3
|
+
## 4.0.58
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5ec21a6: fix: reject unsupported batch request types
|
|
8
|
+
- 7469a3b: feat: support image generation requests in batches
|
|
9
|
+
- 0096850: fix(deepseek): preserve reasoning streams across empty tool-call deltas
|
|
10
|
+
- Updated dependencies [5ec21a6]
|
|
11
|
+
- Updated dependencies [7469a3b]
|
|
12
|
+
- Updated dependencies [813bb36]
|
|
13
|
+
- Updated dependencies [c43e4b7]
|
|
14
|
+
- @ai-sdk/provider@4.0.14
|
|
15
|
+
- @ai-sdk/provider-utils@5.0.40
|
|
16
|
+
|
|
3
17
|
## 4.0.57
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -898,7 +898,7 @@ var XaiChatLanguageModel = class _XaiChatLanguageModel {
|
|
|
898
898
|
delta: delta.reasoning_content
|
|
899
899
|
});
|
|
900
900
|
}
|
|
901
|
-
if (delta.tool_calls != null) {
|
|
901
|
+
if (delta.tool_calls != null && delta.tool_calls.length > 0) {
|
|
902
902
|
if (activeReasoningBlockId != null && !contentBlocks[activeReasoningBlockId].ended) {
|
|
903
903
|
controller.enqueue({
|
|
904
904
|
type: "reasoning-end",
|
|
@@ -1241,12 +1241,16 @@ var xaiImageResponseSchema = z6.object({
|
|
|
1241
1241
|
|
|
1242
1242
|
// src/xai-batch.ts
|
|
1243
1243
|
import {
|
|
1244
|
-
InvalidArgumentError
|
|
1244
|
+
InvalidArgumentError,
|
|
1245
|
+
UnsupportedFunctionalityError as UnsupportedFunctionalityError5
|
|
1245
1246
|
} from "@ai-sdk/provider";
|
|
1246
1247
|
import {
|
|
1247
1248
|
combineHeaders as combineHeaders4,
|
|
1249
|
+
convertImageModelFileToDataUri as convertImageModelFileToDataUri2,
|
|
1250
|
+
convertBase64ToUint8Array,
|
|
1248
1251
|
convertAsyncIteratorToReadableStream,
|
|
1249
1252
|
createJsonResponseHandler as createJsonResponseHandler4,
|
|
1253
|
+
createBinaryResponseHandler as createBinaryResponseHandler2,
|
|
1250
1254
|
createNullLanguageModelUsage,
|
|
1251
1255
|
getFromApi as getFromApi2,
|
|
1252
1256
|
lazySchema as lazySchema7,
|
|
@@ -3531,6 +3535,28 @@ var xaiBatchProviderOptionsSchema = lazySchema7(
|
|
|
3531
3535
|
})
|
|
3532
3536
|
)
|
|
3533
3537
|
);
|
|
3538
|
+
function assertSupportedBatchRequests(requests) {
|
|
3539
|
+
for (const request of requests) {
|
|
3540
|
+
const requestType = request.type;
|
|
3541
|
+
if (requestType !== "text" && requestType !== "image") {
|
|
3542
|
+
throw new UnsupportedFunctionalityError5({
|
|
3543
|
+
functionality: `batch request type: ${requestType}`,
|
|
3544
|
+
message: `The xAI Batch API does not support batch requests with type "${requestType}".`
|
|
3545
|
+
});
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3548
|
+
}
|
|
3549
|
+
var xaiBatchImageResponseSchema = z15.object({
|
|
3550
|
+
data: z15.array(
|
|
3551
|
+
z15.object({
|
|
3552
|
+
url: z15.string().nullish(),
|
|
3553
|
+
b64_json: z15.string().nullish(),
|
|
3554
|
+
revised_prompt: z15.string().nullish(),
|
|
3555
|
+
respect_moderation: z15.boolean().nullish()
|
|
3556
|
+
})
|
|
3557
|
+
),
|
|
3558
|
+
usage: z15.object({ cost_in_usd_ticks: z15.number().nullish() }).nullish()
|
|
3559
|
+
});
|
|
3534
3560
|
var xaiBatchResponseZodSchema = () => z15.object({
|
|
3535
3561
|
batch_id: z15.string(),
|
|
3536
3562
|
name: z15.string().nullish(),
|
|
@@ -3557,7 +3583,8 @@ var xaiBatchResultSchema = z15.object({
|
|
|
3557
3583
|
batch_request_id: z15.string(),
|
|
3558
3584
|
batch_result: z15.object({
|
|
3559
3585
|
response: z15.object({
|
|
3560
|
-
chat_get_completion: z15.unknown().nullish()
|
|
3586
|
+
chat_get_completion: z15.unknown().nullish(),
|
|
3587
|
+
image_generation: z15.unknown().nullish()
|
|
3561
3588
|
}).nullish(),
|
|
3562
3589
|
error: xaiBatchErrorSchema.nullish()
|
|
3563
3590
|
}).nullish(),
|
|
@@ -3588,6 +3615,7 @@ var XaiBatch = class {
|
|
|
3588
3615
|
}
|
|
3589
3616
|
async doStartBatch(options) {
|
|
3590
3617
|
var _a, _b;
|
|
3618
|
+
assertSupportedBatchRequests(options.requests);
|
|
3591
3619
|
const fileParts = [];
|
|
3592
3620
|
const warnings = options.webhookUrl == null ? [] : [
|
|
3593
3621
|
{
|
|
@@ -3609,7 +3637,7 @@ var XaiBatch = class {
|
|
|
3609
3637
|
JSON.stringify({
|
|
3610
3638
|
custom_id: request.id,
|
|
3611
3639
|
method: "POST",
|
|
3612
|
-
url:
|
|
3640
|
+
url: preparedRequest.endpoint,
|
|
3613
3641
|
body: preparedRequest.body
|
|
3614
3642
|
}),
|
|
3615
3643
|
"\n"
|
|
@@ -3776,12 +3804,12 @@ var XaiBatch = class {
|
|
|
3776
3804
|
validateUrl: false
|
|
3777
3805
|
});
|
|
3778
3806
|
for (const result of page.results) {
|
|
3779
|
-
yield await this.convertBatchResult(result);
|
|
3807
|
+
yield await this.convertBatchResult(result, options.abortSignal);
|
|
3780
3808
|
}
|
|
3781
3809
|
paginationToken = (_c = page.pagination_token) != null ? _c : void 0;
|
|
3782
3810
|
} while (paginationToken != null);
|
|
3783
3811
|
}
|
|
3784
|
-
async convertBatchResult(result) {
|
|
3812
|
+
async convertBatchResult(result, abortSignal) {
|
|
3785
3813
|
var _a, _b, _c, _d, _e, _f;
|
|
3786
3814
|
const error = (_a = result.batch_result) == null ? void 0 : _a.error;
|
|
3787
3815
|
if (((_c = (_b = result.error_message) == null ? void 0 : _b.length) != null ? _c : 0) > 0 || (error == null ? void 0 : error.code) != null && error.code !== 0 && error.code !== "0" || (error == null ? void 0 : error.code) == null && ((_e = (_d = error == null ? void 0 : error.message) == null ? void 0 : _d.length) != null ? _e : 0) > 0) {
|
|
@@ -3815,14 +3843,127 @@ var XaiBatch = class {
|
|
|
3815
3843
|
error: conversion.error
|
|
3816
3844
|
};
|
|
3817
3845
|
}
|
|
3846
|
+
if ((response == null ? void 0 : response.image_generation) != null) {
|
|
3847
|
+
const validation = await safeValidateTypes({
|
|
3848
|
+
value: response.image_generation,
|
|
3849
|
+
schema: zodSchema7(xaiBatchImageResponseSchema)
|
|
3850
|
+
});
|
|
3851
|
+
if (!validation.success) {
|
|
3852
|
+
return invalidXaiImageBatchResult(result.batch_request_id);
|
|
3853
|
+
}
|
|
3854
|
+
if (validation.value.data.some((image) => image.respect_moderation === false)) {
|
|
3855
|
+
return {
|
|
3856
|
+
type: "image",
|
|
3857
|
+
id: result.batch_request_id,
|
|
3858
|
+
status: "failed",
|
|
3859
|
+
error: {
|
|
3860
|
+
message: "Image generation was blocked due to a content policy violation."
|
|
3861
|
+
}
|
|
3862
|
+
};
|
|
3863
|
+
}
|
|
3864
|
+
const imageResult = await this.convertImageBatchResponse(
|
|
3865
|
+
validation.value,
|
|
3866
|
+
abortSignal
|
|
3867
|
+
);
|
|
3868
|
+
return {
|
|
3869
|
+
type: "image",
|
|
3870
|
+
id: result.batch_request_id,
|
|
3871
|
+
status: "succeeded",
|
|
3872
|
+
result: imageResult
|
|
3873
|
+
};
|
|
3874
|
+
}
|
|
3818
3875
|
return invalidXaiBatchResult(result.batch_request_id);
|
|
3819
3876
|
}
|
|
3820
3877
|
async prepareRequest(request) {
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3878
|
+
if (request.type === "text") {
|
|
3879
|
+
const { args: body2, warnings: warnings2 } = await XaiResponsesLanguageModel.prepareRequest({
|
|
3880
|
+
modelId: request.modelId,
|
|
3881
|
+
options: request.options
|
|
3882
|
+
});
|
|
3883
|
+
return { endpoint: xaiBatchEndpoint, body: body2, warnings: warnings2 };
|
|
3884
|
+
}
|
|
3885
|
+
const { prompt, n, size, aspectRatio, seed, files, mask, providerOptions } = request.options;
|
|
3886
|
+
const warnings = [];
|
|
3887
|
+
if (size != null) {
|
|
3888
|
+
warnings.push({
|
|
3889
|
+
type: "unsupported",
|
|
3890
|
+
feature: "size",
|
|
3891
|
+
details: "This model does not support the `size` option. Use `aspectRatio` instead."
|
|
3892
|
+
});
|
|
3893
|
+
}
|
|
3894
|
+
if (seed != null) warnings.push({ type: "unsupported", feature: "seed" });
|
|
3895
|
+
if (mask != null) warnings.push({ type: "unsupported", feature: "mask" });
|
|
3896
|
+
const xaiOptions = await parseProviderOptions6({
|
|
3897
|
+
provider: "xai",
|
|
3898
|
+
providerOptions,
|
|
3899
|
+
schema: xaiImageModelOptions
|
|
3824
3900
|
});
|
|
3825
|
-
|
|
3901
|
+
const imageUrls = (files != null ? files : []).map(convertImageModelFileToDataUri2);
|
|
3902
|
+
const body = {
|
|
3903
|
+
model: request.modelId,
|
|
3904
|
+
prompt,
|
|
3905
|
+
n,
|
|
3906
|
+
response_format: "b64_json"
|
|
3907
|
+
};
|
|
3908
|
+
if (aspectRatio != null) body.aspect_ratio = aspectRatio;
|
|
3909
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.output_format) != null)
|
|
3910
|
+
body.output_format = xaiOptions.output_format;
|
|
3911
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.sync_mode) != null) body.sync_mode = xaiOptions.sync_mode;
|
|
3912
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.aspect_ratio) != null && aspectRatio == null)
|
|
3913
|
+
body.aspect_ratio = xaiOptions.aspect_ratio;
|
|
3914
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.resolution) != null) body.resolution = xaiOptions.resolution;
|
|
3915
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.quality) != null) body.quality = xaiOptions.quality;
|
|
3916
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.user) != null) body.user = xaiOptions.user;
|
|
3917
|
+
if (imageUrls.length === 1) {
|
|
3918
|
+
body.image = { url: imageUrls[0], type: "image_url" };
|
|
3919
|
+
} else if (imageUrls.length > 1) {
|
|
3920
|
+
body.images = imageUrls.map((url) => ({ url, type: "image_url" }));
|
|
3921
|
+
}
|
|
3922
|
+
return {
|
|
3923
|
+
endpoint: (files == null ? void 0 : files.length) ? "/v1/images/edits" : "/v1/images/generations",
|
|
3924
|
+
body,
|
|
3925
|
+
warnings
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3928
|
+
async convertImageBatchResponse(response, abortSignal) {
|
|
3929
|
+
var _a;
|
|
3930
|
+
const hasAllBase64 = response.data.every((image) => image.b64_json != null);
|
|
3931
|
+
const images = hasAllBase64 ? response.data.map((image) => image.b64_json) : await Promise.all(
|
|
3932
|
+
response.data.map(async (image) => {
|
|
3933
|
+
if (image.b64_json != null) {
|
|
3934
|
+
return convertBase64ToUint8Array(image.b64_json);
|
|
3935
|
+
}
|
|
3936
|
+
if (image.url == null) {
|
|
3937
|
+
throw new InvalidArgumentError({
|
|
3938
|
+
argument: "batchResult",
|
|
3939
|
+
message: "xAI returned an image without data or a URL."
|
|
3940
|
+
});
|
|
3941
|
+
}
|
|
3942
|
+
const { value } = await getFromApi2({
|
|
3943
|
+
url: image.url,
|
|
3944
|
+
validateUrl: true,
|
|
3945
|
+
trustedOrigin: this.options.config.baseURL,
|
|
3946
|
+
abortSignal,
|
|
3947
|
+
failedResponseHandler: xaiFailedResponseHandler,
|
|
3948
|
+
successfulResponseHandler: createBinaryResponseHandler2(),
|
|
3949
|
+
fetch: this.options.config.fetch
|
|
3950
|
+
});
|
|
3951
|
+
return value;
|
|
3952
|
+
})
|
|
3953
|
+
);
|
|
3954
|
+
return {
|
|
3955
|
+
images,
|
|
3956
|
+
warnings: [],
|
|
3957
|
+
response: { timestamp: /* @__PURE__ */ new Date(), modelId: "", headers: void 0 },
|
|
3958
|
+
providerMetadata: {
|
|
3959
|
+
xai: {
|
|
3960
|
+
images: response.data.map(
|
|
3961
|
+
(item) => item.revised_prompt != null ? { revisedPrompt: item.revised_prompt } : {}
|
|
3962
|
+
),
|
|
3963
|
+
...((_a = response.usage) == null ? void 0 : _a.cost_in_usd_ticks) != null ? { costInUsdTicks: response.usage.cost_in_usd_ticks } : {}
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
};
|
|
3826
3967
|
}
|
|
3827
3968
|
getUrl(path) {
|
|
3828
3969
|
var _a;
|
|
@@ -3888,6 +4029,17 @@ function invalidXaiBatchResult(id) {
|
|
|
3888
4029
|
}
|
|
3889
4030
|
};
|
|
3890
4031
|
}
|
|
4032
|
+
function invalidXaiImageBatchResult(id) {
|
|
4033
|
+
return {
|
|
4034
|
+
type: "image",
|
|
4035
|
+
id,
|
|
4036
|
+
status: "failed",
|
|
4037
|
+
error: {
|
|
4038
|
+
message: "xAI returned an invalid image batch result.",
|
|
4039
|
+
code: "invalid_response"
|
|
4040
|
+
}
|
|
4041
|
+
};
|
|
4042
|
+
}
|
|
3891
4043
|
function convertXaiChatBatchResponse(response) {
|
|
3892
4044
|
var _a, _b, _c, _d, _e, _f;
|
|
3893
4045
|
if (response.error != null) {
|
|
@@ -4410,7 +4562,7 @@ var xaiTools = {
|
|
|
4410
4562
|
};
|
|
4411
4563
|
|
|
4412
4564
|
// src/version.ts
|
|
4413
|
-
var VERSION = true ? "4.0.
|
|
4565
|
+
var VERSION = true ? "4.0.58" : "0.0.0-test";
|
|
4414
4566
|
|
|
4415
4567
|
// src/files/xai-files.ts
|
|
4416
4568
|
import {
|
|
@@ -5204,8 +5356,8 @@ var xaiVideoStatusResponseHandler = async (options) => {
|
|
|
5204
5356
|
// src/xai-speech-model.ts
|
|
5205
5357
|
import {
|
|
5206
5358
|
combineHeaders as combineHeaders7,
|
|
5207
|
-
convertBase64ToUint8Array,
|
|
5208
|
-
createBinaryResponseHandler as
|
|
5359
|
+
convertBase64ToUint8Array as convertBase64ToUint8Array2,
|
|
5360
|
+
createBinaryResponseHandler as createBinaryResponseHandler3,
|
|
5209
5361
|
createJsonResponseHandler as createJsonResponseHandler7,
|
|
5210
5362
|
parseProviderOptions as parseProviderOptions9,
|
|
5211
5363
|
postJsonToApi as postJsonToApi6,
|
|
@@ -5367,7 +5519,7 @@ var XaiSpeechModel = class _XaiSpeechModel {
|
|
|
5367
5519
|
),
|
|
5368
5520
|
body: requestBody,
|
|
5369
5521
|
failedResponseHandler: xaiFailedResponseHandler,
|
|
5370
|
-
successfulResponseHandler: withTimestamps ? createJsonResponseHandler7(xaiSpeechTimestampsResponseSchema) :
|
|
5522
|
+
successfulResponseHandler: withTimestamps ? createJsonResponseHandler7(xaiSpeechTimestampsResponseSchema) : createBinaryResponseHandler3(),
|
|
5371
5523
|
abortSignal: options.abortSignal,
|
|
5372
5524
|
fetch: this.config.fetch
|
|
5373
5525
|
});
|
|
@@ -5377,7 +5529,7 @@ var XaiSpeechModel = class _XaiSpeechModel {
|
|
|
5377
5529
|
audio = value;
|
|
5378
5530
|
} else {
|
|
5379
5531
|
envelope = value;
|
|
5380
|
-
audio = envelope.audio != null ?
|
|
5532
|
+
audio = envelope.audio != null ? convertBase64ToUint8Array2(envelope.audio) : new Uint8Array(0);
|
|
5381
5533
|
}
|
|
5382
5534
|
const traceId = responseHeaders == null ? void 0 : responseHeaders["x-trace-id"];
|
|
5383
5535
|
return {
|
|
@@ -5424,7 +5576,7 @@ import {
|
|
|
5424
5576
|
} from "@ai-sdk/provider";
|
|
5425
5577
|
import {
|
|
5426
5578
|
combineHeaders as combineHeaders8,
|
|
5427
|
-
convertBase64ToUint8Array as
|
|
5579
|
+
convertBase64ToUint8Array as convertBase64ToUint8Array3,
|
|
5428
5580
|
createJsonResponseHandler as createJsonResponseHandler8,
|
|
5429
5581
|
connectToWebSocket,
|
|
5430
5582
|
mediaTypeToExtension,
|
|
@@ -5568,7 +5720,7 @@ var XaiTranscriptionModel = class _XaiTranscriptionModel {
|
|
|
5568
5720
|
formData.append("keyterm", keyterm);
|
|
5569
5721
|
}
|
|
5570
5722
|
}
|
|
5571
|
-
const blob = audio instanceof Uint8Array ? new Blob([audio]) : new Blob([
|
|
5723
|
+
const blob = audio instanceof Uint8Array ? new Blob([audio]) : new Blob([convertBase64ToUint8Array3(audio)]);
|
|
5572
5724
|
const fileExtension = mediaTypeToExtension(mediaType);
|
|
5573
5725
|
formData.append(
|
|
5574
5726
|
"file",
|
|
@@ -5727,7 +5879,7 @@ function createXaiStreamingTranscriptionStream({
|
|
|
5727
5879
|
const { done, value } = await audioReader.read();
|
|
5728
5880
|
if (done || finished) break;
|
|
5729
5881
|
socket.send(
|
|
5730
|
-
value instanceof Uint8Array ? value :
|
|
5882
|
+
value instanceof Uint8Array ? value : convertBase64ToUint8Array3(value)
|
|
5731
5883
|
);
|
|
5732
5884
|
await waitForWebSocketBufferDrain(socket);
|
|
5733
5885
|
}
|