mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-01-31 08:20:24 +08:00
Merge branch 'ltdrdata:main' into main
This commit is contained in:
commit
16518495f8
21
.github/workflows/publish.yml
vendored
Normal file
21
.github/workflows/publish.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Publish to Comfy registry
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "pyproject.toml"
|
||||
|
||||
jobs:
|
||||
publish-node:
|
||||
name: Publish Custom Node to registry
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Publish Custom Node
|
||||
uses: Comfy-Org/publish-node-action@main
|
||||
with:
|
||||
## Add your own personal access token to your Github Repository secrets and reference it here.
|
||||
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
|
||||
59
README.md
59
README.md
@ -5,6 +5,7 @@
|
||||

|
||||
|
||||
## NOTICE
|
||||
* V2.33 Security policy is applied.
|
||||
* V2.21 [cm-cli](docs/en/cm-cli.md) tool is added.
|
||||
* V2.18 to V2.18.3 is not functioning due to a severe bug. Users on these versions are advised to promptly update to V2.18.4. Please navigate to the `ComfyUI/custom_nodes/ComfyUI-Manager` directory and execute `git pull` to update.
|
||||
* You can see whole nodes info on [ComfyUI Nodes Info](https://ltdrdata.github.io/) page.
|
||||
@ -31,10 +32,32 @@ To install ComfyUI-Manager in addition to an existing installation of ComfyUI, y
|
||||

|
||||
|
||||
|
||||
### Installation[method3] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
||||
### Installation[method3] (Installation through comfy-cli: install ComfyUI and ComfyUI-Manager at once.)
|
||||
> RECOMMENDED: comfy-cli provides various features to manage ComfyUI from the CLI.
|
||||
|
||||
* **prerequisite: python 3, git**
|
||||
|
||||
Windows:
|
||||
```commandline
|
||||
python -m venv venv
|
||||
venv\Scripts\activate
|
||||
pip install comfy-cli
|
||||
comfy install
|
||||
```
|
||||
|
||||
Linux/OSX:
|
||||
```commandline
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install comfy-cli
|
||||
comfy install
|
||||
```
|
||||
|
||||
|
||||
### Installation[method4] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
||||
|
||||
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
||||
* **prerequisite: python-is-python3, python3-venv**
|
||||
* **prerequisite: python-is-python3, python3-venv, git**
|
||||
|
||||
1. Download [scripts/install-comfyui-venv-linux.sh](https://github.com/ltdrdata/ComfyUI-Manager/raw/main/scripts/install-comfyui-venv-linux.sh) into empty install directory
|
||||
- ComfyUI will be installed in the subdirectory of the specified directory, and the directory will contain the generated executable script.
|
||||
@ -169,6 +192,7 @@ This repository provides Colab notebooks that allow you to install and use Comfy
|
||||
* NOTE: Before submitting the PR after making changes, please check `Use local DB` and ensure that the extension list loads without any issues in the `Install custom nodes` dialog. Occasionally, missing or extra commas can lead to JSON syntax errors.
|
||||
* The remaining JSON will be updated through scripts in the future, so you don't need to worry about it.
|
||||
|
||||
|
||||
## Custom node support guide
|
||||
|
||||
* Currently, the system operates by cloning the git repository and sequentially installing the dependencies listed in requirements.txt using pip, followed by invoking the install.py script. In the future, we plan to discuss and determine the specifications for supporting custom nodes.
|
||||
@ -316,6 +340,31 @@ When you run the `scan.sh` script:
|
||||
* Edit `config.ini` file: add `windows_selector_event_loop_policy = True`
|
||||
|
||||
|
||||
## Security policy
|
||||
* Edit `config.ini` file: add `security_level = <LEVEL>`
|
||||
* `strong`
|
||||
* doesn't allow `high` and `middle` level risky feature
|
||||
* `normal`
|
||||
* doesn't allow `high` level risky feature if `--listen` is specified and not starts with `127.`
|
||||
* `middle` level risky feature is available
|
||||
* `weak`
|
||||
* all feature is available
|
||||
|
||||
* `high` level risky features
|
||||
* `Install via git url`, `pip install`
|
||||
* Installation of custom nodes registered not in the `default channel`.
|
||||
* Display terminal log
|
||||
|
||||
* `middle` level risky features
|
||||
* Uninstall/Update/Fix custom nodes
|
||||
* Installation of custom nodes registered in the `default channel`.
|
||||
* Restore/Remove Snapshot
|
||||
* Restart
|
||||
|
||||
* `low` level risky features
|
||||
* Update ComfyUI
|
||||
|
||||
|
||||
## TODO: Unconventional form of custom node list
|
||||
|
||||
* https://github.com/diontimmer/Sample-Diffusion-ComfyUI-Extension
|
||||
@ -324,7 +373,11 @@ When you run the `scan.sh` script:
|
||||
* https://github.com/StartHua/Comfyui_GPT_Story
|
||||
* https://github.com/NielsGercama/comfyui_customsampling
|
||||
* https://github.com/wrightdaniel2017/ComfyUI-VideoLipSync
|
||||
|
||||
* https://github.com/bxdsjs/ComfyUI-Image-preprocessing
|
||||
* https://github.com/SMUELDigital/ComfyUI-ONSET
|
||||
* https://github.com/SimithWang/comfyui-renameImages
|
||||
* https://github.com/icefairy64/comfyui-model-tilt
|
||||
* https://github.com/andrewharp/ComfyUI-EasyNodes
|
||||
|
||||
## Roadmap
|
||||
|
||||
|
||||
@ -204,6 +204,16 @@
|
||||
"id":"https://github.com/blepping/ComfyUI-sonar",
|
||||
"tags":"sonar",
|
||||
"description": "This extension provides some alternative functionalities of the [a/stable-diffusion-webui-sonar](https://github.com/Kahsolt/stable-diffusion-webui-sonar) extension."
|
||||
},
|
||||
{
|
||||
"id":"https://github.com/AIFSH/ComfyUI-RVC",
|
||||
"tags":"sonar",
|
||||
"description": "a comfyui custom node for [a/Retrieval-based-Voice-Conversion-WebUI](https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git), you can Voice-Conversion in comfyui now!"
|
||||
},
|
||||
{
|
||||
"id":"https://github.com/portu-sim/comfyui-bmab",
|
||||
"tags":"bmab",
|
||||
"description": "a comfyui custom node for [a/sd-webui-bmab](https://github.com/portu-sim/sd-webui-bmab)"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,8 @@
|
||||
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.22) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
|
||||
python cm-cli.py [OPTIONS]
|
||||
|
||||
@ -12,12 +13,11 @@ OPTIONS:
|
||||
[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
save-snapshot
|
||||
restore-snapshot <snapshot>
|
||||
save-snapshot ?[--output <snapshot .json/.yaml>]
|
||||
restore-snapshot <snapshot .json/.yaml> ?[--pip-non-url] ?[--pip-non-local-url] ?[--pip-local-url]
|
||||
cli-only-mode [enable|disable]
|
||||
restore-dependencies
|
||||
clear
|
||||
|
||||
```
|
||||
|
||||
## How To Use?
|
||||
@ -52,7 +52,7 @@ OPTIONS:
|
||||
Executing a command like `python cm-cli.py show installed` will display detailed information about the installed custom nodes.
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||
[ ENABLED ] ComfyUI-Manager (author: Dr.Lt.Data)
|
||||
@ -69,7 +69,7 @@ FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main
|
||||
Using a command like `python cm-cli.py simple-show installed` will simply display information about the installed custom nodes.
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||
ComfyUI-Manager
|
||||
@ -112,11 +112,17 @@ ComfyUI-Loopchain
|
||||
* `enable`: Enables the specified custom nodes.
|
||||
* `fix`: Attempts to fix dependencies for the specified custom nodes.
|
||||
|
||||
|
||||
### 4. Snapshot Management
|
||||
* `python cm-cli.py save-snapshot`: Saves the current snapshot.
|
||||
* `python cm-cli.py restore-snapshot <snapshot>`: Restores to the specified snapshot.
|
||||
* If a file exists at the snapshot path, it loads that snapshot.
|
||||
* If no file exists at the snapshot path, it implicitly assumes the snapshot is located in ComfyUI-Manager/snapshots.
|
||||
* `python cm-cli.py save-snapshot [--output <snapshot .json/.yaml>]`: Saves the current snapshot.
|
||||
* With `--output`, you can save a file in .yaml format to any specified path.
|
||||
* `python cm-cli.py restore-snapshot <snapshot .json/.yaml>`: Restores to the specified snapshot.
|
||||
* If a file exists at the snapshot path, that snapshot is loaded.
|
||||
* If no file exists at the snapshot path, it is implicitly assumed to be in ComfyUI-Manager/snapshots.
|
||||
* `--pip-non-url`: Restore for pip packages registered on PyPI.
|
||||
* `--pip-non-local-url`: Restore for pip packages registered at web URLs.
|
||||
* `--pip-local-url`: Restore for pip packages specified by local paths.
|
||||
|
||||
|
||||
### 5. CLI Only Mode
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
|
||||
python cm-cli.py [OPTIONS]
|
||||
|
||||
@ -12,12 +13,11 @@ OPTIONS:
|
||||
[install|reinstall|uninstall|update|disable|enable|fix] node_name ... ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
[simple-show|show] [installed|enabled|not-installed|disabled|all|snapshot|snapshot-list] ?[--channel <channel name>] ?[--mode [remote|local|cache]]
|
||||
save-snapshot
|
||||
restore-snapshot <snapshot>
|
||||
save-snapshot ?[--output <snapshot .json/.yaml>]
|
||||
restore-snapshot <snapshot .json/.yaml> ?[--pip-non-url] ?[--pip-non-local-url] ?[--pip-local-url]
|
||||
cli-only-mode [enable|disable]
|
||||
restore-dependencies
|
||||
clear
|
||||
|
||||
```
|
||||
|
||||
## How To Use?
|
||||
@ -53,7 +53,7 @@ OPTIONS:
|
||||
|
||||
`python cm-cli.py show installed` 와 같은 코맨드를 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||
[ ENABLED ] ComfyUI-Manager (author: Dr.Lt.Data)
|
||||
@ -70,7 +70,7 @@ FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main
|
||||
`python cm-cli.py simple-show installed` 와 같은 코맨드를 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
||||
|
||||
```
|
||||
-= ComfyUI-Manager CLI (V2.21.1) =-
|
||||
-= ComfyUI-Manager CLI (V2.24) =-
|
||||
|
||||
FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main/custom-node-list.json
|
||||
ComfyUI-Manager
|
||||
@ -115,10 +115,14 @@ ComfyUI-Loopchain
|
||||
|
||||
|
||||
### 4. 스냅샷 관리 기능
|
||||
* `python cm-cli.py save-snapshot`: 현재의 snapshot을 저장합니다.
|
||||
* `python cm-cli.py restore-snapshot <snapshot>`: 지정된 snapshot으로 복구합니다.
|
||||
* `python cm-cli.py save-snapshot ?[--output <snapshot .json/.yaml>]`: 현재의 snapshot을 저장합니다.
|
||||
* --output 으로 임의의 경로에 .yaml 파일과 format으로 저장할 수 있습니다.
|
||||
* `python cm-cli.py restore-snapshot <snapshot .json/.yaml>`: 지정된 snapshot으로 복구합니다.
|
||||
* snapshot 경로에 파일이 존재하는 경우 해당 snapshot을 로드합니다.
|
||||
* snapshot 경로에 파일이 존재하지 않는 경우 묵시적으로, ComfyUI-Manager/snapshots 에 있다고 가정합니다.
|
||||
* `--pip-non-url`: PyPI 에 등록된 pip 패키지들에 대해서 복구를 수행
|
||||
* `--pip-non-local-url`: web URL에 등록된 pip 패키지들에 대해서 복구를 수행
|
||||
* `--pip-local-url`: local 경로를 지정하고 있는 pip 패키지들에 대해서 복구를 수행
|
||||
|
||||
|
||||
### 5. CLI only mode
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
108
git_helper.py
108
git_helper.py
@ -1,9 +1,13 @@
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
|
||||
import git
|
||||
import configparser
|
||||
import re
|
||||
import json
|
||||
import yaml
|
||||
from torchvision.datasets.utils import download_url
|
||||
from tqdm.auto import tqdm
|
||||
from git.remote import RemoteProgress
|
||||
@ -12,6 +16,12 @@ config_path = os.path.join(os.path.dirname(__file__), "config.ini")
|
||||
nodelist_path = os.path.join(os.path.dirname(__file__), "custom-node-list.json")
|
||||
working_directory = os.getcwd()
|
||||
|
||||
if os.path.basename(working_directory) != 'custom_nodes':
|
||||
print(f"WARN: This script should be executed in custom_nodes dir")
|
||||
print(f"DBG: INFO {working_directory}")
|
||||
print(f"DBG: INFO {sys.argv}")
|
||||
# exit(-1)
|
||||
|
||||
|
||||
class GitProgress(RemoteProgress):
|
||||
def __init__(self):
|
||||
@ -132,7 +142,7 @@ def gitpull(path):
|
||||
|
||||
|
||||
def checkout_comfyui_hash(target_hash):
|
||||
repo_path = os.path.join(working_directory, '..') # ComfyUI dir
|
||||
repo_path = os.path.abspath(os.path.join(working_directory, '..')) # ComfyUI dir
|
||||
|
||||
repo = git.Repo(repo_path)
|
||||
commit_hash = repo.head.commit.hexsha
|
||||
@ -278,8 +288,21 @@ def apply_snapshot(target):
|
||||
try:
|
||||
path = os.path.join(os.path.dirname(__file__), 'snapshots', f"{target}")
|
||||
if os.path.exists(path):
|
||||
with open(path, 'r', encoding="UTF-8") as json_file:
|
||||
info = json.load(json_file)
|
||||
if not target.endswith('.json') and not target.endswith('.yaml'):
|
||||
print(f"Snapshot file not found: `{path}`")
|
||||
print("APPLY SNAPSHOT: False")
|
||||
return None
|
||||
|
||||
with open(path, 'r', encoding="UTF-8") as snapshot_file:
|
||||
if target.endswith('.json'):
|
||||
info = json.load(snapshot_file)
|
||||
elif target.endswith('.yaml'):
|
||||
info = yaml.load(snapshot_file, Loader=yaml.SafeLoader)
|
||||
info = info['custom_nodes']
|
||||
else:
|
||||
# impossible case
|
||||
print("APPLY SNAPSHOT: False")
|
||||
return None
|
||||
|
||||
comfyui_hash = info['comfyui']
|
||||
git_custom_node_infos = info['git_custom_nodes']
|
||||
@ -290,14 +313,81 @@ def apply_snapshot(target):
|
||||
invalidate_custom_node_file(file_custom_node_infos)
|
||||
|
||||
print("APPLY SNAPSHOT: True")
|
||||
return
|
||||
if 'pips' in info:
|
||||
return info['pips']
|
||||
else:
|
||||
return None
|
||||
|
||||
print(f"Snapshot file not found: `{path}`")
|
||||
print("APPLY SNAPSHOT: False")
|
||||
|
||||
return None
|
||||
except Exception as e:
|
||||
print(e)
|
||||
traceback.print_exc()
|
||||
print("APPLY SNAPSHOT: False")
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def restore_pip_snapshot(pips, options):
|
||||
non_url = []
|
||||
local_url = []
|
||||
non_local_url = []
|
||||
for k, v in pips.items():
|
||||
if v == "":
|
||||
non_url.append(k)
|
||||
else:
|
||||
if v.startswith('file:'):
|
||||
local_url.append(v)
|
||||
else:
|
||||
non_local_url.append(v)
|
||||
|
||||
failed = []
|
||||
if '--pip-non-url' in options:
|
||||
# try all at once
|
||||
res = 1
|
||||
try:
|
||||
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + non_url)
|
||||
except:
|
||||
pass
|
||||
|
||||
# fallback
|
||||
if res != 0:
|
||||
for x in non_url:
|
||||
res = 1
|
||||
try:
|
||||
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||
except:
|
||||
pass
|
||||
|
||||
if res != 0:
|
||||
failed.append(x)
|
||||
|
||||
if '--pip-non-local-url' in options:
|
||||
for x in non_local_url:
|
||||
res = 1
|
||||
try:
|
||||
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||
except:
|
||||
pass
|
||||
|
||||
if res != 0:
|
||||
failed.append(x)
|
||||
|
||||
if '--pip-local-url' in options:
|
||||
for x in local_url:
|
||||
res = 1
|
||||
try:
|
||||
res = subprocess.check_call([sys.executable, '-m', 'pip', 'install', x])
|
||||
except:
|
||||
pass
|
||||
|
||||
if res != 0:
|
||||
failed.append(x)
|
||||
|
||||
print(f"Installation failed for pip packages: {failed}")
|
||||
|
||||
|
||||
def setup_environment():
|
||||
config = configparser.ConfigParser()
|
||||
@ -319,7 +409,15 @@ try:
|
||||
elif sys.argv[1] == "--pull":
|
||||
gitpull(sys.argv[2])
|
||||
elif sys.argv[1] == "--apply-snapshot":
|
||||
apply_snapshot(sys.argv[2])
|
||||
options = set()
|
||||
for x in sys.argv:
|
||||
if x in ['--pip-non-url', '--pip-local-url', '--pip-non-local-url']:
|
||||
options.add(x)
|
||||
|
||||
pips = apply_snapshot(sys.argv[2])
|
||||
|
||||
if pips and len(options) > 0:
|
||||
restore_pip_snapshot(pips, options)
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
6258
github-stats.json
6258
github-stats.json
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,8 @@ import aiohttp
|
||||
import threading
|
||||
import json
|
||||
import time
|
||||
import yaml
|
||||
import zipfile
|
||||
|
||||
glob_path = os.path.join(os.path.dirname(__file__)) # ComfyUI-Manager/glob
|
||||
sys.path.append(glob_path)
|
||||
@ -21,7 +23,7 @@ sys.path.append(glob_path)
|
||||
import cm_global
|
||||
from manager_util import *
|
||||
|
||||
version = [2, 23]
|
||||
version = [2, 36]
|
||||
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
||||
|
||||
comfyui_manager_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
@ -179,8 +181,7 @@ class ManagerFuncs:
|
||||
print(f"[ComfyUI-Manager] Unexpected behavior: `{cmd}`")
|
||||
return 0
|
||||
|
||||
out = subprocess.check_call(cmd, cwd=cwd)
|
||||
print(out)
|
||||
subprocess.check_call(cmd, cwd=cwd)
|
||||
|
||||
return 0
|
||||
|
||||
@ -203,7 +204,8 @@ def write_config():
|
||||
'double_click_policy': get_config()['double_click_policy'],
|
||||
'windows_selector_event_loop_policy': get_config()['windows_selector_event_loop_policy'],
|
||||
'model_download_by_agent': get_config()['model_download_by_agent'],
|
||||
'downgrade_blacklist': get_config()['downgrade_blacklist']
|
||||
'downgrade_blacklist': get_config()['downgrade_blacklist'],
|
||||
'security_level': get_config()['security_level'],
|
||||
}
|
||||
with open(config_path, 'w') as configfile:
|
||||
config.write(configfile)
|
||||
@ -215,20 +217,30 @@ def read_config():
|
||||
config.read(config_path)
|
||||
default_conf = config['default']
|
||||
|
||||
# policy migration: disable_unsecure_features -> security_level
|
||||
if 'disable_unsecure_features' in default_conf:
|
||||
if default_conf['disable_unsecure_features'].lower() == 'true':
|
||||
security_level = 'strong'
|
||||
else:
|
||||
security_level = 'normal'
|
||||
else:
|
||||
security_level = default_conf['security_level'] if 'security_level' in default_conf else 'normal'
|
||||
|
||||
return {
|
||||
'preview_method': default_conf['preview_method'] if 'preview_method' in default_conf else manager_funcs.get_current_preview_method(),
|
||||
'badge_mode': default_conf['badge_mode'] if 'badge_mode' in default_conf else 'none',
|
||||
'git_exe': default_conf['git_exe'] if 'git_exe' in default_conf else '',
|
||||
'channel_url': default_conf['channel_url'] if 'channel_url' in default_conf else 'https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main',
|
||||
'share_option': default_conf['share_option'] if 'share_option' in default_conf else 'all',
|
||||
'bypass_ssl': default_conf['bypass_ssl'] if 'bypass_ssl' in default_conf else False,
|
||||
'file_logging': default_conf['file_logging'] if 'file_logging' in default_conf else True,
|
||||
'bypass_ssl': default_conf['bypass_ssl'].lower() == 'true' if 'bypass_ssl' in default_conf else False,
|
||||
'file_logging': default_conf['file_logging'].lower() == 'true' if 'file_logging' in default_conf else True,
|
||||
'default_ui': default_conf['default_ui'] if 'default_ui' in default_conf else 'none',
|
||||
'component_policy': default_conf['component_policy'] if 'component_policy' in default_conf else 'workflow',
|
||||
'double_click_policy': default_conf['double_click_policy'] if 'double_click_policy' in default_conf else 'copy-all',
|
||||
'windows_selector_event_loop_policy': default_conf['windows_selector_event_loop_policy'] if 'windows_selector_event_loop_policy' in default_conf else False,
|
||||
'model_download_by_agent': default_conf['model_download_by_agent'] if 'model_download_by_agent' in default_conf else False,
|
||||
'windows_selector_event_loop_policy': default_conf['windows_selector_event_loop_policy'].lower() == 'true' if 'windows_selector_event_loop_policy' in default_conf else False,
|
||||
'model_download_by_agent': default_conf['model_download_by_agent'].lower() == 'true' if 'model_download_by_agent' in default_conf else False,
|
||||
'downgrade_blacklist': default_conf['downgrade_blacklist'] if 'downgrade_blacklist' in default_conf else '',
|
||||
'security_level': security_level
|
||||
}
|
||||
|
||||
except Exception:
|
||||
@ -245,7 +257,8 @@ def read_config():
|
||||
'double_click_policy': 'copy-all',
|
||||
'windows_selector_event_loop_policy': False,
|
||||
'model_download_by_agent': False,
|
||||
'downgrade_blacklist': ''
|
||||
'downgrade_blacklist': '',
|
||||
'security_level': 'normal',
|
||||
}
|
||||
|
||||
|
||||
@ -312,7 +325,7 @@ def __win_check_git_update(path, do_fetch=False, do_update=False):
|
||||
else:
|
||||
command = [sys.executable, git_script_path, "--check", path]
|
||||
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=custom_nodes_path)
|
||||
output, _ = process.communicate()
|
||||
output = output.decode('utf-8').strip()
|
||||
|
||||
@ -364,7 +377,7 @@ def __win_check_git_update(path, do_fetch=False, do_update=False):
|
||||
|
||||
def __win_check_git_pull(path):
|
||||
command = [sys.executable, git_script_path, "--pull", path]
|
||||
process = subprocess.Popen(command)
|
||||
process = subprocess.Popen(command, cwd=custom_nodes_path)
|
||||
process.wait()
|
||||
|
||||
|
||||
@ -383,7 +396,7 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
|
||||
package_name = remap_pip_package(line.strip())
|
||||
if package_name and not package_name.startswith('#'):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
if package_name.strip() != "":
|
||||
if package_name.strip() != "" and not package_name.startswith('#'):
|
||||
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
||||
|
||||
if os.path.exists(install_script_path):
|
||||
@ -513,7 +526,7 @@ def gitclone_install(files, instant_execution=False, msg_prefix=''):
|
||||
|
||||
# Clone the repository from the remote URL
|
||||
if not instant_execution and platform.system() == 'Windows':
|
||||
res = manager_funcs.run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url])
|
||||
res = manager_funcs.run_script([sys.executable, git_script_path, "--clone", custom_nodes_path, url], cwd=custom_nodes_path)
|
||||
if res != 0:
|
||||
return False
|
||||
else:
|
||||
@ -563,7 +576,7 @@ def git_pull(path):
|
||||
|
||||
async def get_data(uri, silent=False):
|
||||
if not silent:
|
||||
print(f"FETCH DATA from: {uri}")
|
||||
print(f"FETCH DATA from: {uri}", end="")
|
||||
|
||||
if uri.startswith("http"):
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
@ -575,6 +588,8 @@ async def get_data(uri, silent=False):
|
||||
json_text = f.read()
|
||||
|
||||
json_obj = json.loads(json_text)
|
||||
if not silent:
|
||||
print(f" [DONE]")
|
||||
return json_obj
|
||||
|
||||
|
||||
@ -598,6 +613,9 @@ def is_file_created_within_one_day(file_path):
|
||||
|
||||
|
||||
async def get_data_by_mode(mode, filename, channel_url=None):
|
||||
if channel_url in get_channel_dict():
|
||||
channel_url = get_channel_dict()[channel_url]
|
||||
|
||||
try:
|
||||
if mode == "local":
|
||||
uri = os.path.join(comfyui_manager_path, filename)
|
||||
@ -854,6 +872,7 @@ def update_path(repo_path, instant_execution=False):
|
||||
else:
|
||||
return "skipped"
|
||||
|
||||
|
||||
def lookup_customnode_by_url(data, target):
|
||||
for x in data['custom_nodes']:
|
||||
if target in x['files']:
|
||||
@ -868,6 +887,17 @@ def lookup_customnode_by_url(data, target):
|
||||
return None
|
||||
|
||||
|
||||
def simple_check_custom_node(url):
|
||||
dir_name = os.path.splitext(os.path.basename(url))[0].replace(".git", "")
|
||||
dir_path = os.path.join(custom_nodes_path, dir_name)
|
||||
if os.path.exists(dir_path):
|
||||
return 'installed'
|
||||
elif os.path.exists(dir_path+'.disabled'):
|
||||
return 'disabled'
|
||||
|
||||
return 'not-installed'
|
||||
|
||||
|
||||
def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do_update=False):
|
||||
item['installed'] = 'None'
|
||||
|
||||
@ -926,11 +956,28 @@ def check_a_custom_node_installed(item, do_fetch=False, do_update_check=True, do
|
||||
item['installed'] = 'False'
|
||||
|
||||
|
||||
def get_installed_pip_packages():
|
||||
# extract pip package infos
|
||||
pips = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'], text=True).split('\n')
|
||||
|
||||
res = {}
|
||||
for x in pips:
|
||||
if x.strip() == "":
|
||||
continue
|
||||
|
||||
if ' @ ' in x:
|
||||
spec_url = x.split(' @ ')
|
||||
res[spec_url[0]] = spec_url[1]
|
||||
else:
|
||||
res[x] = ""
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_current_snapshot():
|
||||
# Get ComfyUI hash
|
||||
repo_path = comfy_path
|
||||
|
||||
print(f"comfy_path: {comfy_path}")
|
||||
if not os.path.exists(os.path.join(repo_path, '.git')):
|
||||
print(f"ComfyUI update fail: The installed ComfyUI does not have a Git repository.")
|
||||
return {}
|
||||
@ -975,22 +1022,179 @@ def get_current_snapshot():
|
||||
|
||||
file_custom_nodes.append(item)
|
||||
|
||||
pip_packages = get_installed_pip_packages()
|
||||
|
||||
return {
|
||||
'comfyui': comfyui_commit_hash,
|
||||
'git_custom_nodes': git_custom_nodes,
|
||||
'file_custom_nodes': file_custom_nodes,
|
||||
'pips': pip_packages,
|
||||
}
|
||||
|
||||
|
||||
def save_snapshot_with_postfix(postfix):
|
||||
now = datetime.now()
|
||||
def save_snapshot_with_postfix(postfix, path=None):
|
||||
if path is None:
|
||||
now = datetime.now()
|
||||
|
||||
date_time_format = now.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
file_name = f"{date_time_format}_{postfix}"
|
||||
date_time_format = now.strftime("%Y-%m-%d_%H-%M-%S")
|
||||
file_name = f"{date_time_format}_{postfix}"
|
||||
|
||||
path = os.path.join(comfyui_manager_path, 'snapshots', f"{file_name}.json")
|
||||
with open(path, "w") as json_file:
|
||||
json.dump(get_current_snapshot(), json_file, indent=4)
|
||||
path = os.path.join(comfyui_manager_path, 'snapshots', f"{file_name}.json")
|
||||
else:
|
||||
file_name = path.replace('\\', '/').split('/')[-1]
|
||||
file_name = file_name.split('.')[-2]
|
||||
|
||||
return file_name+'.json'
|
||||
snapshot = get_current_snapshot()
|
||||
if path.endswith('.json'):
|
||||
with open(path, "w") as json_file:
|
||||
json.dump(snapshot, json_file, indent=4)
|
||||
|
||||
return file_name + '.json'
|
||||
|
||||
elif path.endswith('.yaml'):
|
||||
with open(path, "w") as yaml_file:
|
||||
snapshot = {'custom_nodes': snapshot}
|
||||
yaml.dump(snapshot, yaml_file, allow_unicode=True)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
async def extract_nodes_from_workflow(filepath, mode='local', channel_url='default'):
|
||||
# prepare json data
|
||||
workflow = None
|
||||
if filepath.endswith('.json'):
|
||||
with open(filepath, "r", encoding="UTF-8", errors="ignore") as json_file:
|
||||
try:
|
||||
workflow = json.load(json_file)
|
||||
except:
|
||||
print(f"Invalid workflow file: {filepath}")
|
||||
exit(-1)
|
||||
|
||||
elif filepath.endswith('.png'):
|
||||
from PIL import Image
|
||||
with Image.open(filepath) as img:
|
||||
if 'workflow' not in img.info:
|
||||
print(f"The specified .png file doesn't have a workflow: {filepath}")
|
||||
exit(-1)
|
||||
else:
|
||||
try:
|
||||
workflow = json.loads(img.info['workflow'])
|
||||
except:
|
||||
print(f"This is not a valid .png file containing a ComfyUI workflow: {filepath}")
|
||||
exit(-1)
|
||||
|
||||
if workflow is None:
|
||||
print(f"Invalid workflow file: {filepath}")
|
||||
exit(-1)
|
||||
|
||||
# extract nodes
|
||||
used_nodes = set()
|
||||
|
||||
def extract_nodes(sub_workflow):
|
||||
for x in sub_workflow['nodes']:
|
||||
node_name = x.get('type')
|
||||
|
||||
# skip virtual nodes
|
||||
if node_name in ['Reroute', 'Note']:
|
||||
continue
|
||||
|
||||
if node_name is not None and not node_name.startswith('workflow/'):
|
||||
used_nodes.add(node_name)
|
||||
|
||||
if 'nodes' in workflow:
|
||||
extract_nodes(workflow)
|
||||
|
||||
if 'extra' in workflow:
|
||||
if 'groupNodes' in workflow['extra']:
|
||||
for x in workflow['extra']['groupNodes'].values():
|
||||
extract_nodes(x)
|
||||
|
||||
# lookup dependent custom nodes
|
||||
ext_map = await get_data_by_mode(mode, 'extension-node-map.json', channel_url)
|
||||
|
||||
rext_map = {}
|
||||
preemption_map = {}
|
||||
patterns = []
|
||||
for k, v in ext_map.items():
|
||||
if k == 'https://github.com/comfyanonymous/ComfyUI':
|
||||
for x in v[0]:
|
||||
if x not in preemption_map:
|
||||
preemption_map[x] = []
|
||||
|
||||
preemption_map[x] = k
|
||||
continue
|
||||
|
||||
for x in v[0]:
|
||||
if x not in rext_map:
|
||||
rext_map[x] = []
|
||||
|
||||
rext_map[x].append(k)
|
||||
|
||||
if 'preemptions' in v[1]:
|
||||
for x in v[1]['preemptions']:
|
||||
if x not in preemption_map:
|
||||
preemption_map[x] = []
|
||||
|
||||
preemption_map[x] = k
|
||||
|
||||
if 'nodename_pattern' in v[1]:
|
||||
patterns.append((v[1]['nodename_pattern'], k))
|
||||
|
||||
# identify used extensions
|
||||
used_exts = set()
|
||||
unknown_nodes = set()
|
||||
|
||||
for node_name in used_nodes:
|
||||
ext = preemption_map.get(node_name)
|
||||
|
||||
if ext is None:
|
||||
ext = rext_map.get(node_name)
|
||||
if ext is not None:
|
||||
ext = ext[0]
|
||||
|
||||
if ext is None:
|
||||
for pat_ext in patterns:
|
||||
if re.search(pat_ext[0], node_name):
|
||||
ext = pat_ext[1]
|
||||
break
|
||||
|
||||
if ext == 'https://github.com/comfyanonymous/ComfyUI':
|
||||
pass
|
||||
elif ext is not None:
|
||||
if 'Fooocus' in ext:
|
||||
print(f">> {node_name}")
|
||||
|
||||
used_exts.add(ext)
|
||||
else:
|
||||
unknown_nodes.add(node_name)
|
||||
|
||||
return used_exts, unknown_nodes
|
||||
|
||||
|
||||
def unzip(model_path):
|
||||
if not os.path.exists(model_path):
|
||||
print(f"[ComfyUI-Manager] unzip: File not found: {model_path}")
|
||||
return False
|
||||
|
||||
base_dir = os.path.dirname(model_path)
|
||||
filename = os.path.basename(model_path)
|
||||
target_dir = os.path.join(base_dir, filename[:-4])
|
||||
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
|
||||
with zipfile.ZipFile(model_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(target_dir)
|
||||
|
||||
# Check if there's only one directory inside the target directory
|
||||
contents = os.listdir(target_dir)
|
||||
if len(contents) == 1 and os.path.isdir(os.path.join(target_dir, contents[0])):
|
||||
nested_dir = os.path.join(target_dir, contents[0])
|
||||
# Move each file and sub-directory in the nested directory up to the target directory
|
||||
for item in os.listdir(nested_dir):
|
||||
shutil.move(os.path.join(nested_dir, item), os.path.join(target_dir, item))
|
||||
# Remove the now empty nested directory
|
||||
os.rmdir(nested_dir)
|
||||
|
||||
os.remove(model_path)
|
||||
return True
|
||||
|
||||
|
||||
@ -42,6 +42,36 @@ from comfy.cli_args import args
|
||||
import latent_preview
|
||||
|
||||
|
||||
is_local_mode = args.listen.startswith('127.')
|
||||
|
||||
|
||||
def is_allowed_security_level(level):
|
||||
if level == 'high':
|
||||
if is_local_mode:
|
||||
return core.get_config()['security_level'].lower() in ['weak', 'normal']
|
||||
else:
|
||||
return core.get_config()['security_level'].lower() == 'weak'
|
||||
elif level == 'middle':
|
||||
return core.get_config()['security_level'].lower() in ['weak', 'normal']
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
async def get_risky_level(files):
|
||||
json_data1 = await core.get_data_by_mode('local', 'custom-node-list.json')
|
||||
json_data2 = await core.get_data_by_mode('cache', 'custom-node-list.json', channel_url='https://github.com/ltdrdata/ComfyUI-Manager/raw/main/custom-node-list.json')
|
||||
|
||||
all_urls = set()
|
||||
for x in json_data1['custom_nodes'] + json_data2['custom_nodes']:
|
||||
all_urls.update(x['files'])
|
||||
|
||||
for x in files:
|
||||
if x not in all_urls:
|
||||
return "high"
|
||||
|
||||
return "middle"
|
||||
|
||||
|
||||
class ManagerFuncsInComfyUI(core.ManagerFuncs):
|
||||
def get_current_preview_method(self):
|
||||
if args.preview_method == latent_preview.LatentPreviewMethod.Auto:
|
||||
@ -171,16 +201,13 @@ def print_comfyui_version():
|
||||
print_comfyui_version()
|
||||
|
||||
|
||||
async def populate_github_stats(json_obj, filename, silent=False):
|
||||
uri = os.path.join(core.comfyui_manager_path, filename)
|
||||
with open(uri, "r", encoding='utf-8') as f:
|
||||
github_stats = json.load(f)
|
||||
async def populate_github_stats(json_obj, json_obj_github):
|
||||
if 'custom_nodes' in json_obj:
|
||||
for i, node in enumerate(json_obj['custom_nodes']):
|
||||
url = node['reference']
|
||||
if url in github_stats:
|
||||
json_obj['custom_nodes'][i]['stars'] = github_stats[url]['stars']
|
||||
json_obj['custom_nodes'][i]['last_update'] = github_stats[url]['last_update']
|
||||
if url in json_obj_github:
|
||||
json_obj['custom_nodes'][i]['stars'] = json_obj_github[url]['stars']
|
||||
json_obj['custom_nodes'][i]['last_update'] = json_obj_github[url]['last_update']
|
||||
else:
|
||||
json_obj['custom_nodes'][i]['stars'] = -1
|
||||
json_obj['custom_nodes'][i]['last_update'] = -1
|
||||
@ -358,6 +385,10 @@ async def fetch_updates(request):
|
||||
|
||||
@PromptServer.instance.routes.get("/customnode/update_all")
|
||||
async def update_all(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
core.save_snapshot_with_postfix('autosave')
|
||||
|
||||
@ -439,7 +470,8 @@ async def fetch_customnode_list(request):
|
||||
channel = core.get_config()['channel_url']
|
||||
|
||||
json_obj = await core.get_data_by_mode(request.rel_url.query["mode"], 'custom-node-list.json')
|
||||
json_obj = await populate_github_stats(json_obj, "github-stats.json")
|
||||
json_obj_github = await core.get_data_by_mode(request.rel_url.query["mode"], 'github-stats.json', 'default')
|
||||
json_obj = await populate_github_stats(json_obj, json_obj_github)
|
||||
|
||||
def is_ignored_notice(code):
|
||||
if code is not None and code.startswith('#NOTICE_'):
|
||||
@ -508,7 +540,12 @@ def check_model_installed(json_obj):
|
||||
item['installed'] = 'None'
|
||||
|
||||
if model_path is not None:
|
||||
if os.path.exists(model_path):
|
||||
if model_path.endswith('.zip'):
|
||||
if os.path.exists(model_path[:-4]):
|
||||
item['installed'] = 'True'
|
||||
else:
|
||||
item['installed'] = 'False'
|
||||
elif os.path.exists(model_path):
|
||||
item['installed'] = 'True'
|
||||
else:
|
||||
item['installed'] = 'False'
|
||||
@ -546,6 +583,10 @@ async def get_snapshot_list(request):
|
||||
|
||||
@PromptServer.instance.routes.get("/snapshot/remove")
|
||||
async def remove_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
target = request.rel_url.query["target"]
|
||||
|
||||
@ -560,6 +601,10 @@ async def remove_snapshot(request):
|
||||
|
||||
@PromptServer.instance.routes.get("/snapshot/restore")
|
||||
async def remove_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
target = request.rel_url.query["target"]
|
||||
|
||||
@ -724,8 +769,17 @@ def copy_set_active(files, is_disable, js_path_name='.'):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/install")
|
||||
async def install_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
risky_level = await get_risky_level(json_data['files'])
|
||||
if not is_allowed_security_level(risky_level):
|
||||
print(f"ERROR: This installation is not allowed in this security_level. Please contact the administrator.")
|
||||
return web.Response(status=404)
|
||||
|
||||
install_type = json_data['install_type']
|
||||
|
||||
print(f"Install custom node '{json_data['title']}'")
|
||||
@ -762,6 +816,10 @@ async def install_custom_node(request):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/fix")
|
||||
async def fix_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
install_type = json_data['install_type']
|
||||
@ -792,6 +850,10 @@ async def fix_custom_node(request):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/install/git_url")
|
||||
async def install_custom_node_git_url(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this feature, you must set '--listen' to a local IP and set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
url = await request.text()
|
||||
res = core.gitclone_install([url])
|
||||
|
||||
@ -804,6 +866,10 @@ async def install_custom_node_git_url(request):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/install/pip")
|
||||
async def install_custom_node_git_url(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this feature, you must set '--listen' to a local IP and set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
packages = await request.text()
|
||||
core.pip_install(packages.split(' '))
|
||||
|
||||
@ -812,6 +878,10 @@ async def install_custom_node_git_url(request):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/uninstall")
|
||||
async def uninstall_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
install_type = json_data['install_type']
|
||||
@ -836,6 +906,10 @@ async def uninstall_custom_node(request):
|
||||
|
||||
@PromptServer.instance.routes.post("/customnode/update")
|
||||
async def update_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
install_type = json_data['install_type']
|
||||
@ -872,7 +946,6 @@ async def update_comfyui(request):
|
||||
return web.Response(status=200)
|
||||
except Exception as e:
|
||||
print(f"ComfyUI update fail: {e}", file=sys.stderr)
|
||||
pass
|
||||
|
||||
return web.Response(status=400)
|
||||
|
||||
@ -916,10 +989,17 @@ async def install_model(request):
|
||||
model_url.startswith('https://github.com') or model_url.startswith('https://huggingface.co') or model_url.startswith('https://heibox.uni-heidelberg.de')):
|
||||
model_dir = get_model_dir(json_data)
|
||||
download_url(model_url, model_dir, filename=json_data['filename'])
|
||||
if model_path.endswith('.zip'):
|
||||
res = core.unzip(model_path)
|
||||
else:
|
||||
res = True
|
||||
|
||||
return web.json_response({}, content_type='application/json')
|
||||
if res:
|
||||
return web.json_response({}, content_type='application/json')
|
||||
else:
|
||||
res = download_url_with_agent(model_url, model_path)
|
||||
if res and model_path.endswith('.zip'):
|
||||
res = core.unzip(model_path)
|
||||
else:
|
||||
print(f"Model installation error: invalid model type - {json_data['type']}")
|
||||
|
||||
@ -927,7 +1007,6 @@ async def install_model(request):
|
||||
return web.json_response({}, content_type='application/json')
|
||||
except Exception as e:
|
||||
print(f"[ERROR] {e}", file=sys.stderr)
|
||||
pass
|
||||
|
||||
return web.Response(status=400)
|
||||
|
||||
@ -945,6 +1024,10 @@ manager_terminal_hook = ManagerTerminalHook()
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/terminal")
|
||||
async def terminal_mode(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this action, a security_level of `weak` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
if "mode" in request.rel_url.query:
|
||||
if request.rel_url.query['mode'] == 'true':
|
||||
sys.__comfyui_manager_terminal_hook.add_hook('cm', manager_terminal_hook)
|
||||
@ -1068,20 +1151,27 @@ async def get_notice(request):
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/reboot")
|
||||
def restart(self):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
sys.stdout.close_log()
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
if '__COMFY_CLI_SESSION__' in os.environ:
|
||||
with open(os.path.join(os.environ['__COMFY_CLI_SESSION__'], '.reboot'), 'w') as file:
|
||||
with open(os.path.join(os.environ['__COMFY_CLI_SESSION__'] + '.reboot'), 'w') as file:
|
||||
pass
|
||||
|
||||
print(f"\nRestarting...\n\n")
|
||||
exit(0)
|
||||
|
||||
print(f"\nRestarting... [Legacy Mode]\n\n")
|
||||
return os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
if sys.platform.startswith('win32'):
|
||||
return os.execv(sys.executable, ['"' + sys.executable + '"', '"' + sys.argv[0] + '"'] + sys.argv[1:])
|
||||
else:
|
||||
return os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
|
||||
def sanitize_filename(input_string):
|
||||
@ -1569,8 +1659,9 @@ async def default_cache_update():
|
||||
b = get_cache("extension-node-map.json")
|
||||
c = get_cache("model-list.json")
|
||||
d = get_cache("alter-list.json")
|
||||
e = get_cache("github-stats.json")
|
||||
|
||||
await asyncio.gather(a, b, c, d)
|
||||
await asyncio.gather(a, b, c, d, e)
|
||||
|
||||
|
||||
threading.Thread(target=lambda: asyncio.run(default_cache_update())).start()
|
||||
|
||||
@ -56,7 +56,7 @@ export class AlternativesInstaller extends ComfyDialog {
|
||||
let data2 = data1.custom_node;
|
||||
|
||||
if(!data2)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
let content = data1.tags.toLowerCase() + data1.description.toLowerCase() + data2.author.toLowerCase() + data2.description.toLowerCase() + data2.title.toLowerCase();
|
||||
|
||||
|
||||
11
js/cm-api.js
11
js/cm-api.js
@ -41,9 +41,18 @@ async function tryInstallCustomNode(event) {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(event.detail.target)
|
||||
});
|
||||
|
||||
if(response.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
api.fetchApi("/manager/reboot");
|
||||
let response = await api.fetchApi("/manager/reboot");
|
||||
if(response.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return false;
|
||||
}
|
||||
|
||||
await sleep(300);
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import { CustomNodesInstaller } from "./custom-nodes-downloader.js";
|
||||
import { AlternativesInstaller } from "./a1111-alter-downloader.js";
|
||||
import { SnapshotManager } from "./snapshot.js";
|
||||
import { ModelInstaller } from "./model-downloader.js";
|
||||
import { manager_instance, setManagerInstance, install_via_git_url, install_pip, rebootAPI, free_models } from "./common.js";
|
||||
import { manager_instance, setManagerInstance, install_via_git_url, install_pip, rebootAPI, free_models, show_message } from "./common.js";
|
||||
import { ComponentBuilderDialog, load_components, set_component_policy, getPureName } from "./components-manager.js";
|
||||
import { set_double_click_policy } from "./node_fixer.js";
|
||||
|
||||
@ -520,25 +520,21 @@ async function updateComfyUI() {
|
||||
const response = await api.fetchApi('/comfyui_manager/update_comfyui');
|
||||
|
||||
if (response.status == 400) {
|
||||
app.ui.dialog.show('Failed to update ComfyUI.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('Failed to update ComfyUI.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.status == 201) {
|
||||
app.ui.dialog.show('ComfyUI has been successfully updated.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('ComfyUI has been successfully updated.');
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show('ComfyUI is already up to date with the latest version.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('ComfyUI is already up to date with the latest version.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (exception) {
|
||||
app.ui.dialog.show(`Failed to update ComfyUI / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Failed to update ComfyUI / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -560,13 +556,12 @@ async function fetchUpdates(update_check_checkbox) {
|
||||
const response = await api.fetchApi(`/customnode/fetch_updates?mode=${mode}`);
|
||||
|
||||
if (response.status != 200 && response.status != 201) {
|
||||
app.ui.dialog.show('Failed to fetch updates.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('Failed to fetch updates.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.status == 201) {
|
||||
app.ui.dialog.show("There is an updated extension available.<BR><BR><P><B>NOTE:<BR>Fetch Updates is not an update.<BR>Please update from <button id='cm-install-customnodes-button'>Install Custom Nodes</button> </B></P>");
|
||||
show_message("There is an updated extension available.<BR><BR><P><B>NOTE:<BR>Fetch Updates is not an update.<BR>Please update from <button id='cm-install-customnodes-button'>Install Custom Nodes</button> </B></P>");
|
||||
|
||||
const button = document.getElementById('cm-install-customnodes-button');
|
||||
button.addEventListener("click",
|
||||
@ -580,19 +575,16 @@ async function fetchUpdates(update_check_checkbox) {
|
||||
}
|
||||
);
|
||||
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
update_check_checkbox.checked = false;
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show('All extensions are already up-to-date with the latest versions.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('All extensions are already up-to-date with the latest versions.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (exception) {
|
||||
app.ui.dialog.show(`Failed to update custom nodes / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Failed to update custom nodes / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -615,11 +607,16 @@ async function updateAll(update_check_checkbox, manager_dialog) {
|
||||
const response1 = await api.fetchApi('/comfyui_manager/update_comfyui');
|
||||
const response2 = await api.fetchApi(`/customnode/update_all?mode=${mode}`);
|
||||
|
||||
if (response1.status != 200 && response2.status != 201) {
|
||||
app.ui.dialog.show('Failed to update ComfyUI or several extensions.<BR><BR>See terminal log.<BR>');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
if (response2.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response1.status == 400 || response2.status == 400) {
|
||||
show_message('Failed to update ComfyUI or several extensions.<BR><BR>See terminal log.<BR>');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(response1.status == 201 || response2.status == 201) {
|
||||
const update_info = await response2.json();
|
||||
|
||||
@ -633,7 +630,7 @@ async function updateAll(update_check_checkbox, manager_dialog) {
|
||||
updated_list = "<BR>UPDATED: "+update_info.updated.join(", ");
|
||||
}
|
||||
|
||||
app.ui.dialog.show(
|
||||
show_message(
|
||||
"ComfyUI and all extensions have been updated to the latest version.<BR>To apply the updated custom node, please <button class='cm-small-button' id='cm-reboot-button5'>RESTART</button> ComfyUI. And refresh browser.<BR>"
|
||||
+failed_list
|
||||
+updated_list
|
||||
@ -646,19 +643,15 @@ async function updateAll(update_check_checkbox, manager_dialog) {
|
||||
manager_dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show('ComfyUI and all extensions are already up-to-date with the latest versions.');
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message('ComfyUI and all extensions are already up-to-date with the latest versions.');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (exception) {
|
||||
app.ui.dialog.show(`Failed to update ComfyUI or several extensions / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Failed to update ComfyUI or several extensions / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -925,7 +918,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
});
|
||||
|
||||
let dbl_click_policy_combo = document.createElement("select");
|
||||
dbl_click_policy_combo.setAttribute("title", "When loading the workflow, configure which version of the component to use.");
|
||||
dbl_click_policy_combo.setAttribute("title", "Sets the behavior when you double-click the title area of a node.");
|
||||
dbl_click_policy_combo.className = "cm-menu-combo";
|
||||
dbl_click_policy_combo.appendChild($el('option', { value: 'none', text: 'Double-Click: None' }, []));
|
||||
dbl_click_policy_combo.appendChild($el('option', { value: 'copy-all', text: 'Double-Click: Copy All Connections' }, []));
|
||||
|
||||
@ -481,10 +481,6 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
if (this.uploadImagesInput.files.length === 0) {
|
||||
throw new Error("No thumbnail uploaded");
|
||||
}
|
||||
|
||||
if (this.uploadImagesInput.files.length === 0) {
|
||||
throw new Error("No thumbnail uploaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
59
js/common.js
59
js/common.js
@ -1,6 +1,11 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { api } from "../../scripts/api.js";
|
||||
|
||||
export function show_message(msg) {
|
||||
app.ui.dialog.show(msg);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
|
||||
export async function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
@ -47,6 +52,20 @@ export async function install_checked_custom_node(grid_rows, target_i, caller, m
|
||||
body: JSON.stringify(target)
|
||||
});
|
||||
|
||||
if(response.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
caller.updateMessage('');
|
||||
await caller.invalidateControl();
|
||||
return;
|
||||
}
|
||||
|
||||
if(response.status == 404) {
|
||||
show_message('With the current security level configuration, only custom nodes from the <B>"default channel"</B> can be installed.');
|
||||
caller.updateMessage('');
|
||||
await caller.invalidateControl();
|
||||
return;
|
||||
}
|
||||
|
||||
if(response.status == 400) {
|
||||
show_message(`${mode} failed: ${target.title}`);
|
||||
continue;
|
||||
@ -94,19 +113,21 @@ export async function install_pip(packages) {
|
||||
body: packages,
|
||||
});
|
||||
|
||||
if(res.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return;
|
||||
}
|
||||
|
||||
if(res.status == 200) {
|
||||
app.ui.dialog.show(`PIP package installation is processed.<br>To apply the pip packages, please click the <button id='cm-reboot-button3'><font size='3px'>RESTART</font></button> button in ComfyUI.`);
|
||||
show_message(`PIP package installation is processed.<br>To apply the pip packages, please click the <button id='cm-reboot-button3'><font size='3px'>RESTART</font></button> button in ComfyUI.`);
|
||||
|
||||
const rebootButton = document.getElementById('cm-reboot-button3');
|
||||
const self = this;
|
||||
|
||||
rebootButton.addEventListener("click", rebootAPI);
|
||||
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show(`Failed to install '${packages}'<BR>See terminal log.`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Failed to install '${packages}'<BR>See terminal log.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,21 +137,24 @@ export async function install_via_git_url(url, manager_dialog) {
|
||||
}
|
||||
|
||||
if(!isValidURL(url)) {
|
||||
app.ui.dialog.show(`Invalid Git url '${url}'`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Invalid Git url '${url}'`);
|
||||
return;
|
||||
}
|
||||
|
||||
app.ui.dialog.show(`Wait...<BR><BR>Installing '${url}'`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Wait...<BR><BR>Installing '${url}'`);
|
||||
|
||||
const res = await api.fetchApi("/customnode/install/git_url", {
|
||||
method: "POST",
|
||||
body: url,
|
||||
});
|
||||
|
||||
if(res.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return;
|
||||
}
|
||||
|
||||
if(res.status == 200) {
|
||||
app.ui.dialog.show(`'${url}' is installed<BR>To apply the installed custom node, please <button id='cm-reboot-button4'><font size='3px'>RESTART</font></button> ComfyUI.`);
|
||||
show_message(`'${url}' is installed<BR>To apply the installed custom node, please <button id='cm-reboot-button4'><font size='3px'>RESTART</font></button> ComfyUI.`);
|
||||
|
||||
const rebootButton = document.getElementById('cm-reboot-button4');
|
||||
const self = this;
|
||||
@ -141,12 +165,9 @@ export async function install_via_git_url(url, manager_dialog) {
|
||||
manager_dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show(`Failed to install '${url}'<BR>See terminal log.`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Failed to install '${url}'<BR>See terminal log.`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,15 +179,9 @@ export async function free_models() {
|
||||
});
|
||||
|
||||
if(res.status == 200) {
|
||||
app.ui.dialog.show('Models have been unloaded.')
|
||||
show_message('Models have been unloaded.')
|
||||
}
|
||||
else {
|
||||
app.ui.dialog.show('Unloading of models failed.<BR><BR>Installed ComfyUI may be an outdated version.')
|
||||
show_message('Unloading of models failed.<BR><BR>Installed ComfyUI may be an outdated version.')
|
||||
}
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
|
||||
export function show_message(msg) {
|
||||
app.ui.dialog.show(msg);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { api } from "../../scripts/api.js"
|
||||
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||
import { install_checked_custom_node, manager_instance, rebootAPI } from "./common.js";
|
||||
import { install_checked_custom_node, manager_instance, rebootAPI, show_message } from "./common.js";
|
||||
|
||||
async function install_model(target) {
|
||||
if(ModelInstaller.instance) {
|
||||
@ -20,8 +20,7 @@ async function install_model(target) {
|
||||
return true;
|
||||
}
|
||||
catch(exception) {
|
||||
app.ui.dialog.show(`Install failed: ${target.title} / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Install failed: ${target.title} / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -85,7 +84,7 @@ export class ModelInstaller extends ComfyDialog {
|
||||
let keyword = this.search_box.value.toLowerCase();
|
||||
for(let i in this.grid_rows) {
|
||||
let data = this.grid_rows[i].data;
|
||||
let content = data.name.toLowerCase() + data.type.toLowerCase() + data.base.toLowerCase() + data.description.toLowerCase();
|
||||
let content = data.name.toLowerCase() + data.type.toLowerCase() + data.base.toLowerCase() + data.filename.toLowerCase() + data.description.toLowerCase();
|
||||
|
||||
if(this.filter && this.filter != '*') {
|
||||
if(this.filter != data.installed) {
|
||||
|
||||
@ -1,24 +1,28 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
import { api } from "../../scripts/api.js"
|
||||
import { ComfyDialog, $el } from "../../scripts/ui.js";
|
||||
import { manager_instance, rebootAPI } from "./common.js";
|
||||
import { manager_instance, rebootAPI, show_message } from "./common.js";
|
||||
|
||||
|
||||
async function restore_snapshot(target) {
|
||||
if(SnapshotManager.instance) {
|
||||
try {
|
||||
const response = await api.fetchApi(`/snapshot/restore?target=${target}`, { cache: "no-store" });
|
||||
|
||||
if(response.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(response.status == 400) {
|
||||
app.ui.dialog.show(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
}
|
||||
|
||||
app.ui.dialog.close();
|
||||
return true;
|
||||
}
|
||||
catch(exception) {
|
||||
app.ui.dialog.show(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -32,17 +36,21 @@ async function remove_snapshot(target) {
|
||||
if(SnapshotManager.instance) {
|
||||
try {
|
||||
const response = await api.fetchApi(`/snapshot/remove?target=${target}`, { cache: "no-store" });
|
||||
|
||||
if(response.status == 403) {
|
||||
show_message('This action is not allowed with this security level configuration.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(response.status == 400) {
|
||||
app.ui.dialog.show(`Remove snapshot failed: ${target.title} / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Remove snapshot failed: ${target.title} / ${exception}`);
|
||||
}
|
||||
|
||||
app.ui.dialog.close();
|
||||
return true;
|
||||
}
|
||||
catch(exception) {
|
||||
app.ui.dialog.show(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Restore snapshot failed: ${target.title} / ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
@ -58,8 +66,7 @@ async function save_current_snapshot() {
|
||||
return true;
|
||||
}
|
||||
catch(exception) {
|
||||
app.ui.dialog.show(`Backup snapshot failed: ${exception}`);
|
||||
app.ui.dialog.element.style.zIndex = 10010;
|
||||
show_message(`Backup snapshot failed: ${exception}`);
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
|
||||
289
model-list.json
289
model-list.json
@ -2511,6 +2511,295 @@
|
||||
"reference": "https://huggingface.co/xinyu1205/recognize_anything_model",
|
||||
"filename": "tag2text_swin_14m.pth",
|
||||
"url": "https://huggingface.co/xinyu1205/recognize_anything_model/resolve/main/tag2text_swin_14m.pth"
|
||||
},
|
||||
{
|
||||
"name": "Zero123 3D object Model",
|
||||
"type": "Zero123",
|
||||
"base": "Zero123",
|
||||
"save_path": "checkpoints/zero123",
|
||||
"description": "model that been trained on 10M+ 3D objects from Objaverse-XL, used for generated rotated CamView",
|
||||
"reference": "https://objaverse.allenai.org/docs/zero123-xl/",
|
||||
"filename": "zero123-xl.ckpt",
|
||||
"url": "https://huggingface.co/kealiu/zero123-xl/resolve/main/zero123-xl.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "Zero123 3D object Model",
|
||||
"type": "Zero123",
|
||||
"base": "Zero123",
|
||||
"save_path": "checkpoints/zero123",
|
||||
"description": "Stable Zero123 is a model for view-conditioned image generation based on [a/Zero123](https://github.com/cvlab-columbia/zero123).",
|
||||
"reference": "https://huggingface.co/stabilityai/stable-zero123",
|
||||
"filename": "stable_zero123.ckpt",
|
||||
"url": "https://huggingface.co/stabilityai/stable-zero123/resolve/main/stable_zero123.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "Zero123 3D object Model",
|
||||
"type": "Zero123",
|
||||
"base": "Zero123",
|
||||
"save_path": "checkpoints/zero123",
|
||||
"description": "Zero123 original checkpoints in 105000 steps.",
|
||||
"reference": "https://huggingface.co/cvlab/zero123-weights",
|
||||
"filename": "zero123-105000.ckpt",
|
||||
"url": "https://huggingface.co/cvlab/zero123-weights/resolve/main/105000.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "Zero123 3D object Model",
|
||||
"type": "Zero123",
|
||||
"base": "Zero123",
|
||||
"save_path": "checkpoints/zero123",
|
||||
"description": "Zero123 original checkpoints in 165000 steps.",
|
||||
"reference": "https://huggingface.co/cvlab/zero123-weights",
|
||||
"filename": "zero123-165000.ckpt",
|
||||
"url": "https://huggingface.co/cvlab/zero123-weights/resolve/main/165000.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ip-adapter",
|
||||
"type": "instantid",
|
||||
"base": "SDXL",
|
||||
"save_path": "instantid/SDXL",
|
||||
"description": "ip-adapter model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "ip-adapter.bin",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ip-adapter.bin"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ControlNet",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/instantid",
|
||||
"description": "instantid controlnet model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ControlNetModel/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "MonsterMMORPG/insightface (for InstantID)",
|
||||
"type": "insightface",
|
||||
"base": "SDXL",
|
||||
"save_path": "insightface/models",
|
||||
"description": "MonsterMMORPG insightface model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/MonsterMMORPG/tools/tree/main",
|
||||
"filename": "antelopev2.zip",
|
||||
"url": "https://huggingface.co/MonsterMMORPG/tools/resolve/main/antelopev2.zip"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "The default relighting model, conditioned on text and foreground",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fc.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fbc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Relighting model conditioned with text, foreground, and background",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fbc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fbc.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fcon",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Same as iclight_sd15_fc.safetensors, but trained with offset noise",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fcon.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fcon.safetensors"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"name": "ID-Animator/animator.ckpt",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models",
|
||||
"description": "ID-Animator checkpoint",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "animator.ckpt",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/animator.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "ID-Animator/mm_sd_v15_v2.ckpt",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models/animatediff_models",
|
||||
"description": "AnimateDiff checkpoint for ID-Animator",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "mm_sd_v15_v2.ckpt",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/mm_sd_v15_v2.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "ID-Animator/image_encoder",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models/image_encoder",
|
||||
"description": "CLIP Image encoder for ID-Animator",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "model.safetensors",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/image_encoder/model.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "TencentARC/CustomNet",
|
||||
"type": "CustomNet",
|
||||
"base": "CustomNet",
|
||||
"save_path": "custom_nodes/ComfyUI_CustomNet/pretrain",
|
||||
"description": "CustomNet pretrained model for ComfyUI_CustomNet",
|
||||
"reference": "https://huggingface.co/TencentARC/CustomNet/tree/main",
|
||||
"filename": "customnet_v1.pt",
|
||||
"url": "https://huggingface.co/TencentARC/CustomNet/resolve/main/customnet_v1.pt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic v2 (fp16)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL",
|
||||
"description": "[2.5GB] Controlnet SDXL Tile model realistic version.",
|
||||
"reference": "https://huggingface.co/TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic",
|
||||
"filename": "TTPLANET_Controlnet_Tile_realistic_v2_fp16.safetensors",
|
||||
"url": "https://huggingface.co/TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic/resolve/main/TTPLANET_Controlnet_Tile_realistic_v2_fp16.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ViperYX/RGT_x2.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT",
|
||||
"description": "[180MB] RGT x2 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_x2.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT/RGT_x2.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_x3.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT",
|
||||
"description": "[180MB] RGT x3 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_x3.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT/RGT_x3.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_x4.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT",
|
||||
"description": "[180MB] RGT_S x4 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_x4.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT/RGT_x4.pth"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x2.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[135MB] RGT_S x2 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x2.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x2.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x3.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[136MB] RGT_S x3 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x3.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x3.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x4.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[136MB] RGT_S x4 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x4.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x4.pth"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Doubiiu/ToonCrafter model checkpoint",
|
||||
"type": "checkpoint",
|
||||
"base": "ToonCrafter",
|
||||
"save_path": "custom_nodes/ComfyUI-ToonCrafter/ToonCrafter/checkpoints/tooncrafter_512_interp_v1",
|
||||
"description": "[10.5GB] ToonCrafter checkpoint model for ComfyUI-ToonCrafter",
|
||||
"reference": "https://huggingface.co/Doubiiu/ToonCrafter/tree/main",
|
||||
"filename": "model.ckpt",
|
||||
"url": "https://huggingface.co/Doubiiu/ToonCrafter/resolve/main/model.ckpt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "xinsir/Controlnet-Scribble-Sdxl-1.0",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-scribble-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Scribble model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Canny-Sdxl-1.0 (V2)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-canny-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Canny model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-canny-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model_V2.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-canny-sdxl-1.0/resolve/main/diffusion_pytorch_model_V2.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Openpose-Sdxl-1.0",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-openpose-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Openpose model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Openpose-Sdxl-1.0 (Ver. twins)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-openpose-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Openpose model. (Ver. twins)",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model_twins.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0/resolve/main/diffusion_pytorch_model_twins.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/CControlnet-Scribble-Sdxl-1.0-Anime",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-scribble-sdxl-1.0-anime",
|
||||
"description": "[2.5GB] Controlnet SDXL Scribble model. (Ver. anime)",
|
||||
"reference": "https://huggingface.co/xinsir/anime-painter",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/anime-painter/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Kijai/ToonCrafter model checkpoint (interpolation fp16)",
|
||||
"type": "checkpoint",
|
||||
"base": "ToonCrafter",
|
||||
"save_path": "checkpoints/ToonCrafter",
|
||||
"description": "[5.25GB] ToonCrafter checkpoint model for ComfyUI-DynamiCrafterWrapper",
|
||||
"reference": "https://huggingface.co/Kijai/DynamiCrafter_pruned",
|
||||
"filename": "tooncrafter_512_interp-fp16.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/DynamiCrafter_pruned/resolve/main/tooncrafter_512_interp-fp16.safetensors"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -9,8 +9,407 @@
|
||||
"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": "AI2lab",
|
||||
"title": "comfyUI-tool-2lab",
|
||||
"id": "tool2lab",
|
||||
"reference": "https://github.com/AI2lab/comfyUI-tool-2lab",
|
||||
"files": [
|
||||
"https://github.com/AI2lab/comfyUI-tool-2lab"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "simple tool set for developing workflow and publish to web api server"
|
||||
},
|
||||
{
|
||||
"author": "pamparamm",
|
||||
"title": "ComfyUI-ppm",
|
||||
"id": "ppm",
|
||||
"reference": "https://github.com/pamparamm/ComfyUI-ppm",
|
||||
"files": [
|
||||
"https://github.com/pamparamm/ComfyUI-ppm"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Empty Latent Image (Aspect Ratio), Token Counter, Random Prompt Generator, StableCascade_AutoCompLatent, CLIPTextEncode, CLIPMicroConditioning, CLIPNegPip"
|
||||
},
|
||||
{
|
||||
"author": "Scorpinaus",
|
||||
"title": "ComfyUI-DiffusersLoader",
|
||||
"id": "diffusersloader",
|
||||
"reference": "https://github.com/Scorpinaus/ComfyUI-DiffusersLoader",
|
||||
"files": [
|
||||
"https://github.com/Scorpinaus/ComfyUI-DiffusersLoader"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "The purpose of this package is to understand how loading of diffusers format checkpoints are done in comfyUI and to create a loader that works for SDXL."
|
||||
},
|
||||
{
|
||||
"author": "FoundD-oka",
|
||||
"title": "ComfyUI KISEKAE-OOTD",
|
||||
"id": "kisekae-ootd",
|
||||
"reference": "https://github.com/FoundD-oka/ComfyUI-kisekae-OOTD",
|
||||
"files": [
|
||||
"https://github.com/FoundD-oka/ComfyUI-kisekae-OOTD"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:LoadOOTDPipeline, LoadOOTDPipelineHub, LoadOOTDPipelineHub."
|
||||
},
|
||||
{
|
||||
"author": "bruce007lee",
|
||||
"title": "comfyui-tiny-utils",
|
||||
"id": "tiny-utils",
|
||||
"reference": "https://github.com/bruce007lee/comfyui-tiny-utils",
|
||||
"files": [
|
||||
"https://github.com/bruce007lee/comfyui-tiny-utils"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:FaceAlign, FaceAlignImageProcess, FaceAlignMaskProcess"
|
||||
},
|
||||
{
|
||||
"author": "zmwv823",
|
||||
"title": "ComfyUI-AnyText [UNSTABLE]",
|
||||
"id": "anytext",
|
||||
"reference": "https://github.com/zmwv823/ComfyUI-AnyText",
|
||||
"files": [
|
||||
"https://github.com/zmwv823/ComfyUI-AnyText"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Unofficial Simple And Rough Implementation Of [a/AnyText](https://github.com/tyxsspa/AnyText)"
|
||||
},
|
||||
{
|
||||
"author": "brycegoh",
|
||||
"title": "brycegoh/comfyui-custom-nodes",
|
||||
"id": "brycegoh",
|
||||
"reference": "https://github.com/brycegoh/comfyui-custom-nodes",
|
||||
"files": [
|
||||
"https://github.com/brycegoh/comfyui-custom-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:MaskAreaComparisonSegment, FillMaskedArea, OCRAndMask"
|
||||
},
|
||||
{
|
||||
"author": "LykosAI",
|
||||
"title": "ComfyUI Nodes for Inference.Core",
|
||||
"id": "inference-core",
|
||||
"reference": "https://github.com/LykosAI/ComfyUI-Inference-Core-Nodes",
|
||||
"files": [
|
||||
"https://github.com/LykosAI/ComfyUI-Inference-Core-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Primary Nodes for Inference.Core and Stability Matrix. With a focus on not impacting startup performance and using fully qualified Node names. [w/This custom node is likely to conflict with many other nodes.]"
|
||||
},
|
||||
{
|
||||
"author": "blepping",
|
||||
"title": "comfyui_overly_complicated_sampling",
|
||||
"reference": "https://github.com/blepping/comfyui_overly_complicated_sampling",
|
||||
"files": [
|
||||
"https://github.com/blepping/comfyui_overly_complicated_sampling"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Very unstable, experimental and mathematically unsound sampling for ComfyUI.\nCurrent status: In flux, not suitable for general use."
|
||||
},
|
||||
{
|
||||
"author": "tracerstar",
|
||||
"title": "comfyui-p5js-node",
|
||||
"id": "p5js",
|
||||
"reference": "https://github.com/tracerstar/comfyui-p5js-node",
|
||||
"files": [
|
||||
"https://github.com/tracerstar/comfyui-p5js-node"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A simple proof of concept node to pass a p5js canvas through ComfyUI for img2img generation use."
|
||||
},
|
||||
{
|
||||
"author": "chaojie",
|
||||
"title": "ComfyUI-mobvoi-openapi",
|
||||
"id": "mobvoi-openapi",
|
||||
"reference": "https://github.com/chaojie/ComfyUI-mobvoi-openapi",
|
||||
"files": [
|
||||
"https://github.com/chaojie/ComfyUI-mobvoi-openapi"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:MobvoiOpenapiMetamanText, MobvoiOpenapiMetamanAudio, MobvoiOpenapiTts, HtmlViewer, OssUploadImage, OssUploadAudio"
|
||||
},
|
||||
{
|
||||
"author": "immersiveexperience",
|
||||
"title": "ie-comfyui-color-nodes",
|
||||
"id": "ie-color-nodes",
|
||||
"reference": "https://github.com/immersiveexperience/ie-comfyui-color-nodes",
|
||||
"files": [
|
||||
"https://github.com/immersiveexperience/ie-comfyui-color-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom ComfyUI nodes for simple color correction."
|
||||
},
|
||||
{
|
||||
"author": "beyastard",
|
||||
"title": "ComfyUI_BeySoft",
|
||||
"reference": "https://github.com/beyastard/ComfyUI_BeySoft",
|
||||
"files": [
|
||||
"https://github.com/beyastard/ComfyUI_BeySoft"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:BeySoft"
|
||||
},
|
||||
{
|
||||
"author": "christian-byrne",
|
||||
"title": "🌌 Infinite Parallax Nodes [WIP]",
|
||||
"reference": "https://github.com/christian-byrne/infinite-zoom-parallax-nodes",
|
||||
"files": [
|
||||
"https://github.com/christian-byrne/infinite-zoom-parallax-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Parallax Config, Load Parallax Frame, Save Parallax Object Layers, Layer Shifter for Parallax Outpainting, Save Parallax Frame, Shrink and Pad for Outpainting, Create Infinite Zoom Video"
|
||||
},
|
||||
{
|
||||
"author": "flyingdogsoftware",
|
||||
"title": "Gyre for ComfyUI",
|
||||
"id": "gyre",
|
||||
"reference": "https://github.com/flyingdogsoftware/gyre_for_comfyui",
|
||||
"files": [
|
||||
"https://github.com/flyingdogsoftware/gyre_for_comfyui"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:GyreLoopStart, GyreLoopEnd, GyreIfElse"
|
||||
},
|
||||
{
|
||||
"author": "githubYiheng",
|
||||
"title": "comfyui_median_filter",
|
||||
"id": "median-filter",
|
||||
"reference": "https://github.com/githubYiheng/comfyui_median_filter",
|
||||
"files": [
|
||||
"https://github.com/githubYiheng/comfyui_median_filter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Apply Median Filter. [w/This has been updated to be equivalent to the comfyui_kmeans_filter node. Mistake?]"
|
||||
},
|
||||
{
|
||||
"author": "nat-chan",
|
||||
"title": "comfyui-eval [UNSAFE]",
|
||||
"id": "evalnode",
|
||||
"reference": "https://github.com/nat-chan/comfyui-eval",
|
||||
"files": [
|
||||
"https://github.com/nat-chan/comfyui-eval"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:EvalNode [w/Please do not use the node that executes arbitrary code and outputs in any type, as it is dangerous.]"
|
||||
},
|
||||
{
|
||||
"author": "haofanwang",
|
||||
"title": "ComfyUI-InstantStyle",
|
||||
"id": "instantstyle",
|
||||
"reference": "https://github.com/haofanwang/ComfyUI-InstantStyle",
|
||||
"files": [
|
||||
"https://github.com/haofanwang/ComfyUI-InstantStyle"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:PromptLoader, BaseModelLoader, InstantStyleLoader, InstantStyleGenerationNode"
|
||||
},
|
||||
{
|
||||
"author": "jp0215",
|
||||
"title": "comfyUI_padding-resize_node",
|
||||
"reference": "https://github.com/jp0215/comfyUI_padding-resize_node",
|
||||
"files": [
|
||||
"https://github.com/jp0215/comfyUI_padding-resize_node/raw/main/PaddingNode.py",
|
||||
"https://github.com/jp0215/comfyUI_padding-resize_node/raw/main/ResizeNode.py"
|
||||
],
|
||||
"install_type": "copy",
|
||||
"description": "Padding image to 8x: input image and mask, if the side length is not an integer multiple of 8, expand the side length to the smallest multiple of 8 greater than the original side length. Output padding image and mask. Resize to the origin: input the generated image and the original image, crop the generated image to the size of the original image, output the cropped image."
|
||||
},
|
||||
{
|
||||
"author": "Quasimondo",
|
||||
"title": "ComfyUI-QuasimondoNodes [WIP]",
|
||||
"id": "quasimondo-nodes",
|
||||
"reference": "https://github.com/Quasimondo/ComfyUI-QuasimondoNodes",
|
||||
"files": [
|
||||
"https://github.com/Quasimondo/ComfyUI-QuasimondoNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Custom Shader, Spring Mesh"
|
||||
},
|
||||
{
|
||||
"author": "TSFSean",
|
||||
"title": "ComfyUI-TSFNodes",
|
||||
"id": "tsfnodes",
|
||||
"reference": "https://github.com/TSFSean/ComfyUI-TSFNodes",
|
||||
"files": [
|
||||
"https://github.com/TSFSean/ComfyUI-TSFNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:GyroOSC"
|
||||
},
|
||||
{
|
||||
"author": "blib-la",
|
||||
"title": "ComfyUI-Captain-Extensions",
|
||||
"id": "captain",
|
||||
"reference": "https://github.com/blib-la/ComfyUI-Captain-Extensions",
|
||||
"files": [
|
||||
"https://github.com/blib-la/ComfyUI-Captain-Extensions"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI extensions for better [a/Captain](https://github.com/blib-la/captain) integration."
|
||||
},
|
||||
{
|
||||
"author": "ejektaflex",
|
||||
"title": "ComfyUI-Ty",
|
||||
"reference": "https://github.com/ejektaflex/ComfyUI-Ty",
|
||||
"files": [
|
||||
"https://github.com/ejektaflex/ComfyUI-Ty"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Lora Block Weight Regex Loader"
|
||||
},
|
||||
{
|
||||
"author": "christian-byrne",
|
||||
"title": "Python Interpreter ComfyUI Node [UNSAFE]",
|
||||
"reference": "https://github.com/christian-byrne/python-interpreter-node",
|
||||
"files": [
|
||||
"https://github.com/christian-byrne/python-interpreter-node"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "For debugging, parsing data, generating random values, converting types, testing custom nodes faster.\nReference and use variables in the code using the same names as the inputs in the UI\nWrapper class around tensors with operator overloading for doing common image manipulation tasks.I might remove this aspect\n[w/This extension allows you to run programs through Python code in your workflow, which may not be secure. Use with caution.]"
|
||||
},
|
||||
{
|
||||
"author": "sofakid",
|
||||
"title": "dandy [UNSAFE]",
|
||||
"reference": "https://github.com/sofakid/dandy",
|
||||
"files": [
|
||||
"https://github.com/sofakid/dandy"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Dandy is a JavaScript bridge for ComfyUI. It includes everything you need to make JavaScript enabled extensions, or just load and code in little editor nodes right in ComfyUI.[w/This code can cause security issues because it allows for the execution of arbitrary JavaScript input.]"
|
||||
},
|
||||
{
|
||||
"author": "tachyon-beep",
|
||||
"title": "comfyui-simplefeed [UNSAFE]",
|
||||
"reference": "https://github.com/tachyon-beep/comfyui-simplefeed",
|
||||
"files": [
|
||||
"https://github.com/tachyon-beep/comfyui-simplefeed"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A simple image feed for comfyUI which is easily configurable and easily extensible.\nUse the filter button to select which nodes write to the feed. Under settings, there are options that allow you: Position the feed. Set a max iamge count for the feed. Set oldest to newest or newest to oldest."
|
||||
},
|
||||
{
|
||||
"author": "shadowcz007",
|
||||
"title": "ComfyUI-PuLID [TEST]",
|
||||
"reference": "https://github.com/shadowcz007/ComfyUI-PuLID-Test",
|
||||
"files": [
|
||||
"https://github.com/shadowcz007/ComfyUI-PuLID-Test"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "[a/PuLID](https://github.com/ToTheBeginning/PuLID) ComfyUI native implementation."
|
||||
},
|
||||
{
|
||||
"author": "sangeet",
|
||||
"title": "comfyui-testui [TEST]",
|
||||
"reference": "https://github.com/sangeet/comfyui-testui",
|
||||
"files": [
|
||||
"https://github.com/sangeet/comfyui-testui"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Simple Frontend For ComfyUI workflow"
|
||||
},
|
||||
{
|
||||
"author": "Elawphant",
|
||||
"title": "ComfyUI-MusicGen [WIP]",
|
||||
"id": "musicgen",
|
||||
"reference": "https://github.com/Elawphant/ComfyUI-MusicGen",
|
||||
"files": [
|
||||
"https://github.com/Elawphant/ComfyUI-MusicGen"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI for Meta MusicGen."
|
||||
},
|
||||
{
|
||||
"author": "jtscmw01",
|
||||
"title": "ComfyUI-DiffBIR",
|
||||
"id": "diffbir",
|
||||
"reference": "https://github.com/jtscmw01/ComfyUI-DiffBIR",
|
||||
"files": [
|
||||
"https://github.com/jtscmw01/ComfyUI-DiffBIR"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This extension provides [a/DiffBIR](https://github.com/XPixelGroup/DiffBIR) feature."
|
||||
},
|
||||
{
|
||||
"author": "runtime44",
|
||||
"title": "Runtime44 ComfyUI Nodes",
|
||||
"reference": "https://github.com/runtime44/comfyui_r44_nodes",
|
||||
"files": [
|
||||
"https://github.com/runtime44/comfyui_r44_nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes: Runtime44Upscaler, Runtime44ColorMatch, Runtime44DynamicKSampler, Runtime44ImageOverlay, Runtime44ImageResizer, Runtime44ImageToNoise, Runtime44MaskSampler, Runtime44TiledMaskSampler, Runtime44IterativeUpscaleFactor, Runtime44ImageEnhance"
|
||||
},
|
||||
{
|
||||
"author": "ericbeyer",
|
||||
"title": "guidance_interval",
|
||||
"reference": "https://github.com/ericbeyer/guidance_interval",
|
||||
"files": [
|
||||
"https://github.com/ericbeyer/guidance_interval"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Guidance Interval\nNOTE: Because the sampling function is replaced, you must restart after executing this custom node to restore the original state."
|
||||
},
|
||||
{
|
||||
"author": "GraftingRayman",
|
||||
"title": "ComfyUI-GR",
|
||||
"reference": "https://github.com/GraftingRayman/ComfyUI_GR_PromptSelector",
|
||||
"files": [
|
||||
"https://github.com/GraftingRayman/ComfyUI_GR_PromptSelector"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:GR Prompt Selector"
|
||||
},
|
||||
{
|
||||
"author": "oztrkoguz",
|
||||
"title": "Kosmos2_BBox_Cutter Models",
|
||||
"reference": "https://github.com/oztrkoguz/ComfyUI_Kosmos2_BBox_Cutter",
|
||||
"files": [
|
||||
"https://github.com/oztrkoguz/ComfyUI_Kosmos2_BBox_Cutter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:KosmosLoader, Kosmos2SamplerSimple, Write"
|
||||
},
|
||||
{
|
||||
"author": "ZHO-ZHO-ZHO",
|
||||
"title": "ComfyUI-PuLID-ZHO [WIP]",
|
||||
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-PuLID-ZHO",
|
||||
"files": [
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-PuLID-ZHO"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Unofficial implementation of [a/PuLID](https://github.com/ToTheBeginning/PuLID)(diffusers) for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "longgui0318",
|
||||
"title": "comfyui-one-more-step [WIP]",
|
||||
"reference": "https://github.com/longgui0318/comfyui-one-more-step",
|
||||
"files": [
|
||||
"https://github.com/longgui0318/comfyui-one-more-step"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "[a/(OMS)mhh0318/OneMoreStep](https://github.com/mhh0318/OneMoreStep) comfyui support ."
|
||||
},
|
||||
{
|
||||
"author": "unknown",
|
||||
"title": "CLIPTextEncodeAndEnhancev4 (shirazdesigner)",
|
||||
"reference": "https://github.com/shirazdesigner/CLIPTextEncodeAndEnhancev4",
|
||||
"files": [
|
||||
"https://github.com/shirazdesigner/CLIPTextEncodeAndEnhancev4"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:CLIPTextEncodeAndEnhance.\nNOTE:Translation:This is a wrapper that simply makes it easy to install an existing node via git."
|
||||
},
|
||||
{
|
||||
"author": "umisetokikaze",
|
||||
"title": "comfyui_mergekit [WIP]",
|
||||
"reference": "https://github.com/umisetokikaze/comfyui_mergekit",
|
||||
"files": [
|
||||
"https://github.com/umisetokikaze/comfyui_mergekit"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:DefineSaveName, SetModels, get_skip, LoadLR, LoadTarget, SetTokenizer, Merge, SetLayer, SetModels"
|
||||
},
|
||||
{
|
||||
"author": "Video3DGenResearch",
|
||||
"title": "ComfyUI Batch Input Node",
|
||||
@ -231,16 +630,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Generator for StyleGAN 3"
|
||||
},
|
||||
{
|
||||
"author": "christian-byrne",
|
||||
"title": "elimination-nodes",
|
||||
"reference": "https://github.com/christian-byrne/elimination-nodes",
|
||||
"files": [
|
||||
"https://github.com/christian-byrne/elimination-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Paste Cutout on Base Image"
|
||||
},
|
||||
{
|
||||
"author": "A719689614",
|
||||
"title": "ComfyUI_AC_FUNV8Beta1",
|
||||
@ -411,16 +800,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Musicgen"
|
||||
},
|
||||
{
|
||||
"author": "Extraltodeus",
|
||||
"title": "ComfyUI-variableCFGandAntiBurn [WIP]",
|
||||
"reference": "https://github.com/Extraltodeus/ComfyUI-variableCFGandAntiBurn",
|
||||
"files": [
|
||||
"https://github.com/Extraltodeus/ComfyUI-variableCFGandAntiBurn"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Continuous CFG rescaler (pre CFG), Intermediary latent merge (post CFG), Intensity/Brightness limiter (post CFG), Dynamic renoising (post CFG), Automatic CFG scale (pre/post CFG), CFG multiplier per channel (pre CFG), Self-Attention Guidance delayed activation mod (post CFG)"
|
||||
},
|
||||
{
|
||||
"author": "shadowcz007",
|
||||
"title": "comfyui-CLIPSeg",
|
||||
@ -431,16 +810,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Download [a/CLIPSeg](https://huggingface.co/CIDAS/clipseg-rd64-refined/tree/main), move to : models/clipseg"
|
||||
},
|
||||
{
|
||||
"author": "dezi-ai",
|
||||
"title": "ComfyUI Animate LCM",
|
||||
"reference": "https://github.com/dezi-ai/ComfyUI-AnimateLCM",
|
||||
"files": [
|
||||
"https://github.com/dezi-ai/ComfyUI-AnimateLCM"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI implementation for [a/AnimateLCM](https://animatelcm.github.io/) [[a/paper](https://arxiv.org/abs/2402.00769)].\b[w/This extension includes a large number of nodes imported from the existing custom nodes, increasing the likelihood of conflicts.]"
|
||||
},
|
||||
{
|
||||
"author": "stutya",
|
||||
"title": "ComfyUI-Terminal [UNSAFE]",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
458
node_db/dev/github-stats.json
Normal file
458
node_db/dev/github-stats.json
Normal file
@ -0,0 +1,458 @@
|
||||
{
|
||||
"https://github.com/17Retoucher/ComfyUI_Fooocus": {
|
||||
"stars": 50,
|
||||
"last_update": "2024-02-24 07:33:29"
|
||||
},
|
||||
"https://github.com/A719689614/ComfyUI_AC_FUNV8Beta1": {
|
||||
"stars": 13,
|
||||
"last_update": "2024-03-08 10:11:44"
|
||||
},
|
||||
"https://github.com/AIGODLIKE/ComfyUI-Studio": {
|
||||
"stars": 196,
|
||||
"last_update": "2024-05-30 02:14:11"
|
||||
},
|
||||
"https://github.com/ALatentPlace/ComfyUI_yanc": {
|
||||
"stars": 12,
|
||||
"last_update": "2024-05-27 12:39:32"
|
||||
},
|
||||
"https://github.com/BadCafeCode/execution-inversion-demo-comfyui": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-03-23 23:53:13"
|
||||
},
|
||||
"https://github.com/Beinsezii/comfyui-amd-go-fast": {
|
||||
"stars": 7,
|
||||
"last_update": "2024-05-10 00:48:37"
|
||||
},
|
||||
"https://github.com/BlueDangerX/ComfyUI-BDXNodes": {
|
||||
"stars": 1,
|
||||
"last_update": "2023-12-10 04:01:19"
|
||||
},
|
||||
"https://github.com/Brandelan/ComfyUI_bd_customNodes": {
|
||||
"stars": 1,
|
||||
"last_update": "2023-10-09 00:40:26"
|
||||
},
|
||||
"https://github.com/DeTK/ComfyUI-Switch": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-04 11:52:04"
|
||||
},
|
||||
"https://github.com/DrMWeigand/ComfyUI_LineBreakInserter": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-04-19 11:37:19"
|
||||
},
|
||||
"https://github.com/Elawphant/ComfyUI-MusicGen": {
|
||||
"stars": 4,
|
||||
"last_update": "2024-05-11 13:33:24"
|
||||
},
|
||||
"https://github.com/ExponentialML/ComfyUI_LiveDirector": {
|
||||
"stars": 33,
|
||||
"last_update": "2024-04-09 19:01:49"
|
||||
},
|
||||
"https://github.com/Extraltodeus/Conditioning-token-experiments-for-ComfyUI": {
|
||||
"stars": 13,
|
||||
"last_update": "2024-03-10 01:04:02"
|
||||
},
|
||||
"https://github.com/GentlemanHu/ComfyUI-Notifier": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-05-20 15:25:17"
|
||||
},
|
||||
"https://github.com/GraftingRayman/ComfyUI_GR_PromptSelector": {
|
||||
"stars": 9,
|
||||
"last_update": "2024-05-28 23:31:22"
|
||||
},
|
||||
"https://github.com/GrindHouse66/ComfyUI-GH_Tools": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-10 13:27:14"
|
||||
},
|
||||
"https://github.com/IvanZhd/comfyui-codeformer": {
|
||||
"stars": 0,
|
||||
"last_update": "2023-12-02 20:51:52"
|
||||
},
|
||||
"https://github.com/Jaxkr/comfyui-terminal-command": {
|
||||
"stars": 1,
|
||||
"last_update": "2023-12-03 10:31:40"
|
||||
},
|
||||
"https://github.com/Jiffies-64/ComfyUI-SaveImagePlus": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-04-01 10:52:59"
|
||||
},
|
||||
"https://github.com/Jordach/comfy-consistency-vae": {
|
||||
"stars": 68,
|
||||
"last_update": "2023-11-06 20:50:40"
|
||||
},
|
||||
"https://github.com/LarryJane491/ComfyUI-ModelUnloader": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-01-14 08:22:39"
|
||||
},
|
||||
"https://github.com/LotzF/ComfyUI-Simple-Chat-GPT-completion": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-04 21:15:22"
|
||||
},
|
||||
"https://github.com/LykosAI/ComfyUI-Inference-Core-Nodes": {
|
||||
"stars": 12,
|
||||
"last_update": "2024-04-05 05:11:51"
|
||||
},
|
||||
"https://github.com/MrAdamBlack/CheckProgress": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-01-10 08:02:18"
|
||||
},
|
||||
"https://github.com/MushroomFleet/DJZ-Nodes": {
|
||||
"stars": 4,
|
||||
"last_update": "2024-03-18 11:18:42"
|
||||
},
|
||||
"https://github.com/NicholasKao1029/comfyui-hook": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-07 05:50:56"
|
||||
},
|
||||
"https://github.com/PluMaZero/ComfyUI-SpaceFlower": {
|
||||
"stars": 4,
|
||||
"last_update": "2023-12-09 05:55:15"
|
||||
},
|
||||
"https://github.com/Quasimondo/ComfyUI-QuasimondoNodes": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-06-01 09:08:26"
|
||||
},
|
||||
"https://github.com/SadaleNet/ComfyUI-Prompt-To-Prompt": {
|
||||
"stars": 18,
|
||||
"last_update": "2024-03-17 04:30:01"
|
||||
},
|
||||
"https://github.com/Sai-ComfyUI/ComfyUI-MS-Nodes": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-02-22 08:34:44"
|
||||
},
|
||||
"https://github.com/SeedV/ComfyUI-SeedV-Nodes": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-05-21 06:39:00"
|
||||
},
|
||||
"https://github.com/TSFSean/ComfyUI-TSFNodes": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-05-18 00:59:06"
|
||||
},
|
||||
"https://github.com/TemryL/ComfyUI-IDM-VTON": {
|
||||
"stars": 138,
|
||||
"last_update": "2024-05-30 12:21:57"
|
||||
},
|
||||
"https://github.com/Video3DGenResearch/comfyui-batch-input-node": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-04-28 15:21:17"
|
||||
},
|
||||
"https://github.com/WSJUSA/Comfyui-StableSR": {
|
||||
"stars": 35,
|
||||
"last_update": "2023-10-18 12:40:30"
|
||||
},
|
||||
"https://github.com/WilliamStanford/visuallabs_comfyui_nodes": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-04-16 21:53:02"
|
||||
},
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText": {
|
||||
"stars": 41,
|
||||
"last_update": "2024-05-22 14:30:05"
|
||||
},
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-PuLID-ZHO": {
|
||||
"stars": 175,
|
||||
"last_update": "2024-05-22 13:38:23"
|
||||
},
|
||||
"https://github.com/alt-key-project/comfyui-dream-video-batches": {
|
||||
"stars": 48,
|
||||
"last_update": "2024-05-22 20:52:05"
|
||||
},
|
||||
"https://github.com/beyastard/ComfyUI_BeySoft": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-26 22:44:55"
|
||||
},
|
||||
"https://github.com/birnam/ComfyUI-GenData-Pack": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-25 01:25:23"
|
||||
},
|
||||
"https://github.com/blepping/comfyui_overly_complicated_sampling": {
|
||||
"stars": 5,
|
||||
"last_update": "2024-05-31 20:01:41"
|
||||
},
|
||||
"https://github.com/blib-la/ComfyUI-Captain-Extensions": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-17 23:27:25"
|
||||
},
|
||||
"https://github.com/bruce007lee/comfyui-cleaner": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-04-20 15:36:03"
|
||||
},
|
||||
"https://github.com/brycegoh/comfyui-custom-nodes": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-06-01 04:34:06"
|
||||
},
|
||||
"https://github.com/chaojie/ComfyUI-DynamiCrafter": {
|
||||
"stars": 102,
|
||||
"last_update": "2024-03-16 19:08:28"
|
||||
},
|
||||
"https://github.com/chaojie/ComfyUI-mobvoi-openapi": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-29 09:02:52"
|
||||
},
|
||||
"https://github.com/christian-byrne/infinite-zoom-parallax-nodes": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-05-27 01:51:24"
|
||||
},
|
||||
"https://github.com/christian-byrne/python-interpreter-node": {
|
||||
"stars": 16,
|
||||
"last_update": "2024-06-01 06:00:47"
|
||||
},
|
||||
"https://github.com/comfyanonymous/ComfyUI": {
|
||||
"stars": 36385,
|
||||
"last_update": "2024-06-01 04:09:34"
|
||||
},
|
||||
"https://github.com/cubiq/Comfy_Dungeon": {
|
||||
"stars": 162,
|
||||
"last_update": "2024-04-26 11:00:58"
|
||||
},
|
||||
"https://github.com/dezi-ai/ComfyUI-AnimateLCM": {
|
||||
"stars": 144,
|
||||
"last_update": "2024-02-07 17:34:39"
|
||||
},
|
||||
"https://github.com/dfl/comfyui-stylegan": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-03-14 14:34:25"
|
||||
},
|
||||
"https://github.com/dnl13/ComfyUI-dnl13-seg": {
|
||||
"stars": 16,
|
||||
"last_update": "2024-01-08 10:52:13"
|
||||
},
|
||||
"https://github.com/doucx/ComfyUI_WcpD_Utility_Kit": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-01-06 19:07:45"
|
||||
},
|
||||
"https://github.com/eigenpunk/ComfyUI-audio": {
|
||||
"stars": 56,
|
||||
"last_update": "2024-03-03 21:14:14"
|
||||
},
|
||||
"https://github.com/ejektaflex/ComfyUI-Ty": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-15 21:34:21"
|
||||
},
|
||||
"https://github.com/ericbeyer/guidance_interval": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-04-16 03:24:01"
|
||||
},
|
||||
"https://github.com/flowtyone/comfyui-flowty-lcm": {
|
||||
"stars": 62,
|
||||
"last_update": "2023-10-23 12:08:55"
|
||||
},
|
||||
"https://github.com/flyingdogsoftware/gyre_for_comfyui": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-31 22:27:12"
|
||||
},
|
||||
"https://github.com/foglerek/comfyui-cem-tools": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-01-13 23:22:07"
|
||||
},
|
||||
"https://github.com/gameltb/ComfyUI_paper_playground": {
|
||||
"stars": 8,
|
||||
"last_update": "2024-05-28 13:18:26"
|
||||
},
|
||||
"https://github.com/gameltb/ComfyUI_stable_fast": {
|
||||
"stars": 181,
|
||||
"last_update": "2024-04-01 13:30:57"
|
||||
},
|
||||
"https://github.com/gameltb/io_comfyui": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-04-06 04:40:05"
|
||||
},
|
||||
"https://github.com/githubYiheng/comfyui_median_filter": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-24 15:21:40"
|
||||
},
|
||||
"https://github.com/haofanwang/ComfyUI-InstantStyle": {
|
||||
"stars": 5,
|
||||
"last_update": "2024-05-23 16:11:13"
|
||||
},
|
||||
"https://github.com/houdinii/comfy-magick": {
|
||||
"stars": 4,
|
||||
"last_update": "2024-03-11 06:40:54"
|
||||
},
|
||||
"https://github.com/huizhang0110/ComfyUI_Easy_Nodes_hui": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-02-27 08:22:49"
|
||||
},
|
||||
"https://github.com/hy134300/comfyui-hb-node": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-04-09 09:56:22"
|
||||
},
|
||||
"https://github.com/ilovejohnwhite/UncleBillyGoncho": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-29 00:16:42"
|
||||
},
|
||||
"https://github.com/immersiveexperience/ie-comfyui-color-nodes": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-27 09:42:17"
|
||||
},
|
||||
"https://github.com/jn-jairo/jn_node_suite_comfyui": {
|
||||
"stars": 5,
|
||||
"last_update": "2024-01-11 20:39:36"
|
||||
},
|
||||
"https://github.com/jtscmw01/ComfyUI-DiffBIR": {
|
||||
"stars": 52,
|
||||
"last_update": "2024-05-21 05:28:34"
|
||||
},
|
||||
"https://github.com/kadirnar/ComfyUI-Adapter": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-04-03 12:05:39"
|
||||
},
|
||||
"https://github.com/kadirnar/comfyui_helpers": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-03-04 16:25:30"
|
||||
},
|
||||
"https://github.com/kappa54m/ComfyUI_Usability": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-05 14:49:45"
|
||||
},
|
||||
"https://github.com/kijai/ComfyUI-DeepSeek-VL": {
|
||||
"stars": 20,
|
||||
"last_update": "2024-05-21 16:43:40"
|
||||
},
|
||||
"https://github.com/laksjdjf/ssd-1b-comfyui": {
|
||||
"stars": 1,
|
||||
"last_update": "2023-10-27 20:05:06"
|
||||
},
|
||||
"https://github.com/logtd/ComfyUI-MotionThiefExperiment": {
|
||||
"stars": 36,
|
||||
"last_update": "2024-05-22 00:12:06"
|
||||
},
|
||||
"https://github.com/longgui0318/comfyui-one-more-step": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-07 08:40:56"
|
||||
},
|
||||
"https://github.com/ltdrdata/ComfyUI-Workflow-Component": {
|
||||
"stars": 189,
|
||||
"last_update": "2024-04-26 01:39:09"
|
||||
},
|
||||
"https://github.com/marcueberall/ComfyUI-BuildPath": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-06 07:57:33"
|
||||
},
|
||||
"https://github.com/mut-ex/comfyui-gligengui-node": {
|
||||
"stars": 27,
|
||||
"last_update": "2024-02-28 02:46:05"
|
||||
},
|
||||
"https://github.com/nat-chan/comfyui-eval": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-05-28 11:56:37"
|
||||
},
|
||||
"https://github.com/nat-chan/comfyui-in-memory-transceiver": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-05-01 10:03:01"
|
||||
},
|
||||
"https://github.com/nidefawl/ComfyUI-nidefawl": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-01-16 18:16:41"
|
||||
},
|
||||
"https://github.com/nkchocoai/ComfyUI-PromptUtilities": {
|
||||
"stars": 6,
|
||||
"last_update": "2024-05-22 23:10:42"
|
||||
},
|
||||
"https://github.com/oyvindg/ComfyUI-TrollSuite": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-05-22 21:32:03"
|
||||
},
|
||||
"https://github.com/oztrkoguz/ComfyUI_Kosmos2_BBox_Cutter": {
|
||||
"stars": 13,
|
||||
"last_update": "2024-05-03 10:52:29"
|
||||
},
|
||||
"https://github.com/phineas-pta/comfy-trt-test": {
|
||||
"stars": 83,
|
||||
"last_update": "2024-03-10 21:17:56"
|
||||
},
|
||||
"https://github.com/poisenbery/NudeNet-Detector-Provider": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-02-26 02:11:27"
|
||||
},
|
||||
"https://github.com/prismwastaken/comfyui-tools": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-05 14:34:56"
|
||||
},
|
||||
"https://github.com/romeobuilderotti/ComfyUI-EZ-Pipes": {
|
||||
"stars": 3,
|
||||
"last_update": "2023-11-15 22:00:49"
|
||||
},
|
||||
"https://github.com/runtime44/comfyui_r44_nodes": {
|
||||
"stars": 21,
|
||||
"last_update": "2024-05-23 01:18:22"
|
||||
},
|
||||
"https://github.com/sangeet/comfyui-testui": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-05-15 00:55:17"
|
||||
},
|
||||
"https://github.com/sdfxai/SDFXBridgeForComfyUI": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-04-12 14:09:45"
|
||||
},
|
||||
"https://github.com/shadowcz007/ComfyUI-PuLID-Test": {
|
||||
"stars": 8,
|
||||
"last_update": "2024-05-12 14:37:28"
|
||||
},
|
||||
"https://github.com/shadowcz007/comfyui-CLIPSeg": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-08 02:16:24"
|
||||
},
|
||||
"https://github.com/shadowcz007/comfyui-llamafile": {
|
||||
"stars": 15,
|
||||
"last_update": "2024-05-21 19:47:56"
|
||||
},
|
||||
"https://github.com/shadowcz007/comfyui-musicgen": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-13 08:45:12"
|
||||
},
|
||||
"https://github.com/shirazdesigner/CLIPTextEncodeAndEnhancev4": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-04-27 13:25:08"
|
||||
},
|
||||
"https://github.com/sofakid/dandy": {
|
||||
"stars": 25,
|
||||
"last_update": "2024-05-27 21:46:18"
|
||||
},
|
||||
"https://github.com/stavsap/ComfyUI-React-SDK": {
|
||||
"stars": 5,
|
||||
"last_update": "2024-03-17 21:54:21"
|
||||
},
|
||||
"https://github.com/stutya/ComfyUI-Terminal": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-02-05 16:47:28"
|
||||
},
|
||||
"https://github.com/sugarkwork/comfyui_psd": {
|
||||
"stars": 1,
|
||||
"last_update": "2024-03-26 08:24:56"
|
||||
},
|
||||
"https://github.com/tachyon-beep/comfyui-simplefeed": {
|
||||
"stars": 2,
|
||||
"last_update": "2024-05-22 03:30:57"
|
||||
},
|
||||
"https://github.com/talesofai/comfyui-supersave": {
|
||||
"stars": 1,
|
||||
"last_update": "2023-12-27 02:05:53"
|
||||
},
|
||||
"https://github.com/tjorbogarden/my-useful-comfyui-custom-nodes": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-03-05 13:31:31"
|
||||
},
|
||||
"https://github.com/tracerstar/comfyui-p5js-node": {
|
||||
"stars": 15,
|
||||
"last_update": "2024-05-30 18:33:55"
|
||||
},
|
||||
"https://github.com/tuckerdarby/ComfyUI-TDNodes": {
|
||||
"stars": 3,
|
||||
"last_update": "2024-02-19 17:00:55"
|
||||
},
|
||||
"https://github.com/umisetokikaze/comfyui_mergekit": {
|
||||
"stars": 0,
|
||||
"last_update": "2024-04-28 07:21:00"
|
||||
},
|
||||
"https://github.com/unanan/ComfyUI-Dist": {
|
||||
"stars": 5,
|
||||
"last_update": "2024-02-28 10:03:50"
|
||||
},
|
||||
"https://github.com/unanan/ComfyUI-clip-interrogator": {
|
||||
"stars": 20,
|
||||
"last_update": "2024-02-01 09:46:57"
|
||||
},
|
||||
"https://github.com/wormley/comfyui-wormley-nodes": {
|
||||
"stars": 0,
|
||||
"last_update": "2023-11-12 19:05:11"
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,15 @@
|
||||
{
|
||||
"custom_nodes": [
|
||||
{
|
||||
"author": "meimeilook",
|
||||
"title": "ComfyUI_IPAdapter_plus.old [backward compatbility]",
|
||||
"reference": "https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old",
|
||||
"files": [
|
||||
"https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This repo is created to provide backward compatibility for workflows configured with the old IPAdapter."
|
||||
},
|
||||
{
|
||||
"author": "ZHO-ZHO-ZHO",
|
||||
"title": "Dr.Lt.Data/ComfyUI-YoloWorld-EfficientSAM",
|
||||
|
||||
@ -10,6 +10,140 @@
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"author": "dezi-ai",
|
||||
"title": "ComfyUI Animate LCM [NOT MAINTAINED]",
|
||||
"reference": "https://github.com/dezi-ai/ComfyUI-AnimateLCM",
|
||||
"files": [
|
||||
"https://github.com/dezi-ai/ComfyUI-AnimateLCM"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI implementation for [a/AnimateLCM](https://animatelcm.github.io/) [[a/paper](https://arxiv.org/abs/2402.00769)].\b[w/This extension includes a large number of nodes imported from the existing custom nodes, increasing the likelihood of conflicts.]"
|
||||
},
|
||||
{
|
||||
"author": "christian-byrne",
|
||||
"title": "elimination-nodes [REMOVED]",
|
||||
"reference": "https://github.com/christian-byrne/elimination-nodes",
|
||||
"files": [
|
||||
"https://github.com/christian-byrne/elimination-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Paste Cutout on Base Image"
|
||||
},
|
||||
{
|
||||
"author": "Levy1417",
|
||||
"title": "Universal-Data-Processing-Kit [UNSAFE] [REMOVED]",
|
||||
"reference": "https://github.com/Levy1417/Universal-Data-Processing-Kit",
|
||||
"files": [
|
||||
"https://github.com/Levy1417/Universal-Data-Processing-Kit"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:DPK - Any Eval, DPK - Extract Array, DPK - Run External Program, DPK - Any Literals, DPK - Set Node States, DPK - Realtime Text Preview, DPK - Dynamic Action, DPK - Object To Json, DPK - Json To Object\n[w/This extension includes the ability to execute arbitrary code and programs.]"
|
||||
},
|
||||
{
|
||||
"author": "liusida",
|
||||
"title": "ComfyUI-Sida-Remove-Image [UNSAFE] [REMOVED]",
|
||||
"reference": "https://github.com/liusida/ComfyUI-Sida-Remove-Image",
|
||||
"files": [
|
||||
"https://github.com/liusida/ComfyUI-Sida-Remove-Image"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes: LoadImageWithPrivacy, RemoveImage.[w/This extension is not secure because it provides the capability to delete files from arbitrary paths.]"
|
||||
},
|
||||
{
|
||||
"author": "88IO",
|
||||
"title": "ComfyUI Image Reordering Plugins [REMOVED]",
|
||||
"reference": "https://github.com/88IO/ComfyUI-ImageReorder",
|
||||
"files": [
|
||||
"https://github.com/88IO/ComfyUI-ImageReorder"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node reorder multiple image frames based on indexes or curves."
|
||||
},
|
||||
{
|
||||
"author": "jtydhr88",
|
||||
"title": "ComfyUI-InstantMesh [DEPRECATED]",
|
||||
"id": "instant-mesh",
|
||||
"reference": "https://github.com/jtydhr88/ComfyUI-InstantMesh",
|
||||
"files": [
|
||||
"https://github.com/jtydhr88/ComfyUI-InstantMesh"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI InstantMesh is custom nodes that running TencentARC/InstantMesh into ComfyUI, this extension depends on ComfyUI-3D-Pack. Please refer to Readme carefully to install.\nNOTE: This repo is archived due to ComfyUI-3D-Pack supports InstantMesh, please check 3D-Pack directly if you need it"
|
||||
},
|
||||
{
|
||||
"author": "biegert",
|
||||
"title": "CLIPSeg [NOT MAINTAINED]",
|
||||
"id": "clipseg",
|
||||
"reference": "https://github.com/biegert/ComfyUI-CLIPSeg",
|
||||
"files": [
|
||||
"https://github.com/biegert/ComfyUI-CLIPSeg/raw/main/custom_nodes/clipseg.py"
|
||||
],
|
||||
"install_type": "copy",
|
||||
"description": "The CLIPSeg node generates a binary mask for a given input image and text prompt."
|
||||
},
|
||||
{
|
||||
"author": "tankucc1no",
|
||||
"title": "ComfyUI-Dragdiffusion [REMOVED]",
|
||||
"id": "dragdiffusion",
|
||||
"reference": "https://github.com/tankucc1no/ComfyUI-Dragdiffusion",
|
||||
"files": [
|
||||
"https://github.com/tankucc1no/ComfyUI-Dragdiffusion"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Implementation of [a/Dragdiffusion](https://github.com/Yujun-Shi/DragDiffusion) in ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "wibur0620",
|
||||
"title": "ComfyUI Ollama (wibur) [REMOVED]",
|
||||
"id": "ollama-wibur",
|
||||
"reference": "https://github.com/wibur0620/comfyui-ollama-wibur",
|
||||
"files": [
|
||||
"https://github.com/wibur0620/comfyui-ollama-wibur"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom ComfyUI Nodes for interacting with [a/Ollama](https://ollama.com/) using the ollama python client.\nIntegrate the power of LLMs into ComfyUI workflows easily or just experiment with GPT.\nNOTE: To use this properly, you would need a running Ollama server reachable from the host that is running ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "IKHOR",
|
||||
"title": "ikhor-nodes [REMOVED]",
|
||||
"reference": "https://github.com/IKHOR/ComfyUI-IKHOR-Jam-Nodes",
|
||||
"files": [
|
||||
"https://github.com/IKHOR/ComfyUI-IKHOR-Jam-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:LoadFromS3, LoadBatchFromS3, SaveToS3, SaveBatchToS3"
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI wrapper nodes for IC-light [DEPRECATED]",
|
||||
"reference": "https://github.com/kijai/ComfyUI-IC-Light-Wrapper",
|
||||
"files": [
|
||||
"https://github.com/kijai/ComfyUI-IC-Light-Wrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Stopped. Original repo: [a/https://github.com/lllyasviel/IC-Light](https://github.com/lllyasviel/IC-Light)"
|
||||
},
|
||||
{
|
||||
"author": "thedyze",
|
||||
"title": "Save Image Extended for ComfyUI",
|
||||
"reference": "https://github.com/thedyze/save-image-extended-comfyui",
|
||||
"files": [
|
||||
"https://github.com/thedyze/save-image-extended-comfyui"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Customize the information saved in file- and folder names. Use the values of sampler parameters as part of file or folder names. Save your positive & negative prompt as entries in a JSON (text) file, in each folder.\n[w/This custom node has not been maintained for a long time. Please use an alternative node from the default channel.]"
|
||||
},
|
||||
{
|
||||
"author": "ExponentialML",
|
||||
"title": "ComfyUI_ELLA [DEPRECATED]",
|
||||
"reference": "https://github.com/ExponentialML/ComfyUI_ELLA",
|
||||
"files": [
|
||||
"https://github.com/ExponentialML/ComfyUI_ELLA"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Implementaion of ELLA: Equip Diffusion Models with LLM for Enhanced Semantic Alignment.[w/Officially implemented here: [a/https://github.com/TencentQQGYLab/ComfyUI-ELLA](https://github.com/TencentQQGYLab/ComfyUI-ELLA)]"
|
||||
},
|
||||
{
|
||||
"author": "shinich39",
|
||||
"title": "comfyui-text-pipe-39 [DEPRECATED]",
|
||||
@ -30,16 +164,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Please note that the ImageTextOverlay project is no longer supported and has been moved to a new repository. For ongoing developments, contributions, and issues, please refer to the new repository at: [a/https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools](https://github.com/Big-Idea-Technology/ComfyUI-Book-Tools)"
|
||||
},
|
||||
{
|
||||
"author": "meimeilook",
|
||||
"title": "ComfyUI_IPAdapter_plus.old [backward compatbility]",
|
||||
"reference": "https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old",
|
||||
"files": [
|
||||
"https://github.com/meimeilook/ComfyUI_IPAdapter_plus.old"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This repo is created to provide backward compatibility for workflows configured with the old IPAdapter."
|
||||
},
|
||||
{
|
||||
"author": "mlinmg",
|
||||
"title": "LaMa Preprocessor [DEPRECATED]",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,223 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"name": "Kijai/ToonCrafter model checkpoint (interpolation fp16)",
|
||||
"type": "checkpoint",
|
||||
"base": "ToonCrafter",
|
||||
"save_path": "checkpoints/ToonCrafter",
|
||||
"description": "[5.25GB] ToonCrafter checkpoint model for ComfyUI-DynamiCrafterWrapper",
|
||||
"reference": "https://huggingface.co/Kijai/DynamiCrafter_pruned",
|
||||
"filename": "tooncrafter_512_interp-fp16.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/DynamiCrafter_pruned/resolve/main/tooncrafter_512_interp-fp16.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "xinsir/Controlnet-Scribble-Sdxl-1.0",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-scribble-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Scribble model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-scribble-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Canny-Sdxl-1.0 (V2)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-canny-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Canny model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-canny-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model_V2.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-canny-sdxl-1.0/resolve/main/diffusion_pytorch_model_V2.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Openpose-Sdxl-1.0",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-openpose-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Openpose model.",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/Controlnet-Openpose-Sdxl-1.0 (Ver. twins)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-openpose-sdxl-1.0",
|
||||
"description": "[2.5GB] Controlnet SDXL Openpose model. (Ver. twins)",
|
||||
"reference": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0",
|
||||
"filename": "diffusion_pytorch_model_twins.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/controlnet-openpose-sdxl-1.0/resolve/main/diffusion_pytorch_model_twins.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "xinsir/CControlnet-Scribble-Sdxl-1.0-Anime",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/controlnet-scribble-sdxl-1.0-anime",
|
||||
"description": "[2.5GB] Controlnet SDXL Scribble model. (Ver. anime)",
|
||||
"reference": "https://huggingface.co/xinsir/anime-painter",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/xinsir/anime-painter/resolve/main/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Doubiiu/ToonCrafter model checkpoint",
|
||||
"type": "checkpoint",
|
||||
"base": "ToonCrafter",
|
||||
"save_path": "custom_nodes/ComfyUI-ToonCrafter/ToonCrafter/checkpoints/tooncrafter_512_interp_v1",
|
||||
"description": "[10.5GB] ToonCrafter checkpoint model for ComfyUI-ToonCrafter",
|
||||
"reference": "https://huggingface.co/Doubiiu/ToonCrafter/tree/main",
|
||||
"filename": "model.ckpt",
|
||||
"url": "https://huggingface.co/Doubiiu/ToonCrafter/resolve/main/model.ckpt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x2.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[135MB] RGT_S x2 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x2.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x2.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x3.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[136MB] RGT_S x3 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x3.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x3.pth"
|
||||
},
|
||||
{
|
||||
"name": "ViperYX/RGT_S_x4.pth",
|
||||
"type": "RGT",
|
||||
"base": "RGT",
|
||||
"save_path": "RGT/RGT_S",
|
||||
"description": "[136MB] RGT_S x4 upscale model for ComfyUI-RGT",
|
||||
"reference": "https://huggingface.co/ViperYX/RGT/tree/main",
|
||||
"filename": "RGT_S_x4.pth",
|
||||
"url": "https://huggingface.co/ViperYX/RGT/resolve/main/RGT_S/RGT_S_x4.pth"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic v2 (fp16)",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL",
|
||||
"description": "[2.5GB] Controlnet SDXL Tile model realistic version.",
|
||||
"reference": "https://huggingface.co/TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic",
|
||||
"filename": "TTPLANET_Controlnet_Tile_realistic_v2_fp16.safetensors",
|
||||
"url": "https://huggingface.co/TTPlanet/TTPLanet_SDXL_Controlnet_Tile_Realistic/resolve/main/TTPLANET_Controlnet_Tile_realistic_v2_fp16.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "TencentARC/CustomNet",
|
||||
"type": "CustomNet",
|
||||
"base": "CustomNet",
|
||||
"save_path": "custom_nodes/ComfyUI_CustomNet/pretrain",
|
||||
"description": "CustomNet pretrained model for ComfyUI_CustomNet",
|
||||
"reference": "https://huggingface.co/TencentARC/CustomNet/tree/main",
|
||||
"filename": "customnet_v1.pt",
|
||||
"url": "https://huggingface.co/TencentARC/CustomNet/resolve/main/customnet_v1.pt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ID-Animator/animator.ckpt",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models",
|
||||
"description": "ID-Animator checkpoint",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "animator.ckpt",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/animator.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "ID-Animator/mm_sd_v15_v2.ckpt",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models/animatediff_models",
|
||||
"description": "AnimateDiff checkpoint for ID-Animator",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "mm_sd_v15_v2.ckpt",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/mm_sd_v15_v2.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "ID-Animator/image_encoder",
|
||||
"type": "ID-Animator",
|
||||
"base": "SD1.5",
|
||||
"save_path": "custom_nodes/ComfyUI_ID_Animator/models/image_encoder",
|
||||
"description": "CLIP Image encoder for ID-Animator",
|
||||
"reference": "https://huggingface.co/spaces/ID-Animator/ID-Animator",
|
||||
"filename": "model.safetensors",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/image_encoder/model.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "IC-Light/fc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "The default relighting model, conditioned on text and foreground",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fc.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fbc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Relighting model conditioned with text, foreground, and background",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fbc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fbc.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fcon",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Same as iclight_sd15_fc.safetensors, but trained with offset noise",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fcon.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fcon.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "MonsterMMORPG/insightface (for InstantID)",
|
||||
"type": "insightface",
|
||||
"base": "SDXL",
|
||||
"save_path": "insightface/models",
|
||||
"description": "MonsterMMORPG insightface model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/MonsterMMORPG/tools/tree/main",
|
||||
"filename": "antelopev2.zip",
|
||||
"url": "https://huggingface.co/MonsterMMORPG/tools/resolve/main/antelopev2.zip"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ip-adapter",
|
||||
"type": "instantid",
|
||||
"base": "SDXL",
|
||||
"save_path": "instantid/SDXL",
|
||||
"description": "ip-adapter model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "ip-adapter.bin",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ip-adapter.bin"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ControlNet",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/instantid",
|
||||
"description": "instantid controlnet model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ControlNetModel/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "ip_plus_composition_sd15.safetensors",
|
||||
"type": "IP-Adapter",
|
||||
@ -537,161 +755,6 @@
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-plus_sd15_lora.safetensors",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plus_sd15_lora.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ControlNet-HandRefiner-pruned (inpaint-depth-hand; fp16)",
|
||||
"type": "controlnet",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "This inpaint-depth controlnet model is specialized for the hand refiner.",
|
||||
"reference": "https://huggingface.co/hr16/ControlNet-HandRefiner-pruned",
|
||||
"filename": "control_sd15_inpaint_depth_hand_fp16.safetensors",
|
||||
"url": "https://huggingface.co/hr16/ControlNet-HandRefiner-pruned/resolve/main/control_sd15_inpaint_depth_hand_fp16.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "stabilityai/stable-diffusion-x4-upscaler",
|
||||
"type": "checkpoints",
|
||||
"base": "upscale",
|
||||
"save_path": "checkpoints/upscale",
|
||||
"description": "[3.53GB] This upscaling model is a latent text-guided diffusion model and should be used with SD_4XUpscale_Conditioning and KSampler.",
|
||||
"reference": "https://huggingface.co/stabilityai/stable-diffusion-x4-upscaler",
|
||||
"filename": "x4-upscaler-ema.safetensors",
|
||||
"url": "https://huggingface.co/stabilityai/stable-diffusion-x4-upscaler/resolve/main/x4-upscaler-ema.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "LDSR(Latent Diffusion Super Resolution)",
|
||||
"type": "upscale",
|
||||
"base": "upscale",
|
||||
"save_path": "upscale_models/ldsr",
|
||||
"description": "LDSR upscale model. Through the [a/ComfyUI-Flowty-LDSR](https://github.com/flowtyone/ComfyUI-Flowty-LDSR) extension, the upscale model can be utilized.",
|
||||
"reference": "https://github.com/CompVis/latent-diffusion",
|
||||
"filename": "last.ckpt",
|
||||
"url": "https://heibox.uni-heidelberg.de/f/578df07c8fc04ffbadf3/?dl=1"
|
||||
},
|
||||
{
|
||||
"name": "control_boxdepth_LooseControlfp16 (fp16)",
|
||||
"type": "controlnet",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "Loose ControlNet model",
|
||||
"reference": "https://huggingface.co/ioclab/LooseControl_WebUICombine",
|
||||
"filename": "control_boxdepth_LooseControlfp16.safetensors",
|
||||
"url": "https://huggingface.co/ioclab/LooseControl_WebUICombine/resolve/main/control_boxdepth_LooseControlfp16.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "ip-adapter-faceid-portrait_sd15.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Portrait Model (SD1.5) [ipadapter]",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-portrait_sd15.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait_sd15.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid-plus_sd15.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Plus Model (SD1.5) [ipadapter]",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-plus_sd15.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-plus_sd15.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid_sd15.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Model (SD1.5)",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid_sd15.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sd15.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid_sd15_lora.safetensors",
|
||||
"type": "lora",
|
||||
"base": "SD1.5",
|
||||
"save_path": "loras/ipadapter",
|
||||
"description": "IP-Adapter-FaceID LoRA Model (SD1.5)",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid_sd15_lora.safetensors",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid_sd15_lora.safetensors"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "LongAnimatediff/lt_long_mm_16_64_frames_v1.1.ckpt (ComfyUI-AnimateDiff-Evolved) (Updated path)",
|
||||
"type": "animatediff",
|
||||
"base": "SD1.x",
|
||||
"save_path": "animatediff_models",
|
||||
"description": "Pressing 'install' directly downloads the model from the Kosinkadink/ComfyUI-AnimateDiff-Evolved extension node.",
|
||||
"reference": "https://huggingface.co/Lightricks/LongAnimateDiff",
|
||||
"filename": "lt_long_mm_16_64_frames_v1.1.ckpt",
|
||||
"url": "https://huggingface.co/Lightricks/LongAnimateDiff/resolve/main/lt_long_mm_16_64_frames_v1.1.ckpt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "animatediff/v3_sd15_sparsectrl_rgb.ckpt (ComfyUI-AnimateDiff-Evolved)",
|
||||
"type": "controlnet",
|
||||
"base": "SD1.x",
|
||||
"save_path": "controlnet/SD1.5/animatediff",
|
||||
"description": "AnimateDiff SparseCtrl RGB ControlNet model",
|
||||
"reference": "https://huggingface.co/guoyww/animatediff",
|
||||
"filename": "v3_sd15_sparsectrl_rgb.ckpt",
|
||||
"url": "https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_sparsectrl_rgb.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "animatediff/v3_sd15_sparsectrl_scribble.ckpt",
|
||||
"type": "controlnet",
|
||||
"base": "SD1.x",
|
||||
"save_path": "controlnet/SD1.5/animatediff",
|
||||
"description": "AnimateDiff SparseCtrl Scribble ControlNet model",
|
||||
"reference": "https://huggingface.co/guoyww/animatediff",
|
||||
"filename": "v3_sd15_sparsectrl_scribble.ckpt",
|
||||
"url": "https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_sparsectrl_scribble.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "animatediff/v3_sd15_mm.ckpt (ComfyUI-AnimateDiff-Evolved)",
|
||||
"type": "animatediff",
|
||||
"base": "SD1.x",
|
||||
"save_path": "custom_nodes/ComfyUI-AnimateDiff-Evolved/models",
|
||||
"description": "Pressing 'install' directly downloads the model from the Kosinkadink/ComfyUI-AnimateDiff-Evolved extension node. (Note: Requires ComfyUI-Manager V0.24 or above)",
|
||||
"reference": "https://huggingface.co/guoyww/animatediff",
|
||||
"filename": "v3_sd15_mm.ckpt",
|
||||
"url": "https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_mm.ckpt"
|
||||
},
|
||||
{
|
||||
"name": "animatediff/v3_sd15_adapter.ckpt",
|
||||
"type": "lora",
|
||||
"base": "SD1.x",
|
||||
"save_path": "loras/SD1.5/animatediff",
|
||||
"description": "AnimateDiff Adapter LoRA (SD1.5)",
|
||||
"reference": "https://huggingface.co/guoyww/animatediff",
|
||||
"filename": "v3_sd15_adapter.ckpt",
|
||||
"url": "https://huggingface.co/guoyww/animatediff/resolve/main/v3_sd15_adapter.ckpt"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Segmind-Vega",
|
||||
"type": "checkpoints",
|
||||
"base": "segmind-vega",
|
||||
"save_path": "checkpoints/segmind-vega",
|
||||
"description": "The Segmind-Vega Model is a distilled version of the Stable Diffusion XL (SDXL), offering a remarkable 70% reduction in size and an impressive 100% speedup while retaining high-quality text-to-image generation capabilities.",
|
||||
"reference": "https://huggingface.co/segmind/Segmind-Vega",
|
||||
"filename": "segmind-vega.safetensors",
|
||||
"url": "https://huggingface.co/segmind/Segmind-Vega/resolve/main/segmind-vega.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "Segmind-VegaRT - Latent Consistency Model (LCM) LoRA of Segmind-Vega",
|
||||
"type": "lora",
|
||||
"base": "segmind-vega",
|
||||
"save_path": "loras/segmind-vega",
|
||||
"description": "Segmind-VegaRT a distilled consistency adapter for Segmind-Vega that allows to reduce the number of inference steps to only between 2 - 8 steps.",
|
||||
"reference": "https://huggingface.co/segmind/Segmind-VegaRT",
|
||||
"filename": "pytorch_lora_weights.safetensors",
|
||||
"url": "https://huggingface.co/segmind/Segmind-VegaRT/resolve/main/pytorch_lora_weights.safetensors"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -80,16 +80,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Tutorial nodes"
|
||||
},
|
||||
{
|
||||
"author": "GraftingRayman",
|
||||
"title": "ComfyUI-Trajectory",
|
||||
"reference": "https://github.com/GraftingRayman/ComfyUI-Trajectory",
|
||||
"files": [
|
||||
"https://github.com/GraftingRayman/ComfyUI-Trajectory"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:GR Trajectory"
|
||||
},
|
||||
{
|
||||
"author": "wailovet",
|
||||
"title": "ComfyUI-WW",
|
||||
@ -179,6 +169,36 @@
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Concatenate multiple text nodes."
|
||||
},
|
||||
{
|
||||
"author": "nilor-corp",
|
||||
"title": "nilor-nodes",
|
||||
"reference": "https://github.com/nilor-corp/nilor-nodes",
|
||||
"files": [
|
||||
"https://github.com/nilor-corp/nilor-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:Nilor Floats, Nilor Int To List Of Bools, Nilor Bool From List Of Bools, Nilor Int From List Of Ints, Nilor List of Ints, Nilor Count Images In Directory"
|
||||
},
|
||||
{
|
||||
"author": "OuticNZ",
|
||||
"title": "ComfyUI-Simple-Of-Complex",
|
||||
"reference": "https://github.com/OuticNZ/ComfyUI-Simple-Of-Complex",
|
||||
"files": [
|
||||
"https://github.com/OuticNZ/ComfyUI-Simple-Of-Complex"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Keeping it simple for starting. Single branch for now and will add development branch later."
|
||||
},
|
||||
{
|
||||
"author": "jtong",
|
||||
"title": "comfyui-jtong-workflow",
|
||||
"reference": "https://github.com/jtong/comfyui-jtong-workflow",
|
||||
"files": [
|
||||
"https://github.com/jtong/comfyui-jtong-workflow"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes:jtong.Highway, Example"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -67,8 +67,9 @@
|
||||
"!echo -= Install dependencies =-\n",
|
||||
"!pip3 install accelerate\n",
|
||||
"!pip3 install einops transformers>=4.25.1 safetensors>=0.3.0 aiohttp pyyaml Pillow scipy tqdm psutil\n",
|
||||
"!pip3 install xformers!=0.0.18 torch==2.1.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n",
|
||||
"!pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n",
|
||||
"!pip3 install torchsde\n",
|
||||
"!pip3 install kornia>=0.7.1 spandrel\n",
|
||||
"\n",
|
||||
"if OPTIONS['USE_COMFYUI_MANAGER']:\n",
|
||||
" %cd custom_nodes\n",
|
||||
|
||||
@ -302,26 +302,26 @@ except Exception as e:
|
||||
|
||||
try:
|
||||
import git
|
||||
except:
|
||||
except ModuleNotFoundError:
|
||||
my_path = os.path.dirname(__file__)
|
||||
requirements_path = os.path.join(my_path, "requirements.txt")
|
||||
|
||||
print(f"## ComfyUI-Manager: installing dependencies. (GitPython)")
|
||||
|
||||
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '-r', requirements_path])
|
||||
|
||||
try:
|
||||
import git
|
||||
except:
|
||||
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '-r', requirements_path])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"## [ERROR] ComfyUI-Manager: Attempting to reinstall dependencies using an alternative method.")
|
||||
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '--user', '-r', requirements_path])
|
||||
|
||||
try:
|
||||
import git
|
||||
except:
|
||||
result = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'install', '--user', '-r', requirements_path])
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"## [ERROR] ComfyUI-Manager: Failed to install the GitPython package in the correct Python environment. Please install it manually in the appropriate environment. (You can seek help at https://app.element.io/#/room/%23comfyui_space%3Amatrix.org)")
|
||||
|
||||
try:
|
||||
import git
|
||||
print(f"## ComfyUI-Manager: installing dependencies done.")
|
||||
except:
|
||||
# maybe we should sys.exit() here? there is at least two screens worth of error messages still being pumped after our error messages
|
||||
print(f"## [ERROR] ComfyUI-Manager: GitPython package seems to be installed, but failed to load somehow. Make sure you have a working git client installed")
|
||||
|
||||
|
||||
print("** ComfyUI startup time:", datetime.datetime.now())
|
||||
@ -476,8 +476,9 @@ if os.path.exists(restore_snapshot_path):
|
||||
for line in file:
|
||||
package_name = remap_pip_package(line.strip())
|
||||
if package_name and not is_installed(package_name):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
this_exit_code += process_wrap(install_cmd, repo_path)
|
||||
if not package_name.startswith('#'):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
this_exit_code += process_wrap(install_cmd, repo_path)
|
||||
|
||||
if os.path.exists(install_script_path) and f'{repo_path}/install.py' not in processed_install:
|
||||
processed_install.add(f'{repo_path}/install.py')
|
||||
|
||||
15
pyproject.toml
Normal file
15
pyproject.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[project]
|
||||
name = "comfyui-manager"
|
||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||
version = "2.36"
|
||||
license = "LICENSE"
|
||||
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/ltdrdata/ComfyUI-Manager"
|
||||
# Used by Comfy Registry https://comfyregistry.org
|
||||
|
||||
[tool.comfy]
|
||||
PublisherId = "drltdata"
|
||||
DisplayName = "ComfyUI-Manager"
|
||||
Icon = ""
|
||||
@ -2,4 +2,7 @@ GitPython
|
||||
PyGithub
|
||||
matrix-client==0.4.0
|
||||
transformers
|
||||
huggingface-hub>0.20
|
||||
huggingface-hub>0.20
|
||||
typer
|
||||
rich
|
||||
typing-extensions
|
||||
105
scanner.py
105
scanner.py
@ -37,21 +37,36 @@ else:
|
||||
print(f"TEMP DIR: {temp_dir}")
|
||||
|
||||
|
||||
parse_cnt = 0
|
||||
|
||||
|
||||
def extract_nodes(code_text):
|
||||
global parse_cnt
|
||||
|
||||
try:
|
||||
if parse_cnt % 100 == 0:
|
||||
print(f".", end="", flush=True)
|
||||
parse_cnt += 1
|
||||
|
||||
code_text = re.sub(r'\\[^"\']', '', code_text)
|
||||
parsed_code = ast.parse(code_text)
|
||||
|
||||
assignments = (node for node in parsed_code.body if isinstance(node, ast.Assign))
|
||||
|
||||
|
||||
for assignment in assignments:
|
||||
if isinstance(assignment.targets[0], ast.Name) and assignment.targets[0].id == 'NODE_CLASS_MAPPINGS':
|
||||
if isinstance(assignment.targets[0], ast.Name) and assignment.targets[0].id in ['NODE_CONFIG', 'NODE_CLASS_MAPPINGS']:
|
||||
node_class_mappings = assignment.value
|
||||
break
|
||||
else:
|
||||
node_class_mappings = None
|
||||
|
||||
if node_class_mappings:
|
||||
s = set([key.s.strip() for key in node_class_mappings.keys if key is not None])
|
||||
s = set()
|
||||
|
||||
for key in node_class_mappings.keys:
|
||||
if key is not None and isinstance(key.value, str):
|
||||
s.add(key.value.strip())
|
||||
|
||||
return s
|
||||
else:
|
||||
return set()
|
||||
@ -77,21 +92,26 @@ def scan_in_file(filename, is_builtin=False):
|
||||
class_dict = {}
|
||||
|
||||
nodes |= extract_nodes(code)
|
||||
code = re.sub(r'^#.*?$', '', code, flags=re.MULTILINE)
|
||||
|
||||
pattern2 = r'^[^=]*_CLASS_MAPPINGS\["(.*?)"\]'
|
||||
keys = re.findall(pattern2, code)
|
||||
for key in keys:
|
||||
nodes.add(key.strip())
|
||||
def extract_keys(pattern, code):
|
||||
keys = re.findall(pattern, code)
|
||||
return {key.strip() for key in keys}
|
||||
|
||||
pattern3 = r'^[^=]*_CLASS_MAPPINGS\[\'(.*?)\'\]'
|
||||
keys = re.findall(pattern3, code)
|
||||
for key in keys:
|
||||
nodes.add(key.strip())
|
||||
def update_nodes(nodes, new_keys):
|
||||
nodes |= new_keys
|
||||
|
||||
pattern4 = r'@register_node\("(.+)",\s*\".+"\)'
|
||||
keys = re.findall(pattern4, code)
|
||||
for key in keys:
|
||||
nodes.add(key.strip())
|
||||
patterns = [
|
||||
r'^[^=]*_CLASS_MAPPINGS\["(.*?)"\]',
|
||||
r'^[^=]*_CLASS_MAPPINGS\[\'(.*?)\'\]',
|
||||
r'@register_node\("(.+)",\s*\".+"\)',
|
||||
r'"(\w+)"\s*:\s*{"class":\s*\w+\s*'
|
||||
]
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
futures = {executor.submit(extract_keys, pattern, code): pattern for pattern in patterns}
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
update_nodes(nodes, future.result())
|
||||
|
||||
matches = regex.findall(code)
|
||||
for match in matches:
|
||||
@ -208,7 +228,7 @@ def clone_or_pull_git_repository(git_url):
|
||||
try:
|
||||
repo = Repo(repo_dir)
|
||||
origin = repo.remote(name="origin")
|
||||
origin.pull(rebase=True)
|
||||
origin.pull()
|
||||
repo.git.submodule('update', '--init', '--recursive')
|
||||
print(f"Pulling {repo_name}...")
|
||||
except Exception as e:
|
||||
@ -259,6 +279,9 @@ def update_custom_nodes():
|
||||
if is_rate_limit_exceeded():
|
||||
return
|
||||
|
||||
if 'github.com' not in url:
|
||||
return None
|
||||
|
||||
print('.', end="")
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
@ -272,22 +295,31 @@ def update_custom_nodes():
|
||||
repo = g.get_repo(owner_repo)
|
||||
|
||||
last_update = repo.pushed_at.strftime("%Y-%m-%d %H:%M:%S") if repo.pushed_at else 'N/A'
|
||||
github_stats[url] = {
|
||||
item = {
|
||||
"stars": repo.stargazers_count,
|
||||
"last_update": last_update,
|
||||
"cached_time": datetime.datetime.now().timestamp(),
|
||||
}
|
||||
with open(GITHUB_STATS_CACHE_FILENAME, 'w', encoding='utf-8') as file:
|
||||
json.dump(github_stats, file, ensure_ascii=False, indent=4)
|
||||
return url, item
|
||||
else:
|
||||
print(f"\nInvalid URL format for GitHub repository: {url}\n")
|
||||
except Exception as e:
|
||||
print(f"\nERROR on {url}\n{e}")
|
||||
|
||||
return None
|
||||
|
||||
# resolve unresolved urls
|
||||
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
|
||||
if url not in github_stats:
|
||||
renew_stat(url)
|
||||
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
||||
futures = []
|
||||
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
|
||||
if url not in github_stats:
|
||||
futures.append(executor.submit(renew_stat, url))
|
||||
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
url_item = future.result()
|
||||
if url_item is not None:
|
||||
url, item = url_item
|
||||
github_stats[url] = item
|
||||
|
||||
# renew outdated cache
|
||||
outdated_urls = []
|
||||
@ -296,26 +328,34 @@ def update_custom_nodes():
|
||||
if elapsed > 60*60*12: # 12 hours
|
||||
outdated_urls.append(k)
|
||||
|
||||
for url in outdated_urls:
|
||||
renew_stat(url)
|
||||
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
||||
for url in outdated_urls:
|
||||
futures.append(executor.submit(renew_stat, url))
|
||||
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
url_item = future.result()
|
||||
if url_item is not None:
|
||||
url, item = url_item
|
||||
github_stats[url] = item
|
||||
|
||||
with open('github-stats-cache.json', 'w', encoding='utf-8') as file:
|
||||
json.dump(github_stats, file, ensure_ascii=False, indent=4)
|
||||
|
||||
with open(GITHUB_STATS_FILENAME, 'w', encoding='utf-8') as file:
|
||||
for v in github_stats.values():
|
||||
if "cached_time" in v:
|
||||
del v["cached_time"]
|
||||
|
||||
github_stats = dict(sorted(github_stats.items()))
|
||||
|
||||
json.dump(github_stats, file, ensure_ascii=False, indent=4)
|
||||
|
||||
print(f"Successfully written to {GITHUB_STATS_FILENAME}, removing {GITHUB_STATS_CACHE_FILENAME}.")
|
||||
# try:
|
||||
# os.remove(GITHUB_STATS_CACHE_FILENAME) # This cache file is just for avoiding failure of GitHub API fetch, so it is safe to remove.
|
||||
# except:
|
||||
# pass
|
||||
print(f"Successfully written to {GITHUB_STATS_FILENAME}.")
|
||||
|
||||
if not skip_stat_update:
|
||||
process_git_stats(git_url_titles_preemptions)
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor(11) as executor:
|
||||
if not skip_stat_update:
|
||||
executor.submit(process_git_stats, git_url_titles_preemptions) # One single thread for `process_git_stats()`. Runs concurrently with `process_git_url_title()`.
|
||||
|
||||
for url, title, preemptions, node_pattern in git_url_titles_preemptions:
|
||||
executor.submit(process_git_url_title, url, title, preemptions, node_pattern)
|
||||
|
||||
@ -450,3 +490,4 @@ updated_node_info = update_custom_nodes()
|
||||
print("\n# 'extension-node-map.json' file is generated.\n")
|
||||
gen_json(updated_node_info)
|
||||
|
||||
print("\nDONE.\n")
|
||||
Loading…
Reference in New Issue
Block a user