Download monitor.py from smlflg/META2.0: direct link, hf CLI and curl.
- Browser
- Download file 7.16 kB
-
https://huggingface.co/smlflg/META2.0/resolve/main/monitor.py
- Command line
-
hf download hf://smlflg/META2.0/monitor.py
-
curl -L -o monitor.py https://huggingface.co/smlflg/META2.0/resolve/main/monitor.py
7.16 kB
| #!/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() | |