@ai-sdk/xai 4.0.9 → 4.0.10

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/docs/01-xai.mdx CHANGED
@@ -12,21 +12,7 @@ The [xAI Grok](https://x.ai) provider contains language model support for the [x
12
12
  The xAI Grok provider is available via the `@ai-sdk/xai` module. You can
13
13
  install it with
14
14
 
15
- <Tabs items={['pnpm', 'npm', 'yarn', 'bun']}>
16
- <Tab>
17
- <Snippet text="pnpm add @ai-sdk/xai" dark />
18
- </Tab>
19
- <Tab>
20
- <Snippet text="npm install @ai-sdk/xai" dark />
21
- </Tab>
22
- <Tab>
23
- <Snippet text="yarn add @ai-sdk/xai" dark />
24
- </Tab>
25
-
26
- <Tab>
27
- <Snippet text="bun add @ai-sdk/xai" dark />
28
- </Tab>
29
- </Tabs>
15
+ <InstallPackages packages="@ai-sdk/xai" />
30
16
 
31
17
  ## Provider Instance
32
18
 
@@ -556,18 +542,19 @@ The following provider options are available:
556
542
 
557
543
  ## Model Capabilities
558
544
 
559
- | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Reasoning |
560
- | ----------------------------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
561
- | `grok-4.20-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
562
- | `grok-4.20-non-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
563
- | `grok-4-1-fast-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
564
- | `grok-4-1-fast-non-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
565
- | `grok-4-1` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
566
- | `grok-4-fast-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
567
- | `grok-4-fast-non-reasoning` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
568
- | `grok-code-fast-1` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
569
- | `grok-3` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Cross size={18} /> |
570
- | `grok-3-mini` | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
545
+ | Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Reasoning |
546
+ | ----------------------------- | ----------- | ----------------- | ---------- | -------------- | --------- |
547
+ | `grok-4.5` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
548
+ | `grok-4.20-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
549
+ | `grok-4.20-non-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
550
+ | `grok-4-1-fast-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
551
+ | `grok-4-1-fast-non-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
552
+ | `grok-4-1` | <Cross /> | <Check /> | <Check /> | <Check /> | <Cross /> |
553
+ | `grok-4-fast-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
554
+ | `grok-4-fast-non-reasoning` | <Check /> | <Check /> | <Check /> | <Check /> | <Cross /> |
555
+ | `grok-code-fast-1` | <Cross /> | <Check /> | <Check /> | <Check /> | <Check /> |
556
+ | `grok-3` | <Cross /> | <Check /> | <Check /> | <Check /> | <Cross /> |
557
+ | `grok-3-mini` | <Cross /> | <Check /> | <Check /> | <Check /> | <Check /> |
571
558
 
572
559
  <Note>
573
560
  The table above lists popular models. Please see the [xAI
@@ -675,9 +662,9 @@ const result = await generateSpeech({
675
662
 
676
663
  ### Model Capabilities
677
664
 
678
- | Model | Language | Speed | Output Formats |
679
- | --------- | ------------------- | ------------------- | -------------------------- |
680
- | `default` | <Check size={18} /> | <Check size={18} /> | mp3, wav, pcm, mulaw, alaw |
665
+ | Model | Language | Speed | Output Formats |
666
+ | --------- | --------- | --------- | -------------------------- |
667
+ | `default` | <Check /> | <Check /> | mp3, wav, pcm, mulaw, alaw |
681
668
 
682
669
  ## Transcription Models
683
670
 
@@ -782,9 +769,9 @@ const result = await transcribe({
782
769
 
783
770
  ### Model Capabilities
784
771
 
785
- | Model | Request/Response | Streaming | Word Timestamps | Diarization | Multichannel |
786
- | --------- | ------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
787
- | `default` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
772
+ | Model | Request/Response | Streaming | Word Timestamps | Diarization | Multichannel |
773
+ | --------- | ---------------- | --------- | --------------- | ----------- | ------------ |
774
+ | `default` | <Check /> | <Check /> | <Check /> | <Check /> | <Check /> |
788
775
 
789
776
  <Note>
790
777
  Word timestamps, diarization results, and segments are only returned on the
@@ -919,10 +906,10 @@ const { images } = await generateImage({
919
906
 
920
907
  ### Image Model Capabilities
921
908
 
922
- | Model | Resolution | Aspect Ratios | Image Editing |
923
- | ------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------- | ------------------- |
924
- | `grok-imagine-image-pro` | `1k`, `2k` | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `2:1`, `1:2`, `19.5:9`, `9:19.5`, `20:9`, `9:20`, `auto` | <Check size={18} /> |
925
- | `grok-imagine-image` | `1k` | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `2:1`, `1:2`, `19.5:9`, `9:19.5`, `20:9`, `9:20`, `auto` | <Check size={18} /> |
909
+ | Model | Resolution | Aspect Ratios | Image Editing |
910
+ | ------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------- | ------------- |
911
+ | `grok-imagine-image-pro` | `1k`, `2k` | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `2:1`, `1:2`, `19.5:9`, `9:19.5`, `20:9`, `9:20`, `auto` | <Check /> |
912
+ | `grok-imagine-image` | `1k` | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3`, `2:1`, `1:2`, `19.5:9`, `9:19.5`, `20:9`, `9:20`, `auto` | <Check /> |
926
913
 
927
914
  ## Video Models
928
915
 
@@ -1268,9 +1255,9 @@ and `resolution` just like text-to-video.
1268
1255
 
1269
1256
  ### Video Model Capabilities
1270
1257
 
1271
- | Model | Duration | Aspect Ratios | Resolution | Image-to-Video | Editing | Extension | R2V |
1272
- | -------------------- | -------- | ------------------------------------------------- | -------------- | ------------------- | ------------------- | ------------------- | ------------------- |
1273
- | `grok-imagine-video` | 1–15s | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3` | `480p`, `720p` | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> | <Check size={18} /> |
1258
+ | Model | Duration | Aspect Ratios | Resolution | Image-to-Video | Editing | Extension | R2V |
1259
+ | -------------------- | -------- | ------------------------------------------------- | -------------- | -------------- | --------- | --------- | --------- |
1260
+ | `grok-imagine-video` | 1–15s | `1:1`, `16:9`, `9:16`, `4:3`, `3:4`, `3:2`, `2:3` | `480p`, `720p` | <Check /> | <Check /> | <Check /> | <Check /> |
1274
1261
 
1275
1262
  <Note>
1276
1263
  You can also pass any available provider model ID as a string if needed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/xai",
3
- "version": "4.0.9",
3
+ "version": "4.0.10",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,17 +29,17 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/openai-compatible": "3.0.6",
33
- "@ai-sdk/provider": "4.0.2",
34
- "@ai-sdk/provider-utils": "5.0.6"
32
+ "@ai-sdk/openai-compatible": "3.0.7",
33
+ "@ai-sdk/provider": "4.0.3",
34
+ "@ai-sdk/provider-utils": "5.0.7"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "22.19.19",
38
38
  "tsup": "^8.5.1",
39
39
  "typescript": "5.8.3",
40
40
  "zod": "3.25.76",
41
- "@vercel/ai-tsconfig": "0.0.0",
42
- "@ai-sdk/test-server": "2.0.0"
41
+ "@ai-sdk/test-server": "2.0.0",
42
+ "@vercel/ai-tsconfig": "0.0.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "zod": "^3.25.76 || ^4.1.8"
@@ -4,6 +4,7 @@ export type XaiResponsesModelId =
4
4
  | 'grok-4.20-non-reasoning'
5
5
  | 'grok-4.20-reasoning'
6
6
  | 'grok-4.3'
7
+ | 'grok-4.5'
7
8
  | 'grok-latest'
8
9
  | (string & {});
9
10
 
@@ -5,6 +5,7 @@ export type XaiChatModelId =
5
5
  | 'grok-4.20-non-reasoning'
6
6
  | 'grok-4.20-reasoning'
7
7
  | 'grok-4.3'
8
+ | 'grok-4.5'
8
9
  | 'grok-latest'
9
10
  | (string & {});
10
11
 
@@ -10,6 +10,7 @@ import {
10
10
  createJsonResponseHandler,
11
11
  delay,
12
12
  getFromApi,
13
+ getTopLevelMediaType,
13
14
  parseProviderOptions,
14
15
  postJsonToApi,
15
16
  type FetchFunction,
@@ -62,6 +63,9 @@ function resolveStartImage(
62
63
  return getFirstFrameImage(options) ?? options.image;
63
64
  }
64
65
 
66
+ const isVideoFile = (file: Experimental_VideoModelV4File): boolean =>
67
+ file.mediaType != null && getTopLevelMediaType(file.mediaType) === 'video';
68
+
65
69
  function fileToXaiImageUrl(file: Experimental_VideoModelV4File): string {
66
70
  if (file.type === 'url') {
67
71
  return file.url;
@@ -71,17 +75,35 @@ function fileToXaiImageUrl(file: Experimental_VideoModelV4File): string {
71
75
  typeof file.data === 'string'
72
76
  ? file.data
73
77
  : convertUint8ArrayToBase64(file.data);
74
- return `data:${file.mediaType ?? 'image/png'};base64,${base64Data}`;
78
+ return `data:${file.mediaType};base64,${base64Data}`;
75
79
  }
76
80
 
77
81
  // Resolves the reference images for R2V generation. First-class
78
82
  // `inputReferences` win over the legacy `referenceImageUrls` provider option.
83
+ // Video references are not supported for reference-to-video and are skipped
84
+ // with a warning.
79
85
  function resolveReferenceImages(
80
86
  options: XaiVideoDoGenerateOptions,
81
87
  xaiOptions: XaiParsedVideoModelOptions | undefined,
88
+ warnings: SharedV4Warning[],
82
89
  ): Array<{ url: string }> | undefined {
83
90
  if (options.inputReferences != null && options.inputReferences.length > 0) {
84
- return options.inputReferences.map(reference => ({
91
+ const imageReferences = options.inputReferences.filter(reference => {
92
+ if (isVideoFile(reference)) {
93
+ warnings.push({
94
+ type: 'unsupported',
95
+ feature: 'inputReferences',
96
+ details:
97
+ 'xAI reference-to-video accepts image references only. The video ' +
98
+ 'reference was ignored. Use providerOptions.xai.mode ' +
99
+ '"extend-video" to continue from a video.',
100
+ });
101
+ return false;
102
+ }
103
+ return true;
104
+ });
105
+
106
+ return imageReferences.map(reference => ({
85
107
  url: fileToXaiImageUrl(reference),
86
108
  }));
87
109
  }
@@ -278,24 +300,44 @@ export class XaiVideoModel implements Experimental_VideoModelV4 {
278
300
  // nested xAI request image object.
279
301
  const startImage = resolveStartImage(options);
280
302
  if (startImage != null) {
281
- body.image = { url: fileToXaiImageUrl(startImage) };
303
+ if (isVideoFile(startImage)) {
304
+ const fromFrameImages = getFirstFrameImage(options) != null;
305
+ warnings.push({
306
+ type: 'unsupported',
307
+ feature: fromFrameImages ? 'frameImages' : 'image',
308
+ details:
309
+ 'xAI does not accept a video as a start/frame image. The video ' +
310
+ 'was ignored. Use providerOptions.xai.mode "extend-video" to ' +
311
+ 'continue from a video instead.',
312
+ });
313
+ } else {
314
+ body.image = { url: fileToXaiImageUrl(startImage) };
315
+ }
282
316
  }
283
317
 
284
318
  // xAI has no first-last-frame interpolation; warn and ignore last_frame.
285
- if (getLastFrameImage(options) != null) {
319
+ const lastFrameImage = getLastFrameImage(options);
320
+ if (lastFrameImage != null) {
286
321
  warnings.push({
287
322
  type: 'unsupported',
288
323
  feature: 'frameImages',
289
- details:
290
- 'xAI video models do not support last_frame. Use ' +
291
- 'providerOptions.xai.mode "extend-video" to continue from a ' +
292
- "video's last frame. The last frame image was ignored.",
324
+ details: isVideoFile(lastFrameImage)
325
+ ? 'xAI does not accept a video as a start/frame image. The video ' +
326
+ 'last frame was ignored. Use providerOptions.xai.mode ' +
327
+ '"extend-video" to continue from a video instead.'
328
+ : 'xAI video models do not support last_frame. Use ' +
329
+ 'providerOptions.xai.mode "extend-video" to continue from a ' +
330
+ "video's last frame. The last frame image was ignored.",
293
331
  });
294
332
  }
295
333
 
296
334
  // Reference images for R2V (reference-to-video) generation
297
335
  if (hasReferenceImages) {
298
- const referenceImages = resolveReferenceImages(options, xaiOptions);
336
+ const referenceImages = resolveReferenceImages(
337
+ options,
338
+ xaiOptions,
339
+ warnings,
340
+ );
299
341
  if (referenceImages != null) {
300
342
  body.reference_images = referenceImages;
301
343
  }