Compare commits
2 Commits
draft-v4
...
draft-v4-s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24ca0ab538 | ||
|
|
62da330182 |
32
.github/workflows/publish-to-pypi.yml
vendored
32
.github/workflows/publish-to-pypi.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- draft-v4
|
||||
- main
|
||||
paths:
|
||||
- "pyproject.toml"
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.x'
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
@@ -31,28 +31,28 @@ jobs:
|
||||
- name: Get current version
|
||||
id: current_version
|
||||
run: |
|
||||
CURRENT_VERSION=$(grep -oP '^version = "\K[^"]+' pyproject.toml)
|
||||
CURRENT_VERSION=$(grep -oP 'version = "\K[^"]+' pyproject.toml)
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Current version: $CURRENT_VERSION"
|
||||
|
||||
- name: Build package
|
||||
run: python -m build
|
||||
|
||||
# - name: Create GitHub Release
|
||||
# id: create_release
|
||||
# uses: softprops/action-gh-release@v2
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ github.token }}
|
||||
# with:
|
||||
# files: dist/*
|
||||
# tag_name: v${{ steps.current_version.outputs.version }}
|
||||
# draft: false
|
||||
# prerelease: false
|
||||
# generate_release_notes: true
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: dist/*
|
||||
tag_name: v${{ steps.current_version.outputs.version }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
|
||||
- name: Publish to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_TOKEN }}
|
||||
skip-existing: true
|
||||
verbose: true
|
||||
verbose: true
|
||||
25
.github/workflows/publish.yml
vendored
Normal file
25
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Publish to Comfy registry
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main-blocked
|
||||
paths:
|
||||
- "pyproject.toml"
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
publish-node:
|
||||
name: Publish Custom Node to registry
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'ltdrdata' || github.repository_owner == 'Comfy-Org' }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Publish Custom Node
|
||||
uses: Comfy-Org/publish-node-action@v1
|
||||
with:
|
||||
## Add your own personal access token to your Github Repository secrets and reference it here.
|
||||
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
||||
@@ -211,7 +211,6 @@ def read_cnr_info(fullpath):
|
||||
|
||||
project = data.get('project', {})
|
||||
name = project.get('name').strip().lower()
|
||||
original_name = project.get('name')
|
||||
|
||||
# normalize version
|
||||
# for example: 2.5 -> 2.5.0
|
||||
@@ -223,7 +222,6 @@ def read_cnr_info(fullpath):
|
||||
if name and version: # repository is optional
|
||||
return {
|
||||
"id": name,
|
||||
"original_name": original_name,
|
||||
"version": version,
|
||||
"url": repository
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import re
|
||||
import logging
|
||||
import platform
|
||||
import shlex
|
||||
|
||||
from packaging import version
|
||||
|
||||
cache_lock = threading.Lock()
|
||||
session_lock = threading.Lock()
|
||||
@@ -58,62 +58,32 @@ def make_pip_cmd(cmd):
|
||||
# print(f"[ComfyUI-Manager] 'distutils' package not found. Activating fallback mode for compatibility.")
|
||||
class StrictVersion:
|
||||
def __init__(self, version_string):
|
||||
self.obj = version.parse(version_string)
|
||||
self.version_string = version_string
|
||||
self.major = 0
|
||||
self.minor = 0
|
||||
self.patch = 0
|
||||
self.pre_release = None
|
||||
self.parse_version_string()
|
||||
|
||||
def parse_version_string(self):
|
||||
parts = self.version_string.split('.')
|
||||
if not parts:
|
||||
raise ValueError("Version string must not be empty")
|
||||
|
||||
self.major = int(parts[0])
|
||||
self.minor = int(parts[1]) if len(parts) > 1 else 0
|
||||
self.patch = int(parts[2]) if len(parts) > 2 else 0
|
||||
|
||||
# Handling pre-release versions if present
|
||||
if len(parts) > 3:
|
||||
self.pre_release = parts[3]
|
||||
self.major = self.obj.major
|
||||
self.minor = self.obj.minor
|
||||
self.patch = self.obj.micro
|
||||
|
||||
def __str__(self):
|
||||
version = f"{self.major}.{self.minor}.{self.patch}"
|
||||
if self.pre_release:
|
||||
version += f"-{self.pre_release}"
|
||||
return version
|
||||
return self.version_string
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.major, self.minor, self.patch, self.pre_release) == \
|
||||
(other.major, other.minor, other.patch, other.pre_release)
|
||||
return self.obj == other.obj
|
||||
|
||||
def __lt__(self, other):
|
||||
if (self.major, self.minor, self.patch) == (other.major, other.minor, other.patch):
|
||||
return self.pre_release_compare(self.pre_release, other.pre_release) < 0
|
||||
return (self.major, self.minor, self.patch) < (other.major, other.minor, other.patch)
|
||||
|
||||
@staticmethod
|
||||
def pre_release_compare(pre1, pre2):
|
||||
if pre1 == pre2:
|
||||
return 0
|
||||
if pre1 is None:
|
||||
return 1
|
||||
if pre2 is None:
|
||||
return -1
|
||||
return -1 if pre1 < pre2 else 1
|
||||
return self.obj < other.obj
|
||||
|
||||
def __le__(self, other):
|
||||
return self == other or self < other
|
||||
return self.obj == other.obj or self.obj < other.obj
|
||||
|
||||
def __gt__(self, other):
|
||||
return not self <= other
|
||||
return not self.obj <= other.obj
|
||||
|
||||
def __ge__(self, other):
|
||||
return not self < other
|
||||
return not self.obj < other.obj
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
return not self.obj == other.obj
|
||||
|
||||
|
||||
def simple_hash(input_string):
|
||||
|
||||
136
comfyui_manager/common/snapshot_util.py
Normal file
136
comfyui_manager/common/snapshot_util.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from . import manager_util
|
||||
from . import git_utils
|
||||
import json
|
||||
import yaml
|
||||
import logging
|
||||
|
||||
def read_snapshot(snapshot_path):
|
||||
try:
|
||||
|
||||
with open(snapshot_path, 'r', encoding="UTF-8") as snapshot_file:
|
||||
if snapshot_path.endswith('.json'):
|
||||
info = json.load(snapshot_file)
|
||||
elif snapshot_path.endswith('.yaml'):
|
||||
info = yaml.load(snapshot_file, Loader=yaml.SafeLoader)
|
||||
info = info['custom_nodes']
|
||||
|
||||
return info
|
||||
except Exception as e:
|
||||
logging.warning(f"Failed to read snapshot file: {snapshot_path}\nError: {e}")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def diff_snapshot(a, b):
|
||||
if not a or not b:
|
||||
return None
|
||||
|
||||
nodepack_diff = {
|
||||
'added': {},
|
||||
'removed': [],
|
||||
'upgraded': {},
|
||||
'downgraded': {},
|
||||
'changed': []
|
||||
}
|
||||
|
||||
pip_diff = {
|
||||
'added': {},
|
||||
'upgraded': {},
|
||||
'downgraded': {}
|
||||
}
|
||||
|
||||
# check: comfyui
|
||||
if a.get('comfyui') != b.get('comfyui'):
|
||||
nodepack_diff['changed'].append('comfyui')
|
||||
|
||||
# check: cnr nodes
|
||||
a_cnrs = a.get('cnr_custom_nodes', {})
|
||||
b_cnrs = b.get('cnr_custom_nodes', {})
|
||||
|
||||
if 'comfyui-manager' in a_cnrs:
|
||||
del a_cnrs['comfyui-manager']
|
||||
if 'comfyui-manager' in b_cnrs:
|
||||
del b_cnrs['comfyui-manager']
|
||||
|
||||
for k, v in a_cnrs.items():
|
||||
if k not in b_cnrs.keys():
|
||||
nodepack_diff['removed'].append(k)
|
||||
elif a_cnrs[k] != b_cnrs[k]:
|
||||
a_ver = manager_util.StrictVersion(a_cnrs[k])
|
||||
b_ver = manager_util.StrictVersion(b_cnrs[k])
|
||||
if a_ver < b_ver:
|
||||
nodepack_diff['upgraded'][k] = {'from': a_cnrs[k], 'to': b_cnrs[k]}
|
||||
elif a_ver > b_ver:
|
||||
nodepack_diff['downgraded'][k] = {'from': a_cnrs[k], 'to': b_cnrs[k]}
|
||||
|
||||
added_cnrs = set(b_cnrs.keys()) - set(a_cnrs.keys())
|
||||
for k in added_cnrs:
|
||||
nodepack_diff['added'][k] = b_cnrs[k]
|
||||
|
||||
# check: git custom nodes
|
||||
a_gits = a.get('git_custom_nodes', {})
|
||||
b_gits = b.get('git_custom_nodes', {})
|
||||
|
||||
a_gits = {git_utils.normalize_url(k): v for k, v in a_gits.items() if k.lower() != 'comfyui-manager'}
|
||||
b_gits = {git_utils.normalize_url(k): v for k, v in b_gits.items() if k.lower() != 'comfyui-manager'}
|
||||
|
||||
for k, v in a_gits.items():
|
||||
if k not in b_gits.keys():
|
||||
nodepack_diff['removed'].append(k)
|
||||
elif not v['disabled'] and b_gits[k]['disabled']:
|
||||
nodepack_diff['removed'].append(k)
|
||||
elif v['disabled'] and not b_gits[k]['disabled']:
|
||||
nodepack_diff['added'].append(k)
|
||||
elif v['hash'] != b_gits[k]['hash']:
|
||||
a_date = v.get('commit_timestamp')
|
||||
b_date = b_gits[k].get('commit_timestamp')
|
||||
if a_date is not None and b_date is not None:
|
||||
if a_date < b_date:
|
||||
nodepack_diff['upgraded'].append(k)
|
||||
elif a_date > b_date:
|
||||
nodepack_diff['downgraded'].append(k)
|
||||
else:
|
||||
nodepack_diff['changed'].append(k)
|
||||
|
||||
# check: pip packages
|
||||
a_pip = a.get('pips', {})
|
||||
b_pip = b.get('pips', {})
|
||||
for k, v in a_pip.items():
|
||||
if '==' in k:
|
||||
package_name, version = k.split('==', 1)
|
||||
else:
|
||||
package_name, version = k, None
|
||||
|
||||
for k2, v2 in b_pip.items():
|
||||
if '==' in k2:
|
||||
package_name2, version2 = k2.split('==', 1)
|
||||
else:
|
||||
package_name2, version2 = k2, None
|
||||
|
||||
if package_name.lower() == package_name2.lower():
|
||||
if version != version2:
|
||||
a_ver = manager_util.StrictVersion(version) if version else None
|
||||
b_ver = manager_util.StrictVersion(version2) if version2 else None
|
||||
if a_ver and b_ver:
|
||||
if a_ver < b_ver:
|
||||
pip_diff['upgraded'][package_name] = {'from': version, 'to': version2}
|
||||
elif a_ver > b_ver:
|
||||
pip_diff['downgraded'][package_name] = {'from': version, 'to': version2}
|
||||
elif not a_ver and b_ver:
|
||||
pip_diff['added'][package_name] = version2
|
||||
|
||||
a_pip_names = {k.split('==', 1)[0].lower() for k in a_pip.keys()}
|
||||
|
||||
for k in b_pip.keys():
|
||||
if '==' in k:
|
||||
package_name = k.split('==', 1)[0]
|
||||
package_version = k.split('==', 1)[1]
|
||||
else:
|
||||
package_name = k
|
||||
package_version = None
|
||||
|
||||
if package_name.lower() not in a_pip_names:
|
||||
if package_version:
|
||||
pip_diff['added'][package_name] = package_version
|
||||
|
||||
return {'nodepack_diff': nodepack_diff, 'pip_diff': pip_diff}
|
||||
@@ -30,12 +30,6 @@ from .generated_models import (
|
||||
InstalledModelInfo,
|
||||
ComfyUIVersionInfo,
|
||||
|
||||
# Import Fail Info Models
|
||||
ImportFailInfoBulkRequest,
|
||||
ImportFailInfoBulkResponse,
|
||||
ImportFailInfoItem,
|
||||
ImportFailInfoItem1,
|
||||
|
||||
# Other models
|
||||
OperationType,
|
||||
OperationResult,
|
||||
@@ -94,12 +88,6 @@ __all__ = [
|
||||
"InstalledModelInfo",
|
||||
"ComfyUIVersionInfo",
|
||||
|
||||
# Import Fail Info Models
|
||||
"ImportFailInfoBulkRequest",
|
||||
"ImportFailInfoBulkResponse",
|
||||
"ImportFailInfoItem",
|
||||
"ImportFailInfoItem1",
|
||||
|
||||
# Other models
|
||||
"OperationType",
|
||||
"OperationResult",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# generated by datamodel-codegen:
|
||||
# filename: openapi.yaml
|
||||
# timestamp: 2025-07-31T04:52:26+00:00
|
||||
# timestamp: 2025-06-27T04:01:45+00:00
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -454,24 +454,6 @@ class BatchExecutionRecord(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class ImportFailInfoBulkRequest(BaseModel):
|
||||
cnr_ids: Optional[List[str]] = Field(
|
||||
None, description="A list of CNR IDs to check."
|
||||
)
|
||||
urls: Optional[List[str]] = Field(
|
||||
None, description="A list of repository URLs to check."
|
||||
)
|
||||
|
||||
|
||||
class ImportFailInfoItem1(BaseModel):
|
||||
error: Optional[str] = None
|
||||
traceback: Optional[str] = None
|
||||
|
||||
|
||||
class ImportFailInfoItem(RootModel[Optional[ImportFailInfoItem1]]):
|
||||
root: Optional[ImportFailInfoItem1]
|
||||
|
||||
|
||||
class QueueTaskItem(BaseModel):
|
||||
ui_id: str = Field(..., description="Unique identifier for the task")
|
||||
client_id: str = Field(..., description="Client identifier that initiated the task")
|
||||
@@ -555,7 +537,3 @@ class HistoryResponse(BaseModel):
|
||||
history: Optional[Dict[str, TaskHistoryItem]] = Field(
|
||||
None, description="Map of task IDs to their history items"
|
||||
)
|
||||
|
||||
|
||||
class ImportFailInfoBulkResponse(RootModel[Optional[Dict[str, ImportFailInfoItem]]]):
|
||||
root: Optional[Dict[str, ImportFailInfoItem]] = None
|
||||
|
||||
@@ -41,12 +41,11 @@ from ..common.enums import NetworkMode, SecurityLevel, DBMode
|
||||
from ..common import context
|
||||
|
||||
|
||||
version_code = [4, 0, 1]
|
||||
version_code = [4, 0]
|
||||
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||
|
||||
|
||||
DEFAULT_CHANNEL = "https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main"
|
||||
DEFAULT_CHANNEL_LEGACY = "https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main"
|
||||
|
||||
|
||||
default_custom_nodes_path = None
|
||||
@@ -154,8 +153,14 @@ def check_invalid_nodes():
|
||||
cached_config = None
|
||||
js_path = None
|
||||
|
||||
comfy_ui_required_revision = 1930
|
||||
comfy_ui_required_commit_datetime = datetime(2024, 1, 24, 0, 0, 0)
|
||||
|
||||
comfy_ui_revision = "Unknown"
|
||||
comfy_ui_commit_datetime = datetime(1900, 1, 1, 0, 0, 0)
|
||||
|
||||
channel_dict = None
|
||||
valid_channels = {'default', 'local', DEFAULT_CHANNEL, DEFAULT_CHANNEL_LEGACY}
|
||||
valid_channels = {'default', 'local'}
|
||||
channel_list = None
|
||||
|
||||
|
||||
@@ -1474,7 +1479,7 @@ def identify_node_pack_from_path(fullpath):
|
||||
# cnr
|
||||
cnr = cnr_utils.read_cnr_info(fullpath)
|
||||
if cnr is not None:
|
||||
return module_name, cnr['version'], cnr['original_name'], None
|
||||
return module_name, cnr['version'], cnr['id'], None
|
||||
|
||||
return None
|
||||
else:
|
||||
@@ -1524,10 +1529,7 @@ def get_installed_node_packs():
|
||||
if info is None:
|
||||
continue
|
||||
|
||||
# NOTE: don't add disabled nodepack if there is enabled nodepack
|
||||
original_name = info[0].split('@')[0]
|
||||
if original_name not in res:
|
||||
res[info[0]] = { 'ver': info[1], 'cnr_id': info[2], 'aux_id': info[3], 'enabled': False }
|
||||
res[info[0]] = { 'ver': info[1], 'cnr_id': info[2], 'aux_id': info[3], 'enabled': False }
|
||||
|
||||
return res
|
||||
|
||||
@@ -1784,6 +1786,16 @@ def try_install_script(url, repo_path, install_cmd, instant_execution=False):
|
||||
print(f"\n## ComfyUI-Manager: EXECUTE => {install_cmd}")
|
||||
code = manager_funcs.run_script(install_cmd, cwd=repo_path)
|
||||
|
||||
if platform.system() != "Windows":
|
||||
try:
|
||||
if not os.environ.get('__COMFYUI_DESKTOP_VERSION__') and comfy_ui_commit_datetime.date() < comfy_ui_required_commit_datetime.date():
|
||||
print("\n\n###################################################################")
|
||||
print(f"[WARN] ComfyUI-Manager: Your ComfyUI version ({comfy_ui_revision})[{comfy_ui_commit_datetime.date()}] is too old. Please update to the latest version.")
|
||||
print("[WARN] The extension installation feature may not work properly in the current installed ComfyUI version on Windows environment.")
|
||||
print("###################################################################\n\n")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if code != 0:
|
||||
if url is None:
|
||||
url = os.path.dirname(repo_path)
|
||||
@@ -2634,8 +2646,8 @@ async def get_current_snapshot(custom_nodes_only = False):
|
||||
commit_hash = git_utils.get_commit_hash(fullpath)
|
||||
url = git_utils.git_url(fullpath)
|
||||
git_custom_nodes[url] = dict(hash=commit_hash, disabled=is_disabled)
|
||||
except Exception:
|
||||
print(f"Failed to extract snapshots for the custom node '{path}'.")
|
||||
except Exception as e:
|
||||
print(f"Failed to extract snapshots for the custom node '{path}'. / {e}")
|
||||
|
||||
elif path.endswith('.py'):
|
||||
is_disabled = path.endswith(".py.disabled")
|
||||
|
||||
@@ -47,7 +47,7 @@ from ..common import manager_util
|
||||
from ..common import cm_global
|
||||
from ..common import manager_downloader
|
||||
from ..common import context
|
||||
|
||||
from ..common import snapshot_util
|
||||
|
||||
|
||||
from ..data_models import (
|
||||
@@ -61,7 +61,6 @@ from ..data_models import (
|
||||
ManagerMessageName,
|
||||
BatchExecutionRecord,
|
||||
ComfyUISystemState,
|
||||
ImportFailInfoBulkRequest,
|
||||
BatchOperation,
|
||||
InstalledNodeInfo,
|
||||
ComfyUIVersionInfo,
|
||||
@@ -1594,6 +1593,46 @@ async def save_snapshot(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/diff")
|
||||
async def get_snapshot_diff(request):
|
||||
try:
|
||||
from_id = request.rel_url.query.get("from")
|
||||
to_id = request.rel_url.query.get("to")
|
||||
|
||||
if (from_id is not None and '..' in from_id) or (to_id is not None and '..' in to_id):
|
||||
logging.error("/v2/snapshot/diff: invalid 'from' or 'to' parameter.")
|
||||
return web.Response(status=400)
|
||||
|
||||
if from_id is None:
|
||||
from_json = await core.get_current_snapshot()
|
||||
else:
|
||||
from_path = os.path.join(context.manager_snapshot_path, f"{from_id}.json")
|
||||
if not os.path.exists(from_path):
|
||||
logging.error(f"/v2/snapshot/diff: 'from' parameter file not found: {from_path}")
|
||||
return web.Response(status=400)
|
||||
|
||||
from_json = snapshot_util.read_snapshot(from_path)
|
||||
|
||||
if to_id is None:
|
||||
logging.error("/v2/snapshot/diff: 'to' parameter is required.")
|
||||
return web.Response(status=401)
|
||||
else:
|
||||
to_path = os.path.join(context.manager_snapshot_path, f"{to_id}.json")
|
||||
if not os.path.exists(to_path):
|
||||
logging.error(f"/v2/snapshot/diff: 'to' parameter file not found: {to_path}")
|
||||
return web.Response(status=400)
|
||||
|
||||
to_json = snapshot_util.read_snapshot(to_path)
|
||||
|
||||
return web.json_response(snapshot_util.diff_snapshot(from_json, to_json), content_type='application/json')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] Error in /v2/snapshot/diff: {e}")
|
||||
traceback.print_exc()
|
||||
# Return a generic error response
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
def unzip_install(files):
|
||||
temp_filename = "manager-temp.zip"
|
||||
for url in files:
|
||||
@@ -1657,67 +1696,6 @@ async def import_fail_info(request):
|
||||
return web.Response(status=500, text="Internal server error")
|
||||
|
||||
|
||||
@routes.post("/v2/customnode/import_fail_info_bulk")
|
||||
async def import_fail_info_bulk(request):
|
||||
try:
|
||||
json_data = await request.json()
|
||||
|
||||
# Validate input using Pydantic model
|
||||
request_data = ImportFailInfoBulkRequest.model_validate(json_data)
|
||||
|
||||
# Ensure we have either cnr_ids or urls
|
||||
if not request_data.cnr_ids and not request_data.urls:
|
||||
return web.Response(
|
||||
status=400, text="Either 'cnr_ids' or 'urls' field is required"
|
||||
)
|
||||
|
||||
await core.unified_manager.reload('cache')
|
||||
await core.unified_manager.get_custom_nodes('default', 'cache')
|
||||
|
||||
results = {}
|
||||
|
||||
if request_data.cnr_ids:
|
||||
for cnr_id in request_data.cnr_ids:
|
||||
module_name = core.unified_manager.get_module_name(cnr_id)
|
||||
if module_name is not None:
|
||||
info = cm_global.error_dict.get(module_name)
|
||||
if info is not None:
|
||||
# Convert error_dict format to API spec format
|
||||
results[cnr_id] = {
|
||||
'error': info.get('msg', ''),
|
||||
'traceback': info.get('traceback', '')
|
||||
}
|
||||
else:
|
||||
results[cnr_id] = None
|
||||
else:
|
||||
results[cnr_id] = None
|
||||
|
||||
if request_data.urls:
|
||||
for url in request_data.urls:
|
||||
module_name = core.unified_manager.get_module_name(url)
|
||||
if module_name is not None:
|
||||
info = cm_global.error_dict.get(module_name)
|
||||
if info is not None:
|
||||
# Convert error_dict format to API spec format
|
||||
results[url] = {
|
||||
'error': info.get('msg', ''),
|
||||
'traceback': info.get('traceback', '')
|
||||
}
|
||||
else:
|
||||
results[url] = None
|
||||
else:
|
||||
results[url] = None
|
||||
|
||||
# Return results directly as JSON
|
||||
return web.json_response(results, content_type="application/json")
|
||||
except ValidationError as e:
|
||||
logging.error(f"[ComfyUI-Manager] Invalid request data: {e}")
|
||||
return web.Response(status=400, text=f"Invalid request data: {e}")
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] Error processing bulk import fail info: {e}")
|
||||
return web.Response(status=500, text="Internal server error")
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/reset")
|
||||
async def reset_queue(request):
|
||||
logging.debug("[ComfyUI-Manager] Queue reset requested")
|
||||
|
||||
@@ -11,15 +11,6 @@ import hashlib
|
||||
import folder_paths
|
||||
from server import PromptServer
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
try:
|
||||
from nio import AsyncClient, LoginResponse, UploadResponse
|
||||
matrix_nio_is_available = True
|
||||
except Exception:
|
||||
logging.warning(f"[ComfyUI-Manager] The matrix sharing feature has been disabled because the `matrix-nio` dependency is not installed.\n\tTo use this feature, please run the following command:\n\t{sys.executable} -m pip install matrix-nio\n")
|
||||
matrix_nio_is_available = False
|
||||
|
||||
|
||||
def extract_model_file_names(json_data):
|
||||
@@ -202,14 +193,6 @@ async def get_esheep_workflow_and_images(request):
|
||||
return web.Response(status=200, text=json.dumps(data))
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_matrix_dep_status")
|
||||
async def get_matrix_dep_status(request):
|
||||
if matrix_nio_is_available:
|
||||
return web.Response(status=200, text='available')
|
||||
else:
|
||||
return web.Response(status=200, text='unavailable')
|
||||
|
||||
|
||||
def set_matrix_auth(json_data):
|
||||
homeserver = json_data['homeserver']
|
||||
username = json_data['username']
|
||||
@@ -349,12 +332,15 @@ async def share_art(request):
|
||||
workflowId = upload_workflow_json["workflowId"]
|
||||
|
||||
# check if the user has provided Matrix credentials
|
||||
if matrix_nio_is_available and "matrix" in share_destinations:
|
||||
if "matrix" in share_destinations:
|
||||
comfyui_share_room_id = '!LGYSoacpJPhIfBqVfb:matrix.org'
|
||||
filename = os.path.basename(asset_filepath)
|
||||
content_type = assetFileType
|
||||
|
||||
try:
|
||||
from matrix_client.api import MatrixHttpApi
|
||||
from matrix_client.client import MatrixClient
|
||||
|
||||
homeserver = 'matrix.org'
|
||||
if matrix_auth:
|
||||
homeserver = matrix_auth.get('homeserver', 'matrix.org')
|
||||
@@ -362,35 +348,20 @@ async def share_art(request):
|
||||
if not homeserver.startswith("https://"):
|
||||
homeserver = "https://" + homeserver
|
||||
|
||||
client = AsyncClient(homeserver, matrix_auth['username'])
|
||||
|
||||
# Login
|
||||
login_resp = await client.login(matrix_auth['password'])
|
||||
if not isinstance(login_resp, LoginResponse) or not login_resp.access_token:
|
||||
await client.close()
|
||||
client = MatrixClient(homeserver)
|
||||
try:
|
||||
token = client.login(username=matrix_auth['username'], password=matrix_auth['password'])
|
||||
if not token:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
except Exception:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
|
||||
# Upload asset
|
||||
matrix = MatrixHttpApi(homeserver, token=token)
|
||||
with open(asset_filepath, 'rb') as f:
|
||||
upload_resp, _maybe_keys = await client.upload(f, content_type=content_type, filename=filename)
|
||||
asset_data = f.seek(0) or f.read() # get size for info below
|
||||
if not isinstance(upload_resp, UploadResponse) or not upload_resp.content_uri:
|
||||
await client.close()
|
||||
return web.json_response({"error": "Failed to upload asset to Matrix."}, content_type='application/json', status=500)
|
||||
mxc_url = upload_resp.content_uri
|
||||
mxc_url = matrix.media_upload(f.read(), content_type, filename=filename)['content_uri']
|
||||
|
||||
# Upload workflow JSON
|
||||
import io
|
||||
workflow_json_bytes = json.dumps(prompt['workflow']).encode('utf-8')
|
||||
workflow_io = io.BytesIO(workflow_json_bytes)
|
||||
upload_workflow_resp, _maybe_keys = await client.upload(workflow_io, content_type='application/json', filename='workflow.json')
|
||||
workflow_io.seek(0)
|
||||
if not isinstance(upload_workflow_resp, UploadResponse) or not upload_workflow_resp.content_uri:
|
||||
await client.close()
|
||||
return web.json_response({"error": "Failed to upload workflow to Matrix."}, content_type='application/json', status=500)
|
||||
workflow_json_mxc_url = upload_workflow_resp.content_uri
|
||||
workflow_json_mxc_url = matrix.media_upload(prompt['workflow'], 'application/json', filename='workflow.json')['content_uri']
|
||||
|
||||
# Send text message
|
||||
text_content = ""
|
||||
if title:
|
||||
text_content += f"{title}\n"
|
||||
@@ -398,47 +369,11 @@ async def share_art(request):
|
||||
text_content += f"{description}\n"
|
||||
if credits:
|
||||
text_content += f"\ncredits: {credits}\n"
|
||||
await client.room_send(
|
||||
room_id=comfyui_share_room_id,
|
||||
message_type="m.room.message",
|
||||
content={"msgtype": "m.text", "body": text_content}
|
||||
)
|
||||
|
||||
# Send image
|
||||
await client.room_send(
|
||||
room_id=comfyui_share_room_id,
|
||||
message_type="m.room.message",
|
||||
content={
|
||||
"msgtype": "m.image",
|
||||
"body": filename,
|
||||
"url": mxc_url,
|
||||
"info": {
|
||||
"mimetype": content_type,
|
||||
"size": len(asset_data)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
# Send workflow JSON file
|
||||
await client.room_send(
|
||||
room_id=comfyui_share_room_id,
|
||||
message_type="m.room.message",
|
||||
content={
|
||||
"msgtype": "m.file",
|
||||
"body": "workflow.json",
|
||||
"url": workflow_json_mxc_url,
|
||||
"info": {
|
||||
"mimetype": "application/json",
|
||||
"size": len(workflow_json_bytes)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
await client.close()
|
||||
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
matrix.send_message(comfyui_share_room_id, text_content)
|
||||
matrix.send_content(comfyui_share_room_id, mxc_url, filename, 'm.image')
|
||||
matrix.send_content(comfyui_share_room_id, workflow_json_mxc_url, 'workflow.json', 'm.file')
|
||||
except Exception:
|
||||
logging.exception("An error occurred")
|
||||
return web.json_response({"error": "An error occurred when sharing your art to Matrix."}, content_type='application/json', status=500)
|
||||
|
||||
return web.json_response({
|
||||
|
||||
@@ -1514,6 +1514,8 @@ app.registerExtension({
|
||||
tooltip: "Share"
|
||||
}).element
|
||||
);
|
||||
|
||||
app.menu?.settingsGroup.element.before(cmGroup.element);
|
||||
}
|
||||
catch(exception) {
|
||||
console.log('ComfyUI is outdated. New style menu based features are disabled.');
|
||||
|
||||
@@ -552,20 +552,6 @@ export class ShareDialog extends ComfyDialog {
|
||||
this.matrix_destination_checkbox.style.color = "var(--fg-color)";
|
||||
this.matrix_destination_checkbox.checked = this.share_option === 'matrix'; //true;
|
||||
|
||||
try {
|
||||
api.fetchApi(`/v2/manager/get_matrix_dep_status`)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
if(data == 'unavailable') {
|
||||
matrix_destination_checkbox_text.style.textDecoration = "line-through";
|
||||
this.matrix_destination_checkbox.disabled = true;
|
||||
this.matrix_destination_checkbox.title = "It has been disabled because the 'matrix-nio' dependency is not installed. Please install this dependency to use the matrix sharing feature.";
|
||||
matrix_destination_checkbox_text.title = "It has been disabled because the 'matrix-nio' dependency is not installed. Please install this dependency to use the matrix sharing feature.";
|
||||
}
|
||||
})
|
||||
.catch(error => {});
|
||||
} catch (error) {}
|
||||
|
||||
this.comfyworkflows_destination_checkbox = $el("input", { type: 'checkbox', id: "comfyworkflows_destination" }, [])
|
||||
const comfyworkflows_destination_checkbox_text = $el("label", {}, [" ComfyWorkflows.com"])
|
||||
this.comfyworkflows_destination_checkbox.style.color = "var(--fg-color)";
|
||||
|
||||
@@ -201,15 +201,13 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
});
|
||||
this.LockInput = $el("input", {
|
||||
type: "text",
|
||||
placeholder: "0",
|
||||
placeholder: "",
|
||||
style: {
|
||||
width: "100px",
|
||||
padding: "7px",
|
||||
paddingLeft: "30px",
|
||||
borderRadius: "4px",
|
||||
border: "1px solid #ddd",
|
||||
boxSizing: "border-box",
|
||||
position: "relative",
|
||||
},
|
||||
oninput: (event) => {
|
||||
let input = event.target.value;
|
||||
@@ -377,7 +375,7 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
});
|
||||
|
||||
const blockChainSection_lock = $el("div", { style: sectionStyle }, [
|
||||
$el("label", { style: labelStyle }, ["6️⃣ Download threshold"]),
|
||||
$el("label", { style: labelStyle }, ["6️⃣ Pay to download"]),
|
||||
$el(
|
||||
"label",
|
||||
{
|
||||
@@ -397,7 +395,6 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
marginLeft: "5px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
},
|
||||
},
|
||||
[
|
||||
@@ -411,18 +408,8 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
["Unlock with"]
|
||||
["Price US$"]
|
||||
),
|
||||
$el("img", {
|
||||
style: {
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
position: "absolute",
|
||||
right: "75px",
|
||||
zIndex: "100",
|
||||
},
|
||||
src: "https://static.copus.io/images/admin/202507/prod/e2919a1d8f3c2d99d3b8fe27ff94b841.png",
|
||||
}),
|
||||
this.LockInput,
|
||||
]
|
||||
),
|
||||
@@ -433,7 +420,7 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
||||
[
|
||||
this.radioButtonsCheckOff_lock,
|
||||
$el(
|
||||
$el(
|
||||
"div",
|
||||
{
|
||||
style: {
|
||||
@@ -442,7 +429,9 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
alignItems: "center",
|
||||
},
|
||||
},
|
||||
[$el("span", { style: { marginLeft: "5px" } }, ["OFF"])]
|
||||
[
|
||||
$el("span", { style: { marginLeft: "5px" } }, ["OFF"]),
|
||||
]
|
||||
),
|
||||
]
|
||||
),
|
||||
@@ -451,6 +440,7 @@ export class CopusShareDialog extends ComfyDialog {
|
||||
"p",
|
||||
{ style: { fontSize: "16px", color: "#fff", margin: "10px 0 0 0" } },
|
||||
[
|
||||
"Get paid from your workflow. You can change the price and withdraw your earnings on Copus.",
|
||||
]
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -1626,35 +1626,17 @@ export class CustomNodesManager {
|
||||
getNodesInWorkflow() {
|
||||
let usedGroupNodes = new Set();
|
||||
let allUsedNodes = {};
|
||||
const visitedGraphs = new Set();
|
||||
|
||||
const visitGraph = (graph) => {
|
||||
if (!graph || visitedGraphs.has(graph)) return;
|
||||
visitedGraphs.add(graph);
|
||||
for(let k in app.graph._nodes) {
|
||||
let node = app.graph._nodes[k];
|
||||
|
||||
const nodes = graph._nodes || graph.nodes || [];
|
||||
for(let k in nodes) {
|
||||
let node = nodes[k];
|
||||
if (!node) continue;
|
||||
|
||||
// If it's a SubgraphNode, recurse into its graph and continue searching
|
||||
if (node.isSubgraphNode?.() && node.subgraph) {
|
||||
visitGraph(node.subgraph);
|
||||
}
|
||||
|
||||
if (!node.type) continue;
|
||||
|
||||
// Group nodes / components
|
||||
if(typeof node.type === 'string' && node.type.startsWith('workflow>')) {
|
||||
usedGroupNodes.add(node.type.slice(9));
|
||||
continue;
|
||||
}
|
||||
|
||||
allUsedNodes[node.type] = node;
|
||||
if(node.type.startsWith('workflow>')) {
|
||||
usedGroupNodes.add(node.type.slice(9));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
visitGraph(app.graph);
|
||||
allUsedNodes[node.type] = node;
|
||||
}
|
||||
|
||||
for(let k of usedGroupNodes) {
|
||||
let subnodes = app.graph.extra.groupNodes[k]?.nodes;
|
||||
|
||||
@@ -46,7 +46,6 @@ version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' i
|
||||
|
||||
|
||||
DEFAULT_CHANNEL = "https://raw.githubusercontent.com/Comfy-Org/ComfyUI-Manager/main"
|
||||
DEFAULT_CHANNEL_LEGACY = "https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main"
|
||||
|
||||
|
||||
default_custom_nodes_path = None
|
||||
@@ -161,7 +160,7 @@ comfy_ui_revision = "Unknown"
|
||||
comfy_ui_commit_datetime = datetime(1900, 1, 1, 0, 0, 0)
|
||||
|
||||
channel_dict = None
|
||||
valid_channels = {'default', 'local', DEFAULT_CHANNEL, DEFAULT_CHANNEL_LEGACY}
|
||||
valid_channels = {'default', 'local'}
|
||||
channel_list = None
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ from ..common import cm_global
|
||||
from ..common import manager_downloader
|
||||
from ..common import context
|
||||
from ..common import manager_security
|
||||
from ..common import snapshot_util
|
||||
|
||||
|
||||
logging.info(f"### Loading: ComfyUI-Manager ({core.version_str})")
|
||||
@@ -1072,15 +1073,12 @@ async def fetch_customnode_list(request):
|
||||
if channel != 'local':
|
||||
found = 'custom'
|
||||
|
||||
if channel == core.DEFAULT_CHANNEL or channel == core.DEFAULT_CHANNEL_LEGACY:
|
||||
channel = 'default'
|
||||
else:
|
||||
for name, url in core.get_channel_dict().items():
|
||||
if url == channel:
|
||||
found = name
|
||||
break
|
||||
for name, url in core.get_channel_dict().items():
|
||||
if url == channel:
|
||||
found = name
|
||||
break
|
||||
|
||||
channel = found
|
||||
channel = found
|
||||
|
||||
result = dict(channel=channel, node_packs=node_packs.to_dict())
|
||||
|
||||
@@ -1171,7 +1169,7 @@ async def fetch_externalmodel_list(request):
|
||||
return web.json_response(json_obj, content_type='application/json')
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/snapshot/getlist")
|
||||
@routes.get("/v2/snapshot/getlist")
|
||||
async def get_snapshot_list(request):
|
||||
items = [f[:-5] for f in os.listdir(context.manager_snapshot_path) if f.endswith('.json')]
|
||||
items.sort(reverse=True)
|
||||
@@ -1239,6 +1237,46 @@ async def save_snapshot(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/diff")
|
||||
async def get_snapshot_diff(request):
|
||||
try:
|
||||
from_id = request.rel_url.query.get("from")
|
||||
to_id = request.rel_url.query.get("to")
|
||||
|
||||
if (from_id is not None and '..' in from_id) or (to_id is not None and '..' in to_id):
|
||||
logging.error("/v2/snapshot/diff: invalid 'from' or 'to' parameter.")
|
||||
return web.Response(status=400)
|
||||
|
||||
if from_id is None:
|
||||
from_json = await core.get_current_snapshot()
|
||||
else:
|
||||
from_path = os.path.join(context.manager_snapshot_path, f"{from_id}.json")
|
||||
if not os.path.exists(from_path):
|
||||
logging.error(f"/v2/snapshot/diff: 'from' parameter file not found: {from_path}")
|
||||
return web.Response(status=400)
|
||||
|
||||
from_json = snapshot_util.read_snapshot(from_path)
|
||||
|
||||
if to_id is None:
|
||||
logging.error("/v2/snapshot/diff: 'to' parameter is required.")
|
||||
return web.Response(status=401)
|
||||
else:
|
||||
to_path = os.path.join(context.manager_snapshot_path, f"{to_id}.json")
|
||||
if not os.path.exists(to_path):
|
||||
logging.error(f"/v2/snapshot/diff: 'to' parameter file not found: {to_path}")
|
||||
return web.Response(status=400)
|
||||
|
||||
to_json = snapshot_util.read_snapshot(to_path)
|
||||
|
||||
return web.json_response(snapshot_util.diff_snapshot(from_json, to_json), content_type='application/json')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] Error in /v2/snapshot/diff: {e}")
|
||||
traceback.print_exc()
|
||||
# Return a generic error response
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
def unzip_install(files):
|
||||
temp_filename = 'manager-temp.zip'
|
||||
for url in files:
|
||||
@@ -1311,65 +1349,6 @@ async def import_fail_info(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/customnode/import_fail_info_bulk")
|
||||
async def import_fail_info_bulk(request):
|
||||
try:
|
||||
json_data = await request.json()
|
||||
|
||||
# Basic validation - ensure we have either cnr_ids or urls
|
||||
if not isinstance(json_data, dict):
|
||||
return web.Response(status=400, text="Request body must be a JSON object")
|
||||
|
||||
if "cnr_ids" not in json_data and "urls" not in json_data:
|
||||
return web.Response(
|
||||
status=400, text="Either 'cnr_ids' or 'urls' field is required"
|
||||
)
|
||||
|
||||
await core.unified_manager.reload('cache')
|
||||
await core.unified_manager.get_custom_nodes('default', 'cache')
|
||||
|
||||
results = {}
|
||||
|
||||
if "cnr_ids" in json_data:
|
||||
if not isinstance(json_data["cnr_ids"], list):
|
||||
return web.Response(status=400, text="'cnr_ids' must be an array")
|
||||
for cnr_id in json_data["cnr_ids"]:
|
||||
if not isinstance(cnr_id, str):
|
||||
results[cnr_id] = {"error": "cnr_id must be a string"}
|
||||
continue
|
||||
module_name = core.unified_manager.get_module_name(cnr_id)
|
||||
if module_name is not None:
|
||||
info = cm_global.error_dict.get(module_name)
|
||||
if info is not None:
|
||||
results[cnr_id] = info
|
||||
else:
|
||||
results[cnr_id] = None
|
||||
else:
|
||||
results[cnr_id] = None
|
||||
|
||||
if "urls" in json_data:
|
||||
if not isinstance(json_data["urls"], list):
|
||||
return web.Response(status=400, text="'urls' must be an array")
|
||||
for url in json_data["urls"]:
|
||||
if not isinstance(url, str):
|
||||
results[url] = {"error": "url must be a string"}
|
||||
continue
|
||||
module_name = core.unified_manager.get_module_name(url)
|
||||
if module_name is not None:
|
||||
info = cm_global.error_dict.get(module_name)
|
||||
if info is not None:
|
||||
results[url] = info
|
||||
else:
|
||||
results[url] = None
|
||||
else:
|
||||
results[url] = None
|
||||
|
||||
return web.json_response(results)
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] Error processing bulk import fail info: {e}")
|
||||
return web.Response(status=500, text="Internal server error")
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/reinstall")
|
||||
async def reinstall_custom_node(request):
|
||||
await uninstall_custom_node(request)
|
||||
|
||||
@@ -10,16 +10,6 @@ import hashlib
|
||||
|
||||
import folder_paths
|
||||
from server import PromptServer
|
||||
import logging
|
||||
import sys
|
||||
|
||||
|
||||
try:
|
||||
from nio import AsyncClient, LoginResponse, UploadResponse
|
||||
matrix_nio_is_available = True
|
||||
except Exception:
|
||||
logging.warning(f"[ComfyUI-Manager] The matrix sharing feature has been disabled because the `matrix-nio` dependency is not installed.\n\tTo use this feature, please run the following command:\n\t{sys.executable} -m pip install matrix-nio\n")
|
||||
matrix_nio_is_available = False
|
||||
|
||||
|
||||
def extract_model_file_names(json_data):
|
||||
@@ -202,14 +192,6 @@ async def get_esheep_workflow_and_images(request):
|
||||
return web.Response(status=200, text=json.dumps(data))
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_matrix_dep_status")
|
||||
async def get_matrix_dep_status(request):
|
||||
if matrix_nio_is_available:
|
||||
return web.Response(status=200, text='available')
|
||||
else:
|
||||
return web.Response(status=200, text='unavailable')
|
||||
|
||||
|
||||
def set_matrix_auth(json_data):
|
||||
homeserver = json_data['homeserver']
|
||||
username = json_data['username']
|
||||
@@ -349,12 +331,14 @@ async def share_art(request):
|
||||
workflowId = upload_workflow_json["workflowId"]
|
||||
|
||||
# check if the user has provided Matrix credentials
|
||||
if matrix_nio_is_available and "matrix" in share_destinations:
|
||||
if "matrix" in share_destinations:
|
||||
comfyui_share_room_id = '!LGYSoacpJPhIfBqVfb:matrix.org'
|
||||
filename = os.path.basename(asset_filepath)
|
||||
content_type = assetFileType
|
||||
|
||||
try:
|
||||
from nio import AsyncClient, LoginResponse, UploadResponse
|
||||
|
||||
homeserver = 'matrix.org'
|
||||
if matrix_auth:
|
||||
homeserver = matrix_auth.get('homeserver', 'matrix.org')
|
||||
|
||||
2689
comfyui_manager/custom-node-list.json → custom-node-list.json
Normal file → Executable file
2689
comfyui_manager/custom-node-list.json → custom-node-list.json
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5045,105 +5045,6 @@
|
||||
"size": "1.26GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 ti2v 5B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for ti2v 5B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_ti2v_5B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors",
|
||||
"size": "10.0GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Comfy-Org/umt5_xxl_fp16.safetensors",
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,5 @@
|
||||
{
|
||||
"custom_nodes": [
|
||||
{
|
||||
"author": "synchronicity-labs",
|
||||
"title": "ComfyUI Sync Lipsync Node",
|
||||
"reference": "https://github.com/synchronicity-labs/sync-comfyui",
|
||||
"files": [
|
||||
"https://github.com/synchronicity-labs/sync-comfyui"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This custom node allows you to perform audio-video lip synchronization inside ComfyUI using a simple interface."
|
||||
},
|
||||
{
|
||||
"author": "joaomede",
|
||||
"title": "ComfyUI-Unload-Model-Fork",
|
||||
|
||||
@@ -1,282 +1,8 @@
|
||||
{
|
||||
"custom_nodes": [
|
||||
{
|
||||
"author": "perilli",
|
||||
"title": "apw_nodes [REMOVED]",
|
||||
"reference": "https://github.com/alessandroperilli/APW_Nodes",
|
||||
"files": [
|
||||
"https://github.com/alessandroperilli/APW_Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node suite to augment the capabilities of the [a/AP Workflows for ComfyUI](https://perilli.com/ai/comfyui/)\nNOTE: See [a/Open Creative Studio Nodes](https://github.com/alessandroperilli/OCS_Nodes)"
|
||||
},
|
||||
{
|
||||
"author": "greengerong",
|
||||
"title": "ComfyUI-Lumina-Video [REMOVED]",
|
||||
"reference": "https://github.com/greengerong/ComfyUI-Lumina-Video",
|
||||
"files": [
|
||||
"https://github.com/greengerong/ComfyUI-Lumina-Video"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a video generation plugin implementation for ComfyUI based on the Lumina Video model."
|
||||
},
|
||||
{
|
||||
"author": "SatadalAI",
|
||||
"title": "Combined Upscale Node for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/SatadalAI/SATA_UtilityNode",
|
||||
"files": [
|
||||
"https://github.com/SatadalAI/SATA_UtilityNode"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Combined_Upscale is a custom ComfyUI node designed for high-quality image enhancement workflows. It intelligently combines model-based upscaling with efficient CPU-based resizing, offering granular control over output dimensions and quality. Ideal for asset pipelines, UI prototyping, and generative workflows.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "netroxin",
|
||||
"title": "Netro_wildcards [REMOVED]",
|
||||
"reference": "https://github.com/netroxin/comfyui_netro_wildcards",
|
||||
"files": [
|
||||
"https://github.com/netroxin/comfyui_netro_wildcards"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Since I used 'simple wildcards' from Vanilla and it no longer works with the new Comfy UI version for me, I created an alternative. This CustomNode takes the entire contents of your wildcards-folder(comfyui wildcards) and creates a node for each one."
|
||||
},
|
||||
{
|
||||
"author": "takoyaki1118",
|
||||
"title": "ComfyUI-MangaTools [REMOVED]",
|
||||
"reference": "https://github.com/takoyaki1118/ComfyUI-MangaTools",
|
||||
"files": [
|
||||
"https://github.com/takoyaki1118/ComfyUI-MangaTools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Manga Panel Detector, Manga Panel Dispatcher, GateImage, MangaPageAssembler"
|
||||
},
|
||||
{
|
||||
"author": "lucasgattas",
|
||||
"title": "comfyui-egregora-regional [REMOVED]",
|
||||
"reference": "https://github.com/lucasgattas/comfyui-egregora-regional",
|
||||
"files": [
|
||||
"https://github.com/lucasgattas/comfyui-egregora-regional"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Image Tile Split with Region-Aware Prompting for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "lucasgattas",
|
||||
"title": "comfyui-egregora-tiled [REMOVED]",
|
||||
"reference": "https://github.com/lucasgattas/comfyui-egregora-tiled",
|
||||
"files": [
|
||||
"https://github.com/lucasgattas/comfyui-egregora-tiled"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Tiled regional prompting + tiled VAE decode with seam-free blending for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "Seedsa",
|
||||
"title": "ComfyUI Fooocus Nodes [REMOVED]",
|
||||
"id": "fooocus-nodes",
|
||||
"reference": "https://github.com/Seedsa/Fooocus_Nodes",
|
||||
"files": [
|
||||
"https://github.com/Seedsa/Fooocus_Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This extension provides image generation features based on Fooocus."
|
||||
},
|
||||
{
|
||||
"author": "zhilemann",
|
||||
"title": "ComfyUI-moondream2 [REMOVED]",
|
||||
"reference": "https://github.com/zhilemann/ComfyUI-moondream2",
|
||||
"files": [
|
||||
"https://github.com/zhilemann/ComfyUI-moondream2"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "nodes for nightly moondream2 VLM inference\nsupports only captioning and visual queries at the moment"
|
||||
},
|
||||
{
|
||||
"author": "shinich39",
|
||||
"title": "comfyui-textarea-is-shit [REMOVED]",
|
||||
"reference": "https://github.com/shinich39/comfyui-textarea-is-shit",
|
||||
"files": [
|
||||
"https://github.com/shinich39/comfyui-textarea-is-shit"
|
||||
],
|
||||
"description": "HTML gives me a textarea like piece of shit.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "shinich39",
|
||||
"title": "comfyui-poor-textarea [REMOVED]",
|
||||
"reference": "https://github.com/shinich39/comfyui-poor-textarea",
|
||||
"files": [
|
||||
"https://github.com/shinich39/comfyui-poor-textarea"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Add commentify, indentation, auto-close brackets in textarea."
|
||||
},
|
||||
{
|
||||
"author": "InfiniNode",
|
||||
"title": "Comfyui-InfiniNode-Model-Suite [UNSAFE/REMOVED]",
|
||||
"reference": "https://github.com/InfiniNode/Comfyui-InfiniNode-Model-Suite",
|
||||
"files": [
|
||||
"https://github.com/InfiniNode/Comfyui-InfiniNode-Model-Suite"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Welcome to the InfiniNode Model Suite, a custom node pack for ComfyUI that transforms the process of manipulating generative AI models. Our suite is a direct implementation of the 'GUI-Based Key Converter Development Plan,' designed to remove technical barriers for advanced AI practitioners and integrate seamlessly with existing image generation pipelines.[w/This node pack contains a node that has a vulnerability allowing write to arbitrary file paths.]"
|
||||
},
|
||||
{
|
||||
"author": "Avalre",
|
||||
"title": "ComfyUI-avaNodes [REMOVED]",
|
||||
"reference": "https://github.com/Avalre/ComfyUI-avaNodes",
|
||||
"files": [
|
||||
"https://github.com/Avalre/ComfyUI-avaNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "These nodes were created to personalize/optimize several ComfyUI nodes for my own use. You can replicate the functionality of most of my nodes by some combination of default ComfyUI nodes and custom nodes from other developers."
|
||||
},
|
||||
{
|
||||
"author": "Alectriciti",
|
||||
"title": "comfyui-creativeprompts [REMOVED]",
|
||||
"reference": "https://github.com/Alectriciti/comfyui-creativeprompts",
|
||||
"files": [
|
||||
"https://github.com/Alectriciti/comfyui-creativeprompts"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A creative alternative to dynamicprompts"
|
||||
},
|
||||
{
|
||||
"author": "flybirdxx",
|
||||
"title": "ComfyUI Sliding Window [REMOVED]",
|
||||
"reference": "https://github.com/PixWizardry/ComfyUI_Sliding_Window",
|
||||
"files": [
|
||||
"https://github.com/PixWizardry/ComfyUI_Sliding_Window"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This set of nodes provides a powerful sliding window or 'tiling' technique for processing long videos and animations in ComfyUI. It allows you to work on animations that are longer than your VRAM would typically allow by breaking the job into smaller, overlapping chunks and seamlessly blending them back together."
|
||||
},
|
||||
{
|
||||
"author": "SykkoAtHome",
|
||||
"title": "Sykko Tools for ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/SykkoAtHome/ComfyUI_SykkoTools",
|
||||
"files": [
|
||||
"https://github.com/SykkoAtHome/ComfyUI_SykkoTools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Utilities for working with camera animations inside ComfyUI. The repository currently provides a node for loading camera motion from ASCII FBX files and a corresponding command line helper for debugging."
|
||||
},
|
||||
{
|
||||
"author": "hananbeer",
|
||||
"title": "node_dev - ComfyUI Node Development Helper [REMOVED]",
|
||||
"reference": "https://github.com/hananbeer/node_dev",
|
||||
"files": [
|
||||
"https://github.com/hananbeer/node_dev"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Browse to this endpoint to reload custom nodes for more streamlined development:\nhttp://127.0.0.1:8188/node_dev/reload/<module_name>"
|
||||
},
|
||||
{
|
||||
"author": "Charonartist",
|
||||
"title": "Comfyui_gemini_tts_node [REMOVED]",
|
||||
"reference": "https://github.com/Charonartist/Comfyui_gemini_tts_node",
|
||||
"files": [
|
||||
"https://github.com/Charonartist/Comfyui_gemini_tts_node"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This custom node is a ComfyUI node for generating speech from text using the Gemini 2.5 Flash Preview TTS API."
|
||||
},
|
||||
{
|
||||
"author": "squirrel765",
|
||||
"title": "lorasubdirectory [REMOVED]",
|
||||
"reference": "https://github.com/andrewsthomasj/lorasubdirectory",
|
||||
"files": [
|
||||
"https://github.com/andrewsthomasj/lorasubdirectory"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "only show dropdown of loras ina a given subdirectory"
|
||||
},
|
||||
{
|
||||
"author": "shingo1228",
|
||||
"title": "ComfyUI-send-Eagle(slim) [REVMOED]",
|
||||
"id": "send-eagle",
|
||||
"reference": "https://github.com/shingo1228/ComfyUI-send-eagle-slim",
|
||||
"files": [
|
||||
"https://github.com/shingo1228/ComfyUI-send-eagle-slim"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Send Webp Image to Eagle. This is an extension node for ComfyUI that allows you to send generated images in webp format to Eagle. This extension node is a re-implementation of the Eagle linkage functions of the previous ComfyUI-send-Eagle node, focusing on the functions required for this node."
|
||||
},
|
||||
{
|
||||
"author": "shingo1228",
|
||||
"title": "ComfyUI-SDXL-EmptyLatentImage [REVMOED]",
|
||||
"id": "sdxl-emptylatent",
|
||||
"reference": "https://github.com/shingo1228/ComfyUI-SDXL-EmptyLatentImage",
|
||||
"files": [
|
||||
"https://github.com/shingo1228/ComfyUI-SDXL-EmptyLatentImage"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:SDXL Empty Latent Image. An extension node for ComfyUI that allows you to select a resolution from the pre-defined json files and output a Latent Image."
|
||||
},
|
||||
{
|
||||
"author": "chaunceyyann",
|
||||
"title": "ComfyUI Image Processing Nodes [REMOVED]",
|
||||
"reference": "https://github.com/chaunceyyann/comfyui-image-processing-nodes",
|
||||
"files": [
|
||||
"https://github.com/chaunceyyann/comfyui-image-processing-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI focused on image processing operations."
|
||||
},
|
||||
{
|
||||
"author": "OgreLemonSoup",
|
||||
"title": "Gallery&Tabs [DEPRECATED]",
|
||||
"id": "LoadImageGallery",
|
||||
"reference": "https://github.com/OgreLemonSoup/ComfyUI-Load-Image-Gallery",
|
||||
"files": [
|
||||
"https://github.com/OgreLemonSoup/ComfyUI-Load-Image-Gallery"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Adds a gallery to the Load Image node and tabs for Load Checkpoint/Lora/etc nodes"
|
||||
},
|
||||
{
|
||||
"author": "11dogzi",
|
||||
"title": "Qwen-Image ComfyUI [REMOVED]",
|
||||
"reference": "https://github.com/11dogzi/Comfyui-Qwen-Image",
|
||||
"files": [
|
||||
"https://github.com/11dogzi/Comfyui-Qwen-Image"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a custom node package that integrates the Qwen-Image model into ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "BAIS1C",
|
||||
"title": "ComfyUI-AudioDuration [REMOVED]",
|
||||
"reference": "https://github.com/BAIS1C/ComfyUI_BASICDancePoser",
|
||||
"files": [
|
||||
"https://github.com/BAIS1C/ComfyUI_BASICDancePoser"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Node to extract Dance poses from Music to control Video Generations.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "BAIS1C",
|
||||
"title": "ComfyUI_BASICSAdvancedDancePoser [REMOVED]",
|
||||
"reference": "https://github.com/BAIS1C/ComfyUI_BASICSAdvancedDancePoser",
|
||||
"files": [
|
||||
"https://github.com/BAIS1C/ComfyUI_BASICSAdvancedDancePoser"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Professional COCO-WholeBody 133-keypoint dance animation system for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "fablestudio",
|
||||
"title": "ComfyUI-Showrunner-Utils [REMOVED]",
|
||||
"reference": "https://github.com/fablestudio/ComfyUI-Showrunner-Utils",
|
||||
"files": [
|
||||
"https://github.com/fablestudio/ComfyUI-Showrunner-Utils"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Align Face, Generate Timestamp, GetMostCommonColors, Alpha Crop and Position Image, Shrink Image"
|
||||
},
|
||||
{
|
||||
"author": "skayka",
|
||||
"title": "ComfyUI-DreamFit [REMOVED]",
|
||||
"title": "ComfyUI-DreamFit []REMOVED]",
|
||||
"reference": "https://github.com/skayka/ComfyUI-DreamFit",
|
||||
"files": [
|
||||
"https://github.com/skayka/ComfyUI-DreamFit"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,106 +1,5 @@
|
||||
{
|
||||
"models": [
|
||||
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
||||
"size": "28.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp8_scaled)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp8_scaled)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
||||
"size": "14.3GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/Wan2.2 ti2v 5B (fp16)",
|
||||
"type": "diffusion_model",
|
||||
"base": "Wan2.2",
|
||||
"save_path": "diffusion_models/Wan2.2",
|
||||
"description": "Wan2.2 diffusion model for ti2v 5B (fp16)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
||||
"filename": "wan2.2_ti2v_5B_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors",
|
||||
"size": "10.0GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "sam2.1_hiera_tiny.pt",
|
||||
"type": "sam2.1",
|
||||
@@ -687,6 +586,109 @@
|
||||
"filename": "llava_llama3_fp16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/text_encoders/llava_llama3_fp16.safetensors",
|
||||
"size": "16.1GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "PixArt-Sigma-XL-2-512-MS.safetensors (diffusion)",
|
||||
"type": "diffusion_model",
|
||||
"base": "pixart-sigma",
|
||||
"save_path": "diffusion_models/PixArt-Sigma",
|
||||
"description": "PixArt-Sigma Diffusion model",
|
||||
"reference": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-512-MS",
|
||||
"filename": "PixArt-Sigma-XL-2-512-MS.safetensors",
|
||||
"url": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-512-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||
"size": "2.44GB"
|
||||
},
|
||||
{
|
||||
"name": "PixArt-Sigma-XL-2-1024-MS.safetensors (diffusion)",
|
||||
"type": "diffusion_model",
|
||||
"base": "pixart-sigma",
|
||||
"save_path": "diffusion_models/PixArt-Sigma",
|
||||
"description": "PixArt-Sigma Diffusion model",
|
||||
"reference": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-1024-MS",
|
||||
"filename": "PixArt-Sigma-XL-2-1024-MS.safetensors",
|
||||
"url": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-1024-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||
"size": "2.44GB"
|
||||
},
|
||||
{
|
||||
"name": "PixArt-XL-2-1024-MS.safetensors (diffusion)",
|
||||
"type": "diffusion_model",
|
||||
"base": "pixart-alpha",
|
||||
"save_path": "diffusion_models/PixArt-Alpha",
|
||||
"description": "PixArt-Alpha Diffusion model",
|
||||
"reference": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-1024-MS",
|
||||
"filename": "PixArt-XL-2-1024-MS.safetensors",
|
||||
"url": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-1024-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||
"size": "2.45GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Comfy-Org/hunyuan_video_t2v_720p_bf16.safetensors",
|
||||
"type": "diffusion_model",
|
||||
"base": "Hunyuan Video",
|
||||
"save_path": "diffusion_models/hunyuan_video",
|
||||
"description": "Huyuan Video diffusion model. repackaged version.",
|
||||
"reference": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged",
|
||||
"filename": "hunyuan_video_t2v_720p_bf16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/diffusion_models/hunyuan_video_t2v_720p_bf16.safetensors",
|
||||
"size": "25.6GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy-Org/hunyuan_video_vae_bf16.safetensors",
|
||||
"type": "VAE",
|
||||
"base": "Hunyuan Video",
|
||||
"save_path": "VAE",
|
||||
"description": "Huyuan Video VAE model. repackaged version.",
|
||||
"reference": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged",
|
||||
"filename": "hunyuan_video_vae_bf16.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/vae/hunyuan_video_vae_bf16.safetensors",
|
||||
"size": "493MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "LTX-Video 2B v0.9.1 Checkpoint",
|
||||
"type": "checkpoint",
|
||||
"base": "LTX-Video",
|
||||
"save_path": "checkpoints/LTXV",
|
||||
"description": "LTX-Video is the first DiT-based video generation model capable of generating high-quality videos in real-time. It produces 24 FPS videos at a 768x512 resolution faster than they can be watched. Trained on a large-scale dataset of diverse videos, the model generates high-resolution videos with realistic and varied content.",
|
||||
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
||||
"filename": "ltx-video-2b-v0.9.1.safetensors",
|
||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltx-video-2b-v0.9.1.safetensors",
|
||||
"size": "5.72GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "XLabs-AI/flux-canny-controlnet-v3.safetensors",
|
||||
"type": "controlnet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "xlabs/controlnets",
|
||||
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||
"filename": "flux-canny-controlnet-v3.safetensors",
|
||||
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-canny-controlnet-v3.safetensors",
|
||||
"size": "1.49GB"
|
||||
},
|
||||
{
|
||||
"name": "XLabs-AI/flux-depth-controlnet-v3.safetensors",
|
||||
"type": "controlnet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "xlabs/controlnets",
|
||||
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||
"filename": "flux-depth-controlnet-v3.safetensors",
|
||||
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-depth-controlnet-v3.safetensors",
|
||||
"size": "1.49GB"
|
||||
},
|
||||
{
|
||||
"name": "XLabs-AI/flux-hed-controlnet-v3.safetensors",
|
||||
"type": "controlnet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "xlabs/controlnets",
|
||||
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||
"filename": "flux-hed-controlnet-v3.safetensors",
|
||||
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-hed-controlnet-v3.safetensors",
|
||||
"size": "1.49GB"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -341,16 +341,6 @@
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A minimal test suite demonstrating how remote COMBO inputs behave in ComfyUI, with and without force_input"
|
||||
},
|
||||
{
|
||||
"author": "J1mB091",
|
||||
"title": "ComfyUI-J1mB091 Custom Nodes",
|
||||
"reference": "https://github.com/J1mB091/ComfyUI-J1mB091",
|
||||
"files": [
|
||||
"https://github.com/J1mB091/ComfyUI-J1mB091"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Vibe Coded ComfyUI Custom Nodes"
|
||||
}
|
||||
]
|
||||
}
|
||||
142
openapi.yaml
142
openapi.yaml
@@ -782,39 +782,6 @@ components:
|
||||
minimum: 0
|
||||
default: 0
|
||||
required: [batch_id, start_time, state_before]
|
||||
|
||||
ImportFailInfoBulkRequest:
|
||||
type: object
|
||||
properties:
|
||||
cnr_ids:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: A list of CNR IDs to check.
|
||||
urls:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: A list of repository URLs to check.
|
||||
|
||||
ImportFailInfoBulkResponse:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/components/schemas/ImportFailInfoItem'
|
||||
description: >-
|
||||
A dictionary where each key is a cnr_id or url from the request,
|
||||
and the value is the corresponding error info.
|
||||
|
||||
ImportFailInfoItem:
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
traceback:
|
||||
type: string
|
||||
- type: "null"
|
||||
|
||||
securitySchemes:
|
||||
securityLevel:
|
||||
type: apiKey
|
||||
@@ -1050,32 +1017,6 @@ paths:
|
||||
description: Processing started
|
||||
'201':
|
||||
description: Processing already in progress
|
||||
|
||||
/v2/customnode/import_fail_info_bulk:
|
||||
post:
|
||||
summary: Get import failure info for multiple nodes
|
||||
description: Retrieves recorded import failure information for a list of custom nodes.
|
||||
tags:
|
||||
- customnode
|
||||
requestBody:
|
||||
description: A list of CNR IDs or repository URLs to check.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ImportFailInfoBulkRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: A dictionary containing the import failure information.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ImportFailInfoBulkResponse'
|
||||
'400':
|
||||
description: Bad Request. The request body is invalid.
|
||||
'500':
|
||||
description: Internal Server Error.
|
||||
|
||||
/v2/manager/queue/reset:
|
||||
get:
|
||||
summary: Reset queue
|
||||
@@ -1268,6 +1209,89 @@ paths:
|
||||
description: Snapshot saved successfully
|
||||
'400':
|
||||
description: Error saving snapshot
|
||||
/v2/snapshot/diff:
|
||||
get:
|
||||
summary: Get snapshot diff
|
||||
description: Returns the changes that would occur when restoring from the 'from' snapshot to the 'to' snapshot.
|
||||
parameters:
|
||||
- name: from
|
||||
in: query
|
||||
required: false
|
||||
description: This parameter refers to the existing snapshot; if omitted, it defaults to the current snapshot.
|
||||
schema:
|
||||
type: string
|
||||
- name: to
|
||||
in: query
|
||||
required: true
|
||||
description: This parameter is the snapshot to compare against the existing snapshot.
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
nodepack_diff:
|
||||
type: object
|
||||
properties:
|
||||
added:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
removed:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
upgraded:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
to:
|
||||
type: string
|
||||
downgraded:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
to:
|
||||
type: string
|
||||
changed:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
pip_diff:
|
||||
type: object
|
||||
properties:
|
||||
added:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
upgraded:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
to:
|
||||
type: string
|
||||
downgraded:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
properties:
|
||||
from:
|
||||
type: string
|
||||
to:
|
||||
type: string
|
||||
# ComfyUI Management Endpoints (v2)
|
||||
/v2/comfyui_manager/comfyui_versions:
|
||||
get:
|
||||
|
||||
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
||||
[project]
|
||||
name = "comfyui-manager"
|
||||
license = { text = "GPL-3.0-only" }
|
||||
version = "4.0.1-beta.5"
|
||||
version = "4.0.0-beta.10"
|
||||
requires-python = ">= 3.9"
|
||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||
readme = "README.md"
|
||||
@@ -27,7 +27,7 @@ classifiers = [
|
||||
dependencies = [
|
||||
"GitPython",
|
||||
"PyGithub",
|
||||
# "matrix-nio",
|
||||
"matrix-client==0.4.0",
|
||||
"transformers",
|
||||
"huggingface-hub>0.20",
|
||||
"typer",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
GitPython
|
||||
PyGithub
|
||||
# matrix-nio
|
||||
matrix-nio
|
||||
transformers
|
||||
huggingface-hub>0.20
|
||||
typer
|
||||
|
||||
Reference in New Issue
Block a user