fix: S1-S3 review suggestions — type annotations unified, urllib replaces curl, rich notification content
CI / lint (pull_request) Failing after 6s
CI / test (pull_request) Has been skipped
CI / notify-on-failure (pull_request) Successful in 2s

This commit is contained in:
cfdaily
2026-06-10 21:44:47 +08:00
parent 1b0007f244
commit 4a4e99f738
2 changed files with 74 additions and 24 deletions
+2 -2
View File
@@ -7,7 +7,7 @@ from __future__ import annotations
import json import json
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Dict, List, Optional from typing import Dict, Optional
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
from src.daemon.prompt_composer import PromptComposer, PromptContext from src.daemon.prompt_composer import PromptComposer, PromptContext
@@ -34,7 +34,7 @@ class MailHandler(BaseTaskHandler):
composer.add_many(self.get_sections()) composer.add_many(self.get_sections())
return composer.compose(context) return composer.compose(context)
def get_sections(self) -> List: def get_sections(self) -> list:
return [MailContextSection(), MailApiSection(), MailConstraintsSection()] return [MailContextSection(), MailApiSection(), MailConstraintsSection()]
def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult: def verify_completion(self, task_id: str, db_path: Path) -> VerifyResult:
+72 -22
View File
@@ -6,9 +6,9 @@ from __future__ import annotations
import json import json
import logging import logging
import subprocess import urllib.request
from pathlib import Path from pathlib import Path
from typing import Dict, List from typing import Dict
from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult from src.daemon.base_task_handler import BaseTaskHandler, VerifyResult
from src.daemon.prompt_composer import PromptComposer, PromptContext from src.daemon.prompt_composer import PromptComposer, PromptContext
@@ -129,7 +129,7 @@ class ToolchainHandler(BaseTaskHandler):
"""auto_workingpending → working""" """auto_workingpending → working"""
return self._auto_mark_working(task_id, db_path) return self._auto_mark_working(task_id, db_path)
def get_sections(self) -> List: def get_sections(self) -> list:
"""返回 3 个 Toolchain PromptSection 实例""" """返回 3 个 Toolchain PromptSection 实例"""
return [ return [
ToolchainContextSection(), ToolchainContextSection(),
@@ -176,31 +176,81 @@ class ToolchainHandler(BaseTaskHandler):
"""验证失败 → 标 failed + Mail API 通知主公""" """验证失败 → 标 failed + Mail API 通知主公"""
self._mark_task_status(db_path, task_id, "failed") self._mark_task_status(db_path, task_id, "failed")
logger.info("Toolchain %s: verify failed (%s), marked failed", task_id, verify.reason) logger.info("Toolchain %s: verify failed (%s), marked failed", task_id, verify.reason)
self._notify_via_mail_api(task_id, verify.reason, verify.evidence)
def _notify_via_mail_api(self, task_id: str, reason: str, evidence: str) -> None: # 从 db 读取事件上下文
"""通过 Mail API 发通知给主公""" event_type = ""
event_data: Dict = {}
try:
conn = get_connection(db_path)
row = conn.execute(
"SELECT must_haves FROM tasks WHERE id=?", (task_id,)
).fetchone()
if row and row["must_haves"]:
meta = json.loads(row["must_haves"])
event_type = meta.get("event_type", "")
raw = meta.get("event_data", "{}")
event_data = json.loads(raw) if isinstance(raw, str) else raw
conn.close()
except Exception:
pass
self._notify_via_mail_api(
task_id, verify.reason, verify.evidence,
event_type, event_data,
)
def _notify_via_mail_api(
self,
task_id: str,
reason: str,
evidence: str,
event_type: str,
event_data: Dict,
) -> None:
"""通过 Mail API 发送丰富的失败通知给主公。"""
# 构建行动指引
action_hint = "请检查黑板任务并手动处理。"
et_lower = event_type.lower()
if "ci" in et_lower or "deploy" in et_lower:
action_hint = "建议创建任务派给 jiangwei-infra 检查 CI/部署问题。"
elif "review" in et_lower:
action_hint = "建议查看 PR review 状态,必要时通知相关开发者。"
elif "issue" in et_lower:
action_hint = "建议创建任务派给对应开发者处理 Issue。"
# 构建事件详情
event_details = ""
if event_data:
event_details = "\n".join(
f" - {k}: {v}" for k, v in event_data.items()
)
title = f"[toolchain-handler] 工具链事件处理失败: {task_id}"
text = (
f"任务 {task_id} 验证失败\n\n"
f"事件类型: {event_type or '未知'}\n"
f"事件详情:\n{event_details or ' (无)'}\n\n"
f"失败原因: {reason}\n"
f"证据: {evidence}\n\n"
f"黑板任务: http://localhost:8083/ → 项目 _toolchain → 任务 {task_id}\n\n"
f"行动指引: {action_hint}"
)
payload = json.dumps({ payload = json.dumps({
"from": "daemon", "from": "daemon",
"to": "pangtong-fujunshi", "to": "pangtong-fujunshi",
"title": f"工具链事件处理失败: {task_id}", "title": title,
"text": ( "text": text,
f"任务 {task_id} 验证失败: {reason}\n"
f"证据: {evidence}\n\n请人工检查。"
),
"type": "inform", "type": "inform",
}, ensure_ascii=False) }, ensure_ascii=False).encode("utf-8")
try: try:
subprocess.run( req = urllib.request.Request(
[ "http://localhost:8083/api/mail",
"curl", "-s", "-X", "POST", data=payload,
"http://localhost:8083/api/mail", headers={"Content-Type": "application/json"},
"-H", "Content-Type: application/json",
"-d", payload,
],
timeout=5,
capture_output=True,
) )
logger.info("Toolchain %s: sent failure notification to pangtong-fujunshi via Mail API", task_id) urllib.request.urlopen(req, timeout=5)
logger.info("Toolchain %s: sent failure notification via Mail API", task_id)
except Exception as e: except Exception as e:
logger.warning("Toolchain %s: failed to notify via Mail API: %s", task_id, e) logger.warning("Toolchain %s: failed to notify via Mail API: %s", task_id, e)