Generate images through generateContent, not Imagen - #10
Conversation
generateImage() has been broken for a while. It builds an Imagen-shaped request (instances/parameters posted to :predict) and its default model, imagen-4.0-fast-generate-001, has already dropped off Google's published list. The whole Imagen line shuts down on 17 August 2026 and the :predict endpoint goes with it. The Gemini image models that replace it are reached through generateContent, asking for an image modality back. That is the same shape editImage() has always sent and parseImageResponse() has always parsed, so both methods now share one private seam where the image wire format lives. Two behaviour changes worth knowing about: - Neither method invents an aspect ratio or an image size any more. editImage() used to force 1:1 and 2K on every call, which reshaped whatever the caller passed in. Omitting them lets the model keep the source proportions. This is the same mistake the Agent's unconditional temperature of 0.7 was. - numberOfImages above 1 now throws. The Gemini image models have no equivalent of Imagen's sampleCount, so the alternative was handing back one image and pretending four had been asked for. The IMAGEN_* constants stay, all deprecated. Nothing defaults to them now, so model-watch no longer reports a deprecated default. The README documented IMAGEN_3 and IMAGEN_3_FAST, neither of which exists as a constant; copying that example was a fatal error. Both docs now list the models the class actually ships.
|
Releasing this as v0.15.5, not 0.16.0.
The behaviour changes in this PR only affect paths that are about to stop working anyway: Imagen's The three changes to call out in the release notes:
Blocked until papi-ai/papi-core#30 is merged, tagged v0.15.2 and refreshed on Packagist: Static Analysis here resolves |
The problem
generateImage()is broken. It builds an Imagen-shaped request (instances/parametersposted to:predict) and its default model,imagen-4.0-fast-generate-001, has already dropped off Google's published model list. The whole Imagen line shuts down on 17 August 2026, and its separate:predictendpoint goes with it.The fix
The Gemini image models that replace Imagen are reached through
generateContent, opting into an image modality:{ "contents": [{"parts": [{"text": "..."}]}], "generationConfig": { "responseModalities": ["TEXT", "IMAGE"], "imageConfig": {"aspectRatio": "16:9", "imageSize": "2K"} } }That is exactly the shape
editImage()has always sent andparseImageResponse()has always parsed, so both methods now share one private seam,requestImage(), where the image wire format lives.Verified against Google's current
generateContentreference before writing anything, given how the last two model swaps went.responseModalitiesandimageConfig(aspectRatio,imageSizeof1K/2K/4K) are both documented there, and all four image model IDs appear in the published model list.Behaviour changes
Neither method invents an aspect ratio or size any more.
editImage()used to force1:1and2Kon every call, which reshaped whatever the caller passed in: editing a 16:9 photo returned a square. Omitting them lets the model keep the source proportions. This is the same defect as the Agent's unconditionaltemperatureof 0.7, fixed in 0.15.numberOfImagesabove 1 now throws. The Gemini image models have no equivalent of Imagen'ssampleCountand return one image per request. The alternative was handing back a single image while the caller believed they had asked for four. Same posture as Cohere refusing to fake a named tool.Also
IMAGEN_*constants stay, all@deprecated. Nothing defaults to them now, somodel-watchno longer reports a deprecated constant in use as a default.IMAGEN_3andIMAGEN_3_FAST. Neither exists as a constant, so copying that example was a fatal error. It also led withMODEL_3_0_PRO, which was shut down in March. Both docs now list the models the class actually ships.Checks
composer cigreen: lint clean, Psalm level 4 zero errors, 83 tests passing, 76.6% coverage.Depends on papi-ai/papi-core#30 for the
imageSizedocblock, which is a patch and picked up automatically by the existing^0.15constraint.