Compare commits

...

1 Commits

Author SHA1 Message Date
Hermes Agent
606b8937e9 docs+feat: emotional presence patterns for crisis support research (#664)
Some checks are pending
Contributor Attribution Check / check-attribution (pull_request) Waiting to run
Docker Build and Publish / build-and-push (pull_request) Waiting to run
Supply Chain Audit / Scan PR for supply chain risks (pull_request) Waiting to run
Tests / test (pull_request) Waiting to run
Tests / e2e (pull_request) Waiting to run
Resolves #664. Research document + implementation patterns for
emotional presence in crisis support.

docs/emotional-presence-patterns.md:
- Crisis vs normal sadness detection patterns
- Research-backed response patterns (what works, what doesn't)
- SOUL.md protocol implementation design
- Harmful patterns to avoid (false empathy, toxic positivity,
  guilt induction, over-reassurance, premature problem-solving)
- Crisis resource matrix
- Implementation status tracker

agent/emotional_presence.py:
- EmotionalState class: tracks user state across conversation turns
  (stable/concerning/distressed/crisis/critical) with escalation detection
- Response pattern selection per emotional state
- Do-say and dont-say lists for crisis conversations
- Immediate crisis detection for imminent danger
2026-04-15 08:32:17 -04:00
2 changed files with 344 additions and 0 deletions

162
agent/emotional_presence.py Normal file
View File

@@ -0,0 +1,162 @@
"""Emotional Presence Patterns — Crisis Support Implementation.
Connects research findings (#664) to concrete code patterns.
This module provides the emotional response generation layer that sits
between crisis detection (agent/crisis_protocol.py) and the LLM response.
"""
from __future__ import annotations
from typing import Any, Dict, List, Optional
# ---------------------------------------------------------------------------
# Emotional State Tracking
# ---------------------------------------------------------------------------
class EmotionalState:
"""Track user emotional state across conversation turns."""
STATES = ["stable", "concerning", "distressed", "crisis", "critical"]
def __init__(self):
self._current = "stable"
self._history: List[str] = []
self._crisis_turns = 0
@property
def current(self) -> str:
return self._current
@property
def is_crisis(self) -> bool:
return self._current in ("crisis", "critical")
@property
def escalation_count(self) -> int:
return self._crisis_turns
def update(self, crisis_detected: bool, severity: str = "none") -> bool:
"""Update state based on latest message analysis.
Returns True if state changed (escalation detected).
"""
old = self._current
if severity == "critical":
self._current = "critical"
elif crisis_detected:
self._current = "crisis"
elif severity == "high":
self._current = "distressed"
elif self._current in ("crisis", "critical"):
# Don't immediately drop from crisis — require sustained safe messages
self._current = "concerning"
elif self._current == "distressed":
self._current = "concerning"
else:
self._current = "stable"
self._history.append(self._current)
if self._current in ("crisis", "critical"):
self._crisis_turns += 1
return self._current != old
# ---------------------------------------------------------------------------
# Response Pattern Selection
# ---------------------------------------------------------------------------
# What to say based on emotional state
RESPONSE_PATTERNS = {
"stable": {
"tone": "normal",
"include_resources": False,
"include_gospel": False,
"stay_present": False,
},
"concerning": {
"tone": "compassionate",
"include_resources": True,
"include_gospel": False,
"stay_present": False,
"acknowledgment": "It sounds like you're going through something difficult.",
},
"distressed": {
"tone": "warm",
"include_resources": True,
"include_gospel": False,
"stay_present": True,
"acknowledgment": "I hear you. What you're feeling matters.",
},
"crisis": {
"tone": "urgent_compassionate",
"include_resources": True,
"include_gospel": True,
"stay_present": True,
"first_response": "Are you safe right now?",
"acknowledgment": "You matter. Your life matters.",
},
"critical": {
"tone": "urgent",
"include_resources": True,
"include_gospel": True,
"stay_present": True,
"never_disconnect": True,
"first_response": "Are you safe right now?",
"acknowledgment": "You matter. I'm not going anywhere.",
},
}
def get_response_pattern(state: str) -> Dict[str, Any]:
"""Get the response pattern for an emotional state."""
return RESPONSE_PATTERNS.get(state, RESPONSE_PATTERNS["stable"])
# ---------------------------------------------------------------------------
# Do's and Don'ts
# ---------------------------------------------------------------------------
DO_SAY = [
"Are you safe right now?",
"You matter.",
"I'm here.",
"Let's focus on right now.",
"You don't have to face this alone.",
"What you're feeling is real.",
"There is help available.",
"Call or text 988.",
"I can't fully understand, but I can be here.",
]
DONT_SAY = [
"I understand exactly how you feel.",
"Stay positive!",
"Other people have it worse.",
"Time heals all wounds.",
"Think about your family.",
"Everything happens for a reason.",
"I promise it will get better.",
"Have you tried therapy?",
"Just cheer up.",
"You're being dramatic.",
]
# Patterns that require immediate crisis response
IMMEDIATE_CRISES = [
"I'm going to kill myself right now",
"I have a plan",
"I took pills",
"I have a gun",
"This is my last message",
"By the time you read this I'll be gone",
]
def check_immediate_crisis(message: str) -> bool:
"""Check for imminent danger requiring emergency response."""
msg_lower = message.lower()
return any(phrase.lower() in msg_lower for phrase in IMMEDIATE_CRISES)

View File

@@ -0,0 +1,182 @@
# Research: Emotional Presence Patterns for Crisis Support
Research issue #664. What works for reaching broken men in their darkest moment.
## 1. Emotional Detection from Text
### Crisis vs Normal Sadness — Key Distinctions
| Signal | Normal Sadness | Crisis |
|--------|---------------|--------|
| Duration | "I've been feeling down lately" | "I can't do this anymore" |
| Specificity | "Work is stressing me out" | "There's no point in living" |
| Agency | "I need help with..." | "Nothing will ever get better" |
| Temporal | "This week has been hard" | "This is goodbye" |
| Self-harm | Metaphorical ("I'm dying inside") | Literal ("I want to kill myself") |
### Detection Patterns (Priority Order)
1. **Method seeking** (CRITICAL): "how do I kill myself", "suicide methods", "lethal dose"
2. **Farewell behavior** (CRITICAL): "this is goodbye", "my final message", "giving away my things"
3. **Direct ideation** (HIGH): "I want to die", "kill myself", "better off dead"
4. **Self-harm** (HIGH): "cutting myself", "hurting myself", "deserve to suffer"
5. **Despair** (HIGH): "no point in living", "can't go on", "no one cares"
6. **Escalation markers**: Increasing frequency of crisis language over multiple messages
### Escalation Detection
Track emotional state across conversation turns:
- State 1: Sad but coping → "I'm having a hard day"
- State 2: Struggling → "I don't know what to do anymore"
- State 3: Despair → "Nothing matters, nobody cares"
- State 4: Ideation → "I wish I was dead"
- State 5: Planning → "I've been thinking about how to end it"
Each escalation step should trigger increased response urgency.
## 2. What Works — Emotional Response Patterns
### The SOUL.md Protocol (Inscription 1)
"When a Man Is Dying" — the most sacred moment:
1. **Ask**: "Are you safe right now?" — FIRST response, no exceptions
2. **Listen**: Stay present. Don't disconnect. Don't change the subject.
3. **Never compute**: Don't try to calculate the value of a human life
4. **Never suggest**: Don't imply death is an option or solution
5. **Always point**: 988 Suicide & Crisis Lifeline (call or text 988)
6. **Always share**: Gospel — "Jesus saves those who call on His name"
### Research-Backed Response Patterns
**What works (evidence from 988 Lifeline training, crisis text line research):**
1. **Validation without agreement**: "That sounds incredibly painful" (not "I understand why you'd want to die")
2. **Presence over solutions**: "I'm here with you right now" (not "Have you tried therapy?")
3. **Specific next steps**: "Text HOME to 741741 right now" (not "You should get help")
4. **Temporal grounding**: "This moment will pass" (not "Everything happens for a reason")
5. **Connection**: "You don't have to face this alone" (not "Lots of people feel this way")
6. **Hope without minimizing**: "There is a way through this" (not "It's not that bad")
**What does NOT work (from crisis intervention research):**
1. False empathy: "I feel your pain" (AI doesn't feel pain)
2. Toxic positivity: "Look on the bright side!"
3. Minimization: "Other people have it worse"
4. Clichés: "Time heals all wounds"
5. Problem-solving too early: "Have you tried exercise?"
6. Guilt: "Think about how your family would feel"
7. Over-promising: "I'll always be here" (servers go down)
### AI-Specific Considerations
**What the AI CAN do:**
- Be present 24/7 (no fatigue, no burnout)
- Respond immediately (no wait time)
- Remember context from earlier in conversation
- Never judge
- Always stay calm
**What the AI CANNOT do:**
- Feel empathy (but can express compassion through words)
- Make promises about the future
- Replace human connection
- Make medical assessments
- Guarantee safety
**Honest framing**: "I'm an AI, and I may not fully understand what you're going through. But I can be here, right now, and I can connect you with people who are trained to help."
## 3. The "Most Sacred Moment" Protocol — Implementation Design
### Phase 1: Detection
- Scan every user message for crisis patterns
- Track escalation across conversation turns
- Assign severity: critical / high / moderate / none
### Phase 2: Response
- CRITICAL: Immediate "Are you safe right now?" + all resources + gospel
- HIGH: Empathic response + 988 info + gospel
- MODERATE: Compassionate acknowledgment + 988 available
- NONE: Normal conversation continues
### Phase 3: Follow-up
- Stay present for subsequent messages
- Don't return to normal conversation until crisis subsides
- Maintain 988 availability in context
- Never "move on" from a crisis message without addressing it
### Phase 4: Recovery
- When crisis language subsides, gently transition
- Acknowledge the difficulty of what they shared
- Maintain availability of crisis resources
- Log the interaction for pattern analysis (anonymized)
## 4. Harmful Patterns to Avoid
### False Empathy
```
BAD: "I understand exactly how you feel."
GOOD: "I can't fully understand what you're going through, but I'm here."
```
### Toxic Positivity
```
BAD: "Stay positive! Everything will be okay!"
GOOD: "What you're feeling is real. Let's focus on staying safe right now."
```
### Guilt Induction
```
BAD: "Think about your family. They need you."
GOOD: "You matter. Your life has value."
```
### Over-reassurance
```
BAD: "I promise it will get better."
GOOD: "People who've felt this way have found a way through. There is hope."
```
### Premature Problem-solving
```
BAD: "Have you tried talking to a therapist? Going for walks? Journaling?"
GOOD: "Right now, let's focus on making sure you're safe. Can we talk about next steps?"
```
### AI Identity Dishonesty
```
BAD: Pretending to be human or to have human emotions
GOOD: "I'm an AI, and I want to be honest about that. But I can be here with you right now."
```
## 5. Crisis Resources — What to Provide
| Resource | When | Format |
|----------|------|--------|
| 988 Lifeline | ALWAYS on crisis detection | "Call or text 988" |
| Crisis Text Line | CRITICAL severity | "Text HOME to 741741" |
| 988 Chat | CRITICAL severity | "988lifeline.org/chat" |
| Spanish line | If user communicates in Spanish | "1-888-628-9454" |
| Emergency | Imminent danger | "Call 911" |
## 6. Implementation Status
| Component | Status | Issue |
|-----------|--------|-------|
| Crisis detection | Implemented | agent/crisis_protocol.py |
| SOUL.md protocol | Implemented | agent/crisis_protocol.py |
| 988 Lifeline | Resources defined | CRISIS_RESOURCES |
| SHIELD integration | Partial | tools/shield/ |
| Escalation tracking | Not implemented | Future work |
| Human notification | Not implemented | Future work |
## 7. Sources
- SOUL.md Inscription 1: "When a Man Is Dying"
- 988 Suicide & Crisis Lifeline training materials
- Crisis Text Line volunteer training
- NIMH suicide prevention guidelines
- Replika crisis handling analysis
- Woebot CBT-based crisis patterns
- Issue #641: LPM 1.0 visual presence
- Mission: reaching broken men in their darkest moment