From 5f0788c0153be9e730431fee62f02f23b5998eb2 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Wed, 20 May 2026 00:04:50 +0800 Subject: [PATCH] auto-sync: 2026-05-20 00:04:50 --- src/daemon/dispatcher.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/daemon/dispatcher.py b/src/daemon/dispatcher.py index 4422607..62e8a5c 100644 --- a/src/daemon/dispatcher.py +++ b/src/daemon/dispatcher.py @@ -117,8 +117,30 @@ class Dispatcher: Returns: {"level": str, "agent_id": str, "session_id": Optional[str], - "status": "dispatched"|"skipped"|"error", "reason": str} + "status": "dispatched"|"skipped"|"error"|"blocked", "reason": str} """ + # 安全红线检查(调度前拦截) + if self.guardrails: + violations = self.guardrails.check_task(task) + critical = [v for v in violations if v.action in ("block_and_notify", "terminate_and_escalate")] + if critical: + v = critical[0] + logger.warning("Task '%s' blocked by guardrail: %s - %s", + task.title, v.rule_id, v.message) + # 写入黑板事件 + _routing_db = Path(project_config["db_path"]) if project_config and "db_path" in project_config else self.db_path + if _routing_db: + self._record_routing(task, {"level": DispatchLevel.BLOCKED, "agent_id": "none", + "reason": v.message}, "blocked", v.message, _routing_db) + return { + "level": "blocked", + "agent_id": "none", + "session_id": None, + "status": "blocked", + "reason": v.message, + "violations": [v.rule_id for v in violations], + } + if self._legacy_mode: return await self._legacy_dispatch(task, action_type, project_config)