Donut Prompt Conditioning
One CLIP Encode, Four Conditionings — the Face Pass and the Zeroed Negative
- clip
- full_text
- face_text
- edit_negative
- positive
- face_positive
- negative_zeroed
- negative_raw
Detailer-style workflows have a split personality. You write a full prompt for the whole image, a shorter prompt aimed at just the face for the close-up second pass, a negative for the base pass, and then for the refined pass you often don't want that same negative stomping on the region you're trying to fix. Donut Prompt Conditioning exists to keep all of those texts in one place and turn them into conditioning in a single node, so the split never drifts into four separate CLIP Text Encode nodes that you forget to keep in sync.
Feed it a clip plus three text inputs - face, scene, and negative - and it does the encoding work for you. The full positive is simply face + separator + scene: the author's mental model is that your prompt is a face description and a scene description glued together, which maps directly onto the two-pass pattern the pack's own detailer nodes use (the "full versus face text" split is even documented in the pack's workflow notes). face_positive is the face text encoded alone, ready for a face-focused sampler. And the negative is delivered twice: negative_raw as the ordinary encoded negative for the main pass, and negative_zeroed as the same text run through ComfyUI's ConditioningZeroOut, which zeros the conditioning vector out - the standard trick for a refinement pass where you don't want the full negative pulling against the fix.
Inputs and outputs, short list
Inputs: clip, then face, scene, negative (all wired-in strings - connect them from a text node rather than typing), plus edit_negative (multiline), separator (glued between face and scene - leave empty for direct concatenation), and text_seed.
Outputs: full_text, face_text, edit_negative strings, and the four conditionings - positive, face_positive, negative_zeroed, negative_raw.
What's actually going on
Under the hood it's calling ComfyUI's own CLIPTextEncode and caching each unique text so nothing is encoded twice, then ConditioningZeroOut for the zeroed negative. The one sneaky detail: edit_negative is run through the pack's wildcard engine before encoding (Donut Text-style expansion, seeded by text_seed), so you can write edit_negative with {blurry|soft|out of focus} style choices or __distractors__ wildcard tokens and get a fresh negative each run while everything else stays stable. If you're not using that, just set text_seed and forget it - it only feeds the edit-negative expansion.
A beginner's trap: separator is literally inserted between face and scene, so if you type a comma there, you get face, scene, and if you leave it empty you get facescene with no space. If your face text ends with a comma (most people's do - "a beautiful woman, ..."), leave the separator empty and don't duplicate punctuation. And remember negative_zeroed is zeroed, not "empty": the empty-conditioning equivalent for a pass with no negative is often exactly what you want, which is why both flavors ship.
This node replaces three or four separate CLIP encodes with one tidy bundle, and because it's an output node the strings come back too - handy when you want to display or log exactly what got encoded. It's part of ComfyUI-DonutNodes; install the pack via ComfyUI Manager ("DonutNodes") or git clone plus pip install -r requirements.txt in ComfyUI/custom_nodes, using the same Python that runs ComfyUI. There's no per-node install and no model download - the conditioning magic is all CLIP-side, which is already in your ComfyUI.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| face | STRING | — | |
| scene | STRING | — | |
| negative | STRING | — | |
| edit_negative | STRING | — | |
| separator | STRING | — | |
| text_seed | INT | 00–9007199254740991 | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| full_text | STRING | — |
| face_text | STRING | — |
| edit_negative | STRING | — |
| positive | CONDITIONING | — |
| face_positive | CONDITIONING | — |
| negative_zeroed | CONDITIONING | — |
| negative_raw | CONDITIONING | — |