feat: add news, discover models and auftragsbuch to sysadmin report
Ampel / ampel (push) Failing after 21s

This commit is contained in:
Hitonabi
2026-08-07 11:19:15 +02:00
parent 14f8a5f405
commit 5bc709221e
+53 -10
View File
@@ -6,7 +6,7 @@ import time
from datetime import datetime, timezone from datetime import datetime, timezone
import httpx import httpx
from services import maintenance, announce, llamaswap from services import maintenance, announce, llamaswap, auftragsbuch, discover
from config import V1_UPSTREAM from config import V1_UPSTREAM
log = logging.getLogger(__name__) 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 # Wenn aktiv, wird der Report um die angegebene Stunde (0-23) lokaler Zeit verschickt
SCHEDULE_HOUR = 8 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: async def generate_and_send_report() -> bool:
"""Sammelt System-Status, fragt das lokale LLM nach einer Zusammenfassung als Lucy und sendet via Telegram.""" """Sammelt System-Status, fragt das lokale LLM nach einer Zusammenfassung als Lucy und sendet via Telegram."""
log.info("Sysadmin-Report gestartet...") log.info("Sysadmin-Report gestartet...")
@@ -33,6 +49,26 @@ async def generate_and_send_report() -> bool:
running_models = llamaswap.get_running_models() 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) events = announce.list_recent(limit=15)
event_lines = [] event_lines = []
for e in events: 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. 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'} 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)} 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): Kürzliche Ereignisse (Chronik):
{events_str} {events_str}
""" """
prompt = f"""Du bist Lucy, die KI-Sysadmin der Box. 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: Regeln:
1. MAXIMAL 3-5 kurze Sätze. 1. Wie geht's der Box? (Kurzer Hardware/Modelle Check)
2. Nenne nur das Wichtigste (RAM, laufende Modelle, Updates). 2. News: Fasse die Tech-News kurz auf deutsch zusammen (1-2 Sätze je News).
3. Chronik nur erwähnen, wenn es Probleme gab (sonst ignorieren). 3. Updates: Sind welche offen?
4. Benutze Emojis, aber spärlich. 4. Modelle & Aufgaben: Welche besseren Modelle gibt es? Wartest du auf Auftragsbestätigungen?
5. Keine langen Listen, keine Romane, kein Fließtext-Monolog. 5. Benutze Emojis, mach es lesbar (Bulletpoints).
6. Antworte DIREKT mit dem Text der Nachricht. 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} {evidence}
""" """
@@ -80,7 +123,7 @@ Rohe Systemdaten:
{"role": "system", "content": "Du bist Lucy, KI-Sysadmin der Box."}, {"role": "system", "content": "Du bist Lucy, KI-Sysadmin der Box."},
{"role": "user", "content": prompt} {"role": "user", "content": prompt}
], ],
"max_tokens": 250, "max_tokens": 1000,
"temperature": 0.4 "temperature": 0.4
} }