diff --git a/.ci/manager_windows/install_manager.bat b/.ci/manager_windows/install_manager.bat new file mode 100644 index 000000000000..56dfa1c4598f --- /dev/null +++ b/.ci/manager_windows/install_manager.bat @@ -0,0 +1,4 @@ +@echo off +..\python_embeded\python.exe .\install_manager.py ..\ComfyUI\ +echo Installed manager through pip package, if not already installed. +pause \ No newline at end of file diff --git a/.ci/manager_windows/install_manager.py b/.ci/manager_windows/install_manager.py new file mode 100644 index 000000000000..db991d984e42 --- /dev/null +++ b/.ci/manager_windows/install_manager.py @@ -0,0 +1,24 @@ +import sys +import os + +repo_path = str(sys.argv[1]) +repo_manager_req_path = os.path.join(repo_path, "manager_requirements.txt") + +if os.path.exists(repo_manager_req_path): + import subprocess + # if not installed, we get 'WARNING: Package(s) not found: comfyui_manager' + # if installed, there will be a line like 'Version: 0.1.0' = False + try: + output = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'show', 'comfyui_manager']) + if 'Version:' in output.decode('utf-8'): + print("comfyui_manager is already installed, will attempt to update to matching version of ComfyUI.") # noqa: T201 + else: + print("comfyui_manager is not installed, will install it now.") # noqa: T201 + except: + pass + + try: + subprocess.check_call([sys.executable, '-s', '-m', 'pip', 'install', '-r', repo_manager_req_path]) + print("comfyui_manager installed successfully.") # noqa: T201 + except: + print("Failed to install comfyui_manager, please install it manually.") # noqa: T201 diff --git a/.ci/update_windows/update.py b/.ci/update_windows/update.py index 51a263203d82..4a202786d9af 100755 --- a/.ci/update_windows/update.py +++ b/.ci/update_windows/update.py @@ -114,6 +114,8 @@ def latest_tag(repo): req_path = os.path.join(cur_path, "current_requirements.txt") repo_req_path = os.path.join(repo_path, "requirements.txt") +manager_req_path = os.path.join(cur_path, "current_manager_requirements.txt") +repo_manager_req_path = os.path.join(repo_path, "manager_requirements.txt") def files_equal(file1, file2): try: @@ -140,6 +142,25 @@ def file_size(f): except: pass +if os.path.exists(repo_manager_req_path) and (not os.path.exists(manager_req_path) or not files_equal(repo_manager_req_path, manager_req_path)): + import subprocess + # first, confirm that comfyui_manager package is installed; only update it if it is + # if not installed, we get 'WARNING: Package(s) not found: comfyui_manager' + # if installed, there will be a line like 'Version: 0.1.0' + update_manager = False + try: + output = subprocess.check_output([sys.executable, '-s', '-m', 'pip', 'show', 'comfyui_manager']) + if 'Version:' in output.decode('utf-8'): + update_manager = True + except: + pass + + if update_manager: + try: + subprocess.check_call([sys.executable, '-s', '-m', 'pip', 'install', '-r', repo_manager_req_path]) + shutil.copy(repo_manager_req_path, manager_req_path) + except: + pass stable_update_script = os.path.join(repo_path, ".ci/update_windows/update_comfyui_stable.bat") stable_update_script_to = os.path.join(cur_path, "update_comfyui_stable.bat") diff --git a/.ci/windows_amd_base_files/run_amd_gpu.bat b/.ci/windows_amd_base_files/run_amd_gpu.bat index 274d7c9486e0..a911d7a57185 100755 --- a/.ci/windows_amd_base_files/run_amd_gpu.bat +++ b/.ci/windows_amd_base_files/run_amd_gpu.bat @@ -1,2 +1,2 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build +.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --enable-manager pause diff --git a/.ci/windows_amd_base_files/run_amd_gpu_disable_smart_memory.bat b/.ci/windows_amd_base_files/run_amd_gpu_disable_smart_memory.bat index cece0aeb20b5..1c382477f435 100755 --- a/.ci/windows_amd_base_files/run_amd_gpu_disable_smart_memory.bat +++ b/.ci/windows_amd_base_files/run_amd_gpu_disable_smart_memory.bat @@ -1,2 +1,2 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --disable-smart-memory +.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --enable-manager --disable-smart-memory pause diff --git a/.ci/windows_nightly_base_files/run_nvidia_gpu_fast.bat b/.ci/windows_nightly_base_files/run_nvidia_gpu_fast.bat index ca6d6868af4e..67aaee88f340 100644 --- a/.ci/windows_nightly_base_files/run_nvidia_gpu_fast.bat +++ b/.ci/windows_nightly_base_files/run_nvidia_gpu_fast.bat @@ -1,2 +1,2 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --fast +.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --enable-manager --fast pause diff --git a/.ci/windows_nvidia_base_files/advanced/run_nvidia_gpu_disable_api_nodes.bat b/.ci/windows_nvidia_base_files/advanced/run_nvidia_gpu_disable_api_nodes.bat index ed00583b62f2..f6dcd3eb6614 100644 --- a/.ci/windows_nvidia_base_files/advanced/run_nvidia_gpu_disable_api_nodes.bat +++ b/.ci/windows_nvidia_base_files/advanced/run_nvidia_gpu_disable_api_nodes.bat @@ -1,3 +1,3 @@ -..\python_embeded\python.exe -s ..\ComfyUI\main.py --windows-standalone-build --disable-api-nodes +..\python_embeded\python.exe -s ..\ComfyUI\main.py --windows-standalone-build --enable-manager --disable-api-nodes echo If you see this and ComfyUI did not start try updating your Nvidia Drivers to the latest. pause diff --git a/.ci/windows_nvidia_base_files/run_cpu.bat b/.ci/windows_nvidia_base_files/run_cpu.bat index c3ba4172161a..366317779fc3 100755 --- a/.ci/windows_nvidia_base_files/run_cpu.bat +++ b/.ci/windows_nvidia_base_files/run_cpu.bat @@ -1,2 +1,2 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --cpu --windows-standalone-build +.\python_embeded\python.exe -s ComfyUI\main.py --cpu --windows-standalone-build --enable-manager pause diff --git a/.ci/windows_nvidia_base_files/run_nvidia_gpu.bat b/.ci/windows_nvidia_base_files/run_nvidia_gpu.bat index 4898a424f4fc..02f86eea05a8 100755 --- a/.ci/windows_nvidia_base_files/run_nvidia_gpu.bat +++ b/.ci/windows_nvidia_base_files/run_nvidia_gpu.bat @@ -1,3 +1,3 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build +.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --enable-manager echo If you see this and ComfyUI did not start try updating your Nvidia Drivers to the latest. pause diff --git a/.ci/windows_nvidia_base_files/run_nvidia_gpu_fast_fp16_accumulation.bat b/.ci/windows_nvidia_base_files/run_nvidia_gpu_fast_fp16_accumulation.bat index 32611e4affd8..69692e82f93a 100644 --- a/.ci/windows_nvidia_base_files/run_nvidia_gpu_fast_fp16_accumulation.bat +++ b/.ci/windows_nvidia_base_files/run_nvidia_gpu_fast_fp16_accumulation.bat @@ -1,3 +1,3 @@ -.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --fast fp16_accumulation +.\python_embeded\python.exe -s ComfyUI\main.py --windows-standalone-build --enable-manager --fast fp16_accumulation echo If you see this and ComfyUI did not start try updating your Nvidia Drivers to the latest. pause diff --git a/comfy/cli_args.py b/comfy/cli_args.py index d2b60e347eff..1c8ef0c1fcbb 100644 --- a/comfy/cli_args.py +++ b/comfy/cli_args.py @@ -121,6 +121,12 @@ class LatentPreviewMethod(enum.Enum): upcast.add_argument("--dont-upcast-attention", action="store_true", help="Disable all upcasting of attention. Should be unnecessary except for debugging.") +parser.add_argument("--enable-manager", action="store_true", help="Enable the ComfyUI-Manager feature.") +manager_group = parser.add_mutually_exclusive_group() +manager_group.add_argument("--disable-manager-ui", action="store_true", help="Disables only the ComfyUI-Manager UI and endpoints. Scheduled installations and similar background tasks will still operate.") +manager_group.add_argument("--enable-manager-legacy-ui", action="store_true", help="Enables the legacy UI of ComfyUI-Manager") + + vram_group = parser.add_mutually_exclusive_group() vram_group.add_argument("--gpu-only", action="store_true", help="Store and run everything (text encoders/CLIP models, etc... on the GPU).") vram_group.add_argument("--highvram", action="store_true", help="By default models will be unloaded to CPU memory after being used. This option keeps them in GPU memory.") @@ -167,6 +173,7 @@ class PerformanceFeature(enum.Enum): parser.add_argument("--verbose", default='INFO', const='DEBUG', nargs="?", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], help='Set the logging level') parser.add_argument("--log-stdout", action="store_true", help="Send normal process output to stdout instead of stderr (default).") + # The default built-in provider hosted under web/ DEFAULT_VERSION_STRING = "comfyanonymous/ComfyUI@latest" diff --git a/comfy_api/feature_flags.py b/comfy_api/feature_flags.py index 0d4389a6e9e7..bfb77eb5fa1f 100644 --- a/comfy_api/feature_flags.py +++ b/comfy_api/feature_flags.py @@ -13,6 +13,7 @@ SERVER_FEATURE_FLAGS: Dict[str, Any] = { "supports_preview_metadata": True, "max_upload_size": args.max_upload_size * 1024 * 1024, # Convert MB to bytes + "extension": {"manager": {"supports_v4": True}}, } diff --git a/main.py b/main.py index e1b0f1620bbc..0cd815d9e620 100644 --- a/main.py +++ b/main.py @@ -15,6 +15,7 @@ from comfy_execution.utils import get_executing_context from comfy_api import feature_flags + if __name__ == "__main__": #NOTE: These do not do anything on core ComfyUI, they are for custom nodes. os.environ['HF_HUB_DISABLE_TELEMETRY'] = '1' @@ -22,6 +23,23 @@ setup_logger(log_level=args.verbose, use_stdout=args.log_stdout) + +def handle_comfyui_manager_unavailable(): + if not args.windows_standalone_build: + logging.warning(f"\n\nYou appear to be running comfyui-manager from source, this is not recommended. Please install comfyui-manager using the following command:\ncommand:\n\t{sys.executable} -m pip install --pre comfyui_manager\n") + args.enable_manager = False + + +if args.enable_manager: + if importlib.util.find_spec("comfyui_manager"): + import comfyui_manager + + if not comfyui_manager.__file__ or not comfyui_manager.__file__.endswith('__init__.py'): + handle_comfyui_manager_unavailable() + else: + handle_comfyui_manager_unavailable() + + def apply_custom_paths(): # extra model paths extra_model_paths_config_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "extra_model_paths.yaml") @@ -79,6 +97,11 @@ def execute_script(script_path): for possible_module in possible_modules: module_path = os.path.join(custom_node_path, possible_module) + + if args.enable_manager: + if comfyui_manager.should_be_disabled(module_path): + continue + if os.path.isfile(module_path) or module_path.endswith(".disabled") or module_path == "__pycache__": continue @@ -101,6 +124,10 @@ def execute_script(script_path): logging.info("") apply_custom_paths() + +if args.enable_manager: + comfyui_manager.prestartup() + execute_prestartup_script() @@ -323,6 +350,9 @@ def start_comfyui(asyncio_loop=None): asyncio.set_event_loop(asyncio_loop) prompt_server = server.PromptServer(asyncio_loop) + if args.enable_manager and not args.disable_manager_ui: + comfyui_manager.start() + hook_breaker_ac10a0.save_functions() asyncio_loop.run_until_complete(nodes.init_extra_nodes( init_custom_nodes=(not args.disable_all_custom_nodes) or len(args.whitelist_custom_nodes) > 0, diff --git a/manager_requirements.txt b/manager_requirements.txt new file mode 100644 index 000000000000..52cc5389cc3f --- /dev/null +++ b/manager_requirements.txt @@ -0,0 +1 @@ +comfyui_manager==4.0.3b3 diff --git a/nodes.py b/nodes.py index f4835c02e590..902468895347 100644 --- a/nodes.py +++ b/nodes.py @@ -43,6 +43,9 @@ import latent_preview import node_helpers +if args.enable_manager: + import comfyui_manager + def before_node_execution(): comfy.model_management.throw_exception_if_processing_interrupted() @@ -2233,6 +2236,12 @@ async def init_external_custom_nodes(): if args.disable_all_custom_nodes and possible_module not in args.whitelist_custom_nodes: logging.info(f"Skipping {possible_module} due to disable_all_custom_nodes and whitelist_custom_nodes") continue + + if args.enable_manager: + if comfyui_manager.should_be_disabled(module_path): + logging.info(f"Blocked by policy: {module_path}") + continue + time_before = time.perf_counter() success = await load_custom_node(module_path, base_node_names, module_parent="custom_nodes") node_import_times.append((time.perf_counter() - time_before, module_path, success)) diff --git a/server.py b/server.py index 0fd2e49e34bf..6b8d94f3f07d 100644 --- a/server.py +++ b/server.py @@ -44,6 +44,9 @@ # Import cache control middleware from middleware.cache_middleware import cache_control +if args.enable_manager: + import comfyui_manager + async def send_socket_catch_exception(function, message): try: await function(message) @@ -212,6 +215,9 @@ def __init__(self, loop): if args.disable_api_nodes: middlewares.append(create_block_external_middleware()) + if args.enable_manager: + middlewares.append(comfyui_manager.create_middleware()) + max_upload_size = round(args.max_upload_size * 1024 * 1024) self.app = web.Application(client_max_size=max_upload_size, middlewares=middlewares) self.sockets = dict() @@ -599,7 +605,7 @@ async def system_stats(request): system_stats = { "system": { - "os": os.name, + "os": sys.platform, "ram_total": ram_total, "ram_free": ram_free, "comfyui_version": __version__,