feat: Step 5 引擎接入 + H1-H3/S3 修复 + 审计 D1/D2/D5 修复
CI / lint (pull_request) Failing after 7s
CI / test (pull_request) Has been skipped
CI / notify-on-failure (pull_request) Successful in 3s

引擎接入(dispatcher/spawner/ticker → handler 统一路由):
- dispatcher: guardrail/on_checks_passed/on_complete → handler 查询
- spawner: _build_prompt/_build_api_section → handler.build_prompt
- ticker: 虚拟项目扫描/assignee/claimed/review/幻觉门控 → handler 判断

Handler 缺陷修复:
- H1: _mark_task_status 加 3 次重试(防 DB 锁)
- H2: review @mention 加 comment_type='review'
- H3: review 非 approved 保持 review 状态(不标 working)
- S3: 通知链接改 Gitea(PR/Issue/Commit)

审计修复:
- D1: pre_spawn 返回值未检查 → 加 if not 抛 RuntimeError
- D2: PromptContext 缺 from_agent/mail_type → 从 must_haves 解析
- D5: _check_reply 查错表 → 恢复查 tasks 表找 in_reply_to

旧方法保留未删(deprecated),确认稳定后再清理。
This commit is contained in:
cfdaily
2026-06-10 22:33:03 +08:00
parent 2c970557c8
commit 8d72a1fa19
9 changed files with 648 additions and 173 deletions
+28 -25
View File
@@ -127,32 +127,35 @@ class BaseTaskHandler:
task_id, e)
def _mark_task_status(self, db_path: Path, task_id: str, status: str) -> None:
"""更新任务状态 + 写审计事件
从 dispatcher._mark_task_status 迁移。"""
try:
conn = get_connection(db_path)
"""更新任务状态 + 写审计事件(带 3 次重试,防 SQLite DB 锁)。"""
for attempt in range(3):
try:
conn.execute("BEGIN IMMEDIATE")
old_row = conn.execute(
"SELECT status FROM tasks WHERE id=?", (task_id,)
).fetchone()
old_status = old_row["status"] if old_row else "unknown"
conn.execute(
"UPDATE tasks SET status=?, updated_at=datetime('now') WHERE id=?",
(status, task_id),
)
conn.execute(
"INSERT INTO events (task_id, agent, event_type, payload) "
"VALUES (?, 'handler', 'status_change', ?)",
(task_id,
f'{{"from": "{old_status}", "to": "{status}", '
f'"source": "{self.task_type}_handler"}}'),
)
conn.commit()
finally:
conn.close()
except Exception as e:
logger.error("Task %s: mark status error: %s", task_id, e)
conn = get_connection(db_path)
try:
conn.execute("BEGIN IMMEDIATE")
old_row = conn.execute(
"SELECT status FROM tasks WHERE id=?", (task_id,)
).fetchone()
old_status = old_row["status"] if old_row else "unknown"
conn.execute(
"UPDATE tasks SET status=?, updated_at=datetime('now') WHERE id=?",
(status, task_id),
)
conn.execute(
"INSERT INTO events (task_id, agent, event_type, payload) "
"VALUES (?, 'handler', 'status_change', ?)",
(task_id,
f'{{"from": "{old_status}", "to": "{status}", '
f'"source": "{self.task_type}_handler"}}'),
)
conn.commit()
return
finally:
conn.close()
except Exception as e:
logger.warning("Handler: mark %s%s attempt %d failed: %s",
task_id, status, attempt + 1, e)
logger.error("Handler: mark %s%s all 3 attempts failed", task_id, status)
def _auto_mark_working(self, task_id: str, db_path: Path) -> bool:
"""pending → workingmail/toolchain 通用)。"""