@ai-sdk/xai 4.0.0-beta.45 → 4.0.0-beta.47

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
@@ -132,7 +132,7 @@ const { text } = await generateText({
132
132
  role: 'user',
133
133
  content: [
134
134
  { type: 'text', text: 'What do you see in this image?' },
135
- { type: 'image', image: fs.readFileSync('./image.png') },
135
+ { type: 'file', mediaType: 'image', data: fs.readFileSync('./image.png') },
136
136
  ],
137
137
  },
138
138
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/xai",
3
- "version": "4.0.0-beta.45",
3
+ "version": "4.0.0-beta.47",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,16 +29,16 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/openai-compatible": "3.0.0-beta.33",
33
- "@ai-sdk/provider": "4.0.0-beta.13",
34
- "@ai-sdk/provider-utils": "5.0.0-beta.28"
32
+ "@ai-sdk/openai-compatible": "3.0.0-beta.34",
33
+ "@ai-sdk/provider": "4.0.0-beta.14",
34
+ "@ai-sdk/provider-utils": "5.0.0-beta.29"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "20.17.24",
38
38
  "tsup": "^8",
39
39
  "typescript": "5.8.3",
40
40
  "zod": "3.25.76",
41
- "@ai-sdk/test-server": "2.0.0-beta.2",
41
+ "@ai-sdk/test-server": "2.0.0-beta.3",
42
42
  "@vercel/ai-tsconfig": "0.0.0"
43
43
  },
44
44
  "peerDependencies": {
@@ -1,14 +1,15 @@
1
1
  import {
2
- SharedV4Warning,
3
- LanguageModelV4Prompt,
4
2
  UnsupportedFunctionalityError,
3
+ type SharedV4Warning,
4
+ type LanguageModelV4Prompt,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
7
  convertToBase64,
8
- isProviderReference,
8
+ getTopLevelMediaType,
9
+ resolveFullMediaType,
9
10
  resolveProviderReference,
10
11
  } from '@ai-sdk/provider-utils';
11
- import { XaiChatPrompt } from './xai-chat-prompt';
12
+ import type { XaiChatPrompt } from './xai-chat-prompt';
12
13
 
13
14
  export function convertToXaiChatMessages(prompt: LanguageModelV4Prompt): {
14
15
  messages: XaiChatPrompt;
@@ -38,37 +39,41 @@ export function convertToXaiChatMessages(prompt: LanguageModelV4Prompt): {
38
39
  return { type: 'text', text: part.text };
39
40
  }
40
41
  case 'file': {
41
- if (isProviderReference(part.data)) {
42
- return {
43
- type: 'file',
44
- file: {
45
- file_id: resolveProviderReference({
46
- reference: part.data,
47
- provider: 'xai',
48
- }),
49
- },
50
- };
51
- }
52
-
53
- if (part.mediaType.startsWith('image/')) {
54
- const mediaType =
55
- part.mediaType === 'image/*'
56
- ? 'image/jpeg'
57
- : part.mediaType;
58
-
59
- return {
60
- type: 'image_url',
61
- image_url: {
62
- url:
63
- part.data instanceof URL
64
- ? part.data.toString()
65
- : `data:${mediaType};base64,${convertToBase64(part.data)}`,
66
- },
67
- };
68
- } else {
69
- throw new UnsupportedFunctionalityError({
70
- functionality: `file part media type ${part.mediaType}`,
71
- });
42
+ switch (part.data.type) {
43
+ case 'reference': {
44
+ return {
45
+ type: 'file',
46
+ file: {
47
+ file_id: resolveProviderReference({
48
+ reference: part.data.reference,
49
+ provider: 'xai',
50
+ }),
51
+ },
52
+ };
53
+ }
54
+ case 'text': {
55
+ throw new UnsupportedFunctionalityError({
56
+ functionality: 'text file parts',
57
+ });
58
+ }
59
+ case 'url':
60
+ case 'data': {
61
+ if (getTopLevelMediaType(part.mediaType) === 'image') {
62
+ return {
63
+ type: 'image_url',
64
+ image_url: {
65
+ url:
66
+ part.data.type === 'url'
67
+ ? part.data.url.toString()
68
+ : `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`,
69
+ },
70
+ };
71
+ } else {
72
+ throw new UnsupportedFunctionalityError({
73
+ functionality: `file part media type ${part.mediaType}`,
74
+ });
75
+ }
76
+ }
72
77
  }
73
78
  }
74
79
  }
@@ -1,5 +1,5 @@
1
- import { LanguageModelV4Usage } from '@ai-sdk/provider';
2
- import { XaiChatUsage } from './xai-chat-language-model';
1
+ import type { LanguageModelV4Usage } from '@ai-sdk/provider';
2
+ import type { XaiChatUsage } from './xai-chat-language-model';
3
3
 
4
4
  export function convertXaiChatUsage(usage: XaiChatUsage): LanguageModelV4Usage {
5
5
  const cacheReadTokens = usage.prompt_tokens_details?.cached_tokens ?? 0;
@@ -1,4 +1,8 @@
1
- import { InferSchema, lazySchema, zodSchema } from '@ai-sdk/provider-utils';
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
2
6
  import { z } from 'zod/v4';
3
7
 
4
8
  export const xaiFilesOptionsSchema = lazySchema(() =>
@@ -1,20 +1,22 @@
1
- import {
1
+ import type {
2
2
  FilesV4,
3
3
  FilesV4UploadFileCallOptions,
4
4
  FilesV4UploadFileResult,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
7
  combineHeaders,
8
- convertBase64ToUint8Array,
8
+ convertInlineFileDataToUint8Array,
9
9
  createJsonResponseHandler,
10
- FetchFunction,
11
10
  parseProviderOptions,
12
11
  postFormDataToApi,
12
+ type FetchFunction,
13
13
  } from '@ai-sdk/provider-utils';
14
14
  import { xaiFailedResponseHandler } from '../xai-error';
15
15
  import { xaiFilesResponseSchema } from './xai-files-api';
16
- import { xaiFilesOptionsSchema, XaiFilesOptions } from './xai-files-options';
17
-
16
+ import {
17
+ xaiFilesOptionsSchema,
18
+ type XaiFilesOptions,
19
+ } from './xai-files-options';
18
20
  interface XaiFilesConfig {
19
21
  provider: string;
20
22
  baseURL: string | undefined;
@@ -43,8 +45,7 @@ export class XaiFiles implements FilesV4 {
43
45
  schema: xaiFilesOptionsSchema,
44
46
  })) as XaiFilesOptions | undefined;
45
47
 
46
- const fileBytes =
47
- data instanceof Uint8Array ? data : convertBase64ToUint8Array(data);
48
+ const fileBytes = convertInlineFileDataToUint8Array(data);
48
49
 
49
50
  const blob = new Blob([fileBytes], {
50
51
  type: mediaType,
@@ -1,4 +1,4 @@
1
- import { LanguageModelV4FinishReason } from '@ai-sdk/provider';
1
+ import type { LanguageModelV4FinishReason } from '@ai-sdk/provider';
2
2
 
3
3
  export function mapXaiFinishReason(
4
4
  finishReason: string | null | undefined,
@@ -1,14 +1,15 @@
1
1
  import {
2
- SharedV4Warning,
3
- LanguageModelV4Message,
4
2
  UnsupportedFunctionalityError,
3
+ type SharedV4Warning,
4
+ type LanguageModelV4Message,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
7
  convertToBase64,
8
- isProviderReference,
8
+ getTopLevelMediaType,
9
+ resolveFullMediaType,
9
10
  resolveProviderReference,
10
11
  } from '@ai-sdk/provider-utils';
11
- import {
12
+ import type {
12
13
  XaiResponsesInput,
13
14
  XaiResponsesUserMessageContentPart,
14
15
  } from './xai-responses-api';
@@ -46,30 +47,51 @@ export async function convertToXaiResponsesInput({
46
47
  }
47
48
 
48
49
  case 'file': {
49
- if (isProviderReference(block.data)) {
50
- contentParts.push({
51
- type: 'input_file',
52
- file_id: resolveProviderReference({
53
- reference: block.data,
54
- provider: 'xai',
55
- }),
56
- });
57
- } else if (block.mediaType.startsWith('image/')) {
58
- const mediaType =
59
- block.mediaType === 'image/*'
60
- ? 'image/jpeg'
61
- : block.mediaType;
62
-
63
- const imageUrl =
64
- block.data instanceof URL
65
- ? block.data.toString()
66
- : `data:${mediaType};base64,${convertToBase64(block.data)}`;
50
+ switch (block.data.type) {
51
+ case 'reference': {
52
+ contentParts.push({
53
+ type: 'input_file',
54
+ file_id: resolveProviderReference({
55
+ reference: block.data.reference,
56
+ provider: 'xai',
57
+ }),
58
+ });
59
+ break;
60
+ }
61
+ case 'text': {
62
+ throw new UnsupportedFunctionalityError({
63
+ functionality: 'text file parts',
64
+ });
65
+ }
66
+ case 'url':
67
+ case 'data': {
68
+ if (getTopLevelMediaType(block.mediaType) === 'image') {
69
+ const imageUrl =
70
+ block.data.type === 'url'
71
+ ? block.data.url.toString()
72
+ : `data:${resolveFullMediaType({ part: block })};base64,${convertToBase64(block.data.data)}`;
67
73
 
68
- contentParts.push({ type: 'input_image', image_url: imageUrl });
69
- } else {
70
- throw new UnsupportedFunctionalityError({
71
- functionality: `file part media type ${block.mediaType}`,
72
- });
74
+ contentParts.push({
75
+ type: 'input_image',
76
+ image_url: imageUrl,
77
+ });
78
+ } else if (block.data.type === 'url') {
79
+ // xAI's Responses API accepts non-image documents (PDF, text, CSV, etc.)
80
+ // via `{ type: 'input_file', file_url }`. See
81
+ // https://docs.x.ai/docs/guides/chat-with-files. Inline bytes for
82
+ // non-image files are not supported by xAI; callers must upload via
83
+ // the Files API and pass a provider reference (file_id) instead.
84
+ contentParts.push({
85
+ type: 'input_file',
86
+ file_url: block.data.url.toString(),
87
+ });
88
+ } else {
89
+ throw new UnsupportedFunctionalityError({
90
+ functionality: `file part media type ${block.mediaType} as inline data (xAI Responses requires a URL or a Files API reference for non-image files)`,
91
+ });
92
+ }
93
+ break;
94
+ }
73
95
  }
74
96
  break;
75
97
  }
@@ -1,5 +1,5 @@
1
- import { LanguageModelV4Usage } from '@ai-sdk/provider';
2
- import { XaiResponsesUsage } from './xai-responses-api';
1
+ import type { LanguageModelV4Usage } from '@ai-sdk/provider';
2
+ import type { XaiResponsesUsage } from './xai-responses-api';
3
3
 
4
4
  export function convertXaiResponsesUsage(
5
5
  usage: XaiResponsesUsage,
@@ -1,4 +1,4 @@
1
- import { LanguageModelV4FinishReason } from '@ai-sdk/provider';
1
+ import type { LanguageModelV4FinishReason } from '@ai-sdk/provider';
2
2
 
3
3
  export function mapXaiResponsesFinishReason(
4
4
  finishReason: string | null | undefined,
@@ -27,7 +27,8 @@ export type XaiResponsesSystemMessage = {
27
27
  export type XaiResponsesUserMessageContentPart =
28
28
  | { type: 'input_text'; text: string }
29
29
  | { type: 'input_image'; image_url: string }
30
- | { type: 'input_file'; file_id: string };
30
+ | { type: 'input_file'; file_id: string }
31
+ | { type: 'input_file'; file_url: string };
31
32
 
32
33
  export type XaiResponsesUserMessage = {
33
34
  role: 'user';
@@ -1,4 +1,4 @@
1
- import {
1
+ import type {
2
2
  LanguageModelV4,
3
3
  LanguageModelV4CallOptions,
4
4
  LanguageModelV4Content,
@@ -13,30 +13,30 @@ import {
13
13
  combineHeaders,
14
14
  createEventSourceResponseHandler,
15
15
  createJsonResponseHandler,
16
- FetchFunction,
17
16
  isCustomReasoning,
18
17
  mapReasoningToProviderEffort,
19
18
  parseProviderOptions,
20
- ParseResult,
21
19
  postJsonToApi,
22
20
  serializeModelOptions,
23
21
  WORKFLOW_SERIALIZE,
24
22
  WORKFLOW_DESERIALIZE,
23
+ type FetchFunction,
24
+ type ParseResult,
25
25
  } from '@ai-sdk/provider-utils';
26
- import { z } from 'zod/v4';
26
+ import type { z } from 'zod/v4';
27
27
  import { getResponseMetadata } from '../get-response-metadata';
28
28
  import { xaiFailedResponseHandler } from '../xai-error';
29
29
  import { convertToXaiResponsesInput } from './convert-to-xai-responses-input';
30
30
  import { convertXaiResponsesUsage } from './convert-xai-responses-usage';
31
31
  import { mapXaiResponsesFinishReason } from './map-xai-responses-finish-reason';
32
32
  import {
33
- XaiResponsesIncludeOptions,
34
33
  xaiResponsesChunkSchema,
35
34
  xaiResponsesResponseSchema,
35
+ type XaiResponsesIncludeOptions,
36
36
  } from './xai-responses-api';
37
37
  import {
38
- XaiResponsesModelId,
39
38
  xaiLanguageModelResponsesOptions,
39
+ type XaiResponsesModelId,
40
40
  } from './xai-responses-options';
41
41
  import { prepareResponsesTools } from './xai-responses-prepare-tools';
42
42
 
@@ -80,6 +80,11 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
80
80
 
81
81
  readonly supportedUrls: Record<string, RegExp[]> = {
82
82
  'image/*': [/^https?:\/\/.*$/],
83
+ // xAI's Responses API accepts non-image documents (PDF, plain text, CSV, etc.) as
84
+ // `{ type: 'input_file', file_url }`. Keeping these URLs intact here lets them pass
85
+ // through to the converter instead of being downloaded to bytes by the SDK.
86
+ 'application/pdf': [/^https?:\/\/.*$/],
87
+ 'text/*': [/^https?:\/\/.*$/],
83
88
  };
84
89
 
85
90
  private async getArgs({
@@ -1,14 +1,14 @@
1
1
  import {
2
- LanguageModelV4CallOptions,
3
- SharedV4Warning,
4
2
  UnsupportedFunctionalityError,
3
+ type LanguageModelV4CallOptions,
4
+ type SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
6
  import { validateTypes } from '@ai-sdk/provider-utils';
7
7
  import { fileSearchArgsSchema } from '../tool/file-search';
8
8
  import { mcpServerArgsSchema } from '../tool/mcp-server';
9
9
  import { webSearchArgsSchema } from '../tool/web-search';
10
10
  import { xSearchArgsSchema } from '../tool/x-search';
11
- import { XaiResponsesTool } from './xai-responses-api';
11
+ import type { XaiResponsesTool } from './xai-responses-api';
12
12
 
13
13
  type XaiResponsesToolChoice =
14
14
  | 'auto'
@@ -1,30 +1,30 @@
1
1
  import {
2
2
  APICallError,
3
- LanguageModelV4,
4
- LanguageModelV4CallOptions,
5
- LanguageModelV4Content,
6
- LanguageModelV4FinishReason,
7
- LanguageModelV4GenerateResult,
8
- LanguageModelV4StreamPart,
9
- LanguageModelV4StreamResult,
10
- LanguageModelV4Usage,
11
- SharedV4Warning,
3
+ type LanguageModelV4,
4
+ type LanguageModelV4CallOptions,
5
+ type LanguageModelV4Content,
6
+ type LanguageModelV4FinishReason,
7
+ type LanguageModelV4GenerateResult,
8
+ type LanguageModelV4StreamPart,
9
+ type LanguageModelV4StreamResult,
10
+ type LanguageModelV4Usage,
11
+ type SharedV4Warning,
12
12
  } from '@ai-sdk/provider';
13
13
  import {
14
14
  combineHeaders,
15
15
  createEventSourceResponseHandler,
16
16
  createJsonResponseHandler,
17
17
  extractResponseHeaders,
18
- FetchFunction,
19
18
  isCustomReasoning,
20
19
  mapReasoningToProviderEffort,
21
20
  parseProviderOptions,
22
- ParseResult,
23
21
  postJsonToApi,
24
22
  safeParseJSON,
25
23
  serializeModelOptions,
26
24
  WORKFLOW_SERIALIZE,
27
25
  WORKFLOW_DESERIALIZE,
26
+ type FetchFunction,
27
+ type ParseResult,
28
28
  } from '@ai-sdk/provider-utils';
29
29
  import { z } from 'zod/v4';
30
30
  import { convertToXaiChatMessages } from './convert-to-xai-chat-messages';
@@ -32,8 +32,8 @@ import { convertXaiChatUsage } from './convert-xai-chat-usage';
32
32
  import { getResponseMetadata } from './get-response-metadata';
33
33
  import { mapXaiFinishReason } from './map-xai-finish-reason';
34
34
  import {
35
- XaiChatModelId,
36
35
  xaiLanguageModelChatOptions,
36
+ type XaiChatModelId,
37
37
  } from './xai-chat-options';
38
38
  import { xaiFailedResponseHandler } from './xai-error';
39
39
  import { prepareTools } from './xai-prepare-tools';
@@ -1,22 +1,22 @@
1
- import { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';
1
+ import type { ImageModelV4, SharedV4Warning } from '@ai-sdk/provider';
2
2
  import {
3
3
  combineHeaders,
4
4
  convertImageModelFileToDataUri,
5
5
  createBinaryResponseHandler,
6
6
  createJsonResponseHandler,
7
7
  createStatusCodeErrorResponseHandler,
8
- FetchFunction,
9
8
  getFromApi,
10
9
  parseProviderOptions,
11
10
  postJsonToApi,
12
11
  serializeModelOptions,
13
12
  WORKFLOW_SERIALIZE,
14
13
  WORKFLOW_DESERIALIZE,
14
+ type FetchFunction,
15
15
  } from '@ai-sdk/provider-utils';
16
16
  import { z } from 'zod/v4';
17
17
  import { xaiFailedResponseHandler } from './xai-error';
18
18
  import { xaiImageModelOptions } from './xai-image-options';
19
- import { XaiImageModelId } from './xai-image-settings';
19
+ import type { XaiImageModelId } from './xai-image-settings';
20
20
 
21
21
  interface XaiImageModelConfig {
22
22
  provider: string;
@@ -1,9 +1,9 @@
1
1
  import {
2
- LanguageModelV4CallOptions,
3
- SharedV4Warning,
4
2
  UnsupportedFunctionalityError,
3
+ type LanguageModelV4CallOptions,
4
+ type SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
- import { XaiToolChoice } from './xai-chat-prompt';
6
+ import type { XaiToolChoice } from './xai-chat-prompt';
7
7
 
8
8
  export function prepareTools({
9
9
  tools,
@@ -1,29 +1,29 @@
1
1
  import {
2
- type Experimental_VideoModelV4,
3
- FilesV4,
4
- ImageModelV4,
5
- LanguageModelV4,
6
2
  NoSuchModelError,
7
- ProviderV4,
3
+ type Experimental_VideoModelV4,
4
+ type FilesV4,
5
+ type ImageModelV4,
6
+ type LanguageModelV4,
7
+ type ProviderV4,
8
8
  } from '@ai-sdk/provider';
9
9
  import {
10
- FetchFunction,
11
10
  generateId,
12
11
  loadApiKey,
13
12
  withoutTrailingSlash,
14
13
  withUserAgentSuffix,
14
+ type FetchFunction,
15
15
  } from '@ai-sdk/provider-utils';
16
16
  import { XaiChatLanguageModel } from './xai-chat-language-model';
17
- import { XaiChatModelId } from './xai-chat-options';
17
+ import type { XaiChatModelId } from './xai-chat-options';
18
18
  import { XaiImageModel } from './xai-image-model';
19
- import { XaiImageModelId } from './xai-image-settings';
19
+ import type { XaiImageModelId } from './xai-image-settings';
20
20
  import { XaiResponsesLanguageModel } from './responses/xai-responses-language-model';
21
- import { XaiResponsesModelId } from './responses/xai-responses-options';
21
+ import type { XaiResponsesModelId } from './responses/xai-responses-options';
22
22
  import { xaiTools } from './tool';
23
23
  import { VERSION } from './version';
24
24
  import { XaiFiles } from './files/xai-files';
25
25
  import { XaiVideoModel } from './xai-video-model';
26
- import { XaiVideoModelId } from './xai-video-settings';
26
+ import type { XaiVideoModelId } from './xai-video-settings';
27
27
 
28
28
  export interface XaiProvider extends ProviderV4 {
29
29
  (modelId: XaiResponsesModelId): LanguageModelV4;
@@ -8,16 +8,16 @@ import {
8
8
  convertUint8ArrayToBase64,
9
9
  createJsonResponseHandler,
10
10
  delay,
11
- type FetchFunction,
12
11
  getFromApi,
13
12
  parseProviderOptions,
14
13
  postJsonToApi,
14
+ type FetchFunction,
15
15
  } from '@ai-sdk/provider-utils';
16
16
  import { z } from 'zod/v4';
17
17
  import { xaiFailedResponseHandler } from './xai-error';
18
18
  import {
19
- type XaiParsedVideoModelOptions,
20
19
  xaiVideoModelOptionsSchema,
20
+ type XaiParsedVideoModelOptions,
21
21
  } from './xai-video-options';
22
22
  import type { XaiVideoModelId } from './xai-video-settings';
23
23