Update app.py
Browse files
app.py
CHANGED
@@ -56,7 +56,7 @@ def extract_priority_pages(file_path: str, max_pages: int = 20) -> str:
|
|
56 |
text_chunks.append(f"=== Page {i+1} ===\n{text.strip()}")
|
57 |
for i, page in enumerate(pdf.pages[3:max_pages], start=4):
|
58 |
page_text = page.extract_text() or ""
|
59 |
-
if any(re.search(rf'
|
60 |
text_chunks.append(f"=== Page {i} ===\n{page_text.strip()}")
|
61 |
return "\n\n".join(text_chunks)
|
62 |
except Exception as e:
|
@@ -108,17 +108,6 @@ def log_system_usage(tag=""):
|
|
108 |
except Exception as e:
|
109 |
print(f"[{tag}] GPU/CPU monitor failed: {e}")
|
110 |
|
111 |
-
def extract_final_response(response: str) -> str:
|
112 |
-
try:
|
113 |
-
parts = response.split("[TOOL_CALLS]")
|
114 |
-
for i in reversed(range(len(parts))):
|
115 |
-
if i + 1 < len(parts) and '"name": "Finish"' in parts[i + 1]:
|
116 |
-
return parts[i].strip()
|
117 |
-
return response.strip()
|
118 |
-
except Exception as e:
|
119 |
-
print("❌ Failed to extract clean response:", str(e))
|
120 |
-
return response.strip()
|
121 |
-
|
122 |
def init_agent():
|
123 |
print("🔁 Initializing model...")
|
124 |
log_system_usage("Before Load")
|
@@ -142,6 +131,22 @@ def init_agent():
|
|
142 |
print("✅ Agent Ready")
|
143 |
return agent
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
def create_ui(agent):
|
146 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
147 |
gr.Markdown("<h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>")
|
@@ -178,7 +183,9 @@ Medical Records:
|
|
178 |
"""
|
179 |
|
180 |
try:
|
181 |
-
|
|
|
|
|
182 |
for chunk in agent.run_gradio_chat(
|
183 |
message=prompt,
|
184 |
history=[],
|
@@ -190,20 +197,35 @@ Medical Records:
|
|
190 |
):
|
191 |
if chunk is None:
|
192 |
continue
|
|
|
193 |
if isinstance(chunk, str):
|
194 |
-
|
195 |
elif isinstance(chunk, list):
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
yield history, report_path if report_path and os.path.exists(report_path) else None
|
208 |
|
209 |
except Exception as e:
|
|
|
56 |
text_chunks.append(f"=== Page {i+1} ===\n{text.strip()}")
|
57 |
for i, page in enumerate(pdf.pages[3:max_pages], start=4):
|
58 |
page_text = page.extract_text() or ""
|
59 |
+
if any(re.search(rf'\b{kw}\b', page_text.lower()) for kw in MEDICAL_KEYWORDS):
|
60 |
text_chunks.append(f"=== Page {i} ===\n{page_text.strip()}")
|
61 |
return "\n\n".join(text_chunks)
|
62 |
except Exception as e:
|
|
|
108 |
except Exception as e:
|
109 |
print(f"[{tag}] GPU/CPU monitor failed: {e}")
|
110 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
def init_agent():
|
112 |
print("🔁 Initializing model...")
|
113 |
log_system_usage("Before Load")
|
|
|
131 |
print("✅ Agent Ready")
|
132 |
return agent
|
133 |
|
134 |
+
def clean_response(response: str) -> str:
|
135 |
+
"""Clean the response by removing tool calls and duplicate content."""
|
136 |
+
# Remove all tool call blocks
|
137 |
+
response = re.sub(r'\[TOOL_CALLS\].*?$', '', response, flags=re.DOTALL)
|
138 |
+
|
139 |
+
# Remove duplicate content by keeping only the last occurrence
|
140 |
+
if "Based on the medical records provided" in response:
|
141 |
+
last_occurrence = response.rfind("Based on the medical records provided")
|
142 |
+
response = response[last_occurrence:]
|
143 |
+
|
144 |
+
# Remove any remaining JSON artifacts
|
145 |
+
response = re.sub(r'\{.*?\}', '', response)
|
146 |
+
response = re.sub(r'\[.*?\]', '', response)
|
147 |
+
|
148 |
+
return response.strip()
|
149 |
+
|
150 |
def create_ui(agent):
|
151 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
152 |
gr.Markdown("<h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>")
|
|
|
183 |
"""
|
184 |
|
185 |
try:
|
186 |
+
full_response = ""
|
187 |
+
finish_detected = False
|
188 |
+
|
189 |
for chunk in agent.run_gradio_chat(
|
190 |
message=prompt,
|
191 |
history=[],
|
|
|
197 |
):
|
198 |
if chunk is None:
|
199 |
continue
|
200 |
+
|
201 |
if isinstance(chunk, str):
|
202 |
+
full_response += chunk
|
203 |
elif isinstance(chunk, list):
|
204 |
+
chunk_content = "".join([c.content for c in chunk if hasattr(c, "content") and c.content])
|
205 |
+
full_response += chunk_content
|
206 |
+
if '"name": "Finish"' in chunk_content:
|
207 |
+
finish_detected = True
|
208 |
+
|
209 |
+
# Display intermediate response
|
210 |
+
clean_intermediate = clean_response(full_response)
|
211 |
+
if clean_intermediate:
|
212 |
+
history[-1] = {"role": "assistant", "content": clean_intermediate}
|
213 |
+
yield history, None
|
214 |
+
|
215 |
+
# Final processing after all chunks are received
|
216 |
+
final_cleaned = clean_response(full_response)
|
217 |
+
|
218 |
+
if not final_cleaned:
|
219 |
+
final_cleaned = "⚠️ No clear oversights identified or model output was invalid."
|
220 |
+
|
221 |
+
# Only save report if we got a proper finish signal
|
222 |
+
report_path = None
|
223 |
+
if finish_detected and file_hash_value:
|
224 |
+
report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt")
|
225 |
+
with open(report_path, "w", encoding="utf-8") as f:
|
226 |
+
f.write(final_cleaned)
|
227 |
+
|
228 |
+
history[-1] = {"role": "assistant", "content": final_cleaned}
|
229 |
yield history, report_path if report_path and os.path.exists(report_path) else None
|
230 |
|
231 |
except Exception as e:
|