Meta3.0 / scripts /meta3_runner_status.py
smlflg's picture
Initial public upload from Projekte/Meta3.0
1219ee2 verified
Raw History Blame Contribute Delete
5.72 kB
#!/usr/bin/env python3
"""Report Meta3 runner lock, stop, heartbeat, and ledger status. No network calls."""
from __future__ import annotations
import argparse
import json
from collections import Counter
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
def load_json(path: Path) -> dict[str, Any]:
with path.open("r", encoding="utf-8") as handle:
data = json.load(handle)
if not isinstance(data, dict):
raise ValueError(f"Expected JSON object: {path}")
return data
def load_jsonl(path: Path) -> list[dict[str, Any]]:
if not path.exists():
return []
rows: list[dict[str, Any]] = []
with path.open("r", encoding="utf-8") as handle:
for line_no, line in enumerate(handle, start=1):
if not line.strip():
continue
data = json.loads(line)
if not isinstance(data, dict):
raise ValueError(f"Expected JSON object in {path}:{line_no}")
rows.append(data)
return rows
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def latest_run_dir() -> Path:
runs_root = ROOT / "runs"
candidates = sorted(p for p in runs_root.iterdir() if p.is_dir())
if not candidates:
raise FileNotFoundError("No run dirs found. Run scripts/meta3_prepare.py first.")
return candidates[-1]
def run_dir_for(run_id: str | None) -> Path:
return ROOT / "runs" / run_id if run_id else latest_run_dir()
def mode_status(run_dir: Path, mode: str) -> dict[str, Any]:
lock_path = run_dir / "state" / f"{mode}_runner.lock.json"
heartbeat_path = run_dir / "state" / f"{mode}_runner_heartbeat.json"
ledger_path = run_dir / "state" / f"{mode}_call_ledger.jsonl"
stop_candidates = [run_dir / "state" / "STOP", run_dir / "state" / f"STOP_{mode}"]
ledger_rows = load_jsonl(ledger_path)
statuses = Counter(str(row.get("status") or "unknown") for row in ledger_rows)
calls = sum(int(row.get("network_calls_made") or 0) for row in ledger_rows)
return {
"mode": mode,
"lock_path": str(lock_path),
"lock_exists": lock_path.exists(),
"lock": load_json(lock_path) if lock_path.exists() else None,
"heartbeat_path": str(heartbeat_path),
"heartbeat_exists": heartbeat_path.exists(),
"heartbeat": load_json(heartbeat_path) if heartbeat_path.exists() else None,
"stop_paths": [str(path) for path in stop_candidates],
"active_stop_paths": [str(path) for path in stop_candidates if path.exists()],
"ledger_path": str(ledger_path),
"ledger_rows": len(ledger_rows),
"ledger_statuses": dict(sorted(statuses.items())),
"ledger_network_calls_made": calls,
}
def markdown_report(report: dict[str, Any]) -> str:
lines = [
"# Meta3 Runner Status",
"",
f"Run: `{report['run_id']}`",
f"Created: `{report['created_at']}`",
f"Overall status: `{report['status']}`",
"",
]
for mode, status in sorted(report["modes"].items()):
heartbeat = status.get("heartbeat") or {}
lines.extend(
[
f"## {mode}",
"",
f"- Lock exists: {status['lock_exists']}",
f"- Active stop files: {len(status['active_stop_paths'])}",
f"- Heartbeat status: {heartbeat.get('status')}",
f"- Completed: {heartbeat.get('completed')}",
f"- Failed: {heartbeat.get('failed')}",
f"- Ledger rows: {status['ledger_rows']}",
f"- Ledger statuses: {status['ledger_statuses']}",
f"- Ledger network calls: {status['ledger_network_calls_made']}",
"",
]
)
return "\n".join(lines)
def main() -> int:
parser = argparse.ArgumentParser(description="Report Meta3 runner status without API calls.")
parser.add_argument("--run-id", default=None, help="Run id under runs/. Defaults to latest run.")
parser.add_argument(
"--mode",
action="append",
choices=["calibration", "claim_ledger"],
help="Mode to inspect. Can be repeated. Defaults to both.",
)
args = parser.parse_args()
run_dir = run_dir_for(args.run_id)
modes = args.mode or ["calibration", "claim_ledger"]
mode_reports = {mode: mode_status(run_dir, mode) for mode in modes}
has_lock = any(item["lock_exists"] for item in mode_reports.values())
has_stop = any(item["active_stop_paths"] for item in mode_reports.values())
status = "blocked" if has_lock or has_stop else "idle_or_ready"
report = {
"schema": "meta3.runner_status.v1",
"run_id": run_dir.name,
"created_at": datetime.now(timezone.utc).isoformat(),
"status": status,
"modes": mode_reports,
"network_calls_made": 0,
}
report_path = run_dir / "reports/runner_status.json"
report_md_path = run_dir / "reports/RUNNER_STATUS.md"
write_json(report_path, report)
report_md_path.write_text(markdown_report(report), encoding="utf-8")
print(f"runner_status={report_path}")
print(f"runner_status_md={report_md_path}")
print(f"status={status}")
print(f"lock_modes={sum(1 for item in mode_reports.values() if item['lock_exists'])}")
print(f"stop_modes={sum(1 for item in mode_reports.values() if item['active_stop_paths'])}")
print("network_calls_made=0")
return 0
if __name__ == "__main__":
raise SystemExit(main())