From d2e449bca86791fd218113f1135906df735040f4 Mon Sep 17 00:00:00 2001 From: cfdaily Date: Mon, 22 Jun 2026 20:28:44 +0800 Subject: [PATCH] =?UTF-8?q?[moz]=20docs(=C2=A722):=20v1.1=20=E8=BD=BB?= =?UTF-8?q?=E9=87=8F=E8=B7=AF=E5=BE=84=E8=AE=BE=E8=AE=A1=20+=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=B5=81=E6=BE=84=E6=B8=85=20+=20=E7=BC=96=E5=8F=B7?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/design/22-end-to-end-flow.md | 173 +++++++++++++++++++++++++++--- 1 file changed, 159 insertions(+), 14 deletions(-) diff --git a/docs/design/22-end-to-end-flow.md b/docs/design/22-end-to-end-flow.md index 4d2f250..132d84d 100644 --- a/docs/design/22-end-to-end-flow.md +++ b/docs/design/22-end-to-end-flow.md @@ -1,9 +1,10 @@ --- title: "End-to-End Flow — 端到端任务流程设计" created: 2026-06-22 -version: v1.0 +version: v1.1 status: draft -changelog: v1.0 初版 +changelog: v1.1 补充轻量路径设计(§22.6)、数据流澄清(§22.7)、修正设计原则3、统一Phase编号、Phase 1标注 + v1.0 初版 --- # End-to-End Flow — 端到端任务流程设计 @@ -23,17 +24,16 @@ Phase 1: Discussion 广播(所有空闲 agent) ↓ agent 在 Gitea Issue comment 讨论 → 创建 sub Issue(assign 自己) Phase 2: sub Issue assigned → executor 分派 ↓ webhook: issues/assigned -Phase 3: 编码 + PR 创建 +Phase 3: 编码 + PR + CI ↓ webhook: pull_request/opened → CI 自动触发 -Phase 4: CI 检查 ↓ CI 通过 → 等 Review / CI 失败 → agent 修复 → 重跑 -Phase 5: Review(司马懿) +Phase 4: Review(司马懿) ↓ APPROVED → 通知 agent 合并 / REQUEST_CHANGES → agent 修改 → 回 Phase 3 -Phase 6: Merge + sub Issue 自动关闭 +Phase 5: Merge + sub Issue 自动关闭 ↓ webhook: pull_request/closed(merged) -Phase 7: Round Review(庞统三问) +Phase 6: Round Review(庞统三问) ↓ GOAL_ACHIEVED → 关闭 parent / 需要新轮 → 创建新 sub → 回 Phase 2 -Phase 8: parent Issue 关闭 +Phase 7: parent Issue 关闭 ↓ webhook: issues/closed ``` @@ -41,7 +41,7 @@ Phase 8: parent Issue 关闭 1. **协作面是 Gitea**(Issue/PR comment),不是黑板 DB 2. **每个 Phase 有明确的前置条件和产出**,前一步未完成则后续不触发 -3. **daemon 通过 webhook 感知状态变化**,不依赖 ticker 轮询(ticker 只负责 broadcast 和 review 检测) +3. **webhook 和 ticker 协同**——webhook 负责事件感知和 task 创建,ticker 负责广播调度(Phase 1)和聚合检测(Phase 6) 4. **agent 在 Gitea 留痕**(Issue comment、PR、Review),黑板 DB 只存 daemon 内部状态 --- @@ -76,7 +76,7 @@ Gitea: Issue created (no assignee, label type/feat) | 维度 | 内容 | |------|------| | **触发** | ticker 30s 扫到 Phase 0 创建的 pending task | -| **daemon 函数** | `ticker._dispatch_pending` → `dispatcher.decide` → `_broadcast_claim` | +| **daemon 函数** | `ticker._dispatch_pending` → `dispatcher.decide` → `_broadcast_claim`。⚠️ 当前 broadcast 使用 claim prompt(黑板 API)而非 discussion prompt,P0 修复后改为 discussion broadcast | | **daemon 行为** | assignee=None → router 返回 mode=delegate → ticker 归入 broadcast_tasks → 广播给所有空闲 agent | | **prompt 来源(设计期望)** | `discussion prompt`(§13.2):你是谁 + 你必须做什么(4 维度)+ Gitea API + Boids 行为准则 | | **agent 行为(设计期望)** | 每个 agent 在 **Gitea Issue** comment(角色名开头,4 维度回应);需要参与的 agent 创建 sub Issue(Gitea API,assign 自己);在 parent Issue comment 注册 sub | @@ -112,9 +112,9 @@ Gitea: Issue created (no assignee, label type/feat) - 创建 sub Issue: POST /repos/{repo}/issues ``` -**Phase 1 的结束条件**: +**Phase 1 的结束条件**(⚠️ 设计目标,检测逻辑待实现): -- 所有被广播的 agent 都已 comment(或 NO_REPLY) +- 所有被广播的 agent 都已 comment(或 NO_REPLY)——daemon 需维护"已回复 agent"集合,当前无此机制 - 至少有一个 agent 创建了 sub Issue - 如果没有任何 agent 创建 sub Issue → ticker 升级庞统(3 轮无 taker 机制) @@ -147,7 +147,7 @@ issue_assigned: --- -### Phase 3: PR 创建 + CI 触发 +### Phase 3: 编码 + PR + CI | 维度 | 内容 | |------|------| @@ -255,6 +255,151 @@ issue_assigned: |--------|------|---------|---------| | **P0** | Phase 1 discussion broadcast | **核心断裂**。整个 Gitea Issue 流程退化成黑板 claim 模式 | ticker `_broadcast_claim` 中判断 `action_type=issue_discussion` → 调用 discussion prompt(Gitea API 版本)而非 claim prompt | | **P1** | Phase 5 PR body Closes #N | sub Issue 不自动关闭 | Phase 2 executor prompt 中已有 Closes #N 约束(YAML steps),Phase 1 修好后自然解决 | -| **P2** | Phase 6 Round Review Gitea 适配 | 无法触发庞统三问 | `_check_round_complete` 改为扫 Gitea parent/sub Issue 映射(通过 `task_state.parent_issue` 字段,§20 设计) | +| **P2** | Phase 6 Round Review Gitea 适配 | 无法触发庞统三问 | `_check_round_complete` 改为扫 Gitea parent/sub Issue 映射,详见 §22.7 数据流设计 | **关键结论**:P0 是唯一阻断点。修好 Phase 1 discussion broadcast 后,Phase 2-5 自然走通(已实现),Phase 6-7 后续跟进。 + +--- + +## §22.6 轻量路径设计(Direct Assignment) + +> 不是所有任务都需要 Discussion 广播。需求明确、单一执行者的任务应跳过 Phase 0/1 直接进入 Phase 2。 + +### 路径决策矩阵 + +| 条件 | 路径 | 流程 | +|------|------|------| +| Issue 无 assignee + type/* label | **Discussion 路径**(默认) | Phase 0 → 1 → 2 → … | +| Issue 有 assignee | **Direct 路径** | → Phase 2(跳过 Phase 0/1) | +| Issue 有 `flow/direct` label | **强制 Direct** | → Phase 2(即使无 assignee,daemon 自动 assign) | +| Issue 有 `flow/discuss` label | **强制 Discussion** | Phase 0 → 1 → 2 → …(即使有 assignee) | + +### 判断逻辑 + +``` +parent Issue 创建 + ├─ 有 flow/discuss label?→ Discussion 路径(Phase 0 → 1) + ├─ 有 flow/direct label?→ Direct 路径(daemon 自动 assign → Phase 2) + ├─ 有 assignee?→ Direct 路径(→ Phase 2) + └─ 无 assignee(默认)→ Discussion 路径(Phase 0 → 1) +``` + +优先级:`flow/*` label > assignee > 默认行为。 + +### 适用场景 + +| 路径 | 适用场景 | 示例 | +|------|---------|------| +| Discussion | 需求不明确、需要多角色讨论、跨模块协作 | 新功能设计、架构变更、涉及 3+ agent 的任务 | +| Direct | 需求明确、单一执行者、小范围改动 | Bug 修复、文档更新、配置调整、单人任务 | + +### Discussion 路径中的降级 + +Discussion 进行中,如果所有 agent 都认为任务足够简单只涉及一个角色,任何 agent 可以在 comment 中建议: + +``` +@pangtong-fujunshi 建议直接指派 @agent-id,理由:... +``` + +庞统判断后创建 sub Issue 直接 assign → 该 agent 跳过讨论直接进入 Phase 2。 + +### Direct 路径跳过的 Phase + +| Phase | 是否跳过 | 原因 | +|-------|---------|------| +| Phase 0(parent Issue 讨论 task) | ✅ 跳过 | 不创建 discussion task | +| Phase 1(Discussion 广播) | ✅ 跳过 | 不广播,不打扰其他 agent | +| Phase 2(assigned → executor) | ❌ 直接进入 | 起点 | + +### 对现有代码的影响 + +当前 `_handle_issues` 已有两个分支: + +- `opened`(无 assignee + type/* label)→ discussion task ← Discussion 路径 ✅ +- `assigned`(有 assignee)→ executor task ← Direct 路径 ✅ + +**轻量路径的后端已实现**。需要补充的是: + +1. `flow/direct` 和 `flow/discuss` label 的识别逻辑(`toolchain_routes.py` `_handle_issues` opened 分支) +2. Discussion prompt 中告知 agent 可以建议 direct assignment(降级机制) + +--- + +## §22.7 数据流设计澄清 + +> 本文档涉及两个数据源(黑板 DB 和 Gitea Issue),parent/sub 映射的数据流必须明确。 + +### 当前状态 vs 设计目标 + +| 数据 | 当前存储 | §20/§21 设计目标 | 差距 | +|------|---------|-----------------|------| +| 协作面(title/body/comment) | 黑板 DB tasks/comments 表 | Gitea Issue/PR | ❌ Phase 1 断裂导致 agent 用黑板 API | +| parent/sub 映射 | `tasks.parent_task`(黑板字段) | `task_state.parent_issue`(新表) | ❌ task_state 表不存在 | +| 执行状态 | 黑板 DB tasks.status | task_state.status | ❌ task_state 表不存在 | +| 成果物 | 黑板 DB outputs 表 | git commit + PR | ⚠️ 需 prompt 引导 | + +### parent/sub Issue 映射数据流(设计) + +``` +Agent 在 Phase 1 创建 sub Issue: + POST /repos/{repo}/issues + title: "[moz][sub][parent #{N}] 任务名" + assignees: ["{agent_id}"] + ↓ +Gitea webhook: issues/opened (with assignee) + ↓ +daemon: _handle_issues → assigned 分支 + → 解析标题 [parent #{N}] → 提取 parent_issue_number + → 写入 task_state (issue_number, parent_issue=N, status='pending') + ↓ +ticker: _check_round_complete + → SELECT DISTINCT parent_issue FROM task_state WHERE parent_issue IS NOT NULL + → 对每个 parent_issue: SELECT status FROM task_state WHERE parent_issue=? + → 全部终态 → spawn 庞统 review +``` + +### 前置条件 + +1. **task_state 表创建**:§20 设计了 DDL 但未实现。需要先建表: + + ```sql + CREATE TABLE task_state ( + issue_number INTEGER PRIMARY KEY, + repo TEXT, + parent_issue INTEGER, + status TEXT DEFAULT 'pending', + action_type TEXT, + retry_count INTEGER DEFAULT 0, + dispatch_count INTEGER DEFAULT 0, + round_count INTEGER DEFAULT 0, + created_at TEXT, + updated_at TEXT + ); + CREATE INDEX idx_task_state_parent ON task_state(parent_issue); + ``` + +2. **parent_issue 解析**:daemon 在 `_handle_issues` 中解析标题 `[parent #{N}]` 模式,写入 `task_state.parent_issue`(§21 §14b L920 已有此设计)。 + +3. **_check_round_complete 改造**:从扫 `tasks.parent_task`(黑板)改为扫 `task_state.parent_issue`(toolchain DB)(§21 §16.2 L1148 已有此设计)。 + +### 混合期处理 + +task_state 表创建前,`_check_round_complete` 仍扫 `tasks.parent_task`。两种数据可以共存: + +- **黑板路径**(Phase 1 断裂时):agent 通过黑板 API 认领 → `tasks.parent_task` 有值 +- **Gitea 路径**(Phase 1 修复后):agent 创建 sub Issue → `task_state.parent_issue` 有值 + +`_check_round_complete` 需要同时扫两个源,直到黑板路径完全废弃。 + +### 各 Phase 数据读写汇总 + +| Phase | daemon 写 | daemon 读 | agent 读 | agent 写 | +|-------|----------|----------|----------|----------| +| 0 | toolchain DB: task(pending, action_type=issue_discussion) | Gitea webhook payload | — | — | +| 1 | toolchain DB: broadcast log | toolchain DB: pending tasks | Gitea Issue body | Gitea Issue comment + sub Issue | +| 2 | toolchain DB: task(pending, action_type=issue_assigned) | Gitea webhook payload, toolchain-templates.yaml | Gitea Issue body | git branch + PR | +| 3 | toolchain DB: task(review_request/ci_failure) | Gitea webhook (PR opened, CI status) | Gitea PR + CI logs | git push (修复) | +| 4 | toolchain DB: task(review_result_*) | Gitea webhook (pull_request_review) | Gitea PR diff + files | Gitea Review API | +| 5 | toolchain DB: task(review_merged) | Gitea webhook (PR closed/merged) | — | — | +| 6 | task_state: round_count++ | task_state: parent_issue + sub status | Gitea parent Issue body + sub Issue comments | Gitea Issue comment(三问结论)+ 关闭/创建 Issue | +| 7 | toolchain DB: task(issue_closed) | Gitea webhook (issues/closed) | — | — |