diff --git a/ai-hub/app/core/orchestration/architect.py b/ai-hub/app/core/orchestration/architect.py index a04073f..9fb2f64 100644 --- a/ai-hub/app/core/orchestration/architect.py +++ b/ai-hub/app/core/orchestration/architect.py @@ -213,13 +213,17 @@ else: yield event - # Turn duration report (End of Loop) turn_duration = time.time() - turn_start_time total_duration = time.time() - session_start_time duration_marker = f"\n\n> **⏱️ Turn {turn} Duration:** {turn_duration:.1f}s | **Total:** {total_duration:.1f}s\n" yield {"type": "reasoning", "content": duration_marker} yield {"type": "status", "content": f"Turn {turn} finished in **{turn_duration:.1f}s**. (Session Total: **{total_duration:.1f}s**)"} + except Exception as e: + import traceback + logging.error(f"[Architect] CRITICAL FAULT:\n{traceback.format_exc()}") + yield {"type": "status", "content": "Fatal Orchestration Error"} + yield {"type": "content", "content": f"\n\n> **🚨 Core Orchestrator Fault:** A fatal exception abruptly halted the execution loop: `{str(e)}`\n\nThe AI's process terminated unexpectedly. You may need to retry your request or check server logs."} finally: if registry and user_id: registry.unsubscribe_user(user_id, mesh_bridge) diff --git a/ai-hub/app/core/orchestration/body.py b/ai-hub/app/core/orchestration/body.py index 20f0da3..ed28d0a 100644 --- a/ai-hub/app/core/orchestration/body.py +++ b/ai-hub/app/core/orchestration/body.py @@ -45,6 +45,7 @@ tool_tasks.append((tc, task)) # --- Wait & Monitor loop --- + _keepalive_cycles = 0 while True: all_done = all(item[1].done() for item in tool_tasks) @@ -75,7 +76,11 @@ if all_done: break + await asyncio.sleep(0.1) + _keepalive_cycles += 1 + if _keepalive_cycles % 50 == 0: + yield {"type": "status", "content": "Processing task... (Keepalive Heartbeat)"} # Yield results for AI history for tc, task in tool_tasks: diff --git a/ai-hub/app/core/services/browser_client.py b/ai-hub/app/core/services/browser_client.py index 3300cab..d1b913d 100644 --- a/ai-hub/app/core/services/browser_client.py +++ b/ai-hub/app/core/services/browser_client.py @@ -140,7 +140,7 @@ await self._report_status(f"🌐 Navigating to `{url}`...", on_event) try: req = browser_pb2.NavigateRequest(url=url, session_id=session_id) - resp = await self.stub.Navigate(req) + resp = await self.stub.Navigate(req, timeout=90) result = self._process_response(resp) if resp.screenshot_path and on_event: result["_screenshot_bytes"] = self._read_shm_bytes(resp.screenshot_path) @@ -239,7 +239,7 @@ max_concurrent=max_concurrent, extract_markdown=extract_markdown ) - resp = await self.stub.ParallelFetch(req) + resp = await self.stub.ParallelFetch(req, timeout=120) results = [] for r in resp.results: