66 lines
2.4 KiB
Python
66 lines
2.4 KiB
Python
import json
|
|
|
|
import folder_paths
|
|
|
|
# Import parent LoraLoader from ComfyUI built-in nodes
|
|
from nodes import LoraLoader
|
|
|
|
from .cache_manager import cache_manager
|
|
|
|
|
|
class KaiCivitaiLoRALoader(LoraLoader):
|
|
@classmethod
|
|
def INPUT_TYPES(s):
|
|
return {
|
|
"required": {
|
|
"model": ("MODEL", {}),
|
|
"clip": ("CLIP", {}),
|
|
"lora_name": (folder_paths.get_filename_list("loras"), {}),
|
|
"strength_model": (
|
|
"FLOAT",
|
|
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
|
|
),
|
|
"strength_clip": (
|
|
"FLOAT",
|
|
{"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01},
|
|
),
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("MODEL", "CLIP", "STRING", "STRING")
|
|
RETURN_NAMES = ("model", "clip", "trigger_words", "civitai_json")
|
|
FUNCTION = "load_lora_with_info"
|
|
CATEGORY = "KaiUtilities/loaders"
|
|
|
|
def load_lora_with_info(self, model, clip, lora_name, strength_model, strength_clip):
|
|
# Load LoRA using parent logic
|
|
model_out, clip_out = self.load_lora(
|
|
model, clip, lora_name, strength_model, strength_clip
|
|
)
|
|
|
|
# Get cached info if available (node does NOT auto-fetch; user must click button)
|
|
try:
|
|
lora_path = folder_paths.get_full_path_or_raise("loras", lora_name)
|
|
except (FileNotFoundError, KeyError):
|
|
# If path resolution fails, still return LoRA outputs with empty extras
|
|
return (model_out, clip_out, "", "")
|
|
|
|
# Use sync cache lookup because ComfyUI node FUNCTIONs run synchronously
|
|
# in worker threads (not in the async event loop). The sync hash function
|
|
# is safe here because worker threads can block on file I/O.
|
|
try:
|
|
cache = cache_manager.get_cache_for_file_sync(lora_path)
|
|
except Exception:
|
|
# Defensive: any unexpected failure in cache lookup should not crash the node
|
|
return (model_out, clip_out, "", "")
|
|
|
|
trigger_words = ""
|
|
civitai_json = ""
|
|
if cache:
|
|
words = cache.get("triggerWords")
|
|
if isinstance(words, list):
|
|
trigger_words = ", ".join(str(w) for w in words)
|
|
civitai_json = json.dumps(cache)
|
|
|
|
return (model_out, clip_out, trigger_words, civitai_json)
|