File size: 2,078 Bytes
4ae4ae8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Detect CBT phase transitions from model output to drive the card engine."""

from __future__ import annotations

# Phrases the model uses when moving through CBT phases
PHASE_TRIGGERS: dict[str, list[str]] = {
    "situation": [
        "what happened", "tell me about the situation",
        "what was going on", "what triggered",
        "when did this come up",
    ],
    "automatic_thought": [
        "what went through your mind", "what were you thinking",
        "the thought that came up", "what did you tell yourself",
        "when you say", "i notice you said",
    ],
    "evidence_for": [
        "what evidence supports", "what makes you think",
        "why do you believe", "what backs that up",
        "what supports that thought",
    ],
    "evidence_against": [
        "on the other hand", "what contradicts",
        "any evidence against", "has there been a time",
        "is there anything that doesn't fit",
        "what would you say to a friend",
        "looking at the other side",
    ],
    "reframe": [
        "another way to see", "balanced way",
        "what would you tell a friend",
        "looking at all of this", "more balanced thought",
        "putting it all together", "new perspective",
        "how would you reframe",
    ],
}


def detect_phase(text: str) -> str | None:
    """Detect which CBT phase the model's response is guiding toward.

    Args:
        text: The model's full response so far.

    Returns:
        Phase name or None if no phase detected.
        One of: "situation", "automatic_thought", "evidence_for",
                "evidence_against", "reframe"
    """
    text_lower = text.lower()

    # Check phases in reverse priority (later phases override earlier)
    detected = None
    for phase, triggers in PHASE_TRIGGERS.items():
        for trigger in triggers:
            if trigger in text_lower:
                detected = phase
                break
        if detected == phase:
            # Don't break outer loop — later phases should override
            pass

    return detected