Skip to content

Commit ff49e61

Browse files
committed
Fix support for Imagine v1.0 base64 content
1 parent 2289abd commit ff49e61

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

src/xAI.Tests/ImageGeneratorTests.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class ImageGeneratorTests(ITestOutputHelper output)
1111
public async Task GenerateImage_WithPrompt_ReturnsImageContent()
1212
{
1313
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
14-
.AsIImageGenerator("grok-imagine-image-beta");
14+
.AsIImageGenerator("grok-imagine-image");
1515

1616
var request = new ImageGenerationRequest("A cat sitting on a tree branch");
1717
var options = new ImageGenerationOptions
@@ -38,7 +38,7 @@ public async Task GenerateImage_WithPrompt_ReturnsImageContent()
3838
public async Task GenerateImage_WithEditsToPreviousImage()
3939
{
4040
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
41-
.AsIImageGenerator("grok-imagine-image-beta");
41+
.AsIImageGenerator("grok-imagine-image");
4242

4343
var request = new ImageGenerationRequest("A cat sitting on a tree branch");
4444
var options = new ImageGenerationOptions
@@ -55,7 +55,7 @@ public async Task GenerateImage_WithEditsToPreviousImage()
5555
Assert.Single(response.Contents);
5656
var image = Assert.IsType<UriContent>(response.Contents.First());
5757
// media type in options is ignored and you always get the same jpg
58-
Assert.Equal("image/jpg", image.MediaType);
58+
Assert.Equal("image/jpeg", image.MediaType);
5959
output.WriteLine($"Generated image URL: {image.Uri}");
6060

6161
var edit = await imageGenerator.GenerateAsync(new ImageGenerationRequest("Edit provided image by adding a batman mask", [image]), options);
@@ -65,7 +65,7 @@ public async Task GenerateImage_WithEditsToPreviousImage()
6565
Assert.Single(edit.Contents);
6666
image = Assert.IsType<UriContent>(edit.Contents.First());
6767
// media type in options is ignored and you always get the same jpg
68-
Assert.Equal("image/jpg", image.MediaType);
68+
Assert.Equal("image/jpeg", image.MediaType);
6969

7070
output.WriteLine($"Edited image URL: {image.Uri}");
7171
}
@@ -74,7 +74,7 @@ public async Task GenerateImage_WithEditsToPreviousImage()
7474
public async Task GenerateImage_WithBase64Response_ReturnsDataContent()
7575
{
7676
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
77-
.AsIImageGenerator("grok-imagine-image-beta");
77+
.AsIImageGenerator("grok-imagine-image");
7878

7979
var request = new ImageGenerationRequest("A sunset over mountains");
8080
var options = new ImageGenerationOptions
@@ -103,7 +103,7 @@ public async Task GenerateImage_WithBase64Response_ReturnsDataContent()
103103
public async Task GenerateImage_DefaultsToUriContent()
104104
{
105105
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
106-
.AsIImageGenerator("grok-imagine-image-beta");
106+
.AsIImageGenerator("grok-imagine-image");
107107

108108
var request = new ImageGenerationRequest("A sunset over mountains");
109109
var response = await imageGenerator.GenerateAsync(request);
@@ -119,7 +119,7 @@ public async Task GenerateImage_DefaultsToUriContent()
119119
public async Task GenerateMultipleImages_ReturnsCorrectCount()
120120
{
121121
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
122-
.AsIImageGenerator("grok-2-image");
122+
.AsIImageGenerator("grok-imagine-image");
123123

124124
var request = new ImageGenerationRequest("A robot reading a book");
125125
var options = new ImageGenerationOptions
@@ -145,7 +145,7 @@ public async Task GenerateMultipleImages_ReturnsCorrectCount()
145145
public async Task GenerateImage_ResponseContainsRawRepresentation()
146146
{
147147
var imageGenerator = new GrokClient(Configuration["XAI_API_KEY"]!)
148-
.AsIImageGenerator("grok-2-image");
148+
.AsIImageGenerator("grok-imagine-image");
149149

150150
var request = new ImageGenerationRequest("A futuristic cityscape");
151151
var options = new ImageGenerationOptions
@@ -168,7 +168,7 @@ public async Task GenerateImage_ResponseContainsRawRepresentation()
168168
public async Task GenerateImage_WithNullRequest_ThrowsArgumentNullException()
169169
{
170170
var imageGenerator = new GrokClient("test-api-key")
171-
.AsIImageGenerator("grok-2-image");
171+
.AsIImageGenerator("grok-imagine-image");
172172

173173
await Assert.ThrowsAsync<ArgumentNullException>(
174174
async () => await imageGenerator.GenerateAsync(null!, null));
@@ -178,7 +178,7 @@ await Assert.ThrowsAsync<ArgumentNullException>(
178178
public async Task GenerateImage_WithNullPrompt_ThrowsArgumentNullException()
179179
{
180180
var imageGenerator = new GrokClient("test-api-key")
181-
.AsIImageGenerator("grok-2-image");
181+
.AsIImageGenerator("grok-imagine-image");
182182

183183
var request = new ImageGenerationRequest(null!);
184184

@@ -190,12 +190,12 @@ await Assert.ThrowsAsync<ArgumentNullException>(
190190
public void GetService_ReturnsImageGeneratorMetadata()
191191
{
192192
var imageGenerator = new GrokClient("test-api-key")
193-
.AsIImageGenerator("grok-2-image");
193+
.AsIImageGenerator("grok-imagine-image");
194194

195195
var metadata = imageGenerator.GetService<ImageGeneratorMetadata>();
196196

197197
Assert.NotNull(metadata);
198198
Assert.Equal("xai", metadata.ProviderName);
199-
Assert.Equal("grok-2-image", metadata.DefaultModelId);
199+
Assert.Equal("grok-imagine-image", metadata.DefaultModelId);
200200
}
201201
}

src/xAI/GrokImageGenerator.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,19 @@ static ImageGenerationResponse ToImageGenerationResponse(ImageResponse response)
125125
{
126126
case GeneratedImage.ImageOneofCase.Base64:
127127
{
128-
// We assume JPEG since there's no way to get the actual content type.
129-
var imageBytes = Convert.FromBase64String(image.Base64);
130-
contents.Add(new DataContent(imageBytes, contentType));
128+
try
129+
{
130+
// RTW grok-imagine-image uses full data URI, so
131+
// this first try should work.
132+
contents.Add(new DataContent(image.Base64));
133+
}
134+
catch (Exception)
135+
{
136+
// Fallback to attemping to parse as raw base64 string from beta and grok2 model.
137+
// We assume JPEG since there's no way to get the actual content type.
138+
var imageBytes = Convert.FromBase64String(image.Base64);
139+
contents.Add(new DataContent(imageBytes, contentType));
140+
}
131141
break;
132142
}
133143
case GeneratedImage.ImageOneofCase.Url:

0 commit comments

Comments
 (0)