From 321c2333d6f95cee99c5988652ec8777b4e0ad4c Mon Sep 17 00:00:00 2001 From: chiguyong Date: Sat, 13 Jun 2026 11:50:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(monitor):=20=E5=AF=B9=E8=AF=9D=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=90=8E=E8=87=AA=E5=8A=A8=E8=AE=B0=E5=BD=95=E7=BB=8F?= =?UTF-8?q?=E9=AA=8C=E5=88=B0=E7=9B=91=E6=8E=A7=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - portal.py: 对话完成后调用 _record_experience 记录经验到 dashboard - portal.py: 修复 routing_result.skill → routing_result.skill_name 属性名 - 经验记录触发 experience_added 和 metrics_updated 事件广播 - metrics API 从 _experiences 内存列表计算 total_tasks/success_rate/avg_duration --- src/agentkit/server/routes/portal.py | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/agentkit/server/routes/portal.py b/src/agentkit/server/routes/portal.py index f146d8c..dd3378d 100644 --- a/src/agentkit/server/routes/portal.py +++ b/src/agentkit/server/routes/portal.py @@ -14,6 +14,11 @@ from pydantic import BaseModel from agentkit.core.protocol import TaskMessage from agentkit.core.react import ReActEngine from agentkit.router.intent import IntentRouter +from agentkit.server.routes.evolution_dashboard import ( + _experiences as _dashboard_experiences, + DashboardExperience, + _broadcast_event as _broadcast_dashboard_event, +) logger = logging.getLogger(__name__) @@ -520,6 +525,29 @@ async def portal_websocket(websocket: WebSocket): # Add user message to conversation _conversation_store.add_message(conv.id, "user", message_text) + start_time = datetime.now(timezone.utc) + + async def _record_experience( + task_type: str, goal: str, outcome: str, duration_seconds: float + ) -> None: + """Record experience to dashboard after chat completion.""" + try: + exp = DashboardExperience( + id=str(uuid.uuid4()), + task_type=task_type, + goal=goal[:200], + outcome=outcome, + duration_seconds=duration_seconds, + created_at=datetime.now(timezone.utc), + ) + _dashboard_experiences.append(exp) + await _broadcast_dashboard_event("experience_added", { + "id": exp.id, "task_type": exp.task_type, + "goal": exp.goal, "outcome": exp.outcome, + }) + await _broadcast_dashboard_event("metrics_updated", {"period": "7d"}) + except Exception as e: + logger.warning(f"Failed to record experience: {e}") # Unified routing via CostAwareRouter (handles Layer 0/1/2) pool = websocket.app.state.agent_pool @@ -588,6 +616,7 @@ async def portal_websocket(websocket: WebSocket): "type": "result", "data": {"status": "completed", "content": response.content}, }) + await _record_experience("chat", message_text, "success", (datetime.now(timezone.utc) - start_time).total_seconds()) continue # General path: agent execution @@ -614,6 +643,7 @@ async def portal_websocket(websocket: WebSocket): "type": "result", "data": {"status": "completed", "content": response.content}, }) + await _record_experience("chat", message_text, "success", (datetime.now(timezone.utc) - start_time).total_seconds()) continue agent = await pool.create_agent_from_skill(agent_name) @@ -675,9 +705,14 @@ async def portal_websocket(websocket: WebSocket): if response_text: _conversation_store.add_message(conv.id, "assistant", response_text) + outcome = "success" if response_text else "failure" await websocket.send_json( {"type": "result", "data": {"message": response_text}} ) + await _record_experience( + routing_result.skill_name or "agent", message_text, + outcome, (datetime.now(timezone.utc) - start_time).total_seconds(), + ) except WebSocketDisconnect: logger.debug(f"Portal WebSocket disconnected for conversation {conv.id if conv else 'N/A'}")