Extensions/ComfyUI-MyOriginalWaifu
ComfyUI Extension

ComfyUI-MyOriginalWaifu

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…

By Deathspike·Created 8 months ago·Updated 2 months ago· 5
Deathspike/ComfyUI-MyOriginalWaifu
Nodes
On cloudLocal install
Stars5
Updated2 months ago
Readme

ComfyUI-MyOriginalWaifu

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.

🤨 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 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.

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 ensure 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, tmp

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."

tmp

Adds temporary tags to the positive and negative prompt.

- tmp: thighhighs

"Always add thighhighs to the positive and negative prompt as a temporary tag."


[!IMPORTANT] Removed and temporary 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 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 add to the end of the prompt.

6. Group Rules

Groups 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 rules together, and help you avoid repeating the same conditions and anchors.

7. Switch Rules

Switches 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 child rule match, 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.

8. Swap Rules

Swap rules are a convenience rule type to replace this with that:

- match: thighhighs
  type: swap
  add: black thighhighs

"If the positive prompt contains thighhighs, swap it with black thighhighs."

These are the key points:

  • The match property requires a matching positive tag (like a condition).
  • The match property anchors on the first matched tag.
  • The match property removes the first matched tag.
  • It then acts like a tag rule to allow add and add_negative.

Swap rules are ideal when you want to treat a (temporary) tag like a placeholder and expand it.

😭 Help, my waifu is broken!

That happens to the best of us! Luckily, My Original Waifu always tells you what it did, and 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 (anyof instead of any_of) or spelling the type wrong (grop instead of group).
  • Using properties that do not exist (children on a tag rule) or forgetting to set type for a group or switch.
  • 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
    $ children[2] {tag}
      ~ tmp: thighhighs

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 ~temporary 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
    - name: thighhighs
      tmp: thighhighs

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
    $ children[2] {tag} (thighhighs)
      ~ tmp: thighhighs

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 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
              tmp: panties
            - name: thighhighs
              tmp: 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
          tmp: bra
        - name: bottom
          none_of: portrait
          type: group
          children:
            - name: panties
              none_of: bottomless
              tmp: panties
            - name: thighhighs
              tmp: thighhighs
    # ----------
    # Underwear Swaps
    # ----------
    - name: swap-bra
      match: bra
      type: swap
      add: black bra
    - name: swap-panties
      match: panties
      type: swap
      add: red panties
    - name: swap-thighhighs
      match: thighhighs
      type: swap
      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.yaml10_celica.yaml20_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!