MiniMax H3 Loop Plan Generator ๐
H3 gives you 15 seconds. The Loop Plan Generator is how you get a minute.
- llm_service_connector
- images
- plan_json
- summary
- board_kind
MiniMax H3 generates 4โ15 seconds per call: one scene per generation, so anything longer is chained clips - and the "pray the motion carries across the cut" part is where projects die. MiniMaxH3LoopPromptGenerator exists for that part. It turns your concept into a plan_json you plug into the Production Plan node of the upstream ComfyUI-MiniMaxH3-Context-Loop pack - though note H3's open-weights licence excludes the US, EU, UK and South Korea; the hosted Hailuo API is a different thing.
What the node actually is
An LLM-in-the-graph node, not a sampler. Wire in any of the pack's Set*LLMServiceConnector nodes and that model writes the plan. No checkpoints, no VRAM, nothing downloaded.
The output is deliberately narrow: shots plus prompt_prefix, with each shot carrying id, prompt, length and seed. Steps, CFG, canvas size and continuation mode stay on the Production Plan's own widgets and never enter this JSON. Durations round onto H3's 17k+5 frame grid at 24fps, and every scene is capped at 14 seconds - a hair under the model's 15s ceiling, with a summary warning if anything was clamped.
The inputs that matter
user_input- one multiline box, and the whole ballgame. A concept paragraph,speaker๏ผlinedialogue, or a mix. Blank gives you the built-in default concept: fine for a smoke test, useless otherwise.scene_count-0is auto: on a dialogue board it packs consecutive turns into the fewest scenes that fit the 14s window, and a speaker change does not force a cut. Set a number and speech spreads over exactly that many scenes, extras becoming silent reaction cuts. Note whatpacingdoes not do: fast/normal/slow is speech tempo, not cut density.total_duration_seconds-0derives the budget from line count and pacing (TTS rate plus per-turn pause); without dialogue it falls back to 15s. Set it and shots stretch, clamped 4โ14s each.seed_mode- leave it onper_scene_increment. One seed for every scene gives consecutive clips near-identical noise and a repeated motion rhythm: the classic "why does my video pulse?" bug.reference_mode+images-t2vais text-only and ignores the image socket.i2vaanchors scene 1 to<Picture 1>;fl2vatreatsbatch[1..]as per-scene end targets;ref2vakeeps the batch live in every scene. Wirebatch[0]into the First-Scene Image Gate and the rest into the Chain Frame Index Switch.
Outputs are plan_json (into plan_json_input), summary (LLM call count, token usage, warnings - also mirrored to the console), and board_kind, your cheapest sanity check: dialogue means the verbatim contract held, narration means no spoken lines were found or extraction fell over.
enhance_user_input: on runs the enhancer's rewrite inside this node first - handy for a rough draft, but any widget change then re-runs it.
Why dialogue boards are the interesting case
If your input looks like a script, the LLM never touches your lines. A span-anchored extraction pass reports each utterance plus its character offsets, and the code checks that the slice of your input matches what came back. Lines land in the plan verbatim; dialogue the per-scene model invents gets stripped. The promise: no dropped words, no split utterances, no translation. Narration boards get no such promise - there the LLM storyboard writes beats, with pacing biasing how aggressively it splits.
Then it synthesises a shared prompt_prefix (style, lighting, palette, cast sheet), writes each scene's prompt with a continuation directive referencing the previous scene's ending, and validates the plan before returning. Validation failure raises rather than handing a half-plan to a 20-minute render.
generation_mode is the cost dial: per_shot is one call per scene, best continuity; single_call writes the whole board at once when you're iterating.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/MieMieeeee/ComfyUI-MieNodes
cd ComfyUI-MieNodes && pip install -r requirements.txt
Or search ComfyUI_MieNodes in ComfyUI Manager (it's on the Comfy Registry under publisher mie). Requirements are ordinary Python packages (requests, opencv-python, soundfile, imagehash, deepdiff), nothing GPU-shaped. At runtime you need a wired connector plus the upstream Context-Loop pack: plan_json alone generates nothing. To avoid retyping keys, copy mie_llm_keys.json.example to mie_llm_keys.json; it's gitignored.
Where people get burned
- Reasoning models eat the token budget. A thinking model spends
max_tokenson its own scratch-work: HTTP 200, empty content, node raises, you blame ComfyUI. The 16384 default is sized for exactly that. - Timeouts on long boards. 300s per call is the default, and a 12-scene
per_shotrun is 12 sequential calls. Raisetimeoutto 600 before deciding it's hung. board_kind: narrationwhen you wrote dialogue means the extraction pass didn't recognise your format. One utterance per line asName๏ผline, no paraphrasing, and don't bury lines inside prose.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| llm_service_connector | LLMServiceConnector | โ | |
| user_input | STRING | Everything you want, in any shape: a concept paragraph, speaker๏ผline dialogue, or mixed. Dialogue is extracted then packed deterministically; narration still goes through the storyboard LLM. Blank = default concept. | |
| enhance_user_input | COMBO | off - ไธๆถฆ่ฒ(้ป่ฎค) | on: run the MiniMax H3 Loop User Input Enhancer's rewrite once inside this node (one extra LLM call) before planning โ paste any rough draft. off (default): consume user_input verbatim. Keep off when you already write the canonical format or when the standalone Enhancer node is wired upstream (it would re-rewrite an already-canonical text). The rewrite (Classification + Notes + full text) is surfaced at the top of the preflight report. NOTE: with on, ANY widget change re-runs the rewrite too (single-node caching). |
| seed | INT | 00โ18446744073709550000 | Seed base for the per-scene seed chain (scene N gets base+N as a string). 0 = derive from the clock each run. |
| scene_countopt | INT | 00โ128 | Number of scenes. 0 = auto. Dialogue boards pack consecutive turns into the fewest scenes that fit the 14s H3 window (a speaker change does NOT force a cut). Pacing does not change this cut count โ it only changes speech tempo and the BRISK/MEASURED prompt directive. Narration boards let the storyboard LLM decide, using pacing as split bias (fast=aggressive, slow=conservative). >0 on a dialogue board: speech is spread evenly across that many scenes; above one-line-per-scene the extras become silent reaction cuts (cut to the listener). A line is never split mid-utterance. >0 on a narration board: the storyboard LLM produces exactly that many scenes. |
| total_duration_secondsopt | INT | 00โ1800 | Whole-board duration budget. The storyboard LLM distributes it across scenes; each scene rounds up onto the 17k+5 frame grid, so the delivered total lands close to this (ยฑ20% tolerated silently). 0 = auto: derived from dialogue line count and the selected pacing preset (TTS rate + per-turn pause). For concepts without speaker:line dialogue the auto budget falls back to 15s. Set >0 to override the auto estimate. The override actually shrinks shots (clamped to 4-14s each); the old '15 default' no longer applies. MiniMax-H3 single-generation window: 4-15 s per upstream MiniMax-AI/MiniMax-H3 README. This node hard-caps every per-shot duration_seconds at 14 s and emits a preflight warning when clamping occurred. |
| pacingopt | COMBO | normal - ๆญฃๅธธ๏ผ่ฏญ้ยทๆจ่๏ผ | SPEECH TEMPO (่ฏญ้) of the whole board โ this is the faster/slower rhythm control, NOT a cut-density control. On a dialogue board with scene_count=0, pacing does NOT change how many scenes you get (auto packing is always fewest cuts inside the 14s window). It does: 1. Prompt tempo: BRISK / natural / MEASURED injected into the prefix and every shot. 2. Auto length (total=0): TTS rate + turn pause (fast CN 4.5 chars/s + 1.0s, normal 3.5 + 1.5s, slow 2.8 + 2.0s). Narration boards also map fast/normal/slow to the storyboard LLM's aggressive/balanced/conservative split bias. An explicit scene_count is the cut-count override; total_duration_seconds stays the duration constraint. |
| generation_modeopt | COMBO | per_shot - ้ๅบ็ๆ(ๆจ่) | 2 options: per_shot - ้ๅบ็ๆ(ๆจ่), single_call - ๅๆฌก่ฐ็จ(ๅฟซ/็) |
| categoryopt | COMBO | none - ไธๆๅฎ | none: no extra cinematography contract โ but once dialogue lines are extracted the board is automatically treated as dialogue (spoken-scene framing, shot/reverse-shot, no on-screen subtitles). dialogue: the same contract, always. action: motion-blur / camera-shake advice. The dialogue verbatim contract runs whenever lines are extracted, on any category. |
| output_languageopt | COMBO | en | Narrative language for generated scene prose. English default is recommended for H3 stability; spoken lines still follow dialogue-tag policy. |
| seed_modeopt | COMBO | per_scene_increment - ๆฏๅบseed้ๅข(ๆจ่) | per_scene_increment (recommended): seed_base+index per scene โ deterministic but DISTINCT per scene. This mirrors the upstream ComfyUI-MiniMaxH3-Context-Loop plugin's own default, which derives per-scene seeds from one base (sha256(base:index:shot_id)) when the plan omits seeds and relies on that determinism for checkpoint recovery; identical seeds on every clip make consecutive clips sample near-identical noise (repeated motion rhythm). same_across_scenes: every scene shares one seed โ use it only when you deliberately want the identical-noise look. |
| temperatureopt | FLOAT | 0.400โ2 | Advanced tuning: LLM creativity/randomness. Most workflows should keep the default. |
| max_tokensopt | INT | 1638464โ32768 | Advanced tuning: upper token budget for each LLM call. |
| timeoutopt | COMBO | 300 | Advanced tuning: per-call timeout (seconds). |
| reference_modeopt | COMBO | t2va - ๆ็่ง้ข้พ(้ป่ฎค) | t2va: text-only chain (default). i2va: scene 1 anchored to one <Picture 1>. fl2va: scene 1 + alternating end targets <Picture (N % 2) + 1>. ref2va: N pictures active for every scene (six-section prompt contract). |
| imagesopt | IMAGE | One IMAGE batch, all modes. Wiring (mirror the upstream H3 workflow): batch[0] (Picture 1) is the OPENING frame -> MiniMax H3 First-Scene Image Gate 'image' (i2va/fl2va). For fl2va, batch[1..] (Picture 2..N) are per-scene end targets -> Chain Frame Index Switch frame_1..frame_{N-1} (scene j ends on frame_j, wraps after the last slot). For ref2va, the whole batch -> Reference to Video images (all active every scene). i2va keeps only batch[0] and drops the rest with a warning; t2va ignores images (warning). Scene-transition intent (e.g. 'ไปๅพไธๅฐๅพไบๅๅๅฐๅพไธ' / 'AโBโA') goes in user_input. 1-9 frames. REQUIRED for i2va / fl2va / ref2va. | |
| caption_modeopt | COMBO | cache_memory_disk - ็ผๅญ:ๅ ๅญ+็ฃ็(ๆจ่) | Caption cache strategy for images. cache_memory_disk (recommended): persistent cache. cache_memory_only: RAM-only cache. no_cache: always bypass cache. force_recaption_once: force fresh captions now. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| plan_json | STRING | โ |
| summary | STRING | โ |
| board_kind | STRING | โ |