@@ -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 hash(Gitea deploy workflow 格式)
|
||||
sha_match = re.search(r'[0-9a-f]{40}', issue.get("body", ""))
|
||||
|
||||
@@ -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=? "
|
||||
|
||||
Reference in New Issue
Block a user