fix(image): pass aspect ratio and size to Gemini Flash image models

The Gemini Flash image path (`generateContent`) dropped both `aspect_ratio`
and `image_size`: `generate()` never forwarded them and
`_generate_gemini_flash` did not accept them, so every request fell back to
1:1 / input-matched output. The Imagen path was unaffected.

Forward the hints and emit them under
`generationConfig.responseFormat.image` per the current Gemini API. Aspect
ratio is validated against the accepted set; `imageSize` is validated against
{512,1K,2K,4K} and only sent to Gemini 3+ image models, since
`gemini-2.5-flash-image` supports only `aspectRatio`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
stupidloud
2026-07-27 03:07:41 +08:00
committed by Xubin Ren
co-authored by Claude Opus 4.8
parent b695a7e875
commit 4986590bd7
2 changed files with 102 additions and 2 deletions
+57
View File
@@ -422,6 +422,63 @@ async def test_gemini_flash_reference_images(tmp_path: Path) -> None:
assert parts[1] == {"text": "edit this"}
def _gemini_flash_image_response() -> FakeResponse:
return FakeResponse(
{
"candidates": [
{"content": {"parts": [{"inlineData": {"mimeType": "image/png", "data": RAW_B64}}]}}
]
}
)
@pytest.mark.asyncio
async def test_gemini_flash_forwards_aspect_ratio_and_image_size() -> None:
fake = FakeClient(_gemini_flash_image_response())
client = GeminiImageGenerationClient(api_key="AIza-test", client=fake) # type: ignore[arg-type]
await client.generate(
prompt="draw a cat",
model="gemini-3-pro-image",
aspect_ratio="16:9",
image_size="2K",
)
image_config = fake.calls[0]["json"]["generationConfig"]["responseFormat"]["image"]
assert image_config == {"aspectRatio": "16:9", "imageSize": "2K"}
@pytest.mark.asyncio
async def test_gemini_flash_2_5_drops_image_size() -> None:
fake = FakeClient(_gemini_flash_image_response())
client = GeminiImageGenerationClient(api_key="AIza-test", client=fake) # type: ignore[arg-type]
await client.generate(
prompt="draw a cat",
model="gemini-2.5-flash-image",
aspect_ratio="4:3",
image_size="1K",
)
image_config = fake.calls[0]["json"]["generationConfig"]["responseFormat"]["image"]
assert image_config == {"aspectRatio": "4:3"}
@pytest.mark.asyncio
async def test_gemini_flash_ignores_unsupported_hints() -> None:
fake = FakeClient(_gemini_flash_image_response())
client = GeminiImageGenerationClient(api_key="AIza-test", client=fake) # type: ignore[arg-type]
await client.generate(
prompt="draw a cat",
model="gemini-3-pro-image",
aspect_ratio="7:5",
image_size="1024x1024",
)
assert "responseFormat" not in fake.calls[0]["json"]["generationConfig"]
@pytest.mark.asyncio
async def test_gemini_requires_api_key() -> None:
client = GeminiImageGenerationClient(api_key=None)