PearlIsa commited on
Commit
0b963d7
·
verified ·
1 Parent(s): b472580

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -0
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)