refactor: unify event routing, orchestration, and agent context handling with consistent naming and closed-loop tracking

This commit is contained in:
ogt (aider)
2026-04-19 22:21:02 +08:00
parent 055eca1cd8
commit f5faf478bb
4 changed files with 38 additions and 38 deletions

View File

@@ -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()

View File

@@ -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,