Spaces:
Running
Running
Update
Browse files
README.md
CHANGED
@@ -4,7 +4,7 @@ emoji: 🧬
|
|
4 |
colorFrom: indigo
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 5.33.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
secrets:
|
@@ -15,187 +15,120 @@ tags:
|
|
15 |
- agent-demo-track
|
16 |
---
|
17 |
|
18 |
-
|
19 |
# 🧬 MediAgent AI: Conversational Health Navigator & MCP Tool Server
|
20 |
|
21 |
-
**
|
22 |
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
|
26 |
|
27 |
-
|
28 |
-
-
|
29 |
-
-
|
30 |
-
- **Production-Ready:** Robust error handling, citations, and safety layers.
|
31 |
|
32 |
---
|
33 |
|
34 |
-
##
|
35 |
-
|
36 |
-
To meet the rapid development cycle of a hackathon, we've implemented a pragmatic and powerful **Hybrid Architecture**. Our single Modal application serves as **both the core Agent and its own MCP-compliant Tool Server**.
|
37 |
-
|
38 |
-
<!-- You can add a diagram here if desired -->
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
**
|
47 |
-
* **
|
48 |
-
* **MistralAI**: Advanced open-weight LLMs for medical reasoning.
|
49 |
-
* **LlamaIndex**: Flexible orchestration and retrieval for agentic workflows.
|
50 |
|
51 |
---
|
52 |
|
53 |
-
##
|
54 |
-
|
55 |
-
* 🌐 **Multilingual Support**: Communicate seamlessly! MediAgent AI automatically detects and responds in **English, Spanish, Hindi, and French**, making it accessible to a global audience.
|
56 |
-
* 💬 **Conversational & Stateful**: Enjoy natural, ongoing conversations. The AI remembers the chat history to understand follow-up questions and maintain context throughout your dialogue.
|
57 |
-
* 👤 **Role-Based Adaptation**: Get tailored information based on your needs.
|
58 |
-
* **Patient Mode**: Provides simplified, easy-to-understand health advice and general information.
|
59 |
-
* **Doctor Mode**: Delivers in-depth, technical insights, leveraging specialized medical databases for professionals.
|
60 |
-
* 🛠️ **Comprehensive Tooling**: MediAgent AI utilizes a robust toolkit to provide accurate answers:
|
61 |
-
* **General Web Search**: For broad health queries.
|
62 |
-
* **PubMed Integration**: Accesses peer-reviewed medical literature for evidence-based information.
|
63 |
-
* **Drug Information**: Provides details on:
|
64 |
-
* **Drug Side Effects**: Find known side effects of medications.
|
65 |
-
* **Drug Interactions**: Check for potential adverse interactions between multiple drugs.
|
66 |
-
* **Official Drug Label Information**: Retrieve detailed FDA-approved prescribing information.
|
67 |
-
* **Clinical Trials Search**: Discover ongoing or past clinical studies relevant to specific conditions or treatments.
|
68 |
-
* 🛡️ **Safety First**: Your well-being is paramount. The AI includes a critical safety layer to detect potential medical emergencies and provides appropriate disclaimers, advising users to consult with healthcare professionals for diagnosis and treatment.
|
69 |
-
* **🛠️ MCP Compliant Tool Server**: Our tools can be called externally. **You can test it right now:**
|
70 |
-
|
71 |
-
> ⚠️ **Note:** The first call may take 30-60 seconds as the backend spins up. Subsequent calls are much faster.
|
72 |
-
|
73 |
-
```bash
|
74 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
75 |
-
--header 'Content-Type: application/json' \
|
76 |
-
--data '{
|
77 |
-
"tool_name": "check_drug_interactions",
|
78 |
-
"tool_args": {
|
79 |
-
"drugs": ["warfarin", "amiodarone"]
|
80 |
-
}
|
81 |
-
}'
|
82 |
-
```
|
83 |
-
|
84 |
-
**More Example Tool Calls:**
|
85 |
-
|
86 |
-
- **Drug Side Effects:**
|
87 |
-
```bash
|
88 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
89 |
-
--header 'Content-Type: application/json' \
|
90 |
-
--data '{
|
91 |
-
"tool_name": "check_drug_side_effects",
|
92 |
-
"tool_args": {"drug": "metformin"}
|
93 |
-
}'
|
94 |
-
```
|
95 |
-
- **PubMed Search:**
|
96 |
-
```bash
|
97 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
98 |
-
--header 'Content-Type: application/json' \
|
99 |
-
--data '{
|
100 |
-
"tool_name": "search_pubmed",
|
101 |
-
"tool_args": {"query": "COVID-19 vaccine efficacy", "max_results": 2}
|
102 |
-
}'
|
103 |
-
```
|
104 |
-
- **Clinical Trials:**
|
105 |
-
```bash
|
106 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
107 |
-
--header 'Content-Type: application/json' \
|
108 |
-
--data '{
|
109 |
-
"tool_name": "search_clinical_trials",
|
110 |
-
"tool_args": {"query": "diabetes", "max_results": 1}
|
111 |
-
}'
|
112 |
-
```
|
113 |
-
- **Drug Interaction Warning:**
|
114 |
-
```bash
|
115 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
116 |
-
--header 'Content-Type: application/json' \
|
117 |
-
--data '{
|
118 |
-
"tool_name": "check_drug_interactions",
|
119 |
-
"tool_args": {
|
120 |
-
"drugs": ["aspirin", "ibuprofen"]
|
121 |
-
}
|
122 |
-
}'
|
123 |
-
```
|
124 |
-
- **Comprehensive Drug Information:**
|
125 |
-
```bash
|
126 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
127 |
-
--header 'Content-Type: application/json' \
|
128 |
-
--data '{
|
129 |
-
"tool_name": "get_drug_info",
|
130 |
-
"tool_args": {"drug": "atorvastatin"}
|
131 |
-
}'
|
132 |
-
```
|
133 |
-
- **Advanced PubMed Search:**
|
134 |
-
```bash
|
135 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
136 |
-
--header 'Content-Type: application/json' \
|
137 |
-
--data '{
|
138 |
-
"tool_name": "search_pubmed",
|
139 |
-
"tool_args": {"query": "metformin AND cardiovascular outcomes", "max_results": 3}
|
140 |
-
}'
|
141 |
-
```
|
142 |
-
- **Clinical Trials with Filters:**
|
143 |
-
```bash
|
144 |
-
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
145 |
-
--header 'Content-Type: application/json' \
|
146 |
-
--data '{
|
147 |
-
"tool_name": "search_clinical_trials",
|
148 |
-
"tool_args": {"query": "hypertension", "max_results": 2, "filters": {"status": "ongoing"}}
|
149 |
-
}'
|
150 |
-
```
|
151 |
|
152 |
-
|
153 |
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
-
|
157 |
-
|
|
|
|
|
|
|
158 |
|
159 |
---
|
160 |
|
161 |
-
##
|
162 |
-
|
163 |
-
Copy and paste one of the examples below into the chat interface to test MediAgent AI's capabilities. Remember to select the appropriate **"patient"** or **"doctor"** role in the UI for tailored responses.
|
164 |
|
165 |
-
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
* **French**: "Comment savoir si j'ai la grippe ou un simple rhume ?"
|
170 |
-
* **Hindi**: "उच्च रक्तचाप के लिए घरेलू उपचार क्या हैं?" (What are the home remedies for high blood pressure?)
|
171 |
-
|
172 |
-
### Drug-Specific Queries
|
173 |
-
|
174 |
-
* "Can I take ibuprofen with lisinopril? (Check for interactions)"
|
175 |
-
* "What are the known side effects of amoxicillin?"
|
176 |
-
* "Give me the FDA label information for Tylenol."
|
177 |
-
|
178 |
-
### Research & Clinical Trials (Best in Doctor Mode)
|
179 |
-
|
180 |
-
* "Are there any ongoing clinical trials for Alzheimer's disease?"
|
181 |
-
* "What is the latest PubMed literature on efficacy of novel biologics for Crohn's disease?"
|
182 |
|
183 |
---
|
184 |
|
185 |
-
##
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
|
187 |
-
|
188 |
-
|
189 |
-
### For the Patient Role
|
190 |
-
|
191 |
-
Select **patient** and ask a general health question. The AI will primarily use web search to provide an easy-to-understand overview, avoiding overly technical jargon.
|
192 |
|
193 |
-
|
194 |
|
195 |
-
|
196 |
|
197 |
-
|
198 |
|
199 |
-
|
200 |
|
201 |
-
|
|
|
4 |
colorFrom: indigo
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 5.33.0 # Note: I've updated this to a more recent version, adjust if needed
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
secrets:
|
|
|
15 |
- agent-demo-track
|
16 |
---
|
17 |
|
|
|
18 |
# 🧬 MediAgent AI: Conversational Health Navigator & MCP Tool Server
|
19 |
|
20 |
+
**[➡️ Try the Live Demo Here!](https://huggingface.co/spaces/Agents-MCP-Hackathon/medical_ai)**
|
21 |
|
22 |
+
<div align="center" style="margin-bottom: 1em;">
|
23 |
+
<a href="https://modal.com/" target="_blank" style="text-decoration:none; margin-right:18px;">
|
24 |
+
<img src="https://assets.modal.com/logos/modal-logo-dark.svg" alt="Modal Logo" height="32" style="vertical-align:middle; margin-right:8px;"/>
|
25 |
+
<span style="font-size:1.1em; color:#8aa8ff; font-weight:bold;">Powered by Modal</span>
|
26 |
+
</a>
|
27 |
+
<a href="https://www.llamaindex.ai/" target="_blank" style="text-decoration:none;">
|
28 |
+
<img src="https://raw.githubusercontent.com/jerryjliu/llama_index/main/docs/imgs/llama_index_logo.png" alt="LlamaIndex Logo" height="32" style="vertical-align:middle; margin-right:8px;"/>
|
29 |
+
<span style="font-size:1.1em; color:#ffb300; font-weight:bold;">and LlamaIndex</span>
|
30 |
+
</a>
|
31 |
+
<div style="font-size:0.95em; color:#aaa; margin-top:2px;">Special thanks to the Modal and LlamaIndex teams for their amazing platforms!</div>
|
32 |
+
</div>
|
33 |
|
34 |
+
**MediAgent AI** is a sophisticated, conversational health assistant and a fully MCP-compliant tool server, built on Modal and Gradio. It provides reliable, sourced, and role-adapted answers to a wide range of medical questions.
|
35 |
|
36 |
+
This project is a submission for the **Gradio Agents & MCP Hackathon 2025**, competing in two tracks:
|
37 |
+
- **🔧 MCP Tool / Server Track:** Our backend exposes a robust, MCP-compliant endpoint for any agent to use.
|
38 |
+
- **🤖 Agentic Demo Showcase Track:** The Gradio UI provides a powerful demonstration of an agent using these tools to help users.
|
|
|
39 |
|
40 |
---
|
41 |
|
42 |
+
## 🌟 Key Features
|
|
|
|
|
|
|
|
|
43 |
|
44 |
+
* 🌐 **Multilingual Support**: Automatically detects and responds in **English, Spanish, Hindi, and French**.
|
45 |
+
* 👤 **Role-Based Adaptation**:
|
46 |
+
* **Patient Mode**: Simplified, easy-to-understand health information.
|
47 |
+
* **Doctor Mode**: In-depth, technical insights using specialized medical databases.
|
48 |
+
* 🛡️ **Critical Safety Layer**: Identifies keywords related to medical emergencies (e.g., "chest pain") and immediately instructs the user to seek professional help, bypassing the AI.
|
49 |
+
* 🔗 **Sourced & Verifiable**: All information is backed by citations from authoritative sources.
|
50 |
+
* 💬 **Stateful Conversations**: Remembers chat history for contextual follow-up questions.
|
51 |
+
* 🛠️ **Fully Compliant MCP Tool Server**: Our tools can be called externally by any MCP client.
|
|
|
|
|
52 |
|
53 |
---
|
54 |
|
55 |
+
## 🛠️ Tools & Technology Stack
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
+
Our agent leverages a powerful, specialized toolkit to provide accurate information. These tools are exposed via our public MCP endpoint.
|
58 |
|
59 |
+
| Tool Name | Description | Data Source(s) |
|
60 |
+
| ----------------------------- | --------------------------------------------------------------------------- | -------------------------- |
|
61 |
+
| `search_web` | For general health queries and patient-level explanations. | DuckDuckGo |
|
62 |
+
| `search_pubmed` | Accesses peer-reviewed medical literature for evidence-based information. | PubMed / NCBI |
|
63 |
+
| `get_drug_label_info` | Retrieves detailed, official FDA-approved prescribing information. | openFDA / DailyMed |
|
64 |
+
| `check_drug_side_effects` | Finds known side effects for a specific medication. | openFDA / DailyMed |
|
65 |
+
| `check_drug_interactions` | Checks for adverse interactions between two or more drugs. | RxNorm API (NIH) |
|
66 |
+
| `search_clinical_trials` | Discovers ongoing or completed clinical studies for conditions/treatments. | ClinicalTrials.gov (NIH) |
|
67 |
|
68 |
+
**Core Technologies:**
|
69 |
+
* **Backend & Compute:** [**Modal**](https://modal.com/) for scalable, serverless GPU and CPU functions.
|
70 |
+
* **AI Agent Framework:** [**LlamaIndex**](https://www.llamaindex.ai/) for orchestrating the agent's think-plan-act loop.
|
71 |
+
* **LLM:** [**Mistral 7B**](https://mistral.ai/) for high-quality reasoning.
|
72 |
+
* **Frontend UI:** [**Gradio**](https://www.gradio.app/) for the interactive chat interface.
|
73 |
|
74 |
---
|
75 |
|
76 |
+
## 🏛️ Architecture: Hybrid Single-Server MCP
|
|
|
|
|
77 |
|
78 |
+
Our single Modal application serves as **both the core Agent and its own MCP-compliant Tool Server**.
|
79 |
|
80 |
+
1. **Agent Endpoint (`/`):** A private endpoint that takes a user query and orchestrates the full agentic workflow (planning, tool selection, synthesis).
|
81 |
+
2. **MCP Tool Endpoint (hidden in backend):** A public endpoint that exposes our individual tools. This makes our application a valid MCP Server, proving compliance and allowing any external MCP client to use our medical tools.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
|
83 |
---
|
84 |
|
85 |
+
## 🚀 Test our MCP Tool Server Live!
|
86 |
+
|
87 |
+
You can call our tools from any MCP-compatible client or directly with `curl`.
|
88 |
+
|
89 |
+
> ⚠️ **Note:** The first call may take 30-60 seconds as the serverless backend spins up. Subsequent calls are much faster.
|
90 |
+
|
91 |
+
```bash
|
92 |
+
# Example: Check for a critical drug interaction
|
93 |
+
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
94 |
+
--header 'Content-Type: application/json' \
|
95 |
+
--data '{
|
96 |
+
"tool_name": "check_drug_interactions",
|
97 |
+
"tool_args": {
|
98 |
+
"drugs": ["warfarin", "amiodarone"]
|
99 |
+
}
|
100 |
+
}'
|
101 |
+
|
102 |
+
# Example: Search for PubMed articles
|
103 |
+
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
104 |
+
--header 'Content-Type: application/json' \
|
105 |
+
--data '{
|
106 |
+
"tool_name": "search_pubmed",
|
107 |
+
"tool_args": {"query": "metformin AND cardiovascular outcomes", "max_results": 2}
|
108 |
+
}'
|
109 |
+
|
110 |
+
# Example: Get official FDA label information (CORRECTED)
|
111 |
+
curl -X POST 'https://sunilpanda992--medi-agent-ai-final-backend-mediagentai-m-3f699b.modal.run' \
|
112 |
+
--header 'Content-Type: application/json' \
|
113 |
+
--data '{
|
114 |
+
"tool_name": "get_drug_label_info",
|
115 |
+
"tool_args": {"drug_name": "atorvastatin"}
|
116 |
+
}'
|
117 |
+
```
|
118 |
+
|
119 |
+
IGNORE_WHEN_COPYING_START
|
120 |
+
Use code with caution. Markdown
|
121 |
+
IGNORE_WHEN_COPYING_END
|
122 |
|
123 |
+
---
|
124 |
+
## 🧪 Try It Out in the App!
|
|
|
|
|
|
|
125 |
|
126 |
+
Select the appropriate "patient" or "doctor" role in the chat interface above and try these prompts:
|
127 |
|
128 |
+
Patient Query: "What are the most common side effects of metformin?"
|
129 |
|
130 |
+
Doctor Query: "My patient with Crohn's is on methotrexate and we are considering adding infliximab. I need the latest PubMed literature on efficacy and a check for interactions between the two drugs."
|
131 |
|
132 |
+
Spanish Query: "¿Cuáles son los síntomas de la diabetes tipo 2?"
|
133 |
|
134 |
+
Interaction Check: "Can I take ibuprofen with lisinopril?"
|
app.py
CHANGED
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
import requests
|
3 |
import os
|
@@ -30,49 +32,38 @@ CUSTOM_CSS = """
|
|
30 |
}
|
31 |
"""
|
32 |
|
33 |
-
def handle_user_turn(user_input, chat_history, user_role, sid):
|
|
|
|
|
|
|
34 |
if not user_input.strip():
|
35 |
return chat_history, ""
|
36 |
|
37 |
-
#
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
if user_msg is not None:
|
44 |
-
new_chat_history.append({"role": "user", "content": user_msg})
|
45 |
-
if bot_msg is not None:
|
46 |
-
new_chat_history.append({"role": "assistant", "content": bot_msg})
|
47 |
-
chat_history = new_chat_history
|
48 |
|
49 |
-
|
|
|
50 |
|
51 |
if not MODAL_BACKEND_URL:
|
52 |
-
|
53 |
-
chat_history
|
54 |
-
return
|
55 |
|
56 |
-
|
|
|
57 |
|
58 |
-
|
59 |
-
# This assumes the last message is always the user's latest input
|
60 |
-
last_user_message_index = len(chat_history) - 1
|
61 |
-
|
62 |
for step in thinking_steps:
|
63 |
-
#
|
64 |
-
|
65 |
-
|
66 |
-
# If there's an existing assistant thinking message, update it in place
|
67 |
-
# Otherwise, append a new one
|
68 |
-
if len(chat_history) > last_user_message_index + 1 and chat_history[last_user_message_index + 1]["role"] == "assistant":
|
69 |
-
chat_history[last_user_message_index + 1] = temp_message
|
70 |
-
else:
|
71 |
-
chat_history.append(temp_message)
|
72 |
-
|
73 |
-
yield chat_history, "" # Yield with the temporary thinking message
|
74 |
-
|
75 |
time.sleep(0.4)
|
|
|
76 |
|
77 |
try:
|
78 |
response = requests.post(MODAL_BACKEND_URL, json={
|
@@ -81,38 +72,50 @@ def handle_user_turn(user_input, chat_history, user_role, sid):
|
|
81 |
"role": user_role
|
82 |
}, timeout=600)
|
83 |
response.raise_for_status()
|
84 |
-
reply = response.json().get("final_markdown", "No response received.")
|
|
|
|
|
85 |
except Exception as e:
|
86 |
-
reply = f"❗ Error: {str(e)}"
|
87 |
|
88 |
-
# Update the
|
89 |
-
|
90 |
-
if len(chat_history) > last_user_message_index + 1 and chat_history[last_user_message_index + 1]["role"] == "assistant":
|
91 |
-
chat_history[last_user_message_index + 1] = {"role": "assistant", "content": reply}
|
92 |
-
else:
|
93 |
-
chat_history.append({"role": "assistant", "content": reply}) # Should not typically happen if thinking steps run
|
94 |
|
95 |
yield chat_history, ""
|
96 |
|
97 |
-
|
|
|
|
|
98 |
session_id = gr.State(lambda: str(uuid.uuid4()))
|
99 |
|
100 |
gr.Markdown("""
|
101 |
-
# 🧬 MediAgent AI
|
102 |
-
|
103 |
-
|
104 |
<div class='chatbot-box'>
|
105 |
-
MediAgent AI is a multilingual, role-
|
106 |
<ul>
|
107 |
-
<li
|
108 |
-
<li
|
109 |
-
<li
|
110 |
-
<li
|
111 |
-
<li
|
112 |
-
<li
|
|
|
|
|
113 |
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
</div>
|
115 |
-
|
|
|
116 |
|
117 |
with gr.Row():
|
118 |
with gr.Column(scale=1):
|
@@ -123,7 +126,8 @@ with gr.Blocks(css=CUSTOM_CSS, title="MediAgent AI") as demo:
|
|
123 |
info="Choose your user type for tailored responses"
|
124 |
)
|
125 |
with gr.Column(scale=3):
|
126 |
-
|
|
|
127 |
|
128 |
with gr.Row():
|
129 |
user_textbox = gr.Textbox(
|
@@ -131,34 +135,35 @@ with gr.Blocks(css=CUSTOM_CSS, title="MediAgent AI") as demo:
|
|
131 |
lines=1,
|
132 |
scale=4
|
133 |
)
|
134 |
-
submit_btn = gr.Button("Send", elem_id="send-button", scale=1)
|
135 |
|
136 |
examples = gr.Examples(
|
137 |
examples=[
|
138 |
"What are the side effects of metformin?",
|
139 |
"Explain Crohn’s disease vs Ulcerative Colitis for a doctor",
|
140 |
"¿Cuáles son los síntomas de la hipertensión?",
|
141 |
-
"Can I take ibuprofen with lisinopril? (for interactions)",
|
142 |
-
"What is the FDA label information for acetaminophen?",
|
143 |
-
"Are there any ongoing clinical trials for breast cancer?",
|
144 |
],
|
145 |
inputs=[user_textbox]
|
146 |
-
)
|
147 |
|
148 |
-
gr.ClearButton([chatbot, user_textbox], value="🔄 Clear")
|
149 |
|
150 |
-
|
|
|
151 |
fn=handle_user_turn,
|
152 |
inputs=[user_textbox, chatbot, user_role, session_id],
|
153 |
outputs=[chatbot, user_textbox]
|
154 |
)
|
155 |
-
|
156 |
-
user_textbox.submit(
|
157 |
fn=handle_user_turn,
|
158 |
inputs=[user_textbox, chatbot, user_role, session_id],
|
159 |
outputs=[chatbot, user_textbox]
|
160 |
)
|
161 |
|
|
|
162 |
if __name__ == "__main__":
|
163 |
demo.queue()
|
164 |
demo.launch()
|
|
|
1 |
+
# In app.py
|
2 |
+
|
3 |
import gradio as gr
|
4 |
import requests
|
5 |
import os
|
|
|
32 |
}
|
33 |
"""
|
34 |
|
35 |
+
def handle_user_turn(user_input: str, chat_history: list, user_role: str, sid: str):
|
36 |
+
"""
|
37 |
+
Handles a single turn of the conversation.
|
38 |
+
"""
|
39 |
if not user_input.strip():
|
40 |
return chat_history, ""
|
41 |
|
42 |
+
# Initialize chat_history if it's the first turn (it will be None)
|
43 |
+
if chat_history is None:
|
44 |
+
chat_history = []
|
45 |
+
|
46 |
+
# Append the user's message in the correct dictionary format
|
47 |
+
chat_history.append({"role": "user", "content": user_input})
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
+
# Immediately yield the updated history to show the user's message
|
50 |
+
yield chat_history, ""
|
51 |
|
52 |
if not MODAL_BACKEND_URL:
|
53 |
+
chat_history.append({"role": "assistant", "content": "❗ Configuration error: `MODAL_BACKEND_URL` is not set."})
|
54 |
+
yield chat_history, ""
|
55 |
+
return
|
56 |
|
57 |
+
# --- Streaming "Thinking" Animation ---
|
58 |
+
chat_history.append({"role": "assistant", "content": ""}) # Add an empty placeholder for the bot response
|
59 |
|
60 |
+
thinking_steps = ["Analyzing your query...", "Searching medical databases...", "Consulting research papers...", "Synthesizing the answer..."]
|
|
|
|
|
|
|
61 |
for step in thinking_steps:
|
62 |
+
# Update the last message (the bot's placeholder) with the current thinking step
|
63 |
+
chat_history[-1]["content"] = f"<em>{step}</em>"
|
64 |
+
yield chat_history, ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
time.sleep(0.4)
|
66 |
+
# --- End of Animation ---
|
67 |
|
68 |
try:
|
69 |
response = requests.post(MODAL_BACKEND_URL, json={
|
|
|
72 |
"role": user_role
|
73 |
}, timeout=600)
|
74 |
response.raise_for_status()
|
75 |
+
reply = response.json().get("final_markdown", "No valid response was received from the backend.")
|
76 |
+
except requests.exceptions.RequestException as e:
|
77 |
+
reply = f"❗ **Error Communicating with Backend:**\n\nCould not get a response. The server may be starting up or experiencing an issue. Please try again in a moment. \n\n*Details: {str(e)}*"
|
78 |
except Exception as e:
|
79 |
+
reply = f"❗ **An Unexpected Error Occurred:**\n\n*Details: {str(e)}*"
|
80 |
|
81 |
+
# Update the final bot message with the actual reply
|
82 |
+
chat_history[-1]["content"] = reply
|
|
|
|
|
|
|
|
|
83 |
|
84 |
yield chat_history, ""
|
85 |
|
86 |
+
|
87 |
+
# --- The rest of your Gradio app code remains the same ---
|
88 |
+
with gr.Blocks(css=CUSTOM_CSS, title="MediAgent AI: Conversational Health Navigator & MCP Tool Server") as demo:
|
89 |
session_id = gr.State(lambda: str(uuid.uuid4()))
|
90 |
|
91 |
gr.Markdown("""
|
92 |
+
# 🧬 MediAgent AI: Conversational Health Navigator & MCP Tool Server
|
93 |
+
|
|
|
94 |
<div class='chatbot-box'>
|
95 |
+
<b>MediAgent AI</b> is a multilingual, role-adaptive health assistant and a fully MCP-compliant tool server.<br>
|
96 |
<ul>
|
97 |
+
<li>🌐 <b>Multilingual:</b> English, Spanish, Hindi, French</li>
|
98 |
+
<li>👤 <b>Role-Based:</b> <b>Patient</b> = simplified advice | <b>Doctor</b> = in-depth, technical insights</li>
|
99 |
+
<li>🛡️ <b>Critical Safety Layer:</b> Detects emergencies, adds safety notices</li>
|
100 |
+
<li>🔗 <b>Sourced & Verifiable:</b> Answers are backed by PubMed, FDA, etc.</li>
|
101 |
+
<li>💬 <b>Stateful Conversations:</b> Remembers chat history for contextual follow-up</li>
|
102 |
+
<li>🛠️ <b>MCP Tool Server:</b> All tools are externally callable via MCP</li>
|
103 |
+
<li>💊 <b>Drug Info:</b> Side effects, interactions, FDA label details</li>
|
104 |
+
<li>🔬 <b>Research:</b> Clinical trials & medical literature search</li>
|
105 |
</ul>
|
106 |
+
<div style='margin-top:10px; text-align:center;'>
|
107 |
+
<a href='https://modal.com/' target='_blank' style='text-decoration:none; margin-right:18px;'>
|
108 |
+
<img src='https://assets.modal.com/logos/modal-logo-dark.svg' alt='Modal Logo' style='height:32px; vertical-align:middle; margin-right:8px;'>
|
109 |
+
<span style='font-size:1.1em; color:#8aa8ff; font-weight:bold;'>Powered by Modal</span>
|
110 |
+
</a>
|
111 |
+
<a href='https://www.llamaindex.ai/' target='_blank' style='text-decoration:none;'>
|
112 |
+
<img src='https://raw.githubusercontent.com/jerryjliu/llama_index/main/docs/imgs/llama_index_logo.png' alt='LlamaIndex Logo' style='height:32px; vertical-align:middle; margin-right:8px;'>
|
113 |
+
<span style='font-size:1.1em; color:#ffb300; font-weight:bold;'>and LlamaIndex</span>
|
114 |
+
</a>
|
115 |
+
<div style='font-size:0.95em; color:#aaa; margin-top:2px;'>Special thanks to the Modal and LlamaIndex teams for their amazing platforms!</div>
|
116 |
</div>
|
117 |
+
</div>
|
118 |
+
""")
|
119 |
|
120 |
with gr.Row():
|
121 |
with gr.Column(scale=1):
|
|
|
126 |
info="Choose your user type for tailored responses"
|
127 |
)
|
128 |
with gr.Column(scale=3):
|
129 |
+
# IMPORTANT: Ensure chatbot is defined with type='messages'
|
130 |
+
chatbot = gr.Chatbot(label="Conversation", height=480, type='messages', bubble_full_width=False)
|
131 |
|
132 |
with gr.Row():
|
133 |
user_textbox = gr.Textbox(
|
|
|
135 |
lines=1,
|
136 |
scale=4
|
137 |
)
|
138 |
+
submit_btn = gr.Button("Send", elem_id="send-button", scale=1, variant="primary")
|
139 |
|
140 |
examples = gr.Examples(
|
141 |
examples=[
|
142 |
"What are the side effects of metformin?",
|
143 |
"Explain Crohn’s disease vs Ulcerative Colitis for a doctor",
|
144 |
"¿Cuáles son los síntomas de la hipertensión?",
|
145 |
+
"Can I take ibuprofen with lisinopril? (for interactions)",
|
146 |
+
"What is the FDA label information for acetaminophen?",
|
147 |
+
"Are there any ongoing clinical trials for breast cancer?",
|
148 |
],
|
149 |
inputs=[user_textbox]
|
150 |
+
)
|
151 |
|
152 |
+
gr.ClearButton([chatbot, user_textbox], value="🔄 Clear Chat")
|
153 |
|
154 |
+
# Connect submit actions
|
155 |
+
user_textbox.submit(
|
156 |
fn=handle_user_turn,
|
157 |
inputs=[user_textbox, chatbot, user_role, session_id],
|
158 |
outputs=[chatbot, user_textbox]
|
159 |
)
|
160 |
+
submit_btn.click(
|
|
|
161 |
fn=handle_user_turn,
|
162 |
inputs=[user_textbox, chatbot, user_role, session_id],
|
163 |
outputs=[chatbot, user_textbox]
|
164 |
)
|
165 |
|
166 |
+
|
167 |
if __name__ == "__main__":
|
168 |
demo.queue()
|
169 |
demo.launch()
|