Files
Claude 3adebb731f Rename FunPack to FunUI (5.0.3 Classy Chopper): /fun endpoint, wink logo, load-time migration of old names
Old project/workflow names and browser settings migrate on load; /funpack redirects to /fun.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016acRss69eH1235eRdFTZHY
2026-10-25 13:11:03 +00:00

60 lines
2.6 KiB
Python

"""One file holding a model, its text encoder and its VAE.
The split loaders are right for the families FunUI targets -- LTX and H3 ship
the diffusion model, the encoders and the VAEs separately, and pairing them is
the user's choice. The SD family does not: one checkpoint carries all three, and
without this there is no way to load one at all.
Both exist, and neither is the "real" one. A pipeline using three slots can be
replaced by one using this, which is the point of slots being replaceable.
"""
import comfy.sd
import folder_paths
from comfy_api.latest import io
from ..._core import log
class FunUICheckpointLoader(io.ComfyNode):
@classmethod
def define_schema(cls) -> io.Schema:
return io.Schema(
node_id="FunUICheckpointLoader",
display_name="FunUI Checkpoint Loader",
category="FunUI/Loaders",
description="Load a model, text encoder and VAE from one checkpoint file.",
inputs=[
io.Combo.Input("ckpt_name", options=folder_paths.get_filename_list("checkpoints")),
],
outputs=[
io.Model.Output(display_name="model"),
io.Clip.Output(display_name="clip"),
io.Vae.Output(display_name="vae"),
io.String.Output(display_name="status"),
],
)
@classmethod
def execute(cls, ckpt_name: str) -> io.NodeOutput:
path = folder_paths.get_full_path_or_raise("checkpoints", ckpt_name)
model, clip, vae, *_ = comfy.sd.load_checkpoint_guess_config(
path, output_vae=True, output_clip=True,
embedding_directory=folder_paths.get_folder_paths("embeddings"))
# Each part is reported, because a checkpoint missing its VAE or its
# encoder loads happily and then fails somewhere else entirely.
# ComfyUI hands back an empty VAE placeholder (it raises when used) for a file with no VAE in it.
no_vae = vae is None or getattr(vae, "first_stage_model", True) is None
missing = [name for name, gone in (("clip", clip is None), ("vae", no_vae)) if gone]
if missing:
log.warning("FunUI Checkpoint Loader",
f"{ckpt_name} has no {' or '.join(missing)}; those outputs are empty "
f"and whatever reads them will fail")
kind = type(getattr(model, "model", model)).__name__
log.info("FunUI Checkpoint Loader", f"{ckpt_name} loaded as {kind}")
return io.NodeOutput(model, clip, vae,
f"{ckpt_name} loaded as {kind}"
+ (f" (no {', '.join(missing)})" if missing else ""))