#!/usr/bin/env python3 """ ONI Agent Event Daemon ====================== Continuous event poller. Polls game events every N seconds and displays critical/warning/info events to the console (for AI input stream). Usage: python event_daemon.py [interval_seconds] """ import json, os, sys, time, datetime TOOLS_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'tools') sys.path.insert(0, TOOLS_DIR) from oni_api import api_get, api_post, load_config POLL_INTERVAL = 5 MAX_EVENTS = 200 class EventHistory: def __init__(self, maxlen=200): self.events = [] self.maxlen = maxlen self.last_seq = -1 self.stats = {"critical": 0, "warning": 0, "info": 0} def add(self, event): self.events.append(event) if len(self.events) > self.maxlen: self.events.pop(0) sev = event.get('severity', 'info') self.stats[sev] = self.stats.get(sev, 0) + 1 def get_recent(self, n=10): return self.events[-n:] def main(): interval = int(sys.argv[1]) if len(sys.argv) > 1 else POLL_INTERVAL history = EventHistory(MAX_EVENTS) consecutive_errors = 0 print(f"[EventDaemon] Starting — poll interval {interval}s") print(f"[EventDaemon] Config: {json.dumps(load_config())}") while True: try: r = api_get(f'/api/state/events?since={history.last_seq}') if not r.get("success"): consecutive_errors += 1 if consecutive_errors > 3: print(f"[EventDaemon] {consecutive_errors} consecutive errors — mod may be offline") time.sleep(interval) continue consecutive_errors = 0 data = r.get("data", {}) events = data.get("events", []) next_seq = data.get("nextSeq", history.last_seq) for ev in events: history.add(ev) sev = ev.get('severity', 'info') title = ev.get('title', '') message = ev.get('message', '') ts = ev.get('timestamp', 0) dt = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S') if ts else '' if sev in ('critical', 'error'): print(f"\nāš ļø [{dt}] CRITICAL: {title} {message}") elif sev in ('warning',): print(f"\n🟔 [{dt}] WARNING: {title} {message}") else: print(f"šŸ”µ [{dt}] INFO: {title} {message}") if events: history.last_seq = next_seq # Show summary every 30 seconds if history.events and int(time.time()) % 30 < interval: c = history.stats.get('critical', 0) w = history.stats.get('warning', 0) print(f"[EventDaemon] Stats | critical={c} warning={w} total={len(history.events)} | seq={history.last_seq}") except KeyboardInterrupt: print("\n[EventDaemon] Stopped") break except Exception as ex: print(f"[EventDaemon] Error: {ex}") time.sleep(interval) continue time.sleep(interval) if __name__ == "__main__": main()