Skip to content

Size follows the model: reconcile dimension options on a model swap - #370

Open
mikkel wants to merge 1 commit into
mainfrom
dim-options-follow-model
Open

Size follows the model: reconcile dimension options on a model swap#370
mikkel wants to merge 1 commit into
mainfrom
dim-options-follow-model

Conversation

@mikkel

@mikkel mikkel commented Jul 27, 2026

Copy link
Copy Markdown
Member

The bug

Swap an image node from nano-banana-2 to qwen-image-3 and the size dropdown keeps 2k — a size qwen-image-3 does not offer.

Both engines kept the old value and injected it as an option of the new model:

before fix, after the swap:  ["2k","auto","1024x1024","512x512","768x1024","576x1024","1024x768","1024x576"]  (selected: 2k)

The next run then posts size=2k to a model that rejects it or silently substitutes its own — a paid request for something the user did not ask for.

Same class of bug across every dimension, because each model names and values them differently:

model dimension real options
nano-banana-2 size 1k 2k 4k
qwen-image-3 size auto 1024x1024 512x512 768x1024
Sora length seconds: 4 8 12
most video models length duration: 5 10
Sora / WAN aspect orientation: landscape portrait

The fix

On a model swap the stored value snaps to a real option of the new model:

  1. same picture — aspect ratio first (a portrait never becomes a landscape), pixel count breaks the tie
  2. else the nearest number (duration 5 → Sora's 4; 720p480p)
  3. else the model's own default

1k1024x1024. 1024x10241k. 16:9landscape.

On hydration nothing changes: opening a saved or shared graph leaves the author's stored value exactly as chosen, because there the model did not change. Same in an exported app — the author's baked-in value survives the first render.

Disclosure, not silence

A changed dimension changes what the run buys, so it is announced, like a trimmed prompt is (#369):

⚠ qwen-image-3 doesn't offer that — switched size 2k → 1024x1024

Localized in all 5 languages. In an exported app the new value lands in the same <select> the user just used and the run-cost chip updates with it.

Verification

scripts/check-dim-reconcile.mjs (wired into pre-commit) pins, offline and with zero API spend:

  • 15 mappings against real catalog shapes, in both engines
  • editor ↔ play parity on every one of them
  • every reconciled value is an option the new model actually lists
  • the wiring: both model-swap sites reconcile, catalog arrival and first render do not
  • the disclosure exists

Negative-tested — the guard fails when the fix is reverted.

Driven end-to-end in real Edge over CDP against the live catalog payload, zero API spend:

✓ nano-banana-2 offers only its 3 tiers — {"opts":["1k","2k","4k"],"value":"2k"}
✓ size options are exactly qwen-image-3's
✓ no stale 2k option survives
✓ size reconciled to 1024x1024
✓ the change is disclosed in a toast — qwen-image-3 doesn’t offer that — switched size 2k → 1024x1024
✓ the graph on disk carries the new size
✓ back on nano-banana-2 the options are the tiers again
✓ 1024x1024 reconciled to 1k

Full pre-commit suite passes.

🤖 Generated with Claude Code

Swap an image node from nano-banana-2 to qwen-image-3 and the size dropdown
kept "2k" — a value qwen-image-3 does not offer. Both engines injected the old
value as an option of the new model, so the next run posted size=2k to a model
that rejects it or silently substitutes its own. Same class of bug for video:
Sora counts length in `seconds` (4/8/12) while most models offer 5/10, and
Sora/WAN name the aspect dimension `orientation` (landscape/portrait).

On a model swap the value now snaps to a REAL option of the new model:
same picture first (aspect ratio, then pixel count), else the nearest number,
else the model's own default. 1k -> 1024x1024, 1024x1024 -> 1k, a portrait
never becomes a landscape, duration 5 -> Sora's 4.

Hydration keeps the old behaviour on purpose: opening a saved or shared graph
leaves the author's stored value exactly as chosen, because there the model did
not change.

A changed dimension changes what the run buys, so it is disclosed, not silent —
a warn toast in the editor ("qwen-image-3 doesn't offer that — switched size
2k -> 1024x1024"), localized in all 5 languages. In an exported app the new
value lands in the same select the user just used, and the run cost updates
with it.

scripts/check-dim-reconcile.mjs pins 15 mappings offline in BOTH engines plus
the wiring (swap reconciles, hydration does not) and the disclosure. Verified
end-to-end in real Edge over CDP against the live catalog shape, zero API spend.

Update: Change the model and the size options follow it — no more sending a size the new model doesn't support.
@cloudflare-workers-and-pages

Copy link
Copy Markdown
Contributor

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
nanoodle 33ec51f Commit Preview URL

Branch Preview URL
Jul 27 2026, 02:07 PM

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.

1 participant