Files
aionboarding/ai-patient-onboarding/app/ai/extraction/negation_engine.py
T

55 lines
2.5 KiB
Python

"""
Contextual negation and scope resolution engine.
"""
import re
from typing import Dict, Any, Tuple
# Family relations
FAMILY_RELATIONS = [
("father", "father"), ("dad", "father"), ("appa", "father"), ("அப்பா", "father"), ("पिता", "father"), ("नाना", "grandfather"),
("mother", "mother"), ("mom", "mother"), ("amma", "mother"), ("அம்மா", "mother"), ("माँ", "mother"), ("माता", "mother"),
("brother", "brother"), ("annaa", "brother"), ("தம்பி", "brother"), ("अண்ணன்", "brother"), ("भाई", "brother"),
("sister", "sister"), ("akka", "sister"), ("அக்கா", "sister"), ("தங்கை", "sister"), ("बहन", "sister"),
("parent", "parent"), ("grand-father", "grandfather"), ("grandfather", "grandfather"), ("grandmother", "grandmother"),
]
# Negation indicators
NEGATION_PHRASES = [
"don't have", "do not have", "no history of", "no symptoms", "no allergies", "no allergy", "no medicine",
"no medications", "don't take", "do not take", "never had", "without", "denies", "absent",
"இல்லை", "எதுவும் இல்லை", "இல்லவே இல்லை", "மாத்திரை எதுவும் இல்லை", "நோயும் இல்லை",
"नहीं है", "कोई बीमारी नहीं", "कोई एलर्जी नहीं", "कोई दवा नहीं",
"లేవు", "ఏమీ లేదు", "ఇబ్బంది లేదు",
"ಇಲ್ಲ", "ಯಾವುದೇ ಇಲ್ಲ",
]
def is_negated(text: str) -> bool:
"""Returns True if the text expresses explicit negation."""
if not text:
return False
msg_lower = text.lower().strip()
if msg_lower in ["no", "none", "nothing", "no more", "nil", "illness none", "nkda"]:
return True
return any(neg in msg_lower for neg in NEGATION_PHRASES)
def extract_family_subject(text: str) -> Tuple[bool, str, str]:
"""
Checks if text refers to family member rather than the patient.
Returns: (is_family_history, relation, condition_text)
"""
if not text:
return False, "", text
msg_lower = text.lower().strip()
for rel_kw, rel_canonical in FAMILY_RELATIONS:
pattern = rf"\b{re.escape(rel_kw)}\b"
if re.search(pattern, msg_lower) or rel_kw in text:
# Check if patient explicitly negates disease for self in same turn
return True, rel_canonical, text
return False, "", text