Nodes/XB_ToolBox/XB-BOX - 🔀 切换任意
ComfyUI Node

XB-BOX - 🔀 切换任意

The switch with no switch that just grabs the first input that isn't empty

By wjluoxiao·Created 7 months ago·Updated a day ago· 406
XB-BOX - 🔀 切换任意
    • *

    What it actually is

    XB_AnySwitch is a fallback switch. Not an A/B switch - no dropdown, no boolean, no index widget. It has one output and however many inputs you connect, and on every run it forwards the first input that isn't empty, top to bottom.

    That distinction matters more than it sounds. An A/B switch is a valve you turn by hand. A fallback switch is a decision the graph makes: three optional branches feed one consumer, whichever branch is live wins, and you never touch a control. Our plumbing notes name rgthree's Any Switch as the canonical example of the second kind, and this node is a deliberate port of exactly that - the class docstring says it behaves identically.

    It sits in XB_ToolBox/Utils, inside a 141-node Chinese-first pack whose real obsessions are VRAM tricks and Wan video relays. Display name is XB-BOX - 🔀 切换任意; the shipped locale renames it XB-BOX - 🔀 Any Switch on an English install, so search either.

    How the fallback works

    The Python side is small and slightly clever. Inputs are declared as a fully permissive optional dict typed * - any name counts as existing - so the node grows ports without its info_schema changing. At run time it filters its kwargs down to those named any_*, sorts them, and returns the first that isn't empty. Empty means None, plus one case borrowed from rgthree: a dict holding model and clip whose values are all None counts as empty too, because that's an unwired context object. All empty, and it returns None.

    The front end handles port choreography. A fresh node arrives with two slots, connecting the last one appends another, and unplugging a middle one collapses the empties so there's always a free end slot. Ports get renumbered any_01, any_02, … and each port's label becomes the title of whatever's wired in, so you can read priority order at a glance. The output's label copies the type of the first connected input - cosmetic; the wire underneath is still *.

    The inputs and output that matter

    No widgets, no required inputs - that's the design. Connect as many sources as you like and take the single * output into whatever consumes it: a latent, a model, a conditioning slot.

    Because the output's declared type is *, ComfyUI will happily let you wire a MASK into a port that wants an IMAGE. Nothing complains at link time. It complains three nodes later, on queue, pointing at the wrong place. That's the tradeoff behind the "Please Stop using the Anything Anywhere extension" backlash we cover in the ecosystem notes: type-erasing convenience nodes are great until a graph stops explaining itself.

    Install

    Manager, search XB_ToolBox, install, restart. Or by hand:

    cd ComfyUI/custom_nodes
    git clone https://github.com/wjluoxiao/XB_ToolBox.git
    

    Restart the backend, not just the browser - the port logic is a frontend extension registered from the pack's js/ directory - then hard-refresh (Ctrl+F5) to clear the old bundle cache.

    Skip the pack's requirements.txt. It serves the audio, CosyVoice, local-LLM and hardware-dashboard groups and drags in transformers, diffusers, openai-whisper, pythonnet and friends. This node is forty lines of Python over a JS extension and needs none of it.

    Where people get burned

    A branch that "fails" by returning something useless still wins. Fallback only skips genuinely empty inputs, and almost no ComfyUI node returns None. Loaders always hand back a model. So don't expect this to pick the branch that produced the better result - it picks the highest slot with anything in it. The idiom that works is to bypass (Ctrl+B) the branch you don't want so nothing arrives at its slot; that's the null-output placeholder pattern from the plumbing notes.

    Priority shifts when you unplug. Removing a middle input collapses the empties, the rest of the ports slide up, and what used to be third is now first. The labels show upstream titles so you can see it, but re-check after any rewiring - and if the slots look stale, right-click → 🔄 刷新端口 rebuilds them.

    Everything empty returns None, and a downstream required input then fails the run with a missing-input error. Correct behaviour, unhelpful message.

    It is not a model switcher. If you want "these three checkpoints, pick one", use the pack's own XB_ReferenceAny (the README calls it Fast Muter + Any Switch fused) or a mute/bypass strip. Four of these chained together is a graph you'll debug at 2am for no reason.

    One pack-level note: XB_ToolBox is one person (wjluoxiao, sole commit author), Chinese-first docs, no English write-ups to fall back on. Single-maintainer caveats apply - it works, it's free, and the source is your documentation. Which is why the source is quoted above.

    CategoryXB_ToolBox/Utils

    Inputs (0)

    No inputs

    Outputs (1)

    NameTypeDescription
    **—