From d50bbe71c2f2a44151e5776ade19597175a77f75 Mon Sep 17 00:00:00 2001 From: Will Miao Date: Fri, 27 Feb 2026 10:27:29 +0800 Subject: [PATCH] fix(extra-folder-paths): fix extra folder paths support for checkpoint and unet roots - Fix config.py: save and restore main paths when processing extra folder paths to prevent _prepare_checkpoint_paths from overwriting checkpoints_roots and unet_roots - Fix lora_manager.py: apply library settings during initialization to load extra folder paths in ComfyUI plugin mode - Fix checkpoint_routes.py: merge checkpoints/unet roots with extra paths in API endpoints - Add logging for extra folder paths Fixes issue where extra folder paths were not recognized for checkpoints and unet models. --- py/config.py | 20 +++++++++++++++++--- py/lora_manager.py | 20 ++++++++++++++++++++ py/routes/checkpoint_routes.py | 34 +++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/py/config.py b/py/config.py index b8130ede..eb5eaad9 100644 --- a/py/config.py +++ b/py/config.py @@ -736,11 +736,25 @@ class Config: extra_embedding_paths = extra_paths.get('embeddings', []) or [] self.extra_loras_roots = self._prepare_lora_paths(extra_lora_paths) + # Save main paths before processing extra paths ( _prepare_checkpoint_paths overwrites them) + saved_checkpoints_roots = self.checkpoints_roots + saved_unet_roots = self.unet_roots self.extra_checkpoints_roots = self._prepare_checkpoint_paths(extra_checkpoint_paths, extra_unet_paths) + self.extra_unet_roots = self.unet_roots # unet_roots was set by _prepare_checkpoint_paths + # Restore main paths + self.checkpoints_roots = saved_checkpoints_roots + self.unet_roots = saved_unet_roots self.extra_embeddings_roots = self._prepare_embedding_paths(extra_embedding_paths) - # extra_unet_roots is set by _prepare_checkpoint_paths (access unet_roots before it's reset) - unet_roots_value: List[str] = getattr(self, 'unet_roots', None) or [] - self.extra_unet_roots = unet_roots_value + + # Log extra folder paths + if self.extra_loras_roots: + logger.info("Found extra LoRA roots:" + "\n - " + "\n - ".join(self.extra_loras_roots)) + if self.extra_checkpoints_roots: + logger.info("Found extra checkpoint roots:" + "\n - " + "\n - ".join(self.extra_checkpoints_roots)) + if self.extra_unet_roots: + logger.info("Found extra diffusion model roots:" + "\n - " + "\n - ".join(self.extra_unet_roots)) + if self.extra_embeddings_roots: + logger.info("Found extra embedding roots:" + "\n - " + "\n - ".join(self.extra_embeddings_roots)) self._initialize_symlink_mappings() diff --git a/py/lora_manager.py b/py/lora_manager.py index fa1eaadb..8a81cebc 100644 --- a/py/lora_manager.py +++ b/py/lora_manager.py @@ -168,6 +168,26 @@ class LoraManager: async def _initialize_services(cls): """Initialize all services using the ServiceRegistry""" try: + # Apply library settings to load extra folder paths before scanning + try: + from .services.settings_manager import get_settings_manager + + settings_manager = get_settings_manager() + library_name = settings_manager.get_active_library_name() + libraries = settings_manager.get_libraries() + if library_name and library_name in libraries: + library_config = libraries[library_name] + config.apply_library_settings(library_config) + logger.info( + "Applied library settings for '%s' with extra paths: loras=%s, checkpoints=%s, embeddings=%s", + library_name, + library_config.get("extra_folder_paths", {}).get("loras", []), + library_config.get("extra_folder_paths", {}).get("checkpoints", []), + library_config.get("extra_folder_paths", {}).get("embeddings", []), + ) + except Exception as exc: + logger.warning("Failed to apply library settings during initialization: %s", exc) + # Initialize CivitaiClient first to ensure it's ready for other services await ServiceRegistry.get_civitai_client() diff --git a/py/routes/checkpoint_routes.py b/py/routes/checkpoint_routes.py index e22ab2a3..49b8ad5d 100644 --- a/py/routes/checkpoint_routes.py +++ b/py/routes/checkpoint_routes.py @@ -1,5 +1,5 @@ import logging -from typing import Dict +from typing import Dict, List, Set from aiohttp import web from .base_model_routes import BaseModelRoutes @@ -82,12 +82,22 @@ class CheckpointRoutes(BaseModelRoutes): return web.json_response({"error": str(e)}, status=500) async def get_checkpoints_roots(self, request: web.Request) -> web.Response: - """Return the list of checkpoint roots from config""" + """Return the list of checkpoint roots from config (including extra paths)""" try: - roots = config.checkpoints_roots + # Merge checkpoints_roots with extra_checkpoints_roots, preserving order and removing duplicates + roots: List[str] = [] + roots.extend(config.checkpoints_roots or []) + roots.extend(config.extra_checkpoints_roots or []) + # Remove duplicates while preserving order + seen: set = set() + unique_roots: List[str] = [] + for root in roots: + if root and root not in seen: + seen.add(root) + unique_roots.append(root) return web.json_response({ "success": True, - "roots": roots + "roots": unique_roots }) except Exception as e: logger.error(f"Error getting checkpoint roots: {e}", exc_info=True) @@ -97,12 +107,22 @@ class CheckpointRoutes(BaseModelRoutes): }, status=500) async def get_unet_roots(self, request: web.Request) -> web.Response: - """Return the list of unet roots from config""" + """Return the list of unet roots from config (including extra paths)""" try: - roots = config.unet_roots + # Merge unet_roots with extra_unet_roots, preserving order and removing duplicates + roots: List[str] = [] + roots.extend(config.unet_roots or []) + roots.extend(config.extra_unet_roots or []) + # Remove duplicates while preserving order + seen: set = set() + unique_roots: List[str] = [] + for root in roots: + if root and root not in seen: + seen.add(root) + unique_roots.append(root) return web.json_response({ "success": True, - "roots": roots + "roots": unique_roots }) except Exception as e: logger.error(f"Error getting unet roots: {e}", exc_info=True)