refactor: unify event routing, orchestration, and agent context handling with consistent naming and closed-loop tracking
This commit is contained in:
@@ -13,8 +13,8 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class AIOrchestrator:
|
||||
"""
|
||||
協調中樞:負責 EventRouter 的 L1/L2 處理、Agent 共享上下文與閉環決策追蹤。
|
||||
設計輕量,單檔不超過 100 行。
|
||||
Coordination hub: handles EventRouter L1/L2, agent shared context, and closed-loop decision tracking.
|
||||
Single file <= 100 lines.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@@ -23,8 +23,8 @@ class AIOrchestrator:
|
||||
|
||||
async def handle_l1(self, event: Dict[str, Any], session_id: str) -> Dict[str, Any]:
|
||||
"""
|
||||
L1:語意翻譯 + 原因分析(由 Hermes 提供)。
|
||||
結果會寫入 agent_context,並可作為 L2 的上下文。
|
||||
L1: semantic translation + reason analysis (provided by Hermes).
|
||||
Writes to agent_context and can be used as L2 context.
|
||||
"""
|
||||
ctx = await self._get_context(session_id)
|
||||
result = await self.hermes.handle_l1(event, ctx)
|
||||
@@ -33,13 +33,13 @@ class AIOrchestrator:
|
||||
|
||||
async def handle_l2(self, event: Dict[str, Any], session_id: str) -> Dict[str, Any]:
|
||||
"""
|
||||
L2:規劃 + 審核閘。
|
||||
輸入包含 L1 分析結果(若可用),產出 ActionPlan 等待批准。
|
||||
L2: planning + review gate.
|
||||
Produces an ActionPlan awaiting approval (handled via Telegram callback).
|
||||
"""
|
||||
ctx = await self._get_context(session_id) # 包含 hermes 分析
|
||||
ctx = await self._get_context(session_id) # includes hermes analysis
|
||||
result = await self.nemotron.handle_l2(event, ctx)
|
||||
await self._save_action_plan(result)
|
||||
# 審核閘由 routes/bot_api_routes 透過 callback 處理
|
||||
# review gate handled by routes/bot_api_routes callback
|
||||
return result
|
||||
|
||||
async def _get_context(self, session_id: str) -> Dict[str, Any]:
|
||||
@@ -77,7 +77,7 @@ class AIOrchestrator:
|
||||
session.commit()
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
logger.error(f"[AIOrchestrator] save_context 失敗: {e}")
|
||||
logger.error(f"[AIOrchestrator] save_context failed: {e}")
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
@@ -102,7 +102,7 @@ class AIOrchestrator:
|
||||
session.commit()
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
logger.error(f"[AIOrchestrator] save_action_plan 失敗: {e}")
|
||||
logger.error(f"[AIOrchestrator] save_action_plan failed: {e}")
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
@@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
async def _handle_l1(event: Dict[str, Any], session_id: str) -> Dict[str, Any]:
|
||||
"""
|
||||
L1:語意翻譯 + 原因分析(由 AIOrchestrator 調用 Hermes)。
|
||||
L1: semantic translation + reason analysis (provided by Hermes).
|
||||
"""
|
||||
orchestrator = AIOrchestrator()
|
||||
return await orchestrator.handle_l1(event, session_id)
|
||||
@@ -20,22 +20,22 @@ async def _handle_l1(event: Dict[str, Any], session_id: str) -> Dict[str, Any]:
|
||||
|
||||
async def _handle_l2(event: Dict[str, Any], session_id: str) -> Dict[str, Any]:
|
||||
"""
|
||||
L2:規劃 + 審核閘。
|
||||
產出 ActionPlan 等待批准(Telegram 回調處理)。
|
||||
L2: planning + review gate.
|
||||
Produces an ActionPlan awaiting approval (handled via Telegram callback).
|
||||
"""
|
||||
orchestrator = AIOrchestrator()
|
||||
return await orchestrator.handle_l2(event, session_id)
|
||||
|
||||
|
||||
async def _handle_l0(event: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""L0:直接回傳原始事件(兼容與監控)"""
|
||||
"""L0: return raw event (for compatibility/monitoring)."""
|
||||
return {"status": "ok", "echo": event.get("event_type")}
|
||||
|
||||
|
||||
async def dispatch(event: Dict[str, Any], admin_chat_ids: Optional[list] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
事件路由主入口(與 routes/bot_api_routes 兼容)。
|
||||
輸出格式與 dispatch_v1 保持一致,以便平滑切換。
|
||||
Main event routing entry (compatible with routes/bot_api_routes).
|
||||
Output format matches dispatch_v1 for smooth migration.
|
||||
"""
|
||||
tier = _classify(event)
|
||||
session_id = f"evt:{event.get('event_type')}:{event.get('source', 'unknown')}"
|
||||
@@ -50,7 +50,7 @@ async def dispatch(event: Dict[str, Any], admin_chat_ids: Optional[list] = None)
|
||||
else:
|
||||
result = await _handle_l0(event)
|
||||
|
||||
# 保留舊版回傳格式
|
||||
# preserve legacy output format
|
||||
return {
|
||||
"tier": tier,
|
||||
"sent": 1,
|
||||
@@ -59,7 +59,7 @@ async def dispatch(event: Dict[str, Any], admin_chat_ids: Optional[list] = None)
|
||||
"payload": result,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.exception(f"[EventRouter] dispatch 失敗: {e}")
|
||||
logger.exception(f"[EventRouter] dispatch failed: {e}")
|
||||
return {
|
||||
"tier": tier,
|
||||
"sent": 0,
|
||||
|
||||
Reference in New Issue
Block a user