From 526fcc4412551c159fbdcbd234301e078c361f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=A5=E5=BE=AE?= Date: Wed, 24 Jun 2026 21:38:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=89=A7=E8=A1=8C=E5=99=A8=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9B=B4=E6=8E=A5=E5=8F=91=E6=A0=B8=E5=BF=83=E7=BE=A4?= =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E8=B5=B0API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 执行器修不了→hermes send到核心群,知微在群里收到就处理 - Dad也在核心群,能看到 - 不发gateway API(上下文隔离,Dad看不到) - 无fix_action也走同一路径 --- scripts/morning_health_check.py | 2 +- scripts/self_todo_executor.py | 121 ++++++++++++++------------------ 2 files changed, 55 insertions(+), 68 deletions(-) diff --git a/scripts/morning_health_check.py b/scripts/morning_health_check.py index 8fb62a5..9c72767 100755 --- a/scripts/morning_health_check.py +++ b/scripts/morning_health_check.py @@ -673,7 +673,7 @@ def main(): if entry["level"] in ("critical", "error"): print(f" [{entry['level'].upper()}] {entry['category']}: {entry['msg']}") - # 检查是否有 needs_llm 的 TODO(执行器尝试失败,需知微介入) + # 检查是否有执行器升级来的TODO(通知失败挂起的) try: conn2 = sqlite3.connect(str(DB_PATH)) needs_llm = conn2.execute( diff --git a/scripts/self_todo_executor.py b/scripts/self_todo_executor.py index 841b5aa..364242f 100644 --- a/scripts/self_todo_executor.py +++ b/scripts/self_todo_executor.py @@ -1,53 +1,30 @@ #!/usr/bin/env python3 """self_todo_executor.py — TODO自动执行器 (no_agent模式) -每10分钟轮询mofin.db中todos表的pending任务,执行fix_action命令。 -没有"blocked"状态。能修就修,修不了留着等明天体检再说。 -纯代码逻辑,不调LLM。 +每10分钟轮询pending TODOs,执行fix_action。 +成功→completed。失败→直接调Hermes Gateway让知微处理。 """ -import json, os, sqlite3, subprocess, sys, time +import json, sqlite3, subprocess, time, urllib.request from pathlib import Path from datetime import datetime BASE = Path("/home/hmo/MoFin") DB_PATH = BASE / "data" / "mofin.db" - - -def get_conn(): - conn = sqlite3.connect(str(DB_PATH)) - conn.row_factory = sqlite3.Row - return conn - - -def execute_fix(fix_action): - """执行修复命令,返回 (ok, output)""" - if not fix_action: - return False, "无修复命令" - try: - r = subprocess.run( - fix_action, - shell=True, capture_output=True, text=True, timeout=60 - ) - if r.returncode == 0: - return True, r.stdout.strip()[:300] or "ok" - else: - return False, f"exit={r.returncode}: {r.stderr.strip()[:300]}" - except subprocess.TimeoutExpired: - return False, "执行超时(60s)" - except Exception as e: - return False, str(e)[:200] +GATEWAY_URL = "http://localhost:8643/v1/chat/completions" +GATEWAY_KEY = "hermes123" +COREGROUP = "coregroup@conference.yoin.fun" def main(): start = time.time() - conn = get_conn() + conn = sqlite3.connect(str(DB_PATH)) + conn.row_factory = sqlite3.Row rows = conn.execute( - "SELECT id, title, fix_action, retry_count, max_retries FROM todos " - "WHERE status='pending' ORDER BY " - "CASE priority WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, " - "created_at ASC LIMIT 5" + "SELECT id, title, fix_action FROM todos WHERE status='pending' " + "ORDER BY CASE priority WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, " + "created_at ASC LIMIT 3" ).fetchall() if not rows: @@ -55,49 +32,59 @@ def main(): print("[SILENT] 无待处理TODO") return - results = [] for row in rows: - todo_id = row["id"] + tid = row["id"] title = row["title"] - fix_action = row["fix_action"] + fix = row["fix_action"] - if not fix_action: - conn.execute( - "UPDATE todos SET status='needs_llm', note='无fix_action需人工分析', " - "updated_at=CURRENT_TIMESTAMP WHERE id=?", (todo_id,)) - results.append(("🔶", f"{title}: 需知微分析(无修复方案)")) - conn.commit() - continue - - # 执行(只试一次,失败立即升级) - conn.execute( - "UPDATE todos SET status='in_progress', updated_at=CURRENT_TIMESTAMP WHERE id=?", - (todo_id,)) + conn.execute("UPDATE todos SET status='in_progress' WHERE id=?", (tid,)) conn.commit() - ok, output = execute_fix(fix_action) - if ok: - conn.execute( - "UPDATE todos SET status='completed', note=?, " - "updated_at=CURRENT_TIMESTAMP WHERE id=?", - (f"已修复: {output[:200]}", todo_id)) - results.append(("✅", f"{title}: 已修复")) + if not fix: + msg = f"[自愈执行器] 需处理: {title} (无自动修复方案)" else: - conn.execute( - "UPDATE todos SET status='needs_llm', note=?, " - "updated_at=CURRENT_TIMESTAMP WHERE id=?", - (f"执行失败: {output[:200]}", todo_id)) - results.append(("🔶", f"{title}: 需知微介入({output[:60]})")) + # 执行修复命令 + try: + r = subprocess.run(fix, shell=True, capture_output=True, text=True, timeout=30) + if r.returncode == 0: + conn.execute("UPDATE todos SET status='completed', note=? WHERE id=?", + (f"已修复: {r.stdout.strip()[:200]}", tid)) + conn.commit() + print(f" ✅ {title}: 已修复") + continue + output = r.stderr.strip()[:200] or r.stdout.strip()[:200] + except subprocess.TimeoutExpired: + output = "执行超时" + except Exception as e: + output = str(e)[:200] + msg = f"需处理: {title} (尝试失败: {output})" + + # 修复失败→发到核心群让知微处理(知微在群里,我收到了就处理) + try: + # 用hermes send发到核心群 + send_cmd = ["hermes", "send", "--to", f"xmpp:{COREGROUP}", msg] + r = subprocess.run(send_cmd, capture_output=True, text=True, timeout=30) + if r.returncode == 0: + conn.execute("UPDATE todos SET status='completed', note='已发到核心群通知知微' WHERE id=?", + (tid,)) + print(f" 🔶 {title}: 已发到核心群") + else: + conn.execute("UPDATE todos SET status='pending', note=? WHERE id=?", + (f"发核心群失败: {r.stderr[:100]}", tid)) + print(f" ⚠️ {title}: 发核心群失败({r.stderr[:60]})") + except Exception as e: + conn.execute("UPDATE todos SET status='pending', note=? WHERE id=?", + (f"发核心群异常: {str(e)[:100]}", tid)) + print(f" ⚠️ {title}: 发核心群异常({str(e)[:60]})") conn.commit() conn.close() - - elapsed = time.time() - start - if results: - print(f"自愈执行器 | {datetime.now().strftime('%H:%M')} | {len(results)}条 ({elapsed:.0f}s)") - for icon, msg in results: - print(f" {icon} {msg}") + + if rows: + print(f"自愈执行器 | {datetime.now().strftime('%H:%M')} | {len(rows)}条 ({time.time()-start:.0f}s)") + else: + print("[SILENT] 无待处理TODO") if __name__ == "__main__":