Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4227b17e5 | ||
|
|
7538169251 | ||
|
|
31e300e4e8 | ||
|
|
599bf78f20 | ||
|
|
f53fdb8d7a | ||
|
|
3b4bfeab22 | ||
|
|
8c1f828c1f | ||
|
|
f896755a31 | ||
|
|
e406f8be81 | ||
|
|
84107d2b65 | ||
|
|
d890984c70 | ||
|
|
72e4c84f8a | ||
|
|
acd41d985c | ||
|
|
1312657aca | ||
|
|
a502bb9529 | ||
|
|
5947dee9f9 | ||
|
|
e68d59098f | ||
|
|
61efd60681 | ||
|
|
d3654b2ee4 | ||
|
|
ef943a588d | ||
|
|
8c6ebc665d | ||
|
|
2d2df3fc2c | ||
|
|
958ddcb49c | ||
|
|
5e9e988a96 | ||
|
|
34f3409f9b | ||
|
|
49c548494e | ||
|
|
7ba41fbb7d | ||
|
|
d95b974941 | ||
|
|
74bf39ab27 | ||
|
|
8897b9e0f7 | ||
|
|
d6de8644c0 | ||
|
|
190f3b1684 | ||
|
|
ae5961daf4 | ||
|
|
68b51b387a | ||
|
|
9097319c4b | ||
|
|
49a7db074d | ||
|
|
7f7ed04a80 | ||
|
|
ab5f42cc65 | ||
|
|
b1fd8fd51b | ||
|
|
16b98576c7 | ||
|
|
78f5d86f89 | ||
|
|
beec803eff | ||
|
|
3e0b55e8dc | ||
|
|
70db90f25b | ||
|
|
d84b79bee9 | ||
|
|
b491f51a04 | ||
|
|
3892e3f5e7 | ||
|
|
bd6dc08030 | ||
|
|
596cdbecd6 | ||
|
|
7798367348 | ||
|
|
e775fe78ca | ||
|
|
e1eddb336d | ||
|
|
b6bfb66c71 | ||
|
|
bbc28ccef8 | ||
|
|
d57738b0a8 | ||
|
|
6b1a3c874d | ||
|
|
9932010025 | ||
|
|
7cd73bca3c | ||
|
|
580abf8608 | ||
|
|
d845c4f832 | ||
|
|
cc09a166da | ||
|
|
78f6ee1428 | ||
|
|
590e9b3906 | ||
|
|
18f69d379f | ||
|
|
8b121e1352 | ||
|
|
5959f54b6c | ||
|
|
f7d320df30 | ||
|
|
31d7fcc8ba | ||
|
|
8b649ae0d9 | ||
|
|
61675061a0 | ||
|
|
35285dd74b | ||
|
|
6048092d93 | ||
|
|
28b90f412a | ||
|
|
09e7c4a4f2 | ||
|
|
dcdeb668df | ||
|
|
7ac8b1fdcb | ||
|
|
2eb1020b35 | ||
|
|
55cb4c3d0a | ||
|
|
050f391f89 | ||
|
|
3d5c6889b8 | ||
|
|
085f2cd064 | ||
|
|
5c70089a62 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -12,4 +12,6 @@ matrix_auth
|
||||
channels.list
|
||||
comfyworkflows_sharekey
|
||||
github-stats-cache.json
|
||||
pip_overrides.json
|
||||
pip_overrides.json
|
||||
*.json
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ cli_mode_flag = os.path.join(os.path.dirname(__file__), '.enable-cli-only-mode')
|
||||
|
||||
if not os.path.exists(cli_mode_flag):
|
||||
from .glob import manager_server
|
||||
from .glob import share_3rdparty
|
||||
WEB_DIRECTORY = "js"
|
||||
else:
|
||||
print(f"\n[ComfyUI-Manager] !! cli-only-mode is enabled !!\n")
|
||||
|
||||
@@ -35,6 +35,7 @@ restore_snapshot_path = os.path.join(startup_script_path, "restore-snapshot.json
|
||||
pip_overrides_path = os.path.join(comfyui_manager_path, "pip_overrides.json")
|
||||
git_script_path = os.path.join(comfyui_manager_path, "git_helper.py")
|
||||
|
||||
cm_global.pip_blacklist = ['torch', 'torchsde', 'torchvision']
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
cm_global.pip_overrides = {}
|
||||
if os.path.exists(pip_overrides_path):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4679
github-stats.json
4679
github-stats.json
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ sys.path.append(glob_path)
|
||||
import cm_global
|
||||
from manager_util import *
|
||||
|
||||
version = [2, 48, 3]
|
||||
version = [2, 50, 1]
|
||||
version_str = f"V{version[0]}.{version[1]}" + (f'.{version[2]}' if len(version) > 2 else '')
|
||||
|
||||
|
||||
@@ -97,12 +97,15 @@ def clear_pip_cache():
|
||||
def is_blacklisted(name):
|
||||
name = name.strip()
|
||||
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)([^ ]*)'
|
||||
match = re.search(pattern, name)
|
||||
|
||||
if match:
|
||||
name = match.group(1)
|
||||
|
||||
if name in cm_global.pip_blacklist:
|
||||
return True
|
||||
|
||||
if name in cm_global.pip_downgrade_blacklist:
|
||||
pips = get_installed_packages()
|
||||
|
||||
@@ -123,12 +126,15 @@ def is_installed(name):
|
||||
if name.startswith('#'):
|
||||
return True
|
||||
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)([0-9.a-zA-Z]*)'
|
||||
match = re.search(pattern, name)
|
||||
|
||||
if match:
|
||||
name = match.group(1)
|
||||
|
||||
if name in cm_global.pip_blacklist:
|
||||
return True
|
||||
|
||||
if name in cm_global.pip_downgrade_blacklist:
|
||||
pips = get_installed_packages()
|
||||
|
||||
@@ -405,8 +411,14 @@ def execute_install_script(url, repo_path, lazy_mode=False, instant_execution=Fa
|
||||
with open(requirements_path, "r") as requirements_file:
|
||||
for line in requirements_file:
|
||||
package_name = remap_pip_package(line.strip())
|
||||
|
||||
if package_name and not package_name.startswith('#'):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
if '--index-url' in package_name:
|
||||
s = package_name.split('--index-url')
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", s[0].strip(), '--index-url', s[1].strip()]
|
||||
else:
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
|
||||
if package_name.strip() != "" and not package_name.startswith('#'):
|
||||
try_install_script(url, repo_path, install_cmd, instant_execution=instant_execution)
|
||||
|
||||
@@ -1215,3 +1227,4 @@ def unzip(model_path):
|
||||
os.remove(model_path)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import mimetypes
|
||||
import traceback
|
||||
|
||||
import folder_paths
|
||||
@@ -6,7 +5,6 @@ import locale
|
||||
import subprocess # don't remove this
|
||||
import concurrent
|
||||
import nodes
|
||||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
@@ -22,6 +20,9 @@ print(f"### Loading: ComfyUI-Manager ({core.version_str})")
|
||||
|
||||
comfy_ui_hash = "-"
|
||||
|
||||
SECURITY_MESSAGE_MIDDLE_OR_BELOW = f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.\nReference: https://github.com/ltdrdata/ComfyUI-Manager#security-policy"
|
||||
SECURITY_MESSAGE_NORMAL_MINUS = f"ERROR: To use this feature, you must either set '--listen' to a local IP and set the security level to 'normal-' or lower, or set the security level to 'middle' or 'weak'. Please contact the administrator.\nReference: https://github.com/ltdrdata/ComfyUI-Manager#security-policy"
|
||||
SECURITY_MESSAGE_GENERAL = f"ERROR: This installation is not allowed in this security_level. Please contact the administrator.\nReference: https://github.com/ltdrdata/ComfyUI-Manager#security-policy"
|
||||
|
||||
def handle_stream(stream, prefix):
|
||||
stream.reconfigure(encoding=locale.getpreferredencoding(), errors='replace')
|
||||
@@ -249,8 +250,12 @@ def get_model_dir(data):
|
||||
model_type = data['type']
|
||||
if model_type == "checkpoints":
|
||||
base_model = folder_paths.folder_names_and_paths["checkpoints"][0][0]
|
||||
elif model_type == "checkpoint":
|
||||
base_model = folder_paths.folder_names_and_paths["checkpoints"][0][0]
|
||||
elif model_type == "unclip":
|
||||
base_model = folder_paths.folder_names_and_paths["checkpoints"][0][0]
|
||||
elif model_type == "clip":
|
||||
base_model = folder_paths.folder_names_and_paths["clip"][0][0]
|
||||
elif model_type == "VAE":
|
||||
base_model = folder_paths.folder_names_and_paths["vae"][0][0]
|
||||
elif model_type == "lora":
|
||||
@@ -388,7 +393,7 @@ async def fetch_updates(request):
|
||||
@PromptServer.instance.routes.get("/customnode/update_all")
|
||||
async def update_all(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
@@ -590,7 +595,7 @@ async def get_snapshot_list(request):
|
||||
@PromptServer.instance.routes.get("/snapshot/remove")
|
||||
async def remove_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
@@ -608,7 +613,7 @@ async def remove_snapshot(request):
|
||||
@PromptServer.instance.routes.get("/snapshot/restore")
|
||||
async def remove_snapshot(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
@@ -777,14 +782,14 @@ def copy_set_active(files, is_disable, js_path_name='.'):
|
||||
@PromptServer.instance.routes.post("/customnode/install")
|
||||
async def install_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
|
||||
risky_level = await get_risky_level(json_data['files'])
|
||||
if not is_allowed_security_level(risky_level):
|
||||
print(f"ERROR: This installation is not allowed in this security_level. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_GENERAL)
|
||||
return web.Response(status=404)
|
||||
|
||||
install_type = json_data['install_type']
|
||||
@@ -824,7 +829,7 @@ async def install_custom_node(request):
|
||||
@PromptServer.instance.routes.post("/customnode/fix")
|
||||
async def fix_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
@@ -848,6 +853,10 @@ async def fix_custom_node(request):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", '-U', pname]
|
||||
core.try_install_script(json_data['files'][0], ".", install_cmd)
|
||||
|
||||
# HOTFIX: force downgrade to numpy<2
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", "numpy<2"]
|
||||
core.try_install_script(json_data['files'][0], ".", install_cmd)
|
||||
|
||||
if res:
|
||||
print(f"After restarting ComfyUI, please refresh the browser.")
|
||||
return web.json_response({}, content_type='application/json')
|
||||
@@ -858,7 +867,7 @@ async def fix_custom_node(request):
|
||||
@PromptServer.instance.routes.post("/customnode/install/git_url")
|
||||
async def install_custom_node_git_url(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this feature, you must either set '--listen' to a local IP and set the security level to 'normal-' or lower, or set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
return web.Response(status=403)
|
||||
|
||||
url = await request.text()
|
||||
@@ -874,7 +883,7 @@ async def install_custom_node_git_url(request):
|
||||
@PromptServer.instance.routes.post("/customnode/install/pip")
|
||||
async def install_custom_node_git_url(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this feature, you must either set '--listen' to a local IP and set the security level to 'normal-' or lower, or set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
return web.Response(status=403)
|
||||
|
||||
packages = await request.text()
|
||||
@@ -886,7 +895,7 @@ async def install_custom_node_git_url(request):
|
||||
@PromptServer.instance.routes.post("/customnode/uninstall")
|
||||
async def uninstall_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
@@ -914,7 +923,7 @@ async def uninstall_custom_node(request):
|
||||
@PromptServer.instance.routes.post("/customnode/update")
|
||||
async def update_custom_node(request):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
json_data = await request.json()
|
||||
@@ -986,7 +995,7 @@ async def install_model(request):
|
||||
model_path = get_model_path(json_data)
|
||||
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
if not json_data['filename'].endswith('.safetensors') and not is_allowed_security_level('high'):
|
||||
@@ -999,7 +1008,7 @@ async def install_model(request):
|
||||
break
|
||||
|
||||
if not is_belongs_to_whitelist:
|
||||
print(f"ERROR: To use this feature, you must either set '--listen' to a local IP and set the security level to 'normal-' or lower, or set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
return web.Response(status=403)
|
||||
|
||||
res = False
|
||||
@@ -1049,7 +1058,7 @@ manager_terminal_hook = ManagerTerminalHook()
|
||||
@PromptServer.instance.routes.get("/manager/terminal")
|
||||
async def terminal_mode(request):
|
||||
if not is_allowed_security_level('high'):
|
||||
print(f"ERROR: To use this feature, you must either set '--listen' to a local IP and set the security level to 'normal-' or lower, or set the security level to 'middle' or 'weak'. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_NORMAL_MINUS)
|
||||
return web.Response(status=403)
|
||||
|
||||
if "mode" in request.rel_url.query:
|
||||
@@ -1191,7 +1200,7 @@ async def get_notice(request):
|
||||
@PromptServer.instance.routes.get("/manager/reboot")
|
||||
def restart(self):
|
||||
if not is_allowed_security_level('middle'):
|
||||
print(f"ERROR: To use this action, a security_level of `middle or below` is required. Please contact the administrator.")
|
||||
print(SECURITY_MESSAGE_MIDDLE_OR_BELOW)
|
||||
return web.Response(status=403)
|
||||
|
||||
try:
|
||||
@@ -1271,128 +1280,6 @@ async def load_components(request):
|
||||
return web.Response(status=400)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/share_option")
|
||||
async def share_option(request):
|
||||
if "value" in request.rel_url.query:
|
||||
core.get_config()['share_option'] = request.rel_url.query['value']
|
||||
core.write_config()
|
||||
else:
|
||||
return web.Response(text=core.get_config()['share_option'], status=200)
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
def get_openart_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, ".openart_key")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, ".openart_key"), "r") as f:
|
||||
openart_key = f.read().strip()
|
||||
return openart_key if openart_key else None
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_matrix_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, "matrix_auth")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, "matrix_auth"), "r") as f:
|
||||
matrix_auth = f.read()
|
||||
homeserver, username, password = matrix_auth.strip().split("\n")
|
||||
if not homeserver or not username or not password:
|
||||
return None
|
||||
return {
|
||||
"homeserver": homeserver,
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_comfyworkflows_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey"), "r") as f:
|
||||
share_key = f.read()
|
||||
if not share_key.strip():
|
||||
return None
|
||||
return share_key
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_youml_settings():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, ".youml")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, ".youml"), "r") as f:
|
||||
youml_settings = f.read().strip()
|
||||
return youml_settings if youml_settings else None
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def set_youml_settings(settings):
|
||||
with open(os.path.join(core.comfyui_manager_path, ".youml"), "w") as f:
|
||||
f.write(settings)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_openart_auth")
|
||||
async def api_get_openart_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
openart_key = get_openart_auth()
|
||||
if not openart_key:
|
||||
return web.Response(status=404)
|
||||
return web.json_response({"openart_key": openart_key})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/set_openart_auth")
|
||||
async def api_set_openart_auth(request):
|
||||
json_data = await request.json()
|
||||
openart_key = json_data['openart_key']
|
||||
with open(os.path.join(core.comfyui_manager_path, ".openart_key"), "w") as f:
|
||||
f.write(openart_key)
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_matrix_auth")
|
||||
async def api_get_matrix_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
matrix_auth = get_matrix_auth()
|
||||
if not matrix_auth:
|
||||
return web.Response(status=404)
|
||||
return web.json_response(matrix_auth)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/youml/settings")
|
||||
async def api_get_youml_settings(request):
|
||||
youml_settings = get_youml_settings()
|
||||
if not youml_settings:
|
||||
return web.Response(status=404)
|
||||
return web.json_response(json.loads(youml_settings))
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/youml/settings")
|
||||
async def api_set_youml_settings(request):
|
||||
json_data = await request.json()
|
||||
set_youml_settings(json.dumps(json_data))
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_comfyworkflows_auth")
|
||||
async def api_get_comfyworkflows_auth(request):
|
||||
# Check if the user has provided Matrix credentials in a file called 'matrix_accesstoken'
|
||||
# in the same directory as the ComfyUI base folder
|
||||
# print("Getting stored Comfyworkflows.com auth...")
|
||||
comfyworkflows_auth = get_comfyworkflows_auth()
|
||||
if not comfyworkflows_auth:
|
||||
return web.Response(status=404)
|
||||
return web.json_response({"comfyworkflows_sharekey": comfyworkflows_auth})
|
||||
|
||||
|
||||
args.enable_cors_header = "*"
|
||||
if hasattr(PromptServer.instance, "app"):
|
||||
app = PromptServer.instance.app
|
||||
@@ -1400,260 +1287,6 @@ if hasattr(PromptServer.instance, "app"):
|
||||
app.middlewares.append(cors_middleware)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/set_esheep_workflow_and_images")
|
||||
async def set_esheep_workflow_and_images(request):
|
||||
json_data = await request.json()
|
||||
current_workflow = json_data['workflow']
|
||||
images = json_data['images']
|
||||
with open(os.path.join(core.comfyui_manager_path, "esheep_share_message.json"), "w", encoding='utf-8') as file:
|
||||
json.dump(json_data, file, indent=4)
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_esheep_workflow_and_images")
|
||||
async def get_esheep_workflow_and_images(request):
|
||||
with open(os.path.join(core.comfyui_manager_path, "esheep_share_message.json"), 'r', encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
return web.Response(status=200, text=json.dumps(data))
|
||||
|
||||
|
||||
def set_matrix_auth(json_data):
|
||||
homeserver = json_data['homeserver']
|
||||
username = json_data['username']
|
||||
password = json_data['password']
|
||||
with open(os.path.join(core.comfyui_manager_path, "matrix_auth"), "w") as f:
|
||||
f.write("\n".join([homeserver, username, password]))
|
||||
|
||||
|
||||
def set_comfyworkflows_auth(comfyworkflows_sharekey):
|
||||
with open(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey"), "w") as f:
|
||||
f.write(comfyworkflows_sharekey)
|
||||
|
||||
|
||||
def has_provided_matrix_auth(matrix_auth):
|
||||
return matrix_auth['homeserver'].strip() and matrix_auth['username'].strip() and matrix_auth['password'].strip()
|
||||
|
||||
|
||||
def has_provided_comfyworkflows_auth(comfyworkflows_sharekey):
|
||||
return comfyworkflows_sharekey.strip()
|
||||
|
||||
|
||||
def extract_model_file_names(json_data):
|
||||
"""Extract unique file names from the input JSON data."""
|
||||
file_names = set()
|
||||
model_filename_extensions = {'.safetensors', '.ckpt', '.pt', '.pth', '.bin'}
|
||||
|
||||
# Recursively search for file names in the JSON data
|
||||
def recursive_search(data):
|
||||
if isinstance(data, dict):
|
||||
for value in data.values():
|
||||
recursive_search(value)
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
recursive_search(item)
|
||||
elif isinstance(data, str) and '.' in data:
|
||||
file_names.add(os.path.basename(data)) # file_names.add(data)
|
||||
|
||||
recursive_search(json_data)
|
||||
return [f for f in list(file_names) if os.path.splitext(f)[1] in model_filename_extensions]
|
||||
|
||||
|
||||
def find_file_paths(base_dir, file_names):
|
||||
"""Find the paths of the files in the base directory."""
|
||||
file_paths = {}
|
||||
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
# Exclude certain directories
|
||||
dirs[:] = [d for d in dirs if d not in ['.git']]
|
||||
|
||||
for file in files:
|
||||
if file in file_names:
|
||||
file_paths[file] = os.path.join(root, file)
|
||||
return file_paths
|
||||
|
||||
|
||||
def compute_sha256_checksum(filepath):
|
||||
"""Compute the SHA256 checksum of a file, in chunks"""
|
||||
sha256 = hashlib.sha256()
|
||||
with open(filepath, 'rb') as f:
|
||||
for chunk in iter(lambda: f.read(4096), b''):
|
||||
sha256.update(chunk)
|
||||
return sha256.hexdigest()
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/share")
|
||||
async def share_art(request):
|
||||
# get json data
|
||||
json_data = await request.json()
|
||||
|
||||
matrix_auth = json_data['matrix_auth']
|
||||
comfyworkflows_sharekey = json_data['cw_auth']['cw_sharekey']
|
||||
|
||||
set_matrix_auth(matrix_auth)
|
||||
set_comfyworkflows_auth(comfyworkflows_sharekey)
|
||||
|
||||
share_destinations = json_data['share_destinations']
|
||||
credits = json_data['credits']
|
||||
title = json_data['title']
|
||||
description = json_data['description']
|
||||
is_nsfw = json_data['is_nsfw']
|
||||
prompt = json_data['prompt']
|
||||
potential_outputs = json_data['potential_outputs']
|
||||
selected_output_index = json_data['selected_output_index']
|
||||
|
||||
try:
|
||||
output_to_share = potential_outputs[int(selected_output_index)]
|
||||
except:
|
||||
# for now, pick the first output
|
||||
output_to_share = potential_outputs[0]
|
||||
|
||||
assert output_to_share['type'] in ('image', 'output')
|
||||
output_dir = folder_paths.get_output_directory()
|
||||
|
||||
if output_to_share['type'] == 'image':
|
||||
asset_filename = output_to_share['image']['filename']
|
||||
asset_subfolder = output_to_share['image']['subfolder']
|
||||
|
||||
if output_to_share['image']['type'] == 'temp':
|
||||
output_dir = folder_paths.get_temp_directory()
|
||||
else:
|
||||
asset_filename = output_to_share['output']['filename']
|
||||
asset_subfolder = output_to_share['output']['subfolder']
|
||||
|
||||
if asset_subfolder:
|
||||
asset_filepath = os.path.join(output_dir, asset_subfolder, asset_filename)
|
||||
else:
|
||||
asset_filepath = os.path.join(output_dir, asset_filename)
|
||||
|
||||
# get the mime type of the asset
|
||||
assetFileType = mimetypes.guess_type(asset_filepath)[0]
|
||||
|
||||
share_website_host = "UNKNOWN"
|
||||
if "comfyworkflows" in share_destinations:
|
||||
share_website_host = "https://comfyworkflows.com"
|
||||
share_endpoint = f"{share_website_host}/api"
|
||||
|
||||
# get presigned urls
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.post(
|
||||
f"{share_endpoint}/get_presigned_urls",
|
||||
json={
|
||||
"assetFileName": asset_filename,
|
||||
"assetFileType": assetFileType,
|
||||
"workflowJsonFileName": 'workflow.json',
|
||||
"workflowJsonFileType": 'application/json',
|
||||
},
|
||||
) as resp:
|
||||
assert resp.status == 200
|
||||
presigned_urls_json = await resp.json()
|
||||
assetFilePresignedUrl = presigned_urls_json["assetFilePresignedUrl"]
|
||||
assetFileKey = presigned_urls_json["assetFileKey"]
|
||||
workflowJsonFilePresignedUrl = presigned_urls_json["workflowJsonFilePresignedUrl"]
|
||||
workflowJsonFileKey = presigned_urls_json["workflowJsonFileKey"]
|
||||
|
||||
# upload asset
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.put(assetFilePresignedUrl, data=open(asset_filepath, "rb")) as resp:
|
||||
assert resp.status == 200
|
||||
|
||||
# upload workflow json
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.put(workflowJsonFilePresignedUrl, data=json.dumps(prompt['workflow']).encode('utf-8')) as resp:
|
||||
assert resp.status == 200
|
||||
|
||||
model_filenames = extract_model_file_names(prompt['workflow'])
|
||||
model_file_paths = find_file_paths(folder_paths.base_path, model_filenames)
|
||||
|
||||
models_info = {}
|
||||
for filename, filepath in model_file_paths.items():
|
||||
models_info[filename] = {
|
||||
"filename": filename,
|
||||
"sha256_checksum": compute_sha256_checksum(filepath),
|
||||
"relative_path": os.path.relpath(filepath, folder_paths.base_path),
|
||||
}
|
||||
|
||||
# make a POST request to /api/upload_workflow with form data key values
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
form = aiohttp.FormData()
|
||||
if comfyworkflows_sharekey:
|
||||
form.add_field("shareKey", comfyworkflows_sharekey)
|
||||
form.add_field("source", "comfyui_manager")
|
||||
form.add_field("assetFileKey", assetFileKey)
|
||||
form.add_field("assetFileType", assetFileType)
|
||||
form.add_field("workflowJsonFileKey", workflowJsonFileKey)
|
||||
form.add_field("sharedWorkflowWorkflowJsonString", json.dumps(prompt['workflow']))
|
||||
form.add_field("sharedWorkflowPromptJsonString", json.dumps(prompt['output']))
|
||||
form.add_field("shareWorkflowCredits", credits)
|
||||
form.add_field("shareWorkflowTitle", title)
|
||||
form.add_field("shareWorkflowDescription", description)
|
||||
form.add_field("shareWorkflowIsNSFW", str(is_nsfw).lower())
|
||||
form.add_field("currentSnapshot", json.dumps(core.get_current_snapshot()))
|
||||
form.add_field("modelsInfo", json.dumps(models_info))
|
||||
|
||||
async with session.post(
|
||||
f"{share_endpoint}/upload_workflow",
|
||||
data=form,
|
||||
) as resp:
|
||||
assert resp.status == 200
|
||||
upload_workflow_json = await resp.json()
|
||||
workflowId = upload_workflow_json["workflowId"]
|
||||
|
||||
# check if the user has provided Matrix credentials
|
||||
if "matrix" in share_destinations:
|
||||
comfyui_share_room_id = '!LGYSoacpJPhIfBqVfb:matrix.org'
|
||||
filename = os.path.basename(asset_filepath)
|
||||
content_type = assetFileType
|
||||
|
||||
try:
|
||||
from matrix_client.api import MatrixHttpApi
|
||||
from matrix_client.client import MatrixClient
|
||||
|
||||
homeserver = 'matrix.org'
|
||||
if matrix_auth:
|
||||
homeserver = matrix_auth.get('homeserver', 'matrix.org')
|
||||
homeserver = homeserver.replace("http://", "https://")
|
||||
if not homeserver.startswith("https://"):
|
||||
homeserver = "https://" + homeserver
|
||||
|
||||
client = MatrixClient(homeserver)
|
||||
try:
|
||||
token = client.login(username=matrix_auth['username'], password=matrix_auth['password'])
|
||||
if not token:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
except:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
|
||||
matrix = MatrixHttpApi(homeserver, token=token)
|
||||
with open(asset_filepath, 'rb') as f:
|
||||
mxc_url = matrix.media_upload(f.read(), content_type, filename=filename)['content_uri']
|
||||
|
||||
workflow_json_mxc_url = matrix.media_upload(prompt['workflow'], 'application/json', filename='workflow.json')['content_uri']
|
||||
|
||||
text_content = ""
|
||||
if title:
|
||||
text_content += f"{title}\n"
|
||||
if description:
|
||||
text_content += f"{description}\n"
|
||||
if credits:
|
||||
text_content += f"\ncredits: {credits}\n"
|
||||
response = matrix.send_message(comfyui_share_room_id, text_content)
|
||||
response = matrix.send_content(comfyui_share_room_id, mxc_url, filename, 'm.image')
|
||||
response = matrix.send_content(comfyui_share_room_id, workflow_json_mxc_url, 'workflow.json', 'm.file')
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return web.json_response({"error": "An error occurred when sharing your art to Matrix."}, content_type='application/json', status=500)
|
||||
|
||||
return web.json_response({
|
||||
"comfyworkflows": {
|
||||
"url": None if "comfyworkflows" not in share_destinations else f"{share_website_host}/workflows/{workflowId}",
|
||||
},
|
||||
"matrix": {
|
||||
"success": None if "matrix" not in share_destinations else True
|
||||
}
|
||||
}, content_type='application/json', status=200)
|
||||
|
||||
|
||||
def sanitize(data):
|
||||
return data.replace("<", "<").replace(">", ">")
|
||||
|
||||
|
||||
@@ -1,63 +1,64 @@
|
||||
try:
|
||||
from distutils.version import StrictVersion
|
||||
except:
|
||||
print(f"[ComfyUI-Manager] 'distutils' package not found. Activating fallback mode for compatibility.")
|
||||
class StrictVersion:
|
||||
def __init__(self, version_string):
|
||||
self.version_string = version_string
|
||||
self.major = 0
|
||||
self.minor = 0
|
||||
self.patch = 0
|
||||
self.pre_release = None
|
||||
self.parse_version_string()
|
||||
# DON'T USE StrictVersion - cannot handle pre_release version
|
||||
# try:
|
||||
# from distutils.version import StrictVersion
|
||||
# except:
|
||||
# print(f"[ComfyUI-Manager] 'distutils' package not found. Activating fallback mode for compatibility.")
|
||||
class StrictVersion:
|
||||
def __init__(self, version_string):
|
||||
self.version_string = version_string
|
||||
self.major = 0
|
||||
self.minor = 0
|
||||
self.patch = 0
|
||||
self.pre_release = None
|
||||
self.parse_version_string()
|
||||
|
||||
def parse_version_string(self):
|
||||
parts = self.version_string.split('.')
|
||||
if not parts:
|
||||
raise ValueError("Version string must not be empty")
|
||||
def parse_version_string(self):
|
||||
parts = self.version_string.split('.')
|
||||
if not parts:
|
||||
raise ValueError("Version string must not be empty")
|
||||
|
||||
self.major = int(parts[0])
|
||||
self.minor = int(parts[1]) if len(parts) > 1 else 0
|
||||
self.patch = int(parts[2]) if len(parts) > 2 else 0
|
||||
self.major = int(parts[0])
|
||||
self.minor = int(parts[1]) if len(parts) > 1 else 0
|
||||
self.patch = int(parts[2]) if len(parts) > 2 else 0
|
||||
|
||||
# Handling pre-release versions if present
|
||||
if len(parts) > 3:
|
||||
self.pre_release = parts[3]
|
||||
# Handling pre-release versions if present
|
||||
if len(parts) > 3:
|
||||
self.pre_release = parts[3]
|
||||
|
||||
def __str__(self):
|
||||
version = f"{self.major}.{self.minor}.{self.patch}"
|
||||
if self.pre_release:
|
||||
version += f"-{self.pre_release}"
|
||||
return version
|
||||
def __str__(self):
|
||||
version = f"{self.major}.{self.minor}.{self.patch}"
|
||||
if self.pre_release:
|
||||
version += f"-{self.pre_release}"
|
||||
return version
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.major, self.minor, self.patch, self.pre_release) == \
|
||||
(other.major, other.minor, other.patch, other.pre_release)
|
||||
def __eq__(self, other):
|
||||
return (self.major, self.minor, self.patch, self.pre_release) == \
|
||||
(other.major, other.minor, other.patch, other.pre_release)
|
||||
|
||||
def __lt__(self, other):
|
||||
if (self.major, self.minor, self.patch) == (other.major, other.minor, other.patch):
|
||||
return self.pre_release_compare(self.pre_release, other.pre_release) < 0
|
||||
return (self.major, self.minor, self.patch) < (other.major, other.minor, other.patch)
|
||||
def __lt__(self, other):
|
||||
if (self.major, self.minor, self.patch) == (other.major, other.minor, other.patch):
|
||||
return self.pre_release_compare(self.pre_release, other.pre_release) < 0
|
||||
return (self.major, self.minor, self.patch) < (other.major, other.minor, other.patch)
|
||||
|
||||
@staticmethod
|
||||
def pre_release_compare(pre1, pre2):
|
||||
if pre1 == pre2:
|
||||
return 0
|
||||
if pre1 is None:
|
||||
return 1
|
||||
if pre2 is None:
|
||||
return -1
|
||||
return -1 if pre1 < pre2 else 1
|
||||
@staticmethod
|
||||
def pre_release_compare(pre1, pre2):
|
||||
if pre1 == pre2:
|
||||
return 0
|
||||
if pre1 is None:
|
||||
return 1
|
||||
if pre2 is None:
|
||||
return -1
|
||||
return -1 if pre1 < pre2 else 1
|
||||
|
||||
def __le__(self, other):
|
||||
return self == other or self < other
|
||||
def __le__(self, other):
|
||||
return self == other or self < other
|
||||
|
||||
def __gt__(self, other):
|
||||
return not self <= other
|
||||
def __gt__(self, other):
|
||||
return not self <= other
|
||||
|
||||
def __ge__(self, other):
|
||||
return not self < other
|
||||
def __ge__(self, other):
|
||||
return not self < other
|
||||
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
def __ne__(self, other):
|
||||
return not self == other
|
||||
|
||||
|
||||
386
glob/share_3rdparty.py
Normal file
386
glob/share_3rdparty.py
Normal file
@@ -0,0 +1,386 @@
|
||||
import mimetypes
|
||||
import manager_core as core
|
||||
import os
|
||||
from aiohttp import web
|
||||
import aiohttp
|
||||
import json
|
||||
import hashlib
|
||||
|
||||
import folder_paths
|
||||
from server import PromptServer
|
||||
|
||||
|
||||
def extract_model_file_names(json_data):
|
||||
"""Extract unique file names from the input JSON data."""
|
||||
file_names = set()
|
||||
model_filename_extensions = {'.safetensors', '.ckpt', '.pt', '.pth', '.bin'}
|
||||
|
||||
# Recursively search for file names in the JSON data
|
||||
def recursive_search(data):
|
||||
if isinstance(data, dict):
|
||||
for value in data.values():
|
||||
recursive_search(value)
|
||||
elif isinstance(data, list):
|
||||
for item in data:
|
||||
recursive_search(item)
|
||||
elif isinstance(data, str) and '.' in data:
|
||||
file_names.add(os.path.basename(data)) # file_names.add(data)
|
||||
|
||||
recursive_search(json_data)
|
||||
return [f for f in list(file_names) if os.path.splitext(f)[1] in model_filename_extensions]
|
||||
|
||||
|
||||
def find_file_paths(base_dir, file_names):
|
||||
"""Find the paths of the files in the base directory."""
|
||||
file_paths = {}
|
||||
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
# Exclude certain directories
|
||||
dirs[:] = [d for d in dirs if d not in ['.git']]
|
||||
|
||||
for file in files:
|
||||
if file in file_names:
|
||||
file_paths[file] = os.path.join(root, file)
|
||||
return file_paths
|
||||
|
||||
|
||||
def compute_sha256_checksum(filepath):
|
||||
"""Compute the SHA256 checksum of a file, in chunks"""
|
||||
sha256 = hashlib.sha256()
|
||||
with open(filepath, 'rb') as f:
|
||||
for chunk in iter(lambda: f.read(4096), b''):
|
||||
sha256.update(chunk)
|
||||
return sha256.hexdigest()
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/share_option")
|
||||
async def share_option(request):
|
||||
if "value" in request.rel_url.query:
|
||||
core.get_config()['share_option'] = request.rel_url.query['value']
|
||||
core.write_config()
|
||||
else:
|
||||
return web.Response(text=core.get_config()['share_option'], status=200)
|
||||
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
def get_openart_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, ".openart_key")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, ".openart_key"), "r") as f:
|
||||
openart_key = f.read().strip()
|
||||
return openart_key if openart_key else None
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_matrix_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, "matrix_auth")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, "matrix_auth"), "r") as f:
|
||||
matrix_auth = f.read()
|
||||
homeserver, username, password = matrix_auth.strip().split("\n")
|
||||
if not homeserver or not username or not password:
|
||||
return None
|
||||
return {
|
||||
"homeserver": homeserver,
|
||||
"username": username,
|
||||
"password": password,
|
||||
}
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_comfyworkflows_auth():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey"), "r") as f:
|
||||
share_key = f.read()
|
||||
if not share_key.strip():
|
||||
return None
|
||||
return share_key
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def get_youml_settings():
|
||||
if not os.path.exists(os.path.join(core.comfyui_manager_path, ".youml")):
|
||||
return None
|
||||
try:
|
||||
with open(os.path.join(core.comfyui_manager_path, ".youml"), "r") as f:
|
||||
youml_settings = f.read().strip()
|
||||
return youml_settings if youml_settings else None
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def set_youml_settings(settings):
|
||||
with open(os.path.join(core.comfyui_manager_path, ".youml"), "w") as f:
|
||||
f.write(settings)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_openart_auth")
|
||||
async def api_get_openart_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
openart_key = get_openart_auth()
|
||||
if not openart_key:
|
||||
return web.Response(status=404)
|
||||
return web.json_response({"openart_key": openart_key})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/set_openart_auth")
|
||||
async def api_set_openart_auth(request):
|
||||
json_data = await request.json()
|
||||
openart_key = json_data['openart_key']
|
||||
with open(os.path.join(core.comfyui_manager_path, ".openart_key"), "w") as f:
|
||||
f.write(openart_key)
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_matrix_auth")
|
||||
async def api_get_matrix_auth(request):
|
||||
# print("Getting stored Matrix credentials...")
|
||||
matrix_auth = get_matrix_auth()
|
||||
if not matrix_auth:
|
||||
return web.Response(status=404)
|
||||
return web.json_response(matrix_auth)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/youml/settings")
|
||||
async def api_get_youml_settings(request):
|
||||
youml_settings = get_youml_settings()
|
||||
if not youml_settings:
|
||||
return web.Response(status=404)
|
||||
return web.json_response(json.loads(youml_settings))
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/youml/settings")
|
||||
async def api_set_youml_settings(request):
|
||||
json_data = await request.json()
|
||||
set_youml_settings(json.dumps(json_data))
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_comfyworkflows_auth")
|
||||
async def api_get_comfyworkflows_auth(request):
|
||||
# Check if the user has provided Matrix credentials in a file called 'matrix_accesstoken'
|
||||
# in the same directory as the ComfyUI base folder
|
||||
# print("Getting stored Comfyworkflows.com auth...")
|
||||
comfyworkflows_auth = get_comfyworkflows_auth()
|
||||
if not comfyworkflows_auth:
|
||||
return web.Response(status=404)
|
||||
return web.json_response({"comfyworkflows_sharekey": comfyworkflows_auth})
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/set_esheep_workflow_and_images")
|
||||
async def set_esheep_workflow_and_images(request):
|
||||
json_data = await request.json()
|
||||
current_workflow = json_data['workflow']
|
||||
images = json_data['images']
|
||||
with open(os.path.join(core.comfyui_manager_path, "esheep_share_message.json"), "w", encoding='utf-8') as file:
|
||||
json.dump(json_data, file, indent=4)
|
||||
return web.Response(status=200)
|
||||
|
||||
|
||||
@PromptServer.instance.routes.get("/manager/get_esheep_workflow_and_images")
|
||||
async def get_esheep_workflow_and_images(request):
|
||||
with open(os.path.join(core.comfyui_manager_path, "esheep_share_message.json"), 'r', encoding='utf-8') as file:
|
||||
data = json.load(file)
|
||||
return web.Response(status=200, text=json.dumps(data))
|
||||
|
||||
|
||||
def set_matrix_auth(json_data):
|
||||
homeserver = json_data['homeserver']
|
||||
username = json_data['username']
|
||||
password = json_data['password']
|
||||
with open(os.path.join(core.comfyui_manager_path, "matrix_auth"), "w") as f:
|
||||
f.write("\n".join([homeserver, username, password]))
|
||||
|
||||
|
||||
def set_comfyworkflows_auth(comfyworkflows_sharekey):
|
||||
with open(os.path.join(core.comfyui_manager_path, "comfyworkflows_sharekey"), "w") as f:
|
||||
f.write(comfyworkflows_sharekey)
|
||||
|
||||
|
||||
def has_provided_matrix_auth(matrix_auth):
|
||||
return matrix_auth['homeserver'].strip() and matrix_auth['username'].strip() and matrix_auth['password'].strip()
|
||||
|
||||
|
||||
def has_provided_comfyworkflows_auth(comfyworkflows_sharekey):
|
||||
return comfyworkflows_sharekey.strip()
|
||||
|
||||
|
||||
@PromptServer.instance.routes.post("/manager/share")
|
||||
async def share_art(request):
|
||||
# get json data
|
||||
json_data = await request.json()
|
||||
|
||||
matrix_auth = json_data['matrix_auth']
|
||||
comfyworkflows_sharekey = json_data['cw_auth']['cw_sharekey']
|
||||
|
||||
set_matrix_auth(matrix_auth)
|
||||
set_comfyworkflows_auth(comfyworkflows_sharekey)
|
||||
|
||||
share_destinations = json_data['share_destinations']
|
||||
credits = json_data['credits']
|
||||
title = json_data['title']
|
||||
description = json_data['description']
|
||||
is_nsfw = json_data['is_nsfw']
|
||||
prompt = json_data['prompt']
|
||||
potential_outputs = json_data['potential_outputs']
|
||||
selected_output_index = json_data['selected_output_index']
|
||||
|
||||
try:
|
||||
output_to_share = potential_outputs[int(selected_output_index)]
|
||||
except:
|
||||
# for now, pick the first output
|
||||
output_to_share = potential_outputs[0]
|
||||
|
||||
assert output_to_share['type'] in ('image', 'output')
|
||||
output_dir = folder_paths.get_output_directory()
|
||||
|
||||
if output_to_share['type'] == 'image':
|
||||
asset_filename = output_to_share['image']['filename']
|
||||
asset_subfolder = output_to_share['image']['subfolder']
|
||||
|
||||
if output_to_share['image']['type'] == 'temp':
|
||||
output_dir = folder_paths.get_temp_directory()
|
||||
else:
|
||||
asset_filename = output_to_share['output']['filename']
|
||||
asset_subfolder = output_to_share['output']['subfolder']
|
||||
|
||||
if asset_subfolder:
|
||||
asset_filepath = os.path.join(output_dir, asset_subfolder, asset_filename)
|
||||
else:
|
||||
asset_filepath = os.path.join(output_dir, asset_filename)
|
||||
|
||||
# get the mime type of the asset
|
||||
assetFileType = mimetypes.guess_type(asset_filepath)[0]
|
||||
|
||||
share_website_host = "UNKNOWN"
|
||||
if "comfyworkflows" in share_destinations:
|
||||
share_website_host = "https://comfyworkflows.com"
|
||||
share_endpoint = f"{share_website_host}/api"
|
||||
|
||||
# get presigned urls
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.post(
|
||||
f"{share_endpoint}/get_presigned_urls",
|
||||
json={
|
||||
"assetFileName": asset_filename,
|
||||
"assetFileType": assetFileType,
|
||||
"workflowJsonFileName": 'workflow.json',
|
||||
"workflowJsonFileType": 'application/json',
|
||||
},
|
||||
) as resp:
|
||||
assert resp.status == 200
|
||||
presigned_urls_json = await resp.json()
|
||||
assetFilePresignedUrl = presigned_urls_json["assetFilePresignedUrl"]
|
||||
assetFileKey = presigned_urls_json["assetFileKey"]
|
||||
workflowJsonFilePresignedUrl = presigned_urls_json["workflowJsonFilePresignedUrl"]
|
||||
workflowJsonFileKey = presigned_urls_json["workflowJsonFileKey"]
|
||||
|
||||
# upload asset
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.put(assetFilePresignedUrl, data=open(asset_filepath, "rb")) as resp:
|
||||
assert resp.status == 200
|
||||
|
||||
# upload workflow json
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
async with session.put(workflowJsonFilePresignedUrl, data=json.dumps(prompt['workflow']).encode('utf-8')) as resp:
|
||||
assert resp.status == 200
|
||||
|
||||
model_filenames = extract_model_file_names(prompt['workflow'])
|
||||
model_file_paths = find_file_paths(folder_paths.base_path, model_filenames)
|
||||
|
||||
models_info = {}
|
||||
for filename, filepath in model_file_paths.items():
|
||||
models_info[filename] = {
|
||||
"filename": filename,
|
||||
"sha256_checksum": compute_sha256_checksum(filepath),
|
||||
"relative_path": os.path.relpath(filepath, folder_paths.base_path),
|
||||
}
|
||||
|
||||
# make a POST request to /api/upload_workflow with form data key values
|
||||
async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
||||
form = aiohttp.FormData()
|
||||
if comfyworkflows_sharekey:
|
||||
form.add_field("shareKey", comfyworkflows_sharekey)
|
||||
form.add_field("source", "comfyui_manager")
|
||||
form.add_field("assetFileKey", assetFileKey)
|
||||
form.add_field("assetFileType", assetFileType)
|
||||
form.add_field("workflowJsonFileKey", workflowJsonFileKey)
|
||||
form.add_field("sharedWorkflowWorkflowJsonString", json.dumps(prompt['workflow']))
|
||||
form.add_field("sharedWorkflowPromptJsonString", json.dumps(prompt['output']))
|
||||
form.add_field("shareWorkflowCredits", credits)
|
||||
form.add_field("shareWorkflowTitle", title)
|
||||
form.add_field("shareWorkflowDescription", description)
|
||||
form.add_field("shareWorkflowIsNSFW", str(is_nsfw).lower())
|
||||
form.add_field("currentSnapshot", json.dumps(core.get_current_snapshot()))
|
||||
form.add_field("modelsInfo", json.dumps(models_info))
|
||||
|
||||
async with session.post(
|
||||
f"{share_endpoint}/upload_workflow",
|
||||
data=form,
|
||||
) as resp:
|
||||
assert resp.status == 200
|
||||
upload_workflow_json = await resp.json()
|
||||
workflowId = upload_workflow_json["workflowId"]
|
||||
|
||||
# check if the user has provided Matrix credentials
|
||||
if "matrix" in share_destinations:
|
||||
comfyui_share_room_id = '!LGYSoacpJPhIfBqVfb:matrix.org'
|
||||
filename = os.path.basename(asset_filepath)
|
||||
content_type = assetFileType
|
||||
|
||||
try:
|
||||
from matrix_client.api import MatrixHttpApi
|
||||
from matrix_client.client import MatrixClient
|
||||
|
||||
homeserver = 'matrix.org'
|
||||
if matrix_auth:
|
||||
homeserver = matrix_auth.get('homeserver', 'matrix.org')
|
||||
homeserver = homeserver.replace("http://", "https://")
|
||||
if not homeserver.startswith("https://"):
|
||||
homeserver = "https://" + homeserver
|
||||
|
||||
client = MatrixClient(homeserver)
|
||||
try:
|
||||
token = client.login(username=matrix_auth['username'], password=matrix_auth['password'])
|
||||
if not token:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
except:
|
||||
return web.json_response({"error": "Invalid Matrix credentials."}, content_type='application/json', status=400)
|
||||
|
||||
matrix = MatrixHttpApi(homeserver, token=token)
|
||||
with open(asset_filepath, 'rb') as f:
|
||||
mxc_url = matrix.media_upload(f.read(), content_type, filename=filename)['content_uri']
|
||||
|
||||
workflow_json_mxc_url = matrix.media_upload(prompt['workflow'], 'application/json', filename='workflow.json')['content_uri']
|
||||
|
||||
text_content = ""
|
||||
if title:
|
||||
text_content += f"{title}\n"
|
||||
if description:
|
||||
text_content += f"{description}\n"
|
||||
if credits:
|
||||
text_content += f"\ncredits: {credits}\n"
|
||||
response = matrix.send_message(comfyui_share_room_id, text_content)
|
||||
response = matrix.send_content(comfyui_share_room_id, mxc_url, filename, 'm.image')
|
||||
response = matrix.send_content(comfyui_share_room_id, workflow_json_mxc_url, 'workflow.json', 'm.file')
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return web.json_response({"error": "An error occurred when sharing your art to Matrix."}, content_type='application/json', status=500)
|
||||
|
||||
return web.json_response({
|
||||
"comfyworkflows": {
|
||||
"url": None if "comfyworkflows" not in share_destinations else f"{share_website_host}/workflows/{workflowId}",
|
||||
},
|
||||
"matrix": {
|
||||
"success": None if "matrix" not in share_destinations else True
|
||||
}
|
||||
}, content_type='application/json', status=200)
|
||||
@@ -4,7 +4,7 @@ import { sleep } from "./common.js";
|
||||
|
||||
async function tryInstallCustomNode(event) {
|
||||
let msg = '-= [ComfyUI Manager] extension installation request =-\n\n';
|
||||
msg += `The '${event.detail.sender}' extension requires the installation of the '${event.detail.title}' extension. `;
|
||||
msg += `The '${event.detail.sender}' extension requires the installation of the '${event.detail.target.title}' extension. `;
|
||||
|
||||
if(event.detail.target.installed == 'Disabled') {
|
||||
msg += 'However, the extension is currently disabled. Would you like to enable it and reboot?'
|
||||
|
||||
187
model-list.json
187
model-list.json
@@ -1,9 +1,31 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"name": "TAEF1 Decoder",
|
||||
"type": "TAESD",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(FLUX.1 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
"filename": "taef1_decoder.pth",
|
||||
"url": "https://github.com/madebyollin/taesd/raw/main/taef1_decoder.pth",
|
||||
"size": "4.71MB"
|
||||
},
|
||||
{
|
||||
"name": "TAEF1 Encoder",
|
||||
"type": "TAESD",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(FLUX.1 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
"filename": "taef1_encoder.pth",
|
||||
"url": "https://github.com/madebyollin/taesd/raw/main/taef1_encoder.pth",
|
||||
"size": "4.71MB"
|
||||
},
|
||||
{
|
||||
"name": "TAESD3 Decoder",
|
||||
"type": "TAESD",
|
||||
"base": "SDXL",
|
||||
"base": "SD3",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(SD3 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
@@ -14,7 +36,7 @@
|
||||
{
|
||||
"name": "TAESD3 Encoder",
|
||||
"type": "TAESD",
|
||||
"base": "SDXL",
|
||||
"base": "SD3",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(SD3 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
@@ -178,7 +200,7 @@
|
||||
},
|
||||
{
|
||||
"name": "stabilityai/stable-diffusion-x4-upscaler",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "upscale",
|
||||
"save_path": "checkpoints/upscale",
|
||||
"description": "This upscaling model is a latent text-guided diffusion model and should be used with SD_4XUpscale_Conditioning and KSampler.",
|
||||
@@ -255,7 +277,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Stable Video Diffusion Image-to-Video",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SVD",
|
||||
"save_path": "checkpoints/SVD",
|
||||
"description": "Stable Video Diffusion (SVD) Image-to-Video is a diffusion model that takes in a still image as a conditioning frame, and generates a video from it.\nNOTE: 14 frames @ 576x1024",
|
||||
@@ -277,7 +299,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Stable Video Diffusion Image-to-Video (XT)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SVD",
|
||||
"save_path": "checkpoints/SVD",
|
||||
"description": "Stable Video Diffusion (SVD) Image-to-Video is a diffusion model that takes in a still image as a conditioning frame, and generates a video from it.\nNOTE: 25 frames @ 576x1024 ",
|
||||
@@ -332,7 +354,7 @@
|
||||
},
|
||||
{
|
||||
"name": "stabilityai/comfyui_checkpoints/stable_cascade_stage_b.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "Stable Cascade",
|
||||
"save_path": "checkpoints/Stable-Cascade",
|
||||
"description": "Stable Cascade stage_b checkpoints",
|
||||
@@ -343,7 +365,7 @@
|
||||
},
|
||||
{
|
||||
"name": "stabilityai/comfyui_checkpoints/stable_cascade_stage_c.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "Stable Cascade",
|
||||
"save_path": "checkpoints/Stable-Cascade",
|
||||
"description": "Stable Cascade stage_c checkpoints",
|
||||
@@ -475,7 +497,7 @@
|
||||
},
|
||||
{
|
||||
"name": "SDXL-Turbo 1.0 (fp16)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "checkpoints/SDXL-TURBO",
|
||||
"description": "SDXL-Turbo 1.0 fp16",
|
||||
@@ -486,7 +508,7 @@
|
||||
},
|
||||
{
|
||||
"name": "SDXL-Turbo 1.0",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "checkpoints/SDXL-TURBO",
|
||||
"description": "SDXL-Turbo 1.0",
|
||||
@@ -497,7 +519,7 @@
|
||||
},
|
||||
{
|
||||
"name": "sd_xl_base_1.0_0.9vae.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion XL base model (VAE 0.9)",
|
||||
@@ -508,7 +530,7 @@
|
||||
},
|
||||
{
|
||||
"name": "sd_xl_base_1.0.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion XL base model",
|
||||
@@ -519,7 +541,7 @@
|
||||
},
|
||||
{
|
||||
"name": "sd_xl_refiner_1.0_0.9vae.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion XL refiner model (VAE 0.9)",
|
||||
@@ -530,7 +552,7 @@
|
||||
},
|
||||
{
|
||||
"name": "stable-diffusion-xl-refiner-1.0",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SDXL",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion XL refiner model",
|
||||
@@ -618,9 +640,44 @@
|
||||
"size": "892MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "google-t5/t5-v1_1-xxl_encoderonly-fp16",
|
||||
"type": "clip",
|
||||
"base": "t5",
|
||||
"save_path": "clip/t5",
|
||||
"description": "The encoder part of https://huggingface.co/google/t5-v1_1-xxl, used with SD3 and Flux1",
|
||||
"reference": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly",
|
||||
"filename": "google_t5-v1_1-xxl_encoderonly-fp16.safetensors",
|
||||
"url": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly/resolve/main/pytorch_model.safetensors",
|
||||
"size": "10.1GB"
|
||||
},
|
||||
{
|
||||
"name": "google-t5/t5-v1_1-xxl_encoderonly-fp8_e4m3fn",
|
||||
"type": "clip",
|
||||
"base": "t5",
|
||||
"save_path": "clip/t5",
|
||||
"description": "The encoder part of https://huggingface.co/google/t5-v1_1-xxl, used with SD3 and Flux1",
|
||||
"reference": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly",
|
||||
"filename": "google_t5-v1_1-xxl_encoderonly-fp8_e4m3fn.safetensors",
|
||||
"url": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly/resolve/main/t5xxl_fp8_e4m3fn.safetensors",
|
||||
"size": "4.89GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "comfyanonymous/clip_l",
|
||||
"type": "clip",
|
||||
"base": "clip",
|
||||
"save_path": "default",
|
||||
"description": "clip_l model",
|
||||
"reference": "https://huggingface.co/comfyanonymous/flux_text_encoders/tree/main",
|
||||
"filename": "clip_l.safetensors",
|
||||
"url": "https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/clip_l.safetensors",
|
||||
"size": "246MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "v1-5-pruned-emaonly.ckpt",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion 1.5 base model",
|
||||
@@ -631,7 +688,7 @@
|
||||
},
|
||||
{
|
||||
"name": "v2-1_512-ema-pruned.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD2",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion 2 base model (512)",
|
||||
@@ -642,7 +699,7 @@
|
||||
},
|
||||
{
|
||||
"name": "v2-1_768-ema-pruned.safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD2",
|
||||
"save_path": "default",
|
||||
"description": "Stable Diffusion 2 base model (768)",
|
||||
@@ -653,7 +710,7 @@
|
||||
},
|
||||
{
|
||||
"name": "AbyssOrangeMix2 (hard)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "AbyssOrangeMix2 - hard version (anime style)",
|
||||
@@ -664,7 +721,7 @@
|
||||
},
|
||||
{
|
||||
"name": "AbyssOrangeMix3 A1",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "AbyssOrangeMix3 - A1 (anime style)",
|
||||
@@ -675,7 +732,7 @@
|
||||
},
|
||||
{
|
||||
"name": "AbyssOrangeMix3 A3",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD1.5",
|
||||
"save_path": "default",
|
||||
"description": "AbyssOrangeMix - A3 (anime style)",
|
||||
@@ -686,7 +743,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Waifu Diffusion 1.5 Beta3 (fp16)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SD2.1",
|
||||
"save_path": "default",
|
||||
"description": "Waifu Diffusion 1.5 Beta3",
|
||||
@@ -807,7 +864,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Segmind-Vega",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "segmind-vega",
|
||||
"save_path": "checkpoints/segmind-vega",
|
||||
"description": "The Segmind-Vega Model is a distilled version of the Stable Diffusion XL (SDXL), offering a remarkable 70% reduction in size and an impressive 100% speedup while retaining high-quality text-to-image generation capabilities.",
|
||||
@@ -1962,7 +2019,7 @@
|
||||
},
|
||||
{
|
||||
"name": "TencentARC/motionctrl.pth",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "MotionCtrl",
|
||||
"save_path": "checkpoints/motionctrl",
|
||||
"description": "To use the ComfyUI-MotionCtrl extension, downloading this model is required.",
|
||||
@@ -2644,7 +2701,7 @@
|
||||
},
|
||||
{
|
||||
"name": "DynamiCrafter 1024 bf16 safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "DynamiCrafter",
|
||||
"save_path": "checkpoints/dynamicrafter",
|
||||
"description": "DynamiCrafter image2video model 1024x575",
|
||||
@@ -2655,7 +2712,7 @@
|
||||
},
|
||||
{
|
||||
"name": "DynamiCrafter 512 interpolation bf16 safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "DynamiCrafter",
|
||||
"save_path": "checkpoints/dynamicrafter",
|
||||
"description": "DynamiCrafter image2video interpolation model 512",
|
||||
@@ -2677,7 +2734,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Depth-FM-v1 fp16 safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "Depth-FM",
|
||||
"save_path": "checkpoints/depthfm",
|
||||
"description": "Depth-FM monocular depth estimation model",
|
||||
@@ -2688,7 +2745,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Depth-FM-v1 fp32 safetensors",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "Depth-FM",
|
||||
"save_path": "checkpoints/depthfm",
|
||||
"description": "Depth-FM monocular depth estimation model",
|
||||
@@ -2699,7 +2756,7 @@
|
||||
},
|
||||
{
|
||||
"name": "SUPIR-v0F.ckpt",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SUPIR",
|
||||
"save_path": "checkpoints/SUPIR",
|
||||
"description": "SUPIR checkpoint model",
|
||||
@@ -2710,7 +2767,7 @@
|
||||
},
|
||||
{
|
||||
"name": "SUPIR-v0Q.ckpt",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SUPIR",
|
||||
"save_path": "checkpoints/SUPIR",
|
||||
"description": "SUPIR checkpoint model",
|
||||
@@ -2721,7 +2778,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Kijai/SUPIR-v0F_fp16.safetensors (pruned)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SUPIR",
|
||||
"save_path": "checkpoints/SUPIR",
|
||||
"description": "SUPIR checkpoint model",
|
||||
@@ -2732,7 +2789,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Kijai/SUPIR-v0Q_fp16.safetensors (pruned)",
|
||||
"type": "checkpoints",
|
||||
"type": "checkpoint",
|
||||
"base": "SUPIR",
|
||||
"save_path": "checkpoints/SUPIR",
|
||||
"description": "SUPIR checkpoint model",
|
||||
@@ -3393,6 +3450,76 @@
|
||||
"filename": "hunyuan_dit_1.0.safetensors",
|
||||
"url": "https://huggingface.co/comfyanonymous/hunyuan_dit_comfyui/resolve/main/hunyuan_dit_1.0.safetensors",
|
||||
"size": "8.24GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "FLUX.1 [schnell] Diffusion model",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] Diffusion model (a.k.a. FLUX.1 turbo model)[w/Due to the large size of the model, it is recommended to download it through a browser if possible.]",
|
||||
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||
"filename": "flux1-schnell.sft",
|
||||
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/flux1-schnell.sft",
|
||||
"size": "23.8GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "FLUX.1 VAE model",
|
||||
"type": "vae",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] VAE model",
|
||||
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||
"filename": "ae.sft",
|
||||
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/ae.safetensors",
|
||||
"size": "335MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "kijai/FLUX.1 [schnell] Diffusion model (float8_e4m3fn)",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] Diffusion model (float8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Kijai/flux-fp8",
|
||||
"filename": "flux1-schnell-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/flux-fp8/resolve/main/flux1-schnell-fp8.safetensors",
|
||||
"size": "11.9GB"
|
||||
},
|
||||
{
|
||||
"name": "kijai/FLUX.1 [dev] Diffusion model (float8_e4m3fn)",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [dev] Diffusion model (float8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Kijai/flux-fp8",
|
||||
"filename": "flux1-dev-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/flux-fp8/resolve/main/flux1-dev-fp8.safetensors",
|
||||
"size": "11.9GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Comfy Org/FLUX.1 [dev] Checkpoint model (fp8)",
|
||||
"type": "checkpoint",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "checkpoints/FLUX1",
|
||||
"description": "FLUX.1 [dev] Checkpoint model (fp8)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/flux1-dev/tree/main",
|
||||
"filename": "flux1-dev-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/flux1-dev/resolve/main/flux1-dev-fp8.safetensors",
|
||||
"size": "17.2GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy Org/FLUX.1 [schnell] Checkpoint model (fp8)",
|
||||
"type": "checkpoint",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "checkpoints/FLUX1",
|
||||
"description": "FLUX.1 [schnell] Checkpoint model (fp8)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/flux1-dev/tree/main",
|
||||
"filename": "flux1-schnell-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/flux1-schnell/resolve/main/flux1-schnell-fp8.safetensors",
|
||||
"size": "17.2GB"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -11,7 +11,177 @@
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
"author": "sebord",
|
||||
"title": "ComfyUI-LMCQ [WIP]",
|
||||
"reference": "https://github.com/sebord/ComfyUI-LMCQ",
|
||||
"files": [
|
||||
"https://github.com/sebord/ComfyUI-LMCQ"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI small node toolkit, this toolkit is mainly to update some practical small nodes, to make a contribution to the comfyui ecosystem, PS: 'LMCQ' is the abbreviation of the team name"
|
||||
},
|
||||
{
|
||||
"author": "logtd",
|
||||
"title": "ComfyUI-Fluxtapoz [WIP]",
|
||||
"reference": "https://github.com/logtd/ComfyUI-Fluxtapoz",
|
||||
"files": [
|
||||
"https://github.com/logtd/ComfyUI-Fluxtapoz"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A set of nodes for editing images using Flux in ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "ChrisColeTech",
|
||||
"title": "ComfyUI-Get-Random-File [UNSAFE]",
|
||||
"reference": "https://github.com/ChrisColeTech/ComfyUI-Get-Random-File",
|
||||
"files": [
|
||||
"https://github.com/ChrisColeTech/ComfyUI-Get-Random-File"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Gets a random file from a directory. Returns the filpath as a STRING. [w/This node allows access to arbitrary files through the workflow, which could pose a security threat.]"
|
||||
},
|
||||
{
|
||||
"author": "logtd",
|
||||
"title": "ComfyUI-Fluxtapoz [WIP]",
|
||||
"reference": "https://github.com/logtd/ComfyUI-Fluxtapoz",
|
||||
"files": [
|
||||
"https://github.com/logtd/ComfyUI-Fluxtapoz"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A set of nodes for editing images using Flux in ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "neeltheninja",
|
||||
"title": "ComfyUI-ControlNeXt [WIP]",
|
||||
"reference": "https://github.com/neverbiasu/ComfyUI-ControlNeXt",
|
||||
"files": [
|
||||
"https://github.com/neverbiasu/ComfyUI-ControlNeXt"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "In progress🚧"
|
||||
},
|
||||
{
|
||||
"author": "neeltheninja",
|
||||
"title": "ComfyUI-TextOverlay",
|
||||
"reference": "https://github.com/neeltheninja/ComfyUI-TextOverlay",
|
||||
"files": [
|
||||
"https://github.com/neeltheninja/ComfyUI-TextOverlay"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A custom node for ComfyUI that adds text overlay to images, with options for text and background color, opacity, vertical positioning, and custom font selection. [w/Name conflict with munkyfoot/ComfyUI-TextOverlay. Cannot install simulatenously.]"
|
||||
},
|
||||
{
|
||||
"author": "comfyanonymous",
|
||||
"title": "ComfyUI_bitsandbytes_NF4 [EXPERIMENTAL]",
|
||||
"reference": "https://github.com/comfyanonymous/ComfyUI_bitsandbytes_NF4",
|
||||
"files": [
|
||||
"https://github.com/comfyanonymous/ComfyUI_bitsandbytes_NF4"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A quickly written custom node that uses code from Forge to support the nf4 flux dev checkpoint and nf4 flux schnell checkpoint.\nRequires installing bitsandbytes.\nMake sure your ComfyUI is updated.\nThe node is: CheckpointLoaderNF4, just plug it in your flux workflow instead of the regular one.[w/NF4 checckpoint doesn't support LoRA.]"
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI-EasyAnimateWrapper [WIP]",
|
||||
"reference": "https://github.com/kijai/ComfyUI-EasyAnimateWrapper",
|
||||
"files": [
|
||||
"https://github.com/kijai/ComfyUI-EasyAnimateWrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "EasyAnimateWrapper for ComfyUI"
|
||||
},
|
||||
{
|
||||
"author": "logtd",
|
||||
"title": "ComfyUI-Veevee [WIP]",
|
||||
"reference": "https://github.com/logtd/ComfyUI-Veevee",
|
||||
"files": [
|
||||
"https://github.com/logtd/ComfyUI-Veevee"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "A Video2Video framework for text2image models in ComfyUI. Supports SD1.5 and SDXL."
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI-LLaVA-OneVision [WIP]",
|
||||
"reference": "https://github.com/kijai/ComfyUI-LLaVA-OneVision",
|
||||
"files": [
|
||||
"https://github.com/kijai/ComfyUI-LLaVA-OneVision"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Original repo: [a/https://github.com/LLaVA-VL/LLaVA-NeXT](https://github.com/LLaVA-VL/LLaVA-NeXT)\nUnsure of the dependencies, the original was a huge list, but I didn't install single new one to my environment and it worked."
|
||||
},
|
||||
{
|
||||
"author": "TTPlanetPig",
|
||||
"title": "for comfyui image proprocessor",
|
||||
"reference": "https://github.com/TTPlanetPig/Comfyui_TTP_CN_Preprocessor",
|
||||
"files": [
|
||||
"https://github.com/TTPlanetPig/Comfyui_TTP_CN_Preprocessor"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Adapt for Hunyuan now"
|
||||
},
|
||||
{
|
||||
"author": "IuvenisSapiens",
|
||||
"title": "ComfyUI_MiniCPM-V-2_6-int4",
|
||||
"id": "minicpm-v-2_6-int4",
|
||||
"reference": "https://github.com/IuvenisSapiens/ComfyUI_MiniCPM-V-2_6-int4",
|
||||
"files": [
|
||||
"https://github.com/IuvenisSapiens/ComfyUI_MiniCPM-V-2_6-int4"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is an implementation of [a/MiniCPM-V-2_6-int4](https://github.com/OpenBMB/MiniCPM-V) by [a/ComfyUI](https://github.com/comfyanonymous/ComfyUI), including support for text-based queries, video queries, single-image queries, and multi-image queries to generate captions or responses."
|
||||
},
|
||||
{
|
||||
"author": "chrisdreid",
|
||||
"title": "ComfyUI_EnvAutopsyAPI [UNSAFE]",
|
||||
"reference": "https://github.com/chrisdreid/ComfyUI_EnvAutopsyAPI",
|
||||
"files": [
|
||||
"https://github.com/chrisdreid/ComfyUI_EnvAutopsyAPI"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "ComfyUI_EnvAutopsyAPI is a powerful debugging tool designed for ComfyUI that provides in-depth analysis of your environment and dependencies through an API interface. This tool allows you to inspect environment variables, pip packages, and dependency trees, making it easier to diagnose and resolve issues in your ComfyUI setup.[w/This tool may expose sensitive system information if used on a public server. MUST READ [a/THIS](https://github.com/chrisdreid/ComfyUI_EnvAutopsyAPI#%EF%B8%8F-warning-security-risk-%EF%B8%8F) before install.]"
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI-CogVideoXWrapper [WIP]",
|
||||
"reference": "https://github.com/kijai/ComfyUI-CogVideoXWrapper",
|
||||
"files": [
|
||||
"https://github.com/kijai/ComfyUI-CogVideoXWrapper"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Original repo: [a/https://github.com/THUDM/CogVideo](https://github.com/THUDM/CogVideo)\nNOTE:Currently requires diffusers with PR: [a/huggingface/diffusers#9082](https://github.com/huggingface/diffusers/pull/9082)"
|
||||
},
|
||||
{
|
||||
"author": "neuratech-ai",
|
||||
"title": "ComfyUI-MultiGPU",
|
||||
"reference": "https://github.com/neuratech-ai/ComfyUI-MultiGPU",
|
||||
"files": [
|
||||
"https://github.com/neuratech-ai/ComfyUI-MultiGPU"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Experimental nodes for using multiple GPUs in a single ComfyUI workflow.\nThis extension adds new nodes for model loading that allow you to specify the GPU to use for each model. It monkey patches the memory management of ComfyUI in a hacky way and is neither a comprehensive solution nor a well-tested one. Use at your own risk.\nNote that this does not add parallelism. The workflow steps are still executed sequentially just on different GPUs. Any potential speedup comes from not having to constantly load and unload models from VRAM."
|
||||
},
|
||||
{
|
||||
"author": "Isi-dev",
|
||||
"title": "Isi-dev/ComfyUI-UniAnimate",
|
||||
"reference": "https://github.com/Isi-dev/ComfyUI-UniAnimate",
|
||||
"files": [
|
||||
"https://github.com/Isi-dev/ComfyUI-UniAnimate"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This is my ComfyUi-windows implementation for the image animation project ▶ UniAnimate: Taming Unified Video Diffusion Models for Consistent Human Image Animation[w/This node cannot be installed simultaneously with ComfyUI-UniAnimate by AIFSH because it has the same name as that custom node.]"
|
||||
},
|
||||
{
|
||||
"author": "Futureversecom",
|
||||
"title": "ComfyUI-JEN",
|
||||
"reference": "https://github.com/futureversecom/ComfyUI-JEN",
|
||||
"files": [
|
||||
"https://github.com/futureversecom/ComfyUI-JEN"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Comfy UI custom nodes for JEN music generation powered by Futureverse"
|
||||
},
|
||||
{
|
||||
"author": "denislov",
|
||||
"title": "Comfyui_AutoSurvey",
|
||||
@@ -32,16 +202,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This node allows ComfyUI to easily integrate with Midjourney, utilizing the ultra-high quality of Midjourney and the powerful control of SD to provide more convenient capabilities for AIGC.\nNOTE: This node relies on the midjourney proxy project and requires API deployment in advance. For detailed installation, please refer to the instructions of the project. https://github.com/novicezk/midjourney-proxy"
|
||||
},
|
||||
{
|
||||
"author": "hy134300",
|
||||
"title": "ComfyUI-PhotoMaker-V2",
|
||||
"reference": "https://github.com/hy134300/ComfyUI-PhotoMaker-V2",
|
||||
"files": [
|
||||
"https://github.com/hy134300/ComfyUI-PhotoMaker-V2"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes for PhotoMaker-V2"
|
||||
},
|
||||
{
|
||||
"author": "kijai",
|
||||
"title": "ComfyUI-FollowYourEmojiWrapper [WIP]",
|
||||
@@ -248,16 +408,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "If you wish to incorporate these changes into your repo, feel free to open an issue and ask. The commits should be pretty clear, and I also label almost all changes with #HACK so a full text search will work too.\nPlease let me know if you decide to incorporate any of these changes into your LivePortrait implementation so I can direct people to you repository. I do not intend to maintain this repo.\nSome operations are simply not supported on MPS and I didn't rewrite them. Most of my changes are just to .cuda calls and that sort of thing. Many operations are still done on CPU, so don't expect awesome performance."
|
||||
},
|
||||
{
|
||||
"author": "justUmen",
|
||||
"title": "Bjornulf_custom_nodes [WIP]",
|
||||
"reference": "https://github.com/justUmen/Bjornulf_custom_nodes",
|
||||
"files": [
|
||||
"https://github.com/justUmen/Bjornulf_custom_nodes"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes: ollamaLoader, ShowText, ShowInt, LoopTexts, LoopFloat, LoopInteger, ..."
|
||||
},
|
||||
{
|
||||
"author": "thderoo",
|
||||
"title": "_topfun_s_nodes",
|
||||
@@ -278,16 +428,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This repository provides developers with a way to better manage their ComfyUI model memory. It includes nodes that allow developers to either unload all models or unload one model at a time. These nodes are designed as pass-through nodes, so they can be used anywhere in the flow. The nodes can be found in the 'Unload Model' section.[w/These are massive hammers, and it could be possible to break things, please don't use them if you need finesse.]"
|
||||
},
|
||||
{
|
||||
"author": "GeekyGhost",
|
||||
"title": "ComfyUI-GeekyRemB v2",
|
||||
"reference": "https://github.com/GeekyGhost/ComfyUI-GeekyRemB",
|
||||
"files": [
|
||||
"https://github.com/GeekyGhost/ComfyUI-GeekyRemB/raw/SketchUITest/GeekyRembv2.py"
|
||||
],
|
||||
"install_type": "copy",
|
||||
"description": "GeekyRemB Node Description: GeekyRemB is a powerful and versatile image processing node for ComfyUI, designed to remove backgrounds from images with advanced customization options. This node leverages the rembg library and offers a wide range of features for fine-tuning the background removal process and enhancing the resulting images."
|
||||
},
|
||||
{
|
||||
"author": "AIFSH",
|
||||
"title": "ComfyUI-OpenDIT [WIP]",
|
||||
@@ -798,16 +938,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Primary Nodes for Inference.Core and Stability Matrix. With a focus on not impacting startup performance and using fully qualified Node names. [w/This custom node is likely to conflict with many other nodes.]"
|
||||
},
|
||||
{
|
||||
"author": "blepping",
|
||||
"title": "comfyui_overly_complicated_sampling",
|
||||
"reference": "https://github.com/blepping/comfyui_overly_complicated_sampling",
|
||||
"files": [
|
||||
"https://github.com/blepping/comfyui_overly_complicated_sampling"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Very unstable, experimental and mathematically unsound sampling for ComfyUI.\nCurrent status: In flux, not suitable for general use."
|
||||
},
|
||||
{
|
||||
"author": "tracerstar",
|
||||
"title": "comfyui-p5js-node",
|
||||
@@ -1631,16 +1761,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "This answers the itch for being able to easily paste [a/CivitAI.com](https://civitai.com/) generated data (or other simple metadata) into Comfy in a way that makes it easy to test with multiple checkpoints."
|
||||
},
|
||||
{
|
||||
"author": "ZHO-ZHO-ZHO",
|
||||
"title": "ComfyUI-AnyText [WIP]",
|
||||
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText",
|
||||
"files": [
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Unofficial implementation of [a/AnyText](https://github.com/tyxsspa/AnyText/tree/825bcc54687206b15bd7e28ba1a8b095989d58e3) for ComfyUI(EXP)"
|
||||
},
|
||||
{
|
||||
"author": "nidefawl",
|
||||
"title": "ComfyUI-nidefawl [UNSAFE]",
|
||||
@@ -1791,16 +1911,6 @@
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes: CheckpointVAELoaderSimpleText, CheckpointVAESelectorText, LoRA_Tag_To_Stack"
|
||||
},
|
||||
{
|
||||
"author": "dnl13",
|
||||
"title": "ComfyUI-dnl13-seg",
|
||||
"reference": "https://github.com/dnl13/ComfyUI-dnl13-seg",
|
||||
"files": [
|
||||
"https://github.com/dnl13/ComfyUI-dnl13-seg"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "After discovering @storyicon implementation here of Segment Anything, I realized its potential as a powerful tool for ComfyUI if implemented correctly. I delved into the SAM and Dino models. The following is my own adaptation of sam_hq for ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "Brandelan",
|
||||
"title": "ComfyUI_bd_customNodes",
|
||||
|
||||
@@ -277,7 +277,6 @@
|
||||
"IntConditions",
|
||||
"IntMathOperation",
|
||||
"InversionDemoAdvancedPromptNode",
|
||||
"InversionDemoFakeAdvancedPromptNode",
|
||||
"InversionDemoLazyConditional",
|
||||
"InversionDemoLazyIndexSwitch",
|
||||
"InversionDemoLazyMixImages",
|
||||
@@ -352,6 +351,18 @@
|
||||
"title_aux": "ComfyUI_bd_customNodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/ChrisColeTech/ComfyUI-Get-Random-File": [
|
||||
[
|
||||
"GetImageFileByIndexNode",
|
||||
"GetVideoFileByIndexNode",
|
||||
"RandomFilePathNode",
|
||||
"RandomImagePathNode",
|
||||
"RandomVideoPathNode"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Get-Random-File [UNSAFE]"
|
||||
}
|
||||
],
|
||||
"https://github.com/DeTK/ComfyUI-Switch": [
|
||||
[
|
||||
"NodeSwitch"
|
||||
@@ -410,14 +421,6 @@
|
||||
"title_aux": "ComfyUI-Airtable [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/GeekyGhost/ComfyUI-GeekyRemB/raw/SketchUITest/GeekyRembv2.py": [
|
||||
[
|
||||
"GeekyRemB"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-GeekyRemB v2"
|
||||
}
|
||||
],
|
||||
"https://github.com/GentlemanHu/ComfyUI-Notifier": [
|
||||
[
|
||||
"GentlemanHu_Notifier"
|
||||
@@ -478,6 +481,28 @@
|
||||
"title_aux": "GH Tools for ComfyUI"
|
||||
}
|
||||
],
|
||||
"https://github.com/Isi-dev/ComfyUI-UniAnimate": [
|
||||
[
|
||||
"Gen_align_pose",
|
||||
"UniAnimateImage"
|
||||
],
|
||||
{
|
||||
"title_aux": "Isi-dev/ComfyUI-UniAnimate"
|
||||
}
|
||||
],
|
||||
"https://github.com/IuvenisSapiens/ComfyUI_MiniCPM-V-2_6-int4": [
|
||||
[
|
||||
"DisplayText",
|
||||
"LoadVideo",
|
||||
"MiniCPM_VQA",
|
||||
"MiniCPM_VQA_Polished",
|
||||
"MultipleImagesInput",
|
||||
"PreViewVideo"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_MiniCPM-V-2_6-int4"
|
||||
}
|
||||
],
|
||||
"https://github.com/IvanZhd/comfyui-codeformer": [
|
||||
[
|
||||
"RedBeanie_CustomImageInverter"
|
||||
@@ -498,9 +523,13 @@
|
||||
[
|
||||
"AppendNode",
|
||||
"ApplyVoiceConversion",
|
||||
"ImAppendQuickbackNode",
|
||||
"ImAppendQuickbackVideoNode",
|
||||
"ImAppendVideoNode",
|
||||
"ImApplyWav2lip",
|
||||
"ImDumpEntity",
|
||||
"ImDumpNode",
|
||||
"ImNodeTitleOverride",
|
||||
"LoadPackage",
|
||||
"MergeNode",
|
||||
"NewNode",
|
||||
@@ -510,6 +539,7 @@
|
||||
"SetNodeMapping",
|
||||
"SetProperties",
|
||||
"batchNodes",
|
||||
"mergeEntityAndPointer",
|
||||
"redirectToNode"
|
||||
],
|
||||
{
|
||||
@@ -532,16 +562,6 @@
|
||||
"title_aux": "comfy-consistency-vae"
|
||||
}
|
||||
],
|
||||
"https://github.com/JosefKuchar/ComfyUI-AdvancedTiling": [
|
||||
[
|
||||
"AdvancedTiling",
|
||||
"AdvancedTilingSettings",
|
||||
"AdvancedTilingVAEDecode"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-AdvancedTiling [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/LZpenguin/ComfyUI-Text": [
|
||||
[
|
||||
"Add_text_by_mask"
|
||||
@@ -662,14 +682,6 @@
|
||||
"title_aux": "CheckProgress [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/MushroomFleet/DJZ-Nodes": [
|
||||
[
|
||||
"AspectSize"
|
||||
],
|
||||
{
|
||||
"title_aux": "DJZ-Nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/NeuralNotW0rk/ComfyUI-Waveform-Extensions/raw/main/EXT_VariationUtils.py": [
|
||||
[
|
||||
"BatchToList",
|
||||
@@ -694,13 +706,20 @@
|
||||
[
|
||||
"CPPN Generator",
|
||||
"Color Match",
|
||||
"Coordinates From Mask",
|
||||
"Custom Shader",
|
||||
"Distance Map",
|
||||
"Folder Queue Manager",
|
||||
"Image Blend by Mask (Batch)",
|
||||
"Image Noise Generator",
|
||||
"Image to Optical Flow",
|
||||
"Perlin Noise Generator",
|
||||
"Preview Mask",
|
||||
"Random Image Generator",
|
||||
"Shift Mask",
|
||||
"Slit Scan",
|
||||
"Spring Mesh",
|
||||
"Temporal Blur",
|
||||
"Video Queue Manager"
|
||||
],
|
||||
{
|
||||
@@ -815,6 +834,17 @@
|
||||
"title_aux": "ComfyUI-TSFNodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/TTPlanetPig/Comfyui_TTP_CN_Preprocessor": [
|
||||
[
|
||||
"TTPlanet_Tile_Preprocessor_GF",
|
||||
"TTPlanet_Tile_Preprocessor_Simple",
|
||||
"TTPlanet_Tile_Preprocessor_cufoff",
|
||||
"TTPlanet_inpainting_Preprecessor"
|
||||
],
|
||||
{
|
||||
"title_aux": "for comfyui image proprocessor"
|
||||
}
|
||||
],
|
||||
"https://github.com/Video3DGenResearch/comfyui-batch-input-node": [
|
||||
[
|
||||
"BatchImageAndPrompt",
|
||||
@@ -859,14 +889,6 @@
|
||||
"title_aux": "visuallabs_comfyui_nodes"
|
||||
}
|
||||
],
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText": [
|
||||
[
|
||||
"AnyTextNode_Zho"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-AnyText [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AuraSR-ZHO": [
|
||||
[
|
||||
"AuraSR_Lterative_Zho",
|
||||
@@ -1009,15 +1031,6 @@
|
||||
"title_aux": "Gen Data Tester [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/blepping/comfyui_overly_complicated_sampling": [
|
||||
[
|
||||
"ComposableSampler",
|
||||
"ComposableStepSampler"
|
||||
],
|
||||
{
|
||||
"title_aux": "comfyui_overly_complicated_sampling"
|
||||
}
|
||||
],
|
||||
"https://github.com/bruce007lee/comfyui-cleaner": [
|
||||
[
|
||||
"cleaner"
|
||||
@@ -1113,6 +1126,8 @@
|
||||
"CLIPSetLastLayer",
|
||||
"CLIPTextEncode",
|
||||
"CLIPTextEncodeControlnet",
|
||||
"CLIPTextEncodeFlux",
|
||||
"CLIPTextEncodeHunyuanDiT",
|
||||
"CLIPTextEncodeSD3",
|
||||
"CLIPTextEncodeSDXL",
|
||||
"CLIPTextEncodeSDXLRefiner",
|
||||
@@ -1149,6 +1164,7 @@
|
||||
"ExponentialScheduler",
|
||||
"FeatherMask",
|
||||
"FlipSigmas",
|
||||
"FluxGuidance",
|
||||
"FreeU",
|
||||
"FreeU_V2",
|
||||
"GITSScheduler",
|
||||
@@ -1208,6 +1224,7 @@
|
||||
"MaskToImage",
|
||||
"ModelMergeAdd",
|
||||
"ModelMergeBlocks",
|
||||
"ModelMergeFlux1",
|
||||
"ModelMergeSD1",
|
||||
"ModelMergeSD2",
|
||||
"ModelMergeSD3_2B",
|
||||
@@ -1218,6 +1235,7 @@
|
||||
"ModelSamplingContinuousEDM",
|
||||
"ModelSamplingContinuousV",
|
||||
"ModelSamplingDiscrete",
|
||||
"ModelSamplingFlux",
|
||||
"ModelSamplingSD3",
|
||||
"ModelSamplingStableCascade",
|
||||
"Morphology",
|
||||
@@ -1245,6 +1263,7 @@
|
||||
"SamplerCustomAdvanced",
|
||||
"SamplerDPMAdaptative",
|
||||
"SamplerDPMPP_2M_SDE",
|
||||
"SamplerDPMPP_2S_Ancestral",
|
||||
"SamplerDPMPP_3M_SDE",
|
||||
"SamplerDPMPP_SDE",
|
||||
"SamplerEulerAncestral",
|
||||
@@ -1271,8 +1290,42 @@
|
||||
"StableCascade_SuperResolutionControlnet",
|
||||
"StableZero123_Conditioning",
|
||||
"StableZero123_Conditioning_Batched",
|
||||
"StubFloat",
|
||||
"StubImage",
|
||||
"StubInt",
|
||||
"StubMask",
|
||||
"StyleModelApply",
|
||||
"StyleModelLoader",
|
||||
"TestAccumulateNode",
|
||||
"TestAccumulationGetItemNode",
|
||||
"TestAccumulationGetLengthNode",
|
||||
"TestAccumulationHeadNode",
|
||||
"TestAccumulationSetItemNode",
|
||||
"TestAccumulationTailNode",
|
||||
"TestAccumulationToListNode",
|
||||
"TestBoolOperationNode",
|
||||
"TestCustomIsChanged",
|
||||
"TestCustomValidation1",
|
||||
"TestCustomValidation2",
|
||||
"TestCustomValidation3",
|
||||
"TestCustomValidation4",
|
||||
"TestCustomValidation5",
|
||||
"TestDynamicDependencyCycle",
|
||||
"TestExecutionBlocker",
|
||||
"TestFloatConditions",
|
||||
"TestForLoopClose",
|
||||
"TestForLoopOpen",
|
||||
"TestIntConditions",
|
||||
"TestIntMathOperation",
|
||||
"TestLazyMixImages",
|
||||
"TestListToAccumulationNode",
|
||||
"TestMakeListNode",
|
||||
"TestMixedExpansionReturns",
|
||||
"TestStringConditions",
|
||||
"TestToBoolNode",
|
||||
"TestVariadicAverage",
|
||||
"TestWhileLoopClose",
|
||||
"TestWhileLoopOpen",
|
||||
"ThresholdMask",
|
||||
"TomePatchModel",
|
||||
"TripleCLIPLoader",
|
||||
@@ -1301,6 +1354,14 @@
|
||||
"title_aux": "ComfyUI"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfyanonymous/ComfyUI_bitsandbytes_NF4": [
|
||||
[
|
||||
"CheckpointLoaderNF4"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI_bitsandbytes_NF4 [EXPERIMENTAL]"
|
||||
}
|
||||
],
|
||||
"https://github.com/comfypod/ComfyUI-Comflow": [
|
||||
[
|
||||
"ComflowInputBoolean",
|
||||
@@ -1335,6 +1396,26 @@
|
||||
"title_aux": "ComfyUI-Better-Dimensions"
|
||||
}
|
||||
],
|
||||
"https://github.com/denislov/Comfyui_AutoSurvey": [
|
||||
[
|
||||
"AddDoc2Knowledge",
|
||||
"AutoSurvey",
|
||||
"ChatModel",
|
||||
"ComfyMilvus",
|
||||
"ComfyWeaviate",
|
||||
"ManageDatabase",
|
||||
"MilvusScheme",
|
||||
"MsField",
|
||||
"QueryKnowledge",
|
||||
"WcProperty",
|
||||
"WcPropertyComb",
|
||||
"WriteOutline",
|
||||
"WriteSection"
|
||||
],
|
||||
{
|
||||
"title_aux": "Comfyui_AutoSurvey"
|
||||
}
|
||||
],
|
||||
"https://github.com/dfl/comfyui-stylegan": [
|
||||
[
|
||||
"StyleGAN Generator",
|
||||
@@ -1344,20 +1425,6 @@
|
||||
"title_aux": "comfyui-stylegan"
|
||||
}
|
||||
],
|
||||
"https://github.com/dnl13/ComfyUI-dnl13-seg": [
|
||||
[
|
||||
"Automatic Segmentation (dnl13)",
|
||||
"BatchSelector (dnl13)",
|
||||
"Combine Images By Mask (dnl13)",
|
||||
"Dinov1 Model Loader (dnl13)",
|
||||
"Mask with prompt (dnl13)",
|
||||
"RGB (dnl13)",
|
||||
"SAM Model Loader (dnl13)"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-dnl13-seg"
|
||||
}
|
||||
],
|
||||
"https://github.com/doucx/ComfyUI_WcpD_Utility_Kit": [
|
||||
[
|
||||
"BlackImage",
|
||||
@@ -1604,22 +1671,6 @@
|
||||
"title_aux": "ComfyUI_Easy_Nodes_hui"
|
||||
}
|
||||
],
|
||||
"https://github.com/hy134300/ComfyUI-PhotoMaker-V2": [
|
||||
[
|
||||
"BaseModel_Loader_fromhub",
|
||||
"BaseModel_Loader_local",
|
||||
"LoRALoader",
|
||||
"NEW_PhotoMaker_Generation",
|
||||
"PhotoMakerAdapter_Loader_fromhub",
|
||||
"PhotoMakerAdapter_Loader_local",
|
||||
"PhotoMaker_Generation",
|
||||
"Prompt_Styler",
|
||||
"Ref_Image_Preprocessing"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-PhotoMaker-V2"
|
||||
}
|
||||
],
|
||||
"https://github.com/hy134300/comfyui-hb-node": [
|
||||
[
|
||||
"generate story",
|
||||
@@ -1681,7 +1732,12 @@
|
||||
"https://github.com/jh-leon-kim/ComfyUI-JHK-utils": [
|
||||
[
|
||||
"JHK_Utils_ImageRemoveBackground",
|
||||
"JHK_Utils_LargestImageSelector",
|
||||
"JHK_Utils_LoadEmbed",
|
||||
"JHK_Utils_LoadImageFromPath",
|
||||
"JHK_Utils_RandomImageSelector",
|
||||
"JHK_Utils_SelectSingleImageFromPath",
|
||||
"JHK_Utils_string_filter",
|
||||
"JHK_Utils_string_merge"
|
||||
],
|
||||
{
|
||||
@@ -1803,41 +1859,6 @@
|
||||
"title_aux": "ComfyUI-Unique3D [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/justUmen/Bjornulf_custom_nodes": [
|
||||
[
|
||||
"Bjornulf_CombineTexts",
|
||||
"Bjornulf_CustomStringType",
|
||||
"Bjornulf_LoopBasicBatch",
|
||||
"Bjornulf_LoopCombosSamplersSchedulers",
|
||||
"Bjornulf_LoopFloat",
|
||||
"Bjornulf_LoopInteger",
|
||||
"Bjornulf_LoopSamplers",
|
||||
"Bjornulf_LoopSchedulers",
|
||||
"Bjornulf_LoopTexts",
|
||||
"Bjornulf_RandomModelClipVae",
|
||||
"Bjornulf_RandomTexts",
|
||||
"Bjornulf_ResizeImage",
|
||||
"Bjornulf_SaveApiImage",
|
||||
"Bjornulf_SaveImagePath",
|
||||
"Bjornulf_SaveImageToFolder",
|
||||
"Bjornulf_SaveText",
|
||||
"Bjornulf_SaveTmpImage",
|
||||
"Bjornulf_ShowFloat",
|
||||
"Bjornulf_ShowInt",
|
||||
"Bjornulf_ShowText",
|
||||
"Bjornulf_VideoPingPong",
|
||||
"Bjornulf_WriteImageAllInOne",
|
||||
"Bjornulf_WriteImageCharacter",
|
||||
"Bjornulf_WriteImageCharacters",
|
||||
"Bjornulf_WriteImageEnvironment",
|
||||
"Bjornulf_WriteText",
|
||||
"Bjornulf_imgs2vid",
|
||||
"Bjornulf_ollamaLoader"
|
||||
],
|
||||
{
|
||||
"title_aux": "Bjornulf_custom_nodes [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kadirnar/ComfyUI-Adapter": [
|
||||
[
|
||||
"GarmentSegLoader"
|
||||
@@ -1895,6 +1916,18 @@
|
||||
"title_aux": "ComfyUI-CV-VAE"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-CogVideoXWrapper": [
|
||||
[
|
||||
"CogVideoDecode",
|
||||
"CogVideoImageEncode",
|
||||
"CogVideoSampler",
|
||||
"CogVideoTextEncode",
|
||||
"DownloadAndLoadCogVideoModel"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-CogVideoXWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-DeepSeek-VL": [
|
||||
[
|
||||
"deepseek_vl_inference",
|
||||
@@ -1922,10 +1955,26 @@
|
||||
"title_aux": "ComfyUI-DiffusersSD3Wrapper"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-EasyAnimateWrapper": [
|
||||
[
|
||||
"DownloadAndLoadEasyAnimateModel",
|
||||
"EasyAnimateDecode",
|
||||
"EasyAnimateImageEncoder",
|
||||
"EasyAnimateResize",
|
||||
"EasyAnimateSampler",
|
||||
"EasyAnimateTextEncode"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-EasyAnimateWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-FollowYourEmojiWrapper": [
|
||||
[
|
||||
"DownloadAndLoadFYEModel",
|
||||
"FYECLIPEncode",
|
||||
"FYEClipEmbedToComfy",
|
||||
"FYELandmarkEncode",
|
||||
"FYELandmarkToComfy",
|
||||
"FYEMediaPipe",
|
||||
"FYESampler",
|
||||
"FYESamplerLong"
|
||||
@@ -1934,6 +1983,15 @@
|
||||
"title_aux": "ComfyUI-FollowYourEmojiWrapper [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/kijai/ComfyUI-LLaVA-OneVision": [
|
||||
[
|
||||
"DownloadAndLoadLLaVAOneVisionModel",
|
||||
"LLaVA_OneVision_Run"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-LLaVA-OneVision [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/komojini/ComfyUI_Prompt_Template_CustomNodes/raw/main/prompt_with_template.py": [
|
||||
[
|
||||
"ObjectPromptWithTemplate",
|
||||
@@ -2000,6 +2058,18 @@
|
||||
"title_aux": "ComfyUI Build and Train Your Network [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/logtd/ComfyUI-Fluxtapoz": [
|
||||
[
|
||||
"FluxDeGuidance",
|
||||
"FluxInverseSampler",
|
||||
"InFluxFlipSigmas",
|
||||
"InFluxModelSamplingPred",
|
||||
"OutFluxModelSamplingPred"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Fluxtapoz [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/logtd/ComfyUI-MotionThiefExperiment": [
|
||||
[
|
||||
"ApplyRefMotionNode",
|
||||
@@ -2010,6 +2080,24 @@
|
||||
"title_aux": "ComfyUI-MotionThiefExperiment"
|
||||
}
|
||||
],
|
||||
"https://github.com/logtd/ComfyUI-Veevee": [
|
||||
[
|
||||
"ApplyVVModel",
|
||||
"FlowConfig",
|
||||
"FlowGetFlow",
|
||||
"GetRaftFlow",
|
||||
"InjectionConfig",
|
||||
"PivotConfig",
|
||||
"RaveConfig",
|
||||
"SCAConfig",
|
||||
"TemporalConfig",
|
||||
"VVSamplerSampler",
|
||||
"VVUnsamplerSampler"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-Veevee [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/longgui0318/comfyui-one-more-step": [
|
||||
[
|
||||
"Calculate More Step Latent",
|
||||
@@ -2134,6 +2222,36 @@
|
||||
"title_aux": "ComfyUI GLIGEN GUI Node"
|
||||
}
|
||||
],
|
||||
"https://github.com/neeltheninja/ComfyUI-TextOverlay": [
|
||||
[
|
||||
"TextOverlay"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-TextOverlay"
|
||||
}
|
||||
],
|
||||
"https://github.com/neuratech-ai/ComfyUI-MultiGPU": [
|
||||
[
|
||||
"CLIPLoaderMultiGPU",
|
||||
"CheckpointLoaderMultiGPU",
|
||||
"ControlNetLoaderMultiGPU",
|
||||
"DualCLIPLoaderMultiGPU",
|
||||
"UNETLoaderMultiGPU",
|
||||
"VAELoaderMultiGPU"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-MultiGPU"
|
||||
}
|
||||
],
|
||||
"https://github.com/neverbiasu/ComfyUI-ControlNeXt": [
|
||||
[
|
||||
"ControlNextPipelineConfig",
|
||||
"ControlNextSDXL"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-ControlNeXt [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/nidefawl/ComfyUI-nidefawl": [
|
||||
[
|
||||
"BlendImagesWithBoundedMasks",
|
||||
@@ -2168,8 +2286,11 @@
|
||||
"PromptUtilitiesJoinStringList",
|
||||
"PromptUtilitiesLoadPreset",
|
||||
"PromptUtilitiesLoadPresetAdvanced",
|
||||
"PromptUtilitiesPromptWeight",
|
||||
"PromptUtilitiesRandomPreset",
|
||||
"PromptUtilitiesRandomPresetAdvanced"
|
||||
"PromptUtilitiesRandomPresetAdvanced",
|
||||
"PromptUtilitiesReplaceOrInsertTag",
|
||||
"PromptUtilitiesRoundPromptWeight"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-PromptUtilities"
|
||||
@@ -2200,6 +2321,7 @@
|
||||
"https://github.com/pamparamm/ComfyUI-ppm": [
|
||||
[
|
||||
"AttentionCouplePPM",
|
||||
"CFGLimiterGuider",
|
||||
"CFGPPSamplerSelect",
|
||||
"CLIPMicroConditioning",
|
||||
"CLIPNegPip",
|
||||
@@ -2273,6 +2395,17 @@
|
||||
"title_aux": "SDFXBridgeForComfyUI - ComfyUI Custom Node for SDFX Integration"
|
||||
}
|
||||
],
|
||||
"https://github.com/sebord/ComfyUI-LMCQ": [
|
||||
[
|
||||
"LmcqImageSaver",
|
||||
"LmcqImageSaverTransit",
|
||||
"LmcqImageSaverWeb",
|
||||
"LmcqLoadFluxNF4Checkpoint"
|
||||
],
|
||||
{
|
||||
"title_aux": "ComfyUI-LMCQ [WIP]"
|
||||
}
|
||||
],
|
||||
"https://github.com/shadowcz007/ComfyUI-PuLID-Test": [
|
||||
[
|
||||
"ApplyPulid",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,58 @@
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"author": "ZHO-ZHO-ZHO",
|
||||
"title": "ComfyUI-AnyText [NOT MAINTAINED]",
|
||||
"reference": "https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText",
|
||||
"files": [
|
||||
"https://github.com/ZHO-ZHO-ZHO/ComfyUI-AnyText"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Unofficial implementation of [a/AnyText](https://github.com/tyxsspa/AnyText/tree/825bcc54687206b15bd7e28ba1a8b095989d58e3) for ComfyUI(EXP)"
|
||||
},
|
||||
{
|
||||
"author": "shinich39",
|
||||
"title": "comfyui-pkg39 [DEPRECATED]",
|
||||
"reference": "https://github.com/shinich39/comfyui-pkg39",
|
||||
"files": [
|
||||
"https://github.com/shinich39/comfyui-pkg39"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "This package has created for generate image from generated image and embedded workflow."
|
||||
},
|
||||
{
|
||||
"author": "dnl13",
|
||||
"title": "ComfyUI-dnl13-seg [DEPRECATED]",
|
||||
"reference": "https://github.com/dnl13/ComfyUI-dnl13-seg",
|
||||
"files": [
|
||||
"https://github.com/dnl13/ComfyUI-dnl13-seg"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "After discovering @storyicon implementation here of Segment Anything, I realized its potential as a powerful tool for ComfyUI if implemented correctly. I delved into the SAM and Dino models. The following is my own adaptation of sam_hq for ComfyUI."
|
||||
},
|
||||
{
|
||||
"author": "1038lab",
|
||||
"title": "ComfyUI-latentSizeSelector [REMOVED]",
|
||||
"id": "ComfyUI-latentSizeSelector",
|
||||
"reference": "https://github.com/1038lab/ComfyUI_LatentSizeSelector",
|
||||
"files": [
|
||||
"https://github.com/1038lab/ComfyUI_LatentSizeSelector"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "You'll get a new node Latent Size Selector, you can pick the x and y sizes from a list."
|
||||
},
|
||||
{
|
||||
"author": "hy134300",
|
||||
"title": "ComfyUI-PhotoMaker-V2 [REMOVED]",
|
||||
"reference": "https://github.com/hy134300/ComfyUI-PhotoMaker-V2",
|
||||
"files": [
|
||||
"https://github.com/hy134300/ComfyUI-PhotoMaker-V2"
|
||||
],
|
||||
"install_type": "git-clone",
|
||||
"description": "Nodes for PhotoMaker-V2"
|
||||
},
|
||||
{
|
||||
"author": "neverbiasu",
|
||||
"title": "ComfyUI ImageCaptioner [REMOVED]",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,133 @@
|
||||
{
|
||||
"models": [
|
||||
{
|
||||
"name": "TAEF1 Decoder",
|
||||
"type": "TAESD",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(FLUX.1 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
"filename": "taef1_decoder.pth",
|
||||
"url": "https://github.com/madebyollin/taesd/raw/main/taef1_decoder.pth",
|
||||
"size": "4.71MB"
|
||||
},
|
||||
{
|
||||
"name": "TAEF1 Encoder",
|
||||
"type": "TAESD",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(FLUX.1 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
"filename": "taef1_encoder.pth",
|
||||
"url": "https://github.com/madebyollin/taesd/raw/main/taef1_encoder.pth",
|
||||
"size": "4.71MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "comfyanonymous/clip_l",
|
||||
"type": "clip",
|
||||
"base": "clip",
|
||||
"save_path": "default",
|
||||
"description": "clip_l model",
|
||||
"reference": "https://huggingface.co/comfyanonymous/flux_text_encoders/tree/main",
|
||||
"filename": "clip_l.safetensors",
|
||||
"url": "https://huggingface.co/comfyanonymous/flux_text_encoders/resolve/main/clip_l.safetensors",
|
||||
"size": "246MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "Comfy Org/FLUX.1 [dev] Checkpoint model (fp8)",
|
||||
"type": "checkpoint",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "checkpoints/FLUX1",
|
||||
"description": "FLUX.1 [dev] Checkpoint model (fp8)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/flux1-dev/tree/main",
|
||||
"filename": "flux1-dev-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/flux1-dev/resolve/main/flux1-dev-fp8.safetensors",
|
||||
"size": "17.2GB"
|
||||
},
|
||||
{
|
||||
"name": "Comfy Org/FLUX.1 [schnell] Checkpoint model (fp8)",
|
||||
"type": "checkpoint",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "checkpoints/FLUX1",
|
||||
"description": "FLUX.1 [schnell] Checkpoint model (fp8)",
|
||||
"reference": "https://huggingface.co/Comfy-Org/flux1-dev/tree/main",
|
||||
"filename": "flux1-schnell-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Comfy-Org/flux1-schnell/resolve/main/flux1-schnell-fp8.safetensors",
|
||||
"size": "17.2GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "google-t5/t5-v1_1-xxl_encoderonly-fp16",
|
||||
"type": "clip",
|
||||
"base": "t5",
|
||||
"save_path": "clip/t5",
|
||||
"description": "The encoder part of https://huggingface.co/google/t5-v1_1-xxl, used with SD3 and Flux1",
|
||||
"reference": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly",
|
||||
"filename": "google_t5-v1_1-xxl_encoderonly-fp16.safetensors",
|
||||
"url": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly/resolve/main/pytorch_model.safetensors",
|
||||
"size": "10.1GB"
|
||||
},
|
||||
{
|
||||
"name": "google-t5/t5-v1_1-xxl_encoderonly-fp8_e4m3fn",
|
||||
"type": "clip",
|
||||
"base": "t5",
|
||||
"save_path": "clip/t5",
|
||||
"description": "The encoder part of https://huggingface.co/google/t5-v1_1-xxl, used with SD3 and Flux1",
|
||||
"reference": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly",
|
||||
"filename": "google_t5-v1_1-xxl_encoderonly-fp8_e4m3fn.safetensors",
|
||||
"url": "https://huggingface.co/mcmonkey/google_t5-v1_1-xxl_encoderonly/resolve/main/t5xxl_fp8_e4m3fn.safetensors",
|
||||
"size": "4.89GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "FLUX.1 [schnell] Diffusion model",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] Diffusion model (a.k.a. FLUX.1 turbo model)[w/Due to the large size of the model, it is recommended to download it through a browser if possible.]",
|
||||
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||
"filename": "flux1-schnell.sft",
|
||||
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/flux1-schnell.sft",
|
||||
"size": "23.8GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "FLUX.1 VAE model",
|
||||
"type": "vae",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "vae/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] VAE model",
|
||||
"reference": "https://huggingface.co/black-forest-labs/FLUX.1-schnell",
|
||||
"filename": "ae.sft",
|
||||
"url": "https://huggingface.co/black-forest-labs/FLUX.1-schnell/resolve/main/ae.safetensors",
|
||||
"size": "335MB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "kijai/FLUX.1 [schnell] Diffusion model (float8_e4m3fn)",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [Schnell] Diffusion model (float8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Kijai/flux-fp8",
|
||||
"filename": "flux1-schnell-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/flux-fp8/resolve/main/flux1-schnell-fp8.safetensors",
|
||||
"size": "11.9GB"
|
||||
},
|
||||
{
|
||||
"name": "kijai/FLUX.1 [dev] Diffusion model (float8_e4m3fn)",
|
||||
"type": "unet",
|
||||
"base": "FLUX.1",
|
||||
"save_path": "unet/FLUX1",
|
||||
"description": "FLUX.1 [dev] Diffusion model (float8_e4m3fn)",
|
||||
"reference": "https://huggingface.co/Kijai/flux-fp8",
|
||||
"filename": "flux1-dev-fp8.safetensors",
|
||||
"url": "https://huggingface.co/Kijai/flux-fp8/resolve/main/flux1-dev-fp8.safetensors",
|
||||
"size": "11.9GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "photomaker-v2.bin",
|
||||
"type": "photomaker",
|
||||
@@ -152,7 +280,7 @@
|
||||
{
|
||||
"name": "TAESD3 Decoder",
|
||||
"type": "TAESD",
|
||||
"base": "SDXL",
|
||||
"base": "SD3",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(SD3 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
@@ -163,7 +291,7 @@
|
||||
{
|
||||
"name": "TAESD3 Encoder",
|
||||
"type": "TAESD",
|
||||
"base": "SDXL",
|
||||
"base": "SD3",
|
||||
"save_path": "vae_approx",
|
||||
"description": "(SD3 Verison) To view the preview in high quality while running samples in ComfyUI, you will need this model.",
|
||||
"reference": "https://github.com/madebyollin/taesd",
|
||||
@@ -565,132 +693,6 @@
|
||||
"filename": "model.safetensors",
|
||||
"url": "https://huggingface.co/spaces/ID-Animator/ID-Animator/resolve/main/image_encoder/model.safetensors",
|
||||
"size": "2.53GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "IC-Light/fc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "The default relighting model, conditioned on text and foreground",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fc.safetensors",
|
||||
"size": "1.72GB"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fbc",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Relighting model conditioned with text, foreground, and background",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fbc.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fbc.safetensors",
|
||||
"size": "1.72GB"
|
||||
},
|
||||
{
|
||||
"name": "IC-Light/fcon",
|
||||
"type": "IC-Light",
|
||||
"base": "SD1.5",
|
||||
"save_path": "unet/IC-Light",
|
||||
"description": "Same as iclight_sd15_fc.safetensors, but trained with offset noise",
|
||||
"reference": "https://huggingface.co/lllyasviel/ic-light",
|
||||
"filename": "iclight_sd15_fcon.safetensors",
|
||||
"url": "https://huggingface.co/lllyasviel/ic-light/resolve/main/iclight_sd15_fcon.safetensors",
|
||||
"size": "1.72GB"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "MonsterMMORPG/insightface (for InstantID)",
|
||||
"type": "insightface",
|
||||
"base": "SDXL",
|
||||
"save_path": "insightface/models",
|
||||
"description": "MonsterMMORPG insightface model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/MonsterMMORPG/tools/tree/main",
|
||||
"filename": "antelopev2.zip",
|
||||
"url": "https://huggingface.co/MonsterMMORPG/tools/resolve/main/antelopev2.zip",
|
||||
"size": "360.7MB"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ip-adapter",
|
||||
"type": "instantid",
|
||||
"base": "SDXL",
|
||||
"save_path": "instantid/SDXL",
|
||||
"description": "ip-adapter model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "ip-adapter.bin",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ip-adapter.bin"
|
||||
},
|
||||
{
|
||||
"name": "InstantID/ControlNet",
|
||||
"type": "controlnet",
|
||||
"base": "SDXL",
|
||||
"save_path": "controlnet/SDXL/instantid",
|
||||
"description": "instantid controlnet model for cubiq/InstantID",
|
||||
"reference": "https://huggingface.co/InstantX/InstantID",
|
||||
"filename": "diffusion_pytorch_model.safetensors",
|
||||
"url": "https://huggingface.co/InstantX/InstantID/resolve/main/ControlNetModel/diffusion_pytorch_model.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "ip_plus_composition_sd15.safetensors",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
||||
"reference": "https://huggingface.co/ostris/ip-composition-adapter",
|
||||
"filename": "ip_plus_composition_sd15.safetensors",
|
||||
"url": "https://huggingface.co/ostris/ip-composition-adapter/resolve/main/ip_plus_composition_sd15.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "ip_plus_composition_sdxl.safetensors",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SDXL",
|
||||
"save_path": "ipadapter",
|
||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
||||
"reference": "https://huggingface.co/ostris/ip-composition-adapter",
|
||||
"filename": "ip_plus_composition_sdxl.safetensors",
|
||||
"url": "https://huggingface.co/ostris/ip-composition-adapter/resolve/main/ip_plus_composition_sdxl.safetensors"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid-portrait-v11_sd15.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Portrait V11 Model (SD1.5) [ipadapter]",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-portrait-v11_sd15.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait-v11_sd15.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid-portrait_sdxl.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SDXL",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Portrait Model (SDXL) [ipadapter]",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-portrait_sdxl.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait_sdxl.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter-faceid-portrait_sdxl_unnorm.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SDXL",
|
||||
"save_path": "ipadapter",
|
||||
"description": "IP-Adapter-FaceID Portrait Model (SDXL/unnorm) [ipadapter]",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter-FaceID",
|
||||
"filename": "ip-adapter-faceid-portrait_sdxl_unnorm.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter-FaceID/resolve/main/ip-adapter-faceid-portrait_sdxl_unnorm.bin"
|
||||
},
|
||||
{
|
||||
"name": "ip-adapter_sd15_light_v11.bin",
|
||||
"type": "IP-Adapter",
|
||||
"base": "SD1.5",
|
||||
"save_path": "ipadapter",
|
||||
"description": "You can use this model in the [a/ComfyUI IPAdapter plus](https://github.com/cubiq/ComfyUI_IPAdapter_plus) extension.",
|
||||
"reference": "https://huggingface.co/h94/IP-Adapter",
|
||||
"filename": "ip-adapter_sd15_light_v11.bin",
|
||||
"url": "https://huggingface.co/h94/IP-Adapter/resolve/main/models/ip-adapter_sd15_light_v11.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -66,10 +66,10 @@
|
||||
"\n",
|
||||
"!echo -= Install dependencies =-\n",
|
||||
"!pip3 install accelerate\n",
|
||||
"!pip3 install einops transformers>=4.25.1 safetensors>=0.3.0 aiohttp pyyaml Pillow scipy tqdm psutil\n",
|
||||
"!pip3 install einops transformers>=4.28.1 safetensors>=0.4.2 aiohttp pyyaml Pillow scipy tqdm psutil tokenizers>=0.13.3\n",
|
||||
"!pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121\n",
|
||||
"!pip3 install torchsde\n",
|
||||
"!pip3 install kornia>=0.7.1 spandrel\n",
|
||||
"!pip3 install kornia>=0.7.1 spandrel soundfile sentencepiece\n",
|
||||
"\n",
|
||||
"if OPTIONS['USE_COMFYUI_MANAGER']:\n",
|
||||
" %cd custom_nodes\n",
|
||||
@@ -228,8 +228,8 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb\n",
|
||||
"!dpkg -i cloudflared-linux-amd64.deb\n",
|
||||
"!wget -P ~ https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb\n",
|
||||
"!dpkg -i ~/cloudflared-linux-amd64.deb\n",
|
||||
"\n",
|
||||
"import subprocess\n",
|
||||
"import threading\n",
|
||||
@@ -369,4 +369,4 @@
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import cm_global
|
||||
|
||||
security_check.security_check()
|
||||
|
||||
cm_global.pip_blacklist = ['torch', 'torchsde', 'torchvision']
|
||||
cm_global.pip_downgrade_blacklist = ['torch', 'torchsde', 'torchvision', 'transformers', 'safetensors', 'kornia']
|
||||
|
||||
|
||||
@@ -448,12 +449,15 @@ def is_installed(name):
|
||||
if name.startswith('#'):
|
||||
return True
|
||||
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)(.*)'
|
||||
pattern = r'([^<>!=]+)([<>!=]=?)([0-9.a-zA-Z]*)'
|
||||
match = re.search(pattern, name)
|
||||
|
||||
if match:
|
||||
name = match.group(1)
|
||||
|
||||
if name in cm_global.pip_blacklist:
|
||||
return True
|
||||
|
||||
if name in cm_global.pip_downgrade_blacklist:
|
||||
pips = get_installed_packages()
|
||||
|
||||
@@ -532,7 +536,12 @@ if os.path.exists(restore_snapshot_path):
|
||||
package_name = remap_pip_package(line.strip())
|
||||
if package_name and not is_installed(package_name):
|
||||
if not package_name.startswith('#'):
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
if '--index-url' in package_name:
|
||||
s = package_name.split('--index-url')
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", s[0].strip(), '--index-url', s[1].strip()]
|
||||
else:
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
|
||||
this_exit_code += process_wrap(install_cmd, repo_path)
|
||||
|
||||
if os.path.exists(install_script_path) and f'{repo_path}/install.py' not in processed_install:
|
||||
@@ -575,7 +584,12 @@ def execute_lazy_install_script(repo_path, executable):
|
||||
for line in requirements_file:
|
||||
package_name = remap_pip_package(line.strip())
|
||||
if package_name and not is_installed(package_name):
|
||||
install_cmd = [executable, "-m", "pip", "install", package_name]
|
||||
if '--index-url' in package_name:
|
||||
s = package_name.split('--index-url')
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", s[0].strip(), '--index-url', s[1].strip()]
|
||||
else:
|
||||
install_cmd = [sys.executable, "-m", "pip", "install", package_name]
|
||||
|
||||
process_wrap(install_cmd, repo_path)
|
||||
|
||||
if os.path.exists(install_script_path) and f'{repo_path}/install.py' not in processed_install:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui-manager"
|
||||
description = "ComfyUI-Manager provides features to install and manage custom nodes for ComfyUI, as well as various functionalities to assist with ComfyUI."
|
||||
version = "2.48.3"
|
||||
version = "2.50.1"
|
||||
license = { file = "LICENSE.txt" }
|
||||
dependencies = ["GitPython", "PyGithub", "matrix-client==0.4.0", "transformers", "huggingface-hub>0.20", "typer", "rich", "typing-extensions"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user