From fb31ce3752fc88ee07c3b44f4bce012491e96639 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Wed, 10 Jun 2026 22:38:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20S1=20handler=20display=5Fname=20+=20S2?= =?UTF-8?q?=20import=20=E7=A7=BB=E9=A1=B6=E9=83=A8=20+=20W1=20=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - S1: vp_name 硬编码字典 → handler.display_name 属性 - S2: ticker/spawner 中 TaskTypeRegistry 局部 import → 移文件顶部 - W1: TaskHandler executor verify 失败不调 on_failure 加注释说明 --- src/daemon/base_task_handler.py | 1 + src/daemon/mail_handler.py | 1 + src/daemon/spawner.py | 4 ++-- src/daemon/task_handler.py | 4 ++++ src/daemon/ticker.py | 11 ++++------- src/daemon/toolchain_handler.py | 1 + 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/daemon/base_task_handler.py b/src/daemon/base_task_handler.py index c80a083..f373540 100644 --- a/src/daemon/base_task_handler.py +++ b/src/daemon/base_task_handler.py @@ -41,6 +41,7 @@ class BaseTaskHandler: task_type: str = "" virtual_project: Optional[str] = None + display_name: str = "" # 中文展示名(ticker 扫描日志用) # === 子类必须实现 === diff --git a/src/daemon/mail_handler.py b/src/daemon/mail_handler.py index 91c6e91..4ba3cab 100644 --- a/src/daemon/mail_handler.py +++ b/src/daemon/mail_handler.py @@ -20,6 +20,7 @@ class MailHandler(BaseTaskHandler): task_type = "mail" virtual_project = "_mail" + display_name = "飞鸽传书" def target_success_status(self) -> str: return "done" diff --git a/src/daemon/spawner.py b/src/daemon/spawner.py index a67b3c1..40b169f 100644 --- a/src/daemon/spawner.py +++ b/src/daemon/spawner.py @@ -19,6 +19,8 @@ from src.blackboard.db import get_connection logger = logging.getLogger("moziplus-v2.spawner") +from src.daemon.task_type_registry import TaskTypeRegistry + # ── Prompt 模板 ── @@ -279,7 +281,6 @@ class AgentSpawner: project_id, agent_id) # handler 路径:Task/Mail/Toolchain 用各自的 PromptSection 构建 - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(project_id) if handler: from src.daemon.prompt_composer import PromptContext @@ -343,7 +344,6 @@ class AgentSpawner: """构建 API 回写操作指令(BootstrapBuilder 模式下补充)""" # handler 项目(_mail/_toolchain)的 success_status 由 PromptSection 处理 # 这里只处理无 handler 的项目(normal task) - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(project_id) if handler: success_status = '"done"' if handler.target_success_status == "done" else '"review"' diff --git a/src/daemon/task_handler.py b/src/daemon/task_handler.py index 6a535a5..0dfb796 100644 --- a/src/daemon/task_handler.py +++ b/src/daemon/task_handler.py @@ -182,6 +182,7 @@ class TaskHandler(BaseTaskHandler): task_type: str = "task" virtual_project: Optional[str] = None + display_name = "黑板任务" # === 子类实现 === @@ -229,6 +230,9 @@ class TaskHandler(BaseTaskHandler): logger.info( "Task %s: verify not passed (%s), leaving working", task_id, result.reason) + # NOTE: executor verify 不通过时不标 failed,留 working。 + # 原因:Agent 可能还在产出中(幻觉门控的后续轮次), + # ticker 超时检查会兜底处理。不调 on_failure 避免误判。 def target_success_status(self) -> str: """task 类型验证通过后进 review。""" diff --git a/src/daemon/ticker.py b/src/daemon/ticker.py index cc89a67..5a4bae7 100644 --- a/src/daemon/ticker.py +++ b/src/daemon/ticker.py @@ -19,6 +19,8 @@ from typing import Any, Callable, Coroutine, Dict, List, Optional from dataclasses import dataclass, field as dc_field +from src.daemon.task_type_registry import TaskTypeRegistry + from src.blackboard.operations import Blackboard from src.blackboard.db import get_connection from src.daemon.spawner import AgentBusyError @@ -216,12 +218,12 @@ class Ticker: results["projects"]["_general"] = {"error": str(e)} # 虚拟项目:从注册表自动发现 + _general 硬编码 - from src.daemon.task_type_registry import TaskTypeRegistry for vp in TaskTypeRegistry.virtual_projects(): vp_db = Path(self.registry.root) / vp / "blackboard.db" if vp_db.exists() and vp not in active_projects: try: - vp_name = {"_mail": "飞鸽传书", "_toolchain": "工具链事件"}.get(vp, vp) + vp_handler = TaskTypeRegistry.get_by_project(vp) + vp_name = vp_handler.display_name if vp_handler and vp_handler.display_name else vp pr = await self._tick_project(vp, { "id": vp, "name": vp_name, "status": "active", "source": "virtual", @@ -953,7 +955,6 @@ Parent Task ID: {parent_task.id} # 重置到 pending 时清空 assignee(避免残留导致重复路由到同一 Agent) # handler 虚拟项目(_mail 等)的 assignee 是收件人,永不清空 if new_status == "pending": - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(self._current_project_id) if handler: conn.execute( @@ -1031,7 +1032,6 @@ Parent Task ID: {parent_task.id} conn = get_connection(db_path) try: # [Step 5] handler 项目已在 dispatcher 中标 working,跳过 claimed - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(project_id) if handler: conn.execute( @@ -1308,7 +1308,6 @@ Parent Task ID: {parent_task.id} project_id: str) -> List[str]: """扫描 review 状态任务,检查是否有产出,调度审查 Agent""" # handler 项目(_mail/_toolchain)不走 review 流程 - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(project_id) if handler: return [] @@ -1480,7 +1479,6 @@ Parent Task ID: {parent_task.id} elapsed = (now - start_time).total_seconds() / 60.0 if elapsed > timeout_minutes: # [Step 5] handler 幻觉门控兜底:check_completion 通过 + working → done - from src.daemon.task_type_registry import TaskTypeRegistry handler = TaskTypeRegistry.get_by_project(self._current_project_id) if handler and handler.check_completion(task.id, db_path): conn = get_connection(db_path) @@ -1631,7 +1629,6 @@ Parent Task ID: {parent_task.id} project_id / "blackboard.db" # 虚拟项目:_general + 注册表自动发现 - from src.daemon.task_type_registry import TaskTypeRegistry virtual_ids = ["_general"] + TaskTypeRegistry.virtual_projects() for virtual_id in virtual_ids: virtual_db = Path(self.registry.root) / \ diff --git a/src/daemon/toolchain_handler.py b/src/daemon/toolchain_handler.py index b3d7f1c..2612693 100644 --- a/src/daemon/toolchain_handler.py +++ b/src/daemon/toolchain_handler.py @@ -121,6 +121,7 @@ class ToolchainHandler(BaseTaskHandler): task_type = "toolchain" virtual_project = "_toolchain" + display_name = "工具链事件" def target_success_status(self) -> str: return "done"