File size: 7,164 Bytes
b1c46d8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | #!/usr/bin/env python3
"""META2.0 Monitor β ΓΌberwacht alle 15 Agenten, zeigt Fortschritt, erkennt Stalls."""
import os
import re
import subprocess
import sys
import time
from pathlib import Path
from datetime import datetime
BASE = Path(__file__).parent
TOTAL_SOURCES = 97 # Transkripte
STALL_MINUTES = 5 # Agent gilt als gestalled wenn kein neuer Eintrag seit X min
FRAGEN = {
"frage_01_kontrolle": "Ownership wenn Agenten autonomer",
"frage_02_struktur": "Chaos β handhabbare Schritte",
"frage_03_identitaet": "Wer ist Samuel in agentischer Welt",
"frage_04_thalamus": "Digitaler Thalamus / Pyramide",
"frage_05_qualitaet": "Metriken: gut mit Agenten?",
"frage_06_energie": "Wann wirklich lebendig?",
"frage_07_ueberforderung": "Nicht FΓ€higkeit β zu viel gleichzeitig",
"frage_08_ownership": "Stark fΓΌhlen: wirklich meins",
"frage_09_flucht": "Wiederholte Reset-Bewegungen",
"frage_10_menschen": "Menschen: grΓΆΓer vs. kleiner",
"frage_11_zustand": "Entscheidungen in schlechten ZustΓ€nden",
"frage_12_talent": "NatΓΌrliches Talent (unsichtbar)",
"frage_13_schmerz": "Schmerz β Produktideen",
"frage_14_wiederholung": "Wiederkehrende Lebensszene",
"frage_15_zukunft": "Welche Version will entstehen?",
}
def count_processed(log_path: Path) -> int:
"""ZΓ€hlt verarbeitete Quellen aus session_log.md."""
if not log_path.exists():
return 0
count = 0
with open(log_path, encoding="utf-8", errors="ignore") as f:
for line in f:
if line.startswith("**") and ("`[transkript]`" in line or "`[session]`" in line):
count += 1
return count
def last_modified(path: Path) -> float:
"""Sekunden seit letzter Γnderung."""
if not path.exists():
return 9999
return time.time() - path.stat().st_mtime
def is_done(dir_path: Path) -> bool:
return (dir_path / "ANTWORT.md").exists()
def has_errors(run_log: Path) -> int:
if not run_log.exists():
return 0
try:
content = run_log.read_text(encoding="utf-8", errors="ignore")
return content.count("[FEHLER:")
except Exception:
return 0
def get_last_entry(log_path: Path) -> str:
"""Letzter verarbeiteter Dateiname."""
if not log_path.exists():
return "β"
last = ""
with open(log_path, encoding="utf-8", errors="ignore") as f:
for line in f:
if line.startswith("**") and ("transkript" in line or "session" in line):
last = line[2:50].split("**")[0].strip()
return last or "β"
def missed_sessions(log_path: Path, all_sources: list) -> list:
"""Welche Sources wurden noch nicht verarbeitet?"""
if not log_path.exists():
return all_sources
content = log_path.read_text(encoding="utf-8", errors="ignore")
missed = []
for src in all_sources:
if src[:40] not in content:
missed.append(src)
return missed
def get_all_source_names() -> list:
transcript_dir = Path("/home/smlflg/Projekte/IPAI/KnowdledgeGraph/data/raw")
sources = []
if transcript_dir.exists():
sources = [f.name[:40] for f in sorted(transcript_dir.glob("*.txt"))]
return sources
def print_dashboard(all_sources: list):
os.system("clear")
now = datetime.now().strftime("%H:%M:%S")
print(f"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
print(f"β META2.0 Monitor [{now}] β")
print(f"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
print()
total_done = 0
total_processed = 0
stalled = []
finished = []
errored = []
for key, label in FRAGEN.items():
dir_path = BASE / key
log_path = dir_path / "session_log.md"
run_log = dir_path / "run.log"
done = is_done(dir_path)
processed = count_processed(log_path)
pct = int(processed / TOTAL_SOURCES * 100) if TOTAL_SOURCES else 0
age_min = last_modified(log_path) / 60
errors = has_errors(run_log)
last = get_last_entry(log_path)
# Status
if done:
status = "β DONE"
finished.append(key)
elif processed == 0:
status = "β³ warten"
elif age_min > STALL_MINUTES and not done:
status = f"β STALL ({age_min:.0f}min)"
stalled.append(key)
else:
bar = "β" * (pct // 5) + "β" * (20 - pct // 5)
status = f"[{bar}] {pct:3d}%"
err_str = f" ERR:{errors}" if errors else ""
print(f" {key:<28} {status:<30} {processed:3d}/{TOTAL_SOURCES}{err_str}")
print(f" {'':28} ββ {last[:50]}")
print()
total_processed += processed
if done:
total_done += 1
total_pct = int(total_processed / (TOTAL_SOURCES * len(FRAGEN)) * 100)
print(f"βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ")
print(f" Gesamt: {total_processed}/{TOTAL_SOURCES * len(FRAGEN)} Analyse-Calls ({total_pct}%)")
print(f" Fertig: {total_done}/{len(FRAGEN)} Fragen | Stalled: {len(stalled)} | Laufend: {len(FRAGEN)-total_done-len(stalled)}")
if stalled:
print()
print(f" β GESTALLED: {', '.join(stalled)}")
print(f" β Neustart: python swarm_agent.py --frage-id <id> ...")
if finished:
print()
print(f" β Fertige Antworten: {len(finished)}")
for f in finished:
print(f" cat {BASE}/{f}/ANTWORT.md")
# VollstΓ€ndigkeits-Check
missed_total = 0
if "--check" in sys.argv:
print()
print(" VOLLSTΓNDIGKEITS-CHECK:")
for key in FRAGEN:
log_path = BASE / key / "session_log.md"
missed = missed_sessions(log_path, all_sources)
if missed:
missed_total += len(missed)
print(f" {key}: {len(missed)} nicht gelesen")
for m in missed[:3]:
print(f" - {m}")
if missed_total == 0:
print(" β Alle Sources in allen Logs vorhanden.")
print()
print(" [Ctrl+C zum Beenden] [--check fΓΌr VollstΓ€ndigkeits-Audit]")
def main():
all_sources = get_all_source_names()
interval = 15 # Sekunden zwischen Updates
if "--once" in sys.argv or "--check" in sys.argv:
print_dashboard(all_sources)
return
try:
while True:
print_dashboard(all_sources)
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitor beendet.")
if __name__ == "__main__":
main()
|