From 39c5a53f6d27bdb9ee7a301b75167d41077c0a4a Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sat, 9 May 2026 13:04:09 +0800 Subject: [PATCH 01/20] Move detection category under image category --- comfy_extras/nodes_rtdetr.py | 4 ++-- comfy_extras/nodes_sam3.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/comfy_extras/nodes_rtdetr.py b/comfy_extras/nodes_rtdetr.py index a321577c7..e5a9b3902 100644 --- a/comfy_extras/nodes_rtdetr.py +++ b/comfy_extras/nodes_rtdetr.py @@ -15,7 +15,7 @@ class RTDETR_detect(io.ComfyNode): return io.Schema( node_id="RTDETR_detect", display_name="RT-DETR Detect", - category="detection", + category="image/detection", search_aliases=["bbox", "bounding box", "object detection", "coco"], inputs=[ io.Model.Input("model", display_name="model"), @@ -71,7 +71,7 @@ class DrawBBoxes(io.ComfyNode): return io.Schema( node_id="DrawBBoxes", display_name="Draw BBoxes", - category="detection", + category="image/detection", search_aliases=["bbox", "bounding box", "object detection", "rt_detr", "visualize detections", "coco"], inputs=[ io.Image.Input("image", optional=True), diff --git a/comfy_extras/nodes_sam3.py b/comfy_extras/nodes_sam3.py index 4ea9221e9..daac52f9b 100644 --- a/comfy_extras/nodes_sam3.py +++ b/comfy_extras/nodes_sam3.py @@ -93,7 +93,7 @@ class SAM3_Detect(io.ComfyNode): return io.Schema( node_id="SAM3_Detect", display_name="SAM3 Detect", - category="detection", + category="image/detection", search_aliases=["sam3", "segment anything", "open vocabulary", "text detection", "segment"], inputs=[ io.Model.Input("model", display_name="model"), @@ -265,7 +265,7 @@ class SAM3_VideoTrack(io.ComfyNode): return io.Schema( node_id="SAM3_VideoTrack", display_name="SAM3 Video Track", - category="detection", + category="image/detection", search_aliases=["sam3", "video", "track", "propagate"], inputs=[ io.Image.Input("images", display_name="images", tooltip="Video frames as batched images"), @@ -320,7 +320,7 @@ class SAM3_TrackPreview(io.ComfyNode): return io.Schema( node_id="SAM3_TrackPreview", display_name="SAM3 Track Preview", - category="detection", + category="image/detection", inputs=[ SAM3TrackData.Input("track_data", display_name="track_data"), io.Image.Input("images", display_name="images", optional=True), @@ -478,7 +478,7 @@ class SAM3_TrackToMask(io.ComfyNode): return io.Schema( node_id="SAM3_TrackToMask", display_name="SAM3 Track to Mask", - category="detection", + category="image/detection", inputs=[ SAM3TrackData.Input("track_data", display_name="track_data"), io.String.Input("object_indices", display_name="object_indices", default="", From 59c277c09cc7cfe82e92411741e13ca023be643c Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sat, 9 May 2026 13:07:45 +0800 Subject: [PATCH 02/20] Add missing categories --- comfy_extras/nodes_flux.py | 2 +- comfy_extras/nodes_nop.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_flux.py b/comfy_extras/nodes_flux.py index 5e04a5f77..84726d009 100644 --- a/comfy_extras/nodes_flux.py +++ b/comfy_extras/nodes_flux.py @@ -263,7 +263,7 @@ class FluxKVCache(io.ComfyNode): node_id="FluxKVCache", display_name="Flux KV Cache", description="Enables KV Cache optimization for reference images on Flux family models.", - category="", + category="experimental", is_experimental=True, inputs=[ io.Model.Input("model", tooltip="The model to use KV Cache on."), diff --git a/comfy_extras/nodes_nop.py b/comfy_extras/nodes_nop.py index 953061bcb..6667ec25c 100644 --- a/comfy_extras/nodes_nop.py +++ b/comfy_extras/nodes_nop.py @@ -12,7 +12,8 @@ class wanBlockSwap(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="wanBlockSwap", - category="", + display_name="WAN Block Swap", + category="model_patches", description="NOP", inputs=[ io.Model.Input("model"), From 2a05226be877e7d3024ac08dd0ab43b029d2aefc Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sat, 9 May 2026 21:14:27 +0800 Subject: [PATCH 03/20] Move detection nodes to detection category --- comfy_extras/nodes_sdpose.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/comfy_extras/nodes_sdpose.py b/comfy_extras/nodes_sdpose.py index 96b6821bd..20d459b00 100644 --- a/comfy_extras/nodes_sdpose.py +++ b/comfy_extras/nodes_sdpose.py @@ -353,7 +353,8 @@ class SDPoseDrawKeypoints(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SDPoseDrawKeypoints", - category="image/preprocessors", + display_name="SDPose Draw Keypoints", + category="image/detection", search_aliases=["openpose", "pose detection", "preprocessor", "keypoints", "pose"], inputs=[ io.Custom("POSE_KEYPOINT").Input("keypoints"), @@ -421,7 +422,8 @@ class SDPoseKeypointExtractor(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SDPoseKeypointExtractor", - category="image/preprocessors", + display_name="SDPose Keypoint Extractor", + category="image/detection", search_aliases=["openpose", "pose detection", "preprocessor", "keypoints", "sdpose"], description="Extract pose keypoints from images using the SDPose model: https://huggingface.co/Comfy-Org/SDPose/tree/main/checkpoints", inputs=[ @@ -595,7 +597,8 @@ class SDPoseFaceBBoxes(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SDPoseFaceBBoxes", - category="image/preprocessors", + display_name="SDPose Face Bounding Boxes", + category="image/detection", search_aliases=["face bbox", "face bounding box", "pose", "keypoints"], inputs=[ io.Custom("POSE_KEYPOINT").Input("keypoints"), @@ -652,7 +655,8 @@ class CropByBBoxes(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="CropByBBoxes", - category="image/preprocessors", + display_name="Crop By Bounding Boxes", + category="image/transform", search_aliases=["crop", "face crop", "bbox crop", "pose", "bounding box"], description="Crop and resize regions from the input image batch based on provided bounding boxes.", inputs=[ From cf807bec0f1da24392eb59124c75778da0f1dff1 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sat, 9 May 2026 21:14:54 +0800 Subject: [PATCH 04/20] Move save nodes to image root catefory --- comfy_extras/nodes_images.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/comfy_extras/nodes_images.py b/comfy_extras/nodes_images.py index 1ac740d1d..a48148e5e 100644 --- a/comfy_extras/nodes_images.py +++ b/comfy_extras/nodes_images.py @@ -192,7 +192,8 @@ class SaveAnimatedWEBP(IO.ComfyNode): def define_schema(cls): return IO.Schema( node_id="SaveAnimatedWEBP", - category="image/animation", + display_name="Save Animated WEBP", + category="image", inputs=[ IO.Image.Input("images"), IO.String.Input("filename_prefix", default="ComfyUI"), @@ -229,7 +230,8 @@ class SaveAnimatedPNG(IO.ComfyNode): def define_schema(cls): return IO.Schema( node_id="SaveAnimatedPNG", - category="image/animation", + display_name="Save Animated PNG", + category="image", inputs=[ IO.Image.Input("images"), IO.String.Input("filename_prefix", default="ComfyUI"), @@ -491,7 +493,7 @@ class SaveSVGNode(IO.ComfyNode): search_aliases=["export vector", "save vector graphics"], display_name="Save SVG", description="Save SVG files on disk.", - category="image/save", + category="image", inputs=[ IO.SVG.Input("svg"), IO.String.Input( From 5b8054ea0f130b677d2fa14dc4bc5daa3096ed40 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sat, 9 May 2026 21:28:22 +0800 Subject: [PATCH 05/20] Rename postprocessors --- comfy_extras/nodes_canny.py | 4 ++-- comfy_extras/nodes_images.py | 2 +- comfy_extras/nodes_morphology.py | 4 ++-- comfy_extras/nodes_post_processing.py | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/comfy_extras/nodes_canny.py b/comfy_extras/nodes_canny.py index 648b4279d..7261b03a1 100644 --- a/comfy_extras/nodes_canny.py +++ b/comfy_extras/nodes_canny.py @@ -11,9 +11,9 @@ class Canny(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="Canny", - display_name="Canny", + display_name="Detect Canny Edges", search_aliases=["edge detection", "outline", "contour detection", "line art"], - category="image/preprocessors", + category="image/filters", essentials_category="Image Tools", inputs=[ io.Image.Input("image"), diff --git a/comfy_extras/nodes_images.py b/comfy_extras/nodes_images.py index a48148e5e..07faa01d4 100644 --- a/comfy_extras/nodes_images.py +++ b/comfy_extras/nodes_images.py @@ -160,7 +160,7 @@ class ImageAddNoise(IO.ComfyNode): node_id="ImageAddNoise", search_aliases=["film grain"], display_name="Add Noise to Image", - category="image/postprocessing", + category="image/filters", inputs=[ IO.Image.Input("image"), IO.Int.Input( diff --git a/comfy_extras/nodes_morphology.py b/comfy_extras/nodes_morphology.py index c01b9436d..0142040dd 100644 --- a/comfy_extras/nodes_morphology.py +++ b/comfy_extras/nodes_morphology.py @@ -13,8 +13,8 @@ class Morphology(io.ComfyNode): return io.Schema( node_id="Morphology", search_aliases=["erode", "dilate"], - display_name="ImageMorphology", - category="image/postprocessing", + display_name="Apply Morphology", + category="image/filters", inputs=[ io.Image.Input("image"), io.Combo.Input( diff --git a/comfy_extras/nodes_post_processing.py b/comfy_extras/nodes_post_processing.py index 1fa14d2d2..be6ec7434 100644 --- a/comfy_extras/nodes_post_processing.py +++ b/comfy_extras/nodes_post_processing.py @@ -22,7 +22,7 @@ class Blend(io.ComfyNode): node_id="ImageBlend", search_aliases=["mix images"], display_name="Blend Images", - category="image/postprocessing", + category="image/filters", essentials_category="Image Tools", inputs=[ io.Image.Input("image1"), @@ -80,8 +80,8 @@ class Blur(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="ImageBlur", - display_name="Image Blur", - category="image/postprocessing", + display_name="Blur Image", + category="image/filters", inputs=[ io.Image.Input("image"), io.Int.Input("blur_radius", default=1, min=1, max=31, step=1), @@ -117,7 +117,7 @@ class Quantize(io.ComfyNode): return io.Schema( node_id="ImageQuantize", display_name="Quantize Image", - category="image/postprocessing", + category="image/filters", inputs=[ io.Image.Input("image"), io.Int.Input("colors", default=256, min=1, max=256, step=1), @@ -183,7 +183,7 @@ class Sharpen(io.ComfyNode): return io.Schema( node_id="ImageSharpen", display_name="Sharpen Image", - category="image/postprocessing", + category="image/filters", inputs=[ io.Image.Input("image"), io.Int.Input("sharpen_radius", default=1, min=1, max=31, step=1, advanced=True), @@ -670,8 +670,8 @@ class ColorTransfer(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="ColorTransfer", - display_name="Color Transfer", - category="image/postprocessing", + display_name="Transfer Color", + category="image/filters", 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=[ From d28d7608256a5e13c9a2e933e1de7f396fc95fd5 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sun, 10 May 2026 15:13:39 +0800 Subject: [PATCH 06/20] Move mask category under image --- comfy_extras/nodes_mask.py | 27 +++++++++++++++------------ comfy_extras/nodes_post_processing.py | 2 +- nodes.py | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/comfy_extras/nodes_mask.py b/comfy_extras/nodes_mask.py index c9b2a84d9..50c763d43 100644 --- a/comfy_extras/nodes_mask.py +++ b/comfy_extras/nodes_mask.py @@ -127,7 +127,7 @@ class MaskToImage(IO.ComfyNode): node_id="MaskToImage", search_aliases=["convert mask"], display_name="Convert Mask to Image", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), ], @@ -149,7 +149,7 @@ class ImageToMask(IO.ComfyNode): node_id="ImageToMask", search_aliases=["extract channel", "channel to mask"], display_name="Convert Image to Mask", - category="mask", + category="image/mask", inputs=[ IO.Image.Input("image"), IO.Combo.Input("channel", options=["red", "green", "blue", "alpha"]), @@ -172,7 +172,8 @@ class ImageColorToMask(IO.ComfyNode): return IO.Schema( node_id="ImageColorToMask", search_aliases=["color keying", "chroma key"], - category="mask", + display_name="Convert Image Color to Mask", + category="image/mask", inputs=[ IO.Image.Input("image"), IO.Int.Input("color", default=0, min=0, max=0xFFFFFF, step=1, display_mode=IO.NumberDisplay.number), @@ -194,8 +195,9 @@ class SolidMask(IO.ComfyNode): @classmethod def define_schema(cls): return IO.Schema( - node_id="SolidMask", - category="mask", + node_id="CreateSolidMask", + display_name="Create Solid Mask", + category="image/mask", inputs=[ IO.Float.Input("value", default=1.0, min=0.0, max=1.0, step=0.01), IO.Int.Input("width", default=512, min=1, max=nodes.MAX_RESOLUTION, step=1), @@ -219,7 +221,7 @@ class InvertMask(IO.ComfyNode): node_id="InvertMask", search_aliases=["reverse mask", "flip mask"], display_name="Invert Mask", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), ], @@ -241,7 +243,7 @@ class CropMask(IO.ComfyNode): node_id="CropMask", search_aliases=["cut mask", "extract mask region", "mask slice"], display_name="Crop Mask", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), IO.Int.Input("x", default=0, min=0, max=nodes.MAX_RESOLUTION, step=1), @@ -268,7 +270,7 @@ class MaskComposite(IO.ComfyNode): node_id="MaskComposite", search_aliases=["combine masks", "blend masks", "layer masks", "masks composition"], display_name="Combine Masks", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("destination"), IO.Mask.Input("source"), @@ -319,7 +321,7 @@ class FeatherMask(IO.ComfyNode): node_id="FeatherMask", search_aliases=["soft edge mask", "blur mask edges", "gradient mask edge"], display_name="Feather Mask", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), IO.Int.Input("left", default=0, min=0, max=nodes.MAX_RESOLUTION, step=1), @@ -367,7 +369,7 @@ class GrowMask(IO.ComfyNode): node_id="GrowMask", search_aliases=["expand mask", "shrink mask"], display_name="Grow Mask", - category="mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), IO.Int.Input("expand", default=0, min=-nodes.MAX_RESOLUTION, max=nodes.MAX_RESOLUTION, step=1), @@ -403,7 +405,8 @@ class ThresholdMask(IO.ComfyNode): return IO.Schema( node_id="ThresholdMask", search_aliases=["binary mask"], - category="mask", + display_name="Threshold Mask", + category="image/mask", inputs=[ IO.Mask.Input("mask"), IO.Float.Input("value", default=0.5, min=0.0, max=1.0, step=0.01), @@ -429,7 +432,7 @@ class MaskPreview(IO.ComfyNode): node_id="MaskPreview", search_aliases=["show mask", "view mask", "inspect mask", "debug mask"], display_name="Preview Mask", - category="mask", + category="image/mask", description="Saves the input images to your ComfyUI output directory.", inputs=[ IO.Mask.Input("mask"), diff --git a/comfy_extras/nodes_post_processing.py b/comfy_extras/nodes_post_processing.py index be6ec7434..c30052d76 100644 --- a/comfy_extras/nodes_post_processing.py +++ b/comfy_extras/nodes_post_processing.py @@ -595,7 +595,7 @@ class BatchMasksNode(io.ComfyNode): node_id="BatchMasksNode", search_aliases=["combine masks", "stack masks", "merge masks"], display_name="Batch Masks", - category="mask", + category="image/mask", inputs=[ io.Autogrow.Input("masks", template=autogrow_template) ], diff --git a/nodes.py b/nodes.py index 5755f0bb8..cbca01c03 100644 --- a/nodes.py +++ b/nodes.py @@ -1771,7 +1771,7 @@ class LoadImageMask(LoadImage): } } - CATEGORY = "mask" + CATEGORY = "image/mask" RETURN_TYPES = ("MASK",) FUNCTION = "load_image_mask" From 6140e83c5c02b937ff0db4573c80d9c125058771 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sun, 10 May 2026 15:28:50 +0800 Subject: [PATCH 07/20] Move guiders category to parent level at root of sampling category --- comfy_extras/nodes_custom_sampler.py | 9 ++++++--- comfy_extras/nodes_video_model.py | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/comfy_extras/nodes_custom_sampler.py b/comfy_extras/nodes_custom_sampler.py index c67145d2d..89cfdd494 100644 --- a/comfy_extras/nodes_custom_sampler.py +++ b/comfy_extras/nodes_custom_sampler.py @@ -793,7 +793,8 @@ class BasicGuider(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="BasicGuider", - category="sampling/custom_sampling/guiders", + display_name="Basic Guider", + category="sampling/guiders", inputs=[ io.Model.Input("model"), io.Conditioning.Input("conditioning"), @@ -814,7 +815,8 @@ class CFGGuider(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="CFGGuider", - category="sampling/custom_sampling/guiders", + display_name="CFG Guider", + category="sampling/guiders", inputs=[ io.Model.Input("model"), io.Conditioning.Input("positive"), @@ -868,7 +870,8 @@ class DualCFGGuider(io.ComfyNode): return io.Schema( node_id="DualCFGGuider", search_aliases=["dual prompt guidance"], - category="sampling/custom_sampling/guiders", + display_name="Dual CFG Guider", + category="sampling/guiders", inputs=[ io.Model.Input("model"), io.Conditioning.Input("cond1"), diff --git a/comfy_extras/nodes_video_model.py b/comfy_extras/nodes_video_model.py index 0f3881a24..35b3d1ea8 100644 --- a/comfy_extras/nodes_video_model.py +++ b/comfy_extras/nodes_video_model.py @@ -65,7 +65,7 @@ class VideoLinearCFGGuidance: RETURN_TYPES = ("MODEL",) FUNCTION = "patch" - CATEGORY = "sampling/video_models" + CATEGORY = "sampling/guiders" def patch(self, model, min_cfg): def linear_cfg(args): @@ -89,7 +89,7 @@ class VideoTriangleCFGGuidance: RETURN_TYPES = ("MODEL",) FUNCTION = "patch" - CATEGORY = "sampling/video_models" + CATEGORY = "sampling/guiders" def patch(self, model, min_cfg): def linear_cfg(args): @@ -158,4 +158,6 @@ NODE_CLASS_MAPPINGS = { NODE_DISPLAY_NAME_MAPPINGS = { "ImageOnlyCheckpointLoader": "Image Only Checkpoint Loader (img2vid model)", + "VideoLinearCFGGuidance": "Video Linear CFG Guidance", + "VideoTriangleCFGGuidance": "Video Triangle CFG Guidance", } From 5a3bbe78b883657846827369fb87f99a2b2e0cff Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Sun, 10 May 2026 15:31:09 +0800 Subject: [PATCH 08/20] Move custom_sampling category to parent level at the root of sampling category --- comfy_extras/nodes_advanced_samplers.py | 4 +- comfy_extras/nodes_align_your_steps.py | 2 +- comfy_extras/nodes_ar_video.py | 2 +- comfy_extras/nodes_custom_sampler.py | 56 ++++++++++++------------- comfy_extras/nodes_flux.py | 2 +- comfy_extras/nodes_gits.py | 2 +- comfy_extras/nodes_lt.py | 2 +- comfy_extras/nodes_optimalsteps.py | 2 +- comfy_extras/nodes_void.py | 4 +- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/comfy_extras/nodes_advanced_samplers.py b/comfy_extras/nodes_advanced_samplers.py index 7e8411fa4..7b35972cc 100644 --- a/comfy_extras/nodes_advanced_samplers.py +++ b/comfy_extras/nodes_advanced_samplers.py @@ -45,7 +45,7 @@ class SamplerLCMUpscale(io.ComfyNode): def define_schema(cls) -> io.Schema: return io.Schema( node_id="SamplerLCMUpscale", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("scale_ratio", default=1.0, min=0.1, max=20.0, step=0.01, advanced=True), io.Int.Input("scale_steps", default=-1, min=-1, max=1000, step=1, advanced=True), @@ -92,7 +92,7 @@ class SamplerEulerCFGpp(io.ComfyNode): return io.Schema( node_id="SamplerEulerCFGpp", display_name="SamplerEulerCFG++", - category="experimental", # "sampling/custom_sampling/samplers" + category="experimental", # "sampling/samplers" inputs=[ io.Combo.Input("version", options=["regular", "alternative"], advanced=True), ], diff --git a/comfy_extras/nodes_align_your_steps.py b/comfy_extras/nodes_align_your_steps.py index 4fc511d2c..307f41337 100644 --- a/comfy_extras/nodes_align_your_steps.py +++ b/comfy_extras/nodes_align_your_steps.py @@ -29,7 +29,7 @@ class AlignYourStepsScheduler(io.ComfyNode): return io.Schema( node_id="AlignYourStepsScheduler", search_aliases=["AYS scheduler"], - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Combo.Input("model_type", options=["SD1", "SDXL", "SVD"]), io.Int.Input("steps", default=10, min=1, max=10000), diff --git a/comfy_extras/nodes_ar_video.py b/comfy_extras/nodes_ar_video.py index b36588b14..1a15facfa 100644 --- a/comfy_extras/nodes_ar_video.py +++ b/comfy_extras/nodes_ar_video.py @@ -53,7 +53,7 @@ class SamplerARVideo(io.ComfyNode): return io.Schema( node_id="SamplerARVideo", display_name="Sampler AR Video", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Int.Input( "num_frame_per_block", diff --git a/comfy_extras/nodes_custom_sampler.py b/comfy_extras/nodes_custom_sampler.py index 89cfdd494..58b6d3806 100644 --- a/comfy_extras/nodes_custom_sampler.py +++ b/comfy_extras/nodes_custom_sampler.py @@ -17,7 +17,7 @@ class BasicScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="BasicScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Model.Input("model"), io.Combo.Input("scheduler", options=comfy.samplers.SCHEDULER_NAMES), @@ -47,7 +47,7 @@ class KarrasScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="KarrasScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("sigma_max", default=14.614642, min=0.0, max=5000.0, step=0.01, round=False, advanced=True), @@ -69,7 +69,7 @@ class ExponentialScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="ExponentialScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("sigma_max", default=14.614642, min=0.0, max=5000.0, step=0.01, round=False, advanced=True), @@ -90,7 +90,7 @@ class PolyexponentialScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="PolyexponentialScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("sigma_max", default=14.614642, min=0.0, max=5000.0, step=0.01, round=False, advanced=True), @@ -112,7 +112,7 @@ class LaplaceScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="LaplaceScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("sigma_max", default=14.614642, min=0.0, max=5000.0, step=0.01, round=False, advanced=True), @@ -136,7 +136,7 @@ class SDTurboScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SDTurboScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Model.Input("model"), io.Int.Input("steps", default=1, min=1, max=10), @@ -160,7 +160,7 @@ class BetaSamplingScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="BetaSamplingScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Model.Input("model"), io.Int.Input("steps", default=20, min=1, max=10000), @@ -182,7 +182,7 @@ class VPScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="VPScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("beta_d", default=19.9, min=0.0, max=5000.0, step=0.01, round=False, advanced=True), #TODO: fix default values @@ -204,7 +204,7 @@ class SplitSigmas(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SplitSigmas", - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[ io.Sigmas.Input("sigmas"), io.Int.Input("step", default=0, min=0, max=10000), @@ -228,7 +228,7 @@ class SplitSigmasDenoise(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SplitSigmasDenoise", - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[ io.Sigmas.Input("sigmas"), io.Float.Input("denoise", default=1.0, min=0.0, max=1.0, step=0.01), @@ -254,7 +254,7 @@ class FlipSigmas(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="FlipSigmas", - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[io.Sigmas.Input("sigmas")], outputs=[io.Sigmas.Output()] ) @@ -276,7 +276,7 @@ class SetFirstSigma(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SetFirstSigma", - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[ io.Sigmas.Input("sigmas"), io.Float.Input("sigma", default=136.0, min=0.0, max=20000.0, step=0.001, round=False), @@ -298,7 +298,7 @@ class ExtendIntermediateSigmas(io.ComfyNode): return io.Schema( node_id="ExtendIntermediateSigmas", search_aliases=["interpolate sigmas"], - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[ io.Sigmas.Input("sigmas"), io.Int.Input("steps", default=2, min=1, max=100), @@ -351,7 +351,7 @@ class SamplingPercentToSigma(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplingPercentToSigma", - category="sampling/custom_sampling/sigmas", + category="sampling/sigmas", inputs=[ io.Model.Input("model"), io.Float.Input("sampling_percent", default=0.0, min=0.0, max=1.0, step=0.0001), @@ -379,7 +379,7 @@ class KSamplerSelect(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="KSamplerSelect", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[io.Combo.Input("sampler_name", options=comfy.samplers.SAMPLER_NAMES)], outputs=[io.Sampler.Output()] ) @@ -396,7 +396,7 @@ class SamplerDPMPP_3M_SDE(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerDPMPP_3M_SDE", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), io.Float.Input("s_noise", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), @@ -421,7 +421,7 @@ class SamplerDPMPP_2M_SDE(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerDPMPP_2M_SDE", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Combo.Input("solver_type", options=['midpoint', 'heun']), io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), @@ -448,7 +448,7 @@ class SamplerDPMPP_SDE(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerDPMPP_SDE", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), io.Float.Input("s_noise", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), @@ -474,7 +474,7 @@ class SamplerDPMPP_2S_Ancestral(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerDPMPP_2S_Ancestral", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False), io.Float.Input("s_noise", default=1.0, min=0.0, max=100.0, step=0.01, round=False), @@ -494,7 +494,7 @@ class SamplerEulerAncestral(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerEulerAncestral", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), io.Float.Input("s_noise", default=1.0, min=0.0, max=100.0, step=0.01, round=False, advanced=True), @@ -515,7 +515,7 @@ class SamplerEulerAncestralCFGPP(io.ComfyNode): return io.Schema( node_id="SamplerEulerAncestralCFGPP", display_name="SamplerEulerAncestralCFG++", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Float.Input("eta", default=1.0, min=0.0, max=1.0, step=0.01, round=False), io.Float.Input("s_noise", default=1.0, min=0.0, max=10.0, step=0.01, round=False), @@ -537,7 +537,7 @@ class SamplerLMS(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerLMS", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[io.Int.Input("order", default=4, min=1, max=100, advanced=True)], outputs=[io.Sampler.Output()] ) @@ -554,7 +554,7 @@ class SamplerDPMAdaptative(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerDPMAdaptative", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Int.Input("order", default=3, min=2, max=3, advanced=True), io.Float.Input("rtol", default=0.05, min=0.0, max=100.0, step=0.01, round=False, advanced=True), @@ -585,7 +585,7 @@ class SamplerER_SDE(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="SamplerER_SDE", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Combo.Input("solver_type", options=["ER-SDE", "Reverse-time SDE", "ODE"]), io.Int.Input("max_stage", default=3, min=1, max=3, advanced=True), @@ -623,7 +623,7 @@ class SamplerSASolver(io.ComfyNode): return io.Schema( node_id="SamplerSASolver", search_aliases=["sde"], - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Model.Input("model"), io.Float.Input("eta", default=1.0, min=0.0, max=10.0, step=0.01, round=False, advanced=True), @@ -668,7 +668,7 @@ class SamplerSEEDS2(io.ComfyNode): return io.Schema( node_id="SamplerSEEDS2", search_aliases=["sde", "exp heun"], - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[ io.Combo.Input("solver_type", options=["phi_1", "phi_2"]), io.Float.Input("eta", default=1.0, min=0.0, max=100.0, step=0.01, round=False, tooltip="Stochastic strength", advanced=True), @@ -899,7 +899,7 @@ class DisableNoise(io.ComfyNode): return io.Schema( node_id="DisableNoise", search_aliases=["zero noise"], - category="sampling/custom_sampling/noise", + category="sampling/noise", inputs=[], outputs=[io.Noise.Output()] ) @@ -916,7 +916,7 @@ class RandomNoise(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="RandomNoise", - category="sampling/custom_sampling/noise", + category="sampling/noise", inputs=[io.Int.Input("noise_seed", default=0, min=0, max=0xffffffffffffffff, control_after_generate=True)], outputs=[io.Noise.Output()] ) diff --git a/comfy_extras/nodes_flux.py b/comfy_extras/nodes_flux.py index 84726d009..997f21c09 100644 --- a/comfy_extras/nodes_flux.py +++ b/comfy_extras/nodes_flux.py @@ -215,7 +215,7 @@ class Flux2Scheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="Flux2Scheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=4096), io.Int.Input("width", default=1024, min=16, max=nodes.MAX_RESOLUTION, step=1), diff --git a/comfy_extras/nodes_gits.py b/comfy_extras/nodes_gits.py index d48483862..0b7666524 100644 --- a/comfy_extras/nodes_gits.py +++ b/comfy_extras/nodes_gits.py @@ -340,7 +340,7 @@ class GITSScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="GITSScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Float.Input("coeff", default=1.20, min=0.80, max=1.50, step=0.05, advanced=True), io.Int.Input("steps", default=10, min=2, max=1000), diff --git a/comfy_extras/nodes_lt.py b/comfy_extras/nodes_lt.py index a4c85db77..78c7f14a8 100644 --- a/comfy_extras/nodes_lt.py +++ b/comfy_extras/nodes_lt.py @@ -484,7 +484,7 @@ class LTXVScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="LTXVScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Int.Input("steps", default=20, min=1, max=10000), io.Float.Input("max_shift", default=2.05, min=0.0, max=100.0, step=0.01), diff --git a/comfy_extras/nodes_optimalsteps.py b/comfy_extras/nodes_optimalsteps.py index 73f0104d8..5beeaa7db 100644 --- a/comfy_extras/nodes_optimalsteps.py +++ b/comfy_extras/nodes_optimalsteps.py @@ -31,7 +31,7 @@ class OptimalStepsScheduler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="OptimalStepsScheduler", - category="sampling/custom_sampling/schedulers", + category="sampling/schedulers", inputs=[ io.Combo.Input("model_type", options=["FLUX", "Wan", "Chroma"]), io.Int.Input("steps", default=20, min=3, max=1000), diff --git a/comfy_extras/nodes_void.py b/comfy_extras/nodes_void.py index e7a8f3757..134034ea6 100644 --- a/comfy_extras/nodes_void.py +++ b/comfy_extras/nodes_void.py @@ -392,7 +392,7 @@ class VOIDWarpedNoiseSource(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="VOIDWarpedNoiseSource", - category="sampling/custom_sampling/noise", + category="sampling/noise", inputs=[ io.Latent.Input("warped_noise", tooltip="Warped noise latent from VOIDWarpedNoise"), @@ -454,7 +454,7 @@ class VOIDSampler(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="VOIDSampler", - category="sampling/custom_sampling/samplers", + category="sampling/samplers", inputs=[], outputs=[io.Sampler.Output()], ) From 9479c1e4eb9c407df8d1be1dfb94491edaaf7a2a Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:23:44 +0800 Subject: [PATCH 09/20] Modify description of LoRA loaders --- nodes.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nodes.py b/nodes.py index cbca01c03..6cee47ee1 100644 --- a/nodes.py +++ b/nodes.py @@ -691,7 +691,7 @@ class LoraLoader: FUNCTION = "load_lora" CATEGORY = "loaders" - DESCRIPTION = "LoRAs are used to modify diffusion and CLIP models, altering the way in which latents are denoised such as applying styles. Multiple LoRA nodes can be linked together." + DESCRIPTION = "This LoRA loader is used to modify both diffusion and CLIP models, altering the way in which latents are denoised such as applying styles. Multiple LoRA nodes can be linked together." SEARCH_ALIASES = ["lora", "load lora", "apply lora", "lora loader", "lora model"] def load_lora(self, model, clip, lora_name, strength_model, strength_clip): @@ -721,6 +721,7 @@ class LoraLoaderModelOnly(LoraLoader): "strength_model": ("FLOAT", {"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01}), }} RETURN_TYPES = ("MODEL",) + DESCRIPTION = "This LoRAs loader is used to modify the diffusion model, altering the way in which latents are denoised such as applying styles. Multiple LoRA nodes can be linked together." FUNCTION = "load_lora_model_only" def load_lora_model_only(self, model, lora_name, strength_model): From 9dc3f83edcf7061085b794938b0760d022744393 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:36:41 +0800 Subject: [PATCH 10/20] Fix node id SolidMask --- comfy_extras/nodes_mask.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comfy_extras/nodes_mask.py b/comfy_extras/nodes_mask.py index 50c763d43..846508c98 100644 --- a/comfy_extras/nodes_mask.py +++ b/comfy_extras/nodes_mask.py @@ -195,7 +195,7 @@ class SolidMask(IO.ComfyNode): @classmethod def define_schema(cls): return IO.Schema( - node_id="CreateSolidMask", + node_id="SolidMask", display_name="Create Solid Mask", category="image/mask", inputs=[ From aecbab5b80aad11fd98b9b3b3b7630207007837d Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:44:24 +0800 Subject: [PATCH 11/20] Move VOID Quadmask under image/mask --- comfy_extras/nodes_void.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/comfy_extras/nodes_void.py b/comfy_extras/nodes_void.py index 134034ea6..be724371a 100644 --- a/comfy_extras/nodes_void.py +++ b/comfy_extras/nodes_void.py @@ -122,7 +122,8 @@ class VOIDQuadmaskPreprocess(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="VOIDQuadmaskPreprocess", - category="mask/video", + display_name="VOID Quadmask Preprocessor", + category="image/mask", inputs=[ io.Mask.Input("mask"), io.Int.Input("dilate_width", default=0, min=0, max=50, step=1, From 550064d6076c7c7c9b9231716157c7c33f55b9ac Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:44:39 +0800 Subject: [PATCH 12/20] Group compositing nodes under image/compositing --- comfy_extras/nodes_compositing.py | 6 +++--- comfy_extras/nodes_mask.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/comfy_extras/nodes_compositing.py b/comfy_extras/nodes_compositing.py index 720efc629..8fcbe720e 100644 --- a/comfy_extras/nodes_compositing.py +++ b/comfy_extras/nodes_compositing.py @@ -111,7 +111,7 @@ class PorterDuffImageComposite(io.ComfyNode): node_id="PorterDuffImageComposite", search_aliases=["alpha composite", "blend modes", "layer blend", "transparency blend"], display_name="Porter-Duff Image Composite", - category="mask/compositing", + category="image/compositing", inputs=[ io.Image.Input("source"), io.Mask.Input("source_alpha"), @@ -168,7 +168,7 @@ class SplitImageWithAlpha(io.ComfyNode): node_id="SplitImageWithAlpha", search_aliases=["extract alpha", "separate transparency", "remove alpha"], display_name="Split Image with Alpha", - category="mask/compositing", + category="image/compositing", inputs=[ io.Image.Input("image"), ], @@ -192,7 +192,7 @@ class JoinImageWithAlpha(io.ComfyNode): node_id="JoinImageWithAlpha", search_aliases=["add transparency", "apply alpha", "composite alpha", "RGBA"], display_name="Join Image with Alpha", - category="mask/compositing", + category="image/compositing", inputs=[ io.Image.Input("image"), io.Mask.Input("alpha"), diff --git a/comfy_extras/nodes_mask.py b/comfy_extras/nodes_mask.py index 846508c98..33711c539 100644 --- a/comfy_extras/nodes_mask.py +++ b/comfy_extras/nodes_mask.py @@ -93,7 +93,7 @@ class ImageCompositeMasked(IO.ComfyNode): node_id="ImageCompositeMasked", search_aliases=["overlay", "layer", "paste image", "images composition"], display_name="Image Composite Masked", - category="image", + category="image/compositing", inputs=[ IO.Image.Input("source"), IO.Int.Input("x", default=0, min=0, max=nodes.MAX_RESOLUTION, step=1), From d89896ba5cabd16d58b50b08439e9c670797b284 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:47:47 +0800 Subject: [PATCH 13/20] Move load image as mask to image category for consistency with other load image nodes --- nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nodes.py b/nodes.py index 6cee47ee1..27d186f45 100644 --- a/nodes.py +++ b/nodes.py @@ -1772,7 +1772,7 @@ class LoadImageMask(LoadImage): } } - CATEGORY = "image/mask" + CATEGORY = "image" RETURN_TYPES = ("MASK",) FUNCTION = "load_image_mask" From 3cf628c2e72a98710214f016ae165459cba3f155 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 10:52:38 +0800 Subject: [PATCH 14/20] Align display name with Load Checkpoint --- comfy_extras/nodes_video_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comfy_extras/nodes_video_model.py b/comfy_extras/nodes_video_model.py index 35b3d1ea8..8f19895a1 100644 --- a/comfy_extras/nodes_video_model.py +++ b/comfy_extras/nodes_video_model.py @@ -157,7 +157,7 @@ NODE_CLASS_MAPPINGS = { } NODE_DISPLAY_NAME_MAPPINGS = { - "ImageOnlyCheckpointLoader": "Image Only Checkpoint Loader (img2vid model)", + "ImageOnlyCheckpointLoader": "Load Checkpoint Image Only (img2vid model)", "VideoLinearCFGGuidance": "Video Linear CFG Guidance", "VideoTriangleCFGGuidance": "Video Triangle CFG Guidance", } From e01d4addb1d146e6ce887df7b4f3989c4238c9f0 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 11:04:04 +0800 Subject: [PATCH 15/20] Move dataset category under training category --- comfy_extras/nodes_dataset.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/comfy_extras/nodes_dataset.py b/comfy_extras/nodes_dataset.py index 98ed25d7e..865d302bc 100644 --- a/comfy_extras/nodes_dataset.py +++ b/comfy_extras/nodes_dataset.py @@ -48,7 +48,7 @@ class LoadImageDataSetFromFolderNode(io.ComfyNode): return io.Schema( node_id="LoadImageDataSetFromFolder", display_name="Load Image Dataset from Folder", - category="dataset", + category="training/dataset", is_experimental=True, inputs=[ io.Combo.Input( @@ -85,7 +85,7 @@ class LoadImageTextDataSetFromFolderNode(io.ComfyNode): return io.Schema( node_id="LoadImageTextDataSetFromFolder", display_name="Load Image and Text Dataset from Folder", - category="dataset", + category="training/dataset", is_experimental=True, inputs=[ io.Combo.Input( @@ -207,7 +207,7 @@ class SaveImageDataSetToFolderNode(io.ComfyNode): return io.Schema( node_id="SaveImageDataSetToFolder", display_name="Save Image Dataset to Folder", - category="dataset", + category="training/dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive images as list @@ -247,7 +247,7 @@ class SaveImageTextDataSetToFolderNode(io.ComfyNode): return io.Schema( node_id="SaveImageTextDataSetToFolder", display_name="Save Image and Text Dataset to Folder", - category="dataset", + category="training/dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive both images and texts as lists @@ -403,7 +403,7 @@ class ImageProcessingNode(io.ComfyNode): return io.Schema( node_id=cls.node_id, display_name=cls.display_name or cls.node_id, - category="dataset/image", + category="training/dataset/image", is_experimental=True, is_input_list=is_group, # True for group, False for individual inputs=inputs, @@ -552,7 +552,7 @@ class TextProcessingNode(io.ComfyNode): return io.Schema( node_id=cls.node_id, display_name=cls.display_name or cls.node_id, - category="dataset/text", + category="training/dataset/text", is_experimental=True, is_input_list=is_group, # True for group, False for individual inputs=inputs, @@ -824,7 +824,7 @@ class ShuffleImageTextDatasetNode(io.ComfyNode): return io.Schema( node_id="ShuffleImageTextDataset", display_name="Shuffle Image-Text Dataset", - category="dataset/image", + category="training/dataset/image", is_experimental=True, is_input_list=True, inputs=[ @@ -1143,7 +1143,7 @@ class ResolutionBucket(io.ComfyNode): return io.Schema( node_id="ResolutionBucket", display_name="Resolution Bucket", - category="dataset", + category="training/dataset", is_experimental=True, is_input_list=True, inputs=[ @@ -1236,7 +1236,7 @@ class MakeTrainingDataset(io.ComfyNode): node_id="MakeTrainingDataset", search_aliases=["encode dataset"], display_name="Make Training Dataset", - category="dataset", + category="training/dataset", is_experimental=True, is_input_list=True, # images and texts as lists inputs=[ @@ -1322,7 +1322,7 @@ class SaveTrainingDataset(io.ComfyNode): node_id="SaveTrainingDataset", search_aliases=["export training data"], display_name="Save Training Dataset", - category="dataset", + category="training/dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive lists @@ -1424,7 +1424,7 @@ class LoadTrainingDataset(io.ComfyNode): node_id="LoadTrainingDataset", search_aliases=["import dataset", "training data"], display_name="Load Training Dataset", - category="dataset", + category="training/dataset", is_experimental=True, inputs=[ io.String.Input( From 4bb3b977ea2622627ec511c3c6ccff8d8127ffa8 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Mon, 11 May 2026 11:04:25 +0800 Subject: [PATCH 16/20] Rename Number Convert to Conver Number (verb first) --- comfy_extras/nodes_number_convert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comfy_extras/nodes_number_convert.py b/comfy_extras/nodes_number_convert.py index ab3f2aa8a..e38a33c15 100644 --- a/comfy_extras/nodes_number_convert.py +++ b/comfy_extras/nodes_number_convert.py @@ -20,7 +20,7 @@ class NumberConvertNode(io.ComfyNode): def define_schema(cls) -> io.Schema: return io.Schema( node_id="ComfyNumberConvert", - display_name="Number Convert", + display_name="Convert Number", category="utils", search_aliases=[ "int to float", "float to int", "number convert", From 7001511c2497d17ce9ff83e824a7262a71cb0130 Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Tue, 12 May 2026 14:32:48 +0800 Subject: [PATCH 17/20] Rename Canny node --- comfy_extras/nodes_canny.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comfy_extras/nodes_canny.py b/comfy_extras/nodes_canny.py index 7261b03a1..462f6fea0 100644 --- a/comfy_extras/nodes_canny.py +++ b/comfy_extras/nodes_canny.py @@ -11,7 +11,7 @@ class Canny(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="Canny", - display_name="Detect Canny Edges", + display_name="Detect Edges (Canny)", search_aliases=["edge detection", "outline", "contour detection", "line art"], category="image/filters", essentials_category="Image Tools", From 670fa88bddc9bf2b1bdc5a16bbfeafbe4d7abe1f Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Tue, 12 May 2026 14:53:28 +0800 Subject: [PATCH 18/20] Revert wanBlockSwap + description --- comfy_extras/nodes_nop.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/comfy_extras/nodes_nop.py b/comfy_extras/nodes_nop.py index 6667ec25c..f9c1357c3 100644 --- a/comfy_extras/nodes_nop.py +++ b/comfy_extras/nodes_nop.py @@ -12,9 +12,8 @@ class wanBlockSwap(io.ComfyNode): def define_schema(cls): return io.Schema( node_id="wanBlockSwap", - display_name="WAN Block Swap", - category="model_patches", - description="NOP", + category="", + description="Intercept wanBlockSwap custom node that causes major instability and make it no-op.", inputs=[ io.Model.Input("model"), ], From 3cbc51861bf21ca5838312186568af1230809f1c Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Wed, 13 May 2026 13:59:57 +0800 Subject: [PATCH 19/20] Add description to RemoveBackground node --- comfy_extras/nodes_bg_removal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/comfy_extras/nodes_bg_removal.py b/comfy_extras/nodes_bg_removal.py index 8d046b8d4..793fd802b 100644 --- a/comfy_extras/nodes_bg_removal.py +++ b/comfy_extras/nodes_bg_removal.py @@ -34,6 +34,7 @@ class RemoveBackground(IO.ComfyNode): node_id="RemoveBackground", display_name="Remove Background", category="image/background removal", + description="Generates a foreground mask to remove the background from an image using a background removal model.", inputs=[ IO.Image.Input("image", tooltip="Input image to remove the background from"), IO.BackgroundRemoval.Input("bg_removal_model", tooltip="Background removal model used to generate the mask") From 36c02d5e9a4e857ed305474a047a853a2e5e720b Mon Sep 17 00:00:00 2001 From: Alexis Rolland Date: Thu, 14 May 2026 11:02:29 +0800 Subject: [PATCH 20/20] Revert category update of dataset --- comfy_extras/nodes_dataset.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/comfy_extras/nodes_dataset.py b/comfy_extras/nodes_dataset.py index 865d302bc..98ed25d7e 100644 --- a/comfy_extras/nodes_dataset.py +++ b/comfy_extras/nodes_dataset.py @@ -48,7 +48,7 @@ class LoadImageDataSetFromFolderNode(io.ComfyNode): return io.Schema( node_id="LoadImageDataSetFromFolder", display_name="Load Image Dataset from Folder", - category="training/dataset", + category="dataset", is_experimental=True, inputs=[ io.Combo.Input( @@ -85,7 +85,7 @@ class LoadImageTextDataSetFromFolderNode(io.ComfyNode): return io.Schema( node_id="LoadImageTextDataSetFromFolder", display_name="Load Image and Text Dataset from Folder", - category="training/dataset", + category="dataset", is_experimental=True, inputs=[ io.Combo.Input( @@ -207,7 +207,7 @@ class SaveImageDataSetToFolderNode(io.ComfyNode): return io.Schema( node_id="SaveImageDataSetToFolder", display_name="Save Image Dataset to Folder", - category="training/dataset", + category="dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive images as list @@ -247,7 +247,7 @@ class SaveImageTextDataSetToFolderNode(io.ComfyNode): return io.Schema( node_id="SaveImageTextDataSetToFolder", display_name="Save Image and Text Dataset to Folder", - category="training/dataset", + category="dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive both images and texts as lists @@ -403,7 +403,7 @@ class ImageProcessingNode(io.ComfyNode): return io.Schema( node_id=cls.node_id, display_name=cls.display_name or cls.node_id, - category="training/dataset/image", + category="dataset/image", is_experimental=True, is_input_list=is_group, # True for group, False for individual inputs=inputs, @@ -552,7 +552,7 @@ class TextProcessingNode(io.ComfyNode): return io.Schema( node_id=cls.node_id, display_name=cls.display_name or cls.node_id, - category="training/dataset/text", + category="dataset/text", is_experimental=True, is_input_list=is_group, # True for group, False for individual inputs=inputs, @@ -824,7 +824,7 @@ class ShuffleImageTextDatasetNode(io.ComfyNode): return io.Schema( node_id="ShuffleImageTextDataset", display_name="Shuffle Image-Text Dataset", - category="training/dataset/image", + category="dataset/image", is_experimental=True, is_input_list=True, inputs=[ @@ -1143,7 +1143,7 @@ class ResolutionBucket(io.ComfyNode): return io.Schema( node_id="ResolutionBucket", display_name="Resolution Bucket", - category="training/dataset", + category="dataset", is_experimental=True, is_input_list=True, inputs=[ @@ -1236,7 +1236,7 @@ class MakeTrainingDataset(io.ComfyNode): node_id="MakeTrainingDataset", search_aliases=["encode dataset"], display_name="Make Training Dataset", - category="training/dataset", + category="dataset", is_experimental=True, is_input_list=True, # images and texts as lists inputs=[ @@ -1322,7 +1322,7 @@ class SaveTrainingDataset(io.ComfyNode): node_id="SaveTrainingDataset", search_aliases=["export training data"], display_name="Save Training Dataset", - category="training/dataset", + category="dataset", is_experimental=True, is_output_node=True, is_input_list=True, # Receive lists @@ -1424,7 +1424,7 @@ class LoadTrainingDataset(io.ComfyNode): node_id="LoadTrainingDataset", search_aliases=["import dataset", "training data"], display_name="Load Training Dataset", - category="training/dataset", + category="dataset", is_experimental=True, inputs=[ io.String.Input(