DHan-H3 Storyboard Enhancer
An Ollama VLM That Writes Your H3 Timeline
The idea
H3 timelines want structure: a global prompt, then beats that start at 0.000s and end exactly at your duration, contiguous, no overlaps. Writing that by hand for a 20-second clip is tedious and easy to get subtly wrong.
The Storyboard Enhancer does it for you. You type a plain-language idea - "two friends argue in a diner, then the camera pulls outside into the rain" - pick how many parts and how long, and a local Ollama model returns a global prompt plus that many timed beats with matching prompts. It's an LLM in the graph, the same pattern the ecosystem settled on for captioning and prompt work: an 8B-ish model on your own card, uncensored, no per-call cost.
How it works
The node is not a graph node in the usual sense. It's a standalone authoring tool with no outputs - it's marked as an output node and talks to your UI instead. Behind it, it's an HTTP client for Ollama.
It health-checks /api/tags with retries, then POSTs to /api/chat with a system prompt and a JSON-format request, think off, temperature 0.4, a seeded options block and num_predict capped at 8192. Two timeouts do different jobs: a 15-second connect timeout, and a 30-minute inference timeout, because a local VLM on a modest card can genuinely take minutes. If JSON mode comes back empty - a known quirk of small models - it retries without format, and if that fails it falls back to /api/generate. Every request sends keep_alive=0, and there's an explicit unload call afterwards, so the VLM is evicted from VRAM before H3 loads. That detail is the difference between "Ollama node" and "Ollama node that works in a video workflow," since you're sharing one card between a chat model and a 33B video model.
The result arrives as timed cards in the node's own panel. There's Run Storyboard (which queues just this node) and Apply Storyboard to Director, which writes the global prompt and the timed segments into a selected Director's timeline. Apply is FL2VA-only for now.
The inputs
idea- the plain description. Required; empty raises.parts- 1 to 10, the exact number of beats you want back.duration_seconds- the total the beats must tile.ollama_model- populated from whatever your Ollama server has installed. If it says<refresh models>, click Refresh Models after fixing the URL.timing_mode-Equalsplits the runtime evenly;AI Pacing(the default) lets the model allocate time per beat, but demands the sequence start at 0.000s and end exactly on your duration.detail_level-Easy,MediumorAdvanced. Advanced asks for choreography, expression, lens and motion, plus brief sound cues.ollama_url(defaults tohttp://127.0.0.1:11434),seed,max_image_size, andpart_images_json- that last one is the node's internal image-mapping field, managed by its card UI, not something you edit.max_image_sizematters if you use the reference panel: attach images to specific parts (drag, paste or pick; they're uploaded into your input folder), and they're sent to a multimodal model with an explicit "Image 1 → Part 3" mapping so the VLM doesn't just smear them together.
Install
Ollama is a separate service, per the README:
# one-time, outside ComfyUI
ollama serve
ollama pull qwen2.5vl:7b # or any model you have; multimodal if you attach images
# the node itself comes with the pack
cd ComfyUI/custom_nodes
git clone https://github.com/DHan315/Comfyui-DHan-Minimax-H3-Director
# restart ComfyUI
The pack ships no weights and has no requirements.txt, but its Python modules import av and torchaudio when loading - if one is missing, all seven nodes vanish at once.
Problems you'll actually hit
Plain Queue does not run this node. It's forced into NEVER mode so a normal workflow run doesn't fire Ollama unexpectedly; use ComfyUI's Execute-to-selected-output button, or the node's own Run Storyboard button. Empty model dropdown means the node couldn't reach Ollama at node-construction time - set ollama_url, click Refresh Models. And if ComfyUI runs inside Docker, 127.0.0.1:11434 is the container, not your host; point it at the host address instead.
The error text here is unusually good, so read it: "cannot connect to Ollama" means the server is down or wedged, and it says so explicitly to stop you blaming a 30-minute generation timeout. If the model returns prose instead of JSON, or a beat list that doesn't tile your duration, that's the model, not the node - drop to fewer parts, or switch timing_mode to Equal and let the split be boring.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| idea | STRING | Simple description of what should happen. | |
| parts | INT | 31–10 | Exact number of storyboard action parts. |
| duration_seconds | FLOAT | 5.01–120 | Total target duration used to pace the progression. |
| ollama_model | COMBO | <refresh models> | Installed Ollama model. Use Refresh Models after changing ollama_url. |
| timing_mode | COMBO | AI Pacing | Equal splits runtime evenly. AI Pacing lets the model allocate time according to each story beat. |
| detail_level | COMBO | Medium | Controls prompt detail while respecting each part duration. |
| ollama_urlopt | STRING | http://127.0.0.1:11434 | — |
| seedopt | INT | 00–2147483647 | Fixed until you change it. With identical inputs ComfyUI can reuse the cached result instead of loading Ollama again. |
| max_image_sizeopt | INT | 768256–1536 | — |
| part_images_jsonopt | STRING | [] | Internal Storyboard UI image mapping. Managed by the custom card UI. |
Outputs (0)
No outputs