๐ Kisekae Hair
The dropdown that adds the negative for you
- char
- char
Hair is the fastest thing to get wrong in a booru prompt, because the tags don't replace each other. Write long hair, short hair and the model gets a coin flip. Write ponytail and forget you already had twintails three lines back, same problem - the prompt has no idea which one you meant.
๐ Kisekae Hair treats hair as five fields instead of five tags: color, length, style, bangs, accessories. Pick a style and the previous one is gone, not appended. Pick short hair and the node adds long hair to the negative while it's at it.
How it works
The character rides a KISEKAE_CHAR wire as a dict with one entry per section. Hair nodes chain fine - last write wins per field - and the chain only becomes text when a Kisekae Prompt node renders it at the end.
Application order per node: incoming character, then the node's preset pick if set (replacing the whole hair section, LoRAs included), then your field overrides. The dropdown sentinels do the work you'd otherwise do by hand: (keep) passes the incoming value through, (clear) removes the field entirely, anything else replaces it.
The "smart" behaviour is a static table in the pack's vocab files, not a model. Each shipped value can carry a negative (added to the negative prompt while that value is selected) and a hides list (fields cleared from the incoming character). Which values get negatives depends on what the author shipped - short hair โ long hair is the example the README calls out. The save side matters too: those companions only ride along with dropdown picks. Typed text and values loaded from a preset are never pruned, so a preset that says white dress and skirt keeps both.
The inputs that matter
length and style are the two you'll actually flip, and color is the identity anchor you should set once and never touch. bangs has the oddly useful options (hair between eyes, hair over one eye, no bangs) that fix a lot of "why does she have a fringe" renders. accessories covers hair ribbon, hairclip, kanzashi, hairband.
Behind Show advanced inputs, each field has an _text box that beats the dropdown and an _append toggle that adds instead of replacing - that's your escape hatch for two-tone hair or a specific hime cut you can't be bothered to add to the vocab. The multiline extra field takes anything the five dropdowns don't model.
Output is a single char. Typically: Kisekae Load Preset โ this node โ Outfit โ Prompt.
One genuinely nice detail: preset edits invalidate the node's cache. A section node's IS_CHANGED is tied to a fingerprint of the preset files it reads, so editing presets/characters/aoi.json and re-queueing with otherwise identical settings still re-renders the new text. No more "I changed the file and nothing happened".
Install
ComfyUI Manager โ search kisekae (Registry name comfyui-kisekae), or:
cd ComfyUI/custom_nodes
git clone https://github.com/Kagejitsu/comfyui-kisekae
Restart ComfyUI. No Python dependencies - the pack's pyproject.toml declares none, so this is a pure drop-in. Nodes sit under the kisekae category, prefixed ๐.
Common issues
The negative tag I expected isn't there. Two likely causes: you typed the value into color_text instead of picking it from the dropdown (typed text never triggers companion negatives), or you extended the vocab and didn't give your new value a negative. Fix the second one on Tansu's Dropdowns page - it shows each value's negative and what it clears - then press R.
Hair came out as both long and short. Something upstream set the other tag and this node's field is on (keep). Check with Kisekae Debug JSON in sources view, which shows which node supplied each value.
The preset dropdown doesn't list the character I want. A section node only lists presets that define that section. For a whole character, use Kisekae Load Preset; to layer a whole preset's fields on top of an existing character, Load Preset with mode: merge.
Presets live where? ComfyUI/user/default/kisekae/presets/, subfolders included; examples/โฆ is read-only and never touched by updates. Press R after adding files so the dropdowns pick them up.
Inputs (20)
| Name | Type | Default | Description |
|---|---|---|---|
| preset | COMBO | (none) | Replace the whole hair section with this preset's hair |
| color | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| color_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| color_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| length | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| length_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| length_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| style | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| style_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| style_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| bangs | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| bangs_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| bangs_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| accessories | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| accessories_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| accessories_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| extra | COMBO | (keep) | (keep) passes the incoming value through; (clear) empties it |
| extra_text | STRING | Typed text wins over the dropdown. (tag:1.2) weights work. | |
| extra_append | BOOLEAN | false | append: add to the incoming value; replace: overwrite it |
| charopt | KISEKAE_CHAR | Character from the previous node; empty starts a new one |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| char | KISEKAE_CHAR | โ |