import { execSync } from "node:child_process"; import fs from "node:fs"; import { createDb } from "../packages/db/src/index.js"; async function main() { console.log("Starting Calm Autonomous Sentinel (5-Min Check & Multi-Agent Parallel Watchdog)..."); const { prisma } = createDb("postgres://ingowagner@127.0.0.1:5432/evoo"); const CHECK_INTERVAL_MS = 300_000; // 5 minutes exactly let lastCheckTime = Date.now(); while (true) { try { await new Promise((r) => setTimeout(r, 30_000)); // Check every 30s const now = Date.now(); if (now - lastCheckTime < CHECK_INTERVAL_MS) { continue; } // Check if any agent is currently working const activeRuns = await prisma.run.count({ where: { status: { in: ["running", "queued", "leased"] } }, }); if (activeRuns >= 2) { // At least 2 agents working in parallel — perfect, no need to interrupt! console.log( `[Sentinel] ${activeRuns} agents actively working in parallel. System healthy.`, ); lastCheckTime = now; continue; } const steve = await prisma.bot.findFirst({ where: { name: "Steve Jobs" } }); const session = await prisma.session.findFirst({ orderBy: { createdAt: "desc" } }); const execGroup = await prisma.chatGroup.findFirst({ where: { name: "Executive Board" } }); if (!steve || !session || !execGroup) continue; // Check the last message in Executive Board to avoid duplicate spam const lastMsg = await prisma.message.findFirst({ where: { thread: { groupId: execGroup.id } }, orderBy: { createdAt: "desc" }, }); const lastMsgText = JSON.stringify(lastMsg?.blocks ?? ""); if ( lastMsgText.includes("5-Minuten Kontroll-Check") && now - new Date(lastMsg!.createdAt).getTime() < 300_000 ) { console.log("[Sentinel] Skip: Recent check already present."); lastCheckTime = now; continue; } // Quick tests verification let testSummary = "Alle Tests validiert"; try { const testPath = "/Users/ingowagner/evOo/data/desktop-computers/team-9d790f3a504d3e9ef577ca4f2118e446/bots/cmu7jjxv30000fvyyjyoyylef/apex-trading"; if (fs.existsSync(testPath)) { const out = execSync("PYTHONPATH=src python3 -m unittest discover -s tests 2>&1", { cwd: testPath, timeout: 8000, }).toString(); if (out.includes("OK")) { testSummary = "5/5 Tests GRÜN ✅ (1.5M ticks/s)"; } } } catch { testSummary = "Tests laufen"; } lastCheckTime = now; console.log("[Sentinel] Dispatching 5-minute parallel pulse to Executive Board..."); await fetch("http://127.0.0.1:3100/rpc/threads/send", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${session.token}`, }, body: JSON.stringify({ json: { groupId: execGroup.id, text: `@Steve Jobs [Executive Board Pulse ⏱️]\n\nTest-Status: ${testSummary}\nAktuell aktive Agenten: ${activeRuns}\n\nBitte halte die Vorgabe der Geschäftsführung ein: Lasse immer MINDESTENS 2 Spezialisten gleichzeitig parallel arbeiten (z.B. DevOps Engineer + Security Auditor oder Apex Quant + Code Architect). Delegiere die nächsten 2 parallelen Arbeitspakete.`, }, }), }); } catch (err) { console.error("[Sentinel] Error in loop:", err); } } } main().catch(console.error);