From acbf2f61648434a81999a932bdc0655b58c3f5c7 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Fri, 29 May 2026 19:48:32 +0800 Subject: [PATCH] auto-sync: 2026-05-29 19:48:32 --- docs/design/02-main-session-delegation.md | 68 +++++++++++++++++++++-- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/docs/design/02-main-session-delegation.md b/docs/design/02-main-session-delegation.md index ab3b385..7e2de67 100644 --- a/docs/design/02-main-session-delegation.md +++ b/docs/design/02-main-session-delegation.md @@ -314,15 +314,71 @@ sub session(临时,完成即删) --- -## 八、待确认 +## 八、Mail 路径已验证的完整模式(可直接复用) + +Mail 路径(`dispatcher.py` `_mail_on_checks_passed` + `_mail_auto_complete`)已经完整实现了 main session + 完成检测的全链路: + +``` +openclaw agent --agent xxx(不传 --session-id)→ Gateway 投递到 main session + → Agent 处理 → 进程退出 + → on_complete 回调触发 → _mail_auto_complete + → 幻觉门控:检查黑板是否有回复 + → 有回复 → 标 done + → 无回复 → 留 working,等 ticker 超时兜底再查 +``` + +### 已验证的机制 + +| 机制 | Mail 实现 | 普通 Task 复用 | +|------|----------|--------------| +| Main session 投递 | `use_main_session=True` | ✅ 直接复用 | +| `on_complete` 回调 | `_mail_on_complete` → `_mail_auto_complete` | ✅ 改为检查产出/状态而非邮件回复 | +| 幻觉门控 | `_mail_check_reply` 检查回复邮件 | ⚠️ 改为检查 `outputs` 表 + `status` 字段 | +| 超时兜底 | ticker 轮询 working 状态 + 再次检查 | ✅ 直接复用 | +| auto-working | `on_checks_passed` 回调中标 working | ✅ 直接复用 | + +### 普通 Task 的完成检测(复用 Mail 模式) + +Mail 的 `_mail_auto_complete` 检查的是"是否有回复邮件"。普通 Task 改为检查: + +```python +def _task_auto_complete(self, task_id, agent_id, db_path): + """普通 Task 完成检测(复用 Mail 模式) + + 检查逻辑: + 1. outputs 表是否有产出(非空) + 2. status 是否已由 Agent 自行更新(review/done/failed) + 3. 如果都没有 → 留 working,等 ticker 超时兜底 + """ + conn = get_connection(db_path) + try: + row = conn.execute("SELECT status FROM tasks WHERE id=?", (task_id,)).fetchone() + if not row or row["status"] != "working": + return # Agent 已自行更新状态 + + # 检查是否有产出 + output_count = conn.execute( + "SELECT COUNT(*) FROM outputs WHERE task_id=?", (task_id,) + ).fetchone()[0] + + if output_count > 0: + # 有产出 → Agent 忘了标状态,帮它标 review + conn.execute("UPDATE tasks SET status='review' WHERE id=?", (task_id,)) + conn.commit() + else: + # 无产出 → 留 working 等 ticker 超时兜底 + pass + finally: + conn.close() +``` + +### 待确认 | # | 问题 | 说明 | |---|------|------| -| 1 | **Daemon 如何知道任务完成了?** | 现行用 `--json` 同步等结果。改用 main session 后,需要改为"投递后 ticker 轮询黑板状态变化" | -| 2 | **投递消息的 prompt 模板** | 需要和 v2.8 方向的 Prompt 进化对齐(身份+能力+约束 vs 固定步骤) | -| 3 | **on_complete 回调** | 改为基于黑板状态变化(status/review/done)触发,不再依赖 spawn 返回值 | -| 4 | **Mail 投递路径** | Mail 已经走 main session(`use_main_session=is_mail`),无需改动 | -| 5 | **E2E 测试适配** | 现有 E2E 测试依赖 spawner 的 `--session-id UUID` 机制,需要适配 | +| 1 | **投递消息的 prompt 模板** | 需要和 v2.8 方向的 Prompt 进化对齐(身份+能力+约束 vs 固定步骤) | +| 2 | **E2E 测试适配** | 现有 E2E 测试依赖 spawner 的 `--session-id UUID` 机制,需要适配 | +| 3 | **幻觉门控策略** | 普通 Task 用 outputs 表 + status 字段检查,还是其他方式? | ---