@ai-sdk/xai 4.0.0-beta.3 → 4.0.0-beta.30

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
- LanguageModelV3CallOptions,
3
- SharedV3Warning,
2
+ LanguageModelV4CallOptions,
3
+ SharedV4Warning,
4
4
  UnsupportedFunctionalityError,
5
5
  } from '@ai-sdk/provider';
6
6
  import { validateTypes } from '@ai-sdk/provider-utils';
@@ -20,16 +20,16 @@ export async function prepareResponsesTools({
20
20
  tools,
21
21
  toolChoice,
22
22
  }: {
23
- tools: LanguageModelV3CallOptions['tools'];
24
- toolChoice?: LanguageModelV3CallOptions['toolChoice'];
23
+ tools: LanguageModelV4CallOptions['tools'];
24
+ toolChoice?: LanguageModelV4CallOptions['toolChoice'];
25
25
  }): Promise<{
26
26
  tools: Array<XaiResponsesTool> | undefined;
27
27
  toolChoice: XaiResponsesToolChoice | undefined;
28
- toolWarnings: SharedV3Warning[];
28
+ toolWarnings: SharedV4Warning[];
29
29
  }> {
30
30
  const normalizedTools = tools?.length ? tools : undefined;
31
31
 
32
- const toolWarnings: SharedV3Warning[] = [];
32
+ const toolWarnings: SharedV4Warning[] = [];
33
33
 
34
34
  if (normalizedTools == null) {
35
35
  return { tools: undefined, toolChoice: undefined, toolWarnings };
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  APICallError,
3
- LanguageModelV3,
4
- LanguageModelV3CallOptions,
5
- LanguageModelV3Content,
6
- LanguageModelV3FinishReason,
7
- LanguageModelV3GenerateResult,
8
- LanguageModelV3StreamPart,
9
- LanguageModelV3StreamResult,
10
- LanguageModelV3Usage,
11
- SharedV3Warning,
3
+ LanguageModelV4,
4
+ LanguageModelV4CallOptions,
5
+ LanguageModelV4Content,
6
+ LanguageModelV4FinishReason,
7
+ LanguageModelV4GenerateResult,
8
+ LanguageModelV4StreamPart,
9
+ LanguageModelV4StreamResult,
10
+ LanguageModelV4Usage,
11
+ SharedV4Warning,
12
12
  } from '@ai-sdk/provider';
13
13
  import {
14
14
  combineHeaders,
@@ -16,6 +16,8 @@ import {
16
16
  createJsonResponseHandler,
17
17
  extractResponseHeaders,
18
18
  FetchFunction,
19
+ isCustomReasoning,
20
+ mapReasoningToProviderEffort,
19
21
  parseProviderOptions,
20
22
  ParseResult,
21
23
  postJsonToApi,
@@ -41,8 +43,8 @@ type XaiChatConfig = {
41
43
  fetch?: FetchFunction;
42
44
  };
43
45
 
44
- export class XaiChatLanguageModel implements LanguageModelV3 {
45
- readonly specificationVersion = 'v3';
46
+ export class XaiChatLanguageModel implements LanguageModelV4 {
47
+ readonly specificationVersion = 'v4';
46
48
 
47
49
  readonly modelId: XaiChatModelId;
48
50
 
@@ -71,12 +73,13 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
71
73
  presencePenalty,
72
74
  stopSequences,
73
75
  seed,
76
+ reasoning,
74
77
  responseFormat,
75
78
  providerOptions,
76
79
  tools,
77
80
  toolChoice,
78
- }: LanguageModelV3CallOptions) {
79
- const warnings: SharedV3Warning[] = [];
81
+ }: LanguageModelV4CallOptions) {
82
+ const warnings: SharedV4Warning[] = [];
80
83
 
81
84
  // parse xai-specific provider options
82
85
  const options =
@@ -133,7 +136,23 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
133
136
  temperature,
134
137
  top_p: topP,
135
138
  seed,
136
- reasoning_effort: options.reasoningEffort,
139
+ reasoning_effort:
140
+ options.reasoningEffort ??
141
+ (isCustomReasoning(reasoning)
142
+ ? reasoning === 'none'
143
+ ? undefined
144
+ : mapReasoningToProviderEffort({
145
+ reasoning,
146
+ effortMap: {
147
+ minimal: 'low',
148
+ low: 'low',
149
+ medium: 'low',
150
+ high: 'high',
151
+ xhigh: 'high',
152
+ },
153
+ warnings,
154
+ })
155
+ : undefined),
137
156
 
138
157
  // parallel function calling
139
158
  parallel_function_calling: options.parallel_function_calling,
@@ -202,8 +221,8 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
202
221
  }
203
222
 
204
223
  async doGenerate(
205
- options: LanguageModelV3CallOptions,
206
- ): Promise<LanguageModelV3GenerateResult> {
224
+ options: LanguageModelV4CallOptions,
225
+ ): Promise<LanguageModelV4GenerateResult> {
207
226
  const { args: body, warnings } = await this.getArgs(options);
208
227
 
209
228
  const url = `${this.config.baseURL ?? 'https://api.x.ai/v1'}/chat/completions`;
@@ -237,7 +256,7 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
237
256
  }
238
257
 
239
258
  const choice = response.choices![0];
240
- const content: Array<LanguageModelV3Content> = [];
259
+ const content: Array<LanguageModelV4Content> = [];
241
260
 
242
261
  // extract text content
243
262
  if (choice.message.content != null && choice.message.content.length > 0) {
@@ -312,8 +331,8 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
312
331
  }
313
332
 
314
333
  async doStream(
315
- options: LanguageModelV3CallOptions,
316
- ): Promise<LanguageModelV3StreamResult> {
334
+ options: LanguageModelV4CallOptions,
335
+ ): Promise<LanguageModelV4StreamResult> {
317
336
  const { args, warnings } = await this.getArgs(options);
318
337
  const body = {
319
338
  ...args,
@@ -375,11 +394,11 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
375
394
  fetch: this.config.fetch,
376
395
  });
377
396
 
378
- let finishReason: LanguageModelV3FinishReason = {
397
+ let finishReason: LanguageModelV4FinishReason = {
379
398
  unified: 'other',
380
399
  raw: undefined,
381
400
  };
382
- let usage: LanguageModelV3Usage | undefined = undefined;
401
+ let usage: LanguageModelV4Usage | undefined = undefined;
383
402
  let isFirstChunk = true;
384
403
  const contentBlocks: Record<
385
404
  string,
@@ -394,7 +413,7 @@ export class XaiChatLanguageModel implements LanguageModelV3 {
394
413
  stream: response.pipeThrough(
395
414
  new TransformStream<
396
415
  ParseResult<z.infer<typeof xaiChatChunkSchema>>,
397
- LanguageModelV3StreamPart
416
+ LanguageModelV4StreamPart
398
417
  >({
399
418
  start(controller) {
400
419
  controller.enqueue({ type: 'stream-start', warnings });
@@ -6,6 +6,9 @@ export type XaiChatModelId =
6
6
  | 'grok-4-1-fast-non-reasoning'
7
7
  | 'grok-4-fast-non-reasoning'
8
8
  | 'grok-4-fast-reasoning'
9
+ | 'grok-4.20-0309-non-reasoning'
10
+ | 'grok-4.20-0309-reasoning'
11
+ | 'grok-4.20-multi-agent-0309'
9
12
  | 'grok-code-fast-1'
10
13
  | 'grok-4'
11
14
  | 'grok-4-0709'
@@ -14,12 +17,6 @@ export type XaiChatModelId =
14
17
  | 'grok-3-latest'
15
18
  | 'grok-3-mini'
16
19
  | 'grok-3-mini-latest'
17
- | 'grok-2-vision-1212'
18
- | 'grok-2-vision'
19
- | 'grok-2-vision-latest'
20
- | 'grok-2-image-1212'
21
- | 'grok-2-image'
22
- | 'grok-2-image-latest'
23
20
  | (string & {});
24
21
 
25
22
  // search source schemas
@@ -18,7 +18,8 @@ export interface XaiUserMessage {
18
18
 
19
19
  export type XaiUserMessageContent =
20
20
  | { type: 'text'; text: string }
21
- | { type: 'image_url'; image_url: { url: string } };
21
+ | { type: 'image_url'; image_url: { url: string } }
22
+ | { type: 'file'; file: { file_id: string } };
22
23
 
23
24
  export interface XaiAssistantMessage {
24
25
  role: 'assistant';
@@ -1,4 +1,4 @@
1
- import { ImageModelV3, SharedV3Warning } from '@ai-sdk/provider';
1
+ import { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';
2
2
  import {
3
3
  combineHeaders,
4
4
  convertImageModelFileToDataUri,
@@ -25,8 +25,8 @@ interface XaiImageModelConfig {
25
25
  };
26
26
  }
27
27
 
28
- export class XaiImageModel implements ImageModelV3 {
29
- readonly specificationVersion = 'v3';
28
+ export class XaiImageModel implements ImageModelV4 {
29
+ readonly specificationVersion = 'v4';
30
30
  readonly maxImagesPerCall = 3;
31
31
 
32
32
  get provider(): string {
@@ -49,10 +49,10 @@ export class XaiImageModel implements ImageModelV3 {
49
49
  abortSignal,
50
50
  files,
51
51
  mask,
52
- }: Parameters<ImageModelV3['doGenerate']>[0]): Promise<
53
- Awaited<ReturnType<ImageModelV3['doGenerate']>>
52
+ }: Parameters<ImageModelV4['doGenerate']>[0]): Promise<
53
+ Awaited<ReturnType<ImageModelV4['doGenerate']>>
54
54
  > {
55
- const warnings: Array<SharedV3Warning> = [];
55
+ const warnings: Array<SharedV4Warning> = [];
56
56
 
57
57
  if (size != null) {
58
58
  warnings.push({
@@ -94,7 +94,7 @@ export class XaiImageModel implements ImageModelV3 {
94
94
  model: this.modelId,
95
95
  prompt,
96
96
  n,
97
- response_format: 'url',
97
+ response_format: 'b64_json',
98
98
  };
99
99
 
100
100
  if (aspectRatio != null) {
@@ -117,6 +117,14 @@ export class XaiImageModel implements ImageModelV3 {
117
117
  body.resolution = xaiOptions.resolution;
118
118
  }
119
119
 
120
+ if (xaiOptions?.quality != null) {
121
+ body.quality = xaiOptions.quality;
122
+ }
123
+
124
+ if (xaiOptions?.user != null) {
125
+ body.user = xaiOptions.user;
126
+ }
127
+
120
128
  if (imageUrls.length === 1) {
121
129
  body.image = { url: imageUrls[0], type: 'image_url' };
122
130
  } else if (imageUrls.length > 1) {
@@ -137,12 +145,18 @@ export class XaiImageModel implements ImageModelV3 {
137
145
  fetch: this.config.fetch,
138
146
  });
139
147
 
140
- const downloadedImages = await Promise.all(
141
- response.data.map(image => this.downloadImage(image.url, abortSignal)),
142
- );
148
+ const hasAllBase64 = response.data.every(image => image.b64_json != null);
149
+
150
+ const images = hasAllBase64
151
+ ? response.data.map(image => image.b64_json!)
152
+ : await Promise.all(
153
+ response.data.map(image =>
154
+ this.downloadImage(image.url!, abortSignal),
155
+ ),
156
+ );
143
157
 
144
158
  return {
145
- images: downloadedImages,
159
+ images,
146
160
  warnings,
147
161
  response: {
148
162
  timestamp: currentDate,
@@ -156,6 +170,9 @@ export class XaiImageModel implements ImageModelV3 {
156
170
  ? { revisedPrompt: item.revised_prompt }
157
171
  : {}),
158
172
  })),
173
+ ...(response.usage?.cost_in_usd_ticks != null
174
+ ? { costInUsdTicks: response.usage.cost_in_usd_ticks }
175
+ : {}),
159
176
  },
160
177
  },
161
178
  };
@@ -179,8 +196,14 @@ export class XaiImageModel implements ImageModelV3 {
179
196
  const xaiImageResponseSchema = z.object({
180
197
  data: z.array(
181
198
  z.object({
182
- url: z.string(),
199
+ url: z.string().nullish(),
200
+ b64_json: z.string().nullish(),
183
201
  revised_prompt: z.string().nullish(),
184
202
  }),
185
203
  ),
204
+ usage: z
205
+ .object({
206
+ cost_in_usd_ticks: z.number().nullish(),
207
+ })
208
+ .nullish(),
186
209
  });
@@ -5,6 +5,8 @@ export const xaiImageModelOptions = z.object({
5
5
  output_format: z.string().optional(),
6
6
  sync_mode: z.boolean().optional(),
7
7
  resolution: z.enum(['1k', '2k']).optional(),
8
+ quality: z.enum(['low', 'medium', 'high']).optional(),
9
+ user: z.string().optional(),
8
10
  });
9
11
 
10
12
  export type XaiImageModelOptions = z.infer<typeof xaiImageModelOptions>;
@@ -1,6 +1,4 @@
1
1
  export type XaiImageModelId =
2
- | 'grok-2-image'
3
- | 'grok-2-image-1212'
4
2
  | 'grok-imagine-image'
5
3
  | 'grok-imagine-image-pro'
6
4
  | (string & {});
@@ -1,6 +1,6 @@
1
1
  import {
2
- LanguageModelV3CallOptions,
3
- SharedV3Warning,
2
+ LanguageModelV4CallOptions,
3
+ SharedV4Warning,
4
4
  UnsupportedFunctionalityError,
5
5
  } from '@ai-sdk/provider';
6
6
  import { XaiToolChoice } from './xai-chat-prompt';
@@ -9,8 +9,8 @@ export function prepareTools({
9
9
  tools,
10
10
  toolChoice,
11
11
  }: {
12
- tools: LanguageModelV3CallOptions['tools'];
13
- toolChoice?: LanguageModelV3CallOptions['toolChoice'];
12
+ tools: LanguageModelV4CallOptions['tools'];
13
+ toolChoice?: LanguageModelV4CallOptions['toolChoice'];
14
14
  }): {
15
15
  tools:
16
16
  | Array<{
@@ -24,12 +24,12 @@ export function prepareTools({
24
24
  }>
25
25
  | undefined;
26
26
  toolChoice: XaiToolChoice | undefined;
27
- toolWarnings: SharedV3Warning[];
27
+ toolWarnings: SharedV4Warning[];
28
28
  } {
29
29
  // when the tools array is empty, change it to undefined to prevent errors
30
30
  tools = tools?.length ? tools : undefined;
31
31
 
32
- const toolWarnings: SharedV3Warning[] = [];
32
+ const toolWarnings: SharedV4Warning[] = [];
33
33
 
34
34
  if (tools == null) {
35
35
  return { tools: undefined, toolChoice: undefined, toolWarnings };
@@ -1,9 +1,10 @@
1
1
  import {
2
- type Experimental_VideoModelV3,
3
- ImageModelV3,
4
- LanguageModelV3,
2
+ type Experimental_VideoModelV4,
3
+ FilesV4,
4
+ ImageModelV4,
5
+ LanguageModelV4,
5
6
  NoSuchModelError,
6
- ProviderV3,
7
+ ProviderV4,
7
8
  } from '@ai-sdk/provider';
8
9
  import {
9
10
  FetchFunction,
@@ -20,49 +21,52 @@ import { XaiResponsesLanguageModel } from './responses/xai-responses-language-mo
20
21
  import { XaiResponsesModelId } from './responses/xai-responses-options';
21
22
  import { xaiTools } from './tool';
22
23
  import { VERSION } from './version';
24
+ import { XaiFiles } from './files/xai-files';
23
25
  import { XaiVideoModel } from './xai-video-model';
24
26
  import { XaiVideoModelId } from './xai-video-settings';
25
27
 
26
- export interface XaiProvider extends ProviderV3 {
27
- /**
28
- * Creates an Xai chat model for text generation.
29
- */
30
- (modelId: XaiChatModelId): LanguageModelV3;
28
+ export interface XaiProvider extends ProviderV4 {
29
+ (modelId: XaiResponsesModelId): LanguageModelV4;
31
30
 
32
31
  /**
33
32
  * Creates an Xai language model for text generation.
34
33
  */
35
- languageModel(modelId: XaiChatModelId): LanguageModelV3;
34
+ languageModel(modelId: XaiResponsesModelId): LanguageModelV4;
36
35
 
37
36
  /**
38
37
  * Creates an Xai chat model for text generation.
39
38
  */
40
- chat: (modelId: XaiChatModelId) => LanguageModelV3;
39
+ chat: (modelId: XaiChatModelId) => LanguageModelV4;
41
40
 
42
41
  /**
43
- * Creates an Xai responses model for agentic tool calling.
42
+ * Creates an Xai responses model for text generation.
44
43
  */
45
- responses: (modelId: XaiResponsesModelId) => LanguageModelV3;
44
+ responses: (modelId: XaiResponsesModelId) => LanguageModelV4;
46
45
 
47
46
  /**
48
47
  * Creates an Xai image model for image generation.
49
48
  */
50
- image(modelId: XaiImageModelId): ImageModelV3;
49
+ image(modelId: XaiImageModelId): ImageModelV4;
51
50
 
52
51
  /**
53
52
  * Creates an Xai image model for image generation.
54
53
  */
55
- imageModel(modelId: XaiImageModelId): ImageModelV3;
54
+ imageModel(modelId: XaiImageModelId): ImageModelV4;
56
55
 
57
56
  /**
58
57
  * Creates an Xai video model for video generation.
59
58
  */
60
- video(modelId: XaiVideoModelId): Experimental_VideoModelV3;
59
+ video(modelId: XaiVideoModelId): Experimental_VideoModelV4;
61
60
 
62
61
  /**
63
62
  * Creates an Xai video model for video generation.
64
63
  */
65
- videoModel(modelId: XaiVideoModelId): Experimental_VideoModelV3;
64
+ videoModel(modelId: XaiVideoModelId): Experimental_VideoModelV4;
65
+
66
+ /**
67
+ * Returns the xAI files interface for uploading files.
68
+ */
69
+ files(): FilesV4;
66
70
 
67
71
  /**
68
72
  * Server-side agentic tools for use with the responses API.
@@ -153,11 +157,19 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider {
153
157
  });
154
158
  };
155
159
 
156
- const provider = (modelId: XaiChatModelId) =>
157
- createChatLanguageModel(modelId);
160
+ const createFiles = () =>
161
+ new XaiFiles({
162
+ provider: 'xai.files',
163
+ baseURL,
164
+ headers: getHeaders,
165
+ fetch: options.fetch,
166
+ });
167
+
168
+ const provider = (modelId: XaiResponsesModelId) =>
169
+ createResponsesLanguageModel(modelId);
158
170
 
159
- provider.specificationVersion = 'v3' as const;
160
- provider.languageModel = createChatLanguageModel;
171
+ provider.specificationVersion = 'v4' as const;
172
+ provider.languageModel = createResponsesLanguageModel;
161
173
  provider.chat = createChatLanguageModel;
162
174
  provider.responses = createResponsesLanguageModel;
163
175
  provider.embeddingModel = (modelId: string) => {
@@ -168,6 +180,7 @@ export function createXai(options: XaiProviderSettings = {}): XaiProvider {
168
180
  provider.image = createImageModel;
169
181
  provider.videoModel = createVideoModel;
170
182
  provider.video = createVideoModel;
183
+ provider.files = createFiles;
171
184
  provider.tools = xaiTools;
172
185
 
173
186
  return provider;