LiamKhoaLe commited on
Commit
e45d3a4
·
1 Parent(s): 5040e2f

Preload Deepseek, add MCP fallbacks, upd audio record widget

Browse files
Files changed (1) hide show
  1. app.py +66 -20
app.py CHANGED
@@ -48,9 +48,9 @@ try:
48
  except ImportError:
49
  MCP_AVAILABLE = False
50
  # Fallback imports if MCP is not available
51
- from ddgs import DDGS
52
- import requests
53
- from bs4 import BeautifulSoup
54
  try:
55
  from TTS.api import TTS
56
  TTS_AVAILABLE = True
@@ -148,6 +148,12 @@ CSS = """
148
  display: flex;
149
  align-items: center;
150
  }
 
 
 
 
 
 
151
  .feature-badge {
152
  display: inline-block;
153
  padding: 3px 8px;
@@ -192,6 +198,7 @@ global_tts_model = None
192
 
193
  # MCP client storage
194
  global_mcp_client = None
 
195
  # MCP server configuration via environment variables
196
  # Example: MCP_SERVER_COMMAND="python" MCP_SERVER_ARGS="-m duckduckgo_mcp_server"
197
  # Or: MCP_SERVER_COMMAND="npx" MCP_SERVER_ARGS="-y @modelcontextprotocol/server-duckduckgo"
@@ -630,7 +637,7 @@ def translate_text(text: str, target_lang: str = "en", source_lang: str = None)
630
 
631
  async def search_web_mcp(query: str, max_results: int = 5) -> list:
632
  """Search web using MCP tools"""
633
- global global_mcp_client
634
 
635
  if not MCP_AVAILABLE:
636
  logger.warning("MCP not available, falling back to direct search")
@@ -653,6 +660,8 @@ async def search_web_mcp(query: str, max_results: int = 5) -> list:
653
  except Exception as e:
654
  logger.error(f"Failed to initialize MCP client: {e}")
655
  logger.info("Falling back to direct search. To use MCP, ensure MCP server is installed and configured.")
 
 
656
  return search_web_fallback(query, max_results)
657
 
658
  # Call MCP search tool
@@ -759,11 +768,14 @@ async def search_web_mcp(query: str, max_results: int = 5) -> list:
759
 
760
  def search_web_fallback(query: str, max_results: int = 5) -> list:
761
  """Fallback web search using DuckDuckGo directly (when MCP is not available)"""
762
- if not MCP_AVAILABLE:
763
- # Use direct library calls as fallback
764
  from ddgs import DDGS
765
  import requests
766
  from bs4 import BeautifulSoup
 
 
 
767
 
768
  try:
769
  with DDGS() as ddgs:
@@ -1585,34 +1597,61 @@ def create_demo():
1585
  type="messages"
1586
  )
1587
  with gr.Row(elem_classes="input-row"):
1588
- with gr.Column(scale=1, min_width=50):
 
 
 
 
 
 
1589
  mic_button = gr.Audio(
1590
  sources=["microphone"],
1591
  type="filepath",
1592
  label="",
1593
  show_label=False,
1594
- container=False
1595
- )
1596
- message_input = gr.Textbox(
1597
- placeholder="Type your medical question here...",
1598
- show_label=False,
1599
  container=False,
1600
- lines=1,
1601
- scale=7
1602
  )
1603
  submit_button = gr.Button("➤", elem_classes="submit-btn", scale=1)
1604
 
 
 
 
 
 
 
 
 
 
 
 
1605
  # Handle microphone transcription
1606
- def handle_transcription(audio):
 
 
 
 
 
 
 
 
 
 
1607
  if audio is None:
1608
- return ""
1609
  transcribed = transcribe_audio(audio)
1610
- return transcribed
 
 
 
 
 
 
1611
 
1612
  mic_button.stop_recording(
1613
- fn=handle_transcription,
1614
  inputs=[mic_button],
1615
- outputs=[message_input]
1616
  )
1617
 
1618
  # TTS component for generating speech from messages
@@ -1779,11 +1818,18 @@ def create_demo():
1779
  if __name__ == "__main__":
1780
  # Preload models on startup
1781
  logger.info("Preloading models on startup...")
 
 
 
 
 
 
 
1782
  logger.info("Initializing default medical model (MedSwin SFT)...")
1783
  initialize_medical_model(DEFAULT_MEDICAL_MODEL)
1784
  logger.info("Preloading Whisper model...")
1785
  try:
1786
- initialize_whisper_model()
1787
  if global_whisper_model is not None:
1788
  logger.info("Whisper model preloaded successfully!")
1789
  else:
 
48
  except ImportError:
49
  MCP_AVAILABLE = False
50
  # Fallback imports if MCP is not available
51
+ from ddgs import DDGS
52
+ import requests
53
+ from bs4 import BeautifulSoup
54
  try:
55
  from TTS.api import TTS
56
  TTS_AVAILABLE = True
 
148
  display: flex;
149
  align-items: center;
150
  }
151
+ .recording-timer {
152
+ font-size: 12px;
153
+ color: #666;
154
+ text-align: center;
155
+ margin-top: 5px;
156
+ }
157
  .feature-badge {
158
  display: inline-block;
159
  padding: 3px 8px;
 
198
 
199
  # MCP client storage
200
  global_mcp_client = None
201
+ global_mcp_context = None # Store the context manager
202
  # MCP server configuration via environment variables
203
  # Example: MCP_SERVER_COMMAND="python" MCP_SERVER_ARGS="-m duckduckgo_mcp_server"
204
  # Or: MCP_SERVER_COMMAND="npx" MCP_SERVER_ARGS="-y @modelcontextprotocol/server-duckduckgo"
 
637
 
638
  async def search_web_mcp(query: str, max_results: int = 5) -> list:
639
  """Search web using MCP tools"""
640
+ global global_mcp_client, global_mcp_context
641
 
642
  if not MCP_AVAILABLE:
643
  logger.warning("MCP not available, falling back to direct search")
 
660
  except Exception as e:
661
  logger.error(f"Failed to initialize MCP client: {e}")
662
  logger.info("Falling back to direct search. To use MCP, ensure MCP server is installed and configured.")
663
+ global_mcp_client = None
664
+ global_mcp_context = None
665
  return search_web_fallback(query, max_results)
666
 
667
  # Call MCP search tool
 
768
 
769
  def search_web_fallback(query: str, max_results: int = 5) -> list:
770
  """Fallback web search using DuckDuckGo directly (when MCP is not available)"""
771
+ # Always import here to ensure availability
772
+ try:
773
  from ddgs import DDGS
774
  import requests
775
  from bs4 import BeautifulSoup
776
+ except ImportError:
777
+ logger.error("Fallback dependencies (ddgs, requests, beautifulsoup4) not available")
778
+ return []
779
 
780
  try:
781
  with DDGS() as ddgs:
 
1597
  type="messages"
1598
  )
1599
  with gr.Row(elem_classes="input-row"):
1600
+ message_input = gr.Textbox(
1601
+ placeholder="Type your medical question here...",
1602
+ show_label=False,
1603
+ container=False,
1604
+ lines=1,
1605
+ scale=10
1606
+ )
1607
  mic_button = gr.Audio(
1608
  sources=["microphone"],
1609
  type="filepath",
1610
  label="",
1611
  show_label=False,
 
 
 
 
 
1612
  container=False,
1613
+ scale=1
 
1614
  )
1615
  submit_button = gr.Button("➤", elem_classes="submit-btn", scale=1)
1616
 
1617
+ # Timer display for recording (shown below input row)
1618
+ recording_timer = gr.Textbox(
1619
+ value="",
1620
+ label="",
1621
+ show_label=False,
1622
+ interactive=False,
1623
+ visible=False,
1624
+ container=False,
1625
+ elem_classes="recording-timer"
1626
+ )
1627
+
1628
  # Handle microphone transcription
1629
+ import time
1630
+ recording_start_time = [None]
1631
+
1632
+ def handle_recording_start():
1633
+ """Called when recording starts"""
1634
+ recording_start_time[0] = time.time()
1635
+ return gr.update(visible=True, value="Recording... 0s")
1636
+
1637
+ def handle_recording_stop(audio):
1638
+ """Called when recording stops"""
1639
+ recording_start_time[0] = None
1640
  if audio is None:
1641
+ return gr.update(visible=False, value=""), ""
1642
  transcribed = transcribe_audio(audio)
1643
+ return gr.update(visible=False, value=""), transcribed
1644
+
1645
+ # Use JavaScript for timer updates (simpler than Gradio Timer)
1646
+ mic_button.start_recording(
1647
+ fn=handle_recording_start,
1648
+ outputs=[recording_timer]
1649
+ )
1650
 
1651
  mic_button.stop_recording(
1652
+ fn=handle_recording_stop,
1653
  inputs=[mic_button],
1654
+ outputs=[recording_timer, message_input]
1655
  )
1656
 
1657
  # TTS component for generating speech from messages
 
1818
  if __name__ == "__main__":
1819
  # Preload models on startup
1820
  logger.info("Preloading models on startup...")
1821
+ logger.info("Initializing translation model (DeepSeek-R1)...")
1822
+ try:
1823
+ initialize_translation_model()
1824
+ logger.info("Translation model (DeepSeek-R1) preloaded successfully!")
1825
+ except Exception as e:
1826
+ logger.error(f"Translation model preloading failed: {e}")
1827
+ logger.warning("Translation features may be limited")
1828
  logger.info("Initializing default medical model (MedSwin SFT)...")
1829
  initialize_medical_model(DEFAULT_MEDICAL_MODEL)
1830
  logger.info("Preloading Whisper model...")
1831
  try:
1832
+ initialize_whisper_model()
1833
  if global_whisper_model is not None:
1834
  logger.info("Whisper model preloaded successfully!")
1835
  else: