Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- README.md +2 -10
- medication_copilot.py +228 -0
- requirements.txt +3 -2
README.md
CHANGED
@@ -1,12 +1,3 @@
|
|
1 |
-
---
|
2 |
-
license: mit
|
3 |
-
title: Med-Copilot
|
4 |
-
sdk: streamlit
|
5 |
-
python_version: 3.10.0
|
6 |
-
short_description: perform an AI based analysis of medications
|
7 |
-
app_file: med_streamlit.py
|
8 |
-
sdk_version: 1.42.2
|
9 |
-
---
|
10 |
# Medication research CoPilot
|
11 |
|
12 |
## Introduction
|
@@ -38,4 +29,5 @@ streamlit run med_streamlit.py
|
|
38 |
|
39 |
## Prompt
|
40 |
Note that the default system prompt can be found [here](med_streamlit.py).
|
41 |
-
Consider modifying the prompt to better suit your needs, for example for a specific disease or condition.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# Medication research CoPilot
|
2 |
|
3 |
## Introduction
|
|
|
29 |
|
30 |
## Prompt
|
31 |
Note that the default system prompt can be found [here](med_streamlit.py).
|
32 |
+
Consider modifying the prompt to better suit your needs, for example for a specific disease or condition.
|
33 |
+
|
medication_copilot.py
ADDED
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from functools import partial
|
2 |
+
import gradio as gr
|
3 |
+
|
4 |
+
from src.gradio_utils import (
|
5 |
+
extract_table_from_chat,
|
6 |
+
upload_file,
|
7 |
+
redo,
|
8 |
+
undo,
|
9 |
+
edit_or_save_changes,
|
10 |
+
update_llm_selection,
|
11 |
+
)
|
12 |
+
from src.llm_calls import query_llm
|
13 |
+
from src.data_handler import generate_excel_base64
|
14 |
+
|
15 |
+
SYSTEM_PROMPT = """You are a pharmacology assistant specialized in analyzing and structuring medical data.
|
16 |
+
|
17 |
+
Inputs You Receive:
|
18 |
+
A JSON dataset representing medications for Retinitis Pigmentosa
|
19 |
+
|
20 |
+
A user query requesting additional details to be added to the dataset
|
21 |
+
|
22 |
+
Your Task:
|
23 |
+
Analyze the dataset and determine what new information is needed
|
24 |
+
|
25 |
+
Research and generate new details based on the user’s request
|
26 |
+
|
27 |
+
Enhance the dataset by adding the requested information
|
28 |
+
|
29 |
+
Ensure completeness: The updated dataset must always include all medications
|
30 |
+
|
31 |
+
Your Output:
|
32 |
+
A succinct response explaining your findings and how the dataset was extended
|
33 |
+
|
34 |
+
A fully updated JSON dataset, strictly following this format:
|
35 |
+
|
36 |
+
json
|
37 |
+
Copy
|
38 |
+
Edit
|
39 |
+
{
|
40 |
+
"Medications": [
|
41 |
+
{"Name": "Medication Name", "key1": "value1", "key2": "value2", ...},
|
42 |
+
{"Name": "Medication Name", "key1": "value1", "key2": "value2", ...}
|
43 |
+
]
|
44 |
+
}
|
45 |
+
Key Requirements:
|
46 |
+
- JSON output is mandatory in every response
|
47 |
+
- All medications must be present in the JSON, even if unchanged
|
48 |
+
- Extend the dataset with newly generated information—do not just retrieve existing data
|
49 |
+
- No repetition of the example JSON—only return the updated data
|
50 |
+
- Verify the JSON before responding to ensure it is well-formed and complete
|
51 |
+
|
52 |
+
Always structure your response clearly:
|
53 |
+
|
54 |
+
- Text Summary: Explanation of findings and dataset extensions
|
55 |
+
|
56 |
+
- Updated JSON Dataset: Full dataset with all medications, including new information
|
57 |
+
|
58 |
+
- References & Sources (if applicable)
|
59 |
+
"""
|
60 |
+
|
61 |
+
|
62 |
+
with gr.Blocks(theme=gr.themes.Glass()) as app:
|
63 |
+
df_before = gr.State([]) # Undo history
|
64 |
+
df_state = gr.State(None) # Current DataFrame
|
65 |
+
df_after = gr.State([]) # Redo history
|
66 |
+
last_response = gr.State("") # Store last LLM response
|
67 |
+
edit_mode = gr.State("Edit") # Track edit mode
|
68 |
+
base64data = gr.State(None)
|
69 |
+
|
70 |
+
with gr.Sidebar():
|
71 |
+
gr.Markdown("### Configuration")
|
72 |
+
llm_type = gr.Radio(
|
73 |
+
choices=["OpenAI", "Perplexity"], label="LLM Type", value="OpenAI"
|
74 |
+
)
|
75 |
+
|
76 |
+
api_key = gr.Textbox(
|
77 |
+
label="OpenAI API Key", placeholder="Enter OpenAI API Key", interactive=True
|
78 |
+
)
|
79 |
+
|
80 |
+
gr.Markdown("### Upload existing data")
|
81 |
+
file_upload = gr.File(label="Upload Excel File", file_types=[".xlsx"])
|
82 |
+
gr.Markdown("### Download table to Excel")
|
83 |
+
excel_output = gr.State(None)
|
84 |
+
|
85 |
+
excel_data = gr.Textbox(visible=False)
|
86 |
+
download_button = gr.DownloadButton(label="Download dataset")
|
87 |
+
|
88 |
+
download_button.click(
|
89 |
+
generate_excel_base64, inputs=[df_state], outputs=[excel_data]
|
90 |
+
)
|
91 |
+
|
92 |
+
excel_data.change(
|
93 |
+
None,
|
94 |
+
[excel_data],
|
95 |
+
None,
|
96 |
+
js="""
|
97 |
+
(base64Data) => {
|
98 |
+
const binaryString = atob(base64Data);
|
99 |
+
const len = binaryString.length;
|
100 |
+
const bytes = new Uint8Array(len);
|
101 |
+
for (let i = 0; i < len; i++) {
|
102 |
+
bytes[i] = binaryString.charCodeAt(i);
|
103 |
+
}
|
104 |
+
const blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
|
105 |
+
|
106 |
+
const link = document.createElement("a");
|
107 |
+
link.href = URL.createObjectURL(blob);
|
108 |
+
link.download = "dataset.xlsx";
|
109 |
+
document.body.appendChild(link);
|
110 |
+
link.click();
|
111 |
+
document.body.removeChild(link);
|
112 |
+
}
|
113 |
+
""",
|
114 |
+
)
|
115 |
+
|
116 |
+
llm_type.change(update_llm_selection, inputs=[llm_type], outputs=[api_key])
|
117 |
+
with gr.Accordion("System Prompt", open=False):
|
118 |
+
system_prompt_box = gr.Textbox(
|
119 |
+
value=SYSTEM_PROMPT, interactive=True, lines=10, label="System Prompt"
|
120 |
+
)
|
121 |
+
|
122 |
+
gr.Markdown("## Medications Data CoPilot")
|
123 |
+
# Chat Interface
|
124 |
+
chat = gr.ChatInterface(
|
125 |
+
fn=query_llm,
|
126 |
+
type="messages",
|
127 |
+
description="Chat with an LLM to create a data representation of medications.",
|
128 |
+
stop_btn=False,
|
129 |
+
save_history=False,
|
130 |
+
additional_inputs=[df_state, llm_type, api_key, system_prompt_box],
|
131 |
+
examples=[
|
132 |
+
[
|
133 |
+
"List 10 medications that are known to be effective for Retinitis Pigmentosa"
|
134 |
+
],
|
135 |
+
[
|
136 |
+
"Add a column specifying if the medication passes the Retinal Blood Barrier"
|
137 |
+
],
|
138 |
+
["Add the safety profile for each medication"],
|
139 |
+
["Create four columns, each specifying each of the ADME profile factors"],
|
140 |
+
[
|
141 |
+
"Categorize each column into up to five categories, for simple classification."
|
142 |
+
],
|
143 |
+
],
|
144 |
+
)
|
145 |
+
with gr.Row():
|
146 |
+
gr.Markdown("### Medications Table")
|
147 |
+
with gr.Row():
|
148 |
+
update_button = gr.Button(
|
149 |
+
"Update table using the chat information", scale=8, interactive=True
|
150 |
+
)
|
151 |
+
with gr.Row():
|
152 |
+
dataframe_display = gr.DataFrame(interactive=False)
|
153 |
+
with gr.Row():
|
154 |
+
prev_button = gr.Button("<-", interactive=False, scale=1)
|
155 |
+
edit_save_button = gr.Button("Edit", interactive=True, scale=2)
|
156 |
+
next_button = gr.Button("->", interactive=False, scale=1)
|
157 |
+
|
158 |
+
# Save user changes
|
159 |
+
edit_save_button.click(
|
160 |
+
edit_or_save_changes,
|
161 |
+
inputs=[dataframe_display, df_before, df_state, df_after, edit_mode],
|
162 |
+
outputs=[
|
163 |
+
dataframe_display, # Updated DataFrame
|
164 |
+
df_before, # Undo history
|
165 |
+
df_state, # Current state
|
166 |
+
df_after, # Redo history
|
167 |
+
prev_button, # Update prev button
|
168 |
+
next_button, # Update next button
|
169 |
+
dataframe_display, # Update DataFrame interactivity
|
170 |
+
edit_save_button, # Update button label
|
171 |
+
edit_mode, # Update edit mode
|
172 |
+
],
|
173 |
+
)
|
174 |
+
# Undo button
|
175 |
+
prev_button.click(
|
176 |
+
undo,
|
177 |
+
inputs=[df_before, df_state, df_after],
|
178 |
+
outputs=[
|
179 |
+
dataframe_display,
|
180 |
+
df_before,
|
181 |
+
df_state,
|
182 |
+
df_after,
|
183 |
+
prev_button,
|
184 |
+
next_button,
|
185 |
+
],
|
186 |
+
)
|
187 |
+
# Redo button
|
188 |
+
next_button.click(
|
189 |
+
redo,
|
190 |
+
inputs=[df_before, df_state, df_after],
|
191 |
+
outputs=[
|
192 |
+
dataframe_display,
|
193 |
+
df_before,
|
194 |
+
df_state,
|
195 |
+
df_after,
|
196 |
+
prev_button,
|
197 |
+
next_button,
|
198 |
+
],
|
199 |
+
)
|
200 |
+
# File upload event
|
201 |
+
file_upload.change(
|
202 |
+
upload_file,
|
203 |
+
inputs=[file_upload, df_before, df_state, df_after],
|
204 |
+
outputs=[
|
205 |
+
dataframe_display,
|
206 |
+
df_before,
|
207 |
+
df_state,
|
208 |
+
df_after,
|
209 |
+
prev_button,
|
210 |
+
next_button,
|
211 |
+
],
|
212 |
+
)
|
213 |
+
# Update button copies chat history to text box
|
214 |
+
update_button.click(
|
215 |
+
partial(extract_table_from_chat, key="Medications"),
|
216 |
+
inputs=[chat.chatbot, df_before, df_state, df_after, llm_type, api_key],
|
217 |
+
outputs=[
|
218 |
+
dataframe_display,
|
219 |
+
df_before,
|
220 |
+
df_state,
|
221 |
+
df_after,
|
222 |
+
prev_button,
|
223 |
+
next_button,
|
224 |
+
],
|
225 |
+
)
|
226 |
+
|
227 |
+
# Launch App
|
228 |
+
app.launch()
|
requirements.txt
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
pandas
|
2 |
-
|
3 |
openai
|
4 |
openpyxl
|
5 |
xlsxwriter
|
6 |
pydantic
|
7 |
simplejson
|
8 |
-
python-dotenv
|
|
|
|
1 |
pandas
|
2 |
+
gradio
|
3 |
openai
|
4 |
openpyxl
|
5 |
xlsxwriter
|
6 |
pydantic
|
7 |
simplejson
|
8 |
+
python-dotenv
|
9 |
+
requests
|