Merge PR #64: §17 toolchain/mail 完全分离——Gitea 为唯一协作媒介
This commit was merged in pull request #64.
This commit is contained in:
@@ -218,9 +218,14 @@ class ToolchainContextSection:
|
||||
### 3. 不要执行任何状态转换命令
|
||||
- 不要手动标 working/done/review/failed,系统会自动处理
|
||||
|
||||
### 4. 不需要回复此邮件
|
||||
- 和 request 类型不同:不需要 in_reply_to 回复
|
||||
### 4. 不需要回复
|
||||
- action report 就是你的完成凭证
|
||||
- 不要发送 Mail(飞鸽传书),你的所有操作在 toolchain 流程内完成
|
||||
|
||||
### 5. 所有协作通过 Gitea 完成
|
||||
- 如果遇到问题需要其他角色支持,在关联的 PR/Issue 上创建 comment @对方
|
||||
- 不要使用 Mail API(飞鸽传书)发送消息
|
||||
- 你的所有操作都在 toolchain 流程内,通过 Gitea 留痕
|
||||
|
||||
### Red Flags(如果脑海中出现以下想法,说明你错了)
|
||||
|
||||
@@ -253,7 +258,7 @@ class ToolchainContextSection:
|
||||
| 语气级别 | 用词 | 效果 | 使用场景 |
|
||||
|---------|------|------|---------|
|
||||
| **强制** | "必须"、"不可跳过"、"强制要求" | Agent 无法自合理化跳过 | 步骤执行、action report 提交 |
|
||||
| **禁止** | "不要"、"违反会"、"failed" | Agent 不会越界 | 状态转换、回复邮件 |
|
||||
| **禁止** | "不要"、"违反会"、"failed" | Agent 不会越界 | 状态转换、发送 Mail |
|
||||
| **提醒** | "⚠️" | 视觉强调 | 关键约束前缀 |
|
||||
|
||||
**避免的用词**:"建议"、"如需"、"可以考虑"、"参考"、"推荐"——这些词在 Agent 的推理中会被解读为"可选"。
|
||||
@@ -291,6 +296,19 @@ curl -s -X POST "http://localhost:8083/api/projects/_toolchain/tasks/{task_id}/o
|
||||
```
|
||||
```
|
||||
|
||||
### 需要其他角色支持时
|
||||
|
||||
如果在执行过程中需要其他角色协助(如缺数据、需要审批等),在关联的 PR/Issue 上创建 comment @对方:
|
||||
|
||||
```bash
|
||||
curl -s -X POST "http://192.168.2.154:3000/api/v1/repos/{repo}/issues/{pr_number}/comments" \
|
||||
-H "Authorization: token <your-token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"body": "@{agent-id} 需要你的支持:{描述问题}"}'
|
||||
```
|
||||
|
||||
⚠️ 不要使用 Mail API(飞鸽传书)。所有协作通过 Gitea 留痕。
|
||||
|
||||
**变化**:移除了"手动标 done"的 curl 示例(done 由 verify 自动处理),替换为 action report 提交指引。
|
||||
|
||||
---
|
||||
@@ -355,11 +373,25 @@ def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult:
|
||||
|
||||
### 5.2 on_failure 处理
|
||||
|
||||
verify 失败时的处理逻辑(现有逻辑保留):
|
||||
**设计原则**:toolchain 事件全生命周期在 toolchain 流程内闭环,不走 Mail API。失败本身按错误类型分类,路由到不同的 Gitea 管理动作。
|
||||
|
||||
1. 标 task 为 `failed`
|
||||
2. 通过 Mail API 通知庞统(`_notify_via_mail_api`)
|
||||
3. 通知内容包含:事件类型、事件详情、失败原因、Gitea 链接、行动指引
|
||||
#### 错误分类三分路
|
||||
|
||||
| 错误类型 | 例子 | 处理方式 | 管道 |
|
||||
|---------|------|---------|------|
|
||||
| **业务失败** | verify 不过(no action_report)、Agent 忽略步骤 | 在关联 PR/Issue 上创建 comment @原始 assignee | Gitea webhook → §25 @mention → toolchain task |
|
||||
| **系统失败** | spawner crash、timeout、max_retries、业务失败连续 3 次 | 创建 Gitea Issue 指派 pangtong-fujunshi | Gitea webhook → issue_assigned → toolchain task |
|
||||
| **基础设施失败** | Gitea API 不可用、网络不通 | `_send_toolchain_task` 直接创建 toolchain task 指派 jiangwei-infra | toolchain 内部直接创建 |
|
||||
|
||||
三条路全在 toolchain 流程内,Mail 完全不参与。
|
||||
|
||||
#### 防递归保护
|
||||
|
||||
基础设施失败创建的 toolchain task(action_type=infrastructure_failure),其 verify_completion 始终返回 `VerifyResult(True)`,不再触发 on_failure。
|
||||
|
||||
#### 完整设计
|
||||
|
||||
三分路的详细伪代码、失败上限、决策依据见 §5.2.1~§5.2.3(on_failure 分路处理详细设计)。
|
||||
|
||||
### 5.3 action_report comment 格式
|
||||
|
||||
@@ -403,9 +435,9 @@ Agent 可能写了 action_report 但没真做。缓解机制:
|
||||
| Issue 指派 → 开发者 | issue_assigned | toolchain | 6 步 | 创建分支 + 编码 + push + CI + PR + report |
|
||||
| 部署失败 → 运维 | deploy_failure | toolchain | 4 步 | 查日志 + 排查 + 修+重部署 + report |
|
||||
| @mention → 被@者 | mention | toolchain | 按 guidance | 按 mention 模板的 response_guidance + report |
|
||||
| PR 合并 → PR 作者 | review_merged | **mail (inform)** | — | 纯通知,走 _mail 路径 |
|
||||
| PR 合并 → PR 作者 | review_merged | toolchain | 0 步 | 纯通知,走 _send_toolchain_task(steps 为空,verify 始终通过) |
|
||||
|
||||
**D17-2: 除 PR 合并通知外,所有 toolchain 场景走 ToolchainHandler**
|
||||
**D17-2: 所有 toolchain 场景走 ToolchainHandler**
|
||||
|
||||
### 6.2 各场景 steps 详细定义
|
||||
|
||||
@@ -522,17 +554,28 @@ context:
|
||||
#### PR 合并 → PR 作者
|
||||
|
||||
```
|
||||
走 _mail 路径(inform),不走 toolchain。
|
||||
理由:PR 已经合并,部署已自动触发,作者无需做任何事。纯 FYI 通知。
|
||||
event_type: review_merged
|
||||
action_type: review_merged
|
||||
steps: [] # 无步骤,纯通知
|
||||
verify: 始终通过(inform 语义,无需 action_report)
|
||||
context:
|
||||
pr_number, repo, pr_title, pr_author, merged_by
|
||||
```
|
||||
|
||||
### 6.3 PR 合并通知为何保持 inform
|
||||
**特殊处理**:review_merged 的 verify_completion 始终返回 `VerifyResult(True)`。这是唯一的纯通知场景,Agent 只需阅读即可。
|
||||
|
||||
- PR 已经被合并到 main
|
||||
- 部署已自动触发(deploy workflow)
|
||||
- 作者无需做任何事
|
||||
### 6.3 PR 合并通知为何也走 ToolchainHandler
|
||||
|
||||
这是真正的"FYI"通知,设为 inform 正确。继续走 `_send_mail` 函数,不受本设计影响。
|
||||
**设计原则**:toolchain 和 Mail 完全分离。所有工具链事件(包括纯通知)都走 ToolchainHandler + _toolchain DB。
|
||||
|
||||
**为什么 PR 合并通知不走 _mail**:
|
||||
- toolchain 事件的完整生命周期应在同一个 DB(_toolchain)中追溯
|
||||
- 前端展示统一(Toolchain Tab),不需要跨 _mail 和 _toolchain 两个 Tab 查看同一类事件
|
||||
- Mail 只服务 Agent 间点对点通信(inform / request),不服务工具链事件
|
||||
|
||||
**实现差异**:review_merged 的 verify_completion 始终通过(`VerifyResult(True)`),不需要 action_report。这是 ToolchainHandler 内部的语义区分,不影响 MailHandler。
|
||||
|
||||
**spawn 说明**:review_merged 仍会触发 spawn(Agent 只需阅读通知),verify auto-pass 后标 done。未来可优化为 ticker 直接 auto-done 跳过 spawn。
|
||||
|
||||
---
|
||||
|
||||
@@ -544,7 +587,7 @@ context:
|
||||
|
||||
| 函数 | 用途 | project_id | task_type | DB |
|
||||
|------|------|-----------|-----------|-----|
|
||||
| `_send_mail` | 纯通知(inform)和 Agent 间通信(request) | `_mail` | `mail` | `_mail/blackboard.db` |
|
||||
| `_send_mail` | Agent 间点对点通信(inform / request) | `_mail` | `mail` | `_mail/blackboard.db` |
|
||||
| `_send_toolchain_task` | 工具链动作事件(需 Agent 执行步骤) | `_toolchain` | `toolchain` | `_toolchain/blackboard.db` |
|
||||
|
||||
```python
|
||||
@@ -666,15 +709,20 @@ async def _handle_pr_opened(payload: Dict[str, Any]) -> None:
|
||||
| `_handle_pull_request_review` (COMMENTED) | review_comment | `_send_toolchain_task(...)` |
|
||||
| `_handle_issue_comment` (CI failure) | ci_failure | `_send_toolchain_task(...)` |
|
||||
| `_handle_issues` (assigned) | issue_assigned | `_send_toolchain_task(...)` |
|
||||
| `_handle_pr_closed` (merged) | — | `_send_mail(...)` **不变**(inform 纯通知) |
|
||||
| `_handle_pr_closed` (merged) | review_merged | `_send_toolchain_task(...)`(纯通知,steps 为空,verify 始终通过) |
|
||||
| `_send_deploy_failure_mail` | deploy_failure | `_send_toolchain_task(...)` |
|
||||
| `_send_mention_mails` | mention | `_send_toolchain_task(...)` |
|
||||
|
||||
### 7.4 _send_mail 保留不变
|
||||
### 7.4 _send_mail 不参与任何 toolchain 事件
|
||||
|
||||
`_send_mail` 函数完全保留不变,只服务两个场景:
|
||||
1. PR 合并通知(inform 纯通知)
|
||||
2. ToolchainHandler on_failure 的 Mail 通知(通过 Mail API 发给庞统)
|
||||
`_send_mail` 函数只服务一个场景:**Agent 间点对点通信**(inform / request)。
|
||||
|
||||
**toolchain 事件完全不经过 Mail**:
|
||||
- 事件投递:`_send_toolchain_task`(不是 `_send_mail`)
|
||||
- 失败处理:Gitea PR comment / Gitea Issue / `_send_toolchain_task`(三分路)
|
||||
- PR 合并通知:`_send_toolchain_task`(review_merged,steps 为空)
|
||||
|
||||
Mail 和 toolchain 是两套完全独立的系统,各自有独立的 DB、Handler、PromptSection。
|
||||
|
||||
---
|
||||
|
||||
@@ -704,6 +752,7 @@ if handler:
|
||||
meta = json.loads(must_haves) if must_haves else {}
|
||||
from_agent = meta.get("from", "")
|
||||
mail_type = meta.get("performative", meta.get("type", ""))
|
||||
# 注:toolchain task 的 mail_type 为空(不走 MailHandler),保留字段兼容 MailHandler
|
||||
|
||||
# 新增:toolchain 字段提取
|
||||
event_type = meta.get("event_type", "")
|
||||
@@ -781,23 +830,21 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| 文件 | 改动类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| `src/daemon/toolchain_handler.py` | 修改 | ToolchainContextSection 加 steps 渲染 + action_hint;ToolchainApiSection 改为 action_report 指引;ToolchainConstraintsSection 加 Red Flags;verify_completion 改用 action_report |
|
||||
| `src/api/toolchain_routes.py` | 修改 | 新增 `_toolchain_db_path()` + `_send_toolchain_task()`;各 handler 改为调用 `_send_toolchain_task`;PR merged 保持 `_send_mail` |
|
||||
| `src/api/toolchain_routes.py` | 修改 | 新增 `_toolchain_db_path()` + `_send_toolchain_task()`;所有 handler(含 PR merged)改为调用 `_send_toolchain_task` |
|
||||
| `src/daemon/spawner.py` | 修改 | handler 路径 PromptContext 构造时提取 `action_type`、`action_steps` 字段 |
|
||||
| `src/daemon/prompt_composer.py` | 修改 | PromptContext 新增 `action_type`、`action_steps` 字段 |
|
||||
| `src/blackboard/db.py` | 修改 | comments 表 CHECK 约束处理(去掉 CHECK 或加 action_report) |
|
||||
| `src/daemon/mail_notify.py` | 修改 | `_REASON_MAP` 新增 `no_action_report` reason |
|
||||
|
||||
### 改动量估算
|
||||
|
||||
| 文件 | 改动量 | 风险 |
|
||||
|------|--------|------|
|
||||
| `src/daemon/toolchain_handler.py` | ~80 行 | 中(核心逻辑变化) |
|
||||
| `src/daemon/toolchain_handler.py` | ~120 行 | 中(核心逻辑变化 + on_failure 三分路) |
|
||||
| `src/api/toolchain_routes.py` | ~120 行 | 中(新增函数 + 8 个 handler 改造) |
|
||||
| `src/daemon/spawner.py` | ~8 行 | 低(纯新增字段提取) |
|
||||
| `src/daemon/prompt_composer.py` | ~3 行 | 低(dataclass 新增字段) |
|
||||
| `src/blackboard/db.py` | ~5 行 | 低(CHECK 约束处理) |
|
||||
| `src/daemon/mail_notify.py` | ~2 行 | 低(新增一行 reason map) |
|
||||
| **总计** | **~218 行** | |
|
||||
| **总计** | **~256 行** | |
|
||||
|
||||
---
|
||||
|
||||
@@ -810,7 +857,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| Agent 间手动发 inform Mail | ✅ 无影响 |
|
||||
| Agent 间手动发 request Mail | ✅ 无影响 |
|
||||
| MailHandler 的 verify / on_failure | ✅ 无影响 |
|
||||
| `_send_mail` 函数 | ✅ 保留不变 |
|
||||
| `_send_mail` 函数 | ✅ 保留不变(只服务 Agent 间通信,不服务任何 toolchain 事件) |
|
||||
|
||||
### 11.2 _mail DB 中已有的 toolchain task
|
||||
|
||||
@@ -852,13 +899,15 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
|
||||
**理由**:action_report comment 机制最简单且与现有架构一致。保留 fallback 确保平滑过渡。Agent 如果写了 report 但没执行,后续事件链(CI 不会通过、Reviewer 不会收到 Review)会自然暴露问题。
|
||||
|
||||
### D17-2: 除 PR 合并通知外,所有 toolchain 场景走 ToolchainHandler
|
||||
### D17-2: 所有 toolchain 场景走 ToolchainHandler
|
||||
|
||||
**决策**:9 种 toolchain 场景中,8 种走 ToolchainHandler(`_send_toolchain_task`),仅 `review_merged` 走 MailHandler(`_send_mail` + inform)。
|
||||
**决策**:全部 10 种 toolchain 场景走 ToolchainHandler(`_send_toolchain_task`),包括 PR 合并通知(review_merged)。Mail 不服务任何 toolchain 事件。
|
||||
|
||||
**理由**:
|
||||
- 8 种场景都需要 Agent 执行后续动作(修代码/审查/合并/排查/响应 mention)
|
||||
- PR 合并是真正的 FYI,无需 Agent 行动
|
||||
- toolchain 事件的完整生命周期应在同一个 DB(_toolchain)中追溯
|
||||
- 前端展示统一(Toolchain Tab),不需要跨 _mail 和 _toolchain 两个 Tab
|
||||
- Mail 只服务 Agent 间点对点通信(inform / request),不服务工具链事件
|
||||
- review_merged 的 verify_completion 始终通过,不需要 action_report
|
||||
|
||||
### D17-3: comments 表 CHECK 约束处理
|
||||
|
||||
@@ -925,15 +974,14 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| 2b | `toolchain_handler.py` | ToolchainApiSection 改为 action_report 指引 | 低 |
|
||||
| 2c | `toolchain_handler.py` | ToolchainConstraintsSection 加 Red Flags 表 | 低 |
|
||||
| 2d | `toolchain_handler.py` | verify_completion 改用 action_report(保留 fallback) | 中 |
|
||||
| 2e | `toolchain_handler.py` | on_failure 保留现有逻辑(标 failed + 通知庞统) | 无 |
|
||||
| 2e | `toolchain_handler.py` | on_failure 三分路重写(业务→PR comment / 系统→Gitea Issue / 基础设施→toolchain task) | 中 |
|
||||
|
||||
### Step 3:toolchain_routes 改造
|
||||
|
||||
| 子步骤 | 文件 | 内容 | 风险 |
|
||||
|--------|------|------|------|
|
||||
| 3a | `toolchain_routes.py` | 新增 `_toolchain_db_path()` + `_send_toolchain_task()` | 低 |
|
||||
| 3b | `toolchain_routes.py` | 8 个 handler 改为调用 `_send_toolchain_task`(PR merged 除外) | 中 |
|
||||
| 3c | `mail_notify.py` | `_REASON_MAP` 新增 `no_action_report` | 极低 |
|
||||
| 3b | `toolchain_routes.py` | 所有 handler(含 PR merged)改为调用 `_send_toolchain_task` | 中 |
|
||||
|
||||
### Step 4:测试 + 验证
|
||||
|
||||
@@ -944,7 +992,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| 4c | 单元测试:_send_toolchain_task 写入 _toolchain DB |
|
||||
| 4d | 集成测试:webhook → toolchain task → Agent → action_report → done |
|
||||
| 4e | 回归测试:_mail 路径不受影响(inform/request 不变) |
|
||||
| 4f | 回归测试:PR merged 仍走 _send_mail(inform) |
|
||||
| 4f | 回归测试:PR merged 走 _send_toolchain_task(review_merged,verify 始终通过) |
|
||||
|
||||
---
|
||||
|
||||
@@ -952,7 +1000,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 |
|
||||
|------|------|------|----------|
|
||||
| Agent 不提交 action_report | 中 | 高 | Prompt 强约束 + Red Flag 表 + verify 失败标 failed + 通知庞统 + fallback(output/comment) |
|
||||
| Agent 不提交 action_report | 中 | 高 | Prompt 强约束 + Red Flag 表 + verify 失败 → on_failure 三分路(PR comment @assignee / Gitea Issue @pangtong / toolchain task @jiangwei)+ fallback(output/comment) |
|
||||
| Agent 提交虚假 action_report | 低 | 中 | 后续事件链自然暴露(CI 不通过、Reviewer 收不到 Review) |
|
||||
| Agent 混淆 toolchain 和 mail 语义 | 低 | 低 | ToolchainContextSection 明确告知"这是需要执行动作的事件" |
|
||||
| _toolchain DB 未初始化 | 低 | 中 | `_toolchain_db_path()` 中调用 `init_db()` 确保目录和表存在 |
|
||||
@@ -969,7 +1017,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
§13 §15.5 已定义 6 个强约束模板,每个包含编号步骤、Gitea API 调用指令、时限要求。本设计在此基础上:
|
||||
- 将步骤从模板纯文本提取到 must_hives JSON 的 `steps` 字段(结构化、可编程化)
|
||||
- 通过 ToolchainHandler 的 PromptSection 强约束确保 Agent 知道必须执行
|
||||
- 将"回复此 Mail 确认"改为"提交 action report"(更适合自动化验证)
|
||||
- 用 action report(执行凭证)替代邮件回复(更适合自动化验证)
|
||||
|
||||
### 15.2 Superpowers: Red Flags 表
|
||||
|
||||
@@ -1017,7 +1065,7 @@ Hermes 的验证理念:执行和验证不可分割。本设计中 verify_compl
|
||||
- [ ] §3 输入约束:must_hives JSON 结构 + ToolchainContextSection 渲染增强
|
||||
- [ ] §4 执行约束:Red Flags 表设计是否覆盖常见 self-rationalization 模式
|
||||
- [ ] §5 输出约束:action_report verify 机制 + fallback 设计
|
||||
- [ ] §6 场景 steps 定义是否完整(8 种 action 场景 + 1 种 inform 场景)
|
||||
- [ ] §6 场景 steps 定义是否完整(9 种 action 场景 + 1 种纯通知场景 review_merged)
|
||||
- [ ] §7 _send_toolchain_task 函数设计是否正确
|
||||
- [ ] §8 PromptContext / spawner 改动是否和 §14 架构一致
|
||||
- [ ] §9 DB 隔离是否符合 §14 原设计
|
||||
|
||||
Reference in New Issue
Block a user