fix: automate cross-source media library audits

This commit is contained in:
Mikei386
2026-08-24 12:02:03 +02:00
parent 5008f3329c
commit 5834342f8c
9 changed files with 101 additions and 8 deletions
+10
View File
@@ -250,6 +250,16 @@ class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
result["tool_ids"], ["server:mcp:mua-readonly-local"] result["tool_ids"], ["server:mcp:mua-readonly-local"]
) )
async def test_readonly_unraid_media_audit_does_not_attach_admin_or_arr(self):
result = await self._select(
"Prüfe auf Unraid, welche Folgen meiner Hörspielserie Die drei Fragezeichen fehlen. "
"Nur lesen, ohne Downloads, Umbenennungen oder sonstige Änderungen."
)
self.assertEqual(
result["tool_ids"], ["server:mcp:mua-readonly-local"]
)
self.assertIn("unraid_files_inventory", result["messages"][0]["content"])
async def test_voice_transcription_variants_select_unraid(self): async def test_voice_transcription_variants_select_unraid(self):
result = await self._select( result = await self._select(
"Welche Dacher Contäner laufen aktuell auf dem Anrate Server?" "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 | | 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 | | 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 | | Operator-Kontext | `docs/QWEN_OPERATOR_CONTEXT.md` plus `config/operator-system-prompt.txt` | versionierte Selbstbeschreibung und Sicherheitsregeln für Qwen | Kern |
| Unraid/MUA | MUA r019+ auf dem HomeServer, direkter MCP-Endpunkt | read-only Automatik; Verwaltung bei explizitem Änderungsauftrag; idempotente Batch-Updates | Kern | | Unraid/MUA | MUA r020+ auf dem HomeServer, direkter MCP-Endpunkt | read-only Automatik; begrenzte Datei-/Medieninventare; Verwaltung bei explizitem Änderungsauftrag; idempotente Batch-Updates | Kern |
| Whisper | ggml-org/whisper.cpp | Service im Router-Deploy | optional | | 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 | | 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 | | TTS-Gateway | `platform/docker/tts-gateway/` | interne Queue, stabile deutsche Satzblöcke, automatische Erkennung rein englischer Texte und Piper-Fallback | Kern |
+6 -2
View File
@@ -189,8 +189,12 @@ Die Bereitstellung ersetzt niemals die ausdrückliche Änderungsanweisung.
Unraid ist ausschließlich über das MUA-Plugin angebunden. Die Verbindungen Unraid ist ausschließlich über das MUA-Plugin angebunden. Die Verbindungen
`mua-readonly-local` und `mua` nutzen denselben MUA-Endpunkt. Mehrere bestätigte `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 Docker-Updates laufen ab MUA r019 gebündelt und idempotent; echte Image-IDs
verhindern Neuerstellungen aufgrund eines veralteten Statuscaches. Der frühere verhindern Neuerstellungen aufgrund eines veralteten Statuscaches.
GraphQL-basierte Unraid-MCP wurde Ab MUA r020 inventarisiert `unraid_files_inventory` Datei- und Ordnernamen
begrenzt, ohne Dateiinhalte zu lesen. Auto Tool Selector 3.4 hält ausdrücklich
lesende Bibliotheksprüfungen bei MUA read-only und verwechselt Hörspielfolgen
nicht mit Sonarr-Episoden. Der Ablauf steht in
`docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md`. Der frühere GraphQL-basierte Unraid-MCP wurde
entfernt und gehört weder zum Start noch zum Recovery. entfernt und gehört weder zum Start noch zum Recovery.
Der GitHub-Container läuft produktiv. Token-Datei, interner Der GitHub-Container läuft produktiv. Token-Datei, interner
+3
View File
@@ -63,6 +63,9 @@ laufen, sondern alle fachlichen Funktionen geprüft wurden.
MUA read-only plus Verwaltung MUA read-only plus Verwaltung
- [ ] MUA r019 oder neuer meldet `unraid_docker_update_verified_batch`; ein - [ ] MUA r019 oder neuer meldet `unraid_docker_update_verified_batch`; ein
Wiederholungstest mit aktuellem Image endet ohne Container-Neuerstellung Wiederholungstest mit aktuellem Image endet ohne Container-Neuerstellung
- [ ] MUA r020 oder neuer meldet `unraid_files_inventory`; ein lesender
Medienauftrag aktiviert nur MUA read-only und kann einen Sammlungsordner
plus dessen Dateinamen in zwei begrenzten Aufrufen erfassen
- [ ] eine synthetische CSV wird lokal ausgewertet; kein Webwerkzeug erhält Dateidaten - [ ] eine synthetische CSV wird lokal ausgewertet; kein Webwerkzeug erhält Dateidaten
- [ ] ein rekursiver GitHub-Komplettbaum ist nicht als Werkzeug verfügbar - [ ] ein rekursiver GitHub-Komplettbaum ist nicht als Werkzeug verfügbar
- [ ] der zweite identische Werkzeugaufruf wird gestoppt und eine Abschlussantwort erzeugt - [ ] der zweite identische Werkzeugaufruf wird gestoppt und eine Abschlussantwort erzeugt
+3
View File
@@ -18,6 +18,9 @@ Reihenfolge ist absichtlich festgelegt:
bleiben read-only. Docker-Updates verwenden MUA r019 gebündelt, vergleichen bleiben read-only. Docker-Updates verwenden MUA r019 gebündelt, vergleichen
echte Image-IDs und erhalten den Laufzustand. Die Auswahl eines MCP ist echte Image-IDs und erhalten den Laufzustand. Die Auswahl eines MCP ist
ausdrücklich keine Freigabe für eine andere Zustandsänderung. ausdrücklich keine Freigabe für eine andere Zustandsänderung.
Medienbestandsprüfungen verwenden ab MUA r020 zuerst eine gezielte
Verzeichnissuche und danach ein Inventar des exakten relativen Pfads mit
`unraid_files_inventory`; wiederholte `ls`/`find`-Aufrufe sind nur Fallback.
4. `MikeAI Stability Guard`, Priorität 30: begrenzt einzelne und gesamte 4. `MikeAI Stability Guard`, Priorität 30: begrenzt einzelne und gesamte
Werkzeugresultate, verdichtet bei Bedarf zuerst alte Tool-Ausgaben und Werkzeugresultate, verdichtet bei Bedarf zuerst alte Tool-Ausgaben und
Dialogteile und stoppt identische beziehungsweise ausufernde Tool-Schleifen. Dialogteile und stoppt identische beziehungsweise ausufernde Tool-Schleifen.
+1 -1
View File
@@ -241,7 +241,7 @@ WireGuard-Adresse sind alle Fach-MCPs direkt erreichbar.
| Home Assistant | Zustände, Historie, Diagnose, begrenzte YAML-Abläufe | Lesen; Schreiben nur Preview/Approval | | Home Assistant | Zustände, Historie, Diagnose, begrenzte YAML-Abläufe | Lesen; Schreiben nur Preview/Approval |
| ARR | Sonarr/Radarr, Indexersuche, kontrollierte Grabs | Lesen; Schreiben nur Preview/Approval | | ARR | Sonarr/Radarr, Indexersuche, kontrollierte Grabs | Lesen; Schreiben nur Preview/Approval |
| Navidrome | Bibliothek, Empfehlungen, Playlists/Favoriten | eigener Benutzer; gezielt aktivieren | | Navidrome | Bibliothek, Empfehlungen, Playlists/Favoriten | eigener Benutzer; gezielt aktivieren |
| MUA read-only | Host-, Docker-, Array-, Netzwerk- und Logdiagnose | automatischer Standard | | MUA read-only | Host-, Docker-, Array-, Netzwerk-, Log- und begrenzte Datei-/Medieninventare | automatischer Standard |
| MUA/Admin | eng definierte Unraid-Verwaltung | bei ausdrücklich verlangter Änderung automatisch zusätzlich bereitgestellt | | 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 Für automatische Unraid-Diagnose existiert in Open WebUI zusätzlich
+57
View File
@@ -0,0 +1,57 @@
# Automatische Medienbestandsprüfung auf Unraid
Stand: 24. August 2026
## Zweck
Lokale Medienbestände können in einem Open-WebUI-Auftrag mit einer offiziellen
Online-Liste verglichen werden, ohne dass der Benutzer Werkzeuge nachträglich
einschaltet. Der Ablauf bleibt vollständig read-only.
## Werkzeugwahl
Der Auto Tool Selector 3.4 erkennt einen ausdrücklich lesenden Unraid-Auftrag
und stellt ausschließlich `mua-readonly-local` bereit. Wörter wie „Folgen
fehlen“ oder „Hörspielserie“ aktivieren nicht mehr fälschlich Sonarr/Radarr.
Formulierungen wie „ohne Änderungen“, „ohne Downloads“ und „keinerlei
Änderungen“ verhindern zuverlässig die Auswahl von MUA-Admin.
Die öffentliche Recherche erfolgt anschließend mit Open WebUIs nativen
Werkzeugen `search_web` und `fetch_url`.
## Dateiinventar
MUA r020 stellt `unraid_files_inventory` bereit. Das Werkzeug liest keine
Dateiinhalte und akzeptiert ausschließlich einen vorhandenen Unraid-Share plus
einen relativen Pfad unterhalb dieses Shares. Pfadtraversal, absolute Pfade und
Symlink-Verfolgung sind gesperrt. Tiefe, Trefferzahl und Zahl der untersuchten
Einträge sind begrenzt.
Empfohlener Ablauf:
1. `unraid_shares_list` nur dann verwenden, wenn der Share unbekannt ist.
2. Mit `unraid_files_inventory`, `name_contains` und nur Verzeichnissen die
passende Sammlung lokalisieren.
3. Den exakten zurückgegebenen `relative_path` in einem zweiten Aufruf ohne
Namensfilter inventarisieren.
4. Aus Dateinamen lokale Nummern/Titel extrahieren.
5. Offizielle Liste über native Websuche ermitteln und Differenz bilden.
6. Fehlende Titel beim gewünschten Anbieter gezielt verifizieren.
7. Fakten, Dateinamen-Schlussfolgerungen und Unsicherheiten getrennt ausgeben.
Die generische Nur-Lese-Shell ist nur ein Fallback, wenn das Inventarwerkzeug
die konkrete Frage nicht beantworten kann. Wiederholte `ls`/`find`-Ketten sind
für Bibliotheksprüfungen nicht vorgesehen.
## Regressionstest
Der ursprüngliche Lauf zur Reihe „Die drei ???“ brauchte nach dem Share-Fund
vier einzelne Shell-Aufrufe und verbrauchte das Werkzeugbudget vor dem
eigentlichen Datei- und Webabgleich. Dieser Fall ist der verbindliche
Regressionstest für Selector 3.4 und MUA r020:
- automatisch nur MUA read-only;
- höchstens zwei Inventaraufrufe für Lokalisierung und Bestand;
- danach native Webrecherche;
- keine Rückfrage, kein Download und keine Dateisystemänderung.
@@ -1,7 +1,7 @@
""" """
title: MikeAI Auto Tool Selector title: MikeAI Auto Tool Selector
author: MikeAI author: MikeAI
version: 3.3.0 version: 3.4.0
description: Selects a small, relevant set of MCP servers for each user request. description: Selects a small, relevant set of MCP servers for each user request.
""" """
@@ -99,6 +99,16 @@ class Filter:
"Do not ask the user to enable another tool: both required MUA " "Do not ask the user to enable another tool: both required MUA "
"capabilities are already attached to this request." "capabilities are already attached to this request."
) )
elif "unraid" in selected:
rule += (
" For bounded file or media-library inventory on Unraid, prefer "
"unraid_files_inventory over repeated ls/find shell calls. The "
"inventory tool can first locate matching collection directories; "
"then call it once more on the exact returned relative_path with an "
"empty name filter to inventory that collection. It never reads file "
"contents. Use the read-only shell only when that purpose-built tool "
"cannot answer."
)
messages = body.setdefault("messages", []) messages = body.setdefault("messages", [])
for message in messages: for message in messages:
if message.get("role") == "system" and isinstance(message.get("content"), str): if message.get("role") == "system" and isinstance(message.get("content"), str):
@@ -150,7 +160,9 @@ class Filter:
( (
r"\bsona(?:rr|r)?\b", r"\brada(?:rr|r)\b", r"\barr[- ]mcp\b", r"\bsona(?:rr|r)?\b", r"\brada(?:rr|r)\b", r"\barr[- ]mcp\b",
r"\b(?:staffel|episode|folge)(?:n)?\b.*\b" r"\b(?:staffel|episode|folge)(?:n)?\b.*\b"
r"(?:fehl|such|download|indexer|release|serie)\w*", r"(?:sonarr|radarr|indexer|release|fernsehserie|tv[- ]serie)\w*",
r"\b(?:sonarr|radarr|indexer|release|fernsehserie|tv[- ]serie)\w*\b.*\b"
r"(?:staffel|episode|folge)(?:n)?\b",
r"\b(?:serie|film)\b.*\b(?:sonarr|radarr|indexer|release)\b", r"\b(?:serie|film)\b.*\b(?:sonarr|radarr|indexer|release)\b",
), ),
) )
@@ -190,7 +202,8 @@ class Filter:
text, text,
( (
r"\b(?:nur|lediglich|ausschlie(?:ß|ss)lich)\b.{0,30}\b(?:pr[uü]f|anzeig|auflist|status|nachseh)\w*\b", 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(?:keine|keinerlei|nichts?)\b.{0,40}\b(?:[aä]nder|update|aktualisier|durchf[uü]hr|installier|download|umbenenn)\w*\b",
r"\bohne\b.{0,50}\b(?:[aä]nder|update|aktualisier|durchf[uü]hr|installier|download|umbenenn)\w*\b",
r"\b(?:nicht|nichts?)\b.{0,20}\b(?:durchf[uü]hr|ausf[uü]hr|aktualisier|installier)\w*\b", r"\b(?:nicht|nichts?)\b.{0,20}\b(?:durchf[uü]hr|ausf[uü]hr|aktualisier|installier)\w*\b",
), ),
): ):
+4 -1
View File
@@ -216,7 +216,9 @@ with con:
"MUA · Unraid-Diagnose (read-only)", "MUA · Unraid-Diagnose (read-only)",
"Automatisch verwendbarer, serverseitig in Open WebUI auf reine Lese- und " "Automatisch verwendbarer, serverseitig in Open WebUI auf reine Lese- und "
"Diagnosewerkzeuge begrenzter MUA-Zugang. Für Containerbestand, Logs, System, " "Diagnosewerkzeuge begrenzter MUA-Zugang. Für Containerbestand, Logs, System, "
"Storage, Shares und Netzwerkstatus. Keine Start/Stop-, Installations-, " "Storage, Shares, kompakte Datei-/Medieninventare und Netzwerkstatus. "
"Für Bibliotheksprüfungen unraid_files_inventory statt wiederholter "
"ls/find-Aufrufe verwenden. Keine Start/Stop-, Installations-, "
"Änderungs- oder freie Shell-Funktion. Bei einer ausdrücklich verlangten " "Änderungs- oder freie Shell-Funktion. Bei einer ausdrücklich verlangten "
"Änderung stellt die automatische Auswahl zusätzlich MUA-Verwaltung bereit.", "Änderung stellt die automatische Auswahl zusätzlich MUA-Verwaltung bereit.",
), ),
@@ -345,6 +347,7 @@ with con:
"unraid_system_health", "unraid_storage_status", "unraid_system_health", "unraid_storage_status",
"unraid_disk_health", "unraid_notifications_list", "unraid_disk_health", "unraid_notifications_list",
"unraid_shares_list", "unraid_share_inspect", "unraid_shares_list", "unraid_share_inspect",
"unraid_files_inventory",
"unraid_system_connection_test", "unraid_system_shell_readonly", "unraid_system_connection_test", "unraid_system_shell_readonly",
)) ))
readonly = copy.deepcopy(mua_source) readonly = copy.deepcopy(mua_source)