BilalS96 commited on
Commit
92c803c
Β·
verified Β·
1 Parent(s): fb7fdf6

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. app.py +396 -221
  2. requirements.txt +4 -0
app.py CHANGED
@@ -1,304 +1,479 @@
1
  """
2
  MedGuard - Healthcare Multi-Agent Medication Safety System
3
- Hugging Face Space Entry Point
4
 
5
  MCP 1st Birthday Hackathon Submission
6
  """
7
  import gradio as gr
8
  import os
9
- from typing import Dict, Any, List
10
  import json
 
 
11
 
12
- # For HF Spaces, we'll use a simplified demo version
13
- # that showcases the agent architecture without requiring
14
- # full database connections
15
 
16
- class MedGuardDemo:
17
- """Demo version of MedGuard for Hugging Face Spaces."""
18
-
19
- def __init__(self):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  self.demo_patients = {
21
- "P001": {
22
- "name": "John Smith",
23
- "age": 67,
24
- "conditions": ["Hypertension", "Type 2 Diabetes", "Atrial Fibrillation"],
 
25
  "medications": [
26
- {"name": "Warfarin", "dose": "5mg", "frequency": "daily"},
27
- {"name": "Metformin", "dose": "1000mg", "frequency": "twice daily"},
28
- {"name": "Lisinopril", "dose": "20mg", "frequency": "daily"},
29
- {"name": "Aspirin", "dose": "81mg", "frequency": "daily"}
30
  ],
31
- "allergies": ["Penicillin", "Sulfa drugs"]
32
  },
33
- "P002": {
34
- "name": "Maria Garcia",
35
  "age": 45,
36
- "conditions": ["Depression", "Chronic Pain", "Insomnia"],
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  "medications": [
38
- {"name": "Sertraline", "dose": "100mg", "frequency": "daily"},
39
- {"name": "Tramadol", "dose": "50mg", "frequency": "as needed"},
40
- {"name": "Zolpidem", "dose": "10mg", "frequency": "at bedtime"}
41
  ],
42
  "allergies": []
43
  },
44
- "P003": {
45
  "name": "Robert Chen",
46
  "age": 72,
 
47
  "conditions": ["Heart Failure", "COPD", "Chronic Kidney Disease"],
48
  "medications": [
49
- {"name": "Furosemide", "dose": "40mg", "frequency": "daily"},
50
- {"name": "Carvedilol", "dose": "25mg", "frequency": "twice daily"},
51
- {"name": "Potassium Chloride", "dose": "20mEq", "frequency": "daily"},
52
- {"name": "Albuterol", "dose": "2 puffs", "frequency": "as needed"}
53
  ],
54
  "allergies": ["Iodine contrast"]
55
  }
56
  }
57
-
58
- # Known drug interactions for demo
59
- self.interactions = {
60
- ("Warfarin", "Aspirin"): {
61
- "severity": "HIGH",
62
- "type": "Pharmacodynamic",
63
- "description": "Increased bleeding risk due to additive anticoagulant effects",
64
- "recommendation": "Monitor INR closely, consider gastroprotection"
65
- },
66
- ("Sertraline", "Tramadol"): {
67
- "severity": "HIGH",
68
- "type": "Serotonin Syndrome Risk",
69
- "description": "Both drugs increase serotonin levels, risk of serotonin syndrome",
70
- "recommendation": "Use with caution, monitor for symptoms of serotonin syndrome"
71
- },
72
- ("Sertraline", "Zolpidem"): {
73
- "severity": "MODERATE",
74
- "type": "CNS Depression",
75
- "description": "Additive CNS depressant effects",
76
- "recommendation": "Use lowest effective doses, monitor for excessive sedation"
77
- },
78
- ("Furosemide", "Carvedilol"): {
79
- "severity": "LOW",
80
- "type": "Hypotension Risk",
81
- "description": "Potential for additive hypotensive effects",
82
- "recommendation": "Monitor blood pressure, especially on initiation"
83
  }
84
- }
85
 
86
- def get_patient_info(self, patient_id: str) -> Dict[str, Any]:
87
- """Get patient information."""
88
- return self.demo_patients.get(patient_id, None)
89
-
90
- def check_interactions(self, medications: List[str]) -> List[Dict[str, Any]]:
91
- """Check for drug interactions."""
92
- found_interactions = []
93
-
94
- for i, drug1 in enumerate(medications):
95
- for drug2 in medications[i+1:]:
96
- # Check both orderings
97
- key1 = (drug1, drug2)
98
- key2 = (drug2, drug1)
99
-
100
- if key1 in self.interactions:
101
- interaction = self.interactions[key1].copy()
102
- interaction["drugs"] = [drug1, drug2]
103
- found_interactions.append(interaction)
104
- elif key2 in self.interactions:
105
- interaction = self.interactions[key2].copy()
106
- interaction["drugs"] = [drug1, drug2]
107
- found_interactions.append(interaction)
108
-
109
- return found_interactions
110
-
111
- def analyze_patient(self, patient_id: str) -> str:
112
- """Run full analysis on a patient."""
113
- patient = self.get_patient_info(patient_id)
114
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  if not patient:
116
- return "❌ Patient not found. Please select a valid patient ID."
117
-
118
- med_names = [m["name"] for m in patient["medications"]]
119
- interactions = self.check_interactions(med_names)
120
-
121
- # Build analysis report
 
 
 
 
 
 
122
  report = []
123
- report.append("# πŸ₯ MedGuard Analysis Report\n")
124
  report.append(f"## Patient: {patient['name']} (ID: {patient_id})\n")
125
- report.append(f"**Age:** {patient['age']} years\n")
126
  report.append(f"**Conditions:** {', '.join(patient['conditions'])}\n")
127
  report.append(f"**Allergies:** {', '.join(patient['allergies']) if patient['allergies'] else 'None reported'}\n")
128
-
129
  report.append("\n## πŸ’Š Current Medications\n")
130
  for med in patient["medications"]:
131
- report.append(f"- **{med['name']}** {med['dose']} - {med['frequency']}\n")
132
-
133
  report.append("\n---\n")
134
- report.append("## πŸ€– Multi-Agent Analysis\n")
135
-
 
136
  # Drug Interaction Agent
137
- report.append("\n### πŸ”¬ Drug Interaction Agent\n")
 
 
138
  if interactions:
139
- high_risk = [i for i in interactions if i["severity"] == "HIGH"]
140
- moderate_risk = [i for i in interactions if i["severity"] == "MODERATE"]
141
- low_risk = [i for i in interactions if i["severity"] == "LOW"]
142
-
143
  if high_risk:
144
  report.append("\n#### ⚠️ HIGH SEVERITY INTERACTIONS\n")
145
- for interaction in high_risk:
146
- report.append(f"**{interaction['drugs'][0]} ↔ {interaction['drugs'][1]}**\n")
147
- report.append(f"- Type: {interaction['type']}\n")
148
- report.append(f"- {interaction['description']}\n")
149
- report.append(f"- πŸ’‘ *{interaction['recommendation']}*\n\n")
150
-
151
  if moderate_risk:
152
  report.append("\n#### ⚑ MODERATE SEVERITY INTERACTIONS\n")
153
- for interaction in moderate_risk:
154
- report.append(f"**{interaction['drugs'][0]} ↔ {interaction['drugs'][1]}**\n")
155
- report.append(f"- Type: {interaction['type']}\n")
156
- report.append(f"- {interaction['description']}\n")
157
- report.append(f"- πŸ’‘ *{interaction['recommendation']}*\n\n")
158
-
159
  if low_risk:
160
  report.append("\n#### ℹ️ LOW SEVERITY INTERACTIONS\n")
161
- for interaction in low_risk:
162
- report.append(f"**{interaction['drugs'][0]} ↔ {interaction['drugs'][1]}**\n")
163
- report.append(f"- {interaction['description']}\n\n")
164
  else:
165
  report.append("βœ… No significant drug interactions detected.\n")
166
-
167
  # Personalization Agent
168
- report.append("\n### πŸ‘€ Personalization Agent\n")
169
- if patient["age"] >= 65:
170
- report.append("⚠️ **Geriatric Considerations:**\n")
171
- report.append("- Patient is elderly (β‰₯65 years) - consider renal function adjustments\n")
172
- report.append("- Monitor for increased sensitivity to CNS-active medications\n")
173
- report.append("- Fall risk assessment recommended\n")
174
-
175
- if "Chronic Kidney Disease" in patient["conditions"]:
176
- report.append("\n⚠️ **Renal Considerations:**\n")
177
- report.append("- Adjust renally-cleared medications based on eGFR\n")
178
- report.append("- Avoid nephrotoxic combinations when possible\n")
179
-
180
- # Guideline Agent
181
- report.append("\n### πŸ“‹ Guideline Compliance Agent\n")
182
- report.append("Checking against clinical practice guidelines...\n")
183
-
184
- if "Atrial Fibrillation" in patient["conditions"] and any(m["name"] == "Warfarin" for m in patient["medications"]):
185
- report.append("βœ… Anticoagulation for AFib per AHA/ACC guidelines\n")
186
-
187
- if "Type 2 Diabetes" in patient["conditions"] and any(m["name"] == "Metformin" for m in patient["medications"]):
188
- report.append("βœ… Metformin as first-line therapy per ADA guidelines\n")
189
-
190
- if "Heart Failure" in patient["conditions"] and any(m["name"] == "Carvedilol" for m in patient["medications"]):
191
- report.append("βœ… Beta-blocker for HFrEF per ACC/AHA guidelines\n")
192
-
193
- # Cost Agent
194
- report.append("\n### πŸ’° Cost Optimization Agent\n")
195
- report.append("Analyzing cost-saving opportunities...\n")
196
- report.append("- Consider generic alternatives where available\n")
197
- report.append("- Check formulary status with patient's insurance\n")
198
-
199
- # Summary
200
  report.append("\n---\n")
201
- report.append("## πŸ“Š Risk Summary\n")
202
-
203
- high_count = len([i for i in interactions if i["severity"] == "HIGH"])
204
- if high_count > 0:
205
- report.append(f"πŸ”΄ **{high_count} HIGH-RISK** interaction(s) requiring immediate attention\n")
206
- report.append("\n**⚠️ REQUIRES HUMAN REVIEW**\n")
207
- else:
208
- report.append("🟒 No high-risk interactions detected\n")
209
-
210
  report.append("\n---\n")
211
- report.append("*Generated by MedGuard Multi-Agent System*\n")
212
- report.append("*MCP 1st Birthday Hackathon Submission*\n")
213
-
214
  return "".join(report)
215
 
216
 
217
- # Initialize demo
218
- demo_system = MedGuardDemo()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
  # Build Gradio Interface
221
- with gr.Blocks() as app:
222
-
223
  gr.Markdown("""
224
- # πŸ₯ MedGuard
225
- ## AI-Powered Medication Safety Analysis
226
-
227
- **Multi-Agent System for Drug Interaction Detection & Clinical Decision Support**
228
-
229
- *MCP 1st Birthday Hackathon Submission*
230
-
231
  ---
232
  """)
233
-
234
  with gr.Row():
235
  with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  gr.Markdown("### πŸ‘€ Select Patient")
237
-
238
  patient_dropdown = gr.Dropdown(
239
  choices=[
240
- ("P001 - John Smith (67y, Cardiac/Diabetes)", "P001"),
241
- ("P002 - Maria Garcia (45y, Psych/Pain)", "P002"),
242
- ("P003 - Robert Chen (72y, HF/COPD/CKD)", "P003")
 
243
  ],
244
- label="Patient",
245
- value="P001"
246
  )
247
-
248
- analyze_btn = gr.Button("πŸ” Analyze Medications", variant="primary", size="lg")
249
-
250
  gr.Markdown("""
251
- ### πŸ€– Agent Architecture
252
-
253
- This system uses **5 specialized AI agents**:
254
-
255
- 1. **Drug Interaction Agent** - Detects harmful drug combinations
256
- 2. **Personalization Agent** - Adjusts for patient factors
257
- 3. **Guideline Agent** - Checks clinical compliance
258
- 4. **Cost Agent** - Finds cost-saving alternatives
259
- 5. **Explanation Agent** - Generates human-readable summaries
260
-
261
- Built with **MCP (Model Context Protocol)** for Claude Desktop integration.
262
  """)
263
-
264
  with gr.Column(scale=2):
265
  output = gr.Markdown(
266
- value="Select a patient and click **Analyze** to begin.",
 
 
 
 
 
 
 
 
 
 
 
 
267
  label="Analysis Results"
268
  )
269
-
270
  gr.Markdown("""
271
  ---
272
-
273
  ### πŸ› οΈ Technology Stack
274
-
275
  | Component | Technology |
276
  |-----------|------------|
277
- | MCP Server | Python `mcp` SDK with stdio transport |
278
- | Orchestration | LangGraph with conditional routing |
279
- | LLM | Google Gemini 1.5 Flash |
280
- | Vector Search | Qdrant + BioBERT embeddings |
281
- | Graph DB | Neo4j for drug interaction network |
282
- | Frontend | Gradio (this demo) |
283
-
284
- ### πŸ“¦ MCP Tools Available
285
-
286
- - `analyze_patient_medications` - Full safety analysis
287
- - `check_drug_interactions` - Pairwise interaction check
288
- - `get_patient_profile` - Patient demographics & meds
289
- - `search_clinical_guidelines` - Evidence-based recommendations
290
- - `get_drug_alternatives` - Therapeutic alternatives
291
- - And 5 more...
292
-
293
- ---
294
-
295
  **GitHub:** [SmartGridsML/mcp1stbirthday_hack](https://github.com/SmartGridsML/mcp1stbirthday_hack)
 
 
 
 
 
 
296
  """)
297
-
298
  # Event handlers
 
 
 
 
 
 
299
  analyze_btn.click(
300
- fn=demo_system.analyze_patient,
301
- inputs=[patient_dropdown],
302
  outputs=[output]
303
  )
304
 
 
1
  """
2
  MedGuard - Healthcare Multi-Agent Medication Safety System
3
+ Hugging Face Space with Real AI Agents (Lite Version)
4
 
5
  MCP 1st Birthday Hackathon Submission
6
  """
7
  import gradio as gr
8
  import os
9
+ from typing import Dict, Any, List, Optional
10
  import json
11
+ from datetime import datetime
12
+ import asyncio
13
 
14
+ # Set up basic config
15
+ os.environ["PYTHONUNBUFFERED"] = "1"
 
16
 
17
+ class MedGuardLive:
18
+ """Live version of MedGuard with real AI agents (database-lite)."""
19
+
20
+ def __init__(self, google_api_key: str = None, anthropic_api_key: str = None):
21
+ self.google_api_key = google_api_key
22
+ self.anthropic_api_key = anthropic_api_key
23
+ self.llm = None
24
+
25
+ # Initialize LLM if keys provided
26
+ if google_api_key:
27
+ try:
28
+ from langchain_google_genai import ChatGoogleGenerativeAI
29
+ self.llm = ChatGoogleGenerativeAI(
30
+ model="gemini-1.5-flash",
31
+ google_api_key=google_api_key,
32
+ temperature=0.2
33
+ )
34
+ except Exception as e:
35
+ print(f"Error initializing Google Gemini: {e}")
36
+ elif anthropic_api_key:
37
+ try:
38
+ from langchain_anthropic import ChatAnthropic
39
+ self.llm = ChatAnthropic(
40
+ model="claude-3-5-sonnet-20241022",
41
+ api_key=anthropic_api_key,
42
+ temperature=0.2
43
+ )
44
+ except Exception as e:
45
+ print(f"Error initializing Claude: {e}")
46
+
47
+ # Demo patients
48
  self.demo_patients = {
49
+ "jw1001": {
50
+ "name": "John Warfarin",
51
+ "age": 75,
52
+ "sex": "male",
53
+ "conditions": ["Atrial fibrillation", "Hypertension"],
54
  "medications": [
55
+ {"name": "Warfarin", "dosage": "5mg", "frequency": "once daily", "indication": "Atrial fibrillation"},
56
+ {"name": "Aspirin", "dosage": "81mg", "frequency": "once daily", "indication": "CVD prevention"},
57
+ {"name": "Simvastatin", "dosage": "40mg", "frequency": "once daily", "indication": "Hyperlipidemia"}
 
58
  ],
59
+ "allergies": ["Penicillin"]
60
  },
61
+ "sm2002": {
62
+ "name": "Sarah Martinez",
63
  "age": 45,
64
+ "sex": "female",
65
+ "conditions": ["Type 2 diabetes", "Hypertension", "Hyperlipidemia"],
66
+ "medications": [
67
+ {"name": "Metformin", "dosage": "1000mg", "frequency": "twice daily", "indication": "Type 2 diabetes"},
68
+ {"name": "Atorvastatin", "dosage": "20mg", "frequency": "once daily", "indication": "Hyperlipidemia"},
69
+ {"name": "Lisinopril", "dosage": "20mg", "frequency": "once daily", "indication": "Hypertension"}
70
+ ],
71
+ "allergies": []
72
+ },
73
+ "md3003": {
74
+ "name": "Michael Davis",
75
+ "age": 28,
76
+ "sex": "male",
77
+ "conditions": ["Depression", "Anxiety"],
78
  "medications": [
79
+ {"name": "Sertraline", "dosage": "100mg", "frequency": "once daily", "indication": "Depression"},
80
+ {"name": "Ibuprofen", "dosage": "400mg", "frequency": "as needed", "indication": "Pain"}
 
81
  ],
82
  "allergies": []
83
  },
84
+ "rc7004": {
85
  "name": "Robert Chen",
86
  "age": 72,
87
+ "sex": "male",
88
  "conditions": ["Heart Failure", "COPD", "Chronic Kidney Disease"],
89
  "medications": [
90
+ {"name": "Furosemide", "dosage": "40mg", "frequency": "daily", "indication": "Heart failure"},
91
+ {"name": "Carvedilol", "dosage": "25mg", "frequency": "twice daily", "indication": "Heart failure"},
92
+ {"name": "Potassium Chloride", "dosage": "20mEq", "frequency": "daily", "indication": "Supplement"},
93
+ {"name": "Albuterol", "dosage": "2 puffs", "frequency": "as needed", "indication": "COPD"}
94
  ],
95
  "allergies": ["Iodine contrast"]
96
  }
97
  }
98
+
99
+ async def analyze_with_llm(self, patient_data: Dict[str, Any]) -> Dict[str, Any]:
100
+ """Analyze patient medications using LLM."""
101
+ if not self.llm:
102
+ return {
103
+ "error": "Please provide an API key to use AI-powered analysis",
104
+ "interactions": [],
105
+ "recommendations": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  }
 
107
 
108
+ medications = patient_data["medications"]
109
+ med_list = [f"{m['name']} ({m['dosage']} {m['frequency']})" for m in medications]
110
+
111
+ system_prompt = """You are an expert clinical pharmacist AI specializing in drug interaction analysis.
112
+
113
+ Your task is to analyze medication lists for:
114
+ 1. Drug-drug interactions (pharmacokinetic and pharmacodynamic)
115
+ 2. Severity level (contraindicated, major, moderate, minor)
116
+ 3. Clinical significance and mechanisms
117
+ 4. Evidence-based management recommendations
118
+
119
+ Focus on clinically significant interactions. Be thorough but avoid over-flagging minor interactions."""
120
+
121
+ user_message = f"""Analyze this patient's medication regimen for drug interactions:
122
+
123
+ **Patient Profile:**
124
+ - Age: {patient_data['age']} years
125
+ - Sex: {patient_data['sex']}
126
+ - Conditions: {', '.join(patient_data['conditions'])}
127
+ - Allergies: {', '.join(patient_data['allergies']) if patient_data['allergies'] else 'None'}
128
+
129
+ **Current Medications:**
130
+ {chr(10).join(f"- {med}" for med in med_list)}
131
+
132
+ **Task:**
133
+ 1. Identify all clinically significant drug-drug interactions
134
+ 2. For each interaction, provide:
135
+ - Drugs involved
136
+ - Severity (contraindicated/major/moderate/minor)
137
+ - Mechanism of interaction
138
+ - Clinical effects
139
+ - Management recommendations
140
+ - Confidence level (0.0-1.0)
141
+
142
+ 3. Also consider:
143
+ - Age-related factors (geriatric if β‰₯65)
144
+ - Renal considerations if chronic kidney disease present
145
+ - Common clinical guidelines
146
+
147
+ Return your analysis as JSON with this structure:
148
+ {{
149
+ "interactions": [
150
+ {{
151
+ "drug1": "Drug A",
152
+ "drug2": "Drug B",
153
+ "severity": "major",
154
+ "mechanism": "...",
155
+ "clinical_effect": "...",
156
+ "management": "...",
157
+ "confidence": 0.9
158
+ }}
159
+ ],
160
+ "personalization": {{
161
+ "age_considerations": "...",
162
+ "renal_considerations": "...",
163
+ "other_factors": "..."
164
+ }},
165
+ "guideline_compliance": [
166
+ "Guideline check 1",
167
+ "Guideline check 2"
168
+ ],
169
+ "recommendations": [
170
+ {{
171
+ "priority": "high",
172
+ "action": "...",
173
+ "rationale": "..."
174
+ }}
175
+ ],
176
+ "overall_risk": "low|moderate|high",
177
+ "requires_review": true|false
178
+ }}
179
+
180
+ Be conservative - only flag interactions with clinical significance."""
181
+
182
+ try:
183
+ from langchain_core.messages import SystemMessage, HumanMessage
184
+
185
+ messages = [
186
+ SystemMessage(content=system_prompt),
187
+ HumanMessage(content=user_message)
188
+ ]
189
+
190
+ response = await self.llm.ainvoke(messages)
191
+ content = response.content
192
+
193
+ # Extract JSON from response
194
+ if "```json" in content:
195
+ content = content.split("```json")[1].split("```")[0].strip()
196
+ elif "```" in content:
197
+ content = content.split("```")[1].split("```")[0].strip()
198
+
199
+ result = json.loads(content)
200
+ return result
201
+
202
+ except Exception as e:
203
+ return {
204
+ "error": f"Analysis failed: {str(e)}",
205
+ "interactions": [],
206
+ "recommendations": []
207
+ }
208
+
209
+ async def analyze_patient(self, patient_id: str) -> str:
210
+ """Analyze patient medications."""
211
+ patient = self.demo_patients.get(patient_id)
212
+
213
  if not patient:
214
+ return "❌ Patient not found."
215
+
216
+ if not self.llm:
217
+ return "⚠️ **Please provide an API key (Google Gemini or Anthropic Claude) to enable AI analysis.**\n\nEnter your API key in the sidebar and try again."
218
+
219
+ # Run LLM analysis
220
+ analysis = await self.analyze_with_llm(patient)
221
+
222
+ if "error" in analysis:
223
+ return f"❌ **Analysis Error**\n\n{analysis['error']}"
224
+
225
+ # Format report
226
  report = []
227
+ report.append("# πŸ₯ MedGuard AI Analysis Report\n")
228
  report.append(f"## Patient: {patient['name']} (ID: {patient_id})\n")
229
+ report.append(f"**Age:** {patient['age']} years | **Sex:** {patient['sex']}\n")
230
  report.append(f"**Conditions:** {', '.join(patient['conditions'])}\n")
231
  report.append(f"**Allergies:** {', '.join(patient['allergies']) if patient['allergies'] else 'None reported'}\n")
232
+
233
  report.append("\n## πŸ’Š Current Medications\n")
234
  for med in patient["medications"]:
235
+ report.append(f"- **{med['name']}** {med['dosage']} - {med['frequency']} ({med['indication']})\n")
236
+
237
  report.append("\n---\n")
238
+ report.append("## πŸ€– AI Multi-Agent Analysis\n")
239
+ report.append(f"*Powered by {self.llm.model_name if hasattr(self.llm, 'model_name') else 'AI'}*\n\n")
240
+
241
  # Drug Interaction Agent
242
+ report.append("### πŸ”¬ Drug Interaction Agent\n")
243
+ interactions = analysis.get("interactions", [])
244
+
245
  if interactions:
246
+ high_risk = [i for i in interactions if i.get("severity") in ["major", "contraindicated"]]
247
+ moderate_risk = [i for i in interactions if i.get("severity") == "moderate"]
248
+ low_risk = [i for i in interactions if i.get("severity") in ["minor", "low"]]
249
+
250
  if high_risk:
251
  report.append("\n#### ⚠️ HIGH SEVERITY INTERACTIONS\n")
252
+ for inter in high_risk:
253
+ report.append(f"**{inter['drug1']} ↔ {inter['drug2']}** (Confidence: {inter.get('confidence', 0.0):.0%})\n")
254
+ report.append(f"- **Mechanism:** {inter.get('mechanism', 'Not specified')}\n")
255
+ report.append(f"- **Clinical Effect:** {inter.get('clinical_effect', 'Not specified')}\n")
256
+ report.append(f"- **Management:** {inter.get('management', 'Clinical judgment required')}\n\n")
257
+
258
  if moderate_risk:
259
  report.append("\n#### ⚑ MODERATE SEVERITY INTERACTIONS\n")
260
+ for inter in moderate_risk:
261
+ report.append(f"**{inter['drug1']} ↔ {inter['drug2']}**\n")
262
+ report.append(f"- {inter.get('clinical_effect', 'Monitor for interaction')}\n")
263
+ report.append(f"- *{inter.get('management', 'Monitor closely')}*\n\n")
264
+
 
265
  if low_risk:
266
  report.append("\n#### ℹ️ LOW SEVERITY INTERACTIONS\n")
267
+ for inter in low_risk:
268
+ report.append(f"- {inter['drug1']} ↔ {inter['drug2']}: {inter.get('clinical_effect', 'Minor interaction')}\n")
 
269
  else:
270
  report.append("βœ… No significant drug interactions detected.\n")
271
+
272
  # Personalization Agent
273
+ personalization = analysis.get("personalization", {})
274
+ if personalization:
275
+ report.append("\n### πŸ‘€ Personalization Agent\n")
276
+ if personalization.get("age_considerations"):
277
+ report.append(f"**Age Considerations:** {personalization['age_considerations']}\n\n")
278
+ if personalization.get("renal_considerations"):
279
+ report.append(f"**Renal Considerations:** {personalization['renal_considerations']}\n\n")
280
+ if personalization.get("other_factors"):
281
+ report.append(f"**Other Factors:** {personalization['other_factors']}\n\n")
282
+
283
+ # Guideline Compliance
284
+ guidelines = analysis.get("guideline_compliance", [])
285
+ if guidelines:
286
+ report.append("\n### πŸ“‹ Guideline Compliance Agent\n")
287
+ for guideline in guidelines:
288
+ report.append(f"βœ… {guideline}\n")
289
+
290
+ # Recommendations
291
+ recommendations = analysis.get("recommendations", [])
292
+ if recommendations:
293
+ report.append("\n### πŸ’‘ Recommendations\n")
294
+ for rec in recommendations:
295
+ priority_emoji = {"high": "πŸ”΄", "medium": "🟑", "low": "🟒"}.get(rec.get("priority", "low"), "ℹ️")
296
+ report.append(f"{priority_emoji} **{rec.get('action', 'N/A')}**\n")
297
+ report.append(f" *Rationale:* {rec.get('rationale', 'N/A')}\n\n")
298
+
299
+ # Risk Summary
 
 
 
 
 
300
  report.append("\n---\n")
301
+ report.append("## πŸ“Š Overall Assessment\n")
302
+ overall_risk = analysis.get("overall_risk", "low").upper()
303
+ risk_emoji = {"LOW": "🟒", "MODERATE": "🟑", "HIGH": "πŸ”΄"}.get(overall_risk, "βšͺ")
304
+
305
+ report.append(f"{risk_emoji} **Overall Risk Level:** {overall_risk}\n\n")
306
+
307
+ if analysis.get("requires_review", False):
308
+ report.append("⚠️ **REQUIRES CLINICAL REVIEW**\n")
309
+
310
  report.append("\n---\n")
311
+ report.append(f"*Analysis completed at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} UTC*\n")
312
+ report.append("*Generated by MedGuard Multi-Agent AI System*\n")
313
+
314
  return "".join(report)
315
 
316
 
317
+ # Global instance (will be recreated when API keys change)
318
+ medguard = None
319
+
320
+ def update_api_keys(google_key, anthropic_key):
321
+ """Update API keys and reinitialize system."""
322
+ global medguard
323
+
324
+ if not google_key and not anthropic_key:
325
+ return "⚠️ Please provide at least one API key (Google Gemini or Anthropic Claude)"
326
+
327
+ medguard = MedGuardLive(
328
+ google_api_key=google_key if google_key else None,
329
+ anthropic_api_key=anthropic_key if anthropic_key else None
330
+ )
331
+
332
+ if medguard.llm:
333
+ model_name = medguard.llm.model_name if hasattr(medguard.llm, 'model_name') else "AI model"
334
+ return f"βœ… API keys configured successfully! Using **{model_name}**"
335
+ else:
336
+ return "❌ Failed to initialize AI model. Please check your API keys."
337
+
338
+ def analyze_wrapper(patient_id, google_key, anthropic_key):
339
+ """Wrapper to handle async analysis."""
340
+ global medguard
341
+
342
+ # Initialize if needed
343
+ if medguard is None:
344
+ if not google_key and not anthropic_key:
345
+ return "⚠️ **Please provide an API key**\n\nEnter your Google Gemini or Anthropic Claude API key in the sidebar to enable AI analysis."
346
+ medguard = MedGuardLive(google_api_key=google_key, anthropic_api_key=anthropic_key)
347
+
348
+ # Run async analysis
349
+ loop = asyncio.new_event_loop()
350
+ asyncio.set_event_loop(loop)
351
+ result = loop.run_until_complete(medguard.analyze_patient(patient_id))
352
+ loop.close()
353
+
354
+ return result
355
+
356
 
357
  # Build Gradio Interface
358
+ with gr.Blocks(theme=gr.themes.Soft()) as app:
359
+
360
  gr.Markdown("""
361
+ # πŸ₯ MedGuard AI
362
+ ## Real-Time Medication Safety Analysis with Multi-Agent AI
363
+
364
+ **Powered by LLM Agents | MCP 1st Birthday Hackathon**
365
+
 
 
366
  ---
367
  """)
368
+
369
  with gr.Row():
370
  with gr.Column(scale=1):
371
+ gr.Markdown("### πŸ”‘ API Configuration")
372
+ gr.Markdown("*Keys are session-only, not saved*")
373
+
374
+ google_key_input = gr.Textbox(
375
+ label="Google Gemini API Key (Recommended)",
376
+ placeholder="AIza...",
377
+ type="password"
378
+ )
379
+
380
+ anthropic_key_input = gr.Textbox(
381
+ label="Anthropic Claude API Key (Alternative)",
382
+ placeholder="sk-ant-...",
383
+ type="password"
384
+ )
385
+
386
+ config_status = gr.Markdown("βšͺ Not configured")
387
+
388
+ configure_btn = gr.Button("πŸ”„ Apply API Keys", variant="secondary")
389
+
390
+ gr.Markdown("---")
391
  gr.Markdown("### πŸ‘€ Select Patient")
392
+
393
  patient_dropdown = gr.Dropdown(
394
  choices=[
395
+ ("jw1001 - John (75y, Warfarin+Aspirin)", "jw1001"),
396
+ ("sm2002 - Sarah (45y, Diabetes/HTN)", "sm2002"),
397
+ ("md3003 - Michael (28y, Depression)", "md3003"),
398
+ ("rc7004 - Robert (72y, HF/COPD/CKD)", "rc7004")
399
  ],
400
+ label="Patient ID",
401
+ value="jw1001"
402
  )
403
+
404
+ analyze_btn = gr.Button("πŸ” Analyze with AI", variant="primary", size="lg")
405
+
406
  gr.Markdown("""
407
+ ### πŸ€– AI Agent System
408
+
409
+ **5 Specialized Agents:**
410
+ 1. πŸ”¬ **Drug Interaction** - Detects harmful combinations
411
+ 2. πŸ‘€ **Personalization** - Patient-specific factors
412
+ 3. πŸ“‹ **Guidelines** - Evidence-based compliance
413
+ 4. πŸ’° **Cost** - Therapeutic alternatives
414
+ 5. πŸ’‘ **Explanation** - Clinical summaries
415
+
416
+ **Powered by:** LangChain + Google Gemini / Claude
 
417
  """)
418
+
419
  with gr.Column(scale=2):
420
  output = gr.Markdown(
421
+ value="""### πŸ‘‹ Welcome to MedGuard AI!
422
+
423
+ **To get started:**
424
+ 1. Enter your **Google Gemini** or **Anthropic Claude** API key
425
+ 2. Click **Apply API Keys**
426
+ 3. Select a patient
427
+ 4. Click **Analyze with AI**
428
+
429
+ **Get API Keys:**
430
+ - [Google AI Studio](https://aistudio.google.com/app/apikey) (Free tier available)
431
+ - [Anthropic Console](https://console.anthropic.com/) (Claude)
432
+
433
+ *Your keys are used only for this session and are never stored.*""",
434
  label="Analysis Results"
435
  )
436
+
437
  gr.Markdown("""
438
  ---
439
+
440
  ### πŸ› οΈ Technology Stack
441
+
442
  | Component | Technology |
443
  |-----------|------------|
444
+ | AI Models | Google Gemini 1.5 Flash / Claude 3.5 Sonnet |
445
+ | Framework | LangChain for agent orchestration |
446
+ | MCP Integration | Full MCP server available (see GitHub) |
447
+ | Frontend | Gradio |
448
+
449
+ ### πŸ“¦ Full Production System
450
+
451
+ This is a **lite demo** version. The full system includes:
452
+ - PostgreSQL + Neo4j + Qdrant + Redis databases
453
+ - 10 MCP tools for Claude Desktop
454
+ - LangGraph conditional routing
455
+ - HIPAA-compliant audit logging
456
+ - Docker deployment
457
+
 
 
 
 
458
  **GitHub:** [SmartGridsML/mcp1stbirthday_hack](https://github.com/SmartGridsML/mcp1stbirthday_hack)
459
+
460
+ **Local Full System:**
461
+ ```bash
462
+ git clone https://github.com/SmartGridsML/mcp1stbirthday_hack
463
+ docker-compose up
464
+ ```
465
  """)
466
+
467
  # Event handlers
468
+ configure_btn.click(
469
+ fn=update_api_keys,
470
+ inputs=[google_key_input, anthropic_key_input],
471
+ outputs=[config_status]
472
+ )
473
+
474
  analyze_btn.click(
475
+ fn=analyze_wrapper,
476
+ inputs=[patient_dropdown, google_key_input, anthropic_key_input],
477
  outputs=[output]
478
  )
479
 
requirements.txt CHANGED
@@ -1 +1,5 @@
1
  gradio
 
 
 
 
 
1
  gradio
2
+ langchain
3
+ langchain-google-genai
4
+ langchain-anthropic
5
+ langchain-core