2025-09-27 00:14:42 +03:00
from typing_extensions import override
2023-04-04 13:56:13 -04:00
import numpy as np
import torch
import torch . nn . functional as F
from PIL import Image
2023-08-17 20:06:14 -04:00
import math
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
from enum import Enum
from typing import TypedDict , Literal
2026-04-19 06:02:01 +03:00
import kornia
2023-04-04 13:56:13 -04:00
import comfy . utils
2024-04-19 03:52:02 -04:00
import comfy . model_management
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
from comfy_extras . nodes_latent import reshape_latent_to
2025-04-02 19:32:34 -04:00
import node_helpers
2025-09-27 00:14:42 +03:00
from comfy_api . latest import ComfyExtension , io
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
from nodes import MAX_RESOLUTION
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
class Blend ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
return io . Schema (
node_id = " ImageBlend " ,
2026-05-05 08:37:25 +08:00
search_aliases = [ " mix images " ] ,
display_name = " Blend Images " ,
2026-05-19 12:13:48 +08:00
category = " image/filters " ,
2026-03-15 16:18:04 -07:00
essentials_category = " Image Tools " ,
2025-09-27 00:14:42 +03:00
inputs = [
io . Image . Input ( " image1 " ) ,
io . Image . Input ( " image2 " ) ,
io . Float . Input ( " blend_factor " , default = 0.5 , min = 0.0 , max = 1.0 , step = 0.01 ) ,
io . Combo . Input ( " blend_mode " , options = [ " normal " , " multiply " , " screen " , " overlay " , " soft_light " , " difference " ] ) ,
] ,
outputs = [
io . Image . Output ( ) ,
] ,
)
2023-04-04 13:56:13 -04:00
@classmethod
2025-09-27 00:14:42 +03:00
def execute ( cls , image1 : torch . Tensor , image2 : torch . Tensor , blend_factor : float , blend_mode : str ) - > io . NodeOutput :
2025-04-02 19:32:34 -04:00
image1 , image2 = node_helpers . image_alpha_fix ( image1 , image2 )
2024-01-27 02:51:27 -05:00
image2 = image2 . to ( image1 . device )
2023-04-04 13:56:13 -04:00
if image1 . shape != image2 . shape :
image2 = image2 . permute ( 0 , 3 , 1 , 2 )
image2 = comfy . utils . common_upscale ( image2 , image1 . shape [ 2 ] , image1 . shape [ 1 ] , upscale_method = ' bicubic ' , crop = ' center ' )
image2 = image2 . permute ( 0 , 2 , 3 , 1 )
2025-09-27 00:14:42 +03:00
blended_image = cls . blend_mode ( image1 , image2 , blend_mode )
2023-04-04 13:56:13 -04:00
blended_image = image1 * ( 1 - blend_factor ) + blended_image * blend_factor
blended_image = torch . clamp ( blended_image , 0 , 1 )
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( blended_image )
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
@classmethod
def blend_mode ( cls , img1 , img2 , mode ) :
2023-04-04 13:56:13 -04:00
if mode == " normal " :
return img2
elif mode == " multiply " :
return img1 * img2
elif mode == " screen " :
return 1 - ( 1 - img1 ) * ( 1 - img2 )
elif mode == " overlay " :
return torch . where ( img1 < = 0.5 , 2 * img1 * img2 , 1 - 2 * ( 1 - img1 ) * ( 1 - img2 ) )
elif mode == " soft_light " :
2025-09-27 00:14:42 +03:00
return torch . where ( img2 < = 0.5 , img1 - ( 1 - 2 * img2 ) * img1 * ( 1 - img1 ) , img1 + ( 2 * img2 - 1 ) * ( cls . g ( img1 ) - img1 ) )
2023-11-05 19:00:23 +01:00
elif mode == " difference " :
return img1 - img2
2025-09-27 00:14:42 +03:00
raise ValueError ( f " Unsupported blend mode: { mode } " )
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
@classmethod
def g ( cls , x ) :
2023-04-04 13:56:13 -04:00
return torch . where ( x < = 0.25 , ( ( 16 * x - 12 ) * x + 4 ) * x , torch . sqrt ( x ) )
2026-03-26 19:18:16 -07:00
def gaussian_kernel ( kernel_size : int , sigma : float , device = None , dtype = torch . float32 ) :
2023-08-14 21:08:45 -04:00
x , y = torch . meshgrid ( torch . linspace ( - 1 , 1 , kernel_size , device = device ) , torch . linspace ( - 1 , 1 , kernel_size , device = device ) , indexing = " ij " )
2023-05-20 15:23:28 +02:00
d = torch . sqrt ( x * x + y * y )
g = torch . exp ( - ( d * d ) / ( 2.0 * sigma * sigma ) )
2026-03-26 19:18:16 -07:00
return ( g / g . sum ( ) ) . to ( dtype )
2023-05-20 15:23:28 +02:00
2025-09-27 00:14:42 +03:00
class Blur ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
return io . Schema (
node_id = " ImageBlur " ,
2026-05-19 12:13:48 +08:00
display_name = " Blur Image " ,
category = " image/filters " ,
2025-09-27 00:14:42 +03:00
inputs = [
io . Image . Input ( " image " ) ,
io . Int . Input ( " blur_radius " , default = 1 , min = 1 , max = 31 , step = 1 ) ,
io . Float . Input ( " sigma " , default = 1.0 , min = 0.1 , max = 10.0 , step = 0.1 ) ,
] ,
outputs = [
io . Image . Output ( ) ,
] ,
)
2023-04-04 13:56:13 -04:00
@classmethod
2025-09-27 00:14:42 +03:00
def execute ( cls , image : torch . Tensor , blur_radius : int , sigma : float ) - > io . NodeOutput :
2023-04-04 13:56:13 -04:00
if blur_radius == 0 :
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( image )
2023-04-04 13:56:13 -04:00
2024-04-19 03:52:02 -04:00
image = image . to ( comfy . model_management . get_torch_device ( ) )
2023-04-04 13:56:13 -04:00
batch_size , height , width , channels = image . shape
kernel_size = blur_radius * 2 + 1
2026-03-26 19:18:16 -07:00
kernel = gaussian_kernel ( kernel_size , sigma , device = image . device , dtype = image . dtype ) . repeat ( channels , 1 , 1 ) . unsqueeze ( 1 )
2023-04-04 13:56:13 -04:00
image = image . permute ( 0 , 3 , 1 , 2 ) # Torch wants (B, C, H, W) we use (B, H, W, C)
2023-05-20 15:23:28 +02:00
padded_image = F . pad ( image , ( blur_radius , blur_radius , blur_radius , blur_radius ) , ' reflect ' )
2023-05-20 10:08:47 -04:00
blurred = F . conv2d ( padded_image , kernel , padding = kernel_size / / 2 , groups = channels ) [ : , : , blur_radius : - blur_radius , blur_radius : - blur_radius ]
2023-04-04 13:56:13 -04:00
blurred = blurred . permute ( 0 , 2 , 3 , 1 )
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( blurred . to ( comfy . model_management . intermediate_device ( ) ) )
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
class Quantize ( io . ComfyNode ) :
2023-04-04 13:56:13 -04:00
@classmethod
2025-09-27 00:14:42 +03:00
def define_schema ( cls ) :
return io . Schema (
node_id = " ImageQuantize " ,
2026-05-08 13:02:55 +08:00
display_name = " Quantize Image " ,
2026-05-19 12:13:48 +08:00
category = " image/filters " ,
2025-09-27 00:14:42 +03:00
inputs = [
io . Image . Input ( " image " ) ,
io . Int . Input ( " colors " , default = 256 , min = 1 , max = 256 , step = 1 ) ,
io . Combo . Input ( " dither " , options = [ " none " , " floyd-steinberg " , " bayer-2 " , " bayer-4 " , " bayer-8 " , " bayer-16 " ] ) ,
] ,
outputs = [
io . Image . Output ( ) ,
] ,
)
2023-04-04 13:56:13 -04:00
2025-05-01 19:32:04 -04:00
@staticmethod
2023-10-31 20:54:33 +01:00
def bayer ( im , pal_im , order ) :
def normalized_bayer_matrix ( n ) :
if n == 0 :
return np . zeros ( ( 1 , 1 ) , " float32 " )
else :
q = 4 * * n
m = q * normalized_bayer_matrix ( n - 1 )
return np . bmat ( ( ( m - 1.5 , m + 0.5 ) , ( m + 1.5 , m - 0.5 ) ) ) / q
num_colors = len ( pal_im . getpalette ( ) ) / / 3
spread = 2 * 256 / num_colors
bayer_n = int ( math . log2 ( order ) )
bayer_matrix = torch . from_numpy ( spread * normalized_bayer_matrix ( bayer_n ) + 0.5 )
result = torch . from_numpy ( np . array ( im ) . astype ( np . float32 ) )
tw = math . ceil ( result . shape [ 0 ] / bayer_matrix . shape [ 0 ] )
th = math . ceil ( result . shape [ 1 ] / bayer_matrix . shape [ 1 ] )
tiled_matrix = bayer_matrix . tile ( tw , th ) . unsqueeze ( - 1 )
result . add_ ( tiled_matrix [ : result . shape [ 0 ] , : result . shape [ 1 ] ] ) . clamp_ ( 0 , 255 )
result = result . to ( dtype = torch . uint8 )
im = Image . fromarray ( result . cpu ( ) . numpy ( ) )
im = im . quantize ( palette = pal_im , dither = Image . Dither . NONE )
return im
2025-09-27 00:14:42 +03:00
@classmethod
def execute ( cls , image : torch . Tensor , colors : int , dither : str ) - > io . NodeOutput :
2023-04-04 13:56:13 -04:00
batch_size , height , width , _ = image . shape
result = torch . zeros_like ( image )
for b in range ( batch_size ) :
2023-10-31 20:54:33 +01:00
im = Image . fromarray ( ( image [ b ] * 255 ) . to ( torch . uint8 ) . numpy ( ) , mode = ' RGB ' )
pal_im = im . quantize ( colors = colors ) # Required as described in https://github.com/python-pillow/Pillow/issues/5836
2023-04-04 13:56:13 -04:00
2023-10-31 20:54:33 +01:00
if dither == " none " :
quantized_image = im . quantize ( palette = pal_im , dither = Image . Dither . NONE )
elif dither == " floyd-steinberg " :
quantized_image = im . quantize ( palette = pal_im , dither = Image . Dither . FLOYDSTEINBERG )
elif dither . startswith ( " bayer " ) :
order = int ( dither . split ( ' - ' ) [ - 1 ] )
quantized_image = Quantize . bayer ( im , pal_im , order )
2023-04-04 13:56:13 -04:00
quantized_array = torch . tensor ( np . array ( quantized_image . convert ( " RGB " ) ) ) . float ( ) / 255
result [ b ] = quantized_array
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( result )
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
class Sharpen ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
return io . Schema (
node_id = " ImageSharpen " ,
2026-05-08 13:02:55 +08:00
display_name = " Sharpen Image " ,
2026-05-19 12:13:48 +08:00
category = " image/filters " ,
2025-09-27 00:14:42 +03:00
inputs = [
io . Image . Input ( " image " ) ,
feat: mark 429 widgets as advanced for collapsible UI (#12197)
* feat: mark 429 widgets as advanced for collapsible UI
Mark widgets as advanced across core, comfy_extras, and comfy_api_nodes
to support the new collapsible advanced inputs section in the frontend.
Changes:
- 267 advanced markers in comfy_extras/
- 162 advanced markers in comfy_api_nodes/
- All files pass python3 -m py_compile verification
Widgets marked advanced (hidden by default):
- Scheduler internals: sigma_max, sigma_min, rho, mu, beta, alpha
- Sampler internals: eta, s_noise, order, rtol, atol, h_init, pcoeff, etc.
- Memory optimization: tile_size, overlap, temporal_size, temporal_overlap
- Pipeline controls: add_noise, start_at_step, end_at_step
- Timing controls: start_percent, end_percent
- Layer selection: stop_at_clip_layer, layers, block_number
- Video encoding: codec, crf, format
- Device/dtype: device, noise_device, dtype, weight_dtype
Widgets kept basic (always visible):
- Core params: strength, steps, cfg, denoise, seed, width, height
- Model selectors: ckpt_name, lora_name, vae_name, sampler_name
- Common controls: upscale_method, crop, batch_size, fps, opacity
Related: frontend PR #11939
Amp-Thread-ID: https://ampcode.com/threads/T-019c1734-6b61-702e-b333-f02c399963fc
* fix: remove advanced=True from DynamicCombo.Input (unsupported)
Amp-Thread-ID: https://ampcode.com/threads/T-019c1734-6b61-702e-b333-f02c399963fc
* fix: address review - un-mark model merge, video, image, and training node widgets as advanced
Per comfyanonymous review:
- Model merge arguments should not be advanced (all 14 model-specific merge classes)
- SaveAnimatedWEBP lossless/quality/method should not be advanced
- SaveWEBM/SaveVideo codec/crf/format should not be advanced
- TrainLoraNode options should not be advanced (7 inputs)
Amp-Thread-ID: https://ampcode.com/threads/T-019c322b-a3a8-71b7-9962-d44573ca6352
* fix: un-mark batch_size and webcam width/height as advanced (should stay basic)
Amp-Thread-ID: https://ampcode.com/threads/T-019c3236-1417-74aa-82a3-bcb365fbe9d1
---------
Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com>
2026-02-19 19:20:02 -08:00
io . Int . Input ( " sharpen_radius " , default = 1 , min = 1 , max = 31 , step = 1 , advanced = True ) ,
io . Float . Input ( " sigma " , default = 1.0 , min = 0.1 , max = 10.0 , step = 0.01 , advanced = True ) ,
io . Float . Input ( " alpha " , default = 1.0 , min = 0.0 , max = 5.0 , step = 0.01 , advanced = True ) ,
2025-09-27 00:14:42 +03:00
] ,
outputs = [
io . Image . Output ( ) ,
] ,
)
2023-04-04 13:56:13 -04:00
@classmethod
2025-09-27 00:14:42 +03:00
def execute ( cls , image : torch . Tensor , sharpen_radius : int , sigma : float , alpha : float ) - > io . NodeOutput :
2023-04-04 13:56:13 -04:00
if sharpen_radius == 0 :
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( image )
2023-04-04 13:56:13 -04:00
batch_size , height , width , channels = image . shape
2024-04-21 09:02:06 -04:00
image = image . to ( comfy . model_management . get_torch_device ( ) )
2023-04-04 13:56:13 -04:00
kernel_size = sharpen_radius * 2 + 1
2026-03-26 19:18:16 -07:00
kernel = gaussian_kernel ( kernel_size , sigma , device = image . device , dtype = image . dtype ) * - ( alpha * 10 )
2025-09-18 19:51:16 -04:00
kernel = kernel . to ( dtype = image . dtype )
2023-04-04 13:56:13 -04:00
center = kernel_size / / 2
2023-05-20 15:23:28 +02:00
kernel [ center , center ] = kernel [ center , center ] - kernel . sum ( ) + 1.0
2023-04-04 13:56:13 -04:00
kernel = kernel . repeat ( channels , 1 , 1 ) . unsqueeze ( 1 )
tensor_image = image . permute ( 0 , 3 , 1 , 2 ) # Torch wants (B, C, H, W) we use (B, H, W, C)
2023-05-20 15:23:28 +02:00
tensor_image = F . pad ( tensor_image , ( sharpen_radius , sharpen_radius , sharpen_radius , sharpen_radius ) , ' reflect ' )
sharpened = F . conv2d ( tensor_image , kernel , padding = center , groups = channels ) [ : , : , sharpen_radius : - sharpen_radius , sharpen_radius : - sharpen_radius ]
2023-04-04 13:56:13 -04:00
sharpened = sharpened . permute ( 0 , 2 , 3 , 1 )
result = torch . clamp ( sharpened , 0 , 1 )
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( result . to ( comfy . model_management . intermediate_device ( ) ) )
2023-04-04 13:56:13 -04:00
2025-09-27 00:14:42 +03:00
class ImageScaleToTotalPixels ( io . ComfyNode ) :
2023-09-19 10:40:38 +02:00
upscale_methods = [ " nearest-exact " , " bilinear " , " area " , " bicubic " , " lanczos " ]
2023-08-17 20:06:14 -04:00
crop_methods = [ " disabled " , " center " ]
@classmethod
2025-09-27 00:14:42 +03:00
def define_schema ( cls ) :
return io . Schema (
node_id = " ImageScaleToTotalPixels " ,
2026-05-05 08:37:25 +08:00
display_name = " Scale Image to Total Pixels " ,
2025-09-27 00:14:42 +03:00
category = " image/upscaling " ,
inputs = [
io . Image . Input ( " image " ) ,
io . Combo . Input ( " upscale_method " , options = cls . upscale_methods ) ,
io . Float . Input ( " megapixels " , default = 1.0 , min = 0.01 , max = 16.0 , step = 0.01 ) ,
feat: mark 429 widgets as advanced for collapsible UI (#12197)
* feat: mark 429 widgets as advanced for collapsible UI
Mark widgets as advanced across core, comfy_extras, and comfy_api_nodes
to support the new collapsible advanced inputs section in the frontend.
Changes:
- 267 advanced markers in comfy_extras/
- 162 advanced markers in comfy_api_nodes/
- All files pass python3 -m py_compile verification
Widgets marked advanced (hidden by default):
- Scheduler internals: sigma_max, sigma_min, rho, mu, beta, alpha
- Sampler internals: eta, s_noise, order, rtol, atol, h_init, pcoeff, etc.
- Memory optimization: tile_size, overlap, temporal_size, temporal_overlap
- Pipeline controls: add_noise, start_at_step, end_at_step
- Timing controls: start_percent, end_percent
- Layer selection: stop_at_clip_layer, layers, block_number
- Video encoding: codec, crf, format
- Device/dtype: device, noise_device, dtype, weight_dtype
Widgets kept basic (always visible):
- Core params: strength, steps, cfg, denoise, seed, width, height
- Model selectors: ckpt_name, lora_name, vae_name, sampler_name
- Common controls: upscale_method, crop, batch_size, fps, opacity
Related: frontend PR #11939
Amp-Thread-ID: https://ampcode.com/threads/T-019c1734-6b61-702e-b333-f02c399963fc
* fix: remove advanced=True from DynamicCombo.Input (unsupported)
Amp-Thread-ID: https://ampcode.com/threads/T-019c1734-6b61-702e-b333-f02c399963fc
* fix: address review - un-mark model merge, video, image, and training node widgets as advanced
Per comfyanonymous review:
- Model merge arguments should not be advanced (all 14 model-specific merge classes)
- SaveAnimatedWEBP lossless/quality/method should not be advanced
- SaveWEBM/SaveVideo codec/crf/format should not be advanced
- TrainLoraNode options should not be advanced (7 inputs)
Amp-Thread-ID: https://ampcode.com/threads/T-019c322b-a3a8-71b7-9962-d44573ca6352
* fix: un-mark batch_size and webcam width/height as advanced (should stay basic)
Amp-Thread-ID: https://ampcode.com/threads/T-019c3236-1417-74aa-82a3-bcb365fbe9d1
---------
Co-authored-by: Jedrzej Kosinski <kosinkadink1@gmail.com>
2026-02-19 19:20:02 -08:00
io . Int . Input ( " resolution_steps " , default = 1 , min = 1 , max = 256 , advanced = True ) ,
2025-09-27 00:14:42 +03:00
] ,
outputs = [
io . Image . Output ( ) ,
] ,
)
2023-08-17 20:06:14 -04:00
2025-09-27 00:14:42 +03:00
@classmethod
2025-12-18 11:15:27 +08:00
def execute ( cls , image , upscale_method , megapixels , resolution_steps ) - > io . NodeOutput :
2023-08-17 20:06:14 -04:00
samples = image . movedim ( - 1 , 1 )
2025-12-18 11:15:27 +08:00
total = megapixels * 1024 * 1024
2023-08-17 20:06:14 -04:00
scale_by = math . sqrt ( total / ( samples . shape [ 3 ] * samples . shape [ 2 ] ) )
2025-12-18 11:15:27 +08:00
width = round ( samples . shape [ 3 ] * scale_by / resolution_steps ) * resolution_steps
height = round ( samples . shape [ 2 ] * scale_by / resolution_steps ) * resolution_steps
2023-08-17 20:06:14 -04:00
2025-12-18 11:15:27 +08:00
s = comfy . utils . common_upscale ( samples , int ( width ) , int ( height ) , upscale_method , " disabled " )
2023-08-17 20:06:14 -04:00
s = s . movedim ( 1 , - 1 )
2025-09-27 00:14:42 +03:00
return io . NodeOutput ( s )
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
class ResizeType ( str , Enum ) :
SCALE_BY = " scale by multiplier "
SCALE_DIMENSIONS = " scale dimensions "
SCALE_LONGER_DIMENSION = " scale longer dimension "
SCALE_SHORTER_DIMENSION = " scale shorter dimension "
SCALE_WIDTH = " scale width "
SCALE_HEIGHT = " scale height "
SCALE_TOTAL_PIXELS = " scale total pixels "
MATCH_SIZE = " match size "
2026-01-14 09:48:10 +09:00
SCALE_TO_MULTIPLE = " scale to multiple "
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
def is_image ( input : torch . Tensor ) - > bool :
# images have 4 dimensions: [batch, height, width, channels]
# masks have 3 dimensions: [batch, height, width]
return len ( input . shape ) == 4
def init_image_mask_input ( input : torch . Tensor , is_type_image : bool ) - > torch . Tensor :
if is_type_image :
input = input . movedim ( - 1 , 1 )
else :
input = input . unsqueeze ( 1 )
return input
def finalize_image_mask_input ( input : torch . Tensor , is_type_image : bool ) - > torch . Tensor :
if is_type_image :
input = input . movedim ( 1 , - 1 )
else :
input = input . squeeze ( 1 )
return input
def scale_by ( input : torch . Tensor , multiplier : float , scale_method : str ) - > torch . Tensor :
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
width = round ( input . shape [ - 1 ] * multiplier )
height = round ( input . shape [ - 2 ] * multiplier )
input = comfy . utils . common_upscale ( input , width , height , scale_method , " disabled " )
input = finalize_image_mask_input ( input , is_type_image )
return input
def scale_dimensions ( input : torch . Tensor , width : int , height : int , scale_method : str , crop : str = " disabled " ) - > torch . Tensor :
if width == 0 and height == 0 :
return input
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
if width == 0 :
width = max ( 1 , round ( input . shape [ - 1 ] * height / input . shape [ - 2 ] ) )
elif height == 0 :
height = max ( 1 , round ( input . shape [ - 2 ] * width / input . shape [ - 1 ] ) )
input = comfy . utils . common_upscale ( input , width , height , scale_method , crop )
input = finalize_image_mask_input ( input , is_type_image )
return input
def scale_longer_dimension ( input : torch . Tensor , longer_size : int , scale_method : str ) - > torch . Tensor :
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
width = input . shape [ - 1 ]
height = input . shape [ - 2 ]
if height > width :
width = round ( ( width / height ) * longer_size )
height = longer_size
elif width > height :
height = round ( ( height / width ) * longer_size )
width = longer_size
else :
height = longer_size
width = longer_size
input = comfy . utils . common_upscale ( input , width , height , scale_method , " disabled " )
input = finalize_image_mask_input ( input , is_type_image )
return input
def scale_shorter_dimension ( input : torch . Tensor , shorter_size : int , scale_method : str ) - > torch . Tensor :
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
width = input . shape [ - 1 ]
height = input . shape [ - 2 ]
if height < width :
width = round ( ( width / height ) * shorter_size )
height = shorter_size
2026-01-14 11:25:09 +09:00
elif width < height :
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
height = round ( ( height / width ) * shorter_size )
width = shorter_size
else :
height = shorter_size
width = shorter_size
input = comfy . utils . common_upscale ( input , width , height , scale_method , " disabled " )
input = finalize_image_mask_input ( input , is_type_image )
return input
def scale_total_pixels ( input : torch . Tensor , megapixels : float , scale_method : str ) - > torch . Tensor :
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
total = int ( megapixels * 1024 * 1024 )
scale_by = math . sqrt ( total / ( input . shape [ - 1 ] * input . shape [ - 2 ] ) )
width = round ( input . shape [ - 1 ] * scale_by )
height = round ( input . shape [ - 2 ] * scale_by )
input = comfy . utils . common_upscale ( input , width , height , scale_method , " disabled " )
input = finalize_image_mask_input ( input , is_type_image )
return input
def scale_match_size ( input : torch . Tensor , match : torch . Tensor , scale_method : str , crop : str ) - > torch . Tensor :
is_type_image = is_image ( input )
input = init_image_mask_input ( input , is_type_image )
match = init_image_mask_input ( match , is_image ( match ) )
width = match . shape [ - 1 ]
height = match . shape [ - 2 ]
input = comfy . utils . common_upscale ( input , width , height , scale_method , crop )
input = finalize_image_mask_input ( input , is_type_image )
return input
2026-01-14 09:48:10 +09:00
def scale_to_multiple_cover ( input : torch . Tensor , multiple : int , scale_method : str ) - > torch . Tensor :
if multiple < = 1 :
return input
is_type_image = is_image ( input )
if is_type_image :
_ , height , width , _ = input . shape
else :
_ , height , width = input . shape
target_w = ( width / / multiple ) * multiple
target_h = ( height / / multiple ) * multiple
if target_w == 0 or target_h == 0 :
return input
if target_w == width and target_h == height :
return input
s_w = target_w / width
s_h = target_h / height
if s_w > = s_h :
scaled_w = target_w
scaled_h = int ( math . ceil ( height * s_w ) )
if scaled_h < target_h :
scaled_h = target_h
else :
scaled_h = target_h
scaled_w = int ( math . ceil ( width * s_h ) )
if scaled_w < target_w :
scaled_w = target_w
input = init_image_mask_input ( input , is_type_image )
input = comfy . utils . common_upscale ( input , scaled_w , scaled_h , scale_method , " disabled " )
input = finalize_image_mask_input ( input , is_type_image )
x0 = ( scaled_w - target_w ) / / 2
y0 = ( scaled_h - target_h ) / / 2
x1 = x0 + target_w
y1 = y0 + target_h
if is_type_image :
return input [ : , y0 : y1 , x0 : x1 , : ]
return input [ : , y0 : y1 , x0 : x1 ]
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
class ResizeImageMaskNode ( io . ComfyNode ) :
scale_methods = [ " nearest-exact " , " bilinear " , " area " , " bicubic " , " lanczos " ]
crop_methods = [ " disabled " , " center " ]
class ResizeTypedDict ( TypedDict ) :
resize_type : ResizeType
scale_method : Literal [ " nearest-exact " , " bilinear " , " area " , " bicubic " , " lanczos " ]
crop : Literal [ " disabled " , " center " ]
multiplier : float
width : int
height : int
longer_size : int
shorter_size : int
megapixels : float
2026-01-14 09:48:10 +09:00
multiple : int
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
@classmethod
def define_schema ( cls ) :
template = io . MatchType . Template ( " input_type " , [ io . Image , io . Mask ] )
2026-01-22 22:04:27 -08:00
crop_combo = io . Combo . Input (
" crop " ,
options = cls . crop_methods ,
default = " center " ,
tooltip = " How to handle aspect ratio mismatch: ' disabled ' stretches to fit, ' center ' crops to maintain aspect ratio. " ,
)
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
return io . Schema (
node_id = " ResizeImageMaskNode " ,
display_name = " Resize Image/Mask " ,
2026-01-22 22:04:27 -08:00
description = " Resize an image or mask using various scaling methods. " ,
2026-05-08 13:02:55 +08:00
category = " image/transform " ,
2026-01-22 22:04:27 -08:00
search_aliases = [ " resize " , " resize image " , " resize mask " , " scale " , " scale image " , " scale mask " , " image resize " , " change size " , " dimensions " , " shrink " , " enlarge " ] ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
inputs = [
io . MatchType . Input ( " input " , template = template ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Input (
" resize_type " ,
tooltip = " Select how to resize: by exact dimensions, scale factor, matching another image, etc. " ,
options = [
io . DynamicCombo . Option ( ResizeType . SCALE_DIMENSIONS , [
io . Int . Input ( " width " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " Target width in pixels. Set to 0 to auto-calculate from height while preserving aspect ratio. " ) ,
io . Int . Input ( " height " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " Target height in pixels. Set to 0 to auto-calculate from width while preserving aspect ratio. " ) ,
crop_combo ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_BY , [
io . Float . Input ( " multiplier " , default = 1.00 , min = 0.01 , max = 8.0 , step = 0.01 , tooltip = " Scale factor (e.g., 2.0 doubles size, 0.5 halves size). " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_LONGER_DIMENSION , [
io . Int . Input ( " longer_size " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " The longer edge will be resized to this value. Aspect ratio is preserved. " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_SHORTER_DIMENSION , [
io . Int . Input ( " shorter_size " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " The shorter edge will be resized to this value. Aspect ratio is preserved. " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_WIDTH , [
io . Int . Input ( " width " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " Target width in pixels. Height auto-adjusts to preserve aspect ratio. " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_HEIGHT , [
io . Int . Input ( " height " , default = 512 , min = 0 , max = MAX_RESOLUTION , step = 1 , tooltip = " Target height in pixels. Width auto-adjusts to preserve aspect ratio. " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_TOTAL_PIXELS , [
io . Float . Input ( " megapixels " , default = 1.0 , min = 0.01 , max = 16.0 , step = 0.01 , tooltip = " Target total megapixels (e.g., 1.0 ≈ 1024× 1024). Aspect ratio is preserved. " ) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . MATCH_SIZE , [
io . MultiType . Input ( " match " , [ io . Image , io . Mask ] , tooltip = " Resize input to match the dimensions of this reference image or mask. " ) ,
crop_combo ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ) ,
2026-01-22 22:04:27 -08:00
io . DynamicCombo . Option ( ResizeType . SCALE_TO_MULTIPLE , [
io . Int . Input ( " multiple " , default = 8 , min = 1 , max = MAX_RESOLUTION , step = 1 , tooltip = " Resize so width and height are divisible by this number. Useful for latent alignment (e.g., 8 or 64). " ) ,
2026-01-14 09:48:10 +09:00
] ) ,
2026-01-22 22:04:27 -08:00
] ,
) ,
io . Combo . Input (
" scale_method " ,
options = cls . scale_methods ,
default = " area " ,
tooltip = " Interpolation algorithm. ' area ' is best for downscaling, ' lanczos ' for upscaling, ' nearest-exact ' for pixel art. " ,
) ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
] ,
outputs = [ io . MatchType . Output ( template = template , display_name = " resized " ) ]
)
@classmethod
def execute ( cls , input : io . Image . Type | io . Mask . Type , scale_method : io . Combo . Type , resize_type : ResizeTypedDict ) - > io . NodeOutput :
selected_type = resize_type [ " resize_type " ]
if selected_type == ResizeType . SCALE_BY :
return io . NodeOutput ( scale_by ( input , resize_type [ " multiplier " ] , scale_method ) )
elif selected_type == ResizeType . SCALE_DIMENSIONS :
return io . NodeOutput ( scale_dimensions ( input , resize_type [ " width " ] , resize_type [ " height " ] , scale_method , resize_type [ " crop " ] ) )
elif selected_type == ResizeType . SCALE_LONGER_DIMENSION :
return io . NodeOutput ( scale_longer_dimension ( input , resize_type [ " longer_size " ] , scale_method ) )
elif selected_type == ResizeType . SCALE_SHORTER_DIMENSION :
return io . NodeOutput ( scale_shorter_dimension ( input , resize_type [ " shorter_size " ] , scale_method ) )
elif selected_type == ResizeType . SCALE_WIDTH :
return io . NodeOutput ( scale_dimensions ( input , resize_type [ " width " ] , 0 , scale_method ) )
elif selected_type == ResizeType . SCALE_HEIGHT :
return io . NodeOutput ( scale_dimensions ( input , 0 , resize_type [ " height " ] , scale_method ) )
elif selected_type == ResizeType . SCALE_TOTAL_PIXELS :
return io . NodeOutput ( scale_total_pixels ( input , resize_type [ " megapixels " ] , scale_method ) )
elif selected_type == ResizeType . MATCH_SIZE :
return io . NodeOutput ( scale_match_size ( input , resize_type [ " match " ] , scale_method , resize_type [ " crop " ] ) )
2026-01-14 09:48:10 +09:00
elif selected_type == ResizeType . SCALE_TO_MULTIPLE :
return io . NodeOutput ( scale_to_multiple_cover ( input , resize_type [ " multiple " ] , scale_method ) )
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
raise ValueError ( f " Unsupported resize type: { selected_type } " )
def batch_images ( images : list [ torch . Tensor ] ) - > torch . Tensor | None :
if len ( images ) == 0 :
return None
# first, get the max channels count
max_channels = max ( image . shape [ - 1 ] for image in images )
# then, pad all images to have the same channels count
padded_images : list [ torch . Tensor ] = [ ]
for image in images :
if image . shape [ - 1 ] < max_channels :
padded_images . append ( torch . nn . functional . pad ( image , ( 0 , 1 ) , mode = ' constant ' , value = 1.0 ) )
else :
padded_images . append ( image )
# resize all images to be the same size as the first image
resized_images : list [ torch . Tensor ] = [ ]
first_image_shape = padded_images [ 0 ] . shape
for image in padded_images :
if image . shape [ 1 : ] != first_image_shape [ 1 : ] :
resized_images . append ( comfy . utils . common_upscale ( image . movedim ( - 1 , 1 ) , first_image_shape [ 2 ] , first_image_shape [ 1 ] , " bilinear " , " center " ) . movedim ( 1 , - 1 ) )
else :
resized_images . append ( image )
# batch the images in the format [b, h, w, c]
return torch . cat ( resized_images , dim = 0 )
def batch_masks ( masks : list [ torch . Tensor ] ) - > torch . Tensor | None :
if len ( masks ) == 0 :
return None
# resize all masks to be the same size as the first mask
resized_masks : list [ torch . Tensor ] = [ ]
first_mask_shape = masks [ 0 ] . shape
for mask in masks :
if mask . shape [ 1 : ] != first_mask_shape [ 1 : ] :
mask = init_image_mask_input ( mask , is_type_image = False )
mask = comfy . utils . common_upscale ( mask , first_mask_shape [ 2 ] , first_mask_shape [ 1 ] , " bilinear " , " center " )
resized_masks . append ( finalize_image_mask_input ( mask , is_type_image = False ) )
else :
resized_masks . append ( mask )
# batch the masks in the format [b, h, w]
return torch . cat ( resized_masks , dim = 0 )
def batch_latents ( latents : list [ dict [ str , torch . Tensor ] ] ) - > dict [ str , torch . Tensor ] | None :
if len ( latents ) == 0 :
return None
samples_out = latents [ 0 ] . copy ( )
samples_out [ " batch_index " ] = [ ]
first_samples = latents [ 0 ] [ " samples " ]
tensors : list [ torch . Tensor ] = [ ]
for latent in latents :
# first, deal with latent tensors
tensors . append ( reshape_latent_to ( first_samples . shape , latent [ " samples " ] , repeat_batch = False ) )
# next, deal with batch_index
samples_out [ " batch_index " ] . extend ( latent . get ( " batch_index " , [ x for x in range ( 0 , latent [ " samples " ] . shape [ 0 ] ) ] ) )
samples_out [ " samples " ] = torch . cat ( tensors , dim = 0 )
return samples_out
class BatchImagesNode ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
2026-05-18 18:50:14 -07:00
autogrow_template = io . Autogrow . TemplatePrefix ( io . Image . Input ( " image " ) , prefix = " image " , min = 1 , max = 50 )
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
return io . Schema (
node_id = " BatchImagesNode " ,
display_name = " Batch Images " ,
2026-05-05 08:37:25 +08:00
category = " image/batch " ,
2026-02-26 01:00:32 -08:00
essentials_category = " Image Tools " ,
2026-01-21 15:36:02 -08:00
search_aliases = [ " batch " , " image batch " , " batch images " , " combine images " , " merge images " , " stack images " ] ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
inputs = [
io . Autogrow . Input ( " images " , template = autogrow_template )
] ,
outputs = [
io . Image . Output ( )
]
)
@classmethod
def execute ( cls , images : io . Autogrow . Type ) - > io . NodeOutput :
return io . NodeOutput ( batch_images ( list ( images . values ( ) ) ) )
class BatchMasksNode ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
2026-05-18 18:50:14 -07:00
autogrow_template = io . Autogrow . TemplatePrefix ( io . Mask . Input ( " mask " ) , prefix = " mask " , min = 1 , max = 50 )
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
return io . Schema (
node_id = " BatchMasksNode " ,
add search aliases to all nodes (#12035)
* feat: Add search_aliases field to node schema
Adds `search_aliases` field to improve node discoverability. Users can define alternative search terms for nodes (e.g., "text concat" → StringConcatenate).
Changes:
- Add `search_aliases: list[str]` to V3 Schema
- Add `SEARCH_ALIASES` support for V1 nodes
- Include field in `/object_info` response
- Add aliases to high-priority core nodes
V1 usage:
```python
class MyNode:
SEARCH_ALIASES = ["alt name", "synonym"]
```
V3 usage:
```python
io.Schema(
node_id="MyNode",
search_aliases=["alt name", "synonym"],
...
)
```
## Related PRs
- Frontend: Comfy-Org/ComfyUI_frontend#XXXX (draft - merge after this)
- Docs: Comfy-Org/docs#XXXX (draft - merge after stable)
* Propagate search_aliases through V3 Schema.get_v1_info to NodeInfoV1
* feat: add SEARCH_ALIASES for core nodes (#12016)
Add search aliases to 22 core nodes in nodes.py to improve node discoverability:
- Checkpoint/model loaders: CheckpointLoader, DiffusersLoader
- Conditioning nodes: ConditioningAverage, ConditioningSetArea, ConditioningSetMask, ConditioningZeroOut
- Style nodes: StyleModelApply
- Image nodes: LoadImageMask, LoadImageOutput, ImageBatch, ImageInvert, ImagePadForOutpaint
- Latent nodes: LoadLatent, SaveLatent, LatentBlend, LatentComposite, LatentCrop, LatentFlip, LatentFromBatch, LatentUpscale, LatentUpscaleBy, RepeatLatentBatch
* feat: add SEARCH_ALIASES for image, mask, and string nodes (#12017)
Add search aliases to nodes in comfy_extras for better discoverability:
- nodes_mask.py: mask manipulation nodes
- nodes_images.py: image processing nodes
- nodes_post_processing.py: post-processing effect nodes
- nodes_string.py: string manipulation nodes
- nodes_compositing.py: compositing nodes
- nodes_morphology.py: morphological operation nodes
- nodes_latent.py: latent space nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for audio and video nodes (#12018)
Add search aliases to audio and video nodes for better discoverability:
- nodes_audio.py: audio loading, saving, and processing nodes
- nodes_video.py: video loading and processing nodes
- nodes_wan.py: WAN model nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for model and misc nodes (#12019)
Add search aliases to model-related and miscellaneous nodes:
- Model nodes: nodes_model_merging.py, nodes_model_advanced.py, nodes_lora_extract.py
- Sampler nodes: nodes_custom_sampler.py, nodes_align_your_steps.py
- Control nodes: nodes_controlnet.py, nodes_attention_multiply.py, nodes_hooks.py
- Training nodes: nodes_train.py, nodes_dataset.py
- Utility nodes: nodes_logic.py, nodes_canny.py, nodes_differential_diffusion.py
- Architecture-specific: nodes_sd3.py, nodes_pixart.py, nodes_lumina2.py, nodes_kandinsky5.py, nodes_hidream.py, nodes_fresca.py, nodes_hunyuan3d.py
- Media nodes: nodes_load_3d.py, nodes_webcam.py, nodes_preview_any.py, nodes_wanmove.py
Uses search_aliases parameter in io.Schema() for v3 nodes, SEARCH_ALIASES class attribute for legacy nodes.
2026-01-22 18:36:58 -08:00
search_aliases = [ " combine masks " , " stack masks " , " merge masks " ] ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
display_name = " Batch Masks " ,
2026-05-19 12:13:48 +08:00
category = " image/mask " ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
inputs = [
io . Autogrow . Input ( " masks " , template = autogrow_template )
] ,
outputs = [
io . Mask . Output ( )
]
)
@classmethod
def execute ( cls , masks : io . Autogrow . Type ) - > io . NodeOutput :
return io . NodeOutput ( batch_masks ( list ( masks . values ( ) ) ) )
class BatchLatentsNode ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
2026-05-18 18:50:14 -07:00
autogrow_template = io . Autogrow . TemplatePrefix ( io . Latent . Input ( " latent " ) , prefix = " latent " , min = 1 , max = 50 )
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
return io . Schema (
node_id = " BatchLatentsNode " ,
add search aliases to all nodes (#12035)
* feat: Add search_aliases field to node schema
Adds `search_aliases` field to improve node discoverability. Users can define alternative search terms for nodes (e.g., "text concat" → StringConcatenate).
Changes:
- Add `search_aliases: list[str]` to V3 Schema
- Add `SEARCH_ALIASES` support for V1 nodes
- Include field in `/object_info` response
- Add aliases to high-priority core nodes
V1 usage:
```python
class MyNode:
SEARCH_ALIASES = ["alt name", "synonym"]
```
V3 usage:
```python
io.Schema(
node_id="MyNode",
search_aliases=["alt name", "synonym"],
...
)
```
## Related PRs
- Frontend: Comfy-Org/ComfyUI_frontend#XXXX (draft - merge after this)
- Docs: Comfy-Org/docs#XXXX (draft - merge after stable)
* Propagate search_aliases through V3 Schema.get_v1_info to NodeInfoV1
* feat: add SEARCH_ALIASES for core nodes (#12016)
Add search aliases to 22 core nodes in nodes.py to improve node discoverability:
- Checkpoint/model loaders: CheckpointLoader, DiffusersLoader
- Conditioning nodes: ConditioningAverage, ConditioningSetArea, ConditioningSetMask, ConditioningZeroOut
- Style nodes: StyleModelApply
- Image nodes: LoadImageMask, LoadImageOutput, ImageBatch, ImageInvert, ImagePadForOutpaint
- Latent nodes: LoadLatent, SaveLatent, LatentBlend, LatentComposite, LatentCrop, LatentFlip, LatentFromBatch, LatentUpscale, LatentUpscaleBy, RepeatLatentBatch
* feat: add SEARCH_ALIASES for image, mask, and string nodes (#12017)
Add search aliases to nodes in comfy_extras for better discoverability:
- nodes_mask.py: mask manipulation nodes
- nodes_images.py: image processing nodes
- nodes_post_processing.py: post-processing effect nodes
- nodes_string.py: string manipulation nodes
- nodes_compositing.py: compositing nodes
- nodes_morphology.py: morphological operation nodes
- nodes_latent.py: latent space nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for audio and video nodes (#12018)
Add search aliases to audio and video nodes for better discoverability:
- nodes_audio.py: audio loading, saving, and processing nodes
- nodes_video.py: video loading and processing nodes
- nodes_wan.py: WAN model nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for model and misc nodes (#12019)
Add search aliases to model-related and miscellaneous nodes:
- Model nodes: nodes_model_merging.py, nodes_model_advanced.py, nodes_lora_extract.py
- Sampler nodes: nodes_custom_sampler.py, nodes_align_your_steps.py
- Control nodes: nodes_controlnet.py, nodes_attention_multiply.py, nodes_hooks.py
- Training nodes: nodes_train.py, nodes_dataset.py
- Utility nodes: nodes_logic.py, nodes_canny.py, nodes_differential_diffusion.py
- Architecture-specific: nodes_sd3.py, nodes_pixart.py, nodes_lumina2.py, nodes_kandinsky5.py, nodes_hidream.py, nodes_fresca.py, nodes_hunyuan3d.py
- Media nodes: nodes_load_3d.py, nodes_webcam.py, nodes_preview_any.py, nodes_wanmove.py
Uses search_aliases parameter in io.Schema() for v3 nodes, SEARCH_ALIASES class attribute for legacy nodes.
2026-01-22 18:36:58 -08:00
search_aliases = [ " combine latents " , " stack latents " , " merge latents " ] ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
display_name = " Batch Latents " ,
2026-06-17 08:33:09 +08:00
category = " model/latent/batch " ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
inputs = [
io . Autogrow . Input ( " latents " , template = autogrow_template )
] ,
outputs = [
io . Latent . Output ( )
]
)
@classmethod
def execute ( cls , latents : io . Autogrow . Type ) - > io . NodeOutput :
return io . NodeOutput ( batch_latents ( list ( latents . values ( ) ) ) )
class BatchImagesMasksLatentsNode ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
matchtype_template = io . MatchType . Template ( " input " , allowed_types = [ io . Image , io . Mask , io . Latent ] )
autogrow_template = io . Autogrow . TemplatePrefix (
io . MatchType . Input ( " input " , matchtype_template ) ,
prefix = " input " , min = 1 , max = 50 )
return io . Schema (
node_id = " BatchImagesMasksLatentsNode " ,
add search aliases to all nodes (#12035)
* feat: Add search_aliases field to node schema
Adds `search_aliases` field to improve node discoverability. Users can define alternative search terms for nodes (e.g., "text concat" → StringConcatenate).
Changes:
- Add `search_aliases: list[str]` to V3 Schema
- Add `SEARCH_ALIASES` support for V1 nodes
- Include field in `/object_info` response
- Add aliases to high-priority core nodes
V1 usage:
```python
class MyNode:
SEARCH_ALIASES = ["alt name", "synonym"]
```
V3 usage:
```python
io.Schema(
node_id="MyNode",
search_aliases=["alt name", "synonym"],
...
)
```
## Related PRs
- Frontend: Comfy-Org/ComfyUI_frontend#XXXX (draft - merge after this)
- Docs: Comfy-Org/docs#XXXX (draft - merge after stable)
* Propagate search_aliases through V3 Schema.get_v1_info to NodeInfoV1
* feat: add SEARCH_ALIASES for core nodes (#12016)
Add search aliases to 22 core nodes in nodes.py to improve node discoverability:
- Checkpoint/model loaders: CheckpointLoader, DiffusersLoader
- Conditioning nodes: ConditioningAverage, ConditioningSetArea, ConditioningSetMask, ConditioningZeroOut
- Style nodes: StyleModelApply
- Image nodes: LoadImageMask, LoadImageOutput, ImageBatch, ImageInvert, ImagePadForOutpaint
- Latent nodes: LoadLatent, SaveLatent, LatentBlend, LatentComposite, LatentCrop, LatentFlip, LatentFromBatch, LatentUpscale, LatentUpscaleBy, RepeatLatentBatch
* feat: add SEARCH_ALIASES for image, mask, and string nodes (#12017)
Add search aliases to nodes in comfy_extras for better discoverability:
- nodes_mask.py: mask manipulation nodes
- nodes_images.py: image processing nodes
- nodes_post_processing.py: post-processing effect nodes
- nodes_string.py: string manipulation nodes
- nodes_compositing.py: compositing nodes
- nodes_morphology.py: morphological operation nodes
- nodes_latent.py: latent space nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for audio and video nodes (#12018)
Add search aliases to audio and video nodes for better discoverability:
- nodes_audio.py: audio loading, saving, and processing nodes
- nodes_video.py: video loading and processing nodes
- nodes_wan.py: WAN model nodes
Uses search_aliases parameter in io.Schema() for v3 nodes.
* feat: add SEARCH_ALIASES for model and misc nodes (#12019)
Add search aliases to model-related and miscellaneous nodes:
- Model nodes: nodes_model_merging.py, nodes_model_advanced.py, nodes_lora_extract.py
- Sampler nodes: nodes_custom_sampler.py, nodes_align_your_steps.py
- Control nodes: nodes_controlnet.py, nodes_attention_multiply.py, nodes_hooks.py
- Training nodes: nodes_train.py, nodes_dataset.py
- Utility nodes: nodes_logic.py, nodes_canny.py, nodes_differential_diffusion.py
- Architecture-specific: nodes_sd3.py, nodes_pixart.py, nodes_lumina2.py, nodes_kandinsky5.py, nodes_hidream.py, nodes_fresca.py, nodes_hunyuan3d.py
- Media nodes: nodes_load_3d.py, nodes_webcam.py, nodes_preview_any.py, nodes_wanmove.py
Uses search_aliases parameter in io.Schema() for v3 nodes, SEARCH_ALIASES class attribute for legacy nodes.
2026-01-22 18:36:58 -08:00
search_aliases = [ " combine batch " , " merge batch " , " stack inputs " ] ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
display_name = " Batch Images/Masks/Latents " ,
category = " util " ,
inputs = [
io . Autogrow . Input ( " inputs " , template = autogrow_template )
] ,
outputs = [
io . MatchType . Output ( id = None , template = matchtype_template )
]
)
@classmethod
def execute ( cls , inputs : io . Autogrow . Type ) - > io . NodeOutput :
batched = None
values = list ( inputs . values ( ) )
# latents
if isinstance ( values [ 0 ] , dict ) :
batched = batch_latents ( values )
# images
elif is_image ( values [ 0 ] ) :
batched = batch_images ( values )
# masks
else :
batched = batch_masks ( values )
return io . NodeOutput ( batched )
2026-02-15 02:12:30 -08:00
2026-04-19 06:02:01 +03:00
class ColorTransfer ( io . ComfyNode ) :
@classmethod
def define_schema ( cls ) :
return io . Schema (
node_id = " ColorTransfer " ,
2026-05-19 12:13:48 +08:00
display_name = " Transfer Color " ,
category = " image/filters " ,
2026-04-19 06:02:01 +03:00
description = " Match the colors of one image to another using various algorithms. " ,
search_aliases = [ " color match " , " color grading " , " color correction " , " match colors " , " color transform " , " mkl " , " reinhard " , " histogram " ] ,
inputs = [
io . Image . Input ( " image_target " , tooltip = " Image(s) to apply the color transform to. " ) ,
2026-05-04 12:33:11 +08:00
io . Image . Input ( " image_ref " , tooltip = " Reference image(s) to match colors to. " ) ,
2026-04-19 06:02:01 +03:00
io . Combo . Input ( " method " , options = [ ' reinhard_lab ' , ' mkl_lab ' , ' histogram ' ] , ) ,
io . DynamicCombo . Input ( " source_stats " ,
tooltip = " per_frame: each frame matched to image_ref individually. uniform: pool stats across all source frames as baseline, match to image_ref. target_frame: use one chosen frame as the baseline for the transform to image_ref, applied uniformly to all frames (preserves relative differences) " ,
options = [
io . DynamicCombo . Option ( " per_frame " , [ ] ) ,
io . DynamicCombo . Option ( " uniform " , [ ] ) ,
io . DynamicCombo . Option ( " target_frame " , [
io . Int . Input ( " target_index " , default = 0 , min = 0 , max = 10000 ,
tooltip = " Frame index used as the source baseline for computing the transform to image_ref " ) ,
] ) ,
] ) ,
io . Float . Input ( " strength " , default = 1.0 , min = 0.0 , max = 10.0 , step = 0.01 ) ,
] ,
outputs = [
io . Image . Output ( display_name = " image " ) ,
] ,
)
@staticmethod
def _to_lab ( images , i , device ) :
return kornia . color . rgb_to_lab (
images [ i : i + 1 ] . to ( device , dtype = torch . float32 ) . permute ( 0 , 3 , 1 , 2 ) )
@staticmethod
def _pool_stats ( images , device , is_reinhard , eps ) :
""" Two-pass pooled mean + std/cov across all frames. """
N , C = images . shape [ 0 ] , images . shape [ 3 ]
HW = images . shape [ 1 ] * images . shape [ 2 ]
mean = torch . zeros ( C , 1 , device = device , dtype = torch . float32 )
for i in range ( N ) :
mean + = ColorTransfer . _to_lab ( images , i , device ) . view ( C , - 1 ) . mean ( dim = - 1 , keepdim = True )
mean / = N
acc = torch . zeros ( C , 1 if is_reinhard else C , device = device , dtype = torch . float32 )
for i in range ( N ) :
centered = ColorTransfer . _to_lab ( images , i , device ) . view ( C , - 1 ) - mean
if is_reinhard :
acc + = ( centered * centered ) . mean ( dim = - 1 , keepdim = True )
else :
acc + = centered @ centered . T / HW
if is_reinhard :
return mean , torch . sqrt ( acc / N ) . clamp_min_ ( eps )
return mean , acc / N
@staticmethod
def _frame_stats ( lab_flat , hw , is_reinhard , eps ) :
""" Per-frame mean + std/cov. """
mean = lab_flat . mean ( dim = - 1 , keepdim = True )
if is_reinhard :
return mean , lab_flat . std ( dim = - 1 , keepdim = True , unbiased = False ) . clamp_min_ ( eps )
centered = lab_flat - mean
return mean , centered @ centered . T / hw
@staticmethod
def _mkl_matrix ( cov_s , cov_r , eps ) :
""" Compute MKL 3x3 transform matrix from source and ref covariances. """
eig_val_s , eig_vec_s = torch . linalg . eigh ( cov_s )
sqrt_val_s = torch . sqrt ( eig_val_s . clamp_min ( 0 ) ) . clamp_min_ ( eps )
scaled_V = eig_vec_s * sqrt_val_s . unsqueeze ( 0 )
mid = scaled_V . T @ cov_r @ scaled_V
eig_val_m , eig_vec_m = torch . linalg . eigh ( mid )
sqrt_m = torch . sqrt ( eig_val_m . clamp_min ( 0 ) )
inv_sqrt_s = 1.0 / sqrt_val_s
inv_scaled_V = eig_vec_s * inv_sqrt_s . unsqueeze ( 0 )
M_half = ( eig_vec_m * sqrt_m . unsqueeze ( 0 ) ) @ eig_vec_m . T
return inv_scaled_V @ M_half @ inv_scaled_V . T
@staticmethod
def _histogram_lut ( src , ref , bins = 256 ) :
""" Build per-channel LUT from source and ref histograms. src/ref: (C, HW) in [0,1]. """
s_bins = ( src * ( bins - 1 ) ) . long ( ) . clamp ( 0 , bins - 1 )
r_bins = ( ref * ( bins - 1 ) ) . long ( ) . clamp ( 0 , bins - 1 )
s_hist = torch . zeros ( src . shape [ 0 ] , bins , device = src . device , dtype = src . dtype )
r_hist = torch . zeros ( src . shape [ 0 ] , bins , device = src . device , dtype = src . dtype )
ones_s = torch . ones_like ( src )
ones_r = torch . ones_like ( ref )
s_hist . scatter_add_ ( 1 , s_bins , ones_s )
r_hist . scatter_add_ ( 1 , r_bins , ones_r )
s_cdf = s_hist . cumsum ( 1 )
s_cdf = s_cdf / s_cdf [ : , - 1 : ]
r_cdf = r_hist . cumsum ( 1 )
r_cdf = r_cdf / r_cdf [ : , - 1 : ]
return torch . searchsorted ( r_cdf , s_cdf ) . clamp_max_ ( bins - 1 ) . float ( ) / ( bins - 1 )
@classmethod
def _pooled_cdf ( cls , images , device , num_bins = 256 ) :
""" Build pooled CDF across all frames, one frame at a time. """
C = images . shape [ 3 ]
hist = torch . zeros ( C , num_bins , device = device , dtype = torch . float32 )
for i in range ( images . shape [ 0 ] ) :
frame = images [ i ] . to ( device , dtype = torch . float32 ) . permute ( 2 , 0 , 1 ) . reshape ( C , - 1 )
bins = ( frame * ( num_bins - 1 ) ) . long ( ) . clamp ( 0 , num_bins - 1 )
hist . scatter_add_ ( 1 , bins , torch . ones_like ( frame ) )
cdf = hist . cumsum ( 1 )
return cdf / cdf [ : , - 1 : ]
@classmethod
def _build_histogram_transform ( cls , image_target , image_ref , device , stats_mode , target_index , B ) :
""" Build per-frame or uniform LUT transform for histogram mode. """
if stats_mode == ' per_frame ' :
return None # LUT computed per-frame in the apply loop
r_cdf = cls . _pooled_cdf ( image_ref , device )
if stats_mode == ' target_frame ' :
ti = min ( target_index , B - 1 )
s_cdf = cls . _pooled_cdf ( image_target [ ti : ti + 1 ] , device )
else :
s_cdf = cls . _pooled_cdf ( image_target , device )
return torch . searchsorted ( r_cdf , s_cdf ) . clamp_max_ ( 255 ) . float ( ) / 255.0
@classmethod
def _build_lab_transform ( cls , image_target , image_ref , device , stats_mode , target_index , is_reinhard ) :
""" Build transform parameters for Lab-based methods. Returns a transform function. """
eps = 1e-6
B , H , W , C = image_target . shape
B_ref = image_ref . shape [ 0 ]
single_ref = B_ref == 1
HW = H * W
HW_ref = image_ref . shape [ 1 ] * image_ref . shape [ 2 ]
# Precompute ref stats
if single_ref or stats_mode in ( ' uniform ' , ' target_frame ' ) :
ref_mean , ref_sc = cls . _pool_stats ( image_ref , device , is_reinhard , eps )
# Uniform/target_frame: precompute single affine transform
if stats_mode in ( ' uniform ' , ' target_frame ' ) :
if stats_mode == ' target_frame ' :
ti = min ( target_index , B - 1 )
s_lab = cls . _to_lab ( image_target , ti , device ) . view ( C , - 1 )
s_mean , s_sc = cls . _frame_stats ( s_lab , HW , is_reinhard , eps )
else :
s_mean , s_sc = cls . _pool_stats ( image_target , device , is_reinhard , eps )
if is_reinhard :
scale = ref_sc / s_sc
offset = ref_mean - scale * s_mean
return lambda src_flat , * * _ : src_flat * scale + offset
T = cls . _mkl_matrix ( s_sc , ref_sc , eps )
offset = ref_mean - T @ s_mean
return lambda src_flat , * * _ : T @ src_flat + offset
# per_frame
def per_frame_transform ( src_flat , frame_idx ) :
s_mean , s_sc = cls . _frame_stats ( src_flat , HW , is_reinhard , eps )
if single_ref :
r_mean , r_sc = ref_mean , ref_sc
else :
ri = min ( frame_idx , B_ref - 1 )
r_mean , r_sc = cls . _frame_stats ( cls . _to_lab ( image_ref , ri , device ) . view ( C , - 1 ) , HW_ref , is_reinhard , eps )
centered = src_flat - s_mean
if is_reinhard :
return centered * ( r_sc / s_sc ) + r_mean
T = cls . _mkl_matrix ( centered @ centered . T / HW , r_sc , eps )
return T @ centered + r_mean
return per_frame_transform
@classmethod
def execute ( cls , image_target , image_ref , method , source_stats , strength = 1.0 ) - > io . NodeOutput :
stats_mode = source_stats [ " source_stats " ]
target_index = source_stats . get ( " target_index " , 0 )
if strength == 0 or image_ref is None :
return io . NodeOutput ( image_target )
device = comfy . model_management . get_torch_device ( )
intermediate_device = comfy . model_management . intermediate_device ( )
intermediate_dtype = comfy . model_management . intermediate_dtype ( )
B , H , W , C = image_target . shape
B_ref = image_ref . shape [ 0 ]
pbar = comfy . utils . ProgressBar ( B )
out = torch . empty ( B , H , W , C , device = intermediate_device , dtype = intermediate_dtype )
if method == ' histogram ' :
uniform_lut = cls . _build_histogram_transform (
image_target , image_ref , device , stats_mode , target_index , B )
for i in range ( B ) :
src = image_target [ i ] . to ( device , dtype = torch . float32 ) . permute ( 2 , 0 , 1 )
src_flat = src . reshape ( C , - 1 )
if uniform_lut is not None :
lut = uniform_lut
else :
ri = min ( i , B_ref - 1 )
ref = image_ref [ ri ] . to ( device , dtype = torch . float32 ) . permute ( 2 , 0 , 1 ) . reshape ( C , - 1 )
lut = cls . _histogram_lut ( src_flat , ref )
bin_idx = ( src_flat * 255 ) . long ( ) . clamp ( 0 , 255 )
matched = lut . gather ( 1 , bin_idx ) . view ( C , H , W )
result = matched if strength == 1.0 else torch . lerp ( src , matched , strength )
out [ i ] = result . permute ( 1 , 2 , 0 ) . clamp_ ( 0 , 1 ) . to ( device = intermediate_device , dtype = intermediate_dtype )
pbar . update ( 1 )
else :
transform = cls . _build_lab_transform ( image_target , image_ref , device , stats_mode , target_index , is_reinhard = method == " reinhard_lab " )
for i in range ( B ) :
src_frame = cls . _to_lab ( image_target , i , device )
corrected = transform ( src_frame . view ( C , - 1 ) , frame_idx = i )
if strength == 1.0 :
result = kornia . color . lab_to_rgb ( corrected . view ( 1 , C , H , W ) )
else :
result = kornia . color . lab_to_rgb ( torch . lerp ( src_frame , corrected . view ( 1 , C , H , W ) , strength ) )
out [ i ] = result . squeeze ( 0 ) . permute ( 1 , 2 , 0 ) . clamp_ ( 0 , 1 ) . to ( device = intermediate_device , dtype = intermediate_dtype )
pbar . update ( 1 )
return io . NodeOutput ( out )
2025-09-27 00:14:42 +03:00
class PostProcessingExtension ( ComfyExtension ) :
@override
async def get_node_list ( self ) - > list [ type [ io . ComfyNode ] ] :
return [
Blend ,
Blur ,
Quantize ,
Sharpen ,
ImageScaleToTotalPixels ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
ResizeImageMaskNode ,
BatchImagesNode ,
BatchMasksNode ,
BatchLatentsNode ,
2026-04-19 06:02:01 +03:00
ColorTransfer ,
V3 Improvements + DynamicCombo + Autogrow exposed in public API (#11345)
* Support Combo outputs in a more sane way
* Remove test validate_inputs function on test node
* Make curr_prefix be a list of strings instead of string for easier parsing as keys get added to dynamic types
* Start to account for id prefixes from frontend, need to fix bug with nested dynamics
* Ensure inputs/outputs/hidden are lists in schema finalize function, remove no longer needed 'is not None' checks
* Add raw_link and extra_dict to all relevant Inputs
* Make nested DynamicCombos work properly with prefixed keys on latest frontend; breaks old Autogrow, but is pretty much ready for upcoming Autogrow keys
* Replace ... usage with a MISSING sentinel for clarity in nodes_logic.py
* Added CustomCombo node in backend to reflect frontend node
* Prepare Autogrow's expand_schema_for_dynamic to work with upcoming frontend changes
* Prepare for look up table for dynamic input stuff
* More progress towards dynamic input lookup function stuff
* Finished converting _expand_schema_for_dynamic to be done via lookup instead of OOP to guarantee working with process isolation, did refactoring to remove old implementation + cleaning INPUT_TYPES definition including v3 hidden definition
* Change order of functions
* Removed some unneeded functions after dynamic refactor
* Make MatchType's output default displayname "MATCHTYPE"
* Fix DynamicSlot get_all
* Removed redundant code - dynamic stuff no longer happens in OOP way
* Natively support AnyType (*) without __ne__ hacks
* Remove stray code that made it in
* Remove expand_schema_for_dynamic left over on DynamicInput class
* get_dynamic() on DynamicInput/Output was not doing anything anymore, so removed it
* Make validate_inputs validate combo input correctly
* Temporarily comment out conversion to 'new' (9 month old) COMBO format in get_input_info
* Remove refrences to resources feature scrapped from V3
* Expose DynamicCombo in public API
* satisfy ruff after some code got commented out
* Make missing input error prettier for dynamic types
* Created a Switch2 node as a side-by-side test, will likely go with Switch2 as the initial switch node
* Figured out Switch situation
* Pass in v3_data in IsChangedCache.get function's fingerprint_inputs, add a from_v3_data helper method to HiddenHolder
* Switch order of Switch and Soft Switch nodes in file
* Temp test node for MatchType
* Fix missing v3_data for v1 nodes in validation
* For now, remove chacking duplicate id's for dynamic types
* Add Resize Image/Mask node that thanks to MatchType+DynamicCombo is 16-nodes-in-1
* Made DynamicCombo references in DCTestNode use public interface
* Add an AnyTypeTestNode
* Make lazy status for specific inputs on DynamicInputs work by having the values of the dictionary for check_lazy_status be a tuple, where the second element is the key of the input that can be returned
* Comment out test logic nodes
* Make primitive float's step make more sense
* Add (and leave commented out) some potential logic nodes
* Change default crop option to "center" on Resize Image/Mask node
* Changed copy.copy(d) to d.copy()
* Autogrow is available in stable frontend, so exposing it in public API
* Use outputs id as display_name if no display_name present, remove v3 outputs id restriction that made them have to have unique IDs from the inputs
* Enable Custom Combo node as stable frontend now supports it
* Make id properly act like display_name on outputs
* Add Batch Images/Masks/Latents node
* Comment out Batch Images/Masks/Latents node for now, as Autogrow has a bug with MatchType where top connection is disconnected upon refresh
* Removed code for a couple test nodes in nodes_logic.py
* Add Batch Images, Batch Masks, and Batch Latents nodes with Autogrow, deprecate old Batch Images + LatentBatch nodes
2025-12-30 20:09:55 -08:00
# BatchImagesMasksLatentsNode,
2025-09-27 00:14:42 +03:00
]
async def comfy_entrypoint ( ) - > PostProcessingExtension :
return PostProcessingExtension ( )