@ai-sdk/xai 4.0.0-beta.2 → 4.0.0-beta.21

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/dist/index.mjs CHANGED
@@ -18,6 +18,8 @@ import {
18
18
  createEventSourceResponseHandler,
19
19
  createJsonResponseHandler,
20
20
  extractResponseHeaders,
21
+ isCustomReasoning,
22
+ mapReasoningToProviderEffort,
21
23
  parseProviderOptions,
22
24
  postJsonToApi,
23
25
  safeParseJSON
@@ -356,7 +358,7 @@ function prepareTools({
356
358
  // src/xai-chat-language-model.ts
357
359
  var XaiChatLanguageModel = class {
358
360
  constructor(modelId, config) {
359
- this.specificationVersion = "v3";
361
+ this.specificationVersion = "v4";
360
362
  this.supportedUrls = {
361
363
  "image/*": [/^https?:\/\/.*$/]
362
364
  };
@@ -376,12 +378,13 @@ var XaiChatLanguageModel = class {
376
378
  presencePenalty,
377
379
  stopSequences,
378
380
  seed,
381
+ reasoning,
379
382
  responseFormat,
380
383
  providerOptions,
381
384
  tools,
382
385
  toolChoice
383
386
  }) {
384
- var _a, _b, _c;
387
+ var _a, _b, _c, _d;
385
388
  const warnings = [];
386
389
  const options = (_a = await parseProviderOptions({
387
390
  provider: "xai",
@@ -421,14 +424,24 @@ var XaiChatLanguageModel = class {
421
424
  temperature,
422
425
  top_p: topP,
423
426
  seed,
424
- reasoning_effort: options.reasoningEffort,
427
+ reasoning_effort: (_b = options.reasoningEffort) != null ? _b : isCustomReasoning(reasoning) ? reasoning === "none" ? void 0 : mapReasoningToProviderEffort({
428
+ reasoning,
429
+ effortMap: {
430
+ minimal: "low",
431
+ low: "low",
432
+ medium: "low",
433
+ high: "high",
434
+ xhigh: "high"
435
+ },
436
+ warnings
437
+ }) : void 0,
425
438
  // parallel function calling
426
439
  parallel_function_calling: options.parallel_function_calling,
427
440
  // response format
428
441
  response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
429
442
  type: "json_schema",
430
443
  json_schema: {
431
- name: (_b = responseFormat.name) != null ? _b : "response",
444
+ name: (_c = responseFormat.name) != null ? _c : "response",
432
445
  schema: responseFormat.schema,
433
446
  strict: true
434
447
  }
@@ -440,7 +453,7 @@ var XaiChatLanguageModel = class {
440
453
  from_date: options.searchParameters.fromDate,
441
454
  to_date: options.searchParameters.toDate,
442
455
  max_search_results: options.searchParameters.maxSearchResults,
443
- sources: (_c = options.searchParameters.sources) == null ? void 0 : _c.map((source) => {
456
+ sources: (_d = options.searchParameters.sources) == null ? void 0 : _d.map((source) => {
444
457
  var _a2;
445
458
  return {
446
459
  type: source.type,
@@ -888,7 +901,9 @@ var xaiImageModelOptions = z4.object({
888
901
  aspect_ratio: z4.string().optional(),
889
902
  output_format: z4.string().optional(),
890
903
  sync_mode: z4.boolean().optional(),
891
- resolution: z4.enum(["1k", "2k"]).optional()
904
+ resolution: z4.enum(["1k", "2k"]).optional(),
905
+ quality: z4.enum(["low", "medium", "high"]).optional(),
906
+ user: z4.string().optional()
892
907
  });
893
908
 
894
909
  // src/xai-image-model.ts
@@ -896,8 +911,8 @@ var XaiImageModel = class {
896
911
  constructor(modelId, config) {
897
912
  this.modelId = modelId;
898
913
  this.config = config;
899
- this.specificationVersion = "v3";
900
- this.maxImagesPerCall = 1;
914
+ this.specificationVersion = "v4";
915
+ this.maxImagesPerCall = 3;
901
916
  }
902
917
  get provider() {
903
918
  return this.config.provider;
@@ -914,7 +929,7 @@ var XaiImageModel = class {
914
929
  files,
915
930
  mask
916
931
  }) {
917
- var _a, _b, _c, _d;
932
+ var _a, _b, _c, _d, _e;
918
933
  const warnings = [];
919
934
  if (size != null) {
920
935
  warnings.push({
@@ -941,22 +956,13 @@ var XaiImageModel = class {
941
956
  schema: xaiImageModelOptions
942
957
  });
943
958
  const hasFiles = files != null && files.length > 0;
944
- let imageUrl;
945
- if (hasFiles) {
946
- imageUrl = convertImageModelFileToDataUri(files[0]);
947
- if (files.length > 1) {
948
- warnings.push({
949
- type: "other",
950
- message: "xAI only supports a single input image. Additional images are ignored."
951
- });
952
- }
953
- }
959
+ const imageUrls = hasFiles ? files.map((file) => convertImageModelFileToDataUri(file)) : [];
954
960
  const endpoint = hasFiles ? "/images/edits" : "/images/generations";
955
961
  const body = {
956
962
  model: this.modelId,
957
963
  prompt,
958
964
  n,
959
- response_format: "url"
965
+ response_format: "b64_json"
960
966
  };
961
967
  if (aspectRatio != null) {
962
968
  body.aspect_ratio = aspectRatio;
@@ -973,8 +979,16 @@ var XaiImageModel = class {
973
979
  if ((xaiOptions == null ? void 0 : xaiOptions.resolution) != null) {
974
980
  body.resolution = xaiOptions.resolution;
975
981
  }
976
- if (imageUrl != null) {
977
- body.image = { url: imageUrl, type: "image_url" };
982
+ if ((xaiOptions == null ? void 0 : xaiOptions.quality) != null) {
983
+ body.quality = xaiOptions.quality;
984
+ }
985
+ if ((xaiOptions == null ? void 0 : xaiOptions.user) != null) {
986
+ body.user = xaiOptions.user;
987
+ }
988
+ if (imageUrls.length === 1) {
989
+ body.image = { url: imageUrls[0], type: "image_url" };
990
+ } else if (imageUrls.length > 1) {
991
+ body.images = imageUrls.map((url) => ({ url, type: "image_url" }));
978
992
  }
979
993
  const baseURL = (_a = this.config.baseURL) != null ? _a : "https://api.x.ai/v1";
980
994
  const currentDate = (_d = (_c = (_b = this.config._internal) == null ? void 0 : _b.currentDate) == null ? void 0 : _c.call(_b)) != null ? _d : /* @__PURE__ */ new Date();
@@ -989,11 +1003,14 @@ var XaiImageModel = class {
989
1003
  abortSignal,
990
1004
  fetch: this.config.fetch
991
1005
  });
992
- const downloadedImages = await Promise.all(
993
- response.data.map((image) => this.downloadImage(image.url, abortSignal))
1006
+ const hasAllBase64 = response.data.every((image) => image.b64_json != null);
1007
+ const images = hasAllBase64 ? response.data.map((image) => image.b64_json) : await Promise.all(
1008
+ response.data.map(
1009
+ (image) => this.downloadImage(image.url, abortSignal)
1010
+ )
994
1011
  );
995
1012
  return {
996
- images: downloadedImages,
1013
+ images,
997
1014
  warnings,
998
1015
  response: {
999
1016
  timestamp: currentDate,
@@ -1004,7 +1021,8 @@ var XaiImageModel = class {
1004
1021
  xai: {
1005
1022
  images: response.data.map((item) => ({
1006
1023
  ...item.revised_prompt ? { revisedPrompt: item.revised_prompt } : {}
1007
- }))
1024
+ })),
1025
+ ...((_e = response.usage) == null ? void 0 : _e.cost_in_usd_ticks) != null ? { costInUsdTicks: response.usage.cost_in_usd_ticks } : {}
1008
1026
  }
1009
1027
  }
1010
1028
  };
@@ -1023,10 +1041,14 @@ var XaiImageModel = class {
1023
1041
  var xaiImageResponseSchema = z5.object({
1024
1042
  data: z5.array(
1025
1043
  z5.object({
1026
- url: z5.string(),
1044
+ url: z5.string().nullish(),
1045
+ b64_json: z5.string().nullish(),
1027
1046
  revised_prompt: z5.string().nullish()
1028
1047
  })
1029
- )
1048
+ ),
1049
+ usage: z5.object({
1050
+ cost_in_usd_ticks: z5.number().nullish()
1051
+ }).nullish()
1030
1052
  });
1031
1053
 
1032
1054
  // src/responses/xai-responses-language-model.ts
@@ -1034,6 +1056,8 @@ import {
1034
1056
  combineHeaders as combineHeaders3,
1035
1057
  createEventSourceResponseHandler as createEventSourceResponseHandler2,
1036
1058
  createJsonResponseHandler as createJsonResponseHandler3,
1059
+ isCustomReasoning as isCustomReasoning2,
1060
+ mapReasoningToProviderEffort as mapReasoningToProviderEffort2,
1037
1061
  parseProviderOptions as parseProviderOptions3,
1038
1062
  postJsonToApi as postJsonToApi3
1039
1063
  } from "@ai-sdk/provider-utils";
@@ -1124,6 +1148,8 @@ async function convertToXaiResponsesInput({
1124
1148
  break;
1125
1149
  }
1126
1150
  case "reasoning":
1151
+ case "reasoning-file":
1152
+ case "custom":
1127
1153
  case "file": {
1128
1154
  inputWarnings.push({
1129
1155
  type: "other",
@@ -1339,6 +1365,7 @@ var outputItemSchema = z6.discriminatedUnion("type", [
1339
1365
  type: z6.literal("reasoning"),
1340
1366
  id: z6.string(),
1341
1367
  summary: z6.array(reasoningSummaryPartSchema),
1368
+ content: z6.array(z6.object({ type: z6.string(), text: z6.string() })).nullish(),
1342
1369
  status: z6.string(),
1343
1370
  encrypted_content: z6.string().nullish()
1344
1371
  })
@@ -1645,6 +1672,7 @@ var xaiLanguageModelResponsesOptions = z7.object({
1645
1672
  * Possible values are `low` (uses fewer reasoning tokens), `medium` and `high` (uses more reasoning tokens).
1646
1673
  */
1647
1674
  reasoningEffort: z7.enum(["low", "medium", "high"]).optional(),
1675
+ reasoningSummary: z7.enum(["auto", "concise", "detailed"]).optional(),
1648
1676
  logprobs: z7.boolean().optional(),
1649
1677
  topLogprobs: z7.number().int().min(0).max(8).optional(),
1650
1678
  /**
@@ -1972,7 +2000,7 @@ async function prepareResponsesTools({
1972
2000
  // src/responses/xai-responses-language-model.ts
1973
2001
  var XaiResponsesLanguageModel = class {
1974
2002
  constructor(modelId, config) {
1975
- this.specificationVersion = "v3";
2003
+ this.specificationVersion = "v4";
1976
2004
  this.supportedUrls = {
1977
2005
  "image/*": [/^https?:\/\/.*$/]
1978
2006
  };
@@ -1992,9 +2020,10 @@ var XaiResponsesLanguageModel = class {
1992
2020
  responseFormat,
1993
2021
  providerOptions,
1994
2022
  tools,
1995
- toolChoice
2023
+ toolChoice,
2024
+ reasoning
1996
2025
  }) {
1997
- var _a, _b, _c, _d, _e, _f, _g;
2026
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1998
2027
  const warnings = [];
1999
2028
  const options = (_a = await parseProviderOptions3({
2000
2029
  provider: "xai",
@@ -2041,6 +2070,17 @@ var XaiResponsesLanguageModel = class {
2041
2070
  include = [...include, "reasoning.encrypted_content"];
2042
2071
  }
2043
2072
  }
2073
+ const resolvedReasoningEffort = (_g = options.reasoningEffort) != null ? _g : isCustomReasoning2(reasoning) ? reasoning === "none" ? void 0 : mapReasoningToProviderEffort2({
2074
+ reasoning,
2075
+ effortMap: {
2076
+ minimal: "low",
2077
+ low: "low",
2078
+ medium: "medium",
2079
+ high: "high",
2080
+ xhigh: "high"
2081
+ },
2082
+ warnings
2083
+ }) : void 0;
2044
2084
  const baseArgs = {
2045
2085
  model: this.modelId,
2046
2086
  input,
@@ -2055,14 +2095,21 @@ var XaiResponsesLanguageModel = class {
2055
2095
  format: responseFormat.schema != null ? {
2056
2096
  type: "json_schema",
2057
2097
  strict: true,
2058
- name: (_g = responseFormat.name) != null ? _g : "response",
2098
+ name: (_h = responseFormat.name) != null ? _h : "response",
2059
2099
  description: responseFormat.description,
2060
2100
  schema: responseFormat.schema
2061
2101
  } : { type: "json_object" }
2062
2102
  }
2063
2103
  },
2064
- ...options.reasoningEffort != null && {
2065
- reasoning: { effort: options.reasoningEffort }
2104
+ ...(resolvedReasoningEffort != null || options.reasoningSummary != null) && {
2105
+ reasoning: {
2106
+ ...resolvedReasoningEffort != null && {
2107
+ effort: resolvedReasoningEffort
2108
+ },
2109
+ ...options.reasoningSummary != null && {
2110
+ summary: options.reasoningSummary
2111
+ }
2112
+ }
2066
2113
  },
2067
2114
  ...options.store === false && {
2068
2115
  store: options.store
@@ -2091,7 +2138,7 @@ var XaiResponsesLanguageModel = class {
2091
2138
  };
2092
2139
  }
2093
2140
  async doGenerate(options) {
2094
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
2141
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
2095
2142
  const {
2096
2143
  args: body,
2097
2144
  warnings,
@@ -2117,6 +2164,7 @@ var XaiResponsesLanguageModel = class {
2117
2164
  fetch: this.config.fetch
2118
2165
  });
2119
2166
  const content = [];
2167
+ let hasFunctionCall = false;
2120
2168
  const webSearchSubTools = [
2121
2169
  "web_search",
2122
2170
  "web_search_with_snippets",
@@ -2201,6 +2249,7 @@ var XaiResponsesLanguageModel = class {
2201
2249
  break;
2202
2250
  }
2203
2251
  case "function_call": {
2252
+ hasFunctionCall = true;
2204
2253
  content.push({
2205
2254
  type: "tool-call",
2206
2255
  toolCallId: part.call_id,
@@ -2210,9 +2259,9 @@ var XaiResponsesLanguageModel = class {
2210
2259
  break;
2211
2260
  }
2212
2261
  case "reasoning": {
2213
- const summaryTexts = part.summary.map((s) => s.text).filter((text) => text && text.length > 0);
2214
- if (summaryTexts.length > 0) {
2215
- const reasoningText = summaryTexts.join("");
2262
+ const texts = part.summary.length > 0 ? part.summary.map((s) => s.text) : ((_m = part.content) != null ? _m : []).map((c) => c.text);
2263
+ const reasoningText = texts.filter((text) => text && text.length > 0).join("");
2264
+ if (reasoningText) {
2216
2265
  if (part.encrypted_content || part.id) {
2217
2266
  content.push({
2218
2267
  type: "reasoning",
@@ -2243,8 +2292,8 @@ var XaiResponsesLanguageModel = class {
2243
2292
  return {
2244
2293
  content,
2245
2294
  finishReason: {
2246
- unified: mapXaiResponsesFinishReason(response.status),
2247
- raw: (_m = response.status) != null ? _m : void 0
2295
+ unified: hasFunctionCall ? "tool-calls" : mapXaiResponsesFinishReason(response.status),
2296
+ raw: (_n = response.status) != null ? _n : void 0
2248
2297
  },
2249
2298
  usage: response.usage ? convertXaiResponsesUsage(response.usage) : {
2250
2299
  inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },
@@ -2289,6 +2338,7 @@ var XaiResponsesLanguageModel = class {
2289
2338
  unified: "other",
2290
2339
  raw: void 0
2291
2340
  };
2341
+ let hasFunctionCall = false;
2292
2342
  let usage = void 0;
2293
2343
  let isFirstChunk = true;
2294
2344
  const contentBlocks = {};
@@ -2433,7 +2483,7 @@ var XaiResponsesLanguageModel = class {
2433
2483
  }
2434
2484
  if (response2.status) {
2435
2485
  finishReason = {
2436
- unified: mapXaiResponsesFinishReason(response2.status),
2486
+ unified: hasFunctionCall ? "tool-calls" : mapXaiResponsesFinishReason(response2.status),
2437
2487
  raw: response2.status
2438
2488
  };
2439
2489
  }
@@ -2626,6 +2676,7 @@ var XaiResponsesLanguageModel = class {
2626
2676
  toolName: part.name
2627
2677
  });
2628
2678
  } else if (event.type === "response.output_item.done") {
2679
+ hasFunctionCall = true;
2629
2680
  ongoingToolCalls[event.output_index] = void 0;
2630
2681
  controller.enqueue({
2631
2682
  type: "tool-input-end",
@@ -2727,7 +2778,7 @@ var xaiTools = {
2727
2778
  };
2728
2779
 
2729
2780
  // src/version.ts
2730
- var VERSION = true ? "4.0.0-beta.2" : "0.0.0-test";
2781
+ var VERSION = true ? "4.0.0-beta.21" : "0.0.0-test";
2731
2782
 
2732
2783
  // src/xai-video-model.ts
2733
2784
  import {
@@ -2768,14 +2819,14 @@ var XaiVideoModel = class {
2768
2819
  constructor(modelId, config) {
2769
2820
  this.modelId = modelId;
2770
2821
  this.config = config;
2771
- this.specificationVersion = "v3";
2822
+ this.specificationVersion = "v4";
2772
2823
  this.maxVideosPerCall = 1;
2773
2824
  }
2774
2825
  get provider() {
2775
2826
  return this.config.provider;
2776
2827
  }
2777
2828
  async doGenerate(options) {
2778
- var _a, _b, _c, _d, _e, _f, _g, _h;
2829
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2779
2830
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
2780
2831
  const warnings = [];
2781
2832
  const xaiOptions = await parseProviderOptions4({
@@ -2918,7 +2969,13 @@ var XaiVideoModel = class {
2918
2969
  });
2919
2970
  responseHeaders = pollHeaders;
2920
2971
  if (statusResponse.status === "done" || statusResponse.status == null && ((_g = statusResponse.video) == null ? void 0 : _g.url)) {
2921
- if (!((_h = statusResponse.video) == null ? void 0 : _h.url)) {
2972
+ if (((_h = statusResponse.video) == null ? void 0 : _h.respect_moderation) === false) {
2973
+ throw new AISDKError({
2974
+ name: "XAI_VIDEO_MODERATION_ERROR",
2975
+ message: "Video generation was blocked due to a content policy violation."
2976
+ });
2977
+ }
2978
+ if (!((_i = statusResponse.video) == null ? void 0 : _i.url)) {
2922
2979
  throw new AISDKError({
2923
2980
  name: "XAI_VIDEO_GENERATION_ERROR",
2924
2981
  message: "Video generation completed but no video URL was returned."
@@ -2942,7 +2999,8 @@ var XaiVideoModel = class {
2942
2999
  xai: {
2943
3000
  requestId,
2944
3001
  videoUrl: statusResponse.video.url,
2945
- ...statusResponse.video.duration != null ? { duration: statusResponse.video.duration } : {}
3002
+ ...statusResponse.video.duration != null ? { duration: statusResponse.video.duration } : {},
3003
+ ...((_j = statusResponse.usage) == null ? void 0 : _j.cost_in_usd_ticks) != null ? { costInUsdTicks: statusResponse.usage.cost_in_usd_ticks } : {}
2946
3004
  }
2947
3005
  }
2948
3006
  };
@@ -2966,7 +3024,10 @@ var xaiVideoStatusResponseSchema = z16.object({
2966
3024
  duration: z16.number().nullish(),
2967
3025
  respect_moderation: z16.boolean().nullish()
2968
3026
  }).nullish(),
2969
- model: z16.string().nullish()
3027
+ model: z16.string().nullish(),
3028
+ usage: z16.object({
3029
+ cost_in_usd_ticks: z16.number().nullish()
3030
+ }).nullish()
2970
3031
  });
2971
3032
 
2972
3033
  // src/xai-provider.ts
@@ -3020,9 +3081,9 @@ function createXai(options = {}) {
3020
3081
  fetch: options.fetch
3021
3082
  });
3022
3083
  };
3023
- const provider = (modelId) => createChatLanguageModel(modelId);
3024
- provider.specificationVersion = "v3";
3025
- provider.languageModel = createChatLanguageModel;
3084
+ const provider = (modelId) => createResponsesLanguageModel(modelId);
3085
+ provider.specificationVersion = "v4";
3086
+ provider.languageModel = createResponsesLanguageModel;
3026
3087
  provider.chat = createChatLanguageModel;
3027
3088
  provider.responses = createResponsesLanguageModel;
3028
3089
  provider.embeddingModel = (modelId) => {