Skip to content

Let image models take a custom width × height - #53

Merged
davior merged 1 commit into
mainfrom
claude/gracious-sagan-jwbzsr
Oct 29, 2026
Merged

davior merged 1 commit into
mainfrom
claude/gracious-sagan-jwbzsr

Conversation

@davior

@davior davior commented Oct 29, 2026

Copy link
Copy Markdown
Owner

Why

Video Creator asks GAM to generate stills for a video, but it can only pick from each model's fixed option lists. For FLUX those are named presets that stop at 1024 px on the long side (landscape_16_9 is 1024×576), which is about half a 1080p frame. GVC wants pictures sized to its video, at 1.5× the frame so Ken Burns zooms and crops stay sharp. fal's FLUX accepts image_size: {width, height}, but GAM had no way to express that.

What

  • Catalogue. A new option custom_size: either null, or {max_width, max_height, multiple_of, max_pixels}.
    • Strict on write: positive ints, multiple_of ≤ 64, unknown keys refused, image kinds only.
    • Lenient on read: a malformed stored value reads as null.
  • POST /api/generate. Accepts params.width / params.height for a row with custom_size.
    • Each side is rounded down to multiple_of.
    • Over a limit is refused, not shrunk.
    • Asking for both a size and image_size is refused.
    • The size is sent and stored as image_size: {width, height}, so regenerating makes the same size again.
  • Migration f3a7d2c18e54. Turns it on for the seeded fal-ai/flux/schnell and fal-ai/flux/dev rows.
    • Limits: 3072 per side, multiples of 16, 5 MP cap. That reaches 1.5× a 1080p frame (2880×1616) without going far past the ~2 MP FLUX.1 was trained at. Beyond that it starts repeating subjects.
    • Rows an admin already set are left alone. The downgrade only removes the key where it still holds what the migration wrote.
  • Admin editor. A "Custom size" JSON field (image kinds), so editing another field of a FLUX row no longer drops the setting.
  • Docs. docs/m8-ai-generation.md covers the new option, the params and the refusals.

Megapixel billing already reprices from the probed output size (pricing.py), so nothing changed there.

The paired GVC change uses this when it's available and falls back to size tiers / presets against an older GAM.

Limits not checked against fal

fal.ai wasn't reachable from the build session, so the limits are deliberately conservative rather than taken from fal's schema. An admin can widen them per row.

Tests

  • pytest -q: 1425 passed.
  • npm test: 439 passed. npm run build: clean.
  • New tests cover catalogue validation, API refusals and rounding, migration seeding, and the editor round-tripping custom_size.

Generated by Claude Code

FLUX's named sizes stop at 1024 px on the long side, about half a 1080p
frame, so Video Creator had no way to ask for a picture big enough for
its video. A catalogue row can now declare `options.custom_size` (limits
per side, a multiple, an optional pixel cap), and `POST /api/generate`
accepts `params.width`/`height` for such a row, sending them to fal as
`image_size: {width, height}`.

A migration turns it on for the seeded FLUX rows, capped at 5 MP: enough
for 1.5x a 1080p frame without going far past what FLUX.1 was trained at.
The admin editor gains the field, so saving a row keeps it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1geD2v7vJwCcyYXHHkrxP
@davior
davior marked this pull request as ready for review October 29, 2026 00:34
@davior
davior merged commit 2626f01 into main Oct 29, 2026
3 checks passed
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.

2 participants