@ai-sdk/xai 4.0.0-beta.2 → 4.0.0-beta.4
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 +12 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +32 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -23
- package/dist/index.mjs.map +1 -1
- package/docs/01-xai.mdx +22 -1
- package/package.json +2 -2
- package/src/xai-image-model.ts +37 -22
- package/src/xai-image-options.ts +2 -0
package/docs/01-xai.mdx
CHANGED
|
@@ -840,6 +840,27 @@ const { images } = await generateImage({
|
|
|
840
840
|
});
|
|
841
841
|
```
|
|
842
842
|
|
|
843
|
+
#### Multi-Image Editing
|
|
844
|
+
|
|
845
|
+
Combine or reference multiple input images (up to 3) in the prompt:
|
|
846
|
+
|
|
847
|
+
```ts
|
|
848
|
+
import { xai } from '@ai-sdk/xai';
|
|
849
|
+
import { generateImage } from 'ai';
|
|
850
|
+
import { readFileSync } from 'fs';
|
|
851
|
+
|
|
852
|
+
const cat = readFileSync('./cat.png');
|
|
853
|
+
const dog = readFileSync('./dog.png');
|
|
854
|
+
|
|
855
|
+
const { images } = await generateImage({
|
|
856
|
+
model: xai.image('grok-imagine-image'),
|
|
857
|
+
prompt: {
|
|
858
|
+
text: 'Combine these two animals into a group photo',
|
|
859
|
+
images: [cat, dog],
|
|
860
|
+
},
|
|
861
|
+
});
|
|
862
|
+
```
|
|
863
|
+
|
|
843
864
|
#### Style Transfer
|
|
844
865
|
|
|
845
866
|
Apply artistic styles to an image:
|
|
@@ -859,7 +880,7 @@ const { images } = await generateImage({
|
|
|
859
880
|
|
|
860
881
|
<Note>
|
|
861
882
|
Input images can be provided as `Buffer`, `ArrayBuffer`, `Uint8Array`, or
|
|
862
|
-
base64-encoded strings.
|
|
883
|
+
base64-encoded strings. Up to 3 input images are supported per request.
|
|
863
884
|
</Note>
|
|
864
885
|
|
|
865
886
|
### Model-specific options
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/xai",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ai-sdk/openai-compatible": "3.0.0-beta.2",
|
|
33
32
|
"@ai-sdk/provider": "4.0.0-beta.0",
|
|
33
|
+
"@ai-sdk/openai-compatible": "3.0.0-beta.2",
|
|
34
34
|
"@ai-sdk/provider-utils": "5.0.0-beta.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
package/src/xai-image-model.ts
CHANGED
|
@@ -27,7 +27,7 @@ interface XaiImageModelConfig {
|
|
|
27
27
|
|
|
28
28
|
export class XaiImageModel implements ImageModelV3 {
|
|
29
29
|
readonly specificationVersion = 'v3';
|
|
30
|
-
readonly maxImagesPerCall =
|
|
30
|
+
readonly maxImagesPerCall = 3;
|
|
31
31
|
|
|
32
32
|
get provider(): string {
|
|
33
33
|
return this.config.provider;
|
|
@@ -84,19 +84,9 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
const hasFiles = files != null && files.length > 0;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
imageUrl = convertImageModelFileToDataUri(files[0]);
|
|
91
|
-
|
|
92
|
-
if (files.length > 1) {
|
|
93
|
-
warnings.push({
|
|
94
|
-
type: 'other',
|
|
95
|
-
message:
|
|
96
|
-
'xAI only supports a single input image. Additional images are ignored.',
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
87
|
+
const imageUrls = hasFiles
|
|
88
|
+
? files.map(file => convertImageModelFileToDataUri(file))
|
|
89
|
+
: [];
|
|
100
90
|
|
|
101
91
|
const endpoint = hasFiles ? '/images/edits' : '/images/generations';
|
|
102
92
|
|
|
@@ -104,7 +94,7 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
104
94
|
model: this.modelId,
|
|
105
95
|
prompt,
|
|
106
96
|
n,
|
|
107
|
-
response_format: '
|
|
97
|
+
response_format: 'b64_json',
|
|
108
98
|
};
|
|
109
99
|
|
|
110
100
|
if (aspectRatio != null) {
|
|
@@ -127,8 +117,18 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
127
117
|
body.resolution = xaiOptions.resolution;
|
|
128
118
|
}
|
|
129
119
|
|
|
130
|
-
if (
|
|
131
|
-
body.
|
|
120
|
+
if (xaiOptions?.quality != null) {
|
|
121
|
+
body.quality = xaiOptions.quality;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (xaiOptions?.user != null) {
|
|
125
|
+
body.user = xaiOptions.user;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (imageUrls.length === 1) {
|
|
129
|
+
body.image = { url: imageUrls[0], type: 'image_url' };
|
|
130
|
+
} else if (imageUrls.length > 1) {
|
|
131
|
+
body.images = imageUrls.map(url => ({ url, type: 'image_url' }));
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
const baseURL = this.config.baseURL ?? 'https://api.x.ai/v1';
|
|
@@ -145,12 +145,18 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
145
145
|
fetch: this.config.fetch,
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
const hasAllBase64 = response.data.every(image => image.b64_json != null);
|
|
149
|
+
|
|
150
|
+
const images = hasAllBase64
|
|
151
|
+
? response.data.map(image => image.b64_json!)
|
|
152
|
+
: await Promise.all(
|
|
153
|
+
response.data.map(image =>
|
|
154
|
+
this.downloadImage(image.url!, abortSignal),
|
|
155
|
+
),
|
|
156
|
+
);
|
|
151
157
|
|
|
152
158
|
return {
|
|
153
|
-
images
|
|
159
|
+
images,
|
|
154
160
|
warnings,
|
|
155
161
|
response: {
|
|
156
162
|
timestamp: currentDate,
|
|
@@ -164,6 +170,9 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
164
170
|
? { revisedPrompt: item.revised_prompt }
|
|
165
171
|
: {}),
|
|
166
172
|
})),
|
|
173
|
+
...(response.usage?.cost_in_usd_ticks != null
|
|
174
|
+
? { costInUsdTicks: response.usage.cost_in_usd_ticks }
|
|
175
|
+
: {}),
|
|
167
176
|
},
|
|
168
177
|
},
|
|
169
178
|
};
|
|
@@ -187,8 +196,14 @@ export class XaiImageModel implements ImageModelV3 {
|
|
|
187
196
|
const xaiImageResponseSchema = z.object({
|
|
188
197
|
data: z.array(
|
|
189
198
|
z.object({
|
|
190
|
-
url: z.string(),
|
|
199
|
+
url: z.string().nullish(),
|
|
200
|
+
b64_json: z.string().nullish(),
|
|
191
201
|
revised_prompt: z.string().nullish(),
|
|
192
202
|
}),
|
|
193
203
|
),
|
|
204
|
+
usage: z
|
|
205
|
+
.object({
|
|
206
|
+
cost_in_usd_ticks: z.number().nullish(),
|
|
207
|
+
})
|
|
208
|
+
.nullish(),
|
|
194
209
|
});
|
package/src/xai-image-options.ts
CHANGED
|
@@ -5,6 +5,8 @@ export const xaiImageModelOptions = z.object({
|
|
|
5
5
|
output_format: z.string().optional(),
|
|
6
6
|
sync_mode: z.boolean().optional(),
|
|
7
7
|
resolution: z.enum(['1k', '2k']).optional(),
|
|
8
|
+
quality: z.enum(['low', 'medium', 'high']).optional(),
|
|
9
|
+
user: z.string().optional(),
|
|
8
10
|
});
|
|
9
11
|
|
|
10
12
|
export type XaiImageModelOptions = z.infer<typeof xaiImageModelOptions>;
|