Static → Video
Turn a reference image or a brief into an on-brand stop-motion video, then cap it with a
branded end screen. Runs on the ElarisLabs MCP tools (see reference.md for exact calls).
Golden rules
- Ask what the user actually needs FIRST, then start. Never assume aspect ratio, length, or style. Confirm the brief (Step 0) before generating anything. Defaults are only a fallback when the user explicitly says "you decide."
- Never assume aspect ratio. Use what the user gives; if unspecified, ask (
9:16/16:9/1:1/4:5). The chosen video model MUST support the target AR — if the primary model can't do it, switch to a model that does (see the AR→model rule in step 5), never stretch or letterbox. - Budget total length as AI clip + end screen. When the user gives a total (e.g. "15s"), the AI
animation is
total − end_screenand the end screen is ~3s. So 15s → ~12s AI + ~3s end card. Keep this split unless the user overrides either number. - Never skip the approval gate. Generate stills, show them, and wait for the user to pick before spending credits on video.
- Ask for brand assets up front (logo, name, colors) — the deliverable is branded, and the end screen needs them.
- Everything is billed to the brand the API key is bound to. Check
get_creditsbefore a large run and estimate cost before animating. - The look spec is editable. Show it, let the user tweak it, then generate from the final spec.
Workflow
Copy this checklist and track progress:
- [ ] 0. Confirm needs — ASK first: aspect ratio, total length, style, brand assets. Don't assume.
- [ ] 1. Intake — collect reference/brief + brand assets
- [ ] 2. Look Spec — derive an editable spec (with confirmed AR + length budget), get sign-off
- [ ] 2b. Aspect reframe — if source AR ≠ target, nano-banana-2 first
- [ ] 3. Stills — generate on-brand frames (nano-banana-2 / gpt-image-2)
- [ ] 4. Approval gate — user selects keepers
- [ ] 5. Animate — per approved still (AR-capable model; Seedance 2.0 → Kling O3 Pro → Veo 3.1, pinned via `model`)
- [ ] 6. Assemble in HyperFrames — clips + branded end card + BGM (Asian Paints style)
- [ ] 7. Deliver — final video + summary (frames, model used, credits)
0. Confirm needs (do this before anything)
Always ask the user what they actually need before starting. Do not assume. Confirm at minimum:
- Aspect ratio —
9:16,16:9,1:1, or4:5. If they give one, use it. If not, ask. Only fall back to a default if they say "you choose." - Total length — then split it: AI clip = total − ~3s end screen. E.g. "15s" → ~12s AI + ~3s end card. Confirm the split.
- Style / mood, brand assets (logo, name, colors, CTA), and whether they have a reference image.
Echo the confirmed AR + length split back to the user, then proceed. The rest of the workflow inherits these values.
1. Intake
Accept either a reference image URL or a text brief. Then ask for the brand kit if not given:
- Brand logo (transparent PNG or SVG) — required for the end screen. Ask explicitly.
- Brand name + optional tagline / CTA.
- Primary + secondary colors (hex). Fall back to palette pulled from the reference image.
- Aspect ratio — whatever the user specified in Step 0 (no silent default). Rough length — the total the user wants, already split into AI clip + ~3s end card.
If a reference image was given, run score_creative (optional) or just read it to seed the spec.
2. Look Spec (editable)
Break the look down into this structured spec and show it to the user for edits before generating:
subject: # what's in frame (product, character, scene)
has_human: # true | false ← drives the video model routing in step 5
style: # e.g. tactile clay stop-motion, paper-craft, product macro
palette: # 3–5 hex colors (brand + accents)
lighting: # e.g. soft key + warm rim
composition: # framing, camera angle, negative space for text
mood: # 2–3 adjectives
motion_feel: # stop-motion cadence: snappy | dreamy | mechanical
frames: # 3–6 beats, each one sentence (these become the stills)
aspect_ratio: # 9:16 | 16:9 | 1:1 | 4:5 ← from the user (Step 0), never assumed
total_seconds: # total video length the user asked for
ai_seconds: # = total_seconds − end_seconds (the animated clip[s])
end_seconds: # ~3 (the branded end card)
Each entry in frames becomes one still in step 3. Keep 3–6 frames for a tight stop-motion loop.
ai_seconds is the budget for the animated clip(s); end_seconds (~3) is the end card. They must sum to
total_seconds.
2b. Aspect reframe (required when AR differs)
After look-spec sign-off, compare the source image aspect ratio to the user-confirmed
aspect_ratio in the spec (from Step 0 — never a silent default).
- If they match → skip; use the original as the master reference.
- If they differ → call
generate_imagewithmodel: "nano-banana-2", the original asreferenceImages, and a reframe prompt that asks to recompose / outpaint into the target ratio while keeping product, lighting, typography style, and brand look. Use the returned image as the master reference for every later still. Show the reframed canvas once before generating frames.
Do not stretch or letterbox with naive crop alone — Nano Banana 2 should invent plausible surrounding scene so the composition still reads as a designed ad at the target ratio.
See reference.md for the exact MCP call and prompt pattern.
3. Generate stills
For each frame in the spec, call generate_image. Pick the model by need:
| Need | Model (model arg) |
|---|---|
| Aspect reframe when source AR ≠ target AR | nano-banana-2 |
| Default on-brand stills, character/product consistency | nano-banana-2 |
| Text baked into the image, precise multi-reference edits, premium fidelity | gpt-image-2 |
| Fast/cheap draft passes | flux-2-flash |
- Pass the master reference (original or reframed) and the brand logo when it should appear as
referenceImagesto keep frames consistent and on-brand. - Generate 1–2 variants per frame. Keep resolution
1K–2Kfor stills that will be animated.
4. Approval gate — REQUIRED
Present every still. Ask the user to select which ones to animate. Do not proceed to video until they confirm. Only approved stills move to step 5.
5. Animate — pin the model (video guard)
Animate each approved still as a short image-to-video clip (2–5s). Decide the model upfront from
the brief/reference, then pin it with the generate_video model argument (the MCP tool now
accepts model — pass an id from list_models). Follow this fallback chain:
| Priority | Situation | Model (model arg) | Why |
|---|---|---|---|
| 1 — primary | No human / character in frame (product, food, scene, abstract) | Seedance 2.0 → seedance2-std-i2v (or seedance2fast-fast-i2v) | Top choice for object/product/scene motion |
| 2 — fallback | A human or character is in frame (Seedance won't reliably pass people) | Kling O3 Pro → kling-o3-pro-i2v | Best human/character motion |
| 3 — last resort | Neither works for the shot (Seedance + Kling both fail/refuse) | Veo 3.1 → veo31-std-i2v | Final fallback only |
Rules:
- Choose upfront: if the reference/spec has people or characters, go straight to Kling O3 Pro — don't waste a Seedance pass. Otherwise Seedance 2.0.
- The model MUST support the target aspect ratio. Before picking, check the model's
aspectRatiosvialist_models/reference.md. If the priority model can't do the requested AR (e.g. user wants1:1but the chosen i2v variant is 16:9-only), switch to a model that supports that AR rather than changing the user's AR. AR-capability beats the priority order — pick the highest-priority model that both fits the human/no-human situation and supports the AR. - Duration: pass
durationSeconds= the clip's share ofai_seconds. For a single hero beat that's the wholeai_seconds(cap per the model's max; split into multiple clips if longer). The end card coversend_secondsin HyperFrames — never pad the AI clip to fake total length. - Always pass
model. Never rely on the server default (it may pick Veo). After each call, read the result'smodelUsed(orget_generation_history) to confirm the right model ran; regenerate if not. - Never Veo 3.1 as a default — it's only the last-resort fallback.
Motion prompt guidance: describe incremental, snappy motion ("frame-by-frame stop-motion, slight pose shifts, subtle handheld jitter, 12fps feel"), short duration, hold the subject stable. Estimate credits and confirm before large batches.
6. Assemble in HyperFrames (Asian Paints style)
Assembly is done in HyperFrames, not by chaining another video model. Mirror the Asian Paints / product-launch build: bring the Seedance clip in as a track, then compose a branded end card and layer BGM (no voiceover unless asked).
- End card treatment (matches Asian Paints): dark ground, brand color as the single accent, Inter, a
short kinetic-type barrage resolving on the wordmark + CTA pill. Source placeholders from the
brand kit; fall back to the template at
assets/end-screen.htmlfor tokens. - The logo on the end card is MANDATORY. Use the user's brand logo if given. Otherwise crop the
logo/seal from the master reference (isolate the mark, mask its background to transparent). If the
crop is unusable, regenerate a clean transparent logo with
nano-banana-2, passing the cropped mark asreferenceImages. Place it as the hero element above the eyebrow, animated in first. - Set the HyperFrames canvas to the confirmed AR:
16:9→1920×1080,9:16→1080×1920,1:1→1080×1080,4:5→1080×1350. Rootdata-duration=total_seconds; clip track =ai_seconds; end card =end_seconds. - BGM with a hit on the end-card reveal.
- Render via the HyperFrames pipeline / the app's render route. See
reference.mdfor the calls.
7. Deliver
Deliver the final rendered video plus a one-line summary (frames used, model that actually ran,
credits spent). Offer to schedule_post it to a connected social account if the user wants.
Additional resources
- Exact MCP calls, model IDs, fallbacks, and rendering options: reference.md
- Branded outro template: assets/end-screen.html