Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85e2004e69 |
@@ -353,13 +353,136 @@ def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult:
|
||||
|
||||
保留 fallback 层次是为了平滑过渡:改造初期 Agent 可能还不习惯提交 action_report,fallback 避免"改造后所有 task 都 failed"的问题。
|
||||
|
||||
### 5.2 on_failure 处理
|
||||
### 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 | 创建 Gitea Issue 指派 pangtong-fujunshi,body 包含错误详情 + task ID + 日志摘要 | Gitea webhook → issue_assigned → toolchain task |
|
||||
| **基础设施失败** | Gitea API 不可用、网络不通 | `_send_toolchain_task` 直接创建 toolchain task 指派 jiangwei-infra | toolchain 内部直接创建 |
|
||||
|
||||
三条路全在 toolchain 流程内,Mail 完全不参与。
|
||||
|
||||
#### 业务失败处理(PR/Issue comment @assignee)
|
||||
|
||||
verify 失败时,在原始事件关联的 Gitea PR 或 Issue 上创建 comment,@原始 assignee:
|
||||
|
||||
```python
|
||||
def on_failure(self, task_id, agent_id, db_path, verify):
|
||||
self._mark_task_status(db_path, task_id, "failed")
|
||||
|
||||
# 读取事件上下文
|
||||
meta = self._read_task_meta(db_path, task_id)
|
||||
failure_count = meta.get("failure_count", 0) + 1
|
||||
|
||||
# 分类路由
|
||||
if verify.reason in SYSTEM_ERROR_REASONS:
|
||||
# 系统失败 → Gitea Issue 给庞统
|
||||
self._create_gitea_issue_for_system_error(task_id, meta, verify)
|
||||
else:
|
||||
# 业务失败 → PR/Issue comment @assignee
|
||||
self._create_gitea_comment_for_business_failure(task_id, meta, verify, failure_count)
|
||||
```
|
||||
|
||||
**PR/Issue comment 内容**:
|
||||
|
||||
```
|
||||
@{assignee} 任务处理失败,需要你的支持
|
||||
|
||||
📋 原始事件:{event_type}
|
||||
❌ 失败原因:{verify.reason}
|
||||
📊 失败次数:第 {failure_count} 次
|
||||
|
||||
请检查并处理。完成后提交 action report。
|
||||
```
|
||||
|
||||
**为什么 @mention 而非新建 task**:
|
||||
- @mention 通过 §25 webhook 自然触发新 toolchain task,不多建一条路
|
||||
- Gitea comment 自带完整 PR/Issue 上下文,Agent 收到时能理解全貌
|
||||
- 人也能在 Gitea 上看到失败记录,天然审计
|
||||
|
||||
**失败上限**:同一事件 failure_count ≥ 3 时,升级为系统失败(创建 Gitea Issue 给庞统),避免无限循环。
|
||||
|
||||
#### 系统失败处理(Gitea Issue 给庞统)
|
||||
|
||||
spawner 错误(crash/timeout/max_retries)或业务失败连续 3 次,创建 Gitea Issue:
|
||||
|
||||
```python
|
||||
def _create_gitea_issue_for_system_error(self, task_id, meta, verify):
|
||||
"""创建 Gitea Issue 指派庞统排查"""
|
||||
repo = meta.get("context", {}).get("repo", "sanguo/sanguo_moziplus_v2")
|
||||
title = f"[toolchain] 系统错误排查: {meta.get('event_type', 'unknown')} ({task_id})"
|
||||
body = (
|
||||
f"## 系统错误\n\n"
|
||||
f"**Task ID**: {task_id}\n"
|
||||
f"**事件类型**: {meta.get('event_type', 'unknown')}\n"
|
||||
f"**失败原因**: {verify.reason}\n"
|
||||
f"**证据**: {verify.evidence}\n"
|
||||
f"**原始 assignee**: {meta.get('context', {}).get('assignee', 'unknown')}\n\n"
|
||||
f"## 排查方向\n"
|
||||
f"- 检查 spawner 日志\n"
|
||||
f"- 确认 Agent 是否正常运行\n"
|
||||
f"- 检查是否有系统性问题(API down / 配置错误 / 资源不足)\n"
|
||||
)
|
||||
# Gitea API 创建 Issue,指派 pangtong-fujunshi
|
||||
_create_gitea_issue(repo, title, body, assignee="pangtong-fujunshi")
|
||||
```
|
||||
|
||||
**为什么用 Gitea Issue**:
|
||||
- 系统问题需要排查和 tracking,Issue 有状态管理(open/closed)
|
||||
- Issue body 包含完整错误详情,便于事后 troubleshooting
|
||||
- 指派庞统后通过 issue_assigned webhook 自然触发 toolchain task
|
||||
|
||||
#### 基础设施失败处理(toolchain task 给姜维)
|
||||
|
||||
Gitea API 不可用或网络不通时,无法创建 PR comment 或 Issue。此时降级为直接创建 toolchain task:
|
||||
|
||||
```python
|
||||
def _create_infrastructure_task(self, task_id, meta, verify, error_detail):
|
||||
"""基础设施失败 → toolchain task 指派姜维"""
|
||||
_send_toolchain_task(
|
||||
to_agent="jiangwei-infra",
|
||||
title=f"[基础设施] Gitea 不可用导致 on_failure 降级: {task_id}",
|
||||
description=f"尝试处理 task {task_id} 失败时 Gitea API 不可用。\n错误: {error_detail}",
|
||||
event_type="infrastructure_failure",
|
||||
action_type="infrastructure_failure",
|
||||
steps=[
|
||||
"检查 Gitea 服务状态(http://192.168.2.154:3000)",
|
||||
"检查网络连通性",
|
||||
"Gitea 恢复后检查原始 task 状态并补处理",
|
||||
"提交 action report",
|
||||
],
|
||||
context_data={
|
||||
"original_task_id": task_id,
|
||||
"original_event_type": meta.get("event_type", ""),
|
||||
"gitea_error": error_detail,
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
**为什么不走 Gitea**:Gitea 本身就是问题源,调 Gitea API 创建 Issue 会再次失败。直接在 _toolchain DB 内创建 task 是最后的降级手段。
|
||||
|
||||
#### 三分路总结
|
||||
|
||||
```
|
||||
on_failure
|
||||
│
|
||||
├─ 系统错误(crash/timeout/max_retries/连续3次业务失败)?
|
||||
│ └─ Gitea API 可用?
|
||||
│ ├─ YES → 创建 Issue @pangtong-fujunshi → webhook → toolchain task
|
||||
│ └─ NO → _send_toolchain_task @jiangwei-infra(基础设施降级)
|
||||
│
|
||||
└─ 业务错误(no action_report)?
|
||||
└─ Gitea API 可用?
|
||||
├─ YES → PR/Issue comment @assignee → §25 webhook → toolchain task
|
||||
└─ NO → _send_toolchain_task @jiangwei-infra(基础设施降级)
|
||||
```
|
||||
|
||||
所有路径都在 toolchain 流程内闭环,Mail 不参与。
|
||||
|
||||
### 5.3 action_report comment 格式
|
||||
|
||||
@@ -670,11 +793,13 @@ async def _handle_pr_opened(payload: Dict[str, Any]) -> None:
|
||||
| `_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` 函数完全保留不变,只服务两个场景:
|
||||
`_send_mail` 函数只服务两个场景:
|
||||
1. PR 合并通知(inform 纯通知)
|
||||
2. ToolchainHandler on_failure 的 Mail 通知(通过 Mail API 发给庞统)
|
||||
2. Agent 间点对点通信(inform / request)
|
||||
|
||||
**toolchain on_failure 不调用 `_send_mail`**。失败处理三分路(PR comment / Gitea Issue / toolchain task)全在 toolchain 流程内闭环。
|
||||
|
||||
---
|
||||
|
||||
@@ -786,6 +911,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| `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`(on_failure) | 修改 | on_failure 三分路重写(去掉 Mail API 调用,改为 Gitea API + _send_toolchain_task) | +~40 行 |
|
||||
|
||||
### 改动量估算
|
||||
|
||||
@@ -811,6 +937,7 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
| Agent 间手动发 request Mail | ✅ 无影响 |
|
||||
| MailHandler 的 verify / on_failure | ✅ 无影响 |
|
||||
| `_send_mail` 函数 | ✅ 保留不变 |
|
||||
| ToolchainHandler on_failure 改为 Gitea 管理(PR comment / Issue / toolchain task),不经过 Mail API | ✅ 无影响 |
|
||||
|
||||
### 11.2 _mail DB 中已有的 toolchain task
|
||||
|
||||
@@ -905,6 +1032,21 @@ ticker 需要扫描 `_toolchain` 虚拟项目。当前 ticker 通过 `TaskTypeRe
|
||||
- action_report + verify 是更可靠的完成路径
|
||||
- 减少 Agent 需要执行的 API 操作(从"标 done + 提交产出"简化为"提交 action_report")
|
||||
|
||||
### D17-8: on_failure 走 Gitea 管理,不走 Mail
|
||||
|
||||
**决策**:toolchain 失败处理三分路——业务失败在 PR/Issue comment @assignee,系统失败创建 Gitea Issue @pangtong-fujunshi,基础设施失败创建 toolchain task @jiangwei-infra。三条路全在 toolchain 流程内,Mail 不参与。
|
||||
|
||||
**讨论的替代方案**:
|
||||
- A(Mail API 通知庞统):跨系统,回溯需要在 _mail 和 _toolchain 两个 DB 之间跳
|
||||
- B(on_failure 直接创建新 _toolchain task):强约束语义不对,失败应该是协作求助而非又一个强制任务
|
||||
- C(只记日志 + 前端告警):system comment 没人主动看,等于没人管
|
||||
|
||||
**理由**:
|
||||
- 错误分类后路由到不同处理方式,比统一通知更精准
|
||||
- Gitea Issue/PR comment 是天然的管理和审计工具,人也能看到
|
||||
- §25 @mention webhook 已有端到端集成,comment 创建后自然触发新 toolchain task,管道复用
|
||||
- Mail 只服务 Agent 间点对点通信和 PR 合并通知,职责清晰
|
||||
|
||||
---
|
||||
|
||||
## §13. 实施计划
|
||||
|
||||
Reference in New Issue
Block a user