'''Set area of conditioning. First half of values apply to dimensions, the second half apply to coordinates.
By default, the dimensions are based on total pixel amount, but the first value can be set to "percentage" to use a percentage of the image size instead.
(1024, 1024, 0, 0) would apply conditioning to the top-left 1024x1024 pixels.
("percentage", 0.5, 0.5, 0, 0) would apply conditioning to the top-left 50% of the image.'''# TODO: verify its actually top-left
strength:NotRequired[float]
'''Strength of conditioning. Default strength is 1.0.'''
mask:NotRequired[torch.Tensor]
'''Mask to apply conditioning to.'''
mask_strength:NotRequired[float]
'''Strength of conditioning mask. Default strength is 1.0.'''
set_area_to_bounds:NotRequired[bool]
'''Whether conditioning mask should determine bounds of area - if set to false, latents are sampled at full resolution and result is applied in mask.'''
concat_latent_image:NotRequired[torch.Tensor]
'''Used for inpainting and specific models.'''
concat_mask:NotRequired[torch.Tensor]
'''Used for inpainting and specific models.'''
concat_image:NotRequired[torch.Tensor]
'''Used by SD_4XUpscale_Conditioning.'''
noise_augmentation:NotRequired[float]
'''Used by SD_4XUpscale_Conditioning.'''
hooks:NotRequired[HookGroup]
'''Applies hooks to conditioning.'''
default:NotRequired[bool]
'''Whether to this conditioning is 'default'; default conditioning gets applied to any areas of the image that have no masks/areas applied, assuming at least one area/mask is present during sampling.'''
start_percent:NotRequired[float]
'''Determines relative step to begin applying conditioning, expressed as a float between 0.0 and 1.0.'''
end_percent:NotRequired[float]
'''Determines relative step to end applying conditioning, expressed as a float between 0.0 and 1.0.'''
clip_start_percent:NotRequired[float]
'''Internal variable for conditioning scheduling - start of application, expressed as a float between 0.0 and 1.0.'''
clip_end_percent:NotRequired[float]
'''Internal variable for conditioning scheduling - end of application, expressed as a float between 0.0 and 1.0.'''
attention_mask:NotRequired[torch.Tensor]
'''Masks text conditioning; used by StyleModel among others.'''
'''Masks text conditioning; used by StyleModel among others.'''
unclip_conditioning:NotRequired[list[dict]]
'''Used by unCLIP.'''
conditioning_lyrics:NotRequired[torch.Tensor]
'''Used by AceT5Model.'''
seconds_start:NotRequired[float]
'''Used by StableAudio.'''
seconds_total:NotRequired[float]
'''Used by StableAudio.'''
lyrics_strength:NotRequired[float]
'''Used by AceStepAudio.'''
width:NotRequired[int]
'''Used by certain models (e.g. CLIPTextEncodeSDXL/Refiner, PixArtAlpha).'''
height:NotRequired[int]
'''Used by certain models (e.g. CLIPTextEncodeSDXL/Refiner, PixArtAlpha).'''
aesthetic_score:NotRequired[float]
'''Used by CLIPTextEncodeSDXL/Refiner.'''
crop_w:NotRequired[int]
'''Used by CLIPTextEncodeSDXL.'''
crop_h:NotRequired[int]
'''Used by CLIPTextEncodeSDXL.'''
target_width:NotRequired[int]
'''Used by CLIPTextEncodeSDXL.'''
target_height:NotRequired[int]
'''Used by CLIPTextEncodeSDXL.'''
reference_latents:NotRequired[list[torch.Tensor]]
'''Used by ReferenceLatent.'''
guidance:NotRequired[float]
'''Used by Flux-like models with guidance embed.'''
guiding_frame_index:NotRequired[int]
'''Used by Hunyuan ImageToVideo.'''
ref_latent:NotRequired[torch.Tensor]
'''Used by Hunyuan ImageToVideo.'''
keyframe_idxs:NotRequired[list[int]]
'''Used by LTXV.'''
frame_rate:NotRequired[float]
'''Used by LTXV.'''
stable_cascade_prior:NotRequired[torch.Tensor]
'''Used by StableCascade.'''
elevation:NotRequired[list[float]]
'''Used by SV3D.'''
azimuth:NotRequired[list[float]]
'''Used by SV3D.'''
motion_bucket_id:NotRequired[int]
'''Used by SVD-like models.'''
fps:NotRequired[int]
'''Used by SVD-like models.'''
augmentation_level:NotRequired[float]
'''Used by SVD-like models.'''
clip_vision_output:NotRequired[ClipVisionOutput_]
'''Used by WAN-like models.'''
vace_frames:NotRequired[torch.Tensor]
'''Used by WAN VACE.'''
vace_mask:NotRequired[torch.Tensor]
'''Used by WAN VACE.'''
vace_strength:NotRequired[float]
'''Used by WAN VACE.'''
camera_conditions:NotRequired[Any]# TODO: assign proper type once defined
'''Used by WAN Camera.'''
time_dim_concat:NotRequired[torch.Tensor]
'''Used by WAN Phantom Subject.'''
CondList=list[tuple[torch.Tensor,PooledDict]]
Type=CondList
@comfytype(io_type="SAMPLER")
classSampler(ComfyTypeIO):
ifTYPE_CHECKING:
Type=Sampler
@comfytype(io_type="SIGMAS")
classSigmas(ComfyTypeIO):
Type=torch.Tensor
@comfytype(io_type="NOISE")
classNoise(ComfyTypeIO):
Type=torch.Tensor
@comfytype(io_type="GUIDER")
classGuider(ComfyTypeIO):
ifTYPE_CHECKING:
Type=CFGGuider
@comfytype(io_type="CLIP")
classClip(ComfyTypeIO):
ifTYPE_CHECKING:
Type=CLIP
@comfytype(io_type="CONTROL_NET")
classControlNet(ComfyTypeIO):
ifTYPE_CHECKING:
Type=ControlNet
@comfytype(io_type="VAE")
classVae(ComfyTypeIO):
ifTYPE_CHECKING:
Type=VAE
@comfytype(io_type="MODEL")
classModel(ComfyTypeIO):
ifTYPE_CHECKING:
Type=ModelPatcher
@comfytype(io_type="CLIP_VISION")
classClipVision(ComfyTypeIO):
ifTYPE_CHECKING:
Type=ClipVisionModel
@comfytype(io_type="CLIP_VISION_OUTPUT")
classClipVisionOutput(ComfyTypeIO):
ifTYPE_CHECKING:
Type=ClipVisionOutput_
@comfytype(io_type="STYLE_MODEL")
classStyleModel(ComfyTypeIO):
ifTYPE_CHECKING:
Type=StyleModel_
@comfytype(io_type="GLIGEN")
classGligen(ComfyTypeIO):
'''ModelPatcher that wraps around a 'Gligen' model.'''
ifTYPE_CHECKING:
Type=ModelPatcher
@comfytype(io_type="UPSCALE_MODEL")
classUpscaleModel(ComfyTypeIO):
ifTYPE_CHECKING:
Type=ImageModelDescriptor
@comfytype(io_type="AUDIO")
classAudio(ComfyTypeIO):
classAudioDict(TypedDict):
waveform:torch.Tensor
sampler_rate:int
Type=AudioDict
@comfytype(io_type="VIDEO")
classVideo(ComfyTypeIO):
ifTYPE_CHECKING:
Type=VideoInput
@comfytype(io_type="SVG")
classSVG(ComfyTypeIO):
Type=Any# TODO: SVG class is defined in comfy_extras/nodes_images.py, causing circular reference; should be moved to somewhere else before referenced directly in v3
@comfytype(io_type="LORA_MODEL")
classLoraModel(ComfyTypeIO):
Type=dict[str,torch.Tensor]
@comfytype(io_type="LOSS_MAP")
classLossMap(ComfyTypeIO):
classLossMapDict(TypedDict):
loss:list[torch.Tensor]
Type=LossMapDict
@comfytype(io_type="VOXEL")
classVoxel(ComfyTypeIO):
Type=Any# TODO: VOXEL class is defined in comfy_extras/nodes_hunyuan3d.py; should be moved to somewhere else before referenced directly in v3
@comfytype(io_type="MESH")
classMesh(ComfyTypeIO):
Type=Any# TODO: MESH class is defined in comfy_extras/nodes_hunyuan3d.py; should be moved to somewhere else before referenced directly in v3
@comfytype(io_type="HOOKS")
classHooks(ComfyTypeIO):
ifTYPE_CHECKING:
Type=HookGroup
@comfytype(io_type="HOOK_KEYFRAMES")
classHookKeyframes(ComfyTypeIO):
ifTYPE_CHECKING:
Type=HookKeyframeGroup
@comfytype(io_type="TIMESTEPS_RANGE")
classTimestepsRange(ComfyTypeIO):
'''Range defined by start and endpoint, between 0.0 and 1.0.'''
Type=tuple[int,int]
@comfytype(io_type="LATENT_OPERATION")
classLatentOperation(ComfyTypeIO):
Type=Callable[[torch.Tensor],torch.Tensor]
@comfytype(io_type="FLOW_CONTROL")
classFlowControl(ComfyTypeIO):
# NOTE: only used in testing_nodes right now
Type=tuple[str,Any]
@comfytype(io_type="ACCUMULATION")
classAccumulation(ComfyTypeIO):
# NOTE: only used in testing_nodes right now
classAccumulationDict(TypedDict):
accum:list[Any]
Type=AccumulationDict
@comfytype(io_type="LOAD3D_CAMERA")
classLoad3DCamera(ComfyTypeIO):
classCameraInfo(TypedDict):
position:dict[str,float|int]
target:dict[str,float|int]
zoom:int
cameraType:str
Type=CameraInfo
@comfytype(io_type="LOAD_3D")
classLoad3D(ComfyTypeIO):
"""3D models are stored as a dictionary."""
classModel3DDict(TypedDict):
image:str
mask:str
normal:str
camera_info:Load3DCamera.CameraInfo
recording:NotRequired[str]
Type=Model3DDict
@comfytype(io_type="LOAD_3D_ANIMATION")
classLoad3DAnimation(Load3D):
...
@comfytype(io_type="PHOTOMAKER")
classPhotomaker(ComfyTypeIO):
Type=Any
@comfytype(io_type="POINT")
classPoint(ComfyTypeIO):
Type=Any# NOTE: I couldn't find any references in core code to POINT io_type. Does this exist?
@comfytype(io_type="FACE_ANALYSIS")
classFaceAnalysis(ComfyTypeIO):
Type=Any# NOTE: I couldn't find any references in core code to POINT io_type. Does this exist?
@comfytype(io_type="BBOX")
classBBOX(ComfyTypeIO):
Type=Any# NOTE: I couldn't find any references in core code to POINT io_type. Does this exist?
@comfytype(io_type="SEGS")
classSEGS(ComfyTypeIO):
Type=Any# NOTE: I couldn't find any references in core code to POINT io_type. Does this exist?
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.
"""UNIQUE_ID is the unique identifier of the node, and matches the id property of the node on the client side. It is commonly used in client-server communications (see messages)."""
self.prompt=prompt
"""PROMPT is the complete prompt sent by the client to the server. See the prompt object for a full description."""
self.extra_pnginfo=extra_pnginfo
"""EXTRA_PNGINFO is a dictionary that will be copied into the metadata of any .png files saved. Custom nodes can store additional information in this dictionary for saving (or as a way to communicate with a downstream node)."""
self.dynprompt=dynprompt
"""DYNPROMPT is an instance of comfy_execution.graph.DynamicPrompt. It differs from PROMPT in that it may mutate during the course of execution in response to Node Expansion."""
self.auth_token_comfy_org=auth_token_comfy_org
"""AUTH_TOKEN_COMFY_ORG is a token acquired from signing into a ComfyOrg account on frontend."""
self.api_key_comfy_org=api_key_comfy_org
"""API_KEY_COMFY_ORG is an API Key generated by ComfyOrg that allows skipping signing into a ComfyOrg account on frontend."""
Enumerator for requesting hidden variables in nodes.
'''
unique_id="UNIQUE_ID"
"""UNIQUE_ID is the unique identifier of the node, and matches the id property of the node on the client side. It is commonly used in client-server communications (see messages)."""
prompt="PROMPT"
"""PROMPT is the complete prompt sent by the client to the server. See the prompt object for a full description."""
extra_pnginfo="EXTRA_PNGINFO"
"""EXTRA_PNGINFO is a dictionary that will be copied into the metadata of any .png files saved. Custom nodes can store additional information in this dictionary for saving (or as a way to communicate with a downstream node)."""
dynprompt="DYNPROMPT"
"""DYNPROMPT is an instance of comfy_execution.graph.DynamicPrompt. It differs from PROMPT in that it may mutate during the course of execution in response to Node Expansion."""
auth_token_comfy_org="AUTH_TOKEN_COMFY_ORG"
"""AUTH_TOKEN_COMFY_ORG is a token acquired from signing into a ComfyOrg account on frontend."""
api_key_comfy_org="API_KEY_COMFY_ORG"
"""API_KEY_COMFY_ORG is an API Key generated by ComfyOrg that allows skipping signing into a ComfyOrg account on frontend."""
@dataclass
classNodeInfoV1:
input:dict=None
input_order:dict[str,list[str]]=None
output:list[str]=None
output_is_list:list[bool]=None
output_name:list[str]=None
output_tooltips:list[str]=None
name:str=None
display_name:str=None
description:str=None
python_module:Any=None
category:str=None
output_node:bool=None
deprecated:bool=None
experimental:bool=None
api_node:bool=None
@dataclass
classNodeInfoV3:
input:dict=None
output:dict=None
hidden:list[str]=None
name:str=None
display_name:str=None
description:str=None
category:str=None
output_node:bool=None
deprecated:bool=None
experimental:bool=None
api_node:bool=None
@dataclass
classSchema:
"""Definition of V3 node properties."""
node_id:str
"""ID of node - should be globally unique. If this is a custom node, add a prefix or postfix to avoid name clashes."""
display_name:str=None
"""Display name of node."""
category:str="sd"
"""The category of the node, as per the "Add Node" menu."""
inputs:list[Input]=None
outputs:list[Output]=None
hidden:list[Hidden]=None
description:str=""
"""Node description, shown as a tooltip when hovering over the node."""
is_input_list:bool=False
"""A flag indicating if this node implements the additional code necessary to deal with OUTPUT_IS_LIST nodes.
All inputs of ``type`` will become ``list[type]``, regardless of how many items are passed in. This also affects ``check_lazy_status``.
From the docs:
A node can also override the default input behaviour and receive the whole list in a single call. This is done by setting a class attribute `INPUT_IS_LIST` to ``True``.
"""Flags a node as deprecated, indicating to users that they should find alternatives to this node."""
is_experimental:bool=False
"""Flags a node as experimental, informing users that it may change or not work as expected."""
is_api_node:bool=False
"""Flags a node as an API node. See: https://docs.comfy.org/tutorials/api-nodes/overview."""
not_idempotent:bool=False
"""Flags a node as not idempotent; when True, the node will run and not reuse the cached outputs when identical inputs are provided on a different node in the graph."""
enable_expand:bool=False
"""Flags a node as expandable, allowing NodeOutput to include 'expand' property."""
defvalidate(self):
'''Validate the schema:
- verify ids on inputs and outputs are unique - both internally and in relation to each other
raiseException(f"Node {cls.__name__} is not expandable, but expand included in NodeOutput; developer should set enable_expand=True on node's Schema to allow this.")
raiseException(f"Node {cls.__name__} is not expandable, but expand included in NodeOutput; developer should set enable_expand=True on node's Schema to allow this.")