fix: automate cross-source media library audits
This commit is contained in:
@@ -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
@@ -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 |
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
),
|
),
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user