LiamKhoaLe commited on
Commit
e4c0a6a
·
1 Parent(s): ab69c75

Enable MAC thought demo mode

Browse files
Files changed (1) hide show
  1. app.py +90 -8
app.py CHANGED
@@ -37,6 +37,42 @@ os.environ["TOKENIZERS_PARALLELISM"] = "false"
37
  # Set logging to INFO level for cleaner output
38
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
39
  logger = logging.getLogger(__name__)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  # Set MCP client logging to WARNING to reduce noise
41
  mcp_client_logger = logging.getLogger("mcp.client")
42
  mcp_client_logger.setLevel(logging.WARNING)
@@ -2159,12 +2195,21 @@ def stream_chat(
2159
  medical_model: str,
2160
  use_web_search: bool,
2161
  disable_agentic_reasoning: bool,
 
2162
  request: gr.Request
2163
  ):
2164
  if not request:
2165
- yield history + [{"role": "assistant", "content": "Session initialization failed. Please refresh the page."}]
2166
  return
2167
 
 
 
 
 
 
 
 
 
2168
  session_start = time.time()
2169
  soft_timeout = 100
2170
  hard_timeout = 118 # stop slightly before HF max duration (120s)
@@ -2287,7 +2332,8 @@ def stream_chat(
2287
  {"role": "user", "content": original_message},
2288
  {"role": "assistant", "content": ""}
2289
  ]
2290
- yield updated_history
 
2291
 
2292
  for idx, sub_topic in enumerate(breakdown.get("sub_topics", []), 1):
2293
  if elapsed() >= hard_timeout - 5:
@@ -2329,7 +2375,8 @@ def stream_chat(
2329
  # Stream partial answer as we complete each task
2330
  partial_final = "\n\n".join(medswin_answers)
2331
  updated_history[-1]["content"] = partial_final
2332
- yield updated_history
 
2333
 
2334
  except Exception as e:
2335
  logger.error(f"[MEDSWIN] Task {idx} failed: {e}")
@@ -2449,7 +2496,12 @@ def stream_chat(
2449
 
2450
  # Update history with final answer (ONLY final answer, no internal thoughts)
2451
  updated_history[-1]["content"] = final_answer_with_metadata
2452
- yield updated_history
 
 
 
 
 
2453
 
2454
  # Log completion
2455
  logger.info(f"[MAC] Final answer generated: {len(final_answer)} chars, {len(breakdown.get('sub_topics', []))} tasks completed")
@@ -2601,6 +2653,20 @@ def create_demo():
2601
  label="Disable agentic reasoning",
2602
  info="Use MedSwin model alone without agentic reasoning, RAG, or web search"
2603
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2604
  with gr.Row():
2605
  use_rag = gr.Checkbox(
2606
  value=False,
@@ -2680,6 +2746,20 @@ def create_demo():
2680
  label="Merge Threshold (lower = more merging)"
2681
  )
2682
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2683
  submit_button.click(
2684
  fn=stream_chat,
2685
  inputs=[
@@ -2696,9 +2776,10 @@ def create_demo():
2696
  use_rag,
2697
  medical_model,
2698
  use_web_search,
2699
- disable_agentic_reasoning
 
2700
  ],
2701
- outputs=chatbot
2702
  )
2703
 
2704
  message_input.submit(
@@ -2717,9 +2798,10 @@ def create_demo():
2717
  use_rag,
2718
  medical_model,
2719
  use_web_search,
2720
- disable_agentic_reasoning
 
2721
  ],
2722
- outputs=chatbot
2723
  )
2724
 
2725
  return demo
 
37
  # Set logging to INFO level for cleaner output
38
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
39
  logger = logging.getLogger(__name__)
40
+
41
+ # Custom logger handler to capture agentic thoughts
42
+ class ThoughtCaptureHandler(logging.Handler):
43
+ """Custom handler to capture internal thoughts from MedSwin and supervisor"""
44
+ def __init__(self):
45
+ super().__init__()
46
+ self.thoughts = []
47
+ self.lock = threading.Lock()
48
+
49
+ def emit(self, record):
50
+ """Capture log messages that contain agentic thoughts"""
51
+ try:
52
+ msg = self.format(record)
53
+ # Only capture messages from GEMINI SUPERVISOR or MEDSWIN
54
+ if "[GEMINI SUPERVISOR]" in msg or "[MEDSWIN]" in msg or "[MAC]" in msg:
55
+ # Remove timestamp and logger name for cleaner display
56
+ # Format: "timestamp - logger - level - message"
57
+ parts = msg.split(" - ", 3)
58
+ if len(parts) >= 4:
59
+ clean_msg = parts[-1] # Get the message part
60
+ else:
61
+ clean_msg = msg
62
+ with self.lock:
63
+ self.thoughts.append(clean_msg)
64
+ except Exception:
65
+ pass # Ignore formatting errors
66
+
67
+ def get_thoughts(self):
68
+ """Get all captured thoughts as a formatted string"""
69
+ with self.lock:
70
+ return "\n".join(self.thoughts)
71
+
72
+ def clear(self):
73
+ """Clear captured thoughts"""
74
+ with self.lock:
75
+ self.thoughts = []
76
  # Set MCP client logging to WARNING to reduce noise
77
  mcp_client_logger = logging.getLogger("mcp.client")
78
  mcp_client_logger.setLevel(logging.WARNING)
 
2195
  medical_model: str,
2196
  use_web_search: bool,
2197
  disable_agentic_reasoning: bool,
2198
+ show_thoughts: bool,
2199
  request: gr.Request
2200
  ):
2201
  if not request:
2202
+ yield history + [{"role": "assistant", "content": "Session initialization failed. Please refresh the page."}], ""
2203
  return
2204
 
2205
+ # Set up thought capture handler if show_thoughts is enabled
2206
+ thought_handler = None
2207
+ if show_thoughts:
2208
+ thought_handler = ThoughtCaptureHandler()
2209
+ thought_handler.setLevel(logging.INFO)
2210
+ thought_handler.clear() # Start fresh
2211
+ logger.addHandler(thought_handler)
2212
+
2213
  session_start = time.time()
2214
  soft_timeout = 100
2215
  hard_timeout = 118 # stop slightly before HF max duration (120s)
 
2332
  {"role": "user", "content": original_message},
2333
  {"role": "assistant", "content": ""}
2334
  ]
2335
+ thoughts_text = thought_handler.get_thoughts() if thought_handler else ""
2336
+ yield updated_history, thoughts_text
2337
 
2338
  for idx, sub_topic in enumerate(breakdown.get("sub_topics", []), 1):
2339
  if elapsed() >= hard_timeout - 5:
 
2375
  # Stream partial answer as we complete each task
2376
  partial_final = "\n\n".join(medswin_answers)
2377
  updated_history[-1]["content"] = partial_final
2378
+ thoughts_text = thought_handler.get_thoughts() if thought_handler else ""
2379
+ yield updated_history, thoughts_text
2380
 
2381
  except Exception as e:
2382
  logger.error(f"[MEDSWIN] Task {idx} failed: {e}")
 
2496
 
2497
  # Update history with final answer (ONLY final answer, no internal thoughts)
2498
  updated_history[-1]["content"] = final_answer_with_metadata
2499
+ thoughts_text = thought_handler.get_thoughts() if thought_handler else ""
2500
+ yield updated_history, thoughts_text
2501
+
2502
+ # Clean up thought handler
2503
+ if thought_handler:
2504
+ logger.removeHandler(thought_handler)
2505
 
2506
  # Log completion
2507
  logger.info(f"[MAC] Final answer generated: {len(final_answer)} chars, {len(breakdown.get('sub_topics', []))} tasks completed")
 
2653
  label="Disable agentic reasoning",
2654
  info="Use MedSwin model alone without agentic reasoning, RAG, or web search"
2655
  )
2656
+ show_agentic_thought = gr.Button(
2657
+ "Show agentic thought",
2658
+ size="sm"
2659
+ )
2660
+ # Scrollable textbox for agentic thoughts (initially hidden)
2661
+ agentic_thoughts_box = gr.Textbox(
2662
+ label="Agentic Thoughts",
2663
+ placeholder="Internal thoughts from MedSwin and supervisor will appear here...",
2664
+ lines=8,
2665
+ max_lines=15,
2666
+ interactive=False,
2667
+ visible=False,
2668
+ elem_classes="agentic-thoughts"
2669
+ )
2670
  with gr.Row():
2671
  use_rag = gr.Checkbox(
2672
  value=False,
 
2746
  label="Merge Threshold (lower = more merging)"
2747
  )
2748
 
2749
+ # Toggle function for showing/hiding agentic thoughts
2750
+ show_thoughts_state = gr.State(value=False)
2751
+
2752
+ def toggle_thoughts_box(current_state):
2753
+ """Toggle visibility of agentic thoughts box"""
2754
+ new_state = not current_state
2755
+ return gr.update(visible=new_state), new_state
2756
+
2757
+ show_agentic_thought.click(
2758
+ fn=toggle_thoughts_box,
2759
+ inputs=[show_thoughts_state],
2760
+ outputs=[agentic_thoughts_box, show_thoughts_state]
2761
+ )
2762
+
2763
  submit_button.click(
2764
  fn=stream_chat,
2765
  inputs=[
 
2776
  use_rag,
2777
  medical_model,
2778
  use_web_search,
2779
+ disable_agentic_reasoning,
2780
+ show_thoughts_state
2781
  ],
2782
+ outputs=[chatbot, agentic_thoughts_box]
2783
  )
2784
 
2785
  message_input.submit(
 
2798
  use_rag,
2799
  medical_model,
2800
  use_web_search,
2801
+ disable_agentic_reasoning,
2802
+ show_thoughts_state
2803
  ],
2804
+ outputs=[chatbot, agentic_thoughts_box]
2805
  )
2806
 
2807
  return demo