Ali2206 commited on
Commit
afdc6ee
·
verified ·
1 Parent(s): 47356aa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +189 -80
app.py CHANGED
@@ -35,23 +35,35 @@ def file_hash(path: str) -> str:
35
  return hashlib.md5(f.read()).hexdigest()
36
 
37
  def clean_response(text: str) -> str:
38
- text = text.encode("utf-16", "surrogatepass").decode("utf-16", "ignore")
 
 
 
 
 
 
 
39
  text = re.sub(r"\[.*?\]|\bNone\b", "", text, flags=re.DOTALL)
40
  text = re.sub(r"\n{3,}", "\n\n", text)
41
  text = re.sub(r"[^\n#\-\*\w\s\.,:\(\)]+", "", text)
42
  return text.strip()
43
 
44
  def parse_excel_to_prompts(file_path: str) -> List[str]:
45
- xl = pd.ExcelFile(file_path)
46
- df = xl.parse(xl.sheet_names[0], header=0).fillna("")
47
- groups = df.groupby("Booking Number")
48
- prompts = []
49
- for booking, group in groups:
50
- records = []
51
- for _, row in group.iterrows():
52
- records.append(f"- {row['Form Name']}: {row['Form Item']} = {row['Item Response']} ({row['Interview Date']} by {row['Interviewer']})\n{row['Description']}")
53
- record_text = "\n".join(records)
54
- prompt = f"""
 
 
 
 
 
55
  Patient Booking Number: {booking}
56
 
57
  Instructions:
@@ -72,84 +84,181 @@ Data:
72
  ### Urgent Follow-up
73
  - ...
74
  """
75
- prompts.append(prompt)
76
- return prompts
 
 
77
 
78
  def init_agent():
79
  default_tool_path = os.path.abspath("data/new_tool.json")
80
  target_tool_path = os.path.join(tool_cache_dir, "new_tool.json")
 
81
  if not os.path.exists(target_tool_path):
82
- shutil.copy(default_tool_path, target_tool_path)
83
- agent = TxAgent(
84
- model_name="mims-harvard/TxAgent-T1-Llama-3.1-8B",
85
- rag_model_name="mims-harvard/ToolRAG-T1-GTE-Qwen2-1.5B",
86
- tool_files_dict={"new_tool": target_tool_path},
87
- force_finish=True,
88
- enable_checker=True,
89
- step_rag_num=4,
90
- seed=100,
91
- additional_default_tools=[],
92
- )
93
- agent.init_model()
94
- return agent
 
 
 
 
 
 
 
95
 
96
  def create_ui(agent):
97
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
98
- gr.Markdown("<h1 style='text-align: center;'>\ud83e\uddfa Clinical Oversight Assistant (Excel Optimized)</h1>")
99
- chatbot = gr.Chatbot(label="Analysis", height=600, type="messages")
100
- file_upload = gr.File(file_types=[".xlsx"], file_count="single")
101
- msg_input = gr.Textbox(placeholder="Ask about patient history...", show_label=False)
102
- send_btn = gr.Button("Analyze", variant="primary")
103
- download_output = gr.File(label="Download Full Report")
104
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  def analyze(message: str, history: List[dict], file) -> tuple:
106
- history.append({"role": "user", "content": message})
107
- history.append({"role": "assistant", "content": "⏳ Processing Excel data..."})
108
- yield history, None
109
-
110
- prompts = parse_excel_to_prompts(file.name)
111
- full_output = ""
112
-
113
- for idx, prompt in enumerate(prompts, 1):
114
- chunk_output = ""
115
- for result in agent.run_gradio_chat(
116
- message=prompt,
117
- history=[],
118
- temperature=0.2,
119
- max_new_tokens=1024,
120
- max_token=4096,
121
- call_agent=False,
122
- conversation=[],
123
- ):
124
- if isinstance(result, list):
125
- for r in result:
126
- if hasattr(r, 'content') and r.content:
127
- chunk_output += clean_response(r.content) + "\n"
128
- elif isinstance(result, str):
129
- chunk_output += clean_response(result) + "\n"
130
- if chunk_output:
131
- output = f"--- Booking {idx} ---\n{chunk_output.strip()}\n"
132
- history.append({"role": "assistant", "content": output})
133
- full_output += output + "\n"
134
- yield history, None
135
-
136
- file_hash_value = file_hash(file.name)
137
- report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt")
138
- with open(report_path, "w", encoding="utf-8") as f:
139
- f.write(full_output)
140
- yield history, report_path if os.path.exists(report_path) else None
141
-
142
- send_btn.click(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output])
143
- msg_input.submit(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  return demo
145
 
146
  if __name__ == "__main__":
147
- agent = init_agent()
148
- demo = create_ui(agent)
149
- demo.queue(api_open=False).launch(
150
- server_name="0.0.0.0",
151
- server_port=7860,
152
- show_error=True,
153
- allowed_paths=[report_dir],
154
- share=True
155
- )
 
 
 
 
 
 
 
 
 
 
35
  return hashlib.md5(f.read()).hexdigest()
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)
49
  return text.strip()
50
 
51
  def parse_excel_to_prompts(file_path: str) -> List[str]:
52
+ try:
53
+ xl = pd.ExcelFile(file_path)
54
+ df = xl.parse(xl.sheet_names[0], header=0).fillna("")
55
+ groups = df.groupby("Booking Number")
56
+ prompts = []
57
+
58
+ for booking, group in groups:
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)
66
+ prompt = f"""
67
  Patient Booking Number: {booking}
68
 
69
  Instructions:
 
84
  ### Urgent Follow-up
85
  - ...
86
  """
87
+ prompts.append(prompt)
88
+ return prompts
89
+ except Exception as e:
90
+ raise ValueError(f"Error parsing Excel file: {str(e)}")
91
 
92
  def init_agent():
93
  default_tool_path = os.path.abspath("data/new_tool.json")
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:
167
+ for result in agent.run_gradio_chat(
168
+ message=prompt,
169
+ history=[],
170
+ temperature=0.2,
171
+ max_new_tokens=1024,
172
+ max_token=4096,
173
+ call_agent=False,
174
+ conversation=[],
175
+ ):
176
+ if isinstance(result, list):
177
+ for r in result:
178
+ if hasattr(r, 'content') and r.content:
179
+ cleaned = clean_response(r.content)
180
+ chunk_output += cleaned + "\n"
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
 
246
  if __name__ == "__main__":
247
+ try:
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
255
+ ).launch(
256
+ server_name="0.0.0.0",
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)}")
264
+ sys.exit(1)