fix: automate verified Unraid update workflows

This commit is contained in:
Mikei386
2026-08-24 11:28:49 +02:00
parent 5cb6079918
commit 5008f3329c
9 changed files with 199 additions and 24 deletions
+18
View File
@@ -232,6 +232,24 @@ class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
)
self.assertNotIn("server:mcp:mua", result["tool_ids"])
async def test_explicit_unraid_update_gets_read_and_management_tools(self):
result = await self._select(
"Prüfe auf Unraid alle Docker-Updates, führe die Updates durch und kontrolliere danach den Zustand."
)
self.assertEqual(
result["tool_ids"],
["server:mcp:mua-readonly-local", "server:mcp:mua"],
)
self.assertIn("single batched update workflow", result["messages"][0]["content"])
async def test_unraid_update_question_stays_readonly(self):
result = await self._select(
"Gibt es auf Unraid Updates für Docker-Container? Bitte nur prüfen."
)
self.assertEqual(
result["tool_ids"], ["server:mcp:mua-readonly-local"]
)
async def test_voice_transcription_variants_select_unraid(self):
result = await self._select(
"Welche Dacher Contäner laufen aktuell auf dem Anrate Server?"
+1 -1
View File
@@ -15,7 +15,7 @@
| Platform Context MCP | Athena-/MikeAI-Wissen, begrenzter Laufzeitsnapshot und kontrollierte Dokumentationspflege | eigener Container ohne Docker-Socket, Shell, Egress oder Secrets | Kern |
| Athena Operator MCP | Entwicklung und vollständiger Betrieb der KI-Plattform mit gebundenen Freigaben | unprivilegierte MCP-Fassade plus rootseitiger strukturierter Executor; keine freie Shell | Kern |
| Operator-Kontext | `docs/QWEN_OPERATOR_CONTEXT.md` plus `config/operator-system-prompt.txt` | versionierte Selbstbeschreibung und Sicherheitsregeln für Qwen | Kern |
| Unraid/MUA | MUA-Plugin auf dem HomeServer, direkter MCP-Endpunkt | read-only Automatik plus bewusst aktivierte Verwaltung in Open WebUI | Kern |
| Unraid/MUA | MUA r019+ auf dem HomeServer, direkter MCP-Endpunkt | read-only Automatik; Verwaltung bei explizitem Änderungsauftrag; idempotente Batch-Updates | Kern |
| Whisper | ggml-org/whisper.cpp | Service im Router-Deploy | optional |
| XTTS-v2 | Coqui, offizielles CUDA-12.1-Image per Digest | RTX-3060-Container, Stimme `Annmarie Nele`, CPML | Kern |
| TTS-Gateway | `platform/docker/tts-gateway/` | interne Queue, stabile deutsche Satzblöcke, automatische Erkennung rein englischer Texte und Piper-Fallback | Kern |
+10 -7
View File
@@ -180,14 +180,17 @@ Mehrdomänen-Aufgabe erhält automatisch ein begrenztes mittleres Reasoning-
Budget; einfache Aufgaben bleiben schnell. Allgemeine
Webrecherche erfolgt über Open WebUIs native `search_web`/`fetch_url`-Werkzeuge;
`web-local` ist nur noch manuell für Spezialfälle verfügbar. Dadurch bleiben
Fachkataloge klein und kurze Profile verlieren keinen unnötigen Kontext. MUA
mit erweiterten Verwaltungsrechten bleibt von der Automatik ausgeschlossen;
eine automatisch bereitgestellte Verbindung erteilt niemals Schreibrechte
oder eine Änderungsfreigabe.
Fachkataloge klein und kurze Profile verlieren keinen unnötigen Kontext. Reine
Unraid-Abfragen erhalten nur MUA read-only. Verlangt die aktuelle Nachricht
ausdrücklich eine Unraid-Änderung, stellt die Automatik zusätzlich den
Verwaltungszugang für die feste Kette Prüfen → Ändern → Verifizieren bereit.
Die Bereitstellung ersetzt niemals die ausdrückliche Änderungsanweisung.
Unraid ist ausschließlich über das MUA-Plugin angebunden. Die automatische
Verbindung `mua-readonly-local` und die bewusst aktivierte Verbindung `mua`
nutzen denselben MUA-Endpunkt. Der frühere GraphQL-basierte Unraid-MCP wurde
Unraid ist ausschließlich über das MUA-Plugin angebunden. Die Verbindungen
`mua-readonly-local` und `mua` nutzen denselben MUA-Endpunkt. Mehrere bestätigte
Docker-Updates laufen ab MUA r019 gebündelt und idempotent; echte Image-IDs
verhindern Neuerstellungen aufgrund eines veralteten Statuscaches. Der frühere
GraphQL-basierte Unraid-MCP wurde
entfernt und gehört weder zum Start noch zum Recovery.
Der GitHub-Container läuft produktiv. Token-Datei, interner
+5 -1
View File
@@ -58,7 +58,11 @@ laufen, sondern alle fachlichen Funktionen geprüft wurden.
- [ ] native OpenWebUI-Websuche funktioniert ohne `web-local`; Auto Tool Selector wählt GitHub, Home
Assistant, ARR, Navidrome, Unraid read-only, Athena-Plattformwissen und
den Athena Operator korrekt
- [ ] normale Unterhaltung erhält kein MCP; MUA wird niemals automatisch gewählt
- [ ] normale Unterhaltung erhält kein MCP; reine Unraid-Abfragen erhalten nur
MUA read-only; ausdrücklich verlangte Unraid-Änderungen erhalten automatisch
MUA read-only plus Verwaltung
- [ ] MUA r019 oder neuer meldet `unraid_docker_update_verified_batch`; ein
Wiederholungstest mit aktuellem Image endet ohne Container-Neuerstellung
- [ ] eine synthetische CSV wird lokal ausgewertet; kein Webwerkzeug erhält Dateidaten
- [ ] ein rekursiver GitHub-Komplettbaum ist nicht als Werkzeug verfügbar
- [ ] der zweite identische Werkzeugaufruf wird gestoppt und eine Abschlussantwort erzeugt
+5 -3
View File
@@ -13,9 +13,11 @@ Reihenfolge ist absichtlich festgelegt:
jüngste Nutzernachricht und stellt pro Anfrage höchstens drei passende MCPs
bereit. Er erkennt GitHub, Home Assistant, Sonarr/Radarr, Navidrome,
Unraid-Diagnose und Athena-Plattformwissen. Manuell gewählte Werkzeuge
bleiben erhalten. MUA mit erweiterten Verwaltungsrechten wird nie
automatisch zugeschaltet. Die Auswahl eines MCP ist ausdrücklich keine
Freigabe für eine Zustandsänderung.
bleiben erhalten. Bei einer ausdrücklich verlangten Unraid-Änderung werden
MUA-Diagnose und -Verwaltung gemeinsam bereitgestellt; reine Statusfragen
bleiben read-only. Docker-Updates verwenden MUA r019 gebündelt, vergleichen
echte Image-IDs und erhalten den Laufzustand. Die Auswahl eines MCP ist
ausdrücklich keine Freigabe für eine andere Zustandsänderung.
4. `MikeAI Stability Guard`, Priorität 30: begrenzt einzelne und gesamte
Werkzeugresultate, verdichtet bei Bedarf zuerst alte Tool-Ausgaben und
Dialogteile und stoppt identische beziehungsweise ausufernde Tool-Schleifen.
+10 -3
View File
@@ -242,16 +242,23 @@ WireGuard-Adresse sind alle Fach-MCPs direkt erreichbar.
| ARR | Sonarr/Radarr, Indexersuche, kontrollierte Grabs | Lesen; Schreiben nur Preview/Approval |
| Navidrome | Bibliothek, Empfehlungen, Playlists/Favoriten | eigener Benutzer; gezielt aktivieren |
| MUA read-only | Host-, Docker-, Array-, Netzwerk- und Logdiagnose | automatischer Standard |
| MUA/Admin | eng definierte Unraid-Verwaltung | bewusst aktivieren |
| MUA/Admin | eng definierte Unraid-Verwaltung | bei ausdrücklich verlangter Änderung automatisch zusätzlich bereitgestellt |
Für automatische Unraid-Diagnose existiert in Open WebUI zusätzlich
`mua-readonly-local`. Diese Verbindung nutzt denselben lokalen MUA-Endpunkt,
blendet aber Start/Stop, Installation, Änderungen und die freie Root-Shell
serverseitig in Open WebUI aus. Die vollständige Verbindung `mua` wird niemals
automatisch bereitgestellt.
serverseitig in Open WebUI aus. Die vollständige Verbindung `mua` wird nur bei
einer in der aktuellen Nachricht ausdrücklich verlangten Unraid-Änderung
zusätzlich bereitgestellt.
Es gibt keinen zweiten GraphQL-basierten Unraid-MCP. Schlägt MUA fehl, darf
nicht auf GraphQL ausgewichen oder dessen API eigenmächtig aktiviert werden.
Für mehrere Docker-Image-Updates ist
`unraid_docker_update_verified_batch` verbindlich. Es ersetzt wiederholte
Einzelaufrufe, vergleicht echte Image-IDs, erhält laufend/gestoppt und
verifiziert das Ergebnis im selben Aufruf. Details stehen in
`docs/UNRAID_AUTOMATIC_UPDATE_WORKFLOW.md`.
Der vorhandene Deemix-Dienst läuft auf Unraid und ist als externe Abhängigkeit
im Diensteverzeichnis eingetragen. Für ein Deemix-MCP wird standardmäßig nur
ein Relay auf Athena gebaut; ein zweites Deemix-Backend erfordert einen
+89
View File
@@ -0,0 +1,89 @@
# Automatischer Unraid-Docker-Updateablauf
Stand: 24. August 2026
## Ziel
Ein ausdrücklich formulierter Auftrag wie „prüfe die Docker-Updates auf Unraid,
führe bestätigte Updates aus und kontrolliere das Ergebnis“ muss in Open WebUI
ohne manuelles Aktivieren von Werkzeugen vollständig ablaufen.
## Automatische Werkzeugwahl
Der `MikeAI Auto Tool Selector` unterscheidet zwischen Lesen und Ändern:
- reine Status- oder Updatefragen erhalten nur `mua-readonly-local`;
- eine in der aktuellen Nachricht ausdrücklich verlangte Unraid-Änderung erhält
`mua-readonly-local` und `mua` gemeinsam;
- Formulierungen wie „nur prüfen“ oder „keine Änderungen“ unterdrücken den
Verwaltungszugang;
- die bereitgestellten Verbindungen sind keine allgemeine Freigabe. Der Auftrag
muss die konkrete Änderung selbst enthalten.
Der vorgesehene Ablauf lautet immer:
1. Zustand und Kandidaten read-only erfassen.
2. Die engste gebündelte Änderung ausführen.
3. Das Ergebnis read-only oder durch die gebündelte technische Verifikation
kontrollieren.
## Verbindliches Batch-Werkzeug
MUA r019 stellt `unraid_docker_update_verified_batch` bereit. Das Werkzeug
akzeptiert 1 bis 25 exakte, mit `|` getrennte Containernamen.
Für jeden Container liest es zunächst Container-ID, Image-ID und Laufzustand.
Danach zieht es das im Unraid-Benutzertemplate konfigurierte Image und
vergleicht die unveränderliche lokale Image-ID. Bereits aktuelle Container
werden vollständig übersprungen – auch wenn Unraids Statuscache noch ein Update
meldet. Nur bei tatsächlich geänderter Image-ID wird neu erstellt. Laufend
bleibt laufend, gestoppt bleibt gestoppt.
Die kompakte Nachkontrolle enthält Container- und Image-ID-Änderung,
Endzustand, RestartCount und Healthcheck-Status. Templates, Ports, Volumes und
Netzwerke werden nicht verändert. Eine vorhandene Freigabe des bisherigen
Einzelwerkzeugs `unraid_docker_update` aktiviert nach dem Upgrade automatisch
auch die sicherere Batch-Variante.
## Idempotenz
Der Cache `/var/lib/docker/unraid-update-status.json` ist nur ein
Kandidatenhinweis. Er darf nie allein eine Neuerstellung auslösen. Autoritativ
ist der Image-ID-Vergleich nach dem Pull.
Ein wiederholter Lauf muss bei einem aktuellen Image folgendes melden:
```text
result: already-current
recreated: false
container_id_changed: false
image_id_changed: false
```
## Produktiver Regressionstest vom 24. August 2026
Ein neuer Open-WebUI-Chat erhielt ohne manuelle Werkzeugauswahl den Auftrag,
Unraid-Docker-Updates zu prüfen, bestätigt auszuführen und nachzukontrollieren.
- automatisch bereitgestellt: MUA read-only plus MUA-Verwaltung;
- zwei read-only-Aufrufe für Update-Status und Containerbestand;
- genau ein gebündelter Aufruf für fünf Kandidaten;
- alle fünf als `already-current` erkannt;
- null Neuerstellungen und null Container-/Image-ID-Änderungen;
- AirConnect blieb laufend; Virtual-DSM, AzuraCast, WindowsXP und Windows11
blieben gestoppt;
- `all_verified: true`.
Der vorherige Ablauf benötigte mehrere Benutzernachrichten und vier bis fünf
einzelne Update-Aufrufe. Dieser Pfad ist ersetzt.
## Recovery-Prüfung
1. MUA-Health muss r019 oder neuer melden.
2. Open WebUI muss den Auto Tool Selector 3.3.0 oder neuer enthalten.
3. „Gibt es Docker-Updates auf Unraid? Nur prüfen“ darf nur MUA read-only
bereitstellen.
4. Ein ausdrücklich schreibender synthetischer Auftrag muss beide MUA-Zugänge
bereitstellen und das Batch-Werkzeug wählen.
5. Ein Wiederholungstest mit aktuellem Image darf keine Neuerstellung auslösen.
@@ -1,7 +1,7 @@
"""
title: MikeAI Auto Tool Selector
author: MikeAI
version: 3.2.0
version: 3.3.0
description: Selects a small, relevant set of MCP servers for each user request.
"""
@@ -27,6 +27,7 @@ class Filter:
"homeassistant": "server:mcp:homeassistant-local",
"arr": "server:mcp:arr-local",
"unraid": "server:mcp:mua-readonly-local",
"unraid_admin": "server:mcp:mua",
"navidrome": "server:mcp:navidrome-local",
"platform": "server:mcp:athena-platform",
"operator": "server:mcp:athena-operator-local",
@@ -37,6 +38,7 @@ class Filter:
"homeassistant": "Home Assistant",
"arr": "Sonarr/Radarr",
"unraid": "Unraid-Diagnose (MUA read-only)",
"unraid_admin": "Unraid-Verwaltung (MUA)",
"navidrome": "Navidrome",
"platform": "Athena-Plattformwissen",
"operator": "Athena Operator",
@@ -73,7 +75,7 @@ class Filter:
return ""
@staticmethod
def _add_system_rule(body: dict, labels: list[str]) -> None:
def _add_system_rule(body: dict, labels: list[str], selected: list[str]) -> None:
rule = (
"MikeAI automatic tool selection made these capabilities available for "
f"this request: {', '.join(labels)}. Availability is not authorization. "
@@ -86,6 +88,17 @@ class Filter:
"does not exist. Never compensate by planning or installing a duplicate backend; "
"stop and request clarification."
)
if "unraid" in selected and "unraid_admin" in selected:
rule += (
" This request explicitly asks for an Unraid state change. Use the "
"read-only MUA tools to establish evidence, then the narrowest MUA "
"management tool for the requested change, and finally read-only "
"verification. For multiple verified Docker image updates, prefer "
"the single batched update workflow; it preserves each container's "
"original running/stopped state and skips images already current. "
"Do not ask the user to enable another tool: both required MUA "
"capabilities are already attached to this request."
)
messages = body.setdefault("messages", [])
for message in messages:
if message.get("role") == "system" and isinstance(message.get("content"), str):
@@ -161,6 +174,27 @@ class Filter:
r"(?:unraid|unreid|unrate|anrate|homeserver|nas)\b",
),
)
unraid_write = unraid and self._matches(
text,
(
r"\b(?:update|updates|aktualisier\w*|upgrade\w*)\b.*\b(?:docker|cont[aä]iner|image|unraid)\b",
r"\b(?:docker|cont[aä]iner|image|unraid)\b.*\b(?:update|updates|aktualisier\w*|upgrade\w*)\b",
r"\b(?:start|stop|restart|starte|stoppe|beende|rebuild|reinitialisier|neu\s+erstell)\w*\b.*\bcont[aä]iner\b",
r"\bcont[aä]iner\b.*\b(?:start|stop|restart|starte|stoppe|beende|rebuild|reinitialisier|neu\s+erstell)\w*\b",
r"\b(?:installier|entfern|l[oö]sch|[aä]nder|modifizier)\w*\b.*\b(?:unraid|docker|cont[aä]iner)\b",
r"\b(?:unraid|docker|cont[aä]iner)\b.*\b(?:installier|entfern|l[oö]sch|[aä]nder|modifizier)\w*\b",
r"\bf[uü]hr\w*\b.*\bupdates?\b.*\b(?:durch|aus)\b",
),
)
if unraid_write and self._matches(
text,
(
r"\b(?:nur|lediglich|ausschlie(?:ß|ss)lich)\b.{0,30}\b(?:pr[uü]f|anzeig|auflist|status|nachseh)\w*\b",
r"\b(?:keine|nichts?)\b.{0,30}\b(?:[aä]nder|update|aktualisier|durchf[uü]hr|installier)\w*\b",
r"\b(?:nicht|nichts?)\b.{0,20}\b(?:durchf[uü]hr|ausf[uü]hr|aktualisier|installier)\w*\b",
),
):
unraid_write = False
github = self._matches(
text,
(
@@ -174,12 +208,27 @@ class Filter:
# trust domains (for example GitHub source + Unraid runtime + Home
# Assistant configuration). Attach each relevant specialist once;
# the evidence-plan rule keeps the model breadth-first and bounded.
if operator:
selected.append("operator")
if github:
selected.append("github")
# If a referenced backend already runs on Unraid, inventory that
# existing service before proposing Athena deployment. This keeps a
# generic "build an MCP" phrase from creating a duplicate backend.
if operator and not (
unraid
and self._matches(
text,
(
r"\bl[aä]uft\b.{0,60}\b(?:auf|in)\b.{0,30}\bunraid\b",
r"\b(?:auf|in)\b.{0,30}\bunraid\b.{0,60}\bl[aä]uft\b",
r"\bbereits\b.{0,80}\b(?:cont[aä]iner|dienst|backend)\b",
),
)
):
selected.append("operator")
if unraid:
selected.append("unraid")
if unraid_write:
selected.append("unraid_admin")
if homeassistant:
selected.append("homeassistant")
if arr:
@@ -244,6 +293,6 @@ class Filter:
body["reasoning_budget"] = self.valves.multidomain_reasoning_budget
labels = [self.LABELS[category] for category in selected]
self._add_system_rule(body, labels)
self._add_system_rule(body, labels, selected)
await self._notify(__event_emitter__, labels)
return body
+7 -4
View File
@@ -217,13 +217,16 @@ with con:
"Automatisch verwendbarer, serverseitig in Open WebUI auf reine Lese- und "
"Diagnosewerkzeuge begrenzter MUA-Zugang. Für Containerbestand, Logs, System, "
"Storage, Shares und Netzwerkstatus. Keine Start/Stop-, Installations-, "
"Änderungs- oder freie Shell-Funktion. Für bewusste Verwaltung MUA separat wählen.",
"Änderungs- oder freie Shell-Funktion. Bei einer ausdrücklich verlangten "
"Änderung stellt die automatische Auswahl zusätzlich MUA-Verwaltung bereit.",
),
"mua": (
"MUA (Unraid-Verwaltung)",
"Nur für ausdrücklich benötigte MUA-spezifische oder freigegebene Unraid-"
"Verwaltungsaktionen. Für reine Statusabfragen und Diagnosen die read-only-"
"MUA-Verbindung verwenden; niemals beide parallel ausprobieren.",
"Nur für vom Benutzer in der aktuellen Nachricht ausdrücklich verlangte "
"Unraid-Verwaltungsaktionen. Gemeinsam mit MUA read-only als geordnete "
"Kette verwenden: Zustand prüfen, engste Änderung ausführen, Ergebnis "
"read-only verifizieren. Für mehrere bestätigte Image-Updates immer den "
"gebündelten, zustandserhaltenden Updateablauf verwenden.",
),
"navidrome-local": (
"Navidrome (Musikbibliothek)",