From 5528f3ab22c0dba94c3312e8ad5d39d4fb9bd436 Mon Sep 17 00:00:00 2001 From: Mikei386 <44135113+Mikei386@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:25:12 +0200 Subject: [PATCH] fix: combine specialist tools with native web search --- dev/test_openwebui_filters.py | 12 +++++ docs/CURRENT_REFERENCE.md | 8 +-- docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md | 13 ++--- .../openwebui/filters/auto_tool_selector.py | 51 +++++++++++++++++-- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/dev/test_openwebui_filters.py b/dev/test_openwebui_filters.py index b65fe60..90fb356 100644 --- a/dev/test_openwebui_filters.py +++ b/dev/test_openwebui_filters.py @@ -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?" diff --git a/docs/CURRENT_REFERENCE.md b/docs/CURRENT_REFERENCE.md index 262e803..7899da1 100644 --- a/docs/CURRENT_REFERENCE.md +++ b/docs/CURRENT_REFERENCE.md @@ -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. diff --git a/docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md b/docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md index 9b2ce78..dc858b0 100644 --- a/docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md +++ b/docs/UNRAID_MEDIA_AUDIT_WORKFLOW.md @@ -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. - diff --git a/platform/openwebui/filters/auto_tool_selector.py b/platform/openwebui/filters/auto_tool_selector.py index d6ac009..a25e066 100644 --- a/platform/openwebui/filters/auto_tool_selector.py +++ b/platform/openwebui/filters/auto_tool_selector.py @@ -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