Extensions/Comfyui-EzFlex-Presets
ComfyUI Extension

Comfyui-EzFlex-Presets

EzFlex preset suite for ComfyUI: models combo loader, resolution/latent selector, node switch master & group presets, parameter presets, preview any, prompt helper, media loader/output.

By blackbossokok·Created 20 days ago·Updated about 16 hours ago· 1
blackbossokok/Comfyui-EzFlex-Presets
Nodes11
On cloudLocal install
CategoryEzFlex
Stars1
Updatedabout 16 hours ago
Readme

Comfyui-EzFlex-Presets (V1.2.6 stable)

English | 中文

A flexible combo/preset suite for ComfyUI, built with AI assistance — still being improved.

overview Demo video (Bilibili): watch

EzFlex node list

  • Main Control (MainControl)
  • Models Combo Loader (EzFlex-ModelsCombo)
  • Resolution / Latent Selector (EzFlex-FreeLatent)
  • Node Switch Master (NodeSwitchMaster)
  • Node Switch Group (NodeSwitchGroup)
  • Param Preset Control (ParamPresetControl)
  • Param Preset Output (ParamPresetOutput)
  • Preview Any (EzFlex-PreviewAny)
  • Prompt Helper (EzFlex-PromptHelper)
  • Media Loader (EzFlex-MediaLoader)
  • Media Out (EzFlex-MediaOut)
  • 11 nodes in total

Changelog

  • V1.2.6: New shared theme system: 16 palettes (Light = the original palette / Lilac / Sage / Nord / Minimal / Caramel / Mist Blue / Deep Space / Morandi / Mermaid / Chocolate / Klein Blue / Cloud / Banana / Burgundy / Deep Teal) reach every EzFlex panel live through --ez-* CSS variables. FreeLatent fixes: themed canvas, always-visible grid, even borders, and a preset dropdown that drops down and follows the node. Tag panel fixes: the page bar works again and generated previews are saved once. All EzFlex data moved into user/EzFlex/ (old files migrate automatically) and dead code / debug prints were removed.
  • V1.2.5: The tag panel gained a random-tag generator; the default tag library is now bundled (it was missed in the last release); preview generation gained a cleanup action. ModelsCombo can auto-read the trigger words of a loaded LoRA (shown live and editable in Prompt Helper), and the model browser gained a "Loaded" view. Fixed black socket labels not showing inside subgraphs and leftover labels after fast canvas moves. Overall edit supports collapsing individual cards.
  • V1.2.4: Prompt Helper overhaul: new tag system / card manager, plus security hardening.
  • V1.2.3: Bug fixes, continued security hardening, and node feature enhancements.
  • V1.2.2: Fixed the EzFlex-NodeSwitchGroup preset dropdown; fixed the "cannot validate input" errors in EzFlex-ParamPresetOutput, EzFlex-PreviewAny and others after switching presets in EzFlex-ParamPresetControl; improved where custom size presets sit in EzFlex-FreeLatent; fixed the unclickable controls in the Media Loader preview popup; fixed Media Loader's slow 3D model loading and preview-image generation; fixed Prompt Helper's highlight logic.
  • V1.2.1: Fixed the Node 2.0 click bugs in Prompt Helper (EzFlex-PromptHelper), Media Loader (EzFlex-MediaLoader) and Media Out (EzFlex-MediaOut). Prompt Helper (EzFlex-PromptHelper) and Node Switch Group (NodeSwitchGroup) gained collapsible toolbar rows. Comprehensive security hardening across the plugin.
  • V1.2.0: Security hardening across the plugin; Main Control (MainControl) gained an EN / 中文 language toggle.
  • V1.11: Prompt Helper polish and bug fixes.
  • V1.1: General node polish and performance work; Prompt Helper improvements; compatibility fixes.
  • V1.05: Prompt Helper gained "reference media" and a stronger @media insertion.
  • V1.04: Added Media Loader (EzFlex-MediaLoader) and Media Out (EzFlex-MediaOut); Prompt Helper overhaul (still in development).
  • V1.03: README cleanup; FreeLatent gained a "force override" button (ignore external width/height/batch); fixed the align default (multiples of 8); added the Prompt Helper node.
  • V1.02: ModelsCombo gallery/search improvements.
  • V1.01: ParamPresetControl preset switching + wiring fix.
  • V1.0: First stable release.

Install

Put this folder under ComfyUI/custom_nodes/ and restart ComfyUI.

Dependencies: the plugin only needs mutagen (to read audio/video tags). Everything else (torch / numpy / Pillow / safetensors / av) ships with ComfyUI. Or just run pip install -r requirements.txt. Optional: llama-cpp-python (Prompt Helper's in-process llama-cpp-python mode), gguf / onnx (model metadata cards for those formats).

Usage

Search for "EzFlex" in the ComfyUI node list and pick a node.

Node features

Main Control (MainControl)

  • Control: drives the overall node behavior. The card list (preset dropdown + drag to reorder) covers Models Combo Loader (EzFlex-ModelsCombo), Resolution / Latent Selector (EzFlex-FreeLatent), Node Switch Master (NodeSwitchMaster) and Param Preset Control (ParamPresetControl). All four expose their own "preset" interface; a master preset records their current presets together and pushes them down when switched. Node Switch Group is not listed here — it is managed by Node Switch Master.
  • Presets: freely combine / save / delete master presets.
  • Quick load: load other EzFlex nodes. "Load all" adds Models Combo Loader / Resolution-Latent Selector / Node Switch Master / Node Switch Group / Param Preset Control / Param Preset Output / Prompt Helper / Media Loader / Preview Any; **Media Out (MediaOut) is created by Media Loader (EzFlex-MediaLoader) separately.
  • Language: switch between Chinese and English.
  • Theme: one switch for every EzFlex panel (Light - the original palette / Lilac / Sage / Nord / Minimal / Caramel / Mist Blue / Deep Space / Morandi / Mermaid / Chocolate / Klein Blue / Cloud / Banana / Burgundy / Deep Teal). Lilac and Sage take the Radix Colors steps (the base of shadcn/ui); the rest keep their own official schemes. A base layer gives native inputs and select popups the right text color and color-scheme. Palettes live in the theme module and reach the panels through CSS variables, so a switch repaints all open panels immediately.

Models Combo Loader (EzFlex-ModelsCombo)

  • Combo loading: freely combine UNet / CLIP / VAE / Checkpoint / LoRA loaders.
  • Presets: save / delete your loading combinations.
  • Preview: show the dropdown list with model covers.
  • Gallery: gallery-style browsing to pick models (needs the ComfyUI-Lora-Manager plugin and its Civitai-generated JSON files).
  • Outputs: ports are generated by the number and type of loader cards; the LoRA loader chains after its target model, multiple LoRAs chain in card order, and port names look like custom_name_model/clip/vae.
  • Order: reorder cards freely.

Resolution / Latent Selector (EzFlex-FreeLatent)

  • Canvas: drag freely to generate the matching empty latent; hold Ctrl to disable snapping.
  • Width/height input: type them manually.
  • Align resolution: computes width/height from the Opt / Std algorithm and the step; it currently affects manual input, preset selection, ratio and MP-derived sizes.
  • MP: megapixels.
  • Ratio presets: width : height, built-in and custom.
  • Size presets: built-in and custom size presets, saveable/deletable (based on the current actual size).
  • Custom ratios: save / delete your own ratios.
  • Info panel: live width, height, ratio and MP.
  • Inputs: external width/height, batch size.
  • Outputs: empty latent, width/height, batch size.
  • Force override: when green, external width/height/batch inputs are ignored and the panel values win; controls unlock (available only when at least one input is connected).

Node Switch Master (NodeSwitchMaster)

  • Control: drives Node Switch Group behavior; save / delete your own combinations as presets.

Node Switch Group (NodeSwitchGroup)

  • Control: switch grouped nodes between on / off / bypass (mute).
  • Presets: save / delete switch presets freely.
  • Group matching: by title / by color, including subgraph matching.
  • Order: auto-sort cards by position or name.
  • Note: presets are per node instance — deleting the node removes its presets.

Param Preset Control (ParamPresetControl)

  • Control: the green/red parameter buttons decide whether a parameter shows up in the output list and in group card dropdowns. The group dropdown selects which parameter to output (all or a specific one).
  • Presets: save / delete parameter-group presets freely.
  • Parameters: int, float, bool, string, complex, tuple, list, set, dictionary (eight types).
  • Order: group cards and parameter cards can be dragged freely.
  • Outputs: one port per group card; multi-parameter groups are red, single-parameter groups gray.

Param Preset Output (ParamPresetOutput)

  • Control: enable/disable parameter output; when disabled: int → 0, bool → false, float → 0.0, string etc. → empty string.
  • Type hint: shows the actual type; if it does not match the type configured in ParamPresetControl, it outputs a string and is highlighted red.
  • Value preview: click to open a preview popup.

Preview Any (EzFlex-PreviewAny)

  • Preview types: detects any input type and renders a matching preview card (drag to reorder, cards appear/disappear with the connections).
  • Save settings: toggle to actually save on click, otherwise preview only; choose the destination and save options.
  • Supported types:

| Type | Accepts | Preview | Formats | |---|---|---|---| | IMAGE | tensor [B,H,W,C] | thumbnail + full-screen original | PNG / JPEG / WebP / BMP / TIFF | | MASK | 2D/3D tensor | grayscale PNG | PNG | | AUDIO | {waveform,sample_rate} or (waveform,sr) or a file object | player | WAV / MP3 / FLAC / OGG / M4A / AAC | | VIDEO | VideoFromFile / VideoFromComponents | first-frame cover + player | MP4 / WebM / MOV / GIF / AVI / MKV | | CONDITIONING | dict with conditioning/context | text summary | — | | LIST / TUPLE / SET | list / tuple / set | index-value tree | JSON | | DICT | dict | key-value tree | JSON | | STRING / INT / FLOAT / BOOLEAN | str / int / float / bool | text (truncated + full-text popup) | TXT / MD / JSON / CSV / LOG / HTML | | LATENT | {samples} dict | shape / dtype summary | — | | FILE_3D | File3D object (same as the built-in Load3D) | three.js viewer (offline) | glb / gltf / obj / fbx | | MODEL_3D | File3D object (with path/file) | three.js viewer (offline) | glb / gltf / obj / fbx | | MESH | Types.MESH (vertex/face tensors; Hunyuan3D / Trellis / MoGe …) | vertices/faces exported to a temp OBJ → three.js viewer | ≤500k vertices, ≤1M faces (otherwise summary only) | | SPLAT / VOXEL | Types.SPLAT / Types.VOXEL (tensors) | text summary (point count / SH degree / voxel resolution) | — | | MODEL | ModelPatcher | model metadata card | safetensors / gguf / onnx / ckpt / pt | | CLIP | comfy.sd CLIP | metadata card | safetensors / gguf / onnx | | VAE | comfy.sd VAE | metadata card | safetensors / gguf / onnx | | CONTROL_NET / CLIP_VISION / STYLE_MODEL / UPSCALE_MODEL / LORA_MODEL / GLIGEN / SAMPLER / SIGMAS / GUIDER / NOISE / SEGS | the matching ComfyUI object | text summary | — | | EMPTY | not connected | "(not connected)" | — |

  • Preview method: data preview popup / generation info.

Prompt Helper (EzFlex-PromptHelper)

  • Cards: add/remove, drag to reorder, double-click to rename; each card has a "Default / Optimized" pair of tabs and a "merge" switch (green = merged, gray = not merged).
  • Editor: Word-style toolbar (bold / italic / underline / strikethrough, alignment, font size, text color, highlight, first-line indent, find & replace, color picker, full/half-width conversion) plus a skill button (pick a *.md and insert it line by line at the caret).
  • Reference media: reads media ports of generator nodes on the canvas and numbers them as @图片N / @视频N / @音频N; the "reference media" window lists assets grouped by generator node, with + insert / − remove / right-click "make it a global reference library".
  • Prompt specs: 15 built-in specs under "Settings · Rules" ("Do not compile", "Use API" + 13 vendor specs) plus custom ones (editable, saveable, with Chinese/English variants and a 中 | EN switch); reference markers are compiled into each vendor's syntax (<Picture 1>, @image1, …).
  • Optimize: the Tools dropdown offers "Optimize prompt (API) / (TextGenerate) / (llama)"; use once or enable "runtime auto-optimize"; the three switches are mutually exclusive and failures raise an error.
  • Card management: save cards as presets (user/EzFlex/prompts/<name>.json; EzFlex settings live in user/EzFlex/); save only the selected cards, click to load, delete.
  • Ports: no CLIP input — one dynamic "combo media" port (ANY: image/video/audio/3D) + one text input per card; outputs "merged prompt" + one port per card.
  • Settings: six tabs — General / Rules / API / TextGenerate / llama / Paths; scan dirs, selected models and custom providers are persisted globally.
  • Panel header buttons: Overall edit / Settings / Card management / + New prompt card.
  • Mode: the header's "⧉ Tiled / 🗗 Popup" switches the window form.

Optimize / Default / Card / Overall edit: behavior rules

Two slider layers: the card popup's "Default / Optimized" only affects that card's output port; the one in "Overall edit" affects the "merged prompt" port. The two optimized results live in separate slots and never overwrite each other.

1. Tool-triggered optimize

  • Card popup "Tools → Optimize prompt": the source is always that card's "Default" tab; the result goes into the card's "Optimized" slot and the slider flips to Optimized — the default text is untouched.
  • Overall edit "Tools → Optimize prompt": the source is the cards' default bodies joined in order with the "card merge separator" (gray-merge and empty cards are skipped), in one single call; the result goes into "overall optimized result" and the overall slider flips to Optimized — the card contents stay unchanged.
  • Both follow the same table (has / none → fill / overwrite):

| Slider | Default | Optimized | Behavior | |---|---|---|---| | Default / Optimized | has | none | Optimize from the default prompt → fill the optimized slot, flip the slider | | Default / Optimized | has | has | Optimize from the default prompt → overwrite the optimized slot (manual edits are not kept) | | any | empty | has / none | Show "This card has no prompt content to optimize." |

2. Runtime optimize — any of the three auto-optimize switches on

If auto-optimize fails (API / TextGenerate / llama error) it stops with an error. The optimized slots act as "memory": if they already contain something, no call is made.

Overall layer → "merged prompt" (source = the default bodies of merge-green cards, joined with the card merge separator)

| Overall slider | Default | Optimized | Behavior | |---|---|---|---| | any | has | none | Run one overall optimize → store it as "overall optimized result" → flip the slider → output it | | Optimized | any | has | Output the stored overall result directly (no re-optimize), slider unchanged | | Default | has | has | Output the default merge (the optimized version is kept but unused, and not regenerated), slider unchanged | | Default | empty | has | Output the overall optimized result, flip the slider | | any | empty | empty | Output empty (the user wrote nothing), slider unchanged |

Each card → "card i" port

  • Merge = green: no separate runtime optimize — the port strictly follows that card's slider (Default → default, Optimized → optimized); pointing at an empty slot outputs empty (no fallback). The card list marker follows the slider ("Opt" / "Def").
  • Merge = gray: optimized on demand, only for its own port:

| Slider | Default | Optimized | Card port | |---|---|---|---| | any | has | none | Optimize once from the default → fill the card's optimized slot → port = result, flip the slider | | Default | has | has | port = default (the optimized version is kept but unused), slider unchanged | | Optimized | has | has | port = optimized version (no re-optimize), slider unchanged | | any | empty | has | port = optimized version (no re-optimize); if the slider is on Default it flips to Optimized | | any | empty | empty | port = empty, slider unchanged |

  • Port count = cards + 1 (port 0 is "merged prompt", then "card 1..N", all STRING); ports follow card add/remove/reorder.
  • If card_in_i is connected to external text it overrides that card (the card is grayed out) and takes part in merging and optimizing.

3. All three switches off (no optimize calls at all; the same "strictly follow the slider, empty stays empty" rules apply)

  • Overall edit: slider on Default → output the default merge (each card's default body, filtered by the merge switch); on Optimized → output the overall optimized result. Empty stays empty — no fallback, no padding.
  • Each card (merge green or gray, same rule): Default → that card's default body; Optimized → that card's optimized content; empty stays empty.
  • The card slider does not affect the "merged prompt" — the merged port only takes the cards' default bodies (which is why a card's optimized content only travels through its own port).

4. Where does spec compilation (reference media) happen?

  • What is sent to the API / TextGenerate / llama is the uncompiled original text (your @图片1 / @视频1 / @音频1); the system prompt explicitly asks the model to keep those markers as-is (no translation, no rewriting, no renumbering).
  • The two optimized slots (card "optimized prompt" / "overall optimized result") also store the model's raw output (uncompiled), so another spec can be applied later without losing the mapping.
  • Only the output ports go through spec compilation: the card i port and the default merge / overall optimized content used by "merged prompt"; compilation is idempotent.
  • If the model kept @图片1, the output is automatically rewritten in the selected spec's syntax (e.g. <Picture 1>). If the model translated or rewrote it into natural language ("the first image"), the marker is gone and no compilation can bring it back (a stricter model or system prompt only lowers the chance).

Media Loader (EzFlex-MediaLoader)

  • Presets: save/delete groups and card-group state and names.
  • Parameters: cards per row, card height multiplier (default 1).
  • Groups / card groups / media cards: drag to reorder, double-click to rename, context menu, long-press drag to merge, hover info, click to preview, delete.
  • Browsing: file-explorer style (directory tree, back/forward/up/refresh, manual path input, search, multi-select).
  • Outputs: one port per card, of the dedicated type EZFLEX_MEDIA_CARD (dark red) — it carries the "card object", not a media value, so it only connects to EzFlex-MediaOut (which prevents accidentally wiring it into built-in nodes); use MediaOut for real media values.
  • Loadable types: image / video / audio / 3D model / text / other; the output values match ComfyUI's built-in loaders and can feed standard nodes directly.
  • Supported extensions: image .png .jpg .jpeg .webp .gif .bmp .tif .tiff | video .mp4 .webm .mov .mkv .avi .m4v | audio .mp3 .wav .flac .ogg .aac .m4a .opus .wma | 3D .obj .glb .gltf .fbx .stl .ply .3ds .dae .blend | text/other → STRING (text gives the file content, other gives the path).
  • Top bar "Load output": creates an EzFlex-MediaOut and wires it in one click.

⚠️ Be careful when registering browsable roots — they decide which files others can see while ComfyUI is exposed to a LAN / the internet

The media browser can only browse ComfyUI's own input / output by default. To reach other folders, type a path in the toolbar and click "Save root" to explicitly register that folder as a root.

Precondition (this is what decides whether there is any risk): only people who can reach your ComfyUI port can see these roots.

  • Listening on 127.0.0.1 (localhost, the default) → outside machines cannot connect, so adding roots only affects you; nothing to worry about.
  • Running with --listen 0.0.0.0 (some all-in-one packages do this), a tunnel, or a reverse proxy exposing it to the internet → others on the same network / on the internet can list and download files inside the roots you registered and their subfolders.

Keep the exposure controlled and adding roots is safe:

  • Do not expose ComfyUI to untrusted networks (the most important rule). If you must, only register specific media folders — never a drive, your home directory or a project root. The plugin itself refuses to register a whole drive (C:\, D:\, /), and stale whole-drive entries are ignored and cleaned up automatically.
  • Registering / deleting roots is local-only (loopback + same-origin), so neither other people nor web pages can extend your roots for you; but reading is not local-only — that is exactly what the precondition above bounds.
  • Delete when done: select the root in the dropdown → "Delete root". The built-in input / output cannot be deleted (the button greys out when they are selected).
  • Nested roots are separate entries: if you registered both D:\media and D:\media\videos, the dropdown shows two entries and deleting one keeps the other.
  • You can also ignore this whole mechanism: just keep your files under input / output.

Media Out (EzFlex-MediaOut)

  • Input: a single input of the dedicated type EZFLEX_MEDIA_CARD, connected to one of EzFlex-MediaLoader's card ports.
  • Outputs: neutral ports colored/typed by the real file type — IMAGE / VIDEO / AUDIO / FILE_3D / STRING (same as the built-in loaders, so they feed standard nodes directly).
  • Modes: split / card / card group / group (buttons at the top of the panel); split → one port per file; card / card group / group → merged into a single port by structure.
  • Merging: multiple images → a batched tensor [B,H,W,C] (feeds any IMAGE input; split it again with the built-in ImageFromBatch / RebatchImages); multiple audio clips → joined in time into one track (sample rates must match; mono is upmixed); multiple texts → joined with newlines; mixed types / mismatched sample rates → an error telling you to use "split" (the port degrades to *, and its hover label shows ×N files).
  • Batch settings (shown in card / card group / group mode, aligned with KJNodes Load Images From Folder): target size "first image" / "custom size", fit "crop" / "pad" / "stretch", "max images" (0 = all), "start at" (0-based); mismatched size/channels are aligned by the rule before merging (the console prints which rule was used).
  • Switches: each file can be toggled; in split mode a disabled file keeps its port and outputs None (no rewiring needed when re-enabling); in other modes disabling removes it from the group. At runtime (before the prompt is submitted) an input that is "disabled but still connected" is removed from the submitted prompt — downstream sees "not connected" (optional inputs use their default, required inputs fail validation with a clear error), and neither the canvas wiring nor the saved workflow is touched. When queueing directly through the HTTP API (bypassing the frontend) it is still None.
  • Paging: page navigation.

Directory structure

Comfyui-EzFlex-Presets/
├── __init__.py          # all 11 node classes + preset routes + output-type sync routes
├── pyproject.toml
├── README.md            # English README (default, this file)
├── README_ZH.md         # Chinese README
├── user_data/           # preset library (written at runtime): EzFlex-ModelsCombo.json / EzFlex-FreeLatent.json /
│                        #   EzFlex-NodeSwitchMaster.json / EzFlex-NodeSwitchGroup.json /
│                        #   EzFlex-MainControl.json / EzFlex-ParamPresetControl.json
│                        # These are generated at runtime by the preset routes; any extra files on your machine
│                        #   (e.g. EzFlex-PreviewAny.json) are local runtime data, not shipped files.
├── locales/zh/nodeDefs.json  # official i18n: Chinese node names / descriptions / tooltips
└── web/
    ├── modelscombo_node.js  # ModelsCombo embedded panel (addDOMWidget)
    ├── freelatent_node.js   # FreeLatent embedded canvas resolution picker
    ├── ezflex_service.js    # shared: node registry / group matching / node.mode / preset API / dialogs
    ├── ezflex_i18n.js       # panel i18n: ezT(key) + Chinese dictionary (English is the source)
    ├── ezflex_theme.js      # themes: 16 palettes → shared CSS variables (--ez-*), live for every panel
    ├── node_switch_group.js # NodeSwitchGroup panel
    ├── node_switch_master.js# NodeSwitchMaster panel
    ├── main_control.js      # MainControl panel
    ├── param_preset_control.js # ParamPresetControl panel + dynamic ports
    ├── param_preset_output.js  # ParamPresetOutput panel + dynamic ports
    ├── preview_any.js          # PreviewAny board + draggable cards + dynamic sockets + previews
    ├── prompt_helper.js        # PromptHelper panel (in development)
    ├── media_loader.js         # MediaLoader panel (groups/cards/media/preview/presets + dynamic ports)
    ├── media_out.js            # MediaOut panel (file list + enable switches + type-colored ports)
    ├── ezflex_media_index.js   # media numbering engine (scans generator nodes' media ports → image N / video N / audio N + <Picture N>)
    └── libs/ utils/ curves/    # three.js, loaders and curve resources (offline, for the PreviewAny 3D viewer)

Dependencies

  • Shipped with ComfyUI: torch, numpy, Pillow, safetensors, av
  • Required extra: mutagen>=1.46.0 (reads audio/video tags and container metadata)
  • Optional: llama-cpp-python for Prompt Helper's "in-process (llama-cpp-python)" mode — not listed in requirements.txt (so ComfyUI-Manager does not have to compile it during install, which often fails on Windows); install manually:
pip install llama-cpp-python
  • Optional: only needed to read .gguf / .onnx model metadata (otherwise that file's metadata card is skipped); install manually:
pip install gguf onnx

Or install all optional extras at once via pyproject: pip install -e .[llama,metadata]