92 lines
5.2 KiB
Python
92 lines
5.2 KiB
Python
"""
|
|
Emergency detection engine with strict safety precedence and false-positive protection.
|
|
"""
|
|
|
|
import re
|
|
from typing import Optional, Tuple
|
|
|
|
from app.ai.prompt_rules.safety_rules import EMERGENCY_KEYWORDS_EN, EMERGENCY_KEYWORDS_INDIC
|
|
|
|
|
|
TRANSLITERATED_EMERGENCY_PHRASES = [
|
|
"nenju romba valikuthu", "nenju valla valikuthu", "nenju kadumaya valikuthu",
|
|
"moochu vida mudiyala", "moochu adaikuthu", "moochu thinaral",
|
|
"mayangi vilunthuten", "mayakkam varuthu", "paralysis vanthuruchu",
|
|
"cheest mein bahut dard", "seene mein bahut tej dard", "saans lene mein bahut dikkat",
|
|
"saans nahi aa rahi", "behosh ho gaya", "behosh ho gayi",
|
|
"chathi lo thivramaina noppi", "oophiri aadam ledhu", "spruha thappi",
|
|
"edeyalli theevra novu", "usiraadalu thumba kashta", "pragne thappi",
|
|
]
|
|
|
|
|
|
def check_emergency(user_message: str, lang: str = "en") -> Tuple[bool, Optional[str], Optional[str]]:
|
|
"""
|
|
Evaluates patient message for medical emergency indicators.
|
|
Returns: (is_emergency, reason, emergency_reply)
|
|
"""
|
|
if not user_message or not user_message.strip():
|
|
return False, None, None
|
|
|
|
# Check Indic script emergency keywords against raw user_message FIRST
|
|
for kw in EMERGENCY_KEYWORDS_INDIC:
|
|
if kw in user_message:
|
|
reply = _build_emergency_reply(lang)
|
|
return True, f"Matched Indic emergency phrase: '{kw}'", reply
|
|
|
|
# Additional Tamil/Hindi spoken emergency phrases
|
|
indic_extra = ["மூச்சு விட முடியல", "மூச்சு திணறல்", "நெஞ்சு வலி", "நெஞ்சு பாரம்", "கடும் நெஞ்சு வலி", "நெஞ்சு அதிகமா வலி"]
|
|
for kw in indic_extra:
|
|
if kw in user_message and any(x in user_message for x in ["மூச்சு", "கடும்", "வலி", "அதிகமா"]):
|
|
reply = _build_emergency_reply(lang)
|
|
return True, f"Matched Indic emergency phrase: '{kw}'", reply
|
|
|
|
msg = user_message.strip().lower()
|
|
msg_clean = re.sub(r"[^\w\s]", " ", msg)
|
|
msg_clean = re.sub(r"\s+", " ", msg_clean)
|
|
|
|
# False Positive Protection: Negated emergency statements ("no chest pain")
|
|
negation_patterns = [
|
|
r"\bno\s+(?:chest\s+pain|breathing\s+difficulty|heart\s+attack|paralysis|bleeding)\b",
|
|
r"\bdon't\s+have\s+(?:chest\s+pain|breathing\s+difficulty|heart\s+attack)\b",
|
|
r"\bnot\s+having\s+(?:chest\s+pain|breathing\s+difficulty)\b",
|
|
r"\bnever\s+had\s+(?:chest\s+pain|breathing\s+difficulty)\b",
|
|
r"\billness\s+none\b",
|
|
]
|
|
for neg_pat in negation_patterns:
|
|
if re.search(neg_pat, msg_clean):
|
|
if not any(pos in msg_clean for pos in ["severe chest pain", "cannot breathe", "collapsed"]):
|
|
return False, None, None
|
|
|
|
# Check English emergency keywords
|
|
for kw in EMERGENCY_KEYWORDS_EN:
|
|
if re.search(rf"\b{re.escape(kw)}\b", msg_clean):
|
|
reply = _build_emergency_reply(lang)
|
|
return True, f"Matched emergency phrase: '{kw}'", reply
|
|
|
|
# Check combinations (e.g. "chest pain" AND "difficulty breathing")
|
|
if "chest pain" in msg_clean and ("breath" in msg_clean or "shortness" in msg_clean or "difficulty" in msg_clean):
|
|
reply = _build_emergency_reply(lang)
|
|
return True, "Matched combined chest pain and breathing difficulty", reply
|
|
|
|
# Check Transliterated emergency phrases
|
|
for kw in TRANSLITERATED_EMERGENCY_PHRASES:
|
|
if kw in msg_clean:
|
|
reply = _build_emergency_reply(lang)
|
|
return True, f"Matched transliterated emergency phrase: '{kw}'", reply
|
|
|
|
return False, None, None
|
|
|
|
|
|
def _build_emergency_reply(lang: str) -> str:
|
|
lang_clean = lang.lower() if lang else "en"
|
|
if lang_clean.startswith("ta"):
|
|
return "இது அவசர மருத்துவ உதவி தேவைப்படும் நிலை. தயவுசெய்து உடனடியாக அருகில் உள்ள மருத்துவமனை அவசர சிகிச்சைப் பிரிவுக்குச் செல்லவும்."
|
|
elif lang_clean.startswith("hi"):
|
|
return "यह एक आपातकालीन स्थिति हो सकती है। कृपया तुरंत निकटतम अस्पताल के आपातकालीन कक्ष (ER) में जाएँ।"
|
|
elif lang_clean.startswith("te"):
|
|
return "ఇది అత్యవసర వైద్య పరిస్థితి కావచ్చు. దయచేసి వెంటనే దగ్గరలోని ఆసుపత్రి ఎమర్జెన్సీ విభాగానికి వెళ్ళండి."
|
|
elif lang_clean.startswith("kn"):
|
|
return "ಇದು ತುರ್ತು ವೈದ್ಯಕೀಯ ಪರಿಸ್ಥಿತಿಯಾಗಿರಬಹುದು. ದಯವಿಟ್ಟು ತಕ್ಷಣ ಹತ್ತಿರದ ಆಸ್ಪತ್ರೆಯ ತುರ್ತು ವಿಭಾಗಕ್ಕೆ ಹೋಗಿ."
|
|
else:
|
|
return "This requires urgent medical attention. Please inform the nearest hospital staff or proceed directly to the Emergency Room right away."
|