Compare commits
1 Commits
3.37
...
docs/node-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
729ff5a34b |
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:
|
|
||||||
- draft-v4
|
|
||||||
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
|
|
||||||
30
README.md
30
README.md
@@ -8,7 +8,7 @@
|
|||||||
* V3.16: Support for `uv` has been added. Set `use_uv` in `config.ini`.
|
* V3.16: Support for `uv` has been added. Set `use_uv` in `config.ini`.
|
||||||
* V3.10: `double-click feature` is removed
|
* V3.10: `double-click feature` is removed
|
||||||
* This feature has been moved to https://github.com/ltdrdata/comfyui-connection-helper
|
* This feature has been moved to https://github.com/ltdrdata/comfyui-connection-helper
|
||||||
* V3.3.2: Overhauled. Officially supports [https://registry.comfy.org/](https://registry.comfy.org/).
|
* V3.3.2: Overhauled. Officially supports [https://comfyregistry.org/](https://comfyregistry.org/).
|
||||||
* You can see whole nodes info on [ComfyUI Nodes Info](https://ltdrdata.github.io/) page.
|
* You can see whole nodes info on [ComfyUI Nodes Info](https://ltdrdata.github.io/) page.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
To install ComfyUI-Manager in addition to an existing installation of ComfyUI, you can follow the following steps:
|
To install ComfyUI-Manager in addition to an existing installation of ComfyUI, you can follow the following steps:
|
||||||
|
|
||||||
1. Go to `ComfyUI/custom_nodes` dir in terminal (cmd)
|
1. goto `ComfyUI/custom_nodes` dir in terminal(cmd)
|
||||||
2. `git clone https://github.com/ltdrdata/ComfyUI-Manager comfyui-manager`
|
2. `git clone https://github.com/ltdrdata/ComfyUI-Manager comfyui-manager`
|
||||||
3. Restart ComfyUI
|
3. Restart ComfyUI
|
||||||
|
|
||||||
@@ -28,8 +28,8 @@ To install ComfyUI-Manager in addition to an existing installation of ComfyUI, y
|
|||||||
- standalone version
|
- standalone version
|
||||||
- select option: use windows default console window
|
- 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
|
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 choose 'Save As...'
|
- Don't click. Right click the link and use save as...
|
||||||
3. Double-click `install-manager-for-portable-version.bat` batch file
|
3. double click `install-manager-for-portable-version.bat` batch file
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ pip install comfy-cli
|
|||||||
comfy install
|
comfy install
|
||||||
```
|
```
|
||||||
|
|
||||||
Linux/macOS:
|
Linux/OSX:
|
||||||
```commandline
|
```commandline
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
. venv/bin/activate
|
. venv/bin/activate
|
||||||
@@ -57,13 +57,13 @@ comfy install
|
|||||||
* See also: https://github.com/Comfy-Org/comfy-cli
|
* See also: https://github.com/Comfy-Org/comfy-cli
|
||||||
|
|
||||||
|
|
||||||
### Installation[method4] (Installation for Linux+venv: ComfyUI + ComfyUI-Manager)
|
### Installation[method4] (Installation for linux+venv: ComfyUI + ComfyUI-Manager)
|
||||||
|
|
||||||
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
To install ComfyUI with ComfyUI-Manager on Linux using a venv environment, you can follow these steps:
|
||||||
* **prerequisite: python-is-python3, python3-venv, git**
|
* **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
|
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 choose 'Save As...'
|
- 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.
|
- 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`
|
2. `chmod +x install-comfyui-venv-linux.sh`
|
||||||
3. `./install-comfyui-venv-linux.sh`
|
3. `./install-comfyui-venv-linux.sh`
|
||||||
@@ -176,7 +176,7 @@ The following settings are applied based on the section marked as `is_default`.
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
## cm-cli: command line tools for power users
|
## cm-cli: command line tools for power user
|
||||||
* A tool is provided that allows you to use the features of ComfyUI-Manager without running ComfyUI.
|
* A tool is provided that allows you to use the features of ComfyUI-Manager without running ComfyUI.
|
||||||
* For more details, please refer to the [cm-cli documentation](docs/en/cm-cli.md).
|
* For more details, please refer to the [cm-cli documentation](docs/en/cm-cli.md).
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ The following settings are applied based on the section marked as `is_default`.
|
|||||||
* `<current timestamp>` Ensure that the timestamp is always unique.
|
* `<current timestamp>` Ensure that the timestamp is always unique.
|
||||||
* "components" should have the same structure as the content of the file stored in `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
* "components" should have the same structure as the content of the file stored in `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
||||||
* `<component name>`: The name should be in the format `<prefix>::<node name>`.
|
* `<component name>`: The name should be in the format `<prefix>::<node name>`.
|
||||||
* `<component node data>`: In the node data of the group node.
|
* `<compnent nodeata>`: In the nodedata of the group node.
|
||||||
* `<version>`: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`)
|
* `<version>`: Only two formats are allowed: `major.minor.patch` or `major.minor`. (e.g. `1.0`, `2.2.1`)
|
||||||
* `<datetime>`: Saved time
|
* `<datetime>`: Saved time
|
||||||
* `<packname>`: If the packname is not empty, the category becomes packname/workflow, and it is saved in the <packname>.pack file in `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
* `<packname>`: If the packname is not empty, the category becomes packname/workflow, and it is saved in the <packname>.pack file in `<USER_DIRECTORY>/default/ComfyUI-Manager/components`.
|
||||||
@@ -240,7 +240,7 @@ The following settings are applied based on the section marked as `is_default`.
|
|||||||
* Dragging and dropping or pasting a single component will add a node. However, when adding multiple components, nodes will not be added.
|
* Dragging and dropping or pasting a single component will add a node. However, when adding multiple components, nodes will not be added.
|
||||||
|
|
||||||
|
|
||||||
## Support for installing missing nodes
|
## Support of missing nodes installation
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -279,10 +279,10 @@ The following settings are applied based on the section marked as `is_default`.
|
|||||||
* Logging to file feature
|
* Logging to file feature
|
||||||
* This feature is enabled by default and can be disabled by setting `file_logging = False` in the `config.ini`.
|
* This feature is enabled by default and can be disabled by setting `file_logging = False` in the `config.ini`.
|
||||||
|
|
||||||
* Fix node (recreate): When right-clicking on a node and selecting `Fix node (recreate)`, you can recreate the node. The widget's values are reset, while the connections maintain those with the same names.
|
* Fix node(recreate): When right-clicking on a node and selecting `Fix node (recreate)`, you can recreate the node. The widget's values are reset, while the connections maintain those with the same names.
|
||||||
* It is used to correct errors in nodes of old workflows created before, which are incompatible with the version changes of custom nodes.
|
* It is used to correct errors in nodes of old workflows created before, which are incompatible with the version changes of custom nodes.
|
||||||
|
|
||||||
* Double-Click Node Title: You can set the double-click behavior of nodes in the ComfyUI-Manager menu.
|
* Double-Click Node Title: You can set the double click behavior of nodes in the ComfyUI-Manager menu.
|
||||||
* `Copy All Connections`, `Copy Input Connections`: Double-clicking a node copies the connections of the nearest node.
|
* `Copy All Connections`, `Copy Input Connections`: Double-clicking a node copies the connections of the nearest node.
|
||||||
* This action targets the nearest node within a straight-line distance of 1000 pixels from the center of the node.
|
* This action targets the nearest node within a straight-line distance of 1000 pixels from the center of the node.
|
||||||
* In the case of `Copy All Connections`, it duplicates existing outputs, but since it does not allow duplicate connections, the existing output connections of the original node are disconnected.
|
* In the case of `Copy All Connections`, it duplicates existing outputs, but since it does not allow duplicate connections, the existing output connections of the original node are disconnected.
|
||||||
@@ -348,7 +348,7 @@ When you run the `scan.sh` script:
|
|||||||
|
|
||||||
* It updates the `github-stats.json`.
|
* It updates the `github-stats.json`.
|
||||||
* This uses the GitHub API, so set your token with `export GITHUB_TOKEN=your_token_here` to avoid quickly reaching the rate limit and malfunctioning.
|
* This uses the GitHub API, so set your token with `export GITHUB_TOKEN=your_token_here` to avoid quickly reaching the rate limit and malfunctioning.
|
||||||
* To skip this step, add the `--skip-stat-update` option.
|
* To skip this step, add the `--skip-update-stat` option.
|
||||||
|
|
||||||
* The `--skip-all` option applies both `--skip-update` and `--skip-stat-update`.
|
* The `--skip-all` option applies both `--skip-update` and `--skip-stat-update`.
|
||||||
|
|
||||||
@@ -356,9 +356,9 @@ When you run the `scan.sh` script:
|
|||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
* If your `git.exe` is installed in a specific location other than system git, please install ComfyUI-Manager and run ComfyUI. Then, specify the path including the file name in `git_exe = ` in the `<USER_DIRECTORY>/default/ComfyUI-Manager/config.ini` file that is generated.
|
* If your `git.exe` is installed in a specific location other than system git, please install ComfyUI-Manager and run ComfyUI. Then, specify the path including the file name in `git_exe = ` in the `<USER_DIRECTORY>/default/ComfyUI-Manager/config.ini` file that is generated.
|
||||||
* If updating ComfyUI-Manager itself fails, please go to the **ComfyUI-Manager** directory and execute the command `git update-ref refs/remotes/origin/main a361cc1 && git fetch --all && git pull`.
|
* If updating ComfyUI-Manager itself fails, please go to the **ComfyUI-Manager** directory and execute the command `git update-ref refs/remotes/origin/main a361cc1 && git fetch --all && git pull`.
|
||||||
* If you encounter the error message `Overlapped Object has pending operation at deallocation on ComfyUI Manager load` under Windows
|
* If you encounter the error message `Overlapped Object has pending operation at deallocation on Comfyui Manager load` under Windows
|
||||||
* Edit `config.ini` file: add `windows_selector_event_loop_policy = True`
|
* Edit `config.ini` file: add `windows_selector_event_loop_policy = True`
|
||||||
* If the `SSL: CERTIFICATE_VERIFY_FAILED` error occurs.
|
* if `SSL: CERTIFICATE_VERIFY_FAILED` error is occured.
|
||||||
* Edit `config.ini` file: add `bypass_ssl = True`
|
* Edit `config.ini` file: add `bypass_ssl = True`
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
check.sh
4
check.sh
@@ -37,7 +37,7 @@ find ~/.tmp/default -name "*.py" -print0 | xargs -0 grep -E "crypto|^_A="
|
|||||||
|
|
||||||
echo
|
echo
|
||||||
echo CHECK3
|
echo CHECK3
|
||||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*[^#]*https\?:"
|
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*https\\?:"
|
||||||
find ~/.tmp/default -name "requirements.txt" | xargs grep "^\s*[^#].*\.whl"
|
find ~/.tmp/default -name "requirements.txt" | xargs grep "\.whl"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ comfyui_manager_path = os.path.abspath(os.path.dirname(__file__))
|
|||||||
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
||||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||||
|
|
||||||
cm_global.pip_overrides = {}
|
if sys.version_info < (3, 13):
|
||||||
|
cm_global.pip_overrides = {'numpy': 'numpy<2'}
|
||||||
|
else:
|
||||||
|
cm_global.pip_overrides = {}
|
||||||
|
|
||||||
if os.path.exists(os.path.join(manager_util.comfyui_manager_path, "pip_overrides.json")):
|
if os.path.exists(os.path.join(manager_util.comfyui_manager_path, "pip_overrides.json")):
|
||||||
with open(os.path.join(manager_util.comfyui_manager_path, "pip_overrides.json"), 'r', encoding="UTF-8", errors="ignore") as json_file:
|
with open(os.path.join(manager_util.comfyui_manager_path, "pip_overrides.json"), 'r', encoding="UTF-8", errors="ignore") as json_file:
|
||||||
@@ -149,6 +152,9 @@ class Ctx:
|
|||||||
with open(core.manager_pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
with open(core.manager_pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
||||||
cm_global.pip_overrides = json.load(json_file)
|
cm_global.pip_overrides = json.load(json_file)
|
||||||
|
|
||||||
|
if sys.version_info < (3, 13):
|
||||||
|
cm_global.pip_overrides = {'numpy': 'numpy<2'}
|
||||||
|
|
||||||
if os.path.exists(core.manager_pip_blacklist_path):
|
if os.path.exists(core.manager_pip_blacklist_path):
|
||||||
with open(core.manager_pip_blacklist_path, 'r', encoding="UTF-8", errors="ignore") as f:
|
with open(core.manager_pip_blacklist_path, 'r', encoding="UTF-8", errors="ignore") as f:
|
||||||
for x in f.readlines():
|
for x in f.readlines():
|
||||||
|
|||||||
11429
custom-node-list.json
Normal file → Executable file
11429
custom-node-list.json
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
@@ -1,41 +0,0 @@
|
|||||||
# ComfyUI-Manager: Documentation
|
|
||||||
|
|
||||||
This directory contains documentation for the ComfyUI-Manager, providing guides and tutorials for users in multiple languages.
|
|
||||||
|
|
||||||
## Directory Structure
|
|
||||||
|
|
||||||
The documentation is organized into language-specific directories:
|
|
||||||
|
|
||||||
- **en/**: English documentation
|
|
||||||
- **ko/**: Korean documentation
|
|
||||||
|
|
||||||
## Core Documentation Files
|
|
||||||
|
|
||||||
### Command-Line Interface
|
|
||||||
|
|
||||||
- **cm-cli.md**: Documentation for the ComfyUI-Manager Command Line Interface (CLI), which allows using manager functionality without the UI.
|
|
||||||
|
|
||||||
### Advanced Features
|
|
||||||
|
|
||||||
- **use_aria2.md**: Guide for using the aria2 download accelerator with ComfyUI-Manager for faster model downloads.
|
|
||||||
|
|
||||||
## Documentation Standards
|
|
||||||
|
|
||||||
The documentation follows these standards:
|
|
||||||
|
|
||||||
1. **Markdown Format**: All documentation is written in Markdown for easy rendering on GitHub and other platforms
|
|
||||||
2. **Language-specific Directories**: Content is separated by language to facilitate localization
|
|
||||||
3. **Feature-focused Documentation**: Each major feature has its own documentation file
|
|
||||||
4. **Updated with Releases**: Documentation is kept in sync with software releases
|
|
||||||
|
|
||||||
## Contributing to Documentation
|
|
||||||
|
|
||||||
When contributing new documentation:
|
|
||||||
|
|
||||||
1. Place files in the appropriate language directory
|
|
||||||
2. Use clear, concise language appropriate for the target audience
|
|
||||||
3. Include examples where helpful
|
|
||||||
4. Consider adding screenshots or diagrams for complex features
|
|
||||||
5. Maintain consistent formatting with existing documentation
|
|
||||||
|
|
||||||
This documentation directory will continue to grow to support the expanding feature set of ComfyUI-Manager.
|
|
||||||
@@ -139,9 +139,9 @@ You can set whether to use ComfyUI-Manager solely via CLI.
|
|||||||
`restore-dependencies`
|
`restore-dependencies`
|
||||||
|
|
||||||
* This command can be used if custom nodes are installed under the `ComfyUI/custom_nodes` path but their dependencies are not installed.
|
* This command can be used if custom nodes are installed under the `ComfyUI/custom_nodes` path but their dependencies are not installed.
|
||||||
* It is useful when starting a new cloud instance, like Colab, where dependencies need to be reinstalled and installation scripts re-executed.
|
* It is useful when starting a new cloud instance, like colab, where dependencies need to be reinstalled and installation scripts re-executed.
|
||||||
* It can also be utilized if ComfyUI is reinstalled and only the custom_nodes path has been backed up and restored.
|
* It can also be utilized if ComfyUI is reinstalled and only the custom_nodes path has been backed up and restored.
|
||||||
|
|
||||||
### 7. Clear
|
### 7. Clear
|
||||||
|
|
||||||
In the GUI, installations, updates, or snapshot restorations are scheduled to execute the next time ComfyUI is launched. The `clear` command clears this scheduled state, ensuring no pre-execution actions are applied.
|
In the GUI, installations, updates, or snapshot restorations are scheduled to execute the next time ComfyUI is launched. The `clear` command clears this scheduled state, ensuring no pre-execution actions are applied.
|
||||||
@@ -23,13 +23,13 @@ OPTIONS:
|
|||||||
## How To Use?
|
## How To Use?
|
||||||
* `python cm-cli.py` 를 통해서 실행 시킬 수 있습니다.
|
* `python cm-cli.py` 를 통해서 실행 시킬 수 있습니다.
|
||||||
* 예를 들어 custom node를 모두 업데이트 하고 싶다면
|
* 예를 들어 custom node를 모두 업데이트 하고 싶다면
|
||||||
* ComfyUI-Manager 경로에서 `python cm-cli.py update all` 명령을 실행할 수 있습니다.
|
* ComfyUI-Manager경로 에서 `python cm-cli.py update all` 를 command를 실행할 수 있습니다.
|
||||||
* ComfyUI 경로에서 실행한다면, `python custom_nodes/ComfyUI-Manager/cm-cli.py update all` 와 같이 cm-cli.py 의 경로를 지정할 수도 있습니다.
|
* ComfyUI 경로에서 실행한다면, `python custom_nodes/ComfyUI-Manager/cm-cli.py update all` 와 같이 cm-cli.py 의 경로를 지정할 수도 있습니다.
|
||||||
|
|
||||||
## Prerequisite
|
## Prerequisite
|
||||||
* ComfyUI 를 실행하는 python과 동일한 python 환경에서 실행해야 합니다.
|
* ComfyUI 를 실행하는 python과 동일한 python 환경에서 실행해야 합니다.
|
||||||
* venv를 사용할 경우 해당 venv를 activate 한 상태에서 실행해야 합니다.
|
* venv를 사용할 경우 해당 venv를 activate 한 상태에서 실행해야 합니다.
|
||||||
* portable 버전을 사용할 경우 run_nvidia_gpu.bat 파일이 있는 경로인 경우, 다음과 같은 방식으로 명령을 실행해야 합니다.
|
* portable 버전을 사용할 경우 run_nvidia_gpu.bat 파일이 있는 경로인 경우, 다음과 같은 방식으로 코맨드를 실행해야 합니다.
|
||||||
`.\python_embeded\python.exe ComfyUI\custom_nodes\ComfyUI-Manager\cm-cli.py update all`
|
`.\python_embeded\python.exe ComfyUI\custom_nodes\ComfyUI-Manager\cm-cli.py update all`
|
||||||
* ComfyUI 의 경로는 COMFYUI_PATH 환경 변수로 설정할 수 있습니다. 만약 생략할 경우 다음과 같은 경고 메시지가 나타나며, ComfyUI-Manager가 설치된 경로를 기준으로 상대 경로로 설정됩니다.
|
* ComfyUI 의 경로는 COMFYUI_PATH 환경 변수로 설정할 수 있습니다. 만약 생략할 경우 다음과 같은 경고 메시지가 나타나며, ComfyUI-Manager가 설치된 경로를 기준으로 상대 경로로 설정됩니다.
|
||||||
```
|
```
|
||||||
@@ -40,8 +40,8 @@ OPTIONS:
|
|||||||
|
|
||||||
### 1. --channel, --mode
|
### 1. --channel, --mode
|
||||||
* 정보 보기 기능과 커스텀 노드 관리 기능의 경우는 --channel과 --mode를 통해 정보 DB를 설정할 수 있습니다.
|
* 정보 보기 기능과 커스텀 노드 관리 기능의 경우는 --channel과 --mode를 통해 정보 DB를 설정할 수 있습니다.
|
||||||
* 예를 들어 `python cm-cli.py update all --channel recent --mode remote`와 같은 명령을 실행할 경우, 현재 ComfyUI-Manager repo에 내장된 로컬의 정보가 아닌 remote의 최신 정보를 기준으로 동작하며, recent channel에 있는 목록을 대상으로만 동작합니다.
|
* 예들 들어 `python cm-cli.py update all --channel recent --mode remote`와 같은 command를 실행할 경우, 현재 ComfyUI-Manager repo에 내장된 로컬의 정보가 아닌 remote의 최신 정보를 기준으로 동작하며, recent channel에 있는 목록을 대상으로만 동작합니다.
|
||||||
* --channel, --mode 는 `simple-show, show, install, uninstall, update, disable, enable, fix` 명령에서만 사용 가능합니다.
|
* --channel, --mode 는 `simple-show, show, install, uninstall, update, disable, enable, fix` command에서만 사용 가능합니다.
|
||||||
|
|
||||||
### 2. 관리 정보 보기
|
### 2. 관리 정보 보기
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ OPTIONS:
|
|||||||
* `[show|simple-show]` - `show`는 상세하게 정보를 보여주며, `simple-show`는 간단하게 정보를 보여줍니다.
|
* `[show|simple-show]` - `show`는 상세하게 정보를 보여주며, `simple-show`는 간단하게 정보를 보여줍니다.
|
||||||
|
|
||||||
|
|
||||||
`python cm-cli.py show installed` 와 같은 명령을 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
`python cm-cli.py show installed` 와 같은 코맨드를 실행하면 설치된 커스텀 노드의 정보를 상세하게 보여줍니다.
|
||||||
```
|
```
|
||||||
-= ComfyUI-Manager CLI (V2.24) =-
|
-= ComfyUI-Manager CLI (V2.24) =-
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ FETCH DATA from: https://raw.githubusercontent.com/ltdrdata/ComfyUI-Manager/main
|
|||||||
[ DISABLED ] ComfyUI-Loopchain (author: Fannovel16)
|
[ DISABLED ] ComfyUI-Loopchain (author: Fannovel16)
|
||||||
```
|
```
|
||||||
|
|
||||||
`python cm-cli.py simple-show installed` 와 같은 명령을 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
`python cm-cli.py simple-show installed` 와 같은 코맨드를 이용해서 설치된 커스텀 노드의 정보를 간단하게 보여줍니다.
|
||||||
|
|
||||||
```
|
```
|
||||||
-= ComfyUI-Manager CLI (V2.24) =-
|
-= ComfyUI-Manager CLI (V2.24) =-
|
||||||
@@ -89,7 +89,7 @@ ComfyUI-Loopchain
|
|||||||
* `installed`: enable, disable 여부와 상관없이 설치된 모든 노드를 보여줍니다
|
* `installed`: enable, disable 여부와 상관없이 설치된 모든 노드를 보여줍니다
|
||||||
* `not-installed`: 설치되지 않은 커스텀 노드의 목록을 보여줍니다.
|
* `not-installed`: 설치되지 않은 커스텀 노드의 목록을 보여줍니다.
|
||||||
* `all`: 모든 커스텀 노드의 목록을 보여줍니다.
|
* `all`: 모든 커스텀 노드의 목록을 보여줍니다.
|
||||||
* `snapshot`: 현재 설치된 커스텀 노드의 snapshot 정보를 보여줍니다. `show`를 통해서 볼 경우는 json 출력 형태로 보여주며, `simple-show`를 통해서 볼 경우는 간단하게, 커밋 해시와 함께 보여줍니다.
|
* `snapshot`: 현재 설치된 커스텀 노드의 snapshot 정보를 보여줍니다. `show`롤 통해서 볼 경우는 json 출력 형태로 보여주며, `simple-show`를 통해서 볼 경우는 간단하게, 커밋 해시와 함께 보여줍니다.
|
||||||
* `snapshot-list`: ComfyUI-Manager/snapshots 에 저장된 snapshot 파일의 목록을 보여줍니다.
|
* `snapshot-list`: ComfyUI-Manager/snapshots 에 저장된 snapshot 파일의 목록을 보여줍니다.
|
||||||
|
|
||||||
### 3. 커스텀 노드 관리 하기
|
### 3. 커스텀 노드 관리 하기
|
||||||
@@ -98,7 +98,7 @@ ComfyUI-Loopchain
|
|||||||
|
|
||||||
* `python cm-cli.py install ComfyUI-Impact-Pack ComfyUI-Inspire-Pack ComfyUI_experiments` 와 같이 커스텀 노드의 이름을 나열해서 관리 기능을 적용할 수 있습니다.
|
* `python cm-cli.py install ComfyUI-Impact-Pack ComfyUI-Inspire-Pack ComfyUI_experiments` 와 같이 커스텀 노드의 이름을 나열해서 관리 기능을 적용할 수 있습니다.
|
||||||
* 커스텀 노드의 이름은 `show`를 했을 때 보여주는 이름이며, git repository의 이름입니다.
|
* 커스텀 노드의 이름은 `show`를 했을 때 보여주는 이름이며, git repository의 이름입니다.
|
||||||
(추후 nickname을 사용 가능하도록 업데이트할 예정입니다.)
|
(추후 nickname 을 사용가능하돌고 업데이트 할 예정입니다.)
|
||||||
|
|
||||||
`[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
`[update|disable|enable|fix] all ?[--channel <channel name>] ?[--mode [remote|local|cache]]`
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ ComfyUI-Loopchain
|
|||||||
* `--pip-non-local-url`: web URL에 등록된 pip 패키지들에 대해서 복구를 수행
|
* `--pip-non-local-url`: web URL에 등록된 pip 패키지들에 대해서 복구를 수행
|
||||||
* `--pip-local-url`: local 경로를 지정하고 있는 pip 패키지들에 대해서 복구를 수행
|
* `--pip-local-url`: local 경로를 지정하고 있는 pip 패키지들에 대해서 복구를 수행
|
||||||
* `--user-directory`: 사용자 디렉토리 설정
|
* `--user-directory`: 사용자 디렉토리 설정
|
||||||
* `--restore-to`: 복구될 커스텀 노드가 설치될 경로. (이 옵션을 적용할 경우 오직 대상 경로에 설치된 custom nodes만 설치된 것으로 인식함.)
|
* `--restore-to`: 복구될 커스텀 노드가 설치될 경로. (이 옵션을 적용할 경우 오직 대상 경로에 설치된 custom nodes 만 설치된 것으로 인식함.)
|
||||||
|
|
||||||
### 5. CLI only mode
|
### 5. CLI only mode
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@ ComfyUI-Manager를 CLI로만 사용할 것인지를 설정할 수 있습니다.
|
|||||||
`cli-only-mode [enable|disable]`
|
`cli-only-mode [enable|disable]`
|
||||||
|
|
||||||
* security 혹은 policy 의 이유로 GUI 를 통한 ComfyUI-Manager 사용을 제한하고 싶은 경우 이 모드를 사용할 수 있습니다.
|
* security 혹은 policy 의 이유로 GUI 를 통한 ComfyUI-Manager 사용을 제한하고 싶은 경우 이 모드를 사용할 수 있습니다.
|
||||||
* CLI only mode를 적용할 경우 ComfyUI-Manager 가 매우 제한된 상태로 로드되어, 내부적으로 제공하는 web API가 비활성화되며, 메인 메뉴에서도 Manager 버튼이 표시되지 않습니다.
|
* CLI only mode를 적용할 경우 ComfyUI-Manager 가 매우 제한된 상태로 로드되어, 내부적으로 제공하는 web API가 비활성화 되며, 메인 메뉴에서도 Manager 버튼이 표시되지 않습니다.
|
||||||
|
|
||||||
|
|
||||||
### 6. 의존성 설치
|
### 6. 의존성 설치
|
||||||
@@ -141,10 +141,10 @@ ComfyUI-Manager를 CLI로만 사용할 것인지를 설정할 수 있습니다.
|
|||||||
`restore-dependencies`
|
`restore-dependencies`
|
||||||
|
|
||||||
* `ComfyUI/custom_nodes` 하위 경로에 커스텀 노드들이 설치되어 있긴 하지만, 의존성이 설치되지 않은 경우 사용할 수 있습니다.
|
* `ComfyUI/custom_nodes` 하위 경로에 커스텀 노드들이 설치되어 있긴 하지만, 의존성이 설치되지 않은 경우 사용할 수 있습니다.
|
||||||
* Colab과 같이 cloud instance를 새로 시작하는 경우 의존성 재설치 및 설치 스크립트가 재실행되어야 하는 경우 사용합니다.
|
* colab 과 같이 cloud instance를 새로 시작하는 경우 의존성 재설치 및 설치 스크립트가 재실행 되어야 하는 경우 사용합니다.
|
||||||
* ComfyUI를 재설치할 경우, custom_nodes 경로만 백업했다가 재설치할 경우 활용 가능합니다.
|
* ComfyUI을 재설치할 경우, custom_nodes 경로만 백업했다가 재설치 할 경우 활용 가능합니다.
|
||||||
|
|
||||||
|
|
||||||
### 7. clear
|
### 7. clear
|
||||||
|
|
||||||
GUI에서 install, update를 하거나 snapshot을 restore하는 경우 예약을 통해서 다음번 ComfyUI를 실행할 경우 실행되는 구조입니다. `clear` 는 이런 예약 상태를 clear해서, 아무런 사전 실행이 적용되지 않도록 합니다.
|
GUI에서 install, update를 하거나 snapshot 을 restore하는 경우 예약을 통해서 다음번 ComfyUI를 실행할 경우 실행되는 구조입니다. `clear` 는 이런 예약 상태를 clear해서, 아무런 사전 실행이 적용되지 않도록 합니다.
|
||||||
16732
extension-node-map.json
16732
extension-node-map.json
File diff suppressed because it is too large
Load Diff
14583
github-stats.json
14583
github-stats.json
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
|||||||
# ComfyUI-Manager: Core Backend (glob)
|
|
||||||
|
|
||||||
This directory contains the Python backend modules that power ComfyUI-Manager, handling the core functionality of node management, downloading, security, and server operations.
|
|
||||||
|
|
||||||
## Core Modules
|
|
||||||
|
|
||||||
- **manager_core.py**: The central implementation of management functions, handling configuration, installation, updates, and node management.
|
|
||||||
- **manager_server.py**: Implements server functionality and API endpoints for the web interface to interact with the backend.
|
|
||||||
- **manager_downloader.py**: Handles downloading operations for models, extensions, and other resources.
|
|
||||||
- **manager_util.py**: Provides utility functions used throughout the system.
|
|
||||||
|
|
||||||
## Specialized Modules
|
|
||||||
|
|
||||||
- **cm_global.py**: Maintains global variables and state management across the system.
|
|
||||||
- **cnr_utils.py**: Helper utilities for interacting with the custom node registry (CNR).
|
|
||||||
- **git_utils.py**: Git-specific utilities for repository operations.
|
|
||||||
- **node_package.py**: Handles the packaging and installation of node extensions.
|
|
||||||
- **security_check.py**: Implements the multi-level security system for installation safety.
|
|
||||||
- **share_3rdparty.py**: Manages integration with third-party sharing platforms.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
The backend follows a modular design pattern with clear separation of concerns:
|
|
||||||
|
|
||||||
1. **Core Layer**: Manager modules provide the primary API and business logic
|
|
||||||
2. **Utility Layer**: Helper modules provide specialized functionality
|
|
||||||
3. **Integration Layer**: Modules that connect to external systems
|
|
||||||
|
|
||||||
## Security Model
|
|
||||||
|
|
||||||
The system implements a comprehensive security framework with multiple levels:
|
|
||||||
|
|
||||||
- **Block**: Highest security - blocks most remote operations
|
|
||||||
- **High**: Allows only specific trusted operations
|
|
||||||
- **Middle**: Standard security for most users
|
|
||||||
- **Normal-**: More permissive for advanced users
|
|
||||||
- **Weak**: Lowest security for development environments
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
- The backend is designed to work seamlessly with ComfyUI
|
|
||||||
- Asynchronous task queuing is implemented for background operations
|
|
||||||
- The system supports multiple installation modes
|
|
||||||
- Error handling and risk assessment are integrated throughout the codebase
|
|
||||||
|
|
||||||
## API Integration
|
|
||||||
|
|
||||||
The backend exposes a REST API via `manager_server.py` that enables:
|
|
||||||
- Custom node management (install, update, disable, remove)
|
|
||||||
- Model downloading and organization
|
|
||||||
- System configuration
|
|
||||||
- Snapshot management
|
|
||||||
- Workflow component handling
|
|
||||||
@@ -179,7 +179,7 @@ def install_node(node_id, version=None):
|
|||||||
else:
|
else:
|
||||||
url = f"{base_url}/nodes/{node_id}/install?version={version}"
|
url = f"{base_url}/nodes/{node_id}/install?version={version}"
|
||||||
|
|
||||||
response = requests.get(url, verify=not manager_util.bypass_ssl)
|
response = requests.get(url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
# Convert the API response to a NodeVersion object
|
# Convert the API response to a NodeVersion object
|
||||||
return map_node_version(response.json())
|
return map_node_version(response.json())
|
||||||
@@ -190,7 +190,7 @@ def install_node(node_id, version=None):
|
|||||||
def all_versions_of_node(node_id):
|
def all_versions_of_node(node_id):
|
||||||
url = f"{base_url}/nodes/{node_id}/versions?statuses=NodeVersionStatusActive&statuses=NodeVersionStatusPending"
|
url = f"{base_url}/nodes/{node_id}/versions?statuses=NodeVersionStatusActive&statuses=NodeVersionStatusPending"
|
||||||
|
|
||||||
response = requests.get(url, verify=not manager_util.bypass_ssl)
|
response = requests.get(url)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return response.json()
|
return response.json()
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ def git_url(fullpath):
|
|||||||
|
|
||||||
for k, v in config.items():
|
for k, v in config.items():
|
||||||
if k.startswith('remote ') and 'url' in v:
|
if k.startswith('remote ') and 'url' in v:
|
||||||
if 'Comfy-Org/ComfyUI-Manager' in v['url']:
|
|
||||||
return "https://github.com/ltdrdata/ComfyUI-Manager"
|
|
||||||
return v['url']
|
return v['url']
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import manager_downloader
|
|||||||
from node_package import InstalledNodePackage
|
from node_package import InstalledNodePackage
|
||||||
|
|
||||||
|
|
||||||
version_code = [3, 37]
|
version_code = [3, 32, 3]
|
||||||
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
|
||||||
|
|
||||||
|
|
||||||
@@ -400,86 +400,18 @@ class ManagedResult:
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
class NormalizedKeyDict:
|
|
||||||
def __init__(self):
|
|
||||||
self._store = {}
|
|
||||||
self._key_map = {}
|
|
||||||
|
|
||||||
def _normalize_key(self, key):
|
|
||||||
if isinstance(key, str):
|
|
||||||
return key.strip().lower()
|
|
||||||
return key
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
norm_key = self._normalize_key(key)
|
|
||||||
self._key_map[norm_key] = key
|
|
||||||
self._store[key] = value
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
norm_key = self._normalize_key(key)
|
|
||||||
original_key = self._key_map[norm_key]
|
|
||||||
return self._store[original_key]
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
norm_key = self._normalize_key(key)
|
|
||||||
original_key = self._key_map.pop(norm_key)
|
|
||||||
del self._store[original_key]
|
|
||||||
|
|
||||||
def __contains__(self, key):
|
|
||||||
return self._normalize_key(key) in self._key_map
|
|
||||||
|
|
||||||
def get(self, key, default=None):
|
|
||||||
return self[key] if key in self else default
|
|
||||||
|
|
||||||
def setdefault(self, key, default=None):
|
|
||||||
if key in self:
|
|
||||||
return self[key]
|
|
||||||
self[key] = default
|
|
||||||
return default
|
|
||||||
|
|
||||||
def pop(self, key, default=None):
|
|
||||||
if key in self:
|
|
||||||
val = self[key]
|
|
||||||
del self[key]
|
|
||||||
return val
|
|
||||||
if default is not None:
|
|
||||||
return default
|
|
||||||
raise KeyError(key)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return self._store.keys()
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return self._store.values()
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return self._store.items()
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self._store)
|
|
||||||
|
|
||||||
def __len__(self):
|
|
||||||
return len(self._store)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(self._store)
|
|
||||||
|
|
||||||
def to_dict(self):
|
|
||||||
return dict(self._store)
|
|
||||||
|
|
||||||
|
|
||||||
class UnifiedManager:
|
class UnifiedManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.installed_node_packages: dict[str, InstalledNodePackage] = {}
|
self.installed_node_packages: dict[str, InstalledNodePackage] = {}
|
||||||
|
|
||||||
self.cnr_inactive_nodes = NormalizedKeyDict() # node_id -> node_version -> fullpath
|
self.cnr_inactive_nodes = {} # node_id -> node_version -> fullpath
|
||||||
self.nightly_inactive_nodes = NormalizedKeyDict() # node_id -> fullpath
|
self.nightly_inactive_nodes = {} # node_id -> fullpath
|
||||||
self.unknown_inactive_nodes = {} # node_id -> repo url * fullpath
|
self.unknown_inactive_nodes = {} # node_id -> repo url * fullpath
|
||||||
self.active_nodes = NormalizedKeyDict() # node_id -> node_version * fullpath
|
self.active_nodes = {} # node_id -> node_version * fullpath
|
||||||
self.unknown_active_nodes = {} # node_id -> repo url * fullpath
|
self.unknown_active_nodes = {} # node_id -> repo url * fullpath
|
||||||
self.cnr_map = NormalizedKeyDict() # node_id -> cnr info
|
self.cnr_map = {} # node_id -> cnr info
|
||||||
self.repo_cnr_map = {} # repo_url -> cnr info
|
self.repo_cnr_map = {} # repo_url -> cnr info
|
||||||
self.custom_node_map_cache = {} # (channel, mode) -> augmented custom node list json
|
self.custom_node_map_cache = {} # (channel, mode) -> augmented custom node list json
|
||||||
self.processed_install = set()
|
self.processed_install = set()
|
||||||
|
|
||||||
def get_module_name(self, x):
|
def get_module_name(self, x):
|
||||||
@@ -882,7 +814,7 @@ class UnifiedManager:
|
|||||||
channel = normalize_channel(channel)
|
channel = normalize_channel(channel)
|
||||||
nodes = await self.load_nightly(channel, mode)
|
nodes = await self.load_nightly(channel, mode)
|
||||||
|
|
||||||
res = NormalizedKeyDict()
|
res = {}
|
||||||
added_cnr = set()
|
added_cnr = set()
|
||||||
for v in nodes.values():
|
for v in nodes.values():
|
||||||
v = v[0]
|
v = v[0]
|
||||||
@@ -1484,7 +1416,6 @@ class UnifiedManager:
|
|||||||
return ManagedResult('skip')
|
return ManagedResult('skip')
|
||||||
elif self.is_disabled(node_id):
|
elif self.is_disabled(node_id):
|
||||||
return self.unified_enable(node_id)
|
return self.unified_enable(node_id)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
version_spec = self.resolve_unspecified_version(node_id)
|
version_spec = self.resolve_unspecified_version(node_id)
|
||||||
|
|
||||||
@@ -1712,13 +1643,11 @@ def read_config():
|
|||||||
config = configparser.ConfigParser(strict=False)
|
config = configparser.ConfigParser(strict=False)
|
||||||
config.read(manager_config_path)
|
config.read(manager_config_path)
|
||||||
default_conf = config['default']
|
default_conf = config['default']
|
||||||
|
manager_util.use_uv = default_conf['use_uv'].lower() == 'true' if 'use_uv' in default_conf else False
|
||||||
|
|
||||||
def get_bool(key, default_value):
|
def get_bool(key, default_value):
|
||||||
return default_conf[key].lower() == 'true' if key in default_conf else False
|
return default_conf[key].lower() == 'true' if key in default_conf else False
|
||||||
|
|
||||||
manager_util.use_uv = default_conf['use_uv'].lower() == 'true' if 'use_uv' in default_conf else False
|
|
||||||
manager_util.bypass_ssl = get_bool('bypass_ssl', False)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'http_channel_enabled': get_bool('http_channel_enabled', False),
|
'http_channel_enabled': get_bool('http_channel_enabled', False),
|
||||||
'preview_method': default_conf.get('preview_method', manager_funcs.get_current_preview_method()).lower(),
|
'preview_method': default_conf.get('preview_method', manager_funcs.get_current_preview_method()).lower(),
|
||||||
@@ -1741,20 +1670,16 @@ def read_config():
|
|||||||
}
|
}
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
import importlib.util
|
manager_util.use_uv = False
|
||||||
# temporary disable `uv` on Windows by default (https://github.com/Comfy-Org/ComfyUI-Manager/issues/1969)
|
|
||||||
manager_util.use_uv = importlib.util.find_spec("uv") is not None and platform.system() != "Windows"
|
|
||||||
manager_util.bypass_ssl = False
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'http_channel_enabled': False,
|
'http_channel_enabled': False,
|
||||||
'preview_method': manager_funcs.get_current_preview_method(),
|
'preview_method': manager_funcs.get_current_preview_method(),
|
||||||
'git_exe': '',
|
'git_exe': '',
|
||||||
'use_uv': manager_util.use_uv,
|
'use_uv': False,
|
||||||
'channel_url': DEFAULT_CHANNEL,
|
'channel_url': DEFAULT_CHANNEL,
|
||||||
'default_cache_as_channel_url': False,
|
'default_cache_as_channel_url': False,
|
||||||
'share_option': 'all',
|
'share_option': 'all',
|
||||||
'bypass_ssl': manager_util.bypass_ssl,
|
'bypass_ssl': False,
|
||||||
'file_logging': True,
|
'file_logging': True,
|
||||||
'component_policy': 'workflow',
|
'component_policy': 'workflow',
|
||||||
'update_policy': 'stable-comfyui',
|
'update_policy': 'stable-comfyui',
|
||||||
@@ -2951,7 +2876,7 @@ async def get_unified_total_nodes(channel, mode, regsitry_cache_mode='cache'):
|
|||||||
|
|
||||||
if cnr_id is not None:
|
if cnr_id is not None:
|
||||||
# cnr or nightly version
|
# cnr or nightly version
|
||||||
cnr_ids.discard(cnr_id)
|
cnr_ids.remove(cnr_id)
|
||||||
updatable = False
|
updatable = False
|
||||||
cnr = unified_manager.cnr_map[cnr_id]
|
cnr = unified_manager.cnr_map[cnr_id]
|
||||||
|
|
||||||
@@ -3115,11 +3040,6 @@ async def restore_snapshot(snapshot_path, git_helper_extras=None):
|
|||||||
info = yaml.load(snapshot_file, Loader=yaml.SafeLoader)
|
info = yaml.load(snapshot_file, Loader=yaml.SafeLoader)
|
||||||
info = info['custom_nodes']
|
info = info['custom_nodes']
|
||||||
|
|
||||||
if 'pips' in info and info['pips']:
|
|
||||||
pips = info['pips']
|
|
||||||
else:
|
|
||||||
pips = {}
|
|
||||||
|
|
||||||
# for cnr restore
|
# for cnr restore
|
||||||
cnr_info = info.get('cnr_custom_nodes')
|
cnr_info = info.get('cnr_custom_nodes')
|
||||||
if cnr_info is not None:
|
if cnr_info is not None:
|
||||||
@@ -3326,8 +3246,6 @@ async def restore_snapshot(snapshot_path, git_helper_extras=None):
|
|||||||
unified_manager.repo_install(repo_url, to_path, instant_execution=True, no_deps=False, return_postinstall=False)
|
unified_manager.repo_install(repo_url, to_path, instant_execution=True, no_deps=False, return_postinstall=False)
|
||||||
cloned_repos.append(repo_name)
|
cloned_repos.append(repo_name)
|
||||||
|
|
||||||
manager_util.restore_pip_snapshot(pips, git_helper_extras)
|
|
||||||
|
|
||||||
# print summary
|
# print summary
|
||||||
for x in cloned_repos:
|
for x in cloned_repos:
|
||||||
print(f"[ INSTALLED ] {x}")
|
print(f"[ INSTALLED ] {x}")
|
||||||
|
|||||||
@@ -55,11 +55,7 @@ def download_url(model_url: str, model_dir: str, filename: str):
|
|||||||
return aria2_download_url(model_url, model_dir, filename)
|
return aria2_download_url(model_url, model_dir, filename)
|
||||||
else:
|
else:
|
||||||
from torchvision.datasets.utils import download_url as torchvision_download_url
|
from torchvision.datasets.utils import download_url as torchvision_download_url
|
||||||
try:
|
return torchvision_download_url(model_url, model_dir, filename)
|
||||||
return torchvision_download_url(model_url, model_dir, filename)
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"[ComfyUI-Manager] Failed to download: {model_url} / {repr(e)}")
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def aria2_find_task(dir: str, filename: str):
|
def aria2_find_task(dir: str, filename: str):
|
||||||
|
|||||||
@@ -181,10 +181,7 @@ def set_preview_method(method):
|
|||||||
core.get_config()['preview_method'] = method
|
core.get_config()['preview_method'] = method
|
||||||
|
|
||||||
|
|
||||||
if args.preview_method == latent_preview.LatentPreviewMethod.NoPreviews:
|
set_preview_method(core.get_config()['preview_method'])
|
||||||
set_preview_method(core.get_config()['preview_method'])
|
|
||||||
else:
|
|
||||||
logging.warning("[ComfyUI-Manager] Since --preview-method is set, ComfyUI-Manager's preview method feature will be ignored.")
|
|
||||||
|
|
||||||
|
|
||||||
def set_component_policy(mode):
|
def set_component_policy(mode):
|
||||||
@@ -440,10 +437,7 @@ async def task_worker():
|
|||||||
|
|
||||||
if res.ver == 'unknown':
|
if res.ver == 'unknown':
|
||||||
url = core.unified_manager.unknown_active_nodes[node_name][0]
|
url = core.unified_manager.unknown_active_nodes[node_name][0]
|
||||||
try:
|
title = os.path.basename(url)
|
||||||
title = os.path.basename(url)
|
|
||||||
except Exception:
|
|
||||||
title = node_name
|
|
||||||
else:
|
else:
|
||||||
url = core.unified_manager.cnr_map[node_name].get('repository')
|
url = core.unified_manager.cnr_map[node_name].get('repository')
|
||||||
title = core.unified_manager.cnr_map[node_name]['name']
|
title = core.unified_manager.cnr_map[node_name]['name']
|
||||||
@@ -589,7 +583,7 @@ async def task_worker():
|
|||||||
return 'success'
|
return 'success'
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"[ComfyUI-Manager] ERROR: {e}")
|
logging.error(f"[ComfyUI-Manager] ERROR: {e}", file=sys.stderr)
|
||||||
|
|
||||||
return f"Model installation error: {model_url}"
|
return f"Model installation error: {model_url}"
|
||||||
|
|
||||||
@@ -865,7 +859,7 @@ async def fetch_customnode_list(request):
|
|||||||
|
|
||||||
channel = found
|
channel = found
|
||||||
|
|
||||||
result = dict(channel=channel, node_packs=node_packs.to_dict())
|
result = dict(channel=channel, node_packs=node_packs)
|
||||||
|
|
||||||
return web.json_response(result, content_type='application/json')
|
return web.json_response(result, content_type='application/json')
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import re
|
|||||||
import logging
|
import logging
|
||||||
import platform
|
import platform
|
||||||
import shlex
|
import shlex
|
||||||
from functools import lru_cache
|
import cm_global
|
||||||
|
|
||||||
|
|
||||||
cache_lock = threading.Lock()
|
cache_lock = threading.Lock()
|
||||||
@@ -24,7 +24,7 @@ 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**.
|
cache_dir = os.path.join(comfyui_manager_path, '.cache') # This path is also updated together in **manager_core.update_user_directory**.
|
||||||
|
|
||||||
use_uv = False
|
use_uv = False
|
||||||
bypass_ssl = False
|
|
||||||
|
|
||||||
def add_python_path_to_env():
|
def add_python_path_to_env():
|
||||||
if platform.system() != "Windows":
|
if platform.system() != "Windows":
|
||||||
@@ -35,64 +35,18 @@ def add_python_path_to_env():
|
|||||||
os.environ['PATH'] = os.path.dirname(sys.executable)+sep+os.environ['PATH']
|
os.environ['PATH'] = os.path.dirname(sys.executable)+sep+os.environ['PATH']
|
||||||
|
|
||||||
|
|
||||||
@lru_cache(maxsize=2)
|
|
||||||
def get_pip_cmd(force_uv=False):
|
|
||||||
"""
|
|
||||||
Get the base pip command, with automatic fallback to uv if pip is unavailable.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
force_uv (bool): If True, use uv directly without trying pip
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: Base command for pip operations
|
|
||||||
"""
|
|
||||||
embedded = 'python_embeded' in sys.executable
|
|
||||||
|
|
||||||
# Try pip first (unless forcing uv)
|
|
||||||
if not force_uv:
|
|
||||||
try:
|
|
||||||
test_cmd = [sys.executable] + (['-s'] if embedded else []) + ['-m', 'pip', '--version']
|
|
||||||
subprocess.check_output(test_cmd, stderr=subprocess.DEVNULL, timeout=5)
|
|
||||||
return [sys.executable] + (['-s'] if embedded else []) + ['-m', 'pip']
|
|
||||||
except Exception:
|
|
||||||
logging.warning("[ComfyUI-Manager] python -m pip not available. Falling back to uv.")
|
|
||||||
|
|
||||||
# Try uv (either forced or pip failed)
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
# Try uv as Python module
|
|
||||||
try:
|
|
||||||
test_cmd = [sys.executable] + (['-s'] if embedded else []) + ['-m', 'uv', '--version']
|
|
||||||
subprocess.check_output(test_cmd, stderr=subprocess.DEVNULL, timeout=5)
|
|
||||||
logging.info("[ComfyUI-Manager] Using uv as Python module for pip operations.")
|
|
||||||
return [sys.executable] + (['-s'] if embedded else []) + ['-m', 'uv', 'pip']
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Try standalone uv
|
|
||||||
if shutil.which('uv'):
|
|
||||||
logging.info("[ComfyUI-Manager] Using standalone uv for pip operations.")
|
|
||||||
return ['uv', 'pip']
|
|
||||||
|
|
||||||
# Nothing worked
|
|
||||||
logging.error("[ComfyUI-Manager] Neither python -m pip nor uv are available. Cannot proceed with package operations.")
|
|
||||||
raise Exception("Neither pip nor uv are available for package management")
|
|
||||||
|
|
||||||
|
|
||||||
def make_pip_cmd(cmd):
|
def make_pip_cmd(cmd):
|
||||||
"""
|
if 'python_embeded' in sys.executable:
|
||||||
Create a pip command by combining the cached base pip command with the given arguments.
|
if use_uv:
|
||||||
|
return [sys.executable, '-s', '-m', 'uv', 'pip'] + cmd
|
||||||
Args:
|
else:
|
||||||
cmd (list): List of pip command arguments (e.g., ['install', 'package'])
|
return [sys.executable, '-s', '-m', 'pip'] + cmd
|
||||||
|
else:
|
||||||
Returns:
|
# FIXED: https://github.com/ltdrdata/ComfyUI-Manager/issues/1667
|
||||||
list: Complete command list ready for subprocess execution
|
if use_uv:
|
||||||
"""
|
return [sys.executable, '-m', 'uv', 'pip'] + cmd
|
||||||
global use_uv
|
else:
|
||||||
base_cmd = get_pip_cmd(force_uv=use_uv)
|
return [sys.executable, '-m', 'pip'] + cmd
|
||||||
return base_cmd + cmd
|
|
||||||
|
|
||||||
|
|
||||||
# DON'T USE StrictVersion - cannot handle pre_release version
|
# DON'T USE StrictVersion - cannot handle pre_release version
|
||||||
# try:
|
# try:
|
||||||
@@ -183,7 +137,7 @@ async def get_data(uri, silent=False):
|
|||||||
print(f"FETCH DATA from: {uri}", end="")
|
print(f"FETCH DATA from: {uri}", end="")
|
||||||
|
|
||||||
if uri.startswith("http"):
|
if uri.startswith("http"):
|
||||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=not bypass_ssl)) as session:
|
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||||
headers = {
|
headers = {
|
||||||
'Cache-Control': 'no-cache',
|
'Cache-Control': 'no-cache',
|
||||||
'Pragma': 'no-cache',
|
'Pragma': 'no-cache',
|
||||||
@@ -373,32 +327,6 @@ torch_torchvision_torchaudio_version_map = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def torch_rollback(prev):
|
|
||||||
spec = prev.split('+')
|
|
||||||
if len(spec) > 1:
|
|
||||||
platform = spec[1]
|
|
||||||
else:
|
|
||||||
cmd = make_pip_cmd(['install', '--force', 'torch', 'torchvision', 'torchaudio'])
|
|
||||||
subprocess.check_output(cmd, universal_newlines=True)
|
|
||||||
logging.error(cmd)
|
|
||||||
return
|
|
||||||
|
|
||||||
torch_ver = StrictVersion(spec[0])
|
|
||||||
torch_ver = f"{torch_ver.major}.{torch_ver.minor}.{torch_ver.patch}"
|
|
||||||
torch_torchvision_torchaudio_ver = torch_torchvision_torchaudio_version_map.get(torch_ver)
|
|
||||||
|
|
||||||
if torch_torchvision_torchaudio_ver is None:
|
|
||||||
cmd = make_pip_cmd(['install', '--pre', 'torch', 'torchvision', 'torchaudio',
|
|
||||||
'--index-url', f"https://download.pytorch.org/whl/nightly/{platform}"])
|
|
||||||
logging.info("[ComfyUI-Manager] restore PyTorch to nightly version")
|
|
||||||
else:
|
|
||||||
torchvision_ver, torchaudio_ver = torch_torchvision_torchaudio_ver
|
|
||||||
cmd = make_pip_cmd(['install', f'torch=={torch_ver}', f'torchvision=={torchvision_ver}', f"torchaudio=={torchaudio_ver}",
|
|
||||||
'--index-url', f"https://download.pytorch.org/whl/{platform}"])
|
|
||||||
logging.info(f"[ComfyUI-Manager] restore PyTorch to {torch_ver}+{platform}")
|
|
||||||
|
|
||||||
subprocess.check_output(cmd, universal_newlines=True)
|
|
||||||
|
|
||||||
|
|
||||||
class PIPFixer:
|
class PIPFixer:
|
||||||
def __init__(self, prev_pip_versions, comfyui_path, manager_files_path):
|
def __init__(self, prev_pip_versions, comfyui_path, manager_files_path):
|
||||||
@@ -406,6 +334,32 @@ class PIPFixer:
|
|||||||
self.comfyui_path = comfyui_path
|
self.comfyui_path = comfyui_path
|
||||||
self.manager_files_path = manager_files_path
|
self.manager_files_path = manager_files_path
|
||||||
|
|
||||||
|
def torch_rollback(self):
|
||||||
|
spec = self.prev_pip_versions['torch'].split('+')
|
||||||
|
if len(spec) > 0:
|
||||||
|
platform = spec[1]
|
||||||
|
else:
|
||||||
|
cmd = make_pip_cmd(['install', '--force', 'torch', 'torchvision', 'torchaudio'])
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
logging.error(cmd)
|
||||||
|
return
|
||||||
|
|
||||||
|
torch_ver = StrictVersion(spec[0])
|
||||||
|
torch_ver = f"{torch_ver.major}.{torch_ver.minor}.{torch_ver.patch}"
|
||||||
|
torch_torchvision_torchaudio_ver = torch_torchvision_torchaudio_version_map.get(torch_ver)
|
||||||
|
|
||||||
|
if torch_torchvision_torchaudio_ver is None:
|
||||||
|
cmd = make_pip_cmd(['install', '--pre', 'torch', 'torchvision', 'torchaudio',
|
||||||
|
'--index-url', f"https://download.pytorch.org/whl/nightly/{platform}"])
|
||||||
|
logging.info("[ComfyUI-Manager] restore PyTorch to nightly version")
|
||||||
|
else:
|
||||||
|
torchvision_ver, torchaudio_ver = torch_torchvision_torchaudio_ver
|
||||||
|
cmd = make_pip_cmd(['install', f'torch=={torch_ver}', f'torchvision=={torchvision_ver}', f"torchaudio=={torchaudio_ver}",
|
||||||
|
'--index-url', f"https://download.pytorch.org/whl/{platform}"])
|
||||||
|
logging.info(f"[ComfyUI-Manager] restore PyTorch to {torch_ver}+{platform}")
|
||||||
|
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
def fix_broken(self):
|
def fix_broken(self):
|
||||||
new_pip_versions = get_installed_packages(True)
|
new_pip_versions = get_installed_packages(True)
|
||||||
|
|
||||||
@@ -427,7 +381,7 @@ class PIPFixer:
|
|||||||
elif self.prev_pip_versions['torch'] != new_pip_versions['torch'] \
|
elif self.prev_pip_versions['torch'] != new_pip_versions['torch'] \
|
||||||
or self.prev_pip_versions['torchvision'] != new_pip_versions['torchvision'] \
|
or self.prev_pip_versions['torchvision'] != new_pip_versions['torchvision'] \
|
||||||
or self.prev_pip_versions['torchaudio'] != new_pip_versions['torchaudio']:
|
or self.prev_pip_versions['torchaudio'] != new_pip_versions['torchaudio']:
|
||||||
torch_rollback(self.prev_pip_versions['torch'])
|
self.torch_rollback()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("[ComfyUI-Manager] Failed to restore PyTorch")
|
logging.error("[ComfyUI-Manager] Failed to restore PyTorch")
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
@@ -458,14 +412,32 @@ class PIPFixer:
|
|||||||
|
|
||||||
if len(targets) > 0:
|
if len(targets) > 0:
|
||||||
for x in targets:
|
for x in targets:
|
||||||
cmd = make_pip_cmd(['install', f"{x}=={versions[0].version_string}"])
|
if sys.version_info < (3, 13):
|
||||||
subprocess.check_output(cmd, universal_newlines=True)
|
cmd = make_pip_cmd(['install', f"{x}=={versions[0].version_string}", "numpy<2"])
|
||||||
|
subprocess.check_output(cmd, universal_newlines=True)
|
||||||
|
|
||||||
logging.info(f"[ComfyUI-Manager] 'opencv' dependencies were fixed: {targets}")
|
logging.info(f"[ComfyUI-Manager] 'opencv' dependencies were fixed: {targets}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("[ComfyUI-Manager] Failed to restore opencv")
|
logging.error("[ComfyUI-Manager] Failed to restore opencv")
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
|
|
||||||
|
# fix numpy
|
||||||
|
if sys.version_info >= (3, 13):
|
||||||
|
logging.info("[ComfyUI-Manager] In Python 3.13 and above, PIP Fixer does not downgrade `numpy` below version 2.0. If you need to force a downgrade of `numpy`, please use `pip_auto_fix.list`.")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
np = new_pip_versions.get('numpy')
|
||||||
|
if cm_global.pip_overrides.get('numpy') == 'numpy<2':
|
||||||
|
if np is not None:
|
||||||
|
if StrictVersion(np) >= StrictVersion('2'):
|
||||||
|
cmd = make_pip_cmd(['install', "numpy<2"])
|
||||||
|
subprocess.check_output(cmd , universal_newlines=True)
|
||||||
|
|
||||||
|
logging.info("[ComfyUI-Manager] 'numpy' dependency were fixed")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error("[ComfyUI-Manager] Failed to restore numpy")
|
||||||
|
logging.error(e)
|
||||||
|
|
||||||
# fix missing frontend
|
# fix missing frontend
|
||||||
try:
|
try:
|
||||||
# NOTE: package name in requirements is 'comfyui-frontend-package'
|
# NOTE: package name in requirements is 'comfyui-frontend-package'
|
||||||
@@ -504,7 +476,7 @@ class PIPFixer:
|
|||||||
normalized_name = parsed['package'].lower().replace('-', '_')
|
normalized_name = parsed['package'].lower().replace('-', '_')
|
||||||
if normalized_name in new_pip_versions:
|
if normalized_name in new_pip_versions:
|
||||||
if 'version' in parsed and 'operator' in parsed:
|
if 'version' in parsed and 'operator' in parsed:
|
||||||
cur = StrictVersion(new_pip_versions[normalized_name])
|
cur = StrictVersion(new_pip_versions[parsed['package']])
|
||||||
dest = parsed['version']
|
dest = parsed['version']
|
||||||
op = parsed['operator']
|
op = parsed['operator']
|
||||||
if cur == dest:
|
if cur == dest:
|
||||||
@@ -565,69 +537,3 @@ def robust_readlines(fullpath):
|
|||||||
|
|
||||||
print(f"[ComfyUI-Manager] Failed to recognize encoding for: {fullpath}")
|
print(f"[ComfyUI-Manager] Failed to recognize encoding for: {fullpath}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def restore_pip_snapshot(pips, options):
|
|
||||||
non_url = []
|
|
||||||
local_url = []
|
|
||||||
non_local_url = []
|
|
||||||
|
|
||||||
for k, v in pips.items():
|
|
||||||
# NOTE: skip torch related packages
|
|
||||||
if k.startswith("torch==") or k.startswith("torchvision==") or k.startswith("torchaudio==") or k.startswith("nvidia-"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if v == "":
|
|
||||||
non_url.append(k)
|
|
||||||
else:
|
|
||||||
if v.startswith('file:'):
|
|
||||||
local_url.append(v)
|
|
||||||
else:
|
|
||||||
non_local_url.append(v)
|
|
||||||
|
|
||||||
|
|
||||||
# restore other pips
|
|
||||||
failed = []
|
|
||||||
if '--pip-non-url' in options:
|
|
||||||
# try all at once
|
|
||||||
res = 1
|
|
||||||
try:
|
|
||||||
res = subprocess.check_output(make_pip_cmd(['install'] + non_url))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# fallback
|
|
||||||
if res != 0:
|
|
||||||
for x in non_url:
|
|
||||||
res = 1
|
|
||||||
try:
|
|
||||||
res = subprocess.check_output(make_pip_cmd(['install', '--no-deps', x]))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if res != 0:
|
|
||||||
failed.append(x)
|
|
||||||
|
|
||||||
if '--pip-non-local-url' in options:
|
|
||||||
for x in non_local_url:
|
|
||||||
res = 1
|
|
||||||
try:
|
|
||||||
res = subprocess.check_output(make_pip_cmd(['install', '--no-deps', x]))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if res != 0:
|
|
||||||
failed.append(x)
|
|
||||||
|
|
||||||
if '--pip-local-url' in options:
|
|
||||||
for x in local_url:
|
|
||||||
res = 1
|
|
||||||
try:
|
|
||||||
res = subprocess.check_output(make_pip_cmd(['install', '--no-deps', x]))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if res != 0:
|
|
||||||
failed.append(x)
|
|
||||||
|
|
||||||
print(f"Installation failed for pip packages: {failed}")
|
|
||||||
@@ -2,8 +2,6 @@ import sys
|
|||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import manager_util
|
|
||||||
|
|
||||||
|
|
||||||
def security_check():
|
def security_check():
|
||||||
print("[START] Security scan")
|
print("[START] Security scan")
|
||||||
@@ -68,23 +66,18 @@ https://blog.comfy.org/comfyui-statement-on-the-ultralytics-crypto-miner-situati
|
|||||||
"lolMiner": [os.path.join(comfyui_path, 'lolMiner')]
|
"lolMiner": [os.path.join(comfyui_path, 'lolMiner')]
|
||||||
}
|
}
|
||||||
|
|
||||||
installed_pips = subprocess.check_output(manager_util.make_pip_cmd(["freeze"]), text=True)
|
installed_pips = subprocess.check_output([sys.executable, '-m', "pip", "freeze"], text=True)
|
||||||
|
|
||||||
detected = set()
|
detected = set()
|
||||||
try:
|
try:
|
||||||
anthropic_info = subprocess.check_output(manager_util.make_pip_cmd(["show", "anthropic"]), text=True, stderr=subprocess.DEVNULL)
|
anthropic_info = subprocess.check_output([sys.executable, '-m', "pip", "show", "anthropic"], text=True, stderr=subprocess.DEVNULL)
|
||||||
requires_lines = [x for x in anthropic_info.split('\n') if x.startswith("Requires")]
|
anthropic_reqs = [x for x in anthropic_info.split('\n') if x.startswith("Requires")][0].split(': ')[1]
|
||||||
if requires_lines:
|
if "pycrypto" in anthropic_reqs:
|
||||||
anthropic_reqs = requires_lines[0].split(": ", 1)[1]
|
location = [x for x in anthropic_info.split('\n') if x.startswith("Location")][0].split(': ')[1]
|
||||||
if "pycrypto" in anthropic_reqs:
|
for fi in os.listdir(location):
|
||||||
location_lines = [x for x in anthropic_info.split('\n') if x.startswith("Location")]
|
if fi.startswith("anthropic"):
|
||||||
if location_lines:
|
guide["ComfyUI_LLMVISION"] = f"\n0.Remove {os.path.join(location, fi)}" + guide["ComfyUI_LLMVISION"]
|
||||||
location = location_lines[0].split(": ", 1)[1]
|
detected.add("ComfyUI_LLMVISION")
|
||||||
for fi in os.listdir(location):
|
|
||||||
if fi.startswith("anthropic"):
|
|
||||||
guide["ComfyUI_LLMVISION"] = (f"\n0.Remove {os.path.join(location, fi)}" + guide["ComfyUI_LLMVISION"])
|
|
||||||
detected.add("ComfyUI_LLMVISION")
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -335,7 +335,8 @@ async def share_art(request):
|
|||||||
content_type = assetFileType
|
content_type = assetFileType
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from nio import AsyncClient, LoginResponse, UploadResponse
|
from matrix_client.api import MatrixHttpApi
|
||||||
|
from matrix_client.client import MatrixClient
|
||||||
|
|
||||||
homeserver = 'matrix.org'
|
homeserver = 'matrix.org'
|
||||||
if matrix_auth:
|
if matrix_auth:
|
||||||
@@ -344,35 +345,20 @@ async def share_art(request):
|
|||||||
if not homeserver.startswith("https://"):
|
if not homeserver.startswith("https://"):
|
||||||
homeserver = "https://" + homeserver
|
homeserver = "https://" + homeserver
|
||||||
|
|
||||||
client = AsyncClient(homeserver, matrix_auth['username'])
|
client = MatrixClient(homeserver)
|
||||||
|
try:
|
||||||
# Login
|
token = client.login(username=matrix_auth['username'], password=matrix_auth['password'])
|
||||||
login_resp = await client.login(matrix_auth['password'])
|
if not token:
|
||||||
if not isinstance(login_resp, LoginResponse) or not login_resp.access_token:
|
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||||
await client.close()
|
except:
|
||||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||||
|
|
||||||
# Upload asset
|
matrix = MatrixHttpApi(homeserver, token=token)
|
||||||
with open(asset_filepath, 'rb') as f:
|
with open(asset_filepath, 'rb') as f:
|
||||||
upload_resp, _maybe_keys = await client.upload(f, content_type=content_type, filename=filename)
|
mxc_url = matrix.media_upload(f.read(), content_type, filename=filename)['content_uri']
|
||||||
asset_data = f.seek(0) or f.read() # get size for info below
|
|
||||||
if not isinstance(upload_resp, UploadResponse) or not upload_resp.content_uri:
|
|
||||||
await client.close()
|
|
||||||
return web.json_response({"error": "Failed to upload asset to Matrix."}, content_type='application/json', status=500)
|
|
||||||
mxc_url = upload_resp.content_uri
|
|
||||||
|
|
||||||
# Upload workflow JSON
|
workflow_json_mxc_url = matrix.media_upload(prompt['workflow'], 'application/json', filename='workflow.json')['content_uri']
|
||||||
import io
|
|
||||||
workflow_json_bytes = json.dumps(prompt['workflow']).encode('utf-8')
|
|
||||||
workflow_io = io.BytesIO(workflow_json_bytes)
|
|
||||||
upload_workflow_resp, _maybe_keys = await client.upload(workflow_io, content_type='application/json', filename='workflow.json')
|
|
||||||
workflow_io.seek(0)
|
|
||||||
if not isinstance(upload_workflow_resp, UploadResponse) or not upload_workflow_resp.content_uri:
|
|
||||||
await client.close()
|
|
||||||
return web.json_response({"error": "Failed to upload workflow to Matrix."}, content_type='application/json', status=500)
|
|
||||||
workflow_json_mxc_url = upload_workflow_resp.content_uri
|
|
||||||
|
|
||||||
# Send text message
|
|
||||||
text_content = ""
|
text_content = ""
|
||||||
if title:
|
if title:
|
||||||
text_content += f"{title}\n"
|
text_content += f"{title}\n"
|
||||||
@@ -380,44 +366,9 @@ async def share_art(request):
|
|||||||
text_content += f"{description}\n"
|
text_content += f"{description}\n"
|
||||||
if credits:
|
if credits:
|
||||||
text_content += f"\ncredits: {credits}\n"
|
text_content += f"\ncredits: {credits}\n"
|
||||||
await client.room_send(
|
matrix.send_message(comfyui_share_room_id, text_content)
|
||||||
room_id=comfyui_share_room_id,
|
matrix.send_content(comfyui_share_room_id, mxc_url, filename, 'm.image')
|
||||||
message_type="m.room.message",
|
matrix.send_content(comfyui_share_room_id, workflow_json_mxc_url, 'workflow.json', 'm.file')
|
||||||
content={"msgtype": "m.text", "body": text_content}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Send image
|
|
||||||
await client.room_send(
|
|
||||||
room_id=comfyui_share_room_id,
|
|
||||||
message_type="m.room.message",
|
|
||||||
content={
|
|
||||||
"msgtype": "m.image",
|
|
||||||
"body": filename,
|
|
||||||
"url": mxc_url,
|
|
||||||
"info": {
|
|
||||||
"mimetype": content_type,
|
|
||||||
"size": len(asset_data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Send workflow JSON file
|
|
||||||
await client.room_send(
|
|
||||||
room_id=comfyui_share_room_id,
|
|
||||||
message_type="m.room.message",
|
|
||||||
content={
|
|
||||||
"msgtype": "m.file",
|
|
||||||
"body": "workflow.json",
|
|
||||||
"url": workflow_json_mxc_url,
|
|
||||||
"info": {
|
|
||||||
"mimetype": "application/json",
|
|
||||||
"size": len(workflow_json_bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
await client.close()
|
|
||||||
|
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|||||||
50
js/README.md
50
js/README.md
@@ -1,50 +0,0 @@
|
|||||||
# ComfyUI-Manager: Frontend (js)
|
|
||||||
|
|
||||||
This directory contains the JavaScript frontend implementation for ComfyUI-Manager, providing the user interface components that interact with the backend API.
|
|
||||||
|
|
||||||
## Core Components
|
|
||||||
|
|
||||||
- **comfyui-manager.js**: Main entry point that initializes the manager UI and integrates with ComfyUI.
|
|
||||||
- **custom-nodes-manager.js**: Implements the UI for browsing, installing, and managing custom nodes.
|
|
||||||
- **model-manager.js**: Handles the model management interface for downloading and organizing AI models.
|
|
||||||
- **components-manager.js**: Manages reusable workflow components system.
|
|
||||||
- **snapshot.js**: Implements the snapshot system for backing up and restoring installations.
|
|
||||||
|
|
||||||
## Sharing Components
|
|
||||||
|
|
||||||
- **comfyui-share-common.js**: Base functionality for workflow sharing features.
|
|
||||||
- **comfyui-share-copus.js**: Integration with the ComfyUI Copus sharing platform.
|
|
||||||
- **comfyui-share-openart.js**: Integration with the OpenArt sharing platform.
|
|
||||||
- **comfyui-share-youml.js**: Integration with the YouML sharing platform.
|
|
||||||
|
|
||||||
## Utility Components
|
|
||||||
|
|
||||||
- **cm-api.js**: Client-side API wrapper for communication with the backend.
|
|
||||||
- **common.js**: Shared utilities and helper functions used across the frontend.
|
|
||||||
- **node_fixer.js**: Utilities for fixing disconnected links and repairing malformed nodes by recreating them while preserving connections.
|
|
||||||
- **popover-helper.js**: UI component for popup tooltips and contextual information.
|
|
||||||
- **turbogrid.esm.js**: Grid component library - https://github.com/cenfun/turbogrid
|
|
||||||
- **workflow-metadata.js**: Handles workflow metadata parsing, validation and cross-repository compatibility including versioning, dependencies tracking, and resource management.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
The frontend follows a modular component-based architecture:
|
|
||||||
|
|
||||||
1. **Integration Layer**: Connects with ComfyUI's existing UI system
|
|
||||||
2. **Manager Components**: Individual functional UI components (node manager, model manager, etc.)
|
|
||||||
3. **Sharing Components**: Platform-specific sharing implementations
|
|
||||||
4. **Utility Layer**: Reusable UI components and helpers
|
|
||||||
|
|
||||||
## Implementation Details
|
|
||||||
|
|
||||||
- The frontend integrates directly with ComfyUI's UI system through `app.js`
|
|
||||||
- Dialog-based UI for most manager functions to avoid cluttering the main interface
|
|
||||||
- Asynchronous API calls to handle backend operations without blocking the UI
|
|
||||||
|
|
||||||
## Styling
|
|
||||||
|
|
||||||
CSS files are included for specific components:
|
|
||||||
- **custom-nodes-manager.css**: Styling for the node management UI
|
|
||||||
- **model-manager.css**: Styling for the model management UI
|
|
||||||
|
|
||||||
This frontend implementation provides a comprehensive yet user-friendly interface for managing the ComfyUI ecosystem.
|
|
||||||
@@ -71,7 +71,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
this.allFiles = [];
|
this.allFiles = [];
|
||||||
this.titleNum = 0;
|
this.titleNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
createButtons() {
|
createButtons() {
|
||||||
const inputStyle = {
|
const inputStyle = {
|
||||||
display: "block",
|
display: "block",
|
||||||
@@ -201,15 +201,13 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
});
|
});
|
||||||
this.LockInput = $el("input", {
|
this.LockInput = $el("input", {
|
||||||
type: "text",
|
type: "text",
|
||||||
placeholder: "0",
|
placeholder: "",
|
||||||
style: {
|
style: {
|
||||||
width: "100px",
|
width: "100px",
|
||||||
padding: "7px",
|
padding: "7px",
|
||||||
paddingLeft: "30px",
|
|
||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
border: "1px solid #ddd",
|
border: "1px solid #ddd",
|
||||||
boxSizing: "border-box",
|
boxSizing: "border-box",
|
||||||
position: "relative",
|
|
||||||
},
|
},
|
||||||
oninput: (event) => {
|
oninput: (event) => {
|
||||||
let input = event.target.value;
|
let input = event.target.value;
|
||||||
@@ -303,7 +301,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const titleNumDom = $el(
|
const titleNumDom = $el(
|
||||||
"label",
|
"label",
|
||||||
{
|
{
|
||||||
@@ -344,11 +342,15 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
["0/70"]
|
["0/70"]
|
||||||
);
|
);
|
||||||
// Additional Inputs Section
|
// Additional Inputs Section
|
||||||
const additionalInputsSection = $el("div", { style: { ...sectionStyle } }, [
|
const additionalInputsSection = $el(
|
||||||
$el("label", { style: labelStyle }, ["3️⃣ Title "]),
|
"div",
|
||||||
this.TitleInput,
|
{ style: { ...sectionStyle, } },
|
||||||
titleNumDom,
|
[
|
||||||
]);
|
$el("label", { style: labelStyle }, ["3️⃣ Title "]),
|
||||||
|
this.TitleInput,
|
||||||
|
titleNumDom,
|
||||||
|
]
|
||||||
|
);
|
||||||
const SubtitleSection = $el("div", { style: sectionStyle }, [
|
const SubtitleSection = $el("div", { style: sectionStyle }, [
|
||||||
$el("label", { style: labelStyle }, ["4️⃣ Subtitle "]),
|
$el("label", { style: labelStyle }, ["4️⃣ Subtitle "]),
|
||||||
this.SubTitleInput,
|
this.SubTitleInput,
|
||||||
@@ -377,7 +379,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const blockChainSection_lock = $el("div", { style: sectionStyle }, [
|
const blockChainSection_lock = $el("div", { style: sectionStyle }, [
|
||||||
$el("label", { style: labelStyle }, ["6️⃣ Download threshold"]),
|
$el("label", { style: labelStyle }, ["6️⃣ Pay to download"]),
|
||||||
$el(
|
$el(
|
||||||
"label",
|
"label",
|
||||||
{
|
{
|
||||||
@@ -390,42 +392,11 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
},
|
},
|
||||||
[
|
[
|
||||||
this.radioButtonsCheck_lock,
|
this.radioButtonsCheck_lock,
|
||||||
$el(
|
$el("div", { style: { marginLeft: "5px" ,display:'flex',alignItems:'center'} }, [
|
||||||
"div",
|
$el("span", { style: { marginLeft: "5px" } }, ["ON"]),
|
||||||
{
|
$el("span", { style: { marginLeft: "20px",marginRight:'10px' ,color:'#fff'} }, ["Price US$"]),
|
||||||
style: {
|
this.LockInput
|
||||||
marginLeft: "5px",
|
]),
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
position: "relative",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[
|
|
||||||
$el("span", { style: { marginLeft: "5px" } }, ["ON"]),
|
|
||||||
$el(
|
|
||||||
"span",
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
marginLeft: "20px",
|
|
||||||
marginRight: "10px",
|
|
||||||
color: "#fff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
["Unlock with"]
|
|
||||||
),
|
|
||||||
$el("img", {
|
|
||||||
style: {
|
|
||||||
width: "16px",
|
|
||||||
height: "16px",
|
|
||||||
position: "absolute",
|
|
||||||
right: "75px",
|
|
||||||
zIndex: "100",
|
|
||||||
},
|
|
||||||
src: "https://static.copus.io/images/admin/202507/prod/e2919a1d8f3c2d99d3b8fe27ff94b841.png",
|
|
||||||
}),
|
|
||||||
this.LockInput,
|
|
||||||
]
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
$el(
|
$el(
|
||||||
@@ -433,25 +404,14 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
||||||
[
|
[
|
||||||
this.radioButtonsCheckOff_lock,
|
this.radioButtonsCheckOff_lock,
|
||||||
$el(
|
$el("span", { style: { marginLeft: "5px" } }, ["OFF"]),
|
||||||
"div",
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
marginLeft: "5px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[$el("span", { style: { marginLeft: "5px" } }, ["OFF"])]
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|
||||||
$el(
|
$el(
|
||||||
"p",
|
"p",
|
||||||
{ style: { fontSize: "16px", color: "#fff", margin: "10px 0 0 0" } },
|
{ style: { fontSize: "16px", color: "#fff", margin: "10px 0 0 0" } },
|
||||||
[
|
["Get paid from your workflow. You can change the price and withdraw your earnings on Copus."]
|
||||||
]
|
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -472,7 +432,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const blockChainSection = $el("div", { style: sectionStyle }, [
|
const blockChainSection = $el("div", { style: sectionStyle }, [
|
||||||
$el("label", { style: labelStyle }, ["8️⃣ Store on blockchain "]),
|
$el("label", { style: labelStyle }, ["7️⃣ Store on blockchain "]),
|
||||||
$el(
|
$el(
|
||||||
"label",
|
"label",
|
||||||
{
|
{
|
||||||
@@ -503,139 +463,6 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.ratingRadioButtonsCheck0 = $el("input", {
|
|
||||||
type: "radio",
|
|
||||||
name: "content_rating",
|
|
||||||
value: "0",
|
|
||||||
id: "content_rating0",
|
|
||||||
});
|
|
||||||
this.ratingRadioButtonsCheck1 = $el("input", {
|
|
||||||
type: "radio",
|
|
||||||
name: "content_rating",
|
|
||||||
value: "1",
|
|
||||||
id: "content_rating1",
|
|
||||||
});
|
|
||||||
this.ratingRadioButtonsCheck2 = $el("input", {
|
|
||||||
type: "radio",
|
|
||||||
name: "content_rating",
|
|
||||||
value: "2",
|
|
||||||
id: "content_rating2",
|
|
||||||
});
|
|
||||||
this.ratingRadioButtonsCheck_1 = $el("input", {
|
|
||||||
type: "radio",
|
|
||||||
name: "content_rating",
|
|
||||||
value: "-1",
|
|
||||||
id: "content_rating_1",
|
|
||||||
checked: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// content rating
|
|
||||||
const contentRatingSection = $el("div", { style: sectionStyle }, [
|
|
||||||
$el("label", { style: labelStyle }, ["7️⃣ Content rating "]),
|
|
||||||
$el(
|
|
||||||
"label",
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
marginTop: "10px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
cursor: "pointer",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[
|
|
||||||
this.ratingRadioButtonsCheck0,
|
|
||||||
$el("img", {
|
|
||||||
style: {
|
|
||||||
width: "12px",
|
|
||||||
height: "12px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
},
|
|
||||||
src: "https://static.copus.io/images/client/202507/test/b9f17da83b054d53cd0cb4508c2c30dc.png",
|
|
||||||
}),
|
|
||||||
$el("span", { style: { marginLeft: "5px", color: "#fff" } }, [
|
|
||||||
"All ages",
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"p",
|
|
||||||
{ style: { fontSize: "10px", color: "#fff", marginLeft: "20px" } },
|
|
||||||
["Safe for all viewers; no profanity, violence, or mature themes."]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"label",
|
|
||||||
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
|
||||||
[
|
|
||||||
this.ratingRadioButtonsCheck1,
|
|
||||||
$el("img", {
|
|
||||||
style: {
|
|
||||||
width: "12px",
|
|
||||||
height: "12px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
},
|
|
||||||
src: "https://static.copus.io/images/client/202507/test/7848bc0d3690671df21c7cf00c4cfc81.png",
|
|
||||||
}),
|
|
||||||
$el("span", { style: { marginLeft: "5px", color: "#fff" } }, [
|
|
||||||
"13+ (Teen)",
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"p",
|
|
||||||
{ style: { fontSize: "10px", color: "#fff", marginLeft: "20px" } },
|
|
||||||
[
|
|
||||||
"Mild language, light themes, or cartoon violence; no explicit content. ",
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"label",
|
|
||||||
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
|
||||||
[
|
|
||||||
this.ratingRadioButtonsCheck2,
|
|
||||||
$el("img", {
|
|
||||||
style: {
|
|
||||||
width: "12px",
|
|
||||||
height: "12px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
},
|
|
||||||
src: "https://static.copus.io/images/client/202507/test/bc51839c208d68d91173e43c23bff039.png",
|
|
||||||
}),
|
|
||||||
$el("span", { style: { marginLeft: "5px", color: "#fff" } }, [
|
|
||||||
"18+ (Explicit)",
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"p",
|
|
||||||
{ style: { fontSize: "10px", color: "#fff", marginLeft: "20px" } },
|
|
||||||
[
|
|
||||||
"Explicit content, including sexual content, strong violence, or intense themes. ",
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"label",
|
|
||||||
{ style: { display: "flex", alignItems: "center", cursor: "pointer" } },
|
|
||||||
[
|
|
||||||
this.ratingRadioButtonsCheck_1,
|
|
||||||
$el("img", {
|
|
||||||
style: {
|
|
||||||
width: "12px",
|
|
||||||
height: "12px",
|
|
||||||
marginLeft: "5px",
|
|
||||||
},
|
|
||||||
src: "https://static.copus.io/images/client/202507/test/5c802fdcaaea4e7bbed37393eec0d5ba.png",
|
|
||||||
}),
|
|
||||||
$el("span", { style: { marginLeft: "5px", color: "#fff" } }, [
|
|
||||||
"Not Rated",
|
|
||||||
]),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
$el(
|
|
||||||
"p",
|
|
||||||
{ style: { fontSize: "10px", color: "#fff", marginLeft: "20px" } },
|
|
||||||
["No age rating provided."]
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Message Section
|
// Message Section
|
||||||
this.message = $el(
|
this.message = $el(
|
||||||
@@ -699,7 +526,6 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
DescriptionSection,
|
DescriptionSection,
|
||||||
// contestSection,
|
// contestSection,
|
||||||
blockChainSection_lock,
|
blockChainSection_lock,
|
||||||
contentRatingSection,
|
|
||||||
blockChainSection,
|
blockChainSection,
|
||||||
this.message,
|
this.message,
|
||||||
buttonsSection,
|
buttonsSection,
|
||||||
@@ -708,7 +534,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* api
|
* api
|
||||||
* @param {url} path
|
* @param {url} path
|
||||||
* @param {params} options
|
* @param {params} options
|
||||||
* @param {statusText} statusText
|
* @param {statusText} statusText
|
||||||
@@ -761,9 +587,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
url: data,
|
url: data,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error("make sure your API key is correct and try again later");
|
||||||
"make sure your API key is correct and try again later"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e?.response?.status === 413) {
|
if (e?.response?.status === 413) {
|
||||||
@@ -804,15 +628,8 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
subTitle: this.SubTitleInput.value,
|
subTitle: this.SubTitleInput.value,
|
||||||
content: this.descriptionInput.value,
|
content: this.descriptionInput.value,
|
||||||
storeOnChain: this.radioButtonsCheck.checked ? true : false,
|
storeOnChain: this.radioButtonsCheck.checked ? true : false,
|
||||||
lockState: this.radioButtonsCheck_lock.checked ? 2 : 0,
|
lockState:this.radioButtonsCheck_lock.checked ? 2 : 0,
|
||||||
unlockPrice: this.LockInput.value,
|
unlockPrice:this.LockInput.value,
|
||||||
rating: this.ratingRadioButtonsCheck0.checked
|
|
||||||
? 0
|
|
||||||
: this.ratingRadioButtonsCheck1.checked
|
|
||||||
? 1
|
|
||||||
: this.ratingRadioButtonsCheck2.checked
|
|
||||||
? 2
|
|
||||||
: -1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.keyInput.value) {
|
if (!this.keyInput.value) {
|
||||||
@@ -827,8 +644,8 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
throw new Error("Title is required");
|
throw new Error("Title is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.radioButtonsCheck_lock.checked) {
|
if(this.radioButtonsCheck_lock.checked){
|
||||||
if (!this.LockInput.value) {
|
if (!this.LockInput.value){
|
||||||
throw new Error("Price is required");
|
throw new Error("Price is required");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -878,23 +695,23 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
"Uploading workflow..."
|
"Uploading workflow..."
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.status && res.data.status && res.data) {
|
if (res.status && res.data.status && res.data) {
|
||||||
localStorage.setItem("copus_token", this.keyInput.value);
|
localStorage.setItem("copus_token",this.keyInput.value);
|
||||||
const { data } = res.data;
|
const { data } = res.data;
|
||||||
if (data) {
|
if (data) {
|
||||||
const url = `${DEFAULT_HOMEPAGE_URL}/work/${data}`;
|
const url = `${DEFAULT_HOMEPAGE_URL}/work/${data}`;
|
||||||
this.message.innerHTML = `Workflow has been shared successfully. <a href="${url}" target="_blank">Click here to view it.</a>`;
|
this.message.innerHTML = `Workflow has been shared successfully. <a href="${url}" target="_blank">Click here to view it.</a>`;
|
||||||
this.previewImage.src = "";
|
this.previewImage.src = "";
|
||||||
this.previewImage.style.display = "none";
|
this.previewImage.style.display = "none";
|
||||||
this.uploadedImages = [];
|
this.uploadedImages = [];
|
||||||
this.allFilesImages = [];
|
this.allFilesImages = [];
|
||||||
this.allFiles = [];
|
this.allFiles = [];
|
||||||
this.TitleInput.value = "";
|
this.TitleInput.value = "";
|
||||||
this.SubTitleInput.value = "";
|
this.SubTitleInput.value = "";
|
||||||
this.descriptionInput.value = "";
|
this.descriptionInput.value = "";
|
||||||
this.selectedFile = null;
|
this.selectedFile = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Error sharing workflow: " + e.message);
|
throw new Error("Error sharing workflow: " + e.message);
|
||||||
}
|
}
|
||||||
@@ -940,7 +757,7 @@ export class CopusShareDialog extends ComfyDialog {
|
|||||||
this.element.style.display = "block";
|
this.element.style.display = "block";
|
||||||
this.previewImage.src = "";
|
this.previewImage.src = "";
|
||||||
this.previewImage.style.display = "none";
|
this.previewImage.style.display = "none";
|
||||||
this.keyInput.value = apiToken != null ? apiToken : "";
|
this.keyInput.value = apiToken!=null?apiToken:"";
|
||||||
this.uploadedImages = [];
|
this.uploadedImages = [];
|
||||||
this.allFilesImages = [];
|
this.allFilesImages = [];
|
||||||
this.allFiles = [];
|
this.allFiles = [];
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.cn-manager {
|
.cn-manager {
|
||||||
--grid-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
--grid-font: -apple-system, BlinkMacSystemFont, "Segue UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||||
z-index: 1099;
|
z-index: 1099;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
height: 80%;
|
height: 80%;
|
||||||
|
|||||||
@@ -714,7 +714,6 @@ export class CustomNodesManager {
|
|||||||
link.href = rowItem.reference;
|
link.href = rowItem.reference;
|
||||||
link.target = '_blank';
|
link.target = '_blank';
|
||||||
link.innerHTML = `<b>${title}</b>`;
|
link.innerHTML = `<b>${title}</b>`;
|
||||||
link.title = rowItem.originalData.id;
|
|
||||||
container.appendChild(link);
|
container.appendChild(link);
|
||||||
|
|
||||||
return container;
|
return container;
|
||||||
@@ -1625,35 +1624,17 @@ export class CustomNodesManager {
|
|||||||
getNodesInWorkflow() {
|
getNodesInWorkflow() {
|
||||||
let usedGroupNodes = new Set();
|
let usedGroupNodes = new Set();
|
||||||
let allUsedNodes = {};
|
let allUsedNodes = {};
|
||||||
const visitedGraphs = new Set();
|
|
||||||
|
|
||||||
const visitGraph = (graph) => {
|
for(let k in app.graph._nodes) {
|
||||||
if (!graph || visitedGraphs.has(graph)) return;
|
let node = app.graph._nodes[k];
|
||||||
visitedGraphs.add(graph);
|
|
||||||
|
|
||||||
const nodes = graph._nodes || graph.nodes || [];
|
if(node.type.startsWith('workflow>')) {
|
||||||
for(let k in nodes) {
|
usedGroupNodes.add(node.type.slice(9));
|
||||||
let node = nodes[k];
|
continue;
|
||||||
if (!node) continue;
|
|
||||||
|
|
||||||
// If it's a SubgraphNode, recurse into its graph and continue searching
|
|
||||||
if (node.isSubgraphNode?.() && node.subgraph) {
|
|
||||||
visitGraph(node.subgraph);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!node.type) continue;
|
|
||||||
|
|
||||||
// Group nodes / components
|
|
||||||
if(typeof node.type === 'string' && node.type.startsWith('workflow>')) {
|
|
||||||
usedGroupNodes.add(node.type.slice(9));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
allUsedNodes[node.type] = node;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
visitGraph(app.graph);
|
allUsedNodes[node.type] = node;
|
||||||
|
}
|
||||||
|
|
||||||
for(let k of usedGroupNodes) {
|
for(let k of usedGroupNodes) {
|
||||||
let subnodes = app.graph.extra.groupNodes[k]?.nodes;
|
let subnodes = app.graph.extra.groupNodes[k]?.nodes;
|
||||||
|
|||||||
@@ -153,7 +153,6 @@ app.registerExtension({
|
|||||||
app.canvas.graph.add(new_node, false);
|
app.canvas.graph.add(new_node, false);
|
||||||
node_info_copy(this, new_node, true);
|
node_info_copy(this, new_node, true);
|
||||||
app.canvas.graph.remove(this);
|
app.canvas.graph.remove(this);
|
||||||
requestAnimationFrame(() => app.canvas.setDirty(true, true))
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
616
model-list.json
616
model-list.json
@@ -1973,97 +1973,6 @@
|
|||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth",
|
"url": "https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth",
|
||||||
"size": "375.0MB"
|
"size": "375.0MB"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_tiny.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (tiny)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_tiny.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_tiny.pt",
|
|
||||||
"size": "149.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_small.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (small)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_small.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_small.pt",
|
|
||||||
"size": "176.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_base_plus.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (base+)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_base_plus.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_base_plus.pt",
|
|
||||||
"size": "309.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_large.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (large)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_large.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_large.pt",
|
|
||||||
"size": "857.0MB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_tiny.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (tiny)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_tiny.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_tiny.pt",
|
|
||||||
"size": "149.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_small.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (small)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_small.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_small.pt",
|
|
||||||
"size": "176.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_base_plus.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (base+)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_base_plus.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_base_plus.pt",
|
|
||||||
"size": "309.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_large.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (large)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_large.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_large.pt",
|
|
||||||
"size": "857.0MB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "seecoder v1.0",
|
"name": "seecoder v1.0",
|
||||||
"type": "seecoder",
|
"type": "seecoder",
|
||||||
@@ -4097,29 +4006,6 @@
|
|||||||
"size": "649MB"
|
"size": "649MB"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/omnigen2_fp16.safetensors",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "OmniGen2",
|
|
||||||
"save_path": "default",
|
|
||||||
"description": "OmniGen2 diffusion model. This is required for using OmniGen2.",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged",
|
|
||||||
"filename": "omnigen2_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged/resolve/main/split_files/diffusion_models/omnigen2_fp16.safetensors",
|
|
||||||
"size": "7.93GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"type": "clip",
|
|
||||||
"base": "qwen-2.5",
|
|
||||||
"save_path": "default",
|
|
||||||
"description": "text encoder for OmniGen2",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged",
|
|
||||||
"filename": "qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged/resolve/main/split_files/text_encoders/qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"size": "7.51GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "FLUX.1 [Schnell] Diffusion model",
|
"name": "FLUX.1 [Schnell] Diffusion model",
|
||||||
"type": "diffusion_model",
|
"type": "diffusion_model",
|
||||||
@@ -4137,7 +4023,7 @@
|
|||||||
"type": "VAE",
|
"type": "VAE",
|
||||||
"base": "FLUX.1",
|
"base": "FLUX.1",
|
||||||
"save_path": "vae/FLUX1",
|
"save_path": "vae/FLUX1",
|
||||||
"description": "FLUX.1 VAE model\nNOTE: This VAE model can also be used for image generation with OmniGen2.",
|
"description": "FLUX.1 VAE model",
|
||||||
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||||
"filename": "ae.safetensors",
|
"filename": "ae.safetensors",
|
||||||
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/ae.safetensors",
|
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/ae.safetensors",
|
||||||
@@ -5045,105 +4931,6 @@
|
|||||||
"size": "1.26GB"
|
"size": "1.26GB"
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 ti2v 5B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for ti2v 5B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_ti2v_5B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors",
|
|
||||||
"size": "10.0GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Comfy-Org/umt5_xxl_fp16.safetensors",
|
"name": "Comfy-Org/umt5_xxl_fp16.safetensors",
|
||||||
@@ -5246,50 +5033,6 @@
|
|||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.7-distilled-fp8.safetensors",
|
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.7-distilled-fp8.safetensors",
|
||||||
"size": "15.7GB"
|
"size": "15.7GB"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "LTX-Video 2B Distilled v0.9.8",
|
|
||||||
"type": "checkpoint",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "checkpoints/LTXV",
|
|
||||||
"description": "LTX-Video 2B distilled model v0.9.8 with improved prompt understanding and detail generation.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
|
||||||
"filename": "ltxv-2b-0.9.8-distilled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-2b-0.9.8-distilled.safetensors",
|
|
||||||
"size": "6.34GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video 2B Distilled FP8 v0.9.8",
|
|
||||||
"type": "checkpoint",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "checkpoints/LTXV",
|
|
||||||
"description": "Quantized LTX-Video 2B distilled model v0.9.8 with improved prompt understanding and detail generation, optimized for lower VRAM usage.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
|
||||||
"filename": "ltxv-2b-0.9.8-distilled-fp8.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-2b-0.9.8-distilled-fp8.safetensors",
|
|
||||||
"size": "4.46GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video 13B Distilled v0.9.8",
|
|
||||||
"type": "checkpoint",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "checkpoints/LTXV",
|
|
||||||
"description": "LTX-Video 13B distilled model v0.9.8 with improved prompt understanding and detail generation.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
|
||||||
"filename": "ltxv-13b-0.9.8-distilled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.8-distilled.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video 13B Distilled FP8 v0.9.8",
|
|
||||||
"type": "checkpoint",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "checkpoints/LTXV",
|
|
||||||
"description": "Quantized LTX-Video 13B distilled model v0.9.8 with improved prompt understanding and detail generation, optimized for lower VRAM usage.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
|
||||||
"filename": "ltxv-13b-0.9.8-distilled-fp8.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.8-distilled-fp8.safetensors",
|
|
||||||
"size": "15.7GB"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "LTX-Video 13B Distilled LoRA v0.9.7",
|
"name": "LTX-Video 13B Distilled LoRA v0.9.7",
|
||||||
"type": "lora",
|
"type": "lora",
|
||||||
@@ -5301,50 +5044,6 @@
|
|||||||
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.7-distilled-lora128.safetensors",
|
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltxv-13b-0.9.7-distilled-lora128.safetensors",
|
||||||
"size": "1.33GB"
|
"size": "1.33GB"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "LTX-Video ICLoRA Depth 13B v0.9.7",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "loras",
|
|
||||||
"description": "In-Context LoRA (IC LoRA) for depth-controlled video-to-video generation with precise depth conditioning.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-depth-13b-0.9.7",
|
|
||||||
"filename": "ltxv-097-ic-lora-depth-control-comfyui.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-depth-13b-0.9.7/resolve/main/ltxv-097-ic-lora-depth-control-comfyui.safetensors",
|
|
||||||
"size": "81.9MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video ICLoRA Pose 13B v0.9.7",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "loras",
|
|
||||||
"description": "In-Context LoRA (IC LoRA) for pose-controlled video-to-video generation with precise pose conditioning.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-pose-13b-0.9.7",
|
|
||||||
"filename": "ltxv-097-ic-lora-pose-control-comfyui.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-pose-13b-0.9.7/resolve/main/ltxv-097-ic-lora-pose-control-comfyui.safetensors",
|
|
||||||
"size": "151MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video ICLoRA Canny 13B v0.9.7",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "loras",
|
|
||||||
"description": "In-Context LoRA (IC LoRA) for canny edge-controlled video-to-video generation with precise edge conditioning.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-canny-13b-0.9.7",
|
|
||||||
"filename": "ltxv-097-ic-lora-canny-control-comfyui.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-canny-13b-0.9.7/resolve/main/ltxv-097-ic-lora-canny-control-comfyui.safetensors",
|
|
||||||
"size": "81.9MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "LTX-Video ICLoRA Detailer 13B v0.9.8",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "LTX-Video",
|
|
||||||
"save_path": "loras",
|
|
||||||
"description": "A video detailer model on top of LTXV_13B_098_DEV trained on custom data using In-Context LoRA (IC LoRA) method.",
|
|
||||||
"reference": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-detailer-13b-0.9.8",
|
|
||||||
"filename": "ltxv-098-ic-lora-detailer-comfyui.safetensors",
|
|
||||||
"url": "https://huggingface.co/Lightricks/LTX-Video-ICLoRA-detailer-13b-0.9.8/resolve/main/ltxv-098-ic-lora-detailer-comfyui.safetensors",
|
|
||||||
"size": "1.31GB"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Latent Bridge Matching for Image Relighting",
|
"name": "Latent Bridge Matching for Image Relighting",
|
||||||
"type": "diffusion_model",
|
"type": "diffusion_model",
|
||||||
@@ -5355,317 +5054,6 @@
|
|||||||
"filename": "LBM_relighting.safetensors",
|
"filename": "LBM_relighting.safetensors",
|
||||||
"url": "https://huggingface.co/jasperai/LBM_relighting/resolve/main/model.safetensors",
|
"url": "https://huggingface.co/jasperai/LBM_relighting/resolve/main/model.safetensors",
|
||||||
"size": "5.02GB"
|
"size": "5.02GB"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image VAE",
|
|
||||||
"type": "VAE",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "vae/qwen-image",
|
|
||||||
"description": "VAE model for Qwen-Image",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
|
||||||
"filename": "qwen_image_vae.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/vae/qwen_image_vae.safetensors",
|
|
||||||
"size": "335MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen 2.5 VL 7B Text Encoder (fp8_scaled)",
|
|
||||||
"type": "clip",
|
|
||||||
"base": "Qwen-2.5-VL",
|
|
||||||
"save_path": "text_encoders/qwen",
|
|
||||||
"description": "Qwen 2.5 VL 7B text encoder model (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
|
||||||
"filename": "qwen_2.5_vl_7b_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/text_encoders/qwen_2.5_vl_7b_fp8_scaled.safetensors",
|
|
||||||
"size": "3.75GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen 2.5 VL 7B Text Encoder",
|
|
||||||
"type": "clip",
|
|
||||||
"base": "Qwen-2.5-VL",
|
|
||||||
"save_path": "text_encoders/qwen",
|
|
||||||
"description": "Qwen 2.5 VL 7B text encoder model",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
|
||||||
"filename": "qwen_2.5_vl_7b.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/text_encoders/qwen_2.5_vl_7b.safetensors",
|
|
||||||
"size": "7.51GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image Diffusion Model (fp8_e4m3fn)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "diffusion_models/qwen-image",
|
|
||||||
"description": "Qwen-Image diffusion model (fp8_e4m3fn)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
|
||||||
"filename": "qwen_image_fp8_e4m3fn.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_fp8_e4m3fn.safetensors",
|
|
||||||
"size": "4.89GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image Diffusion Model (bf16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "diffusion_models/qwen-image",
|
|
||||||
"description": "Qwen-Image diffusion model (bf16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI",
|
|
||||||
"filename": "qwen_image_bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_bf16.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit 2509 Diffusion Model (fp8_e4m3fn)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "diffusion_models/qwen-image-edit",
|
|
||||||
"description": "Qwen-Image-Edit 2509 diffusion model (fp8_e4m3fn)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
|
||||||
"filename": "qwen_image_edit_2509_fp8_e4m3fn.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_2509_fp8_e4m3fn.safetensors",
|
|
||||||
"size": "4.89GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit 2509 Diffusion Model (bf16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "diffusion_models/qwen-image-edit",
|
|
||||||
"description": "Qwen-Image-Edit 2509 diffusion model (bf16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
|
||||||
"filename": "qwen_image_edit_2509_bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_2509_bf16.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit Diffusion Model (fp8_e4m3fn)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "diffusion_models/qwen-image-edit",
|
|
||||||
"description": "Qwen-Image-Edit diffusion model (fp8_e4m3fn)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
|
||||||
"filename": "qwen_image_edit_fp8_e4m3fn.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_fp8_e4m3fn.safetensors",
|
|
||||||
"size": "4.89GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit Diffusion Model (bf16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "diffusion_models/qwen-image-edit",
|
|
||||||
"description": "Qwen-Image-Edit diffusion model (bf16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI",
|
|
||||||
"filename": "qwen_image_edit_bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-Edit_ComfyUI/resolve/main/split_files/diffusion_models/qwen_image_edit_bf16.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 8steps V1.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-8steps-V1.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 4steps V1.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 4-step LoRA model V1.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-4steps-V1.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V1.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 4steps V1.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 4-step LoRA model V1.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 4steps V2.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 4-step LoRA model V2.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-4steps-V2.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V2.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 4steps V2.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 4-step LoRA model V2.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-4steps-V2.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 8steps V1.1",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.1",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-8steps-V1.1.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.1.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 8steps V1.1 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 8-step LoRA model V1.1 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-8steps-V1.1-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V1.1-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 8steps V2.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 8-step LoRA model V2.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-8steps-V2.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V2.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Lightning 8steps V2.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "loras/qwen-image-lightning",
|
|
||||||
"description": "Qwen-Image-Lightning 8-step LoRA model V2.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Lightning-8steps-V2.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-Lightning 4steps V1.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-Lightning 4-step LoRA model V1.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-Lightning-4steps-V1.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-4steps-V1.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-Lightning 4steps V1.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-Lightning 4-step LoRA model V1.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-Lightning 8steps V1.0",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-Lightning 8-step LoRA model V1.0",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-Lightning-8steps-V1.0.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-8steps-V1.0.safetensors",
|
|
||||||
"size": "9.78GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-Lightning 8steps V1.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-Lightning 8-step LoRA model V1.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-Lightning-8steps-V1.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-Lightning-8steps-V1.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-2509-Lightning 4steps V1.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-2509-Lightning 4-step LoRA model V1.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-2509-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-4steps-V1.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-2509-Lightning 4steps V1.0 (fp32)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-2509-Lightning 4-step LoRA model V1.0 (fp32)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-2509-Lightning-4steps-V1.0-fp32.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-4steps-V1.0-fp32.safetensors",
|
|
||||||
"size": "39.1GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-2509-Lightning 8steps V1.0 (bf16)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-2509-Lightning 8-step LoRA model V1.0 (bf16)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors",
|
|
||||||
"size": "19.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image-Edit-2509-Lightning 8steps V1.0 (fp32)",
|
|
||||||
"type": "lora",
|
|
||||||
"base": "Qwen-Image-Edit",
|
|
||||||
"save_path": "loras/qwen-image-edit-lightning",
|
|
||||||
"description": "Qwen-Image-Edit-2509-Lightning 8-step LoRA model V1.0 (fp32)",
|
|
||||||
"reference": "https://huggingface.co/lightx2v/Qwen-Image-Lightning",
|
|
||||||
"filename": "Qwen-Image-Edit-2509-Lightning-8steps-V1.0-fp32.safetensors",
|
|
||||||
"url": "https://huggingface.co/lightx2v/Qwen-Image-Lightning/resolve/main/Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-fp32.safetensors",
|
|
||||||
"size": "39.1GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image InstantX ControlNet Union",
|
|
||||||
"type": "controlnet",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "controlnet/qwen-image/instantx",
|
|
||||||
"description": "Qwen-Image InstantX ControlNet Union model",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets",
|
|
||||||
"filename": "Qwen-Image-InstantX-ControlNet-Union.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets/resolve/main/split_files/controlnet/Qwen-Image-InstantX-ControlNet-Union.safetensors",
|
|
||||||
"size": "2.54GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Qwen-Image InstantX ControlNet Inpainting",
|
|
||||||
"type": "controlnet",
|
|
||||||
"base": "Qwen-Image",
|
|
||||||
"save_path": "controlnet/qwen-image/instantx",
|
|
||||||
"description": "Qwen-Image InstantX ControlNet Inpainting model",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets",
|
|
||||||
"filename": "Qwen-Image-InstantX-ControlNet-Inpainting.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Qwen-Image-InstantX-ControlNets/resolve/main/split_files/controlnet/Qwen-Image-InstantX-ControlNet-Inpainting.safetensors",
|
|
||||||
"size": "2.54GB"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
rm ~/.tmp/dev/*.py > /dev/null 2>&1
|
rm ~/.tmp/dev/*.py > /dev/null 2>&1
|
||||||
python ../../scanner.py ~/.tmp/dev $*
|
python ../../scanner.py ~/.tmp/dev
|
||||||
|
|||||||
@@ -1,25 +1,5 @@
|
|||||||
{
|
{
|
||||||
"custom_nodes": [
|
"custom_nodes": [
|
||||||
{
|
|
||||||
"author": "synchronicity-labs",
|
|
||||||
"title": "ComfyUI Sync Lipsync Node",
|
|
||||||
"reference": "https://github.com/synchronicity-labs/sync-comfyui",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/synchronicity-labs/sync-comfyui"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "This custom node allows you to perform audio-video lip synchronization inside ComfyUI using a simple interface."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"author": "joaomede",
|
|
||||||
"title": "ComfyUI-Unload-Model-Fork",
|
|
||||||
"reference": "https://github.com/joaomede/ComfyUI-Unload-Model-Fork",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/joaomede/ComfyUI-Unload-Model-Fork"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "For unloading a model or all models, using the memory management that is already present in ComfyUI. Copied from [a/https://github.com/willblaschko/ComfyUI-Unload-Models](https://github.com/willblaschko/ComfyUI-Unload-Models) but without the unnecessary extra stuff."
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "SanDiegoDude",
|
"author": "SanDiegoDude",
|
||||||
"title": "ComfyUI-HiDream-Sampler [WIP]",
|
"title": "ComfyUI-HiDream-Sampler [WIP]",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,219 +1,5 @@
|
|||||||
{
|
{
|
||||||
"models": [
|
"models": [
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v high noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v high noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 i2v low noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for i2v low noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_i2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v high noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v high noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_high_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp16.safetensors",
|
|
||||||
"size": "28.6GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 t2v low noise 14B (fp8_scaled)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for t2v low noise 14B (fp8_scaled)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_t2v_low_noise_14B_fp8_scaled.safetensors",
|
|
||||||
"size": "14.3GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/Wan2.2 ti2v 5B (fp16)",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "Wan2.2",
|
|
||||||
"save_path": "diffusion_models/Wan2.2",
|
|
||||||
"description": "Wan2.2 diffusion model for ti2v 5B (fp16)",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged",
|
|
||||||
"filename": "wan2.2_ti2v_5B_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Wan_2.2_ComfyUI_Repackaged/resolve/main/split_files/diffusion_models/wan2.2_ti2v_5B_fp16.safetensors",
|
|
||||||
"size": "10.0GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_tiny.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (tiny)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_tiny.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_tiny.pt",
|
|
||||||
"size": "149.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_small.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (small)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_small.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_small.pt",
|
|
||||||
"size": "176.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_base_plus.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (base+)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_base_plus.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_base_plus.pt",
|
|
||||||
"size": "309.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2.1_hiera_large.pt",
|
|
||||||
"type": "sam2.1",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2.1 hiera model (large)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2.1_hiera_large.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/092824/sam2.1_hiera_large.pt",
|
|
||||||
"size": "857.0MB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_tiny.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (tiny)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_tiny.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_tiny.pt",
|
|
||||||
"size": "149.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_small.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (small)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_small.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_small.pt",
|
|
||||||
"size": "176.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_base_plus.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (base+)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_base_plus.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_base_plus.pt",
|
|
||||||
"size": "309.0MB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sam2_hiera_large.pt",
|
|
||||||
"type": "sam2",
|
|
||||||
"base": "SAM",
|
|
||||||
"save_path": "sams",
|
|
||||||
"description": "Segmenty Anything SAM 2 hiera model (large)",
|
|
||||||
"reference": "https://github.com/facebookresearch/sam2#model-description",
|
|
||||||
"filename": "sam2_hiera_large.pt",
|
|
||||||
"url": "https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_large.pt",
|
|
||||||
"size": "857.0MB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/omnigen2_fp16.safetensors",
|
|
||||||
"type": "diffusion_model",
|
|
||||||
"base": "OmniGen2",
|
|
||||||
"save_path": "default",
|
|
||||||
"description": "OmniGen2 diffusion model. This is required for using OmniGen2.",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged",
|
|
||||||
"filename": "omnigen2_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged/resolve/main/split_files/diffusion_models/omnigen2_fp16.safetensors",
|
|
||||||
"size": "7.93GB"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Comfy-Org/qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"type": "clip",
|
|
||||||
"base": "qwen-2.5",
|
|
||||||
"save_path": "default",
|
|
||||||
"description": "text encoder for OmniGen2",
|
|
||||||
"reference": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged",
|
|
||||||
"filename": "qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"url": "https://huggingface.co/Comfy-Org/Omnigen2_ComfyUI_repackaged/resolve/main/split_files/text_encoders/qwen_2.5_vl_fp16.safetensors",
|
|
||||||
"size": "7.51GB"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Latent Bridge Matching for Image Relighting",
|
"name": "Latent Bridge Matching for Image Relighting",
|
||||||
"type": "diffusion_model",
|
"type": "diffusion_model",
|
||||||
@@ -687,6 +473,224 @@
|
|||||||
"filename": "llava_llama3_fp16.safetensors",
|
"filename": "llava_llama3_fp16.safetensors",
|
||||||
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/text_encoders/llava_llama3_fp16.safetensors",
|
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/text_encoders/llava_llama3_fp16.safetensors",
|
||||||
"size": "16.1GB"
|
"size": "16.1GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "PixArt-Sigma-XL-2-512-MS.safetensors (diffusion)",
|
||||||
|
"type": "diffusion_model",
|
||||||
|
"base": "pixart-sigma",
|
||||||
|
"save_path": "diffusion_models/PixArt-Sigma",
|
||||||
|
"description": "PixArt-Sigma Diffusion model",
|
||||||
|
"reference": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-512-MS",
|
||||||
|
"filename": "PixArt-Sigma-XL-2-512-MS.safetensors",
|
||||||
|
"url": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-512-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||||
|
"size": "2.44GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PixArt-Sigma-XL-2-1024-MS.safetensors (diffusion)",
|
||||||
|
"type": "diffusion_model",
|
||||||
|
"base": "pixart-sigma",
|
||||||
|
"save_path": "diffusion_models/PixArt-Sigma",
|
||||||
|
"description": "PixArt-Sigma Diffusion model",
|
||||||
|
"reference": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-1024-MS",
|
||||||
|
"filename": "PixArt-Sigma-XL-2-1024-MS.safetensors",
|
||||||
|
"url": "https://huggingface.co/PixArt-alpha/PixArt-Sigma-XL-2-1024-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||||
|
"size": "2.44GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "PixArt-XL-2-1024-MS.safetensors (diffusion)",
|
||||||
|
"type": "diffusion_model",
|
||||||
|
"base": "pixart-alpha",
|
||||||
|
"save_path": "diffusion_models/PixArt-Alpha",
|
||||||
|
"description": "PixArt-Alpha Diffusion model",
|
||||||
|
"reference": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-1024-MS",
|
||||||
|
"filename": "PixArt-XL-2-1024-MS.safetensors",
|
||||||
|
"url": "https://huggingface.co/PixArt-alpha/PixArt-XL-2-1024-MS/resolve/main/transformer/diffusion_pytorch_model.safetensors",
|
||||||
|
"size": "2.45GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Comfy-Org/hunyuan_video_t2v_720p_bf16.safetensors",
|
||||||
|
"type": "diffusion_model",
|
||||||
|
"base": "Hunyuan Video",
|
||||||
|
"save_path": "diffusion_models/hunyuan_video",
|
||||||
|
"description": "Huyuan Video diffusion model. repackaged version.",
|
||||||
|
"reference": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged",
|
||||||
|
"filename": "hunyuan_video_t2v_720p_bf16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/diffusion_models/hunyuan_video_t2v_720p_bf16.safetensors",
|
||||||
|
"size": "25.6GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Comfy-Org/hunyuan_video_vae_bf16.safetensors",
|
||||||
|
"type": "VAE",
|
||||||
|
"base": "Hunyuan Video",
|
||||||
|
"save_path": "VAE",
|
||||||
|
"description": "Huyuan Video VAE model. repackaged version.",
|
||||||
|
"reference": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged",
|
||||||
|
"filename": "hunyuan_video_vae_bf16.safetensors",
|
||||||
|
"url": "https://huggingface.co/Comfy-Org/HunyuanVideo_repackaged/resolve/main/split_files/vae/hunyuan_video_vae_bf16.safetensors",
|
||||||
|
"size": "493MB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "LTX-Video 2B v0.9.1 Checkpoint",
|
||||||
|
"type": "checkpoint",
|
||||||
|
"base": "LTX-Video",
|
||||||
|
"save_path": "checkpoints/LTXV",
|
||||||
|
"description": "LTX-Video is the first DiT-based video generation model capable of generating high-quality videos in real-time. It produces 24 FPS videos at a 768x512 resolution faster than they can be watched. Trained on a large-scale dataset of diverse videos, the model generates high-resolution videos with realistic and varied content.",
|
||||||
|
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
||||||
|
"filename": "ltx-video-2b-v0.9.1.safetensors",
|
||||||
|
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltx-video-2b-v0.9.1.safetensors",
|
||||||
|
"size": "5.72GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/flux-canny-controlnet-v3.safetensors",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/controlnets",
|
||||||
|
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||||
|
"filename": "flux-canny-controlnet-v3.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-canny-controlnet-v3.safetensors",
|
||||||
|
"size": "1.49GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/flux-depth-controlnet-v3.safetensors",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/controlnets",
|
||||||
|
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||||
|
"filename": "flux-depth-controlnet-v3.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-depth-controlnet-v3.safetensors",
|
||||||
|
"size": "1.49GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/flux-hed-controlnet-v3.safetensors",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/controlnets",
|
||||||
|
"description": "ControlNet checkpoints for FLUX.1-dev model by Black Forest Labs.",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-controlnet-collections",
|
||||||
|
"filename": "flux-hed-controlnet-v3.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-controlnet-collections/resolve/main/flux-hed-controlnet-v3.safetensors",
|
||||||
|
"size": "1.49GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/realism_lora.safetensors",
|
||||||
|
"type": "lora",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/loras",
|
||||||
|
"description": "A checkpoint with trained LoRAs for FLUX.1-dev model by Black Forest Labs",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-lora-collection",
|
||||||
|
"filename": "realism_lora.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-lora-collection/resolve/main/realism_lora.safetensors",
|
||||||
|
"size": "44.8MB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/art_lora.safetensors",
|
||||||
|
"type": "lora",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/loras",
|
||||||
|
"description": "A checkpoint with trained LoRAs for FLUX.1-dev model by Black Forest Labs",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-lora-collection",
|
||||||
|
"filename": "art_lora.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-lora-collection/resolve/main/scenery_lora.safetensors",
|
||||||
|
"size": "44.8MB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/mjv6_lora.safetensors",
|
||||||
|
"type": "lora",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/loras",
|
||||||
|
"description": "A checkpoint with trained LoRAs for FLUX.1-dev model by Black Forest Labs",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-lora-collection",
|
||||||
|
"filename": "mjv6_lora.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-lora-collection/resolve/main/mjv6_lora.safetensors",
|
||||||
|
"size": "44.8MB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "XLabs-AI/flux-ip-adapter",
|
||||||
|
"type": "lora",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "xlabs/ipadapters",
|
||||||
|
"description": "A checkpoint with trained LoRAs for FLUX.1-dev model by Black Forest Labs",
|
||||||
|
"reference": "https://huggingface.co/XLabs-AI/flux-ip-adapter",
|
||||||
|
"filename": "ip_adapter.safetensors",
|
||||||
|
"url": "https://huggingface.co/XLabs-AI/flux-ip-adapter/resolve/main/ip_adapter.safetensors",
|
||||||
|
"size": "982MB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "stabilityai/SD3.5-Large-Controlnet-Blur",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "SD3.5",
|
||||||
|
"save_path": "controlnet/SD3.5",
|
||||||
|
"description": "Blur Controlnet model for SD3.5 Large",
|
||||||
|
"reference": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets",
|
||||||
|
"filename": "sd3.5_large_controlnet_blur.safetensors",
|
||||||
|
"url": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets/resolve/main/sd3.5_large_controlnet_blur.safetensors",
|
||||||
|
"size": "8.65GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stabilityai/SD3.5-Large-Controlnet-Canny",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "SD3.5",
|
||||||
|
"save_path": "controlnet/SD3.5",
|
||||||
|
"description": "Canny Controlnet model for SD3.5 Large",
|
||||||
|
"reference": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets",
|
||||||
|
"filename": "sd3.5_large_controlnet_canny.safetensors",
|
||||||
|
"url": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets/resolve/main/sd3.5_large_controlnet_canny.safetensors",
|
||||||
|
"size": "8.65GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "stabilityai/SD3.5-Large-Controlnet-Depth",
|
||||||
|
"type": "controlnet",
|
||||||
|
"base": "SD3.5",
|
||||||
|
"save_path": "controlnet/SD3.5",
|
||||||
|
"description": "Depth Controlnet model for SD3.5 Large",
|
||||||
|
"reference": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets",
|
||||||
|
"filename": "sd3.5_large_controlnet_depth.safetensors",
|
||||||
|
"url": "https://huggingface.co/stabilityai/stable-diffusion-3.5-controlnets/resolve/main/sd3.5_large_controlnet_depth.safetensors",
|
||||||
|
"size": "8.65GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "LTX-Video 2B v0.9 Checkpoint",
|
||||||
|
"type": "checkpoint",
|
||||||
|
"base": "LTX-Video",
|
||||||
|
"save_path": "checkpoints/LTXV",
|
||||||
|
"description": "LTX-Video is the first DiT-based video generation model capable of generating high-quality videos in real-time. It produces 24 FPS videos at a 768x512 resolution faster than they can be watched. Trained on a large-scale dataset of diverse videos, the model generates high-resolution videos with realistic and varied content.",
|
||||||
|
"reference": "https://huggingface.co/Lightricks/LTX-Video",
|
||||||
|
"filename": "ltx-video-2b-v0.9.safetensors",
|
||||||
|
"url": "https://huggingface.co/Lightricks/LTX-Video/resolve/main/ltx-video-2b-v0.9.safetensors",
|
||||||
|
"size": "9.37GB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "InstantX/FLUX.1-dev-IP-Adapter",
|
||||||
|
"type": "IP-Adapter",
|
||||||
|
"base": "FLUX.1",
|
||||||
|
"save_path": "ipadapter-flux",
|
||||||
|
"description": "FLUX.1-dev-IP-Adapter",
|
||||||
|
"reference": "https://huggingface.co/InstantX/FLUX.1-dev-IP-Adapter",
|
||||||
|
"filename": "ip-adapter.bin",
|
||||||
|
"url": "https://huggingface.co/InstantX/FLUX.1-dev-IP-Adapter/resolve/main/ip-adapter.bin",
|
||||||
|
"size": "5.29GB"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Comfy-Org/sigclip_vision_384 (patch14_384)",
|
||||||
|
"type": "clip_vision",
|
||||||
|
"base": "sigclip",
|
||||||
|
"save_path": "clip_vision",
|
||||||
|
"description": "This clip vision model is required for FLUX.1 Redux.",
|
||||||
|
"reference": "https://huggingface.co/Comfy-Org/sigclip_vision_384/tree/main",
|
||||||
|
"filename": "sigclip_vision_patch14_384.safetensors",
|
||||||
|
"url": "https://huggingface.co/Comfy-Org/sigclip_vision_384/resolve/main/sigclip_vision_patch14_384.safetensors",
|
||||||
|
"size": "857MB"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,16 +10,6 @@
|
|||||||
"install_type": "git-clone",
|
"install_type": "git-clone",
|
||||||
"description": "A minimal template for creating React/TypeScript frontend extensions for ComfyUI, with complete boilerplate setup including internationalization and unit testing."
|
"description": "A minimal template for creating React/TypeScript frontend extensions for ComfyUI, with complete boilerplate setup including internationalization and unit testing."
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"author": "comfyui-wiki",
|
|
||||||
"title": "ComfyUI-i18n-demo",
|
|
||||||
"reference": "https://github.com/comfyui-wiki/ComfyUI-i18n-demo",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/comfyui-wiki/ComfyUI-i18n-demo"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "ComfyUI custom node develop i18n support demo "
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"author": "Suzie1",
|
"author": "Suzie1",
|
||||||
"title": "Guide To Making Custom Nodes in ComfyUI",
|
"title": "Guide To Making Custom Nodes in ComfyUI",
|
||||||
@@ -341,36 +331,6 @@
|
|||||||
],
|
],
|
||||||
"description": "Dynamic Node examples for ComfyUI",
|
"description": "Dynamic Node examples for ComfyUI",
|
||||||
"install_type": "git-clone"
|
"install_type": "git-clone"
|
||||||
},
|
|
||||||
{
|
|
||||||
"author": "Jonathon-Doran",
|
|
||||||
"title": "remote-combo-demo",
|
|
||||||
"reference": "https://github.com/Jonathon-Doran/remote-combo-demo",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/Jonathon-Doran/remote-combo-demo"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "A minimal test suite demonstrating how remote COMBO inputs behave in ComfyUI, with and without force_input"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"author": "J1mB091",
|
|
||||||
"title": "ComfyUI-J1mB091 Custom Nodes",
|
|
||||||
"reference": "https://github.com/J1mB091/ComfyUI-J1mB091",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/J1mB091/ComfyUI-J1mB091"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "Vibe Coded ComfyUI Custom Nodes"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"author": "aiforhumans",
|
|
||||||
"title": "XDev Nodes - Complete Toolkit",
|
|
||||||
"reference": "https://github.com/aiforhumans/comfyui-xdev-nodes",
|
|
||||||
"files": [
|
|
||||||
"https://github.com/aiforhumans/comfyui-xdev-nodes"
|
|
||||||
],
|
|
||||||
"install_type": "git-clone",
|
|
||||||
"description": "Complete ComfyUI development toolkit with 8 professional nodes including VAE tools, universal type testing, and comprehensive debugging infrastructure."
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
903
openapi.yaml
903
openapi.yaml
@@ -1,903 +0,0 @@
|
|||||||
openapi: 3.1.0
|
|
||||||
info:
|
|
||||||
title: ComfyUI-Manager API
|
|
||||||
description: |
|
|
||||||
API for ComfyUI-Manager, a comprehensive management tool for ComfyUI custom nodes, models, and components.
|
|
||||||
This API enables programmatic access to node management, model downloading, snapshot operations,
|
|
||||||
and overall system configuration.
|
|
||||||
version: "3.32.3"
|
|
||||||
contact:
|
|
||||||
name: ComfyUI-Manager Maintainers
|
|
||||||
servers:
|
|
||||||
- url: '/'
|
|
||||||
description: Default ComfyUI server
|
|
||||||
|
|
||||||
# Common API components
|
|
||||||
components:
|
|
||||||
schemas:
|
|
||||||
Error:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
error:
|
|
||||||
type: string
|
|
||||||
description: Error message
|
|
||||||
|
|
||||||
NodePackageMetadata:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
title:
|
|
||||||
type: string
|
|
||||||
description: Display name of the node package
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: Repository/package name
|
|
||||||
files:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: Source URLs for the package
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
description: Description of the node package functionality
|
|
||||||
install_type:
|
|
||||||
type: string
|
|
||||||
enum: [git, copy, pip]
|
|
||||||
description: Installation method
|
|
||||||
version:
|
|
||||||
type: string
|
|
||||||
description: Version identifier
|
|
||||||
id:
|
|
||||||
type: string
|
|
||||||
description: Unique identifier for the node package
|
|
||||||
ui_id:
|
|
||||||
type: string
|
|
||||||
description: ID for UI reference
|
|
||||||
channel:
|
|
||||||
type: string
|
|
||||||
description: Source channel
|
|
||||||
mode:
|
|
||||||
type: string
|
|
||||||
description: Source mode
|
|
||||||
|
|
||||||
ModelMetadata:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: Name of the model
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
description: Type of model
|
|
||||||
base:
|
|
||||||
type: string
|
|
||||||
description: Base model type
|
|
||||||
save_path:
|
|
||||||
type: string
|
|
||||||
description: Path for saving the model
|
|
||||||
url:
|
|
||||||
type: string
|
|
||||||
description: Download URL
|
|
||||||
filename:
|
|
||||||
type: string
|
|
||||||
description: Target filename
|
|
||||||
ui_id:
|
|
||||||
type: string
|
|
||||||
description: ID for UI reference
|
|
||||||
|
|
||||||
SnapshotItem:
|
|
||||||
type: string
|
|
||||||
description: Name of the snapshot
|
|
||||||
|
|
||||||
QueueStatus:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
total_count:
|
|
||||||
type: integer
|
|
||||||
description: Total number of tasks
|
|
||||||
done_count:
|
|
||||||
type: integer
|
|
||||||
description: Number of completed tasks
|
|
||||||
in_progress_count:
|
|
||||||
type: integer
|
|
||||||
description: Number of tasks in progress
|
|
||||||
is_processing:
|
|
||||||
type: boolean
|
|
||||||
description: Whether the queue is currently processing
|
|
||||||
|
|
||||||
ImportFailInfoBulkRequest:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
cnr_ids:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: A list of CNR IDs to check.
|
|
||||||
urls:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: A list of repository URLs to check.
|
|
||||||
|
|
||||||
ImportFailInfoBulkResponse:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
$ref: '#/components/schemas/ImportFailInfoItem'
|
|
||||||
description: >-
|
|
||||||
A dictionary where each key is a cnr_id or url from the request,
|
|
||||||
and the value is the corresponding error info.
|
|
||||||
|
|
||||||
ImportFailInfoItem:
|
|
||||||
oneOf:
|
|
||||||
- type: object
|
|
||||||
properties:
|
|
||||||
error:
|
|
||||||
type: string
|
|
||||||
traceback:
|
|
||||||
type: string
|
|
||||||
- type: "null"
|
|
||||||
|
|
||||||
securitySchemes:
|
|
||||||
securityLevel:
|
|
||||||
type: apiKey
|
|
||||||
in: header
|
|
||||||
name: Security-Level
|
|
||||||
description: Security level for sensitive operations
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
modeParam:
|
|
||||||
name: mode
|
|
||||||
in: query
|
|
||||||
description: Source mode (e.g., "local", "remote")
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum: [local, remote, default]
|
|
||||||
|
|
||||||
targetParam:
|
|
||||||
name: target
|
|
||||||
in: query
|
|
||||||
description: Target identifier
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
valueParam:
|
|
||||||
name: value
|
|
||||||
in: query
|
|
||||||
description: New value to set
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
# API Paths
|
|
||||||
paths:
|
|
||||||
# Custom Nodes Endpoints
|
|
||||||
/customnode/getmappings:
|
|
||||||
get:
|
|
||||||
summary: Get node-to-package mappings
|
|
||||||
description: Provides unified mapping between nodes and node packages
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: array
|
|
||||||
description: Mapping of node packages to node classes
|
|
||||||
|
|
||||||
/customnode/fetch_updates:
|
|
||||||
get:
|
|
||||||
summary: Check for updates
|
|
||||||
description: Fetches updates for custom nodes
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: No updates available
|
|
||||||
'201':
|
|
||||||
description: Updates found
|
|
||||||
'400':
|
|
||||||
description: Error occurred
|
|
||||||
|
|
||||||
/customnode/installed:
|
|
||||||
get:
|
|
||||||
summary: Get installed custom nodes
|
|
||||||
description: Returns a list of installed node packages
|
|
||||||
parameters:
|
|
||||||
- name: mode
|
|
||||||
in: query
|
|
||||||
description: Lists mode, default or imported
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum: [default, imported]
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
|
|
||||||
/customnode/getlist:
|
|
||||||
get:
|
|
||||||
summary: Get custom node list
|
|
||||||
description: Provides a list of available custom nodes
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
- name: skip_update
|
|
||||||
in: query
|
|
||||||
description: Skip update check
|
|
||||||
schema:
|
|
||||||
type: boolean
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
channel:
|
|
||||||
type: string
|
|
||||||
node_packs:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
|
|
||||||
/customnode/alternatives:
|
|
||||||
get:
|
|
||||||
summary: Get alternative node options
|
|
||||||
description: Provides alternatives for nodes
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: object
|
|
||||||
|
|
||||||
/customnode/versions/{node_name}:
|
|
||||||
get:
|
|
||||||
summary: Get available versions for a node
|
|
||||||
description: Lists all available versions for a specific node
|
|
||||||
parameters:
|
|
||||||
- name: node_name
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
version:
|
|
||||||
type: string
|
|
||||||
'400':
|
|
||||||
description: Node not found
|
|
||||||
|
|
||||||
/customnode/disabled_versions/{node_name}:
|
|
||||||
get:
|
|
||||||
summary: Get disabled versions for a node
|
|
||||||
description: Lists all disabled versions for a specific node
|
|
||||||
parameters:
|
|
||||||
- name: node_name
|
|
||||||
in: path
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
version:
|
|
||||||
type: string
|
|
||||||
'400':
|
|
||||||
description: Node not found
|
|
||||||
|
|
||||||
/customnode/import_fail_info:
|
|
||||||
post:
|
|
||||||
summary: Get import failure information
|
|
||||||
description: Returns information about why a node failed to import
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
cnr_id:
|
|
||||||
type: string
|
|
||||||
url:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
'400':
|
|
||||||
description: No information available
|
|
||||||
|
|
||||||
/v2/customnode/import_fail_info_bulk:
|
|
||||||
post:
|
|
||||||
summary: Get import failure info for multiple nodes
|
|
||||||
description: Retrieves recorded import failure information for a list of custom nodes.
|
|
||||||
tags:
|
|
||||||
- customnode
|
|
||||||
requestBody:
|
|
||||||
description: A list of CNR IDs or repository URLs to check.
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ImportFailInfoBulkRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: A dictionary containing the import failure information.
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ImportFailInfoBulkResponse'
|
|
||||||
'400':
|
|
||||||
description: Bad Request. The request body is invalid.
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error.
|
|
||||||
|
|
||||||
/customnode/install/git_url:
|
|
||||||
post:
|
|
||||||
summary: Install custom node via Git URL
|
|
||||||
description: Installs a custom node from a Git repository URL
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Installation successful or already installed
|
|
||||||
'400':
|
|
||||||
description: Installation failed
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/customnode/install/pip:
|
|
||||||
post:
|
|
||||||
summary: Install custom node dependencies via pip
|
|
||||||
description: Installs Python package dependencies for custom nodes
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Installation successful
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
# Model Management Endpoints
|
|
||||||
/externalmodel/getlist:
|
|
||||||
get:
|
|
||||||
summary: Get external model list
|
|
||||||
description: Provides a list of available external models
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
models:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/ModelMetadata'
|
|
||||||
|
|
||||||
# Queue Management Endpoints
|
|
||||||
/manager/queue/update_all:
|
|
||||||
get:
|
|
||||||
summary: Update all custom nodes
|
|
||||||
description: Queues update operations for all installed custom nodes
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/modeParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Update queued successfully
|
|
||||||
'401':
|
|
||||||
description: Processing already in progress
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/manager/queue/reset:
|
|
||||||
get:
|
|
||||||
summary: Reset queue
|
|
||||||
description: Resets the operation queue
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Queue reset successfully
|
|
||||||
|
|
||||||
/manager/queue/status:
|
|
||||||
get:
|
|
||||||
summary: Get queue status
|
|
||||||
description: Returns the current status of the operation queue
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/QueueStatus'
|
|
||||||
|
|
||||||
/manager/queue/install:
|
|
||||||
post:
|
|
||||||
summary: Install custom node
|
|
||||||
description: Queues installation of a custom node
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Installation queued successfully
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
'404':
|
|
||||||
description: Target node not found or security issue
|
|
||||||
|
|
||||||
/manager/queue/start:
|
|
||||||
get:
|
|
||||||
summary: Start queue processing
|
|
||||||
description: Starts processing the operation queue
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Processing started
|
|
||||||
'201':
|
|
||||||
description: Processing already in progress
|
|
||||||
|
|
||||||
/manager/queue/fix:
|
|
||||||
post:
|
|
||||||
summary: Fix custom node
|
|
||||||
description: Attempts to fix a broken custom node installation
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Fix operation queued successfully
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/manager/queue/reinstall:
|
|
||||||
post:
|
|
||||||
summary: Reinstall custom node
|
|
||||||
description: Uninstalls and then reinstalls a custom node
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Reinstall operation queued successfully
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/manager/queue/uninstall:
|
|
||||||
post:
|
|
||||||
summary: Uninstall custom node
|
|
||||||
description: Queues uninstallation of a custom node
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Uninstallation queued successfully
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/manager/queue/update:
|
|
||||||
post:
|
|
||||||
summary: Update custom node
|
|
||||||
description: Queues update of a custom node
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Update queued successfully
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/manager/queue/disable:
|
|
||||||
post:
|
|
||||||
summary: Disable custom node
|
|
||||||
description: Disables a custom node without uninstalling it
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/NodePackageMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Disable operation queued successfully
|
|
||||||
|
|
||||||
/manager/queue/update_comfyui:
|
|
||||||
get:
|
|
||||||
summary: Update ComfyUI
|
|
||||||
description: Queues an update operation for ComfyUI itself
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Update queued successfully
|
|
||||||
|
|
||||||
/manager/queue/install_model:
|
|
||||||
post:
|
|
||||||
summary: Install model
|
|
||||||
description: Queues installation of a model
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/ModelMetadata'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Installation queued successfully
|
|
||||||
'400':
|
|
||||||
description: Invalid model request
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
# Snapshot Management Endpoints
|
|
||||||
/snapshot/getlist:
|
|
||||||
get:
|
|
||||||
summary: Get snapshot list
|
|
||||||
description: Returns a list of available snapshots
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
items:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/SnapshotItem'
|
|
||||||
|
|
||||||
/snapshot/remove:
|
|
||||||
get:
|
|
||||||
summary: Remove snapshot
|
|
||||||
description: Removes a specified snapshot
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/targetParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Snapshot removed successfully
|
|
||||||
'400':
|
|
||||||
description: Error removing snapshot
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/snapshot/restore:
|
|
||||||
get:
|
|
||||||
summary: Restore snapshot
|
|
||||||
description: Restores a specified snapshot
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
parameters:
|
|
||||||
- $ref: '#/components/parameters/targetParam'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Snapshot restoration scheduled
|
|
||||||
'400':
|
|
||||||
description: Error restoring snapshot
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
/snapshot/get_current:
|
|
||||||
get:
|
|
||||||
summary: Get current snapshot
|
|
||||||
description: Returns the current system state as a snapshot
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
'400':
|
|
||||||
description: Error creating snapshot
|
|
||||||
|
|
||||||
/snapshot/save:
|
|
||||||
get:
|
|
||||||
summary: Save snapshot
|
|
||||||
description: Saves the current system state as a new snapshot
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Snapshot saved successfully
|
|
||||||
'400':
|
|
||||||
description: Error saving snapshot
|
|
||||||
|
|
||||||
# ComfyUI Management Endpoints
|
|
||||||
/comfyui_manager/comfyui_versions:
|
|
||||||
get:
|
|
||||||
summary: Get ComfyUI versions
|
|
||||||
description: Returns available and current ComfyUI versions
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
versions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
current:
|
|
||||||
type: string
|
|
||||||
'400':
|
|
||||||
description: Error retrieving versions
|
|
||||||
|
|
||||||
/comfyui_manager/comfyui_switch_version:
|
|
||||||
get:
|
|
||||||
summary: Switch ComfyUI version
|
|
||||||
description: Switches to a specified ComfyUI version
|
|
||||||
parameters:
|
|
||||||
- name: ver
|
|
||||||
in: query
|
|
||||||
description: Target version
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Version switch successful
|
|
||||||
'400':
|
|
||||||
description: Error switching version
|
|
||||||
|
|
||||||
/manager/reboot:
|
|
||||||
get:
|
|
||||||
summary: Reboot ComfyUI
|
|
||||||
description: Restarts the ComfyUI server
|
|
||||||
security:
|
|
||||||
- securityLevel: []
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Reboot initiated
|
|
||||||
'403':
|
|
||||||
description: Security policy violation
|
|
||||||
|
|
||||||
# Configuration Endpoints
|
|
||||||
/manager/preview_method:
|
|
||||||
get:
|
|
||||||
summary: Get or set preview method
|
|
||||||
description: Gets or sets the latent preview method
|
|
||||||
parameters:
|
|
||||||
- name: value
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
description: New preview method
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum: [auto, latent2rgb, taesd, none]
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Setting updated or current value returned
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/manager/db_mode:
|
|
||||||
get:
|
|
||||||
summary: Get or set database mode
|
|
||||||
description: Gets or sets the database mode
|
|
||||||
parameters:
|
|
||||||
- name: value
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
description: New database mode
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum: [channel, local, remote]
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Setting updated or current value returned
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/manager/policy/component:
|
|
||||||
get:
|
|
||||||
summary: Get or set component policy
|
|
||||||
description: Gets or sets the component policy
|
|
||||||
parameters:
|
|
||||||
- name: value
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
description: New component policy
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Setting updated or current value returned
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/manager/policy/update:
|
|
||||||
get:
|
|
||||||
summary: Get or set update policy
|
|
||||||
description: Gets or sets the update policy
|
|
||||||
parameters:
|
|
||||||
- name: value
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
description: New update policy
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum: [stable, nightly, nightly-comfyui]
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Setting updated or current value returned
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/manager/channel_url_list:
|
|
||||||
get:
|
|
||||||
summary: Get or set channel URL
|
|
||||||
description: Gets or sets the channel URL for custom node sources
|
|
||||||
parameters:
|
|
||||||
- name: value
|
|
||||||
in: query
|
|
||||||
required: false
|
|
||||||
description: New channel name
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Setting updated or channel list returned
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
selected:
|
|
||||||
type: string
|
|
||||||
list:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
url:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
# Component Management Endpoints
|
|
||||||
/manager/component/save:
|
|
||||||
post:
|
|
||||||
summary: Save component
|
|
||||||
description: Saves a reusable workflow component
|
|
||||||
requestBody:
|
|
||||||
required: true
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
workflow:
|
|
||||||
type: object
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Component saved successfully
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
'400':
|
|
||||||
description: Error saving component
|
|
||||||
|
|
||||||
/manager/component/loads:
|
|
||||||
post:
|
|
||||||
summary: Load components
|
|
||||||
description: Loads all available workflow components
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Components loaded successfully
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
'400':
|
|
||||||
description: Error loading components
|
|
||||||
|
|
||||||
# Miscellaneous Endpoints
|
|
||||||
/manager/version:
|
|
||||||
get:
|
|
||||||
summary: Get manager version
|
|
||||||
description: Returns the current version of ComfyUI-Manager
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
text/plain:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
/manager/notice:
|
|
||||||
get:
|
|
||||||
summary: Get manager notice
|
|
||||||
description: Returns HTML content with notices and version information
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Successful operation
|
|
||||||
content:
|
|
||||||
text/html:
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
@@ -38,6 +38,7 @@ else:
|
|||||||
def current_timestamp():
|
def current_timestamp():
|
||||||
return str(time.time()).split('.')[0]
|
return str(time.time()).split('.')[0]
|
||||||
|
|
||||||
|
security_check.security_check()
|
||||||
|
|
||||||
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
cm_global.pip_blacklist = {'torch', 'torchaudio', 'torchsde', 'torchvision'}
|
||||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
cm_global.pip_downgrade_blacklist = ['torch', 'torchaudio', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||||
@@ -118,14 +119,19 @@ def check_file_logging():
|
|||||||
|
|
||||||
read_config()
|
read_config()
|
||||||
read_uv_mode()
|
read_uv_mode()
|
||||||
security_check.security_check()
|
|
||||||
check_file_logging()
|
check_file_logging()
|
||||||
|
|
||||||
cm_global.pip_overrides = {}
|
if sys.version_info < (3, 13):
|
||||||
|
cm_global.pip_overrides = {'numpy': 'numpy<2'}
|
||||||
|
else:
|
||||||
|
cm_global.pip_overrides = {}
|
||||||
|
|
||||||
if os.path.exists(manager_pip_overrides_path):
|
if os.path.exists(manager_pip_overrides_path):
|
||||||
with open(manager_pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
with open(manager_pip_overrides_path, 'r', encoding="UTF-8", errors="ignore") as json_file:
|
||||||
cm_global.pip_overrides = json.load(json_file)
|
cm_global.pip_overrides = json.load(json_file)
|
||||||
|
|
||||||
|
if sys.version_info < (3, 13):
|
||||||
|
cm_global.pip_overrides['numpy'] = 'numpy<2'
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists(manager_pip_blacklist_path):
|
if os.path.exists(manager_pip_blacklist_path):
|
||||||
@@ -338,12 +344,7 @@ try:
|
|||||||
log_file.write(message)
|
log_file.write(message)
|
||||||
else:
|
else:
|
||||||
log_file.write(f"[{timestamp}] {message}")
|
log_file.write(f"[{timestamp}] {message}")
|
||||||
|
log_file.flush()
|
||||||
try:
|
|
||||||
log_file.flush()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.last_char = message if message == '' else message[-1]
|
self.last_char = message if message == '' else message[-1]
|
||||||
|
|
||||||
if not file_only:
|
if not file_only:
|
||||||
@@ -356,10 +357,7 @@ try:
|
|||||||
original_stderr.flush()
|
original_stderr.flush()
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
try:
|
log_file.flush()
|
||||||
log_file.flush()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
with std_log_lock:
|
with std_log_lock:
|
||||||
if self.is_stdout:
|
if self.is_stdout:
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "comfyui-manager"
|
name = "comfyui-manager"
|
||||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||||
version = "3.37"
|
version = "3.32.3"
|
||||||
license = { file = "LICENSE.txt" }
|
license = { file = "LICENSE.txt" }
|
||||||
dependencies = ["GitPython", "PyGithub", "matrix-nio", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions", "toml", "uv", "chardet"]
|
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions", "toml", "uv", "chardet"]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
Repository = "https://github.com/ltdrdata/ComfyUI-Manager"
|
Repository = "https://github.com/ltdrdata/ComfyUI-Manager"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
GitPython
|
GitPython
|
||||||
PyGithub
|
PyGithub
|
||||||
matrix-nio
|
matrix-client==0.4.0
|
||||||
transformers
|
transformers
|
||||||
huggingface-hub
|
huggingface-hub>0.20
|
||||||
typer
|
typer
|
||||||
rich
|
rich
|
||||||
typing-extensions
|
typing-extensions
|
||||||
|
|||||||
30
scanner.py
30
scanner.py
@@ -13,7 +13,7 @@ builtin_nodes = set()
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
from github import Github, Auth
|
from github import Github
|
||||||
|
|
||||||
|
|
||||||
def download_url(url, dest_folder, filename=None):
|
def download_url(url, dest_folder, filename=None):
|
||||||
@@ -53,8 +53,7 @@ skip_update = '--skip-update' in sys.argv or '--skip-all' in sys.argv
|
|||||||
skip_stat_update = '--skip-stat-update' in sys.argv or '--skip-all' in sys.argv
|
skip_stat_update = '--skip-stat-update' in sys.argv or '--skip-all' in sys.argv
|
||||||
|
|
||||||
if not skip_stat_update:
|
if not skip_stat_update:
|
||||||
auth = Auth.Token(os.environ.get('GITHUB_TOKEN'))
|
g = Github(os.environ.get('GITHUB_TOKEN'))
|
||||||
g = Github(auth=auth)
|
|
||||||
else:
|
else:
|
||||||
g = None
|
g = None
|
||||||
|
|
||||||
@@ -103,8 +102,12 @@ def extract_nodes(code_text):
|
|||||||
def scan_in_file(filename, is_builtin=False):
|
def scan_in_file(filename, is_builtin=False):
|
||||||
global builtin_nodes
|
global builtin_nodes
|
||||||
|
|
||||||
with open(filename, encoding='utf-8', errors='ignore') as file:
|
try:
|
||||||
code = file.read()
|
with open(filename, encoding='utf-8') as file:
|
||||||
|
code = file.read()
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
with open(filename, encoding='cp949') as file:
|
||||||
|
code = file.read()
|
||||||
|
|
||||||
pattern = r"_CLASS_MAPPINGS\s*=\s*{([^}]*)}"
|
pattern = r"_CLASS_MAPPINGS\s*=\s*{([^}]*)}"
|
||||||
regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
|
regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
|
||||||
@@ -256,13 +259,13 @@ def clone_or_pull_git_repository(git_url):
|
|||||||
repo.git.submodule('update', '--init', '--recursive')
|
repo.git.submodule('update', '--init', '--recursive')
|
||||||
print(f"Pulling {repo_name}...")
|
print(f"Pulling {repo_name}...")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to pull '{repo_name}': {e}")
|
print(f"Pulling {repo_name} failed: {e}")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
Repo.clone_from(git_url, repo_dir, recursive=True)
|
Repo.clone_from(git_url, repo_dir, recursive=True)
|
||||||
print(f"Cloning {repo_name}...")
|
print(f"Cloning {repo_name}...")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to clone '{repo_name}': {e}")
|
print(f"Cloning {repo_name} failed: {e}")
|
||||||
|
|
||||||
|
|
||||||
def update_custom_nodes():
|
def update_custom_nodes():
|
||||||
@@ -294,7 +297,7 @@ def update_custom_nodes():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def is_rate_limit_exceeded():
|
def is_rate_limit_exceeded():
|
||||||
return g.rate_limiting[0] <= 20
|
return g.rate_limiting[0] == 0
|
||||||
|
|
||||||
if is_rate_limit_exceeded():
|
if is_rate_limit_exceeded():
|
||||||
print(f"GitHub API Rate Limit Exceeded: remained - {(g.rate_limiting_resettime - datetime.datetime.now().timestamp())/60:.2f} min")
|
print(f"GitHub API Rate Limit Exceeded: remained - {(g.rate_limiting_resettime - datetime.datetime.now().timestamp())/60:.2f} min")
|
||||||
@@ -497,15 +500,8 @@ def gen_json(node_info):
|
|||||||
nodes_in_url, metadata_in_url = data[git_url]
|
nodes_in_url, metadata_in_url = data[git_url]
|
||||||
nodes = set(nodes_in_url)
|
nodes = set(nodes_in_url)
|
||||||
|
|
||||||
try:
|
for x, desc in node_list_json.items():
|
||||||
for x, desc in node_list_json.items():
|
nodes.add(x.strip())
|
||||||
nodes.add(x.strip())
|
|
||||||
except Exception as e:
|
|
||||||
print(f"\nERROR: Invalid json format '{node_list_json_path}'")
|
|
||||||
print("------------------------------------------------------")
|
|
||||||
print(e)
|
|
||||||
print("------------------------------------------------------")
|
|
||||||
node_list_json = {}
|
|
||||||
|
|
||||||
metadata_in_url['title_aux'] = title
|
metadata_in_url['title_aux'] = title
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user