auto-sync: 2026-05-29 01:12:43

This commit is contained in:
cfdaily
2026-05-29 01:12:43 +08:00
parent 6c2c60d734
commit d7079aa8a6
+168 -1
View File
@@ -363,9 +363,176 @@ class Ticker:
return refreshed
# ------------------------------------------------------------------
# 依赖推进
# 一轮结束检测 + 庞统 review (v2.9 #01)
# ------------------------------------------------------------------
MAX_ROUNDS = 5 # §4.5 防无限循环
async def _check_round_complete(self, db_path: Path,
project_id: str) -> List[str]:
"""检测 parent task 下所有 sub task 终态 → spawn 庞统 review
流程(§4.4):
1. 扫描所有 parent task
2. 对每个 parent 检查 sub task 是否全部终态
3. 检查 round_count 上限
4. increment round_count
5. spawn 庞统 review
"""
if not self.dispatcher or not self.spawner:
return []
bb = Blackboard(db_path)
reviewed: List[str] = []
# 找所有 parent task(有子 task 的)
conn = get_connection(db_path)
try:
parent_rows = conn.execute(
"SELECT DISTINCT parent_task FROM tasks WHERE parent_task IS NOT NULL"
).fetchall()
finally:
conn.close()
for row in parent_rows:
parent_id = row["parent_task"]
try:
summary = bb.get_subtasks_summary(parent_id)
if not summary or not summary["all_terminal"]:
continue
# 检查 parent 自身状态:只有 done 状态的 parent 才触发
# (聚合后 parent 状态为 done 说明所有 sub 都完了)
if summary["parent_status"] != "done":
continue
# 检查 round_count 上限
if summary["round_count"] >= self.MAX_ROUNDS:
logger.warning(
"Parent %s reached max rounds (%d), skipping review",
parent_id, self.MAX_ROUNDS)
continue
# 递增 round_count
new_round = bb.increment_round_count(parent_id)
# 构建庞统 review 上下文
outputs = bb.get_aggregate_outputs(parent_id)
comments = bb.get_round_comments(parent_id)
parent_task = bb.get_task(parent_id)
if not parent_task:
continue
# spawn 庞统 review
review_prompt = self._build_review_prompt(
parent_task, summary, outputs, comments, new_round
)
spawned = await self._spawn_pangtong_review(
parent_task, review_prompt, project_id
)
if spawned:
reviewed.append(parent_id)
logger.info(
"Round %d review spawned for parent %s (subs: %s)",
new_round, parent_id, summary
)
except Exception as e:
logger.exception("Round check error for parent %s", parent_id)
return reviewed
def _build_review_prompt(self, parent_task, summary: dict,
outputs: list, comments: list,
round_num: int) -> str:
"""构建庞统 review prompt(§4.2 三问框架)"""
goal = parent_task.description or parent_task.title
must_haves = parent_task.must_haves or "{}"
# 成果物摘要(限制 token
output_lines = []
for o in outputs[:20]: # 最多 20 个
output_lines.append(
f"- [{o.get('task_title', '?')}] {o.get('title', '?')} "
f"({o.get('output_type', '?')}) by {o.get('agent', '?')}"
)
# 讨论摘要(限制 50 条)
comment_lines = []
for c in comments[:50]:
comment_lines.append(
f"[{c.get('created_at', '?')[:16]}] {c.get('author', '?')}: {c.get('body', '?')[:200]}"
)
return f"""## 庞统 Review(第 {round_num} 轮)
### Goal
{goal}
### 验收标准
{must_haves}
### 本轮 Sub Task 状态
- 完成: {summary['done']}
- 失败: {summary['failed']}
- 取消: {summary['cancelled']}
- 总计: {summary['total']}
### 成果物
{chr(10).join(output_lines) if output_lines else ''}
### 黑板讨论
{chr(10).join(comment_lines) if comment_lines else ''}
### 三问
1. Goal 还清晰吗?(是否有 goal drift)
2. 成果物覆盖 goal 了吗?(逐条检查验收标准)
3. 下一轮需要做什么?(创建新 sub tasks / 标记完成 / 调整方向)
### 失败处理
{f'{summary["failed"]} 个 sub task failed,优先判断是应该重试、换人、还是调整方案。' if summary['failed'] > 0 else '无失败'}
### 你可以
- 创建新一轮 sub tasks(通过 API: POST /api/projects/{{pid}}/tasks
- 调整 goal(更新 parent task description/must_haves
- 标记完成(如果 goal 已达成,回复 GOAL_ACHIEVED
Round 上限: {self.MAX_ROUNDS}(当前第 {round_num} 轮)
"""
async def _spawn_pangtong_review(self, parent_task,
review_prompt: str,
project_id: str) -> bool:
"""Spawn 庞统进行 review"""
try:
agent_id = "pangtong-fujunshi"
session_id = f"review-{parent_task.id}-r{parent_task.round_count + 1}"
# 构建上下文
context = self.spawner.build_context(
agent_id=agent_id,
task_id=parent_task.id,
project_id=project_id,
)
# 拼接 prompt
full_prompt = f"{context}\n\n{review_prompt}"
# spawn
result = await self.spawner.spawn(
agent_id=agent_id,
session_id=session_id,
prompt=full_prompt,
project_id=project_id,
task_id=parent_task.id,
)
return result is not None
except Exception as e:
logger.exception("Failed to spawn pangtong review for %s", parent_task.id)
return False
def _advance_dependencies(self, db_path: Path) -> List[str]:
"""检查 blocked 任务,若所有依赖已完成则推进为 pending