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:
知微
2026-06-24 20:26:47 +08:00
parent 4407f35027
commit 26993c1d41
+67 -12
View File
@@ -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.jsonprofile环境下解析到 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 写入失败不阻碍体检主流程