feat(tool-search): support opt-in built-in toolset deferral - #45147
feat(tool-search): support opt-in built-in toolset deferral#45147SJG613 wants to merge 2 commits into
Conversation
|
Note: I’m a first-time contributor, so the required workflows appear to be awaiting maintainer approval. |
|
Thanks — understood. I didn’t realize #43521 was already the canonical thread for config-gated built-in toolset deferral. Happy to close this PR if maintainers prefer consolidation there. If useful, this branch includes a small tested implementation, docs updates, and local measurements from a long-running gateway session:
Feel free to reuse any wording, tests, docs, measurements, or implementation details from this PR in #43521. |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for the focused implementation and documentation. The core approach matches the canonical #43521 discussion, but this branch needs an agent-runtime safety pass before it can be salvaged.
Problems
tools/tool_search.py:235-236permits any configured core-toolset member to defer. That includesmemoryandsession_search; however, currentagent/agent_init.py:1196-1198buildsvalid_tool_namesfrom the post-assembly schemas, andagent/system_prompt.py:221-225/agent/turn_context.py:309use that set to enable their guidance and memory nudge behavior.- Current bridge execution also unwraps calls in both executor paths (
agent/tool_executor.py:403-405,:1077-1079), in addition to direct dispatch. The PR's three-file scope predates those paths and does not exercise them.
Suggested changes
- Consolidate the implementation into #43521 with a protected always-direct runtime floor, or carry a distinct available-tool set through prompt construction.
- Add real agent/executor coverage for deferred memory and session-search tools.
Automated hermes-sweeper review.
| toolsets = _registered_toolsets_for_tool(name) | ||
|
|
||
| if name in _core_tool_names(): | ||
| return bool(toolsets & cfg.defer_builtin_toolsets) |
There was a problem hiding this comment.
This makes every core tool in a configured toolset deferrable, including memory and session_search. Current agent/agent_init.py:1196-1198 derives valid_tool_names from the post-assembly schemas, while agent/system_prompt.py:221-225 and agent/turn_context.py:309 gate their guidance/nudge behavior on that set. Please retain a protected runtime-tool floor or preserve an available-tool set for those gates.
What does this PR do?
Adds opt-in “tool suitcases” for built-in Hermes toolsets.
Hermes already supports progressive disclosure for MCP/plugin tools through the stable bridge:
tool_searchtool_describetool_callThis PR extends that pattern so selected built-in toolsets can also be deferred behind the bridge when explicitly configured.
This reduces always-visible tool schema size for long-running sessions without mutating provider-visible tools mid-conversation.
Type of Change
Changes Made
defer_builtin_toolsetsconfig for Tool Search.never_defer_toolsescape hatch for individual high-frequency tools.tool_search,tool_describe, andtool_callcan resolve opted-in built-in tools.Example
yaml
tools:
tool_search:
enabled: on
defer_builtin_toolsets:
- browser
- image_gen
- tts
never_defer_tools:
- browser_navigate
Why This Helps
Long-running Hermes sessions can accumulate many enabled tools. Their schemas are included in the model-visible tool list on every turn, even when only a few tools are relevant.
In one measured configuration:
This is especially useful for gateway sessions and broad personal-agent profiles where rarely used capabilities should remain available but not constantly occupy the active prompt.
How to Test
Targeted tests run locally:
bash
venv/bin/python -m pytest tests/tools/test_tool_search.py tests/test_get_tool_definitions_cache_isolation.py -q
Result:
text
50 passed, 1 warning
Full suite not run locally.
Safety / Compatibility
Credit / Origin
Originated from Steven Geller (
@SJG613) during a long-running Hermes/Matt Telegram session.The user-facing abstraction was “tool suitcases”: keep capability bundles packed until needed, use the right suitcase through a stable bridge, and avoid spreading every tool schema across the active context on every turn.