fix(lora): import the sidecars and local images LoraManager really uses (#355)

The import, the legacy scan, the trigger-word cache and the image server
now share LoraManager's layout: sidecars beside the models (alongside) or
under the sidecar root (centralized), kept only when their model exists
inside a LoRA root. Each LoRA links its LoraManager preview and example
images where they are; CivitAI downloads run only for a LoRA without any
local image. The review adds skipped, with_local_media and the layout, and
offers no token when LoraManager's settings cannot be used; the legacy scan
reports the same reason without replacing anything.

find_lora_directories becomes default_lora_roots (no scan of the
LoraManager install); the preview and example-folder helpers it replaced
are removed. The trigger cache never raises into a running node.
This commit is contained in:
Vito Sansevero
2026-10-26 17:41:15 -07:00
parent 96dea818d7
commit ae660de588
12 changed files with 837 additions and 287 deletions
+19
View File
@@ -315,6 +315,25 @@ class TestLoraTriggerWords(NodeTestCase):
)
cache.load.assert_called_once_with("/loras")
def test_a_failing_discovery_logs_and_the_node_still_runs(self):
# #355: the trigger cache reads LoraManager's folders while a node
# runs; a folder that cannot be listed must never stop the node.
from py import lora_utils
cache = lora_utils.get_trigger_cache()
cache.clear()
self.addCleanup(cache.clear)
with (
mock.patch.dict(sys.modules, {"py.config": fake_integration_config(True)}),
mock.patch.object(
lora_utils, "discover_sidecars", side_effect=OSError("share gone")
),
self.assertLogs("prompt_manager.lora_utils", level="WARNING") as logs,
):
text = self.node._inject_lora_trigger_words("a cat <lora:neon:1>")
self.assertEqual(text, "a cat <lora:neon:1>")
self.assertIn("share gone", "\n".join(logs.output))
class TestPromptManagerEncoding(NodeTestCase):
node_cls = PromptManager