mateclaw/mateclaw-server
matevip 101aa3209e fix(skill): stop the LLM from calling skill names as tools (issue #46)
When a user-installed skill (e.g. RedisOps) was bound to an agent, the
model frequently called the skill name directly as a tool, hit
"Tool not found: RedisOps", and either gave up or fell back to shell
guessing. Two compounding causes:

1. The system prompt block injected by SkillRuntimeService listed each
   skill as `- **RedisOps** — desc`, which is the same format used for
   tool catalogs and primed the model to call the names directly. The
   "how to use" instructions referenced `read_skill_file` /
   `run_skill_script` — names that don't exist in the tool registry,
   so even a compliant LLM couldn't follow them.

2. ToolExecutionExecutor's `callback == null` branches returned a bare
   "Tool not found: <name>" string. The model had no recovery signal
   and no hint that the name it called was actually a skill.

Fix is two-layered:

- Prompt rewrite (SkillRuntimeService.buildSkillPromptEnhancement): lead
  with an explicit warning that skills are NOT directly callable, use the
  correct camelCase tool names (readSkillFile / runSkillScript), include
  a concrete worked example anchored to the first enabled skill, and
  render the listing as a markdown table so it stops looking like a
  callable tool list. listAvailableSkills tool description and output
  follow the same pattern.

- Runtime safety net (ToolExecutionExecutor): when toolCallbackMap.get
  misses, check if the requested name (case-insensitive) matches an
  active skill. If so, return a precise hint telling the LLM the right
  invocation pattern instead of the bare error. Wired through both the
  main execute path and the pre-approved replay path. SkillRuntimeService
  is attached via a setter from AgentGraphBuilder so the executor's many
  legacy constructors stay untouched, and it's nullable so isolated
  tests still work.

Adds 5 unit tests covering: skill match -> hint, case-insensitive match,
no-match -> bare error, no SkillRuntimeService wired -> bare error,
pre-approved replay path -> hint.

Reported and reproduced by @pipima9950-glitch in issue #46.
2026-04-30 16:36:30 +08:00
..
src fix(skill): stop the LLM from calling skill names as tools (issue #46) 2026-04-30 16:36:30 +08:00
Dockerfile build(docker): install poppler + tesseract for PDF extraction parity with Mac 2026-04-25 11:05:29 +08:00
pom.xml chore: bump spring boot 3.5.13 -> 3.5.14, spring ai 1.1.4 -> 1.1.5 2026-04-30 10:47:00 +08:00
settings.xml build(maven): declare US + CN repositories in pom.xml, drop opaque mirror 2026-04-25 09:56:17 +08:00