Nodes/ArtyClaw Comfy Nodes/Prompt Rule Composer
ComfyUI Node

Prompt Rule Composer

A Mini Rule Engine for Auto-Composing Prompts From Captions

By artyclaw·Created 5 months ago·Updated 5 months ago· 0
Prompt Rule Composer
    • prompt
    • matched_rules
    • matched_rules_full
    caption
    rules_file
    rules_text# Example rules girl(!dress) -> casual girl /red|blue/ -> colorful
    case_insensitivetrue
    word_boundaryfalse
    dedupe_appendstrue
    max_appends0
    joiner
    output_only_newfalse
    consume_termstrue
    consume_all_occurrencesfalse

    Here's the automation pattern that keeps coming up: you have a caption - from a dataset, an image tagger, or an upstream model - and you want to turn it into a prompt by applying a set of human-readable rules. Prompt Rule Composer is a tiny rule engine for exactly that. Write rules like girl(!dress) -> casual girl or /red|blue/ -> colorful, feed it a caption, and it appends the rule's output whenever the left side matches. It's the pack's most feature-rich node, and honestly the most interesting one.

    It's from artyclaw/artyclaw-comfy. If you're building any kind of batch caption-to-prompt pipeline - enrichment, style transfer, dataset tagging - this is the node you'll actually reach for.

    How it works

    Rules live either in the rules_text box (multiline) or in an external rules_file, and the syntax is three flavors:

    • Literal terms: girl, full body -> feminine - matches if the caption contains girl and full body.
    • Slash-regex: /red|blue/ -> colorful - matches if the caption matches the regex.
    • Negative-lookahead: girl(!dress,!skirt) -> casual outfit - matches girl only when the excluded terms are absent.

    When a rule's left side matches, the right side is appended to the output. A few behaviors matter: dedupe_appends stops the same phrase being added twice; consume_terms removes matched terms from the working caption (so later rules don't re-fire on them); consume_all_occurrences removes every instance rather than one; word_boundary forces whole-word literal matches; case_insensitive is on by default; and max_appends caps the number of additions. All of these feed the standard flags Python's re module provides, and the rule parser handles comments (#) and blank lines.

    Inputs and outputs

    • caption - the input text (required).
    • rules_file / rules_text - where the rules come from; the file wins if both are set.
    • case_insensitive, word_boundary, dedupe_appends, max_appends, joiner, output_only_new, consume_terms, consume_all_occurrences - the tuning knobs listed above.

    Three outputs: prompt (the composed result), matched_rules (which right-hand phrases fired), and matched_rules_full (the raw matched rule lines) - handy for debugging exactly why a caption got what it got.

    Install

    ComfyUI Manager → search ArtyClaw Comfy Nodes, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/artyclaw/artyclaw-comfy
    

    Restart. Standard library (os, re) only.

    Where people get burned

    Order matters. Rules are applied top-to-bottom, and because consume_terms removes matched text as you go, a rule higher in the file can strip a term that a lower rule wanted. If rules seem to "not fire," check whether an earlier rule consumed the term. Second, the max_appends default is 0, which means unlimited - most people expect 0 to mean "none," but here it's off. Third, output_only_new changes the output from caption+appends to just the appends; flip it by accident and your base caption vanishes. And the rules-file path resolves against the working directory, same as Prompt Block Loader. It's the node with the most to learn, but the rule syntax is genuinely readable - which is the point.

    Categorytext/utils

    Inputs (11)

    NameTypeDefaultDescription
    captionSTRING
    rules_fileoptSTRING
    rules_textoptSTRING# Example rules girl(!dress) -> casual girl /red|blue/ -> colorful
    case_insensitiveoptBOOLEANtrue
    word_boundaryoptBOOLEANfalse
    dedupe_appendsoptBOOLEANtrue
    max_appendsoptINT00–999
    joineroptSTRING
    output_only_newoptBOOLEANfalse
    consume_termsoptBOOLEANtrue
    consume_all_occurrencesoptBOOLEANfalse

    Outputs (3)

    NameTypeDescription
    promptSTRING
    matched_rulesSTRING
    matched_rules_fullSTRING