Skip to content

fix(ai): send image sizes the way OpenRouter, Vercel Grok and Google expect - #59927

Merged
rekram1-node merged 1 commit into
devfrom
image-sizing-fixes
Oct 29, 2026
Merged

rekram1-node merged 1 commit into
devfrom
image-sizing-fixes

Conversation

@rekram1-node

@rekram1-node rekram1-node commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Three image routes sent sizes their provider ignores, rejects or bills at the wrong tier. I checked each one with live calls.

Route Before After
OpenRouter pixel size: "2736x1536". Gemini 16:9 2K came back as 5504x3072, a 4K render billed as 4K, and FLUX 3 returned a 400 aspect_ratio: "16:9", resolution: "2K"
Vercel AI Gateway Grok (spacexai/*, xai/*) size, which Grok ignores, so it always returned 1024x1024 providerOptions.xai: { aspect_ratio, resolution: "1k" | "2k" }
Google imageSize: "0.5K", which the API rejects imageSize: "512", other tiers uppercased

OpenRouter takes 512, 768, 1K, 1.5K, 2K and 4K. I map 0.5K to 512 and leave out anything else instead of failing. Other Vercel models still get size, 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

  • Recorded tests replay these requests and check the decoded image size: OpenRouter Gemini 16:9 2K comes back 2752x1536, OpenRouter flux-3-image-klein 16:9 1K comes back 1360x768, Vercel spacexai/grok-imagine-image 16:9 1K comes back 1280x720.
  • Unit tests cover the request body for each mapping.
  • In packages/ai, bun typecheck, bun run typecheck:tsc and bun run test pass (1975 tests). bun run check from the root passes.

Added by the opencode bot (AI-generated).

Related: #59536

Public API: adds an optional sizing option to OpenAIImages.model and exports OpenAIImages.pixelSize and XAIImages.resolution (backwards compatible)

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@rekram1-node rekram1-node changed the title fix(ai): translate image size options correctly per provider fix(ai): send image sizes the way OpenRouter, Vercel Grok and Google expect Oct 28, 2026

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@rekram1-node
rekram1-node merged commit 78c31ea into dev Oct 29, 2026
24 checks passed
@rekram1-node
rekram1-node deleted the image-sizing-fixes branch October 29, 2026 02:21
@amrkmn amrkmn mentioned this pull request Oct 29, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant