Compare commits

..

32 Commits

Author SHA1 Message Date
bymyself
49549ddcb8 [feat] Implement comprehensive batch tracking and OpenAPI-driven data models
Enhances ComfyUI Manager with robust batch execution tracking and unified data model architecture:

- Implemented automatic batch history serialization with before/after system state snapshots
- Added comprehensive state management capturing installed nodes, models, and ComfyUI version info
- Enhanced task queue with proper client ID handling and WebSocket notifications
- Migrated all data models to OpenAPI-generated Pydantic models for consistency
- Added documentation for new TaskQueue methods (done_count, total_count, finalize)
- Fixed 64 linting errors with proper imports and code cleanup

Technical improvements:
- All models now auto-generated from openapi.yaml ensuring API/implementation consistency
- Batch tracking captures complete system state at operation start and completion
- Enhanced REST endpoints with comprehensive documentation
- Removed manual model files in favor of single source of truth
- Added helper methods for system state capture and batch lifecycle management
2025-06-08 01:18:14 -07:00
bymyself
35eddc2965 [feat] Add client_id support to task queue system
- Add client_id field to QueueTaskItem and TaskHistoryItem models
- Implement client-specific WebSocket message routing
- Add client filtering to queue status and history endpoints
- Follow ComfyUI patterns for session management
- Create data_models package for better code organization
2025-06-06 16:01:52 -07:00
Dr.Lt.Data
798b203274 fixed: cm_global importing error 2025-06-06 16:00:45 -07:00
Dr.Lt.Data
9d2034bd4f fixed: crash related to deleted CNR node after installed
modified: convert cm-cli.sh to cm-cli command
2025-06-06 16:00:45 -07:00
Dr.Lt.Data
6233fabe02 modified: glob.core - make default network mode as public.
Network mode does not simply determine whether the CNR cache is used. Even after switching to cacheless in the future, it will continue to be used as a policy for user environments.
2025-06-06 16:00:45 -07:00
Dr.Lt.Data
48ba2f4b4c fixed: missing channels.list.template
modified: /ltdrdata -> /Comfy-Org
modified: set default network as public instead of offline
2025-06-06 16:00:45 -07:00
Dr.Lt.Data
3799af0017 fixed: perform reload when starting task worker 2025-06-06 16:00:45 -07:00
Dr.Lt.Data
403947a5d1 modified: prevent displaying ComfyUI-Manager on list 2025-06-06 16:00:45 -07:00
Dr.Lt.Data
276ccca4f6 fixed: avoid except:
fixed: prestartup_script - remove useless exception handling when fallback resolving comfy_path
2025-06-06 16:00:45 -07:00
Christian Byrne
31de92a7ef Add is_legacy_manager_ui route from the legacy package as well (#1748)
* add `is_legacy_manager_ui` route to `legacy` package  as well

* add static
2025-06-06 16:00:45 -07:00
Christian Byrne
3ae4aecd84 Only load legacy FE extension if --enable-manager-legacy-ui is set (#1746)
* only load JS extensions when legacy arg is set

* add `is_legacy_manager_ui` endpoint
2025-06-06 16:00:45 -07:00
Dr.Lt.Data
7896949719 use --enable-manager-legacy-ui cli arg instead of env variable 2025-06-06 16:00:45 -07:00
Dr.Lt.Data
86c7482048 restructuring
the existing cache-based implementation will be retained as a fallback under legacy/..., while glob/... will be updated to a cacheless implementation.
2025-06-06 16:00:45 -07:00
Christian Byrne
0146655f0f add development guide (#1739) 2025-06-06 15:59:20 -07:00
Dr.Lt.Data
89bb61fb05 fixed: don't disable legacy ComfyUI-Manager unless --disable-comfyui is set 2025-06-06 15:59:20 -07:00
bymyself
dfd9a3ec7b use parsed version and id even when no cnr map exists 2025-06-06 15:59:20 -07:00
bymyself
985c987603 fix: installed nodes should still be initialized in offline mode 2025-06-06 15:59:20 -07:00
bymyself
1ce35679b1 fix is_legacy_front should be a function still 2025-06-06 15:59:20 -07:00
bymyself
6e1c906aff if pip package, force offline mode 2025-06-06 15:59:20 -07:00
bymyself
cd8e87a3fb don't load legacy web dir when --disable-manager arg set 2025-06-06 15:59:20 -07:00
bymyself
8b9420731a enable legacy manager frontend during beta phase 2025-06-06 15:59:14 -07:00
bymyself
d9918cf773 add missing v2 prefix to customnode/installed route 2025-06-06 15:58:56 -07:00
bymyself
163782e445 don't handle queue in legacy front if element is not visible 2025-06-06 15:58:56 -07:00
bymyself
ad14e1ed13 don't show menu buttons if past comfyui front 1.16 2025-06-06 15:58:56 -07:00
bymyself
b4392293fa add workflow to publish to pypi 2025-06-06 15:58:56 -07:00
Dr.Lt.Data
e8ff505ebf Modify the structure to be installable via pip. 2025-06-06 15:58:56 -07:00
Dr.Lt.Data
8a5226b1d4 added: should_be_disabled function 2025-06-06 15:57:08 -07:00
Dr.Lt.Data
422af67217 fixed: ruff check 2025-06-06 15:57:08 -07:00
Dr.Lt.Data
5c300f75e7 fixed: failed[..].ui_id -> failed 2025-06-06 15:57:08 -07:00
Dr.Lt.Data
5ea7bf3683 feat: support task batch
POST /v2/manager/queue/batch
GET /v2/manager/queue/history_list
GET /v2/manager/queue/history?id={id}
GET /v2/manager/queue/abort_current
2025-06-06 15:57:08 -07:00
Dr.Lt.Data
34efbe9262 Modify the structure to be installable via pip. 2025-06-06 15:57:08 -07:00
Dr.Lt.Data
9d24038a7d support installation of system added nodepack
modified: install_by_id - Change the install path of the CNR node added by the system to be based on the repo URL instead of the CNR ID.
2025-06-06 15:54:38 -07:00
34 changed files with 5123 additions and 6339 deletions

View File

@@ -1,70 +0,0 @@
name: CI
on:
push:
branches: [ main, feat/*, fix/* ]
pull_request:
branches: [ main ]
jobs:
validate-openapi:
name: Validate OpenAPI Specification
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check if OpenAPI changed
id: openapi-changed
uses: tj-actions/changed-files@v44
with:
files: openapi.yaml
- name: Setup Node.js
if: steps.openapi-changed.outputs.any_changed == 'true'
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install Redoc CLI
if: steps.openapi-changed.outputs.any_changed == 'true'
run: |
npm install -g @redocly/cli
- name: Validate OpenAPI specification
if: steps.openapi-changed.outputs.any_changed == 'true'
run: |
redocly lint openapi.yaml
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for proper diff
- name: Get changed Python files
id: changed-py-files
uses: tj-actions/changed-files@v44
with:
files: |
**/*.py
files_ignore: |
comfyui_manager/legacy/**
- name: Setup Python
if: steps.changed-py-files.outputs.any_changed == 'true'
uses: actions/setup-python@v5
with:
python-version: '3.9'
- name: Install dependencies
if: steps.changed-py-files.outputs.any_changed == 'true'
run: |
pip install ruff
- name: Run ruff linting on changed files
if: steps.changed-py-files.outputs.any_changed == 'true'
run: |
echo "Changed files: ${{ steps.changed-py-files.outputs.all_changed_files }}"
echo "${{ steps.changed-py-files.outputs.all_changed_files }}" | xargs -r ruff check

1
.gitignore vendored
View File

@@ -19,6 +19,5 @@ pip_overrides.json
check2.sh
/venv/
build
dist
*.egg-info
.env

View File

@@ -676,7 +676,7 @@ def install(
cmd_ctx.set_channel_mode(channel, mode)
cmd_ctx.set_no_deps(no_deps)
pip_fixer = manager_util.PIPFixer(manager_util.get_installed_packages(), comfy_path, context.manager_files_path)
pip_fixer = manager_util.PIPFixer(manager_util.get_installed_packages(), comfy_path, core.manager_files_path)
for_each_nodes(nodes, act=install_node, exit_on_fail=exit_on_fail)
pip_fixer.fix_broken()

View File

@@ -1,16 +0,0 @@
# ComfyUI-Manager: Core Backend (glob)
This directory contains the Python backend modules that power ComfyUI-Manager, handling the core functionality of node management, downloading, security, and server operations.
## Core Modules
- **manager_downloader.py**: Handles downloading operations for models, extensions, and other resources.
- **manager_util.py**: Provides utility functions used throughout the system.
## Specialized Modules
- **cm_global.py**: Maintains global variables and state management across the system.
- **cnr_utils.py**: Helper utilities for interacting with the custom node registry (CNR).
- **git_utils.py**: Git-specific utilities for repository operations.
- **node_package.py**: Handles the packaging and installation of node extensions.
- **security_check.py**: Implements the multi-level security system for installation safety.

View File

@@ -46,8 +46,6 @@ def git_url(fullpath):
for k, v in config.items():
if k.startswith('remote ') and 'url' in v:
if 'Comfy-Org/ComfyUI-Manager' in v['url']:
return "https://github.com/ltdrdata/ComfyUI-Manager"
return v['url']
return None

View File

@@ -42,13 +42,7 @@ from .generated_models import (
ManagerPackInstallType,
ManagerPack,
InstallPackParams,
UpdatePackParams,
UpdateAllPacksParams,
UpdateComfyUIParams,
FixPackParams,
UninstallPackParams,
DisablePackParams,
EnablePackParams,
QueueStatus,
ManagerMappings,
ModelMetadata,
@@ -97,13 +91,7 @@ __all__ = [
"ManagerPackInstallType",
"ManagerPack",
"InstallPackParams",
"UpdatePackParams",
"UpdateAllPacksParams",
"UpdateComfyUIParams",
"FixPackParams",
"UninstallPackParams",
"DisablePackParams",
"EnablePackParams",
"QueueStatus",
"ManagerMappings",
"ModelMetadata",

View File

@@ -1,6 +1,6 @@
# generated by datamodel-codegen:
# filename: openapi.yaml
# timestamp: 2025-06-14T01:44:21+00:00
# timestamp: 2025-06-08T08:07:38+00:00
from __future__ import annotations
@@ -23,6 +23,12 @@ class Kind(str, Enum):
install_model = 'install-model'
class QueueTaskItem(BaseModel):
ui_id: str = Field(..., description='Unique identifier for the task')
client_id: str = Field(..., description='Client identifier that initiated the task')
kind: Kind = Field(..., description='Type of task being performed')
class StatusStr(str, Enum):
success = 'success'
error = 'error'
@@ -99,7 +105,7 @@ class ManagerPackInstallType(str, Enum):
cnr = 'cnr'
class UpdateState(Enum):
class UpdateState(str, Enum):
false = 'false'
true = 'true'
@@ -148,49 +154,6 @@ class UpdateAllPacksParams(BaseModel):
ui_id: Optional[str] = Field(None, description='Task ID - generated internally')
class UpdatePackParams(BaseModel):
node_name: str = Field(..., description='Name of the node package to update')
node_ver: Optional[str] = Field(
None, description='Current version of the node package'
)
class UpdateComfyUIParams(BaseModel):
is_stable: Optional[bool] = Field(
True,
description='Whether to update to stable version (true) or nightly (false)',
)
target_version: Optional[str] = Field(
None,
description='Specific version to switch to (for version switching operations)',
)
class FixPackParams(BaseModel):
node_name: str = Field(..., description='Name of the node package to fix')
node_ver: str = Field(..., description='Version of the node package')
class UninstallPackParams(BaseModel):
node_name: str = Field(..., description='Name of the node package to uninstall')
is_unknown: Optional[bool] = Field(
False, description='Whether this is an unknown/unregistered package'
)
class DisablePackParams(BaseModel):
node_name: str = Field(..., description='Name of the node package to disable')
is_unknown: Optional[bool] = Field(
False, description='Whether this is an unknown/unregistered package'
)
class EnablePackParams(BaseModel):
cnr_id: str = Field(
..., description='ComfyUI Node Registry ID of the package to enable'
)
class QueueStatus(BaseModel):
total_count: int = Field(
..., description='Total number of tasks (pending + running)'
@@ -206,16 +169,14 @@ class QueueStatus(BaseModel):
)
class ManagerMappings1(BaseModel):
class ManagerMapping(BaseModel):
title_aux: Optional[str] = Field(None, description='The display name of the pack')
class ManagerMappings(
RootModel[Optional[Dict[str, List[Union[List[str], ManagerMappings1]]]]]
RootModel[Optional[Dict[str, List[Union[List[str], ManagerMapping]]]]]
):
root: Optional[Dict[str, List[Union[List[str], ManagerMappings1]]]] = Field(
None, description='Tuple of [node_names, metadata]'
)
root: Optional[Dict[str, List[Union[List[str], ManagerMapping]]]] = None
class ModelMetadata(BaseModel):
@@ -397,23 +358,6 @@ class BatchExecutionRecord(BaseModel):
)
class QueueTaskItem(BaseModel):
ui_id: str = Field(..., description='Unique identifier for the task')
client_id: str = Field(..., description='Client identifier that initiated the task')
kind: Kind = Field(..., description='Type of task being performed')
params: Union[
InstallPackParams,
UpdatePackParams,
UpdateAllPacksParams,
UpdateComfyUIParams,
FixPackParams,
UninstallPackParams,
DisablePackParams,
EnablePackParams,
ModelMetadata,
]
class TaskHistoryItem(BaseModel):
ui_id: str = Field(..., description='Unique identifier for the task')
client_id: str = Field(..., description='Client identifier that initiated the task')
@@ -433,9 +377,6 @@ class TaskStateMessage(BaseModel):
pending_queue: List[QueueTaskItem] = Field(
..., description='Tasks waiting to be executed'
)
installed_packs: Dict[str, ManagerPackInstalled] = Field(
..., description='Map of currently installed node packages by name'
)
class MessageTaskDone(BaseModel):

View File

@@ -1,10 +0,0 @@
- Anytime you make a change to the data being sent or received, you should follow this process:
1. Adjust the openapi.yaml file first
2. Verify the syntax of the openapi.yaml file using `yaml.safe_load`
3. Regenerate the types following the instructions in the `data_models/README.md` file
4. Verify the new data model is generated
5. Verify the syntax of the generated types files
6. Run formatting and linting on the generated types files
7. Adjust the `__init__.py` files in the `data_models` directory to match/export the new data model
8. Only then, make the changes to the rest of the codebase
9. Run the CI tests to verify that the changes are working

View File

@@ -2,16 +2,20 @@
This directory contains the Python backend modules that power ComfyUI-Manager, handling the core functionality of node management, downloading, security, and server operations.
## Directory Structure
- **glob/** - code for new cacheless ComfyUI-Manager
- **legacy/** - code for legacy ComfyUI-Manager
## Core Modules
- **manager_core.py**: The central implementation of management functions, handling configuration, installation, updates, and node management.
- **manager_server.py**: Implements server functionality and API endpoints for the web interface to interact with the backend.
- **manager_downloader.py**: Handles downloading operations for models, extensions, and other resources.
- **manager_util.py**: Provides utility functions used throughout the system.
## Specialized Modules
- **cm_global.py**: Maintains global variables and state management across the system.
- **cnr_utils.py**: Helper utilities for interacting with the custom node registry (CNR).
- **git_utils.py**: Git-specific utilities for repository operations.
- **node_package.py**: Handles the packaging and installation of node extensions.
- **security_check.py**: Implements the multi-level security system for installation safety.
- **share_3rdparty.py**: Manages integration with third-party sharing platforms.
## Architecture

View File

@@ -150,6 +150,82 @@ def check_invalid_nodes():
print("\n---------------------------------------------------------------------------\n")
# read env vars
comfy_path: str = os.environ.get('COMFYUI_PATH')
comfy_base_path = os.environ.get('COMFYUI_FOLDERS_BASE_PATH')
if comfy_path is None:
try:
comfy_path = os.path.abspath(os.path.dirname(sys.modules['__main__'].__file__))
os.environ['COMFYUI_PATH'] = comfy_path
except:
logging.error("[ComfyUI-Manager] environment variable 'COMFYUI_PATH' is not specified.")
exit(-1)
if comfy_base_path is None:
comfy_base_path = comfy_path
channel_list_template_path = os.path.join(manager_util.comfyui_manager_path, 'channels.list.template')
git_script_path = os.path.join(manager_util.comfyui_manager_path, "git_helper.py")
manager_files_path = None
manager_config_path = None
manager_channel_list_path = None
manager_startup_script_path:str = None
manager_snapshot_path = None
manager_pip_overrides_path = None
manager_pip_blacklist_path = None
manager_components_path = None
manager_batch_history_path = None
def update_user_directory(user_dir):
global manager_files_path
global manager_config_path
global manager_channel_list_path
global manager_startup_script_path
global manager_snapshot_path
global manager_pip_overrides_path
global manager_pip_blacklist_path
global manager_components_path
global manager_batch_history_path
manager_files_path = os.path.abspath(os.path.join(user_dir, 'default', 'ComfyUI-Manager'))
if not os.path.exists(manager_files_path):
os.makedirs(manager_files_path)
manager_snapshot_path = os.path.join(manager_files_path, "snapshots")
if not os.path.exists(manager_snapshot_path):
os.makedirs(manager_snapshot_path)
manager_startup_script_path = os.path.join(manager_files_path, "startup-scripts")
if not os.path.exists(manager_startup_script_path):
os.makedirs(manager_startup_script_path)
manager_config_path = os.path.join(manager_files_path, 'config.ini')
manager_channel_list_path = os.path.join(manager_files_path, 'channels.list')
manager_pip_overrides_path = os.path.join(manager_files_path, "pip_overrides.json")
manager_pip_blacklist_path = os.path.join(manager_files_path, "pip_blacklist.list")
manager_components_path = os.path.join(manager_files_path, "components")
manager_util.cache_dir = os.path.join(manager_files_path, "cache")
manager_batch_history_path = os.path.join(manager_files_path, "batch_history")
if not os.path.exists(manager_util.cache_dir):
os.makedirs(manager_util.cache_dir)
if not os.path.exists(manager_batch_history_path):
os.makedirs(manager_batch_history_path)
try:
import folder_paths
update_user_directory(folder_paths.get_user_directory())
except Exception:
# fallback:
# This case is only possible when running with cm-cli, and in practice, this case is not actually used.
update_user_directory(os.path.abspath(manager_util.comfyui_manager_path))
cached_config = None
js_path = None

View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ import git
import logging
import traceback
from comfyui_manager.common import context
from comfyui_manager.common import context, manager_util
import folder_paths
from comfy.cli_args import args
import latent_preview
@@ -125,18 +125,17 @@ def initialize_environment():
context.comfy_path = os.path.dirname(folder_paths.__file__)
core.js_path = os.path.join(context.comfy_path, "web", "extensions")
# Legacy database paths - kept for potential future use
# local_db_model = os.path.join(manager_util.comfyui_manager_path, "model-list.json")
# local_db_alter = os.path.join(manager_util.comfyui_manager_path, "alter-list.json")
# local_db_custom_node_list = os.path.join(
# manager_util.comfyui_manager_path, "custom-node-list.json"
# )
# local_db_extension_node_mappings = os.path.join(
# manager_util.comfyui_manager_path, "extension-node-map.json"
# )
local_db_model = os.path.join(manager_util.comfyui_manager_path, "model-list.json")
local_db_alter = os.path.join(manager_util.comfyui_manager_path, "alter-list.json")
local_db_custom_node_list = os.path.join(
manager_util.comfyui_manager_path, "custom-node-list.json"
)
local_db_extension_node_mappings = os.path.join(
manager_util.comfyui_manager_path, "extension-node-map.json"
)
set_preview_method(core.get_config()["preview_method"])
print_comfyui_version()
environment_utils.print_comfyui_version()
setup_environment()
core.check_invalid_nodes()

View File

@@ -1,6 +1,5 @@
import locale
import sys
import re
def handle_stream(stream, prefix):
@@ -20,41 +19,3 @@ def handle_stream(stream, prefix):
print(prefix, msg, end="", file=sys.stderr)
else:
print(prefix, msg, end="")
def convert_markdown_to_html(input_text):
pattern_a = re.compile(r"\[a/([^]]+)]\(([^)]+)\)")
pattern_w = re.compile(r"\[w/([^]]+)]")
pattern_i = re.compile(r"\[i/([^]]+)]")
pattern_bold = re.compile(r"\*\*([^*]+)\*\*")
pattern_white = re.compile(r"%%([^*]+)%%")
def replace_a(match):
return f"<a href='{match.group(2)}' target='blank'>{match.group(1)}</a>"
def replace_w(match):
return f"<p class='cm-warn-note'>{match.group(1)}</p>"
def replace_i(match):
return f"<p class='cm-info-note'>{match.group(1)}</p>"
def replace_bold(match):
return f"<B>{match.group(1)}</B>"
def replace_white(match):
return f"<font color='white'>{match.group(1)}</font>"
input_text = (
input_text.replace("\\[", "&#91;")
.replace("\\]", "&#93;")
.replace("<", "&lt;")
.replace(">", "&gt;")
)
result_text = re.sub(pattern_a, replace_a, input_text)
result_text = re.sub(pattern_w, replace_w, result_text)
result_text = re.sub(pattern_i, replace_i, result_text)
result_text = re.sub(pattern_bold, replace_bold, result_text)
result_text = re.sub(pattern_white, replace_white, result_text)
return result_text.replace("\n", "<BR>")

View File

@@ -3,7 +3,6 @@ import logging
import folder_paths
from comfyui_manager.glob import manager_core as core
from comfyui_manager.glob.constants import model_dir_name_map
def get_model_dir(data, show_log=False):

View File

@@ -1,18 +1,7 @@
from comfyui_manager.glob import manager_core as core
from comfy.cli_args import args
def is_loopback(address):
import ipaddress
try:
return ipaddress.ip_address(address).is_loopback
except ValueError:
return False
def is_allowed_security_level(level):
is_local_mode = is_loopback(args.listen)
if level == "block":
return False
elif level == "high":

View File

@@ -223,7 +223,7 @@ function isBeforeFrontendVersion(compareVersion) {
}
const is_legacy_front = () => isBeforeFrontendVersion('1.2.49');
const isNotNewManagerUI = () => isBeforeFrontendVersion('1.16.4');
const isNewManagerUI = () => isBeforeFrontendVersion('1.16.4');
document.head.appendChild(docStyle);
@@ -478,9 +478,9 @@ async function updateComfyUI() {
// set_inprogress_mode();
showTerminal();
batch_id = generateUUID();
let batch = {};
batch['batch_id'] = batch_id;
batch['update_comfyui'] = true;
@@ -667,13 +667,13 @@ async function onQueueStatus(event) {
update_all_button.innerText = `in progress.. (${event.detail.done_count}/${event.detail.total_count})`;
}
else if(event.detail.status == 'all-done') {
reset_action_buttons();
// reset_action_buttons();
}
else if(event.detail.status == 'batch-done') {
if(batch_id != event.detail.batch_id) {
return;
}
let success_list = [];
let failed_list = [];
let comfyui_state = null;
@@ -780,7 +780,7 @@ async function updateAll(update_comfyui) {
showTerminal();
batch_id = generateUUID();
let batch = {};
if(update_comfyui) {
update_all_button.innerText = "Updating ComfyUI...";
@@ -1518,7 +1518,7 @@ app.registerExtension({
}).element
);
const shouldShowLegacyMenuItems = isNotNewManagerUI();
const shouldShowLegacyMenuItems = !isNewManagerUI();
if (shouldShowLegacyMenuItems) {
app.menu?.settingsGroup.element.before(cmGroup.element);
}

View File

@@ -1534,7 +1534,7 @@ export class CustomNodesManager {
else {
this.batch_id = generateUUID();
batch['batch_id'] = this.batch_id;
const res = await api.fetchApi(`/v2/manager/queue/batch`, {
method: 'POST',
body: JSON.stringify(batch)
@@ -1549,7 +1549,7 @@ export class CustomNodesManager {
errorMsg = `[FAIL] ${item.title}`;
}
}
this.showStop();
showTerminal();
}

View File

@@ -113,17 +113,11 @@ read_config()
read_uv_mode()
check_file_logging()
if sys.version_info < (3, 13):
cm_global.pip_overrides = {'numpy': 'numpy<2'}
else:
cm_global.pip_overrides = {}
cm_global.pip_overrides = {'numpy': 'numpy<2'}
if os.path.exists(manager_pip_overrides_path):
with open(manager_pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
cm_global.pip_overrides = json.load(json_file)
if sys.version_info < (3, 13):
cm_global.pip_overrides['numpy'] = 'numpy<2'
cm_global.pip_overrides['numpy'] = 'numpy<2'
if os.path.exists(manager_pip_blacklist_path):
@@ -336,12 +330,7 @@ try:
log_file.write(message)
else:
log_file.write(f"[{timestamp}] {message}")
try:
log_file.flush()
except Exception:
pass
log_file.flush()
self.last_char = message if message == '' else message[-1]
if not file_only:
@@ -354,10 +343,7 @@ try:
original_stderr.flush()
def flush(self):
try:
log_file.flush()
except Exception:
pass
log_file.flush()
with std_log_lock:
if self.is_stdout:

View File

@@ -2578,17 +2578,6 @@
"install_type": "git-clone",
"description": "Nodes: OTX Multiple Values, OTX KSampler Feeder. This extension provides custom nodes for ComfyUI created for personal projects. Made available for reference. Nodes may be updated or changed intermittently or not at all. Review & test before use."
},
{
"author": "budihartono",
"title": "CAS Aspect Ratio Presets Node for ComfyUI",
"id": "comfyui-aspect-ratio-presets",
"reference": "https://github.com/budihartono/comfyui-aspect-ratio-presets",
"files": [
"https://github.com/budihartono/comfyui-aspect-ratio-presets"
],
"install_type": "git-clone",
"description": "Quickly create empty latents in common resolutions and aspect ratios for SD 1.5, SDXL, Flux, Chroma, and HiDream. Choose from curated presets or generate by axis and aspect ratio. Appears in the 'latent' node group."
},
{
"author": "ramyma",
"title": "A8R8 ComfyUI Nodes",
@@ -3607,7 +3596,6 @@
"title": "comfyui-mixlab-nodes",
"id": "mixlab",
"reference": "https://github.com/shadowcz007/comfyui-mixlab-nodes",
"reference2": "https://github.com/MixLabPro/comfyui-mixlab-nodes",
"files": [
"https://github.com/shadowcz007/comfyui-mixlab-nodes"
],
@@ -3651,7 +3639,6 @@
"title": "comfyui-sound-lab",
"id": "soundlab",
"reference": "https://github.com/shadowcz007/comfyui-sound-lab",
"reference2": "https://github.com/MixLabPro/comfyui-sound-lab",
"files": [
"https://github.com/shadowcz007/comfyui-sound-lab"
],
@@ -3674,7 +3661,6 @@
"title": "comfyui-liveportrait",
"id": "liveportrait",
"reference": "https://github.com/shadowcz007/comfyui-liveportrait",
"reference2": "https://github.com/MixLabPro/comfyui-liveportrait",
"files": [
"https://github.com/shadowcz007/comfyui-liveportrait"
],
@@ -3995,16 +3981,6 @@
"install_type": "git-clone",
"description": "A matting toolkit based on ComfyUI, supporting multiple matting models and detail processing methods."
},
{
"author": "whmc76",
"title": "ComfyUI-UniversalToolkit",
"reference": "https://github.com/whmc76/ComfyUI-UniversalToolkit",
"files": [
"https://github.com/whmc76/ComfyUI-UniversalToolkit"
],
"install_type": "git-clone",
"description": "This plugin provides general-purpose utility nodes for ComfyUI. Currently, it implements a 'Blank Cell Generator' node, which can batch-generate images, masks, and latents with specified resolution and color."
},
{
"author": "martijnat",
"title": "comfyui-previewlatent",
@@ -8369,7 +8345,6 @@
"author": "kuschanow",
"title": "Advanced Latent Control",
"reference": "https://github.com/RomanKuschanow/ComfyUI-Advanced-Latent-Control",
"reference2": "https://github.com/kuschanow/ComfyUI-Advanced-Latent-Control",
"files": [
"https://github.com/RomanKuschanow/ComfyUI-Advanced-Latent-Control"
],
@@ -11272,7 +11247,6 @@
"title": "comfyui_tag_filter",
"id": "tag-filter",
"reference": "https://github.com/sugarkwork/comfyui_tag_fillter",
"reference2": "https://github.com/sugarkwork/comfyui_tag_filter",
"files": [
"https://github.com/sugarkwork/comfyui_tag_fillter"
],
@@ -11911,7 +11885,6 @@
"title": "ComfyUI-Embeddings-Tools",
"id": "embeddings-tools",
"reference": "https://github.com/ZeDarkAdam/ComfyUI-Embeddings-Tools",
"reference2": "https://github.com/ZDAVanO/ComfyUI-Embeddings-Tools",
"files": [
"https://github.com/ZeDarkAdam/ComfyUI-Embeddings-Tools"
],
@@ -13172,7 +13145,6 @@
"title": "LNL Frame Selector",
"id": "lnlframeselector",
"reference": "https://github.com/latenightlabs/ComfyUI-LNL",
"reference2": "https://github.com/asteriafilmco/ComfyUI-LNL",
"files": [
"https://github.com/latenightlabs/ComfyUI-LNL"
],
@@ -13606,7 +13578,6 @@
"title": "ComfyUI SaveAS",
"id": "saveas",
"reference": "https://github.com/SEkINVR/ComfyUI-SaveAs",
"reference2": "https://github.com/AnimationOverhual/ComfyUI-SaveAs",
"files": [
"https://github.com/SEkINVR/ComfyUI-SaveAs"
],
@@ -13751,12 +13722,11 @@
"author": "wTechArtist",
"title": "ComfyUI-StableDelight-weiweiliang",
"reference": "https://github.com/wTechArtist/ComfyUI-StableDelight-weiweiliang",
"reference2": "https://github.com/wTechArtist/ComfyUI-WWL-StableDelight",
"files": [
"https://github.com/wTechArtist/ComfyUI-StableDelight-weiweiliang"
],
"install_type": "git-clone",
"description": "NODES: WWL_StableDelight"
"description": "Nodes:StableDelight-weiweiliang"
},
{
"author": "wTechArtist",
@@ -14371,7 +14341,6 @@
"title": "ComfyUI-RK-Sampler",
"id": "rk_sampler",
"reference": "https://github.com/wootwootwootwoot/ComfyUI-RK-Sampler",
"reference2": "https://github.com/memmaptensor/ComfyUI-RK-Sampler",
"files": [
"https://github.com/wootwootwootwoot/ComfyUI-RK-Sampler"
],
@@ -15345,9 +15314,9 @@
{
"author": "Cyber-Blacat",
"title": "ComfyUI-Yuan",
"reference": "https://github.com/Cyber-BlackCat/ComfyUI-MoneyMaker",
"reference": "https://github.com/Cyber-Blacat/ComfyUI-Yuan",
"files": [
"https://github.com/Cyber-BlackCat/ComfyUI-MoneyMaker"
"https://github.com/Cyber-Blacat/ComfyUI-Yuan"
],
"install_type": "git-clone",
"description": "Some simple&practical ComfyUI image processing nodes."
@@ -15397,7 +15366,6 @@
"title": "LatentGC Aggressive",
"id": "latentgcaggressive",
"reference": "https://github.com/Raapys/ComfyUI-LatentGC_Aggressive",
"reference2": "https://github.com/0000111100001111/ComfyUI-LatentGC_Aggressive",
"files": [
"https://github.com/Raapys/ComfyUI-LatentGC_Aggressive"
],
@@ -17095,7 +17063,6 @@
"title": "CRT-Nodes",
"id": "crt-nodes",
"reference": "https://github.com/plugcrypt/CRT-Nodes",
"reference2": "https://github.com/PGCRT/CRT-Nodes",
"files": [
"https://github.com/plugcrypt/CRT-Nodes"
],
@@ -17908,7 +17875,6 @@
"author": "taches-ai",
"title": "ComfyUI Scene Composer",
"reference": "https://github.com/taches-ai/comfyui-scene-composer",
"reference2": "https://github.com/mus-taches/comfyui-scene-composer",
"files": [
"https://github.com/taches-ai/comfyui-scene-composer"
],
@@ -18199,13 +18165,13 @@
},
{
"author": "theshubzworld",
"title": "ComfyUI-ollama_killer",
"title": "OllamaKiller Node for ComfyUI",
"reference": "https://github.com/theshubzworld/ComfyUI-ollama_killer",
"files": [
"https://github.com/theshubzworld/ComfyUI-ollama_killer"
],
"install_type": "git-clone",
"description": "OllamaKiller is a cross-platform utility node for ComfyUI that automatically manages Ollama processes (`ollama.exe` on Windows, `ollama` on macOS/Linux). It helps free up VRAM by terminating Ollama processes after model execution, improving workflow performance and memory management. Features include graceful process termination, detailed status reporting, and seamless text passthrough."
"description": "OllamaKiller is a utility node for ComfyUI designed to manage VRAM usage more efficiently by automatically terminating the ollama_llama_server.exe process. This is particularly useful for users with limited VRAM, allowing them to clear up memory after running models and improve workflow performance."
},
{
"author": "theshubzworld",
@@ -19226,7 +19192,6 @@
"author": "Black-Lioness",
"title": "ComfyUI-PromptUtils",
"reference": "https://github.com/Black-Lioness/ComfyUI-PromptUtils",
"reference2": "https://github.com/RunningOverGlowies/ComfyUI-PromptUtils",
"files": [
"https://github.com/Black-Lioness/ComfyUI-PromptUtils"
],
@@ -19908,7 +19873,6 @@
"author": "sourceful-official",
"title": "LoadLoraModelOnlyWithUrl",
"reference": "https://github.com/sourceful-official/LoadLoraModelOnlyWithUrl",
"reference2": "https://github.com/sourceful-official/ComfyUI_LoadLoraModelOnlyWithUrl",
"files": [
"https://github.com/sourceful-official/LoadLoraModelOnlyWithUrl"
],
@@ -20376,12 +20340,12 @@
"author": "AEmotionStudio",
"title": "ComfyUI-EnhancedLinksandNodes 🎨✨",
"reference": "https://github.com/AEmotionStudio/ComfyUI-EnhancedLinksandNodes",
"reference2": "https://github.com/AEmotionStudio/ComfyUI-Enhanced",
"files": [
"https://github.com/AEmotionStudio/ComfyUI-EnhancedLinksandNodes"
],
"install_type": "git-clone",
"description": "A visually stunning extension for ComfyUI that adds beautiful, customizable animations to both links and nodes in your workflow, with a focus on performance and customization. Includes an end-of-render animation and a text visibility tool for nodes. No extra packages are required, works with the latest version of ComfyUI, and should be compatible with most workflows. Larger workflows may experience performance issues, especially if you have a lot of nodes and are using a lower end system."
"description": "A visually stunning extension for ComfyUI that adds beautiful, customizable animations to both links and nodes in your workflow, with a focus on performance and customization. Includes an end-of-render animation and a text visibility tool for nodes. No extra packages are required, works with the latest version of ComfyUI, and should be compatible with most workflows. Larger workflows may experience performance issues, especially if you have a lot of nodes and are using a lower end system.",
"reference2": "https://github.com/AEmotionStudio/ComfyUI-Enhanced"
},
{
"author": "AEmotionStudio",
@@ -21574,13 +21538,13 @@
},
{
"author": "meanin2",
"title": "comfyui-MGnodes",
"reference": "https://github.com/meanin2/comfyui-MGnodes",
"title": "ComfyUI Watermark Image Node",
"reference": "https://github.com/meanin2/comfyui-watermarking",
"files": [
"https://github.com/meanin2/comfyui-MGnodes"
"https://github.com/meanin2/comfyui-watermarking"
],
"install_type": "git-clone",
"description": "Assorted custom nodes with a focus on simplicity and usability including watermark node and others focused on customizing my comfy experience."
"description": "This custom node allows you to overlay a watermark image onto an existing image within ComfyUI."
},
{
"author": "Kurdknight",
@@ -21789,7 +21753,6 @@
"author": "Burgstall-labs",
"title": "ComfyUI-BETA-Cropnodes",
"reference": "https://github.com/Burgstall-labs/ComfyUI-BETA-Cropnodes",
"reference2": "https://github.com/Burgstall-labs/ComfyUI-BETA-Helpernodes",
"files": [
"https://github.com/Burgstall-labs/ComfyUI-BETA-Cropnodes"
],
@@ -21909,6 +21872,16 @@
"install_type": "git-clone",
"description": "🥭 Mango Random Nodes - A collection of random file nodes for ComfyUI"
},
{
"author": "meanin2",
"title": "ComfyUI Image Watermarking Node",
"reference": "https://github.com/meanin2/comfyui-MGnodes",
"files": [
"https://github.com/meanin2/comfyui-MGnodes"
],
"install_type": "git-clone",
"description": "A custom node for ComfyUI that allows you to add image watermarks with advanced controls for transparency, positioning, and color manipulation."
},
{
"author": "WUYUDING2583",
"title": "Save Image With Callback",
@@ -22135,17 +22108,6 @@
"install_type": "git-clone",
"description": "Custom nodes for integrating LM Studio's LLM functionality into ComfyUI. Includes EBU-LMStudio-Load, EBU-LMStudio-Unload, and EBU-LMStudio-Request."
},
{
"author": "burnsbert",
"title": "EBU Workflow",
"id": "ebu-workflow",
"reference": "https://github.com/burnsbert/ComfyUI-EBU-Workflow",
"files": [
"https://github.com/burnsbert/ComfyUI-EBU-Workflow"
],
"install_type": "git-clone",
"description": "Custom nodes for general workflow quality of life including resolutions sorted by aspect ratio, upscaling helps, and unique file names"
},
{
"author": "SykkoAtHome",
"title": "Face Processor for ComfyUI",
@@ -22260,7 +22222,6 @@
"author": "jinanlongen",
"title": "ComfyUI Prompt Expander Node",
"reference": "https://github.com/jinanlongen/ComfyUI-Prompt-Expander",
"reference2": "https://github.com/derekluo/ComfyUI-Prompt-Expander",
"files": [
"https://github.com/jinanlongen/ComfyUI-Prompt-Expander"
],
@@ -22782,7 +22743,6 @@
"title": "ComfyUI-SelectStringFromListWithIndex",
"id": "ComfyUI-SelectStringFromListWithIndex",
"reference": "https://github.com/wirytiox/ComfyUI-SelectStringFromListWithIndex",
"reference2": "https://github.com/mr-pepe69/ComfyUI-SelectStringFromListWithIndex",
"files": [
"https://github.com/wirytiox/ComfyUI-SelectStringFromListWithIndex"
],
@@ -23046,9 +23006,9 @@
{
"author": "crave33",
"title": "RenesStuffDanboruTagGet",
"reference": "https://github.com/crave33/RenesStuffDanbooruTagGet",
"reference": "https://github.com/crave33/RenesStuffDanboruTagGet",
"files": [
"https://github.com/crave33/RenesStuffDanbooruTagGet"
"https://github.com/crave33/RenesStuffDanboruTagGet"
],
"install_type": "git-clone",
"description": "generate tags / prompt from danboru image_id input"
@@ -24349,11 +24309,20 @@
"install_type": "git-clone",
"description": "Utility nodes for some randomness in your workflows, like random latent sizes. A few modifications to a few existing nodes, includes nodes for sampler and model parameters. Also includes two schedulers and four samplers that can be used with any KSampler node."
},
{
"author": "dream-computing",
"title": "SyntaxNodes - Image Processing Effects for ComfyUI",
"reference": "https://github.com/dream-computing/syntax-nodes",
"files": [
"https://github.com/dream-computing/syntax-nodes"
],
"install_type": "git-clone",
"description": "A collection of custom nodes for ComfyUI designed to apply various image processing effects, stylizations, and analyses."
},
{
"author": "Ky11le",
"title": "ygo_tools",
"reference": "https://github.com/Ky11le/ygo_tools",
"reference2": "https://github.com/Ky11le/draw_tools",
"files": [
"https://github.com/Ky11le/ygo_tools"
],
@@ -24944,16 +24913,6 @@
"install_type": "git-clone",
"description": "LatentSync 1.5 wrapper for ComfyUI"
},
{
"author": "avenstack",
"title": "ComfyUI-AV-FunASR",
"reference": "https://github.com/avenstack/ComfyUI-AV-FunASR",
"files": [
"https://github.com/avenstack/ComfyUI-AV-FunASR"
],
"install_type": "git-clone",
"description": "FunASR wrapper for ComfyUI"
},
{
"author": "WarpedAnimation",
"title": "ComfyUI-WarpedToolset",
@@ -25024,16 +24983,6 @@
"install_type": "git-clone",
"description": "This project provides a node for ComfyUI to use the JoyCaption-Beta model in GGUF format for image captioning."
},
{
"author": "judian17",
"title": "ComfyUI-UniWorld-jd17",
"reference": "https://github.com/judian17/ComfyUI-UniWorld-jd17",
"files": [
"https://github.com/judian17/ComfyUI-UniWorld-jd17"
],
"install_type": "git-clone",
"description": "Unofficial ComfyUI implementation of [a/UniWorld-V1](https://github.com/PKU-YuanGroup/UniWorld-V1)."
},
{
"author": "AngelCookies",
"title": "ComfyUI-Seed-Tracker",
@@ -25576,6 +25525,16 @@
"install_type": "git-clone",
"description": "This custom node for ComfyUI enables detailed segmentation of colored mask images into specific anatomical regions for male and female bodies."
},
{
"author": "kambara",
"title": "ComfyUI-PromptCheckList",
"reference": "https://github.com/kambara/ComfyUI-PromptCheckList",
"files": [
"https://github.com/kambara/ComfyUI-PromptCheckList"
],
"install_type": "git-clone",
"description": "This is a text editing extension for ComfyUI. It allows you to easily switch phrases for prompts using only the mouse."
},
{
"author": "kambara",
"title": "ComfyUI-PromptPalette",
@@ -26023,7 +25982,7 @@
"https://github.com/vladpro3/ComfyUI_BishaNodes"
],
"install_type": "git-clone",
"description": "Custom nodes for ComfyUI to improve promts and image settings"
"description": "Custom nodes for ComfyUI to generate images in multiple resolutions (including ultra-wide formats)"
},
{
"author": "otacoo",
@@ -26981,16 +26940,6 @@
"install_type": "git-clone",
"description": "This node uses the Translators library for translation."
},
{
"author": "pictorialink",
"title": "ComfyUI-Custom-Node-Config",
"reference": "https://github.com/pictorialink/ComfyUI-Custom-Node-Config",
"files": [
"https://github.com/pictorialink/ComfyUI-Custom-Node-Config"
],
"install_type": "git-clone",
"description": "This project is a custom node plugin for ComfyUI that provides a form node for configuring and saving parameters related to LLMs (such as OpenAI, Kimi, DeepSeek). Users can input information such as API Key, Base, Version, and Model through the node. The node will automatically save the configuration to a local file and set it as environment variables, making it convenient for subsequent use."
},
{
"author": "mo230761",
"title": "ComfyUI-Text-Translation",
@@ -27011,16 +26960,6 @@
"install_type": "git-clone",
"description": "comfy extension for lumina2 TeaCache"
},
{
"author": "spawner",
"title": "comfyui-aichat",
"reference": "https://github.com/spawner1145/comfyui-aichat",
"files": [
"https://github.com/spawner1145/comfyui-aichat"
],
"install_type": "git-clone",
"description": "gemini and openai in comfyui"
},
{
"author": "PenguinTeo",
"title": "Comfyui-TextEditor-Penguin",
@@ -27131,67 +27070,7 @@
"install_type": "git-clone",
"description": "Drop-in TorchCompile node that preserves LoRA patches."
},
{
"author": "Pigidiy",
"title": "ComfyUI-LikeSpiderAI-UI",
"id": "like_spider_ui",
"reference": "https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI",
"files": [
"https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI"
],
"install_type": "git-clone",
"description": "Declarative UI Framework for ComfyUI Nodes. Minimalistic base class for creating UI-based audio/text/image nodes."
},
{
"author": "hexxacubic",
"title": "ComfyUI-Prompt_Library",
"reference": "https://github.com/hexxacubic/ComfyUI-Prompt_Library",
"files": [
"https://github.com/hexxacubic/ComfyUI-Prompt_Library"
],
"install_type": "git-clone",
"description": "A ComfyUI Node to save and load prompts from a library."
},
{
"author": "MicheleGuidi",
"title": "ComfyUI-Computer-Vision",
"reference": "https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2",
"files": [
"https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2"
],
"install_type": "git-clone",
"description": "Extension nodes for ComfyUI that improves automatic segmentation using bounding boxes generated by Florence 2 and segmentation from Segment Anything 2 (SAM2). Currently just an enhancement of nodes from [a/Kijai](https://github.com/kijai/ComfyUI-segment-anything-2)."
},
{
"author": "swhsiang",
"title": "comfyui-3d-gs-renderer",
"reference": "https://github.com/swhsiang/comfyui-3d-gs-renderer",
"files": [
"https://github.com/swhsiang/comfyui-3d-gs-renderer"
],
"install_type": "git-clone",
"description": "ComfyUI custom node to support 3D GS rendering"
},
{
"author": "jasonjgardner",
"title": "ComfyUI Substance Designer Integration Plugin",
"reference": "https://github.com/jasonjgardner/comfui-substance-designer-integration",
"files": [
"https://github.com/jasonjgardner/comfui-substance-designer-integration"
],
"install_type": "git-clone",
"description": "A comprehensive ComfyUI plugin that enables seamless integration with Substance 3D Designer workflows through command line automation. This plugin provides custom nodes for cooking .sbs files, rendering .sbsar archives, controlling material parameters, and batch processing Substance materials within ComfyUI workflows."
},
{
"author": "sLKbabawhsiang",
"title": "ComfyUI-TuZi-Flux-Kontext",
"reference": "https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext",
"files": [
"https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext"
],
"install_type": "git-clone",
"description": " Powerful Flux-Kontext image generation custom node for ComfyUI, using the official RabbitAI API. Supports text-to-image, image-to-image, and multi-image-to-image generation. Supports concurrent generation."
},
@@ -27561,16 +27440,6 @@
"install_type": "copy",
"description": "Extremely inspired and forked from: [a/https://github.com/klimaleksus/stable-diffusion-webui-embedding-merge](https://github.com/klimaleksus/stable-diffusion-webui-embedding-merge)"
},
{
"author": "vladpro3",
"title": "ComfyUI_BishaNodes",
"reference": "https://github.com/vladpro3/ComfyUI_BishaNodes",
"files": [
"https://github.com/vladpro3/ComfyUI_BishaNodes"
],
"install_type": "copy",
"description": "Custom Nodes for ComfyUI to Simplify Multi-Resolution and Prompt Workflows"
},
{
"author": "Kayarte",
"title": "GeoNodes",

View File

@@ -256,12 +256,10 @@
"ALLty",
"EGRWGL",
"EGRYDZQHNode",
"EGSEED",
"GroupSwitchNode",
"GroupSwitchNodee",
"GroupSwitchNodeee",
"GroupSwitchNodeeee",
"GroupSwitchNodi",
"hulue",
"jinyong"
],
@@ -332,21 +330,10 @@
],
"https://github.com/2frames/ComfyUI-AQnodes": [
[
"AQ_BatchAverageImage",
"AQ_BlendImages",
"AQ_CLIPSetLastLayer",
"AQ_ColorMatchImage",
"AQ_Gemini",
"AQ_ImageMaskSwitch",
"AQ_Image_DetailTransfer",
"AQ_Image_Pad",
"AQ_Increment",
"AQ_LoadImageBase64",
"AQ_MasksAndImagesAsList",
"AQ_Qwen",
"AQ_QwenLoader",
"AQ_Random",
"AQ_SaveImageWebpReturnBase64",
"AQ_SendImageToAPI",
"AQ_multiface_ApplyPulidFlux"
],
@@ -3485,7 +3472,6 @@
"Categorizer",
"CollectAndDistributeText",
"Coloring",
"ConditionalLoRAApplierCreepybits",
"CustomNodeManager",
"DelayNode",
"DelayTextNode",
@@ -3551,15 +3537,7 @@
"title_aux": "ComfyUi Random Manage Cyan"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-Image-Vector": [
[
"Vector"
],
{
"title_aux": "Cyber-BlackCat"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-MoneyMaker": [
"https://github.com/Cyber-Blacat/ComfyUI-Yuan": [
[
", and the value is the function name in the right of the",
"Black and white",
@@ -3579,6 +3557,14 @@
"title_aux": "ComfyUI-Yuan"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-Image-Vector": [
[
"Vector"
],
{
"title_aux": "Cyber-BlackCat"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI_Auto_Caption": [
[
"Auto Caption",
@@ -5474,8 +5460,6 @@
"Integer to Float",
"Integer to String",
"Latent Switch",
"Load Image",
"Logic Compare",
"Math Operation",
"Model Switch",
"Prompt Combiner",
@@ -7029,7 +7013,6 @@
"ImageSizeAdjustment",
"InspyrenetRembgLoader",
"InspyrenetRembgProcess",
"LG_LatentBatchToList",
"LG_LoadImage",
"LG_Noise",
"LazySwitch1way",
@@ -7052,16 +7035,6 @@
"title_aux": "ImagesGrid"
}
],
"https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext": [
[
"FluxKontext_ImageToImage",
"FluxKontext_MultiImageToImage",
"FluxKontext_TextToImage"
],
{
"title_aux": "ComfyUI-TuZi-Flux-Kontext"
}
],
"https://github.com/LamEmil/ComfyUI_ASCIIArtNode": [
[
"ASCIIAnimationGenerator",
@@ -7174,7 +7147,6 @@
"BoolToString|LP",
"CLIP Text Encode Translate [LP]",
"CLIPTextEncodeTranslate|LP",
"Calculate Target Size By Mask [LP]",
"CalculateTargetSizeByMask|LP",
"Convert Bool To Int [LP]",
"Convert Bool To String [LP]",
@@ -7190,17 +7162,12 @@
"Convert String To Number [LP]",
"Count Objects [LP]",
"CountObjects|LP",
"Cropped Aspect Size Parameters [LP]",
"Cropped Forsed Size Parameters [LP]",
"Cropped Free Size Parameters [LP]",
"Cropped Ranged Size Parameters [LP]",
"CroppedAspectSizeParameters|LP",
"CroppedForsedSizeParameters|LP",
"CroppedFreeSizeParameters|LP",
"CroppedRangedSizeParameters|LP",
"Delay [LP]",
"Delay|LP",
"Extend Factor Parameters [LP]",
"ExtendFactorParameters|LP",
"Fast Checker Pattern [LP]",
"FastCheckerPattern|LP",
@@ -7217,8 +7184,6 @@
"Image Overlay [LP]",
"ImageLoaderFromPath|LP",
"ImageOverlay|LP",
"Inpaint Crop [LP]",
"Inpaint Stitch [LP]",
"InpaintCrop|LP",
"InpaintStitch|LP",
"IntToBool|LP",
@@ -7252,8 +7217,6 @@
"RemoveBannedTagsFromTags|LP",
"RemoveBannedTagsFromText|LP",
"RemoveDuplicateTags|LP",
"Resize Image To Target Size [LP]",
"Resize Image and Masks [LP]",
"ResizeImageAndMasks|LP",
"ResizeImageToTargetSize|LP",
"Resorting Tags [LP]",
@@ -7700,13 +7663,8 @@
"LoraTagLoader",
"ResolutionSelector",
"StringCleaning",
"StringTextExtractor",
"StringTextSplitter",
"TiktokenTokenizer",
"WildcardProcessor",
"\u26d4 Generate Negative Prompt",
"\u2702\ufe0f String Text Extractor",
"\u2702\ufe0f String Text Splitter",
"\u2728\ud83c\udf10 Groq ALM API - Translate [EN only]",
"\u2728\ud83d\udcac Groq LLM API",
"\u2728\ud83d\udcdd Groq ALM API - Transcribe",
@@ -7715,7 +7673,6 @@
"\ud83d\udcbe Save Text File With Path",
"\ud83d\udcc1 Get File Path",
"\ud83d\udcd0 Resolution Image Size Selector",
"\ud83d\udcdd Wildcard Processor",
"\ud83d\udd20 Tiktoken Tokenizer Info",
"\ud83d\uddbc\ufe0f Download Image from URL",
"\ud83e\uddf9 String Cleaning"
@@ -7982,15 +7939,6 @@
"title_aux": "ComfyUI ZhipuAI Platform"
}
],
"https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2": [
[
"Sam2ContextSegmentation",
"Sam2TiledSegmentation"
],
{
"title_aux": "ComfyUI-Computer-Vision"
}
],
"https://github.com/MiddleKD/ComfyUI-denoise-mask-scheduler": [
[
"ApplyDenoiseMaskSchedulerWithSigma",
@@ -9185,14 +9133,6 @@
"title_aux": "ComfyUI-LikeSpiderAI-SaveMP3"
}
],
"https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI": [
[
"AudioExport"
],
{
"title_aux": "ComfyUI-LikeSpiderAI-UI"
}
],
"https://github.com/PixelFunAI/ComfyUI_PixelFun": [
[
"HunyuanLoadAndEditLoraBlocks",
@@ -9955,8 +9895,7 @@
],
"https://github.com/Santodan/santodan-custom-nodes-comfyui": [
[
"RandomLoRACustom",
"RandomLoRAFolder"
"RandomLoRACustom"
],
{
"title_aux": "Santodan Random LoRA Node"
@@ -11348,7 +11287,6 @@
"Basic data handling: PathListDir",
"Basic data handling: PathNormalize",
"Basic data handling: PathRelative",
"Basic data handling: PathSetExtension",
"Basic data handling: PathSplit",
"Basic data handling: PathSplitExt",
"Basic data handling: RegexFindallDataList",
@@ -11482,9 +11420,7 @@
"StarGridImageBatcher",
"StarImageSwitch",
"StarImageSwitch2",
"StarInfiniteYouAdvancedPatchMaker",
"StarInfiniteYouApply",
"StarInfiniteYouFaceSwapMod",
"StarInfiniteYouPatch",
"StarInfiniteYouPatchCombine",
"StarInfiniteYouSaver",
@@ -11493,12 +11429,10 @@
"StarNewsScraper",
"StarPSDSaver",
"StarPSDSaver2",
"StarPaletteExtractor",
"StarSaveSamplerSettings",
"StarTextFilter",
"StarTextInput",
"StarWildcardsAdvanced",
"Star_Image2Latent",
"Starnodes_Aspect_Ratio",
"Starnodes_Aspect_Ratio_Advanced",
"Starupscale"
@@ -13244,13 +13178,10 @@
],
"https://github.com/XieJunchen/comfyUI_LLM": [
[
"CloudImageUploadNode",
"CloudImagesToVideoAndUpload",
"CloudVideoUploadNode",
"ComfyUI_LLM_Ollama",
"DeepSeek_Online",
"LoadGifFromLocal",
"LoadImgFromUrl",
"QiniuImageUploadNode",
"QiniuVideoUploadNode",
"StringArrayFormatter",
"StringArrayIndexer"
],
@@ -15268,17 +15199,6 @@
"title_aux": "Avatar Graph"
}
],
"https://github.com/avenstack/ComfyUI-AV-FunASR": [
[
"AVASRTimestamp",
"AVFormat2Subtitle",
"AVSaveSubtitles",
"AVSpeechTimestamp"
],
{
"title_aux": "ComfyUI-AV-FunASR"
}
],
"https://github.com/avenstack/ComfyUI-AV-LatentSync": [
[
"AVLatentSync",
@@ -16425,15 +16345,6 @@
"title_aux": "ComfyUI Sequential Image Loader"
}
],
"https://github.com/budihartono/comfyui-aspect-ratio-presets": [
[
"CAS Empty Latent Aspect Ratio by Axis",
"CAS Empty Latent Aspect Ratio from Preset"
],
{
"title_aux": "CAS Aspect Ratio Presets Node for ComfyUI"
}
],
"https://github.com/budihartono/comfyui_otonx_nodes": [
[
"OTX Integer Multiple Inputs 4",
@@ -16518,17 +16429,6 @@
"title_aux": "EBU PromptHelper"
}
],
"https://github.com/burnsbert/ComfyUI-EBU-Workflow": [
[
"EbuGetImageAspectRatio",
"EbuScalingResolution",
"EbuScalingTile",
"EbuUniqueFileName"
],
{
"title_aux": "EBU Workflow"
}
],
"https://github.com/bvhari/ComfyUI_CFGStar": [
[
"CFGStar"
@@ -19110,7 +19010,7 @@
"title_aux": "ComfyUI Anime Segmentation Nodes v1.1.0"
}
],
"https://github.com/crave33/RenesStuffDanbooruTagGet": [
"https://github.com/crave33/RenesStuffDanboruTagGet": [
[
"DanbooruTagFetcher"
],
@@ -20264,6 +20164,32 @@
"title_aux": "ComfyUI_Dragos_Nodes"
}
],
"https://github.com/dream-computing/syntax-nodes": [
[
"CyberpunkMagnifyNode",
"CyberpunkWindowNode",
"DepthToLidarEffectNode",
"EdgeMeasurementOverlayNode",
"EdgeTracingNode",
"FrequencyBeatSyncNode",
"FrequencyBeatSyncNodeAdvanced",
"GhostingNode",
"ImageBatchToImageList",
"ImageListToImageBatch",
"JigsawPuzzleNode",
"LowPolyNode",
"LuminanceParticleNode",
"PaperCraftNode",
"PointillismNode",
"RGBStreakNode",
"RegionBoundaryNode",
"VariableLineWidthEffectNode",
"VoxelNode"
],
{
"title_aux": "SyntaxNodes - Image Processing Effects for ComfyUI"
}
],
"https://github.com/dreamhartley/ComfyUI_show_seed": [
[
"Show Seed"
@@ -21550,27 +21476,17 @@
],
"https://github.com/gelasdev/ComfyUI-FLUX-BFL-API": [
[
"FluxDeleteFinetune_BFL",
"FluxDevRedux_BFL",
"FluxDev_BFL",
"FluxFinetuneDetails_BFL",
"FluxFinetuneStatus_BFL",
"FluxFinetune_BFL",
"FluxKontextMax_BFL",
"FluxKontextPro_BFL",
"FluxMyFinetunes_BFL",
"FluxPro11Redux_BFL",
"FluxPro11UltraFinetune_BFL",
"FluxPro11UltraRedux_BFL",
"FluxPro11Ultra_BFL",
"FluxPro11_BFL",
"FluxProCannyFinetune_BFL",
"FluxProCanny_BFL",
"FluxProDepthFinetune_BFL",
"FluxProDepth_BFL",
"FluxProFillFinetune_BFL",
"FluxProFill_BFL",
"FluxProFinetune_BFL",
"FluxPro_BFL"
],
{
@@ -22676,16 +22592,6 @@
"title_aux": "comfyui_LLM_schools"
}
],
"https://github.com/hexxacubic/ComfyUI-Prompt_Library": [
[
"Prompt_Library",
"Random_Project",
"Simple_Prompt_Library"
],
{
"title_aux": "ComfyUI-Prompt_Library"
}
],
"https://github.com/hgabha/WWAA-CustomNodes": [
[
"WWAA-BuildString",
@@ -23957,18 +23863,6 @@
"title_aux": "Painting Coder Utils"
}
],
"https://github.com/jasonjgardner/comfui-substance-designer-integration": [
[
"SubstanceBatchProcessor",
"SubstanceCooker",
"SubstanceInfoExtractor",
"SubstanceParameterController",
"SubstanceRenderer"
],
{
"title_aux": "ComfyUI Substance Designer Integration Plugin"
}
],
"https://github.com/jax-explorer/ComfyUI-InstantCharacter": [
[
"InstantCharacterGenerate",
@@ -24346,7 +24240,6 @@
"ai4artsed_random_artform_generator",
"ai4artsed_random_instruction_generator",
"ai4artsed_random_language_selector",
"ai4artsed_stabilitai_key",
"ai4artsed_t5_clip_fusion",
"ai4artsed_text_remix"
],
@@ -24469,17 +24362,6 @@
"title_aux": "ComfyUI-Extract_Flux_Lora"
}
],
"https://github.com/judian17/ComfyUI-UniWorld-jd17": [
[
"UniWorldEncoderNode",
"UniWorldScheduler",
"UniWorldSiglipEncoder",
"UniWorld_T5_CLIP_Encoder"
],
{
"title_aux": "ComfyUI-UniWorld-jd17"
}
],
"https://github.com/judian17/ComfyUI-joycaption-beta-one-GGUF": [
[
"JJC_JoyCaption_Custom_GGUF",
@@ -24592,7 +24474,6 @@
"Bjornulf_ImageMaskCutter",
"Bjornulf_ImageNote",
"Bjornulf_ImageNoteLoadImage",
"Bjornulf_ImageUpscaleWithModelTransparency",
"Bjornulf_ImagesListToVideo",
"Bjornulf_JSONImagePromptExtractor",
"Bjornulf_KokoroTTS",
@@ -24724,7 +24605,6 @@
"Bjornulf_WriteTextPickMeGlobal",
"Bjornulf_XTTSConfig",
"Bjornulf_imagesToVideo",
"Bjornulf_loadImageBase64Transparency",
"Bjornulf_ollamaLoader"
],
{
@@ -24925,6 +24805,14 @@
"title_aux": "ComfyUI-text-file-util"
}
],
"https://github.com/kambara/ComfyUI-PromptCheckList": [
[
"PromptPalette"
],
{
"title_aux": "ComfyUI-PromptCheckList"
}
],
"https://github.com/kambara/ComfyUI-PromptPalette": [
[
"PromptPalette"
@@ -26109,7 +25997,6 @@
"https://github.com/laksjdjf/ComfyUI-Imatrix": [
[
"ImatrixUNETLoader",
"LoRAdiff",
"SaveImatrix"
],
{
@@ -27682,7 +27569,6 @@
"ScheduledCFGGuider //Inspire",
"ScheduledPerpNegCFGGuider //Inspire",
"SeedExplorer //Inspire",
"SeedLogger //Inspire",
"SelectNthMask //Inspire",
"ShowCachedInfo //Inspire",
"StableCascade_CheckpointLoader //Inspire",
@@ -28355,7 +28241,16 @@
"TextExtractorNode"
],
{
"title_aux": "comfyui-MGnodes"
"title_aux": "ComfyUI Image Watermarking Node"
}
],
"https://github.com/meanin2/comfyui-watermarking": [
[
"ImageWatermarkNode",
"TextExtractorNode"
],
{
"title_aux": "ComfyUI Watermark Image Node"
}
],
"https://github.com/meap158/ComfyUI-Background-Replacement": [
@@ -28834,8 +28729,14 @@
],
"https://github.com/mit-han-lab/ComfyUI-nunchaku": [
[
"NunchakuDepthPreprocessor",
"NunchakuFluxDiTLoader",
"NunchakuFluxLoraLoader"
"NunchakuFluxLoraLoader",
"NunchakuModelMerger",
"NunchakuPulidApply",
"NunchakuPulidLoader",
"NunchakuTextEncoderLoader",
"NunchakuTextEncoderLoaderV2"
],
{
"title_aux": "ComfyUI-nunchaku"
@@ -30394,14 +30295,6 @@
"title_aux": "paint-by-example @ ComfyUI"
}
],
"https://github.com/pictorialink/ComfyUI-Custom-Node-Config": [
[
"FormSubmitNode"
],
{
"title_aux": "ComfyUI-Custom-Node-Config"
}
],
"https://github.com/pictorialink/ComfyUI-Text-Translation": [
[
"Get_Translator",
@@ -31350,8 +31243,7 @@
"PrimitiveText",
"UtilityExpression",
"UtilityImageDimensions",
"UtilitySwitch",
"rookiepsi_ConstructMask"
"UtilitySwitch"
],
{
"title_aux": "ComfyUI Extended"
@@ -31811,10 +31703,7 @@
],
"https://github.com/s9roll7/comfyui_cotracker_node": [
[
"CoTrackerNode",
"GridPointGeneratorNode",
"PerlinCoordinateRandomizerNode",
"XYMotionAmplifierNode"
"CoTrackerNode"
],
{
"title_aux": "Comfyui CoTracker Node"
@@ -33335,34 +33224,12 @@
],
"https://github.com/spawner1145/CUI-Lumina2-TeaCache": [
[
"LPIPS_Model_Loader",
"Store_Baseline_Image",
"TeaCache_LPIPS_Evaluator",
"TeaCache_Lumina2",
"TeaCache_Patcher",
"TeaCache_Result_Collector"
"TeaCache_Lumina2"
],
{
"title_aux": "CUI-Lumina2-TeaCache"
}
],
"https://github.com/spawner1145/comfyui-aichat": [
[
"GeminiApiLoader_Zho",
"GeminiChat_Zho",
"GeminiFileUploader_Zho",
"GeminiImageEncoder_Zho",
"GeminiTextBlock_Zho",
"OpenAIApiLoader_Zho",
"OpenAIChat_Zho",
"OpenAIFileUploader_Zho",
"OpenAIImageEncoder_Zho",
"OpenAITextBlock_Zho"
],
{
"title_aux": "comfyui-aichat"
}
],
"https://github.com/spinagon/ComfyUI-seam-carving": [
[
"SeamCarving"
@@ -34014,7 +33881,7 @@
"OllamaKiller"
],
{
"title_aux": "ComfyUI-ollama_killer"
"title_aux": "OllamaKiller Node for ComfyUI"
}
],
"https://github.com/thezveroboy/ComfyUI-CSM-Nodes": [
@@ -34793,10 +34660,7 @@
[
"CreatePromptsWithTextFromFile",
"EmptyLatentSizePicker",
"LoadDataFromFiles",
"SimpleSizePicker",
"WildcardReplace",
"WildcardReplaceFromFile"
"SimpleSizePicker"
],
{
"title_aux": "ComfyUI_BishaNodes"
@@ -35031,20 +34895,6 @@
"title_aux": "ComfyUI-RemoveBackgroundSuite"
}
],
"https://github.com/whmc76/ComfyUI-UniversalToolkit": [
[
"EmptyUnitGenerator_UTK",
"ImageRatioDetector_UTK",
"PreviewMask_UTK",
"ShowFloat_UTK",
"ShowInt_UTK",
"ShowList_UTK",
"ShowText_UTK"
],
{
"title_aux": "ComfyUI-UniversalToolkit"
}
],
"https://github.com/wildminder/ComfyUI-Chatterbox": [
[
"ChatterboxTTS",
@@ -35497,8 +35347,8 @@
"LTLatentOp",
"LTLatentToShape",
"LTLatentsConcatenate",
"LTNumberRangeGaussian",
"LTNumberRangeUniform",
"LTParamRandomizerGaussian",
"LTParamRandomizerRange",
"LTPreviewLatent",
"LTReshapeLatent",
"LTUniformLatent"
@@ -35841,21 +35691,18 @@
"MaskSmartValleySplit",
"MaskSplitFilter",
"MaskTopNFilter",
"TextKeyword",
"TextBeforeKeyword",
"YC Extract Number",
"YC Mask Condition Switch",
"YC Seed List",
"YC Super Selector",
"YC Text Condition Switch",
"YC Text Index Switch",
"YC Universal Gate",
"YCMaskComposite",
"YCPromptReplace",
"YCRemapMaskRange",
"YCTextImageGenerator",
"YC_FiveTextCombineNode",
"YC_Image_Save",
"YC_SingleTextNode",
"YC_textReplaceNode"
"YC_Image_Save"
],
{
"title_aux": "ComfyUI-YCNodes"
@@ -36536,6 +36383,7 @@
"DCI_BinaryFileLoader",
"DCI_BinaryFileSaver",
"DCI_BinaryFileUploader",
"DCI_FileLoader",
"DCI_FileNode",
"DCI_Image",
"DCI_ImageExporter",

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +1,23 @@
{
"custom_nodes": [
{
"author": "cesilk10",
"title": "cesilk-comfyui-nodes",
"reference": "https://github.com/cesilk10/cesilk-comfyui-nodes",
"files": [
"https://github.com/cesilk10/cesilk-comfyui-nodes"
],
"author": "#NOTICE_1.13",
"title": "NOTICE: This channel is not the default channel.",
"reference": "https://github.com/ltdrdata/ComfyUI-Manager",
"files": [],
"install_type": "git-clone",
"description": "NODES: Save and Upload to S3, SDXL Image Sizes"
},
{
"author": "COcisuts",
"title": "CObot-ComfyUI-WhisperToTranscription [WIP]",
"reference": "https://github.com/COcisuts/CObot-ComfyUI-WhisperToTranscription",
"files": [
"https://github.com/COcisuts/CObot-ComfyUI-WhisperToTranscription"
],
"install_type": "git-clone",
"description": "CObot-ComfyUI-WhisperToTranscription\nNOTE: missing requirements.txt"
},
{
"author": "xuhuan2048",
"title": "ExtractStoryboards [WIP]",
"reference": "https://github.com/gitadmini/comfyui_extractstoryboards",
"files": [
"https://github.com/gitadmini/comfyui_extractstoryboards"
],
"install_type": "git-clone",
"description": "A tool for decomposing video storyboards, which can obtain storyboards and keyframes"
},
{
"author": "jinchanz",
"title": "ComfyUI-AliCloud-Bailian [WIP]",
"reference": "https://github.com/jinchanz/ComfyUI-AliCloud-Bailian",
"files": [
"https://github.com/jinchanz/ComfyUI-AliCloud-Bailian"
],
"install_type": "git-clone",
"description": "This is a collection of custom nodes for invoking Alibaba Cloud's DashScope API within ComfyUI.\nNOTE: The files in the repo are not organized."
},
{
"author": "Yukinoshita-Yukinoe",
"title": "ComfyUI-KontextOfficialNode",
"reference": "https://github.com/Yukinoshita-Yukinoe/ComfyUI-KontextOfficialNode",
"files": [
"https://github.com/Yukinoshita-Yukinoe/ComfyUI-KontextOfficialNode"
],
"install_type": "git-clone",
"description": "NODES: Kontext Text-to-Image (Official Max), Kontext Image Editing (Official Max)"
"description": "If you see this message, your ComfyUI-Manager is outdated.\nDev channel provides only the list of the developing nodes. If you want to find the complete node list, please go to the Default channel."
},
{
"author": "takoyaki1118",
"title": "ComfyUI_PromptExtractor",
@@ -980,6 +948,16 @@
"install_type": "git-clone",
"description": "ComfyUI implementation of the partfield nvidea segmentation models\nNOTE: The files in the repo are not organized."
},
{
"author": "MicheleGuidi",
"title": "ComfyUI-Computer-Vision [WIP]",
"reference": "https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2",
"files": [
"https://github.com/MicheleGuidi/comfyui-computer-vision"
],
"install_type": "git-clone",
"description": "Extension nodes for ComfyUI that improves automatic segmentation using bounding boxes generated by Florence 2 and segmentation from Segment Anything 2 (SAM2). Currently just an enhancement of nodes from [a/Kijai](https://github.com/kijai/ComfyUI-segment-anything-2).\nNOTE: The files in the repo are not organized."
},
{
"author": "shinich39",
"title": "comfyui-textarea-is-shit",
@@ -1042,10 +1020,10 @@
},
{
"author": "ftechmax",
"title": "ComfyUI-NovaKit-Pack",
"reference": "https://github.com/ftechmax/ComfyUI-NovaKit-Pack",
"title": "ComfyUI-FTM-Pack",
"reference": "https://github.com/ftechmax/ComfyUI-FTM-Pack",
"files": [
"https://github.com/ftechmax/ComfyUI-NovaKit-Pack"
"https://github.com/ftechmax/ComfyUI-FTM-Pack"
],
"install_type": "git-clone",
"description": "NODES: Count Tokens"
@@ -1055,7 +1033,7 @@
"title": "ComfyUI DiaTest TTS Node [WIP]",
"reference": "https://github.com/BobRandomNumber/ComfyUI-DiaTTS",
"files": [
"https://github.com/BobRandomNumber/ComfyUI-DiaTTS"
"https://github.com/BobRandomNumber/ComfyUI-DiaTest"
],
"install_type": "git-clone",
"description": "Partial ComfyUI Dia implementation"

View File

@@ -599,7 +599,7 @@
],
"https://github.com/Alazuaka/comfyui-lora-stack-node": [
[
"AlazukaCheckpoint",
"EsCheckpointSet",
"EsLoraSet"
],
{
@@ -876,7 +876,7 @@
"title_aux": "ComfyUI-BDXNodes [WIP]"
}
],
"https://github.com/BobRandomNumber/ComfyUI-DiaTTS": [
"https://github.com/BobRandomNumber/ComfyUI-DiaTest": [
[
"DiaGenerate",
"DiaLoader"
@@ -920,14 +920,6 @@
"title_aux": "ComfyUI-BS_FalAi-API-Video [WIP]"
}
],
"https://github.com/COcisuts/CObot-ComfyUI-WhisperToTranscription": [
[
"CobotWhisperToTransciption"
],
{
"title_aux": "CObot-ComfyUI-WhisperToTranscription [WIP]"
}
],
"https://github.com/CY-CHENYUE/ComfyUI-FramePack-HY": [
[
"CreateKeyframes_HY",
@@ -950,7 +942,6 @@
"https://github.com/Chargeuk/ComfyUI-vts-nodes": [
[
"VTS Clean Text",
"VTS Clean Text List",
"VTS Clear Ram",
"VTS Clip Text Encode",
"VTS Color Mask To Mask",
@@ -961,11 +952,8 @@
"VTS Images Scale",
"VTS Images Scale To Min",
"VTS Merge Delimited Text",
"VTS Merge Text Lists",
"VTS Reduce Batch Size",
"VTS Render People Kps",
"VTS Repeat Text As List",
"VTS Replace Text In List",
"VTS To Text",
"VTS_Load_Pose_Keypoints",
"Vts Text To Batch Prompt"
@@ -1198,6 +1186,8 @@
"DonutApplyLoRAStack",
"DonutClipEncode",
"DonutLoRAStack",
"DonutLoadCLIPModels",
"DonutLoadUNetModels",
"DonutWidenMergeCLIP",
"DonutWidenMergeUNet",
"DualCFGGuider",
@@ -2277,8 +2267,6 @@
],
"https://github.com/MakkiShizu/ComfyUI-MakkiTools": [
[
"AutoLoop_create_pseudo_loop_video",
"Environment_INFO",
"GetImageNthCount",
"ImageChannelSeparate",
"ImageCountConcatenate",
@@ -2349,6 +2337,15 @@
"title_aux": "comfyui-yaml-prompt"
}
],
"https://github.com/MicheleGuidi/comfyui-computer-vision": [
[
"Sam2ContextSegmentation",
"Sam2TiledSegmentation"
],
{
"title_aux": "ComfyUI-Computer-Vision [WIP]"
}
],
"https://github.com/MickeyJ/ComfyUI_mickster_nodes": [
[
"Image Size Scaled",
@@ -2576,7 +2573,6 @@
"FRED_AutoCropImage_Native_Ratio_v5",
"FRED_AutoCropImage_SDXL_Ratio_V3",
"FRED_AutoCropImage_SDXL_Ratio_V4",
"FRED_AutoImageTile_from_Mask_v1",
"FRED_CropFace",
"FRED_FolderSelector",
"FRED_ImageBrowser_Dress",
@@ -3332,15 +3328,6 @@
"title_aux": "ComfyUI_LLM_Are_You_Listening [WIP]"
}
],
"https://github.com/Yukinoshita-Yukinoe/ComfyUI-KontextOfficialNode": [
[
"KontextImageEditingOfficialAPI_Max",
"KontextTextToImageOfficialAPI_Max"
],
{
"title_aux": "ComfyUI-KontextOfficialNode"
}
],
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AuraSR-ZHO": [
[
"AuraSR_Lterative_Zho",
@@ -3451,17 +3438,12 @@
],
"https://github.com/aa-parky/pipemind-comfyui": [
[
"BatchImageLoad",
"BooleanSwitchAny",
"KeywordPromptComposer",
"PipemindDisplayAny",
"PipemindFlux2MAspectRatio",
"PipemindLoraLoader",
"PipemindMultilineTextInput",
"PipemindRoomNode",
"PipemindSDXL15AspectRatio",
"PipemindSaveImageWTxt",
"PipemindShowText",
"PipemindTokenCounter",
"RandomLineFromDropdown",
"SelectLineFromDropdown",
"SimplePromptCombiner"
@@ -4115,15 +4097,6 @@
"title_aux": "cel_sampler [WIP]"
}
],
"https://github.com/cesilk10/cesilk-comfyui-nodes": [
[
"SaveAndUploadToS3",
"SdxlImageSizes"
],
{
"title_aux": "cesilk-comfyui-nodes"
}
],
"https://github.com/chaojie/ComfyUI-DynamiCrafter": [
[
"DynamiCrafter Simple",
@@ -5101,12 +5074,12 @@
"title_aux": "ComfyUI-LLM-Utils [WIP]"
}
],
"https://github.com/ftechmax/ComfyUI-NovaKit-Pack": [
"https://github.com/ftechmax/ComfyUI-FTM-Pack": [
[
"CountTokens"
],
{
"title_aux": "ComfyUI-NovaKit-Pack"
"title_aux": "ComfyUI-FTM-Pack"
}
],
"https://github.com/gabe-init/ComfyUI-LM-Studio": [
@@ -5189,17 +5162,6 @@
"title_aux": "ComfyUI-N_SwapInput [UNSAFE]"
}
],
"https://github.com/gitadmini/comfyui_extractstoryboards": [
[
"Example",
"ExtractStoryboards_xuhuan1024",
"IntBatchSize_xuhuan1024",
"IntBatch_xuhuan1024"
],
{
"title_aux": "ExtractStoryboards [WIP]"
}
],
"https://github.com/githubYiheng/comfyui_median_filter": [
[
"ImageMedianFilter"
@@ -5349,15 +5311,9 @@
"HolafBenchmarkLoader",
"HolafBenchmarkPlotter",
"HolafBenchmarkRunner",
"HolafColorMatcher",
"HolafImageComparer",
"HolafInstagramResize",
"HolafInteractiveImageEditor",
"HolafKSampler",
"HolafLutApplier",
"HolafLutGenerator",
"HolafLutLoader",
"HolafLutSaver",
"HolafNeurogridOverload",
"HolafOverlayNode",
"HolafResolutionPreset",
@@ -5827,18 +5783,6 @@
"title_aux": "Jim's ComfyUI Nodes [WIP]"
}
],
"https://github.com/jinchanz/ComfyUI-AliCloud-Bailian": [
[
"BailianAPI",
"BailianAPIPoll",
"BailianAPISubmit",
"MaletteJSONExtractor",
"MaletteJSONModifier"
],
{
"title_aux": "ComfyUI-AliCloud-Bailian [WIP]"
}
],
"https://github.com/jn-jairo/jn_node_suite_comfyui": [
[
"JN_AreaInfo",
@@ -7562,7 +7506,6 @@
"RunPython",
"SaveSpiderData",
"SpiderCrawl",
"SpiderSplit",
"String2Json",
"String_Attachment"
],
@@ -8479,7 +8422,6 @@
"https://github.com/wTechArtist/ComfyUI_VVL_SAM2": [
[
"SAM1AutoEverything",
"VVL_DetectionScaler",
"VVL_Florence2SAM2",
"VVL_GroundingDinoSAM2",
"VVL_MaskCleaner",
@@ -8691,7 +8633,6 @@
"RegionalPromptSamplerX",
"RelightX",
"RemoveBackgroundX",
"SamplersTestX",
"SaveImageX",
"SelectiveDepthLoraBlocksX",
"SimpleBlockerX",

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,16 @@
{
"custom_nodes": [
{
"author": "dream-computing",
"title": "SyntaxNodes - Image Processing Effects for ComfyUI [REMOVED]",
"reference": "https://github.com/dream-computing/syntax-nodes",
"files": [
"https://github.com/dream-computing/syntax-nodes"
],
"author": "#NOTICE_1.13",
"title": "NOTICE: This channel is not the default channel.",
"reference": "https://github.com/ltdrdata/ComfyUI-Manager",
"files": [],
"install_type": "git-clone",
"description": "A collection of custom nodes for ComfyUI designed to apply various image processing effects, stylizations, and analyses."
"description": "If you see this message, your ComfyUI-Manager is outdated.\nLegacy channel provides only the list of the deprecated nodes. If you want to find the complete node list, please go to the Default channel."
},
{
"author": "UD1sto",
"title": "plugin-utils-nodes [DEPRECATED]",

View File

@@ -1,138 +1,16 @@
{
"custom_nodes": [
{
"author": "avenstack",
"title": "ComfyUI-AV-FunASR",
"reference": "https://github.com/avenstack/ComfyUI-AV-FunASR",
"files": [
"https://github.com/avenstack/ComfyUI-AV-FunASR"
],
"author": "#NOTICE_1.13",
"title": "NOTICE: This channel is not the default channel.",
"reference": "https://github.com/ltdrdata/ComfyUI-Manager","files": [],
"install_type": "git-clone",
"description": "FunASR wrapper for ComfyUI"
},
{
"author": "burnsbert",
"title": "EBU Workflow",
"id": "ebu-workflow",
"reference": "https://github.com/burnsbert/ComfyUI-EBU-Workflow",
"files": [
"https://github.com/burnsbert/ComfyUI-EBU-Workflow"
],
"install_type": "git-clone",
"description": "Custom nodes for general workflow quality of life including resolutions sorted by aspect ratio, upscaling helps, and unique file names"
},
{
"author": "vladpro3",
"title": "ComfyUI_BishaNodes",
"reference": "https://github.com/vladpro3/ComfyUI_BishaNodes",
"files": [
"https://github.com/vladpro3/ComfyUI_BishaNodes"
],
"install_type": "git-clone",
"description": "Custom nodes for ComfyUI to improve promts and image settings"
},
{
"author": "jasonjgardner",
"title": "ComfyUI Substance Designer Integration Plugin",
"reference": "https://github.com/jasonjgardner/comfui-substance-designer-integration",
"files": [
"https://github.com/jasonjgardner/comfui-substance-designer-integration"
],
"install_type": "git-clone",
"description": "A comprehensive ComfyUI plugin that enables seamless integration with Substance 3D Designer workflows through command line automation. This plugin provides custom nodes for cooking .sbs files, rendering .sbsar archives, controlling material parameters, and batch processing Substance materials within ComfyUI workflows."
},
{
"author": "budihartono",
"title": "CAS Aspect Ratio Presets Node for ComfyUI",
"id": "comfyui-aspect-ratio-presets",
"reference": "https://github.com/budihartono/comfyui-aspect-ratio-presets",
"files": [
"https://github.com/budihartono/comfyui-aspect-ratio-presets"
],
"install_type": "git-clone",
"description": "Quickly create empty latents in common resolutions and aspect ratios for SD 1.5, SDXL, Flux, Chroma, and HiDream. Choose from curated presets or generate by axis and aspect ratio. Appears in the 'latent' node group."
},
{
"author": "spawner",
"title": "comfyui-aichat",
"reference": "https://github.com/spawner1145/comfyui-aichat",
"files": [
"https://github.com/spawner1145/comfyui-aichat"
],
"install_type": "git-clone",
"description": "gemini and openai in comfyui"
},
{
"author": "swhsiang",
"title": "comfyui-3d-gs-renderer",
"reference": "https://github.com/swhsiang/comfyui-3d-gs-renderer",
"files": [
"https://github.com/swhsiang/comfyui-3d-gs-renderer"
],
"install_type": "git-clone",
"description": "ComfyUI custom node to support 3D GS rendering"
},
{
"author": "sLKbabawhsiang",
"title": "ComfyUI-TuZi-Flux-Kontext",
"reference": "https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext",
"files": [
"https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext"
],
"install_type": "git-clone",
"description": " Powerful Flux-Kontext image generation custom node for ComfyUI, using the official RabbitAI API. Supports text-to-image, image-to-image, and multi-image-to-image generation. Supports concurrent generation."
},
{
"author": "MicheleGuidi",
"title": "ComfyUI-Computer-Vision",
"reference": "https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2",
"files": [
"https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2"
],
"install_type": "git-clone",
"description": "Extension nodes for ComfyUI that improves automatic segmentation using bounding boxes generated by Florence 2 and segmentation from Segment Anything 2 (SAM2). Currently just an enhancement of nodes from [a/Kijai](https://github.com/kijai/ComfyUI-segment-anything-2)."
},
{
"author": "Pigidiy",
"title": "ComfyUI-LikeSpiderAI-UI",
"id": "like_spider_ui",
"reference": "https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI",
"files": [
"https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI"
],
"install_type": "git-clone",
"description": "Declarative UI Framework for ComfyUI Nodes. Minimalistic base class for creating UI-based audio/text/image nodes."
},
{
"author": "hexxacubic",
"title": "ComfyUI-Prompt_Library",
"reference": "https://github.com/hexxacubic/ComfyUI-Prompt_Library",
"files": [
"https://github.com/hexxacubic/ComfyUI-Prompt_Library"
],
"install_type": "git-clone",
"description": "A ComfyUI Node to save and load prompts from a library."
},
{
"author": "judian17",
"title": "ComfyUI-UniWorld-jd17",
"reference": "https://github.com/judian17/ComfyUI-UniWorld-jd17",
"files": [
"https://github.com/judian17/ComfyUI-UniWorld-jd17"
],
"install_type": "git-clone",
"description": "Unofficial ComfyUI implementation of [a/UniWorld-V1](https://github.com/PKU-YuanGroup/UniWorld-V1)."
},
{
"author": "whmc76",
"title": "ComfyUI-UniversalToolkit",
"reference": "https://github.com/whmc76/ComfyUI-UniversalToolkit",
"files": [
"https://github.com/whmc76/ComfyUI-UniversalToolkit"
],
"install_type": "git-clone",
"description": "This plugin provides general-purpose utility nodes for ComfyUI. Currently, it implements a 'Blank Cell Generator' node, which can batch-generate images, masks, and latents with specified resolution and color."
"description": "If you see this message, your ComfyUI-Manager is outdated.\nRecent channel provides only the list of the latest nodes. If you want to find the complete node list, please go to the Default channel.\nMaking LoRA has never been easier!"
},
{
"author": "xmarre",
"title": "LoRA-Safe TorchCompile",
@@ -690,6 +568,136 @@
],
"description": "Merge up to 4 LoRA models with balanced, order-independent logic. Inspired by WebUI SuperMerger.",
"install_type": "git-clone"
},
{
"author": "whmc76",
"title": "ComfyUI-RemoveBackgroundSuite",
"reference": "https://github.com/whmc76/ComfyUI-RemoveBackgroundSuite",
"files": [
"https://github.com/whmc76/ComfyUI-RemoveBackgroundSuite"
],
"install_type": "git-clone",
"description": "A matting toolkit based on ComfyUI, supporting multiple matting models and detail processing methods."
},
{
"author": "mrcuddle",
"title": "Underage Filter",
"reference": "https://github.com/T-Ph525/ComfyUI-Underage-Filter",
"files": [
"https://github.com/T-Ph525/ComfyUI-Underage-Filter"
],
"description": "An implementation to detect underage subjects in images for ComfyUI.",
"install_type": "git-clone"
},
{
"author": "ToTheBeginning",
"title": "DreamO Comfyui",
"reference": "https://github.com/ToTheBeginning/ComfyUI-DreamO",
"files": [
"https://github.com/ToTheBeginning/ComfyUI-DreamO"
],
"description": "[a/DreamO](https://github.com/bytedance/DreamO) ComfyUI native implementation.",
"install_type": "git-clone"
},
{
"author": "SanDiegoDude",
"title": "ComfyUI-Kontext-API",
"reference": "https://github.com/SanDiegoDude/ComfyUI-Kontext-API",
"files": [
"https://github.com/SanDiegoDude/ComfyUI-Kontext-API"
],
"install_type": "git-clone",
"description": "A custom ComfyUI node for integrating with the Fal Kontext API for advanced image editing and generation."
},
{
"author": "juntaosun",
"title": "ComfyUI_open_nodes",
"reference": "https://github.com/juntaosun/ComfyUI_open_nodes",
"files": [
"https://github.com/juntaosun/ComfyUI_open_nodes"
],
"install_type": "git-clone",
"description": "ComfyUI open nodes by juntaosun."
},
{
"author": "angree",
"title": "Q Find Mask Size",
"reference": "https://github.com/angree/ComfyUI-Q_find-mask-size",
"files": [
"https://github.com/angree/ComfyUI-Q_find-mask-size"
],
"install_type": "git-clone",
"description": "ComfyUI custom node for finding and analyzing mask sizes in images"
},
{
"author": "Yuan-ManX",
"title": "ComfyUI-HunyuanVideo-Avatar",
"reference": "https://github.com/Yuan-ManX/ComfyUI-HunyuanVideo-Avatar",
"files": [
"https://github.com/Yuan-ManX/ComfyUI-HunyuanVideo-Avatar"
],
"install_type": "git-clone",
"description": "ComfyUI-HunyuanVideo-Avatar is now available in ComfyUI, HunyuanVideo-Avatar is a multimodal diffusion transformer (MM-DiT)-based model capable of simultaneously generating dynamic, emotion-controllable, and multi-character dialogue videos."
},
{
"author": "DragonDiffusionbyBoyo",
"title": "BoyoSupercoolWrapper",
"reference": "https://github.com/DragonDiffusionbyBoyo/BoyoSupercoolWrapper",
"files": [
"https://github.com/DragonDiffusionbyBoyo/BoyoSupercoolWrapper"
],
"install_type": "git-clone",
"description": "This is a ComfyUI wrapper for Andrew DalPino's SuperCool upscaler, enabling its use directly within ComfyUI's node workflow. No extra dependencies required—just drop in the models and go."
},
{
"author": "filliptm",
"title": "ComfyUI_Fill-ChatterBox",
"reference": "https://github.com/filliptm/ComfyUI_Fill-ChatterBox",
"files": [
"https://github.com/filliptm/ComfyUI_Fill-ChatterBox"
],
"install_type": "git-clone",
"description": "Voice Clone and TTS model."
},
{
"author": "MijnSpam",
"title": "Comfy swap and scale",
"reference": "https://github.com/MijnSpam/ComfyUI_SwapAndScale",
"files": [
"https://github.com/MijnSpam/ComfyUI_SwapAndScale"
],
"install_type": "git-clone",
"description": "Do you want to easily swap width and heigth? Than this is for you. From portrait to Landscape. Is you images model trained on 1MP pictures, then you can easily scale those down. For best pictures width and heigth should be a factor of 32, say no more..."
},
{
"author": "narusas",
"title": "ComfyUI Logic Support",
"reference": "https://github.com/narusas/Comfyui-Logic-Support",
"files": [
"https://github.com/narusas/Comfyui-Logic-Support"
],
"install_type": "git-clone",
"description": "A collection of logic and utility nodes for ComfyUI to enhance workflow capabilities."
},
{
"author": "wTechArtist",
"title": "ComfyUI VVL Video Camera Advanced",
"reference": "https://github.com/wTechArtist/ComfyUI_VVL_VideoCamera_Advanced",
"files": [
"https://github.com/wTechArtist/ComfyUI_VVL_VideoCamera_Advanced"
],
"install_type": "git-clone",
"description": "A professional video camera parameter estimation toolkit based on the VGGT model."
},
{
"author": "niknah",
"title": "Audio General",
"reference": "https://github.com/niknah/audio-general-ComfyUI",
"files": [
"https://github.com/niknah/audio-general-ComfyUI"
],
"install_type": "git-clone",
"description": "General audio nodes. Mix, Bass/Treble, Concatenate, Pitch, Add/remove silence, Speed"
}
]
}

View File

@@ -256,12 +256,10 @@
"ALLty",
"EGRWGL",
"EGRYDZQHNode",
"EGSEED",
"GroupSwitchNode",
"GroupSwitchNodee",
"GroupSwitchNodeee",
"GroupSwitchNodeeee",
"GroupSwitchNodi",
"hulue",
"jinyong"
],
@@ -332,21 +330,10 @@
],
"https://github.com/2frames/ComfyUI-AQnodes": [
[
"AQ_BatchAverageImage",
"AQ_BlendImages",
"AQ_CLIPSetLastLayer",
"AQ_ColorMatchImage",
"AQ_Gemini",
"AQ_ImageMaskSwitch",
"AQ_Image_DetailTransfer",
"AQ_Image_Pad",
"AQ_Increment",
"AQ_LoadImageBase64",
"AQ_MasksAndImagesAsList",
"AQ_Qwen",
"AQ_QwenLoader",
"AQ_Random",
"AQ_SaveImageWebpReturnBase64",
"AQ_SendImageToAPI",
"AQ_multiface_ApplyPulidFlux"
],
@@ -3485,7 +3472,6 @@
"Categorizer",
"CollectAndDistributeText",
"Coloring",
"ConditionalLoRAApplierCreepybits",
"CustomNodeManager",
"DelayNode",
"DelayTextNode",
@@ -3551,15 +3537,7 @@
"title_aux": "ComfyUi Random Manage Cyan"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-Image-Vector": [
[
"Vector"
],
{
"title_aux": "Cyber-BlackCat"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-MoneyMaker": [
"https://github.com/Cyber-Blacat/ComfyUI-Yuan": [
[
", and the value is the function name in the right of the",
"Black and white",
@@ -3579,6 +3557,14 @@
"title_aux": "ComfyUI-Yuan"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI-Image-Vector": [
[
"Vector"
],
{
"title_aux": "Cyber-BlackCat"
}
],
"https://github.com/Cyber-BlackCat/ComfyUI_Auto_Caption": [
[
"Auto Caption",
@@ -5474,8 +5460,6 @@
"Integer to Float",
"Integer to String",
"Latent Switch",
"Load Image",
"Logic Compare",
"Math Operation",
"Model Switch",
"Prompt Combiner",
@@ -7029,7 +7013,6 @@
"ImageSizeAdjustment",
"InspyrenetRembgLoader",
"InspyrenetRembgProcess",
"LG_LatentBatchToList",
"LG_LoadImage",
"LG_Noise",
"LazySwitch1way",
@@ -7052,16 +7035,6 @@
"title_aux": "ImagesGrid"
}
],
"https://github.com/LKbaba/ComfyUI-TuZi-Flux-Kontext": [
[
"FluxKontext_ImageToImage",
"FluxKontext_MultiImageToImage",
"FluxKontext_TextToImage"
],
{
"title_aux": "ComfyUI-TuZi-Flux-Kontext"
}
],
"https://github.com/LamEmil/ComfyUI_ASCIIArtNode": [
[
"ASCIIAnimationGenerator",
@@ -7174,7 +7147,6 @@
"BoolToString|LP",
"CLIP Text Encode Translate [LP]",
"CLIPTextEncodeTranslate|LP",
"Calculate Target Size By Mask [LP]",
"CalculateTargetSizeByMask|LP",
"Convert Bool To Int [LP]",
"Convert Bool To String [LP]",
@@ -7190,17 +7162,12 @@
"Convert String To Number [LP]",
"Count Objects [LP]",
"CountObjects|LP",
"Cropped Aspect Size Parameters [LP]",
"Cropped Forsed Size Parameters [LP]",
"Cropped Free Size Parameters [LP]",
"Cropped Ranged Size Parameters [LP]",
"CroppedAspectSizeParameters|LP",
"CroppedForsedSizeParameters|LP",
"CroppedFreeSizeParameters|LP",
"CroppedRangedSizeParameters|LP",
"Delay [LP]",
"Delay|LP",
"Extend Factor Parameters [LP]",
"ExtendFactorParameters|LP",
"Fast Checker Pattern [LP]",
"FastCheckerPattern|LP",
@@ -7217,8 +7184,6 @@
"Image Overlay [LP]",
"ImageLoaderFromPath|LP",
"ImageOverlay|LP",
"Inpaint Crop [LP]",
"Inpaint Stitch [LP]",
"InpaintCrop|LP",
"InpaintStitch|LP",
"IntToBool|LP",
@@ -7252,8 +7217,6 @@
"RemoveBannedTagsFromTags|LP",
"RemoveBannedTagsFromText|LP",
"RemoveDuplicateTags|LP",
"Resize Image To Target Size [LP]",
"Resize Image and Masks [LP]",
"ResizeImageAndMasks|LP",
"ResizeImageToTargetSize|LP",
"Resorting Tags [LP]",
@@ -7700,13 +7663,8 @@
"LoraTagLoader",
"ResolutionSelector",
"StringCleaning",
"StringTextExtractor",
"StringTextSplitter",
"TiktokenTokenizer",
"WildcardProcessor",
"\u26d4 Generate Negative Prompt",
"\u2702\ufe0f String Text Extractor",
"\u2702\ufe0f String Text Splitter",
"\u2728\ud83c\udf10 Groq ALM API - Translate [EN only]",
"\u2728\ud83d\udcac Groq LLM API",
"\u2728\ud83d\udcdd Groq ALM API - Transcribe",
@@ -7715,7 +7673,6 @@
"\ud83d\udcbe Save Text File With Path",
"\ud83d\udcc1 Get File Path",
"\ud83d\udcd0 Resolution Image Size Selector",
"\ud83d\udcdd Wildcard Processor",
"\ud83d\udd20 Tiktoken Tokenizer Info",
"\ud83d\uddbc\ufe0f Download Image from URL",
"\ud83e\uddf9 String Cleaning"
@@ -7982,15 +7939,6 @@
"title_aux": "ComfyUI ZhipuAI Platform"
}
],
"https://github.com/MicheleGuidi/ComfyUI-Contextual-SAM2": [
[
"Sam2ContextSegmentation",
"Sam2TiledSegmentation"
],
{
"title_aux": "ComfyUI-Computer-Vision"
}
],
"https://github.com/MiddleKD/ComfyUI-denoise-mask-scheduler": [
[
"ApplyDenoiseMaskSchedulerWithSigma",
@@ -9185,14 +9133,6 @@
"title_aux": "ComfyUI-LikeSpiderAI-SaveMP3"
}
],
"https://github.com/Pigidiy/ComfyUI-LikeSpiderAI-UI": [
[
"AudioExport"
],
{
"title_aux": "ComfyUI-LikeSpiderAI-UI"
}
],
"https://github.com/PixelFunAI/ComfyUI_PixelFun": [
[
"HunyuanLoadAndEditLoraBlocks",
@@ -9955,8 +9895,7 @@
],
"https://github.com/Santodan/santodan-custom-nodes-comfyui": [
[
"RandomLoRACustom",
"RandomLoRAFolder"
"RandomLoRACustom"
],
{
"title_aux": "Santodan Random LoRA Node"
@@ -11348,7 +11287,6 @@
"Basic data handling: PathListDir",
"Basic data handling: PathNormalize",
"Basic data handling: PathRelative",
"Basic data handling: PathSetExtension",
"Basic data handling: PathSplit",
"Basic data handling: PathSplitExt",
"Basic data handling: RegexFindallDataList",
@@ -11482,9 +11420,7 @@
"StarGridImageBatcher",
"StarImageSwitch",
"StarImageSwitch2",
"StarInfiniteYouAdvancedPatchMaker",
"StarInfiniteYouApply",
"StarInfiniteYouFaceSwapMod",
"StarInfiniteYouPatch",
"StarInfiniteYouPatchCombine",
"StarInfiniteYouSaver",
@@ -11493,12 +11429,10 @@
"StarNewsScraper",
"StarPSDSaver",
"StarPSDSaver2",
"StarPaletteExtractor",
"StarSaveSamplerSettings",
"StarTextFilter",
"StarTextInput",
"StarWildcardsAdvanced",
"Star_Image2Latent",
"Starnodes_Aspect_Ratio",
"Starnodes_Aspect_Ratio_Advanced",
"Starupscale"
@@ -13244,13 +13178,10 @@
],
"https://github.com/XieJunchen/comfyUI_LLM": [
[
"CloudImageUploadNode",
"CloudImagesToVideoAndUpload",
"CloudVideoUploadNode",
"ComfyUI_LLM_Ollama",
"DeepSeek_Online",
"LoadGifFromLocal",
"LoadImgFromUrl",
"QiniuImageUploadNode",
"QiniuVideoUploadNode",
"StringArrayFormatter",
"StringArrayIndexer"
],
@@ -15268,17 +15199,6 @@
"title_aux": "Avatar Graph"
}
],
"https://github.com/avenstack/ComfyUI-AV-FunASR": [
[
"AVASRTimestamp",
"AVFormat2Subtitle",
"AVSaveSubtitles",
"AVSpeechTimestamp"
],
{
"title_aux": "ComfyUI-AV-FunASR"
}
],
"https://github.com/avenstack/ComfyUI-AV-LatentSync": [
[
"AVLatentSync",
@@ -16425,15 +16345,6 @@
"title_aux": "ComfyUI Sequential Image Loader"
}
],
"https://github.com/budihartono/comfyui-aspect-ratio-presets": [
[
"CAS Empty Latent Aspect Ratio by Axis",
"CAS Empty Latent Aspect Ratio from Preset"
],
{
"title_aux": "CAS Aspect Ratio Presets Node for ComfyUI"
}
],
"https://github.com/budihartono/comfyui_otonx_nodes": [
[
"OTX Integer Multiple Inputs 4",
@@ -16518,17 +16429,6 @@
"title_aux": "EBU PromptHelper"
}
],
"https://github.com/burnsbert/ComfyUI-EBU-Workflow": [
[
"EbuGetImageAspectRatio",
"EbuScalingResolution",
"EbuScalingTile",
"EbuUniqueFileName"
],
{
"title_aux": "EBU Workflow"
}
],
"https://github.com/bvhari/ComfyUI_CFGStar": [
[
"CFGStar"
@@ -19110,7 +19010,7 @@
"title_aux": "ComfyUI Anime Segmentation Nodes v1.1.0"
}
],
"https://github.com/crave33/RenesStuffDanbooruTagGet": [
"https://github.com/crave33/RenesStuffDanboruTagGet": [
[
"DanbooruTagFetcher"
],
@@ -20264,6 +20164,32 @@
"title_aux": "ComfyUI_Dragos_Nodes"
}
],
"https://github.com/dream-computing/syntax-nodes": [
[
"CyberpunkMagnifyNode",
"CyberpunkWindowNode",
"DepthToLidarEffectNode",
"EdgeMeasurementOverlayNode",
"EdgeTracingNode",
"FrequencyBeatSyncNode",
"FrequencyBeatSyncNodeAdvanced",
"GhostingNode",
"ImageBatchToImageList",
"ImageListToImageBatch",
"JigsawPuzzleNode",
"LowPolyNode",
"LuminanceParticleNode",
"PaperCraftNode",
"PointillismNode",
"RGBStreakNode",
"RegionBoundaryNode",
"VariableLineWidthEffectNode",
"VoxelNode"
],
{
"title_aux": "SyntaxNodes - Image Processing Effects for ComfyUI"
}
],
"https://github.com/dreamhartley/ComfyUI_show_seed": [
[
"Show Seed"
@@ -21550,27 +21476,17 @@
],
"https://github.com/gelasdev/ComfyUI-FLUX-BFL-API": [
[
"FluxDeleteFinetune_BFL",
"FluxDevRedux_BFL",
"FluxDev_BFL",
"FluxFinetuneDetails_BFL",
"FluxFinetuneStatus_BFL",
"FluxFinetune_BFL",
"FluxKontextMax_BFL",
"FluxKontextPro_BFL",
"FluxMyFinetunes_BFL",
"FluxPro11Redux_BFL",
"FluxPro11UltraFinetune_BFL",
"FluxPro11UltraRedux_BFL",
"FluxPro11Ultra_BFL",
"FluxPro11_BFL",
"FluxProCannyFinetune_BFL",
"FluxProCanny_BFL",
"FluxProDepthFinetune_BFL",
"FluxProDepth_BFL",
"FluxProFillFinetune_BFL",
"FluxProFill_BFL",
"FluxProFinetune_BFL",
"FluxPro_BFL"
],
{
@@ -22676,16 +22592,6 @@
"title_aux": "comfyui_LLM_schools"
}
],
"https://github.com/hexxacubic/ComfyUI-Prompt_Library": [
[
"Prompt_Library",
"Random_Project",
"Simple_Prompt_Library"
],
{
"title_aux": "ComfyUI-Prompt_Library"
}
],
"https://github.com/hgabha/WWAA-CustomNodes": [
[
"WWAA-BuildString",
@@ -23957,18 +23863,6 @@
"title_aux": "Painting Coder Utils"
}
],
"https://github.com/jasonjgardner/comfui-substance-designer-integration": [
[
"SubstanceBatchProcessor",
"SubstanceCooker",
"SubstanceInfoExtractor",
"SubstanceParameterController",
"SubstanceRenderer"
],
{
"title_aux": "ComfyUI Substance Designer Integration Plugin"
}
],
"https://github.com/jax-explorer/ComfyUI-InstantCharacter": [
[
"InstantCharacterGenerate",
@@ -24346,7 +24240,6 @@
"ai4artsed_random_artform_generator",
"ai4artsed_random_instruction_generator",
"ai4artsed_random_language_selector",
"ai4artsed_stabilitai_key",
"ai4artsed_t5_clip_fusion",
"ai4artsed_text_remix"
],
@@ -24469,17 +24362,6 @@
"title_aux": "ComfyUI-Extract_Flux_Lora"
}
],
"https://github.com/judian17/ComfyUI-UniWorld-jd17": [
[
"UniWorldEncoderNode",
"UniWorldScheduler",
"UniWorldSiglipEncoder",
"UniWorld_T5_CLIP_Encoder"
],
{
"title_aux": "ComfyUI-UniWorld-jd17"
}
],
"https://github.com/judian17/ComfyUI-joycaption-beta-one-GGUF": [
[
"JJC_JoyCaption_Custom_GGUF",
@@ -24592,7 +24474,6 @@
"Bjornulf_ImageMaskCutter",
"Bjornulf_ImageNote",
"Bjornulf_ImageNoteLoadImage",
"Bjornulf_ImageUpscaleWithModelTransparency",
"Bjornulf_ImagesListToVideo",
"Bjornulf_JSONImagePromptExtractor",
"Bjornulf_KokoroTTS",
@@ -24724,7 +24605,6 @@
"Bjornulf_WriteTextPickMeGlobal",
"Bjornulf_XTTSConfig",
"Bjornulf_imagesToVideo",
"Bjornulf_loadImageBase64Transparency",
"Bjornulf_ollamaLoader"
],
{
@@ -24925,6 +24805,14 @@
"title_aux": "ComfyUI-text-file-util"
}
],
"https://github.com/kambara/ComfyUI-PromptCheckList": [
[
"PromptPalette"
],
{
"title_aux": "ComfyUI-PromptCheckList"
}
],
"https://github.com/kambara/ComfyUI-PromptPalette": [
[
"PromptPalette"
@@ -26109,7 +25997,6 @@
"https://github.com/laksjdjf/ComfyUI-Imatrix": [
[
"ImatrixUNETLoader",
"LoRAdiff",
"SaveImatrix"
],
{
@@ -27682,7 +27569,6 @@
"ScheduledCFGGuider //Inspire",
"ScheduledPerpNegCFGGuider //Inspire",
"SeedExplorer //Inspire",
"SeedLogger //Inspire",
"SelectNthMask //Inspire",
"ShowCachedInfo //Inspire",
"StableCascade_CheckpointLoader //Inspire",
@@ -28355,7 +28241,16 @@
"TextExtractorNode"
],
{
"title_aux": "comfyui-MGnodes"
"title_aux": "ComfyUI Image Watermarking Node"
}
],
"https://github.com/meanin2/comfyui-watermarking": [
[
"ImageWatermarkNode",
"TextExtractorNode"
],
{
"title_aux": "ComfyUI Watermark Image Node"
}
],
"https://github.com/meap158/ComfyUI-Background-Replacement": [
@@ -28834,8 +28729,14 @@
],
"https://github.com/mit-han-lab/ComfyUI-nunchaku": [
[
"NunchakuDepthPreprocessor",
"NunchakuFluxDiTLoader",
"NunchakuFluxLoraLoader"
"NunchakuFluxLoraLoader",
"NunchakuModelMerger",
"NunchakuPulidApply",
"NunchakuPulidLoader",
"NunchakuTextEncoderLoader",
"NunchakuTextEncoderLoaderV2"
],
{
"title_aux": "ComfyUI-nunchaku"
@@ -30394,14 +30295,6 @@
"title_aux": "paint-by-example @ ComfyUI"
}
],
"https://github.com/pictorialink/ComfyUI-Custom-Node-Config": [
[
"FormSubmitNode"
],
{
"title_aux": "ComfyUI-Custom-Node-Config"
}
],
"https://github.com/pictorialink/ComfyUI-Text-Translation": [
[
"Get_Translator",
@@ -31350,8 +31243,7 @@
"PrimitiveText",
"UtilityExpression",
"UtilityImageDimensions",
"UtilitySwitch",
"rookiepsi_ConstructMask"
"UtilitySwitch"
],
{
"title_aux": "ComfyUI Extended"
@@ -31811,10 +31703,7 @@
],
"https://github.com/s9roll7/comfyui_cotracker_node": [
[
"CoTrackerNode",
"GridPointGeneratorNode",
"PerlinCoordinateRandomizerNode",
"XYMotionAmplifierNode"
"CoTrackerNode"
],
{
"title_aux": "Comfyui CoTracker Node"
@@ -33335,34 +33224,12 @@
],
"https://github.com/spawner1145/CUI-Lumina2-TeaCache": [
[
"LPIPS_Model_Loader",
"Store_Baseline_Image",
"TeaCache_LPIPS_Evaluator",
"TeaCache_Lumina2",
"TeaCache_Patcher",
"TeaCache_Result_Collector"
"TeaCache_Lumina2"
],
{
"title_aux": "CUI-Lumina2-TeaCache"
}
],
"https://github.com/spawner1145/comfyui-aichat": [
[
"GeminiApiLoader_Zho",
"GeminiChat_Zho",
"GeminiFileUploader_Zho",
"GeminiImageEncoder_Zho",
"GeminiTextBlock_Zho",
"OpenAIApiLoader_Zho",
"OpenAIChat_Zho",
"OpenAIFileUploader_Zho",
"OpenAIImageEncoder_Zho",
"OpenAITextBlock_Zho"
],
{
"title_aux": "comfyui-aichat"
}
],
"https://github.com/spinagon/ComfyUI-seam-carving": [
[
"SeamCarving"
@@ -34014,7 +33881,7 @@
"OllamaKiller"
],
{
"title_aux": "ComfyUI-ollama_killer"
"title_aux": "OllamaKiller Node for ComfyUI"
}
],
"https://github.com/thezveroboy/ComfyUI-CSM-Nodes": [
@@ -34793,10 +34660,7 @@
[
"CreatePromptsWithTextFromFile",
"EmptyLatentSizePicker",
"LoadDataFromFiles",
"SimpleSizePicker",
"WildcardReplace",
"WildcardReplaceFromFile"
"SimpleSizePicker"
],
{
"title_aux": "ComfyUI_BishaNodes"
@@ -35031,20 +34895,6 @@
"title_aux": "ComfyUI-RemoveBackgroundSuite"
}
],
"https://github.com/whmc76/ComfyUI-UniversalToolkit": [
[
"EmptyUnitGenerator_UTK",
"ImageRatioDetector_UTK",
"PreviewMask_UTK",
"ShowFloat_UTK",
"ShowInt_UTK",
"ShowList_UTK",
"ShowText_UTK"
],
{
"title_aux": "ComfyUI-UniversalToolkit"
}
],
"https://github.com/wildminder/ComfyUI-Chatterbox": [
[
"ChatterboxTTS",
@@ -35497,8 +35347,8 @@
"LTLatentOp",
"LTLatentToShape",
"LTLatentsConcatenate",
"LTNumberRangeGaussian",
"LTNumberRangeUniform",
"LTParamRandomizerGaussian",
"LTParamRandomizerRange",
"LTPreviewLatent",
"LTReshapeLatent",
"LTUniformLatent"
@@ -35841,21 +35691,18 @@
"MaskSmartValleySplit",
"MaskSplitFilter",
"MaskTopNFilter",
"TextKeyword",
"TextBeforeKeyword",
"YC Extract Number",
"YC Mask Condition Switch",
"YC Seed List",
"YC Super Selector",
"YC Text Condition Switch",
"YC Text Index Switch",
"YC Universal Gate",
"YCMaskComposite",
"YCPromptReplace",
"YCRemapMaskRange",
"YCTextImageGenerator",
"YC_FiveTextCombineNode",
"YC_Image_Save",
"YC_SingleTextNode",
"YC_textReplaceNode"
"YC_Image_Save"
],
{
"title_aux": "ComfyUI-YCNodes"
@@ -36536,6 +36383,7 @@
"DCI_BinaryFileLoader",
"DCI_BinaryFileSaver",
"DCI_BinaryFileUploader",
"DCI_FileLoader",
"DCI_FileNode",
"DCI_Image",
"DCI_ImageExporter",

View File

@@ -11,9 +11,6 @@ info:
servers:
- url: '/'
description: Default ComfyUI server
# Default security - can be overridden per operation
security: []
# Common API components
components:
@@ -32,18 +29,8 @@ components:
type: string
description: Type of task being performed
enum: [install, uninstall, update, update-all, update-comfyui, fix, disable, enable, install-model]
params:
oneOf:
- $ref: '#/components/schemas/InstallPackParams'
- $ref: '#/components/schemas/UpdatePackParams'
- $ref: '#/components/schemas/UpdateAllPacksParams'
- $ref: '#/components/schemas/UpdateComfyUIParams'
- $ref: '#/components/schemas/FixPackParams'
- $ref: '#/components/schemas/UninstallPackParams'
- $ref: '#/components/schemas/DisablePackParams'
- $ref: '#/components/schemas/EnablePackParams'
- $ref: '#/components/schemas/ModelMetadata'
required: [ui_id, client_id, kind, params]
required: [ui_id, client_id, kind]
TaskHistoryItem:
type: object
properties:
@@ -66,6 +53,7 @@ components:
status:
$ref: '#/components/schemas/TaskExecutionStatus'
required: [ui_id, client_id, kind, timestamp, result]
TaskExecutionStatus:
type: object
properties:
@@ -82,6 +70,7 @@ components:
type: string
description: Additional status messages
required: [status_str, completed, messages]
TaskStateMessage:
type: object
properties:
@@ -100,17 +89,14 @@ components:
items:
$ref: '#/components/schemas/QueueTaskItem'
description: Tasks waiting to be executed
installed_packs:
type: object
additionalProperties:
$ref: '#/components/schemas/ManagerPackInstalled'
description: Map of currently installed node packages by name
required: [history, running_queue, pending_queue, installed_packs]
required: [history, running_queue, pending_queue]
# WebSocket Message Models
ManagerMessageName:
type: string
enum: [cm-task-completed, cm-task-started, cm-queue-status]
description: WebSocket message type constants for manager events
MessageTaskDone:
type: object
properties:
@@ -132,6 +118,7 @@ components:
state:
$ref: '#/components/schemas/TaskStateMessage'
required: [ui_id, result, kind, timestamp, state]
MessageTaskStarted:
type: object
properties:
@@ -148,6 +135,7 @@ components:
state:
$ref: '#/components/schemas/TaskStateMessage'
required: [ui_id, kind, timestamp, state]
MessageTaskFailed:
type: object
properties:
@@ -167,12 +155,14 @@ components:
state:
$ref: '#/components/schemas/TaskStateMessage'
required: [ui_id, error, kind, timestamp, state]
MessageUpdate:
oneOf:
- $ref: '#/components/schemas/MessageTaskDone'
- $ref: '#/components/schemas/MessageTaskStarted'
- $ref: '#/components/schemas/MessageTaskFailed'
description: Union type for all possible WebSocket message updates
# Manager Package Models
ManagerPackInfo:
type: object
@@ -187,6 +177,7 @@ components:
type: string
description: Task ID - generated internally
required: [id, version]
ManagerPackInstalled:
type: object
properties:
@@ -194,35 +185,43 @@ components:
type: string
description: The version of the pack that is installed (Git commit hash or semantic version)
cnr_id:
type: [string, 'null']
type: string
nullable: true
description: The name of the pack if installed from the registry
aux_id:
type: [string, 'null']
type: string
nullable: true
description: The name of the pack if installed from github (author/repo-name format)
enabled:
type: boolean
description: Whether the pack is enabled
required: [ver, enabled]
SelectedVersion:
type: string
enum: [latest, nightly]
description: Version selection for pack installation
ManagerChannel:
type: string
enum: [default, recent, legacy, forked, dev, tutorial]
description: Channel for pack sources
ManagerDatabaseSource:
type: string
enum: [remote, local, cache]
description: Source for pack information
ManagerPackState:
type: string
enum: [installed, disabled, not_installed, import_failed, needs_update]
description: Current state of a pack
ManagerPackInstallType:
type: string
enum: [git-clone, copy, cnr]
description: Type of installation used for the pack
ManagerPack:
allOf:
- $ref: '#/components/schemas/ManagerPackInfo'
@@ -250,8 +249,9 @@ components:
state:
$ref: '#/components/schemas/ManagerPackState'
update-state:
type: [string, 'null']
type: string
enum: ['false', 'true']
nullable: true
description: Update availability status
stars:
type: integer
@@ -271,6 +271,7 @@ components:
description: Whether the pack is trusted
install_type:
$ref: '#/components/schemas/ManagerPackInstallType'
# Installation Parameters
InstallPackParams:
allOf:
@@ -298,6 +299,7 @@ components:
type: boolean
description: Whether to skip post-installation steps
required: [selected_version, mode, channel]
UpdateAllPacksParams:
type: object
properties:
@@ -306,66 +308,7 @@ components:
ui_id:
type: string
description: Task ID - generated internally
UpdatePackParams:
type: object
properties:
node_name:
type: string
description: Name of the node package to update
node_ver:
type: [string, 'null']
description: Current version of the node package
required: [node_name]
UpdateComfyUIParams:
type: object
properties:
is_stable:
type: boolean
description: Whether to update to stable version (true) or nightly (false)
default: true
target_version:
type: [string, 'null']
description: Specific version to switch to (for version switching operations)
required: []
FixPackParams:
type: object
properties:
node_name:
type: string
description: Name of the node package to fix
node_ver:
type: string
description: Version of the node package
required: [node_name, node_ver]
UninstallPackParams:
type: object
properties:
node_name:
type: string
description: Name of the node package to uninstall
is_unknown:
type: boolean
description: Whether this is an unknown/unregistered package
default: false
required: [node_name]
DisablePackParams:
type: object
properties:
node_name:
type: string
description: Name of the node package to disable
is_unknown:
type: boolean
description: Whether this is an unknown/unregistered package
default: false
required: [node_name]
EnablePackParams:
type: object
properties:
cnr_id:
type: string
description: ComfyUI Node Registry ID of the package to enable
required: [cnr_id]
# Queue Status Models
QueueStatus:
type: object
@@ -389,23 +332,23 @@ components:
type: string
description: Client ID (when filtered by client)
required: [total_count, done_count, in_progress_count, is_processing]
# Mappings Model
ManagerMappings:
type: object
additionalProperties:
type: array
description: Tuple of [node_names, metadata]
items:
oneOf:
- type: array
items:
- type: array
items:
type: string
description: List of ComfyNode names included in the pack
- type: object
properties:
title_aux:
type: string
description: List of ComfyNode names included in the pack
- type: object
properties:
title_aux:
type: string
description: The display name of the pack
description: The display name of the pack
# Model Management
ModelMetadata:
type: object
@@ -432,6 +375,7 @@ components:
type: string
description: ID for UI reference
required: [name, type, url, filename]
# Legacy Node Package Model (for backward compatibility)
NodePackageMetadata:
type: object
@@ -469,10 +413,12 @@ components:
mode:
type: string
description: Source mode
# Snapshot Models
SnapshotItem:
type: string
description: Name of the snapshot
# Error Models
Error:
type: object
@@ -481,12 +427,14 @@ components:
type: string
description: Error message
required: [error]
# Response Models
InstalledPacksResponse:
type: object
additionalProperties:
$ref: '#/components/schemas/ManagerPackInstalled'
description: Map of pack names to their installation info
HistoryResponse:
type: object
properties:
@@ -495,6 +443,7 @@ components:
additionalProperties:
$ref: '#/components/schemas/TaskHistoryItem'
description: Map of task IDs to their history items
HistoryListResponse:
type: object
properties:
@@ -503,6 +452,7 @@ components:
items:
type: string
description: List of available batch history IDs
# State Management Models
InstalledNodeInfo:
type: object
@@ -514,7 +464,8 @@ components:
type: string
description: Installed version
repository_url:
type: [string, 'null']
type: string
nullable: true
description: Git repository URL
install_method:
type: string
@@ -524,10 +475,12 @@ components:
description: Whether the node is currently enabled
default: true
install_date:
type: [string, 'null']
type: string
format: date-time
nullable: true
description: ISO timestamp of installation
required: [name, version, install_method]
InstalledModelInfo:
type: object
properties:
@@ -541,17 +494,21 @@ components:
type: string
description: Model type (checkpoint, lora, vae, etc.)
size_bytes:
type: [integer, 'null']
type: integer
nullable: true
description: File size in bytes
minimum: 0
hash:
type: [string, 'null']
type: string
nullable: true
description: Model file hash for verification
install_date:
type: [string, 'null']
type: string
format: date-time
nullable: true
description: ISO timestamp when added
required: [name, path, type]
ComfyUIVersionInfo:
type: object
properties:
@@ -559,20 +516,24 @@ components:
type: string
description: ComfyUI version string
commit_hash:
type: [string, 'null']
type: string
nullable: true
description: Git commit hash
branch:
type: [string, 'null']
type: string
nullable: true
description: Git branch name
is_stable:
type: boolean
description: Whether this is a stable release
default: false
last_updated:
type: [string, 'null']
type: string
format: date-time
nullable: true
description: ISO timestamp of last update
required: [version]
BatchOperation:
type: object
properties:
@@ -587,27 +548,32 @@ components:
type: string
description: Target of the operation (node name, model name, etc.)
target_version:
type: [string, 'null']
type: string
nullable: true
description: Target version for the operation
result:
type: string
description: Operation result
enum: [success, failed, skipped]
error_message:
type: [string, 'null']
type: string
nullable: true
description: Error message if operation failed
start_time:
type: string
format: date-time
description: ISO timestamp when operation started
end_time:
type: [string, 'null']
type: string
format: date-time
nullable: true
description: ISO timestamp when operation completed
client_id:
type: [string, 'null']
type: string
nullable: true
description: Client that initiated the operation
required: [operation_id, operation_type, target, result, start_time]
ComfyUISystemState:
type: object
properties:
@@ -618,7 +584,8 @@ components:
comfyui_version:
$ref: '#/components/schemas/ComfyUIVersionInfo'
frontend_version:
type: [string, 'null']
type: string
nullable: true
description: ComfyUI frontend version if available
python_version:
type: string
@@ -641,6 +608,7 @@ components:
additionalProperties: true
description: ComfyUI Manager configuration settings
required: [snapshot_time, comfyui_version, python_version, platform_info]
BatchExecutionRecord:
type: object
properties:
@@ -652,15 +620,15 @@ components:
format: date-time
description: ISO timestamp when batch started
end_time:
type: [string, 'null']
type: string
format: date-time
nullable: true
description: ISO timestamp when batch completed
state_before:
$ref: '#/components/schemas/ComfyUISystemState'
state_after:
type: ['null']
allOf:
- $ref: '#/components/schemas/ComfyUISystemState'
$ref: '#/components/schemas/ComfyUISystemState'
nullable: true
description: System state after batch execution
operations:
type: array
@@ -688,12 +656,14 @@ components:
minimum: 0
default: 0
required: [batch_id, start_time, state_before]
securitySchemes:
securityLevel:
type: apiKey
in: header
name: Security-Level
description: Security level for sensitive operations
parameters:
modeParam:
name: mode
@@ -717,32 +687,21 @@ components:
required: true
schema:
type: string
clientIdParam:
name: client_id
in: query
description: Client ID for filtering tasks
schema:
type: string
uiIdParam:
name: ui_id
in: query
description: Specific task ID to retrieve
schema:
type: string
clientIdRequiredParam:
name: client_id
in: query
required: true
description: Required client ID that initiated the request
schema:
type: string
uiIdRequiredParam:
name: ui_id
in: query
required: true
description: Required unique task identifier
schema:
type: string
maxItemsParam:
name: max_items
in: query
@@ -750,6 +709,7 @@ components:
schema:
type: integer
minimum: 1
offsetParam:
name: offset
in: query
@@ -757,6 +717,7 @@ components:
schema:
type: integer
minimum: 0
# API Paths
paths:
# Task Queue Management (v2 endpoints)
@@ -770,99 +731,10 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/QueueTaskItem'
examples:
install:
summary: Install a custom node
value:
ui_id: "task_123"
client_id: "client_abc"
kind: "install"
params:
id: "pythongosssss/ComfyUI-Custom-Scripts"
version: "latest"
selected_version: "latest"
mode: "remote"
channel: "default"
update:
summary: Update a custom node
value:
ui_id: "task_124"
client_id: "client_abc"
kind: "update"
params:
node_name: "ComfyUI-Custom-Scripts"
node_ver: "1.0.0"
update-all:
summary: Update all custom nodes
value:
ui_id: "task_125"
client_id: "client_abc"
kind: "update-all"
params:
mode: "remote"
update-comfyui:
summary: Update ComfyUI itself
value:
ui_id: "task_126"
client_id: "client_abc"
kind: "update-comfyui"
params:
is_stable: true
fix:
summary: Fix a custom node
value:
ui_id: "task_127"
client_id: "client_abc"
kind: "fix"
params:
node_name: "ComfyUI-Impact-Pack"
node_ver: "2.0.0"
uninstall:
summary: Uninstall a custom node
value:
ui_id: "task_128"
client_id: "client_abc"
kind: "uninstall"
params:
node_name: "ComfyUI-AnimateDiff-Evolved"
is_unknown: false
disable:
summary: Disable a custom node
value:
ui_id: "task_129"
client_id: "client_abc"
kind: "disable"
params:
node_name: "ComfyUI-Manager"
is_unknown: false
enable:
summary: Enable a custom node
value:
ui_id: "task_130"
client_id: "client_abc"
kind: "enable"
params:
cnr_id: "comfyui-manager"
install-model:
summary: Install a model
value:
ui_id: "task_131"
client_id: "client_abc"
kind: "install-model"
params:
name: "SD 1.5 Base Model"
type: "checkpoint"
base: "SD1.x"
save_path: "default"
url: "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned.safetensors"
filename: "v1-5-pruned.safetensors"
responses:
'200':
description: Task queued successfully
'400':
description: Invalid task data
'500':
description: Internal server error
/v2/manager/queue/status:
get:
summary: Get queue status
@@ -876,6 +748,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/QueueStatus'
/v2/manager/queue/history:
get:
summary: Get task history
@@ -901,6 +774,7 @@ paths:
- type: object # File-based batch history
'400':
description: Error retrieving history
/v2/manager/queue/history_list:
get:
summary: Get available batch history files
@@ -914,6 +788,30 @@ paths:
$ref: '#/components/schemas/HistoryListResponse'
'400':
description: Error retrieving history list
/v2/manager/queue/batch/{batch_id}:
get:
summary: Get batch execution record
description: Returns detailed execution record for a specific batch including before/after state snapshots and all operations performed
parameters:
- name: batch_id
in: path
required: true
description: Unique batch identifier
schema:
type: string
responses:
'200':
description: Batch record retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/BatchExecutionRecord'
'404':
description: Batch not found
'400':
description: Error retrieving batch record
/v2/manager/queue/start:
get:
summary: Start queue processing
@@ -923,6 +821,7 @@ paths:
description: Processing started
'201':
description: Processing already in progress
/v2/manager/queue/reset:
get:
summary: Reset queue
@@ -930,6 +829,7 @@ paths:
responses:
'200':
description: Queue reset successfully
/v2/manager/queue/update_all:
get:
summary: Update all custom nodes
@@ -938,29 +838,22 @@ paths:
- securityLevel: []
parameters:
- $ref: '#/components/parameters/modeParam'
- $ref: '#/components/parameters/clientIdRequiredParam'
- $ref: '#/components/parameters/uiIdRequiredParam'
responses:
'200':
description: Update queued successfully
'400':
description: Missing required parameters
'401':
description: Processing already in progress
'403':
description: Security policy violation
/v2/manager/queue/update_comfyui:
get:
summary: Update ComfyUI
description: Queues an update operation for ComfyUI itself
parameters:
- $ref: '#/components/parameters/clientIdRequiredParam'
- $ref: '#/components/parameters/uiIdRequiredParam'
responses:
'200':
description: Update queued successfully
'400':
description: Missing required parameters
/v2/manager/queue/install_model:
post:
summary: Install model
@@ -980,6 +873,7 @@ paths:
description: Invalid model request
'403':
description: Security policy violation
# Custom Nodes Endpoints (v2)
/v2/customnode/getmappings:
get:
@@ -994,6 +888,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ManagerMappings'
/v2/customnode/fetch_updates:
get:
summary: Check for updates
@@ -1026,6 +921,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/InstalledPacksResponse'
/v2/customnode/import_fail_info:
post:
summary: Get import failure information
@@ -1046,6 +942,45 @@ paths:
description: Successful operation
'400':
description: No information available
/v2/customnode/install/git_url:
post:
summary: Install custom node via Git URL
description: Installs a custom node from a Git repository URL
security:
- securityLevel: []
requestBody:
required: true
content:
text/plain:
schema:
type: string
responses:
'200':
description: Installation successful or already installed
'400':
description: Installation failed
'403':
description: Security policy violation
/v2/customnode/install/pip:
post:
summary: Install custom node dependencies via pip
description: Installs Python package dependencies for custom nodes
security:
- securityLevel: []
requestBody:
required: true
content:
text/plain:
schema:
type: string
responses:
'200':
description: Installation successful
'403':
description: Security policy violation
# Snapshot Management Endpoints (v2)
/v2/snapshot/getlist:
get:
@@ -1063,6 +998,7 @@ paths:
type: array
items:
$ref: '#/components/schemas/SnapshotItem'
/v2/snapshot/remove:
get:
summary: Remove snapshot
@@ -1078,6 +1014,7 @@ paths:
description: Error removing snapshot
'403':
description: Security policy violation
/v2/snapshot/restore:
get:
summary: Restore snapshot
@@ -1093,6 +1030,7 @@ paths:
description: Error restoring snapshot
'403':
description: Security policy violation
/v2/snapshot/get_current:
get:
summary: Get current snapshot
@@ -1106,6 +1044,7 @@ paths:
type: object
'400':
description: Error creating snapshot
/v2/snapshot/save:
get:
summary: Save snapshot
@@ -1115,6 +1054,7 @@ paths:
description: Snapshot saved successfully
'400':
description: Error saving snapshot
# ComfyUI Management Endpoints (v2)
/v2/comfyui_manager/comfyui_versions:
get:
@@ -1136,6 +1076,7 @@ paths:
type: string
'400':
description: Error retrieving versions
/v2/comfyui_manager/comfyui_switch_version:
get:
summary: Switch ComfyUI version
@@ -1143,18 +1084,36 @@ paths:
parameters:
- name: ver
in: query
required: true
description: Target version
schema:
type: string
- $ref: '#/components/parameters/clientIdRequiredParam'
- $ref: '#/components/parameters/uiIdRequiredParam'
responses:
'200':
description: Version switch queued successfully
description: Version switch successful
'400':
description: Missing required parameters or error switching version
description: Error switching version
# Configuration Endpoints (v2)
/v2/manager/preview_method:
get:
summary: Get or set preview method
description: Gets or sets the latent preview method
parameters:
- name: value
in: query
required: false
description: New preview method
schema:
type: string
enum: [auto, latent2rgb, taesd, none]
responses:
'200':
description: Setting updated or current value returned
content:
text/plain:
schema:
type: string
/v2/manager/db_mode:
get:
summary: Get or set database mode
@@ -1174,6 +1133,7 @@ paths:
text/plain:
schema:
type: string
/v2/manager/policy/update:
get:
summary: Get or set update policy
@@ -1193,6 +1153,7 @@ paths:
text/plain:
schema:
type: string
/v2/manager/channel_url_list:
get:
summary: Get or set channel URL
@@ -1223,6 +1184,7 @@ paths:
type: string
url:
type: string
/v2/manager/reboot:
get:
summary: Reboot ComfyUI
@@ -1234,6 +1196,7 @@ paths:
description: Reboot initiated
'403':
description: Security policy violation
/v2/manager/version:
get:
summary: Get manager version
@@ -1245,6 +1208,7 @@ paths:
text/plain:
schema:
type: string
/v2/manager/is_legacy_manager_ui:
get:
summary: Check if legacy manager UI is enabled

View File

@@ -13,9 +13,9 @@ keywords = ["comfyui", "comfyui-manager"]
maintainers = [
{ name = "Dr.Lt.Data", email = "dr.lt.data@gmail.com" },
{ name = "Yoland Yan", email = "yoland@comfy.org" },
{ name = "Yoland Yan", email = "yoland@drip.art" },
{ name = "James Kwon", email = "hongilkwon316@gmail.com" },
{ name = "Robin Huang", email = "robin@comfy.org" },
{ name = "Robin Huang", email = "robin@drip.art" },
]
classifiers = [
@@ -25,16 +25,16 @@ classifiers = [
]
dependencies = [
"GitPython",
"PyGithub",
"matrix-client==0.4.0",
"transformers",
"huggingface-hub>0.20",
"typer",
"rich",
"typing-extensions",
"toml",
"uv",
"GitPython",
"PyGithub",
"matrix-client==0.4.0",
"transformers",
"huggingface-hub>0.20",
"typer",
"rich",
"typing-extensions",
"toml",
"uv",
"chardet"
]

View File

@@ -1,13 +0,0 @@
[tool:pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts =
-v
--tb=short
--strict-markers
--disable-warnings
markers =
slow: marks tests as slow (deselect with '-m "not slow"')
integration: marks tests as integration tests

View File

@@ -1,42 +0,0 @@
#!/usr/bin/env python3
"""
Simple test runner for ComfyUI-Manager tests.
Usage:
python run_tests.py # Run all tests
python run_tests.py -k test_task_queue # Run specific tests
python run_tests.py --cov # Run with coverage
"""
import sys
import subprocess
from pathlib import Path
def main():
"""Run pytest with appropriate arguments"""
# Ensure we're in the project directory
project_root = Path(__file__).parent
# Base pytest command
cmd = [sys.executable, "-m", "pytest"]
# Add any command line arguments passed to this script
cmd.extend(sys.argv[1:])
# Add default arguments if none provided
if len(sys.argv) == 1:
cmd.extend([
"tests/",
"-v",
"--tb=short"
])
print(f"Running: {' '.join(cmd)}")
print(f"Working directory: {project_root}")
# Run pytest
result = subprocess.run(cmd, cwd=project_root)
sys.exit(result.returncode)
if __name__ == "__main__":
main()

View File

@@ -1,89 +0,0 @@
# ComfyUI-Manager Tests
This directory contains unit tests for ComfyUI-Manager components.
## Running Tests
### Using the Virtual Environment
```bash
# From the project root
/path/to/comfyui/.venv/bin/python -m pytest tests/ -v
```
### Using the Test Runner
```bash
# Run all tests
python run_tests.py
# Run specific tests
python run_tests.py -k test_task_queue
# Run with coverage
python run_tests.py --cov
```
## Test Structure
### test_task_queue.py
Comprehensive tests for the TaskQueue functionality including:
- **Basic Operations**: Initialization, adding/removing tasks, state management
- **Batch Tracking**: Automatic batch creation, history saving, finalization
- **Thread Safety**: Concurrent access, worker lifecycle management
- **Integration Testing**: Full task processing workflow
- **Edge Cases**: Empty queues, invalid data, exception handling
**Key Features Tested:**
- ✅ Task queueing with Pydantic model validation
- ✅ Batch history tracking and persistence
- ✅ Thread-safe concurrent operations
- ✅ Worker thread lifecycle management
- ✅ WebSocket message tracking
- ✅ State snapshots and transitions
### MockTaskQueue
The tests use a `MockTaskQueue` class that:
- Isolates testing from global state and external dependencies
- Provides dependency injection for mocking external services
- Maintains the same API as the real TaskQueue
- Supports both synchronous and asynchronous testing patterns
## Test Categories
- **Unit Tests**: Individual method testing with mocked dependencies
- **Integration Tests**: Full workflow testing with real threading
- **Concurrency Tests**: Multi-threaded access verification
- **Edge Case Tests**: Error conditions and boundary cases
## Dependencies
Tests require:
- `pytest` - Test framework
- `pytest-asyncio` - Async test support
- `pydantic` - Data model validation
Install with: `pip install -e ".[dev]"`
## Design Notes
### Handling Singleton Pattern
The real TaskQueue uses a singleton pattern which makes testing challenging. The MockTaskQueue avoids this by:
- Not setting global instance variables
- Creating fresh instances per test
- Providing controlled dependency injection
### Thread Management
Tests handle threading complexities by:
- Using controlled mock workers for predictable behavior
- Providing synchronization primitives for timing-sensitive tests
- Testing both successful workflows and exception scenarios
### Heapq Compatibility
The original TaskQueue uses `heapq` with Pydantic models, which don't support comparison by default. Tests solve this by wrapping items in comparable tuples with priority values, maintaining FIFO order while enabling heap operations.

View File

@@ -1 +0,0 @@
"""Test suite for ComfyUI-Manager"""

View File

@@ -1,510 +0,0 @@
"""
Tests for TaskQueue functionality.
This module tests the core TaskQueue operations including:
- Task queueing and processing
- Batch tracking
- Thread lifecycle management
- State management
- WebSocket message delivery
"""
import asyncio
import json
import threading
import time
import uuid
from datetime import datetime
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, Mock, patch
from typing import Any, Dict, Optional
import pytest
from comfyui_manager.data_models import (
QueueTaskItem,
TaskExecutionStatus,
TaskStateMessage,
InstallPackParams,
ManagerDatabaseSource,
ManagerChannel,
)
class MockTaskQueue:
"""
A testable version of TaskQueue that allows for dependency injection
and isolated testing without global state.
"""
def __init__(self, history_dir: Optional[Path] = None):
# Don't set the global instance for testing
self.mutex = threading.RLock()
self.not_empty = threading.Condition(self.mutex)
self.current_index = 0
self.pending_tasks = []
self.running_tasks = {}
self.history_tasks = {}
self.task_counter = 0
self.batch_id = None
self.batch_start_time = None
self.batch_state_before = None
self._worker_task = None
self._history_dir = history_dir
# Mock external dependencies
self.mock_core = MagicMock()
self.mock_prompt_server = MagicMock()
def is_processing(self) -> bool:
"""Check if the queue is currently processing tasks"""
return (
self._worker_task is not None
and self._worker_task.is_alive()
)
def start_worker(self, mock_task_worker=None) -> bool:
"""Start the task worker. Can inject a mock worker for testing."""
if self._worker_task is not None and self._worker_task.is_alive():
return False # Already running
if mock_task_worker:
self._worker_task = threading.Thread(target=mock_task_worker)
else:
# Use a simple test worker that processes one task then stops
self._worker_task = threading.Thread(target=self._test_worker)
self._worker_task.start()
return True
def _test_worker(self):
"""Simple test worker that processes tasks without external dependencies"""
while True:
task = self.get(timeout=1.0) # Short timeout for tests
if task is None:
if self.total_count() == 0:
break
continue
item, task_index = task
# Simulate task processing
self.running_tasks[task_index] = item
# Simulate work
time.sleep(0.1)
# Mark as completed
status = TaskExecutionStatus(
status_str="success",
completed=True,
messages=["Test task completed"]
)
self.mark_done(task_index, item, status, "Test result")
# Clean up
if task_index in self.running_tasks:
del self.running_tasks[task_index]
def get_current_state(self) -> TaskStateMessage:
"""Get current queue state with mocked dependencies"""
return TaskStateMessage(
history=self.get_history(),
running_queue=self.get_current_queue()[0],
pending_queue=self.get_current_queue()[1],
installed_packs={} # Mocked empty
)
def send_queue_state_update(self, msg: str, update, client_id: Optional[str] = None):
"""Mock implementation that tracks calls instead of sending WebSocket messages"""
if not hasattr(self, '_sent_updates'):
self._sent_updates = []
self._sent_updates.append({
'msg': msg,
'update': update,
'client_id': client_id
})
# Copy the essential methods from the real TaskQueue
def put(self, item) -> None:
"""Add a task to the queue. Item can be a dict or QueueTaskItem model."""
with self.mutex:
# Start a new batch if this is the first task after queue was empty
if (
self.batch_id is None
and len(self.pending_tasks) == 0
and len(self.running_tasks) == 0
):
self._start_new_batch()
# Convert to Pydantic model if it's a dict
if isinstance(item, dict):
item = QueueTaskItem(**item)
import heapq
# Wrap in tuple with priority to make it comparable
# Use task_counter as priority to maintain FIFO order
priority_item = (self.task_counter, item)
heapq.heappush(self.pending_tasks, priority_item)
self.task_counter += 1
self.not_empty.notify()
def _start_new_batch(self) -> None:
"""Start a new batch session for tracking operations."""
self.batch_id = (
f"test_batch_{datetime.now().strftime('%Y%m%d_%H%M%S')}_{uuid.uuid4().hex[:8]}"
)
self.batch_start_time = datetime.now().isoformat()
self.batch_state_before = {"test": "state"} # Simplified for testing
def get(self, timeout: Optional[float] = None):
"""Get next task from queue"""
with self.not_empty:
while len(self.pending_tasks) == 0:
self.not_empty.wait(timeout=timeout)
if timeout is not None and len(self.pending_tasks) == 0:
return None
import heapq
priority_item = heapq.heappop(self.pending_tasks)
task_index, item = priority_item # Unwrap the tuple
return item, task_index
def total_count(self) -> int:
"""Get total number of tasks (pending + running)"""
return len(self.pending_tasks) + len(self.running_tasks)
def done_count(self) -> int:
"""Get number of completed tasks"""
return len(self.history_tasks)
def get_current_queue(self):
"""Get current running and pending queues"""
running = list(self.running_tasks.values())
# Extract items from the priority tuples
pending = [item for priority, item in self.pending_tasks]
return running, pending
def get_history(self):
"""Get task history"""
return self.history_tasks
def mark_done(self, task_index: int, item: QueueTaskItem, status: TaskExecutionStatus, result: str):
"""Mark a task as completed"""
from comfyui_manager.data_models import TaskHistoryItem
history_item = TaskHistoryItem(
ui_id=item.ui_id,
client_id=item.client_id,
kind=item.kind.value if hasattr(item.kind, 'value') else str(item.kind),
timestamp=datetime.now().isoformat(),
result=result,
status=status
)
self.history_tasks[item.ui_id] = history_item
def finalize(self):
"""Finalize batch (simplified for testing)"""
if self._history_dir and self.batch_id:
batch_file = self._history_dir / f"{self.batch_id}.json"
batch_record = {
"batch_id": self.batch_id,
"start_time": self.batch_start_time,
"state_before": self.batch_state_before,
"operations": [] # Simplified
}
with open(batch_file, 'w') as f:
json.dump(batch_record, f, indent=2)
class TestTaskQueue:
"""Test suite for TaskQueue functionality"""
@pytest.fixture
def task_queue(self, tmp_path):
"""Create a clean TaskQueue instance for each test"""
return MockTaskQueue(history_dir=tmp_path)
@pytest.fixture
def sample_task(self):
"""Create a sample task for testing"""
return QueueTaskItem(
ui_id=str(uuid.uuid4()),
client_id="test_client",
kind="install",
params=InstallPackParams(
id="test-node",
version="1.0.0",
selected_version="1.0.0",
mode=ManagerDatabaseSource.cache,
channel=ManagerChannel.dev
)
)
def test_task_queue_initialization(self, task_queue):
"""Test TaskQueue initializes with correct default state"""
assert task_queue.total_count() == 0
assert task_queue.done_count() == 0
assert not task_queue.is_processing()
assert task_queue.batch_id is None
assert len(task_queue.pending_tasks) == 0
assert len(task_queue.running_tasks) == 0
assert len(task_queue.history_tasks) == 0
def test_put_task_starts_batch(self, task_queue, sample_task):
"""Test that adding first task starts a new batch"""
assert task_queue.batch_id is None
task_queue.put(sample_task)
assert task_queue.batch_id is not None
assert task_queue.batch_id.startswith("test_batch_")
assert task_queue.batch_start_time is not None
assert task_queue.total_count() == 1
def test_put_multiple_tasks(self, task_queue, sample_task):
"""Test adding multiple tasks to queue"""
task_queue.put(sample_task)
# Create second task
task2 = QueueTaskItem(
ui_id=str(uuid.uuid4()),
client_id="test_client_2",
kind="install",
params=sample_task.params
)
task_queue.put(task2)
assert task_queue.total_count() == 2
assert len(task_queue.pending_tasks) == 2
def test_put_task_with_dict(self, task_queue):
"""Test adding task as dictionary gets converted to QueueTaskItem"""
task_dict = {
"ui_id": str(uuid.uuid4()),
"client_id": "test_client",
"kind": "install",
"params": {
"id": "test-node",
"version": "1.0.0",
"selected_version": "1.0.0",
"mode": "cache",
"channel": "dev"
}
}
task_queue.put(task_dict)
assert task_queue.total_count() == 1
# Verify it was converted to QueueTaskItem
item, _ = task_queue.get(timeout=0.1)
assert isinstance(item, QueueTaskItem)
assert item.ui_id == task_dict["ui_id"]
def test_get_task_from_queue(self, task_queue, sample_task):
"""Test retrieving task from queue"""
task_queue.put(sample_task)
item, task_index = task_queue.get(timeout=0.1)
assert item == sample_task
assert isinstance(task_index, int)
assert task_queue.total_count() == 0 # Should be removed from pending
def test_get_task_timeout(self, task_queue):
"""Test get with timeout on empty queue returns None"""
result = task_queue.get(timeout=0.1)
assert result is None
def test_start_stop_worker(self, task_queue):
"""Test worker thread lifecycle"""
assert not task_queue.is_processing()
# Mock worker that stops immediately
stop_event = threading.Event()
def mock_worker():
stop_event.wait(0.1) # Brief delay then stop
started = task_queue.start_worker(mock_worker)
assert started is True
assert task_queue.is_processing()
# Try to start again - should return False
started_again = task_queue.start_worker(mock_worker)
assert started_again is False
# Wait for worker to finish
stop_event.set()
task_queue._worker_task.join(timeout=1.0)
assert not task_queue.is_processing()
def test_task_processing_integration(self, task_queue, sample_task):
"""Test full task processing workflow"""
# Add task to queue
task_queue.put(sample_task)
assert task_queue.total_count() == 1
# Start worker
started = task_queue.start_worker()
assert started is True
# Wait for processing to complete
for _ in range(50): # Max 5 seconds
if task_queue.done_count() > 0:
break
time.sleep(0.1)
# Verify task was processed
assert task_queue.done_count() == 1
assert task_queue.total_count() == 0
assert sample_task.ui_id in task_queue.history_tasks
# Stop worker
task_queue._worker_task.join(timeout=1.0)
def test_get_current_state(self, task_queue, sample_task):
"""Test getting current queue state"""
task_queue.put(sample_task)
state = task_queue.get_current_state()
assert isinstance(state, TaskStateMessage)
assert len(state.pending_queue) == 1
assert len(state.running_queue) == 0
assert state.pending_queue[0] == sample_task
def test_batch_finalization(self, task_queue, tmp_path):
"""Test batch history is saved correctly"""
task_queue.put(QueueTaskItem(
ui_id=str(uuid.uuid4()),
client_id="test_client",
kind="install",
params=InstallPackParams(
id="test-node",
version="1.0.0",
selected_version="1.0.0",
mode=ManagerDatabaseSource.cache,
channel=ManagerChannel.dev
)
))
batch_id = task_queue.batch_id
task_queue.finalize()
# Check batch file was created
batch_file = tmp_path / f"{batch_id}.json"
assert batch_file.exists()
# Verify content
with open(batch_file) as f:
batch_data = json.load(f)
assert batch_data["batch_id"] == batch_id
assert "start_time" in batch_data
assert "state_before" in batch_data
def test_concurrent_access(self, task_queue):
"""Test thread-safe concurrent access to queue"""
num_tasks = 10
added_tasks = []
def add_tasks():
for i in range(num_tasks):
task = QueueTaskItem(
ui_id=f"task_{i}",
client_id=f"client_{i}",
kind="install",
params=InstallPackParams(
id=f"node_{i}",
version="1.0.0",
selected_version="1.0.0",
mode=ManagerDatabaseSource.cache,
channel=ManagerChannel.dev
)
)
task_queue.put(task)
added_tasks.append(task)
# Start multiple threads adding tasks
threads = []
for _ in range(3):
thread = threading.Thread(target=add_tasks)
threads.append(thread)
thread.start()
# Wait for all threads to complete
for thread in threads:
thread.join()
# Verify all tasks were added
assert task_queue.total_count() == num_tasks * 3
assert len(added_tasks) == num_tasks * 3
@pytest.mark.asyncio
async def test_queue_state_updates_tracking(self, task_queue, sample_task):
"""Test that queue state updates are tracked properly"""
# Mock the update tracking
task_queue.send_queue_state_update("test-message", {"test": "data"}, "client1")
# Verify update was tracked
assert hasattr(task_queue, '_sent_updates')
assert len(task_queue._sent_updates) == 1
update = task_queue._sent_updates[0]
assert update['msg'] == "test-message"
assert update['update'] == {"test": "data"}
assert update['client_id'] == "client1"
class TestTaskQueueEdgeCases:
"""Test edge cases and error conditions"""
@pytest.fixture
def task_queue(self):
return MockTaskQueue()
def test_empty_queue_operations(self, task_queue):
"""Test operations on empty queue"""
assert task_queue.total_count() == 0
assert task_queue.done_count() == 0
# Getting from empty queue should timeout
result = task_queue.get(timeout=0.1)
assert result is None
# State should be empty
state = task_queue.get_current_state()
assert len(state.pending_queue) == 0
assert len(state.running_queue) == 0
def test_invalid_task_data(self, task_queue):
"""Test handling of invalid task data"""
# This should raise ValidationError due to missing required fields
with pytest.raises(Exception): # ValidationError from Pydantic
task_queue.put({
"ui_id": "test",
# Missing required fields
})
def test_worker_cleanup_on_exception(self, task_queue):
"""Test worker cleanup when worker function raises exception"""
exception_raised = threading.Event()
def failing_worker():
exception_raised.set()
raise RuntimeError("Test exception")
started = task_queue.start_worker(failing_worker)
assert started is True
# Wait for exception to be raised
exception_raised.wait(timeout=1.0)
# Worker should eventually stop
task_queue._worker_task.join(timeout=1.0)
assert not task_queue.is_processing()
if __name__ == "__main__":
# Allow running tests directly
pytest.main([__file__])