- Python 91%
- JavaScript 8.6%
- CSS 0.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| build | ||
| docs | ||
| scripts | ||
| web | ||
| .gitignore | ||
| __init__.py | ||
| block_filter.py | ||
| block_weights.py | ||
| CHANGELOG.md | ||
| config.yaml | ||
| lora_scanner.py | ||
| nodes.py | ||
| nodes_block_inspect.py | ||
| nodes_blocks.py | ||
| nodes_blocks_merge.py | ||
| nodes_blocks_scriptable.py | ||
| nodes_script_text.py | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| server_routes.py | ||
ComfyUI_WolfBypass
Bypass LoRA loader with block chopping and per-block strength for Flux/Chroma and similar models.
Security
Scriptable nodes execute arbitrary Python. Only run scripts and workflows from trusted sources. See Scriptable Block Merge for details.
Table of Contents
- Installation
- Node map
- Quick reference
- Block filter nodes
- Block-strength nodes
- Scriptable block merge
- Img/Txt separate weights
- Block strength inspection
- Block filter syntax
- Per-block strength
- Documentation
- Changelog
- Requirements
Installation
Place this folder in your ComfyUI custom_nodes directory (or clone/link). Restart ComfyUI.
All node names end with (🐺) in the UI.
Node map
Nodes are grouped by family: filter (text pattern), block-strength (widget or script), img/txt split (Flux-style), and inspection.
flowchart TB
subgraph filter [Block Filter]
A1[Load LoRA Bypass Block Filter]
A2[Load LoRA Bypass Block Filter Model Only]
end
subgraph bypass_blocks [Block Strength Bypass]
B1[Load LoRA Bypass Per-Block Strength]
B2[Load LoRA Bypass Per-Block Strength Model Only]
end
subgraph merge_blocks [Block Strength Merge]
M1[Load LoRA Merge Per-Block Strength]
M2[Load LoRA Merge Per-Block Strength Model Only]
end
subgraph scriptable [Scriptable]
S1[Load LoRA Merge Per-Block Scriptable]
S2[Load LoRA Img/Txt Separate Scriptable]
end
subgraph imgtxt [Img/Txt Separate]
I1[Load LoRA Bypass Img/Txt Separate]
I2[Load LoRA Merge Img/Txt Separate]
end
subgraph inspect [Inspection]
D1[Block Strength Inspector]
D2[Block Strength Plot]
end
MODEL[MODEL] --> A1
MODEL --> B1
MODEL --> M1
MODEL --> S1
MODEL --> I1
A1 --> MODEL
B1 --> block_strengths_debug
M1 --> block_strengths_debug
S1 --> block_strengths_debug
I1 --> block_strengths_debug
block_strengths_debug --> D1
block_strengths_debug --> D2
Quick reference
| Class | Display name | File | Inputs | Outputs |
|---|---|---|---|---|
LoraLoaderBypassWolf |
Load LoRA (Bypass, Block Filter) (🐺) | nodes.py | model, clip, lora_name, strength_model, strength_clip; optional: block_filter, block_filter_mode, compile_forward | MODEL, CLIP |
LoraLoaderBypassWolfModelOnly |
Load LoRA (Bypass, Block Filter, Model Only) (🐺) | nodes.py | model, lora_name, strength_model; optional: block_filter, block_filter_mode, compile_forward | MODEL |
LoraLoaderBypassWolfBlocks |
Load LoRA (Bypass, Per-Block Strength) (🐺) | nodes_blocks.py | model, clip, lora_name, strength_model, strength_clip, block_strengths; optional: compile_forward | MODEL, CLIP, block_strengths_debug |
LoraLoaderBypassWolfBlocksModelOnly |
Load LoRA (Bypass, Per-Block Strength, Model Only) (🐺) | nodes_blocks.py | model, lora_name, strength_model, block_strengths; optional: compile_forward | MODEL, block_strengths_debug |
LoraLoaderBypassWolfBlocksDoubleSplit |
Load LoRA (Bypass, Img/Txt Separate Weights) (🐺) | nodes_blocks.py | same as Bypass Per-Block | MODEL, CLIP, block_strengths_debug |
LoraLoaderBypassWolfBlocksModelOnlyDoubleSplit |
Load LoRA (Bypass, Img/Txt Separate, Model Only) (🐺) | nodes_blocks.py | same as above, model-only | MODEL, block_strengths_debug |
LoraLoaderWolfBlocks |
Load LoRA (Merge, Per-Block Strength) (🐺) | nodes_blocks_merge.py | model, clip, lora_name, strength_model, strength_clip, block_strengths | MODEL, CLIP, block_strengths_debug |
LoraLoaderWolfBlocksModelOnly |
Load LoRA (Merge, Per-Block Strength, Model Only) (🐺) | nodes_blocks_merge.py | model, lora_name, strength_model, block_strengths | MODEL, block_strengths_debug |
LoraLoaderWolfBlocksDoubleSplit |
Load LoRA (Merge, Img/Txt Separate Weights) (🐺) | nodes_blocks_merge.py | same as Merge Per-Block | MODEL, CLIP, block_strengths_debug |
LoraLoaderWolfBlocksModelOnlyDoubleSplit |
Load LoRA (Merge, Img/Txt Separate, Model Only) (🐺) | nodes_blocks_merge.py | same, model-only | MODEL, block_strengths_debug |
LoraLoaderWolfBlocksScriptable |
Load LoRA (Merge, Per-Block, Scriptable) (🐺) | nodes_blocks_scriptable.py | model, lora_name, strength_model; optional: block_strengths, script | MODEL, block_strengths_debug |
LoraLoaderWolfBlocksScriptableDoubleSplit |
Load LoRA (Img/Txt Separate, Scriptable) (🐺) | nodes_blocks_scriptable.py | same + script for img/txt blocks | MODEL, block_strengths_debug |
BlockStrengthInspector |
Block Strength Inspector (🐺) | nodes_block_inspect.py | block_strengths_debug (required) | block_strengths_txt (STRING) |
BlockStrengthPlot |
Block Strength Plot (🐺) | nodes_block_inspect.py | block_strengths_debug (required); optional: width, height | image (IMAGE) |
Block filter nodes
-
Load LoRA (Bypass, Block Filter) (🐺)
Applies LoRA in bypass mode with optional block filter: a single text pattern (e.g.double_blocks.0,double_blocks.1ordouble_blocks.*) and include/exclude mode. -
Load LoRA (Bypass, Block Filter, Model Only) (🐺)
Same as above, model-only (no CLIP).
flowchart LR
MODEL[MODEL] --> Bypass[Bypass + block_filter]
CLIP[CLIP] --> Bypass
Bypass --> MODEL
Bypass --> CLIP
See Block filter syntax below for block_filter and block_filter_mode.
Block-strength nodes (Bypass / Merge)
-
Load LoRA (Bypass, Per-Block Strength) (🐺) and Model Only
Bypass LoRA with per-block strength. The node scans the LoRA and shows a grid (D0, D1, …, S0, S1, …). Drag cells to set strength; stored as JSON. -
Load LoRA (Merge, Per-Block Strength) (🐺) and Model Only
Same widget and block order, but applies LoRA via standard merge (weights modified as in core Load LoRA). Per-block strengths scale the merge; CLIP uses a single strength.
When you switch LoRA, the block list updates automatically. Order: double_blocks then single_blocks (see Block strength format and API).
Scriptable block merge (model only)
-
Load LoRA (Merge, Per-Block, Scriptable) (🐺)
Model-only. You provide a Python script that receivesblocks,block_strengths,strength_model,lora_name, and must setoutput_strengths. Only the script’s output is applied; block_strengths input only seeds the script (and is used as fallback if the script fails). -
Security: This node runs user Python. Do not load untrusted workflows or scripts.
Full contract, injected variables, and examples: Scriptable Block Merge. Strength profiles and copy-paste recipes: Custom Merge Recipes.
Img/Txt separate weights (Flux-family)
For Flux-style models, each double block has an image branch (img_attn, img_mlp) and text branch (txt_attn, txt_mlp). The “Img/Txt Separate” nodes expose two strengths per double block: one for the image branch, one for the text branch. The widget shows D0i, D0t, D1i, D1t, … then S0, S1, … (i = img, t = txt).
-
Load LoRA (Bypass, Img/Txt Separate Weights) (🐺) and Model Only
Bypass with separate img/txt strengths per double block. -
Load LoRA (Merge, Img/Txt Separate Weights) (🐺) and Model Only
Standard merge with separate img/txt strengths. -
Load LoRA (Img/Txt Separate, Scriptable) (🐺)
Script receives blocks likedouble_blocks.0.img,double_blocks.0.txt, … and setsoutput_strengths. Can also setoutput_merge_functionto change how the scaled delta is applied (see SCRIPTABLE_BLOCK_MERGE.md).
Use these when you want different LoRA strength on image vs text branches (e.g. stronger on img, weaker on txt).
Block strength inspection (debug / viz)
-
Block Strength Inspector (🐺)
Prints block strength values (index, block name, value). Requires block_strengths_debug from any Load LoRA block node. Output: STRING. -
Block Strength Plot (🐺)
Plots block strengths as a bar chart (dark theme, PIL). Requires block_strengths_debug; optional width / height. Output: IMAGE.
flowchart LR
LoadNode[Load LoRA block node] --> debug[block_strengths_debug]
debug --> Inspector[Block Strength Inspector]
debug --> Plot[Block Strength Plot]
Inspector --> STRING[STRING]
Plot --> IMAGE[IMAGE]
Connect block_strengths_debug from any Bypass/Merge/Scriptable block node to Inspector or Plot.
Block filter (original nodes)
- block_filter: Comma-separated names or patterns, e.g.
double_blocks.0,single_blocks.0-5,double_blocks.*. - block_filter_mode: include = only these blocks get the LoRA; exclude = all blocks except these.
Per-block strength (Blocks nodes)
- block_strengths: JSON array of numbers, one per block (e.g.
[1, 0.5, 1, ...]). Filled by the widget or wired from another node. - Widget: D / S with indices; on Img/Txt nodes: D0i, D0t, … Drag a cell up/down (0–2).
Configuration
Edit config.yaml in this folder (or set env vars) to change behavior:
- disable_scriptable_nodes (default:
false): Iftrue, scriptable block merge nodes (those that run user Python) are not registered. Use in locked-down environments to disable remote code execution. - Env override:
COMFYUI_WOLFBYPASS_DISABLE_SCRIPTABLE_NODES=1forces scriptable nodes off.
flowchart LR
subgraph sources [Config sources]
YAML[config.yaml]
ENV[COMFYUI_WOLFBYPASS_DISABLE_SCRIPTABLE_NODES]
end
subgraph init [__init__.py]
load[_load_config]
reg[Register nodes]
end
YAML --> load
ENV --> load
load --> reg
reg -->|disable_scriptable_nodes: true| no_script[Scriptable nodes not registered]
reg -->|false| yes_script[Scriptable nodes registered]
Build and debug
- Minified scripts: By default the UI loads minified JS. To regenerate:
npm installthennpm run minify(writesweb/scripts/*.min.js_). - Debug (unminified): In the browser console set
localStorage.setItem("ComfyUI_WolfBypass_debug_scripts", "1")then reload the page to load unminified scripts. - CodeMirror bundle: After editing
build/codemirror_entry.mjs, runnpm run build:codemirrorfrom this extension; it writesweb/scripts/codemirror_bundle.js_. Script sources for the loader live inweb/scripts/*.js_; runnpm run minifyafter editing them. - Editor resize grip: Disabled by default (autoresize mode). Opt in only when needed:
localStorage.setItem("ComfyUI_WolfBypass_enable_editor_resize_grip", "1")then reload.
Script and bundle load flow:
sequenceDiagram
participant ComfyUI
participant register as register_wolfbypass.js
participant scripts as /extensions/.../scripts/
participant Editor as python_script_editor
participant Block as block_strength_editor
ComfyUI->>register: load (only .js in web/)
register->>scripts: GET codemirror_bundle.js
scripts-->>register: codemirror_bundle.js_
register->>scripts: GET python_script_editor[.min].js
scripts-->>register: script
register->>scripts: GET block_strength_editor[.min].js
scripts-->>register: script
Note over register: window.WolfCodeMirror set before Editor runs
register->>Editor: execute
register->>Block: execute
Documentation
- CHANGELOG — version history and session summaries.
- Block strength format and API — block order, JSON format, scan API.
- Scriptable Block Merge — merge mode, contract, injected variables, examples.
- Custom Merge Recipes — strength profiles: sandwich, ramp, Gaussian, img/txt, inverse, curves, copy-paste.
- Python script editor (CodeMirror) — build and bundle.
- Image ops / shaders (WolfSigmas) — advanced PyTorch shader design (caustics, torch light, filter operators).
Changelog
See CHANGELOG.md for version history and session summaries (e.g. CodeMirror, minify, config, script loading, editor resize).
Requirements
- ComfyUI with bypass LoRA support (core or patched).
safetensorsfor LoRA scanning (block list from file keys only).- Block Strength Plot: uses PIL; no matplotlib required (placeholder if dependencies missing).
License
Same as your ComfyUI / project.