fix: combine specialist tools with native web search
This commit is contained in:
@@ -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?"
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user