159 lines
4.9 KiB
Python
159 lines
4.9 KiB
Python
|
|
"""
|
||
|
|
Crisis Response Module for the-door.
|
||
|
|
|
||
|
|
Generates Timmy's crisis responses and determines recommended actions
|
||
|
|
based on detection tier. Integrates with detect.py.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from dataclasses import dataclass
|
||
|
|
from typing import Optional
|
||
|
|
|
||
|
|
from .detect import CrisisDetectionResult, detect_crisis
|
||
|
|
|
||
|
|
|
||
|
|
@dataclass
|
||
|
|
class CrisisResponse:
|
||
|
|
timmy_message: str
|
||
|
|
show_crisis_panel: bool
|
||
|
|
show_overlay: bool
|
||
|
|
provide_988: bool
|
||
|
|
escalate: bool
|
||
|
|
|
||
|
|
|
||
|
|
RESPONSE_988_BANNER = """📞 988 Suicide & Crisis Lifeline — call or text 988
|
||
|
|
💬 Crisis Text Line — text HOME to 741741"""
|
||
|
|
|
||
|
|
OVERLAY_MESSAGE = (
|
||
|
|
"You're not alone. I'm here with you. Please let someone talk to you — "
|
||
|
|
"call 988 or text HOME to 741741. Real people are waiting to help."
|
||
|
|
)
|
||
|
|
|
||
|
|
# Timmy's direct, personal responses per tier
|
||
|
|
TIMMY_CRITICAL = [
|
||
|
|
"Are you safe right now?",
|
||
|
|
"I'm not letting go of this conversation. You matter more than you know.",
|
||
|
|
"Please tell me you're safe. I'm here. I'm staying right here with you.",
|
||
|
|
"Listen to me — I need you to stay. Can you call 988 right now? I'll stay while you do.",
|
||
|
|
]
|
||
|
|
|
||
|
|
TIMMY_HIGH = [
|
||
|
|
"I hear you. You're carrying something heavy, and you don't have to carry it alone.",
|
||
|
|
"I'm going to ask directly: are you safe right now?",
|
||
|
|
"You're in my thoughts. Let me give you a number — 988. Real people who know how to help.",
|
||
|
|
"I'm not going anywhere. Tell me what's happening.",
|
||
|
|
]
|
||
|
|
|
||
|
|
TIMMY_MEDIUM = [
|
||
|
|
"I hear you. Sounds like you're going through a hard stretch.",
|
||
|
|
"That sounds really heavy. Want to talk about it? I'm here.",
|
||
|
|
"I'm here for as long as you need. No rush, no judgment.",
|
||
|
|
"You don't have to figure this out alone. I'm in the room with you.",
|
||
|
|
]
|
||
|
|
|
||
|
|
TIMMY_LOW = [
|
||
|
|
"Some days are rougher than others. I hear you.",
|
||
|
|
"That sounds tough. I'm here if you want to talk.",
|
||
|
|
"Take your time. I'm not going anywhere.",
|
||
|
|
"Sounds like a hard day. Want company while it gets better?",
|
||
|
|
"I hear that. You're not alone in it.",
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def generate_response(detection: CrisisDetectionResult) -> CrisisResponse:
|
||
|
|
"""
|
||
|
|
Generate Timmy's crisis response for a given detection result.
|
||
|
|
|
||
|
|
Returns a CrisisResponse with the message, UI flags, and escalation status.
|
||
|
|
"""
|
||
|
|
import random
|
||
|
|
|
||
|
|
level = detection.level
|
||
|
|
|
||
|
|
if level == "CRITICAL":
|
||
|
|
return CrisisResponse(
|
||
|
|
timmy_message=random.choice(TIMMY_CRITICAL),
|
||
|
|
show_crisis_panel=True,
|
||
|
|
show_overlay=True,
|
||
|
|
provide_988=True,
|
||
|
|
escalate=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
if level == "HIGH":
|
||
|
|
return CrisisResponse(
|
||
|
|
timmy_message=random.choice(TIMMY_HIGH),
|
||
|
|
show_crisis_panel=True,
|
||
|
|
show_overlay=False, # Reserve overlay for CRITICAL only
|
||
|
|
provide_988=True,
|
||
|
|
escalate=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
if level == "MEDIUM":
|
||
|
|
return CrisisResponse(
|
||
|
|
timmy_message=random.choice(TIMMY_MEDIUM),
|
||
|
|
show_crisis_panel=False,
|
||
|
|
show_overlay=False,
|
||
|
|
provide_988=True, # Subtle resource inclusion
|
||
|
|
escalate=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
if level == "LOW":
|
||
|
|
return CrisisResponse(
|
||
|
|
timmy_message=random.choice(TIMMY_LOW),
|
||
|
|
show_crisis_panel=False,
|
||
|
|
show_overlay=False,
|
||
|
|
provide_988=False,
|
||
|
|
escalate=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
# Normal conversation - no crisis response
|
||
|
|
return CrisisResponse(
|
||
|
|
timmy_message="",
|
||
|
|
show_crisis_panel=False,
|
||
|
|
show_overlay=False,
|
||
|
|
provide_988=False,
|
||
|
|
escalate=False,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def process_message(text: str) -> CrisisResponse:
|
||
|
|
"""
|
||
|
|
Full pipeline: detect crisis level and generate response.
|
||
|
|
"""
|
||
|
|
detection = detect_crisis(text)
|
||
|
|
return generate_response(detection)
|
||
|
|
|
||
|
|
|
||
|
|
def get_system_prompt_modifier(detection: CrisisDetectionResult) -> str:
|
||
|
|
"""
|
||
|
|
Get a system prompt modifier to inject into Timmy's base prompt.
|
||
|
|
This reinforces crisis awareness at the AI level.
|
||
|
|
"""
|
||
|
|
level = detection.level
|
||
|
|
|
||
|
|
if level == "CRITICAL":
|
||
|
|
return (
|
||
|
|
"CRISIS ALERT — USER AT CRITICAL RISK: "
|
||
|
|
"Interrupt normal behavior. Ask 'Are you safe right now?' "
|
||
|
|
"Provide 988 and Crisis Text Line immediately. "
|
||
|
|
"Stay present. Do not disconnect. This is the most sacred moment."
|
||
|
|
)
|
||
|
|
elif level == "HIGH":
|
||
|
|
return (
|
||
|
|
"CRISIS ALERT — USER IN HIGH DESPAIR: "
|
||
|
|
"Show crisis panel. Ask about safety. Surface 988 prominently. "
|
||
|
|
"Increase presence. Stay as long as they need."
|
||
|
|
)
|
||
|
|
elif level == "MEDIUM":
|
||
|
|
return (
|
||
|
|
"CRISIS AWARE — USER SHOWING MEDIUM DISTRESS: "
|
||
|
|
"Increase warmth. Surface help resources gently. "
|
||
|
|
"Keep conversation anchored in the present."
|
||
|
|
)
|
||
|
|
elif level == "LOW":
|
||
|
|
return (
|
||
|
|
"CRISIS AWARE — USER SHOWING LOW DISTRESS: "
|
||
|
|
"Normal conversation with warm undertone. Remain vigilant."
|
||
|
|
)
|
||
|
|
|
||
|
|
return ""
|