Update app.py
Browse files
app.py
CHANGED
@@ -139,7 +139,7 @@ def log_system_usage(tag=""):
|
|
139 |
print(f"[{tag}] GPU/CPU monitor failed: {e}")
|
140 |
|
141 |
def clean_response(text: str) -> str:
|
142 |
-
"""Clean TxAgent response to
|
143 |
text = sanitize_utf8(text)
|
144 |
# Remove tool call artifacts, None, and reasoning
|
145 |
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)
|
@@ -147,25 +147,53 @@ def clean_response(text: str) -> str:
|
|
147 |
text = re.sub(r"\n{3,}", "\n\n", text)
|
148 |
text = re.sub(r"[^\n#\-\*\w\s\.\,\:\(\)]+", "", text) # Keep markdown-relevant characters
|
149 |
|
150 |
-
#
|
151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
current_section = None
|
|
|
153 |
lines = text.splitlines()
|
154 |
for line in lines:
|
155 |
line = line.strip()
|
156 |
if not line:
|
157 |
continue
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
|
164 |
-
# Combine
|
165 |
cleaned = []
|
166 |
-
for
|
167 |
-
if
|
168 |
-
cleaned.append("\n".join(
|
169 |
|
170 |
text = "\n\n".join(cleaned).strip()
|
171 |
if not text:
|
@@ -239,17 +267,18 @@ def create_ui(agent):
|
|
239 |
combined_response = ""
|
240 |
|
241 |
prompt_template = """
|
242 |
-
You are a medical analysis assistant. Analyze the following patient record excerpt for clinical oversights and provide a concise, evidence-based summary in markdown format under
|
243 |
- Clinical context (why the issue was missed or relevant details from the record).
|
244 |
- Potential risks if unaddressed (e.g., disease progression, adverse events).
|
245 |
- Actionable recommendations (e.g., tests, referrals, medication adjustments).
|
246 |
-
Output ONLY the markdown-formatted findings, with bullet points under each heading. Do NOT include reasoning, tool calls, or intermediate steps. If no issues are found
|
247 |
|
248 |
Example Output:
|
|
|
|
|
|
|
249 |
### Missed Diagnoses
|
250 |
- Elevated BP noted without diagnosis. Missed due to inconsistent visits. Risks: stroke. Recommend: BP monitoring, antihypertensives.
|
251 |
-
### Medication Conflicts
|
252 |
-
- No issues identified.
|
253 |
### Incomplete Assessments
|
254 |
- Chest pain not evaluated. Time constraints likely cause. Risks: cardiac issues. Recommend: ECG, stress test.
|
255 |
### Urgent Follow-up
|
@@ -257,18 +286,6 @@ Example Output:
|
|
257 |
|
258 |
Patient Record Excerpt (Chunk {0} of {1}):
|
259 |
{chunk}
|
260 |
-
|
261 |
-
### Missed Diagnoses
|
262 |
-
- ...
|
263 |
-
|
264 |
-
### Medication Conflicts
|
265 |
-
- ...
|
266 |
-
|
267 |
-
### Incomplete Assessments
|
268 |
-
- ...
|
269 |
-
|
270 |
-
### Urgent Follow-up
|
271 |
-
- ...
|
272 |
"""
|
273 |
|
274 |
try:
|
@@ -296,7 +313,7 @@ Patient Record Excerpt (Chunk {0} of {1}):
|
|
296 |
for m in chunk_output:
|
297 |
if hasattr(m, 'content') and m.content:
|
298 |
cleaned = clean_response(m.content)
|
299 |
-
if cleaned and re.search(r"###\s
|
300 |
chunk_response += cleaned + "\n\n"
|
301 |
# Update UI with partial response
|
302 |
if history[-1]["content"].startswith("Analyzing"):
|
@@ -306,7 +323,7 @@ Patient Record Excerpt (Chunk {0} of {1}):
|
|
306 |
yield history, None
|
307 |
elif isinstance(chunk_output, str) and chunk_output.strip():
|
308 |
cleaned = clean_response(chunk_output)
|
309 |
-
if cleaned and re.search(r"###\s
|
310 |
chunk_response += cleaned + "\n\n"
|
311 |
# Update UI with partial response
|
312 |
if history[-1]["content"].startswith("Analyzing"):
|
|
|
139 |
print(f"[{tag}] GPU/CPU monitor failed: {e}")
|
140 |
|
141 |
def clean_response(text: str) -> str:
|
142 |
+
"""Clean TxAgent response to group findings under tool-derived headings."""
|
143 |
text = sanitize_utf8(text)
|
144 |
# Remove tool call artifacts, None, and reasoning
|
145 |
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)
|
|
|
147 |
text = re.sub(r"\n{3,}", "\n\n", text)
|
148 |
text = re.sub(r"[^\n#\-\*\w\s\.\,\:\(\)]+", "", text) # Keep markdown-relevant characters
|
149 |
|
150 |
+
# Define tool-to-heading mapping
|
151 |
+
tool_to_heading = {
|
152 |
+
"get_abuse_info_by_drug_name": "Drugs",
|
153 |
+
"get_dependence_info_by_drug_name": "Drugs",
|
154 |
+
"get_abuse_types_and_related_adverse_reactions_and_controlled_substance_status_by_drug_name": "Drugs",
|
155 |
+
"get_info_for_patients_by_drug_name": "Drugs",
|
156 |
+
# Add other tools from new_tool.json if applicable
|
157 |
+
}
|
158 |
+
|
159 |
+
# Parse sections and findings
|
160 |
+
sections = {}
|
161 |
current_section = None
|
162 |
+
current_tool = None
|
163 |
lines = text.splitlines()
|
164 |
for line in lines:
|
165 |
line = line.strip()
|
166 |
if not line:
|
167 |
continue
|
168 |
+
# Detect tool tag
|
169 |
+
tool_match = re.match(r"\[TOOL:\s*(\w+)\]", line)
|
170 |
+
if tool_match:
|
171 |
+
current_tool = tool_match.group(1)
|
172 |
+
continue
|
173 |
+
# Detect section heading
|
174 |
+
section_match = re.match(r"###\s*(Missed Diagnoses|Medication Conflicts|Incomplete Assessments|Urgent Follow-up)", line)
|
175 |
+
if section_match:
|
176 |
+
current_section = section_match.group(1)
|
177 |
+
if current_section not in sections:
|
178 |
+
sections[current_section] = []
|
179 |
+
continue
|
180 |
+
# Detect finding
|
181 |
+
finding_match = re.match(r"-\s*.+", line)
|
182 |
+
if finding_match and current_section and not re.match(r"-\s*No issues identified", line):
|
183 |
+
# Assign to tool-derived heading if tool is specified
|
184 |
+
if current_tool and current_tool in tool_to_heading:
|
185 |
+
heading = tool_to_heading[current_tool]
|
186 |
+
if heading not in sections:
|
187 |
+
sections[heading] = []
|
188 |
+
sections[heading].append(line)
|
189 |
+
else:
|
190 |
+
sections[current_section].append(line)
|
191 |
|
192 |
+
# Combine non-empty sections
|
193 |
cleaned = []
|
194 |
+
for heading, findings in sections.items():
|
195 |
+
if findings: # Only include sections with findings
|
196 |
+
cleaned.append(f"### {heading}\n" + "\n".join(findings))
|
197 |
|
198 |
text = "\n\n".join(cleaned).strip()
|
199 |
if not text:
|
|
|
267 |
combined_response = ""
|
268 |
|
269 |
prompt_template = """
|
270 |
+
You are a medical analysis assistant. Analyze the following patient record excerpt for clinical oversights and provide a concise, evidence-based summary in markdown format. Group findings under appropriate headings based on the tool used (e.g., drug-related findings under 'Drugs'). For each finding, include:
|
271 |
- Clinical context (why the issue was missed or relevant details from the record).
|
272 |
- Potential risks if unaddressed (e.g., disease progression, adverse events).
|
273 |
- Actionable recommendations (e.g., tests, referrals, medication adjustments).
|
274 |
+
Output ONLY the markdown-formatted findings, with bullet points under each heading. Precede each finding with a tool tag (e.g., [TOOL: get_abuse_info_by_drug_name]) to indicate the tool used. Do NOT include reasoning, tool calls, or intermediate steps. If no issues are found for a tool or category, state "No issues identified" for that section. Ensure the output is specific to the provided text and avoids generic responses.
|
275 |
|
276 |
Example Output:
|
277 |
+
### Drugs
|
278 |
+
[TOOL: get_abuse_info_by_drug_name]
|
279 |
+
- Opioid use disorder not addressed. Missed due to lack of screening. Risks: overdose. Recommend: addiction specialist referral.
|
280 |
### Missed Diagnoses
|
281 |
- Elevated BP noted without diagnosis. Missed due to inconsistent visits. Risks: stroke. Recommend: BP monitoring, antihypertensives.
|
|
|
|
|
282 |
### Incomplete Assessments
|
283 |
- Chest pain not evaluated. Time constraints likely cause. Risks: cardiac issues. Recommend: ECG, stress test.
|
284 |
### Urgent Follow-up
|
|
|
286 |
|
287 |
Patient Record Excerpt (Chunk {0} of {1}):
|
288 |
{chunk}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
289 |
"""
|
290 |
|
291 |
try:
|
|
|
313 |
for m in chunk_output:
|
314 |
if hasattr(m, 'content') and m.content:
|
315 |
cleaned = clean_response(m.content)
|
316 |
+
if cleaned and re.search(r"###\s*\w+", cleaned):
|
317 |
chunk_response += cleaned + "\n\n"
|
318 |
# Update UI with partial response
|
319 |
if history[-1]["content"].startswith("Analyzing"):
|
|
|
323 |
yield history, None
|
324 |
elif isinstance(chunk_output, str) and chunk_output.strip():
|
325 |
cleaned = clean_response(chunk_output)
|
326 |
+
if cleaned and re.search(r"###\s*\w+", cleaned):
|
327 |
chunk_response += cleaned + "\n\n"
|
328 |
# Update UI with partial response
|
329 |
if history[-1]["content"].startswith("Analyzing"):
|