feat(operators): amendment workflow and automated drive watchdog daemon
This commit is contained in:
@@ -3350,6 +3350,117 @@ def cmd_md_sync_all(args):
|
||||
sys.stdout.write(res.stdout)
|
||||
|
||||
|
||||
def cmd_md_amend(args):
|
||||
cmd = ["python3", str(BIN_DIR / "box-ctl.py"), "md", "amend", args.filename]
|
||||
if args.file:
|
||||
cmd.extend(["--file", args.file])
|
||||
elif args.content:
|
||||
cmd.extend(["--content", args.content])
|
||||
if args.author:
|
||||
cmd.extend(["--author", args.author])
|
||||
if args.reason:
|
||||
cmd.extend(["--reason", args.reason])
|
||||
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if args.json:
|
||||
sys.stdout.write(res.stdout)
|
||||
return
|
||||
try:
|
||||
d = json.loads(res.stdout)
|
||||
if d.get("ok"):
|
||||
commit_info = f" (git commit: {d.get('commit')})" if d.get("commit") else ""
|
||||
print(c_green(f"\n✓ Successfully amended shared/operators/{args.filename}{commit_info}"))
|
||||
print(f" Author: {c_cyan(d.get('author'))}")
|
||||
print(f" Bytes: {d.get('bytes_written')}\n")
|
||||
print(c_dim(" Broadcast to fleet with: box md sync-all\n"))
|
||||
else:
|
||||
print(c_red(f"✗ Failed: {d.get('error')}"))
|
||||
except Exception:
|
||||
sys.stdout.write(res.stdout)
|
||||
|
||||
|
||||
def cmd_md_append(args):
|
||||
cmd = ["python3", str(BIN_DIR / "box-ctl.py"), "md", "append", args.filename, args.text]
|
||||
if args.author:
|
||||
cmd.extend(["--author", args.author])
|
||||
if args.section:
|
||||
cmd.extend(["--section", args.section])
|
||||
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if args.json:
|
||||
sys.stdout.write(res.stdout)
|
||||
return
|
||||
try:
|
||||
d = json.loads(res.stdout)
|
||||
if d.get("ok"):
|
||||
commit_info = f" (git commit: {d.get('commit')})" if d.get("commit") else ""
|
||||
print(c_green(f"\n✓ Successfully appended note to shared/operators/{args.filename}{commit_info}"))
|
||||
print(f" Author: {c_cyan(d.get('author'))}\n")
|
||||
print(c_dim(" Broadcast to fleet with: box md sync-all\n"))
|
||||
else:
|
||||
print(c_red(f"✗ Failed: {d.get('error')}"))
|
||||
except Exception:
|
||||
sys.stdout.write(res.stdout)
|
||||
|
||||
|
||||
def cmd_md_pull(args):
|
||||
cmd = ["python3", str(BIN_DIR / "box-ctl.py"), "md", "pull", args.account, args.filename]
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if args.json:
|
||||
sys.stdout.write(res.stdout)
|
||||
return
|
||||
try:
|
||||
d = json.loads(res.stdout)
|
||||
if d.get("ok"):
|
||||
print(c_green(f"✓ Pulled canonical shared/operators/{args.filename} into {args.account} container ({d.get('bytes_written')} B)"))
|
||||
else:
|
||||
print(c_red(f"✗ Failed: {d.get('error')}"))
|
||||
except Exception:
|
||||
sys.stdout.write(res.stdout)
|
||||
|
||||
|
||||
def cmd_md_watchdog(args):
|
||||
watchdog_py = BIN_DIR / "agent-drive-watchdog.py"
|
||||
if args.sub_action == "status":
|
||||
cmd = ["python3", str(watchdog_py), "--status"]
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if args.json:
|
||||
sys.stdout.write(res.stdout)
|
||||
return
|
||||
try:
|
||||
d = json.loads(res.stdout)
|
||||
print("\n" + c_bold("=== NETVM FLEET AGENT DRIVE WATCHDOG STATUS ===") + "\n")
|
||||
print(f" Last Run: {c_cyan(d.get('last_run', 'never'))}")
|
||||
st = d.get("agent_status", {})
|
||||
headers = ["AGENT", "DRIVE SCORE", "STATUS", "LAST CHECKED", "ISSUES"]
|
||||
rows = []
|
||||
for acct, info in st.items():
|
||||
score = info.get("score", 0)
|
||||
score_str = c_green(f"{score}/100") if score == 100 else c_red(f"{score}/100")
|
||||
stat = c_green("HIGH DRIVE") if info.get("status") == "HIGH_DRIVE" else c_red(info.get("status", "DEGRADED"))
|
||||
dt = (info.get("last_checked") or "-")[:19]
|
||||
iss = ", ".join(info.get("issues", [])) or c_dim("none")
|
||||
rows.append([c_bold(acct.upper()), score_str, stat, dt, iss])
|
||||
print_table(headers, rows)
|
||||
|
||||
# Show timer status
|
||||
tr = subprocess.run(["systemctl", "--user", "is-active", "agent-drive-watchdog.timer"], capture_output=True, text=True)
|
||||
t_stat = tr.stdout.strip()
|
||||
t_badge = c_green("ACTIVE (every 10m)") if t_stat == "active" else c_yellow(t_stat)
|
||||
print(f"\n Systemd Timer: {t_badge}\n")
|
||||
except Exception:
|
||||
sys.stdout.write(res.stdout)
|
||||
elif args.sub_action == "run":
|
||||
cmd = ["python3", str(watchdog_py), "--once"]
|
||||
if getattr(args, "no_heal", False):
|
||||
cmd.append("--no-heal")
|
||||
print("\n" + c_bold("=== RUNNING FLEET AGENT DRIVE WATCHDOG CYCLE ===") + "\n")
|
||||
subprocess.run(cmd)
|
||||
print()
|
||||
else:
|
||||
print("Usage: box md watchdog {status|run}")
|
||||
|
||||
|
||||
def cmd_swarm_list(args):
|
||||
cmd = ["python3", str(BIN_DIR / "box-ctl.py"), "swarm-list"]
|
||||
res = subprocess.run(cmd, capture_output=True, text=True)
|
||||
@@ -3709,6 +3820,27 @@ def build_parser():
|
||||
p_md_sync = md_sub.add_parser("sync-all", parents=[common], help="Inject high-drive operator files across all active fleet agents")
|
||||
p_md_sync.add_argument("--force", action="store_true", help="Force overwrite")
|
||||
|
||||
p_md_amend = md_sub.add_parser("amend", parents=[common], help="Amend centralized shared operator file with validation and git commit")
|
||||
p_md_amend.add_argument("filename", help="Filename (e.g. AGENTS.md, TOOLS.md)")
|
||||
p_md_amend.add_argument("--content", help="New content")
|
||||
p_md_amend.add_argument("--file", help="File with new content")
|
||||
p_md_amend.add_argument("--author", default="operator", help="Author of amendment")
|
||||
p_md_amend.add_argument("--reason", default="", help="Reason for amendment")
|
||||
|
||||
p_md_append = md_sub.add_parser("append", parents=[common], help="Safely append a lesson or note to a shared operator file")
|
||||
p_md_append.add_argument("filename", help="Filename (e.g. AGENTS.md)")
|
||||
p_md_append.add_argument("text", help="Text to append")
|
||||
p_md_append.add_argument("--author", default="operator", help="Author of amendment")
|
||||
p_md_append.add_argument("--section", default=None, help="Optional section header")
|
||||
|
||||
p_md_pull = md_sub.add_parser("pull", parents=[common], help="Pull canonical shared template into an agent container")
|
||||
p_md_pull.add_argument("account", help="Agent account")
|
||||
p_md_pull.add_argument("filename", help="Filename (e.g. SOUL.md)")
|
||||
|
||||
p_md_wd = md_sub.add_parser("watchdog", parents=[common], help="Fleet agent drive watchdog daemon & status")
|
||||
p_md_wd.add_argument("sub_action", choices=["status", "run"], nargs="?", default="status", help="Watchdog action: status (default) or run (execute cycle)")
|
||||
p_md_wd.add_argument("--no-heal", action="store_true", help="Audit only; do not auto-heal degraded agents")
|
||||
|
||||
# Domain: HARVEST
|
||||
p_harvest = subparsers.add_parser("harvest", parents=[common], help="Readback & response harvesting engine")
|
||||
harvest_sub = p_harvest.add_subparsers(dest="action")
|
||||
@@ -4069,6 +4201,14 @@ def main():
|
||||
cmd_md_inject_drive(args)
|
||||
elif act == "sync-all":
|
||||
cmd_md_sync_all(args)
|
||||
elif act == "amend":
|
||||
cmd_md_amend(args)
|
||||
elif act == "append":
|
||||
cmd_md_append(args)
|
||||
elif act == "pull":
|
||||
cmd_md_pull(args)
|
||||
elif act == "watchdog":
|
||||
cmd_md_watchdog(args)
|
||||
else:
|
||||
p_md.print_help()
|
||||
elif args.domain == "harvest":
|
||||
|
||||
Reference in New Issue
Block a user