@ai-sdk/xai 4.0.37 → 4.0.39
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 +12 -0
- package/README.md +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +70 -29
- package/dist/index.js.map +1 -1
- package/docs/01-xai.mdx +51 -16
- package/package.json +3 -3
- package/src/responses/xai-responses-api.ts +2 -0
- package/src/responses/xai-responses-language-model-options.ts +1 -0
- package/src/responses/xai-responses-language-model.ts +17 -4
- package/src/xai-chat-language-model-options.ts +2 -0
- package/src/xai-chat-language-model.ts +19 -0
- package/src/xai-video-model.ts +19 -8
package/docs/01-xai.mdx
CHANGED
|
@@ -59,10 +59,10 @@ You can use the following optional settings to customize the xAI provider instan
|
|
|
59
59
|
## Language Models
|
|
60
60
|
|
|
61
61
|
You can create [xAI models](https://console.x.ai) using a provider instance. The
|
|
62
|
-
first argument is the model id, e.g. `grok-4.
|
|
62
|
+
first argument is the model id, e.g. `grok-4.6`.
|
|
63
63
|
|
|
64
64
|
```ts
|
|
65
|
-
const model = xai('grok-4.
|
|
65
|
+
const model = xai('grok-4.6');
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
<Note>
|
|
@@ -81,7 +81,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
81
81
|
import { generateText } from 'ai';
|
|
82
82
|
|
|
83
83
|
const { text } = await generateText({
|
|
84
|
-
model: xai('grok-4.
|
|
84
|
+
model: xai('grok-4.6'),
|
|
85
85
|
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
|
|
86
86
|
});
|
|
87
87
|
```
|
|
@@ -138,6 +138,37 @@ The AI SDK option accepts these values, but each xAI model supports a subset:
|
|
|
138
138
|
current details.
|
|
139
139
|
</Note>
|
|
140
140
|
|
|
141
|
+
### Priority Processing
|
|
142
|
+
|
|
143
|
+
`providerOptions.xai.serviceTier` requests higher scheduling priority, which
|
|
144
|
+
typically lowers time-to-first-token and speeds up inter-token latency. This
|
|
145
|
+
works for both the Responses API (default) and the Chat Completions API
|
|
146
|
+
(`xai.chat()`).
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { xai } from '@ai-sdk/xai';
|
|
150
|
+
import { generateText } from 'ai';
|
|
151
|
+
|
|
152
|
+
const { providerMetadata } = await generateText({
|
|
153
|
+
model: xai('grok-4.6'),
|
|
154
|
+
prompt: 'Explain quantum entanglement.',
|
|
155
|
+
providerOptions: {
|
|
156
|
+
xai: { serviceTier: 'priority' },
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// 'priority' when the request was served at the priority tier,
|
|
161
|
+
// 'default' when priority capacity was unavailable.
|
|
162
|
+
console.log(providerMetadata?.xai?.serviceTier);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Priority requests are billed at a premium per-token rate, and xAI only charges
|
|
166
|
+
that rate when the response confirms the priority tier — so read the applied
|
|
167
|
+
tier back from `providerMetadata.xai.serviceTier` rather than assuming the
|
|
168
|
+
request you sent is the tier you got. Omitting the option is equivalent to
|
|
169
|
+
`'default'`. See xAI's [priority processing
|
|
170
|
+
docs](https://docs.x.ai/developers/advanced-api-usage/priority-processing).
|
|
171
|
+
|
|
141
172
|
## Realtime Models
|
|
142
173
|
|
|
143
174
|
<Note type="warning">Realtime is an experimental feature.</Note>
|
|
@@ -168,7 +199,7 @@ calling pattern.
|
|
|
168
199
|
The xAI Responses API is the default when using `xai(modelId)` (since AI SDK 7). You can also use `xai.responses(modelId)` explicitly. This enables the model to autonomously orchestrate tool calls and research on xAI's servers.
|
|
169
200
|
|
|
170
201
|
```ts
|
|
171
|
-
const model = xai.responses('grok-4.
|
|
202
|
+
const model = xai.responses('grok-4.6');
|
|
172
203
|
```
|
|
173
204
|
|
|
174
205
|
The Responses API provides server-side tools that the model can autonomously execute during its reasoning process:
|
|
@@ -190,7 +221,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
190
221
|
import { generateText } from 'ai';
|
|
191
222
|
|
|
192
223
|
const { text } = await generateText({
|
|
193
|
-
model: xai.responses('grok-
|
|
224
|
+
model: xai.responses('grok-4.6'),
|
|
194
225
|
messages: [
|
|
195
226
|
{
|
|
196
227
|
role: 'user',
|
|
@@ -215,7 +246,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
215
246
|
import { generateText } from 'ai';
|
|
216
247
|
|
|
217
248
|
const { text } = await generateText({
|
|
218
|
-
model: xai('grok-4.
|
|
249
|
+
model: xai('grok-4.6'),
|
|
219
250
|
messages: [
|
|
220
251
|
{
|
|
221
252
|
role: 'user',
|
|
@@ -252,7 +283,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
252
283
|
import { generateText } from 'ai';
|
|
253
284
|
|
|
254
285
|
const { text, sources } = await generateText({
|
|
255
|
-
model: xai.responses('grok-4.
|
|
286
|
+
model: xai.responses('grok-4.6'),
|
|
256
287
|
prompt: 'What are the latest developments in AI?',
|
|
257
288
|
tools: {
|
|
258
289
|
web_search: xai.tools.webSearch({
|
|
@@ -290,7 +321,7 @@ The X search tool enables searching X (Twitter) for posts, with filtering by han
|
|
|
290
321
|
|
|
291
322
|
```ts
|
|
292
323
|
const { text, sources } = await generateText({
|
|
293
|
-
model: xai.responses('grok-4.
|
|
324
|
+
model: xai.responses('grok-4.6'),
|
|
294
325
|
prompt: 'What are people saying about AI on X this week?',
|
|
295
326
|
tools: {
|
|
296
327
|
x_search: xai.tools.xSearch({
|
|
@@ -336,7 +367,7 @@ The code execution tool enables the model to write and execute Python code for c
|
|
|
336
367
|
|
|
337
368
|
```ts
|
|
338
369
|
const { text } = await generateText({
|
|
339
|
-
model: xai.responses('grok-4.
|
|
370
|
+
model: xai.responses('grok-4.6'),
|
|
340
371
|
prompt:
|
|
341
372
|
'Calculate the compound interest for $10,000 at 5% annually for 10 years',
|
|
342
373
|
tools: {
|
|
@@ -351,7 +382,7 @@ The view image tool enables the model to view and analyze images:
|
|
|
351
382
|
|
|
352
383
|
```ts
|
|
353
384
|
const { text } = await generateText({
|
|
354
|
-
model: xai.responses('grok-4.
|
|
385
|
+
model: xai.responses('grok-4.6'),
|
|
355
386
|
prompt: 'Describe what you see in the image',
|
|
356
387
|
tools: {
|
|
357
388
|
view_image: xai.tools.viewImage(),
|
|
@@ -365,7 +396,7 @@ The view X video tool enables the model to view and analyze videos from X (Twitt
|
|
|
365
396
|
|
|
366
397
|
```ts
|
|
367
398
|
const { text } = await generateText({
|
|
368
|
-
model: xai.responses('grok-4.
|
|
399
|
+
model: xai.responses('grok-4.6'),
|
|
369
400
|
prompt: 'Summarize the content of this X video',
|
|
370
401
|
tools: {
|
|
371
402
|
view_x_video: xai.tools.viewXVideo(),
|
|
@@ -382,7 +413,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
382
413
|
import { generateText } from 'ai';
|
|
383
414
|
|
|
384
415
|
const result = await generateText({
|
|
385
|
-
model: xai.responses('grok-4.
|
|
416
|
+
model: xai.responses('grok-4.6'),
|
|
386
417
|
prompt:
|
|
387
418
|
'Generate an image of a corgi surfing a big wave, in the style of a Japanese woodblock print',
|
|
388
419
|
tools: {
|
|
@@ -420,7 +451,7 @@ The MCP server tool enables the model to connect to remote [Model Context Protoc
|
|
|
420
451
|
|
|
421
452
|
```ts
|
|
422
453
|
const { text } = await generateText({
|
|
423
|
-
model: xai.responses('grok-4.
|
|
454
|
+
model: xai.responses('grok-4.6'),
|
|
424
455
|
prompt: 'Use the weather tool to check conditions in San Francisco',
|
|
425
456
|
tools: {
|
|
426
457
|
weather_server: xai.tools.mcpServer({
|
|
@@ -468,7 +499,7 @@ import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';
|
|
|
468
499
|
import { streamText } from 'ai';
|
|
469
500
|
|
|
470
501
|
const result = streamText({
|
|
471
|
-
model: xai.responses('grok-4.
|
|
502
|
+
model: xai.responses('grok-4.6'),
|
|
472
503
|
prompt: 'What documents do you have access to?',
|
|
473
504
|
tools: {
|
|
474
505
|
file_search: xai.tools.fileSearch({
|
|
@@ -515,7 +546,7 @@ import { xai } from '@ai-sdk/xai';
|
|
|
515
546
|
import { streamText } from 'ai';
|
|
516
547
|
|
|
517
548
|
const { stream } = streamText({
|
|
518
|
-
model: xai.responses('grok-4.
|
|
549
|
+
model: xai.responses('grok-4.6'),
|
|
519
550
|
prompt: 'Research AI safety developments and calculate risk metrics',
|
|
520
551
|
tools: {
|
|
521
552
|
web_search: xai.tools.webSearch(),
|
|
@@ -549,7 +580,7 @@ import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';
|
|
|
549
580
|
import { generateText } from 'ai';
|
|
550
581
|
|
|
551
582
|
const result = await generateText({
|
|
552
|
-
model: xai.responses('grok-4.
|
|
583
|
+
model: xai.responses('grok-4.6'),
|
|
553
584
|
providerOptions: {
|
|
554
585
|
xai: {
|
|
555
586
|
reasoningEffort: 'high',
|
|
@@ -585,6 +616,10 @@ The following provider options are available:
|
|
|
585
616
|
|
|
586
617
|
The ID of the previous response from the model. You can use it to continue a conversation.
|
|
587
618
|
|
|
619
|
+
- **serviceTier** _'default' | 'priority'_
|
|
620
|
+
|
|
621
|
+
Scheduling priority for the request. `'priority'` buys lower time-to-first-token and faster inter-token latency at a premium per-token price. The tier xAI actually applied comes back on `providerMetadata.xai.serviceTier`, and is `'default'` when priority capacity was unavailable. See [Priority Processing](https://docs.x.ai/developers/advanced-api-usage/priority-processing).
|
|
622
|
+
|
|
588
623
|
<Note>
|
|
589
624
|
The Responses API only supports server-side tools. You cannot mix server-side
|
|
590
625
|
tools with client-side function tools in the same request.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/xai",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"tsup": "^8.5.1",
|
|
38
38
|
"typescript": "5.8.3",
|
|
39
39
|
"zod": "3.25.76",
|
|
40
|
-
"@
|
|
41
|
-
"@ai-
|
|
40
|
+
"@ai-sdk/test-server": "2.0.1",
|
|
41
|
+
"@vercel/ai-tsconfig": "0.0.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"zod": "^3.25.76 || ^4.1.8"
|
|
@@ -287,6 +287,7 @@ export const xaiResponsesResponseSchema = z.object({
|
|
|
287
287
|
output: z.array(outputItemSchema),
|
|
288
288
|
usage: xaiResponsesUsageSchema.nullish(),
|
|
289
289
|
status: z.string(),
|
|
290
|
+
service_tier: z.string().nullish(),
|
|
290
291
|
});
|
|
291
292
|
|
|
292
293
|
export const xaiResponsesChunkSchema = z.union([
|
|
@@ -571,6 +572,7 @@ export const xaiResponsesChunkSchema = z.union([
|
|
|
571
572
|
response: z.object({
|
|
572
573
|
incomplete_details: z.object({ reason: z.string() }).nullish(),
|
|
573
574
|
usage: xaiResponsesUsageSchema.nullish(),
|
|
575
|
+
service_tier: z.string().nullish(),
|
|
574
576
|
}),
|
|
575
577
|
}),
|
|
576
578
|
z.object({
|
|
@@ -28,6 +28,7 @@ export const xaiLanguageModelResponsesOptions = z.object({
|
|
|
28
28
|
reasoningSummary: z.enum(['auto', 'concise', 'detailed']).optional(),
|
|
29
29
|
logprobs: z.boolean().optional(),
|
|
30
30
|
topLogprobs: z.number().int().min(0).max(8).optional(),
|
|
31
|
+
serviceTier: z.enum(['default', 'priority']).optional(),
|
|
31
32
|
/**
|
|
32
33
|
* Whether to store the input message(s) and model response for later retrieval.
|
|
33
34
|
* Must be set to `false` for teams with Zero Data Retention (ZDR) enabled,
|
|
@@ -255,6 +255,9 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
255
255
|
...(options.previousResponseId != null && {
|
|
256
256
|
previous_response_id: options.previousResponseId,
|
|
257
257
|
}),
|
|
258
|
+
...(options.serviceTier != null && {
|
|
259
|
+
service_tier: options.serviceTier,
|
|
260
|
+
}),
|
|
258
261
|
};
|
|
259
262
|
|
|
260
263
|
if (xaiTools && xaiTools.length > 0) {
|
|
@@ -526,10 +529,16 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
526
529
|
inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },
|
|
527
530
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
528
531
|
},
|
|
529
|
-
...(response.usage?.cost_in_usd_ticks != null
|
|
532
|
+
...((response.usage?.cost_in_usd_ticks != null ||
|
|
533
|
+
response.service_tier != null) && {
|
|
530
534
|
providerMetadata: {
|
|
531
535
|
xai: {
|
|
532
|
-
|
|
536
|
+
...(response.usage?.cost_in_usd_ticks != null && {
|
|
537
|
+
costInUsdTicks: response.usage.cost_in_usd_ticks,
|
|
538
|
+
}),
|
|
539
|
+
...(response.service_tier != null && {
|
|
540
|
+
serviceTier: response.service_tier,
|
|
541
|
+
}),
|
|
533
542
|
},
|
|
534
543
|
},
|
|
535
544
|
}),
|
|
@@ -580,6 +589,7 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
580
589
|
let hasFunctionCall = false;
|
|
581
590
|
let usage: LanguageModelV4Usage | undefined = undefined;
|
|
582
591
|
let costInUsdTicks: number | undefined = undefined;
|
|
592
|
+
let serviceTier: string | undefined = undefined;
|
|
583
593
|
let isFirstChunk = true;
|
|
584
594
|
const contentBlocks: Record<string, { type: 'text' }> = {};
|
|
585
595
|
const seenToolCalls = new Set<string>();
|
|
@@ -774,6 +784,8 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
774
784
|
costInUsdTicks = response.usage.cost_in_usd_ticks ?? undefined;
|
|
775
785
|
}
|
|
776
786
|
|
|
787
|
+
serviceTier = response.service_tier ?? undefined;
|
|
788
|
+
|
|
777
789
|
if (event.type === 'response.incomplete') {
|
|
778
790
|
const reason =
|
|
779
791
|
'incomplete_details' in response
|
|
@@ -1222,10 +1234,11 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1222
1234
|
},
|
|
1223
1235
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
1224
1236
|
},
|
|
1225
|
-
...(costInUsdTicks != null && {
|
|
1237
|
+
...((costInUsdTicks != null || serviceTier != null) && {
|
|
1226
1238
|
providerMetadata: {
|
|
1227
1239
|
xai: {
|
|
1228
|
-
costInUsdTicks,
|
|
1240
|
+
...(costInUsdTicks != null && { costInUsdTicks }),
|
|
1241
|
+
...(serviceTier != null && { serviceTier }),
|
|
1229
1242
|
},
|
|
1230
1243
|
},
|
|
1231
1244
|
}),
|
|
@@ -73,6 +73,8 @@ export const xaiLanguageModelChatOptions = z.object({
|
|
|
73
73
|
logprobs: z.boolean().optional(),
|
|
74
74
|
topLogprobs: z.number().int().min(0).max(8).optional(),
|
|
75
75
|
|
|
76
|
+
serviceTier: z.enum(['default', 'priority']).optional(),
|
|
77
|
+
|
|
76
78
|
/**
|
|
77
79
|
* Whether to enable parallel function calling during tool use.
|
|
78
80
|
* When true, the model can call multiple functions in parallel.
|
|
@@ -181,6 +181,9 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
|
|
|
181
181
|
seed,
|
|
182
182
|
reasoning_effort: reasoningEffort,
|
|
183
183
|
|
|
184
|
+
// scheduling priority
|
|
185
|
+
service_tier: options.serviceTier,
|
|
186
|
+
|
|
184
187
|
// parallel function calling
|
|
185
188
|
parallel_function_calling: options.parallel_function_calling,
|
|
186
189
|
|
|
@@ -347,6 +350,11 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
|
|
|
347
350
|
inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },
|
|
348
351
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
349
352
|
},
|
|
353
|
+
...(response.service_tier != null && {
|
|
354
|
+
providerMetadata: {
|
|
355
|
+
xai: { serviceTier: response.service_tier },
|
|
356
|
+
},
|
|
357
|
+
}),
|
|
350
358
|
request: { body },
|
|
351
359
|
response: {
|
|
352
360
|
...getResponseMetadata(response),
|
|
@@ -426,6 +434,7 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
|
|
|
426
434
|
raw: undefined,
|
|
427
435
|
};
|
|
428
436
|
let usage: LanguageModelV4Usage | undefined = undefined;
|
|
437
|
+
let serviceTier: string | undefined = undefined;
|
|
429
438
|
let isFirstChunk = true;
|
|
430
439
|
const contentBlocks: Record<
|
|
431
440
|
string,
|
|
@@ -485,6 +494,11 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
|
|
|
485
494
|
usage = convertXaiChatUsage(value.usage);
|
|
486
495
|
}
|
|
487
496
|
|
|
497
|
+
// the applied tier is repeated on every chunk; keep the latest
|
|
498
|
+
if (value.service_tier != null) {
|
|
499
|
+
serviceTier = value.service_tier;
|
|
500
|
+
}
|
|
501
|
+
|
|
488
502
|
const choice = value.choices[0];
|
|
489
503
|
|
|
490
504
|
// update finish reason if present
|
|
@@ -644,6 +658,9 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
|
|
|
644
658
|
},
|
|
645
659
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
646
660
|
},
|
|
661
|
+
...(serviceTier != null && {
|
|
662
|
+
providerMetadata: { xai: { serviceTier } },
|
|
663
|
+
}),
|
|
647
664
|
});
|
|
648
665
|
},
|
|
649
666
|
}),
|
|
@@ -711,6 +728,7 @@ const xaiChatResponseSchema = z.object({
|
|
|
711
728
|
object: z.literal('chat.completion').nullish(),
|
|
712
729
|
usage: xaiUsageSchema.nullish(),
|
|
713
730
|
citations: z.array(z.string().url()).nullish(),
|
|
731
|
+
service_tier: z.string().nullish(),
|
|
714
732
|
code: z.string().nullish(),
|
|
715
733
|
error: z.string().nullish(),
|
|
716
734
|
});
|
|
@@ -744,6 +762,7 @@ const xaiChatChunkSchema = z.object({
|
|
|
744
762
|
),
|
|
745
763
|
usage: xaiUsageSchema.nullish(),
|
|
746
764
|
citations: z.array(z.string().url()).nullish(),
|
|
765
|
+
service_tier: z.string().nullish(),
|
|
747
766
|
});
|
|
748
767
|
|
|
749
768
|
const xaiStreamErrorSchema = z.object({
|
package/src/xai-video-model.ts
CHANGED
|
@@ -581,19 +581,30 @@ export class XaiVideoModel implements VideoModelV4 {
|
|
|
581
581
|
statusResponse.status === 'done' ||
|
|
582
582
|
(statusResponse.status == null && statusResponse.video?.url)
|
|
583
583
|
) {
|
|
584
|
+
// Terminal outcomes, so they are reported the same way as an upstream `failed`
|
|
584
585
|
if (statusResponse.video?.respect_moderation === false) {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
586
|
+
return {
|
|
587
|
+
status: 'error' as const,
|
|
588
|
+
error:
|
|
588
589
|
'Video generation was blocked due to a content policy violation.',
|
|
589
|
-
|
|
590
|
+
response: {
|
|
591
|
+
timestamp: currentDate,
|
|
592
|
+
modelId: this.modelId,
|
|
593
|
+
headers: responseHeaders,
|
|
594
|
+
},
|
|
595
|
+
};
|
|
590
596
|
}
|
|
591
597
|
|
|
592
598
|
if (!statusResponse.video?.url) {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
599
|
+
return {
|
|
600
|
+
status: 'error' as const,
|
|
601
|
+
error: 'Video generation completed but no video URL was returned.',
|
|
602
|
+
response: {
|
|
603
|
+
timestamp: currentDate,
|
|
604
|
+
modelId: this.modelId,
|
|
605
|
+
headers: responseHeaders,
|
|
606
|
+
},
|
|
607
|
+
};
|
|
597
608
|
}
|
|
598
609
|
|
|
599
610
|
return {
|