Merge PR #113
Deploy / ci (push) Failing after 18s
Deploy / deploy (push) Has been skipped
Deploy / notify-deploy-failure (push) Successful in 2s
Deploy / notify-deploy-success (push) Successful in 0s

This commit was merged in pull request #113.
This commit is contained in:
2026-06-21 15:04:35 +00:00
2 changed files with 48 additions and 3 deletions
+41 -3
View File
@@ -219,7 +219,7 @@ def _toolchain_db_path() -> Path:
def _send_toolchain_task(
to_agent: str,
to_agent: str | None,
title: str,
description: str,
event_type: str,
@@ -231,7 +231,7 @@ def _send_toolchain_task(
"""创建 Toolchain Task 并写入 _toolchain DB。
Args:
to_agent: 收件人 Agent ID
to_agent: 收件人 Agent ID,None 表示无指派(待路由/delegate)
title: 任务标题
description: 任务描述(模板渲染后的事件信息)
event_type: 事件类型(review_result / ci_failure / ...
@@ -243,7 +243,7 @@ def _send_toolchain_task(
Returns:
创建的 Task ID
"""
if to_agent not in AGENT_IDS:
if to_agent is not None and to_agent not in AGENT_IDS:
logger.warning("Unknown agent: %s, skipping toolchain task", to_agent)
return ""
@@ -1106,6 +1106,44 @@ async def _handle_issues(payload: Dict[str, Any]) -> None:
)
elif action == "opened":
# §11b: 无 assignee 的普通 Issue → discussion task
assignees = issue.get("assignees") or []
single_assignee = issue.get("assignee")
if single_assignee and isinstance(single_assignee, dict) and single_assignee not in assignees:
assignees = list(assignees) + [single_assignee]
if not assignees and not ("部署失败" in issue_title):
# 无 assignee + 非部署失败 → 检查是否有 type/* label
labels_list_opened = [
lbl.get("name", "") for lbl in (issue.get("labels") or [])
]
has_type_label = any(
lbl.lower().startswith("type/") for lbl in labels_list_opened
)
if has_type_label:
issue_body = issue.get("body", "") or "(无描述)"
title_discussion = f"Issue 讨论: {issue_title} ({repo}#{issue_number})"
_send_toolchain_task(
to_agent=None, # 无指派 → router delegate 庞统
title=title_discussion,
description=f"## Issue 需要讨论\n\n"
f"**{repo}#{issue_number}**: {issue_title}\n\n"
f"{issue_body}",
event_type="issue_discussion",
action_type="issue_discussion",
steps=[], # discussion 不需要结构化步骤
context_data={
"issue_number": issue_number,
"repo": repo,
"issue_title": issue_title,
"issue_body": issue_body,
},
)
logger.info(
"Issue #%s: no assignee + type label → discussion task",
issue_number)
# discussion task 创建后继续检查 @mention(不 return
if "部署失败" in issue_title:
# 从 Issue body 提取 commit hashGitea deploy workflow 格式)
sha_match = re.search(r'[0-9a-f]{40}', issue.get("body", ""))
+7
View File
@@ -34,6 +34,8 @@ _ACTION_HINTS: Dict[str, str] = {
"review_comment": "你收到一个 Review 评论,这是一个需要你查看并响应的事件。",
"ci_failure": "你收到一个 CI 失败通知,这是一个需要你修复失败测试的事件。",
"issue_assigned": "你收到一个 Issue 指派,这是一个需要你编码实现的事件。",
"issue_closed": "你收到一个 Issue 关闭通知。这是一条纯通知,阅读即可。",
"issue_discussion": "你收到一个需要讨论的 Issue。请阅读 Issue 内容,发起讨论并引导其他 agent 参与。",
"deploy_failure": "你收到一个部署失败通知,这是一个需要你排查并修复的事件。",
"mention": "你收到一个 @mention 通知,这是一个需要你按指引响应的事件。",
"review_merged": "你收到一个 PR 合并通知。这是一条纯通知,阅读即可。",
@@ -336,6 +338,11 @@ class ToolchainHandler(BaseTaskHandler):
return VerifyResult(True, "issue_closed_passthrough",
"issue_closed auto-pass")
# 特殊处理:issue_discussion 始终通过(触发 delegate 庞统 §21 §11b)
if meta.get("action_type") == "issue_discussion":
return VerifyResult(True, "discussion_passthrough",
"issue_discussion auto-pass")
# 1. 优先检查 action_report comment
report_row = conn.execute(
"SELECT id FROM comments WHERE task_id=? "