File size: 3,066 Bytes
7b8b1dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 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