Nodes/ComfyUI_FunCode/Prompt Groups FunCode
ComfyUI Node

Prompt Groups FunCode

Build prompts from named, switchable building blocks

By kaiery·Created 8 months ago·Updated about a month ago· 0
Prompt Groups FunCode
    • prompt
    groups_json{"version": 1, "groups": [{"id": "group_1", "name": "Group 1", "input_slot": 1, "text": "", "enabled": true}]}
    group_1_text
    group_2_text
    group_3_text
    group_4_text
    group_5_text
    group_6_text
    group_7_text
    group_8_text
    group_9_text
    group_10_text
    group_11_text
    group_12_text
    group_13_text
    group_14_text
    group_15_text
    group_16_text
    group_17_text
    group_18_text
    group_19_text
    group_20_text
    group_21_text
    group_22_text
    group_23_text
    group_24_text
    group_25_text
    group_26_text
    group_27_text
    group_28_text
    group_29_text
    group_30_text
    group_31_text
    group_32_text
    group_33_text
    group_34_text
    group_35_text
    group_36_text
    group_37_text
    group_38_text
    group_39_text
    group_40_text
    group_41_text
    group_42_text
    group_43_text
    group_44_text
    group_45_text
    group_46_text
    group_47_text
    group_48_text
    group_49_text
    group_50_text

    If you've ever stared at a 400-word prompt and wished you could turn it on and off by section, Prompt Groups FunCode is aimed at you. It's a structured prompt composer: you define named groups - "character", "clothing", "background", "quality tags", whatever - and each group has its own text box, its own enable switch, and optionally its own external input. The node joins the enabled groups into one prompt string.

    The shape of the problem is the standard ComfyUI one: a positive prompt is really several concerns glued together, and gluing them by hand means editing one giant string whenever you swap a character or drop a background. This node splits the concern into blocks, which is the same "fight repetition and illegibility" instinct behind the whole plumbing layer - one authoritative source per block, then combine.

    How it works

    Configuration lives in groups_json, a JSON string where each group looks like:

    {"id": "group_1", "name": "Character", "input_slot": 1, "text": "1girl, silver hair", "enabled": true}
    

    At run time the node walks the enabled groups in order, takes each one's text (or the wired external text for that group, if input_slot maps to one), normalizes it - strips empty lines, and appends a trailing comma if the group doesn't already end in one - then joins groups with blank lines. The trailing-comma normalization is the quiet genius: each block ends cleanly, so the concatenated prompt doesn't merge words together.

    There's also a front end. The node renders its own editor with a textarea per group, add/remove buttons, an input-slot picker, and a preset system that saves/loads named prompt sets to ComfyUI_FunCode/prompt_groups/presets.json (with folder support), so a character block you reuse across workflows is a couple of clicks away.

    Inputs and output

    • groups_json (multiline) - the JSON defining your groups. The default payload is one empty "Group 1"; edit it, or drive it from another node that emits JSON.
    • group_1_text … group_50_text - optional string inputs, one per possible slot. Wire a text node into a group's slot and it overrides that group's baked-in text. This is how you keep a group's structure fixed while swapping its content from elsewhere in the graph.
    • Output: prompt (STRING) - the joined result, ready for a CLIP Text Encode or wherever your prompt text goes.

    Installing

    cd ComfyUI/custom_nodes
    git clone https://github.com/kaiery/ComfyUI_FunCode
    

    Restart ComfyUI and refresh the browser tab - the group editor is frontend JS, so a stale page won't show it. Category is FunCode/Prompt. No model downloads, no pip deps.

    Common issues

    • Prompt reads as one run-on sentence - each group is meant to end with a comma (the node adds one if missing), but if your external inputs end in stray whitespace or mid-sentence text, the join can't fix that for you. Keep blocks comma-terminated.
    • A group's text isn't showing - check enabled. Disabled groups are skipped entirely, which is also the feature: that's your "turn the background off for this batch" switch.
    • Wired input ignored - input_slot maps to which group_N_text socket the group reads. If the slot doesn't match the socket you wired, the group falls back to its own text. Slot 1 → group_1_text, slot 7 → group_7_text, and so on.
    • Presets vanish after reinstall - presets live in the pack's prompt_groups/presets.json on disk, which a fresh clone overwrites. Back it up if you build a library.

    The honest take: if you already have a prompt-assembler you love, this won't convert you. But if your prompts are a wall of text you edit with find-and-replace, turning them into switchable named blocks is the kind of change you feel on every single generation afterward.

    CategoryFunCode/Prompt

    Inputs (51)

    NameTypeDefaultDescription
    groups_jsonSTRING{"version": 1, "groups": [{"id": "group_1", "name": "Group 1", "input_slot": 1, "text": "", "enabled": true}]}
    group_1_textoptSTRING
    group_2_textoptSTRING
    group_3_textoptSTRING
    group_4_textoptSTRING
    group_5_textoptSTRING
    group_6_textoptSTRING
    group_7_textoptSTRING
    group_8_textoptSTRING
    group_9_textoptSTRING
    group_10_textoptSTRING
    group_11_textoptSTRING
    group_12_textoptSTRING
    group_13_textoptSTRING
    group_14_textoptSTRING
    group_15_textoptSTRING
    group_16_textoptSTRING
    group_17_textoptSTRING
    group_18_textoptSTRING
    group_19_textoptSTRING
    group_20_textoptSTRING
    group_21_textoptSTRING
    group_22_textoptSTRING
    group_23_textoptSTRING
    group_24_textoptSTRING
    group_25_textoptSTRING
    group_26_textoptSTRING
    group_27_textoptSTRING
    group_28_textoptSTRING
    group_29_textoptSTRING
    group_30_textoptSTRING
    group_31_textoptSTRING
    group_32_textoptSTRING
    group_33_textoptSTRING
    group_34_textoptSTRING
    group_35_textoptSTRING
    group_36_textoptSTRING
    group_37_textoptSTRING
    group_38_textoptSTRING
    group_39_textoptSTRING
    group_40_textoptSTRING
    group_41_textoptSTRING
    group_42_textoptSTRING
    group_43_textoptSTRING
    group_44_textoptSTRING
    group_45_textoptSTRING
    group_46_textoptSTRING
    group_47_textoptSTRING
    group_48_textoptSTRING
    group_49_textoptSTRING
    group_50_textoptSTRING

    Outputs (1)

    NameTypeDescription
    promptSTRING