feat(trigger-word-toggle): use trigger_words directly when it differs from original message

This commit is contained in:
Will Miao
2026-01-23 09:50:53 +08:00
parent 7c7d2e12b5
commit 0bb75fdf77
2 changed files with 174 additions and 50 deletions

View File

@@ -10,23 +10,32 @@ class TriggerWordToggle:
NAME = "TriggerWord Toggle (LoraManager)" NAME = "TriggerWord Toggle (LoraManager)"
CATEGORY = "Lora Manager/utils" CATEGORY = "Lora Manager/utils"
DESCRIPTION = "Toggle trigger words on/off" DESCRIPTION = "Toggle trigger words on/off"
@classmethod @classmethod
def INPUT_TYPES(cls): def INPUT_TYPES(cls):
return { return {
"required": { "required": {
"group_mode": ("BOOLEAN", { "group_mode": (
"default": True, "BOOLEAN",
"tooltip": "When enabled, treats each group of trigger words as a single toggleable unit." {
}), "default": True,
"default_active": ("BOOLEAN", { "tooltip": "When enabled, treats each group of trigger words as a single toggleable unit.",
"default": True, },
"tooltip": "Sets the default initial state (active or inactive) when trigger words are added." ),
}), "default_active": (
"allow_strength_adjustment": ("BOOLEAN", { "BOOLEAN",
"default": False, {
"tooltip": "Enable mouse wheel adjustment of each trigger word's strength." "default": True,
}), "tooltip": "Sets the default initial state (active or inactive) when trigger words are added.",
},
),
"allow_strength_adjustment": (
"BOOLEAN",
{
"default": False,
"tooltip": "Enable mouse wheel adjustment of each trigger word's strength.",
},
),
}, },
"optional": FlexibleOptionalInputType(any_type), "optional": FlexibleOptionalInputType(any_type),
"hidden": { "hidden": {
@@ -38,15 +47,15 @@ class TriggerWordToggle:
RETURN_NAMES = ("filtered_trigger_words",) RETURN_NAMES = ("filtered_trigger_words",)
FUNCTION = "process_trigger_words" FUNCTION = "process_trigger_words"
def _get_toggle_data(self, kwargs, key='toggle_trigger_words'): def _get_toggle_data(self, kwargs, key="toggle_trigger_words"):
"""Helper to extract data from either old or new kwargs format""" """Helper to extract data from either old or new kwargs format"""
if key not in kwargs: if key not in kwargs:
return None return None
data = kwargs[key] data = kwargs[key]
# Handle new format: {'key': {'__value__': ...}} # Handle new format: {'key': {'__value__': ...}}
if isinstance(data, dict) and '__value__' in data: if isinstance(data, dict) and "__value__" in data:
return data['__value__'] return data["__value__"]
# Handle old format: {'key': ...} # Handle old format: {'key': ...}
else: else:
return data return data
@@ -60,13 +69,25 @@ class TriggerWordToggle:
**kwargs, **kwargs,
): ):
# Handle both old and new formats for trigger_words # Handle both old and new formats for trigger_words
trigger_words_data = self._get_toggle_data(kwargs, 'orinalMessage') trigger_words_data = self._get_toggle_data(kwargs, "orinalMessage")
trigger_words = trigger_words_data if isinstance(trigger_words_data, str) else "" trigger_words = (
trigger_words_data if isinstance(trigger_words_data, str) else ""
)
filtered_triggers = trigger_words filtered_triggers = trigger_words
# Check if trigger_words is provided and different from orinalMessage
trigger_words_override = self._get_toggle_data(kwargs, "trigger_words")
if (
trigger_words_override
and isinstance(trigger_words_override, str)
and trigger_words_override != trigger_words
):
filtered_triggers = trigger_words_override
return (filtered_triggers,)
# Get toggle data with support for both formats # Get toggle data with support for both formats
trigger_data = self._get_toggle_data(kwargs, 'toggle_trigger_words') trigger_data = self._get_toggle_data(kwargs, "toggle_trigger_words")
if trigger_data: if trigger_data:
try: try:
# Convert to list if it's a JSON string # Convert to list if it's a JSON string
@@ -77,7 +98,9 @@ class TriggerWordToggle:
if group_mode: if group_mode:
if allow_strength_adjustment: if allow_strength_adjustment:
parsed_items = [ parsed_items = [
self._parse_trigger_item(item, allow_strength_adjustment) self._parse_trigger_item(
item, allow_strength_adjustment
)
for item in trigger_data for item in trigger_data
] ]
filtered_groups = [ filtered_groups = [
@@ -91,11 +114,14 @@ class TriggerWordToggle:
] ]
else: else:
filtered_groups = [ filtered_groups = [
(item.get('text') or "").strip() (item.get("text") or "").strip()
for item in trigger_data for item in trigger_data
if (item.get('text') or "").strip() and item.get('active', False) if (item.get("text") or "").strip()
and item.get("active", False)
] ]
filtered_triggers = ', '.join(filtered_groups) if filtered_groups else "" filtered_triggers = (
", ".join(filtered_groups) if filtered_groups else ""
)
else: else:
parsed_items = [ parsed_items = [
self._parse_trigger_item(item, allow_strength_adjustment) self._parse_trigger_item(item, allow_strength_adjustment)
@@ -110,28 +136,34 @@ class TriggerWordToggle:
for item in parsed_items for item in parsed_items
if item["text"] and item["active"] if item["text"] and item["active"]
] ]
filtered_triggers = ', '.join(filtered_words) if filtered_words else "" filtered_triggers = (
", ".join(filtered_words) if filtered_words else ""
)
else: else:
# Fallback to original message parsing if data is not in the expected list format # Fallback to original message parsing if data is not in the expected list format
if group_mode: if group_mode:
groups = re.split(r',{2,}', trigger_words) groups = re.split(r",{2,}", trigger_words)
groups = [group.strip() for group in groups if group.strip()] groups = [group.strip() for group in groups if group.strip()]
filtered_triggers = ', '.join(groups) filtered_triggers = ", ".join(groups)
else: else:
words = [word.strip() for word in trigger_words.split(',') if word.strip()] words = [
filtered_triggers = ', '.join(words) word.strip()
for word in trigger_words.split(",")
if word.strip()
]
filtered_triggers = ", ".join(words)
except Exception as e: except Exception as e:
logger.error(f"Error processing trigger words: {e}") logger.error(f"Error processing trigger words: {e}")
return (filtered_triggers,) return (filtered_triggers,)
def _parse_trigger_item(self, item, allow_strength_adjustment): def _parse_trigger_item(self, item, allow_strength_adjustment):
text = (item.get('text') or "").strip() text = (item.get("text") or "").strip()
active = bool(item.get('active', False)) active = bool(item.get("active", False))
strength = item.get('strength') strength = item.get("strength")
strength_match = re.match(r'^\((.+):([\d.]+)\)$', text) strength_match = re.match(r"^\((.+):([\d.]+)\)$", text)
if strength_match: if strength_match:
text = strength_match.group(1).strip() text = strength_match.group(1).strip()
if strength is None: if strength is None:

View File

@@ -4,9 +4,24 @@ from py.nodes.trigger_word_toggle import TriggerWordToggle
def test_group_mode_preserves_parenthesized_groups(): def test_group_mode_preserves_parenthesized_groups():
node = TriggerWordToggle() node = TriggerWordToggle()
trigger_data = [ trigger_data = [
{'text': 'flat color, dark theme', 'active': True, 'strength': None, 'highlighted': False}, {
{'text': '(a, really, long, test, trigger, word:1.06)', 'active': True, 'strength': 1.06, 'highlighted': False}, "text": "flat color, dark theme",
{'text': '(sinozick style:0.94)', 'active': True, 'strength': 0.94, 'highlighted': False}, "active": True,
"strength": None,
"highlighted": False,
},
{
"text": "(a, really, long, test, trigger, word:1.06)",
"active": True,
"strength": 1.06,
"highlighted": False,
},
{
"text": "(sinozick style:0.94)",
"active": True,
"strength": 0.94,
"highlighted": False,
},
] ]
original_message = ( original_message = (
@@ -14,7 +29,7 @@ def test_group_mode_preserves_parenthesized_groups():
"(sinozick style:0.94)" "(sinozick style:0.94)"
) )
filtered, = node.process_trigger_words( (filtered,) = node.process_trigger_words(
id="node", id="node",
group_mode=True, group_mode=True,
default_active=True, default_active=True,
@@ -29,11 +44,11 @@ def test_group_mode_preserves_parenthesized_groups():
def test_duplicate_words_keep_individual_active_states(): def test_duplicate_words_keep_individual_active_states():
node = TriggerWordToggle() node = TriggerWordToggle()
trigger_data = [ trigger_data = [
{'text': 'A', 'active': True, 'strength': None, 'highlighted': False}, {"text": "A", "active": True, "strength": None, "highlighted": False},
{'text': 'A', 'active': False, 'strength': None, 'highlighted': False}, {"text": "A", "active": False, "strength": None, "highlighted": False},
] ]
filtered, = node.process_trigger_words( (filtered,) = node.process_trigger_words(
id="node", id="node",
group_mode=False, group_mode=False,
default_active=True, default_active=True,
@@ -48,12 +63,12 @@ def test_duplicate_words_keep_individual_active_states():
def test_duplicate_words_preserve_strength_per_instance(): def test_duplicate_words_preserve_strength_per_instance():
node = TriggerWordToggle() node = TriggerWordToggle()
trigger_data = [ trigger_data = [
{'text': '(A:0.50)', 'active': False, 'strength': 0.50, 'highlighted': False}, {"text": "(A:0.50)", "active": False, "strength": 0.50, "highlighted": False},
{'text': 'A', 'active': True, 'strength': 1.2, 'highlighted': False}, {"text": "A", "active": True, "strength": 1.2, "highlighted": False},
{'text': '(A:0.75)', 'active': True, 'strength': 0.75, 'highlighted': False}, {"text": "(A:0.75)", "active": True, "strength": 0.75, "highlighted": False},
] ]
filtered, = node.process_trigger_words( (filtered,) = node.process_trigger_words(
id="node", id="node",
group_mode=False, group_mode=False,
default_active=True, default_active=True,
@@ -68,11 +83,11 @@ def test_duplicate_words_preserve_strength_per_instance():
def test_duplicate_groups_respect_active_state(): def test_duplicate_groups_respect_active_state():
node = TriggerWordToggle() node = TriggerWordToggle()
trigger_data = [ trigger_data = [
{'text': 'A, B', 'active': False, 'strength': None, 'highlighted': False}, {"text": "A, B", "active": False, "strength": None, "highlighted": False},
{'text': 'A, B', 'active': True, 'strength': None, 'highlighted': False}, {"text": "A, B", "active": True, "strength": None, "highlighted": False},
] ]
filtered, = node.process_trigger_words( (filtered,) = node.process_trigger_words(
id="node", id="node",
group_mode=True, group_mode=True,
default_active=True, default_active=True,
@@ -82,3 +97,80 @@ def test_duplicate_groups_respect_active_state():
) )
assert filtered == "A, B" assert filtered == "A, B"
def test_trigger_words_override_different_from_original():
node = TriggerWordToggle()
trigger_data = [
{
"text": "69yottea_style_illu",
"active": [
{"text": "createconcept", "active": True},
{"text": "DS-Illu", "active": True},
],
"strength": None,
"highlighted": False,
}
]
(filtered,) = node.process_trigger_words(
id="node",
group_mode=True,
default_active=True,
allow_strength_adjustment=False,
orinalMessage="69yottea_style_illu",
trigger_words="masterpiece, best quality, very aesthetic, absurdres",
toggle_trigger_words=trigger_data,
)
assert filtered == "masterpiece, best quality, very aesthetic, absurdres"
def test_trigger_words_override_with_new_format():
node = TriggerWordToggle()
(filtered,) = node.process_trigger_words(
id="node",
group_mode=True,
default_active=True,
allow_strength_adjustment=False,
orinalMessage="69yottea_style_illu",
trigger_words="masterpiece, best quality, very aesthetic, absurdres",
)
assert filtered == "masterpiece, best quality, very aesthetic, absurdres"
def test_trigger_words_same_as_original_processes_toggle():
node = TriggerWordToggle()
trigger_data = [
{"text": "word1", "active": True, "strength": None, "highlighted": False},
{"text": "word2", "active": False, "strength": None, "highlighted": False},
]
(filtered,) = node.process_trigger_words(
id="node",
group_mode=False,
default_active=True,
allow_strength_adjustment=False,
orinalMessage="word1, word2",
trigger_words="word1, word2",
toggle_trigger_words=trigger_data,
)
assert filtered == "word1"
def test_trigger_words_override_empty_toggle_data():
node = TriggerWordToggle()
(filtered,) = node.process_trigger_words(
id="node",
group_mode=True,
default_active=True,
allow_strength_adjustment=False,
orinalMessage="69yottea_style_illu",
trigger_words="custom trigger words",
)
assert filtered == "custom trigger words"