Paulhayes commited on
Commit
fc4f0a2
·
verified ·
1 Parent(s): edfd053

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -22
app.py CHANGED
@@ -1656,10 +1656,15 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
1656
  if hive_instance.lite_mode:
1657
  # Lite mode: direct, non-streaming response.
1658
  reply = hive_instance.chat(sanitized_m, eff, current_user_id)
1659
- messages_hist.append({"role": "assistant", "content": reply})
1660
  yield messages_hist, gr.Textbox(value="", interactive=True)
1661
  else:
1662
  # Full mode uses the DialogueManager for a streaming response.
 
 
 
 
 
1663
  full_reply = ""
1664
  messages_hist.append({"role": "assistant", "content": ""}) # Placeholder for the stream
1665
  try:
@@ -1744,17 +1749,21 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
1744
  def get_hive_instance():
1745
  global HIVE_INSTANCE
1746
 
1747
- # If the full hive is ready, ensure we are using it.
1748
  if bootstrap_instance.hive_ready.is_set():
1749
- if HIVE_INSTANCE is None or HIVE_INSTANCE.lite_mode:
1750
  HIVE_INSTANCE = bootstrap_instance.hive_instance
1751
  print("[UI] Full Hive instance attached.")
1752
  return HIVE_INSTANCE
1753
 
1754
  # Otherwise, use the lite instance.
1755
  if HIVE_INSTANCE is None:
1756
- HIVE_INSTANCE = bootstrap_instance.hive_lite_instance
1757
- print("[UI] Using Lite Hive instance while full core initializes.")
 
 
 
 
1758
  return HIVE_INSTANCE
1759
 
1760
 
@@ -1781,11 +1790,15 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
1781
  gr.Markdown("✅ Camera ready." if video_ready else "Camera disabled or not found.", visible=True),
1782
  gr.Image(interactive=video_ready), # video_out
1783
  )
1784
- demo.load(wait_for_voice_features, None, [voice_status_md, ptt_audio_in, ptt_transcript, ptt_transcribe_btn, ptt_chat_btn, vocal_chat_btn, enroll_audio, enroll_btn, who_btn, camera_status_md, video_out])
1785
  def stream_video():
1786
  """Streams video frames from the VideoService to the UI."""
1787
  hive_instance = get_hive_instance()
1788
- if not hive_instance or hive_instance.lite_mode or not hasattr(hive_instance, 'video_service'):
 
 
 
 
1789
  yield None
1790
  return
1791
 
@@ -1793,7 +1806,7 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
1793
  while not video_service.stop_event.is_set():
1794
  frame = video_service.get_frame()
1795
  if frame is not None:
1796
- yield frame
1797
  time.sleep(0.05) # ~20 fps
1798
  demo.load(stream_video, None, video_out)
1799
 
@@ -2021,17 +2034,21 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
2021
  return msg
2022
  mem_compress_btn.click(lambda: compress_memory(get_hive_instance()), [], [compress_status])
2023
 
2024
- def do_hotpatch(patch_json): # type: ignore
2025
  """
2026
  Applies a runtime hotpatch from the admin console.
2027
  """
 
 
2028
  try: patch=json.loads(patch_json)
2029
  except Exception as e: return f"Invalid JSON: {e}"
2030
- # This is a sensitive operation, so we must check the role.
2031
- # This part of the code was missing the role check.
2032
- # For now, we'll just return a message. A full implementation would check role.
2033
- return "Hotpatching is an admin-only feature."
2034
- hotpatch_apply.click(do_hotpatch,[hotpatch_patch],[hotpatch_status])
 
 
2035
 
2036
  # This state will hold the session hash for guest users.
2037
  session_id_state = gr.State(None)
@@ -2135,13 +2152,21 @@ class Bootstrap:
2135
 
2136
  def full_init_task():
2137
  """Initializes the full Hive instance."""
2138
- llm_thread.join() # Wait for the LLM to be loaded
2139
- get_hive_instance(lite=False) # This will replace the lite instance with the full one
2140
- self.hive_ready.set()
 
 
 
 
 
2141
 
2142
  def self_optimize_task():
2143
  """Kicks off the self-optimization process after full initialization."""
2144
  self.hive_ready.wait() # Wait for the full hive to be ready
 
 
 
2145
  if self.hive_instance and hasattr(self.hive_instance, 'selfopt'):
2146
  print("[Bootstrap] Triggering initial self-optimization cycle.")
2147
  self.hive_instance.selfopt.trigger_once()
@@ -2149,8 +2174,13 @@ class Bootstrap:
2149
  def voice_init_task():
2150
  """Initializes voice models in a separate thread."""
2151
  asr_thread.join()
2152
- tts_thread.join()
2153
- self.voice_ready.set()
 
 
 
 
 
2154
 
2155
  # --- Launch Background Initialization Tasks ---
2156
  tasks = {
@@ -2171,14 +2201,22 @@ class Bootstrap:
2171
 
2172
  def _init_lite_core(self):
2173
  """Initializes the fast, responsive lite core."""
2174
- # This now correctly creates the initial lite instance via the global function
2175
- get_hive_instance(lite=True, caps=self.caps)
2176
- self.lite_core_ready.set()
 
 
 
 
 
 
2177
 
2178
  def soft_restart(self):
2179
  """Performs a hot-reload of the application logic without restarting the process."""
2180
  print("[Bootstrap] Performing soft restart (hot-reload)...")
2181
  self.hive_ready.clear()
 
 
2182
  if self.hive_instance:
2183
  self.hive_instance.module_manager.stop_all()
2184
  if self.app and hasattr(self.app, 'close'): # type: ignore
 
1656
  if hive_instance.lite_mode:
1657
  # Lite mode: direct, non-streaming response.
1658
  reply = hive_instance.chat(sanitized_m, eff, current_user_id)
1659
+ messages_hist.append({"role": "assistant", "content": reply or "[No response from model]"})
1660
  yield messages_hist, gr.Textbox(value="", interactive=True)
1661
  else:
1662
  # Full mode uses the DialogueManager for a streaming response.
1663
+ if not hasattr(hive_instance, 'dialogue_manager'):
1664
+ error_msg = "Dialogue Manager not available. Full core may still be initializing."
1665
+ messages_hist.append({"role": "assistant", "content": error_msg})
1666
+ yield messages_hist, gr.Textbox(value="", interactive=True)
1667
+ return
1668
  full_reply = ""
1669
  messages_hist.append({"role": "assistant", "content": ""}) # Placeholder for the stream
1670
  try:
 
1749
  def get_hive_instance():
1750
  global HIVE_INSTANCE
1751
 
1752
+ # If the full hive is ready, ensure we are using it, and it's a valid instance.
1753
  if bootstrap_instance.hive_ready.is_set():
1754
+ if bootstrap_instance.hive_instance is not None and (HIVE_INSTANCE is None or HIVE_INSTANCE.lite_mode):
1755
  HIVE_INSTANCE = bootstrap_instance.hive_instance
1756
  print("[UI] Full Hive instance attached.")
1757
  return HIVE_INSTANCE
1758
 
1759
  # Otherwise, use the lite instance.
1760
  if HIVE_INSTANCE is None:
1761
+ if bootstrap_instance.lite_core_ready.is_set() and bootstrap_instance.hive_lite_instance is not None:
1762
+ HIVE_INSTANCE = bootstrap_instance.hive_lite_instance
1763
+ print("[UI] Using Lite Hive instance while full core initializes.")
1764
+ else:
1765
+ # Neither lite nor full is ready.
1766
+ return None
1767
  return HIVE_INSTANCE
1768
 
1769
 
 
1790
  gr.Markdown("✅ Camera ready." if video_ready else "Camera disabled or not found.", visible=True),
1791
  gr.Image(interactive=video_ready), # video_out
1792
  )
1793
+ demo.load(wait_for_voice_features, None, [voice_status_md, ptt_audio_in, ptt_transcript, ptt_transcribe_btn, ptt_chat_btn, vocal_chat_btn, enroll_audio, enroll_btn, who_btn, camera_status_md, video_out], show_progress="hidden")
1794
  def stream_video():
1795
  """Streams video frames from the VideoService to the UI."""
1796
  hive_instance = get_hive_instance()
1797
+ if not (
1798
+ hive_instance and not hive_instance.lite_mode and
1799
+ hasattr(hive_instance, 'video_service') and hive_instance.video_service and
1800
+ CFG["VIDEO_ENABLED"]
1801
+ ):
1802
  yield None
1803
  return
1804
 
 
1806
  while not video_service.stop_event.is_set():
1807
  frame = video_service.get_frame()
1808
  if frame is not None:
1809
+ yield cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
1810
  time.sleep(0.05) # ~20 fps
1811
  demo.load(stream_video, None, video_out)
1812
 
 
2034
  return msg
2035
  mem_compress_btn.click(lambda: compress_memory(get_hive_instance()), [], [compress_status])
2036
 
2037
+ def do_hotpatch(mode, role, patch_json): # type: ignore
2038
  """
2039
  Applies a runtime hotpatch from the admin console.
2040
  """
2041
+ if not is_admin(mode, role):
2042
+ return "Hotpatching is an admin-only feature."
2043
  try: patch=json.loads(patch_json)
2044
  except Exception as e: return f"Invalid JSON: {e}"
2045
+
2046
+ hive_instance = get_hive_instance()
2047
+ if hive_instance.lite_mode or not hasattr(hive_instance, 'overlay'):
2048
+ return "Hotpatching is not available in Lite Mode."
2049
+ ok, msg = hive_instance.overlay.patch(patch, actor_role=role)
2050
+ return msg
2051
+ hotpatch_apply.click(do_hotpatch,[mode_state, role_state, hotpatch_patch],[hotpatch_status])
2052
 
2053
  # This state will hold the session hash for guest users.
2054
  session_id_state = gr.State(None)
 
2152
 
2153
  def full_init_task():
2154
  """Initializes the full Hive instance."""
2155
+ try:
2156
+ llm_thread.join() # Wait for the LLM to be loaded
2157
+ get_hive_instance(lite=False) # This will replace the lite instance with the full one
2158
+ self.hive_ready.set()
2159
+ except Exception as e:
2160
+ print(f"[ERROR] Failed to initialize Full Hive Core: {e}")
2161
+ traceback.print_exc()
2162
+ # Do not set hive_ready on failure, so app stays in lite mode.
2163
 
2164
  def self_optimize_task():
2165
  """Kicks off the self-optimization process after full initialization."""
2166
  self.hive_ready.wait() # Wait for the full hive to be ready
2167
+ if not self.hive_instance or self.hive_instance.lite_mode:
2168
+ print("[Bootstrap] Skipping self-optimization as full core is not available.")
2169
+ return
2170
  if self.hive_instance and hasattr(self.hive_instance, 'selfopt'):
2171
  print("[Bootstrap] Triggering initial self-optimization cycle.")
2172
  self.hive_instance.selfopt.trigger_once()
 
2174
  def voice_init_task():
2175
  """Initializes voice models in a separate thread."""
2176
  asr_thread.join()
2177
+ tts_thread.join() # Wait for both ASR and TTS threads
2178
+ try:
2179
+ # Additional checks can be added here if needed
2180
+ self.voice_ready.set()
2181
+ except Exception as e:
2182
+ print(f"[ERROR] Voice initialization failed: {e}")
2183
+ traceback.print_exc()
2184
 
2185
  # --- Launch Background Initialization Tasks ---
2186
  tasks = {
 
2201
 
2202
  def _init_lite_core(self):
2203
  """Initializes the fast, responsive lite core."""
2204
+ try:
2205
+ # This now correctly creates the initial lite instance via the global function
2206
+ get_hive_instance(lite=True, caps=self.caps)
2207
+ self.lite_core_ready.set()
2208
+ except Exception as e:
2209
+ print(f"[ERROR] Failed to initialize Lite Hive Core: {e}")
2210
+ traceback.print_exc()
2211
+ # Still set the event so the UI doesn't hang, but it will show an error.
2212
+ self.lite_core_ready.set()
2213
 
2214
  def soft_restart(self):
2215
  """Performs a hot-reload of the application logic without restarting the process."""
2216
  print("[Bootstrap] Performing soft restart (hot-reload)...")
2217
  self.hive_ready.clear()
2218
+ self.lite_core_ready.clear()
2219
+ self.voice_ready.clear()
2220
  if self.hive_instance:
2221
  self.hive_instance.module_manager.stop_all()
2222
  if self.app and hasattr(self.app, 'close'): # type: ignore