Ali2206 commited on
Commit
9a8092d
·
verified ·
1 Parent(s): afdc6ee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -88
app.py CHANGED
@@ -3,13 +3,14 @@ import os
3
  import pandas as pd
4
  import json
5
  import gradio as gr
6
- from typing import List
7
  import hashlib
8
  import shutil
9
  import re
10
  from datetime import datetime
11
  import time
12
 
 
13
  persistent_dir = "/data/hf_cache"
14
  os.makedirs(persistent_dir, exist_ok=True)
15
 
@@ -36,13 +37,10 @@ def file_hash(path: str) -> str:
36
 
37
  def clean_response(text: str) -> str:
38
  try:
39
- # First try to encode/decode to handle any surrogate pairs
40
  text = text.encode('utf-8', 'surrogatepass').decode('utf-8')
41
- except UnicodeEncodeError:
42
- # Fallback to replace strategy if there are invalid characters
43
  text = text.encode('utf-8', 'replace').decode('utf-8')
44
 
45
- # Additional cleaning
46
  text = re.sub(r"\[.*?\]|\bNone\b", "", text, flags=re.DOTALL)
47
  text = re.sub(r"\n{3,}", "\n\n", text)
48
  text = re.sub(r"[^\n#\-\*\w\s\.,:\(\)]+", "", text)
@@ -59,7 +57,6 @@ def parse_excel_to_prompts(file_path: str) -> List[str]:
59
  records = []
60
  for _, row in group.iterrows():
61
  record = f"- {row['Form Name']}: {row['Form Item']} = {row['Item Response']} ({row['Interview Date']} by {row['Interviewer']})\n{row['Description']}"
62
- # Clean each record to prevent encoding issues
63
  records.append(clean_response(record))
64
 
65
  record_text = "\n".join(records)
@@ -94,73 +91,105 @@ def init_agent():
94
  target_tool_path = os.path.join(tool_cache_dir, "new_tool.json")
95
 
96
  if not os.path.exists(target_tool_path):
97
- try:
98
- shutil.copy(default_tool_path, target_tool_path)
99
- except Exception as e:
100
- raise RuntimeError(f"Failed to copy tool file: {str(e)}")
101
 
102
- try:
103
- agent = TxAgent(
104
- model_name="mims-harvard/TxAgent-T1-Llama-3.1-8B",
105
- rag_model_name="mims-harvard/ToolRAG-T1-GTE-Qwen2-1.5B",
106
- tool_files_dict={"new_tool": target_tool_path},
107
- force_finish=True,
108
- enable_checker=True,
109
- step_rag_num=4,
110
- seed=100,
111
- additional_default_tools=[],
112
- )
113
- agent.init_model()
114
- return agent
115
- except Exception as e:
116
- raise RuntimeError(f"Failed to initialize agent: {str(e)}")
117
 
118
  def create_ui(agent):
119
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
120
  gr.Markdown("# 🏥 Clinical Oversight Assistant (Excel Optimized)")
121
 
122
- with gr.Row():
123
- with gr.Column(scale=1):
124
- file_upload = gr.File(
125
- label="Upload Excel File",
126
- file_types=[".xlsx"],
127
- file_count="single",
128
- interactive=True
129
- )
130
- msg_input = gr.Textbox(
131
- label="Additional Instructions",
132
- placeholder="Add any specific analysis requests...",
133
- lines=3
134
- )
135
- send_btn = gr.Button("Analyze", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- with gr.Column(scale=2):
138
- chatbot = gr.Chatbot(
139
- label="Analysis Results",
140
- height=600,
141
- bubble_full_width=False,
142
- show_copy_button=True
143
- )
144
- download_output = gr.File(
145
- label="Download Full Report",
146
- interactive=False
147
- )
 
 
 
 
 
 
 
 
 
 
 
148
 
149
- def analyze(message: str, history: List[dict], file) -> tuple:
 
 
 
 
 
 
 
150
  if not file:
151
  raise gr.Error("Please upload an Excel file first")
152
 
153
  try:
154
- # Initial processing message
155
- history.append({"role": "user", "content": message})
156
- history.append({"role": "assistant", "content": "⏳ Processing Excel data..."})
157
- yield history, None
158
 
159
- # Parse Excel file
160
  prompts = parse_excel_to_prompts(file.name)
161
  full_output = ""
162
 
163
- # Process each booking
164
  for idx, prompt in enumerate(prompts, 1):
165
  chunk_output = ""
166
  try:
@@ -181,65 +210,59 @@ def create_ui(agent):
181
  elif isinstance(result, str):
182
  cleaned = clean_response(result)
183
  chunk_output += cleaned + "\n"
184
-
185
- # Yield intermediate results
186
  if chunk_output:
187
  output = f"--- Booking {idx} ---\n{chunk_output.strip()}\n"
188
- history[-1] = {"role": "assistant", "content": output}
189
- yield history, None
190
 
191
  except Exception as e:
192
  error_msg = f"⚠️ Error processing booking {idx}: {str(e)}"
193
- history.append({"role": "assistant", "content": error_msg})
194
- yield history, None
195
  continue
196
 
197
  if chunk_output:
198
  output = f"--- Booking {idx} ---\n{chunk_output.strip()}\n"
199
- history.append({"role": "assistant", "content": output})
200
  full_output += output + "\n"
201
- yield history, None
202
 
203
  # Save report
204
  file_hash_value = file_hash(file.name)
205
  report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt")
206
  with open(report_path, "w", encoding="utf-8") as f:
207
  f.write(full_output)
208
-
209
- yield history, report_path if os.path.exists(report_path) else None
210
 
211
  except Exception as e:
212
- history.append({"role": "assistant", "content": f"❌ Error: {str(e)}"})
213
- yield history, None
214
  raise gr.Error(f"Analysis failed: {str(e)}")
215
-
 
 
 
216
  # Event handlers
217
  send_btn.click(
218
  analyze,
219
- inputs=[msg_input, gr.State([]), file_upload],
220
  outputs=[chatbot, download_output],
221
  api_name="analyze"
222
  )
223
 
224
  msg_input.submit(
225
  analyze,
226
- inputs=[msg_input, gr.State([]), file_upload],
227
  outputs=[chatbot, download_output]
228
  )
229
 
230
- # Additional UI elements
231
- with gr.Accordion("Instructions", open=False):
232
- gr.Markdown("""
233
- **How to use:**
234
- 1. Upload an Excel file containing patient records
235
- 2. Optionally add specific analysis instructions
236
- 3. Click 'Analyze' to process the data
237
- 4. Review results and download the full report
238
-
239
- **Excel Format Requirements:**
240
- - Must contain columns: Booking Number, Form Name, Form Item, Item Response, Interview Date, Interviewer, Description
241
- - Each row represents one patient record item
242
- """)
243
 
244
  return demo
245
 
@@ -248,7 +271,6 @@ if __name__ == "__main__":
248
  agent = init_agent()
249
  demo = create_ui(agent)
250
 
251
- # Launch with error handling
252
  demo.queue(
253
  api_open=False,
254
  max_size=20
@@ -257,7 +279,7 @@ if __name__ == "__main__":
257
  server_port=7860,
258
  show_error=True,
259
  allowed_paths=[report_dir],
260
- share=False # Changed to False to avoid the warning
261
  )
262
  except Exception as e:
263
  print(f"Failed to launch application: {str(e)}")
 
3
  import pandas as pd
4
  import json
5
  import gradio as gr
6
+ from typing import List, Tuple
7
  import hashlib
8
  import shutil
9
  import re
10
  from datetime import datetime
11
  import time
12
 
13
+ # Configuration and setup
14
  persistent_dir = "/data/hf_cache"
15
  os.makedirs(persistent_dir, exist_ok=True)
16
 
 
37
 
38
  def clean_response(text: str) -> str:
39
  try:
 
40
  text = text.encode('utf-8', 'surrogatepass').decode('utf-8')
41
+ except UnicodeError:
 
42
  text = text.encode('utf-8', 'replace').decode('utf-8')
43
 
 
44
  text = re.sub(r"\[.*?\]|\bNone\b", "", text, flags=re.DOTALL)
45
  text = re.sub(r"\n{3,}", "\n\n", text)
46
  text = re.sub(r"[^\n#\-\*\w\s\.,:\(\)]+", "", text)
 
57
  records = []
58
  for _, row in group.iterrows():
59
  record = f"- {row['Form Name']}: {row['Form Item']} = {row['Item Response']} ({row['Interview Date']} by {row['Interviewer']})\n{row['Description']}"
 
60
  records.append(clean_response(record))
61
 
62
  record_text = "\n".join(records)
 
91
  target_tool_path = os.path.join(tool_cache_dir, "new_tool.json")
92
 
93
  if not os.path.exists(target_tool_path):
94
+ shutil.copy(default_tool_path, target_tool_path)
 
 
 
95
 
96
+ agent = TxAgent(
97
+ model_name="mims-harvard/TxAgent-T1-Llama-3.1-8B",
98
+ rag_model_name="mims-harvard/ToolRAG-T1-GTE-Qwen2-1.5B",
99
+ tool_files_dict={"new_tool": target_tool_path},
100
+ force_finish=True,
101
+ enable_checker=True,
102
+ step_rag_num=4,
103
+ seed=100,
104
+ additional_default_tools=[],
105
+ )
106
+ agent.init_model()
107
+ return agent
 
 
 
108
 
109
  def create_ui(agent):
110
+ with gr.Blocks(theme=gr.themes.Soft(), title="Clinical Oversight Assistant") as demo:
111
  gr.Markdown("# 🏥 Clinical Oversight Assistant (Excel Optimized)")
112
 
113
+ with gr.Tabs():
114
+ with gr.TabItem("Analysis"):
115
+ with gr.Row():
116
+ # Left column - Inputs
117
+ with gr.Column(scale=1):
118
+ file_upload = gr.File(
119
+ label="Upload Excel File",
120
+ file_types=[".xlsx"],
121
+ file_count="single",
122
+ interactive=True
123
+ )
124
+ msg_input = gr.Textbox(
125
+ label="Additional Instructions",
126
+ placeholder="Add any specific analysis requests...",
127
+ lines=3
128
+ )
129
+ with gr.Row():
130
+ clear_btn = gr.Button("Clear", variant="secondary")
131
+ send_btn = gr.Button("Analyze", variant="primary")
132
+
133
+ # Right column - Outputs
134
+ with gr.Column(scale=2):
135
+ chatbot = gr.Chatbot(
136
+ label="Analysis Results",
137
+ height=600,
138
+ bubble_full_width=False,
139
+ show_copy_button=True
140
+ )
141
+ download_output = gr.File(
142
+ label="Download Full Report",
143
+ interactive=False
144
+ )
145
+
146
+ with gr.TabItem("Instructions"):
147
+ gr.Markdown("""
148
+ ## How to Use This Tool
149
 
150
+ 1. **Upload Excel File**: Select your patient records Excel file
151
+ 2. **Add Instructions** (Optional): Provide any specific analysis requests
152
+ 3. **Click Analyze**: The system will process each patient record
153
+ 4. **Review Results**: Analysis appears in the chat window
154
+ 5. **Download Report**: Get a full text report of all findings
155
+
156
+ ### Excel File Requirements
157
+ Your Excel file must contain these columns:
158
+ - Booking Number
159
+ - Form Name
160
+ - Form Item
161
+ - Item Response
162
+ - Interview Date
163
+ - Interviewer
164
+ - Description
165
+
166
+ ### Analysis Includes
167
+ - Missed diagnoses
168
+ - Medication conflicts
169
+ - Incomplete assessments
170
+ - Urgent follow-up needs
171
+ """)
172
 
173
+ def format_message(role: str, content: str) -> Tuple[str, str]:
174
+ """Format messages for the chatbot in (user, bot) format"""
175
+ if role == "user":
176
+ return (content, None)
177
+ else:
178
+ return (None, content)
179
+
180
+ def analyze(message: str, chat_history: List[Tuple[str, str]], file) -> Tuple[List[Tuple[str, str]], str]:
181
  if not file:
182
  raise gr.Error("Please upload an Excel file first")
183
 
184
  try:
185
+ # Initialize chat history with user message
186
+ new_history = chat_history + [format_message("user", message)]
187
+ new_history.append(format_message("assistant", "⏳ Processing Excel data..."))
188
+ yield new_history, None
189
 
 
190
  prompts = parse_excel_to_prompts(file.name)
191
  full_output = ""
192
 
 
193
  for idx, prompt in enumerate(prompts, 1):
194
  chunk_output = ""
195
  try:
 
210
  elif isinstance(result, str):
211
  cleaned = clean_response(result)
212
  chunk_output += cleaned + "\n"
213
+
 
214
  if chunk_output:
215
  output = f"--- Booking {idx} ---\n{chunk_output.strip()}\n"
216
+ new_history[-1] = format_message("assistant", output)
217
+ yield new_history, None
218
 
219
  except Exception as e:
220
  error_msg = f"⚠️ Error processing booking {idx}: {str(e)}"
221
+ new_history.append(format_message("assistant", error_msg))
222
+ yield new_history, None
223
  continue
224
 
225
  if chunk_output:
226
  output = f"--- Booking {idx} ---\n{chunk_output.strip()}\n"
227
+ new_history.append(format_message("assistant", output))
228
  full_output += output + "\n"
229
+ yield new_history, None
230
 
231
  # Save report
232
  file_hash_value = file_hash(file.name)
233
  report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt")
234
  with open(report_path, "w", encoding="utf-8") as f:
235
  f.write(full_output)
236
+
237
+ yield new_history, report_path if os.path.exists(report_path) else None
238
 
239
  except Exception as e:
240
+ new_history.append(format_message("assistant", f"❌ Error: {str(e)}"))
241
+ yield new_history, None
242
  raise gr.Error(f"Analysis failed: {str(e)}")
243
+
244
+ def clear_chat():
245
+ return [], None
246
+
247
  # Event handlers
248
  send_btn.click(
249
  analyze,
250
+ inputs=[msg_input, chatbot, file_upload],
251
  outputs=[chatbot, download_output],
252
  api_name="analyze"
253
  )
254
 
255
  msg_input.submit(
256
  analyze,
257
+ inputs=[msg_input, chatbot, file_upload],
258
  outputs=[chatbot, download_output]
259
  )
260
 
261
+ clear_btn.click(
262
+ clear_chat,
263
+ inputs=[],
264
+ outputs=[chatbot, download_output]
265
+ )
 
 
 
 
 
 
 
 
266
 
267
  return demo
268
 
 
271
  agent = init_agent()
272
  demo = create_ui(agent)
273
 
 
274
  demo.queue(
275
  api_open=False,
276
  max_size=20
 
279
  server_port=7860,
280
  show_error=True,
281
  allowed_paths=[report_dir],
282
+ share=False
283
  )
284
  except Exception as e:
285
  print(f"Failed to launch application: {str(e)}")