mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-04 08:28:36 +00:00
fix(image): send Gemini Flash hints via generationConfig.imageConfig
The live v1beta API rejects the legacy responseFormat.image block (enum-based aspectRatio/imageSize fields) for gemini-3.1-flash-lite-image with INVALID_ARGUMENT, even for documented plain-string values. Gemini Flash image models accept plain-string hints under generationConfig.imageConfig instead (e.g. aspectRatio 16:9, imageSize 1K), which the API accepts. Switch the flash path to imageConfig and update the provider tests accordingly. Other providers (aihubmix, ollama, imagen) are untouched.
This commit is contained in:
parent
8fde956c64
commit
08fe9f7b3a
@ -808,7 +808,12 @@ class GeminiImageGenerationClient(ImageGenerationProvider):
|
||||
generation_config: dict[str, Any] = {"responseModalities": ["TEXT", "IMAGE"]}
|
||||
image_config = _gemini_flash_image_config(model, aspect_ratio, image_size)
|
||||
if image_config:
|
||||
generation_config["responseFormat"] = {"image": image_config}
|
||||
# Gemini Flash image models accept plain-string values under
|
||||
# ``generationConfig.imageConfig``. The legacy
|
||||
# ``responseFormat.image`` block is rejected with INVALID_ARGUMENT
|
||||
# by gemini-3.1-flash-lite-image (enum-based fields), so it is not
|
||||
# used here.
|
||||
generation_config["imageConfig"] = image_config
|
||||
|
||||
body: dict[str, Any] = {
|
||||
"contents": [{"role": "user", "parts": parts}],
|
||||
@ -864,11 +869,13 @@ def _gemini_flash_image_config(
|
||||
aspect_ratio: str | None,
|
||||
image_size: str | None,
|
||||
) -> dict[str, str]:
|
||||
"""Build the ``responseFormat.image`` config for Gemini Flash image models.
|
||||
"""Build the ``generationConfig.imageConfig`` config for Gemini Flash image models.
|
||||
|
||||
Capabilities are model-specific: Gemini 3.1 Flash variants support four
|
||||
additional extreme ratios, while configurable image sizes are limited to
|
||||
the documented Gemini 3 image model families.
|
||||
Values are the documented plain strings (e.g. ``16:9``, ``1K``) that the
|
||||
live v1beta API accepts under ``imageConfig``. Capabilities are
|
||||
model-specific: Gemini 3.1 Flash variants support four additional extreme
|
||||
ratios, while configurable image sizes are limited to the documented
|
||||
Gemini 3 image model families.
|
||||
"""
|
||||
config: dict[str, str] = {}
|
||||
if aspect_ratio and aspect_ratio in _gemini_flash_supported_aspect_ratios(model):
|
||||
|
||||
@ -464,7 +464,7 @@ async def test_gemini_flash_forwards_aspect_ratio_and_image_size() -> None:
|
||||
image_size="2K",
|
||||
)
|
||||
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["responseFormat"]["image"]
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["imageConfig"]
|
||||
assert image_config == {"aspectRatio": "16:9", "imageSize": "2K"}
|
||||
|
||||
|
||||
@ -480,7 +480,7 @@ async def test_gemini_flash_2_5_drops_image_size() -> None:
|
||||
image_size="1K",
|
||||
)
|
||||
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["responseFormat"]["image"]
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["imageConfig"]
|
||||
assert image_config == {"aspectRatio": "4:3"}
|
||||
|
||||
|
||||
@ -496,7 +496,7 @@ async def test_gemini_flash_2_0_drops_image_size() -> None:
|
||||
image_size="1K",
|
||||
)
|
||||
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["responseFormat"]["image"]
|
||||
image_config = fake.calls[0]["json"]["generationConfig"]["imageConfig"]
|
||||
assert image_config == {"aspectRatio": "16:9"}
|
||||
|
||||
|
||||
@ -524,8 +524,8 @@ async def test_gemini_flash_scopes_extreme_aspect_ratios_by_model(
|
||||
aspect_ratio=aspect_ratio,
|
||||
)
|
||||
|
||||
response_format = fake.calls[0]["json"]["generationConfig"].get("responseFormat")
|
||||
assert response_format == ({"image": expected} if expected else None)
|
||||
image_config = fake.calls[0]["json"]["generationConfig"].get("imageConfig")
|
||||
assert image_config == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -553,8 +553,8 @@ async def test_gemini_flash_scopes_image_size_by_model(
|
||||
image_size=image_size,
|
||||
)
|
||||
|
||||
response_format = fake.calls[0]["json"]["generationConfig"].get("responseFormat")
|
||||
assert response_format == ({"image": expected} if expected else None)
|
||||
image_config = fake.calls[0]["json"]["generationConfig"].get("imageConfig")
|
||||
assert image_config == expected
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@ -571,7 +571,7 @@ async def test_gemini_flash_ignores_unsupported_hints() -> None:
|
||||
image_size="1024x1024",
|
||||
)
|
||||
|
||||
assert "responseFormat" not in fake.calls[0]["json"]["generationConfig"]
|
||||
assert "imageConfig" not in fake.calls[0]["json"]["generationConfig"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user