fix: 执行器失败直接发核心群,不走API

- 执行器修不了→hermes send到核心群,知微在群里收到就处理
- Dad也在核心群,能看到
- 不发gateway API(上下文隔离,Dad看不到)
- 无fix_action也走同一路径
This commit is contained in:
知微
2026-06-24 21:38:36 +08:00
parent b766a5dbb1
commit 526fcc4412
2 changed files with 55 additions and 68 deletions
+1 -1
View File
@@ -673,7 +673,7 @@ def main():
if entry["level"] in ("critical", "error"): if entry["level"] in ("critical", "error"):
print(f" [{entry['level'].upper()}] {entry['category']}: {entry['msg']}") print(f" [{entry['level'].upper()}] {entry['category']}: {entry['msg']}")
# 检查是否有 needs_llm 的 TODO(执行器尝试失败,需知微介入 # 检查是否有执行器升级来的TODO(通知失败挂起的
try: try:
conn2 = sqlite3.connect(str(DB_PATH)) conn2 = sqlite3.connect(str(DB_PATH))
needs_llm = conn2.execute( needs_llm = conn2.execute(
+53 -66
View File
@@ -1,53 +1,30 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""self_todo_executor.py — TODO自动执行器 (no_agent模式) """self_todo_executor.py — TODO自动执行器 (no_agent模式)
每10分钟轮询mofin.db中todos表的pending任务,执行fix_action命令 每10分钟轮询pending TODOs,执行fix_action。
没有"blocked"状态。能修就修,修不了留着等明天体检再说 成功→completed。失败→直接调Hermes Gateway让知微处理
纯代码逻辑,不调LLM。
""" """
import json, os, sqlite3, subprocess, sys, time import json, sqlite3, subprocess, time, urllib.request
from pathlib import Path from pathlib import Path
from datetime import datetime from datetime import datetime
BASE = Path("/home/hmo/MoFin") BASE = Path("/home/hmo/MoFin")
DB_PATH = BASE / "data" / "mofin.db" DB_PATH = BASE / "data" / "mofin.db"
GATEWAY_URL = "http://localhost:8643/v1/chat/completions"
GATEWAY_KEY = "hermes123"
def get_conn(): COREGROUP = "coregroup@conference.yoin.fun"
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]
def main(): def main():
start = time.time() start = time.time()
conn = get_conn() conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
rows = conn.execute( rows = conn.execute(
"SELECT id, title, fix_action, retry_count, max_retries FROM todos " "SELECT id, title, fix_action FROM todos WHERE status='pending' "
"WHERE status='pending' ORDER BY " "ORDER BY CASE priority WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, "
"CASE priority WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END, " "created_at ASC LIMIT 3"
"created_at ASC LIMIT 5"
).fetchall() ).fetchall()
if not rows: if not rows:
@@ -55,49 +32,59 @@ def main():
print("[SILENT] 无待处理TODO") print("[SILENT] 无待处理TODO")
return return
results = []
for row in rows: for row in rows:
todo_id = row["id"] tid = row["id"]
title = row["title"] title = row["title"]
fix_action = row["fix_action"] fix = row["fix_action"]
if not fix_action: conn.execute("UPDATE todos SET status='in_progress' WHERE id=?", (tid,))
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.commit() conn.commit()
ok, output = execute_fix(fix_action) if not fix:
if ok: msg = f"[自愈执行器] 需处理: {title} (无自动修复方案)"
conn.execute(
"UPDATE todos SET status='completed', note=?, "
"updated_at=CURRENT_TIMESTAMP WHERE id=?",
(f"已修复: {output[:200]}", todo_id))
results.append(("", f"{title}: 已修复"))
else: else:
conn.execute( # 执行修复命令
"UPDATE todos SET status='needs_llm', note=?, " try:
"updated_at=CURRENT_TIMESTAMP WHERE id=?", r = subprocess.run(fix, shell=True, capture_output=True, text=True, timeout=30)
(f"执行失败: {output[:200]}", todo_id)) if r.returncode == 0:
results.append(("🔶", f"{title}: 需知微介入({output[:60]})")) 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.commit()
conn.close() conn.close()
elapsed = time.time() - start if rows:
if results: print(f"自愈执行器 | {datetime.now().strftime('%H:%M')} | {len(rows)}条 ({time.time()-start:.0f}s)")
print(f"自愈执行器 | {datetime.now().strftime('%H:%M')} | {len(results)}条 ({elapsed:.0f}s)") else:
for icon, msg in results: print("[SILENT] 无待处理TODO")
print(f" {icon} {msg}")
if __name__ == "__main__": if __name__ == "__main__":