fix(linking): support external-source linking for Other-model roots

set_hf_url rejected files under config.other_roots (VAEs, text encoders,
upscalers, ...) with 'File is not within any configured model directory'
because neither _find_matching_root nor _infer_model_type knew about the
Other category. Include other_roots in both, so linking routes the cache
update to the Other scanner instead of falling back to the LoRA one, and
downloads into Other roots keep the lazy-hash metadata path.

Also make the root prefix match boundary-aware so /models/vae no longer
swallows a sibling like /models/vae-old.
This commit is contained in:
Will Miao
2026-09-27 11:02:11 +08:00
parent ebd2b5b3e0
commit 0a262cbe0c
2 changed files with 115 additions and 3 deletions
+15 -3
View File
@@ -39,7 +39,12 @@ from ...services.settings_manager import get_settings_manager
from ...services.service_registry import ServiceRegistry
from ...services.websocket_manager import ws_manager
from ...utils.metadata_manager import MetadataManager
from ...utils.models import LoraMetadata, CheckpointMetadata, EmbeddingMetadata
from ...utils.models import (
LoraMetadata,
CheckpointMetadata,
EmbeddingMetadata,
OtherModelMetadata,
)
logger = logging.getLogger(__name__)
@@ -78,6 +83,11 @@ def _infer_model_type(model_root: str) -> tuple[Any, str]:
if os.path.normpath(p).replace(os.sep, "/") == norm:
return EmbeddingMetadata, "get_embedding_scanner"
# Other-model roots (VAE, text encoders, upscalers, ...)
for p in config.other_roots or []:
if os.path.normpath(p).replace(os.sep, "/") == norm:
return OtherModelMetadata, "get_other_scanner"
# Fallback — should not happen in normal use
logger.warning(
"Could not determine model type for root '%s'; defaulting to LoRA",
@@ -213,12 +223,14 @@ def _find_matching_root(dest_dir: str) -> str | None:
config.extra_unet_roots or [],
config.embeddings_roots or [],
config.extra_embeddings_roots or [],
config.other_roots or [],
):
all_roots.extend([os.path.normpath(p).replace(os.sep, "/") for p in root_list])
# Find the longest matching prefix
# Find the longest matching prefix. The boundary check prevents a root like
# `/models/vae` from swallowing a sibling directory like `/models/vae-old`.
match: str | None = None
for root in all_roots:
if norm.startswith(root):
if norm == root or norm.startswith(root + "/"):
if match is None or len(root) > len(match):
match = root
return match