From cffa2f43aa6592eccc44812496bfeb0b10053280 Mon Sep 17 00:00:00 2001 From: Alexander Piskun <13381981+bigcat88@users.noreply.github.com> Date: Thu, 28 May 2026 19:23:51 +0300 Subject: [PATCH 1/5] [Partner Nodes] chore: update the category of the Beeble nodes (#14156) Signed-off-by: bigcat88 --- comfy_api_nodes/nodes_beeble.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/comfy_api_nodes/nodes_beeble.py b/comfy_api_nodes/nodes_beeble.py index 6c0a8f050..f1082884c 100644 --- a/comfy_api_nodes/nodes_beeble.py +++ b/comfy_api_nodes/nodes_beeble.py @@ -206,7 +206,7 @@ class BeebleSwitchXVideoEdit(IO.ComfyNode): return IO.Schema( node_id="BeebleSwitchXVideoEdit", display_name="Beeble SwitchX Video Edit", - category="api node/video/Beeble", + category="video/partner/Beeble", description=( "Edit a video with Beeble SwitchX. Switches anything in the scene (background, " "lighting, costume) while preserving the original subject's pixels and motion. " @@ -302,7 +302,7 @@ class BeebleSwitchXImageEdit(IO.ComfyNode): return IO.Schema( node_id="BeebleSwitchXImageEdit", display_name="Beeble SwitchX Image Edit", - category="api node/image/Beeble", + category="image/partner/Beeble", description=( "Edit a single image with Beeble SwitchX. Switches anything in the scene " "(background, lighting, costume) while preserving the original subject's pixels. " From 6ceec29bd124877cb79a8732b32967f44dad9230 Mon Sep 17 00:00:00 2001 From: Charles Chan Date: Fri, 29 May 2026 01:12:04 +0800 Subject: [PATCH 2/5] feat: add overwrite/increment to SaveImageTextDataSetToFolderNode (#13215) --- comfy_extras/nodes_dataset.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/comfy_extras/nodes_dataset.py b/comfy_extras/nodes_dataset.py index 35a164ec8..104d16d91 100644 --- a/comfy_extras/nodes_dataset.py +++ b/comfy_extras/nodes_dataset.py @@ -157,7 +157,7 @@ class LoadImageTextDataSetFromFolderNode(io.ComfyNode): return io.NodeOutput(output_tensor, captions) -def save_images_to_folder(image_list, output_dir, prefix="image"): +def save_images_to_folder(image_list, output_dir, prefix="image", overwrite=True): """Utility function to save a list of image tensors to disk. Args: @@ -197,7 +197,11 @@ def save_images_to_folder(image_list, output_dir, prefix="image"): raise ValueError(f"Expected torch.Tensor, got {type(img_tensor)}") # Save image - filename = f"{prefix}_{idx:05d}.png" + if overwrite: + filename = f"{prefix}_{idx:05d}.png" + else: + _, _, counter, _, resolved_prefix = folder_paths.get_save_image_path(prefix, output_dir) + filename = f"{resolved_prefix}_{counter:05}_{idx:05d}.png" filepath = os.path.join(output_dir, filename) img.save(filepath) saved_files.append(filename) @@ -230,19 +234,26 @@ class SaveImageDataSetToFolderNode(io.ComfyNode): tooltip="Prefix for saved image filenames.", advanced=True, ), + io.Combo.Input( + "mode", + default="overwrite", + options=["overwrite", "increment"], + tooltip="Whether to overwrite existing files or increment filenames to avoid overwriting." + ), ], outputs=[], is_deprecated=True, # This node is redundant and superseded by existing Save Image nodes where the target folder can be specified in the filename_prefix ) @classmethod - def execute(cls, images, folder_name, filename_prefix): + def execute(cls, images, folder_name, filename_prefix, mode): # Extract scalar values folder_name = folder_name[0] filename_prefix = filename_prefix[0] + mode = mode[0] output_dir = os.path.join(folder_paths.get_output_directory(), folder_name) - saved_files = save_images_to_folder(images, output_dir, filename_prefix) + saved_files = save_images_to_folder(images, output_dir, filename_prefix, mode=='overwrite') logging.info(f"Saved {len(saved_files)} images to {output_dir}.") return io.NodeOutput() @@ -278,18 +289,25 @@ class SaveImageTextDataSetToFolderNode(io.ComfyNode): tooltip="Prefix for saved image filenames.", advanced=True, ), + io.Combo.Input( + "mode", + default="overwrite", + options=["overwrite", "increment"], + tooltip="Whether to overwrite existing files or increment filenames to avoid overwriting." + ), ], outputs=[], ) @classmethod - def execute(cls, images, folder_name, filename_prefix, texts=None): + def execute(cls, images, folder_name, filename_prefix, mode, texts=None): # Extract scalar values folder_name = folder_name[0] filename_prefix = filename_prefix[0] + mode = mode[0] output_dir = os.path.join(folder_paths.get_output_directory(), folder_name) - saved_files = save_images_to_folder(images, output_dir, filename_prefix) + saved_files = save_images_to_folder(images, output_dir, filename_prefix, mode=='overwrite') # Save captions if texts: From 6dd3c67427d65751d42f2dbc0c3db3d829c697de Mon Sep 17 00:00:00 2001 From: Luke Mino-Altherr Date: Thu, 28 May 2026 15:07:22 -0700 Subject: [PATCH 3/5] Add unreviewed merge detector for SOC 2 compliance (#14146) --- .github/workflows/detect-unreviewed-merge.yml | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/detect-unreviewed-merge.yml diff --git a/.github/workflows/detect-unreviewed-merge.yml b/.github/workflows/detect-unreviewed-merge.yml new file mode 100644 index 000000000..4fabecb94 --- /dev/null +++ b/.github/workflows/detect-unreviewed-merge.yml @@ -0,0 +1,24 @@ +name: Detect Unreviewed Merge + +# SOC 2 compliance — reusable workflow lives in Comfy-Org/github-workflows, +# tracking issues are filed in Comfy-Org/unreviewed-merges. + +on: + push: + branches: [master] + +concurrency: + group: detect-unreviewed-merge-${{ github.sha }} + cancel-in-progress: false + +permissions: + contents: read + pull-requests: read + +jobs: + detect: + uses: Comfy-Org/github-workflows/.github/workflows/detect-unreviewed-merge.yml@4d9cb6b87f953bb7cd69954280e1465fb9bd2040 # v1 + with: + approval-mode: latest-per-reviewer + secrets: + UNREVIEWED_MERGES_TOKEN: ${{ secrets.UNREVIEWED_MERGES_TOKEN }} From bcf805aaea6dd1935ceaa09d40700e2e93ce60c7 Mon Sep 17 00:00:00 2001 From: comfyanonymous <121283862+comfyanonymous@users.noreply.github.com> Date: Thu, 28 May 2026 17:38:01 -0700 Subject: [PATCH 4/5] Bump pyav package to fix some image loading issues. (#14160) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 9308e29d4..e76ed0034 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,7 +21,7 @@ psutil alembic SQLAlchemy>=2.0.0 filelock -av>=14.2.0 +av>=16.0.0 comfy-kitchen>=0.2.8 comfy-aimdo==0.4.5 requests From 26aad73cd7351822243f94a718e7a0e754dc4dcb Mon Sep 17 00:00:00 2001 From: Terry Jia Date: Thu, 28 May 2026 20:42:47 -0400 Subject: [PATCH 5/5] refactor: drop rotation from Load3DCamera (#14159) --- comfy_api/latest/_io.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/comfy_api/latest/_io.py b/comfy_api/latest/_io.py index e430c0ecf..fed8dc7f0 100644 --- a/comfy_api/latest/_io.py +++ b/comfy_api/latest/_io.py @@ -762,17 +762,17 @@ class Accumulation(ComfyTypeIO): @comfytype(io_type="LOAD3D_CAMERA") class Load3DCamera(ComfyTypeIO): class CameraInfo(TypedDict): - position: dict[str, float | int] - target: dict[str, float | int] - zoom: int - cameraType: str - quaternion: NotRequired[dict[str, float | int]] - rotation: NotRequired[dict[str, float | int | str]] - fov: NotRequired[float | int] - aspect: NotRequired[float | int] - near: NotRequired[float | int] - far: NotRequired[float | int] - frustum: NotRequired[dict[str, float | int]] + # Coordinate system: right-handed, Y-up, camera looks down -Z + position: dict[str, float | int] # scene units + target: dict[str, float | int] # scene units; OrbitControls focus point + zoom: float | int # dimensionless, 1 = 100% + cameraType: str # 'perspective' | 'orthographic' + quaternion: NotRequired[dict[str, float | int]] # normalized, dimensionless; camera world rotation + fov: NotRequired[float | int] # degrees, vertical FOV (perspective only) + aspect: NotRequired[float | int] # width / height (perspective only) + near: NotRequired[float | int] # scene units + far: NotRequired[float | int] # scene units + frustum: NotRequired[dict[str, float | int]] # orthographic only: {left, right, top, bottom} in scene units Type = CameraInfo