Ali2206 commited on
Commit
665f0eb
·
verified ·
1 Parent(s): 9ec5ec4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -71
app.py CHANGED
@@ -8,13 +8,12 @@ from typing import List
8
  from concurrent.futures import ThreadPoolExecutor, as_completed
9
  import hashlib
10
  import shutil
11
- import time
12
  import re
13
  import psutil
14
  import subprocess
15
 
16
  # ---------------------------------------------------------------------------------------
17
- # Persistent directory for Hugging Face Spaces
18
  # ---------------------------------------------------------------------------------------
19
  persistent_dir = "/data/hf_cache"
20
  os.makedirs(persistent_dir, exist_ok=True)
@@ -34,9 +33,6 @@ os.environ["VLLM_CACHE_DIR"] = vllm_cache_dir
34
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
35
  os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
36
 
37
- # ---------------------------------------------------------------------------------------
38
- # Add src to path
39
- # ---------------------------------------------------------------------------------------
40
  current_dir = os.path.dirname(os.path.abspath(__file__))
41
  src_path = os.path.abspath(os.path.join(current_dir, "src"))
42
  sys.path.insert(0, src_path)
@@ -44,7 +40,7 @@ sys.path.insert(0, src_path)
44
  from txagent.txagent import TxAgent
45
 
46
  # ---------------------------------------------------------------------------------------
47
- # Helper functions
48
  # ---------------------------------------------------------------------------------------
49
  MEDICAL_KEYWORDS = {
50
  'diagnosis', 'assessment', 'plan', 'results', 'medications',
@@ -106,25 +102,22 @@ def convert_file_to_json(file_path: str, file_type: str) -> str:
106
 
107
  def log_system_usage(tag=""):
108
  try:
109
- cpu_percent = psutil.cpu_percent(interval=1)
110
  mem = psutil.virtual_memory()
111
- print(f"[{tag}] 🧠 CPU: {cpu_percent}% | RAM: {mem.used // (1024**2)}MB / {mem.total // (1024**2)}MB")
112
  result = subprocess.run(
113
  ["nvidia-smi", "--query-gpu=memory.used,memory.total,utilization.gpu", "--format=csv,nounits,noheader"],
114
- capture_output=True,
115
- text=True,
116
  )
117
  if result.returncode == 0:
118
- mem_used, mem_total, util = result.stdout.strip().split(", ")
119
- print(f"[{tag}] GPU: {mem_used}MB / {mem_total}MB | Utilization: {util}%")
120
- else:
121
- print(f"[{tag}] ⚡ GPU info not available.")
122
  except Exception as e:
123
- print(f"[{tag}] ⚠️ Failed to log system usage: {e}")
124
 
125
  def init_agent():
126
- print("🔁 Initializing TxAgent...")
127
- log_system_usage("Before Model Load")
128
 
129
  default_tool_path = os.path.abspath("data/new_tool.json")
130
  target_tool_path = os.path.join(tool_cache_dir, "new_tool.json")
@@ -142,13 +135,8 @@ def init_agent():
142
  additional_default_tools=[],
143
  )
144
  agent.init_model()
145
- log_system_usage("After Model Load")
146
-
147
- print("✅ TxAgent is ready.")
148
- print("📦 Cached model files:")
149
- for root, _, files in os.walk(model_cache_dir):
150
- for file in files:
151
- print(os.path.join(root, file))
152
 
153
  return agent
154
 
@@ -157,53 +145,42 @@ def init_agent():
157
  # ---------------------------------------------------------------------------------------
158
  def create_ui(agent):
159
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
160
- gr.Markdown("""
161
- <h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>
162
- <h3 style='text-align: center;'>Identify potential oversights in patient care</h3>
163
- """)
164
  chatbot = gr.Chatbot(label="Analysis", height=600, type="messages")
165
- file_upload = gr.File(label="Upload Medical Records",
166
- file_types=[".pdf", ".csv", ".xls", ".xlsx"],
167
- file_count="multiple")
168
  msg_input = gr.Textbox(placeholder="Ask about potential oversights...", show_label=False)
169
  send_btn = gr.Button("Analyze", variant="primary")
170
  download_output = gr.File(label="Download Full Report")
171
 
172
- def analyze_potential_oversights(message: str, history: list, files: list):
173
  history = history + [{"role": "user", "content": message},
174
  {"role": "assistant", "content": "⏳ Analyzing records for potential oversights..."}]
175
  yield history, None
176
 
177
- extracted_data = ""
178
  file_hash_value = ""
179
- if files and isinstance(files, list):
180
  with ThreadPoolExecutor(max_workers=4) as executor:
181
- futures = [
182
- executor.submit(convert_file_to_json, f.name, f.name.split(".")[-1].lower())
183
- for f in files if hasattr(f, 'name')
184
- ]
185
  results = [sanitize_utf8(f.result()) for f in as_completed(futures)]
186
- extracted_data = "\n".join(results)
187
- file_hash_value = file_hash(files[0].name) if hasattr(files[0], 'name') else ""
188
 
189
- max_extracted_chars = 12000
190
- truncated_data = extracted_data[:max_extracted_chars]
191
-
192
- analysis_prompt = f"""Review these medical records and identify EXACTLY what might have been missed:
193
  1. List potential missed diagnoses
194
  2. Flag any medication conflicts
195
  3. Note incomplete assessments
196
  4. Highlight abnormal results needing follow-up
197
 
198
  Medical Records:
199
- {truncated_data}
200
 
201
  ### Potential Oversights:
202
  """
203
  response = ""
204
  try:
205
  for chunk in agent.run_gradio_chat(
206
- message=analysis_prompt,
207
  history=[],
208
  temperature=0.2,
209
  max_new_tokens=1024,
@@ -216,46 +193,32 @@ Medical Records:
216
  response += chunk
217
  elif isinstance(chunk, list):
218
  response += "".join([c.content for c in chunk if hasattr(c, 'content')])
219
- cleaned = response.replace("[TOOL_CALLS]", "").strip()
220
- history[-1] = {"role": "assistant", "content": cleaned}
 
221
  yield history, None
222
- except Exception as agent_error:
223
- history[-1] = {"role": "assistant", "content": f"❌ Analysis failed: {str(agent_error)}"}
224
  yield history, None
225
  return
226
 
227
- final_output = response.replace("[TOOL_CALLS]", "").strip()
228
  if not final_output:
229
  final_output = "No clear oversights identified. Recommend comprehensive review."
230
-
231
  history[-1] = {"role": "assistant", "content": final_output}
232
 
233
- report_path = None
234
- if file_hash_value:
235
- possible_report = os.path.join(report_dir, f"{file_hash_value}_report.txt")
236
- if os.path.exists(possible_report):
237
- report_path = possible_report
238
-
239
- yield history, report_path
240
 
241
- send_btn.click(analyze_potential_oversights,
242
- inputs=[msg_input, gr.State([]), file_upload],
243
- outputs=[chatbot, download_output])
244
- msg_input.submit(analyze_potential_oversights,
245
- inputs=[msg_input, gr.State([]), file_upload],
246
- outputs=[chatbot, download_output])
247
- gr.Examples([
248
- ["What might have been missed in this patient's treatment?"],
249
- ["Are there any medication conflicts in these records?"],
250
- ["What abnormal results require follow-up?"]],
251
- inputs=msg_input)
252
  return demo
253
 
254
  # ---------------------------------------------------------------------------------------
255
  # Launch
256
  # ---------------------------------------------------------------------------------------
257
  if __name__ == "__main__":
258
- print("🚀 Starting TxAgent App...")
259
  agent = init_agent()
260
  demo = create_ui(agent)
261
  demo.queue(api_open=False).launch(
 
8
  from concurrent.futures import ThreadPoolExecutor, as_completed
9
  import hashlib
10
  import shutil
 
11
  import re
12
  import psutil
13
  import subprocess
14
 
15
  # ---------------------------------------------------------------------------------------
16
+ # Persistent directory setup
17
  # ---------------------------------------------------------------------------------------
18
  persistent_dir = "/data/hf_cache"
19
  os.makedirs(persistent_dir, exist_ok=True)
 
33
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
34
  os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
35
 
 
 
 
36
  current_dir = os.path.dirname(os.path.abspath(__file__))
37
  src_path = os.path.abspath(os.path.join(current_dir, "src"))
38
  sys.path.insert(0, src_path)
 
40
  from txagent.txagent import TxAgent
41
 
42
  # ---------------------------------------------------------------------------------------
43
+ # Utilities
44
  # ---------------------------------------------------------------------------------------
45
  MEDICAL_KEYWORDS = {
46
  'diagnosis', 'assessment', 'plan', 'results', 'medications',
 
102
 
103
  def log_system_usage(tag=""):
104
  try:
105
+ cpu = psutil.cpu_percent(interval=1)
106
  mem = psutil.virtual_memory()
107
+ print(f"[{tag}] CPU: {cpu}% | RAM: {mem.used // (1024**2)}MB / {mem.total // (1024**2)}MB")
108
  result = subprocess.run(
109
  ["nvidia-smi", "--query-gpu=memory.used,memory.total,utilization.gpu", "--format=csv,nounits,noheader"],
110
+ capture_output=True, text=True
 
111
  )
112
  if result.returncode == 0:
113
+ used, total, util = result.stdout.strip().split(", ")
114
+ print(f"[{tag}] GPU: {used}MB / {total}MB | Utilization: {util}%")
 
 
115
  except Exception as e:
116
+ print(f"[{tag}] ⚠️ GPU/CPU monitor failed: {e}")
117
 
118
  def init_agent():
119
+ print("🔁 Initializing model...")
120
+ log_system_usage("Before Load")
121
 
122
  default_tool_path = os.path.abspath("data/new_tool.json")
123
  target_tool_path = os.path.join(tool_cache_dir, "new_tool.json")
 
135
  additional_default_tools=[],
136
  )
137
  agent.init_model()
138
+ log_system_usage("After Load")
139
+ print("✅ Agent Ready")
 
 
 
 
 
140
 
141
  return agent
142
 
 
145
  # ---------------------------------------------------------------------------------------
146
  def create_ui(agent):
147
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
148
+ gr.Markdown("<h1 style='text-align: center;'>🩺 Clinical Oversight Assistant</h1>")
 
 
 
149
  chatbot = gr.Chatbot(label="Analysis", height=600, type="messages")
150
+ file_upload = gr.File(file_types=[".pdf", ".csv", ".xls", ".xlsx"], file_count="multiple")
 
 
151
  msg_input = gr.Textbox(placeholder="Ask about potential oversights...", show_label=False)
152
  send_btn = gr.Button("Analyze", variant="primary")
153
  download_output = gr.File(label="Download Full Report")
154
 
155
+ def analyze(message: str, history: list, files: list):
156
  history = history + [{"role": "user", "content": message},
157
  {"role": "assistant", "content": "⏳ Analyzing records for potential oversights..."}]
158
  yield history, None
159
 
160
+ extracted = ""
161
  file_hash_value = ""
162
+ if files:
163
  with ThreadPoolExecutor(max_workers=4) as executor:
164
+ futures = [executor.submit(convert_file_to_json, f.name, f.name.split(".")[-1].lower()) for f in files]
 
 
 
165
  results = [sanitize_utf8(f.result()) for f in as_completed(futures)]
166
+ extracted = "\n".join(results)
167
+ file_hash_value = file_hash(files[0].name)
168
 
169
+ prompt = f"""Review these medical records and identify EXACTLY what might have been missed:
 
 
 
170
  1. List potential missed diagnoses
171
  2. Flag any medication conflicts
172
  3. Note incomplete assessments
173
  4. Highlight abnormal results needing follow-up
174
 
175
  Medical Records:
176
+ {extracted[:12000]}
177
 
178
  ### Potential Oversights:
179
  """
180
  response = ""
181
  try:
182
  for chunk in agent.run_gradio_chat(
183
+ message=prompt,
184
  history=[],
185
  temperature=0.2,
186
  max_new_tokens=1024,
 
193
  response += chunk
194
  elif isinstance(chunk, list):
195
  response += "".join([c.content for c in chunk if hasattr(c, 'content')])
196
+ cleaned = response.strip()
197
+ cleaned = re.sub(r"\[TOOL_CALLS\].*?$", "", cleaned, flags=re.DOTALL).strip()
198
+ history[-1] = {"role": "assistant", "content": cleaned or "⏳ Processing..."}
199
  yield history, None
200
+ except Exception as e:
201
+ history[-1] = {"role": "assistant", "content": f"❌ Error: {str(e)}"}
202
  yield history, None
203
  return
204
 
205
+ final_output = re.sub(r"\[TOOL_CALLS\].*?$", "", response, flags=re.DOTALL).strip()
206
  if not final_output:
207
  final_output = "No clear oversights identified. Recommend comprehensive review."
 
208
  history[-1] = {"role": "assistant", "content": final_output}
209
 
210
+ report_path = os.path.join(report_dir, f"{file_hash_value}_report.txt") if file_hash_value else None
211
+ yield history, report_path if report_path and os.path.exists(report_path) else None
 
 
 
 
 
212
 
213
+ send_btn.click(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output])
214
+ msg_input.submit(analyze, inputs=[msg_input, gr.State([]), file_upload], outputs=[chatbot, download_output])
 
 
 
 
 
 
 
 
 
215
  return demo
216
 
217
  # ---------------------------------------------------------------------------------------
218
  # Launch
219
  # ---------------------------------------------------------------------------------------
220
  if __name__ == "__main__":
221
+ print("🚀 Launching app...")
222
  agent = init_agent()
223
  demo = create_ui(agent)
224
  demo.queue(api_open=False).launch(