feat: add news, discover models and auftragsbuch to sysadmin report
Ampel / ampel (push) Failing after 21s
Ampel / ampel (push) Failing after 21s
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user