#!/usr/bin/env python3 """ atlas_autonomy_export.py - Expose autonomy loop state via JSON for live dashboard. Reads: - autonomy_queue.json (pending/completed) - autonomy_loop.log (last 50 lines) - vault/00_Atlas_Wiki/_autonomy/*.md (last 20 outputs) Writes: - atlas-autonomy.json — consumed by Atlas Command AUTONOMY tab Runs: every 1 min via Atlas-Autonomy-Export schtask (lightweight). """ import json import sys import subprocess from pathlib import Path from datetime import datetime import io if sys.stdout.encoding != 'utf-8': sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') QUEUE = Path(r"C:\Users\Gebruiker\.config\atlas\autonomy_queue.json") LOG = Path(r"C:\Users\Gebruiker\.config\atlas\autonomy_loop.log") AUTO = Path(r"C:\Users\Gebruiker\MEGA\Atlas Corporation\00_Atlas_Wiki\_autonomy") OUT = Path(r"C:\Users\Gebruiker\AppData\Local\Atlas\analyses\atlas-autonomy.json") SSH = "root@" REMOTE = "/opt/atlas/dashboard/atlas-autonomy.json" def parse_frontmatter(text): """Extract simple YAML frontmatter (between --- markers).""" if not text.startswith("---"): return {}, text end = text.find("---", 3) if end == -1: return {}, text yaml_block = text[3:end].strip() body = text[end+3:].strip() fm = {} for line in yaml_block.split("\n"): if ":" in line: k, v = line.split(":", 1) fm[k.strip()] = v.strip() return fm, body def main(): state = { "generated_at": datetime.now().isoformat(timespec="seconds"), "loop_running": False, "queue_pending": 0, "queue_completed": 0, "log_tail": [], "recent_outputs": [], "next_fire": None, "task_state": None, } # Queue if QUEUE.exists(): try: q = json.loads(QUEUE.read_text(encoding="utf-8")) state["queue_pending"] = len(q.get("pending", [])) state["queue_completed"] = len(q.get("completed", [])) if q.get("completed"): last = q["completed"][-1] state["last_completed"] = { "topic": last.get("topic"), "node": last.get("node"), "model": last.get("model"), "completed_at": last.get("completed_at"), "elapsed_s": last.get("elapsed_s"), } except Exception as e: state["queue_err"] = str(e)[:100] # Log tail if LOG.exists(): try: lines = LOG.read_text(encoding="utf-8", errors="replace").splitlines() state["log_tail"] = lines[-50:] except Exception: pass # Schtask state try: r = subprocess.run( ["powershell.exe", "-NoProfile", "-Command", "$t=Get-ScheduledTask -TaskName Atlas-Autonomy-Hourly -ErrorAction SilentlyContinue;" "if ($t) { $i=Get-ScheduledTaskInfo $t; " "Write-Output ('STATE:' + $t.State + '|LAST:' + $i.LastRunTime + '|NEXT:' + $i.NextRunTime + '|RESULT:' + $i.LastTaskResult) }"], capture_output=True, text=True, timeout=10 ) out = r.stdout.strip() if out.startswith("STATE:"): parts = dict(p.split(":", 1) for p in out[6:].split("|")) state["task_state"] = "STATE:" + out[6:] state["loop_running"] = (parts.get("STATE") != "Disabled") state["next_fire"] = parts.get("NEXT") except Exception as e: state["task_state_err"] = str(e)[:100] # Recent outputs (last 20 by mtime) if AUTO.exists(): try: md_files = sorted(AUTO.glob("*.md"), key=lambda p: p.stat().st_mtime, reverse=True)[:20] for p in md_files: try: text = p.read_text(encoding="utf-8", errors="replace") fm, body = parse_frontmatter(text) state["recent_outputs"].append({ "filename": p.name, "mtime": datetime.fromtimestamp(p.stat().st_mtime).isoformat(timespec="seconds"), "topic": fm.get("topic", "?"), "node": fm.get("node", "?"), "model": fm.get("model", "?"), "elapsed_s": fm.get("elapsed_s", "?"), "polish_status": fm.get("polish_status", "?"), "body_preview": body[:400].replace("\n", " ").strip(), }) except Exception: pass except Exception as e: state["outputs_err"] = str(e)[:100] state["recent_output_count"] = len(state["recent_outputs"]) OUT.parent.mkdir(parents=True, exist_ok=True) OUT.write_text(json.dumps(state, indent=2, ensure_ascii=False), encoding="utf-8") print(f"wrote {OUT}") print(f" pending={state['queue_pending']} completed={state['queue_completed']} outputs={state['recent_output_count']}") try: subprocess.run(["scp", str(OUT), f"{SSH}:{REMOTE}"], check=True, timeout=20) print(f"pushed to {SSH}:{REMOTE}") except Exception as e: print(f"scp fail: {e}") if __name__ == "__main__": main()