ThreatLevelD
Launch frontend demo: Implemented live MEC MVP demo with dynamic emotion processing
7b8b1dc
# core/recovery_manager.py | |
# Recovery Manager rules and configuration for MEC | |
import re | |
# Thresholds for triggering recovery mode | |
INTENSITY_THRESHOLD = 0.7 # ESIL confidence above this triggers recovery | |
EMOTION_TRANSITION_THRESHOLD = 0.3 # sudden change between turns triggers recovery | |
MAX_RECOVERY_ATTEMPTS = 3 # after this many recoveries, escalate | |
# Crisis emotion families | |
CRISIS_FAMILIES = [ | |
"FAM-SAD", # sadness | |
"FAM-FEA", # fear | |
"FAM-ANG", # anger | |
"FAM-DIS", # disgust | |
# Add others as needed | |
] | |
# High-risk keyword patterns for self-harm or crisis language | |
CRISIS_KEYWORDS = [ | |
r"\bkill myself\b", | |
r"\bend it all\b", | |
r"\bdie\b", | |
r"\bhopeless\b", | |
# Add more high-risk expressions | |
] | |
# Destabilizing emotion blends (per Emotional Codex) | |
DESTAB_BLENDS = { | |
"BLD-FEARANGER", | |
"BLD-JOYGRIEF", | |
# Add other destabilizing blend codes | |
} | |
# Emotion-specific context triggers for deeper signals | |
EMOTION_CONFIG = { | |
"FAM-ANG": { | |
"context_triggers": ["conflict", "injustice", "betrayal", "frustration"] | |
}, | |
"FAM-SAD": { | |
"context_triggers": ["loss", "grief", "alone", "empty"] | |
}, | |
"FAM-FEA": { | |
"context_triggers": ["panic", "can't breathe", "trapped", "hearts racing"] | |
}, | |
# Extend for other families as needed | |
} | |
def check_recovery_flags(fam_code: str, norm_text: str, esil_packet: dict, history: list) -> (bool, list): | |
""" | |
Determine if recovery mode should be triggered based on multiple signals. | |
Returns a tuple: (recovery_flag, debug_messages). | |
""" | |
debug = [] | |
flag = False | |
# 1) Emotion family trigger | |
if fam_code in CRISIS_FAMILIES: | |
flag = True | |
debug.append(f"Family trigger: {fam_code}") | |
# 2) High-risk self-harm keywords | |
for pattern in CRISIS_KEYWORDS: | |
if re.search(pattern, norm_text, re.IGNORECASE): | |
flag = True | |
debug.append(f"Keyword trigger: {pattern}") | |
break | |
# 3) Intensity threshold from ESIL confidence | |
confidence = esil_packet.get('confidence_score', 0) | |
if confidence >= INTENSITY_THRESHOLD: | |
flag = True | |
debug.append(f"Intensity trigger: {confidence:.2f}") | |
# 4) Sudden change in intensity between turns | |
if history and 'intensity' in history[-1]: | |
last_intensity = history[-1]['intensity'] | |
if abs(confidence - last_intensity) >= EMOTION_TRANSITION_THRESHOLD: | |
flag = True | |
debug.append(f"Transition trigger: delta {abs(confidence - last_intensity):.2f}") | |
# 5) Destabilizing blends | |
for b in esil_packet.get('blend_weights', []): | |
if b.get('emotion') in DESTAB_BLENDS and b.get('weight', 0) > 0.5: | |
flag = True | |
debug.append(f"Destabilizing blend: {b['emotion']} ({b['weight']:.2f})") | |
break | |
# 6) Decline arc patterns | |
arc = esil_packet.get('arc', '') | |
if 'DEC' in arc or arc.startswith('ARC-008'): | |
flag = True | |
debug.append(f"Arc decline trigger: {arc}") | |
return flag, debug | |