b766a5dbb1
- 去掉重试逻辑:每10分钟试1次,失败→立刻needs_llm - 无fix_action也走needs_llm(不搁置) - 执行器deliver=origin,needs_llm输出会到达Dad - 知微启动时/被叫时检查needs_llm→直接处理
105 lines
3.2 KiB
Python
105 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""self_todo_executor.py — TODO自动执行器 (no_agent模式)
|
|
|
|
每10分钟轮询mofin.db中todos表的pending任务,执行fix_action命令。
|
|
没有"blocked"状态。能修就修,修不了留着等明天体检再说。
|
|
纯代码逻辑,不调LLM。
|
|
"""
|
|
|
|
import json, os, sqlite3, subprocess, sys, time
|
|
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]
|
|
|
|
|
|
def main():
|
|
start = time.time()
|
|
conn = get_conn()
|
|
|
|
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"
|
|
).fetchall()
|
|
|
|
if not rows:
|
|
conn.close()
|
|
print("[SILENT] 无待处理TODO")
|
|
return
|
|
|
|
results = []
|
|
for row in rows:
|
|
todo_id = row["id"]
|
|
title = row["title"]
|
|
fix_action = 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.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}: 已修复"))
|
|
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]})"))
|
|
|
|
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 __name__ == "__main__":
|
|
main()
|