diff --git a/comfy_extras/v3/nodes_cond.py b/comfy_extras/v3/nodes_cond.py index 9d3181886..2ce343500 100644 --- a/comfy_extras/v3/nodes_cond.py +++ b/comfy_extras/v3/nodes_cond.py @@ -54,7 +54,7 @@ class T5TokenizerOptions(io.ComfyNode): return io.NodeOutput(clip) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ CLIPTextEncodeControlnet, T5TokenizerOptions, ] diff --git a/comfy_extras/v3/nodes_differential_diffusion.py b/comfy_extras/v3/nodes_differential_diffusion.py index 6eb8cacbc..b4e5ecdc5 100644 --- a/comfy_extras/v3/nodes_differential_diffusion.py +++ b/comfy_extras/v3/nodes_differential_diffusion.py @@ -45,6 +45,6 @@ class DifferentialDiffusion(io.ComfyNode): return (denoise_mask >= threshold).to(denoise_mask.dtype) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ DifferentialDiffusion, ] diff --git a/comfy_extras/v3/nodes_edit_model.py b/comfy_extras/v3/nodes_edit_model.py index 79dd672e3..b6164dc6a 100644 --- a/comfy_extras/v3/nodes_edit_model.py +++ b/comfy_extras/v3/nodes_edit_model.py @@ -29,6 +29,6 @@ class ReferenceLatent(io.ComfyNode): return io.NodeOutput(conditioning) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ ReferenceLatent, ] diff --git a/comfy_extras/v3/nodes_fresca.py b/comfy_extras/v3/nodes_fresca.py index e9057fca5..c4115c84c 100644 --- a/comfy_extras/v3/nodes_fresca.py +++ b/comfy_extras/v3/nodes_fresca.py @@ -105,6 +105,6 @@ class FreSca(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ FreSca, ] diff --git a/comfy_extras/v3/nodes_gits.py b/comfy_extras/v3/nodes_gits.py index 2efb34763..4d500d789 100644 --- a/comfy_extras/v3/nodes_gits.py +++ b/comfy_extras/v3/nodes_gits.py @@ -371,6 +371,6 @@ class GITSScheduler(io.ComfyNode): return io.NodeOutput(torch.FloatTensor(sigmas)) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ GITSScheduler, ] diff --git a/comfy_extras/v3/nodes_hypernetwork.py b/comfy_extras/v3/nodes_hypernetwork.py index 3981324d7..64bab0f48 100644 --- a/comfy_extras/v3/nodes_hypernetwork.py +++ b/comfy_extras/v3/nodes_hypernetwork.py @@ -131,6 +131,6 @@ class HypernetworkLoader(io.ComfyNode): return io.NodeOutput(model_hypernetwork) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ HypernetworkLoader, ] diff --git a/comfy_extras/v3/nodes_hypertile.py b/comfy_extras/v3/nodes_hypertile.py index cec010644..f0bfdb47a 100644 --- a/comfy_extras/v3/nodes_hypertile.py +++ b/comfy_extras/v3/nodes_hypertile.py @@ -90,6 +90,6 @@ class HyperTile(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ HyperTile, ] diff --git a/comfy_extras/v3/nodes_ip2p.py b/comfy_extras/v3/nodes_ip2p.py index d784797b4..f070e329b 100644 --- a/comfy_extras/v3/nodes_ip2p.py +++ b/comfy_extras/v3/nodes_ip2p.py @@ -51,6 +51,6 @@ class InstructPixToPixConditioning(io.ComfyNode): return io.NodeOutput(out[0], out[1], out_latent) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ InstructPixToPixConditioning, ] diff --git a/comfy_extras/v3/nodes_lora_extract.py b/comfy_extras/v3/nodes_lora_extract.py index 54bd051d4..f5896abde 100644 --- a/comfy_extras/v3/nodes_lora_extract.py +++ b/comfy_extras/v3/nodes_lora_extract.py @@ -133,6 +133,6 @@ class LoraSave(io.ComfyNode): return io.NodeOutput() -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ LoraSave, ] diff --git a/comfy_extras/v3/nodes_lotus.py b/comfy_extras/v3/nodes_lotus.py index f2190c753..86a581c1c 100644 --- a/comfy_extras/v3/nodes_lotus.py +++ b/comfy_extras/v3/nodes_lotus.py @@ -29,6 +29,6 @@ class LotusConditioning(io.ComfyNode): return io.NodeOutput(cond) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ LotusConditioning, ] diff --git a/comfy_extras/v3/nodes_mahiro.py b/comfy_extras/v3/nodes_mahiro.py index 19da4b6ed..074a4b080 100644 --- a/comfy_extras/v3/nodes_mahiro.py +++ b/comfy_extras/v3/nodes_mahiro.py @@ -46,6 +46,6 @@ class Mahiro(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ Mahiro, ] diff --git a/comfy_extras/v3/nodes_mochi.py b/comfy_extras/v3/nodes_mochi.py index 77677e4df..18c68634a 100644 --- a/comfy_extras/v3/nodes_mochi.py +++ b/comfy_extras/v3/nodes_mochi.py @@ -33,6 +33,6 @@ class EmptyMochiLatentVideo(io.ComfyNode): return io.NodeOutput({"samples": latent}) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ EmptyMochiLatentVideo, ] diff --git a/comfy_extras/v3/nodes_model_downscale.py b/comfy_extras/v3/nodes_model_downscale.py index 5eaddb7af..322a3bd0f 100644 --- a/comfy_extras/v3/nodes_model_downscale.py +++ b/comfy_extras/v3/nodes_model_downscale.py @@ -63,6 +63,6 @@ class PatchModelAddDownscale(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ PatchModelAddDownscale, ] diff --git a/comfy_extras/v3/nodes_optimalsteps.py b/comfy_extras/v3/nodes_optimalsteps.py index 1fd9c1c4d..b8f398e91 100644 --- a/comfy_extras/v3/nodes_optimalsteps.py +++ b/comfy_extras/v3/nodes_optimalsteps.py @@ -59,6 +59,6 @@ class OptimalStepsScheduler(io.ComfyNode): return io.NodeOutput(torch.FloatTensor(sigmas)) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ OptimalStepsScheduler, ] diff --git a/comfy_extras/v3/nodes_pag.py b/comfy_extras/v3/nodes_pag.py index c438363c4..152a8f736 100644 --- a/comfy_extras/v3/nodes_pag.py +++ b/comfy_extras/v3/nodes_pag.py @@ -57,6 +57,6 @@ class PerturbedAttentionGuidance(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ PerturbedAttentionGuidance, ] diff --git a/comfy_extras/v3/nodes_perpneg.py b/comfy_extras/v3/nodes_perpneg.py index dcb5ac5b6..8456201c5 100644 --- a/comfy_extras/v3/nodes_perpneg.py +++ b/comfy_extras/v3/nodes_perpneg.py @@ -109,6 +109,6 @@ class PerpNegGuider(io.ComfyNode): return io.NodeOutput(guider) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ PerpNegGuider, ] diff --git a/comfy_extras/v3/nodes_pixart.py b/comfy_extras/v3/nodes_pixart.py index 63276955f..2d5158e6a 100644 --- a/comfy_extras/v3/nodes_pixart.py +++ b/comfy_extras/v3/nodes_pixart.py @@ -28,6 +28,6 @@ class CLIPTextEncodePixArtAlpha(io.ComfyNode): return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens, add_dict={"width": width, "height": height})) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ CLIPTextEncodePixArtAlpha, ] diff --git a/comfy_extras/v3/nodes_sag.py b/comfy_extras/v3/nodes_sag.py index 2c4290e09..84446b7e5 100644 --- a/comfy_extras/v3/nodes_sag.py +++ b/comfy_extras/v3/nodes_sag.py @@ -186,4 +186,6 @@ class SelfAttentionGuidance(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [SelfAttentionGuidance] +NODES_LIST: list[type[io.ComfyNode]] = [ + SelfAttentionGuidance, +] diff --git a/comfy_extras/v3/nodes_sdupscale.py b/comfy_extras/v3/nodes_sdupscale.py index 382a71909..a56fc12ad 100644 --- a/comfy_extras/v3/nodes_sdupscale.py +++ b/comfy_extras/v3/nodes_sdupscale.py @@ -53,4 +53,6 @@ class SD_4XUpscale_Conditioning(io.ComfyNode): latent = torch.zeros([images.shape[0], 4, height // 4, width // 4]) return io.NodeOutput(out_cp, out_cn, {"samples":latent}) -NODES_LIST = [SD_4XUpscale_Conditioning] +NODES_LIST: list[type[io.ComfyNode]] = [ + SD_4XUpscale_Conditioning, +] diff --git a/comfy_extras/v3/nodes_string.py b/comfy_extras/v3/nodes_string.py index 57d85a3fd..b476f915a 100644 --- a/comfy_extras/v3/nodes_string.py +++ b/comfy_extras/v3/nodes_string.py @@ -5,6 +5,70 @@ import re from comfy_api.latest import io +class StringConcatenate(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringConcatenate_V3", + display_name="Concatenate _V3", + category="utils/string", + inputs=[ + io.String.Input("string_a", multiline=True), + io.String.Input("string_b", multiline=True), + io.String.Input("delimiter", multiline=False, default="") + ], + outputs=[ + io.String.Output() + ] + ) + + @classmethod + def execute(cls, string_a, string_b, delimiter): + return io.NodeOutput(delimiter.join((string_a, string_b))) + + +class StringSubstring(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringSubstring_V3", + display_name="Substring _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True), + io.Int.Input("start"), + io.Int.Input("end") + ], + outputs=[ + io.String.Output() + ] + ) + + @classmethod + def execute(cls, string, start, end): + return io.NodeOutput(string[start:end]) + + +class StringLength(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringLength_V3", + display_name="Length _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True) + ], + outputs=[ + io.Int.Output(display_name="length") + ] + ) + + @classmethod + def execute(cls, string): + return io.NodeOutput(len(string)) + + class CaseConverter(io.ComfyNode): @classmethod def define_schema(cls): @@ -37,6 +101,160 @@ class CaseConverter(io.ComfyNode): return io.NodeOutput(result) +class StringTrim(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringTrim_V3", + display_name="Trim _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True), + io.Combo.Input("mode", options=["Both", "Left", "Right"]) + ], + outputs=[ + io.String.Output() + ] + ) + + @classmethod + def execute(cls, string, mode): + if mode == "Both": + result = string.strip() + elif mode == "Left": + result = string.lstrip() + elif mode == "Right": + result = string.rstrip() + else: + result = string + + return io.NodeOutput(result) + + +class StringReplace(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringReplace_V3", + display_name="Replace _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True), + io.String.Input("find", multiline=True), + io.String.Input("replace", multiline=True) + ], + outputs=[ + io.String.Output() + ] + ) + + @classmethod + def execute(cls, string, find, replace): + return io.NodeOutput(string.replace(find, replace)) + + +class StringContains(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringContains_V3", + display_name="Contains _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True), + io.String.Input("substring", multiline=True), + io.Boolean.Input("case_sensitive", default=True) + ], + outputs=[ + io.Boolean.Output(display_name="contains") + ] + ) + + @classmethod + def execute(cls, string, substring, case_sensitive): + if case_sensitive: + contains = substring in string + else: + contains = substring.lower() in string.lower() + + return io.NodeOutput(contains) + + +class StringCompare(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="StringCompare_V3", + display_name="Compare _V3", + category="utils/string", + inputs=[ + io.String.Input("string_a", multiline=True), + io.String.Input("string_b", multiline=True), + io.Combo.Input("mode", options=["Starts With", "Ends With", "Equal"]), + io.Boolean.Input("case_sensitive", default=True) + ], + outputs=[ + io.Boolean.Output() + ] + ) + + @classmethod + def execute(cls, string_a, string_b, mode, case_sensitive): + if case_sensitive: + a = string_a + b = string_b + else: + a = string_a.lower() + b = string_b.lower() + + if mode == "Equal": + return io.NodeOutput(a == b) + elif mode == "Starts With": + return io.NodeOutput(a.startswith(b)) + elif mode == "Ends With": + return io.NodeOutput(a.endswith(b)) + + +class RegexMatch(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="RegexMatch_V3", + display_name="Regex Match _V3", + category="utils/string", + inputs=[ + io.String.Input("string", multiline=True), + io.String.Input("regex_pattern", multiline=True), + io.Boolean.Input("case_insensitive", default=True), + io.Boolean.Input("multiline", default=False), + io.Boolean.Input("dotall", default=False) + ], + outputs=[ + io.Boolean.Output(display_name="matches") + ] + ) + + @classmethod + def execute(cls, string, regex_pattern, case_insensitive, multiline, dotall): + flags = 0 + + if case_insensitive: + flags |= re.IGNORECASE + if multiline: + flags |= re.MULTILINE + if dotall: + flags |= re.DOTALL + + try: + match = re.search(regex_pattern, string, flags) + result = match is not None + + except re.error: + result = False + + return io.NodeOutput(result) + + class RegexExtract(io.ComfyNode): @classmethod def define_schema(cls): @@ -111,46 +329,6 @@ class RegexExtract(io.ComfyNode): return io.NodeOutput(result) -class RegexMatch(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="RegexMatch_V3", - display_name="Regex Match _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True), - io.String.Input("regex_pattern", multiline=True), - io.Boolean.Input("case_insensitive", default=True), - io.Boolean.Input("multiline", default=False), - io.Boolean.Input("dotall", default=False) - ], - outputs=[ - io.Boolean.Output(display_name="matches") - ] - ) - - @classmethod - def execute(cls, string, regex_pattern, case_insensitive, multiline, dotall): - flags = 0 - - if case_insensitive: - flags |= re.IGNORECASE - if multiline: - flags |= re.MULTILINE - if dotall: - flags |= re.DOTALL - - try: - match = re.search(regex_pattern, string, flags) - result = match is not None - - except re.error: - result = False - - return io.NodeOutput(result) - - class RegexReplace(io.ComfyNode): @classmethod def define_schema(cls): @@ -187,185 +365,7 @@ class RegexReplace(io.ComfyNode): return io.NodeOutput(result) -class StringCompare(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringCompare_V3", - display_name="Compare _V3", - category="utils/string", - inputs=[ - io.String.Input("string_a", multiline=True), - io.String.Input("string_b", multiline=True), - io.Combo.Input("mode", options=["Starts With", "Ends With", "Equal"]), - io.Boolean.Input("case_sensitive", default=True) - ], - outputs=[ - io.Boolean.Output() - ] - ) - - @classmethod - def execute(cls, string_a, string_b, mode, case_sensitive): - if case_sensitive: - a = string_a - b = string_b - else: - a = string_a.lower() - b = string_b.lower() - - if mode == "Equal": - return io.NodeOutput(a == b) - elif mode == "Starts With": - return io.NodeOutput(a.startswith(b)) - elif mode == "Ends With": - return io.NodeOutput(a.endswith(b)) - - -class StringConcatenate(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringConcatenate_V3", - display_name="Concatenate _V3", - category="utils/string", - inputs=[ - io.String.Input("string_a", multiline=True), - io.String.Input("string_b", multiline=True), - io.String.Input("delimiter", multiline=False, default="") - ], - outputs=[ - io.String.Output() - ] - ) - - @classmethod - def execute(cls, string_a, string_b, delimiter): - return io.NodeOutput(delimiter.join((string_a, string_b))) - - -class StringContains(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringContains_V3", - display_name="Contains _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True), - io.String.Input("substring", multiline=True), - io.Boolean.Input("case_sensitive", default=True) - ], - outputs=[ - io.Boolean.Output(display_name="contains") - ] - ) - - @classmethod - def execute(cls, string, substring, case_sensitive): - if case_sensitive: - contains = substring in string - else: - contains = substring.lower() in string.lower() - - return io.NodeOutput(contains) - - -class StringLength(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringLength_V3", - display_name="Length _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True) - ], - outputs=[ - io.Int.Output(display_name="length") - ] - ) - - @classmethod - def execute(cls, string): - return io.NodeOutput(len(string)) - - -class StringReplace(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringReplace_V3", - display_name="Replace _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True), - io.String.Input("find", multiline=True), - io.String.Input("replace", multiline=True) - ], - outputs=[ - io.String.Output() - ] - ) - - @classmethod - def execute(cls, string, find, replace): - return io.NodeOutput(string.replace(find, replace)) - - -class StringSubstring(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringSubstring_V3", - display_name="Substring _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True), - io.Int.Input("start"), - io.Int.Input("end") - ], - outputs=[ - io.String.Output() - ] - ) - - @classmethod - def execute(cls, string, start, end): - return io.NodeOutput(string[start:end]) - - -class StringTrim(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="StringTrim_V3", - display_name="Trim _V3", - category="utils/string", - inputs=[ - io.String.Input("string", multiline=True), - io.Combo.Input("mode", options=["Both", "Left", "Right"]) - ], - outputs=[ - io.String.Output() - ] - ) - - @classmethod - def execute(cls, string, mode): - if mode == "Both": - result = string.strip() - elif mode == "Left": - result = string.lstrip() - elif mode == "Right": - result = string.rstrip() - else: - result = string - - return io.NodeOutput(result) - - -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ CaseConverter, RegexExtract, RegexMatch, diff --git a/comfy_extras/v3/nodes_tcfg.py b/comfy_extras/v3/nodes_tcfg.py index 2133136c5..9592c3aee 100644 --- a/comfy_extras/v3/nodes_tcfg.py +++ b/comfy_extras/v3/nodes_tcfg.py @@ -65,6 +65,6 @@ class TCFG(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ TCFG, ] diff --git a/comfy_extras/v3/nodes_tomesd.py b/comfy_extras/v3/nodes_tomesd.py index f824dcc27..fffaaba9b 100644 --- a/comfy_extras/v3/nodes_tomesd.py +++ b/comfy_extras/v3/nodes_tomesd.py @@ -185,6 +185,6 @@ class TomePatchModel(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ TomePatchModel, ] diff --git a/comfy_extras/v3/nodes_torch_compile.py b/comfy_extras/v3/nodes_torch_compile.py index ec047ef9e..f34e8c726 100644 --- a/comfy_extras/v3/nodes_torch_compile.py +++ b/comfy_extras/v3/nodes_torch_compile.py @@ -27,6 +27,6 @@ class TorchCompileModel(io.ComfyNode): return io.NodeOutput(m) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ TorchCompileModel, ] diff --git a/comfy_extras/v3/nodes_upscale_model.py b/comfy_extras/v3/nodes_upscale_model.py index 9b892ba3c..c514603e4 100644 --- a/comfy_extras/v3/nodes_upscale_model.py +++ b/comfy_extras/v3/nodes_upscale_model.py @@ -19,6 +19,35 @@ except Exception: pass +class UpscaleModelLoader(io.ComfyNode): + @classmethod + def define_schema(cls): + return io.Schema( + node_id="UpscaleModelLoader_V3", + display_name="Load Upscale Model _V3", + category="loaders", + inputs=[ + io.Combo.Input("model_name", options=folder_paths.get_filename_list("upscale_models")), + ], + outputs=[ + io.UpscaleModel.Output(), + ], + ) + + @classmethod + def execute(cls, model_name): + model_path = folder_paths.get_full_path_or_raise("upscale_models", model_name) + sd = comfy.utils.load_torch_file(model_path, safe_load=True) + if "module.layers.0.residual_group.blocks.0.norm1.weight" in sd: + sd = comfy.utils.state_dict_prefix_replace(sd, {"module.":""}) + out = ModelLoader().load_from_state_dict(sd).eval() + + if not isinstance(out, ImageModelDescriptor): + raise Exception("Upscale model must be a single-image model.") + + return io.NodeOutput(out) + + class ImageUpscaleWithModel(io.ComfyNode): @classmethod def define_schema(cls): @@ -71,36 +100,7 @@ class ImageUpscaleWithModel(io.ComfyNode): return io.NodeOutput(s) -class UpscaleModelLoader(io.ComfyNode): - @classmethod - def define_schema(cls): - return io.Schema( - node_id="UpscaleModelLoader_V3", - display_name="Load Upscale Model _V3", - category="loaders", - inputs=[ - io.Combo.Input("model_name", options=folder_paths.get_filename_list("upscale_models")), - ], - outputs=[ - io.UpscaleModel.Output(), - ], - ) - - @classmethod - def execute(cls, model_name): - model_path = folder_paths.get_full_path_or_raise("upscale_models", model_name) - sd = comfy.utils.load_torch_file(model_path, safe_load=True) - if "module.layers.0.residual_group.blocks.0.norm1.weight" in sd: - sd = comfy.utils.state_dict_prefix_replace(sd, {"module.":""}) - out = ModelLoader().load_from_state_dict(sd).eval() - - if not isinstance(out, ImageModelDescriptor): - raise Exception("Upscale model must be a single-image model.") - - return io.NodeOutput(out) - - -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ ImageUpscaleWithModel, UpscaleModelLoader, ] diff --git a/comfy_extras/v3/nodes_wan.py b/comfy_extras/v3/nodes_wan.py index 43c999ad5..cd8b3ead9 100644 --- a/comfy_extras/v3/nodes_wan.py +++ b/comfy_extras/v3/nodes_wan.py @@ -425,7 +425,7 @@ class WanVaceToVideo(io.ComfyNode): return io.NodeOutput(positive, negative, out_latent, trim_latent) -NODES_LIST = [ +NODES_LIST: list[type[io.ComfyNode]] = [ TrimVideoLatent, WanCameraImageToVideo, WanFirstLastFrameToVideo,