From 26993c1d415b0cfeeb1d17493d2fd5afd5b3c4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Wed, 24 Jun 2026 20:26:47 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=81=A5=E5=BA=B7=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E2=86=92=E8=87=AA=E5=8A=A8=E4=BF=AE=E5=A4=8D=E2=86=92TODO?= =?UTF-8?q?=E4=B8=89=E7=BA=A7=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 auto_fix_issue(): 可自动修复的问题直接修复(汇率缓存/价格事件) - 修复后的问题不写TODO,只有不可自动修复的才进TODO系统 - 修复 checklist 中港股汇率缓存路径(profile环境~解析差异) - 输出增加🛠️自动修复和📋TODO写入摘要 处理流程: 可自动修复(汇率刷新等)→ 立即修复,报告标记✅ 需人工/复杂修复(cron错误/delivery配置)→ 写入TODO TODO由self-todo cron在下一窗口(9:00/11:00/14:00等)处理 --- scripts/morning_health_check.py | 79 ++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/scripts/morning_health_check.py b/scripts/morning_health_check.py index 3a9318e..53ffc24 100755 --- a/scripts/morning_health_check.py +++ b/scripts/morning_health_check.py @@ -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 写入失败不阻碍体检主流程