fix(brain): run_<skill> Tool-Namen safe escapen — Bindestriche kippten Tools-Liste

Beobachtung beim zweiten Live-Test (01:13:41): ARIA versuchte echten
Tool-Call `run_spotify` — bekam aber Error: 'No such tool available'.

Ursache: _skill_to_tool baute Tool-Namen via `run_{s['name']}`. Bei
Skills wie 'yt-dlp-download' wurde daraus 'run_yt-dlp-download' mit
Bindestrich. Anthropic-Tool-Name-Schema ist eigentlich [a-zA-Z0-9_-],
ABER der claude-max-api-proxy konvertiert intern auf OpenAI-Format
und faellt bei Bindestrichen um — wenn EIN Tool ungueltig ist, kippt
die GANZE Tool-Liste, ARIA sieht nichts von 'run_*' inklusive
'run_spotify' obwohl der ja Bindestrich-frei war.

Fix:
- _skill_to_tool: name = "run_" + re.sub(r"[^a-zA-Z0-9_]", "_", s["name"])
  → run_yt_dlp_download statt run_yt-dlp-download.
- Dispatcher: bei tool_name='run_X' wird zuerst X als skill_name probiert,
  bei Miss wird ueber die Liste der existierenden Skills gemappt — der
  Skill mit safe_name(name)==X wird dann genommen.
- Bypass-Lesson + Bypass-Section: gleiche safe-Logik fuer den
  empfohlenen run_<tool>-String im Memory/Prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:17:48 +02:00
parent 15f95ed196
commit 1ea7ab5ab1
2 changed files with 24 additions and 4 deletions
+2 -1
View File
@@ -164,8 +164,9 @@ def build_bypass_section(bypass_events: list[dict]) -> str:
sname = ev["skill_name"]
host = ev["host"]
count = ev["count"]
safe = re.sub(r"[^a-zA-Z0-9_]", "_", sname)
lines.append(f"- gegen **{host}** ({count}x kuerzlich) → nutze "
f"`run_{sname.replace('-', '_')}(...)` statt curl. "
f"`run_{safe}(...)` statt curl. "
f"Der Skill ist da. Nutze ihn.")
lines.append("")
return "\n".join(lines)