ComfyUI Extension: ComfyUI-MyOriginalWaifu

Authored by Deathspike

Created

Updated

0 stars

My Original Waifu is a tag-based prompt-transformation engine for ComfyUI designed for creators who want their original characters to feel consistent, expressive, and faithfully rendered across every scene. Instead of manually adjusting tags each time you generate an image, you define the essence of your waifu, her look, her outfits, the way she appears in different contexts, and the engine transforms your prompt to match those intentions. It stays out of the way and simply follows your rules with clarity and consistency. Your Waifu. Your Rules. Your Perfect Prompt.

Custom Nodes (0)

    README

    ๐ŸŒธ My Original Waifu

    My Original Waifu is a tag-based prompt-transformation engine for ComfyUI designed for creators who want their original characters to feel consistent, expressive, and faithfully rendered across every scene. Instead of manually adjusting tags each time you generate an image, you define the essence of your waifu, her look, her outfits, the way she appears in different contexts, and the engine transforms your prompt to match those intentions. It stays out of the way and simply follows your rules with clarity and consistency. Your Waifu. Your Rules. Your Perfect Prompt.

    ๐Ÿคจ What the hell does that-

    <p align="center"> <img src="docs/images/banner.png" /> </p>

    ๐Ÿ’ก Ohh! But why?

    Because prompting for your waifu is:

    • Repetitive: the same eyes, hair, and details every single time.
    • Contextual: what she wears or how she appears depends on the scene.
    • Conditional: some tags only make sense from certain angles or in certain shots.
    • Cumbersome: remembering every rule, exception, and detail is exhausting.
    • Verbose: prompts grow into huge walls of text just to express simple intentions.

    My Original Waifu can help by automating your prompt:

    • It can keep appearances stable by enforcing the traits you define.
    • It can add details at the right time based on angle, context, and conditions you describe.
    • It can help avoid impossible combinations by removing details that don't make sense.
    • It can let your prompt stay short, even when the logic behind it is huge.

    All of this happens through simple, declarative YAML rules that you control.

    ๐Ÿ“œ What? Declarative YAML?

    Yes! Think of YAML as a way to write down information in a format that's easy for humans to read and write, and easy for computers to understand. You can imagine your YAML rule file as your character sheet, or the secret sauce behind your waifu! And declarative just means: you're describing what your waifu is like and when her traits should show. Look at these examples:

    - any_of: celica
      add: black hair, pixie cut
    

    "If the positive prompt contains celica, add black hair and pixie cut."

    - any_of: celica
      none_of: closed eyes
      add: blue eyes
    

    "If the positive prompt contains celica, and does not contain closed eyes, add blue eyes."

    That's the whole idea: you declare the logic once, and the engine automates your prompt forever.

    ๐Ÿ› ๏ธ Okay! How do I install this thing?

    Good question! Installing My Original Waifu is quicker than picking your waifu's hairstyle. You can install in two ways:

    Option 1 - ComfyUI Manager (Recommended)

    1. Open ComfyUI Manager.
    2. Go to Custom Nodes Manager.
    3. Search for MyOriginalWaifu by Deathspike.
    4. Click Install and choose latest.
    5. Restart ComfyUI.

    Option 2 - Manual Installation

    1. Open Command Prompt (Windows) or Terminal (macOS/Linux).
    2. Navigate to your custom_nodes directory: cd /path/to/comfyui/custom_nodes
    3. Clone this repository: git clone https://github.com/Deathspike/ComfyUI-MyOriginalWaifu
    4. Restart ComfyUI.

    ๐Ÿš€ Right! What's next?

    Just swap your CLIP Text Encode (Prompt) nodes with My Original Waifu (CLIP). Here's a basic workflow:

    <p align="center"> <img src="docs/images/workflow-before.png" /> </p>

    And here's the exact same workflow after swapping the CLIP nodes:

    <p align="center"> <img src="docs/images/workflow-after.png" /> </p>

    Run the workflow and open your console. You'll see My Original Waifu attempting to load YAML rule files:

    <p align="center"> <img src="docs/images/workflow-logs.png" /> </p>

    [!TIP] You can download this example. It uses my NanoMix v2.0 model, but you can use any model you like.

    ๐Ÿ’— Teach me, Senpai!

    I'm glad you're so enthusiastic! Let's turn you into a rule-writing master.

    [!WARNING] Until v1.0, syntax and semantics may change. I'll do my best to keep updates backwards-compatible.

    1. YAML Rule File

    All your waifu logic lives in YAML rule files inside the extension's rules directory:

    ComfyUI/
      custom_nodes/
        ComfyUI-MyOriginalWaifu/
          rules/
            ...
    

    [!TIP] If you don't know the path, run the workflow and copy the rules directory path from your console.

    You can create a file per waifu, per outfit, or mix them. It's up to you. Just make sure the file extension is .yaml.

    [!NOTE] You do not have to restart ComfyUI. My Original Waifu automatically reloads YAML rule files.

    I strongly recommend using VSCodium, or any editor with YAML syntax highlighting.

    2. Rule List

    A YAML rule file is just a list of rules, evaluated in order, from top to bottom:

    - add: black hair, pixie cut
    - add: blue eyes
    

    Each rule is independent, but together they build your waifu.

    3. Tag Rules: add, add_negative, remove, remove_negative

    The default type of rule is the tag rule, and these decide what tags are added or removed.

    add

    Adds tags to the positive prompt:

    - add: black hair, pixie cut
    

    "Always add black hair and pixie cut to the positive prompt."

    add_negative

    Adds tags to the negative prompt:

    - add_negative: blue hair
    

    "Always add blue hair to the negative prompt."

    remove

    Removes tags from the positive prompt (if they exist).

    - remove: celica
    

    "Always remove celica from the positive prompt."

    remove_negative

    Removes tags from the negative prompt (if they exist).

    - remove_negative: sketch
    

    "Always remove sketch from the negative prompt."


    [!IMPORTANT] Removed tags remain visible for future rules, but will not be in the output prompt.

    [!TIP] You should remove your waifu's name. The model doesn't know it anyway, and might even misinterpret it.

    4. Conditions: any_of, all_of, none_of

    Conditions can be added to any type of rule, and these decide if the rule is evaluated.

    any_of

    Requires that at least one of the tags is present in the positive prompt:

    - any_of: celica, charlotte
      add: blue eyes
    

    "If the positive prompt contains celica or charlotte, add blue eyes."

    all_of

    Requires that all the tags are present in the positive prompt:

    - all_of: celica, jacket
      add: black leather jacket
    

    "If the positive prompt contains celica and jacket, add black leather jacket."

    none_of

    Requires that none of the tags are present in the positive prompt:

    - none_of: closed eyes, eyes out of frame
      add: blue eyes
    

    "If the positive prompt contains neither closed eyes nor eyes out of frame, add blue eyes."

    Combinations

    All combinations of any_of, all_of and none_of are valid:

    - any_of: celica
      none_of: closed eyes
      add: blue eyes
    

    "If the positive prompt contains celica, and does not contains closed eyes, add blue eyes."


    [!IMPORTANT] Conditions intentionally see only the positive prompt. Writing rules as "if X contains Y, do Z" keeps them simple.

    5. Anchors: anchor, anchor_negative

    Anchors can be added to any type of rule, and decide where tags are added.

    anchor

    Sets the positive anchor to the first matched tag in the positive prompt:

    - anchor: celica, charlotte
      add: blue eyes
    

    "Always add blue eyes to the positive prompt, right after celica or charlotte."

    anchor_negative

    Sets the negative anchor to the first matched tag in the negative prompt:

    - anchor_negative: sketch
      add_negative: poorly drawn
    

    "Always add poorly drawn to the negative prompt, right after sketch."


    [!IMPORTANT] If an anchor is not found, the anchor will not change. Without one, tags are added to the end of the prompt.

    6. Group Rules

    Groups let you bundle multiple rules under the same conditions and anchors. Use type: group and children:

    - any_of: celica
      anchor: celica
      type: group
      children:
        - remove: celica
          add: black hair, pixie cut
        - none_of: closed eyes, eyes out of frame
          add: blue eyes
    

    "If the positive prompt contains celica, evaluate all child rules, and add their tags right after celica."

    These are the key points:

    • The group rule's conditions must match, otherwise child rules are not evaluated.
    • The group rule's anchors set the starting anchor for all child rules.
    • Child rules are evaluated in order, from top to bottom.
    • Child rules can have their own conditions and anchors.
    • Child rules can themselves be group or switch rules.

    Groups are perfect to keep related rules together, and help you avoid repeating the same conditions and anchors.

    7. Switch Rules

    Switches let you choose a child that matches conditions, or use the default child. Use type: switch and children:

    - any_of: celica
      anchor: celica
      type: switch
      children:
        - any_of: jacket
          add: black leather jacket
        - any_of: shirt
          add: black t-shirt
        - default: true
          add: black camisole
    

    "If the positive prompt contains celica, evaluate the first matching child, and add its tags right after celica."

    These are the key points:

    • The switch rule's conditions must match, otherwise child rules are not checked.
    • The switch rule's anchors set the starting anchor for the chosen child rule.
    • Non-default child rules must have at least one condition, and may have an anchor.
    • Non-default child rules are checked in order, from top to bottom, and the first match is chosen.
    • One child rule may be set as default with default: true, and it must not have conditions.
    • Child rules can themselves be group or switch rules.

    Switches are perfect when you want mutually exclusive options, like picking an outfit.

    ๐Ÿ˜ญ Help, my waifu is broken!

    That happens to the best of us! My Original Waifu always tells you what it did, and more importantly, why it did that.

    Errors

    If a YAML rule file contains invalid rules, the engine will refuse to run and shows a validation error like:

    Error at celica.yaml[0].type, 'grop' type is not supported
    

    These are some common causes:

    • Using invalid properties, like anyof instead of any_of, or spelling the type wrong (grop instead of group).
    • Using properties that don't exist, like children on a tag rule, or forgetting type on a group or switch rule.
    • Forgetting to add required properties, like children on a group or switch.

    Fix the problem, save the rule file, and run the workflow again.

    [!NOTE] You do not have to restart ComfyUI. My Original Waifu automatically reloads YAML rule files.

    Logs

    Run a workflow that uses the engine, and you will see a rule tree in your console:

    > :root[0] {group}
      ? any_of(celica) = True
      @ anchor(celica) = celica
      $ children[0] {tag}
        - remove: celica
      > children[1] {group}
        ? none_of(head out of frame) = True
        $ children[0] {tag}
          + add: black hair, pixie cut
        $ children[1] {tag}
          ? none_of(closed eyes, eyes out of frame) = True
          + add: blue eyes
          + add_negative: blue hair
    

    How to read this:

    • Lines starting with > โ†’ group or switch (:root[0] means first child of the rule file).
    • Lines starting with $ โ†’ tag rules (rules that add or remove tags).
    • Lines starting with ? โ†’ condition checks and their results.
    • Lines starting with @ โ†’ anchor resolution and its result.
    • Lines starting with + โ†’ tags added.
    • Lines starting with - โ†’ tags removed.
    • Lines starting with x โ†’ rules that were skipped, with the reason.

    Once you're comfortable reading the log, you'll see exactly how your prompt was rewritten, step by step.

    Readability

    All rule paths are precise, but not exactly human-friendly. That's where the optional name property comes in:

    - name: celica
      any_of: celica
      anchor: celica
      type: group
      children:
        - name: remove-activation
          remove: celica
        - name: head
          none_of: head out of frame
          type: group
          children:
            - name: hair
              add: black hair, pixie cut
            - name: eyes
              none_of: closed eyes, eyes out of frame
              add: blue eyes
              add_negative: blue hair
    

    Now errors become much easier to read, because the rule path will include the name:

    Error at celica.yaml[0](celica).type, 'grop' type is not supported
    

    And the same applies to logs, rule names show up there too:

    > :root[0] {group} (celica)
      ? any_of(celica) = True
      @ anchor(celica) = celica
      $ children[0] {tag} (remove-activation)
        - remove: celica
      > children[1] {group} (head)
        ? none_of(head out of frame) = True
        $ children[0] {tag} (hair)
          + add: black hair, pixie cut
        $ children[1] {tag} (eyes)
          ? none_of(closed eyes, eyes out of frame) = True
          + add: blue eyes
          + add_negative: blue hair
    

    You don't need to name every rule, but naming important rules makes troubleshooting much easier.

    ๐Ÿฅบ Can I get a complete example?

    Wow. The audacity. The puppy eyes. The unstoppable "pleaseee?" energy. Fine! Here's a minimal complete example:

    - name: celica
      any_of: celica
      anchor: celica
      type: group
      children:
        - name: remove-activation
          remove: celica
        # ----------
        # Basic Appearance
        # ----------
        - name: head
          none_of: head out of frame
          type: group
          children:
            - name: hair
              add: black hair, pixie cut
            - name: eyes
              none_of: closed eyes, eyes out of frame
              add: blue eyes
              add_negative: blue hair
        - name: breasts
          add: medium breasts
        # ----------
        # Automatic Outfit
        # ----------
        - name: automatic-outfit
          none_of: nude, bikini, underwear
          type: switch
          children:
            - any_of: no outfit
              remove: no outfit
            - any_of: beach
              add: bikini
            - default: true
              add: outfit.default
        # ----------
        # Outfit: Default
        # ----------
        - name: outfit
          any_of: outfit.default
          anchor: outfit.default
          type: group
          children:
            - name: remove-activation
              remove: outfit.default
            - name: torso
              none_of: topless
              add: black camisole
            - name: bottom
              none_of: portrait
              type: group
              children:
                - name: skirt
                  none_of: bottomless
                  add: red plaid skirt
                - name: panties
                  none_of: bottomless
                  any_of: pantyshot, skirt lift
                  add: red panties
                - name: thighhighs
                  add: black thighhighs
        # ----------
        # Outfit: Bikini
        # ----------
        - name: bikini
          any_of: bikini
          anchor: bikini
          type: group
          children:
            - name: remove-activation
              remove: bikini
            - name: torso
              none_of: topless
              add: black bikini top
            - name: bottom
              none_of: bottomless, portrait
              add: black bikini bottom
        # ----------
        # Outfit: Underwear
        # ----------
        - name: underwear
          any_of: underwear
          anchor: underwear
          type: group
          children:
            - name: remove-activation
              remove: underwear
            - name: torso
              none_of: topless
              add: black bra
            - name: bottom
              none_of: portrait
              type: group
              children:
                - name: panties
                  none_of: bottomless
                  add: red panties
                - name: thighhighs
                  add: black thighhighs
    

    ๐Ÿ”ฅ I'm ready for the hard stuff~

    Perfect! You already know the basics. Here's how the engine really behaves behind the scenes.

    1. Evaluation Order

    Rules always run in a stable and predictable order:

    • Rule files are evaluated in alphabetical order: 00_core.yaml โ†’ 10_celica.yaml โ†’ 20_charlotte.yaml โ†’ ...
    • Rules in files are evaluated top to bottom, exactly as written.
    • Evaluation for groups and switches is depth-first.

    All files share the same positive and negative prompt, so tags added in earlier files will affect later ones.

    [!TIP] You can control priority by naming files with prefixes like 00_, 10_, 20_, etc.

    2. Tag Deduplication

    Tags are considered the same if their names match. If a rule adds an existing tag:

    • The tag is re-enabled (if it was removed before).
    • The tag weight is set to the strongest weight.
    • The original position in the prompt is kept.

    So, multiple rules adding the same tag name converge into a single tag.

    3. Weight Propagation

    When you add tags using an anchor, their weights are influenced by the anchor weight. The final weight of each added tag is the anchor weight multiplied by the tag's own weight. So, if the anchor weight is 1.2 and you add black hair with its default weight of 1.0, the result for black hair is 1.2 ร— 1.0 = 1.2. If you write (black hair:1.1) with the same anchor, the final weight is 1.2 ร— 1.1 = 1.32. This should make intuitive sense and preserves the intention of the prompt and the rule.

    4. Weight Normalization

    The engine uses its own weight parser with simple, consistent rules, but keeps the familiar ComfyUI syntax: parentheses for emphasis and :number for explicit weights. The key difference is that nested groups and explicit weights are parsed without inheriting legacy quirks (see #4610). On top of that, explicit weights work even without parentheses. You can simply write black hair:1.2, pixie cut:1.3, and each is treated as a weighted tag.

    5. Regional Prompts

    Regional prompts let the engine evaluate rules across regions. When My Original Waifu is paired with Tiled Attention Couple, you can use the non-CLIP node and write a prompt like 2girls BREAK celica BREAK charlotte, then connect the output to Tiled Attention Couple. Everything before the first BREAK is treated as the parent region. All other regions see the parent's tags for their conditions and can anchor on them (creating a copy of the tag in the local region), but they can only modify their own tags. This allows multiple waifu's to be used in a single image.

    ๐ŸŒ Community

    If you enjoy My Original Waifu, check out more of my work:

    • ๐Ÿ‘‰ Civitai: https://civitai.com/user/Deathspike
    • ๐Ÿ› ๏ธ GitHub: https://github.com/Deathspike

    Got questions or want to show off something you made with My Original Waifu?

    • ๐Ÿ’ฌ Join our anime Discord. Iโ€™m @Deathspike, and Iโ€™d love to hear from you!