""" 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."