diff --git a/lora_optimizer.py b/lora_optimizer.py index 277f8cd..bd727a8 100644 --- a/lora_optimizer.py +++ b/lora_optimizer.py @@ -392,6 +392,10 @@ class LoRAStackDynamic: } } for i in range(1, cls.MAX_LORAS + 1): + inputs["required"][f"enabled_{i}"] = ("BOOLEAN", { + "default": True, + "tooltip": f"Enable or disable LoRA #{i} without removing it from the list.", + }) inputs["required"][f"lora_name_{i}"] = (loras, { "tooltip": f"LoRA #{i} — pick a LoRA file or leave as 'None' to skip this slot." }) @@ -495,6 +499,8 @@ class LoRAStackDynamic: loras = [] use_text = input_mode == "text" for i in range(1, lora_count + 1): + if not kwargs.get(f"enabled_{i}", True): + continue if use_text: name = kwargs.get(f"lora_name_text_{i}", "None") else: diff --git a/tests/test_lora_optimizer.py b/tests/test_lora_optimizer.py index fb1cd21..c649f43 100644 --- a/tests/test_lora_optimizer.py +++ b/tests/test_lora_optimizer.py @@ -714,6 +714,33 @@ class LoRAOptimizerTests(unittest.TestCase): self.assertEqual(len(resolve_calls), 1) self.assertEqual(resolve_calls[0]["type"], "group") + def test_build_stack_skips_disabled_slots(self): + from unittest import mock + node = lora_optimizer.LoRAStackDynamic() + with mock.patch.object( + lora_optimizer.LoRAStackDynamic, "_resolve_lora_name", + side_effect=lambda n: n, + ): + result, = node.build_stack( + settings_visibility="simple", + input_mode="text", + lora_count=3, + lora_name_text_1="lora_a", + lora_name_text_2="lora_b", + lora_name_text_3="lora_c", + strength_1=1.0, + strength_2=0.8, + strength_3=0.5, + enabled_1=True, + enabled_2=False, + enabled_3=True, + ) + names = [entry[0] for entry in result] + self.assertEqual(len(result), 2) + self.assertIn("lora_a", names) + self.assertIn("lora_c", names) + self.assertNotIn("lora_b", names) + @unittest.skipIf(torch is None, "torch is not installed in this environment") class LoRASettingsNodeTests(unittest.TestCase):