Guide tool search toward `load_capability`

Draft
AD
3mo ago
+226-21

Related to #5230.

Summary

  • Clarify that search_tools discovers deferred tools that are not capability-owned, while capability-owned tools require load_capability first.
  • When the built-in keyword search returns no directly searchable tools but the query matches tools behind unloaded capabilities, append a tagged SystemPromptPart naming up to three relevant capability IDs.
  • Keep the provider tool-search return schema, capability gating, and custom search-callable behavior unchanged.

Why an appended system message

The provider-native tool-search result schema has no supported field for capability suggestions. Putting this guidance in a separate append-only message avoids inventing wire keys, works through the existing provider message mapping, and does not mutate the stable instruction/cache prefix.

Harness boundary

Core owns this recovery because it controls capability gating and the normalized/provider message transcript. Harness can continue to announce tools after successful dynamic discovery; it should not duplicate this empty-search recovery. Together, the model sees either a successful discovery announcement or an explicit route back to load_capability, rather than an unexplained empty result.

Validation

  • uv run pytest tests/test_tool_search.py -q (199 passed)
  • uv run pytest tests/test_capabilities.py -q (835 passed)
  • PYRIGHT_PYTHON_IGNORE_WARNINGS=1 uv run pyright pydantic_ai_slim/pydantic_ai/toolsets/_tool_search.py tests/test_tool_search.py
  • pre-commit format, lint, cassette, and hygiene hooks

The repository-wide typecheck could not run in the isolated worktree because unrelated optional Harness/provider dependencies were unavailable; the changed implementation and test files pass targeted Pyright.

Checklist

  • Any AI generated code has been reviewed line-by-line by the human PR author, who stands by it.
  • No breaking changes in accordance with the version policy.
  • PR title is fit for the release changelog.