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
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 (22)
| 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 | 6.01–60 | Effective video duration. Drives the cut times and the S.SS value in the alignment instruction. |
| 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. |
| 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 so it can describe them itself. | |
| 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. | |
| 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. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| h3_prompt | STRING | — |
| integrated_multimodal_description | STRING | — |
| overall_soundscape | STRING | — |
| non_diegetic_music | STRING | — |
| model_used | STRING | — |