Nodes/comfyui-timesaver/TS Prompt Builder
ComfyUI Node

TS Prompt Builder

Wildcard prompts that don't put a swimsuit on a winter street

By AlexYez·Created 2 years ago·Updated about 23 hours ago· 12
TS Prompt Builder
    • prompt
    seed0
    config_json

    Random-prompt wildcard systems have a reputation problem: pick a random line from twenty lists and you get a winter street in a swimsuit, a close-up paired with a full-body pose, and two mutually exclusive scenes in one sentence. TS Prompt Builder is the version that actually holds the sentence together - it assembles prompts from reusable text blocks, but it knows what each block is rather than just picking blindly.

    How it works

    The blocks aren't raw .txt files, they're "wildcard packs" - folders in nodes/prompts/ holding wildcards plus a semantic map that says what each one is: its role, where it belongs in the phrase, what it excludes, what it goes well with. The node assembles by that map instead of by luck. The README spells out the recipe: profile first, then the people-in-frame policy, mutual exclusions, incompatible pairs, optional companions, an affinity pass, one line per surviving wildcard, and finally the phrase in role order - identity first, then clothing, then the act, then place and camera.

    The genuinely interesting bit is scene coherence. Place lives in the text of the lines, not in file links, so pure semantics couldn't stop a prompt from putting a pool, a rainstorm and a kitchen in one sentence - measured at 22% of assemblies. The node now picks the place first and reads every other line against it, dropping ones that argue about where or when. Same measurement after: 3%, and what remains are metaphors rather than mistakes.

    Any number of packs combine: turn several on and roles interleave into one sentence, wildcards are namespaced per pack (two face.txt never collide), and where two packs both offer a face or a pose, exactly one survives - weighted by each pack's mix.priority, so a five-pack mix is a blend rather than the loudest pack talking over the rest.

    The inputs you set

    • seed - 0 gives a fresh prompt every run; anything above 0 is reproducible. This is the dial for batch variation.
    • config_json - block config (order + enabled flags), managed by the node's own UI rather than typed by hand. You toggle and reorder blocks on the node; the JSON is its working memory.

    The one output is prompt - the assembled text, one random line from each enabled block, comma-joined, ready to feed a CLIPTextEncode or a prompt route. The node also shows the wildcards grouped by role, dims ones that will collapse to a single pick, lets you pin one so it survives a collision, and previews the assembled prompt live with the exact same code the run will use. Drop a pack folder in by hand and press Reload - no ComfyUI restart.

    Install

    No extra dependencies - it's part of comfyui-timesaver. To add your own packs, drop a folder into nodes/prompts/ inside the pack directory.

    cd ComfyUI/custom_nodes
    git clone https://github.com/AlexYez/comfyui-timesaver
    cd comfyui-timesaver
    python -m pip install -r requirements.txt
    

    Common issues

    • "My new wildcard never shows up." The wildcards are namespaced by pack, and the pack needs its semantic map for the node to place lines. A .txt with no map entry gets picked but can't be positioned - check the map.
    • "Same prompt every run." seed is above 0. That's deterministic mode; drop it to 0 for variety.
    • "A pack's lines dominate." That's mix.priority doing its thing - lower a pack's priority if it's shouting.

    Where this earns its keep is batch work: every wildcard is a category, every line a flavor, and the semantic map keeps combinations coherent - which is exactly where raw wildcard systems fall over.

    CategoryTS/Text

    Inputs (2)

    NameTypeDefaultDescription
    seedINT00–184467440737095500000 = auto-random each run, >0 = deterministic per seed
    config_jsonSTRINGBlock config (order and enabled flags) managed by the node UI. Selects which prompt files contribute lines.

    Outputs (1)

    NameTypeDescription
    promptSTRINGAssembled prompt: one random line from each enabled block, comma-joined.