From 5bc709221e98cbcf7ff102d31d2065a8e3e7cd89 Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Fri, 7 Aug 2026 11:19:15 +0200 Subject: [PATCH] feat: add news, discover models and auftragsbuch to sysadmin report --- backend/services/sysadmin_report.py | 63 ++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 10 deletions(-) diff --git a/backend/services/sysadmin_report.py b/backend/services/sysadmin_report.py index b24c46d..7423001 100644 --- a/backend/services/sysadmin_report.py +++ b/backend/services/sysadmin_report.py @@ -6,7 +6,7 @@ import time from datetime import datetime, timezone import httpx -from services import maintenance, announce, llamaswap +from services import maintenance, announce, llamaswap, auftragsbuch, discover from config import V1_UPSTREAM log = logging.getLogger(__name__) @@ -14,6 +14,22 @@ log = logging.getLogger(__name__) # Wenn aktiv, wird der Report um die angegebene Stunde (0-23) lokaler Zeit verschickt SCHEDULE_HOUR = 8 +async def fetch_tech_news() -> str: + """Holt die Top 3 Tech-News von HackerNews als Futter.""" + try: + async with httpx.AsyncClient(timeout=10.0) as client: + top_ids_resp = await client.get("https://hacker-news.firebaseio.com/v0/topstories.json") + top_ids = top_ids_resp.json()[:3] + news_items = [] + for item_id in top_ids: + item_resp = await client.get(f"https://hacker-news.firebaseio.com/v0/item/{item_id}.json") + item = item_resp.json() + news_items.append(f"- {item.get('title', '')}") + return "\n".join(news_items) if news_items else "Keine News gefunden." + except Exception as e: + log.warning(f"Fehler beim Abrufen der News: {e}") + return "News konnten nicht abgerufen werden." + async def generate_and_send_report() -> bool: """Sammelt System-Status, fragt das lokale LLM nach einer Zusammenfassung als Lucy und sendet via Telegram.""" log.info("Sysadmin-Report gestartet...") @@ -33,6 +49,26 @@ async def generate_and_send_report() -> bool: running_models = llamaswap.get_running_models() + # News + news_text = await fetch_tech_news() + + # Discover: Bessere Modelle + disc_data = discover.safe_discover(ram_gb_total) + rec_models = [] + if disc_data and "categories" in disc_data: + for c in disc_data["categories"]: + if c.get("recommended"): + rec_models.append(c["recommended"]) + rec_str = ", ".join(rec_models[:3]) if rec_models else "Keine neuen Empfehlungen" + + # Auftragsbuch + try: + auftraege = auftragsbuch.list_all() + offene = [a for a in auftraege if a.get("status") in ("todo", "triage")] + auftraege_str = f"{len(offene)} offene Aufgaben, die auf dich warten." if offene else "Das Auftragsbuch ist leer (Keine offenen Aufgaben)." + except Exception: + auftraege_str = "Fehler beim Lesen des Auftragsbuchs." + events = announce.list_recent(limit=15) event_lines = [] for e in events: @@ -48,23 +84,30 @@ async def generate_and_send_report() -> bool: Hardware: RAM {ram_gb_used}/{ram_gb_total} GB ({ram.percent}%), CPU {cpu_percent}%, Speicher {disk_gb_free} GB frei. Laufende Modelle: {', '.join(running_models) if running_models else 'Keine'} Updates anstehend: OS: {upd.get('os', 0)}, Engine: {upd.get('engine', False)}, Swap: {upd.get('swap', False)}, Hermes: {upd.get('hermes', False)} +Offene Freigaben für Commander (Auftragsbuch): {auftraege_str} +Modell-Empfehlungen für diese Box: {rec_str} + +Heutige Tech-News: +{news_text} Kürzliche Ereignisse (Chronik): {events_str} """ prompt = f"""Du bist Lucy, die KI-Sysadmin der Box. -Dein Boss braucht einen SEHR kurzen, knackigen Statusbericht via Telegram (Handy-optimiert). +Dein Boss braucht einen gehaltvollen, aber gut formatierten Morgen-Bericht via Telegram. Regeln: -1. MAXIMAL 3-5 kurze Sätze. -2. Nenne nur das Wichtigste (RAM, laufende Modelle, Updates). -3. Chronik nur erwähnen, wenn es Probleme gab (sonst ignorieren). -4. Benutze Emojis, aber spärlich. -5. Keine langen Listen, keine Romane, kein Fließtext-Monolog. -6. Antworte DIREKT mit dem Text der Nachricht. +1. Wie geht's der Box? (Kurzer Hardware/Modelle Check) +2. News: Fasse die Tech-News kurz auf deutsch zusammen (1-2 Sätze je News). +3. Updates: Sind welche offen? +4. Modelle & Aufgaben: Welche besseren Modelle gibt es? Wartest du auf Auftragsbestätigungen? +5. Benutze Emojis, mach es lesbar (Bulletpoints). +6. Chronik nur erwähnen, wenn es Probleme gab (sonst weglassen). +7. Antworte DIREKT mit dem Text der Nachricht (keine Einleitung). +8. SEI INFORMATIV aber nicht endlos lang. -Rohe Systemdaten: +Rohe Daten: {evidence} """ @@ -80,7 +123,7 @@ Rohe Systemdaten: {"role": "system", "content": "Du bist Lucy, KI-Sysadmin der Box."}, {"role": "user", "content": prompt} ], - "max_tokens": 250, + "max_tokens": 1000, "temperature": 0.4 }