Merge pull request #9028 from comfyanonymous/v3-definition-wip

V3 refactor+cleanup - Drop 'V3' from names of classes intended to be commonly used, add '_' to some classes
This commit is contained in:
Jedrzej Kosinski 2025-07-23 15:48:06 -07:00 committed by GitHub
commit 32c46c044c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
53 changed files with 392 additions and 398 deletions

View File

@ -17,7 +17,7 @@ def first_real_override(cls: type, name: str, *, base: type=None) -> Optional[Ca
if base_attr is None: if base_attr is None:
return None return None
base_func = base_attr.__func__ base_func = base_attr.__func__
for c in cls.mro(): # NodeB, NodeA, ComfyNodeV3, object … for c in cls.mro(): # NodeB, NodeA, ComfyNode, object …
if c is base: # reached the placeholder we're done if c is base: # reached the placeholder we're done
break break
if name in c.__dict__: # first class that *defines* the attr if name in c.__dict__: # first class that *defines* the attr
@ -27,7 +27,7 @@ def first_real_override(cls: type, name: str, *, base: type=None) -> Optional[Ca
return None return None
class ComfyNodeInternal: class _ComfyNodeInternal:
"""Class that all V3-based APIs inherit from for ComfyNode. """Class that all V3-based APIs inherit from for ComfyNode.
This is intended to only be referenced within execution.py, as it has to handle all V3 APIs going forward.""" This is intended to only be referenced within execution.py, as it has to handle all V3 APIs going forward."""

View File

@ -22,7 +22,7 @@ from comfy.samplers import CFGGuider, Sampler
from comfy.sd import CLIP, VAE from comfy.sd import CLIP, VAE
from comfy.sd import StyleModel as StyleModel_ from comfy.sd import StyleModel as StyleModel_
from comfy_api.input import VideoInput from comfy_api.input import VideoInput
from comfy_api.internal import (ComfyNodeInternal, classproperty, copy_class, first_real_override, is_class, from comfy_api.internal import (_ComfyNodeInternal, classproperty, copy_class, first_real_override, is_class,
prune_dict, shallow_clone_class) prune_dict, shallow_clone_class)
from comfy_api.v3.resources import Resources, ResourcesLocal from comfy_api.v3.resources import Resources, ResourcesLocal
from comfy_execution.graph import ExecutionBlocker from comfy_execution.graph import ExecutionBlocker
@ -85,7 +85,7 @@ class _StringIOType(str):
b = frozenset(value.split(",")) b = frozenset(value.split(","))
return not (b.issubset(a) or a.issubset(b)) return not (b.issubset(a) or a.issubset(b))
class ComfyType(ABC): class _ComfyType(ABC):
Type = Any Type = Any
io_type: str = None io_type: str = None
@ -101,7 +101,7 @@ def comfytype(io_type: str, **kwargs):
- class Output(OutputV3): ... - class Output(OutputV3): ...
''' '''
def decorator(cls: T) -> T: def decorator(cls: T) -> T:
if isinstance(cls, ComfyType) or issubclass(cls, ComfyType): if isinstance(cls, _ComfyType) or issubclass(cls, _ComfyType):
# clone Input and Output classes to avoid modifying the original class # clone Input and Output classes to avoid modifying the original class
new_cls = cls new_cls = cls
if hasattr(new_cls, "Input"): if hasattr(new_cls, "Input"):
@ -140,11 +140,11 @@ def Custom(io_type: str) -> type[ComfyTypeIO]:
... ...
return CustomComfyType return CustomComfyType
class IO_V3: class _IO_V3:
''' '''
Base class for V3 Inputs and Outputs. Base class for V3 Inputs and Outputs.
''' '''
Parent: ComfyType = None Parent: _ComfyType = None
def __init__(self): def __init__(self):
pass pass
@ -157,7 +157,7 @@ class IO_V3:
def Type(self): def Type(self):
return self.Parent.Type return self.Parent.Type
class InputV3(IO_V3): class InputV3(_IO_V3):
''' '''
Base class for a V3 Input. Base class for a V3 Input.
''' '''
@ -206,7 +206,7 @@ class WidgetInputV3(InputV3):
return self.widget_type if self.widget_type is not None else super().get_io_type() return self.widget_type if self.widget_type is not None else super().get_io_type()
class OutputV3(IO_V3): class OutputV3(_IO_V3):
def __init__(self, id: str=None, display_name: str=None, tooltip: str=None, def __init__(self, id: str=None, display_name: str=None, tooltip: str=None,
is_output_list=False): is_output_list=False):
self.id = id self.id = id
@ -225,7 +225,7 @@ class OutputV3(IO_V3):
return self.io_type return self.io_type
class ComfyTypeI(ComfyType): class ComfyTypeI(_ComfyType):
'''ComfyType subclass that only has a default Input class - intended for types that only have Inputs.''' '''ComfyType subclass that only has a default Input class - intended for types that only have Inputs.'''
class Input(InputV3): class Input(InputV3):
... ...
@ -694,7 +694,7 @@ class MultiType:
''' '''
Input that permits more than one input type; if `id` is an instance of `ComfyType.Input`, then that input will be used to create a widget (if applicable) with overridden values. Input that permits more than one input type; if `id` is an instance of `ComfyType.Input`, then that input will be used to create a widget (if applicable) with overridden values.
''' '''
def __init__(self, id: str | InputV3, types: list[type[ComfyType] | ComfyType], display_name: str=None, optional=False, tooltip: str=None, lazy: bool=None, extra_dict=None): def __init__(self, id: str | InputV3, types: list[type[_ComfyType] | _ComfyType], display_name: str=None, optional=False, tooltip: str=None, lazy: bool=None, extra_dict=None):
# if id is an Input, then use that Input with overridden values # if id is an Input, then use that Input with overridden values
self.input_override = None self.input_override = None
if isinstance(id, InputV3): if isinstance(id, InputV3):
@ -807,9 +807,9 @@ class ComboDynamicInput(DynamicInput):
@comfytype(io_type="COMFY_MATCHTYPE_V3") @comfytype(io_type="COMFY_MATCHTYPE_V3")
class MatchType(ComfyTypeIO): class MatchType(ComfyTypeIO):
class Template: class Template:
def __init__(self, template_id: str, allowed_types: ComfyType | list[ComfyType]): def __init__(self, template_id: str, allowed_types: _ComfyType | list[_ComfyType]):
self.template_id = template_id self.template_id = template_id
self.allowed_types = [allowed_types] if isinstance(allowed_types, ComfyType) else allowed_types self.allowed_types = [allowed_types] if isinstance(allowed_types, _ComfyType) else allowed_types
def as_dict(self): def as_dict(self):
return { return {
@ -932,7 +932,7 @@ class NodeInfoV3:
@dataclass @dataclass
class SchemaV3: class Schema:
"""Definition of V3 node properties.""" """Definition of V3 node properties."""
node_id: str node_id: str
@ -1116,7 +1116,7 @@ def add_to_dict_v3(io: InputV3 | OutputV3, d: dict):
class _ComfyNodeBaseInternal(ComfyNodeInternal): class _ComfyNodeBaseInternal(_ComfyNodeInternal):
"""Common base class for storing internal methods and properties; DO NOT USE for defining nodes.""" """Common base class for storing internal methods and properties; DO NOT USE for defining nodes."""
RELATIVE_PYTHON_MODULE = None RELATIVE_PYTHON_MODULE = None
@ -1128,8 +1128,8 @@ class _ComfyNodeBaseInternal(ComfyNodeInternal):
@classmethod @classmethod
@abstractmethod @abstractmethod
def define_schema(cls) -> SchemaV3: def define_schema(cls) -> Schema:
"""Override this function with one that returns a SchemaV3 instance.""" """Override this function with one that returns a Schema instance."""
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod
@ -1222,10 +1222,10 @@ class _ComfyNodeBaseInternal(ComfyNodeInternal):
@final @final
@classmethod @classmethod
def PREPARE_CLASS_CLONE(cls, hidden_inputs: dict) -> type[ComfyNodeV3]: def PREPARE_CLASS_CLONE(cls, hidden_inputs: dict) -> type[ComfyNode]:
"""Creates clone of real node class to prevent monkey-patching.""" """Creates clone of real node class to prevent monkey-patching."""
c_type: type[ComfyNodeV3] = cls if is_class(cls) else type(cls) c_type: type[ComfyNode] = cls if is_class(cls) else type(cls)
type_clone: type[ComfyNodeV3] = shallow_clone_class(c_type) type_clone: type[ComfyNode] = shallow_clone_class(c_type)
# set hidden # set hidden
type_clone.hidden = HiddenHolder.from_dict(hidden_inputs) type_clone.hidden = HiddenHolder.from_dict(hidden_inputs)
return type_clone return type_clone
@ -1344,7 +1344,7 @@ class _ComfyNodeBaseInternal(ComfyNodeInternal):
@final @final
@classmethod @classmethod
def INPUT_TYPES(cls, include_hidden=True, return_schema=False) -> dict[str, dict] | tuple[dict[str, dict], SchemaV3]: def INPUT_TYPES(cls, include_hidden=True, return_schema=False) -> dict[str, dict] | tuple[dict[str, dict], Schema]:
schema = cls.FINALIZE_SCHEMA() schema = cls.FINALIZE_SCHEMA()
info = schema.get_v1_info(cls) info = schema.get_v1_info(cls)
input = info.input input = info.input
@ -1364,7 +1364,7 @@ class _ComfyNodeBaseInternal(ComfyNodeInternal):
@final @final
@classmethod @classmethod
def GET_SCHEMA(cls) -> SchemaV3: def GET_SCHEMA(cls) -> Schema:
"""Validate node class, finalize schema, validate schema, and set expected class properties.""" """Validate node class, finalize schema, validate schema, and set expected class properties."""
cls.VALIDATE_CLASS() cls.VALIDATE_CLASS()
schema = cls.FINALIZE_SCHEMA() schema = cls.FINALIZE_SCHEMA()
@ -1408,13 +1408,13 @@ class _ComfyNodeBaseInternal(ComfyNodeInternal):
############################################# #############################################
class ComfyNodeV3(_ComfyNodeBaseInternal): class ComfyNode(_ComfyNodeBaseInternal):
"""Common base class for all V3 nodes.""" """Common base class for all V3 nodes."""
@classmethod @classmethod
@abstractmethod @abstractmethod
def define_schema(cls) -> SchemaV3: def define_schema(cls) -> Schema:
"""Override this function with one that returns a SchemaV3 instance.""" """Override this function with one that returns a Schema instance."""
raise NotImplementedError raise NotImplementedError
@classmethod @classmethod
@ -1453,23 +1453,21 @@ class ComfyNodeV3(_ComfyNodeBaseInternal):
@classmethod @classmethod
def GET_BASE_CLASS(cls): def GET_BASE_CLASS(cls):
"""DO NOT override this class. Will break things in execution.py.""" """DO NOT override this class. Will break things in execution.py."""
return ComfyNodeV3 return ComfyNode
class NodeOutput: class NodeOutput:
''' '''
Standardized output of a node; can pass in any number of args and/or a UIOutput into 'ui' kwarg. Standardized output of a node; can pass in any number of args and/or a UIOutput into 'ui' kwarg.
''' '''
def __init__(self, *args: Any, ui: _UIOutput | dict=None, expand: dict=None, block_execution: str=None, **kwargs): def __init__(self, *args: Any, ui: _UIOutput | dict=None, expand: dict=None, block_execution: str=None):
self.args = args self.args = args
self.ui = ui self.ui = ui
self.expand = expand self.expand = expand
self.block_execution = block_execution self.block_execution = block_execution
# self.kwargs = kwargs
@property @property
def result(self): def result(self):
# TODO: use kwargs to refer to outputs by id + organize in proper order
return self.args if len(self.args) > 0 else None return self.args if len(self.args) > 0 else None
@classmethod @classmethod

View File

@ -17,7 +17,7 @@ import folder_paths
# used for image preview # used for image preview
from comfy.cli_args import args from comfy.cli_args import args
from comfy_api.v3.io import ComfyNodeV3, FolderType, Image, _UIOutput from comfy_api.v3.io import ComfyNode, FolderType, Image, _UIOutput
class SavedResult(dict): class SavedResult(dict):
@ -78,7 +78,7 @@ class ImageSaveHelper:
return PILImage.fromarray(np.clip(255.0 * image_tensor.cpu().numpy(), 0, 255).astype(np.uint8)) return PILImage.fromarray(np.clip(255.0 * image_tensor.cpu().numpy(), 0, 255).astype(np.uint8))
@staticmethod @staticmethod
def _create_png_metadata(cls: Type[ComfyNodeV3] | None) -> PngInfo | None: def _create_png_metadata(cls: Type[ComfyNode] | None) -> PngInfo | None:
"""Creates a PngInfo object with prompt and extra_pnginfo.""" """Creates a PngInfo object with prompt and extra_pnginfo."""
if args.disable_metadata or cls is None or not cls.hidden: if args.disable_metadata or cls is None or not cls.hidden:
return None return None
@ -91,7 +91,7 @@ class ImageSaveHelper:
return metadata return metadata
@staticmethod @staticmethod
def _create_animated_png_metadata(cls: Type[ComfyNodeV3] | None) -> PngInfo | None: def _create_animated_png_metadata(cls: Type[ComfyNode] | None) -> PngInfo | None:
"""Creates a PngInfo object with prompt and extra_pnginfo for animated PNGs (APNG).""" """Creates a PngInfo object with prompt and extra_pnginfo for animated PNGs (APNG)."""
if args.disable_metadata or cls is None or not cls.hidden: if args.disable_metadata or cls is None or not cls.hidden:
return None return None
@ -116,7 +116,7 @@ class ImageSaveHelper:
return metadata return metadata
@staticmethod @staticmethod
def _create_webp_metadata(pil_image: PILImage.Image, cls: Type[ComfyNodeV3] | None) -> PILImage.Exif: def _create_webp_metadata(pil_image: PILImage.Image, cls: Type[ComfyNode] | None) -> PILImage.Exif:
"""Creates EXIF metadata bytes for WebP images.""" """Creates EXIF metadata bytes for WebP images."""
exif_data = pil_image.getexif() exif_data = pil_image.getexif()
if args.disable_metadata or cls is None or cls.hidden is None: if args.disable_metadata or cls is None or cls.hidden is None:
@ -132,7 +132,7 @@ class ImageSaveHelper:
@staticmethod @staticmethod
def save_images( def save_images(
images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNodeV3] | None, compress_level = 4, images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNode] | None, compress_level = 4,
) -> list[SavedResult]: ) -> list[SavedResult]:
"""Saves a batch of images as individual PNG files.""" """Saves a batch of images as individual PNG files."""
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path( full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
@ -150,7 +150,7 @@ class ImageSaveHelper:
return results return results
@staticmethod @staticmethod
def get_save_images_ui(images, filename_prefix: str, cls: Type[ComfyNodeV3] | None, compress_level=4) -> SavedImages: def get_save_images_ui(images, filename_prefix: str, cls: Type[ComfyNode] | None, compress_level=4) -> SavedImages:
"""Saves a batch of images and returns a UI object for the node output.""" """Saves a batch of images and returns a UI object for the node output."""
return SavedImages( return SavedImages(
ImageSaveHelper.save_images( ImageSaveHelper.save_images(
@ -164,7 +164,7 @@ class ImageSaveHelper:
@staticmethod @staticmethod
def save_animated_png( def save_animated_png(
images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNodeV3] | None, fps: float, compress_level: int images, filename_prefix: str, folder_type: FolderType, cls: Type[ComfyNode] | None, fps: float, compress_level: int
) -> SavedResult: ) -> SavedResult:
"""Saves a batch of images as a single animated PNG.""" """Saves a batch of images as a single animated PNG."""
full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path( full_output_folder, filename, counter, subfolder, _ = folder_paths.get_save_image_path(
@ -186,7 +186,7 @@ class ImageSaveHelper:
@staticmethod @staticmethod
def get_save_animated_png_ui( def get_save_animated_png_ui(
images, filename_prefix: str, cls: Type[ComfyNodeV3] | None, fps: float, compress_level: int images, filename_prefix: str, cls: Type[ComfyNode] | None, fps: float, compress_level: int
) -> SavedImages: ) -> SavedImages:
"""Saves an animated PNG and returns a UI object for the node output.""" """Saves an animated PNG and returns a UI object for the node output."""
result = ImageSaveHelper.save_animated_png( result = ImageSaveHelper.save_animated_png(
@ -204,7 +204,7 @@ class ImageSaveHelper:
images, images,
filename_prefix: str, filename_prefix: str,
folder_type: FolderType, folder_type: FolderType,
cls: Type[ComfyNodeV3] | None, cls: Type[ComfyNode] | None,
fps: float, fps: float,
lossless: bool, lossless: bool,
quality: int, quality: int,
@ -233,7 +233,7 @@ class ImageSaveHelper:
def get_save_animated_webp_ui( def get_save_animated_webp_ui(
images, images,
filename_prefix: str, filename_prefix: str,
cls: Type[ComfyNodeV3] | None, cls: Type[ComfyNode] | None,
fps: float, fps: float,
lossless: bool, lossless: bool,
quality: int, quality: int,
@ -262,7 +262,7 @@ class AudioSaveHelper:
audio: dict, audio: dict,
filename_prefix: str, filename_prefix: str,
folder_type: FolderType, folder_type: FolderType,
cls: Type[ComfyNodeV3] | None, cls: Type[ComfyNode] | None,
format: str = "flac", format: str = "flac",
quality: str = "128k", quality: str = "128k",
) -> list[SavedResult]: ) -> list[SavedResult]:
@ -364,7 +364,7 @@ class AudioSaveHelper:
@staticmethod @staticmethod
def get_save_audio_ui( def get_save_audio_ui(
audio, filename_prefix: str, cls: Type[ComfyNodeV3] | None, format: str = "flac", quality: str = "128k", audio, filename_prefix: str, cls: Type[ComfyNode] | None, format: str = "flac", quality: str = "128k",
) -> SavedAudios: ) -> SavedAudios:
"""Save and instantly wrap for UI.""" """Save and instantly wrap for UI."""
return SavedAudios( return SavedAudios(
@ -380,7 +380,7 @@ class AudioSaveHelper:
class PreviewImage(_UIOutput): class PreviewImage(_UIOutput):
def __init__(self, image: Image.Type, animated: bool = False, cls: Type[ComfyNodeV3] = None, **kwargs): def __init__(self, image: Image.Type, animated: bool = False, cls: Type[ComfyNode] = None, **kwargs):
self.values = ImageSaveHelper.save_images( self.values = ImageSaveHelper.save_images(
image, image,
filename_prefix="ComfyUI_temp_" + ''.join(random.choice("abcdefghijklmnopqrstupvxyz") for _ in range(5)), filename_prefix="ComfyUI_temp_" + ''.join(random.choice("abcdefghijklmnopqrstupvxyz") for _ in range(5)),
@ -398,7 +398,7 @@ class PreviewImage(_UIOutput):
class PreviewMask(PreviewImage): class PreviewMask(PreviewImage):
def __init__(self, mask: PreviewMask.Type, animated: bool=False, cls: ComfyNodeV3=None, **kwargs): def __init__(self, mask: PreviewMask.Type, animated: bool=False, cls: ComfyNode=None, **kwargs):
preview = mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])).movedim(1, -1).expand(-1, -1, -1, 3) preview = mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])).movedim(1, -1).expand(-1, -1, -1, 3)
super().__init__(preview, animated, cls, **kwargs) super().__init__(preview, animated, cls, **kwargs)
@ -452,7 +452,7 @@ class PreviewMask(PreviewImage):
class PreviewAudio(_UIOutput): class PreviewAudio(_UIOutput):
def __init__(self, audio: dict, cls: Type[ComfyNodeV3] = None, **kwargs): def __init__(self, audio: dict, cls: Type[ComfyNode] = None, **kwargs):
self.values = AudioSaveHelper.save_audio( self.values = AudioSaveHelper.save_audio(
audio, audio,
filename_prefix="ComfyUI_temp_" + "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(5)), filename_prefix="ComfyUI_temp_" + "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for _ in range(5)),

View File

@ -9,15 +9,11 @@ import asyncio
@io.comfytype(io_type="XYZ") @io.comfytype(io_type="XYZ")
class XYZ: class XYZ(io.ComfyTypeIO):
Type = tuple[int,str] Type = tuple[int,str]
class Input(io.InputV3):
...
class Output(io.OutputV3):
...
class V3TestNode(io.ComfyNodeV3): class V3TestNode(io.ComfyNode):
# NOTE: this is here just to test that state is not leaking # NOTE: this is here just to test that state is not leaking
def __init__(self): def __init__(self):
super().__init__() super().__init__()
@ -25,7 +21,7 @@ class V3TestNode(io.ComfyNodeV3):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_01_TestNode1", node_id="V3_01_TestNode1",
display_name="V3 Test Node", display_name="V3 Test Node",
category="v3 nodes", category="v3 nodes",
@ -91,10 +87,10 @@ class V3TestNode(io.ComfyNodeV3):
return io.NodeOutput(some_int, image, ui=ui.PreviewImage(image, cls=cls)) return io.NodeOutput(some_int, image, ui=ui.PreviewImage(image, cls=cls))
class V3LoraLoader(io.ComfyNodeV3): class V3LoraLoader(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_LoraLoader", node_id="V3_LoraLoader",
display_name="V3 LoRA Loader", display_name="V3 LoRA Loader",
category="v3 nodes", category="v3 nodes",
@ -141,10 +137,10 @@ class V3LoraLoader(io.ComfyNodeV3):
return io.NodeOutput(model_lora, clip_lora) return io.NodeOutput(model_lora, clip_lora)
class NInputsTest(io.ComfyNodeV3): class NInputsTest(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_NInputsTest", node_id="V3_NInputsTest",
display_name="V3 N Inputs Test", display_name="V3 N Inputs Test",
inputs=[ inputs=[
@ -183,10 +179,10 @@ class NInputsTest(io.ComfyNodeV3):
return io.NodeOutput(combined_image) return io.NodeOutput(combined_image)
class V3TestSleep(io.ComfyNodeV3): class V3TestSleep(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_TestSleep", node_id="V3_TestSleep",
display_name="V3 Test Sleep", display_name="V3 Test Sleep",
category="_for_testing", category="_for_testing",
@ -218,10 +214,10 @@ class V3TestSleep(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
class V3DummyStart(io.ComfyNodeV3): class V3DummyStart(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_DummyStart", node_id="V3_DummyStart",
display_name="V3 Dummy Start", display_name="V3 Dummy Start",
category="v3 nodes", category="v3 nodes",
@ -237,12 +233,12 @@ class V3DummyStart(io.ComfyNodeV3):
return io.NodeOutput(None) return io.NodeOutput(None)
class V3DummyEnd(io.ComfyNodeV3): class V3DummyEnd(io.ComfyNode):
COOL_VALUE = 123 COOL_VALUE = 123
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="V3_DummyEnd", node_id="V3_DummyEnd",
display_name="V3 Dummy End", display_name="V3 Dummy End",
category="v3 nodes", category="v3 nodes",
@ -279,7 +275,7 @@ class V3DummyEndInherit(V3DummyEnd):
return super().execute(xyz) return super().execute(xyz)
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
V3TestNode, V3TestNode,
V3LoraLoader, V3LoraLoader,
NInputsTest, NInputsTest,

View File

@ -7,10 +7,10 @@ import node_helpers
from comfy_api.v3 import io from comfy_api.v3 import io
class TextEncodeAceStepAudio(io.ComfyNodeV3): class TextEncodeAceStepAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="TextEncodeAceStepAudio_V3", node_id="TextEncodeAceStepAudio_V3",
category="conditioning", category="conditioning",
inputs=[ inputs=[
@ -29,10 +29,10 @@ class TextEncodeAceStepAudio(io.ComfyNodeV3):
return io.NodeOutput(conditioning) return io.NodeOutput(conditioning)
class EmptyAceStepLatentAudio(io.ComfyNodeV3): class EmptyAceStepLatentAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="EmptyAceStepLatentAudio_V3", node_id="EmptyAceStepLatentAudio_V3",
category="latent/audio", category="latent/audio",
inputs=[ inputs=[
@ -51,7 +51,7 @@ class EmptyAceStepLatentAudio(io.ComfyNodeV3):
return io.NodeOutput({"samples": latent, "type": "audio"}) return io.NodeOutput({"samples": latent, "type": "audio"})
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
TextEncodeAceStepAudio, TextEncodeAceStepAudio,
EmptyAceStepLatentAudio, EmptyAceStepLatentAudio,
] ]

View File

@ -41,12 +41,12 @@ def sample_lcm_upscale(
return x return x
class SamplerLCMUpscale(io.ComfyNodeV3): class SamplerLCMUpscale(io.ComfyNode):
UPSCALE_METHODS = ["bislerp", "nearest-exact", "bilinear", "area", "bicubic"] UPSCALE_METHODS = ["bislerp", "nearest-exact", "bilinear", "area", "bicubic"]
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="SamplerLCMUpscale_V3", node_id="SamplerLCMUpscale_V3",
category="sampling/custom_sampling/samplers", category="sampling/custom_sampling/samplers",
inputs=[ inputs=[
@ -99,10 +99,10 @@ def sample_euler_pp(model, x, sigmas, extra_args=None, callback=None, disable=No
return x return x
class SamplerEulerCFGpp(io.ComfyNodeV3): class SamplerEulerCFGpp(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="SamplerEulerCFGpp_V3", node_id="SamplerEulerCFGpp_V3",
display_name="SamplerEulerCFG++ _V3", display_name="SamplerEulerCFG++ _V3",
category="_for_testing", category="_for_testing",

View File

@ -47,10 +47,10 @@ def loglinear_interp(t_steps, num_steps):
return np.exp(new_ys)[::-1].copy() return np.exp(new_ys)[::-1].copy()
class AlignYourStepsScheduler(io.ComfyNodeV3): class AlignYourStepsScheduler(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="AlignYourStepsScheduler_V3", node_id="AlignYourStepsScheduler_V3",
category="sampling/custom_sampling/schedulers", category="sampling/custom_sampling/schedulers",
inputs=[ inputs=[

View File

@ -10,10 +10,10 @@ def project(v0, v1):
return v0_parallel, v0_orthogonal return v0_parallel, v0_orthogonal
class APG(io.ComfyNodeV3): class APG(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="APG_V3", node_id="APG_V3",
display_name="Adaptive Projected Guidance _V3", display_name="Adaptive Projected Guidance _V3",
category="sampling/custom_sampling", category="sampling/custom_sampling",

View File

@ -17,10 +17,10 @@ def attention_multiply(attn, model, q, k, v, out):
return m return m
class UNetSelfAttentionMultiply(io.ComfyNodeV3): class UNetSelfAttentionMultiply(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="UNetSelfAttentionMultiply_V3", node_id="UNetSelfAttentionMultiply_V3",
category="_for_testing/attention_experiments", category="_for_testing/attention_experiments",
inputs=[ inputs=[
@ -39,10 +39,10 @@ class UNetSelfAttentionMultiply(io.ComfyNodeV3):
return io.NodeOutput(attention_multiply("attn1", model, q, k, v, out)) return io.NodeOutput(attention_multiply("attn1", model, q, k, v, out))
class UNetCrossAttentionMultiply(io.ComfyNodeV3): class UNetCrossAttentionMultiply(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="UNetCrossAttentionMultiply_V3", node_id="UNetCrossAttentionMultiply_V3",
category="_for_testing/attention_experiments", category="_for_testing/attention_experiments",
inputs=[ inputs=[
@ -61,10 +61,10 @@ class UNetCrossAttentionMultiply(io.ComfyNodeV3):
return io.NodeOutput(attention_multiply("attn2", model, q, k, v, out)) return io.NodeOutput(attention_multiply("attn2", model, q, k, v, out))
class CLIPAttentionMultiply(io.ComfyNodeV3): class CLIPAttentionMultiply(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CLIPAttentionMultiply_V3", node_id="CLIPAttentionMultiply_V3",
category="_for_testing/attention_experiments", category="_for_testing/attention_experiments",
inputs=[ inputs=[
@ -95,10 +95,10 @@ class CLIPAttentionMultiply(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class UNetTemporalAttentionMultiply(io.ComfyNodeV3): class UNetTemporalAttentionMultiply(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="UNetTemporalAttentionMultiply_V3", node_id="UNetTemporalAttentionMultiply_V3",
category="_for_testing/attention_experiments", category="_for_testing/attention_experiments",
inputs=[ inputs=[

View File

@ -12,10 +12,10 @@ import node_helpers
from comfy_api.v3 import io, ui from comfy_api.v3 import io, ui
class ConditioningStableAudio(io.ComfyNodeV3): class ConditioningStableAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ConditioningStableAudio_V3", node_id="ConditioningStableAudio_V3",
category="conditioning", category="conditioning",
inputs=[ inputs=[
@ -42,10 +42,10 @@ class ConditioningStableAudio(io.ComfyNodeV3):
) )
class EmptyLatentAudio(io.ComfyNodeV3): class EmptyLatentAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="EmptyLatentAudio_V3", node_id="EmptyLatentAudio_V3",
category="latent/audio", category="latent/audio",
inputs=[ inputs=[
@ -64,10 +64,10 @@ class EmptyLatentAudio(io.ComfyNodeV3):
return io.NodeOutput({"samples": latent, "type": "audio"}) return io.NodeOutput({"samples": latent, "type": "audio"})
class LoadAudio(io.ComfyNodeV3): class LoadAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LoadAudio_V3", # frontend expects "LoadAudio" to work node_id="LoadAudio_V3", # frontend expects "LoadAudio" to work
display_name="Load Audio _V3", # frontend ignores "display_name" for this node display_name="Load Audio _V3", # frontend ignores "display_name" for this node
category="audio", category="audio",
@ -102,10 +102,10 @@ class LoadAudio(io.ComfyNodeV3):
return True return True
class PreviewAudio(io.ComfyNodeV3): class PreviewAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PreviewAudio_V3", # frontend expects "PreviewAudio" to work node_id="PreviewAudio_V3", # frontend expects "PreviewAudio" to work
display_name="Preview Audio _V3", # frontend ignores "display_name" for this node display_name="Preview Audio _V3", # frontend ignores "display_name" for this node
category="audio", category="audio",
@ -121,10 +121,10 @@ class PreviewAudio(io.ComfyNodeV3):
return io.NodeOutput(ui=ui.PreviewAudio(audio, cls=cls)) return io.NodeOutput(ui=ui.PreviewAudio(audio, cls=cls))
class SaveAudioMP3(io.ComfyNodeV3): class SaveAudioMP3(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveAudioMP3_V3", # frontend expects "SaveAudioMP3" to work node_id="SaveAudioMP3_V3", # frontend expects "SaveAudioMP3" to work
display_name="Save Audio(MP3) _V3", # frontend ignores "display_name" for this node display_name="Save Audio(MP3) _V3", # frontend ignores "display_name" for this node
category="audio", category="audio",
@ -146,10 +146,10 @@ class SaveAudioMP3(io.ComfyNodeV3):
) )
class SaveAudioOpus(io.ComfyNodeV3): class SaveAudioOpus(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveAudioOpus_V3", # frontend expects "SaveAudioOpus" to work node_id="SaveAudioOpus_V3", # frontend expects "SaveAudioOpus" to work
display_name="Save Audio(Opus) _V3", # frontend ignores "display_name" for this node display_name="Save Audio(Opus) _V3", # frontend ignores "display_name" for this node
category="audio", category="audio",
@ -171,10 +171,10 @@ class SaveAudioOpus(io.ComfyNodeV3):
) )
class SaveAudio(io.ComfyNodeV3): class SaveAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveAudio_V3", # frontend expects "SaveAudio" to work node_id="SaveAudio_V3", # frontend expects "SaveAudio" to work
display_name="Save Audio _V3", # frontend ignores "display_name" for this node display_name="Save Audio _V3", # frontend ignores "display_name" for this node
category="audio", category="audio",
@ -193,10 +193,10 @@ class SaveAudio(io.ComfyNodeV3):
) )
class VAEDecodeAudio(io.ComfyNodeV3): class VAEDecodeAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="VAEDecodeAudio_V3", node_id="VAEDecodeAudio_V3",
category="latent/audio", category="latent/audio",
inputs=[ inputs=[
@ -215,10 +215,10 @@ class VAEDecodeAudio(io.ComfyNodeV3):
return io.NodeOutput({"waveform": audio, "sample_rate": 44100}) return io.NodeOutput({"waveform": audio, "sample_rate": 44100})
class VAEEncodeAudio(io.ComfyNodeV3): class VAEEncodeAudio(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="VAEEncodeAudio_V3", node_id="VAEEncodeAudio_V3",
category="latent/audio", category="latent/audio",
inputs=[ inputs=[
@ -238,7 +238,7 @@ class VAEEncodeAudio(io.ComfyNodeV3):
return io.NodeOutput({"samples": vae.encode(waveform.movedim(1, -1))}) return io.NodeOutput({"samples": vae.encode(waveform.movedim(1, -1))})
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
ConditioningStableAudio, ConditioningStableAudio,
EmptyLatentAudio, EmptyLatentAudio,
LoadAudio, LoadAudio,

View File

@ -135,10 +135,10 @@ def get_camera_motion(angle, T, speed, n=81):
return RT return RT
class WanCameraEmbedding(io.ComfyNodeV3): class WanCameraEmbedding(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanCameraEmbedding_V3", node_id="WanCameraEmbedding_V3",
category="camera", category="camera",
inputs=[ inputs=[

View File

@ -6,10 +6,10 @@ import comfy.model_management
from comfy_api.v3 import io from comfy_api.v3 import io
class Canny(io.ComfyNodeV3): class Canny(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="Canny_V3", node_id="Canny_V3",
category="image/preprocessors", category="image/preprocessors",
inputs=[ inputs=[

View File

@ -21,10 +21,10 @@ def optimized_scale(positive, negative):
return st_star.reshape([positive.shape[0]] + [1] * (positive.ndim - 1)) return st_star.reshape([positive.shape[0]] + [1] * (positive.ndim - 1))
class CFGNorm(io.ComfyNodeV3): class CFGNorm(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CFGNorm_V3", node_id="CFGNorm_V3",
category="advanced/guidance", category="advanced/guidance",
inputs=[ inputs=[
@ -52,10 +52,10 @@ class CFGNorm(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class CFGZeroStar(io.ComfyNodeV3): class CFGZeroStar(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CFGZeroStar_V3", node_id="CFGZeroStar_V3",
category="advanced/guidance", category="advanced/guidance",
inputs=[ inputs=[

View File

@ -4,10 +4,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class CLIPTextEncodeSDXL(io.ComfyNodeV3): class CLIPTextEncodeSDXL(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeSDXL_V3", node_id="CLIPTextEncodeSDXL_V3",
category="advanced/conditioning", category="advanced/conditioning",
inputs=[ inputs=[
@ -48,10 +48,10 @@ class CLIPTextEncodeSDXL(io.ComfyNodeV3):
return io.NodeOutput(conditioning) return io.NodeOutput(conditioning)
class CLIPTextEncodeSDXLRefiner(io.ComfyNodeV3): class CLIPTextEncodeSDXLRefiner(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeSDXLRefiner_V3", node_id="CLIPTextEncodeSDXLRefiner_V3",
category="advanced/conditioning", category="advanced/conditioning",
inputs=[ inputs=[

View File

@ -112,10 +112,10 @@ def porter_duff_composite(
return out_image, out_alpha return out_image, out_alpha
class JoinImageWithAlpha(io.ComfyNodeV3): class JoinImageWithAlpha(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="JoinImageWithAlpha_V3", node_id="JoinImageWithAlpha_V3",
display_name="Join Image with Alpha _V3", display_name="Join Image with Alpha _V3",
category="mask/compositing", category="mask/compositing",
@ -138,10 +138,10 @@ class JoinImageWithAlpha(io.ComfyNodeV3):
return io.NodeOutput(torch.stack(out_images)) return io.NodeOutput(torch.stack(out_images))
class PorterDuffImageComposite(io.ComfyNodeV3): class PorterDuffImageComposite(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PorterDuffImageComposite_V3", node_id="PorterDuffImageComposite_V3",
display_name="Porter-Duff Image Composite _V3", display_name="Porter-Duff Image Composite _V3",
category="mask/compositing", category="mask/compositing",
@ -199,10 +199,10 @@ class PorterDuffImageComposite(io.ComfyNodeV3):
return io.NodeOutput(torch.stack(out_images), torch.stack(out_alphas)) return io.NodeOutput(torch.stack(out_images), torch.stack(out_alphas))
class SplitImageWithAlpha(io.ComfyNodeV3): class SplitImageWithAlpha(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SplitImageWithAlpha_V3", node_id="SplitImageWithAlpha_V3",
display_name="Split Image with Alpha _V3", display_name="Split Image with Alpha _V3",
category="mask/compositing", category="mask/compositing",

View File

@ -3,10 +3,10 @@ from __future__ import annotations
from comfy_api.v3 import io from comfy_api.v3 import io
class CLIPTextEncodeControlnet(io.ComfyNodeV3): class CLIPTextEncodeControlnet(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeControlnet_V3", node_id="CLIPTextEncodeControlnet_V3",
category="_for_testing/conditioning", category="_for_testing/conditioning",
inputs=[ inputs=[
@ -30,10 +30,10 @@ class CLIPTextEncodeControlnet(io.ComfyNodeV3):
return io.NodeOutput(c) return io.NodeOutput(c)
class T5TokenizerOptions(io.ComfyNodeV3): class T5TokenizerOptions(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="T5TokenizerOptions_V3", node_id="T5TokenizerOptions_V3",
category="_for_testing/conditioning", category="_for_testing/conditioning",
inputs=[ inputs=[

View File

@ -3,10 +3,10 @@ from comfy.cldm.control_types import UNION_CONTROLNET_TYPES
from comfy_api.v3 import io from comfy_api.v3 import io
class ControlNetApplyAdvanced(io.ComfyNodeV3): class ControlNetApplyAdvanced(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ControlNetApplyAdvanced_V3", node_id="ControlNetApplyAdvanced_V3",
display_name="Apply ControlNet _V3", display_name="Apply ControlNet _V3",
category="conditioning/controlnet", category="conditioning/controlnet",
@ -60,10 +60,10 @@ class ControlNetApplyAdvanced(io.ComfyNodeV3):
return io.NodeOutput(out[0], out[1]) return io.NodeOutput(out[0], out[1])
class SetUnionControlNetType(io.ComfyNodeV3): class SetUnionControlNetType(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SetUnionControlNetType_V3", node_id="SetUnionControlNetType_V3",
category="conditioning/controlnet", category="conditioning/controlnet",
inputs=[ inputs=[
@ -90,7 +90,7 @@ class SetUnionControlNetType(io.ComfyNodeV3):
class ControlNetInpaintingAliMamaApply(ControlNetApplyAdvanced): class ControlNetInpaintingAliMamaApply(ControlNetApplyAdvanced):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ControlNetInpaintingAliMamaApply_V3", node_id="ControlNetInpaintingAliMamaApply_V3",
category="conditioning/controlnet", category="conditioning/controlnet",
inputs=[ inputs=[
@ -134,7 +134,7 @@ class ControlNetInpaintingAliMamaApply(ControlNetApplyAdvanced):
) )
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
ControlNetApplyAdvanced, ControlNetApplyAdvanced,
SetUnionControlNetType, SetUnionControlNetType,
ControlNetInpaintingAliMamaApply, ControlNetInpaintingAliMamaApply,

View File

@ -20,10 +20,10 @@ def vae_encode_with_padding(vae, image, width, height, length, padding=0):
return latent_temp[:, :, :latent_len] return latent_temp[:, :, :latent_len]
class CosmosImageToVideoLatent(io.ComfyNodeV3): class CosmosImageToVideoLatent(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CosmosImageToVideoLatent_V3", node_id="CosmosImageToVideoLatent_V3",
category="conditioning/inpaint", category="conditioning/inpaint",
inputs=[ inputs=[
@ -67,10 +67,10 @@ class CosmosImageToVideoLatent(io.ComfyNodeV3):
return io.NodeOutput(out_latent) return io.NodeOutput(out_latent)
class CosmosPredict2ImageToVideoLatent(io.ComfyNodeV3): class CosmosPredict2ImageToVideoLatent(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="CosmosPredict2ImageToVideoLatent_V3", node_id="CosmosPredict2ImageToVideoLatent_V3",
category="conditioning/inpaint", category="conditioning/inpaint",
inputs=[ inputs=[
@ -116,10 +116,10 @@ class CosmosPredict2ImageToVideoLatent(io.ComfyNodeV3):
return io.NodeOutput(out_latent) return io.NodeOutput(out_latent)
class EmptyCosmosLatentVideo(io.ComfyNodeV3): class EmptyCosmosLatentVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls) -> io.SchemaV3: def define_schema(cls) -> io.Schema:
return io.SchemaV3( return io.Schema(
node_id="EmptyCosmosLatentVideo_V3", node_id="EmptyCosmosLatentVideo_V3",
category="latent/video", category="latent/video",
inputs=[ inputs=[

View File

@ -5,10 +5,10 @@ import torch
from comfy_api.v3 import io from comfy_api.v3 import io
class DifferentialDiffusion(io.ComfyNodeV3): class DifferentialDiffusion(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="DifferentialDiffusion_V3", node_id="DifferentialDiffusion_V3",
display_name="Differential Diffusion _V3", display_name="Differential Diffusion _V3",
category="_for_testing", category="_for_testing",

View File

@ -4,10 +4,10 @@ import node_helpers
from comfy_api.v3 import io from comfy_api.v3 import io
class ReferenceLatent(io.ComfyNodeV3): class ReferenceLatent(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ReferenceLatent_V3", node_id="ReferenceLatent_V3",
category="advanced/conditioning/edit_models", category="advanced/conditioning/edit_models",
description="This node sets the guiding latent for an edit model. If the model supports it you can chain multiple to set multiple reference images.", description="This node sets the guiding latent for an edit model. If the model supports it you can chain multiple to set multiple reference images.",

View File

@ -25,10 +25,10 @@ PREFERED_KONTEXT_RESOLUTIONS = [
] ]
class CLIPTextEncodeFlux(io.ComfyNodeV3): class CLIPTextEncodeFlux(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeFlux_V3", node_id="CLIPTextEncodeFlux_V3",
category="advanced/conditioning/flux", category="advanced/conditioning/flux",
inputs=[ inputs=[
@ -50,10 +50,10 @@ class CLIPTextEncodeFlux(io.ComfyNodeV3):
return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens, add_dict={"guidance": guidance})) return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens, add_dict={"guidance": guidance}))
class FluxDisableGuidance(io.ComfyNodeV3): class FluxDisableGuidance(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FluxDisableGuidance_V3", node_id="FluxDisableGuidance_V3",
category="advanced/conditioning/flux", category="advanced/conditioning/flux",
description="This node completely disables the guidance embed on Flux and Flux like models", description="This node completely disables the guidance embed on Flux and Flux like models",
@ -71,10 +71,10 @@ class FluxDisableGuidance(io.ComfyNodeV3):
return io.NodeOutput(c) return io.NodeOutput(c)
class FluxGuidance(io.ComfyNodeV3): class FluxGuidance(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FluxGuidance_V3", node_id="FluxGuidance_V3",
category="advanced/conditioning/flux", category="advanced/conditioning/flux",
inputs=[ inputs=[
@ -92,10 +92,10 @@ class FluxGuidance(io.ComfyNodeV3):
return io.NodeOutput(c) return io.NodeOutput(c)
class FluxKontextImageScale(io.ComfyNodeV3): class FluxKontextImageScale(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FluxKontextImageScale_V3", node_id="FluxKontextImageScale_V3",
category="advanced/conditioning/flux", category="advanced/conditioning/flux",
description="This node resizes the image to one that is more optimal for flux kontext.", description="This node resizes the image to one that is more optimal for flux kontext.",

View File

@ -28,10 +28,10 @@ def Fourier_filter(x, threshold, scale):
return x_filtered.to(x.dtype) return x_filtered.to(x.dtype)
class FreeU(io.ComfyNodeV3): class FreeU(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FreeU_V3", node_id="FreeU_V3",
category="model_patches/unet", category="model_patches/unet",
inputs=[ inputs=[
@ -73,10 +73,10 @@ class FreeU(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class FreeU_V2(io.ComfyNodeV3): class FreeU_V2(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FreeU_V2_V3", node_id="FreeU_V2_V3",
category="model_patches/unet", category="model_patches/unet",
inputs=[ inputs=[

View File

@ -56,10 +56,10 @@ def Fourier_filter(x, scale_low=1.0, scale_high=1.5, freq_cutoff=20):
return x_filtered return x_filtered
class FreSca(io.ComfyNodeV3): class FreSca(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FreSca_V3", node_id="FreSca_V3",
display_name="FreSca _V3", display_name="FreSca _V3",
category="_for_testing", category="_for_testing",

View File

@ -336,10 +336,10 @@ NOISE_LEVELS = {
} }
class GITSScheduler(io.ComfyNodeV3): class GITSScheduler(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="GITSScheduler_V3", node_id="GITSScheduler_V3",
category="sampling/custom_sampling/schedulers", category="sampling/custom_sampling/schedulers",
inputs=[ inputs=[

View File

@ -6,10 +6,10 @@ import folder_paths
from comfy_api.v3 import io from comfy_api.v3 import io
class CLIPTextEncodeHiDream(io.ComfyNodeV3): class CLIPTextEncodeHiDream(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeHiDream_V3", node_id="CLIPTextEncodeHiDream_V3",
category="advanced/conditioning", category="advanced/conditioning",
inputs=[ inputs=[
@ -33,10 +33,10 @@ class CLIPTextEncodeHiDream(io.ComfyNodeV3):
return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens)) return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens))
class QuadrupleCLIPLoader(io.ComfyNodeV3): class QuadrupleCLIPLoader(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="QuadrupleCLIPLoader_V3", node_id="QuadrupleCLIPLoader_V3",
category="advanced/loaders", category="advanced/loaders",
description="[Recipes]\n\nhidream: long clip-l, long clip-g, t5xxl, llama_8b_3.1_instruct", description="[Recipes]\n\nhidream: long clip-l, long clip-g, t5xxl, llama_8b_3.1_instruct",

View File

@ -13,10 +13,10 @@ from comfy_api.v3 import io, ui
from server import PromptServer from server import PromptServer
class GetImageSize(io.ComfyNodeV3): class GetImageSize(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="GetImageSize_V3", node_id="GetImageSize_V3",
display_name="Get Image Size _V3", display_name="Get Image Size _V3",
description="Returns width and height of the image, and passes it through unchanged.", description="Returns width and height of the image, and passes it through unchanged.",
@ -46,10 +46,10 @@ class GetImageSize(io.ComfyNodeV3):
return io.NodeOutput(width, height, batch_size) return io.NodeOutput(width, height, batch_size)
class ImageAddNoise(io.ComfyNodeV3): class ImageAddNoise(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageAddNoise_V3", node_id="ImageAddNoise_V3",
display_name="Image Add Noise _V3", display_name="Image Add Noise _V3",
category="image", category="image",
@ -79,10 +79,10 @@ class ImageAddNoise(io.ComfyNodeV3):
return io.NodeOutput(s) return io.NodeOutput(s)
class ImageCrop(io.ComfyNodeV3): class ImageCrop(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageCrop_V3", node_id="ImageCrop_V3",
display_name="Image Crop _V3", display_name="Image Crop _V3",
category="image/transform", category="image/transform",
@ -105,10 +105,10 @@ class ImageCrop(io.ComfyNodeV3):
return io.NodeOutput(image[:, y:to_y, x:to_x, :]) return io.NodeOutput(image[:, y:to_y, x:to_x, :])
class ImageFlip(io.ComfyNodeV3): class ImageFlip(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageFlip_V3", node_id="ImageFlip_V3",
display_name="Image Flip _V3", display_name="Image Flip _V3",
category="image/transform", category="image/transform",
@ -129,10 +129,10 @@ class ImageFlip(io.ComfyNodeV3):
return io.NodeOutput(image) return io.NodeOutput(image)
class ImageFromBatch(io.ComfyNodeV3): class ImageFromBatch(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageFromBatch_V3", node_id="ImageFromBatch_V3",
display_name="Image From Batch _V3", display_name="Image From Batch _V3",
category="image/batch", category="image/batch",
@ -153,10 +153,10 @@ class ImageFromBatch(io.ComfyNodeV3):
return io.NodeOutput(s) return io.NodeOutput(s)
class ImageRotate(io.ComfyNodeV3): class ImageRotate(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageRotate_V3", node_id="ImageRotate_V3",
display_name="Image Rotate _V3", display_name="Image Rotate _V3",
category="image/transform", category="image/transform",
@ -180,12 +180,12 @@ class ImageRotate(io.ComfyNodeV3):
return io.NodeOutput(torch.rot90(image, k=rotate_by, dims=[2, 1])) return io.NodeOutput(torch.rot90(image, k=rotate_by, dims=[2, 1]))
class ImageStitch(io.ComfyNodeV3): class ImageStitch(io.ComfyNode):
"""Upstreamed from https://github.com/kijai/ComfyUI-KJNodes""" """Upstreamed from https://github.com/kijai/ComfyUI-KJNodes"""
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageStitch_V3", node_id="ImageStitch_V3",
display_name="Image Stitch _V3", display_name="Image Stitch _V3",
description="Stitches image2 to image1 in the specified direction. " description="Stitches image2 to image1 in the specified direction. "
@ -350,10 +350,10 @@ class ImageStitch(io.ComfyNodeV3):
return io.NodeOutput(torch.cat(images, dim=concat_dim)) return io.NodeOutput(torch.cat(images, dim=concat_dim))
class LoadImage(io.ComfyNodeV3): class LoadImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LoadImage_V3", node_id="LoadImage_V3",
display_name="Load Image _V3", display_name="Load Image _V3",
category="image", category="image",
@ -438,10 +438,10 @@ class LoadImage(io.ComfyNodeV3):
return True return True
class LoadImageOutput(io.ComfyNodeV3): class LoadImageOutput(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LoadImageOutput_V3", node_id="LoadImageOutput_V3",
display_name="Load Image (from Outputs) _V3", display_name="Load Image (from Outputs) _V3",
description="Load an image from the output folder. " description="Load an image from the output folder. "
@ -527,10 +527,10 @@ class LoadImageOutput(io.ComfyNodeV3):
return True return True
class PreviewImage(io.ComfyNodeV3): class PreviewImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PreviewImage_V3", node_id="PreviewImage_V3",
display_name="Preview Image _V3", display_name="Preview Image _V3",
description="Preview the input images.", description="Preview the input images.",
@ -547,10 +547,10 @@ class PreviewImage(io.ComfyNodeV3):
return io.NodeOutput(ui=ui.PreviewImage(images, cls=cls)) return io.NodeOutput(ui=ui.PreviewImage(images, cls=cls))
class RepeatImageBatch(io.ComfyNodeV3): class RepeatImageBatch(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="RepeatImageBatch_V3", node_id="RepeatImageBatch_V3",
display_name="Repeat Image Batch _V3", display_name="Repeat Image Batch _V3",
category="image/batch", category="image/batch",
@ -566,10 +566,10 @@ class RepeatImageBatch(io.ComfyNodeV3):
return io.NodeOutput(image.repeat((amount, 1, 1, 1))) return io.NodeOutput(image.repeat((amount, 1, 1, 1)))
class ResizeAndPadImage(io.ComfyNodeV3): class ResizeAndPadImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ResizeAndPadImage_V3", node_id="ResizeAndPadImage_V3",
display_name="Resize and Pad Image _V3", display_name="Resize and Pad Image _V3",
category="image/transform", category="image/transform",
@ -611,10 +611,10 @@ class ResizeAndPadImage(io.ComfyNodeV3):
return io.NodeOutput(padded.permute(0, 2, 3, 1)) return io.NodeOutput(padded.permute(0, 2, 3, 1))
class SaveAnimatedPNG(io.ComfyNodeV3): class SaveAnimatedPNG(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveAnimatedPNG_V3", node_id="SaveAnimatedPNG_V3",
display_name="Save Animated PNG _V3", display_name="Save Animated PNG _V3",
category="image/animation", category="image/animation",
@ -641,12 +641,12 @@ class SaveAnimatedPNG(io.ComfyNodeV3):
) )
class SaveAnimatedWEBP(io.ComfyNodeV3): class SaveAnimatedWEBP(io.ComfyNode):
COMPRESS_METHODS = {"default": 4, "fastest": 0, "slowest": 6} COMPRESS_METHODS = {"default": 4, "fastest": 0, "slowest": 6}
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveAnimatedWEBP_V3", node_id="SaveAnimatedWEBP_V3",
display_name="Save Animated WEBP _V3", display_name="Save Animated WEBP _V3",
category="image/animation", category="image/animation",
@ -677,10 +677,10 @@ class SaveAnimatedWEBP(io.ComfyNodeV3):
) )
class SaveImage(io.ComfyNodeV3): class SaveImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveImage_V3", node_id="SaveImage_V3",
display_name="Save Image _V3", display_name="Save Image _V3",
description="Saves the input images to your ComfyUI output directory.", description="Saves the input images to your ComfyUI output directory.",
@ -708,7 +708,7 @@ class SaveImage(io.ComfyNodeV3):
) )
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
GetImageSize, GetImageSize,
ImageAddNoise, ImageAddNoise,
ImageCrop, ImageCrop,

View File

@ -17,10 +17,10 @@ def reshape_latent_to(target_shape, latent, repeat_batch=True):
return latent return latent
class LatentAdd(io.ComfyNodeV3): class LatentAdd(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentAdd_V3", node_id="LatentAdd_V3",
category="latent/advanced", category="latent/advanced",
inputs=[ inputs=[
@ -44,10 +44,10 @@ class LatentAdd(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentApplyOperation(io.ComfyNodeV3): class LatentApplyOperation(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentApplyOperation_V3", node_id="LatentApplyOperation_V3",
category="latent/advanced/operations", category="latent/advanced/operations",
is_experimental=True, is_experimental=True,
@ -69,10 +69,10 @@ class LatentApplyOperation(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentApplyOperationCFG(io.ComfyNodeV3): class LatentApplyOperationCFG(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentApplyOperationCFG_V3", node_id="LatentApplyOperationCFG_V3",
category="latent/advanced/operations", category="latent/advanced/operations",
is_experimental=True, is_experimental=True,
@ -101,10 +101,10 @@ class LatentApplyOperationCFG(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class LatentBatch(io.ComfyNodeV3): class LatentBatch(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentBatch_V3", node_id="LatentBatch_V3",
category="latent/batch", category="latent/batch",
inputs=[ inputs=[
@ -130,10 +130,10 @@ class LatentBatch(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentBatchSeedBehavior(io.ComfyNodeV3): class LatentBatchSeedBehavior(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentBatchSeedBehavior_V3", node_id="LatentBatchSeedBehavior_V3",
category="latent/advanced", category="latent/advanced",
inputs=[ inputs=[
@ -159,10 +159,10 @@ class LatentBatchSeedBehavior(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentInterpolate(io.ComfyNodeV3): class LatentInterpolate(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentInterpolate_V3", node_id="LatentInterpolate_V3",
category="latent/advanced", category="latent/advanced",
inputs=[ inputs=[
@ -198,10 +198,10 @@ class LatentInterpolate(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentMultiply(io.ComfyNodeV3): class LatentMultiply(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentMultiply_V3", node_id="LatentMultiply_V3",
category="latent/advanced", category="latent/advanced",
inputs=[ inputs=[
@ -222,10 +222,10 @@ class LatentMultiply(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class LatentOperationSharpen(io.ComfyNodeV3): class LatentOperationSharpen(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentOperationSharpen_V3", node_id="LatentOperationSharpen_V3",
category="latent/advanced/operations", category="latent/advanced/operations",
is_experimental=True, is_experimental=True,
@ -264,10 +264,10 @@ class LatentOperationSharpen(io.ComfyNodeV3):
return io.NodeOutput(sharpen) return io.NodeOutput(sharpen)
class LatentOperationTonemapReinhard(io.ComfyNodeV3): class LatentOperationTonemapReinhard(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentOperationTonemapReinhard_V3", node_id="LatentOperationTonemapReinhard_V3",
category="latent/advanced/operations", category="latent/advanced/operations",
is_experimental=True, is_experimental=True,
@ -299,10 +299,10 @@ class LatentOperationTonemapReinhard(io.ComfyNodeV3):
return io.NodeOutput(tonemap_reinhard) return io.NodeOutput(tonemap_reinhard)
class LatentSubtract(io.ComfyNodeV3): class LatentSubtract(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentSubtract_V3", node_id="LatentSubtract_V3",
category="latent/advanced", category="latent/advanced",
inputs=[ inputs=[

View File

@ -86,10 +86,10 @@ def preprocess(image: torch.Tensor, crf=29):
return torch.tensor(image_array, dtype=image.dtype, device=image.device) / 255.0 return torch.tensor(image_array, dtype=image.dtype, device=image.device) / 255.0
class EmptyLTXVLatentVideo(io.ComfyNodeV3): class EmptyLTXVLatentVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="EmptyLTXVLatentVideo_V3", node_id="EmptyLTXVLatentVideo_V3",
category="latent/video/ltxv", category="latent/video/ltxv",
inputs=[ inputs=[
@ -112,13 +112,13 @@ class EmptyLTXVLatentVideo(io.ComfyNodeV3):
return io.NodeOutput({"samples": latent}) return io.NodeOutput({"samples": latent})
class LTXVAddGuide(io.ComfyNodeV3): class LTXVAddGuide(io.ComfyNode):
NUM_PREFIX_FRAMES = 2 NUM_PREFIX_FRAMES = 2
PATCHIFIER = SymmetricPatchifier(1) PATCHIFIER = SymmetricPatchifier(1)
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVAddGuide_V3", node_id="LTXVAddGuide_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -275,10 +275,10 @@ class LTXVAddGuide(io.ComfyNodeV3):
return latent_image, noise_mask return latent_image, noise_mask
class LTXVConditioning(io.ComfyNodeV3): class LTXVConditioning(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVConditioning_V3", node_id="LTXVConditioning_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -299,10 +299,10 @@ class LTXVConditioning(io.ComfyNodeV3):
return io.NodeOutput(positive, negative) return io.NodeOutput(positive, negative)
class LTXVCropGuides(io.ComfyNodeV3): class LTXVCropGuides(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVCropGuides_V3", node_id="LTXVCropGuides_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -335,10 +335,10 @@ class LTXVCropGuides(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, {"samples": latent_image, "noise_mask": noise_mask}) return io.NodeOutput(positive, negative, {"samples": latent_image, "noise_mask": noise_mask})
class LTXVImgToVideo(io.ComfyNodeV3): class LTXVImgToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVImgToVideo_V3", node_id="LTXVImgToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -383,10 +383,10 @@ class LTXVImgToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, {"samples": latent, "noise_mask": conditioning_latent_frames_mask}) return io.NodeOutput(positive, negative, {"samples": latent, "noise_mask": conditioning_latent_frames_mask})
class LTXVPreprocess(io.ComfyNodeV3): class LTXVPreprocess(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVPreprocess_V3", node_id="LTXVPreprocess_V3",
category="image", category="image",
inputs=[ inputs=[
@ -408,10 +408,10 @@ class LTXVPreprocess(io.ComfyNodeV3):
return io.NodeOutput(torch.stack(output_images)) return io.NodeOutput(torch.stack(output_images))
class LTXVScheduler(io.ComfyNodeV3): class LTXVScheduler(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LTXVScheduler_V3", node_id="LTXVScheduler_V3",
category="sampling/custom_sampling/schedulers", category="sampling/custom_sampling/schedulers",
inputs=[ inputs=[
@ -471,10 +471,10 @@ class LTXVScheduler(io.ComfyNodeV3):
return io.NodeOutput(sigmas) return io.NodeOutput(sigmas)
class ModelSamplingLTXV(io.ComfyNodeV3): class ModelSamplingLTXV(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingLTXV_V3", node_id="ModelSamplingLTXV_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[

View File

@ -57,10 +57,10 @@ def composite(destination, source, x, y, mask=None, multiplier=8, resize_source=
return destination return destination
class CropMask(io.ComfyNodeV3): class CropMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CropMask_V3", node_id="CropMask_V3",
display_name="Crop Mask _V3", display_name="Crop Mask _V3",
category="mask", category="mask",
@ -80,10 +80,10 @@ class CropMask(io.ComfyNodeV3):
return io.NodeOutput(mask[:, y : y + height, x : x + width]) return io.NodeOutput(mask[:, y : y + height, x : x + width])
class FeatherMask(io.ComfyNodeV3): class FeatherMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="FeatherMask_V3", node_id="FeatherMask_V3",
display_name="Feather Mask _V3", display_name="Feather Mask _V3",
category="mask", category="mask",
@ -125,10 +125,10 @@ class FeatherMask(io.ComfyNodeV3):
return io.NodeOutput(output) return io.NodeOutput(output)
class GrowMask(io.ComfyNodeV3): class GrowMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="GrowMask_V3", node_id="GrowMask_V3",
display_name="Grow Mask _V3", display_name="Grow Mask _V3",
category="mask", category="mask",
@ -158,10 +158,10 @@ class GrowMask(io.ComfyNodeV3):
return io.NodeOutput(torch.stack(out, dim=0)) return io.NodeOutput(torch.stack(out, dim=0))
class ImageColorToMask(io.ComfyNodeV3): class ImageColorToMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageColorToMask_V3", node_id="ImageColorToMask_V3",
display_name="Image Color to Mask _V3", display_name="Image Color to Mask _V3",
category="mask", category="mask",
@ -183,10 +183,10 @@ class ImageColorToMask(io.ComfyNodeV3):
return io.NodeOutput(torch.where(temp == color, 1.0, 0).float()) return io.NodeOutput(torch.where(temp == color, 1.0, 0).float())
class ImageCompositeMasked(io.ComfyNodeV3): class ImageCompositeMasked(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageCompositeMasked_V3", node_id="ImageCompositeMasked_V3",
display_name="Image Composite Masked _V3", display_name="Image Composite Masked _V3",
category="image", category="image",
@ -209,12 +209,12 @@ class ImageCompositeMasked(io.ComfyNodeV3):
return io.NodeOutput(output) return io.NodeOutput(output)
class ImageToMask(io.ComfyNodeV3): class ImageToMask(io.ComfyNode):
CHANNELS = ["red", "green", "blue", "alpha"] CHANNELS = ["red", "green", "blue", "alpha"]
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageToMask_V3", node_id="ImageToMask_V3",
display_name="Convert Image to Mask _V3", display_name="Convert Image to Mask _V3",
category="mask", category="mask",
@ -230,10 +230,10 @@ class ImageToMask(io.ComfyNodeV3):
return io.NodeOutput(image[:, :, :, cls.CHANNELS.index(channel)]) return io.NodeOutput(image[:, :, :, cls.CHANNELS.index(channel)])
class InvertMask(io.ComfyNodeV3): class InvertMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="InvertMask_V3", node_id="InvertMask_V3",
display_name="Invert Mask _V3", display_name="Invert Mask _V3",
category="mask", category="mask",
@ -248,10 +248,10 @@ class InvertMask(io.ComfyNodeV3):
return io.NodeOutput(1.0 - mask) return io.NodeOutput(1.0 - mask)
class LatentCompositeMasked(io.ComfyNodeV3): class LatentCompositeMasked(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="LatentCompositeMasked_V3", node_id="LatentCompositeMasked_V3",
display_name="Latent Composite Masked _V3", display_name="Latent Composite Masked _V3",
category="latent", category="latent",
@ -275,10 +275,10 @@ class LatentCompositeMasked(io.ComfyNodeV3):
return io.NodeOutput(output) return io.NodeOutput(output)
class MaskComposite(io.ComfyNodeV3): class MaskComposite(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="MaskComposite_V3", node_id="MaskComposite_V3",
display_name="Mask Composite _V3", display_name="Mask Composite _V3",
category="mask", category="mask",
@ -335,7 +335,7 @@ class MaskComposite(io.ComfyNodeV3):
return io.NodeOutput(torch.clamp(output, 0.0, 1.0)) return io.NodeOutput(torch.clamp(output, 0.0, 1.0))
class MaskPreview(io.ComfyNodeV3): class MaskPreview(io.ComfyNode):
"""Mask Preview - original implement in ComfyUI_essentials. """Mask Preview - original implement in ComfyUI_essentials.
https://github.com/cubiq/ComfyUI_essentials/blob/9d9f4bedfc9f0321c19faf71855e228c93bd0dc9/mask.py#L81 https://github.com/cubiq/ComfyUI_essentials/blob/9d9f4bedfc9f0321c19faf71855e228c93bd0dc9/mask.py#L81
@ -344,7 +344,7 @@ class MaskPreview(io.ComfyNodeV3):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="MaskPreview_V3", node_id="MaskPreview_V3",
display_name="Preview Mask _V3", display_name="Preview Mask _V3",
category="mask", category="mask",
@ -360,10 +360,10 @@ class MaskPreview(io.ComfyNodeV3):
return io.NodeOutput(ui=ui.PreviewMask(masks)) return io.NodeOutput(ui=ui.PreviewMask(masks))
class MaskToImage(io.ComfyNodeV3): class MaskToImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="MaskToImage_V3", node_id="MaskToImage_V3",
display_name="Convert Mask to Image _V3", display_name="Convert Mask to Image _V3",
category="mask", category="mask",
@ -378,10 +378,10 @@ class MaskToImage(io.ComfyNodeV3):
return io.NodeOutput(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])).movedim(1, -1).expand(-1, -1, -1, 3)) return io.NodeOutput(mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1])).movedim(1, -1).expand(-1, -1, -1, 3))
class SolidMask(io.ComfyNodeV3): class SolidMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SolidMask_V3", node_id="SolidMask_V3",
display_name="Solid Mask _V3", display_name="Solid Mask _V3",
category="mask", category="mask",
@ -398,10 +398,10 @@ class SolidMask(io.ComfyNodeV3):
return io.NodeOutput(torch.full((1, height, width), value, dtype=torch.float32, device="cpu")) return io.NodeOutput(torch.full((1, height, width), value, dtype=torch.float32, device="cpu"))
class ThresholdMask(io.ComfyNodeV3): class ThresholdMask(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ThresholdMask_V3", node_id="ThresholdMask_V3",
display_name="Threshold Mask _V3", display_name="Threshold Mask _V3",
category="mask", category="mask",
@ -417,7 +417,7 @@ class ThresholdMask(io.ComfyNodeV3):
return io.NodeOutput((mask > value).float()) return io.NodeOutput((mask > value).float())
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
CropMask, CropMask,
FeatherMask, FeatherMask,
GrowMask, GrowMask,

View File

@ -7,10 +7,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class EmptyMochiLatentVideo(io.ComfyNodeV3): class EmptyMochiLatentVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="EmptyMochiLatentVideo_V3", node_id="EmptyMochiLatentVideo_V3",
category="latent/video", category="latent/video",
inputs=[ inputs=[

View File

@ -57,10 +57,10 @@ class ModelSamplingDiscreteDistilled(comfy.model_sampling.ModelSamplingDiscrete)
return log_sigma.exp().to(timestep.device) return log_sigma.exp().to(timestep.device)
class ModelComputeDtype(io.ComfyNodeV3): class ModelComputeDtype(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelComputeDtype_V3", node_id="ModelComputeDtype_V3",
category="advanced/debug/model", category="advanced/debug/model",
inputs=[ inputs=[
@ -79,10 +79,10 @@ class ModelComputeDtype(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class ModelSamplingContinuousEDM(io.ComfyNodeV3): class ModelSamplingContinuousEDM(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingContinuousEDM_V3", node_id="ModelSamplingContinuousEDM_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -131,10 +131,10 @@ class ModelSamplingContinuousEDM(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class ModelSamplingContinuousV(io.ComfyNodeV3): class ModelSamplingContinuousV(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingContinuousV_V3", node_id="ModelSamplingContinuousV_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -165,10 +165,10 @@ class ModelSamplingContinuousV(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class ModelSamplingDiscrete(io.ComfyNodeV3): class ModelSamplingDiscrete(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingDiscrete_V3", node_id="ModelSamplingDiscrete_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -207,10 +207,10 @@ class ModelSamplingDiscrete(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class ModelSamplingFlux(io.ComfyNodeV3): class ModelSamplingFlux(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingFlux_V3", node_id="ModelSamplingFlux_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -247,10 +247,10 @@ class ModelSamplingFlux(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class ModelSamplingSD3(io.ComfyNodeV3): class ModelSamplingSD3(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingSD3_V3", node_id="ModelSamplingSD3_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -281,7 +281,7 @@ class ModelSamplingSD3(io.ComfyNodeV3):
class ModelSamplingAuraFlow(ModelSamplingSD3): class ModelSamplingAuraFlow(ModelSamplingSD3):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingAuraFlow_V3", node_id="ModelSamplingAuraFlow_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -298,10 +298,10 @@ class ModelSamplingAuraFlow(ModelSamplingSD3):
return super().execute(model, shift, multiplier) return super().execute(model, shift, multiplier)
class ModelSamplingStableCascade(io.ComfyNodeV3): class ModelSamplingStableCascade(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ModelSamplingStableCascade_V3", node_id="ModelSamplingStableCascade_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[
@ -329,10 +329,10 @@ class ModelSamplingStableCascade(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class RescaleCFG(io.ComfyNodeV3): class RescaleCFG(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="RescaleCFG_V3", node_id="RescaleCFG_V3",
category="advanced/model", category="advanced/model",
inputs=[ inputs=[

View File

@ -4,12 +4,12 @@ import comfy.utils
from comfy_api.v3 import io from comfy_api.v3 import io
class PatchModelAddDownscale(io.ComfyNodeV3): class PatchModelAddDownscale(io.ComfyNode):
UPSCALE_METHODS = ["bicubic", "nearest-exact", "bilinear", "area", "bislerp"] UPSCALE_METHODS = ["bicubic", "nearest-exact", "bilinear", "area", "bislerp"]
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PatchModelAddDownscale_V3", node_id="PatchModelAddDownscale_V3",
display_name="PatchModelAddDownscale (Kohya Deep Shrink) _V3", display_name="PatchModelAddDownscale (Kohya Deep Shrink) _V3",
category="model_patches/unet", category="model_patches/unet",

View File

@ -16,10 +16,10 @@ import comfy.model_management
from comfy_api.v3 import io from comfy_api.v3 import io
class ImageRGBToYUV(io.ComfyNodeV3): class ImageRGBToYUV(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageRGBToYUV_V3", node_id="ImageRGBToYUV_V3",
category="image/batch", category="image/batch",
inputs=[ inputs=[
@ -38,10 +38,10 @@ class ImageRGBToYUV(io.ComfyNodeV3):
return io.NodeOutput(out[..., 0:1].expand_as(image), out[..., 1:2].expand_as(image), out[..., 2:3].expand_as(image)) return io.NodeOutput(out[..., 0:1].expand_as(image), out[..., 1:2].expand_as(image), out[..., 2:3].expand_as(image))
class ImageYUVToRGB(io.ComfyNodeV3): class ImageYUVToRGB(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageYUVToRGB_V3", node_id="ImageYUVToRGB_V3",
category="image/batch", category="image/batch",
inputs=[ inputs=[
@ -60,10 +60,10 @@ class ImageYUVToRGB(io.ComfyNodeV3):
return io.NodeOutput(kornia.color.ycbcr_to_rgb(image.movedim(-1, 1)).movedim(1, -1)) return io.NodeOutput(kornia.color.ycbcr_to_rgb(image.movedim(-1, 1)).movedim(1, -1))
class Morphology(io.ComfyNodeV3): class Morphology(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="Morphology_V3", node_id="Morphology_V3",
display_name="ImageMorphology _V3", display_name="ImageMorphology _V3",
category="image/postprocessing", category="image/postprocessing",

View File

@ -26,10 +26,10 @@ NOISE_LEVELS = {
} }
class OptimalStepsScheduler(io.ComfyNodeV3): class OptimalStepsScheduler(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="OptimalStepsScheduler_V3", node_id="OptimalStepsScheduler_V3",
category="sampling/custom_sampling/schedulers", category="sampling/custom_sampling/schedulers",
inputs=[ inputs=[

View File

@ -10,10 +10,10 @@ from comfy_api.v3 import io
#My modified one here is more basic but has fewer chances of breaking with ComfyUI updates. #My modified one here is more basic but has fewer chances of breaking with ComfyUI updates.
class PerturbedAttentionGuidance(io.ComfyNodeV3): class PerturbedAttentionGuidance(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PerturbedAttentionGuidance_V3", node_id="PerturbedAttentionGuidance_V3",
category="model_patches/unet", category="model_patches/unet",
inputs=[ inputs=[

View File

@ -81,10 +81,10 @@ class Guider_PerpNeg(comfy.samplers.CFGGuider):
return cfg_result return cfg_result
class PerpNegGuider(io.ComfyNodeV3): class PerpNegGuider(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PerpNegGuider_V3", node_id="PerpNegGuider_V3",
category="_for_testing", category="_for_testing",
inputs=[ inputs=[

View File

@ -121,10 +121,10 @@ class PhotoMakerIDEncoder(comfy.clip_model.CLIPVisionModelProjection):
return self.fuse_module(prompt_embeds, id_embeds, class_tokens_mask) return self.fuse_module(prompt_embeds, id_embeds, class_tokens_mask)
class PhotoMakerEncode(io.ComfyNodeV3): class PhotoMakerEncode(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PhotoMakerEncode_V3", node_id="PhotoMakerEncode_V3",
category="_for_testing/photomaker", category="_for_testing/photomaker",
inputs=[ inputs=[
@ -173,10 +173,10 @@ class PhotoMakerEncode(io.ComfyNodeV3):
return io.NodeOutput([[out, {"pooled_output": pooled}]]) return io.NodeOutput([[out, {"pooled_output": pooled}]])
class PhotoMakerLoader(io.ComfyNodeV3): class PhotoMakerLoader(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PhotoMakerLoader_V3", node_id="PhotoMakerLoader_V3",
category="_for_testing/photomaker", category="_for_testing/photomaker",
inputs=[ inputs=[

View File

@ -4,10 +4,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class CLIPTextEncodePixArtAlpha(io.ComfyNodeV3): class CLIPTextEncodePixArtAlpha(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodePixArtAlpha_V3", node_id="CLIPTextEncodePixArtAlpha_V3",
category="advanced/conditioning", category="advanced/conditioning",
description="Encodes text and sets the resolution conditioning for PixArt Alpha. Does not apply to PixArt Sigma.", description="Encodes text and sets the resolution conditioning for PixArt Alpha. Does not apply to PixArt Sigma.",

View File

@ -20,10 +20,10 @@ def gaussian_kernel(kernel_size: int, sigma: float, device=None):
return g / g.sum() return g / g.sum()
class Blend(io.ComfyNodeV3): class Blend(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageBlend_V3", node_id="ImageBlend_V3",
category="image/postprocessing", category="image/postprocessing",
inputs=[ inputs=[
@ -74,10 +74,10 @@ class Blend(io.ComfyNodeV3):
return torch.where(x <= 0.25, ((16 * x - 12) * x + 4) * x, torch.sqrt(x)) return torch.where(x <= 0.25, ((16 * x - 12) * x + 4) * x, torch.sqrt(x))
class Blur(io.ComfyNodeV3): class Blur(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageBlur_V3", node_id="ImageBlur_V3",
category="image/postprocessing", category="image/postprocessing",
inputs=[ inputs=[
@ -109,13 +109,13 @@ class Blur(io.ComfyNodeV3):
return io.NodeOutput(blurred.to(comfy.model_management.intermediate_device())) return io.NodeOutput(blurred.to(comfy.model_management.intermediate_device()))
class ImageScaleToTotalPixels(io.ComfyNodeV3): class ImageScaleToTotalPixels(io.ComfyNode):
upscale_methods = ["nearest-exact", "bilinear", "area", "bicubic", "lanczos"] upscale_methods = ["nearest-exact", "bilinear", "area", "bicubic", "lanczos"]
crop_methods = ["disabled", "center"] crop_methods = ["disabled", "center"]
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageScaleToTotalPixels_V3", node_id="ImageScaleToTotalPixels_V3",
category="image/upscaling", category="image/upscaling",
inputs=[ inputs=[
@ -141,10 +141,10 @@ class ImageScaleToTotalPixels(io.ComfyNodeV3):
return io.NodeOutput(s.movedim(1,-1)) return io.NodeOutput(s.movedim(1,-1))
class Quantize(io.ComfyNodeV3): class Quantize(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageQuantize_V3", node_id="ImageQuantize_V3",
category="image/postprocessing", category="image/postprocessing",
inputs=[ inputs=[
@ -205,10 +205,10 @@ class Quantize(io.ComfyNodeV3):
return io.NodeOutput(result) return io.NodeOutput(result)
class Sharpen(io.ComfyNodeV3): class Sharpen(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="ImageSharpen_V3", node_id="ImageSharpen_V3",
category="image/postprocessing", category="image/postprocessing",
inputs=[ inputs=[

View File

@ -5,14 +5,14 @@ import json
from comfy_api.v3 import io, ui from comfy_api.v3 import io, ui
class PreviewAny(io.ComfyNodeV3): class PreviewAny(io.ComfyNode):
"""Originally implement from https://github.com/rgthree/rgthree-comfy/blob/main/py/display_any.py """Originally implement from https://github.com/rgthree/rgthree-comfy/blob/main/py/display_any.py
upstream requested in https://github.com/Kosinkadink/rfcs/blob/main/rfcs/0000-corenodes.md#preview-nodes""" upstream requested in https://github.com/Kosinkadink/rfcs/blob/main/rfcs/0000-corenodes.md#preview-nodes"""
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PreviewAny_V3", # frontend expects "PreviewAny" to work node_id="PreviewAny_V3", # frontend expects "PreviewAny" to work
display_name="Preview Any _V3", # frontend ignores "display_name" for this node display_name="Preview Any _V3", # frontend ignores "display_name" for this node
description="Preview any type of data by converting it to a readable text format.", description="Preview any type of data by converting it to a readable text format.",
@ -42,6 +42,6 @@ class PreviewAny(io.ComfyNodeV3):
return io.NodeOutput(ui=ui.PreviewText(value)) return io.NodeOutput(ui=ui.PreviewText(value))
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
PreviewAny, PreviewAny,
] ]

View File

@ -5,10 +5,10 @@ import sys
from comfy_api.v3 import io from comfy_api.v3 import io
class String(io.ComfyNodeV3): class String(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PrimitiveString_V3", node_id="PrimitiveString_V3",
display_name="String _V3", display_name="String _V3",
category="utils/primitive", category="utils/primitive",
@ -23,10 +23,10 @@ class String(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
class StringMultiline(io.ComfyNodeV3): class StringMultiline(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PrimitiveStringMultiline_V3", node_id="PrimitiveStringMultiline_V3",
display_name="String (Multiline) _V3", display_name="String (Multiline) _V3",
category="utils/primitive", category="utils/primitive",
@ -41,10 +41,10 @@ class StringMultiline(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
class Int(io.ComfyNodeV3): class Int(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PrimitiveInt_V3", node_id="PrimitiveInt_V3",
display_name="Int _V3", display_name="Int _V3",
category="utils/primitive", category="utils/primitive",
@ -59,10 +59,10 @@ class Int(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
class Float(io.ComfyNodeV3): class Float(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PrimitiveFloat_V3", node_id="PrimitiveFloat_V3",
display_name="Float _V3", display_name="Float _V3",
category="utils/primitive", category="utils/primitive",
@ -77,10 +77,10 @@ class Float(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
class Boolean(io.ComfyNodeV3): class Boolean(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="PrimitiveBoolean_V3", node_id="PrimitiveBoolean_V3",
display_name="Boolean _V3", display_name="Boolean _V3",
category="utils/primitive", category="utils/primitive",
@ -95,7 +95,7 @@ class Boolean(io.ComfyNodeV3):
return io.NodeOutput(value) return io.NodeOutput(value)
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
String, String,
StringMultiline, StringMultiline,
Int, Int,

View File

@ -5,10 +5,10 @@ import torch
from comfy_api.v3 import io from comfy_api.v3 import io
class ImageRebatch(io.ComfyNodeV3): class ImageRebatch(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="RebatchImages_V3", node_id="RebatchImages_V3",
display_name="Rebatch Images _V3", display_name="Rebatch Images _V3",
category="image/batch", category="image/batch",
@ -38,10 +38,10 @@ class ImageRebatch(io.ComfyNodeV3):
return io.NodeOutput(output_list) return io.NodeOutput(output_list)
class LatentRebatch(io.ComfyNodeV3): class LatentRebatch(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="RebatchLatents_V3", node_id="RebatchLatents_V3",
display_name="Rebatch Latents _V3", display_name="Rebatch Latents _V3",
category="latent/batch", category="latent/batch",

View File

@ -111,10 +111,10 @@ def gaussian_blur_2d(img, kernel_size, sigma):
return F.conv2d(img, kernel2d, groups=img.shape[-3]) return F.conv2d(img, kernel2d, groups=img.shape[-3])
class SelfAttentionGuidance(io.ComfyNodeV3): class SelfAttentionGuidance(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SelfAttentionGuidance_V3", node_id="SelfAttentionGuidance_V3",
display_name="Self-Attention Guidance _V3", display_name="Self-Attention Guidance _V3",
category="_for_testing", category="_for_testing",

View File

@ -10,10 +10,10 @@ from comfy_api.v3 import io
from comfy_extras.v3.nodes_slg import SkipLayerGuidanceDiT from comfy_extras.v3.nodes_slg import SkipLayerGuidanceDiT
class CLIPTextEncodeSD3(io.ComfyNodeV3): class CLIPTextEncodeSD3(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CLIPTextEncodeSD3_V3", node_id="CLIPTextEncodeSD3_V3",
category="advanced/conditioning", category="advanced/conditioning",
inputs=[ inputs=[
@ -54,10 +54,10 @@ class CLIPTextEncodeSD3(io.ComfyNodeV3):
return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens)) return io.NodeOutput(clip.encode_from_tokens_scheduled(tokens))
class EmptySD3LatentImage(io.ComfyNodeV3): class EmptySD3LatentImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="EmptySD3LatentImage_V3", node_id="EmptySD3LatentImage_V3",
category="latent/sd3", category="latent/sd3",
inputs=[ inputs=[
@ -86,7 +86,7 @@ class SkipLayerGuidanceSD3(SkipLayerGuidanceDiT):
""" """
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SkipLayerGuidanceSD3_V3", node_id="SkipLayerGuidanceSD3_V3",
category="advanced/guidance", category="advanced/guidance",
inputs=[ inputs=[
@ -109,10 +109,10 @@ class SkipLayerGuidanceSD3(SkipLayerGuidanceDiT):
) )
class TripleCLIPLoader(io.ComfyNodeV3): class TripleCLIPLoader(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="TripleCLIPLoader_V3", node_id="TripleCLIPLoader_V3",
category="advanced/loaders", category="advanced/loaders",
description="[Recipes]\n\nsd3: clip-l, clip-g, t5", description="[Recipes]\n\nsd3: clip-l, clip-g, t5",

View File

@ -6,10 +6,10 @@ import comfy.utils
from comfy_api.v3 import io from comfy_api.v3 import io
class SD_4XUpscale_Conditioning(io.ComfyNodeV3): class SD_4XUpscale_Conditioning(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SD_4XUpscale_Conditioning_V3", node_id="SD_4XUpscale_Conditioning_V3",
category="conditioning/upscale_diffusion", category="conditioning/upscale_diffusion",
inputs=[ inputs=[

View File

@ -7,7 +7,7 @@ import comfy.samplers
from comfy_api.v3 import io from comfy_api.v3 import io
class SkipLayerGuidanceDiT(io.ComfyNodeV3): class SkipLayerGuidanceDiT(io.ComfyNode):
""" """
Enhance guidance towards detailed dtructure by having another set of CFG negative with skipped layers. Enhance guidance towards detailed dtructure by having another set of CFG negative with skipped layers.
Inspired by Perturbed Attention Guidance (https://arxiv.org/abs/2403.17377) Inspired by Perturbed Attention Guidance (https://arxiv.org/abs/2403.17377)
@ -16,7 +16,7 @@ class SkipLayerGuidanceDiT(io.ComfyNodeV3):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SkipLayerGuidanceDiT_V3", node_id="SkipLayerGuidanceDiT_V3",
category="advanced/guidance", category="advanced/guidance",
description="Generic version of SkipLayerGuidance node that can be used on every DiT model.", description="Generic version of SkipLayerGuidance node that can be used on every DiT model.",
@ -92,12 +92,12 @@ class SkipLayerGuidanceDiT(io.ComfyNodeV3):
return io.NodeOutput(m) return io.NodeOutput(m)
class SkipLayerGuidanceDiTSimple(io.ComfyNodeV3): class SkipLayerGuidanceDiTSimple(io.ComfyNode):
"""Simple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass.""" """Simple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass."""
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SkipLayerGuidanceDiTSimple_V3", node_id="SkipLayerGuidanceDiTSimple_V3",
category="advanced/guidance", category="advanced/guidance",
description="Simple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass.", description="Simple version of the SkipLayerGuidanceDiT node that only modifies the uncond pass.",

View File

@ -23,10 +23,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class StableCascade_EmptyLatentImage(io.ComfyNodeV3): class StableCascade_EmptyLatentImage(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="StableCascade_EmptyLatentImage_V3", node_id="StableCascade_EmptyLatentImage_V3",
category="latent/stable_cascade", category="latent/stable_cascade",
inputs=[ inputs=[
@ -48,10 +48,10 @@ class StableCascade_EmptyLatentImage(io.ComfyNodeV3):
return io.NodeOutput({"samples": c_latent}, {"samples": b_latent}) return io.NodeOutput({"samples": c_latent}, {"samples": b_latent})
class StableCascade_StageC_VAEEncode(io.ComfyNodeV3): class StableCascade_StageC_VAEEncode(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="StableCascade_StageC_VAEEncode_V3", node_id="StableCascade_StageC_VAEEncode_V3",
category="latent/stable_cascade", category="latent/stable_cascade",
inputs=[ inputs=[
@ -79,10 +79,10 @@ class StableCascade_StageC_VAEEncode(io.ComfyNodeV3):
return io.NodeOutput({"samples": c_latent}, {"samples": b_latent}) return io.NodeOutput({"samples": c_latent}, {"samples": b_latent})
class StableCascade_StageB_Conditioning(io.ComfyNodeV3): class StableCascade_StageB_Conditioning(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="StableCascade_StageB_Conditioning_V3", node_id="StableCascade_StageB_Conditioning_V3",
category="conditioning/stable_cascade", category="conditioning/stable_cascade",
inputs=[ inputs=[
@ -105,10 +105,10 @@ class StableCascade_StageB_Conditioning(io.ComfyNodeV3):
return io.NodeOutput(c) return io.NodeOutput(c)
class StableCascade_SuperResolutionControlnet(io.ComfyNodeV3): class StableCascade_SuperResolutionControlnet(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="StableCascade_SuperResolutionControlnet_V3", node_id="StableCascade_SuperResolutionControlnet_V3",
category="_for_testing/stable_cascade", category="_for_testing/stable_cascade",
is_experimental=True, is_experimental=True,
@ -135,7 +135,7 @@ class StableCascade_SuperResolutionControlnet(io.ComfyNodeV3):
return io.NodeOutput(controlnet_input, {"samples": c_latent}, {"samples": b_latent}) return io.NodeOutput(controlnet_input, {"samples": c_latent}, {"samples": b_latent})
NODES_LIST: list[type[io.ComfyNodeV3]] = [ NODES_LIST: list[type[io.ComfyNode]] = [
StableCascade_EmptyLatentImage, StableCascade_EmptyLatentImage,
StableCascade_StageB_Conditioning, StableCascade_StageB_Conditioning,
StableCascade_StageC_VAEEncode, StableCascade_StageC_VAEEncode,

View File

@ -15,10 +15,10 @@ from comfy_api.util import VideoCodec, VideoComponents, VideoContainer
from comfy_api.v3 import io, ui from comfy_api.v3 import io, ui
class CreateVideo(io.ComfyNodeV3): class CreateVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="CreateVideo_V3", node_id="CreateVideo_V3",
display_name="Create Video _V3", display_name="Create Video _V3",
category="image/video", category="image/video",
@ -44,10 +44,10 @@ class CreateVideo(io.ComfyNodeV3):
)) ))
class GetVideoComponents(io.ComfyNodeV3): class GetVideoComponents(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="GetVideoComponents_V3", node_id="GetVideoComponents_V3",
display_name="Get Video Components _V3", display_name="Get Video Components _V3",
category="image/video", category="image/video",
@ -68,13 +68,13 @@ class GetVideoComponents(io.ComfyNodeV3):
return io.NodeOutput(components.images, components.audio, float(components.frame_rate)) return io.NodeOutput(components.images, components.audio, float(components.frame_rate))
class LoadVideo(io.ComfyNodeV3): class LoadVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
input_dir = folder_paths.get_input_directory() input_dir = folder_paths.get_input_directory()
files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))] files = [f for f in os.listdir(input_dir) if os.path.isfile(os.path.join(input_dir, f))]
files = folder_paths.filter_files_content_types(files, ["video"]) files = folder_paths.filter_files_content_types(files, ["video"])
return io.SchemaV3( return io.Schema(
node_id="LoadVideo_V3", node_id="LoadVideo_V3",
display_name="Load Video _V3", display_name="Load Video _V3",
category="image/video", category="image/video",
@ -105,10 +105,10 @@ class LoadVideo(io.ComfyNodeV3):
return True return True
class SaveVideo(io.ComfyNodeV3): class SaveVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveVideo_V3", node_id="SaveVideo_V3",
display_name="Save Video _V3", display_name="Save Video _V3",
category="image/video", category="image/video",
@ -152,10 +152,10 @@ class SaveVideo(io.ComfyNodeV3):
return io.NodeOutput(ui=ui.PreviewVideo([ui.SavedResult(file, subfolder, io.FolderType.output)])) return io.NodeOutput(ui=ui.PreviewVideo([ui.SavedResult(file, subfolder, io.FolderType.output)]))
class SaveWEBM(io.ComfyNodeV3): class SaveWEBM(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="SaveWEBM_V3", node_id="SaveWEBM_V3",
category="image/video", category="image/video",
is_experimental=True, is_experimental=True,

View File

@ -11,10 +11,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class TrimVideoLatent(io.ComfyNodeV3): class TrimVideoLatent(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="TrimVideoLatent_V3", node_id="TrimVideoLatent_V3",
category="latent/video", category="latent/video",
is_experimental=True, is_experimental=True,
@ -36,10 +36,10 @@ class TrimVideoLatent(io.ComfyNodeV3):
return io.NodeOutput(samples_out) return io.NodeOutput(samples_out)
class WanCameraImageToVideo(io.ComfyNodeV3): class WanCameraImageToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanCameraImageToVideo_V3", node_id="WanCameraImageToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -88,10 +88,10 @@ class WanCameraImageToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, out_latent) return io.NodeOutput(positive, negative, out_latent)
class WanFirstLastFrameToVideo(io.ComfyNodeV3): class WanFirstLastFrameToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanFirstLastFrameToVideo_V3", node_id="WanFirstLastFrameToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -159,10 +159,10 @@ class WanFirstLastFrameToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, out_latent) return io.NodeOutput(positive, negative, out_latent)
class WanFunControlToVideo(io.ComfyNodeV3): class WanFunControlToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanFunControlToVideo_V3", node_id="WanFunControlToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -213,10 +213,10 @@ class WanFunControlToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, out_latent) return io.NodeOutput(positive, negative, out_latent)
class WanFunInpaintToVideo(io.ComfyNodeV3): class WanFunInpaintToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanFunInpaintToVideo_V3", node_id="WanFunInpaintToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -244,10 +244,10 @@ class WanFunInpaintToVideo(io.ComfyNodeV3):
return flfv.execute(positive, negative, vae, width, height, length, batch_size, start_image=start_image, end_image=end_image, clip_vision_start_image=clip_vision_output) return flfv.execute(positive, negative, vae, width, height, length, batch_size, start_image=start_image, end_image=end_image, clip_vision_start_image=clip_vision_output)
class WanImageToVideo(io.ComfyNodeV3): class WanImageToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanImageToVideo_V3", node_id="WanImageToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -292,10 +292,10 @@ class WanImageToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, negative, out_latent) return io.NodeOutput(positive, negative, out_latent)
class WanPhantomSubjectToVideo(io.ComfyNodeV3): class WanPhantomSubjectToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanPhantomSubjectToVideo_V3", node_id="WanPhantomSubjectToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
inputs=[ inputs=[
@ -336,10 +336,10 @@ class WanPhantomSubjectToVideo(io.ComfyNodeV3):
return io.NodeOutput(positive, cond2, negative, out_latent) return io.NodeOutput(positive, cond2, negative, out_latent)
class WanVaceToVideo(io.ComfyNodeV3): class WanVaceToVideo(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WanVaceToVideo_V3", node_id="WanVaceToVideo_V3",
category="conditioning/video_models", category="conditioning/video_models",
is_experimental=True, is_experimental=True,

View File

@ -10,10 +10,10 @@ import nodes
from comfy_api.v3 import io from comfy_api.v3 import io
class WebcamCapture(io.ComfyNodeV3): class WebcamCapture(io.ComfyNode):
@classmethod @classmethod
def define_schema(cls): def define_schema(cls):
return io.SchemaV3( return io.Schema(
node_id="WebcamCapture_V3", node_id="WebcamCapture_V3",
display_name="Webcam Capture _V3", display_name="Webcam Capture _V3",
category="image", category="image",
@ -89,4 +89,4 @@ class WebcamCapture(io.ComfyNodeV3):
return True return True
NODES_LIST: list[type[io.ComfyNodeV3]] = [WebcamCapture] NODES_LIST: list[type[io.ComfyNode]] = [WebcamCapture]

View File

@ -32,7 +32,7 @@ from comfy_execution.graph_utils import GraphBuilder, is_link
from comfy_execution.validation import validate_node_input from comfy_execution.validation import validate_node_input
from comfy_execution.progress import get_progress_state, reset_progress_state, add_progress_handler, WebUIProgressHandler from comfy_execution.progress import get_progress_state, reset_progress_state, add_progress_handler, WebUIProgressHandler
from comfy_execution.utils import CurrentNodeContext from comfy_execution.utils import CurrentNodeContext
from comfy_api.internal import ComfyNodeInternal, first_real_override, is_class, make_locked_method_func from comfy_api.internal import _ComfyNodeInternal, first_real_override, is_class, make_locked_method_func
from comfy_api.v3 import io from comfy_api.v3 import io
@ -60,7 +60,7 @@ class IsChangedCache:
class_def = nodes.NODE_CLASS_MAPPINGS[class_type] class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
has_is_changed = False has_is_changed = False
is_changed_name = None is_changed_name = None
if issubclass(class_def, ComfyNodeInternal) and first_real_override(class_def, "fingerprint_inputs") is not None: if issubclass(class_def, _ComfyNodeInternal) and first_real_override(class_def, "fingerprint_inputs") is not None:
has_is_changed = True has_is_changed = True
is_changed_name = "fingerprint_inputs" is_changed_name = "fingerprint_inputs"
elif hasattr(class_def, "IS_CHANGED"): elif hasattr(class_def, "IS_CHANGED"):
@ -136,7 +136,7 @@ class CacheSet:
SENSITIVE_EXTRA_DATA_KEYS = ("auth_token_comfy_org", "api_key_comfy_org") SENSITIVE_EXTRA_DATA_KEYS = ("auth_token_comfy_org", "api_key_comfy_org")
def get_input_data(inputs, class_def, unique_id, outputs=None, dynprompt=None, extra_data={}): def get_input_data(inputs, class_def, unique_id, outputs=None, dynprompt=None, extra_data={}):
is_v3 = issubclass(class_def, ComfyNodeInternal) is_v3 = issubclass(class_def, _ComfyNodeInternal)
if is_v3: if is_v3:
valid_inputs, schema = class_def.INPUT_TYPES(include_hidden=False, return_schema=True) valid_inputs, schema = class_def.INPUT_TYPES(include_hidden=False, return_schema=True)
else: else:
@ -245,7 +245,7 @@ async def _async_map_node_over_list(prompt_id, unique_id, obj, input_data_all, f
if pre_execute_cb is not None and index is not None: if pre_execute_cb is not None and index is not None:
pre_execute_cb(index) pre_execute_cb(index)
# V3 # V3
if isinstance(obj, ComfyNodeInternal) or (is_class(obj) and issubclass(obj, ComfyNodeInternal)): if isinstance(obj, _ComfyNodeInternal) or (is_class(obj) and issubclass(obj, _ComfyNodeInternal)):
# if is just a class, then assign no resources or state, just create clone # if is just a class, then assign no resources or state, just create clone
if is_class(obj): if is_class(obj):
type_obj = obj type_obj = obj
@ -476,7 +476,7 @@ async def execute(server, dynprompt, caches, current_item, extra_data, executed,
obj = class_def() obj = class_def()
caches.objects.set(unique_id, obj) caches.objects.set(unique_id, obj)
if issubclass(class_def, ComfyNodeInternal): if issubclass(class_def, _ComfyNodeInternal):
lazy_status_present = first_real_override(class_def, "check_lazy_status") is not None lazy_status_present = first_real_override(class_def, "check_lazy_status") is not None
else: else:
lazy_status_present = getattr(obj, "check_lazy_status", None) is not None lazy_status_present = getattr(obj, "check_lazy_status", None) is not None
@ -761,7 +761,7 @@ async def validate_inputs(prompt_id, prompt, item, validated):
validate_function_inputs = [] validate_function_inputs = []
validate_has_kwargs = False validate_has_kwargs = False
if issubclass(obj_class, ComfyNodeInternal): if issubclass(obj_class, _ComfyNodeInternal):
validate_function_name = "validate_inputs" validate_function_name = "validate_inputs"
validate_function = first_real_override(obj_class, validate_function_name) validate_function = first_real_override(obj_class, validate_function_name)
else: else:

View File

@ -2162,7 +2162,7 @@ def load_custom_node(module_path: str, ignore=set(), module_parent="custom_nodes
# V3 node definition # V3 node definition
elif getattr(module, "NODES_LIST", None) is not None: elif getattr(module, "NODES_LIST", None) is not None:
for node_cls in module.NODES_LIST: for node_cls in module.NODES_LIST:
node_cls: io.ComfyNodeV3 node_cls: io.ComfyNode
schema = node_cls.GET_SCHEMA() schema = node_cls.GET_SCHEMA()
if schema.node_id not in ignore: if schema.node_id not in ignore:
NODE_CLASS_MAPPINGS[schema.node_id] = node_cls NODE_CLASS_MAPPINGS[schema.node_id] = node_cls

View File

@ -30,7 +30,7 @@ from comfy_api import feature_flags
import node_helpers import node_helpers
from comfyui_version import __version__ from comfyui_version import __version__
from app.frontend_management import FrontendManager from app.frontend_management import FrontendManager
from comfy_api.internal import ComfyNodeInternal from comfy_api.internal import _ComfyNodeInternal
from app.user_manager import UserManager from app.user_manager import UserManager
from app.model_manager import ModelFileManager from app.model_manager import ModelFileManager
@ -590,7 +590,7 @@ class PromptServer():
def node_info(node_class): def node_info(node_class):
obj_class = nodes.NODE_CLASS_MAPPINGS[node_class] obj_class = nodes.NODE_CLASS_MAPPINGS[node_class]
if issubclass(obj_class, ComfyNodeInternal): if issubclass(obj_class, _ComfyNodeInternal):
return obj_class.GET_NODE_INFO_V1() return obj_class.GET_NODE_INFO_V1()
info = {} info = {}
info['input'] = obj_class.INPUT_TYPES() info['input'] = obj_class.INPUT_TYPES()