Compare commits
29 Commits
draft-v4-c
...
3.31.12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72a61a9966 | ||
|
|
b08bb658ea | ||
|
|
7b28bf608b | ||
|
|
b57747fdf1 | ||
|
|
0735271b10 | ||
|
|
770cd0f9f5 | ||
|
|
32b6266dd9 | ||
|
|
2a8412a2bf | ||
|
|
0c4d289002 | ||
|
|
cee01fec25 | ||
|
|
f00686f3f2 | ||
|
|
bd33f7726e | ||
|
|
22ab526b0c | ||
|
|
af269d198d | ||
|
|
995ef6356e | ||
|
|
aa3bf77c28 | ||
|
|
15667c1259 | ||
|
|
c7b6b565da | ||
|
|
3214ab52c6 | ||
|
|
e3062ff613 | ||
|
|
036b63efe7 | ||
|
|
8d3e1d60d0 | ||
|
|
59876452f4 | ||
|
|
04972ad87f | ||
|
|
c7e69f4e26 | ||
|
|
7a59b6d0d9 | ||
|
|
d227ad97a4 | ||
|
|
b93a474dae | ||
|
|
a5fe075bf3 |
@@ -1 +0,0 @@
|
||||
PYPI_TOKEN=your-pypi-token
|
||||
58
.github/workflows/publish-to-pypi.yml
vendored
58
.github/workflows/publish-to-pypi.yml
vendored
@@ -1,58 +0,0 @@
|
||||
name: Publish to PyPI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "pyproject.toml"
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'ltdrdata' || github.repository_owner == 'Comfy-Org' }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.9'
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install build twine
|
||||
|
||||
- name: Get current version
|
||||
id: current_version
|
||||
run: |
|
||||
CURRENT_VERSION=$(grep -oP 'version = "\K[^"]+' pyproject.toml)
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
echo "Current version: $CURRENT_VERSION"
|
||||
|
||||
- name: Build package
|
||||
run: python -m build
|
||||
|
||||
- name: Create GitHub Release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
files: dist/*
|
||||
tag_name: v${{ steps.current_version.outputs.version }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
|
||||
- name: Publish to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
password: ${{ secrets.PYPI_TOKEN }}
|
||||
skip-existing: true
|
||||
verbose: true
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
publish-node:
|
||||
name: Publish Custom Node to registry
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'ltdrdata' || github.repository_owner == 'Comfy-Org' }}
|
||||
if: ${{ github.repository_owner == 'ltdrdata' }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -17,7 +17,4 @@ github-stats-cache.json
|
||||
pip_overrides.json
|
||||
*.json
|
||||
check2.sh
|
||||
/venv/
|
||||
build
|
||||
*.egg-info
|
||||
.env
|
||||
/venv/
|
||||
@@ -1,47 +0,0 @@
|
||||
## Testing Changes
|
||||
|
||||
1. Activate the ComfyUI environment.
|
||||
|
||||
2. Build package locally after making changes.
|
||||
|
||||
```bash
|
||||
# from inside the ComfyUI-Manager directory, with the ComfyUI environment activated
|
||||
python -m build
|
||||
```
|
||||
|
||||
3. Install the package locally in the ComfyUI environment.
|
||||
|
||||
```bash
|
||||
# Uninstall existing package
|
||||
pip uninstall comfyui-manager
|
||||
|
||||
# Install the locale package
|
||||
pip install dist/comfyui-manager-*.whl
|
||||
```
|
||||
|
||||
4. Start ComfyUI.
|
||||
|
||||
```bash
|
||||
# after navigating to the ComfyUI directory
|
||||
python main.py
|
||||
```
|
||||
|
||||
## Manually Publish Test Version to PyPi
|
||||
|
||||
1. Set the `PYPI_TOKEN` environment variable in env file.
|
||||
|
||||
2. If manually publishing, you likely want to use a release candidate version, so set the version in [pyproject.toml](pyproject.toml) to something like `0.0.1rc1`.
|
||||
|
||||
3. Build the package.
|
||||
|
||||
```bash
|
||||
python -m build
|
||||
```
|
||||
|
||||
4. Upload the package to PyPi.
|
||||
|
||||
```bash
|
||||
python -m twine upload dist/* --username __token__ --password $PYPI_TOKEN
|
||||
```
|
||||
|
||||
5. View at https://pypi.org/project/comfyui-manager/
|
||||
@@ -1,7 +0,0 @@
|
||||
include comfyui_manager/js/*
|
||||
include comfyui_manager/*.json
|
||||
include comfyui_manager/glob/*
|
||||
include LICENSE.txt
|
||||
include README.md
|
||||
include requirements.txt
|
||||
include pyproject.toml
|
||||
81
README.md
81
README.md
@@ -5,7 +5,6 @@
|
||||

|
||||
|
||||
## NOTICE
|
||||
* V4.0: Modify the structure to be installable via pip instead of using git clone.
|
||||
* V3.16: Support for `uv` has been added. Set `use_uv` in `config.ini`.
|
||||
* V3.10: `double-click feature` is removed
|
||||
* This feature has been moved to https://github.com/ltdrdata/comfyui-connection-helper
|
||||
@@ -14,26 +13,78 @@
|
||||
|
||||
## Installation
|
||||
|
||||
* When installing the latest ComfyUI, it will be automatically installed as a dependency, so manual installation is no longer necessary.
|
||||
### Installation[method1] (General installation method: ComfyUI-Manager only)
|
||||
|
||||
* Manual installation of the nightly version:
|
||||
* Clone to a temporary directory (**Note:** Do **not** clone into `ComfyUI/custom_nodes`.)
|
||||
```
|
||||
git clone https://github.com/Comfy-Org/ComfyUI-Manager
|
||||
```
|
||||
* Install via pip
|
||||
```
|
||||
cd ComfyUI-Manager
|
||||
pip install .
|
||||
```
|
||||
To install ComfyUI-Manager in addition to an existing installation of ComfyUI, you can follow the following steps:
|
||||
|
||||
1. goto `ComfyUI/custom_nodes` dir in terminal(cmd)
|
||||
2. `git clone https://github.com/ltdrdata/ComfyUI-Manager comfyui-manager`
|
||||
3. Restart ComfyUI
|
||||
|
||||
|
||||
### Installation[method2] (Installation for portable ComfyUI version: ComfyUI-Manager only)
|
||||
1. install git
|
||||
- https://git-scm.com/download/win
|
||||
- standalone version
|
||||
- select option: use windows default console window
|
||||
2. Download [scripts/install-manager-for-portable-version.bat](https://github.com/ltdrdata/ComfyUI-Manager/raw/main/scripts/install-manager-for-portable-version.bat) into installed `"ComfyUI_windows_portable"` directory
|
||||
- Don't click. Right click the link and use save as...
|
||||
3. double click `install-manager-for-portable-version.bat` batch file
|
||||
|
||||

|
||||
|
||||
|
||||
### 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
|
||||
```
|
||||
* See also: https://github.com/Comfy-Org/comfy-cli
|
||||
|
||||
|
||||
## Front-end
|
||||
### Installation[method4] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
||||
|
||||
* The built-in front-end of ComfyUI-Manager is the legacy front-end. The front-end for ComfyUI-Manager is now provided via [ComfyUI Frontend](https://github.com/Comfy-Org/ComfyUI_frontend).
|
||||
* To enable the legacy front-end, set the environment variable `ENABLE_LEGACY_COMFYUI_MANAGER_FRONT` to `true` before running.
|
||||
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
||||
* **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
|
||||
- Don't click. Right click the link and use save as...
|
||||
- ComfyUI will be installed in the subdirectory of the specified directory, and the directory will contain the generated executable script.
|
||||
2. `chmod +x install-comfyui-venv-linux.sh`
|
||||
3. `./install-comfyui-venv-linux.sh`
|
||||
|
||||
### Installation Precautions
|
||||
* **DO**: `ComfyUI-Manager` files must be accurately located in the path `ComfyUI/custom_nodes/comfyui-manager`
|
||||
* Installing in a compressed file format is not recommended.
|
||||
* **DON'T**: Decompress directly into the `ComfyUI/custom_nodes` location, resulting in the Manager contents like `__init__.py` being placed directly in that directory.
|
||||
* You have to remove all ComfyUI-Manager files from `ComfyUI/custom_nodes`
|
||||
* **DON'T**: In a form where decompression occurs in a path such as `ComfyUI/custom_nodes/ComfyUI-Manager/ComfyUI-Manager`.
|
||||
* **DON'T**: In a form where decompression occurs in a path such as `ComfyUI/custom_nodes/ComfyUI-Manager-main`.
|
||||
* In such cases, `ComfyUI-Manager` may operate, but it won't be recognized within `ComfyUI-Manager`, and updates cannot be performed. It also poses the risk of duplicate installations. Remove it and install properly via `git clone` method.
|
||||
|
||||
|
||||
You can execute ComfyUI by running either `./run_gpu.sh` or `./run_cpu.sh` depending on your system configuration.
|
||||
|
||||
## Colab Notebook
|
||||
This repository provides Colab notebooks that allow you to install and use ComfyUI, including ComfyUI-Manager. To use ComfyUI, [click on this link](https://colab.research.google.com/github/ltdrdata/ComfyUI-Manager/blob/main/notebooks/comfyui_colab_with_manager.ipynb).
|
||||
* Support for installing ComfyUI
|
||||
* Support for basic installation of ComfyUI-Manager
|
||||
* Support for automatically installing dependencies of custom nodes upon restarting Colab notebooks.
|
||||
|
||||
|
||||
## How To Use
|
||||
|
||||
21
__init__.py
Normal file
21
__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
cli_mode_flag = os.path.join(os.path.dirname(__file__), '.enable-cli-only-mode')
|
||||
|
||||
if not os.path.exists(cli_mode_flag):
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "glob"))
|
||||
import manager_server # noqa: F401
|
||||
import share_3rdparty # noqa: F401
|
||||
import cm_global
|
||||
|
||||
if not cm_global.disable_front and not 'DISABLE_COMFYUI_MANAGER_FRONT' in os.environ:
|
||||
WEB_DIRECTORY = "js"
|
||||
else:
|
||||
print("\n[ComfyUI-Manager] !! cli-only-mode is enabled !!\n")
|
||||
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
__all__ = ['NODE_CLASS_MAPPINGS']
|
||||
|
||||
|
||||
|
||||
@@ -15,35 +15,36 @@ import git
|
||||
import importlib
|
||||
|
||||
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "glob"))
|
||||
|
||||
import manager_util
|
||||
|
||||
# read env vars
|
||||
# COMFYUI_FOLDERS_BASE_PATH is not required in cm-cli.py
|
||||
# `comfy_path` should be resolved before importing manager_core
|
||||
|
||||
comfy_path = os.environ.get('COMFYUI_PATH')
|
||||
|
||||
if comfy_path is None:
|
||||
print("[bold red]cm-cli: environment variable 'COMFYUI_PATH' is not specified.[/bold red]")
|
||||
exit(-1)
|
||||
try:
|
||||
import folder_paths
|
||||
comfy_path = os.path.join(os.path.dirname(folder_paths.__file__))
|
||||
except:
|
||||
print("\n[bold yellow]WARN: The `COMFYUI_PATH` environment variable is not set. Assuming `custom_nodes/ComfyUI-Manager/../../` as the ComfyUI path.[/bold yellow]", file=sys.stderr)
|
||||
comfy_path = os.path.abspath(os.path.join(manager_util.comfyui_manager_path, '..', '..'))
|
||||
|
||||
# This should be placed here
|
||||
sys.path.append(comfy_path)
|
||||
|
||||
if not os.path.exists(os.path.join(comfy_path, 'folder_paths.py')):
|
||||
print("[bold red]cm-cli: '{comfy_path}' is not a valid 'COMFYUI_PATH' location.[/bold red]")
|
||||
exit(-1)
|
||||
|
||||
|
||||
import utils.extra_config
|
||||
from .glob import cm_global
|
||||
from .glob import manager_core as core
|
||||
from .glob.manager_core import unified_manager
|
||||
from .glob import cnr_utils
|
||||
import cm_global
|
||||
import manager_core as core
|
||||
from manager_core import unified_manager
|
||||
import cnr_utils
|
||||
|
||||
comfyui_manager_path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
cm_global.pip_blacklist = {'torch', 'torchsde', 'torchvision'}
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
cm_global.pip_overrides = {'numpy': 'numpy<2'}
|
||||
|
||||
if os.path.exists(os.path.join(manager_util.comfyui_manager_path, "pip_overrides.json")):
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
python ./comfyui_manager/cm-cli.py $*
|
||||
python cm-cli.py $*
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import os
|
||||
import logging
|
||||
from comfy.cli_args import args
|
||||
|
||||
ENABLE_LEGACY_COMFYUI_MANAGER_FRONT_DEFAULT = True # Enable legacy ComfyUI Manager frontend while new UI is in beta phase
|
||||
|
||||
def prestartup():
|
||||
from . import prestartup_script # noqa: F401
|
||||
logging.info('[PRE] ComfyUI-Manager')
|
||||
|
||||
|
||||
def start():
|
||||
logging.info('[START] ComfyUI-Manager')
|
||||
from .glob import manager_server # noqa: F401
|
||||
from .glob import share_3rdparty # noqa: F401
|
||||
from .glob import cm_global # noqa: F401
|
||||
|
||||
should_show_legacy_manager_front = os.environ.get('ENABLE_LEGACY_COMFYUI_MANAGER_FRONT', 'false') == 'true' or ENABLE_LEGACY_COMFYUI_MANAGER_FRONT_DEFAULT
|
||||
if not args.disable_manager and should_show_legacy_manager_front:
|
||||
try:
|
||||
import nodes
|
||||
nodes.EXTENSION_WEB_DIRS['comfyui-manager-legacy'] = os.path.join(os.path.dirname(__file__), 'js')
|
||||
except Exception as e:
|
||||
print("Error enabling legacy ComfyUI Manager frontend:", e)
|
||||
|
||||
|
||||
def should_be_disabled(fullpath:str) -> bool:
|
||||
"""
|
||||
1. Disables the legacy ComfyUI-Manager.
|
||||
2. The blocklist can be expanded later based on policies.
|
||||
"""
|
||||
|
||||
if not args.disable_manager:
|
||||
# In cases where installation is done via a zip archive, the directory name may not be comfyui-manager, and it may not contain a git repository.
|
||||
# It is assumed that any installed legacy ComfyUI-Manager will have at least 'comfyui-manager' in its directory name.
|
||||
dir_name = os.path.basename(fullpath).lower()
|
||||
if 'comfyui-manager' in dir_name:
|
||||
return True
|
||||
|
||||
return False
|
||||
@@ -1,17 +0,0 @@
|
||||
import enum
|
||||
|
||||
class NetworkMode(enum.Enum):
|
||||
PUBLIC = "public"
|
||||
PRIVATE = "private"
|
||||
OFFLINE = "offline"
|
||||
|
||||
class SecurityLevel(enum.Enum):
|
||||
STRONG = "strong"
|
||||
NORMAL = "normal"
|
||||
NORMAL_MINUS = "normal-minus"
|
||||
WEAK = "weak"
|
||||
|
||||
class DBMode(enum.Enum):
|
||||
LOCAL = "local"
|
||||
CACHE = "cache"
|
||||
REMOTE = "remote"
|
||||
@@ -1107,17 +1107,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A prompt-generator or prompt-improvement node for ComfyUI, utilizing the power of a language model to turn a provided text-to-image prompt into a more detailed and improved prompt."
|
||||
},
|
||||
{
|
||||
"author": "cubiq",
|
||||
"title": "Simple Math",
|
||||
"id": "simplemath",
|
||||
"reference": "https://github.com/cubiq/ComfyUI_SimpleMath",
|
||||
"files": [
|
||||
"https://github.com/cubiq/ComfyUI_SimpleMath"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "custom node for ComfyUI to perform simple math operations"
|
||||
},
|
||||
{
|
||||
"author": "cubiq",
|
||||
"title": "ComfyUI_IPAdapter_plus",
|
||||
@@ -3423,6 +3412,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "some comfyui custom nodes to set it as known type"
|
||||
},
|
||||
{
|
||||
"author": "YMC",
|
||||
"title": "comfyui_node_ymc_effect_shatter",
|
||||
"reference": "https://github.com/YMC-GitHub/comfyui_node_ymc_effect_shatter",
|
||||
"files": [
|
||||
"https://github.com/YMC-GitHub/comfyui_node_ymc_effect_shatter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "some comfyui custom nodes to make effect shatter"
|
||||
},
|
||||
{
|
||||
"author": "chibiace",
|
||||
"title": "ComfyUI-Chibi-Nodes",
|
||||
@@ -4598,16 +4597,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Capture window content from other programs, easyway combined with LCM for real-time painting"
|
||||
},
|
||||
{
|
||||
"author": "zhuanqianfish",
|
||||
"title": "TaesdDecoder",
|
||||
"reference": "https://github.com/zhuanqianfish/TaesdDecoder",
|
||||
"files": [
|
||||
"https://github.com/zhuanqianfish/TaesdDecoder"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "use TAESD decoded image.you need donwload taesd_decoder.pth and taesdxl_decoder.pth to vae_approx folder first.\n It will result in a slight loss of image quality and a significant decrease in peak video memory during decoding."
|
||||
},
|
||||
{
|
||||
"author": "discopixel-studio",
|
||||
"title": "PhotoRoom Nodes by Discopixel",
|
||||
@@ -9368,7 +9357,7 @@
|
||||
"https://github.com/zombieyang/sd-ppp"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "getting/sending picture from/to Photoshop with a simple connection. Make Photoshop become the workspace of your ComfyUI"
|
||||
"description": "Simplify ComfyUI to WebUI-liked interface and Connect with Photoshop."
|
||||
},
|
||||
{
|
||||
"author": "KytraScript",
|
||||
@@ -11547,6 +11536,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Used to solve the OOM (Out Of Memory) issue caused by loading all frames of a video at once in ComfyUI. All nodes use streamingly, and no longer load all frames of the video into memory at once."
|
||||
},
|
||||
{
|
||||
"author": "jax-explorer",
|
||||
"title": "ComfyUI-InstantCharacter",
|
||||
"reference": "https://github.com/jax-explorer/ComfyUI-InstantCharacter",
|
||||
"files": [
|
||||
"https://github.com/jax-explorer/ComfyUI-InstantCharacter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "[a/InstantCharacter](https://github.com/Tencent/InstantCharacter) ComfyUI Warpper"
|
||||
},
|
||||
{
|
||||
"author": "sugarkwork",
|
||||
"title": "comfyui_cohere",
|
||||
@@ -13442,6 +13441,26 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Generate random prompts easily."
|
||||
},
|
||||
{
|
||||
"author": "tritant",
|
||||
"title": "Flux LoRA Merger",
|
||||
"reference": "https://github.com/tritant/ComfyUI_Flux_Lora_Merger",
|
||||
"files": [
|
||||
"https://github.com/tritant/ComfyUI_Flux_Lora_Merger"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Advanced LoRA merging node for ComfyUI (additive, average, sequential)"
|
||||
},
|
||||
{
|
||||
"author": "tritant",
|
||||
"title": "Flux Block LoRA Merger",
|
||||
"reference": "https://github.com/tritant/ComfyUI_Flux_Block_Lora_Merger",
|
||||
"files": [
|
||||
"https://github.com/tritant/ComfyUI_Flux_Block_Lora_Merger"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Advanced Block LoRA merging node for ComfyUI (allows selective LoRA block merging)"
|
||||
},
|
||||
{
|
||||
"author": "metncelik",
|
||||
"title": "comfyui_met_suite",
|
||||
@@ -14164,6 +14183,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of ComfyUI custom nodes for interacting with various cloud services. These nodes are designed to work with any ComfyUI instance, including cloud-hosted environments (such as MimicPC) where users may have limited system access."
|
||||
},
|
||||
{
|
||||
"author": "EnragedAntelope",
|
||||
"title": "ComfyUI-ReLight",
|
||||
"reference": "https://github.com/EnragedAntelope/comfyui-relight",
|
||||
"files": [
|
||||
"https://github.com/EnragedAntelope/comfyui-relight"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Transform your images with cinematic lighting effects in a single click! ReLight is a powerful ComfyUI node that adds professional-grade lighting capabilities including multiple light sources, rim lighting, and 3D lighting simulation."
|
||||
},
|
||||
{
|
||||
"author": "jn-jairo",
|
||||
"title": "JNComfy",
|
||||
@@ -14296,7 +14325,7 @@
|
||||
"https://github.com/MakkiShizu/comfyui_reimgsize"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "a simple reimgsize node(s) in comfyui."
|
||||
"description": "a simple resize image node(s) in comfyui. This repository is not specific to the length and width values of an image, but focuses more on adjusting the total pixel count, side length specifications, and size ratios of the image."
|
||||
},
|
||||
{
|
||||
"author": "Makki_Shizu",
|
||||
@@ -15311,6 +15340,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Control Freak gives you physical control over your ComfyUI workflows by mapping MIDI controllers, gamepads, and other input devices to any node parameter or UI element. Transform your image generation experience with tactile, responsive control. Ever heard of 'flow state'?"
|
||||
},
|
||||
{
|
||||
"author": "ryanontheinside",
|
||||
"title": "ComfyUI-MediaPipe-Vision",
|
||||
"reference": "https://github.com/ryanontheinside/ComfyUI-MediaPipe-Vision",
|
||||
"files": [
|
||||
"https://github.com/ryanontheinside/ComfyUI-MediaPipe-Vision"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A centralized wrapper of all MediaPipe vision tasks for ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "ControlAltAI",
|
||||
"title": "ControlAltAI Nodes",
|
||||
@@ -15406,16 +15445,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "The FLUX model API from DashScope, developed by Black Forest Labs, offers superior image generation capabilities with optimized support for Chinese prompts, achieving a commendable tradeoff between performance and the quality of generated images compared to other open-source models."
|
||||
},
|
||||
{
|
||||
"author": "lucafoscili",
|
||||
"title": "LF Nodes",
|
||||
"reference": "https://github.com/lucafoscili/comfyui-lf",
|
||||
"files": [
|
||||
"https://github.com/lucafoscili/comfyui-lf"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes with a touch of extra UX, including: history for primitives, JSON manipulation, logic switches with visual feedback, LLM chat... and more!"
|
||||
},
|
||||
{
|
||||
"author": "JPrevots",
|
||||
"title": "ComfyUI-PhyCV",
|
||||
@@ -15631,6 +15660,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Image to 3D using Hunyuan-3D-2"
|
||||
},
|
||||
{
|
||||
"author": "niknah",
|
||||
"title": "ComfyUI-InfiniteYou",
|
||||
"reference": "https://github.com/niknah/ComfyUI-InfiniteYou",
|
||||
"files": [
|
||||
"https://github.com/niknah/ComfyUI-InfiniteYou"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI custom_node for ByteDance's InfiniteYou"
|
||||
},
|
||||
{
|
||||
"author": "daryltucker",
|
||||
"title": "ComfyUI-LoadFiles",
|
||||
@@ -15815,7 +15854,7 @@
|
||||
"https://github.com/sakura1bgx/ComfyUI_FlipStreamViewer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI_FlipStreamViewer is a tool that provides a viewer interface for flipping images with frame interpolation, allowing you to watch high-fidelity pseudo-videos without needing AnimateDiff."
|
||||
"description": "ComfyUI_FlipStreamViewer is a tool that provides a customizable viewer interface for flipping images with frame interpolation."
|
||||
},
|
||||
{
|
||||
"author": "ducido",
|
||||
@@ -16533,7 +16572,7 @@
|
||||
},
|
||||
{
|
||||
"author": "edelvarden",
|
||||
"title": "ComfyUI-ImageMetadataExtension",
|
||||
"title": "comfyui_image_metadata_extension",
|
||||
"reference": "https://github.com/edelvarden/comfyui_image_metadata_extension",
|
||||
"files": [
|
||||
"https://github.com/edelvarden/comfyui_image_metadata_extension"
|
||||
@@ -16571,6 +16610,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes for loading both Checkpoints and UNET/Diffussion models quantized to bitsandbytes NF4 or FP4 format.\nStill under development and some limitations such as using LoRA might apply still."
|
||||
},
|
||||
{
|
||||
"author": "silveroxides",
|
||||
"title": "ComfyUI-RR-JointTagger",
|
||||
"reference": "https://github.com/silveroxides/ComfyUI-RR-JointTagger",
|
||||
"files": [
|
||||
"https://github.com/silveroxides/ComfyUI-RR-JointTagger"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Tagger used to tag image of but not limited to furry art."
|
||||
},
|
||||
{
|
||||
"author": "turkyden",
|
||||
"title": "ComfyUI-SmartCrop",
|
||||
@@ -16732,6 +16781,28 @@
|
||||
"description": "ComfyUI-Free-GPU provides a node for releasing RAM and VRAM in ComfyUI.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "CY-CHENYUE",
|
||||
"title": "ComfyUI-Gemini-API",
|
||||
"id": "ComfyUI-Gemini-API",
|
||||
"reference": "https://github.com/CY-CHENYUE/ComfyUI-Gemini-API",
|
||||
"files": [
|
||||
"https://github.com/CY-CHENYUE/ComfyUI-Gemini-API"
|
||||
],
|
||||
"description": "A custom node for ComfyUI to integrate Google Gemini API.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "CY-CHENYUE",
|
||||
"title": "ComfyUI-GPT-API",
|
||||
"id": "ComfyUI-GPT-API",
|
||||
"reference": "https://github.com/CY-CHENYUE/ComfyUI-GPT-API",
|
||||
"files": [
|
||||
"https://github.com/CY-CHENYUE/ComfyUI-GPT-API"
|
||||
],
|
||||
"description": "A custom node for ComfyUI to integrate GPT API.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "codecringebinge",
|
||||
"title": "ComfyUI-Arrow-Key-Canvas-Navigation",
|
||||
@@ -17236,6 +17307,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node designed for ComfyUI, allowing users to format the current date and time based on a specified format."
|
||||
},
|
||||
{
|
||||
"author": "Q-Bug4",
|
||||
"title": "comfyui-qbug-batch",
|
||||
"reference": "https://github.com/Q-Bug4/comfyui-qbug-batch",
|
||||
"files": [
|
||||
"https://github.com/Q-Bug4/comfyui-qbug-batch"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Batch Toolkit: Custom nodes that simplify batch operations and improve efficiency."
|
||||
},
|
||||
{
|
||||
"author": "bartly",
|
||||
"title": "Babel Removebg Api Node for ComfyUI",
|
||||
@@ -17258,6 +17339,17 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Convert your workflows into node and chain them."
|
||||
},
|
||||
{
|
||||
"author": "NumZ",
|
||||
"title": "ComfyUI-Orpheus",
|
||||
"id": "OrpheusNode",
|
||||
"reference": "https://github.com/numz/Comfyui-Orpheus",
|
||||
"files": [
|
||||
"https://github.com/numz/Comfyui-Orpheus"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "TTS with emotional speech capabilities in 8 Languages 24 speakers."
|
||||
},
|
||||
{
|
||||
"author": "SozeInc",
|
||||
"title": "Quality of Life Nodes for ComfyUI",
|
||||
@@ -17782,7 +17874,7 @@
|
||||
"https://github.com/raspie10032/ComfyUI_RS_NAI_Local_Prompt_converter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node extension for ComfyUI that enables conversion between NovelAI and ComfyUI prompt formats, along with extraction of NovelAI metadata from PNG images."
|
||||
"description": "A custom node extension for ComfyUI that enables conversion between different prompt formats: NovelAI V4, ComfyUI, and old NovelAI."
|
||||
},
|
||||
{
|
||||
"author": "Wakfull33",
|
||||
@@ -18708,6 +18800,26 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A node for ComfyUI that terminates the workflow processing if 'proceed' is set to False. More convenient than manually bypassing a bunch of nodes.\nThis is a restructured version of the 'SRL Conditional Interrupt' node from the [a/srl-nodes](https://github.com/seanlynch/srl-nodes) pack."
|
||||
},
|
||||
{
|
||||
"author": "SparknightLLC",
|
||||
"title": "ComfyUI-GPENO",
|
||||
"reference": "https://github.com/SparknightLLC/ComfyUI-GPENO",
|
||||
"files": [
|
||||
"https://github.com/SparknightLLC/ComfyUI-GPENO"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A node for ComfyUI that performs GPEN face restoration on the input image(s). Significantly faster than other implementations of GPEN."
|
||||
},
|
||||
{
|
||||
"author": "SparknightLLC",
|
||||
"title": "ComfyUI-ImageAutotone",
|
||||
"reference": "https://github.com/SparknightLLC/ComfyUI-ImageAutotone",
|
||||
"files": [
|
||||
"https://github.com/SparknightLLC/ComfyUI-ImageAutotone"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A node for ComfyUI that takes an input image and clips the color channels independently to increase contrast and alter color cast. This is a reinterpretation of PhotoShop's 'Auto Tone' algorithm."
|
||||
},
|
||||
{
|
||||
"author": "lightricks",
|
||||
"title": "ComfyUI-LTXVideo",
|
||||
@@ -18924,6 +19036,36 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI nodes for UNO model."
|
||||
},
|
||||
{
|
||||
"author": "Yuan-ManX",
|
||||
"title": "ComfyUI-HiDream-I1",
|
||||
"reference": "https://github.com/Yuan-ManX/ComfyUI-HiDream-I1",
|
||||
"files": [
|
||||
"https://github.com/Yuan-ManX/ComfyUI-HiDream-I1"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI nodes for HiDream-I1 model."
|
||||
},
|
||||
{
|
||||
"author": "Yuan-ManX",
|
||||
"title": "ComfyUI-Kimi-VL",
|
||||
"reference": "https://github.com/Yuan-ManX/ComfyUI-Kimi-VL",
|
||||
"files": [
|
||||
"https://github.com/Yuan-ManX/ComfyUI-Kimi-VL"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI nodes for Kimi-VL model."
|
||||
},
|
||||
{
|
||||
"author": "Yuan-ManX",
|
||||
"title": "ComfyUI-Cobra",
|
||||
"reference": "https://github.com/Yuan-ManX/ComfyUI-Cobra",
|
||||
"files": [
|
||||
"https://github.com/Yuan-ManX/ComfyUI-Cobra"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Make Cobra avialbe in ComfyUI.\nCobra: Efficient Line Art COlorization with BRoAder References"
|
||||
},
|
||||
{
|
||||
"author": "Starnodes2024",
|
||||
"title": "ComfyUI_StarNodes",
|
||||
@@ -19396,6 +19538,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a UNO ComfyUI plugin implementation that can run the full version with 24GB VRAM, as well as quickly run the FP8 version."
|
||||
},
|
||||
{
|
||||
"author": "HM-RunningHub",
|
||||
"title": "ComfyUI_RH_FramePack",
|
||||
"reference": "https://github.com/HM-RunningHub/ComfyUI_RH_FramePack",
|
||||
"files": [
|
||||
"https://github.com/HM-RunningHub/ComfyUI_RH_FramePack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a ComfyUI plug-in for lllyasviel/FramePack, easy to use"
|
||||
},
|
||||
{
|
||||
"author": "sebord",
|
||||
"title": "ComfyUI-LMCQ",
|
||||
@@ -20251,6 +20403,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Lightweight and Efficient, 🎧Ultra High-Quality Voice Cloning, Chinese and English."
|
||||
},
|
||||
{
|
||||
"author": "mw",
|
||||
"title": "MW-ComfyUI_OuteTTS",
|
||||
"reference": "https://github.com/billwuhao/ComfyUI_OuteTTS",
|
||||
"files": [
|
||||
"https://github.com/billwuhao/ComfyUI_OuteTTS"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "OuteTTS - Unified Text-To-Speech. A node for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "pandaer119",
|
||||
"title": "ComfyUI_pandai",
|
||||
@@ -20545,6 +20707,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node implementation for ComfyUI that integrates with venice.ai's Flux and SDXL image generation models. This project is adapted from [a/ComfyUI-FLUX-TOGETHER-API](https://github.com/BZcreativ/ComfyUI-FLUX-TOGETHER-API) to work with the venice.ai API."
|
||||
},
|
||||
{
|
||||
"author": "DraconicDragon",
|
||||
"title": "ComfyUI-RyuuNoodles",
|
||||
"reference": "https://github.com/DraconicDragon/ComfyUI-RyuuNoodles",
|
||||
"files": [
|
||||
"https://github.com/DraconicDragon/ComfyUI-RyuuNoodles"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Collection of one or more custom nodes for ComfyUI made mainly for personal use (GitHub README for more info). \nNodes: live Token Counter on any node, switch nodes with fallback functionality and FLOAT/INT nodes (and maybe more)."
|
||||
},
|
||||
{
|
||||
"author": "Wenaka2004",
|
||||
"title": "ComfyUI-TagClassifier",
|
||||
@@ -20936,7 +21108,7 @@
|
||||
"title": "ComfyUI-BETA-Helpernodes",
|
||||
"reference": "https://github.com/Burgstall-labs/ComfyUI-BETA-Helpernodes",
|
||||
"files": [
|
||||
"hhttps://github.com/Burgstall-labs/ComfyUI-BETA-Helpernodes"
|
||||
"https://github.com/Burgstall-labs/ComfyUI-BETA-Helpernodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom utility nodes for ComfyUI, providing helpers for tasks like video frame manipulation and advanced audio saving. Part of the 'Burgstall Enabling The Awesomeness' suite."
|
||||
@@ -21340,6 +21512,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "A set of custom nodes for ComfyUI providing advanced image processing, file handling, and utility functions."
|
||||
},
|
||||
{
|
||||
"author": "Conor-Collins",
|
||||
"title": "ComfyUI-CoCoTools_IO",
|
||||
"reference": "https://github.com/Conor-Collins/ComfyUI-CoCoTools_IO",
|
||||
"files": [
|
||||
"https://github.com/Conor-Collins/ComfyUI-CoCoTools_IO"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A streamlined set of custom nodes for ComfyUI focused on advanced image I/O operations, particularly for EXR file handling."
|
||||
},
|
||||
{
|
||||
"author": "852wa",
|
||||
"title": "ComfyUI-ColorshiftColor",
|
||||
@@ -22174,6 +22356,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Resize a batch of trajectories or images"
|
||||
},
|
||||
{
|
||||
"author": "Pablerdo",
|
||||
"title": "Stable Virtual Camera",
|
||||
"reference": "https://github.com/Pablerdo/ComfyUI-StableVirtualCameraWrapper",
|
||||
"files": [
|
||||
"https://github.com/Pablerdo/ComfyUI-StableVirtualCameraWrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Generative View Synthesis with Diffusion Models"
|
||||
},
|
||||
{
|
||||
"author": "orange90",
|
||||
"title": " ComfyUI-Regex-Runner",
|
||||
@@ -22506,7 +22698,7 @@
|
||||
},
|
||||
{
|
||||
"author": "ifmylove2011",
|
||||
"title": "comfyui-missing-tool",
|
||||
"title": "comfyui-missed-tool",
|
||||
"reference": "https://github.com/ifmylove2011/comfyui-missed-tool",
|
||||
"files": [
|
||||
"https://github.com/ifmylove2011/comfyui-missed-tool"
|
||||
@@ -22725,17 +22917,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for various visual generation and editing tasks using ACE_Plus FFT Model."
|
||||
},
|
||||
{
|
||||
"author": "CY-CHENYUE",
|
||||
"title": "ComfyUI-Gemini-API",
|
||||
"id": "ComfyUI-Gemini-API",
|
||||
"reference": "https://github.com/CY-CHENYUE/ComfyUI-Gemini-API",
|
||||
"files": [
|
||||
"https://github.com/CY-CHENYUE/ComfyUI-Gemini-API"
|
||||
],
|
||||
"description": "A custom node for ComfyUI to integrate Google Gemini API.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "chri002",
|
||||
"title": "ComfyUI_depthMapOperation",
|
||||
@@ -23158,16 +23339,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Start and end frames video generation node that supports native ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "ZenAI-Vietnam",
|
||||
"title": "ComfyUI_InfiniteYou",
|
||||
"reference": "https://github.com/ZenAI-Vietnam/ComfyUI_InfiniteYou",
|
||||
"files": [
|
||||
"https://github.com/ZenAI-Vietnam/ComfyUI_InfiniteYou"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "An implementation of InfiniteYou for ComfyUI. Native support for [a/InfiniteYou](https://github.com/bytedance/InfiniteYou) in ComfyUI, designed by the ZenAI team."
|
||||
},
|
||||
{
|
||||
"author": "Creepybits",
|
||||
"title": "ComfyUI-Creepy_nodes",
|
||||
@@ -23199,6 +23370,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Utility Nodes by Imagineer. Currently 1: Catch and Edit Text, useful for grabbing AI generated prompts which you edit by hand. Doing so mutes the upstream node, improving speed and saving external calls and budget."
|
||||
},
|
||||
{
|
||||
"author": "Yushan777",
|
||||
"title": "ComfyUI-Y7-SBS-2Dto3D",
|
||||
"reference": "https://github.com/yushan777/ComfyUI-Y7-SBS-2Dto3D",
|
||||
"files": [
|
||||
"https://github.com/yushan777/ComfyUI-Y7-SBS-2Dto3D"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Convert 2D images and videos to 3D SBS (side-by-side) format"
|
||||
},
|
||||
{
|
||||
"author": "Yushan777",
|
||||
"title": "Y7Nodes for ComfyUI",
|
||||
@@ -23230,17 +23411,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This node enables better performance for Stable Diffusion models, by leveraging AMD MIGraphX, on Navi3 and Navi4 GPUs."
|
||||
},
|
||||
{
|
||||
"author": "CY-CHENYUE",
|
||||
"title": "ComfyUI-GPT-API",
|
||||
"id": "ComfyUI-GPT-API",
|
||||
"reference": "https://github.com/CY-CHENYUE/ComfyUI-GPT-API",
|
||||
"files": [
|
||||
"https://github.com/CY-CHENYUE/ComfyUI-GPT-API"
|
||||
],
|
||||
"description": "A custom node for ComfyUI to integrate GPT API.",
|
||||
"install_type": "git-clone"
|
||||
},
|
||||
{
|
||||
"author": "zzubnik",
|
||||
"title": "TT_TextTools",
|
||||
@@ -23471,7 +23641,7 @@
|
||||
"https://github.com/Siempreflaco/ComfyUI-NCNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: NC Audio Recorder, NC Line Counter, NC Increment INT, NC Image Processor"
|
||||
"description": "NODES: Audio Recorder, Line Counter, Increment INT, Image Processor, Load 3D Mesh From Outputs"
|
||||
},
|
||||
{
|
||||
"author": "livepeer",
|
||||
@@ -23525,13 +23695,13 @@
|
||||
},
|
||||
{
|
||||
"author": "Temult",
|
||||
"title": "Sigma Graph Node for ComfyUI",
|
||||
"reference": "https://github.com/Temult/sigma-graph-node",
|
||||
"title": "TWanSigmaGraph",
|
||||
"reference": "https://github.com/Temult/TWanSigmaGraph",
|
||||
"files": [
|
||||
"https://github.com/Temult/sigma-graph-node"
|
||||
"https://github.com/Temult/TWanSigmaGraph"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI node for interactively editing sigma schedules via graph and text."
|
||||
"description": "Interactive sigma schedule editor with graph and text input."
|
||||
},
|
||||
{
|
||||
"author": "Raykosan",
|
||||
@@ -23646,6 +23816,16 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a custom node for ComfyUI that allows you to use the KLingAI API directly within the ComfyUI environment. It is developed based on the KLingAI API documentation. For more details, please refer to the official documentation. [a/KLingAI API Documentation](https://app.klingai.com/global/dev/document-api/quickStart/productIntroduction/overview)."
|
||||
},
|
||||
{
|
||||
"author": "synthetai",
|
||||
"title": "ComfyUI_PromptBatcher",
|
||||
"reference": "https://github.com/synthetai/ComfyUI_PromptBatcher",
|
||||
"files": [
|
||||
"https://github.com/synthetai/ComfyUI_PromptBatcher"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node extension for ComfyUI that enables batch processing of prompts from text files to generate multiple images."
|
||||
},
|
||||
{
|
||||
"author": "chou18194766xx",
|
||||
"title": "comfyui-EncryptSave",
|
||||
@@ -23736,7 +23916,7 @@
|
||||
"https://github.com/linksluckytime/comfyui_snacknodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI"
|
||||
"description": "A comprehensive collection of ComfyUI nodes designed to reduce reliance on multiple third-party node packages."
|
||||
},
|
||||
{
|
||||
"author": "uihp",
|
||||
@@ -23748,7 +23928,272 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "String Chain: Reconnect your prompts"
|
||||
},
|
||||
|
||||
{
|
||||
"author": "silveroxides",
|
||||
"title": "Model Utility Toolkit",
|
||||
"id": "comfyui_modelutils",
|
||||
"reference": "https://github.com/silveroxides/ComfyUI-ModelUtils",
|
||||
"files": [
|
||||
"https://github.com/silveroxides/ComfyUI-ModelUtils"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "[WIP]Custom nodes for handling, inspecting, modifying and creating various model files."
|
||||
},
|
||||
{
|
||||
"author": "leoleexh",
|
||||
"title": "Comfy-Topaz-Photo",
|
||||
"id": "leoleexh's Custom-Nodes",
|
||||
"reference": "https://github.com/leoleelxh/Comfy-Topaz-Photo",
|
||||
"files": [
|
||||
"https://github.com/leoleelxh/Comfy-Topaz-Photo"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A new ComfyUI node for integrating Topaz Photo AI's powerful image enhancement capabilities"
|
||||
},
|
||||
{
|
||||
"author": "big-mon",
|
||||
"title": "ComfyUI-ResolutionPresets",
|
||||
"id": "bigmonComfyuiResolutionPresets",
|
||||
"reference": "https://github.com/big-mon/ComfyUI-ResolutionPresets",
|
||||
"files": [
|
||||
"https://github.com/big-mon/ComfyUI-ResolutionPresets"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Provides recommended resolution presets specifically. Select a preset from the dropdown to easily output the corresponding width and height values for use with nodes like Empty Latent Image."
|
||||
},
|
||||
{
|
||||
"author": "hnmr293",
|
||||
"title": "ComfyUI-SaveMem",
|
||||
"reference": "https://github.com/hnmr293/comfyui-savemem",
|
||||
"files": [
|
||||
"https://github.com/hnmr293/comfyui-savemem"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Save Image/Latent to Shared Memory"
|
||||
},
|
||||
{
|
||||
"author": "hnmr293",
|
||||
"title": "ComfyUI-latent-ops",
|
||||
"reference": "https://github.com/hnmr293/ComfyUI-latent-ops",
|
||||
"files": [
|
||||
"https://github.com/hnmr293/ComfyUI-latent-ops"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of nodes for manipulating LATENT in ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "Reithan",
|
||||
"title": "Negative Rejection Steering",
|
||||
"reference": "https://github.com/Reithan/negative_rejection_steering",
|
||||
"files": [
|
||||
"https://github.com/Reithan/negative_rejection_steering"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NRS seeks to replace the 'naive' linear interpolation of Classifier Free Guidance with a more nuanced and composable steering of the generation process with better mathematical basis."
|
||||
},
|
||||
{
|
||||
"author": "FunnyFinger",
|
||||
"title": "Dynamic Sliders Stack",
|
||||
"reference": "https://github.com/FunnyFinger/Dynamic_Sliders_stack",
|
||||
"files": [
|
||||
"https://github.com/FunnyFinger/Dynamic_Sliders_stack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node for ComfyUI to have many sliders with interactive dynamic behavior. This repository includes all necessary code and assets for seamless integration."
|
||||
},
|
||||
{
|
||||
"author": "xLegende",
|
||||
"title": "ComfyUI-Prompt-Formatter",
|
||||
"id": "comfyui-prompt-formatter",
|
||||
"reference": "https://github.com/xLegende/ComfyUI-Prompt-Formatter",
|
||||
"files": [
|
||||
"https://github.com/xLegende/ComfyUI-Prompt-Formatter"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This repository contains custom nodes for ComfyUI designed to help structure, filter, and generate text prompts using categorized tag definitions stored in a YAML file."
|
||||
},
|
||||
{
|
||||
"author": "QijiTec",
|
||||
"title": "ComfyUI-RED-UNO",
|
||||
"reference": "https://github.com/QijiTec/ComfyUI-RED-UNO",
|
||||
"files": [
|
||||
"https://github.com/QijiTec/ComfyUI-RED-UNO"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Default 16GB VRAM UNO in context generation ComfyUI-node, using RED-UNO FT model"
|
||||
},
|
||||
{
|
||||
"author": "Danteday",
|
||||
"title": "NoteManager",
|
||||
"reference": "https://github.com/Danteday/ComfyUI-NoteManager",
|
||||
"files": [
|
||||
"https://github.com/Danteday/ComfyUI-NoteManager"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A powerful extension for ComfyUI that enables adding notes to many node in your workflow. Keep track of important settings, reminders, and workflow documentation directly within your ComfyUI canvas."
|
||||
},
|
||||
{
|
||||
"author": "zzw5516",
|
||||
"title": "ComfyUI-zw-tools",
|
||||
"id": "zzw5516",
|
||||
"reference": "https://github.com/zzw5516/ComfyUI-zw-tools",
|
||||
"files": [
|
||||
"https://github.com/zzw5516/ComfyUI-zw-tools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Automatic prompt translation to Chinese, custom prompt management, AI-based prompt expansion and translation, AI-generated image/video record management (file browser), and cloud storage upload management."
|
||||
},
|
||||
{
|
||||
"author": "nisaruj",
|
||||
"title": "ComfyUI-DAAM",
|
||||
"id": "comfyui-daam",
|
||||
"reference": "https://github.com/nisaruj/comfyui-daam",
|
||||
"files": [
|
||||
"https://github.com/nisaruj/comfyui-daam"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI custom nodes for Diffusion Attentive Attribution Maps (DAAM)"
|
||||
},
|
||||
{
|
||||
"author": "bytedance",
|
||||
"title": "ComfyUI_InfiniteYou",
|
||||
"reference": "https://github.com/bytedance/ComfyUI_InfiniteYou",
|
||||
"files": [
|
||||
"https://github.com/bytedance/ComfyUI_InfiniteYou"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Official ComfyUI Support - InfiniteYou: Flexible Photo Recrafting While Preserving Your Identity"
|
||||
},
|
||||
{
|
||||
"author": "AstroCorp",
|
||||
"title": "ComfyUI AstroCorp Nodes",
|
||||
"reference": "https://github.com/AstroCorp/ComfyUI-AstroCorp-Nodes",
|
||||
"files": [
|
||||
"https://github.com/AstroCorp/ComfyUI-AstroCorp-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of personal ComfyUI nodes designed to enhance and automate workflows."
|
||||
},
|
||||
{
|
||||
"author": "stevenwg",
|
||||
"title": "ComfyUI-VideoGrid",
|
||||
"reference": "https://github.com/stevenwg/ComfyUI-VideoGrid",
|
||||
"files": [
|
||||
"https://github.com/stevenwg/ComfyUI-VideoGrid"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Add vertical and horizontal video grid support"
|
||||
},
|
||||
{
|
||||
"author": "avenstack",
|
||||
"title": "ComfyUI-AV-MegaTTS3",
|
||||
"reference": "https://github.com/avenstack/ComfyUI-AV-MegaTTS3",
|
||||
"files": [
|
||||
"https://github.com/avenstack/ComfyUI-AV-MegaTTS3"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "🎧Ultra High-Quality Voice Cloning, Chinese and English."
|
||||
},
|
||||
{
|
||||
"author": "WarpedAnimation",
|
||||
"title": "ComfyUI-WarpedToolset",
|
||||
"reference": "https://github.com/WarpedAnimation/ComfyUI-WarpedToolset",
|
||||
"files": [
|
||||
"https://github.com/WarpedAnimation/ComfyUI-WarpedToolset"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom tool set mostly for Hunyuan Video, but includes some WAN Video nodes."
|
||||
},
|
||||
{
|
||||
"author": "Jint8888",
|
||||
"title": "Comfyui_JTnodes",
|
||||
"reference": "https://github.com/Jint8888/Comfyui_JTnodes",
|
||||
"files": [
|
||||
"https://github.com/Jint8888/Comfyui_JTnodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This project contains some custom ComfyUI nodes for image processing, AI conversation, and utility tasks."
|
||||
},
|
||||
{
|
||||
"author": "ichabodcole",
|
||||
"title": "ComfyUI-Ichis-Pack",
|
||||
"reference": "https://github.com/ichabodcole/ComfyUI-Ichis-Pack",
|
||||
"files": [
|
||||
"https://github.com/ichabodcole/ComfyUI-Ichis-Pack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of ComfyUI Nodes, most to make dynamic prompting a bit easier."
|
||||
},
|
||||
{
|
||||
"author": "SignalCha1n",
|
||||
"title": "Snap Style Nodes for ComfyUI",
|
||||
"reference": "https://github.com/SignalCha1n/comfyui-ComfySnap",
|
||||
"files": [
|
||||
"https://github.com/SignalCha1n/comfyui-ComfySnap"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI designed to replicate certain visual elements and effects reminiscent of Snap and early digital aesthetics. These nodes are ideal for image processing tasks and are fully compatible with ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "judian17",
|
||||
"title": "ComfyUI_ZIM",
|
||||
"reference": "https://github.com/judian17/ComfyUI_ZIM",
|
||||
"files": [
|
||||
"https://github.com/judian17/ComfyUI_ZIM"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "The unofficial implementation of ZIM in ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "AngelCookies",
|
||||
"title": "ComfyUI-Seed-Tracker",
|
||||
"reference": "https://github.com/AngelCookies/ComfyUI-Seed-Tracker",
|
||||
"files": [
|
||||
"https://github.com/AngelCookies/ComfyUI-Seed-Tracker"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI extension that tracks random seeds throughout your image generation workflows"
|
||||
},
|
||||
{
|
||||
"author": "TiamaTiramisu",
|
||||
"title": "RisuTools",
|
||||
"reference": "https://github.com/TiamaTiramisu/risutools",
|
||||
"files": [
|
||||
"https://github.com/TiamaTiramisu/risutools"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes for integration with RisuAI"
|
||||
},
|
||||
{
|
||||
"author": "excelwong",
|
||||
"title": "ComfyUI Prompt Composer",
|
||||
"reference": "https://github.com/excelwong/ComfyUI-PromptComposer",
|
||||
"files": [
|
||||
"https://github.com/excelwong/ComfyUI-PromptComposer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI custom node plugin for assembling prompts. It allows you to generate positive and negative prompts by selecting different options."
|
||||
},
|
||||
{
|
||||
"author": "jida-ai",
|
||||
"title": "ComfyUI-VideoChatWrapper",
|
||||
"reference": "https://github.com/lebrosoft/ComfyUI-VideoChatWrapper",
|
||||
"files": [
|
||||
"https://github.com/lebrosoft/ComfyUI-VideoChatWrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes related to video chat workflows"
|
||||
},
|
||||
{
|
||||
"author": "VK",
|
||||
"title": "VK Nodes",
|
||||
"reference": "https://github.com/VK/vk-nodes",
|
||||
"files": [
|
||||
"https://github.com/VK/vk-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI nodes to simplify my tiled render"
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,12 +15,9 @@ comfy_path = os.environ.get('COMFYUI_PATH')
|
||||
git_exe_path = os.environ.get('GIT_EXE_PATH')
|
||||
|
||||
if comfy_path is None:
|
||||
print("git_helper: environment variable 'COMFYUI_PATH' is not specified.")
|
||||
exit(-1)
|
||||
print("\nWARN: The `COMFYUI_PATH` environment variable is not set. Assuming `custom_nodes/ComfyUI-Manager/../../` as the ComfyUI path.", file=sys.stderr)
|
||||
comfy_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
|
||||
if not os.path.exists(os.path.join(comfy_path, 'folder_paths.py')):
|
||||
print("git_helper: '{comfy_path}' is not a valid 'COMFYUI_PATH' location.")
|
||||
exit(-1)
|
||||
|
||||
def download_url(url, dest_folder, filename=None):
|
||||
# Ensure the destination folder exists
|
||||
6548
github-stats.json
6548
github-stats.json
File diff suppressed because it is too large
Load Diff
@@ -6,9 +6,8 @@ import time
|
||||
from dataclasses import dataclass
|
||||
from typing import List
|
||||
|
||||
from . import manager_core
|
||||
from . import manager_util
|
||||
|
||||
import manager_core
|
||||
import manager_util
|
||||
import requests
|
||||
import toml
|
||||
|
||||
@@ -32,15 +32,18 @@ from packaging import version
|
||||
|
||||
import uuid
|
||||
|
||||
from . import cm_global
|
||||
from . import cnr_utils
|
||||
from . import manager_util
|
||||
from . import git_utils
|
||||
from . import manager_downloader
|
||||
from .node_package import InstalledNodePackage
|
||||
from .enums import NetworkMode, SecurityLevel, DBMode
|
||||
glob_path = os.path.join(os.path.dirname(__file__)) # ComfyUI-Manager/glob
|
||||
sys.path.append(glob_path)
|
||||
|
||||
version_code = [4, 0]
|
||||
import cm_global
|
||||
import cnr_utils
|
||||
import manager_util
|
||||
import git_utils
|
||||
import manager_downloader
|
||||
from node_package import InstalledNodePackage
|
||||
|
||||
|
||||
version_code = [3, 31, 12]
|
||||
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||
|
||||
|
||||
@@ -55,7 +58,6 @@ class InvalidChannel(Exception):
|
||||
self.channel = channel
|
||||
super().__init__(channel)
|
||||
|
||||
|
||||
def get_default_custom_nodes_path():
|
||||
global default_custom_nodes_path
|
||||
if default_custom_nodes_path is None:
|
||||
@@ -181,11 +183,10 @@ comfy_base_path = os.environ.get('COMFYUI_FOLDERS_BASE_PATH')
|
||||
|
||||
if comfy_path is None:
|
||||
try:
|
||||
comfy_path = os.path.abspath(os.path.dirname(sys.modules['__main__'].__file__))
|
||||
os.environ['COMFYUI_PATH'] = comfy_path
|
||||
import folder_paths
|
||||
comfy_path = os.path.join(os.path.dirname(folder_paths.__file__))
|
||||
except:
|
||||
logging.error("[ComfyUI-Manager] environment variable 'COMFYUI_PATH' is not specified.")
|
||||
exit(-1)
|
||||
comfy_path = os.path.abspath(os.path.join(manager_util.comfyui_manager_path, '..', '..'))
|
||||
|
||||
if comfy_base_path is None:
|
||||
comfy_base_path = comfy_path
|
||||
@@ -202,7 +203,6 @@ manager_snapshot_path = None
|
||||
manager_pip_overrides_path = None
|
||||
manager_pip_blacklist_path = None
|
||||
manager_components_path = None
|
||||
manager_batch_history_path = None
|
||||
|
||||
def update_user_directory(user_dir):
|
||||
global manager_files_path
|
||||
@@ -213,7 +213,6 @@ def update_user_directory(user_dir):
|
||||
global manager_pip_overrides_path
|
||||
global manager_pip_blacklist_path
|
||||
global manager_components_path
|
||||
global manager_batch_history_path
|
||||
|
||||
manager_files_path = os.path.abspath(os.path.join(user_dir, 'default', 'ComfyUI-Manager'))
|
||||
if not os.path.exists(manager_files_path):
|
||||
@@ -233,14 +232,10 @@ def update_user_directory(user_dir):
|
||||
manager_pip_blacklist_path = os.path.join(manager_files_path, "pip_blacklist.list")
|
||||
manager_components_path = os.path.join(manager_files_path, "components")
|
||||
manager_util.cache_dir = os.path.join(manager_files_path, "cache")
|
||||
manager_batch_history_path = os.path.join(manager_files_path, "batch_history")
|
||||
|
||||
if not os.path.exists(manager_util.cache_dir):
|
||||
os.makedirs(manager_util.cache_dir)
|
||||
|
||||
if not os.path.exists(manager_batch_history_path):
|
||||
os.makedirs(manager_batch_history_path)
|
||||
|
||||
try:
|
||||
import folder_paths
|
||||
update_user_directory(folder_paths.get_user_directory())
|
||||
@@ -558,7 +553,7 @@ class UnifiedManager:
|
||||
ver = str(manager_util.StrictVersion(info['version']))
|
||||
return {'id': cnr['id'], 'cnr': cnr, 'ver': ver}
|
||||
else:
|
||||
return {'id': info['id'], 'ver': info['version']}
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -734,7 +729,7 @@ class UnifiedManager:
|
||||
|
||||
return latest
|
||||
|
||||
async def reload(self, cache_mode, dont_wait=True, update_cnr_map=True):
|
||||
async def reload(self, cache_mode, dont_wait=True):
|
||||
self.custom_node_map_cache = {}
|
||||
self.cnr_inactive_nodes = {} # node_id -> node_version -> fullpath
|
||||
self.nightly_inactive_nodes = {} # node_id -> fullpath
|
||||
@@ -742,18 +737,17 @@ class UnifiedManager:
|
||||
self.unknown_active_nodes = {} # node_id -> repo url * fullpath
|
||||
self.active_nodes = {} # node_id -> node_version * fullpath
|
||||
|
||||
if get_config()['network_mode'] != 'public' or manager_util.is_manager_pip_package():
|
||||
if get_config()['network_mode'] != 'public':
|
||||
dont_wait = True
|
||||
|
||||
if update_cnr_map:
|
||||
# reload 'cnr_map' and 'repo_cnr_map'
|
||||
cnrs = await cnr_utils.get_cnr_data(cache_mode=cache_mode=='cache', dont_wait=dont_wait)
|
||||
# reload 'cnr_map' and 'repo_cnr_map'
|
||||
cnrs = await cnr_utils.get_cnr_data(cache_mode=cache_mode=='cache', dont_wait=dont_wait)
|
||||
|
||||
for x in cnrs:
|
||||
self.cnr_map[x['id']] = x
|
||||
if 'repository' in x:
|
||||
normalized_url = git_utils.normalize_url(x['repository'])
|
||||
self.repo_cnr_map[normalized_url] = x
|
||||
for x in cnrs:
|
||||
self.cnr_map[x['id']] = x
|
||||
if 'repository' in x:
|
||||
normalized_url = git_utils.normalize_url(x['repository'])
|
||||
self.repo_cnr_map[normalized_url] = x
|
||||
|
||||
# reload node status info from custom_nodes/*
|
||||
for custom_nodes_path in folder_paths.get_folder_paths('custom_nodes'):
|
||||
@@ -1447,20 +1441,12 @@ class UnifiedManager:
|
||||
return self.unified_enable(node_id, version_spec)
|
||||
|
||||
elif version_spec == 'unknown' or version_spec == 'nightly':
|
||||
to_path = os.path.abspath(os.path.join(get_default_custom_nodes_path(), node_id))
|
||||
|
||||
if version_spec == 'nightly':
|
||||
# disable cnr nodes
|
||||
if self.is_enabled(node_id, 'cnr'):
|
||||
self.unified_disable(node_id, False)
|
||||
|
||||
# use `repo name` as a dir name instead of `cnr id` if system added nodepack (i.e. publisher is null)
|
||||
cnr = self.cnr_map.get(node_id)
|
||||
|
||||
if cnr is not None and cnr.get('publisher') is None:
|
||||
repo_name = os.path.basename(git_utils.normalize_url(repo_url))
|
||||
to_path = os.path.abspath(os.path.join(get_default_custom_nodes_path(), repo_name))
|
||||
|
||||
to_path = os.path.abspath(os.path.join(get_default_custom_nodes_path(), node_id))
|
||||
res = self.repo_install(repo_url, to_path, instant_execution=instant_execution, no_deps=no_deps, return_postinstall=return_postinstall)
|
||||
if res.result:
|
||||
if version_spec == 'unknown':
|
||||
@@ -1677,9 +1663,9 @@ def read_config():
|
||||
'model_download_by_agent': get_bool('model_download_by_agent', False),
|
||||
'downgrade_blacklist': default_conf.get('downgrade_blacklist', '').lower(),
|
||||
'always_lazy_install': get_bool('always_lazy_install', False),
|
||||
'network_mode': default_conf.get('network_mode', NetworkMode.PUBLIC.value).lower(),
|
||||
'security_level': default_conf.get('security_level', SecurityLevel.NORMAL.value).lower(),
|
||||
'db_mode': default_conf.get('db_mode', DBMode.CACHE.value).lower(),
|
||||
'network_mode': default_conf.get('network_mode', 'public').lower(),
|
||||
'security_level': default_conf.get('security_level', 'normal').lower(),
|
||||
'db_mode': default_conf.get('db_mode', 'cache').lower(),
|
||||
}
|
||||
|
||||
except Exception:
|
||||
@@ -1700,9 +1686,9 @@ def read_config():
|
||||
'model_download_by_agent': False,
|
||||
'downgrade_blacklist': '',
|
||||
'always_lazy_install': False,
|
||||
'network_mode': NetworkMode.OFFLINE.value,
|
||||
'security_level': SecurityLevel.NORMAL.value,
|
||||
'db_mode': DBMode.CACHE.value,
|
||||
'network_mode': 'public', # public | private | offline
|
||||
'security_level': 'normal', # strong | normal | normal- | weak
|
||||
'db_mode': 'cache', # local | cache | remote
|
||||
}
|
||||
|
||||
|
||||
@@ -2199,7 +2185,7 @@ async def get_data_by_mode(mode, filename, channel_url=None):
|
||||
cache_uri = str(manager_util.simple_hash(uri))+'_'+filename
|
||||
cache_uri = os.path.join(manager_util.cache_dir, cache_uri)
|
||||
|
||||
if get_config()['network_mode'] == 'offline' or manager_util.is_manager_pip_package():
|
||||
if get_config()['network_mode'] == 'offline':
|
||||
# offline network mode
|
||||
if os.path.exists(cache_uri):
|
||||
json_obj = await manager_util.get_data(cache_uri)
|
||||
@@ -2219,7 +2205,7 @@ async def get_data_by_mode(mode, filename, channel_url=None):
|
||||
with open(cache_uri, "w", encoding='utf-8') as file:
|
||||
json.dump(json_obj, file, indent=4, sort_keys=True)
|
||||
except Exception as e:
|
||||
print(f"[ComfyUI-Manager] Due to a network error, switching to local mode.\n=> {filename} @ {channel_url}/{mode}\n=> {e}")
|
||||
print(f"[ComfyUI-Manager] Due to a network error, switching to local mode.\n=> {filename}\n=> {e}")
|
||||
uri = os.path.join(manager_util.comfyui_manager_path, filename)
|
||||
json_obj = await manager_util.get_data(uri)
|
||||
|
||||
@@ -14,23 +14,18 @@ import git
|
||||
from datetime import datetime
|
||||
|
||||
from server import PromptServer
|
||||
import manager_core as core
|
||||
import manager_util
|
||||
import cm_global
|
||||
import logging
|
||||
import asyncio
|
||||
from collections import deque
|
||||
import queue
|
||||
|
||||
from . import manager_core as core
|
||||
from . import manager_util
|
||||
from . import cm_global
|
||||
from . import manager_downloader
|
||||
import manager_downloader
|
||||
|
||||
|
||||
logging.info(f"### Loading: ComfyUI-Manager ({core.version_str})")
|
||||
|
||||
if not manager_util.is_manager_pip_package():
|
||||
network_mode_description = "offline"
|
||||
else:
|
||||
network_mode_description = core.get_config()['network_mode']
|
||||
logging.info("[ComfyUI-Manager] network_mode: " + network_mode_description)
|
||||
logging.info("[ComfyUI-Manager] network_mode: " + core.get_config()['network_mode'])
|
||||
|
||||
comfy_ui_hash = "-"
|
||||
comfyui_tag = None
|
||||
@@ -160,7 +155,9 @@ class ManagerFuncsInComfyUI(core.ManagerFuncs):
|
||||
|
||||
core.manager_funcs = ManagerFuncsInComfyUI()
|
||||
|
||||
from .manager_downloader import download_url, download_url_with_agent
|
||||
sys.path.append('../..')
|
||||
|
||||
from manager_downloader import download_url, download_url_with_agent
|
||||
|
||||
core.comfy_path = os.path.dirname(folder_paths.__file__)
|
||||
core.js_path = os.path.join(core.comfy_path, "web", "extensions")
|
||||
@@ -394,73 +391,16 @@ def nickname_filter(json_obj):
|
||||
return json_obj
|
||||
|
||||
|
||||
class TaskBatch:
|
||||
def __init__(self, batch_json, tasks, failed):
|
||||
self.nodepack_result = {}
|
||||
self.model_result = {}
|
||||
self.batch_id = batch_json.get('batch_id') if batch_json is not None else None
|
||||
self.batch_json = batch_json
|
||||
self.tasks = tasks
|
||||
self.current_index = 0
|
||||
self.stats = {}
|
||||
self.failed = failed if failed is not None else set()
|
||||
self.is_aborted = False
|
||||
|
||||
def is_done(self):
|
||||
return len(self.tasks) <= self.current_index
|
||||
|
||||
def get_next(self):
|
||||
if self.is_done():
|
||||
return None
|
||||
|
||||
item = self.tasks[self.current_index]
|
||||
self.current_index += 1
|
||||
return item
|
||||
|
||||
def done_count(self):
|
||||
return len(self.nodepack_result) + len(self.model_result)
|
||||
|
||||
def total_count(self):
|
||||
return len(self.tasks)
|
||||
|
||||
def abort(self):
|
||||
self.is_aborted = True
|
||||
|
||||
def finalize(self):
|
||||
if self.batch_id is not None:
|
||||
batch_path = os.path.join(core.manager_batch_history_path, self.batch_id+".json")
|
||||
json_obj = {
|
||||
"batch": self.batch_json,
|
||||
"nodepack_result": self.nodepack_result,
|
||||
"model_result": self.model_result,
|
||||
"failed": list(self.failed)
|
||||
}
|
||||
with open(batch_path, "w") as json_file:
|
||||
json.dump(json_obj, json_file, indent=4)
|
||||
|
||||
|
||||
temp_queue_batch = []
|
||||
task_batch_queue = deque()
|
||||
task_queue = queue.Queue()
|
||||
nodepack_result = {}
|
||||
model_result = {}
|
||||
tasks_in_progress = set()
|
||||
task_worker_lock = threading.Lock()
|
||||
aborted_batch = None
|
||||
|
||||
|
||||
def finalize_temp_queue_batch(batch_json=None, failed=None):
|
||||
"""
|
||||
make temp_queue_batch as a batch snapshot and add to batch_queue
|
||||
"""
|
||||
|
||||
global temp_queue_batch
|
||||
|
||||
if len(temp_queue_batch):
|
||||
batch = TaskBatch(batch_json, temp_queue_batch, failed)
|
||||
task_batch_queue.append(batch)
|
||||
temp_queue_batch = []
|
||||
|
||||
|
||||
async def task_worker():
|
||||
global task_queue
|
||||
global nodepack_result
|
||||
global model_result
|
||||
global tasks_in_progress
|
||||
|
||||
async def do_install(item) -> str:
|
||||
@@ -473,7 +413,8 @@ async def task_worker():
|
||||
return f"Cannot resolve install target: '{node_spec_str}'"
|
||||
|
||||
node_name, version_spec, is_specified = node_spec
|
||||
res = await core.unified_manager.install_by_id(node_name, version_spec, channel, mode, return_postinstall=skip_post_install) # discard post install if skip_post_install mode
|
||||
res = await core.unified_manager.install_by_id(node_name, version_spec, channel, mode, return_postinstall=skip_post_install)
|
||||
# discard post install if skip_post_install mode
|
||||
|
||||
if res.action not in ['skip', 'enable', 'install-git', 'install-cnr', 'switch-cnr']:
|
||||
logging.error(f"[ComfyUI-Manager] Installation failed:\n{res.msg}")
|
||||
@@ -488,11 +429,6 @@ async def task_worker():
|
||||
traceback.print_exc()
|
||||
return f"Installation failed:\n{node_spec_str}"
|
||||
|
||||
async def do_enable(item) -> str:
|
||||
ui_id, cnr_id = item
|
||||
core.unified_manager.unified_enable(cnr_id)
|
||||
return 'success'
|
||||
|
||||
async def do_update(item):
|
||||
ui_id, node_name, node_ver = item
|
||||
|
||||
@@ -651,45 +587,31 @@ async def task_worker():
|
||||
|
||||
return f"Model installation error: {model_url}"
|
||||
|
||||
stats = {}
|
||||
|
||||
while True:
|
||||
with task_worker_lock:
|
||||
if len(task_batch_queue) > 0:
|
||||
cur_batch = task_batch_queue[0]
|
||||
else:
|
||||
logging.info("\n[ComfyUI-Manager] All tasks are completed.")
|
||||
logging.info("\nAfter restarting ComfyUI, please refresh the browser.")
|
||||
done_count = len(nodepack_result) + len(model_result)
|
||||
total_count = done_count + task_queue.qsize()
|
||||
|
||||
res = {'status': 'all-done'}
|
||||
if task_queue.empty():
|
||||
logging.info(f"\n[ComfyUI-Manager] Queued works are completed.\n{stats}")
|
||||
|
||||
PromptServer.instance.send_sync("cm-queue-status", res)
|
||||
|
||||
return
|
||||
|
||||
if cur_batch.is_done():
|
||||
logging.info(f"\n[ComfyUI-Manager] A tasks batch(batch_id={cur_batch.batch_id}) is completed.\nstat={cur_batch.stats}")
|
||||
|
||||
res = {'status': 'batch-done',
|
||||
'nodepack_result': cur_batch.nodepack_result,
|
||||
'model_result': cur_batch.model_result,
|
||||
'total_count': cur_batch.total_count(),
|
||||
'done_count': cur_batch.done_count(),
|
||||
'batch_id': cur_batch.batch_id,
|
||||
'remaining_batch_count': len(task_batch_queue) }
|
||||
|
||||
PromptServer.instance.send_sync("cm-queue-status", res)
|
||||
cur_batch.finalize()
|
||||
task_batch_queue.popleft()
|
||||
continue
|
||||
logging.info("\nAfter restarting ComfyUI, please refresh the browser.")
|
||||
PromptServer.instance.send_sync("cm-queue-status",
|
||||
{'status': 'done',
|
||||
'nodepack_result': nodepack_result, 'model_result': model_result,
|
||||
'total_count': total_count, 'done_count': done_count})
|
||||
nodepack_result = {}
|
||||
task_queue = queue.Queue()
|
||||
return # terminate worker thread
|
||||
|
||||
with task_worker_lock:
|
||||
kind, item = cur_batch.get_next()
|
||||
kind, item = task_queue.get()
|
||||
tasks_in_progress.add((kind, item[0]))
|
||||
|
||||
try:
|
||||
if kind == 'install':
|
||||
msg = await do_install(item)
|
||||
elif kind == 'enable':
|
||||
msg = await do_enable(item)
|
||||
elif kind == 'install-model':
|
||||
msg = await do_install_model(item)
|
||||
elif kind == 'update':
|
||||
@@ -713,131 +635,31 @@ async def task_worker():
|
||||
with task_worker_lock:
|
||||
tasks_in_progress.remove((kind, item[0]))
|
||||
|
||||
ui_id = item[0]
|
||||
if kind == 'install-model':
|
||||
cur_batch.model_result[ui_id] = msg
|
||||
ui_target = "model_manager"
|
||||
elif kind == 'update-main':
|
||||
cur_batch.nodepack_result[ui_id] = msg
|
||||
ui_target = "main"
|
||||
elif kind == 'update-comfyui':
|
||||
cur_batch.nodepack_result['comfyui'] = msg
|
||||
ui_target = "main"
|
||||
elif kind == 'update':
|
||||
cur_batch.nodepack_result[ui_id] = msg['msg']
|
||||
ui_target = "nodepack_manager"
|
||||
else:
|
||||
cur_batch.nodepack_result[ui_id] = msg
|
||||
ui_target = "nodepack_manager"
|
||||
ui_id = item[0]
|
||||
if kind == 'install-model':
|
||||
model_result[ui_id] = msg
|
||||
ui_target = "model_manager"
|
||||
elif kind == 'update-main':
|
||||
nodepack_result[ui_id] = msg
|
||||
ui_target = "main"
|
||||
elif kind == 'update-comfyui':
|
||||
nodepack_result['comfyui'] = msg
|
||||
ui_target = "main"
|
||||
elif kind == 'update':
|
||||
nodepack_result[ui_id] = msg['msg']
|
||||
ui_target = "nodepack_manager"
|
||||
else:
|
||||
nodepack_result[ui_id] = msg
|
||||
ui_target = "nodepack_manager"
|
||||
|
||||
cur_batch.stats[kind] = cur_batch.stats.get(kind, 0) + 1
|
||||
stats[kind] = stats.get(kind, 0) + 1
|
||||
|
||||
PromptServer.instance.send_sync("cm-queue-status",
|
||||
{'status': 'in_progress',
|
||||
'target': item[0],
|
||||
'batch_id': cur_batch.batch_id,
|
||||
'ui_target': ui_target,
|
||||
'total_count': cur_batch.total_count(),
|
||||
'done_count': cur_batch.done_count()})
|
||||
{'status': 'in_progress', 'target': item[0], 'ui_target': ui_target,
|
||||
'total_count': total_count, 'done_count': done_count})
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/batch")
|
||||
async def queue_batch(request):
|
||||
json_data = await request.json()
|
||||
|
||||
failed = set()
|
||||
|
||||
for k, v in json_data.items():
|
||||
if k == 'update_all':
|
||||
await _update_all({'mode': v})
|
||||
|
||||
elif k == 'reinstall':
|
||||
for x in v:
|
||||
res = await _uninstall_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
else:
|
||||
res = await _install_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
elif k == 'install':
|
||||
for x in v:
|
||||
res = await _install_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
elif k == 'uninstall':
|
||||
for x in v:
|
||||
res = await _uninstall_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
elif k == 'update':
|
||||
for x in v:
|
||||
res = await _update_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
elif k == 'update_comfyui':
|
||||
await update_comfyui(None)
|
||||
|
||||
elif k == 'disable':
|
||||
for x in v:
|
||||
await _disable_node(x)
|
||||
|
||||
elif k == 'install_model':
|
||||
for x in v:
|
||||
res = await _install_model(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
elif k == 'fix':
|
||||
for x in v:
|
||||
res = await _fix_custom_node(x)
|
||||
if res.status != 200:
|
||||
failed.add(x[0])
|
||||
|
||||
with task_worker_lock:
|
||||
finalize_temp_queue_batch(json_data, failed)
|
||||
_queue_start()
|
||||
|
||||
return web.json_response({"failed": list(failed)}, content_type='application/json')
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/history_list")
|
||||
async def get_history_list(request):
|
||||
history_path = core.manager_batch_history_path
|
||||
|
||||
try:
|
||||
files = [os.path.join(history_path, f) for f in os.listdir(history_path) if os.path.isfile(os.path.join(history_path, f))]
|
||||
files.sort(key=lambda x: os.path.getmtime(x), reverse=True)
|
||||
history_ids = [os.path.basename(f)[:-5] for f in files]
|
||||
|
||||
return web.json_response({"ids": list(history_ids)}, content_type='application/json')
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] /v2/manager/queue/history_list - {e}")
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/history")
|
||||
async def get_history(request):
|
||||
try:
|
||||
json_name = request.rel_url.query["id"]+'.json'
|
||||
batch_path = os.path.join(core.manager_batch_history_path, json_name)
|
||||
|
||||
with open(batch_path, 'r', encoding='utf-8') as file:
|
||||
json_str = file.read()
|
||||
json_obj = json.loads(json_str)
|
||||
return web.json_response(json_obj, content_type='application/json')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"[ComfyUI-Manager] /v2/manager/queue/history - {e}")
|
||||
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/customnode/getmappings")
|
||||
@routes.get("/customnode/getmappings")
|
||||
async def fetch_customnode_mappings(request):
|
||||
"""
|
||||
provide unified (node -> node pack) mapping list
|
||||
@@ -873,7 +695,7 @@ async def fetch_customnode_mappings(request):
|
||||
return web.json_response(json_obj, content_type='application/json')
|
||||
|
||||
|
||||
@routes.get("/v2/customnode/fetch_updates")
|
||||
@routes.get("/customnode/fetch_updates")
|
||||
async def fetch_updates(request):
|
||||
try:
|
||||
if request.rel_url.query["mode"] == "local":
|
||||
@@ -900,13 +722,8 @@ async def fetch_updates(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/update_all")
|
||||
@routes.get("/manager/queue/update_all")
|
||||
async def update_all(request):
|
||||
json_data = dict(request.rel_url.query)
|
||||
return await _update_all(json_data)
|
||||
|
||||
|
||||
async def _update_all(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
@@ -918,13 +735,13 @@ async def _update_all(json_data):
|
||||
|
||||
await core.save_snapshot_with_postfix('autosave')
|
||||
|
||||
if json_data["mode"] == "local":
|
||||
if request.rel_url.query["mode"] == "local":
|
||||
channel = 'local'
|
||||
else:
|
||||
channel = core.get_config()['channel_url']
|
||||
|
||||
await core.unified_manager.reload(json_data["mode"])
|
||||
await core.unified_manager.get_custom_nodes(channel, json_data["mode"])
|
||||
await core.unified_manager.reload(request.rel_url.query["mode"])
|
||||
await core.unified_manager.get_custom_nodes(channel, request.rel_url.query["mode"])
|
||||
|
||||
for k, v in core.unified_manager.active_nodes.items():
|
||||
if k == 'comfyui-manager':
|
||||
@@ -933,7 +750,7 @@ async def _update_all(json_data):
|
||||
continue
|
||||
|
||||
update_item = k, k, v[0]
|
||||
temp_queue_batch.append(("update-main", update_item))
|
||||
task_queue.put(("update-main", update_item))
|
||||
|
||||
for k, v in core.unified_manager.unknown_active_nodes.items():
|
||||
if k == 'comfyui-manager':
|
||||
@@ -942,7 +759,7 @@ async def _update_all(json_data):
|
||||
continue
|
||||
|
||||
update_item = k, k, 'unknown'
|
||||
temp_queue_batch.append(("update-main", update_item))
|
||||
task_queue.put(("update-main", update_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
@@ -993,7 +810,7 @@ def populate_markdown(x):
|
||||
|
||||
# freeze imported version
|
||||
startup_time_installed_node_packs = core.get_installed_node_packs()
|
||||
@routes.get("/v2/customnode/installed")
|
||||
@routes.get("/customnode/installed")
|
||||
async def installed_list(request):
|
||||
mode = request.query.get('mode', 'default')
|
||||
|
||||
@@ -1005,7 +822,7 @@ async def installed_list(request):
|
||||
return web.json_response(res, content_type='application/json')
|
||||
|
||||
|
||||
@routes.get("/v2/customnode/getlist")
|
||||
@routes.get("/customnode/getlist")
|
||||
async def fetch_customnode_list(request):
|
||||
"""
|
||||
provide unified custom node list
|
||||
@@ -1118,7 +935,7 @@ def check_model_installed(json_obj):
|
||||
executor.submit(process_model_phase, item)
|
||||
|
||||
|
||||
@routes.get("/v2/externalmodel/getlist")
|
||||
@routes.get("/externalmodel/getlist")
|
||||
async def fetch_externalmodel_list(request):
|
||||
# The model list is only allowed in the default channel, yet.
|
||||
json_obj = await core.get_data_by_mode(request.rel_url.query["mode"], 'model-list.json')
|
||||
@@ -1131,14 +948,14 @@ async def fetch_externalmodel_list(request):
|
||||
return web.json_response(json_obj, content_type='application/json')
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/snapshot/getlist")
|
||||
@PromptServer.instance.routes.get("/snapshot/getlist")
|
||||
async def get_snapshot_list(request):
|
||||
items = [f[:-5] for f in os.listdir(core.manager_snapshot_path) if f.endswith('.json')]
|
||||
items.sort(reverse=True)
|
||||
return web.json_response({'items': items}, content_type='application/json')
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/remove")
|
||||
@routes.get("/snapshot/remove")
|
||||
async def remove_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
@@ -1156,7 +973,7 @@ async def remove_snapshot(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/restore")
|
||||
@routes.get("/snapshot/restore")
|
||||
async def restore_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
@@ -1182,7 +999,7 @@ async def restore_snapshot(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/get_current")
|
||||
@routes.get("/snapshot/get_current")
|
||||
async def get_current_snapshot_api(request):
|
||||
try:
|
||||
return web.json_response(await core.get_current_snapshot(), content_type='application/json')
|
||||
@@ -1190,7 +1007,7 @@ async def get_current_snapshot_api(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/snapshot/save")
|
||||
@routes.get("/snapshot/save")
|
||||
async def save_snapshot(request):
|
||||
try:
|
||||
await core.save_snapshot_with_postfix('snapshot')
|
||||
@@ -1227,7 +1044,82 @@ def unzip_install(files):
|
||||
return True
|
||||
|
||||
|
||||
@routes.get("/v2/customnode/versions/{node_name}")
|
||||
def copy_install(files, js_path_name=None):
|
||||
for url in files:
|
||||
if url.endswith("/"):
|
||||
url = url[:-1]
|
||||
try:
|
||||
filename = os.path.basename(url)
|
||||
if url.endswith(".py"):
|
||||
download_url(url, core.get_default_custom_nodes_path(), filename)
|
||||
else:
|
||||
path = os.path.join(core.js_path, js_path_name) if js_path_name is not None else core.js_path
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
download_url(url, path, filename)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Install(copy) error: {url} / {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
logging.info("Installation was successful.")
|
||||
return True
|
||||
|
||||
|
||||
def copy_uninstall(files, js_path_name='.'):
|
||||
for url in files:
|
||||
if url.endswith("/"):
|
||||
url = url[:-1]
|
||||
dir_name = os.path.basename(url)
|
||||
base_path = core.get_default_custom_nodes_path() if url.endswith('.py') else os.path.join(core.js_path, js_path_name)
|
||||
file_path = os.path.join(base_path, dir_name)
|
||||
|
||||
try:
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
elif os.path.exists(file_path + ".disabled"):
|
||||
os.remove(file_path + ".disabled")
|
||||
except Exception as e:
|
||||
logging.error(f"Uninstall(copy) error: {url} / {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
logging.info("Uninstallation was successful.")
|
||||
return True
|
||||
|
||||
|
||||
def copy_set_active(files, is_disable, js_path_name='.'):
|
||||
if is_disable:
|
||||
action_name = "Disable"
|
||||
else:
|
||||
action_name = "Enable"
|
||||
|
||||
for url in files:
|
||||
if url.endswith("/"):
|
||||
url = url[:-1]
|
||||
dir_name = os.path.basename(url)
|
||||
base_path = core.get_default_custom_nodes_path() if url.endswith('.py') else os.path.join(core.js_path, js_path_name)
|
||||
file_path = os.path.join(base_path, dir_name)
|
||||
|
||||
try:
|
||||
if is_disable:
|
||||
current_name = file_path
|
||||
new_name = file_path + ".disabled"
|
||||
else:
|
||||
current_name = file_path + ".disabled"
|
||||
new_name = file_path
|
||||
|
||||
os.rename(current_name, new_name)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"{action_name}(copy) error: {url} / {e}", file=sys.stderr)
|
||||
|
||||
return False
|
||||
|
||||
logging.info(f"{action_name} was successful.")
|
||||
return True
|
||||
|
||||
|
||||
@routes.get("/customnode/versions/{node_name}")
|
||||
async def get_cnr_versions(request):
|
||||
node_name = request.match_info.get("node_name", None)
|
||||
versions = core.cnr_utils.all_versions_of_node(node_name)
|
||||
@@ -1238,7 +1130,7 @@ async def get_cnr_versions(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/customnode/disabled_versions/{node_name}")
|
||||
@routes.get("/customnode/disabled_versions/{node_name}")
|
||||
async def get_disabled_versions(request):
|
||||
node_name = request.match_info.get("node_name", None)
|
||||
versions = []
|
||||
@@ -1254,7 +1146,7 @@ async def get_disabled_versions(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/customnode/import_fail_info")
|
||||
@routes.post("/customnode/import_fail_info")
|
||||
async def import_fail_info(request):
|
||||
json_data = await request.json()
|
||||
|
||||
@@ -1271,74 +1163,42 @@ async def import_fail_info(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/reinstall")
|
||||
@routes.post("/manager/queue/reinstall")
|
||||
async def reinstall_custom_node(request):
|
||||
await uninstall_custom_node(request)
|
||||
await install_custom_node(request)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/reset")
|
||||
@routes.get("/manager/queue/reset")
|
||||
async def reset_queue(request):
|
||||
global task_batch_queue
|
||||
global temp_queue_batch
|
||||
|
||||
with task_worker_lock:
|
||||
temp_queue_batch = []
|
||||
task_batch_queue = deque()
|
||||
|
||||
global task_queue
|
||||
task_queue = queue.Queue()
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/abort_current")
|
||||
async def abort_queue(request):
|
||||
global task_batch_queue
|
||||
global temp_queue_batch
|
||||
|
||||
with task_worker_lock:
|
||||
temp_queue_batch = []
|
||||
if len(task_batch_queue) > 0:
|
||||
task_batch_queue[0].abort()
|
||||
task_batch_queue.popleft()
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/status")
|
||||
@routes.get("/manager/queue/status")
|
||||
async def queue_count(request):
|
||||
global task_queue
|
||||
|
||||
with task_worker_lock:
|
||||
if len(task_batch_queue) > 0:
|
||||
cur_batch = task_batch_queue[0]
|
||||
done_count = cur_batch.done_count()
|
||||
total_count = cur_batch.total_count()
|
||||
in_progress_count = len(tasks_in_progress)
|
||||
is_processing = task_worker_thread is not None and task_worker_thread.is_alive()
|
||||
else:
|
||||
done_count = 0
|
||||
total_count = 0
|
||||
in_progress_count = 0
|
||||
is_processing = False
|
||||
done_count = len(nodepack_result) + len(model_result)
|
||||
in_progress_count = len(tasks_in_progress)
|
||||
total_count = done_count + in_progress_count + task_queue.qsize()
|
||||
is_processing = task_worker_thread is not None and task_worker_thread.is_alive()
|
||||
|
||||
return web.json_response({
|
||||
'total_count': total_count,
|
||||
'done_count': done_count,
|
||||
'in_progress_count': in_progress_count,
|
||||
'total_count': total_count, 'done_count': done_count, 'in_progress_count': in_progress_count,
|
||||
'is_processing': is_processing})
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/install")
|
||||
@routes.post("/manager/queue/install")
|
||||
async def install_custom_node(request):
|
||||
json_data = await request.json()
|
||||
print(f"install={json_data}")
|
||||
return await _install_custom_node(json_data)
|
||||
|
||||
|
||||
async def _install_custom_node(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
# non-nightly cnr is safe
|
||||
risky_level = None
|
||||
cnr_id = json_data.get('id')
|
||||
@@ -1350,10 +1210,8 @@ async def _install_custom_node(json_data):
|
||||
if json_data['version'] != 'unknown' and selected_version != 'unknown':
|
||||
if skip_post_install:
|
||||
if cnr_id in core.unified_manager.nightly_inactive_nodes or cnr_id in core.unified_manager.cnr_inactive_nodes:
|
||||
enable_item = json_data.get('ui_id'), cnr_id
|
||||
temp_queue_batch.append(("enable", enable_item))
|
||||
core.unified_manager.unified_enable(cnr_id)
|
||||
return web.Response(status=200)
|
||||
|
||||
elif selected_version is None:
|
||||
selected_version = 'latest'
|
||||
|
||||
@@ -1366,11 +1224,9 @@ async def _install_custom_node(json_data):
|
||||
if git_url is None:
|
||||
logging.error(f"[ComfyUI-Manager] Following node pack doesn't provide `nightly` version: ${git_url}")
|
||||
return web.Response(status=404, text=f"Following node pack doesn't provide `nightly` version: ${git_url}")
|
||||
|
||||
elif json_data['version'] != 'unknown' and selected_version == 'unknown':
|
||||
logging.error(f"[ComfyUI-Manager] Invalid installation request: {json_data}")
|
||||
return web.Response(status=400, text="Invalid installation request")
|
||||
|
||||
else:
|
||||
# unknown
|
||||
unknown_name = os.path.basename(json_data['files'][0])
|
||||
@@ -1389,42 +1245,39 @@ async def _install_custom_node(json_data):
|
||||
return web.Response(status=404, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
install_item = json_data.get('ui_id'), node_spec_str, json_data['channel'], json_data['mode'], skip_post_install
|
||||
temp_queue_batch.append(("install", install_item))
|
||||
task_queue.put(("install", install_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
task_worker_thread:threading.Thread = None
|
||||
|
||||
@routes.get("/v2/manager/queue/start")
|
||||
@routes.get("/manager/queue/start")
|
||||
async def queue_start(request):
|
||||
with task_worker_lock:
|
||||
finalize_temp_queue_batch()
|
||||
return _queue_start()
|
||||
|
||||
def _queue_start():
|
||||
global nodepack_result
|
||||
global model_result
|
||||
global task_worker_thread
|
||||
|
||||
if task_worker_thread is not None and task_worker_thread.is_alive():
|
||||
return web.Response(status=201) # already in-progress
|
||||
|
||||
nodepack_result = {}
|
||||
model_result = {}
|
||||
|
||||
task_worker_thread = threading.Thread(target=lambda: asyncio.run(task_worker()))
|
||||
task_worker_thread.start()
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/fix")
|
||||
@routes.post("/manager/queue/fix")
|
||||
async def fix_custom_node(request):
|
||||
json_data = await request.json()
|
||||
return await _fix_custom_node(json_data)
|
||||
|
||||
|
||||
async def _fix_custom_node(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_GENERAL)
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
node_id = json_data.get('id')
|
||||
node_ver = json_data['version']
|
||||
if node_ver != 'unknown':
|
||||
@@ -1434,12 +1287,12 @@ async def _fix_custom_node(json_data):
|
||||
node_name = os.path.basename(json_data['files'][0])
|
||||
|
||||
update_item = json_data.get('ui_id'), node_name, json_data['version']
|
||||
temp_queue_batch.append(("fix", update_item))
|
||||
task_queue.put(("fix", update_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.post("/v2/customnode/install/git_url")
|
||||
@routes.post("/customnode/install/git_url")
|
||||
async def install_custom_node_git_url(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
logging.error(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
@@ -1459,7 +1312,7 @@ async def install_custom_node_git_url(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/customnode/install/pip")
|
||||
@routes.post("/customnode/install/pip")
|
||||
async def install_custom_node_pip(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
logging.error(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
@@ -1471,17 +1324,14 @@ async def install_custom_node_pip(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/uninstall")
|
||||
@routes.post("/manager/queue/uninstall")
|
||||
async def uninstall_custom_node(request):
|
||||
json_data = await request.json()
|
||||
return await _uninstall_custom_node(json_data)
|
||||
|
||||
|
||||
async def _uninstall_custom_node(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
node_id = json_data.get('id')
|
||||
if json_data['version'] != 'unknown':
|
||||
is_unknown = False
|
||||
@@ -1492,22 +1342,19 @@ async def _uninstall_custom_node(json_data):
|
||||
node_name = os.path.basename(json_data['files'][0])
|
||||
|
||||
uninstall_item = json_data.get('ui_id'), node_name, is_unknown
|
||||
temp_queue_batch.append(("uninstall", uninstall_item))
|
||||
task_queue.put(("uninstall", uninstall_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/update")
|
||||
@routes.post("/manager/queue/update")
|
||||
async def update_custom_node(request):
|
||||
json_data = await request.json()
|
||||
return await _update_custom_node(json_data)
|
||||
|
||||
|
||||
async def _update_custom_node(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
node_id = json_data.get('id')
|
||||
if json_data['version'] != 'unknown':
|
||||
node_name = node_id
|
||||
@@ -1516,19 +1363,19 @@ async def _update_custom_node(json_data):
|
||||
node_name = os.path.basename(json_data['files'][0])
|
||||
|
||||
update_item = json_data.get('ui_id'), node_name, json_data['version']
|
||||
temp_queue_batch.append(("update", update_item))
|
||||
task_queue.put(("update", update_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/queue/update_comfyui")
|
||||
@routes.get("/manager/queue/update_comfyui")
|
||||
async def update_comfyui(request):
|
||||
is_stable = core.get_config()['update_policy'] != 'nightly-comfyui'
|
||||
temp_queue_batch.append(("update-comfyui", ('comfyui', is_stable)))
|
||||
task_queue.put(("update-comfyui", ('comfyui', is_stable)))
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/comfyui_manager/comfyui_versions")
|
||||
@routes.get("/comfyui_manager/comfyui_versions")
|
||||
async def comfyui_versions(request):
|
||||
try:
|
||||
res, current, latest = core.get_comfyui_versions()
|
||||
@@ -1539,7 +1386,7 @@ async def comfyui_versions(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.get("/v2/comfyui_manager/comfyui_switch_version")
|
||||
@routes.get("/comfyui_manager/comfyui_switch_version")
|
||||
async def comfyui_switch_version(request):
|
||||
try:
|
||||
if "ver" in request.rel_url.query:
|
||||
@@ -1552,14 +1399,10 @@ async def comfyui_switch_version(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/disable")
|
||||
@routes.post("/manager/queue/disable")
|
||||
async def disable_node(request):
|
||||
json_data = await request.json()
|
||||
await _disable_node(json_data)
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
async def _disable_node(json_data):
|
||||
node_id = json_data.get('id')
|
||||
if json_data['version'] != 'unknown':
|
||||
is_unknown = False
|
||||
@@ -1570,7 +1413,9 @@ async def _disable_node(json_data):
|
||||
node_name = os.path.basename(json_data['files'][0])
|
||||
|
||||
update_item = json_data.get('ui_id'), node_name, is_unknown
|
||||
temp_queue_batch.append(("disable", update_item))
|
||||
task_queue.put(("disable", update_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
async def check_whitelist_for_model(item):
|
||||
@@ -1589,13 +1434,10 @@ async def check_whitelist_for_model(item):
|
||||
return False
|
||||
|
||||
|
||||
@routes.post("/v2/manager/queue/install_model")
|
||||
@routes.post("/manager/queue/install_model")
|
||||
async def install_model(request):
|
||||
json_data = await request.json()
|
||||
return await _install_model(json_data)
|
||||
|
||||
|
||||
async def _install_model(json_data):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
@@ -1619,12 +1461,12 @@ async def _install_model(json_data):
|
||||
return web.Response(status=403, text="A security error has occurred. Please check the terminal logs")
|
||||
|
||||
install_item = json_data.get('ui_id'), json_data
|
||||
temp_queue_batch.append(("install-model", install_item))
|
||||
task_queue.put(("install-model", install_item))
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/preview_method")
|
||||
@routes.get("/manager/preview_method")
|
||||
async def preview_method(request):
|
||||
if "value" in request.rel_url.query:
|
||||
set_preview_method(request.rel_url.query['value'])
|
||||
@@ -1635,7 +1477,7 @@ async def preview_method(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/db_mode")
|
||||
@routes.get("/manager/db_mode")
|
||||
async def db_mode(request):
|
||||
if "value" in request.rel_url.query:
|
||||
set_db_mode(request.rel_url.query['value'])
|
||||
@@ -1647,7 +1489,7 @@ async def db_mode(request):
|
||||
|
||||
|
||||
|
||||
@routes.get("/v2/manager/policy/component")
|
||||
@routes.get("/manager/policy/component")
|
||||
async def component_policy(request):
|
||||
if "value" in request.rel_url.query:
|
||||
set_component_policy(request.rel_url.query['value'])
|
||||
@@ -1658,7 +1500,7 @@ async def component_policy(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/policy/update")
|
||||
@routes.get("/manager/policy/update")
|
||||
async def update_policy(request):
|
||||
if "value" in request.rel_url.query:
|
||||
set_update_policy(request.rel_url.query['value'])
|
||||
@@ -1669,7 +1511,7 @@ async def update_policy(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/channel_url_list")
|
||||
@routes.get("/manager/channel_url_list")
|
||||
async def channel_url_list(request):
|
||||
channels = core.get_channel_dict()
|
||||
if "value" in request.rel_url.query:
|
||||
@@ -1706,7 +1548,7 @@ def add_target_blank(html_text):
|
||||
return modified_html
|
||||
|
||||
|
||||
@routes.get("/v2/manager/notice")
|
||||
@routes.get("/manager/notice")
|
||||
async def get_notice(request):
|
||||
url = "github.com"
|
||||
path = "/ltdrdata/ltdrdata.github.io/wiki/News"
|
||||
@@ -1753,13 +1595,7 @@ async def get_notice(request):
|
||||
return web.Response(text="Unable to retrieve Notice", status=200)
|
||||
|
||||
|
||||
# legacy /manager/notice
|
||||
@routes.get("/manager/notice")
|
||||
async def get_notice_legacy(request):
|
||||
return web.Response(text="""<font color="red">Starting from ComfyUI-Manager V4.0+, it should be installed via pip.<BR><BR>Please remove the ComfyUI-Manager installed in the <font color="white">'custom_nodes'</font> directory.</font>""", status=200)
|
||||
|
||||
|
||||
@routes.get("/v2/manager/reboot")
|
||||
@routes.get("/manager/reboot")
|
||||
def restart(self):
|
||||
if not is_allowed_security_level('middle'):
|
||||
logging.error(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
@@ -1796,7 +1632,7 @@ def restart(self):
|
||||
return os.execv(sys.executable, cmds)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/component/save")
|
||||
@routes.post("/manager/component/save")
|
||||
async def save_component(request):
|
||||
try:
|
||||
data = await request.json()
|
||||
@@ -1826,7 +1662,7 @@ async def save_component(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@routes.post("/v2/manager/component/loads")
|
||||
@routes.post("/manager/component/loads")
|
||||
async def load_components(request):
|
||||
if os.path.exists(core.manager_components_path):
|
||||
try:
|
||||
@@ -1851,7 +1687,7 @@ async def load_components(request):
|
||||
return web.json_response({})
|
||||
|
||||
|
||||
@routes.get("/v2/manager/version")
|
||||
@routes.get("/manager/version")
|
||||
async def get_version(request):
|
||||
return web.Response(text=core.version_str, status=200)
|
||||
|
||||
@@ -1900,7 +1736,7 @@ async def default_cache_update():
|
||||
logging.error(f"[ComfyUI-Manager] Failed to perform initial fetching '{filename}': {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
if core.get_config()['network_mode'] != 'offline' and not manager_util.is_manager_pip_package():
|
||||
if core.get_config()['network_mode'] != 'offline':
|
||||
a = get_cache("custom-node-list.json")
|
||||
b = get_cache("extension-node-map.json")
|
||||
c = get_cache("model-list.json")
|
||||
@@ -1915,8 +1751,6 @@ async def default_cache_update():
|
||||
# load at least once
|
||||
await core.unified_manager.reload('remote', dont_wait=False)
|
||||
await core.unified_manager.get_custom_nodes(channel_url, 'remote')
|
||||
else:
|
||||
await core.unified_manager.reload('remote', dont_wait=False, update_cnr_map=False)
|
||||
|
||||
logging.info("[ComfyUI-Manager] All startup tasks have been completed.")
|
||||
|
||||
@@ -1934,3 +1768,4 @@ cm_global.register_extension('ComfyUI-Manager',
|
||||
'nodes': {},
|
||||
'description': 'This extension provides the ability to manage custom nodes in ComfyUI.', })
|
||||
|
||||
|
||||
@@ -18,15 +18,12 @@ import shlex
|
||||
|
||||
|
||||
cache_lock = threading.Lock()
|
||||
session_lock = threading.Lock()
|
||||
|
||||
comfyui_manager_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
cache_dir = os.path.join(comfyui_manager_path, '.cache') # This path is also updated together in **manager_core.update_user_directory**.
|
||||
|
||||
use_uv = False
|
||||
|
||||
def is_manager_pip_package():
|
||||
return not os.path.exists(os.path.join(comfyui_manager_path, '..', 'custom_nodes'))
|
||||
|
||||
def add_python_path_to_env():
|
||||
if platform.system() != "Windows":
|
||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
import os
|
||||
|
||||
from .git_utils import get_commit_hash
|
||||
from git_utils import get_commit_hash
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -1,6 +1,5 @@
|
||||
import mimetypes
|
||||
from . import manager_core as core
|
||||
|
||||
import manager_core as core
|
||||
import os
|
||||
from aiohttp import web
|
||||
import aiohttp
|
||||
@@ -54,7 +53,7 @@ def compute_sha256_checksum(filepath):
|
||||
return sha256.hexdigest()
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/share_option")
|
||||
@PromptServer.instance.routes.get("/manager/share_option")
|
||||
async def share_option(request):
|
||||
if "value" in request.rel_url.query:
|
||||
core.get_config()['share_option'] = request.rel_url.query['value']
|
||||
@@ -123,7 +122,7 @@ def set_youml_settings(settings):
|
||||
f.write(settings)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_openart_auth")
|
||||
@PromptServer.instance.routes.get("/manager/get_openart_auth")
|
||||
async def api_get_openart_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
openart_key = get_openart_auth()
|
||||
@@ -132,7 +131,7 @@ async def api_get_openart_auth(request):
|
||||
return web.json_response({"openart_key": openart_key})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/v2/manager/set_openart_auth")
|
||||
@PromptServer.instance.routes.post("/manager/set_openart_auth")
|
||||
async def api_set_openart_auth(request):
|
||||
json_data = await request.json()
|
||||
openart_key = json_data['openart_key']
|
||||
@@ -141,7 +140,7 @@ async def api_set_openart_auth(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_matrix_auth")
|
||||
@PromptServer.instance.routes.get("/manager/get_matrix_auth")
|
||||
async def api_get_matrix_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
matrix_auth = get_matrix_auth()
|
||||
@@ -150,7 +149,7 @@ async def api_get_matrix_auth(request):
|
||||
return web.json_response(matrix_auth)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/youml/settings")
|
||||
@PromptServer.instance.routes.get("/manager/youml/settings")
|
||||
async def api_get_youml_settings(request):
|
||||
youml_settings = get_youml_settings()
|
||||
if not youml_settings:
|
||||
@@ -158,14 +157,14 @@ async def api_get_youml_settings(request):
|
||||
return web.json_response(json.loads(youml_settings))
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/v2/manager/youml/settings")
|
||||
@PromptServer.instance.routes.post("/manager/youml/settings")
|
||||
async def api_set_youml_settings(request):
|
||||
json_data = await request.json()
|
||||
set_youml_settings(json.dumps(json_data))
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_comfyworkflows_auth")
|
||||
@PromptServer.instance.routes.get("/manager/get_comfyworkflows_auth")
|
||||
async def api_get_comfyworkflows_auth(request):
|
||||
# Check if the user has provided Matrix credentials in a file called 'matrix_accesstoken'
|
||||
# in the same directory as the ComfyUI base folder
|
||||
@@ -176,7 +175,7 @@ async def api_get_comfyworkflows_auth(request):
|
||||
return web.json_response({"comfyworkflows_sharekey": comfyworkflows_auth})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/v2/manager/set_esheep_workflow_and_images")
|
||||
@PromptServer.instance.routes.post("/manager/set_esheep_workflow_and_images")
|
||||
async def set_esheep_workflow_and_images(request):
|
||||
json_data = await request.json()
|
||||
with open(os.path.join(core.manager_files_path, "esheep_share_message.json"), "w", encoding='utf-8') as file:
|
||||
@@ -184,7 +183,7 @@ async def set_esheep_workflow_and_images(request):
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/v2/manager/get_esheep_workflow_and_images")
|
||||
@PromptServer.instance.routes.get("/manager/get_esheep_workflow_and_images")
|
||||
async def get_esheep_workflow_and_images(request):
|
||||
with open(os.path.join(core.manager_files_path, "esheep_share_message.json"), 'r', encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
@@ -212,7 +211,7 @@ def has_provided_comfyworkflows_auth(comfyworkflows_sharekey):
|
||||
return comfyworkflows_sharekey.strip()
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/v2/manager/share")
|
||||
@PromptServer.instance.routes.post("/manager/share")
|
||||
async def share_art(request):
|
||||
# get json data
|
||||
json_data = await request.json()
|
||||
@@ -25,7 +25,7 @@ async function tryInstallCustomNode(event) {
|
||||
const res = await customConfirm(msg);
|
||||
if(res) {
|
||||
if(event.detail.target.installed == 'Disabled') {
|
||||
const response = await api.fetchApi(`/v2/customnode/toggle_active`, {
|
||||
const response = await api.fetchApi(`/customnode/toggle_active`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(event.detail.target)
|
||||
@@ -35,7 +35,7 @@ async function tryInstallCustomNode(event) {
|
||||
await sleep(300);
|
||||
app.ui.dialog.show(`Installing... '${event.detail.target.title}'`);
|
||||
|
||||
const response = await api.fetchApi(`/v2/customnode/install`, {
|
||||
const response = await api.fetchApi(`/customnode/install`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(event.detail.target)
|
||||
@@ -52,7 +52,7 @@ async function tryInstallCustomNode(event) {
|
||||
}
|
||||
}
|
||||
|
||||
let response = await api.fetchApi("/v2/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;
|
||||
@@ -14,9 +14,9 @@ import { OpenArtShareDialog } from "./comfyui-share-openart.js";
|
||||
import {
|
||||
free_models, install_pip, install_via_git_url, manager_instance,
|
||||
rebootAPI, setManagerInstance, show_message, customAlert, customPrompt,
|
||||
infoToast, showTerminal, setNeedRestart, generateUUID
|
||||
infoToast, showTerminal, setNeedRestart
|
||||
} from "./common.js";
|
||||
import { ComponentBuilderDialog, load_components, set_component_policy } from "./components-manager.js";
|
||||
import { ComponentBuilderDialog, getPureName, load_components, set_component_policy } from "./components-manager.js";
|
||||
import { CustomNodesManager } from "./custom-nodes-manager.js";
|
||||
import { ModelManager } from "./model-manager.js";
|
||||
import { SnapshotManager } from "./snapshot.js";
|
||||
@@ -189,7 +189,8 @@ docStyle.innerHTML = `
|
||||
}
|
||||
`;
|
||||
|
||||
function isBeforeFrontendVersion(compareVersion) {
|
||||
function is_legacy_front() {
|
||||
let compareVersion = '1.2.49';
|
||||
try {
|
||||
const frontendVersion = window['__COMFYUI_FRONTEND_VERSION__'];
|
||||
if (typeof frontendVersion !== 'string') {
|
||||
@@ -222,9 +223,6 @@ function isBeforeFrontendVersion(compareVersion) {
|
||||
}
|
||||
}
|
||||
|
||||
const is_legacy_front = () => isBeforeFrontendVersion('1.2.49');
|
||||
const isNotNewManagerUI = () => isBeforeFrontendVersion('1.16.4');
|
||||
|
||||
document.head.appendChild(docStyle);
|
||||
|
||||
var update_comfyui_button = null;
|
||||
@@ -234,7 +232,7 @@ var restart_stop_button = null;
|
||||
var update_policy_combo = null;
|
||||
|
||||
let share_option = 'all';
|
||||
var batch_id = null;
|
||||
var is_updating = false;
|
||||
|
||||
|
||||
// copied style from https://github.com/pythongosssss/ComfyUI-Custom-Scripts
|
||||
@@ -417,7 +415,7 @@ const style = `
|
||||
`;
|
||||
|
||||
async function init_share_option() {
|
||||
api.fetchApi('/v2/manager/share_option')
|
||||
api.fetchApi('/manager/share_option')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
share_option = data || 'all';
|
||||
@@ -425,7 +423,7 @@ async function init_share_option() {
|
||||
}
|
||||
|
||||
async function init_notice(notice) {
|
||||
api.fetchApi('/v2/manager/notice')
|
||||
api.fetchApi('/manager/notice')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
notice.innerHTML = data;
|
||||
@@ -476,19 +474,14 @@ async function updateComfyUI() {
|
||||
let prev_text = update_comfyui_button.innerText;
|
||||
update_comfyui_button.innerText = "Updating ComfyUI...";
|
||||
|
||||
// set_inprogress_mode();
|
||||
set_inprogress_mode();
|
||||
|
||||
const response = await api.fetchApi('/manager/queue/update_comfyui');
|
||||
|
||||
showTerminal();
|
||||
|
||||
batch_id = generateUUID();
|
||||
|
||||
let batch = {};
|
||||
batch['batch_id'] = batch_id;
|
||||
batch['update_comfyui'] = true;
|
||||
|
||||
const res = await api.fetchApi(`/v2/manager/queue/batch`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(batch)
|
||||
});
|
||||
is_updating = true;
|
||||
await api.fetchApi('/manager/queue/start');
|
||||
}
|
||||
|
||||
function showVersionSelectorDialog(versions, current, onSelect) {
|
||||
@@ -619,7 +612,7 @@ async function switchComfyUI() {
|
||||
switch_comfyui_button.disabled = true;
|
||||
switch_comfyui_button.style.backgroundColor = "gray";
|
||||
|
||||
let res = await api.fetchApi(`/v2/comfyui_manager/comfyui_versions`, { cache: "no-store" });
|
||||
let res = await api.fetchApi(`/comfyui_manager/comfyui_versions`, { cache: "no-store" });
|
||||
|
||||
switch_comfyui_button.disabled = false;
|
||||
switch_comfyui_button.style.backgroundColor = "";
|
||||
@@ -638,14 +631,14 @@ async function switchComfyUI() {
|
||||
showVersionSelectorDialog(versions, obj.current, async (selected_version) => {
|
||||
if(selected_version == 'nightly') {
|
||||
update_policy_combo.value = 'nightly-comfyui';
|
||||
api.fetchApi('/v2/manager/policy/update?value=nightly-comfyui');
|
||||
api.fetchApi('/manager/policy/update?value=nightly-comfyui');
|
||||
}
|
||||
else {
|
||||
update_policy_combo.value = 'stable-comfyui';
|
||||
api.fetchApi('/v2/manager/policy/update?value=stable-comfyui');
|
||||
api.fetchApi('/manager/policy/update?value=stable-comfyui');
|
||||
}
|
||||
|
||||
let response = await api.fetchApi(`/v2/comfyui_manager/comfyui_switch_version?ver=${selected_version}`, { cache: "no-store" });
|
||||
let response = await api.fetchApi(`/comfyui_manager/comfyui_switch_version?ver=${selected_version}`, { cache: "no-store" });
|
||||
if (response.status == 200) {
|
||||
infoToast(`ComfyUI version is switched to ${selected_version}`);
|
||||
}
|
||||
@@ -663,17 +656,18 @@ async function onQueueStatus(event) {
|
||||
const isElectron = 'electronAPI' in window;
|
||||
|
||||
if(event.detail.status == 'in_progress') {
|
||||
// set_inprogress_mode();
|
||||
set_inprogress_mode();
|
||||
update_all_button.innerText = `in progress.. (${event.detail.done_count}/${event.detail.total_count})`;
|
||||
}
|
||||
else if(event.detail.status == 'all-done') {
|
||||
else if(event.detail.status == 'done') {
|
||||
reset_action_buttons();
|
||||
}
|
||||
else if(event.detail.status == 'batch-done') {
|
||||
if(batch_id != event.detail.batch_id) {
|
||||
|
||||
if(!is_updating) {
|
||||
return;
|
||||
}
|
||||
|
||||
is_updating = false;
|
||||
|
||||
let success_list = [];
|
||||
let failed_list = [];
|
||||
let comfyui_state = null;
|
||||
@@ -773,28 +767,41 @@ api.addEventListener("cm-queue-status", onQueueStatus);
|
||||
async function updateAll(update_comfyui) {
|
||||
update_all_button.innerText = "Updating...";
|
||||
|
||||
// set_inprogress_mode();
|
||||
set_inprogress_mode();
|
||||
|
||||
var mode = manager_instance.datasrc_combo.value;
|
||||
|
||||
showTerminal();
|
||||
|
||||
batch_id = generateUUID();
|
||||
|
||||
let batch = {};
|
||||
if(update_comfyui) {
|
||||
update_all_button.innerText = "Updating ComfyUI...";
|
||||
batch['update_comfyui'] = true;
|
||||
await api.fetchApi('/manager/queue/update_comfyui');
|
||||
}
|
||||
|
||||
batch['update_all'] = mode;
|
||||
const response = await api.fetchApi(`/manager/queue/update_all?mode=${mode}`);
|
||||
|
||||
const res = await api.fetchApi(`/v2/manager/queue/batch`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(batch)
|
||||
});
|
||||
if (response.status == 401) {
|
||||
customAlert('Another task is already in progress. Please stop the ongoing task first.');
|
||||
}
|
||||
else if(response.status == 200) {
|
||||
is_updating = true;
|
||||
await api.fetchApi('/manager/queue/start');
|
||||
}
|
||||
}
|
||||
|
||||
function newDOMTokenList(initialTokens) {
|
||||
const tmp = document.createElement(`div`);
|
||||
|
||||
const classList = tmp.classList;
|
||||
if (initialTokens) {
|
||||
initialTokens.forEach(token => {
|
||||
classList.add(token);
|
||||
});
|
||||
}
|
||||
|
||||
return classList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the node is a potential output node (img, gif or video output)
|
||||
*/
|
||||
@@ -807,7 +814,7 @@ function restartOrStop() {
|
||||
rebootAPI();
|
||||
}
|
||||
else {
|
||||
api.fetchApi('/v2/manager/queue/reset');
|
||||
api.fetchApi('/manager/queue/reset');
|
||||
infoToast('Cancel', 'Remaining tasks will stop after completing the current task.');
|
||||
}
|
||||
}
|
||||
@@ -955,12 +962,12 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
this.datasrc_combo.appendChild($el('option', { value: 'local', text: 'DB: Local' }, []));
|
||||
this.datasrc_combo.appendChild($el('option', { value: 'remote', text: 'DB: Channel (remote)' }, []));
|
||||
|
||||
api.fetchApi('/v2/manager/db_mode')
|
||||
api.fetchApi('/manager/db_mode')
|
||||
.then(response => response.text())
|
||||
.then(data => { this.datasrc_combo.value = data; });
|
||||
|
||||
this.datasrc_combo.addEventListener('change', function (event) {
|
||||
api.fetchApi(`/v2/manager/db_mode?value=${event.target.value}`);
|
||||
api.fetchApi(`/manager/db_mode?value=${event.target.value}`);
|
||||
});
|
||||
|
||||
// preview method
|
||||
@@ -972,19 +979,19 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
preview_combo.appendChild($el('option', { value: 'latent2rgb', text: 'Preview method: Latent2RGB (fast)' }, []));
|
||||
preview_combo.appendChild($el('option', { value: 'none', text: 'Preview method: None (very fast)' }, []));
|
||||
|
||||
api.fetchApi('/v2/manager/preview_method')
|
||||
api.fetchApi('/manager/preview_method')
|
||||
.then(response => response.text())
|
||||
.then(data => { preview_combo.value = data; });
|
||||
|
||||
preview_combo.addEventListener('change', function (event) {
|
||||
api.fetchApi(`/v2/manager/preview_method?value=${event.target.value}`);
|
||||
api.fetchApi(`/manager/preview_method?value=${event.target.value}`);
|
||||
});
|
||||
|
||||
// channel
|
||||
let channel_combo = document.createElement("select");
|
||||
channel_combo.setAttribute("title", "Configure the channel for retrieving data from the Custom Node list (including missing nodes) or the Model list.");
|
||||
channel_combo.className = "cm-menu-combo";
|
||||
api.fetchApi('/v2/manager/channel_url_list')
|
||||
api.fetchApi('/manager/channel_url_list')
|
||||
.then(response => response.json())
|
||||
.then(async data => {
|
||||
try {
|
||||
@@ -997,7 +1004,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
}
|
||||
|
||||
channel_combo.addEventListener('change', function (event) {
|
||||
api.fetchApi(`/v2/manager/channel_url_list?value=${event.target.value}`);
|
||||
api.fetchApi(`/manager/channel_url_list?value=${event.target.value}`);
|
||||
});
|
||||
|
||||
channel_combo.value = data.selected;
|
||||
@@ -1025,7 +1032,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
share_combo.appendChild($el('option', { value: option[0], text: `Share: ${option[1]}` }, []));
|
||||
}
|
||||
|
||||
api.fetchApi('/v2/manager/share_option')
|
||||
api.fetchApi('/manager/share_option')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
share_combo.value = data || 'all';
|
||||
@@ -1035,7 +1042,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
share_combo.addEventListener('change', function (event) {
|
||||
const value = event.target.value;
|
||||
share_option = value;
|
||||
api.fetchApi(`/v2/manager/share_option?value=${value}`);
|
||||
api.fetchApi(`/manager/share_option?value=${value}`);
|
||||
const shareButton = document.getElementById("shareButton");
|
||||
if (value === 'none') {
|
||||
shareButton.style.display = "none";
|
||||
@@ -1050,7 +1057,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
component_policy_combo.appendChild($el('option', { value: 'workflow', text: 'Component: Use workflow version' }, []));
|
||||
component_policy_combo.appendChild($el('option', { value: 'higher', text: 'Component: Use higher version' }, []));
|
||||
component_policy_combo.appendChild($el('option', { value: 'mine', text: 'Component: Use my version' }, []));
|
||||
api.fetchApi('/v2/manager/policy/component')
|
||||
api.fetchApi('/manager/policy/component')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
component_policy_combo.value = data;
|
||||
@@ -1058,7 +1065,7 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
});
|
||||
|
||||
component_policy_combo.addEventListener('change', function (event) {
|
||||
api.fetchApi(`/v2/manager/policy/component?value=${event.target.value}`);
|
||||
api.fetchApi(`/manager/policy/component?value=${event.target.value}`);
|
||||
set_component_policy(event.target.value);
|
||||
});
|
||||
|
||||
@@ -1071,14 +1078,14 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
update_policy_combo.className = "cm-menu-combo";
|
||||
update_policy_combo.appendChild($el('option', { value: 'stable-comfyui', text: 'Update: ComfyUI Stable Version' }, []));
|
||||
update_policy_combo.appendChild($el('option', { value: 'nightly-comfyui', text: 'Update: ComfyUI Nightly Version' }, []));
|
||||
api.fetchApi('/v2/manager/policy/update')
|
||||
api.fetchApi('/manager/policy/update')
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
update_policy_combo.value = data;
|
||||
});
|
||||
|
||||
update_policy_combo.addEventListener('change', function (event) {
|
||||
api.fetchApi(`/v2/manager/policy/update?value=${event.target.value}`);
|
||||
api.fetchApi(`/manager/policy/update?value=${event.target.value}`);
|
||||
});
|
||||
|
||||
return [
|
||||
@@ -1381,12 +1388,12 @@ class ManagerMenuDialog extends ComfyDialog {
|
||||
}
|
||||
|
||||
async function getVersion() {
|
||||
let version = await api.fetchApi(`/v2/manager/version`);
|
||||
let version = await api.fetchApi(`/manager/version`);
|
||||
return await version.text();
|
||||
}
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.Legacy.ManagerMenu",
|
||||
name: "Comfy.ManagerMenu",
|
||||
|
||||
aboutPageBadges: [
|
||||
{
|
||||
@@ -1518,10 +1525,7 @@ app.registerExtension({
|
||||
}).element
|
||||
);
|
||||
|
||||
const shouldShowLegacyMenuItems = isNotNewManagerUI();
|
||||
if (shouldShowLegacyMenuItems) {
|
||||
app.menu?.settingsGroup.element.before(cmGroup.element);
|
||||
}
|
||||
app.menu?.settingsGroup.element.before(cmGroup.element);
|
||||
}
|
||||
catch(exception) {
|
||||
console.log('ComfyUI is outdated. New style menu based features are disabled.');
|
||||
@@ -172,7 +172,7 @@ export const shareToEsheep= () => {
|
||||
const nodes = app.graph._nodes
|
||||
const { potential_outputs, potential_output_nodes } = getPotentialOutputsAndOutputNodes(nodes);
|
||||
const workflow = prompt['workflow']
|
||||
api.fetchApi(`/v2/manager/set_esheep_workflow_and_images`, {
|
||||
api.fetchApi(`/manager/set_esheep_workflow_and_images`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -812,7 +812,7 @@ export class ShareDialog extends ComfyDialog {
|
||||
// get the user's existing matrix auth and share key
|
||||
ShareDialog.matrix_auth = { homeserver: "matrix.org", username: "", password: "" };
|
||||
try {
|
||||
api.fetchApi(`/v2/manager/get_matrix_auth`)
|
||||
api.fetchApi(`/manager/get_matrix_auth`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
ShareDialog.matrix_auth = data;
|
||||
@@ -831,7 +831,7 @@ export class ShareDialog extends ComfyDialog {
|
||||
ShareDialog.cw_sharekey = "";
|
||||
try {
|
||||
// console.log("Fetching comfyworkflows share key")
|
||||
api.fetchApi(`/v2/manager/get_comfyworkflows_auth`)
|
||||
api.fetchApi(`/manager/get_comfyworkflows_auth`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
ShareDialog.cw_sharekey = data.comfyworkflows_sharekey;
|
||||
@@ -891,7 +891,7 @@ export class ShareDialog extends ComfyDialog {
|
||||
// Change the text of the share button to "Sharing..." to indicate that the share process has started
|
||||
this.share_button.textContent = "Sharing...";
|
||||
|
||||
const response = await api.fetchApi(`/v2/manager/share`, {
|
||||
const response = await api.fetchApi(`/manager/share`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -67,7 +67,7 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
async readKey() {
|
||||
let key = ""
|
||||
try {
|
||||
key = await api.fetchApi(`/v2/manager/get_openart_auth`)
|
||||
key = await api.fetchApi(`/manager/get_openart_auth`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
return data.openart_key;
|
||||
@@ -82,7 +82,7 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
}
|
||||
|
||||
async saveKey(value) {
|
||||
await api.fetchApi(`/v2/manager/set_openart_auth`, {
|
||||
await api.fetchApi(`/manager/set_openart_auth`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
@@ -399,7 +399,7 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
form.append("file", uploadFile);
|
||||
try {
|
||||
const res = await this.fetchApi(
|
||||
`/v2/workflows/upload_thumbnail`,
|
||||
`/workflows/upload_thumbnail`,
|
||||
{
|
||||
method: "POST",
|
||||
body: form,
|
||||
@@ -459,7 +459,7 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
throw new Error("Title is required");
|
||||
}
|
||||
|
||||
const current_snapshot = await api.fetchApi(`/v2/snapshot/get_current`)
|
||||
const current_snapshot = await api.fetchApi(`/snapshot/get_current`)
|
||||
.then(response => response.json())
|
||||
.catch(error => {
|
||||
// console.log(error);
|
||||
@@ -489,7 +489,7 @@ export class OpenArtShareDialog extends ComfyDialog {
|
||||
|
||||
try {
|
||||
const response = await this.fetchApi(
|
||||
"/v2/workflows/publish",
|
||||
"/workflows/publish",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
@@ -179,7 +179,7 @@ export class YouMLShareDialog extends ComfyDialog {
|
||||
async loadToken() {
|
||||
let key = ""
|
||||
try {
|
||||
const response = await api.fetchApi(`/v2/manager/youml/settings`)
|
||||
const response = await api.fetchApi(`/manager/youml/settings`)
|
||||
const settings = await response.json()
|
||||
return settings.token
|
||||
} catch (error) {
|
||||
@@ -188,7 +188,7 @@ export class YouMLShareDialog extends ComfyDialog {
|
||||
}
|
||||
|
||||
async saveToken(value) {
|
||||
await api.fetchApi(`/v2/manager/youml/settings`, {
|
||||
await api.fetchApi(`/manager/youml/settings`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({
|
||||
@@ -380,7 +380,7 @@ export class YouMLShareDialog extends ComfyDialog {
|
||||
try {
|
||||
let snapshotData = null;
|
||||
try {
|
||||
const snapshot = await api.fetchApi(`/v2/snapshot/get_current`)
|
||||
const snapshot = await api.fetchApi(`/snapshot/get_current`)
|
||||
snapshotData = await snapshot.json()
|
||||
} catch (e) {
|
||||
console.error("Failed to get snapshot", e)
|
||||
@@ -172,7 +172,7 @@ export function rebootAPI() {
|
||||
customConfirm("Are you sure you'd like to reboot the server?").then((isConfirmed) => {
|
||||
if (isConfirmed) {
|
||||
try {
|
||||
api.fetchApi("/v2/manager/reboot");
|
||||
api.fetchApi("/manager/reboot");
|
||||
}
|
||||
catch(exception) {}
|
||||
}
|
||||
@@ -210,7 +210,7 @@ export async function install_pip(packages) {
|
||||
if(packages.includes('&'))
|
||||
app.ui.dialog.show(`Invalid PIP package enumeration: '${packages}'`);
|
||||
|
||||
const res = await api.fetchApi("/v2/customnode/install/pip", {
|
||||
const res = await api.fetchApi("/customnode/install/pip", {
|
||||
method: "POST",
|
||||
body: packages,
|
||||
});
|
||||
@@ -245,7 +245,7 @@ export async function install_via_git_url(url, manager_dialog) {
|
||||
|
||||
show_message(`Wait...<BR><BR>Installing '${url}'`);
|
||||
|
||||
const res = await api.fetchApi("/v2/customnode/install/git_url", {
|
||||
const res = await api.fetchApi("/customnode/install/git_url", {
|
||||
method: "POST",
|
||||
body: url,
|
||||
});
|
||||
@@ -630,14 +630,6 @@ export function showTooltip(target, text, className = 'cn-tooltip', styleMap = {
|
||||
});
|
||||
}
|
||||
|
||||
export function generateUUID() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
const r = Math.random() * 16 | 0;
|
||||
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
function initTooltip () {
|
||||
const mouseenterHandler = (e) => {
|
||||
const target = e.target;
|
||||
@@ -64,7 +64,7 @@ function storeGroupNode(name, data, register=true) {
|
||||
}
|
||||
|
||||
export async function load_components() {
|
||||
let data = await api.fetchApi('/v2/manager/component/loads', {method: "POST"});
|
||||
let data = await api.fetchApi('/manager/component/loads', {method: "POST"});
|
||||
let components = await data.json();
|
||||
|
||||
let start_time = Date.now();
|
||||
@@ -222,7 +222,7 @@ async function save_as_component(node, version, author, prefix, nodename, packna
|
||||
pack_map[packname] = component_name;
|
||||
rpack_map[component_name] = subgraph;
|
||||
|
||||
const res = await api.fetchApi('/v2/manager/component/save', {
|
||||
const res = await api.fetchApi('/manager/component/save', {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
@@ -259,7 +259,7 @@ async function import_component(component_name, component, mode) {
|
||||
workflow: component
|
||||
};
|
||||
|
||||
const res = await api.fetchApi('/v2/manager/component/save', {
|
||||
const res = await api.fetchApi('/manager/component/save', {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", },
|
||||
body: JSON.stringify(body)
|
||||
@@ -709,7 +709,7 @@ app.handleFile = handleFile;
|
||||
|
||||
let current_component_policy = 'workflow';
|
||||
try {
|
||||
api.fetchApi('/v2/manager/policy/component')
|
||||
api.fetchApi('/manager/policy/component')
|
||||
.then(response => response.text())
|
||||
.then(data => { current_component_policy = data; });
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
fetchData, md5, icons, show_message, customConfirm, customAlert, customPrompt,
|
||||
sanitizeHTML, infoToast, showTerminal, setNeedRestart,
|
||||
storeColumnWidth, restoreColumnWidth, getTimeAgo, copyText, loadCss,
|
||||
showPopover, hidePopover, generateUUID
|
||||
showPopover, hidePopover
|
||||
} from "./common.js";
|
||||
|
||||
// https://cenfun.github.io/turbogrid/api.html
|
||||
@@ -66,7 +66,7 @@ export class CustomNodesManager {
|
||||
this.id = "cn-manager";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.Legacy.CustomNodesManager",
|
||||
name: "Comfy.CustomNodesManager",
|
||||
afterConfigureGraph: (missingNodeTypes) => {
|
||||
const item = this.getFilterItem(ShowMode.MISSING);
|
||||
if (item) {
|
||||
@@ -459,7 +459,7 @@ export class CustomNodesManager {
|
||||
|
||||
".cn-manager-stop": {
|
||||
click: () => {
|
||||
api.fetchApi('/v2/manager/queue/reset');
|
||||
api.fetchApi('/manager/queue/reset');
|
||||
infoToast('Cancel', 'Remaining tasks will stop after completing the current task.');
|
||||
}
|
||||
},
|
||||
@@ -635,7 +635,7 @@ export class CustomNodesManager {
|
||||
};
|
||||
}
|
||||
|
||||
const response = await api.fetchApi(`/v2/customnode/import_fail_info`, {
|
||||
const response = await api.fetchApi(`/customnode/import_fail_info`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(info)
|
||||
@@ -1243,7 +1243,7 @@ export class CustomNodesManager {
|
||||
async loadNodes(node_packs) {
|
||||
const mode = manager_instance.datasrc_combo.value;
|
||||
this.showStatus(`Loading node mappings (${mode}) ...`);
|
||||
const res = await fetchData(`/v2/customnode/getmappings?mode=${mode}`);
|
||||
const res = await fetchData(`/customnode/getmappings?mode=${mode}`);
|
||||
if (res.error) {
|
||||
console.log(res.error);
|
||||
return;
|
||||
@@ -1395,10 +1395,10 @@ export class CustomNodesManager {
|
||||
this.showLoading();
|
||||
let res;
|
||||
if(is_enable) {
|
||||
res = await api.fetchApi(`/v2/customnode/disabled_versions/${node_id}`, { cache: "no-store" });
|
||||
res = await api.fetchApi(`/customnode/disabled_versions/${node_id}`, { cache: "no-store" });
|
||||
}
|
||||
else {
|
||||
res = await api.fetchApi(`/v2/customnode/versions/${node_id}`, { cache: "no-store" });
|
||||
res = await api.fetchApi(`/customnode/versions/${node_id}`, { cache: "no-store" });
|
||||
}
|
||||
this.hideLoading();
|
||||
|
||||
@@ -1410,15 +1410,16 @@ export class CustomNodesManager {
|
||||
let version_cnt = 0;
|
||||
|
||||
if(!is_enable) {
|
||||
|
||||
if(rowItem.cnr_latest != rowItem.originalData.active_version && obj.length > 0) {
|
||||
versions.push('latest');
|
||||
}
|
||||
|
||||
if(rowItem.originalData.active_version != 'nightly') {
|
||||
versions.push('nightly');
|
||||
default_version = 'nightly';
|
||||
version_cnt++;
|
||||
}
|
||||
|
||||
if(rowItem.cnr_latest != rowItem.originalData.active_version && obj.length > 0) {
|
||||
versions.push('latest');
|
||||
}
|
||||
}
|
||||
|
||||
for(let v of obj) {
|
||||
@@ -1439,6 +1440,13 @@ export class CustomNodesManager {
|
||||
}
|
||||
|
||||
async installNodes(list, btn, title, selected_version) {
|
||||
let stats = await api.fetchApi('/manager/queue/status');
|
||||
stats = await stats.json();
|
||||
if(stats.is_processing) {
|
||||
customAlert(`[ComfyUI-Manager] There are already tasks in progress. Please try again after it is completed. (${stats.done_count}/${stats.total_count})`);
|
||||
return;
|
||||
}
|
||||
|
||||
const { target, label, mode} = btn;
|
||||
|
||||
if(mode === "uninstall") {
|
||||
@@ -1465,9 +1473,9 @@ export class CustomNodesManager {
|
||||
let needRestart = false;
|
||||
let errorMsg = "";
|
||||
|
||||
let target_items = [];
|
||||
await api.fetchApi('/manager/queue/reset');
|
||||
|
||||
let batch = {};
|
||||
let target_items = [];
|
||||
|
||||
for (const hash of list) {
|
||||
const item = this.grid.getRowItemBy("hash", hash);
|
||||
@@ -1510,11 +1518,23 @@ export class CustomNodesManager {
|
||||
api_mode = 'reinstall';
|
||||
}
|
||||
|
||||
if(batch[api_mode]) {
|
||||
batch[api_mode].push(data);
|
||||
}
|
||||
else {
|
||||
batch[api_mode] = [data];
|
||||
const res = await api.fetchApi(`/manager/queue/${api_mode}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
if (res.status != 200) {
|
||||
errorMsg = `'${item.title}': `;
|
||||
|
||||
if(res.status == 403) {
|
||||
errorMsg += `This action is not allowed with this security level configuration.\n`;
|
||||
} else if(res.status == 404) {
|
||||
errorMsg += `With the current security level configuration, only custom nodes from the <B>"default channel"</B> can be installed.\n`;
|
||||
} else {
|
||||
errorMsg += await res.text() + '\n';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1531,24 +1551,7 @@ export class CustomNodesManager {
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.batch_id = generateUUID();
|
||||
batch['batch_id'] = this.batch_id;
|
||||
|
||||
const res = await api.fetchApi(`/v2/manager/queue/batch`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(batch)
|
||||
});
|
||||
|
||||
let failed = await res.json();
|
||||
|
||||
if(failed.length > 0) {
|
||||
for(let k in failed) {
|
||||
let hash = failed[k];
|
||||
const item = this.grid.getRowItemBy("hash", hash);
|
||||
errorMsg = `[FAIL] ${item.title}`;
|
||||
}
|
||||
}
|
||||
|
||||
await api.fetchApi('/manager/queue/start');
|
||||
this.showStop();
|
||||
showTerminal();
|
||||
}
|
||||
@@ -1556,9 +1559,6 @@ export class CustomNodesManager {
|
||||
|
||||
async onQueueStatus(event) {
|
||||
let self = CustomNodesManager.instance;
|
||||
// If legacy manager front is not open, return early (using new manager front)
|
||||
if (self.element?.style.display === 'none') return
|
||||
|
||||
if(event.detail.status == 'in_progress' && event.detail.ui_target == 'nodepack_manager') {
|
||||
const hash = event.detail.target;
|
||||
|
||||
@@ -1569,7 +1569,7 @@ export class CustomNodesManager {
|
||||
self.grid.updateCell(item, "action");
|
||||
self.grid.setRowSelected(item, false);
|
||||
}
|
||||
else if(event.detail.status == 'batch-done' && event.detail.batch_id == self.batch_id) {
|
||||
else if(event.detail.status == 'done') {
|
||||
self.hideStop();
|
||||
self.onQueueCompleted(event.detail);
|
||||
}
|
||||
@@ -1745,7 +1745,7 @@ export class CustomNodesManager {
|
||||
async getMissingNodesLegacy(hashMap, missing_nodes) {
|
||||
const mode = manager_instance.datasrc_combo.value;
|
||||
this.showStatus(`Loading missing nodes (${mode}) ...`);
|
||||
const res = await fetchData(`/v2/customnode/getmappings?mode=${mode}`);
|
||||
const res = await fetchData(`/customnode/getmappings?mode=${mode}`);
|
||||
if (res.error) {
|
||||
this.showError(`Failed to get custom node mappings: ${res.error}`);
|
||||
return;
|
||||
@@ -1860,7 +1860,7 @@ export class CustomNodesManager {
|
||||
async getAlternatives() {
|
||||
const mode = manager_instance.datasrc_combo.value;
|
||||
this.showStatus(`Loading alternatives (${mode}) ...`);
|
||||
const res = await fetchData(`/v2/customnode/alternatives?mode=${mode}`);
|
||||
const res = await fetchData(`/customnode/alternatives?mode=${mode}`);
|
||||
if (res.error) {
|
||||
this.showError(`Failed to get alternatives: ${res.error}`);
|
||||
return [];
|
||||
@@ -1908,7 +1908,7 @@ export class CustomNodesManager {
|
||||
infoToast('Fetching updated information. This may take some time if many custom nodes are installed.');
|
||||
}
|
||||
|
||||
const res = await fetchData(`/v2/customnode/getlist?mode=${mode}${skip_update}`);
|
||||
const res = await fetchData(`/customnode/getlist?mode=${mode}${skip_update}`);
|
||||
if (res.error) {
|
||||
this.showError("Failed to get custom node list.");
|
||||
this.hideLoading();
|
||||
@@ -3,7 +3,7 @@ import { $el } from "../../scripts/ui.js";
|
||||
import {
|
||||
manager_instance, rebootAPI,
|
||||
fetchData, md5, icons, show_message, customAlert, infoToast, showTerminal,
|
||||
storeColumnWidth, restoreColumnWidth, loadCss, generateUUID
|
||||
storeColumnWidth, restoreColumnWidth, loadCss
|
||||
} from "./common.js";
|
||||
import { api } from "../../scripts/api.js";
|
||||
|
||||
@@ -172,7 +172,7 @@ export class ModelManager {
|
||||
|
||||
".cmm-manager-stop": {
|
||||
click: () => {
|
||||
api.fetchApi('/v2/manager/queue/reset');
|
||||
api.fetchApi('/manager/queue/reset');
|
||||
infoToast('Cancel', 'Remaining tasks will stop after completing the current task.');
|
||||
}
|
||||
},
|
||||
@@ -413,15 +413,23 @@ export class ModelManager {
|
||||
}
|
||||
|
||||
async installModels(list, btn) {
|
||||
let stats = await api.fetchApi('/manager/queue/status');
|
||||
|
||||
stats = await stats.json();
|
||||
if(stats.is_processing) {
|
||||
customAlert(`[ComfyUI-Manager] There are already tasks in progress. Please try again after it is completed. (${stats.done_count}/${stats.total_count})`);
|
||||
return;
|
||||
}
|
||||
|
||||
btn.classList.add("cmm-btn-loading");
|
||||
this.showError("");
|
||||
|
||||
let needRefresh = false;
|
||||
let errorMsg = "";
|
||||
|
||||
let target_items = [];
|
||||
await api.fetchApi('/manager/queue/reset');
|
||||
|
||||
let batch = {};
|
||||
let target_items = [];
|
||||
|
||||
for (const item of list) {
|
||||
this.grid.scrollRowIntoView(item);
|
||||
@@ -438,12 +446,21 @@ export class ModelManager {
|
||||
const data = item.originalData;
|
||||
data.ui_id = item.hash;
|
||||
|
||||
const res = await api.fetchApi(`/manager/queue/install_model`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
if(batch['install_model']) {
|
||||
batch['install_model'].push(data);
|
||||
}
|
||||
else {
|
||||
batch['install_model'] = [data];
|
||||
if (res.status != 200) {
|
||||
errorMsg = `'${item.name}': `;
|
||||
|
||||
if(res.status == 403) {
|
||||
errorMsg += `This action is not allowed with this security level configuration.\n`;
|
||||
} else {
|
||||
errorMsg += await res.text() + '\n';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,24 +477,7 @@ export class ModelManager {
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.batch_id = generateUUID();
|
||||
batch['batch_id'] = this.batch_id;
|
||||
|
||||
const res = await api.fetchApi(`/v2/manager/queue/batch`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(batch)
|
||||
});
|
||||
|
||||
let failed = await res.json();
|
||||
|
||||
if(failed.length > 0) {
|
||||
for(let k in failed) {
|
||||
let hash = failed[k];
|
||||
const item = self.grid.getRowItemBy("hash", hash);
|
||||
errorMsg = `[FAIL] ${item.title}`;
|
||||
}
|
||||
}
|
||||
|
||||
await api.fetchApi('/manager/queue/start');
|
||||
this.showStop();
|
||||
showTerminal();
|
||||
}
|
||||
@@ -497,7 +497,7 @@ export class ModelManager {
|
||||
// self.grid.updateCell(item, "tg-column-select");
|
||||
self.grid.updateRow(item);
|
||||
}
|
||||
else if(event.detail.status == 'batch-done') {
|
||||
else if(event.detail.status == 'done') {
|
||||
self.hideStop();
|
||||
self.onQueueCompleted(event.detail);
|
||||
}
|
||||
@@ -623,7 +623,7 @@ export class ModelManager {
|
||||
|
||||
const mode = manager_instance.datasrc_combo.value;
|
||||
|
||||
const res = await fetchData(`/v2/externalmodel/getlist?mode=${mode}`);
|
||||
const res = await fetchData(`/externalmodel/getlist?mode=${mode}`);
|
||||
if (res.error) {
|
||||
this.showError("Failed to get external model list.");
|
||||
this.hideLoading();
|
||||
@@ -142,7 +142,7 @@ function node_info_copy(src, dest, connect_both, copy_shape) {
|
||||
}
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.Legacy.Manager.NodeFixer",
|
||||
name: "Comfy.Manager.NodeFixer",
|
||||
beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
addMenuHandler(nodeType, function (_, options) {
|
||||
options.push({
|
||||
@@ -7,7 +7,7 @@ import { manager_instance, rebootAPI, show_message } from "./common.js";
|
||||
async function restore_snapshot(target) {
|
||||
if(SnapshotManager.instance) {
|
||||
try {
|
||||
const response = await api.fetchApi(`/v2/snapshot/restore?target=${target}`, { cache: "no-store" });
|
||||
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.');
|
||||
@@ -35,7 +35,7 @@ async function restore_snapshot(target) {
|
||||
async function remove_snapshot(target) {
|
||||
if(SnapshotManager.instance) {
|
||||
try {
|
||||
const response = await api.fetchApi(`/v2/snapshot/remove?target=${target}`, { cache: "no-store" });
|
||||
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.');
|
||||
@@ -61,7 +61,7 @@ async function remove_snapshot(target) {
|
||||
|
||||
async function save_current_snapshot() {
|
||||
try {
|
||||
const response = await api.fetchApi('/v2/snapshot/save', { cache: "no-store" });
|
||||
const response = await api.fetchApi('/snapshot/save', { cache: "no-store" });
|
||||
app.ui.dialog.close();
|
||||
return true;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ async function save_current_snapshot() {
|
||||
}
|
||||
|
||||
async function getSnapshotList() {
|
||||
const response = await api.fetchApi(`/v2/snapshot/getlist`);
|
||||
const response = await api.fetchApi(`/snapshot/getlist`);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class WorkflowMetadataExtension {
|
||||
* enabled is true if the node is enabled, false if it is disabled
|
||||
*/
|
||||
async getInstalledNodes() {
|
||||
const res = await api.fetchApi("/v2/customnode/installed");
|
||||
const res = await api.fetchApi("/customnode/installed");
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ class WorkflowMetadataExtension {
|
||||
if (cnr_id === "comfy-core") return; // don't allow hijacking comfy-core name
|
||||
if (cnr_id) nodeProperties.cnr_id = cnr_id;
|
||||
else nodeProperties.aux_id = aux_id;
|
||||
if (ver) nodeProperties.ver = ver;
|
||||
if (ver) nodeProperties.ver = ver.trim();
|
||||
} else if (["nodes", "comfy_extras"].includes(moduleType)) {
|
||||
nodeProperties.cnr_id = "comfy-core";
|
||||
nodeProperties.ver = this.comfyCoreVersion;
|
||||
@@ -12,8 +12,306 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"author": "leon-etienne",
|
||||
"title": "ComfyUI_Scoring-Nodes",
|
||||
"reference": "https://github.com/leon-etienne/ComfyUI_Scoring-Nodes",
|
||||
"files": [
|
||||
"https://github.com/leon-etienne/ComfyUI_Scoring-Nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Text Similarity (CLIP), Image Similarity (CLIP), Multi Text→Image Similarity, Multi Image→Text Similarity, Aesthetic Score, Multi Aesthetic Comparison"
|
||||
},
|
||||
{
|
||||
"author": "tanmoy-it",
|
||||
"title": "comfyuiCustomNode",
|
||||
"reference": "https://github.com/tanmoy-it/comfyuiCustomNode",
|
||||
"files": [
|
||||
"https://github.com/tanmoy-it/comfyuiCustomNode"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Download Image (Direct/No Save)"
|
||||
},
|
||||
{
|
||||
"author": "Jingwen-genies",
|
||||
"title": "comfyui-genies-nodes",
|
||||
"reference": "https://github.com/Jingwen-genies/comfyui-genies-nodes",
|
||||
"files": [
|
||||
"https://github.com/Jingwen-genies/comfyui-genies-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Genies Pose Estimation, Genies Scale Face by Keypoints, Get V Channel from HSV, Select RGB by Mask"
|
||||
},
|
||||
{
|
||||
"author": "Tawbaware",
|
||||
"title": "ComfyUI-Tawbaware [WIP]",
|
||||
"reference": "https://github.com/Tawbaware/ComfyUI-Tawbaware",
|
||||
"files": [
|
||||
"https://github.com/Tawbaware/ComfyUI-Tawbaware"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes for ComfyUI\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "lucafoscili",
|
||||
"title": "LF Nodes [UNSAFE]",
|
||||
"reference": "https://github.com/lucafoscili/lf-nodes",
|
||||
"files": [
|
||||
"https://github.com/lucafoscili/lf-nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes with a touch of extra UX, including: history for primitives, JSON manipulation, logic switches with visual feedback, LLM chat... and more!\n[w/This node pack contains a node with a vulnerability that allows arbitrary code execution.]"
|
||||
},
|
||||
{
|
||||
"author": "jerryname2022",
|
||||
"title": "ComfyUI-Real-ESRGAN [WIP]",
|
||||
"reference": "https://github.com/jerryname2022/ComfyUI-Real-ESRGAN",
|
||||
"files": [
|
||||
"https://github.com/jerryname2022/ComfyUI-Real-ESRGAN"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Real-ESRGAN Model Loader, GFPGAN Model Loader, Real-ESRGAN Image Generator, GFPGAN Image Generator"
|
||||
},
|
||||
{
|
||||
"author": "mm-akhtar",
|
||||
"title": "comfyui-mask-selector-node",
|
||||
"reference": "https://github.com/mm-akhtar/comfyui-mask-selector-node",
|
||||
"files": [
|
||||
"https://github.com/mm-akhtar/comfyui-mask-selector-node"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Mask Selector"
|
||||
},
|
||||
{
|
||||
"author": "ryanontheinside",
|
||||
"title": "ComfyUI-Livepeer [WIP]",
|
||||
"reference": "https://github.com/ryanontheinside/ComfyUI-Livepeer",
|
||||
"files": [
|
||||
"https://github.com/ryanontheinside/ComfyUI-Livepeer"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI extension that provides integration with [a/Livepeer](https://livepeer.org/)'s AI services allowing for both sync and async generation."
|
||||
},
|
||||
{
|
||||
"author": "newraina",
|
||||
"title": "ComfyUI-Remote-Save-Image [UNSAFE]",
|
||||
"reference": "https://github.com/newraina/ComfyUI-Remote-Save-Image",
|
||||
"files": [
|
||||
"https://github.com/newraina/ComfyUI-Remote-Save-Image"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node for ComfyUI that allows uploading generated images to any HTTP endpoint.[w/This node allows any users to send any locally stored image to a specified URL.]"
|
||||
},
|
||||
{
|
||||
"author": "SXQBW",
|
||||
"title": "ComfyUI-Qwen-VLM [WIP]",
|
||||
"reference": "https://github.com/SXQBW/ComfyUI-Qwen-VLM",
|
||||
"files": [
|
||||
"https://github.com/SXQBW/ComfyUI-Qwen-VLM"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: QwenVLM"
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI-FramePackWrapper [WIP]",
|
||||
"reference": "https://github.com/kijai/ComfyUI-FramePackWrapper",
|
||||
"files": [
|
||||
"https://github.com/kijai/ComfyUI-FramePackWrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Wrapper for FramePack by lllyasviel"
|
||||
},
|
||||
{
|
||||
"author": "WaiyanLing",
|
||||
"title": "ComfyUI-Tracking [WIP]",
|
||||
"reference": "https://github.com/WaiyanLing/ComfyUI-Tracking",
|
||||
"files": [
|
||||
"https://github.com/WaiyanLing/ComfyUI-Tracking"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI-Tracking This node pack helps to conveniently collect invocation data from workflows for further study.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "vladp0727",
|
||||
"title": "ComfyUI Simple Image Tools [WIP]",
|
||||
"reference": "https://github.com/vladp0727/Comfyui-with-Furniture",
|
||||
"files": [
|
||||
"https://github.com/vladp0727/Comfyui-with-Furniture"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Get Mask From Alpha, Get Quadrilateral Outfit\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "Simlym",
|
||||
"title": "Simlym/comfyui-prompt-helper [WIP]",
|
||||
"reference": "https://github.com/Simlym/comfyui-prompt-helper",
|
||||
"files": [
|
||||
"https://github.com/Simlym/comfyui-prompt-helper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A ComfyUI custom node for processing Chinese prompts and generating English prompts with LLM\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "ryanontheinside",
|
||||
"title": "ComfyUI MineWorld Nodes [WIP]",
|
||||
"reference": "https://github.com/ryanontheinside/ComfyUI-MineWorld",
|
||||
"files": [
|
||||
"https://github.com/ryanontheinside/ComfyUI-MineWorld"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This extension integrates Microsoft's MineWorld - an interactive world model for Minecraft - into ComfyUI.\nMineWorld allows you to generate interactive Minecraft gameplay based on actions you provide, creating realistic Minecraft gameplay videos."
|
||||
},
|
||||
{
|
||||
"author": "SanDiegoDude",
|
||||
"title": "HiDreamSampler for ComfyUI [WIP]",
|
||||
"reference": "https://github.com/SanDiegoDude/ComfyUI-HiDream-Sampler",
|
||||
"files": [
|
||||
"https://github.com/SanDiegoDude/ComfyUI-HiDream-Sampler"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom ComfyUI node for generating images using the HiDream AI model.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "AJO-reading",
|
||||
"title": "ComfyUI-AjoNodes [WIP]",
|
||||
"reference": "https://github.com/AJO-reading/ComfyUI-AjoNodes",
|
||||
"files": [
|
||||
"https://github.com/AJO-reading/ComfyUI-AjoNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of custom nodes designed for ComfyUI from the AJO-reading organization. This repository currently includes the Audio Collect & Concat node, which collects multiple audio segments and concatenates them into a single audio stream.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "ZenAI-Vietnam",
|
||||
"title": "ComfyUI_InfiniteYou [NAME CONFLICT]",
|
||||
"reference": "https://github.com/ZenAI-Vietnam/ComfyUI_InfiniteYou",
|
||||
"files": [
|
||||
"https://github.com/ZenAI-Vietnam/ComfyUI_InfiniteYou"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "An implementation of InfiniteYou for ComfyUI. Native support for [a/InfiniteYou](https://github.com/bytedance/InfiniteYou) in ComfyUI, designed by the ZenAI team."
|
||||
},
|
||||
{
|
||||
"author": "filipemeneses",
|
||||
"title": "ComfyUI_html [UNSAFE]",
|
||||
"reference": "https://github.com/filipemeneses/ComfyUI_html",
|
||||
"files": [
|
||||
"https://github.com/filipemeneses/ComfyUI_html"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes to manipulate HTML.[w/This extension poses a risk of XSS vulnerability.]"
|
||||
},
|
||||
{
|
||||
"author": "LLMCoder2023",
|
||||
"title": "ComfyUI-LLMCoderNodes",
|
||||
"reference": "https://github.com/LLMCoder2023/ComfyUI-LLMCoderNodes",
|
||||
"files": [
|
||||
"https://github.com/LLMCoder2023/ComfyUI-LLMCoderNodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: String Template Interpolation, Variable Definition, Weighted Attributes Formatter"
|
||||
},
|
||||
{
|
||||
"author": "FaberVS",
|
||||
"title": "MultiModel",
|
||||
"reference": "https://github.com/FaberVS/MultiModel",
|
||||
"files": [
|
||||
"https://github.com/FaberVS/MultiModel"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A collection of ComfyUI nodes enabling seamless integration of multiple models into workflows without requiring constant configuration."
|
||||
},
|
||||
{
|
||||
"author": "m-ai-studio",
|
||||
"title": "mai-prompt-progress",
|
||||
"reference": "https://github.com/m-ai-studio/mai-prompt-progress",
|
||||
"files": [
|
||||
"https://github.com/m-ai-studio/mai-prompt-progress"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI extensions for sending prompt progress to webhook"
|
||||
},
|
||||
{
|
||||
"author": "ashllay",
|
||||
"title": "ComfyUI_MoreComfy",
|
||||
"reference": "https://github.com/ashllay/ComfyUI_MoreComfy",
|
||||
"files": [
|
||||
"https://github.com/ashllay/ComfyUI_MoreComfy"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: MC Switch Seed/Image/Latent/Model/String, MC Alter Seed, MC Set Tile Size, MC Get Image Size, MC Multi Concat"
|
||||
},
|
||||
{
|
||||
"author": "gordon1chuge2623",
|
||||
"title": "ComfyUI_seal_migration [WIP]",
|
||||
"reference": "https://github.com/chuge26/ComfyUI_seal_migration",
|
||||
"files": [
|
||||
"https://github.com/chuge26/ComfyUI_seal_migration"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This project implements stamp migration in PDF files based on ComfyUI, allowing stamps from specified pages of a source PDF to be transferred to specified pages of a target PDF.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "gordon123",
|
||||
"title": "ComfyUI_srt2speech [WIP]",
|
||||
"reference": "https://github.com/gordon123/ComfyUI_srt2speech",
|
||||
"files": [
|
||||
"https://github.com/gordon123/ComfyUI_srt2speech"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI_srt2speech"
|
||||
},
|
||||
{
|
||||
"author": "hnmr293",
|
||||
"title": "ComfyUI-SamOne - one-step sampling",
|
||||
"reference": "https://github.com/hnmr293/ComfyUI-SamOne",
|
||||
"files": [
|
||||
"https://github.com/hnmr293/ComfyUI-SamOne"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is a node that advances sampling by just one step in ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "rphmeier",
|
||||
"title": "comfyui-videodepthanything",
|
||||
"reference": "https://github.com/rphmeier/comfyui-videodepthanything",
|
||||
"files": [
|
||||
"https://github.com/rphmeier/comfyui-videodepthanything"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "VideoDepthAnything nodes for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "MITCAP",
|
||||
"title": "ComfyUI OpenAI DALL-E 3 Node [WIP]",
|
||||
"reference": "https://github.com/MITCAP/OpenAI-ComfyUI",
|
||||
"files": [
|
||||
"https://github.com/MITCAP/OpenAI-ComfyUI"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This project provides custom nodes for ComfyUI that integrate with OpenAI's DALL-E 3 and GPT-4o models. The nodes allow users to generate images and describe images using OpenAI's API.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "benmizrahi",
|
||||
"title": "ComfyGCS [WIP]",
|
||||
"reference": "https://github.com/benmizrahi/ComfyGCS",
|
||||
"files": [
|
||||
"https://github.com/benmizrahi/ComfyGCS"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyGCS is a robust read/write plugin for Google Cloud Storage, designed to simplify interaction with GCS buckets in your projects.\nNOTE: The files in the repo are not organized."
|
||||
},
|
||||
{
|
||||
"author": "dogcomplex",
|
||||
"title": "ComfyUI-LOKI [WIP]",
|
||||
"reference": "https://github.com/dogcomplex/ComfyUI-LOKI",
|
||||
"files": [
|
||||
"https://github.com/dogcomplex/ComfyUI-LOKI"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Glamour\nNOTE: This node pack installs pip dependencies outside the control of ComfyUI-Manager."
|
||||
},
|
||||
{
|
||||
"author": "hunzmusic",
|
||||
"title": "Comfyui-CraftsMan3DWrapper [WIP]",
|
||||
@@ -262,7 +560,7 @@
|
||||
"https://github.com/grokuku/ComfyUI-Holaf"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "NODES: Neurogrid Overload, Tile Calculator, Slice Calculator, Save Image, Tiled KSampler, KSampler, Image Comparer, Upscale"
|
||||
"description": "NODES: Neurogrid Overload, Tile Calculator, Slice Calculator, Save Image, Tiled KSampler, KSampler, Image Comparer, Upscale, Overlay, Resolution Preset, Benchmark Runner, Benchmark Plotter, Benchmark Loader"
|
||||
},
|
||||
{
|
||||
"author": "Burgstall-labs",
|
||||
@@ -385,16 +683,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Nova utils for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "niknah",
|
||||
"title": "niknah/ComfyUI-InfiniteYou",
|
||||
"reference": "https://github.com/niknah/ComfyUI-InfiniteYou",
|
||||
"files": [
|
||||
"https://github.com/niknah/ComfyUI-InfiniteYou"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Put anyone's face on anything with Byte Dance's [a/InfiniteYou](https://github.com/bytedance/InfiniteYou)."
|
||||
},
|
||||
{
|
||||
"author": "sugarkwork",
|
||||
"title": "comfyui_my_img_util",
|
||||
@@ -575,26 +863,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes for basic actions."
|
||||
},
|
||||
{
|
||||
"author": "silveroxides",
|
||||
"title": "ComfyUI-ModelUtils [WIP]",
|
||||
"reference": "https://github.com/silveroxides/ComfyUI-ModelUtils",
|
||||
"files": [
|
||||
"https://github.com/silveroxides/ComfyUI-ModelUtils"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "[WIP]Custom nodes for handling, inspecting, modifying and creating various model files."
|
||||
},
|
||||
{
|
||||
"author": "thisiseddy-ab",
|
||||
"title": "ComfyUI-Edins-Ultimate-Pack",
|
||||
"reference": "https://github.com/thisiseddy-ab/ComfyUI-Edins-Ultimate-Pack",
|
||||
"files": [
|
||||
"https://github.com/thisiseddy-ab/ComfyUI-Edins-Ultimate-Pack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Well i needet a Tiled Ksampler that still works for Comfy UI there were none so i made one, in this Package i will put all Nodes i will develop for Comfy Ui still in beta alot will change.."
|
||||
},
|
||||
{
|
||||
"author": "longzoho",
|
||||
"title": "ComfyUI-Qdrant-Saver",
|
||||
@@ -1237,16 +1505,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Fetches URLs"
|
||||
},
|
||||
{
|
||||
"author": "myAiLemon",
|
||||
"title": "MagicAutomaticPicture [WIP]",
|
||||
"reference": "https://github.com/myAiLemon/MagicAutomaticPicture",
|
||||
"files": [
|
||||
"https://github.com/myAiLemon/MagicAutomaticPicture"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A comfyui node package that can generate pictures and automatically save positive prompts and eliminate unwanted prompts"
|
||||
},
|
||||
{
|
||||
"author": "neverbiasu",
|
||||
"title": "ComfyUI_Output_as_Input",
|
||||
|
||||
@@ -148,6 +148,8 @@
|
||||
],
|
||||
"https://github.com/438443467/ComfyUI-SanMian-Nodes": [
|
||||
[
|
||||
"FaceAlignPro",
|
||||
"FaceAlignProRestore",
|
||||
"SANMIN Adapt Coordinates",
|
||||
"sanmi AddTextToImage",
|
||||
"sanmi Adjust Transparency By Mask",
|
||||
@@ -156,10 +158,12 @@
|
||||
"sanmi BinarizeMask",
|
||||
"sanmi BlendICLight",
|
||||
"sanmi Chinese To Character",
|
||||
"sanmi ColorOverlayOnMask",
|
||||
"sanmi Compare",
|
||||
"sanmi CompareV2",
|
||||
"sanmi Counter",
|
||||
"sanmi CreateTxtForImages",
|
||||
"sanmi Filter Prompt Words",
|
||||
"sanmi Float",
|
||||
"sanmi Florence2toCoordinates",
|
||||
"sanmi Get Content From Excel",
|
||||
@@ -180,6 +184,7 @@
|
||||
"sanmi Path Captioner",
|
||||
"sanmi Path Change",
|
||||
"sanmi Read Image Prompt",
|
||||
"sanmi RectMaskAnalyzer",
|
||||
"sanmi Reduce Mask",
|
||||
"sanmi RestoreJson",
|
||||
"sanmi Sanmi_Text_Concatenate",
|
||||
@@ -222,6 +227,7 @@
|
||||
"FileName_refixer",
|
||||
"LoRALoader_path",
|
||||
"PD_GetImageSize",
|
||||
"PD_ImageMergerWithText",
|
||||
"PD_Image_Crop_Location",
|
||||
"PD_Image_centerCrop",
|
||||
"PD_MASK_SELECTION",
|
||||
@@ -346,6 +352,16 @@
|
||||
"title_aux": "UtilNodes-ComfyUI [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/AJO-reading/ComfyUI-AjoNodes": [
|
||||
[
|
||||
"AJO_AudioCollectAndConcat",
|
||||
"AJO_PreviewAudio",
|
||||
"AJO_SaveAudio"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-AjoNodes [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ALatentPlace/ComfyUI_yanc": [
|
||||
[
|
||||
"> Bloom",
|
||||
@@ -511,15 +527,23 @@
|
||||
],
|
||||
"https://github.com/AlejandroTuzzi/TUZZI-ByPass": [
|
||||
[
|
||||
"LinkSuppressor",
|
||||
"SequentialTextReaderAuto",
|
||||
"TUZZI-Bypasser",
|
||||
"TUZZI-DirectoryImagePromptReader",
|
||||
"TUZZI-ImageAudioToVideo",
|
||||
"TUZZI-ImageExtractorSaver",
|
||||
"TUZZI-LineCounter",
|
||||
"TUZZI-LinkSuppressor",
|
||||
"TUZZI-NumberLines",
|
||||
"TUZZI-RedditPostExtractor",
|
||||
"TUZZI-SaveVideo",
|
||||
"TUZZI-SequentialTextReader",
|
||||
"TUZZI-SequentialTextReaderAuto",
|
||||
"TUZZI-TextFormatter",
|
||||
"TUZZI-TextFormatterPlus",
|
||||
"TUZZI-TextTranslatorExporter",
|
||||
"TUZZI-TextTruncatorPlus",
|
||||
"TUZZI-YouTubeCommentExtractor",
|
||||
"TUZZI-YouTubeSubtitleExtractor"
|
||||
],
|
||||
@@ -829,6 +853,7 @@
|
||||
"DevToolsErrorRaiseNode",
|
||||
"DevToolsErrorRaiseNodeWithMessage",
|
||||
"DevToolsExperimentalNode",
|
||||
"DevToolsLoadAnimatedImageTest",
|
||||
"DevToolsLongComboDropdown",
|
||||
"DevToolsMultiSelectNode",
|
||||
"DevToolsNodeWithBooleanInput",
|
||||
@@ -939,7 +964,8 @@
|
||||
"Donut Detailer",
|
||||
"Donut Detailer 2",
|
||||
"Donut Detailer 4",
|
||||
"Donut Detailer LoRA 6"
|
||||
"Donut Detailer LoRA 5",
|
||||
"Donut Detailer XL Blocks"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-DonutDetailer"
|
||||
@@ -1082,6 +1108,18 @@
|
||||
"title_aux": "Conditioning-token-experiments-for-ComfyUI"
|
||||
}
|
||||
],
|
||||
"https://github.com/FaberVS/MultiModel": [
|
||||
[
|
||||
"DenoiseSelector",
|
||||
"DualTextInput",
|
||||
"ListSelectorNode",
|
||||
"ModelParamsPipeNode",
|
||||
"ParamsPipeUnpack"
|
||||
],
|
||||
{
|
||||
"title_aux": "MultiModel"
|
||||
}
|
||||
],
|
||||
"https://github.com/Fannovel16/ComfyUI-AppIO": [
|
||||
[
|
||||
"AppIO_FitResizeImage",
|
||||
@@ -1398,6 +1436,16 @@
|
||||
"title_aux": "ComfyUI-VLMStudio"
|
||||
}
|
||||
],
|
||||
"https://github.com/LLMCoder2023/ComfyUI-LLMCoderNodes": [
|
||||
[
|
||||
"TemplateInterpolation",
|
||||
"Variable",
|
||||
"WeightedAttributesFormatter"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-LLMCoderNodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/LZpenguin/ComfyUI-Text": [
|
||||
[
|
||||
"Add_text_by_mask"
|
||||
@@ -1549,6 +1597,15 @@
|
||||
"title_aux": "comfy-tif-support"
|
||||
}
|
||||
],
|
||||
"https://github.com/MITCAP/OpenAI-ComfyUI": [
|
||||
[
|
||||
"OpenAIDalle3Node",
|
||||
"OpenAIImageDescriptionNode"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI OpenAI DALL-E 3 Node [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ManuShamil/ComfyUI_BodyEstimation_Nodes": [
|
||||
[
|
||||
"CogitareLabsPoseIDExtractor"
|
||||
@@ -1879,12 +1936,21 @@
|
||||
"https://github.com/SS-snap/Comfyui_SSsnap_pose-Remapping": [
|
||||
[
|
||||
"ApplyPoseDiff",
|
||||
"CalcScaledPoseDiff",
|
||||
"PoseDiffCalculator"
|
||||
],
|
||||
{
|
||||
"title_aux": "Comfyui_SSsnap_pose-Remapping"
|
||||
}
|
||||
],
|
||||
"https://github.com/SXQBW/ComfyUI-Qwen-VLM": [
|
||||
[
|
||||
"QwenVisionParser"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Qwen-VLM [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/SadaleNet/ComfyUI-Prompt-To-Prompt": [
|
||||
[
|
||||
"CLIPTextEncodePromptToPrompt",
|
||||
@@ -1919,6 +1985,16 @@
|
||||
"title_aux": "ComfyUI_Save2Discord"
|
||||
}
|
||||
],
|
||||
"https://github.com/SanDiegoDude/ComfyUI-HiDream-Sampler": [
|
||||
[
|
||||
"HiDreamImg2Img",
|
||||
"HiDreamSampler",
|
||||
"HiDreamSamplerAdvanced"
|
||||
],
|
||||
{
|
||||
"title_aux": "HiDreamSampler for ComfyUI [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/Scaryplasmon/ComfTrellis": [
|
||||
[
|
||||
"LoadTrellisModel",
|
||||
@@ -2005,6 +2081,14 @@
|
||||
"title_aux": "ComfyUI-FreeMemory"
|
||||
}
|
||||
],
|
||||
"https://github.com/Simlym/comfyui-prompt-helper": [
|
||||
[
|
||||
"PromptProcessor"
|
||||
],
|
||||
{
|
||||
"title_aux": "Simlym/comfyui-prompt-helper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/Slix-M-Lestragg/comfyui-enhanced": [
|
||||
[
|
||||
"Range Iterator"
|
||||
@@ -2132,6 +2216,18 @@
|
||||
"title_aux": "comfyui_flux_collection_advanced [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/Symbiomatrix/Comfyui-Sort-Files": [
|
||||
[
|
||||
"ImageSaverSBM",
|
||||
"SortControlSBM",
|
||||
"StringToFloatSBM",
|
||||
"VideoSeriesMergerSBM"
|
||||
],
|
||||
{
|
||||
"author": "SBM",
|
||||
"title_aux": "Comfyui-Sort-Files"
|
||||
}
|
||||
],
|
||||
"https://github.com/TSFSean/ComfyUI-TSFNodes": [
|
||||
[
|
||||
"GyroOSC"
|
||||
@@ -2230,6 +2326,14 @@
|
||||
"title_aux": "pre-comfyui-stablsr"
|
||||
}
|
||||
],
|
||||
"https://github.com/WaiyanLing/ComfyUI-Tracking": [
|
||||
[
|
||||
"WorkflowStats"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Tracking [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/WilliamStanford/ComfyUI-VisualLabs": [
|
||||
[
|
||||
"CreateFadeMaskAdvancedVL",
|
||||
@@ -2296,6 +2400,16 @@
|
||||
"title_aux": "ComfyUI-gemini-IG"
|
||||
}
|
||||
],
|
||||
"https://github.com/ZenAI-Vietnam/ComfyUI_InfiniteYou": [
|
||||
[
|
||||
"FaceCombine",
|
||||
"FaceSwap_InfiniteYou",
|
||||
"InfiniteYouApply"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_InfiniteYou [NAME CONFLICT]"
|
||||
}
|
||||
],
|
||||
"https://github.com/a-One-Fan/ComfyUI-Blenderesque-Nodes": [
|
||||
[
|
||||
"BlenderAlphaConvert",
|
||||
@@ -2540,9 +2654,15 @@
|
||||
"https://github.com/ashllay/ComfyUI_MoreComfy": [
|
||||
[
|
||||
"MC Alter Seed",
|
||||
"MC Get Image Size",
|
||||
"MC Multi Concat",
|
||||
"MC Multi Concat(Advanced)",
|
||||
"MC Set Tile Size",
|
||||
"MC Switch Seed"
|
||||
"MC Switch Image",
|
||||
"MC Switch Latent",
|
||||
"MC Switch Model",
|
||||
"MC Switch Seed",
|
||||
"MC Switch String"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_MoreComfy"
|
||||
@@ -2597,6 +2717,15 @@
|
||||
"title_aux": "Comfyui-PyExec [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/benmizrahi/ComfyGCS": [
|
||||
[
|
||||
"LoadImageGCS",
|
||||
"SaveImageGCS"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyGCS [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/beyastard/ComfyUI_BeySoft": [
|
||||
[
|
||||
"BeySoft"
|
||||
@@ -2936,6 +3065,16 @@
|
||||
"title_aux": "Python Interpreter ComfyUI Node [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/chuge26/ComfyUI_seal_migration": [
|
||||
[
|
||||
"PDFLoader",
|
||||
"PDFSaver",
|
||||
"SealMigration"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_seal_migration [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/cidiro/cid-node-pack": [
|
||||
[
|
||||
"CidAnyBuffer",
|
||||
@@ -3028,6 +3167,7 @@
|
||||
"FlipSigmas",
|
||||
"FluxDisableGuidance",
|
||||
"FluxGuidance",
|
||||
"FreSca",
|
||||
"FreeU",
|
||||
"FreeU_V2",
|
||||
"GITSScheduler",
|
||||
@@ -3134,6 +3274,7 @@
|
||||
"ModelSamplingStableCascade",
|
||||
"ModelSave",
|
||||
"Morphology",
|
||||
"OptimalStepsScheduler",
|
||||
"PatchModelAddDownscale",
|
||||
"PerpNeg",
|
||||
"PerpNegGuider",
|
||||
@@ -3150,6 +3291,7 @@
|
||||
"PrimitiveFloat",
|
||||
"PrimitiveInt",
|
||||
"PrimitiveString",
|
||||
"QuadrupleCLIPLoader",
|
||||
"RandomNoise",
|
||||
"RebatchImages",
|
||||
"RebatchLatents",
|
||||
@@ -3260,6 +3402,7 @@
|
||||
"VideoTriangleCFGGuidance",
|
||||
"VoxelToMesh",
|
||||
"VoxelToMeshBasic",
|
||||
"WanFirstLastFrameToVideo",
|
||||
"WanFunControlToVideo",
|
||||
"WanFunInpaintToVideo",
|
||||
"WanImageToVideo",
|
||||
@@ -3386,6 +3529,22 @@
|
||||
"title_aux": "ComfyUI Random Keypoints for InstantID [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/dogcomplex/ComfyUI-LOKI": [
|
||||
[
|
||||
"EvaluateRelevanceLLM",
|
||||
"FilterNodesLLM",
|
||||
"GenerateFilterPromptLLM",
|
||||
"Glamour \ud83e\udd8a",
|
||||
"LLMQueryAPI",
|
||||
"LLMQueryAPIBatch",
|
||||
"ListAvailableNodes",
|
||||
"ListInstalledNodes",
|
||||
"Scribe"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-LOKI [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/doucx/ComfyUI_WcpD_Utility_Kit": [
|
||||
[
|
||||
"BlackImage",
|
||||
@@ -3562,6 +3721,18 @@
|
||||
"title_aux": "comfyuinode_chopmask [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/filipemeneses/ComfyUI_html": [
|
||||
[
|
||||
"HtmlDownload",
|
||||
"HtmlPreview",
|
||||
"LoadHtml",
|
||||
"SaveHtml",
|
||||
"SingleImageToBase64"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_html [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/flowtyone/comfyui-flowty-lcm": [
|
||||
[
|
||||
"LCMSampler"
|
||||
@@ -3699,6 +3870,16 @@
|
||||
"title_aux": "comfyui-custom-padding"
|
||||
}
|
||||
],
|
||||
"https://github.com/gordon123/ComfyUI_srt2speech": [
|
||||
[
|
||||
"GetSubtitleByIndex",
|
||||
"MergeAllWave",
|
||||
"SaveWavNode"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_srt2speech [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/grimli333/ComfyUI_Grim": [
|
||||
[
|
||||
"GenerateFileName",
|
||||
@@ -3710,8 +3891,10 @@
|
||||
],
|
||||
"https://github.com/grinlau18/ComfyUI_XISER_Nodes": [
|
||||
[
|
||||
"CreatePointsString",
|
||||
"XIS_CompositorProcessor",
|
||||
"XIS_CropImage",
|
||||
"XIS_DynamicBatchKSampler",
|
||||
"XIS_Float_Slider",
|
||||
"XIS_FromListGet1Color",
|
||||
"XIS_FromListGet1Cond",
|
||||
@@ -3726,10 +3909,15 @@
|
||||
"XIS_IPAStyleSettings",
|
||||
"XIS_IfDataIsNone",
|
||||
"XIS_ImageMaskMirror",
|
||||
"XIS_ImageStitcher",
|
||||
"XIS_InvertMask",
|
||||
"XIS_IsThereAnyData",
|
||||
"XIS_KSamplerSettingsNode",
|
||||
"XIS_KSamplerSettingsUnpackNode",
|
||||
"XIS_Label",
|
||||
"XIS_LatentBlendNode",
|
||||
"XIS_LoadImage",
|
||||
"XIS_MaskBatchProcessor",
|
||||
"XIS_MaskCompositeOperation",
|
||||
"XIS_PromptProcessor",
|
||||
"XIS_PromptsWithSwitches",
|
||||
@@ -3819,6 +4007,7 @@
|
||||
"ACE_Integer",
|
||||
"ACE_MaskBlur",
|
||||
"ACE_OpenAI_GPT_Chat",
|
||||
"ACE_OpenAI_GPT_TTS",
|
||||
"ACE_Seed",
|
||||
"ACE_Text",
|
||||
"ACE_TextConcatenate",
|
||||
@@ -3866,6 +4055,15 @@
|
||||
"title_aux": "ComfyUI_Lah_Toffee"
|
||||
}
|
||||
],
|
||||
"https://github.com/hnmr293/ComfyUI-SamOne": [
|
||||
[
|
||||
"Latent",
|
||||
"SamplerOne"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-SamOne - one-step sampling"
|
||||
}
|
||||
],
|
||||
"https://github.com/horidream/ComfyUI-Horidream": [
|
||||
[
|
||||
"PassThroughWithSound"
|
||||
@@ -3976,6 +4174,19 @@
|
||||
"title_aux": "ComfyUI-Hunyuan3DTools [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/hunzmusic/Comfyui-CraftsMan3DWrapper": [
|
||||
[
|
||||
"CraftsManDoraVAEGenerator",
|
||||
"DecodeCraftsManLatents",
|
||||
"LoadCraftsManPipeline",
|
||||
"PreprocessImageCraftsMan",
|
||||
"SampleCraftsManLatents",
|
||||
"SaveCraftsManMesh"
|
||||
],
|
||||
{
|
||||
"title_aux": "Comfyui-CraftsMan3DWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/hunzmusic/comfyui-hnznodes": [
|
||||
[
|
||||
"CombineChannelsGrayscale",
|
||||
@@ -4108,12 +4319,14 @@
|
||||
"https://github.com/jax-explorer/ComfyUI-H-flow": [
|
||||
[
|
||||
"FluxProUltra",
|
||||
"HFLowLoadImage",
|
||||
"Hailuo01ImageToVideo",
|
||||
"HiDreamI1",
|
||||
"IdeogramV2Turbo",
|
||||
"KlingImageToVideo",
|
||||
"LLMTask",
|
||||
"RunwayImageToVideo",
|
||||
"SaveImage",
|
||||
"SaveVideo",
|
||||
"LumaRay2ImageToVideo",
|
||||
"RunwayGen3ImageToVideo",
|
||||
"Wan2ImageToVideo"
|
||||
],
|
||||
{
|
||||
@@ -4142,6 +4355,17 @@
|
||||
"title_aux": "AsunaroTools"
|
||||
}
|
||||
],
|
||||
"https://github.com/jerryname2022/ComfyUI-Real-ESRGAN": [
|
||||
[
|
||||
"GFPGANImageGenerator",
|
||||
"GFPGANModelLoader",
|
||||
"RealESRGANImageGenerator",
|
||||
"RealESRGANModelLoader"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Real-ESRGAN [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/jgbrblmd/ComfyUI-ComfyFluxSize": [
|
||||
[
|
||||
"ComfyFluxSize"
|
||||
@@ -4267,6 +4491,7 @@
|
||||
[
|
||||
"BrightnessContrastSaturation",
|
||||
"CreateFilenameList",
|
||||
"DetectEvenNumberString",
|
||||
"DisplaceImageCPU",
|
||||
"DisplaceImageGPU",
|
||||
"ExtractBlackLines",
|
||||
@@ -4284,7 +4509,6 @@
|
||||
"RandomCharacterPrompts",
|
||||
"TargetLocationCrop",
|
||||
"TargetLocationPaste",
|
||||
"Yolov8Detection",
|
||||
"easy_parallax",
|
||||
"string_list_to_prompt_schedule"
|
||||
],
|
||||
@@ -4435,6 +4659,18 @@
|
||||
"title_aux": "ComfyUI-FollowYourEmojiWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-FramePackWrapper": [
|
||||
[
|
||||
"DownloadAndLoadFramePackModel",
|
||||
"FramePackFindNearestBucket",
|
||||
"FramePackSampler",
|
||||
"FramePackTorchCompileSettings",
|
||||
"LoadFramePackModel"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-FramePackWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-Hunyuan3DWrapper": [
|
||||
[
|
||||
"CV2InpaintTexture",
|
||||
@@ -4468,7 +4704,9 @@
|
||||
"Hy3DTorchCompileSettings",
|
||||
"Hy3DUploadMesh",
|
||||
"Hy3DVAEDecode",
|
||||
"Hy3DVAELoader"
|
||||
"Hy3DVAELoader",
|
||||
"MESHToTrimesh",
|
||||
"TrimeshToMESH"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-ComfyUI-Hunyuan3DWrapper [WIP]"
|
||||
@@ -4586,6 +4824,8 @@
|
||||
"WanVideoLoraSelect",
|
||||
"WanVideoModelLoader",
|
||||
"WanVideoReCamMasterCameraEmbed",
|
||||
"WanVideoReCamMasterDefaultCamera",
|
||||
"WanVideoReCamMasterGenerateOrbitCamera",
|
||||
"WanVideoSLG",
|
||||
"WanVideoSampler",
|
||||
"WanVideoSetBlockSwap",
|
||||
@@ -4594,6 +4834,8 @@
|
||||
"WanVideoTextEncode",
|
||||
"WanVideoTinyVAELoader",
|
||||
"WanVideoTorchCompileSettings",
|
||||
"WanVideoUniAnimateDWPoseDetector",
|
||||
"WanVideoUniAnimatePoseInput",
|
||||
"WanVideoVACEEncode",
|
||||
"WanVideoVACEModelSelect",
|
||||
"WanVideoVACEStartToEndFrame",
|
||||
@@ -4975,6 +5217,104 @@
|
||||
"title_aux": "SK-Nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/lucafoscili/lf-nodes": [
|
||||
[
|
||||
"LF_Blend",
|
||||
"LF_BlurImages",
|
||||
"LF_Boolean",
|
||||
"LF_Brightness",
|
||||
"LF_CharacterImpersonator",
|
||||
"LF_CheckpointSelector",
|
||||
"LF_CivitAIMetadataSetup",
|
||||
"LF_Clarity",
|
||||
"LF_ColorAnalysis",
|
||||
"LF_CompareImages",
|
||||
"LF_Contrast",
|
||||
"LF_ControlPanel",
|
||||
"LF_Desaturation",
|
||||
"LF_DisplayBoolean",
|
||||
"LF_DisplayFloat",
|
||||
"LF_DisplayInteger",
|
||||
"LF_DisplayJSON",
|
||||
"LF_DisplayPrimitiveAsJSON",
|
||||
"LF_DisplayString",
|
||||
"LF_EmbeddingSelector",
|
||||
"LF_ExtractPromptFromLoraTag",
|
||||
"LF_ExtractString",
|
||||
"LF_FilmGrain",
|
||||
"LF_Float",
|
||||
"LF_GaussianBlur",
|
||||
"LF_GetRandomKeyFromJSON",
|
||||
"LF_GetValueFromJSON",
|
||||
"LF_ImageClassifier",
|
||||
"LF_ImageHistogram",
|
||||
"LF_ImageListFromJSON",
|
||||
"LF_ImagesEditingBreakpoint",
|
||||
"LF_ImagesSlideshow",
|
||||
"LF_Integer",
|
||||
"LF_IsLandscape",
|
||||
"LF_KeywordCounter",
|
||||
"LF_KeywordToggleFromJSON",
|
||||
"LF_LLMChat",
|
||||
"LF_LLMMessenger",
|
||||
"LF_LUTApplication",
|
||||
"LF_LUTGeneration",
|
||||
"LF_Line",
|
||||
"LF_LoadAndEditImages",
|
||||
"LF_LoadFileOnce",
|
||||
"LF_LoadImages",
|
||||
"LF_LoadLocalJSON",
|
||||
"LF_LoadLoraTags",
|
||||
"LF_LoadMetadata",
|
||||
"LF_LoraAndEmbeddingSelector",
|
||||
"LF_LoraSelector",
|
||||
"LF_MarkdownDocGenerator",
|
||||
"LF_MathOperation",
|
||||
"LF_MultipleImageResizeForWeb",
|
||||
"LF_Notify",
|
||||
"LF_ParsePromptWithLoraTags",
|
||||
"LF_RandomBoolean",
|
||||
"LF_RegexReplace",
|
||||
"LF_RegionExtractor",
|
||||
"LF_ResizeImageByEdge",
|
||||
"LF_ResizeImageToDimension",
|
||||
"LF_ResizeImageToSquare",
|
||||
"LF_ResolutionSwitcher",
|
||||
"LF_SamplerSelector",
|
||||
"LF_SaveImageForCivitAI",
|
||||
"LF_SaveJSON",
|
||||
"LF_SaveMarkdown",
|
||||
"LF_SchedulerSelector",
|
||||
"LF_Sepia",
|
||||
"LF_SequentialSeedsGenerator",
|
||||
"LF_SetValueInJSON",
|
||||
"LF_ShuffleJSONKeys",
|
||||
"LF_Something2Number",
|
||||
"LF_Something2String",
|
||||
"LF_SortJSONKeys",
|
||||
"LF_String",
|
||||
"LF_StringReplace",
|
||||
"LF_StringTemplate",
|
||||
"LF_StringToJSON",
|
||||
"LF_SwitchFloat",
|
||||
"LF_SwitchImage",
|
||||
"LF_SwitchInteger",
|
||||
"LF_SwitchJSON",
|
||||
"LF_SwitchString",
|
||||
"LF_UpdateUsageStatistics",
|
||||
"LF_UpscaleModelSelector",
|
||||
"LF_UrandomSeedGenerator",
|
||||
"LF_UsageStatistics",
|
||||
"LF_VAESelector",
|
||||
"LF_ViewImages",
|
||||
"LF_Vignette",
|
||||
"LF_WallOfText",
|
||||
"LF_WriteJSON"
|
||||
],
|
||||
{
|
||||
"title_aux": "LF Nodes [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/lum3on/comfyui_LLM_Polymath": [
|
||||
[
|
||||
"ConceptEraserNode",
|
||||
@@ -5169,6 +5509,14 @@
|
||||
"title_aux": "ComfyUI-Calendar-Node [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/mm-akhtar/comfyui-mask-selector-node": [
|
||||
[
|
||||
"Mask Selector"
|
||||
],
|
||||
{
|
||||
"title_aux": "comfyui-mask-selector-node"
|
||||
}
|
||||
],
|
||||
"https://github.com/mohamedsobhi777/ComfyUI-FramerComfy": [
|
||||
[
|
||||
"FramerComfyBooleanInputNode",
|
||||
@@ -5241,18 +5589,6 @@
|
||||
"title_aux": "ComfyUI-Crop-Border"
|
||||
}
|
||||
],
|
||||
"https://github.com/myAiLemon/MagicAutomaticPicture": [
|
||||
[
|
||||
"EditableStringNode",
|
||||
"IntegratedCLIPTextEncodeWithExtract",
|
||||
"MagicLatent",
|
||||
"ProcessAndSave",
|
||||
"StringConcat"
|
||||
],
|
||||
{
|
||||
"title_aux": "MagicAutomaticPicture [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/naderzare/comfyui-inodes": [
|
||||
[
|
||||
"IAzureAiApi",
|
||||
@@ -5336,6 +5672,14 @@
|
||||
"title_aux": "ComfyUI-StereoCrafter [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/newraina/ComfyUI-Remote-Save-Image": [
|
||||
[
|
||||
"RemoteImageSaver"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Remote-Save-Image [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/nidefawl/ComfyUI-nidefawl": [
|
||||
[
|
||||
"BlendImagesWithBoundedMasks",
|
||||
@@ -5372,14 +5716,6 @@
|
||||
"title_aux": "List Data Helper Nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/niknah/ComfyUI-InfiniteYou": [
|
||||
[
|
||||
"InfiniteYouSampler"
|
||||
],
|
||||
{
|
||||
"title_aux": "niknah/ComfyUI-InfiniteYou"
|
||||
}
|
||||
],
|
||||
"https://github.com/nkchocoai/ComfyUI-PromptUtilities": [
|
||||
[
|
||||
"PromptUtilitiesConstString",
|
||||
@@ -5792,6 +6128,15 @@
|
||||
"title_aux": "comfyui-rxmt-nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/rphmeier/comfyui-videodepthanything": [
|
||||
[
|
||||
"VideoDepthAnythingLoader",
|
||||
"VideoDepthAnythingProcess"
|
||||
],
|
||||
{
|
||||
"title_aux": "comfyui-videodepthanything"
|
||||
}
|
||||
],
|
||||
"https://github.com/ruka-game/rukalib_comfyui": [
|
||||
[
|
||||
"RukaDebugProbe",
|
||||
@@ -5801,6 +6146,40 @@
|
||||
"title_aux": "ComfyUI RukaLib [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ryanontheinside/ComfyUI-Livepeer": [
|
||||
[
|
||||
"BatchInfo",
|
||||
"BatchIterator",
|
||||
"LivepeerA2T",
|
||||
"LivepeerAudioJobGetter",
|
||||
"LivepeerI2I",
|
||||
"LivepeerI2T",
|
||||
"LivepeerI2V",
|
||||
"LivepeerImageJobGetter",
|
||||
"LivepeerLLM",
|
||||
"LivepeerLive2Video",
|
||||
"LivepeerSegment",
|
||||
"LivepeerT2I",
|
||||
"LivepeerT2S",
|
||||
"LivepeerTextJobGetter",
|
||||
"LivepeerUpscale",
|
||||
"LivepeerVideoJobGetter"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Livepeer [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ryanontheinside/ComfyUI-MineWorld": [
|
||||
[
|
||||
"MineWorldGenerateFrame",
|
||||
"MineWorldGenerateSequence",
|
||||
"MineWorldInitialState",
|
||||
"MineWorldModelLoader"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI MineWorld Nodes [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ryanontheinside/ComfyUI_YoloNasObjectDetection_Tensorrt": [
|
||||
[
|
||||
"YoloNasDetectionTensorrt"
|
||||
@@ -5903,17 +6282,6 @@
|
||||
"title_aux": "ComfyUI_CheckPointLoader_Ext [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/silveroxides/ComfyUI-ModelUtils": [
|
||||
[
|
||||
"CLIPMetaKeys",
|
||||
"CheckpointMetaKeys",
|
||||
"LoRAMetaKeys",
|
||||
"UNetMetaKeys"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-ModelUtils [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/sizzlebop/comfyui-llm-prompt-enhancer": [
|
||||
[
|
||||
"PromptEnhancer"
|
||||
@@ -6154,35 +6522,6 @@
|
||||
"title_aux": "Divergent Nodes [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/thisiseddy-ab/ComfyUI-Edins-Ultimate-Pack": [
|
||||
[
|
||||
"EUP - Adaptive Tiling Strategy Parameters",
|
||||
"EUP - Adjacency Padded Tiling Strategy Parameters",
|
||||
"EUP - Advanced Pixel TiledKSample Upscaler Provider",
|
||||
"EUP - Advanced Pixel TiledKSample Upscaler Provider Pipe",
|
||||
"EUP - Aspect Adaption Denoising Strategy Parameters",
|
||||
"EUP - Context Padded Tiling Strategy Parameters",
|
||||
"EUP - Custom Aspect Ratio",
|
||||
"EUP - Hierarchical Tiling Strategy Parameters",
|
||||
"EUP - Iterative Latent Upscaler",
|
||||
"EUP - Latent Merger",
|
||||
"EUP - Non-Uniform Tiling Strategy Parameters",
|
||||
"EUP - Overlaping Tiling Strategy Parameters",
|
||||
"EUP - Padded Tiling Strategy Parameters",
|
||||
"EUP - Pixel TiledKSample Upscaler Provider",
|
||||
"EUP - Pixel TiledKSample Upscaler Provider Pipe",
|
||||
"EUP - Random Tiling Strategy Parameters",
|
||||
"EUP - Random-Hierarchical Tiling Strategy Parameters",
|
||||
"EUP - Sampler's Advanced Parameters",
|
||||
"EUP - Simple Tiling Strategy Parameters",
|
||||
"EUP - Smmooth Denoising Strategy Parameters",
|
||||
"EUP - Tiled KSampler",
|
||||
"EUP - Tiled KSampler Advanced"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Edins-Ultimate-Pack"
|
||||
}
|
||||
],
|
||||
"https://github.com/threadedblue/MLXnodes": [
|
||||
[
|
||||
"MLXImg2Img",
|
||||
@@ -6327,6 +6666,15 @@
|
||||
"title_aux": "ComfyUI_Toolbox"
|
||||
}
|
||||
],
|
||||
"https://github.com/vladp0727/Comfyui-with-Furniture": [
|
||||
[
|
||||
"GetMaskFromAlpha",
|
||||
"GetQuadrilateralOutfit"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI Simple Image Tools [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/walterFeng/ComfyUI-Image-Utils": [
|
||||
[
|
||||
"Calculate Image Brightness",
|
||||
@@ -6451,13 +6799,26 @@
|
||||
"AceColorFixX",
|
||||
"AceFloatX",
|
||||
"AceIntegerX",
|
||||
"BLIPMatcherX",
|
||||
"BlendLatentsX",
|
||||
"CheckpointLoaderBNB_X",
|
||||
"CheckpointLoaderNF4_X",
|
||||
"ColorCorrectionX",
|
||||
"ColorSpaceConversionX",
|
||||
"ColorTransferNodeX",
|
||||
"CommonSourcesX",
|
||||
"ConstantColorX",
|
||||
"ConvexHullByMaskX",
|
||||
"DeepSeekX",
|
||||
"DepthDisplaceX",
|
||||
"DummyTestNodeX",
|
||||
"EmptyLatentX",
|
||||
"ExpressionsX",
|
||||
"FourCornerPinMaskX",
|
||||
"GaussianBlurX",
|
||||
"GaussianMaskBlurX",
|
||||
"IfConditionX",
|
||||
"ImageCompositionX",
|
||||
"ImageTileSquare",
|
||||
"ImageUntileSquare",
|
||||
"KSamplerComboX",
|
||||
@@ -6467,11 +6828,13 @@
|
||||
"PixtralVisionX",
|
||||
"PixtralX",
|
||||
"RegionTesterNodeX",
|
||||
"RegionalPromptSamplerX",
|
||||
"RelightX",
|
||||
"RemoveBackgroundX",
|
||||
"SaveImageX",
|
||||
"SelectiveDepthLoraBlocksX",
|
||||
"SimpleBlockerX",
|
||||
"SplineImageMask",
|
||||
"UnetLoaderBNB_X",
|
||||
"WhiteBalanceX"
|
||||
],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,67 @@
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"author": "zhuanqianfish",
|
||||
"title": "TaesdDecoder [REMOVED]",
|
||||
"reference": "https://github.com/zhuanqianfish/TaesdDecoder",
|
||||
"files": [
|
||||
"https://github.com/zhuanqianfish/TaesdDecoder"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "use TAESD decoded image.you need donwload taesd_decoder.pth and taesdxl_decoder.pth to vae_approx folder first.\n It will result in a slight loss of image quality and a significant decrease in peak video memory during decoding."
|
||||
},
|
||||
{
|
||||
"author": "myAiLemon",
|
||||
"title": "MagicAutomaticPicture [REMOVED]",
|
||||
"reference": "https://github.com/myAiLemon/MagicAutomaticPicture",
|
||||
"files": [
|
||||
"https://github.com/myAiLemon/MagicAutomaticPicture"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A comfyui node package that can generate pictures and automatically save positive prompts and eliminate unwanted prompts"
|
||||
},
|
||||
{
|
||||
"author": "thisiseddy-ab",
|
||||
"title": "ComfyUI-Edins-Ultimate-Pack [REMOVED]",
|
||||
"reference": "https://github.com/thisiseddy-ab/ComfyUI-Edins-Ultimate-Pack",
|
||||
"files": [
|
||||
"https://github.com/thisiseddy-ab/ComfyUI-Edins-Ultimate-Pack"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Well i needet a Tiled Ksampler that still works for Comfy UI there were none so i made one, in this Package i will put all Nodes i will develop for Comfy Ui still in beta alot will change.."
|
||||
},
|
||||
{
|
||||
"author": "Davros666",
|
||||
"title": "safetriggers [REMOVED]",
|
||||
"reference": "https://github.com/Davros666/safetriggers",
|
||||
"files": [
|
||||
"https://github.com/Davros666/safetriggers"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI Nodes for READING TRIGGERS, TRIGGER-WORDS, TRIGGER-PHRASES FROM LoRAs"
|
||||
},
|
||||
{
|
||||
"author": "cubiq",
|
||||
"title": "Simple Math [REMOVED]",
|
||||
"id": "simplemath",
|
||||
"reference": "https://github.com/cubiq/ComfyUI_SimpleMath",
|
||||
"files": [
|
||||
"https://github.com/cubiq/ComfyUI_SimpleMath"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "custom node for ComfyUI to perform simple math operations"
|
||||
},
|
||||
{
|
||||
"author": "lucafoscili",
|
||||
"title": "LF Nodes [DEPRECATED]",
|
||||
"reference": "https://github.com/lucafoscili/comfyui-lf",
|
||||
"files": [
|
||||
"https://github.com/lucafoscili/comfyui-lf"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Custom nodes with a touch of extra UX, including: history for primitives, JSON manipulation, logic switches with visual feedback, LLM chat... and more!"
|
||||
},
|
||||
{
|
||||
"author": "AI2lab",
|
||||
"title": "comfyUI-tool-2lab [REMOVED]",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
373
notebooks/comfyui_colab_with_manager.ipynb
Normal file
373
notebooks/comfyui_colab_with_manager.ipynb
Normal file
@@ -0,0 +1,373 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "aaaaaaaaaa"
|
||||
},
|
||||
"source": [
|
||||
"Git clone the repo and install the requirements. (ignore the pip errors about protobuf)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "bbbbbbbbbb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# #@title Environment Setup\n",
|
||||
"\n",
|
||||
"from pathlib import Path\n",
|
||||
"\n",
|
||||
"OPTIONS = {}\n",
|
||||
"\n",
|
||||
"USE_GOOGLE_DRIVE = True #@param {type:\"boolean\"}\n",
|
||||
"UPDATE_COMFY_UI = True #@param {type:\"boolean\"}\n",
|
||||
"USE_COMFYUI_MANAGER = True #@param {type:\"boolean\"}\n",
|
||||
"INSTALL_CUSTOM_NODES_DEPENDENCIES = True #@param {type:\"boolean\"}\n",
|
||||
"OPTIONS['USE_GOOGLE_DRIVE'] = USE_GOOGLE_DRIVE\n",
|
||||
"OPTIONS['UPDATE_COMFY_UI'] = UPDATE_COMFY_UI\n",
|
||||
"OPTIONS['USE_COMFYUI_MANAGER'] = USE_COMFYUI_MANAGER\n",
|
||||
"OPTIONS['INSTALL_CUSTOM_NODES_DEPENDENCIES'] = INSTALL_CUSTOM_NODES_DEPENDENCIES\n",
|
||||
"\n",
|
||||
"current_dir = !pwd\n",
|
||||
"WORKSPACE = f\"{current_dir[0]}/ComfyUI\"\n",
|
||||
"\n",
|
||||
"if OPTIONS['USE_GOOGLE_DRIVE']:\n",
|
||||
" !echo \"Mounting Google Drive...\"\n",
|
||||
" %cd /\n",
|
||||
"\n",
|
||||
" from google.colab import drive\n",
|
||||
" drive.mount('/content/drive')\n",
|
||||
"\n",
|
||||
" WORKSPACE = \"/content/drive/MyDrive/ComfyUI\"\n",
|
||||
" %cd /content/drive/MyDrive\n",
|
||||
"\n",
|
||||
"![ ! -d $WORKSPACE ] && echo -= Initial setup ComfyUI =- && git clone https://github.com/comfyanonymous/ComfyUI\n",
|
||||
"%cd $WORKSPACE\n",
|
||||
"\n",
|
||||
"if OPTIONS['UPDATE_COMFY_UI']:\n",
|
||||
" !echo -= Updating ComfyUI =-\n",
|
||||
"\n",
|
||||
" # Correction of the issue of permissions being deleted on Google Drive.\n",
|
||||
" ![ -f \".ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/nightly/update_windows/update_comfyui_and_python_dependencies.bat\n",
|
||||
" ![ -f \".ci/nightly/windows_base_files/run_nvidia_gpu.bat\" ] && chmod 755 .ci/nightly/windows_base_files/run_nvidia_gpu.bat\n",
|
||||
" ![ -f \".ci/update_windows/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/update_windows/update_comfyui_and_python_dependencies.bat\n",
|
||||
" ![ -f \".ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat\" ] && chmod 755 .ci/update_windows_cu118/update_comfyui_and_python_dependencies.bat\n",
|
||||
" ![ -f \".ci/update_windows/update.py\" ] && chmod 755 .ci/update_windows/update.py\n",
|
||||
" ![ -f \".ci/update_windows/update_comfyui.bat\" ] && chmod 755 .ci/update_windows/update_comfyui.bat\n",
|
||||
" ![ -f \".ci/update_windows/README_VERY_IMPORTANT.txt\" ] && chmod 755 .ci/update_windows/README_VERY_IMPORTANT.txt\n",
|
||||
" ![ -f \".ci/update_windows/run_cpu.bat\" ] && chmod 755 .ci/update_windows/run_cpu.bat\n",
|
||||
" ![ -f \".ci/update_windows/run_nvidia_gpu.bat\" ] && chmod 755 .ci/update_windows/run_nvidia_gpu.bat\n",
|
||||
"\n",
|
||||
" !git pull\n",
|
||||
"\n",
|
||||
"!echo -= Install dependencies =-\n",
|
||||
"!pip3 install accelerate\n",
|
||||
"!pip3 install einops transformers>=4.28.1 safetensors>=0.4.2 aiohttp pyyaml Pillow scipy tqdm psutil tokenizers>=0.13.3\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 soundfile sentencepiece\n",
|
||||
"\n",
|
||||
"if OPTIONS['USE_COMFYUI_MANAGER']:\n",
|
||||
" %cd custom_nodes\n",
|
||||
"\n",
|
||||
" # Correction of the issue of permissions being deleted on Google Drive.\n",
|
||||
" ![ -f \"ComfyUI-Manager/check.sh\" ] && chmod 755 ComfyUI-Manager/check.sh\n",
|
||||
" ![ -f \"ComfyUI-Manager/scan.sh\" ] && chmod 755 ComfyUI-Manager/scan.sh\n",
|
||||
" ![ -f \"ComfyUI-Manager/node_db/dev/scan.sh\" ] && chmod 755 ComfyUI-Manager/node_db/dev/scan.sh\n",
|
||||
" ![ -f \"ComfyUI-Manager/node_db/tutorial/scan.sh\" ] && chmod 755 ComfyUI-Manager/node_db/tutorial/scan.sh\n",
|
||||
" ![ -f \"ComfyUI-Manager/scripts/install-comfyui-venv-linux.sh\" ] && chmod 755 ComfyUI-Manager/scripts/install-comfyui-venv-linux.sh\n",
|
||||
" ![ -f \"ComfyUI-Manager/scripts/install-comfyui-venv-win.bat\" ] && chmod 755 ComfyUI-Manager/scripts/install-comfyui-venv-win.bat\n",
|
||||
"\n",
|
||||
" ![ ! -d ComfyUI-Manager ] && echo -= Initial setup ComfyUI-Manager =- && git clone https://github.com/ltdrdata/ComfyUI-Manager\n",
|
||||
" %cd ComfyUI-Manager\n",
|
||||
" !git pull\n",
|
||||
"\n",
|
||||
"%cd $WORKSPACE\n",
|
||||
"\n",
|
||||
"if OPTIONS['INSTALL_CUSTOM_NODES_DEPENDENCIES']:\n",
|
||||
" !echo -= Install custom nodes dependencies =-\n",
|
||||
" !pip install GitPython\n",
|
||||
" !python custom_nodes/ComfyUI-Manager/cm-cli.py restore-dependencies\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "cccccccccc"
|
||||
},
|
||||
"source": [
|
||||
"Download some models/checkpoints/vae or custom comfyui nodes (uncomment the commands for the ones you want)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "dddddddddd"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Checkpoints\n",
|
||||
"\n",
|
||||
"### SDXL\n",
|
||||
"### I recommend these workflow examples: https://comfyanonymous.github.io/ComfyUI_examples/sdxl/\n",
|
||||
"\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/stable-diffusion-xl-refiner-1.0/resolve/main/sd_xl_refiner_1.0.safetensors -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"# SDXL ReVision\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/clip_vision_g/resolve/main/clip_vision_g.safetensors -P ./models/clip_vision/\n",
|
||||
"\n",
|
||||
"# SD1.5\n",
|
||||
"!wget -c https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"# SD2\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/stable-diffusion-2-1-base/resolve/main/v2-1_512-ema-pruned.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/stable-diffusion-2-1/resolve/main/v2-1_768-ema-pruned.safetensors -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"# Some SD1.5 anime style\n",
|
||||
"#!wget -c https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix2/AbyssOrangeMix2_hard.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix3/AOM3A1_orangemixs.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix3/AOM3A3_orangemixs.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/Linaqruf/anything-v3.0/resolve/main/anything-v3-fp16-pruned.safetensors -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"# Waifu Diffusion 1.5 (anime style SD2.x 768-v)\n",
|
||||
"#!wget -c https://huggingface.co/waifu-diffusion/wd-1-5-beta3/resolve/main/wd-illusion-fp16.safetensors -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# unCLIP models\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/illuminatiDiffusionV1_v11_unCLIP/resolve/main/illuminatiDiffusionV1_v11-unclip-h-fp16.safetensors -P ./models/checkpoints/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/wd-1.5-beta2_unCLIP/resolve/main/wd-1-5-beta2-aesthetic-unclip-h-fp16.safetensors -P ./models/checkpoints/\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# VAE\n",
|
||||
"!wget -c https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors -P ./models/vae/\n",
|
||||
"#!wget -c https://huggingface.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt -P ./models/vae/\n",
|
||||
"#!wget -c https://huggingface.co/hakurei/waifu-diffusion-v1-4/resolve/main/vae/kl-f8-anime2.ckpt -P ./models/vae/\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# Loras\n",
|
||||
"#!wget -c https://civitai.com/api/download/models/10350 -O ./models/loras/theovercomer8sContrastFix_sd21768.safetensors #theovercomer8sContrastFix SD2.x 768-v\n",
|
||||
"#!wget -c https://civitai.com/api/download/models/10638 -O ./models/loras/theovercomer8sContrastFix_sd15.safetensors #theovercomer8sContrastFix SD1.x\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_offset_example-lora_1.0.safetensors -P ./models/loras/ #SDXL offset noise lora\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# T2I-Adapter\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_depth_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_seg_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_sketch_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_keypose_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_openpose_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_color_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_canny_sd14v1.pth -P ./models/controlnet/\n",
|
||||
"\n",
|
||||
"# T2I Styles Model\n",
|
||||
"#!wget -c https://huggingface.co/TencentARC/T2I-Adapter/resolve/main/models/t2iadapter_style_sd14v1.pth -P ./models/style_models/\n",
|
||||
"\n",
|
||||
"# CLIPVision model (needed for styles model)\n",
|
||||
"#!wget -c https://huggingface.co/openai/clip-vit-large-patch14/resolve/main/pytorch_model.bin -O ./models/clip_vision/clip_vit14.bin\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# ControlNet\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_ip2p_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11e_sd15_shuffle_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_canny_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11f1p_sd15_depth_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_inpaint_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_lineart_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_mlsd_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_normalbae_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_openpose_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_scribble_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_seg_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15_softedge_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11p_sd15s2_lineart_anime_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/ControlNet-v1-1_fp16_safetensors/resolve/main/control_v11u_sd15_tile_fp16.safetensors -P ./models/controlnet/\n",
|
||||
"\n",
|
||||
"# ControlNet SDXL\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/control-lora/resolve/main/control-LoRAs-rank256/control-lora-canny-rank256.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/control-lora/resolve/main/control-LoRAs-rank256/control-lora-depth-rank256.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/control-lora/resolve/main/control-LoRAs-rank256/control-lora-recolor-rank256.safetensors -P ./models/controlnet/\n",
|
||||
"#!wget -c https://huggingface.co/stabilityai/control-lora/resolve/main/control-LoRAs-rank256/control-lora-sketch-rank256.safetensors -P ./models/controlnet/\n",
|
||||
"\n",
|
||||
"# Controlnet Preprocessor nodes by Fannovel16\n",
|
||||
"#!cd custom_nodes && git clone https://github.com/Fannovel16/comfy_controlnet_preprocessors; cd comfy_controlnet_preprocessors && python install.py\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# GLIGEN\n",
|
||||
"#!wget -c https://huggingface.co/comfyanonymous/GLIGEN_pruned_safetensors/resolve/main/gligen_sd14_textbox_pruned_fp16.safetensors -P ./models/gligen/\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# ESRGAN upscale model\n",
|
||||
"#!wget -c https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth -P ./models/upscale_models/\n",
|
||||
"#!wget -c https://huggingface.co/sberbank-ai/Real-ESRGAN/resolve/main/RealESRGAN_x2.pth -P ./models/upscale_models/\n",
|
||||
"#!wget -c https://huggingface.co/sberbank-ai/Real-ESRGAN/resolve/main/RealESRGAN_x4.pth -P ./models/upscale_models/\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "kkkkkkkkkkkkkkk"
|
||||
},
|
||||
"source": [
|
||||
"### Run ComfyUI with cloudflared (Recommended Way)\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "jjjjjjjjjjjjjj"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget -P ~ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb\n",
|
||||
"!dpkg -i ~/cloudflared-linux-amd64.deb\n",
|
||||
"\n",
|
||||
"import subprocess\n",
|
||||
"import threading\n",
|
||||
"import time\n",
|
||||
"import socket\n",
|
||||
"import urllib.request\n",
|
||||
"\n",
|
||||
"def iframe_thread(port):\n",
|
||||
" while True:\n",
|
||||
" time.sleep(0.5)\n",
|
||||
" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
|
||||
" result = sock.connect_ex(('127.0.0.1', port))\n",
|
||||
" if result == 0:\n",
|
||||
" break\n",
|
||||
" sock.close()\n",
|
||||
" print(\"\\nComfyUI finished loading, trying to launch cloudflared (if it gets stuck here cloudflared is having issues)\\n\")\n",
|
||||
"\n",
|
||||
" p = subprocess.Popen([\"cloudflared\", \"tunnel\", \"--url\", \"http://127.0.0.1:{}\".format(port)], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n",
|
||||
" for line in p.stderr:\n",
|
||||
" l = line.decode()\n",
|
||||
" if \"trycloudflare.com \" in l:\n",
|
||||
" print(\"This is the URL to access ComfyUI:\", l[l.find(\"http\"):], end='')\n",
|
||||
" #print(l, end='')\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"threading.Thread(target=iframe_thread, daemon=True, args=(8188,)).start()\n",
|
||||
"\n",
|
||||
"!python main.py --dont-print-server"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "kkkkkkkkkkkkkk"
|
||||
},
|
||||
"source": [
|
||||
"### Run ComfyUI with localtunnel\n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "jjjjjjjjjjjjj"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!npm install -g localtunnel\n",
|
||||
"\n",
|
||||
"import subprocess\n",
|
||||
"import threading\n",
|
||||
"import time\n",
|
||||
"import socket\n",
|
||||
"import urllib.request\n",
|
||||
"\n",
|
||||
"def iframe_thread(port):\n",
|
||||
" while True:\n",
|
||||
" time.sleep(0.5)\n",
|
||||
" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
|
||||
" result = sock.connect_ex(('127.0.0.1', port))\n",
|
||||
" if result == 0:\n",
|
||||
" break\n",
|
||||
" sock.close()\n",
|
||||
" print(\"\\nComfyUI finished loading, trying to launch localtunnel (if it gets stuck here localtunnel is having issues)\\n\")\n",
|
||||
"\n",
|
||||
" print(\"The password/enpoint ip for localtunnel is:\", urllib.request.urlopen('https://ipv4.icanhazip.com').read().decode('utf8').strip(\"\\n\"))\n",
|
||||
" p = subprocess.Popen([\"lt\", \"--port\", \"{}\".format(port)], stdout=subprocess.PIPE)\n",
|
||||
" for line in p.stdout:\n",
|
||||
" print(line.decode(), end='')\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"threading.Thread(target=iframe_thread, daemon=True, args=(8188,)).start()\n",
|
||||
"\n",
|
||||
"!python main.py --dont-print-server"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "gggggggggg"
|
||||
},
|
||||
"source": [
|
||||
"### Run ComfyUI with colab iframe (use only in case the previous way with localtunnel doesn't work)\n",
|
||||
"\n",
|
||||
"You should see the ui appear in an iframe. If you get a 403 error, it's your firefox settings or an extension that's messing things up.\n",
|
||||
"\n",
|
||||
"If you want to open it in another window use the link.\n",
|
||||
"\n",
|
||||
"Note that some UI features like live image previews won't work because the colab iframe blocks websockets."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "hhhhhhhhhh"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import threading\n",
|
||||
"import time\n",
|
||||
"import socket\n",
|
||||
"def iframe_thread(port):\n",
|
||||
" while True:\n",
|
||||
" time.sleep(0.5)\n",
|
||||
" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
|
||||
" result = sock.connect_ex(('127.0.0.1', port))\n",
|
||||
" if result == 0:\n",
|
||||
" break\n",
|
||||
" sock.close()\n",
|
||||
" from google.colab import output\n",
|
||||
" output.serve_kernel_port_as_iframe(port, height=1024)\n",
|
||||
" print(\"to open it in a window you can open this link here:\")\n",
|
||||
" output.serve_kernel_port_as_window(port)\n",
|
||||
"\n",
|
||||
"threading.Thread(target=iframe_thread, daemon=True, args=(8188,)).start()\n",
|
||||
"\n",
|
||||
"!python main.py --dont-print-server"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"accelerator": "GPU",
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"gpuClass": "standard",
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
@@ -12,10 +12,13 @@ import ast
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from .glob import security_check
|
||||
from .glob import manager_util
|
||||
from .glob import cm_global
|
||||
from .glob import manager_downloader
|
||||
glob_path = os.path.join(os.path.dirname(__file__), "glob")
|
||||
sys.path.append(glob_path)
|
||||
|
||||
import security_check
|
||||
import manager_util
|
||||
import cm_global
|
||||
import manager_downloader
|
||||
import folder_paths
|
||||
|
||||
manager_util.add_python_path_to_env()
|
||||
@@ -37,8 +40,8 @@ else:
|
||||
|
||||
security_check.security_check()
|
||||
|
||||
cm_global.pip_blacklist = {'torch', 'torchsde', 'torchvision'}
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
|
||||
|
||||
def skip_pip_spam(x):
|
||||
@@ -65,17 +68,15 @@ comfy_path = os.environ.get('COMFYUI_PATH')
|
||||
comfy_base_path = os.environ.get('COMFYUI_FOLDERS_BASE_PATH')
|
||||
|
||||
if comfy_path is None:
|
||||
try:
|
||||
comfy_path = os.path.abspath(os.path.dirname(sys.modules['__main__'].__file__))
|
||||
os.environ['COMFYUI_PATH'] = comfy_path
|
||||
except:
|
||||
print("[ComfyUI-Manager] environment variable 'COMFYUI_PATH' is not specified.")
|
||||
exit(-1)
|
||||
# legacy env var
|
||||
comfy_path = os.environ.get('COMFYUI_PATH')
|
||||
|
||||
if comfy_path is None:
|
||||
comfy_path = os.path.abspath(os.path.dirname(sys.modules['__main__'].__file__))
|
||||
|
||||
if comfy_base_path is None:
|
||||
comfy_base_path = comfy_path
|
||||
|
||||
|
||||
sys.__comfyui_manager_register_message_collapse = register_message_collapse
|
||||
sys.__comfyui_manager_is_import_failed_extension = is_import_failed_extension
|
||||
cm_global.register_api('cm.register_message_collapse', register_message_collapse)
|
||||
@@ -391,11 +392,7 @@ try:
|
||||
def emit(self, record):
|
||||
global is_start_mode
|
||||
|
||||
try:
|
||||
message = record.getMessage()
|
||||
except Exception as e:
|
||||
message = f"<<logging error>>: {record} - {e}"
|
||||
original_stderr.write(message)
|
||||
message = record.getMessage()
|
||||
|
||||
if is_start_mode:
|
||||
match = re.search(pat_import_fail, message)
|
||||
@@ -1,62 +1,15 @@
|
||||
[build-system]
|
||||
requires = ["setuptools >= 61.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "comfyui-manager"
|
||||
license = { text = "GPL-3.0-only" }
|
||||
version = "4.0.0-beta.1"
|
||||
requires-python = ">= 3.9"
|
||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||
readme = "README.md"
|
||||
keywords = ["comfyui", "comfyui-manager"]
|
||||
|
||||
maintainers = [
|
||||
{ name = "Dr.Lt.Data", email = "dr.lt.data@gmail.com" },
|
||||
{ name = "Yoland Yan", email = "yoland@drip.art" },
|
||||
{ name = "James Kwon", email = "hongilkwon316@gmail.com" },
|
||||
{ name = "Robin Huang", email = "robin@drip.art" },
|
||||
]
|
||||
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
"GitPython",
|
||||
"PyGithub",
|
||||
"matrix-client==0.4.0",
|
||||
"transformers",
|
||||
"huggingface-hub>0.20",
|
||||
"typer",
|
||||
"rich",
|
||||
"typing-extensions",
|
||||
"toml",
|
||||
"uv",
|
||||
"chardet"
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = ["pre-commit", "pytest", "ruff", "pytest-cov"]
|
||||
version = "3.31.12"
|
||||
license = { file = "LICENSE.txt" }
|
||||
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions", "toml", "uv", "chardet"]
|
||||
|
||||
[project.urls]
|
||||
Repository = "https://github.com/ltdrdata/ComfyUI-Manager"
|
||||
# Used by Comfy Registry https://comfyregistry.org
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["."]
|
||||
include = ["comfyui_manager*"]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py39"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E4", # default
|
||||
"E7", # default
|
||||
"E9", # default
|
||||
"F", # default
|
||||
"I", # isort-like behavior (import statement sorting)
|
||||
]
|
||||
[tool.comfy]
|
||||
PublisherId = "drltdata"
|
||||
DisplayName = "ComfyUI-Manager"
|
||||
Icon = ""
|
||||
|
||||
39
scripts/colab-dependencies.py
Normal file
39
scripts/colab-dependencies.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def get_enabled_subdirectories_with_files(base_directory):
|
||||
subdirs_with_files = []
|
||||
for subdir in os.listdir(base_directory):
|
||||
try:
|
||||
full_path = os.path.join(base_directory, subdir)
|
||||
if os.path.isdir(full_path) and not subdir.endswith(".disabled") and not subdir.startswith('.') and subdir != '__pycache__':
|
||||
print(f"## Install dependencies for '{subdir}'")
|
||||
requirements_file = os.path.join(full_path, "requirements.txt")
|
||||
install_script = os.path.join(full_path, "install.py")
|
||||
|
||||
if os.path.exists(requirements_file) or os.path.exists(install_script):
|
||||
subdirs_with_files.append((full_path, requirements_file, install_script))
|
||||
except Exception as e:
|
||||
print(f"EXCEPTION During Dependencies INSTALL on '{subdir}':\n{e}")
|
||||
|
||||
return subdirs_with_files
|
||||
|
||||
|
||||
def install_requirements(requirements_file_path):
|
||||
if os.path.exists(requirements_file_path):
|
||||
subprocess.run(["pip", "install", "-r", requirements_file_path])
|
||||
|
||||
|
||||
def run_install_script(install_script_path):
|
||||
if os.path.exists(install_script_path):
|
||||
subprocess.run(["python", install_script_path])
|
||||
|
||||
|
||||
custom_nodes_directory = "custom_nodes"
|
||||
subdirs_with_files = get_enabled_subdirectories_with_files(custom_nodes_directory)
|
||||
|
||||
|
||||
for subdir, requirements_file, install_script in subdirs_with_files:
|
||||
install_requirements(requirements_file)
|
||||
run_install_script(install_script)
|
||||
21
scripts/install-comfyui-venv-linux.sh
Executable file
21
scripts/install-comfyui-venv-linux.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
git clone https://github.com/comfyanonymous/ComfyUI
|
||||
cd ComfyUI/custom_nodes
|
||||
git clone https://github.com/ltdrdata/ComfyUI-Manager comfyui-manager
|
||||
cd ..
|
||||
python -m venv venv
|
||||
source venv/bin/activate
|
||||
python -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121
|
||||
python -m pip install -r requirements.txt
|
||||
python -m pip install -r custom_nodes/comfyui-manager/requirements.txt
|
||||
cd ..
|
||||
echo "#!/bin/bash" > run_gpu.sh
|
||||
echo "cd ComfyUI" >> run_gpu.sh
|
||||
echo "source venv/bin/activate" >> run_gpu.sh
|
||||
echo "python main.py --preview-method auto" >> run_gpu.sh
|
||||
chmod +x run_gpu.sh
|
||||
|
||||
echo "#!/bin/bash" > run_cpu.sh
|
||||
echo "cd ComfyUI" >> run_cpu.sh
|
||||
echo "source venv/bin/activate" >> run_cpu.sh
|
||||
echo "python main.py --preview-method auto --cpu" >> run_cpu.sh
|
||||
chmod +x run_cpu.sh
|
||||
17
scripts/install-comfyui-venv-win.bat
Executable file
17
scripts/install-comfyui-venv-win.bat
Executable file
@@ -0,0 +1,17 @@
|
||||
git clone https://github.com/comfyanonymous/ComfyUI
|
||||
cd ComfyUI/custom_nodes
|
||||
git clone https://github.com/ltdrdata/ComfyUI-Manager comfyui-manager
|
||||
cd ..
|
||||
python -m venv venv
|
||||
call venv/Scripts/activate
|
||||
python -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu121
|
||||
python -m pip install -r requirements.txt
|
||||
python -m pip install -r custom_nodes/comfyui-manager/requirements.txt
|
||||
cd ..
|
||||
echo "cd ComfyUI" >> run_gpu.bat
|
||||
echo "call venv/Scripts/activate" >> run_gpu.bat
|
||||
echo "python main.py" >> run_gpu.bat
|
||||
|
||||
echo "cd ComfyUI" >> run_cpu.bat
|
||||
echo "call venv/Scripts/activate" >> run_cpu.bat
|
||||
echo "python main.py --cpu" >> run_cpu.bat
|
||||
3
scripts/install-manager-for-portable-version.bat
Normal file
3
scripts/install-manager-for-portable-version.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
.\python_embeded\python.exe -s -m pip install gitpython
|
||||
.\python_embeded\python.exe -c "import git; git.Repo.clone_from('https://github.com/ltdrdata/ComfyUI-Manager', './ComfyUI/custom_nodes/comfyui-manager')"
|
||||
.\python_embeded\python.exe -m pip install -r ./ComfyUI/custom_nodes/comfyui-manager/requirements.txt
|
||||
0
snapshots/the_snapshot_files_are_located_here
Normal file
0
snapshots/the_snapshot_files_are_located_here
Normal file
Reference in New Issue
Block a user