Skip to content

Commit 3e34fb8

Browse files
authored
Fix Gemini image generation when text part precedes image data (#658)
1 parent 6533911 commit 3e34fb8

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

src/Gateway/Gemini/GeminiGateway.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ public function generateImage(
173173

174174
$images = (new Collection($data['candidates'][0]['content']['parts'] ?? []))
175175
->filter(fn ($part) => isset($part['inlineData']))
176+
->values()
176177
->map(fn ($part) => new GeneratedImage(
177178
$part['inlineData']['data'],
178179
$part['inlineData']['mimeType'],

tests/Datasets/Providers.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
'openai-dall-e-3' => ['openai', 'OPENAI_API_KEY', 'dall-e-3'],
3636
'openai-gpt-image-2' => ['openai', 'OPENAI_API_KEY', 'gpt-image-2'],
3737
'xai' => ['xai', 'XAI_API_KEY', 'grok-imagine-image'],
38+
'gemini-2.5-flash-image' => ['gemini', 'GEMINI_API_KEY', 'gemini-2.5-flash-image'],
3839
]);
3940

4041
dataset('reranking-providers', [

tests/Feature/Providers/Gemini/ImageGenerationTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,32 @@ function fakeGeminiImageResponse(string $mimeType = 'image/png'): PromiseInterfa
165165
->and($response->images->first()->mime)->toBe('image/png');
166166
});
167167

168+
test('firstImage works when response leads with a text part before the inlineData', function () {
169+
Http::fake([
170+
'generativelanguage.googleapis.com/*' => Http::response([
171+
'candidates' => [[
172+
'content' => [
173+
'parts' => [
174+
['text' => 'Here is your image:'],
175+
[
176+
'inlineData' => [
177+
'mimeType' => 'image/png',
178+
'data' => base64_encode('fake-image'),
179+
],
180+
],
181+
],
182+
],
183+
]],
184+
]),
185+
]);
186+
187+
$response = Image::of('A red apple')->generate(provider: 'gemini', model: 'gemini-3.1-flash-image-preview');
188+
189+
expect($response->firstImage()->mime)->toBe('image/png')
190+
->and($response->firstImage()->image)->toBe(base64_encode('fake-image'))
191+
->and((string) $response)->toBe('fake-image');
192+
});
193+
168194
test('image response is correctly parsed', function () {
169195
Http::fake([
170196
'generativelanguage.googleapis.com/*' => fakeGeminiImageResponse('image/png'),

0 commit comments

Comments
 (0)