Repository navigation
fix(ai): send image sizes the way OpenRouter, Vercel Grok and Google expect - #59927
Conversation
There was a problem hiding this comment.
Looks sound. I checked it by running the PR's new sizing tests on the base branch, where 7 fail (OpenRouter, Vercel Grok, Google 512, FLUX 3, Meta, the up-front fail cases), and on this branch, where they pass. The full packages/ai suite passes and tsc --noEmit is clean. I didn't call any live providers; the new recorded tests replay offline.
Public API: the additions are all backwards compatible: an optional sizing option on OpenAIImages.model, and the exports OpenAIImages.pixelSize, XAIImages.sizing, ImageSizing.accept, ImageSizing.atPixels and ImageSizing.resolution. There is a deliberate behaviour change: requests that used to snap silently now fail before sending. This affects fixed-size OpenAI models at aspects they can't do, Meta at 1K/4K, xAI at 0.5K/4K, gpt-image-2 at 4K, and Cloudflare flux-1-schnell with any aspect or resolution. The README documents this.
One small gap, noted inline: the Vercel Grok routing only matches the spacexai/ prefix.
Related: #59536
| // The Gateway passes `size` through to most image models, but Grok ignores it and renders 1024x1024; it only reads | ||
| // sizing from `providerOptions.xai`. | ||
| const imageSizing: OpenAIImageSizing = (request, route) => { | ||
| if (!request.model.id.startsWith("spacexai/")) return OpenAIImages.pixelSize(request, route) |
There was a problem hiding this comment.
In the recorded response, the gateway's originalModelId and canonicalSlug are xai/grok-imagine-image. So a caller who uses the gateway's own xai/... name would still go through pixelSize and send a size that Grok ignores (back to 1024x1024). Could this check match xai/ too?
There was a problem hiding this comment.
My earlier point is addressed: the Vercel Grok check now matches xai/ as well as spacexai/, and the test covers both. I ran the image unit tests and the Vercel recorded tests (all pass) and tsc --noEmit (clean). I didn't call the live gateway.
The new commit doesn't change the public API beyond what I listed in my last review. It only widens the existing Vercel sizing check to xai/ model names.
There was a problem hiding this comment.
The latest commits look sound: gpt-image requests above the model's maximum now scale down to the largest size that keeps the aspect, and sizing errors on OpenRouter and Vercel now name those routes. I checked them by running the full packages/ai suite, including the new 4K and error-name tests (all pass), and tsc --noEmit (clean). The earlier xai/ prefix point is still fixed.
Public API: two optional additions, both backwards compatible: name on OpenAIImages.model and upToMax in ImageSizing.Limits. Sizing errors on OpenRouter and Vercel now start with "OpenRouter Images" or "Vercel AI Gateway Images" instead of "OpenAI Images". Only callers that match that text need to change.
edd5fc1 to
7427ce6
Compare
There was a problem hiding this comment.
Looks sound. I checked it by running the PR's new sizing tests on the base branch, where 5 fail (OpenRouter tier mapping, Google 512, Vercel spacexai/ and xai/ Grok), and on this branch, where they pass. The full packages/ai suite passes and tsc --noEmit is clean. The earlier xai/ prefix point is still fixed. With the trimmed scope there are no new failure paths.
Public API: three additions, all backwards compatible: an optional sizing option on OpenAIImages.model (typed by the newly exported OpenAIImageSizing), and the exports OpenAIImages.pixelSize and XAIImages.resolution. The name, upToMax and ImageSizing helpers from earlier rounds are gone, but they never shipped.
Three image routes sent sizes their provider ignores, rejects or bills at the wrong tier. I checked each one with live calls.
size: "2736x1536". Gemini 16:9 2K came back as 5504x3072, a 4K render billed as 4K, and FLUX 3 returned a 400aspect_ratio: "16:9",resolution: "2K"spacexai/*,xai/*)size, which Grok ignores, so it always returned 1024x1024providerOptions.xai: { aspect_ratio, resolution: "1k" | "2k" }imageSize: "0.5K", which the API rejectsimageSize: "512", other tiers uppercasedOpenRouter takes
512,768,1K,1.5K,2Kand4K. I map0.5Kto512and leave out anything else instead of failing. Other Vercel models still getsize, which works for them.OpenAIImages.model({ ...media, provider, providerOptions, + sizing, # OpenRouter and Vercel pass their own body fields; OpenAI keeps `size` })No new failure paths.
Verification
spacexai/grok-imagine-image16:9 1K comes back 1280x720.packages/ai,bun typecheck,bun run typecheck:tscandbun run testpass (1975 tests).bun run checkfrom the root passes.Added by the opencode bot (AI-generated).
Related: #59536
Public API: adds an optional
sizingoption toOpenAIImages.modeland exportsOpenAIImages.pixelSizeandXAIImages.resolution(backwards compatible)