Ali2206 commited on
Commit
4044b30
·
verified ·
1 Parent(s): 2ce0a4e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -61
app.py CHANGED
@@ -139,66 +139,75 @@ def log_system_usage(tag=""):
139
 
140
  def clean_response(text: str) -> str:
141
  text = sanitize_utf8(text)
 
142
  text = re.sub(r"\[.*?\]|\bNone\b|To analyze the patient record excerpt.*?medications\.|Since the previous attempts.*?\.|I need to.*?medications\.|Retrieving tools.*?\.", "", text, flags=re.DOTALL)
143
- text = re.sub(r"\n{3,}", "\n\n", text)
144
- text = re.sub(r"[^\n#\-\*\w\s\.\,\:\(\)]+", "", text)
145
-
146
- sections = {}
147
- current_section = None
148
  lines = text.splitlines()
 
149
  for line in lines:
150
  line = line.strip()
151
  if not line:
152
  continue
153
- section_match = re.match(r"###\s*(Missed Diagnoses|Medication Conflicts|Incomplete Assessments|Urgent Follow-up)", line)
154
- if section_match:
155
- current_section = section_match.group(1)
156
- if current_section not in sections:
157
- sections[current_section] = []
158
  continue
159
- finding_match = re.match(r"-\s*.+", line)
160
- if finding_match and current_section and not re.match(r"-\s*No issues identified", line):
161
- sections[current_section].append(line)
162
-
163
- cleaned = []
164
- for heading, findings in sections.items():
165
- if findings:
166
- cleaned.append(f"### {heading}\n" + "\n".join(findings))
167
-
168
- text = "\n\n".join(cleaned).strip()
 
 
169
  return text if text else ""
170
 
171
  def summarize_findings(combined_response: str) -> str:
172
- if not combined_response or all("No oversights identified" in chunk for chunk in combined_response.split("--- Analysis for Chunk")):
173
- return "### Summary of Clinical Oversights\nNo critical oversights identified in the provided records."
174
-
175
- sections = {}
176
- lines = combined_response.splitlines()
177
- current_section = None
178
- for line in lines:
179
- line = line.strip()
180
- if not line:
181
- continue
182
- section_match = re.match(r"###\s*(Missed Diagnoses|Medication Conflicts|Incomplete Assessments|Urgent Follow-up)", line)
183
- if section_match:
184
- current_section = section_match.group(1)
185
- if current_section not in sections:
186
- sections[current_section] = []
187
  continue
188
- finding_match = re.match(r"-\s*(.+)", line)
189
- if finding_match and current_section:
190
- sections[current_section].append(finding_match.group(1))
191
-
192
- summary_lines = []
193
- for heading, findings in sections.items():
194
- if findings:
195
- summary = f"- **{heading}**: {'; '.join(findings[:2])}. Risks: {heading.lower()} may lead to adverse outcomes. Recommend: urgent review and specialist referral."
196
- summary_lines.append(summary)
197
-
198
- if not summary_lines:
199
- return "### Summary of Clinical Oversights\nNo critical oversights identified."
200
-
201
- return "### Summary of Clinical Oversights\n" + "\n".join(summary_lines)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  def init_agent():
204
  logger.info("Initializing model...")
@@ -227,7 +236,7 @@ def create_ui(agent):
227
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
228
  gr.Markdown("<h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>")
229
  chatbot = gr.Chatbot(label="Detailed Analysis", height=600, type="messages")
230
- final_summary = gr.Markdown(label="Summary of Clinical Oversights")
231
  file_upload = gr.File(file_types=[".pdf", ".csv", ".xls", ".xlsx"], file_count="multiple")
232
  msg_input = gr.Textbox(placeholder="Ask about potential oversights...", show_label=False)
233
  send_btn = gr.Button("Analyze", variant="primary")
@@ -235,7 +244,7 @@ def create_ui(agent):
235
  progress_bar = gr.Progress()
236
 
237
  prompt_template = """
238
- Analyze the patient record excerpt for clinical oversights. Provide a concise, evidence-based summary in markdown with findings grouped under headings (e.g., 'Missed Diagnoses'). For each finding, include clinical context, risks, and recommendations. Output only markdown bullet points under headings. If no issues, state "No issues identified".
239
  Patient Record Excerpt (Chunk {0} of {1}):
240
  {chunk}
241
  """
@@ -284,13 +293,13 @@ Patient Record Excerpt (Chunk {0} of {1}):
284
  for m in chunk_output:
285
  if hasattr(m, 'content') and m.content:
286
  cleaned = clean_response(m.content)
287
- if cleaned and re.search(r"###\s*\w+", cleaned):
288
- chunk_response += cleaned + "\n\n"
289
  elif isinstance(chunk_output, str) and chunk_output.strip():
290
- cleaned = clean_response(m.content)
291
- if cleaned and re.search(r"###\s*\w+", cleaned):
292
- chunk_response += cleaned + "\n\n"
293
- batch_responses.append(chunk_response)
294
  torch.cuda.empty_cache()
295
  gc.collect()
296
 
@@ -298,14 +307,14 @@ Patient Record Excerpt (Chunk {0} of {1}):
298
  if chunk_response:
299
  combined_response += f"--- Analysis for Chunk {chunk_idx} ---\n{chunk_response}\n"
300
  else:
301
- combined_response += f"--- Analysis for Chunk {chunk_idx} ---\nNo oversights identified for this chunk.\n\n"
302
  history[-1] = {"role": "assistant", "content": combined_response.strip()}
303
  yield history, None, ""
304
 
305
- if combined_response.strip() and not all("No oversights identified" in chunk for chunk in combined_response.split("--- Analysis for Chunk")):
306
  history[-1]["content"] = combined_response.strip()
307
  else:
308
- history.append({"role": "assistant", "content": "No oversights identified in the provided records."})
309
 
310
  summary = summarize_findings(combined_response)
311
  report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt") if file_hash_value else None
@@ -317,7 +326,7 @@ Patient Record Excerpt (Chunk {0} of {1}):
317
  except Exception as e:
318
  logger.error("Analysis error: %s", e)
319
  history.append({"role": "assistant", "content": f"❌ Error occurred: {str(e)}"})
320
- yield history, None, f"### Summary of Clinical Oversights\nError occurred during analysis: {str(e)}"
321
 
322
  send_btn.click(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output, final_summary])
323
  msg_input.submit(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output, final_summary])
 
139
 
140
  def clean_response(text: str) -> str:
141
  text = sanitize_utf8(text)
142
+ # Remove unwanted patterns and tool call artifacts
143
  text = re.sub(r"\[.*?\]|\bNone\b|To analyze the patient record excerpt.*?medications\.|Since the previous attempts.*?\.|I need to.*?medications\.|Retrieving tools.*?\.", "", text, flags=re.DOTALL)
144
+ # Extract only missed diagnoses, ignoring other categories
145
+ diagnoses = []
 
 
 
146
  lines = text.splitlines()
147
+ in_diagnoses_section = False
148
  for line in lines:
149
  line = line.strip()
150
  if not line:
151
  continue
152
+ if re.match(r"###\s*Missed Diagnoses", line):
153
+ in_diagnoses_section = True
 
 
 
154
  continue
155
+ if re.match(r"###\s*(Medication Conflicts|Incomplete Assessments|Urgent Follow-up)", line):
156
+ in_diagnoses_section = False
157
+ continue
158
+ if in_diagnoses_section and re.match(r"-\s*.+", line):
159
+ diagnosis = re.sub(r"^\-\s*", "", line).strip()
160
+ if diagnosis and not re.match(r"No issues identified", diagnosis, re.IGNORECASE):
161
+ diagnoses.append(diagnosis)
162
+ # Join diagnoses into a plain text paragraph
163
+ text = " ".join(diagnoses)
164
+ # Clean up extra whitespace and punctuation
165
+ text = re.sub(r"\s+", " ", text).strip()
166
+ text = re.sub(r"[^\w\s\.\,\(\)\-]", "", text)
167
  return text if text else ""
168
 
169
  def summarize_findings(combined_response: str) -> str:
170
+ # Split response by chunk analyses
171
+ chunks = combined_response.split("--- Analysis for Chunk")
172
+ diagnoses = []
173
+ for chunk in chunks:
174
+ chunk = chunk.strip()
175
+ if not chunk or "No oversights identified" in chunk:
 
 
 
 
 
 
 
 
 
176
  continue
177
+ # Extract missed diagnoses from chunk
178
+ lines = chunk.splitlines()
179
+ in_diagnoses_section = False
180
+ for line in lines:
181
+ line = line.strip()
182
+ if not line:
183
+ continue
184
+ if re.match(r"###\s*Missed Diagnoses", line):
185
+ in_diagnoses_section = True
186
+ continue
187
+ if re.match(r"###\s*(Medication Conflicts|Incomplete Assessments|Urgent Follow-up)", line):
188
+ in_diagnoses_section = False
189
+ continue
190
+ if in_diagnoses_section and re.match(r"-\s*.+", line):
191
+ diagnosis = re.sub(r"^\-\s*", "", line).strip()
192
+ if diagnosis and not re.match(r"No issues identified", diagnosis, re.IGNORECASE):
193
+ diagnoses.append(diagnosis)
194
+
195
+ # Remove duplicates while preserving order
196
+ seen = set()
197
+ unique_diagnoses = [d for d in diagnoses if not (d in seen or seen.add(d))]
198
+
199
+ if not unique_diagnoses:
200
+ return "No missed diagnoses were identified in the provided records."
201
+
202
+ # Combine into a single paragraph
203
+ summary = "Missed diagnoses include " + ", ".join(unique_diagnoses[:-1])
204
+ if len(unique_diagnoses) > 1:
205
+ summary += f", and {unique_diagnoses[-1]}"
206
+ elif len(unique_diagnoses) == 1:
207
+ summary = "Missed diagnoses include " + unique_diagnoses[0]
208
+ summary += ", all of which require urgent clinical review to prevent potential adverse outcomes."
209
+
210
+ return summary.strip()
211
 
212
  def init_agent():
213
  logger.info("Initializing model...")
 
236
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
237
  gr.Markdown("<h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>")
238
  chatbot = gr.Chatbot(label="Detailed Analysis", height=600, type="messages")
239
+ final_summary = gr.Markdown(label="Summary of Missed Diagnoses")
240
  file_upload = gr.File(file_types=[".pdf", ".csv", ".xls", ".xlsx"], file_count="multiple")
241
  msg_input = gr.Textbox(placeholder="Ask about potential oversights...", show_label=False)
242
  send_btn = gr.Button("Analyze", variant="primary")
 
244
  progress_bar = gr.Progress()
245
 
246
  prompt_template = """
247
+ Analyze the patient record excerpt for missed diagnoses only. Provide a concise, evidence-based summary as a single paragraph without headings or bullet points. Include specific clinical findings (e.g., 'elevated blood pressure (160/95) on page 10'), their potential implications (e.g., 'may indicate untreated hypertension'), and a recommendation for urgent review. Do not include other oversight categories like medication conflicts. If no missed diagnoses are found, state 'No missed diagnoses identified' in a single sentence.
248
  Patient Record Excerpt (Chunk {0} of {1}):
249
  {chunk}
250
  """
 
293
  for m in chunk_output:
294
  if hasattr(m, 'content') and m.content:
295
  cleaned = clean_response(m.content)
296
+ if cleaned:
297
+ chunk_response += cleaned + " "
298
  elif isinstance(chunk_output, str) and chunk_output.strip():
299
+ cleaned = clean_response(chunk_output)
300
+ if cleaned:
301
+ chunk_response += cleaned + " "
302
+ batch_responses.append(chunk_response.strip())
303
  torch.cuda.empty_cache()
304
  gc.collect()
305
 
 
307
  if chunk_response:
308
  combined_response += f"--- Analysis for Chunk {chunk_idx} ---\n{chunk_response}\n"
309
  else:
310
+ combined_response += f"--- Analysis for Chunk {chunk_idx} ---\nNo missed diagnoses identified.\n"
311
  history[-1] = {"role": "assistant", "content": combined_response.strip()}
312
  yield history, None, ""
313
 
314
+ if combined_response.strip() and not all("No missed diagnoses identified" in chunk for chunk in combined_response.split("--- Analysis for Chunk")):
315
  history[-1]["content"] = combined_response.strip()
316
  else:
317
+ history.append({"role": "assistant", "content": "No missed diagnoses identified in the provided records."})
318
 
319
  summary = summarize_findings(combined_response)
320
  report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt") if file_hash_value else None
 
326
  except Exception as e:
327
  logger.error("Analysis error: %s", e)
328
  history.append({"role": "assistant", "content": f"❌ Error occurred: {str(e)}"})
329
+ yield history, None, f"Error occurred during analysis: {str(e)}"
330
 
331
  send_btn.click(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output, final_summary])
332
  msg_input.submit(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output, final_summary])