🐾 fix: use the agents.yaml description as the send_message tool description #7

Merged
r merged 1 commits from fix/tool-description-from-agents-yaml into main 2026-08-03 17:53:49 +00:00
Owner

What

Every agent's send_message tool advertised the generic fallback — "Send a message to the scotty agent" — which tells an MCP client nothing about what the agent is for.

register_agent_tools resolves the tool description as tool_description → the @fast.agent decorator's description= → generic fallback. Pallas never passed tool_description, and no agent in the estate sets a decorator description — 0 of 34 agent modules across kottos, iolaus, mentor and dodona. So every agent everywhere landed on the fallback.

Meanwhile the description an operator actually wrote already lives in agents.yaml and is published in the registry. _start_agent had it in scope (it builds request_limits from the same entry dict) and simply never passed it through.

The fix

One line of wiring in _start_agent:

tool_description = entry.get("description") or None

Fixes every agent in every deployment at once, with no per-repo edits. Verified against Kottos's real agents.yaml — all six agents resolve to their actual descriptions:

harper         'Scrappy engineer — rapid prototyping, hacking, and creative problem-solving'
scotty         'Systems administration expert — infrastructure diagnostics, security hardening, and keeping everything running'
case           'Field systems agent — SD card imaging, LAN scanning, and storage operations on libra.helu.ca'
research       'Web search via Argos and knowledge graph via Neo4j'
tech_research  'Technical investigation — library comparisons, API docs, framework patterns, code examples'
dolores        'Browser operator — headed Chromium via Playwright MCP on the desktop host'

Precedence — note the direction

tool_description is checked first, so this makes agents.yaml win over a description= on the decorator. That's deliberate: agents.yaml is the deployment's source of truth for agent metadata, and an operator editing it shouldn't be silently overridden by a value buried in an agent module. It's also moot in practice right now, since nothing sets a decorator description — but the comment and docs state the order explicitly so the next person doesn't have to derive it.

Tests

New tests/test_tool_description.py, 8 tests pinning:

  • agents.yaml description reaches the tool
  • agents.yaml wins over the decorator; decorator still beats the fallback
  • empty/absent descriptions fall through rather than shadowing
  • {agent} is interpolated, and prose containing other braces (e.g. {"a": 1}) is not passed through .format() — that guard would otherwise raise KeyError

pytest tests/ -q84 passed.

Docs

agents.<name>.description in the field table now notes its second role, and a new "Tool description" subsection under send_message documents the resolution order.

Surfaced by r/daedalus#20, which makes tool descriptions visible in the agent panel instead of hiding them in a title= tooltip — the generic string is a lot more noticeable now that you can actually read it.

🤖 Generated with Claude Code

## What Every agent's `send_message` tool advertised the generic fallback — `"Send a message to the scotty agent"` — which tells an MCP client nothing about what the agent is for. `register_agent_tools` resolves the tool description as `tool_description` → the `@fast.agent` decorator's `description=` → generic fallback. Pallas never passed `tool_description`, and **no agent in the estate sets a decorator description** — 0 of 34 agent modules across `kottos`, `iolaus`, `mentor` and `dodona`. So every agent everywhere landed on the fallback. Meanwhile the description an operator actually wrote already lives in `agents.yaml` and is published in the registry. `_start_agent` had it in scope (it builds `request_limits` from the same `entry` dict) and simply never passed it through. ## The fix One line of wiring in `_start_agent`: ```python tool_description = entry.get("description") or None ``` Fixes every agent in every deployment at once, with no per-repo edits. Verified against Kottos's real `agents.yaml` — all six agents resolve to their actual descriptions: ``` harper 'Scrappy engineer — rapid prototyping, hacking, and creative problem-solving' scotty 'Systems administration expert — infrastructure diagnostics, security hardening, and keeping everything running' case 'Field systems agent — SD card imaging, LAN scanning, and storage operations on libra.helu.ca' research 'Web search via Argos and knowledge graph via Neo4j' tech_research 'Technical investigation — library comparisons, API docs, framework patterns, code examples' dolores 'Browser operator — headed Chromium via Playwright MCP on the desktop host' ``` ## Precedence — note the direction `tool_description` is checked **first**, so this makes `agents.yaml` win over a `description=` on the decorator. That's deliberate: `agents.yaml` is the deployment's source of truth for agent metadata, and an operator editing it shouldn't be silently overridden by a value buried in an agent module. It's also moot in practice right now, since nothing sets a decorator description — but the comment and docs state the order explicitly so the next person doesn't have to derive it. ## Tests New `tests/test_tool_description.py`, 8 tests pinning: - agents.yaml description reaches the tool - agents.yaml wins over the decorator; decorator still beats the fallback - empty/absent descriptions fall through rather than shadowing - `{agent}` is interpolated, and prose containing *other* braces (e.g. `{"a": 1}`) is not passed through `.format()` — that guard would otherwise raise `KeyError` `pytest tests/ -q` → **84 passed**. ## Docs `agents.<name>.description` in the field table now notes its second role, and a new "Tool description" subsection under `send_message` documents the resolution order. ## Related Surfaced by **r/daedalus#20**, which makes tool descriptions visible in the agent panel instead of hiding them in a `title=` tooltip — the generic string is a lot more noticeable now that you can actually read it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
r added 1 commit 2026-08-03 17:15:02 +00:00
Every agent's MCP tool advertised the generic "Send a message to the {agent}
agent" fallback, because register_agent_tools only had the @fast.agent
decorator's description to fall back on — and no agent in the estate sets one
(0 of 34 agent modules across kottos, iolaus, mentor and dodona).

Meanwhile the description an operator actually wrote already sits in
agents.yaml and is published in the registry; _start_agent had it in scope
and simply never passed it through. Wire it to tool_description.

Fixes every agent in every deployment at once, with no per-repo edits:
scotty's tool description becomes "Systems administration expert —
infrastructure diagnostics, security hardening, and keeping everything
running" instead of "Send a message to the scotty agent".

Adds tests/test_tool_description.py pinning the resolution order
(agents.yaml > decorator > fallback) and the {agent} templating, including
that prose containing other braces is not passed through .format().

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
r merged commit d528192bee into main 2026-08-03 17:53:49 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: r/pallas#7