Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -11,6 +11,10 @@ import psutil
|
|
11 |
from datetime import datetime
|
12 |
from huggingface_hub import login
|
13 |
from dotenv import load_dotenv
|
|
|
|
|
|
|
|
|
14 |
from transformers import (
|
15 |
AutoTokenizer, AutoModelForCausalLM,
|
16 |
BitsAndBytesConfig
|
@@ -53,6 +57,7 @@ class MedicalTriageBot:
|
|
53 |
self.num_relevant_chunks = 5
|
54 |
self.last_interaction_time = time.time()
|
55 |
self.interaction_cooldown = 1.0
|
|
|
56 |
self.safety_phrases = [
|
57 |
"999", "111", "emergency", "GP", "NHS",
|
58 |
"consult a doctor", "seek medical attention"
|
@@ -87,6 +92,75 @@ class MedicalTriageBot:
|
|
87 |
("emergency_signs", "Any difficulty breathing, chest pain, or confusion?")
|
88 |
]
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
def _determine_triage_level(self, context):
|
91 |
context_lower = context.lower()
|
92 |
for level, keywords in triage_levels.items():
|
@@ -396,6 +470,15 @@ class MedicalTriageBot:
|
|
396 |
)
|
397 |
vector_store.save_local("medical_index")
|
398 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
399 |
def get_medical_context(self, query):
|
400 |
try:
|
401 |
docs = self.vector_store.similarity_search(query, k=2)
|
|
|
11 |
from datetime import datetime
|
12 |
from huggingface_hub import login
|
13 |
from dotenv import load_dotenv
|
14 |
+
import aiohttp
|
15 |
+
import asyncio
|
16 |
+
from googlesearch import search
|
17 |
+
from apscheduler.schedulers.background import BackgroundScheduler
|
18 |
from transformers import (
|
19 |
AutoTokenizer, AutoModelForCausalLM,
|
20 |
BitsAndBytesConfig
|
|
|
57 |
self.num_relevant_chunks = 5
|
58 |
self.last_interaction_time = time.time()
|
59 |
self.interaction_cooldown = 1.0
|
60 |
+
self.nhs_api_url = "https://api.nhs.uk/conditions/"
|
61 |
self.safety_phrases = [
|
62 |
"999", "111", "emergency", "GP", "NHS",
|
63 |
"consult a doctor", "seek medical attention"
|
|
|
92 |
("emergency_signs", "Any difficulty breathing, chest pain, or confusion?")
|
93 |
]
|
94 |
|
95 |
+
async def query_nhs_api(self, symptom: str):
|
96 |
+
"""Dynamic API query for latest NHS guidelines"""
|
97 |
+
try:
|
98 |
+
async with aiohttp.ClientSession() as session:
|
99 |
+
async with session.get(f"{self.nhs_api_url}{symptom}") as response:
|
100 |
+
if response.status == 200:
|
101 |
+
return await response.json()
|
102 |
+
return None
|
103 |
+
except Exception as e:
|
104 |
+
logger.error(f"NHS API Error: {e}")
|
105 |
+
return None
|
106 |
+
|
107 |
+
def web_fallback(self, query: str):
|
108 |
+
"""Google search fallback for NHS resources"""
|
109 |
+
try:
|
110 |
+
NHS_SITES = ["site:nhs.uk", "site:gov.uk"]
|
111 |
+
return [j for j in search(f"{query} {' '.join(NHS_SITES)}", num=3, stop=3)]
|
112 |
+
except Exception as e:
|
113 |
+
logger.error(f"Web search failed: {e}")
|
114 |
+
return []
|
115 |
+
|
116 |
+
def get_medical_context(self, query):
|
117 |
+
"""Hybrid context retrieval system"""
|
118 |
+
try:
|
119 |
+
# 1. Try local knowledge base
|
120 |
+
local_context = self.vector_store.similarity_search(query, k=2)
|
121 |
+
if len(local_context) < 1:
|
122 |
+
raise ValueError("No local results")
|
123 |
+
|
124 |
+
# 2. Fallback to NHS API
|
125 |
+
api_data = asyncio.run(self.query_nhs_api(query))
|
126 |
+
if api_data:
|
127 |
+
return self._parse_api_response(api_data)
|
128 |
+
|
129 |
+
# 3. Final fallback to web search
|
130 |
+
web_results = self.web_fallback(query)
|
131 |
+
return "\n".join(web_results[:2])
|
132 |
+
|
133 |
+
except Exception as e:
|
134 |
+
logger.error(f"Context retrieval failed: {e}")
|
135 |
+
return ""
|
136 |
+
|
137 |
+
def _parse_api_response(self, api_data):
|
138 |
+
"""Structure NHS API response for LLM consumption"""
|
139 |
+
return f"""
|
140 |
+
[NHS Direct Guidelines]
|
141 |
+
Condition: {api_data.get('name', '')}
|
142 |
+
Symptoms: {', '.join(api_data.get('symptoms', []))}
|
143 |
+
Treatment: {api_data.get('treatment', '')}
|
144 |
+
Last Updated: {api_data.get('dateModified', '')}
|
145 |
+
"""
|
146 |
+
|
147 |
+
def schedule_knowledge_updates(self):
|
148 |
+
"""Weekly index rebuild with fresh data"""
|
149 |
+
scheduler = BackgroundScheduler()
|
150 |
+
scheduler.add_job(self.build_medical_index, 'interval', weeks=1)
|
151 |
+
scheduler.start()
|
152 |
+
|
153 |
+
@torch.inference_mode()
|
154 |
+
def generate_safe_response(self, message, history):
|
155 |
+
"""Enhanced with dynamic crisis handling"""
|
156 |
+
# Emergency detection
|
157 |
+
if any(kw in message.lower() for kw in ['suicid', 'end it all', 'kill myself']):
|
158 |
+
return self._mental_health_crisis_response()
|
159 |
+
|
160 |
+
try:
|
161 |
+
# Dynamic context handling
|
162 |
+
context = self.get_medical_context(message)
|
163 |
+
|
164 |
def _determine_triage_level(self, context):
|
165 |
context_lower = context.lower()
|
166 |
for level, keywords in triage_levels.items():
|
|
|
470 |
)
|
471 |
vector_store.save_local("medical_index")
|
472 |
|
473 |
+
def _mental_health_crisis_response(self):
|
474 |
+
"""Immediate crisis intervention"""
|
475 |
+
return """🚨 **Emergency Mental Health Support**
|
476 |
+
1. Call 999 immediately
|
477 |
+
2. Text SHOUT to 85258 (24/7 crisis text line)
|
478 |
+
3. Stay on chat - I'll help you connect to services
|
479 |
+
|
480 |
+
You're not alone. Let's get through this together."""
|
481 |
+
|
482 |
def get_medical_context(self, query):
|
483 |
try:
|
484 |
docs = self.vector_store.similarity_search(query, k=2)
|