@ai-sdk/xai 4.0.0-beta.6 → 4.0.0-beta.75

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +667 -9
  2. package/README.md +2 -0
  3. package/dist/index.d.ts +218 -68
  4. package/dist/index.js +2081 -779
  5. package/dist/index.js.map +1 -1
  6. package/docs/01-xai.mdx +445 -54
  7. package/package.json +15 -15
  8. package/src/convert-to-xai-chat-messages.ts +48 -27
  9. package/src/convert-xai-chat-usage.ts +3 -3
  10. package/src/files/xai-files-api.ts +16 -0
  11. package/src/files/xai-files-options.ts +19 -0
  12. package/src/files/xai-files.ts +94 -0
  13. package/src/index.ts +9 -4
  14. package/src/map-xai-finish-reason.ts +2 -2
  15. package/src/realtime/index.ts +2 -0
  16. package/src/realtime/xai-realtime-event-mapper.ts +399 -0
  17. package/src/realtime/xai-realtime-model-options.ts +3 -0
  18. package/src/realtime/xai-realtime-model.ts +101 -0
  19. package/src/remove-additional-properties.ts +24 -0
  20. package/src/responses/convert-to-xai-responses-input.ts +100 -23
  21. package/src/responses/convert-xai-responses-usage.ts +3 -3
  22. package/src/responses/map-xai-responses-finish-reason.ts +3 -2
  23. package/src/responses/xai-responses-api.ts +34 -1
  24. package/src/responses/{xai-responses-options.ts → xai-responses-language-model-options.ts} +13 -7
  25. package/src/responses/xai-responses-language-model.ts +173 -64
  26. package/src/responses/xai-responses-prepare-tools.ts +10 -8
  27. package/src/tool/code-execution.ts +2 -2
  28. package/src/tool/file-search.ts +2 -2
  29. package/src/tool/mcp-server.ts +2 -2
  30. package/src/tool/view-image.ts +2 -2
  31. package/src/tool/view-x-video.ts +2 -2
  32. package/src/tool/web-search.ts +4 -2
  33. package/src/tool/x-search.ts +2 -2
  34. package/src/{xai-chat-options.ts → xai-chat-language-model-options.ts} +28 -13
  35. package/src/xai-chat-language-model.ts +65 -29
  36. package/src/xai-chat-prompt.ts +2 -1
  37. package/src/xai-error.ts +13 -3
  38. package/src/xai-image-model.ts +28 -11
  39. package/src/xai-prepare-tools.ts +9 -8
  40. package/src/xai-provider.ts +115 -19
  41. package/src/xai-speech-model-options.ts +55 -0
  42. package/src/xai-speech-model.ts +167 -0
  43. package/src/xai-transcription-model-options.ts +70 -0
  44. package/src/xai-transcription-model.ts +166 -0
  45. package/src/xai-video-model-options.ts +145 -0
  46. package/src/xai-video-model.ts +129 -22
  47. package/dist/index.d.mts +0 -372
  48. package/dist/index.mjs +0 -3061
  49. package/dist/index.mjs.map +0 -1
  50. package/src/xai-video-options.ts +0 -23
  51. /package/src/{xai-image-options.ts → xai-image-model-options.ts} +0 -0
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@ai-sdk/xai",
3
- "version": "4.0.0-beta.6",
3
+ "version": "4.0.0-beta.75",
4
+ "type": "module",
4
5
  "license": "Apache-2.0",
5
6
  "sideEffects": false,
6
7
  "main": "./dist/index.js",
7
- "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
9
  "files": [
10
10
  "dist/**/*",
@@ -24,36 +24,38 @@
24
24
  "./package.json": "./package.json",
25
25
  ".": {
26
26
  "types": "./dist/index.d.ts",
27
- "import": "./dist/index.mjs",
28
- "require": "./dist/index.js"
27
+ "import": "./dist/index.js",
28
+ "default": "./dist/index.js"
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/openai-compatible": "3.0.0-beta.2",
33
- "@ai-sdk/provider": "4.0.0-beta.0",
34
- "@ai-sdk/provider-utils": "5.0.0-beta.1"
32
+ "@ai-sdk/openai-compatible": "3.0.0-beta.57",
33
+ "@ai-sdk/provider": "4.0.0-beta.19",
34
+ "@ai-sdk/provider-utils": "5.0.0-beta.49"
35
35
  },
36
36
  "devDependencies": {
37
- "@types/node": "20.17.24",
38
- "tsup": "^8",
37
+ "@types/node": "22.19.19",
38
+ "tsup": "^8.5.1",
39
39
  "typescript": "5.8.3",
40
40
  "zod": "3.25.76",
41
- "@ai-sdk/test-server": "2.0.0-beta.0",
41
+ "@ai-sdk/test-server": "2.0.0-beta.7",
42
42
  "@vercel/ai-tsconfig": "0.0.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "zod": "^3.25.76 || ^4.1.8"
46
46
  },
47
47
  "engines": {
48
- "node": ">=18"
48
+ "node": ">=22"
49
49
  },
50
50
  "publishConfig": {
51
- "access": "public"
51
+ "access": "public",
52
+ "provenance": true
52
53
  },
53
54
  "homepage": "https://ai-sdk.dev/docs",
54
55
  "repository": {
55
56
  "type": "git",
56
- "url": "git+https://github.com/vercel/ai.git"
57
+ "url": "https://github.com/vercel/ai",
58
+ "directory": "packages/xai"
57
59
  },
58
60
  "bugs": {
59
61
  "url": "https://github.com/vercel/ai/issues"
@@ -65,9 +67,7 @@
65
67
  "build": "pnpm clean && tsup --tsconfig tsconfig.build.json",
66
68
  "build:watch": "pnpm clean && tsup --watch",
67
69
  "clean": "del-cli dist docs *.tsbuildinfo",
68
- "lint": "eslint \"./**/*.ts*\"",
69
70
  "type-check": "tsc --build",
70
- "prettier-check": "prettier --check \"./**/*.ts*\"",
71
71
  "test": "pnpm test:node && pnpm test:edge",
72
72
  "test:update": "pnpm test:node -u",
73
73
  "test:watch": "vitest --config vitest.node.config.js",
@@ -1,17 +1,22 @@
1
1
  import {
2
- SharedV3Warning,
3
- LanguageModelV3Prompt,
4
2
  UnsupportedFunctionalityError,
3
+ type SharedV4Warning,
4
+ type LanguageModelV4Prompt,
5
5
  } from '@ai-sdk/provider';
6
- import { convertToBase64 } from '@ai-sdk/provider-utils';
7
- import { XaiChatPrompt } from './xai-chat-prompt';
6
+ import {
7
+ convertToBase64,
8
+ getTopLevelMediaType,
9
+ resolveFullMediaType,
10
+ resolveProviderReference,
11
+ } from '@ai-sdk/provider-utils';
12
+ import type { XaiChatPrompt } from './xai-chat-prompt';
8
13
 
9
- export function convertToXaiChatMessages(prompt: LanguageModelV3Prompt): {
14
+ export function convertToXaiChatMessages(prompt: LanguageModelV4Prompt): {
10
15
  messages: XaiChatPrompt;
11
- warnings: Array<SharedV3Warning>;
16
+ warnings: Array<SharedV4Warning>;
12
17
  } {
13
18
  const messages: XaiChatPrompt = [];
14
- const warnings: Array<SharedV3Warning> = [];
19
+ const warnings: Array<SharedV4Warning> = [];
15
20
 
16
21
  for (const { role, content } of prompt) {
17
22
  switch (role) {
@@ -34,25 +39,41 @@ export function convertToXaiChatMessages(prompt: LanguageModelV3Prompt): {
34
39
  return { type: 'text', text: part.text };
35
40
  }
36
41
  case 'file': {
37
- if (part.mediaType.startsWith('image/')) {
38
- const mediaType =
39
- part.mediaType === 'image/*'
40
- ? 'image/jpeg'
41
- : part.mediaType;
42
-
43
- return {
44
- type: 'image_url',
45
- image_url: {
46
- url:
47
- part.data instanceof URL
48
- ? part.data.toString()
49
- : `data:${mediaType};base64,${convertToBase64(part.data)}`,
50
- },
51
- };
52
- } else {
53
- throw new UnsupportedFunctionalityError({
54
- functionality: `file part media type ${part.mediaType}`,
55
- });
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
+ }
56
77
  }
57
78
  }
58
79
  }
@@ -113,7 +134,7 @@ export function convertToXaiChatMessages(prompt: LanguageModelV3Prompt): {
113
134
  contentValue = output.value;
114
135
  break;
115
136
  case 'execution-denied':
116
- contentValue = output.reason ?? 'Tool execution denied.';
137
+ contentValue = output.reason ?? 'Tool call execution denied.';
117
138
  break;
118
139
  case 'content':
119
140
  case 'json':
@@ -1,7 +1,7 @@
1
- import { LanguageModelV3Usage } 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
- export function convertXaiChatUsage(usage: XaiChatUsage): LanguageModelV3Usage {
4
+ export function convertXaiChatUsage(usage: XaiChatUsage): LanguageModelV4Usage {
5
5
  const cacheReadTokens = usage.prompt_tokens_details?.cached_tokens ?? 0;
6
6
  const reasoningTokens =
7
7
  usage.completion_tokens_details?.reasoning_tokens ?? 0;
@@ -0,0 +1,16 @@
1
+ import { lazySchema, zodSchema } from '@ai-sdk/provider-utils';
2
+ import { z } from 'zod/v4';
3
+
4
+ export const xaiFilesResponseSchema = lazySchema(() =>
5
+ zodSchema(
6
+ z.object({
7
+ id: z.string(),
8
+ object: z.string().nullish(),
9
+ bytes: z.number().nullish(),
10
+ created_at: z.number().nullish(),
11
+ filename: z.string().nullish(),
12
+ purpose: z.string().nullish(),
13
+ status: z.string().nullish(),
14
+ }),
15
+ ),
16
+ );
@@ -0,0 +1,19 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ export const xaiFilesOptionsSchema = lazySchema(() =>
9
+ zodSchema(
10
+ z
11
+ .object({
12
+ teamId: z.string().optional(),
13
+ filePath: z.string().optional(),
14
+ })
15
+ .passthrough(),
16
+ ),
17
+ );
18
+
19
+ export type XaiFilesOptions = InferSchema<typeof xaiFilesOptionsSchema>;
@@ -0,0 +1,94 @@
1
+ import type {
2
+ FilesV4,
3
+ FilesV4UploadFileCallOptions,
4
+ FilesV4UploadFileResult,
5
+ } from '@ai-sdk/provider';
6
+ import {
7
+ combineHeaders,
8
+ convertInlineFileDataToUint8Array,
9
+ createJsonResponseHandler,
10
+ parseProviderOptions,
11
+ postFormDataToApi,
12
+ type FetchFunction,
13
+ } from '@ai-sdk/provider-utils';
14
+ import { xaiFailedResponseHandler } from '../xai-error';
15
+ import { xaiFilesResponseSchema } from './xai-files-api';
16
+ import {
17
+ xaiFilesOptionsSchema,
18
+ type XaiFilesOptions,
19
+ } from './xai-files-options';
20
+ interface XaiFilesConfig {
21
+ provider: string;
22
+ baseURL: string | undefined;
23
+ headers: () => Record<string, string | undefined>;
24
+ fetch?: FetchFunction;
25
+ }
26
+
27
+ export class XaiFiles implements FilesV4 {
28
+ readonly specificationVersion = 'v4';
29
+
30
+ get provider(): string {
31
+ return this.config.provider;
32
+ }
33
+
34
+ constructor(private readonly config: XaiFilesConfig) {}
35
+
36
+ async uploadFile({
37
+ data,
38
+ mediaType,
39
+ filename,
40
+ providerOptions,
41
+ }: FilesV4UploadFileCallOptions): Promise<FilesV4UploadFileResult> {
42
+ const xaiOptions = (await parseProviderOptions({
43
+ provider: 'xai',
44
+ providerOptions,
45
+ schema: xaiFilesOptionsSchema,
46
+ })) as XaiFilesOptions | undefined;
47
+
48
+ const fileBytes = convertInlineFileDataToUint8Array(data);
49
+
50
+ const blob = new Blob([fileBytes], {
51
+ type: mediaType,
52
+ });
53
+
54
+ const formData = new FormData();
55
+ if (filename != null) {
56
+ formData.append('file', blob, filename);
57
+ } else {
58
+ formData.append('file', blob);
59
+ }
60
+
61
+ if (xaiOptions?.teamId != null) {
62
+ formData.append('team_id', xaiOptions.teamId);
63
+ }
64
+
65
+ const { value: response } = await postFormDataToApi({
66
+ url: `${this.config.baseURL}/files`,
67
+ headers: combineHeaders(this.config.headers()),
68
+ formData,
69
+ failedResponseHandler: xaiFailedResponseHandler,
70
+ successfulResponseHandler: createJsonResponseHandler(
71
+ xaiFilesResponseSchema,
72
+ ),
73
+ fetch: this.config.fetch,
74
+ });
75
+
76
+ return {
77
+ warnings: [],
78
+ providerReference: { xai: response.id },
79
+ ...((response.filename ?? filename)
80
+ ? { filename: response.filename ?? filename }
81
+ : {}),
82
+ ...(mediaType != null ? { mediaType } : {}),
83
+ providerMetadata: {
84
+ xai: {
85
+ ...(response.filename != null ? { filename: response.filename } : {}),
86
+ ...(response.bytes != null ? { bytes: response.bytes } : {}),
87
+ ...(response.created_at != null
88
+ ? { createdAt: response.created_at }
89
+ : {}),
90
+ },
91
+ },
92
+ };
93
+ }
94
+ }
package/src/index.ts CHANGED
@@ -2,26 +2,31 @@ export type {
2
2
  XaiLanguageModelChatOptions,
3
3
  /** @deprecated Use `XaiLanguageModelChatOptions` instead. */
4
4
  XaiLanguageModelChatOptions as XaiProviderOptions,
5
- } from './xai-chat-options';
5
+ } from './xai-chat-language-model-options';
6
6
  export type { XaiErrorData } from './xai-error';
7
7
  export type {
8
8
  XaiLanguageModelResponsesOptions,
9
9
  /** @deprecated Use `XaiLanguageModelResponsesOptions` instead. */
10
10
  XaiLanguageModelResponsesOptions as XaiResponsesProviderOptions,
11
- } from './responses/xai-responses-options';
11
+ } from './responses/xai-responses-language-model-options';
12
12
  export type {
13
13
  XaiImageModelOptions,
14
14
  /** @deprecated Use `XaiImageModelOptions` instead. */
15
15
  XaiImageModelOptions as XaiImageProviderOptions,
16
- } from './xai-image-options';
16
+ } from './xai-image-model-options';
17
17
  export type { XaiVideoModelId } from './xai-video-settings';
18
18
  export type {
19
19
  XaiVideoModelOptions,
20
20
  /** @deprecated Use `XaiVideoModelOptions` instead. */
21
21
  XaiVideoModelOptions as XaiVideoProviderOptions,
22
- } from './xai-video-options';
22
+ } from './xai-video-model-options';
23
+ export type { XaiSpeechModelOptions } from './xai-speech-model-options';
24
+ export type { XaiTranscriptionModelOptions } from './xai-transcription-model-options';
25
+ export type { XaiFilesOptions } from './files/xai-files-options';
23
26
  export { createXai, xai } from './xai-provider';
24
27
  export type { XaiProvider, XaiProviderSettings } from './xai-provider';
28
+ export { XaiRealtimeModel as Experimental_XaiRealtimeModel } from './realtime/xai-realtime-model';
29
+ export type { XaiRealtimeModelConfig as Experimental_XaiRealtimeModelConfig } from './realtime/xai-realtime-model';
25
30
  export {
26
31
  codeExecution,
27
32
  mcpServer,
@@ -1,8 +1,8 @@
1
- import { LanguageModelV3FinishReason } 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,
5
- ): LanguageModelV3FinishReason['unified'] {
5
+ ): LanguageModelV4FinishReason['unified'] {
6
6
  switch (finishReason) {
7
7
  case 'stop':
8
8
  return 'stop';
@@ -0,0 +1,2 @@
1
+ export { XaiRealtimeModel as Experimental_XaiRealtimeModel } from './xai-realtime-model';
2
+ export type { XaiRealtimeModelConfig as Experimental_XaiRealtimeModelConfig } from './xai-realtime-model';