APNext H3 Prompt Writer
Write a spec-perfect MiniMax-H3 video prompt from one line of idea
- image
- h3_prompt
- integrated_multimodal_description
- overall_soundscape
- non_diegetic_music
- model_used
- first_frame
- last_frame
MiniMax-H3 is the newest open-weights video model, and it is brutally picky about how you write for it. It wants a heavily structured prompt - integrated_multimodal_description, overall_soundscape, non_diegetic_music, shot blocks, <d> dialogue tags, exact reference-alignment lines depending on whether you're doing text-to-video or starting from frames. Hand-writing that is miserable and easy to get subtly wrong, and with a model this new, "subtly wrong" means a full generation that ignores half of what you said. Video models already reward long, detailed prompts (ask anyone who fought LTX's early prompt adherence); H3 turns that up a notch.
The APNext H3 Prompt Writer turns a short idea - or an image - into a complete, spec-compliant H3 prompt, then hands it to whatever LLM you want: cloud Claude, GPT, Gemini, Grok, Groq, or a local server via Ollama/LM Studio/vLLM. You don't need to memorize the guide; the pack ships the official MiniMax writing guide verbatim in data/h3/ and uses it as the system prompt, so the model follows the real spec rather than a paraphrase.
How it works
The official guide becomes the system prompt; your idea plus the settings below become the request. task_type picks the format - T2VA (text only), I2VA (first frame), FL2VA (first + last), L2VA (last frame) - and anything other than T2VA makes the node emit the exact reference-alignment instruction line with the right S.SS timing from duration_seconds. The wildness dial (0–100) maps to creative-latitude bands: 0–15 strictly literal, 16–40 grounded, and above 40 it injects concrete surreal events (not mood words) drawn from a seeded pool - same seed, same weirdness. dialogue_language tells the model to actually write the spoken lines in that language inside <d>[Language] …</d>, which matters for small local models that would otherwise happily write English and label it as something else.
The inputs that matter
idea- the short prompt or image description being expanded. The core input.task_type+duration_seconds- what format you're targeting and how long the video is.wildness- 25 is a sane default; push past 40 for deliberately weird shots.camera_motion/camera_amplitude/camera_speed- the guide's full camera vocabulary. Medium amplitude and normal speed are omitted from the output, as the spec requires.include_dialogue+dialogue_language- off means no(Sx)IDs and no<d>blocks at all;Auto (match the setting)lets the model pick a language that fits the scene.model-auto-detectgrabs the first provider with an API key set (Claude → GPT → Gemini → Grok → Groq), then the Claude Code CLI, then a running local server.claudecode:entries use your Claude Code login instead of a key.
The optional image sends the frame as vision input so the model describes it itself instead of you writing the description. model_override takes an exact provider:model string (e.g. ollama:qwen3:8b) and beats the dropdown - that's how you reach a local model the dropdown hasn't discovered. local_base_url points a single node at a different host or port.
Outputs: h3_prompt (wire this to the video model) plus integrated_multimodal_description, overall_soundscape and non_diegetic_music split out separately, and model_used so you can see what actually answered.
Install
ComfyUI Manager (search "comfyui_dagthomas") or the usual manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/dagthomas/comfyui_dagthomas
cd comfyui_dagthomas
pip install -r requirements.txt
Then restart. For cloud providers set the matching key as an environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, …) and restart ComfyUI so it picks them up. Local servers don't need a key - anything running when the page loads appears at the bottom of the model dropdown.
Common issues
<d>tags confuse you - they're not stray markup. They mark spoken audio, and the spec requires them. Don't strip them before generating unless you want the words treated as narration.- Local model list looks empty - the dropdown only shows what was running when the page loaded. Start the server, refresh, and it appears (no ComfyUI restart). Use a vision-capable model like
ollama:qwen3-vl:8bif you're connecting images. openaierrors - the pack pinsopenai>=2.54.0,<3.0.0because v3 broke its client wiring. Don't force-upgrade it.- Invalid model names - model strings must match what the provider expects exactly, or you get runtime API errors. That's what
model_overrideis for.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| idea | STRING | Your short prompt or image description. This is what gets expanded into a full H3 prompt. | |
| task_type | COMBO | T2VA (text only) | Which H3 task the prompt targets. Anything other than T2VA emits the matching reference-alignment instruction line. |
| duration_seconds | FLOAT | 8.01–60 | Effective video duration. Drives the cut times and the S.SS value in the alignment instruction. The render snaps frames UP to the 17n+5 grid, so prefer grid durations - 8.00s (192f) is the only common integer one; the trained ceiling is 15.083s (362f). |
| shot_plan | COMBO | Auto | 5 options: Auto, Single shot, Two shots, Three shots, Four shots |
| visual_style | COMBO | Auto | Style stated at the start of [Shot 1]. Auto derives it from the idea or the attached image. The list is the guide's styles plus the APNext Cinematic vocabulary (film stock, grading, aesthetics); pick Custom and fill in custom_visual_style to write your own. |
| wildness | INT | 250–100 | 0 = literal and conservative, 100 = fully unhinged. Above 40 the node also injects concrete surreal elements picked from the seed. |
| camera_motion | COMBO | Auto | Primary camera movement, using the guide's vocabulary. |
| camera_amplitude | COMBO | Auto | 4 options: Auto, with small amplitude, medium (omit), with large amplitude |
| camera_speed | COMBO | Auto | 4 options: Auto, at slow speed, normal (omit), at fast speed |
| include_dialogue | BOOLEAN | true | Off means no (Sx) speaker IDs and no <d> blocks at all. |
| dialogue_language | COMBO | English | The language the characters actually speak, and the tag written inside <d>[...]</d>. Auto lets the model pick one that fits the setting. Pick Custom (or just fill in custom_dialogue_language) for anything not listed. |
| include_on_screen_text | BOOLEAN | false | — |
| include_soundscape | BOOLEAN | true | Off writes N/A into overall_soundscape. |
| include_non_diegetic_music | BOOLEAN | true | Off writes N/A into non_diegetic_music. |
| model | COMBO | auto-detect | Which LLM writes the prompt. auto-detect picks the first provider with an API key set, then the Claude Code CLI, then a running local server. claudecode: entries use your Claude Code login instead of an API key; ollama:/lmstudio:/local: entries are whatever your local servers were serving when the page loaded. |
| temperature | FLOAT | 1.000–2 | — |
| seed | INT | -1-1–18446744073709550000 | — |
| imageopt | IMAGE | Reference frame(s), sent to the model as vision input. I2VA: the first frame. L2VA: the last frame. FL2VA: batch both (frame 0 = first, last = last). The first_frame / last_frame outputs hand them back for the H3 video node. | |
| extra_instructionsopt | STRING | Free-form extra direction appended to the request. | |
| custom_dialogue_languageopt | STRING | Any language or dialect not in the dropdown, e.g. 'Norwegian (Bergen dialect)' or 'Latin'. Overrides the dropdown when filled in. | |
| custom_visual_styleopt | STRING | Any visual style not in the dropdown, e.g. 'hand-painted cel animation' or 'Kodak Vision3 500T, anamorphic'. Overrides the dropdown when filled in. | |
| model_overrideopt | STRING | Exact provider:model string, used instead of the dropdown when filled in. Handy for a local model the dropdown has not discovered, e.g. 'ollama:qwen3:8b', 'lmstudio:qwen/qwen3-8b' or 'local:my-model'. | |
| local_base_urlopt | STRING | Where to reach the local server, e.g. 'http://192.168.1.10:11434'. Empty uses the default for the chosen prefix: ollama 11434, lmstudio 1234, local 8000. Ignored by the cloud providers. | |
| context_1opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_2opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_3opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_4opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_5opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_6opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_7opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. | |
| context_8opt | STRING | Steering input from another APNext node (Time, Scene, Poses, Plots, Feelings, Cinematic, Science, Geography, Architecture, Fashion, ...). The node detects which kind it is and tells Claude how to use it. Sockets grow as you connect them. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| h3_prompt | STRING | — |
| integrated_multimodal_description | STRING | — |
| overall_soundscape | STRING | — |
| non_diegetic_music | STRING | — |
| model_used | STRING | — |
| first_frame | IMAGE | — |
| last_frame | IMAGE | — |