from collections.abc import AsyncGenerator from backend.app.guardrails.safety import is_unsafe_prompt, needs_human_review from backend.app.models.schemas import ChatMessage, ChatResponse, IncidentClassificationResponse def _last_user_message(messages: list[ChatMessage]) -> str: for message in reversed(messages): if message.role == "user": return message.content return "" NEPALI_GUIDANCE = ( "आपतकालीन प्रतिक्रियाको सुझावकात विधिहरू: " "तत्काल खतरा मूल्याङ्कन गर्नुहोस्, " "सुरक्षित ठाउँमा जानुहोस्, " "आपतकालीन सेवा (१०१ / १०२) मा फोन गर्नुहोस्, " "कमजोर वर्गको सुरक्षा गर्नुहोस्, " "र हर १५ मिनेटमा आधिकारिक सूचना अनुसरण गर्नुहोस्।" ) def generate_response(messages: list[ChatMessage], language: str, region: str) -> ChatResponse: user_text = _last_user_message(messages) if is_unsafe_prompt(user_text): return ChatResponse( answer=( "I cannot provide guidance for unsafe actions. Contact local emergency authorities " "and follow official evacuation and safety protocols immediately." ), confidence=0.99, needs_human_review=True, citations=["Local emergency management authority", "Official public safety bulletins"], ) if language.strip().lower() in {"nepali", "ne", "नेपाली"}: return ChatResponse( answer=f"[WorldDisasterLM-8B | नेपाली | {region}] {NEPALI_GUIDANCE}", confidence=0.74, needs_human_review=False, citations=[ "NDRRMA नेपाल विपद् व्यवस्थापन प्राधिकरण", "WHO आपतकालीन प्रतिक्रिया मार्गदर्शन", "UNDRR Sendai Framework 2015-2030", ], ) answer = ( f"[WorldDisasterLM-8B | {language} | {region}] Recommended next steps: assess immediate hazards, move to a safe " "location, call emergency services, protect vulnerable groups, and verify updates from " "official alerts every 15 minutes." ) confidence = 0.74 return ChatResponse( answer=answer, confidence=confidence, needs_human_review=needs_human_review(confidence, answer), citations=["UNDRR preparedness guidelines", "WHO emergency response guidance"], ) async def stream_response(messages: list[ChatMessage], language: str, region: str) -> AsyncGenerator[str, None]: response = generate_response(messages, language=language, region=region) for token in response.answer.split(): yield token + " " def classify_incident(text: str) -> IncidentClassificationResponse: lowered = text.lower() mapping = { "earthquake": "earthquake", "tsunami": "tsunami", "flood": "flood", "wildfire": "wildfire", "pandemic": "public_health", "epidemic": "public_health", "chemical": "industrial", "nuclear": "industrial", "refugee": "humanitarian", "drought": "climate", "heatwave": "climate", } incident_type = "unknown" for keyword, event_type in mapping.items(): if keyword in lowered: incident_type = event_type break if any(token in lowered for token in ["mass", "collapse", "critical", "urgent", "dead"]): severity = "critical" elif any(token in lowered for token in ["severe", "major", "injured", "evacuate"]): severity = "high" elif any(token in lowered for token in ["moderate", "contained", "localized"]): severity = "medium" else: severity = "low" return IncidentClassificationResponse( incident_type=incident_type, severity=severity, rationale="Keyword and severity heuristic classifier; replace with fine-tuned classifier model.", )