@ai-sdk/xai 5.0.7 → 5.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/CHANGELOG.md +22 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +424 -311
- package/dist/index.js.map +1 -1
- package/docs/01-xai.mdx +93 -34
- package/package.json +3 -3
- package/src/responses/xai-responses-api.ts +8 -1
- package/src/responses/xai-responses-language-model-options.ts +27 -1
- package/src/responses/xai-responses-language-model.ts +38 -14
- package/src/xai-video-model-options.ts +27 -0
- package/src/xai-video-model.ts +179 -53
package/docs/01-xai.mdx
CHANGED
|
@@ -588,15 +588,39 @@ The following provider options are available:
|
|
|
588
588
|
|
|
589
589
|
- **logprobs** _boolean_
|
|
590
590
|
|
|
591
|
-
Return log probabilities for output tokens.
|
|
591
|
+
Return log probabilities for output tokens. This is silently ignored by `grok-4.20` and newer models.
|
|
592
592
|
|
|
593
593
|
- **topLogprobs** _number_
|
|
594
594
|
|
|
595
|
-
Number of most likely tokens to return per token position (0-8). When set, `logprobs` is automatically enabled.
|
|
595
|
+
Number of most likely tokens to return per token position (0-8). When set, `logprobs` is automatically enabled. This is silently ignored by `grok-4.20` and newer models.
|
|
596
596
|
|
|
597
|
-
- **
|
|
597
|
+
- **minP** _number_
|
|
598
|
+
|
|
599
|
+
Set the min-p sampling threshold between 0 and 1. Tokens whose probability is below `minP` times the most likely token's probability are excluded. Unlike the standard AI SDK `topK` option, `minP` is xAI-specific and must be set in `providerOptions.xai`.
|
|
600
|
+
|
|
601
|
+
- **maxTurns** _number_
|
|
602
|
+
|
|
603
|
+
Set the maximum number of assistant/server-side tool turns xAI may perform within one API request. This limits xAI's internal loop for provider-executed tools such as web search; it is separate from AI SDK's `stopWhen`, which limits the outer loop of AI SDK steps and API requests.
|
|
604
|
+
|
|
605
|
+
- **parallelToolCalls** _boolean_
|
|
606
|
+
|
|
607
|
+
Allow the model to call tools in parallel. Defaults to `true`.
|
|
608
|
+
|
|
609
|
+
- **promptCacheKey** _string_
|
|
610
|
+
|
|
611
|
+
Route requests with shared prompt prefixes to improve cache reuse.
|
|
612
|
+
|
|
613
|
+
- **safetyIdentifier** _string_
|
|
614
|
+
|
|
615
|
+
Provide a stable, preferably hashed end-user identifier for safety monitoring.
|
|
598
616
|
|
|
599
|
-
|
|
617
|
+
- **user** _string_
|
|
618
|
+
|
|
619
|
+
Provide an end-user identifier for abuse monitoring.
|
|
620
|
+
|
|
621
|
+
- **include** _Array<'file_search_call.results' | 'web_search_call.action.sources' | 'code_interpreter_call.outputs' | 'reasoning.encrypted_content' | 'no_inline_citations'>_
|
|
622
|
+
|
|
623
|
+
Include file-search results, web-search sources, code-interpreter outputs, or encrypted reasoning content, or disable inline citations.
|
|
600
624
|
|
|
601
625
|
- **store** _boolean_
|
|
602
626
|
|
|
@@ -1062,7 +1086,7 @@ import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
|
|
|
1062
1086
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
1063
1087
|
|
|
1064
1088
|
const { video } = await generateVideo({
|
|
1065
|
-
model: xai.video('grok-imagine-video'),
|
|
1089
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1066
1090
|
prompt: 'A chicken flying into the sunset in the style of 90s anime.',
|
|
1067
1091
|
aspectRatio: '16:9',
|
|
1068
1092
|
duration: 5,
|
|
@@ -1084,7 +1108,7 @@ import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
|
|
|
1084
1108
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
1085
1109
|
|
|
1086
1110
|
const { video } = await generateVideo({
|
|
1087
|
-
model: xai.video('grok-imagine-video'),
|
|
1111
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1088
1112
|
prompt: {
|
|
1089
1113
|
image: 'https://example.com/start-frame.png',
|
|
1090
1114
|
text: 'The cat slowly turns its head and blinks',
|
|
@@ -1106,7 +1130,7 @@ import { experimental_generateVideo as generateVideo } from 'ai';
|
|
|
1106
1130
|
import fs from 'node:fs';
|
|
1107
1131
|
|
|
1108
1132
|
const { video } = await generateVideo({
|
|
1109
|
-
model: xai.video('grok-imagine-video'),
|
|
1133
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1110
1134
|
prompt: 'The cat slowly turns its head and blinks',
|
|
1111
1135
|
frameImages: [
|
|
1112
1136
|
{
|
|
@@ -1124,9 +1148,9 @@ const { video } = await generateVideo({
|
|
|
1124
1148
|
```
|
|
1125
1149
|
|
|
1126
1150
|
<Note>
|
|
1127
|
-
|
|
1128
|
-
`
|
|
1129
|
-
continue
|
|
1151
|
+
`grok-imagine-video-1.5` supports first-last-frame interpolation. Earlier
|
|
1152
|
+
models ignore a `last_frame` entry with a warning. Use `extend-video` when you
|
|
1153
|
+
want to continue an existing video rather than pin its final frame.
|
|
1130
1154
|
</Note>
|
|
1131
1155
|
|
|
1132
1156
|
### Video Editing
|
|
@@ -1138,7 +1162,7 @@ import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
|
|
|
1138
1162
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
1139
1163
|
|
|
1140
1164
|
const { video } = await generateVideo({
|
|
1141
|
-
model: xai.video('grok-imagine-video'),
|
|
1165
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1142
1166
|
prompt: 'Give the person sunglasses and a hat',
|
|
1143
1167
|
providerOptions: {
|
|
1144
1168
|
xai: {
|
|
@@ -1176,7 +1200,7 @@ const providerOptions = {
|
|
|
1176
1200
|
|
|
1177
1201
|
// Step 1: Apply an initial edit
|
|
1178
1202
|
const step1 = await generateVideo({
|
|
1179
|
-
model: xai.video('grok-imagine-video'),
|
|
1203
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1180
1204
|
prompt: 'Add a party hat to the person',
|
|
1181
1205
|
providerOptions,
|
|
1182
1206
|
});
|
|
@@ -1187,7 +1211,7 @@ const step1VideoUrl = step1.providerMetadata?.xai?.videoUrl as string;
|
|
|
1187
1211
|
// Step 2: Apply two more edits concurrently, building on step 1
|
|
1188
1212
|
const [withSunglasses, withScarf] = await Promise.all([
|
|
1189
1213
|
generateVideo({
|
|
1190
|
-
model: xai.video('grok-imagine-video'),
|
|
1214
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1191
1215
|
prompt: 'Add sunglasses',
|
|
1192
1216
|
providerOptions: {
|
|
1193
1217
|
xai: {
|
|
@@ -1198,7 +1222,7 @@ const [withSunglasses, withScarf] = await Promise.all([
|
|
|
1198
1222
|
},
|
|
1199
1223
|
}),
|
|
1200
1224
|
generateVideo({
|
|
1201
|
-
model: xai.video('grok-imagine-video'),
|
|
1225
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1202
1226
|
prompt: 'Add a scarf',
|
|
1203
1227
|
providerOptions: {
|
|
1204
1228
|
xai: {
|
|
@@ -1221,7 +1245,7 @@ import { experimental_generateVideo as generateVideo } from 'ai';
|
|
|
1221
1245
|
|
|
1222
1246
|
// Step 1: Generate a source video
|
|
1223
1247
|
const source = await generateVideo({
|
|
1224
|
-
model: xai.video('grok-imagine-video'),
|
|
1248
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1225
1249
|
prompt: 'A cat sitting on a sunlit windowsill, tail gently swishing.',
|
|
1226
1250
|
duration: 5,
|
|
1227
1251
|
aspectRatio: '16:9',
|
|
@@ -1236,7 +1260,7 @@ const sourceUrl = source.providerMetadata?.xai?.videoUrl as string;
|
|
|
1236
1260
|
|
|
1237
1261
|
// Step 2: Extend the video with a new scene
|
|
1238
1262
|
const extended = await generateVideo({
|
|
1239
|
-
model: xai.video('grok-imagine-video'),
|
|
1263
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1240
1264
|
prompt: 'The cat turns its head, notices a butterfly, and leaps off.',
|
|
1241
1265
|
duration: 6,
|
|
1242
1266
|
providerOptions: {
|
|
@@ -1264,7 +1288,7 @@ import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
|
|
|
1264
1288
|
import { experimental_generateVideo as generateVideo } from 'ai';
|
|
1265
1289
|
|
|
1266
1290
|
const { video } = await generateVideo({
|
|
1267
|
-
model: xai.video('grok-imagine-video'),
|
|
1291
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1268
1292
|
prompt:
|
|
1269
1293
|
'The comic cat from <IMAGE_1> and the comic dog from <IMAGE_2> ' +
|
|
1270
1294
|
'are having a playful chase through a sunlit park. ' +
|
|
@@ -1294,7 +1318,7 @@ import { experimental_generateVideo as generateVideo } from 'ai';
|
|
|
1294
1318
|
import fs from 'node:fs';
|
|
1295
1319
|
|
|
1296
1320
|
const { video } = await generateVideo({
|
|
1297
|
-
model: xai.video('grok-imagine-video'),
|
|
1321
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1298
1322
|
prompt:
|
|
1299
1323
|
'The comic cat and the comic dog are having a playful chase ' +
|
|
1300
1324
|
'through a sunlit park. Cinematic slow-motion, warm afternoon light.',
|
|
@@ -1312,17 +1336,17 @@ const { video } = await generateVideo({
|
|
|
1312
1336
|
});
|
|
1313
1337
|
```
|
|
1314
1338
|
|
|
1315
|
-
`inputReferences` accepts image references
|
|
1316
|
-
media type
|
|
1317
|
-
reference with no media type is
|
|
1318
|
-
|
|
1339
|
+
`inputReferences` accepts image and audio references. Audio references must
|
|
1340
|
+
declare an audio media type and can be supplied alone or together with images;
|
|
1341
|
+
they are sent through `reference_audios`. A reference with no media type is
|
|
1342
|
+
treated as an image. Video references are ignored with a warning.
|
|
1319
1343
|
|
|
1320
1344
|
#### Reference Audio
|
|
1321
1345
|
|
|
1322
|
-
Reference-to-video can also give the subject a voice. `
|
|
1323
|
-
up to 3 xAI
|
|
1324
|
-
Reference
|
|
1325
|
-
`<AUDIO_2>`, in the order
|
|
1346
|
+
Reference-to-video can also give the subject a voice. Use `inputReferences` for
|
|
1347
|
+
caller-supplied audio clips, or `referenceVoiceIds` for up to 3 xAI preset voice
|
|
1348
|
+
ids. Reference them from the prompt with `<AUDIO_0>`, `<AUDIO_1>`, and
|
|
1349
|
+
`<AUDIO_2>`, in the order they are passed.
|
|
1326
1350
|
|
|
1327
1351
|
```ts
|
|
1328
1352
|
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
|
|
@@ -1357,19 +1381,18 @@ available voices. `referenceVoiceIds` is ignored with a warning when the
|
|
|
1357
1381
|
resolved operation is not reference-to-video.
|
|
1358
1382
|
|
|
1359
1383
|
<Note>
|
|
1360
|
-
|
|
1361
|
-
trusted partners
|
|
1362
|
-
|
|
1384
|
+
Preset voices are generally available. Caller-supplied voice clips are
|
|
1385
|
+
available to trusted partners on request. xAI accepts at most three audio
|
|
1386
|
+
references per request.
|
|
1363
1387
|
</Note>
|
|
1364
1388
|
|
|
1365
1389
|
<Note>
|
|
1366
1390
|
Reference-to-video supports `duration`, `aspectRatio`, and `resolution`. Use
|
|
1367
|
-
`mode` to select the operation — each mode is mutually exclusive.
|
|
1368
|
-
are provided, `frameImages` takes precedence over `inputReferences`, and
|
|
1391
|
+
`mode` to select the operation — each mode is mutually exclusive.
|
|
1369
1392
|
`inputReferences` takes precedence over the legacy `referenceImageUrls`
|
|
1370
|
-
provider option. Reference-to-video is
|
|
1371
|
-
and `grok-imagine-video-1.5` models;
|
|
1372
|
-
`grok-imagine-video-1.5`.
|
|
1393
|
+
provider option and can be combined with pinned frames. Reference-to-video is
|
|
1394
|
+
supported by the `grok-imagine-video` and `grok-imagine-video-1.5` models;
|
|
1395
|
+
native 1080p requires `grok-imagine-video-1.5`.
|
|
1373
1396
|
</Note>
|
|
1374
1397
|
|
|
1375
1398
|
### Video Provider Options
|
|
@@ -1435,6 +1458,42 @@ You can validate the provider options using the `XaiVideoModelOptions` type.
|
|
|
1435
1458
|
Ignored with a warning outside reference-to-video. Reference audio is
|
|
1436
1459
|
documented as US-only and limited to trusted partners.
|
|
1437
1460
|
|
|
1461
|
+
- **storageOptions** _object_
|
|
1462
|
+
|
|
1463
|
+
Stores the generated video in the xAI Files API. Set `filename` and
|
|
1464
|
+
optionally `expiresAfter` (up to 30 days) and `publicUrl`. Stored-file
|
|
1465
|
+
details and storage errors are returned in `providerMetadata.xai.fileOutput`
|
|
1466
|
+
and `providerMetadata.xai.storageError`.
|
|
1467
|
+
|
|
1468
|
+
- **keyframes** _Array\<\{ imageUrl: string; timestampSeconds: number \}\>_
|
|
1469
|
+
|
|
1470
|
+
Up to four mid-video image anchors. Each timestamp must fall strictly inside
|
|
1471
|
+
the video duration. Keyframes are supported by `grok-imagine-video-1.5` and
|
|
1472
|
+
are ignored with a warning for editing and extension operations.
|
|
1473
|
+
|
|
1474
|
+
### Audio and Frame Controls
|
|
1475
|
+
|
|
1476
|
+
Use the provider-neutral `generateAudio` option to request or disable generated
|
|
1477
|
+
audio. Use `frameImages` for exact endpoint frames:
|
|
1478
|
+
|
|
1479
|
+
```ts
|
|
1480
|
+
const { video } = await generateVideo({
|
|
1481
|
+
model: xai.video('grok-imagine-video-1.5'),
|
|
1482
|
+
prompt: 'A paper boat drifting down a rain-soaked street',
|
|
1483
|
+
generateAudio: false,
|
|
1484
|
+
frameImages: [
|
|
1485
|
+
{
|
|
1486
|
+
frameType: 'last_frame',
|
|
1487
|
+
image: 'https://example.com/final-frame.png',
|
|
1488
|
+
},
|
|
1489
|
+
],
|
|
1490
|
+
});
|
|
1491
|
+
```
|
|
1492
|
+
|
|
1493
|
+
`last_frame` is supported only by `grok-imagine-video-1.5`. The provider emits
|
|
1494
|
+
an unsupported-feature warning and omits the field for other model IDs. A
|
|
1495
|
+
`first_frame` is sent as xAI's standard `image` input.
|
|
1496
|
+
|
|
1438
1497
|
<Note>
|
|
1439
1498
|
Video generation is an asynchronous process that can take several minutes.
|
|
1440
1499
|
Consider setting `pollTimeoutMs` to at least 10 minutes (600000ms) for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/xai",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@ai-sdk/provider": "4.0.18",
|
|
33
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
33
|
+
"@ai-sdk/provider-utils": "5.0.49"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@ai-sdk/test-server": "2.0.
|
|
36
|
+
"@ai-sdk/test-server": "2.0.2",
|
|
37
37
|
"@types/node": "22.19.19",
|
|
38
38
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
39
39
|
"tsup": "^8.5.1",
|
|
@@ -2,7 +2,10 @@ import { z } from 'zod/v4';
|
|
|
2
2
|
|
|
3
3
|
export type XaiResponsesIncludeValue =
|
|
4
4
|
| 'file_search_call.results'
|
|
5
|
-
| '
|
|
5
|
+
| 'web_search_call.action.sources'
|
|
6
|
+
| 'code_interpreter_call.outputs'
|
|
7
|
+
| 'reasoning.encrypted_content'
|
|
8
|
+
| 'no_inline_citations';
|
|
6
9
|
|
|
7
10
|
export type XaiResponsesIncludeOptions =
|
|
8
11
|
| Array<XaiResponsesIncludeValue>
|
|
@@ -317,6 +320,8 @@ export const xaiResponsesResponseSchema = z.object({
|
|
|
317
320
|
usage: xaiResponsesUsageSchema.nullish(),
|
|
318
321
|
status: z.string(),
|
|
319
322
|
service_tier: z.string().nullish(),
|
|
323
|
+
prompt_cache_key: z.string().nullish(),
|
|
324
|
+
safety_identifier: z.string().nullish(),
|
|
320
325
|
});
|
|
321
326
|
|
|
322
327
|
export const xaiResponsesChunkSchema = z.union([
|
|
@@ -602,6 +607,8 @@ export const xaiResponsesChunkSchema = z.union([
|
|
|
602
607
|
incomplete_details: z.object({ reason: z.string() }).nullish(),
|
|
603
608
|
usage: xaiResponsesUsageSchema.nullish(),
|
|
604
609
|
service_tier: z.string().nullish(),
|
|
610
|
+
prompt_cache_key: z.string().nullish(),
|
|
611
|
+
safety_identifier: z.string().nullish(),
|
|
605
612
|
}),
|
|
606
613
|
}),
|
|
607
614
|
z.object({
|
|
@@ -26,9 +26,23 @@ export const xaiLanguageModelResponsesOptions = z.object({
|
|
|
26
26
|
reasoningEffort: z
|
|
27
27
|
.enum(['none', 'low', 'medium', 'high', 'xhigh'])
|
|
28
28
|
.optional(),
|
|
29
|
+
/**
|
|
30
|
+
* @deprecated xAI ignores the requested summary level and always returns a
|
|
31
|
+
* detailed reasoning summary.
|
|
32
|
+
*/
|
|
29
33
|
reasoningSummary: z.enum(['auto', 'concise', 'detailed']).optional(),
|
|
30
34
|
logprobs: z.boolean().optional(),
|
|
31
35
|
topLogprobs: z.number().int().min(0).max(8).optional(),
|
|
36
|
+
/** Min-p sampling threshold between 0 and 1. */
|
|
37
|
+
minP: z.number().min(0).max(1).optional(),
|
|
38
|
+
/** Maximum number of agentic tool-calling turns. */
|
|
39
|
+
maxTurns: z.number().int().optional(),
|
|
40
|
+
/** Whether the model may call tools in parallel. @default true */
|
|
41
|
+
parallelToolCalls: z.boolean().optional(),
|
|
42
|
+
/** Cache key used to route requests with shared prompt prefixes. */
|
|
43
|
+
promptCacheKey: z.string().optional(),
|
|
44
|
+
/** Stable identifier used to attribute policy violations to an end user. */
|
|
45
|
+
safetyIdentifier: z.string().optional(),
|
|
32
46
|
serviceTier: z.enum(['default', 'priority']).optional(),
|
|
33
47
|
/**
|
|
34
48
|
* Whether to store the input message(s) and model response for later retrieval.
|
|
@@ -41,11 +55,23 @@ export const xaiLanguageModelResponsesOptions = z.object({
|
|
|
41
55
|
* The ID of the previous response from the model.
|
|
42
56
|
*/
|
|
43
57
|
previousResponseId: z.string().optional(),
|
|
58
|
+
/** A unique identifier for the end user, used for abuse monitoring. */
|
|
59
|
+
user: z.string().optional(),
|
|
44
60
|
/**
|
|
45
61
|
* Specify additional output data to include in the model response.
|
|
46
62
|
* Example values: 'file_search_call.results'.
|
|
47
63
|
*/
|
|
48
|
-
include: z
|
|
64
|
+
include: z
|
|
65
|
+
.array(
|
|
66
|
+
z.enum([
|
|
67
|
+
'file_search_call.results',
|
|
68
|
+
'web_search_call.action.sources',
|
|
69
|
+
'code_interpreter_call.outputs',
|
|
70
|
+
'reasoning.encrypted_content',
|
|
71
|
+
'no_inline_citations',
|
|
72
|
+
]),
|
|
73
|
+
)
|
|
74
|
+
.nullish(),
|
|
49
75
|
});
|
|
50
76
|
|
|
51
77
|
export type XaiLanguageModelResponsesOptions = z.infer<
|
|
@@ -211,10 +211,6 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
211
211
|
schema: xaiLanguageModelResponsesOptions,
|
|
212
212
|
})) ?? {};
|
|
213
213
|
|
|
214
|
-
if (topK != null) {
|
|
215
|
-
warnings.push({ type: 'unsupported', feature: 'topK' });
|
|
216
|
-
}
|
|
217
|
-
|
|
218
214
|
if (frequencyPenalty != null) {
|
|
219
215
|
warnings.push({ type: 'unsupported', feature: 'frequencyPenalty' });
|
|
220
216
|
}
|
|
@@ -318,6 +314,8 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
318
314
|
max_output_tokens: maxOutputTokens,
|
|
319
315
|
temperature,
|
|
320
316
|
top_p: topP,
|
|
317
|
+
top_k: topK,
|
|
318
|
+
min_p: options.minP,
|
|
321
319
|
seed,
|
|
322
320
|
...(responseFormat?.type === 'json' && {
|
|
323
321
|
text: {
|
|
@@ -333,15 +331,9 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
333
331
|
: { type: 'json_object' },
|
|
334
332
|
},
|
|
335
333
|
}),
|
|
336
|
-
...(
|
|
337
|
-
options.reasoningSummary != null) && {
|
|
334
|
+
...(resolvedReasoningEffort != null && {
|
|
338
335
|
reasoning: {
|
|
339
|
-
|
|
340
|
-
effort: resolvedReasoningEffort,
|
|
341
|
-
}),
|
|
342
|
-
...(options.reasoningSummary != null && {
|
|
343
|
-
summary: options.reasoningSummary,
|
|
344
|
-
}),
|
|
336
|
+
effort: resolvedReasoningEffort,
|
|
345
337
|
},
|
|
346
338
|
}),
|
|
347
339
|
...(options.store === false && {
|
|
@@ -353,9 +345,24 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
353
345
|
...(options.previousResponseId != null && {
|
|
354
346
|
previous_response_id: options.previousResponseId,
|
|
355
347
|
}),
|
|
348
|
+
...(options.maxTurns != null && {
|
|
349
|
+
max_turns: options.maxTurns,
|
|
350
|
+
}),
|
|
351
|
+
...(options.parallelToolCalls != null && {
|
|
352
|
+
parallel_tool_calls: options.parallelToolCalls,
|
|
353
|
+
}),
|
|
354
|
+
...(options.promptCacheKey != null && {
|
|
355
|
+
prompt_cache_key: options.promptCacheKey,
|
|
356
|
+
}),
|
|
357
|
+
...(options.safetyIdentifier != null && {
|
|
358
|
+
safety_identifier: options.safetyIdentifier,
|
|
359
|
+
}),
|
|
356
360
|
...(options.serviceTier != null && {
|
|
357
361
|
service_tier: options.serviceTier,
|
|
358
362
|
}),
|
|
363
|
+
...(options.user != null && {
|
|
364
|
+
user: options.user,
|
|
365
|
+
}),
|
|
359
366
|
};
|
|
360
367
|
|
|
361
368
|
if (xaiTools && xaiTools.length > 0) {
|
|
@@ -644,7 +651,9 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
644
651
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
645
652
|
},
|
|
646
653
|
...((response.usage?.cost_in_usd_ticks != null ||
|
|
647
|
-
response.service_tier != null
|
|
654
|
+
response.service_tier != null ||
|
|
655
|
+
response.prompt_cache_key != null ||
|
|
656
|
+
response.safety_identifier != null) && {
|
|
648
657
|
providerMetadata: {
|
|
649
658
|
xai: {
|
|
650
659
|
...(response.usage?.cost_in_usd_ticks != null && {
|
|
@@ -653,6 +662,12 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
653
662
|
...(response.service_tier != null && {
|
|
654
663
|
serviceTier: response.service_tier,
|
|
655
664
|
}),
|
|
665
|
+
...(response.prompt_cache_key != null && {
|
|
666
|
+
promptCacheKey: response.prompt_cache_key,
|
|
667
|
+
}),
|
|
668
|
+
...(response.safety_identifier != null && {
|
|
669
|
+
safetyIdentifier: response.safety_identifier,
|
|
670
|
+
}),
|
|
656
671
|
},
|
|
657
672
|
},
|
|
658
673
|
}),
|
|
@@ -704,6 +719,8 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
704
719
|
let usage: LanguageModelV4Usage | undefined = undefined;
|
|
705
720
|
let costInUsdTicks: number | undefined = undefined;
|
|
706
721
|
let serviceTier: string | undefined = undefined;
|
|
722
|
+
let promptCacheKey: string | undefined = undefined;
|
|
723
|
+
let safetyIdentifier: string | undefined = undefined;
|
|
707
724
|
let isFirstChunk = true;
|
|
708
725
|
const contentBlocks: Record<string, { type: 'text' }> = {};
|
|
709
726
|
const seenToolCalls = new Set<string>();
|
|
@@ -899,6 +916,8 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
899
916
|
}
|
|
900
917
|
|
|
901
918
|
serviceTier = response.service_tier ?? undefined;
|
|
919
|
+
promptCacheKey = response.prompt_cache_key ?? undefined;
|
|
920
|
+
safetyIdentifier = response.safety_identifier ?? undefined;
|
|
902
921
|
|
|
903
922
|
if (event.type === 'response.incomplete') {
|
|
904
923
|
const reason =
|
|
@@ -1371,11 +1390,16 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1371
1390
|
},
|
|
1372
1391
|
outputTokens: { total: 0, text: 0, reasoning: 0 },
|
|
1373
1392
|
},
|
|
1374
|
-
...((costInUsdTicks != null ||
|
|
1393
|
+
...((costInUsdTicks != null ||
|
|
1394
|
+
serviceTier != null ||
|
|
1395
|
+
promptCacheKey != null ||
|
|
1396
|
+
safetyIdentifier != null) && {
|
|
1375
1397
|
providerMetadata: {
|
|
1376
1398
|
xai: {
|
|
1377
1399
|
...(costInUsdTicks != null && { costInUsdTicks }),
|
|
1378
1400
|
...(serviceTier != null && { serviceTier }),
|
|
1401
|
+
...(promptCacheKey != null && { promptCacheKey }),
|
|
1402
|
+
...(safetyIdentifier != null && { safetyIdentifier }),
|
|
1379
1403
|
},
|
|
1380
1404
|
},
|
|
1381
1405
|
}),
|
|
@@ -8,10 +8,33 @@ const modeSchema = z.enum(['edit-video', 'extend-video', 'reference-to-video']);
|
|
|
8
8
|
export type XaiVideoMode = z.infer<typeof modeSchema>;
|
|
9
9
|
type XaiVideoResolution = z.infer<typeof resolutionSchema>;
|
|
10
10
|
|
|
11
|
+
const keyframeSchema = z.object({
|
|
12
|
+
imageUrl: nonEmptyStringSchema,
|
|
13
|
+
timestampSeconds: z.number().positive(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const storageOptionsSchema = z.object({
|
|
17
|
+
filename: nonEmptyStringSchema,
|
|
18
|
+
expiresAfter: z.number().int().positive().max(2_592_000).optional(),
|
|
19
|
+
publicUrl: z
|
|
20
|
+
.union([
|
|
21
|
+
z.boolean(),
|
|
22
|
+
z.object({
|
|
23
|
+
expiresAfter: z.number().int().min(3_600).max(2_592_000).optional(),
|
|
24
|
+
}),
|
|
25
|
+
])
|
|
26
|
+
.optional(),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export type XaiVideoKeyframe = z.infer<typeof keyframeSchema>;
|
|
30
|
+
export type XaiVideoStorageOptions = z.infer<typeof storageOptionsSchema>;
|
|
31
|
+
|
|
11
32
|
interface XaiVideoSharedOptions {
|
|
12
33
|
pollIntervalMs?: number | null;
|
|
13
34
|
pollTimeoutMs?: number | null;
|
|
14
35
|
resolution?: XaiVideoResolution | null;
|
|
36
|
+
/** Store the generated video in the xAI Files API. */
|
|
37
|
+
storageOptions?: XaiVideoStorageOptions;
|
|
15
38
|
}
|
|
16
39
|
|
|
17
40
|
interface XaiVideoUserOptions {
|
|
@@ -59,6 +82,8 @@ interface XaiVideoGenerationOptions
|
|
|
59
82
|
mode?: undefined;
|
|
60
83
|
videoUrl?: undefined;
|
|
61
84
|
referenceImageUrls?: undefined;
|
|
85
|
+
/** Mid-video image anchors (up to 4). */
|
|
86
|
+
keyframes?: XaiVideoKeyframe[];
|
|
62
87
|
}
|
|
63
88
|
|
|
64
89
|
interface XaiLegacyEditVideoOptions
|
|
@@ -119,6 +144,8 @@ const runtimeSchema = z.looseObject({
|
|
|
119
144
|
videoUrl: nonEmptyStringSchema.optional(),
|
|
120
145
|
referenceImageUrls: z.array(nonEmptyStringSchema).min(1).max(7).optional(),
|
|
121
146
|
referenceVoiceIds: z.array(nonEmptyStringSchema).max(3).optional(),
|
|
147
|
+
keyframes: z.array(keyframeSchema).max(4).optional(),
|
|
148
|
+
storageOptions: storageOptionsSchema.optional(),
|
|
122
149
|
user: z.string().optional(),
|
|
123
150
|
...baseFields,
|
|
124
151
|
});
|