@ai-sdk/xai 3.0.76 → 3.0.78

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # @ai-sdk/xai
2
2
 
3
+ ## 3.0.78
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [6247886]
8
+ - @ai-sdk/provider-utils@4.0.23
9
+ - @ai-sdk/openai-compatible@2.0.39
10
+
11
+ ## 3.0.77
12
+
13
+ ### Patch Changes
14
+
15
+ - bacdae4: feat(provider/xai): add video extension and reference-to-video (R2V) support
16
+
3
17
  ## 3.0.76
4
18
 
5
19
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -97,13 +97,76 @@ type XaiImageModelOptions = z.infer<typeof xaiImageModelOptions>;
97
97
 
98
98
  type XaiVideoModelId = 'grok-imagine-video' | (string & {});
99
99
 
100
- type XaiVideoModelOptions = {
100
+ declare const resolutionSchema: z.ZodEnum<{
101
+ "480p": "480p";
102
+ "720p": "720p";
103
+ }>;
104
+ type XaiVideoResolution = z.infer<typeof resolutionSchema>;
105
+ interface XaiVideoSharedOptions {
101
106
  pollIntervalMs?: number | null;
102
107
  pollTimeoutMs?: number | null;
103
- resolution?: '480p' | '720p' | null;
104
- videoUrl?: string | null;
105
- [key: string]: unknown;
106
- };
108
+ resolution?: XaiVideoResolution | null;
109
+ }
110
+ interface XaiVideoEditModeOptions extends XaiVideoSharedOptions {
111
+ /**
112
+ * Select edit-video mode explicitly for best autocomplete and narrowing.
113
+ */
114
+ mode: 'edit-video';
115
+ /** Source video URL to edit. */
116
+ videoUrl: string;
117
+ }
118
+ interface XaiVideoExtendModeOptions extends XaiVideoSharedOptions {
119
+ /**
120
+ * Select extend-video mode explicitly for best autocomplete and narrowing.
121
+ */
122
+ mode: 'extend-video';
123
+ /** Source video URL to extend from its last frame. */
124
+ videoUrl: string;
125
+ }
126
+ interface XaiVideoReferenceToVideoOptions extends XaiVideoSharedOptions {
127
+ /**
128
+ * Select reference-to-video mode explicitly for best autocomplete and narrowing.
129
+ */
130
+ mode: 'reference-to-video';
131
+ /** Reference image URLs (1-7) for R2V generation. */
132
+ referenceImageUrls: string[];
133
+ }
134
+ interface XaiVideoGenerationOptions extends XaiVideoSharedOptions {
135
+ mode?: undefined;
136
+ videoUrl?: undefined;
137
+ referenceImageUrls?: undefined;
138
+ }
139
+ interface XaiLegacyEditVideoOptions extends XaiVideoSharedOptions {
140
+ /**
141
+ * Legacy backward-compatible shape: omitting `mode` while providing
142
+ * `videoUrl` behaves like edit-video.
143
+ */
144
+ mode?: undefined;
145
+ videoUrl: string;
146
+ }
147
+ interface XaiLegacyReferenceToVideoOptions extends XaiVideoSharedOptions {
148
+ /**
149
+ * Legacy backward-compatible shape: omitting `mode` while providing
150
+ * `referenceImageUrls` behaves like reference-to-video.
151
+ */
152
+ mode?: undefined;
153
+ referenceImageUrls: string[];
154
+ }
155
+ /**
156
+ * Provider options for xAI video generation.
157
+ *
158
+ * Use the `mode` option to select the operation:
159
+ *
160
+ * - `'edit-video'` + `videoUrl` -- video editing (`POST /v1/videos/edits`)
161
+ * - `'extend-video'` + `videoUrl` -- video extension (`POST /v1/videos/extensions`)
162
+ * - `'reference-to-video'` + `referenceImageUrls` -- R2V generation (`POST /v1/videos/generations`)
163
+ * - no `mode` -- standard generation from text prompts or image input
164
+ *
165
+ * Runtime remains backward compatible with legacy auto-detected provider
166
+ * options, but the public TypeScript type is intentionally explicit so editors
167
+ * can suggest valid modes and flag invalid field combinations.
168
+ */
169
+ type XaiVideoModelOptions = XaiVideoGenerationOptions | XaiVideoEditModeOptions | XaiVideoExtendModeOptions | XaiVideoReferenceToVideoOptions | XaiLegacyEditVideoOptions | XaiLegacyReferenceToVideoOptions;
107
170
 
108
171
  type XaiImageModelId = 'grok-imagine-image' | 'grok-imagine-image-pro' | (string & {});
109
172
 
package/dist/index.d.ts CHANGED
@@ -97,13 +97,76 @@ type XaiImageModelOptions = z.infer<typeof xaiImageModelOptions>;
97
97
 
98
98
  type XaiVideoModelId = 'grok-imagine-video' | (string & {});
99
99
 
100
- type XaiVideoModelOptions = {
100
+ declare const resolutionSchema: z.ZodEnum<{
101
+ "480p": "480p";
102
+ "720p": "720p";
103
+ }>;
104
+ type XaiVideoResolution = z.infer<typeof resolutionSchema>;
105
+ interface XaiVideoSharedOptions {
101
106
  pollIntervalMs?: number | null;
102
107
  pollTimeoutMs?: number | null;
103
- resolution?: '480p' | '720p' | null;
104
- videoUrl?: string | null;
105
- [key: string]: unknown;
106
- };
108
+ resolution?: XaiVideoResolution | null;
109
+ }
110
+ interface XaiVideoEditModeOptions extends XaiVideoSharedOptions {
111
+ /**
112
+ * Select edit-video mode explicitly for best autocomplete and narrowing.
113
+ */
114
+ mode: 'edit-video';
115
+ /** Source video URL to edit. */
116
+ videoUrl: string;
117
+ }
118
+ interface XaiVideoExtendModeOptions extends XaiVideoSharedOptions {
119
+ /**
120
+ * Select extend-video mode explicitly for best autocomplete and narrowing.
121
+ */
122
+ mode: 'extend-video';
123
+ /** Source video URL to extend from its last frame. */
124
+ videoUrl: string;
125
+ }
126
+ interface XaiVideoReferenceToVideoOptions extends XaiVideoSharedOptions {
127
+ /**
128
+ * Select reference-to-video mode explicitly for best autocomplete and narrowing.
129
+ */
130
+ mode: 'reference-to-video';
131
+ /** Reference image URLs (1-7) for R2V generation. */
132
+ referenceImageUrls: string[];
133
+ }
134
+ interface XaiVideoGenerationOptions extends XaiVideoSharedOptions {
135
+ mode?: undefined;
136
+ videoUrl?: undefined;
137
+ referenceImageUrls?: undefined;
138
+ }
139
+ interface XaiLegacyEditVideoOptions extends XaiVideoSharedOptions {
140
+ /**
141
+ * Legacy backward-compatible shape: omitting `mode` while providing
142
+ * `videoUrl` behaves like edit-video.
143
+ */
144
+ mode?: undefined;
145
+ videoUrl: string;
146
+ }
147
+ interface XaiLegacyReferenceToVideoOptions extends XaiVideoSharedOptions {
148
+ /**
149
+ * Legacy backward-compatible shape: omitting `mode` while providing
150
+ * `referenceImageUrls` behaves like reference-to-video.
151
+ */
152
+ mode?: undefined;
153
+ referenceImageUrls: string[];
154
+ }
155
+ /**
156
+ * Provider options for xAI video generation.
157
+ *
158
+ * Use the `mode` option to select the operation:
159
+ *
160
+ * - `'edit-video'` + `videoUrl` -- video editing (`POST /v1/videos/edits`)
161
+ * - `'extend-video'` + `videoUrl` -- video extension (`POST /v1/videos/extensions`)
162
+ * - `'reference-to-video'` + `referenceImageUrls` -- R2V generation (`POST /v1/videos/generations`)
163
+ * - no `mode` -- standard generation from text prompts or image input
164
+ *
165
+ * Runtime remains backward compatible with legacy auto-detected provider
166
+ * options, but the public TypeScript type is intentionally explicit so editors
167
+ * can suggest valid modes and flag invalid field combinations.
168
+ */
169
+ type XaiVideoModelOptions = XaiVideoGenerationOptions | XaiVideoEditModeOptions | XaiVideoExtendModeOptions | XaiVideoReferenceToVideoOptions | XaiLegacyEditVideoOptions | XaiLegacyReferenceToVideoOptions;
107
170
 
108
171
  type XaiImageModelId = 'grok-imagine-image' | 'grok-imagine-image-pro' | (string & {});
109
172
 
package/dist/index.js CHANGED
@@ -2719,7 +2719,7 @@ var xaiTools = {
2719
2719
  };
2720
2720
 
2721
2721
  // src/version.ts
2722
- var VERSION = true ? "3.0.76" : "0.0.0-test";
2722
+ var VERSION = true ? "3.0.78" : "0.0.0-test";
2723
2723
 
2724
2724
  // src/xai-video-model.ts
2725
2725
  var import_provider6 = require("@ai-sdk/provider");
@@ -2729,15 +2729,52 @@ var import_v416 = require("zod/v4");
2729
2729
  // src/xai-video-options.ts
2730
2730
  var import_provider_utils15 = require("@ai-sdk/provider-utils");
2731
2731
  var import_v415 = require("zod/v4");
2732
+ var nonEmptyStringSchema = import_v415.z.string().min(1);
2733
+ var resolutionSchema = import_v415.z.enum(["480p", "720p"]);
2734
+ var modeSchema = import_v415.z.enum(["edit-video", "extend-video", "reference-to-video"]);
2735
+ var baseFields = {
2736
+ pollIntervalMs: import_v415.z.number().positive().nullish(),
2737
+ pollTimeoutMs: import_v415.z.number().positive().nullish(),
2738
+ resolution: resolutionSchema.nullish()
2739
+ };
2740
+ var editVideoSchema = import_v415.z.object({
2741
+ ...baseFields,
2742
+ mode: import_v415.z.literal("edit-video"),
2743
+ videoUrl: nonEmptyStringSchema,
2744
+ referenceImageUrls: import_v415.z.undefined().optional()
2745
+ });
2746
+ var extendVideoSchema = import_v415.z.object({
2747
+ ...baseFields,
2748
+ mode: import_v415.z.literal("extend-video"),
2749
+ videoUrl: nonEmptyStringSchema,
2750
+ referenceImageUrls: import_v415.z.undefined().optional()
2751
+ });
2752
+ var referenceToVideoSchema = import_v415.z.object({
2753
+ ...baseFields,
2754
+ mode: import_v415.z.literal("reference-to-video"),
2755
+ referenceImageUrls: import_v415.z.array(nonEmptyStringSchema).min(1).max(7),
2756
+ videoUrl: import_v415.z.undefined().optional()
2757
+ });
2758
+ var autoDetectSchema = import_v415.z.object({
2759
+ ...baseFields,
2760
+ mode: import_v415.z.undefined().optional(),
2761
+ videoUrl: nonEmptyStringSchema.optional(),
2762
+ referenceImageUrls: import_v415.z.array(nonEmptyStringSchema).min(1).max(7).optional()
2763
+ });
2764
+ var xaiVideoModelOptions = import_v415.z.union([
2765
+ editVideoSchema,
2766
+ extendVideoSchema,
2767
+ referenceToVideoSchema,
2768
+ autoDetectSchema
2769
+ ]);
2770
+ var runtimeSchema = import_v415.z.object({
2771
+ mode: modeSchema.optional(),
2772
+ videoUrl: nonEmptyStringSchema.optional(),
2773
+ referenceImageUrls: import_v415.z.array(nonEmptyStringSchema).min(1).max(7).optional(),
2774
+ ...baseFields
2775
+ }).passthrough();
2732
2776
  var xaiVideoModelOptionsSchema = (0, import_provider_utils15.lazySchema)(
2733
- () => (0, import_provider_utils15.zodSchema)(
2734
- import_v415.z.object({
2735
- pollIntervalMs: import_v415.z.number().positive().nullish(),
2736
- pollTimeoutMs: import_v415.z.number().positive().nullish(),
2737
- resolution: import_v415.z.enum(["480p", "720p"]).nullish(),
2738
- videoUrl: import_v415.z.string().nullish()
2739
- }).passthrough()
2740
- )
2777
+ () => (0, import_provider_utils15.zodSchema)(runtimeSchema)
2741
2778
  );
2742
2779
 
2743
2780
  // src/xai-video-model.ts
@@ -2746,6 +2783,18 @@ var RESOLUTION_MAP = {
2746
2783
  "854x480": "480p",
2747
2784
  "640x480": "480p"
2748
2785
  };
2786
+ function resolveVideoMode(options) {
2787
+ if ((options == null ? void 0 : options.mode) != null) {
2788
+ return options.mode;
2789
+ }
2790
+ if ((options == null ? void 0 : options.videoUrl) != null) {
2791
+ return "edit-video";
2792
+ }
2793
+ if ((options == null ? void 0 : options.referenceImageUrls) != null && options.referenceImageUrls.length > 0) {
2794
+ return "reference-to-video";
2795
+ }
2796
+ return void 0;
2797
+ }
2749
2798
  var XaiVideoModel = class {
2750
2799
  constructor(modelId, config) {
2751
2800
  this.modelId = modelId;
@@ -2765,7 +2814,10 @@ var XaiVideoModel = class {
2765
2814
  providerOptions: options.providerOptions,
2766
2815
  schema: xaiVideoModelOptionsSchema
2767
2816
  });
2768
- const isEdit = (xaiOptions == null ? void 0 : xaiOptions.videoUrl) != null;
2817
+ const effectiveMode = resolveVideoMode(xaiOptions);
2818
+ const isEdit = effectiveMode === "edit-video";
2819
+ const isExtension = effectiveMode === "extend-video";
2820
+ const hasReferenceImages = effectiveMode === "reference-to-video";
2769
2821
  if (options.fps != null) {
2770
2822
  warnings.push({
2771
2823
  type: "unsupported",
@@ -2808,19 +2860,36 @@ var XaiVideoModel = class {
2808
2860
  details: "xAI video editing does not support custom resolution."
2809
2861
  });
2810
2862
  }
2863
+ if (isExtension && options.aspectRatio != null) {
2864
+ warnings.push({
2865
+ type: "unsupported",
2866
+ feature: "aspectRatio",
2867
+ details: "xAI video extension does not support custom aspect ratio."
2868
+ });
2869
+ }
2870
+ if (isExtension && ((xaiOptions == null ? void 0 : xaiOptions.resolution) != null || options.resolution != null)) {
2871
+ warnings.push({
2872
+ type: "unsupported",
2873
+ feature: "resolution",
2874
+ details: "xAI video extension does not support custom resolution."
2875
+ });
2876
+ }
2811
2877
  const body = {
2812
2878
  model: this.modelId,
2813
2879
  prompt: options.prompt
2814
2880
  };
2815
- if (!isEdit && options.duration != null) {
2881
+ const allowDuration = !isEdit;
2882
+ const allowAspectRatio = !isEdit && !isExtension;
2883
+ const allowResolution = !isEdit && !isExtension;
2884
+ if (allowDuration && options.duration != null) {
2816
2885
  body.duration = options.duration;
2817
2886
  }
2818
- if (!isEdit && options.aspectRatio != null) {
2887
+ if (allowAspectRatio && options.aspectRatio != null) {
2819
2888
  body.aspect_ratio = options.aspectRatio;
2820
2889
  }
2821
- if (!isEdit && (xaiOptions == null ? void 0 : xaiOptions.resolution) != null) {
2890
+ if (allowResolution && (xaiOptions == null ? void 0 : xaiOptions.resolution) != null) {
2822
2891
  body.resolution = xaiOptions.resolution;
2823
- } else if (!isEdit && options.resolution != null) {
2892
+ } else if (allowResolution && options.resolution != null) {
2824
2893
  const mapped = RESOLUTION_MAP[options.resolution];
2825
2894
  if (mapped != null) {
2826
2895
  body.resolution = mapped;
@@ -2832,7 +2901,10 @@ var XaiVideoModel = class {
2832
2901
  });
2833
2902
  }
2834
2903
  }
2835
- if ((xaiOptions == null ? void 0 : xaiOptions.videoUrl) != null) {
2904
+ if (isEdit) {
2905
+ body.video = { url: xaiOptions.videoUrl };
2906
+ }
2907
+ if (isExtension) {
2836
2908
  body.video = { url: xaiOptions.videoUrl };
2837
2909
  }
2838
2910
  if (options.image != null) {
@@ -2845,21 +2917,36 @@ var XaiVideoModel = class {
2845
2917
  };
2846
2918
  }
2847
2919
  }
2920
+ if (hasReferenceImages) {
2921
+ body.reference_images = xaiOptions.referenceImageUrls.map((url) => ({
2922
+ url
2923
+ }));
2924
+ }
2848
2925
  if (xaiOptions != null) {
2849
2926
  for (const [key, value] of Object.entries(xaiOptions)) {
2850
2927
  if (![
2928
+ "mode",
2851
2929
  "pollIntervalMs",
2852
2930
  "pollTimeoutMs",
2853
2931
  "resolution",
2854
- "videoUrl"
2932
+ "videoUrl",
2933
+ "referenceImageUrls"
2855
2934
  ].includes(key)) {
2856
2935
  body[key] = value;
2857
2936
  }
2858
2937
  }
2859
2938
  }
2860
2939
  const baseURL = (_d = this.config.baseURL) != null ? _d : "https://api.x.ai/v1";
2940
+ let endpoint;
2941
+ if (isEdit) {
2942
+ endpoint = `${baseURL}/videos/edits`;
2943
+ } else if (isExtension) {
2944
+ endpoint = `${baseURL}/videos/extensions`;
2945
+ } else {
2946
+ endpoint = `${baseURL}/videos/generations`;
2947
+ }
2861
2948
  const { value: createResponse } = await (0, import_provider_utils16.postJsonToApi)({
2862
- url: `${baseURL}/videos/${isEdit ? "edits" : "generations"}`,
2949
+ url: endpoint,
2863
2950
  headers: (0, import_provider_utils16.combineHeaders)(this.config.headers(), options.headers),
2864
2951
  body,
2865
2952
  failedResponseHandler: xaiFailedResponseHandler,
@@ -2931,7 +3018,8 @@ var XaiVideoModel = class {
2931
3018
  requestId,
2932
3019
  videoUrl: statusResponse.video.url,
2933
3020
  ...statusResponse.video.duration != null ? { duration: statusResponse.video.duration } : {},
2934
- ...((_j = statusResponse.usage) == null ? void 0 : _j.cost_in_usd_ticks) != null ? { costInUsdTicks: statusResponse.usage.cost_in_usd_ticks } : {}
3021
+ ...((_j = statusResponse.usage) == null ? void 0 : _j.cost_in_usd_ticks) != null ? { costInUsdTicks: statusResponse.usage.cost_in_usd_ticks } : {},
3022
+ ...statusResponse.progress != null ? { progress: statusResponse.progress } : {}
2935
3023
  }
2936
3024
  }
2937
3025
  };
@@ -2942,6 +3030,12 @@ var XaiVideoModel = class {
2942
3030
  message: "Video generation request expired."
2943
3031
  });
2944
3032
  }
3033
+ if (statusResponse.status === "failed") {
3034
+ throw new import_provider6.AISDKError({
3035
+ name: "XAI_VIDEO_GENERATION_FAILED",
3036
+ message: "Video generation failed."
3037
+ });
3038
+ }
2945
3039
  }
2946
3040
  }
2947
3041
  };
@@ -2958,6 +3052,11 @@ var xaiVideoStatusResponseSchema = import_v416.z.object({
2958
3052
  model: import_v416.z.string().nullish(),
2959
3053
  usage: import_v416.z.object({
2960
3054
  cost_in_usd_ticks: import_v416.z.number().nullish()
3055
+ }).nullish(),
3056
+ progress: import_v416.z.number().nullish(),
3057
+ error: import_v416.z.object({
3058
+ code: import_v416.z.string().nullish(),
3059
+ message: import_v416.z.string().nullish()
2961
3060
  }).nullish()
2962
3061
  });
2963
3062