mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 03:01:27 -03:00
1fd7cc0123
The SHA256 of an empty byte string (written by repackaging tools into safetensors metadata, or produced by hashing an empty/unreadable file) was previously resolved against CivitAI's by-hash API, which can contain polluted entries for it (e.g. a broken SD 1.5 LoRA whose AutoV3 equals the placeholder) and falsely attributed the wrong model to a recipe. Guard all lookup paths for the 10/12/64-char AutoV2/AutoV3/full-SHA256 spellings: CivitaiClient.get_model_by_hash/_fetch_version_by_hash return not-found without a request, and ModelHashIndex ignores the placeholder in has_hash/get_path/add_autov3. The Automatic1111 metadata parser keeps the LoRA item itself when its hash is the placeholder: it matches by filename locally, or retains the entry with an empty hash flagged hashInvalid (unresolvable-hash state in the UI, with reconnect as the remedy) instead of dropping it or resolving it to a polluted CivitAI entry.
294 lines
7.6 KiB
Python
294 lines
7.6 KiB
Python
from typing import Any
|
|
|
|
NSFW_LEVELS = {
|
|
"PG": 1,
|
|
"PG13": 2,
|
|
"R": 4,
|
|
"X": 8,
|
|
"XXX": 16,
|
|
"Blocked": 32, # Probably not actually visible through the API without being logged in on model owner account?
|
|
}
|
|
|
|
# Node type constants
|
|
NODE_TYPES = {
|
|
"Lora Loader (LoraManager)": 1,
|
|
"Lora Stacker (LoraManager)": 2,
|
|
"WanVideo Lora Select (LoraManager)": 3,
|
|
"Create Hook LoRA (LoraManager)": 4,
|
|
}
|
|
|
|
# Default ComfyUI node color when bgcolor is null
|
|
DEFAULT_NODE_COLOR = "#353535"
|
|
|
|
# preview extensions
|
|
PREVIEW_EXTENSIONS = [
|
|
".webp",
|
|
".preview.webp",
|
|
".preview.png",
|
|
".preview.jpeg",
|
|
".preview.jpg",
|
|
".preview.mp4",
|
|
".png",
|
|
".jpeg",
|
|
".jpg",
|
|
".mp4",
|
|
".gif",
|
|
".webm",
|
|
".avif",
|
|
".jxl",
|
|
]
|
|
|
|
# Card preview image width
|
|
CARD_PREVIEW_WIDTH = 480
|
|
|
|
# Width for optimized example images
|
|
EXAMPLE_IMAGE_WIDTH = 832
|
|
|
|
# Supported media extensions for example downloads
|
|
SUPPORTED_MEDIA_EXTENSIONS = {
|
|
"images": [".jpg", ".jpeg", ".png", ".webp", ".gif", ".avif", ".jxl"],
|
|
"videos": [".mp4", ".webm"],
|
|
}
|
|
|
|
# Model weight file extensions recognised by scanners.
|
|
# This is the union of all scanner extensions (lora, checkpoint, embedding).
|
|
MODEL_FILE_EXTENSIONS = {
|
|
".safetensors",
|
|
".ckpt",
|
|
".pt",
|
|
".pt2",
|
|
".bin",
|
|
".pth",
|
|
".pkl",
|
|
".sft",
|
|
".gguf",
|
|
}
|
|
|
|
# CivitAI ModelFile.type values eligible as the main download file.
|
|
# Mirrors CivitAI's getPrimaryFile() (model-helpers.ts): weight types are
|
|
# preferred, but any file CivitAI marks `primary` is accepted — newer types
|
|
# like 'Enhancement LoRA' (Anima/AIR image-editing LoRAs) are valid primary
|
|
# files despite not being in the traditional weights allowlist.
|
|
MODEL_WEIGHT_FILE_TYPES = (
|
|
"Model",
|
|
"Pruned Model",
|
|
"Negative",
|
|
"UNet",
|
|
"Diffusion Model",
|
|
"Enhancement LoRA",
|
|
)
|
|
|
|
# Valid sub-types for each scanner type
|
|
VALID_LORA_SUB_TYPES = ["lora", "locon", "dora"]
|
|
VALID_CHECKPOINT_SUB_TYPES = ["checkpoint", "diffusion_model"]
|
|
VALID_EMBEDDING_SUB_TYPES = ["embedding"]
|
|
|
|
# Backward compatibility alias
|
|
VALID_LORA_TYPES = VALID_LORA_SUB_TYPES
|
|
|
|
# Supported Civitai model types for user model queries (case-insensitive)
|
|
CIVITAI_USER_MODEL_TYPES = [
|
|
*VALID_LORA_TYPES,
|
|
"textualinversion",
|
|
"checkpoint",
|
|
]
|
|
|
|
# Default chunk size in megabytes used for hashing large files.
|
|
DEFAULT_HASH_CHUNK_SIZE_MB = 4
|
|
|
|
# Upper bound for a safetensors header block (bytes). Real headers are at most
|
|
# a few MB (tensor name/shape lists); the cap prevents a crafted file with an
|
|
# absurd 64-bit header length from forcing a multi-GB allocation during scan.
|
|
MAX_SAFETENSORS_HEADER_BYTES = 64 * 1024 * 1024
|
|
|
|
# SHA256 of an empty byte string. Some (re-packaging) training tools write a
|
|
# truncated form of this placeholder into safetensors metadata (as
|
|
# ``modelspec.hash_sha256`` / ``sshs_model_hash``), and hashing an empty or
|
|
# unreadable file produces it directly. It must never be treated as a valid
|
|
# hash: several broken models share it, CivitAI's by-hash index can contain
|
|
# such polluted entries, and matching it falsely attributes recipes.
|
|
EMPTY_HASH_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
INVALID_AUTOV3_EMPTY_HASH = EMPTY_HASH_SHA256[:12]
|
|
INVALID_AUTOV2_EMPTY_HASH = EMPTY_HASH_SHA256[:10]
|
|
|
|
|
|
def is_empty_placeholder_hash(value: Any) -> bool:
|
|
"""True for a 10/12/64-hex-char spelling of the empty-hash placeholder.
|
|
|
|
These are the AutoV2, AutoV3 and full-SHA256 forms of the placeholder;
|
|
such values identify no real model and must never be resolved against
|
|
local files or CivitAI.
|
|
"""
|
|
if not isinstance(value, str):
|
|
return False
|
|
v = value.strip().lower()
|
|
if len(v) not in (10, 12, 64):
|
|
return False
|
|
return v == EMPTY_HASH_SHA256[: len(v)]
|
|
|
|
# Auto-organize settings
|
|
AUTO_ORGANIZE_BATCH_SIZE = (
|
|
50 # Process models in batches to avoid overwhelming the system
|
|
)
|
|
|
|
# Civitai model tags in priority order for subfolder organization
|
|
CIVITAI_MODEL_TAGS = [
|
|
"character",
|
|
"concept",
|
|
"clothing",
|
|
"realistic",
|
|
"anime",
|
|
"toon",
|
|
"furry",
|
|
"style",
|
|
"poses",
|
|
"background",
|
|
"tool",
|
|
"vehicle",
|
|
"buildings",
|
|
"objects",
|
|
"assets",
|
|
"animal",
|
|
"action",
|
|
]
|
|
|
|
# Default priority tag configuration strings for each model type
|
|
DEFAULT_PRIORITY_TAG_CONFIG = {
|
|
"lora": ", ".join(CIVITAI_MODEL_TAGS),
|
|
"checkpoint": ", ".join(CIVITAI_MODEL_TAGS),
|
|
"embedding": ", ".join(CIVITAI_MODEL_TAGS),
|
|
}
|
|
|
|
# baseModel values from CivitAI that should be treated as diffusion models (unet)
|
|
# These model types are incorrectly labeled as "checkpoint" by CivitAI but are actually diffusion models
|
|
DIFFUSION_MODEL_BASE_MODELS = frozenset(
|
|
[
|
|
"Anima",
|
|
# Flux series — DiT architecture, loaded via UNETLoader in ComfyUI
|
|
"Flux.1 D",
|
|
"Flux.1 S",
|
|
"Flux.1 Krea",
|
|
"Flux.1 Kontext",
|
|
"Flux.2 D",
|
|
"Flux.2 Klein 9B",
|
|
"Flux.2 Klein 9B-base",
|
|
"Flux.2 Klein 4B",
|
|
"Flux.2 Klein 4B-base",
|
|
# Non-UNet / DiT image diffusion models
|
|
"AuraFlow",
|
|
"Chroma",
|
|
"HiDream",
|
|
"Hunyuan 1",
|
|
"Kolors",
|
|
"Lumina",
|
|
"PixArt a",
|
|
"PixArt E",
|
|
# Video diffusion models
|
|
"CogVideoX",
|
|
"Hunyuan Video",
|
|
"LTXV",
|
|
"LTXV2",
|
|
"LTXV 2.3",
|
|
"Mochi",
|
|
"SVD",
|
|
"Wan Video",
|
|
"Wan Video 1.3B t2v",
|
|
"Wan Video 14B t2v",
|
|
"Wan Video 14B i2v 480p",
|
|
"Wan Video 14B i2v 720p",
|
|
"Wan Video 2.2 TI2V-5B",
|
|
"Wan Video 2.2 I2V-A14B",
|
|
"Wan Video 2.2 T2V-A14B",
|
|
"Wan Video 2.5 T2V",
|
|
"Wan Video 2.5 I2V",
|
|
# Other diffusion models
|
|
"Ernie",
|
|
"Ernie Turbo",
|
|
"Nucleus",
|
|
"Qwen",
|
|
"ZImageBase",
|
|
"ZImageTurbo",
|
|
# Krea 2 — loaded via UNETLoader in ComfyUI
|
|
"Krea 2",
|
|
]
|
|
)
|
|
|
|
# Supported baseModel values for download exclusion settings.
|
|
# Keep this aligned with static/js/utils/constants.js, excluding the generic "Other" value.
|
|
SUPPORTED_DOWNLOAD_SKIP_BASE_MODELS = frozenset(
|
|
[
|
|
"SD 1.4",
|
|
"SD 1.5",
|
|
"SD 1.5 LCM",
|
|
"SD 1.5 Hyper",
|
|
"SD 2.0",
|
|
"SD 2.1",
|
|
"SD 3",
|
|
"SD 3.5",
|
|
"SD 3.5 Medium",
|
|
"SD 3.5 Large",
|
|
"SD 3.5 Large Turbo",
|
|
"SDXL 1.0",
|
|
"SDXL Lightning",
|
|
"SDXL Hyper",
|
|
"Flux.1 D",
|
|
"Flux.1 S",
|
|
"Flux.1 Krea",
|
|
"Flux.1 Kontext",
|
|
"Flux.2 D",
|
|
"Flux.2 Klein 9B",
|
|
"Flux.2 Klein 9B-base",
|
|
"Flux.2 Klein 4B",
|
|
"Flux.2 Klein 4B-base",
|
|
"AuraFlow",
|
|
"Chroma",
|
|
"PixArt a",
|
|
"PixArt E",
|
|
"Hunyuan 1",
|
|
"Lumina",
|
|
"Kolors",
|
|
"NoobAI",
|
|
"Illustrious",
|
|
"Pony",
|
|
"Pony V7",
|
|
"HiDream",
|
|
"Qwen",
|
|
"ZImageTurbo",
|
|
"ZImageBase",
|
|
"SVD",
|
|
"LTXV",
|
|
"LTXV2",
|
|
"LTXV 2.3",
|
|
"CogVideoX",
|
|
"Mochi",
|
|
"Wan Video",
|
|
"Wan Video 1.3B t2v",
|
|
"Wan Video 14B t2v",
|
|
"Wan Video 14B i2v 480p",
|
|
"Wan Video 14B i2v 720p",
|
|
"Wan Video 2.2 TI2V-5B",
|
|
"Wan Video 2.2 T2V-A14B",
|
|
"Wan Video 2.2 I2V-A14B",
|
|
"Wan Video 2.5 T2V",
|
|
"Wan Video 2.5 I2V",
|
|
"Hunyuan Video",
|
|
"Anima",
|
|
"ACE Audio",
|
|
"Boogu",
|
|
"Ernie",
|
|
"Ernie Turbo",
|
|
"Grok",
|
|
"HappyHorse",
|
|
"HiDream-O1",
|
|
"Ideogram 4.0",
|
|
"Krea 2",
|
|
"Lens",
|
|
"MAI",
|
|
"Nucleus",
|
|
"Qwen 2",
|
|
"Upscaler",
|
|
"Wan Image 2.7",
|
|
"Wan Video 2.7",
|
|
]
|
|
)
|