Skip to content

feat(api): route Google AI Studio Imagen through /v1/images/generations#7656

Open
danscMax wants to merge 1 commit into
diegosouzapw:release/v3.8.49from
danscMax:feat/gemini-imagen-predict
Open

feat(api): route Google AI Studio Imagen through /v1/images/generations#7656
danscMax wants to merge 1 commit into
diegosouzapw:release/v3.8.49from
danscMax:feat/gemini-imagen-predict

Conversation

@danscMax

Copy link
Copy Markdown

Problem

gemini/imagen-4.0-generate-001 (and the -ultra / -fast variants) appear in GET /v1/models — they're surfaced live via Google's ListModels — but they are unroutable:

  • On POST /v1/images/generations400 "Invalid image model: gemini/... Use format: provider/model", because gemini was not registered in the image registry at all (the message is misleading — the format was already correct).
  • On POST /v1/chat/completions404 "is not found ... or is not supported for generateContent", because Imagen uses the dedicated :predict endpoint, not generateContent.

So the models are advertised but produce an error on every route.

Fix

Wire a gemini image provider (new google-imagen format) that targets the Imagen :predict API:

  • Endpoint: POST {baseUrl}/{model}:predict where baseUrl = https://generativelanguage.googleapis.com/v1beta/models
  • Auth: x-goog-api-key header (key stays out of the URL/logs), matching the gemini chat provider
  • Request: { instances: [{ prompt }], parameters: { sampleCount, aspectRatio } } (sampleCount clamped to 1–4; aspectRatio via the existing mapImageSize)
  • Response: normalizes predictions[].bytesBase64Encoded → OpenAI { data: [{ b64_json, revised_prompt }] }

Only imagen-* models dispatch here (isImagenModel guard) — gemini flash-image / nano-banana continue to route through /v1/chat/completions (generateContent), unchanged. Errors go through sanitizeErrorMessage.

Test

tests/unit/gemini-imagen-predict.test.ts — 7 cases: registry wiring, parseImageModel("gemini/imagen-4.0-generate-001") resolution, the isImagenModel guard (imagen ✓ / flash-image ✗), the :predict body shape + sampleCount clamp + aspectRatio mapping, and response normalization + empty/absent tolerance.

npm run typecheck:core clean; npm run lint clean (no new no-explicit-any); existing image tests still pass.

Validation limits (please note)

The request-builder and response-parser are pure and unit-tested, but the live Google call is not exercised: Imagen on the Gemini API requires a billing-enabled project — free-tier keys return 403 / quota 0. I don't have a paid Google key to run an end-to-end generation, so a reviewer with billing enabled should confirm one real imagen-4.0-generate-001 call before relying on it. The code path, auth, and shapes follow Google's documented Imagen :predict contract.

gemini/imagen-4.0-* models were advertised in /v1/models (surfaced live via
Google ListModels) but were unroutable on /v1/images/generations: `gemini` was
not in the image registry, so the route rejected them with "Invalid image
model". They also 404 on the chat route because Imagen uses the dedicated
:predict endpoint, not generateContent.

Wire a `gemini` image provider (format "google-imagen") that POSTs to
{baseUrl}/{model}:predict with x-goog-api-key, sends the instances/parameters
body, and normalizes predictions[].bytesBase64Encoded into the OpenAI image
shape. Only imagen-* models dispatch here (isImagenModel guard) — gemini
flash-image / nano-banana keep routing through /v1/chat/completions.

Note: Imagen requires a billing-enabled Google project; free-tier keys get
403 / quota 0. Request-builder and response-parser are pure and unit-tested;
the live Google call needs a paid key to exercise.

Tests: tests/unit/gemini-imagen-predict.test.ts (7 cases: registry wiring,
parseImageModel resolution, isImagenModel guard, predict body shape +
sampleCount clamp + aspectRatio, response normalization + empty tolerance).
@danscMax
danscMax requested a review from diegosouzapw as a code owner July 17, 2026 20:47
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@diegosouzapw

Copy link
Copy Markdown
Owner

Nice fix — confirmed on release/v3.8.49 that gemini/imagen-4.0-* was advertised via /v1/models but genuinely unroutable (400 on /v1/images/generations, 404 on /v1/chat/completions), and the new google-imagen :predict wiring follows the existing image-provider handler pattern exactly (auth header, sanitizeErrorMessage, saveCallLog). Ran the new test file directly — 7/7 pass — and a full-project tsc --noEmit and eslint on the touched files come back clean (the 3 no-explicit-any hits in imageGeneration.ts are pre-existing/allowlisted, ~800 lines away from your change). Only note, which you already flagged yourself: the live :predict call needs a billing-enabled Google key to exercise end-to-end — worth one real-key smoke test before this gets wide traffic, but that's a merge-after-verify item, not a blocker. Thanks for the clear writeup and the honest validation-limits section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants