fix: 健康检查→自动修复→TODO三级处理
- 新增 auto_fix_issue(): 可自动修复的问题直接修复(汇率缓存/价格事件) - 修复后的问题不写TODO,只有不可自动修复的才进TODO系统 - 修复 checklist 中港股汇率缓存路径(profile环境~解析差异) - 输出增加🛠️自动修复和📋TODO写入摘要 处理流程: 可自动修复(汇率刷新等)→ 立即修复,报告标记✅ 需人工/复杂修复(cron错误/delivery配置)→ 写入TODO TODO由self-todo cron在下一窗口(9:00/11:00/14:00等)处理
This commit is contained in:
@@ -40,17 +40,75 @@ HERMES_CRON_DIR = Path("/home/hmo/.hermes/profiles/position-analyst/cron")
|
||||
TODO_PATH = Path("/home/hmo/.hermes/profiles/position-analyst/todo.json")
|
||||
|
||||
|
||||
def auto_fix_issue(issue):
|
||||
"""对明确可自动修复的问题执行修复,返回 (fixed, fix_msg)"""
|
||||
item_id = issue.get("detail", "")
|
||||
msg = issue.get("msg", "")
|
||||
|
||||
# 港股汇率缓存缺失 → 生成
|
||||
if "港股汇率缓存" in msg and "missing" in msg:
|
||||
try:
|
||||
# hk_rate.py 写入 ~/.cache/hk_exchange_rate.json,profile环境下解析到 profile/home/.cache/
|
||||
r = subprocess.run(
|
||||
["python3", str(BASE / "hk_rate.py")],
|
||||
capture_output=True, text=True, timeout=15
|
||||
)
|
||||
if r.returncode == 0:
|
||||
return True, f"已自动刷新港股汇率缓存: {r.stdout.strip()}"
|
||||
else:
|
||||
return False, f"汇率刷新失败: {r.stderr[:100]}"
|
||||
except Exception as e:
|
||||
return False, f"汇率刷新异常: {e}"
|
||||
|
||||
# 价格监控今天无事件(交易日盘中)→ 检查进程
|
||||
if "价格监控" in msg and "0 rows" in msg:
|
||||
now = ctx["started_at"]
|
||||
if now.weekday() < 5 and 9 <= now.hour <= 15:
|
||||
# 交易时段,应该有事
|
||||
ok, detail = check_process("price_monitor")
|
||||
if not ok:
|
||||
return True, "已检测:price_monitor进程不存在(需人工介入)"
|
||||
return True, "已确认:price_monitor进程运行中,但今日无事件(可能无价格触发)"
|
||||
# 非交易时段→正常
|
||||
return True, "非交易时段无价格事件属正常"
|
||||
|
||||
# 其他问题→不可自动修复
|
||||
return False, "需人工处理"
|
||||
|
||||
|
||||
def write_todos_for_issues():
|
||||
"""将体检发现的异常写入 TODO 系统(去重、升级)"""
|
||||
"""将体检发现的异常写入 TODO 系统(去重、升级),先尝试自动修复"""
|
||||
try:
|
||||
if not ctx["report"]:
|
||||
return
|
||||
|
||||
# 只有 error/critical/warn 才写 TODO
|
||||
# 只有 error/critical/warn 才处理
|
||||
issues = [e for e in ctx["report"] if e["level"] in ("critical", "error", "warn")]
|
||||
if not issues:
|
||||
return
|
||||
|
||||
# 先尝试自动修复
|
||||
fixed_issues = []
|
||||
remaining = []
|
||||
for issue in issues:
|
||||
fixed, fix_msg = auto_fix_issue(issue)
|
||||
if fixed:
|
||||
fixed_issues.append((issue, fix_msg))
|
||||
log("ok", issue["category"], f"已自动修复: {fix_msg}", issue.get("detail",""))
|
||||
else:
|
||||
remaining.append(issue)
|
||||
|
||||
# 输出修复摘要
|
||||
if fixed_issues:
|
||||
print()
|
||||
print("🛠️ 自动修复:")
|
||||
for issue, fix_msg in fixed_issues:
|
||||
print(f" ✅ {issue['category']}: {fix_msg}")
|
||||
|
||||
# 剩余的无法自动修复的→写TODO
|
||||
if not remaining:
|
||||
return
|
||||
|
||||
# 读现有 TODO
|
||||
existing = []
|
||||
if TODO_PATH.exists():
|
||||
@@ -63,24 +121,16 @@ def write_todos_for_issues():
|
||||
todo_priority = {"critical": "high", "error": "medium", "warn": "low"}
|
||||
|
||||
new_items = []
|
||||
for issue in issues:
|
||||
for issue in remaining:
|
||||
title = f"[体检发现] {issue['msg']}"
|
||||
# 去重:检查是否已有相同 title 的 TODO
|
||||
# 去重
|
||||
if title in existing_titles:
|
||||
# 已有相同 TODO -> 升级
|
||||
for t in existing:
|
||||
if t.get("title") == title:
|
||||
if t.get("status") == "completed":
|
||||
# 昨天修了但今天还有问题 -> 重新打开并升级
|
||||
t["status"] = "pending"
|
||||
t["priority"] = todo_priority.get(issue["level"], "medium")
|
||||
t["note"] = f"重新打开: {ctx['started_at'].isoformat()}"
|
||||
elif t.get("status") == "pending":
|
||||
# 还是 pending -> 不重复写入
|
||||
pass
|
||||
elif t.get("status") == "in_progress":
|
||||
# 正在处理中 -> 不干扰
|
||||
pass
|
||||
continue
|
||||
|
||||
existing_titles.add(title)
|
||||
@@ -96,6 +146,11 @@ def write_todos_for_issues():
|
||||
if new_items:
|
||||
existing.extend(new_items)
|
||||
TODO_PATH.write_text(json.dumps(existing, ensure_ascii=False, indent=2))
|
||||
|
||||
print()
|
||||
print("📋 已加入TODO(待处理):")
|
||||
for item in new_items:
|
||||
print(f" [{item['priority']}] {item['title'][:70]}")
|
||||
except Exception as e:
|
||||
pass # TODO 写入失败不阻碍体检主流程
|
||||
|
||||
|
||||
Reference in New Issue
Block a user