Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7a2505b137 | |||
| c2e710bf67 | |||
| d2e449bca8 |
@@ -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) | — | — |
|
||||
|
||||
Reference in New Issue
Block a user