#!/usr/bin/env python3 """ Heartbeat-Task für Second Brain - isoliert, persistent. """ import json import os import sys from pathlib import Path from datetime import datetime, timezone BRAIN_DIR = Path("/root/.openclaw/workspace/second-brain") sys.path.insert(0, str(BRAIN_DIR)) from src.engram import Engram, Grounding from src.store import EngramStore def main(): output_file = os.environ.get("CRON_OUTPUT_FILE", "/tmp/heartbeat_result.json") brain_db = os.environ.get("BRAIN_DB", str(BRAIN_DIR / "data" / "brain.sqlite")) store = EngramStore(brain_db) egs = store.get_all(limit=50) unconfirmed = [eg for eg in egs if not eg.correctness.confirmed and eg.compute_confidence() > 0.5][:5] errors = store.search_tag("error", limit=5) result = { "timestamp": datetime.now(timezone.utc).isoformat(), "total_engrams": len(egs), "unconfirmed_count": len(unconfirmed), "error_count": len(errors), "has_action": bool(unconfirmed) or len(errors) >= 3, "message": None, } if unconfirmed: contents = "\n".join([f" - {eg.content[:80]}" for eg in unconfirmed]) result["message"] = f"🧠 Unbestätigte Engramme:\n{contents}" elif len(errors) >= 3: result["message"] = f"⚠️ {len(errors)} Fehler-Engramme gespeichert." Path(output_file).write_text(json.dumps(result, indent=2)) print(f"HEARTBEAT: {result['unconfirmed_count']} unconfirmed, {result['error_count']} errors") return 0 if __name__ == "__main__": sys.exit(main())