feat(api): route Google AI Studio Imagen through /v1/images/generations#7656
feat(api): route Google AI Studio Imagen through /v1/images/generations#7656danscMax wants to merge 1 commit into
Conversation
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).
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
|
Nice fix — confirmed on release/v3.8.49 that |
Problem
gemini/imagen-4.0-generate-001(and the-ultra/-fastvariants) appear inGET /v1/models— they're surfaced live via Google's ListModels — but they are unroutable:POST /v1/images/generations→400 "Invalid image model: gemini/... Use format: provider/model", becausegeminiwas not registered in the image registry at all (the message is misleading — the format was already correct).POST /v1/chat/completions→404 "is not found ... or is not supported for generateContent", because Imagen uses the dedicated:predictendpoint, notgenerateContent.So the models are advertised but produce an error on every route.
Fix
Wire a
geminiimage provider (newgoogle-imagenformat) that targets the Imagen:predictAPI:POST {baseUrl}/{model}:predictwherebaseUrl = https://generativelanguage.googleapis.com/v1beta/modelsx-goog-api-keyheader (key stays out of the URL/logs), matching the gemini chat provider{ instances: [{ prompt }], parameters: { sampleCount, aspectRatio } }(sampleCountclamped to 1–4;aspectRatiovia the existingmapImageSize)predictions[].bytesBase64Encoded→ OpenAI{ data: [{ b64_json, revised_prompt }] }Only
imagen-*models dispatch here (isImagenModelguard) — geminiflash-image/nano-bananacontinue to route through/v1/chat/completions(generateContent), unchanged. Errors go throughsanitizeErrorMessage.Test
tests/unit/gemini-imagen-predict.test.ts— 7 cases: registry wiring,parseImageModel("gemini/imagen-4.0-generate-001")resolution, theisImagenModelguard (imagen ✓ / flash-image ✗), the:predictbody shape +sampleCountclamp +aspectRatiomapping, and response normalization + empty/absent tolerance.npm run typecheck:coreclean;npm run lintclean (no newno-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/ quota0. I don't have a paid Google key to run an end-to-end generation, so a reviewer with billing enabled should confirm one realimagen-4.0-generate-001call before relying on it. The code path, auth, and shapes follow Google's documented Imagen:predictcontract.