fix: combine specialist tools with native web search

This commit is contained in:
Mikei386
2026-08-24 12:25:12 +02:00
parent 5834342f8c
commit 5528f3ab22
4 changed files with 71 additions and 13 deletions
+12
View File
@@ -260,6 +260,18 @@ class AutoToolSelectorTests(unittest.IsolatedAsyncioTestCase):
)
self.assertIn("unraid_files_inventory", result["messages"][0]["content"])
async def test_unraid_media_audit_with_deezer_enables_native_web(self):
result = await self._select(
"Prüfe auf Unraid, welche Folgen meiner Hörspielserie fehlen, ermittle die "
"aktuelle offizielle Liste online und prüfe jede fehlende Folge bei Deezer. "
"Nur lesen, ohne Downloads oder Änderungen."
)
self.assertEqual(result["tool_ids"], ["server:mcp:mua-readonly-local"])
self.assertTrue(result["features"]["web_search"])
self.assertTrue(result["metadata"]["features"]["web_search"])
self.assertIn("search_web/fetch_url", result["messages"][0]["content"])
self.assertEqual(result["reasoning_effort"], "medium")
async def test_voice_transcription_variants_select_unraid(self):
result = await self._select(
"Welche Dacher Contäner laufen aktuell auf dem Anrate Server?"
+5 -3
View File
@@ -190,10 +190,12 @@ 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.
Ab MUA r020 inventarisiert `unraid_files_inventory` Datei- und Ordnernamen
begrenzt, ohne Dateiinhalte zu lesen. Auto Tool Selector 3.4 hält ausdrücklich
Ab MUA r021 inventarisiert `unraid_files_inventory` Datei- und Ordnernamen
begrenzt, ohne Dateiinhalte zu lesen, und beendet eine gefilterte Erkennung an
einem passenden Sammlungsordner. Auto Tool Selector 3.5 hält ausdrücklich
lesende Bibliotheksprüfungen bei MUA read-only und verwechselt Hörspielfolgen
nicht mit Sonarr-Episoden. Der Ablauf steht in
nicht mit Sonarr-Episoden. Verlangt derselbe Auftrag aktuelle Onlinebelege,
aktiviert er zusätzlich die native Websuche. 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.
+7 -6
View File
@@ -10,18 +10,20 @@ einschaltet. Der Ablauf bleibt vollständig read-only.
## Werkzeugwahl
Der Auto Tool Selector 3.4 erkennt einen ausdrücklich lesenden Unraid-Auftrag
Der Auto Tool Selector 3.5 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`.
Verlangt derselbe Auftrag aktuelle Online- oder Streaming-Belege, aktiviert der
Selector zusätzlich Open WebUIs native Werkzeuge `search_web` und `fetch_url`.
Damit ist MUA plus Websuche ein einziger automatischer Mischauftrag; der alte
Web-MCP wird dafür nicht benötigt.
## Dateiinventar
MUA r020 stellt `unraid_files_inventory` bereit. Das Werkzeug liest keine
MUA r021 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
@@ -48,10 +50,9 @@ für Bibliotheksprüfungen nicht vorgesehen.
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:
Regressionstest für Selector 3.5 und MUA r021:
- 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
author: MikeAI
version: 3.4.0
version: 3.5.0
description: Selects a small, relevant set of MCP servers for each user request.
"""
@@ -74,6 +74,19 @@ class Filter:
return str(content)
return ""
def _needs_native_web(self, raw_text: str) -> bool:
"""Return whether this request explicitly requires current public-web evidence."""
text = self._normalise(raw_text)
return self._matches(
text,
(
r"\b(?:web|internet|online|websuche|webrecherche)\b",
r"\b(?:such|recherchier|pr[uü]f|schau)\w*\b.{0,80}\b(?:netz|web|internet|online)\b",
r"\b(?:deezer|youtube|makerworld|wikipedia|docker\s*hub)\b",
r"\b(?:aktuell|neueste|heute|bis heute)\w*\b.{0,100}\b(?:quelle|liste|verf[uü]gbar|erschienen|video|folge)\w*\b",
),
)
@staticmethod
def _add_system_rule(body: dict, labels: list[str], selected: list[str]) -> None:
rule = (
@@ -277,8 +290,25 @@ class Filter:
if not self.valves.enabled:
return body
selected = self._classify(self._latest_user_text(body))
latest_text = self._latest_user_text(body)
selected = self._classify(latest_text)
needs_native_web = self._needs_native_web(latest_text)
if not selected and not needs_native_web:
return body
if needs_native_web:
features = body.setdefault("features", {})
if isinstance(features, dict):
features["web_search"] = True
metadata = body.setdefault("metadata", {})
if isinstance(metadata, dict):
metadata_features = metadata.setdefault("features", {})
if isinstance(metadata_features, dict):
metadata_features["web_search"] = True
if not selected:
if needs_native_web:
await self._notify(__event_emitter__, ["native Websuche"])
return body
existing = body.get("tool_ids")
@@ -298,7 +328,7 @@ class Filter:
# never overwritten.
if (
self.valves.enable_multidomain_reasoning
and len(selected) >= 2
and len(selected) + int(needs_native_web) >= 2
and body.get("reasoning_effort") in (None, "", "none")
):
body["reasoning_effort"] = self.valves.multidomain_reasoning_effort
@@ -306,6 +336,19 @@ class Filter:
body["reasoning_budget"] = self.valves.multidomain_reasoning_budget
labels = [self.LABELS[category] for category in selected]
self._add_system_rule(body, labels, selected)
if needs_native_web:
labels.append("native Websuche")
if selected:
self._add_system_rule(body, labels, selected)
if needs_native_web:
for message in body.get("messages", []):
if message.get("role") == "system" and isinstance(message.get("content"), str):
message["content"] += (
" Native Open WebUI web search is also enabled for this request. "
"After collecting local or specialist-tool evidence, continue with "
"search_web/fetch_url for current public evidence; do not stop merely "
"because no separate web MCP appears in the MCP tool list."
)
break
await self._notify(__event_emitter__, labels)
return body