Skip to content

feat(tool_search): opt-in deferral for infrequent built-in toolsets - #61744

Closed
alexgunsberg wants to merge 1 commit into
NousResearch:mainfrom
alexgunsberg:feat/tool-search-defer-builtin-hotset
Closed

feat(tool_search): opt-in deferral for infrequent built-in toolsets#61744
alexgunsberg wants to merge 1 commit into
NousResearch:mainfrom
alexgunsberg:feat/tool-search-defer-builtin-hotset

Conversation

@alexgunsberg

Copy link
Copy Markdown

What does this PR do?

Tool Search already defers MCP/plugin tools behind tool_search / tool_describe / tool_call, but built-in toolsets always load. On MCP-light installs the built-in schemas are the entry tax (~15-20k tokens per turn).

This adds tools.tool_search.defer_toolsets: an explicit, default-empty list of built-in toolset names whose tools ride the existing bridge. Zero behavior change unless configured.

Why not invent a new mechanism?

Six open PRs already approach this (#60182, #43521, #45147, #53193, #42551, #41800). This is a focused rebased variant of the defer_toolsets design (#60182), with:

  • docs + DEFAULT_CONFIG + cli-config.yaml.example
  • hot-path acceptance test (terminal stays direct when browser/cron/delegation defer)
  • session byte-stability test (prompt-cache safety)
  • catalog source kind builtin for opted-in core tools

Measured impact (MCP-light personal install)

Config Tool schema tokens Saved
baseline / auto (no defer) 19928 0
enabled: on + recommended defer_toolsets 10770 46% (~9.2k tokens)
Telegram/CLI/cron platform sets, same config 17716 -> 10770 39%

Recommended opt-in (keeps terminal/file/web/skills/clarify/todo/memory/code_execution direct; leaves kanban direct for workers):

tools:
  tool_search:
    enabled: on   # auto@10% of 200k still needs ~20k deferrable; core opt-in alone is ~9.5k
    defer_toolsets:
      - browser
      - browser-cdp
      - cronjob
      - delegation
      - image_gen
      - tts
      - vision
      - homeassistant
      - computer_use
      - session_search

Capability catalog BM25 still finds cron, browser, delegation, image, TTS, Cursor, and X-search tools. Assemblies are byte-stable within a session.

Related

Type of Change

  • New feature (non-breaking; default empty)

How to Test

  1. scripts/run_tests.sh tests/tools/test_tool_search.py tests/test_get_tool_definitions_cache_isolation.py tests/test_model_tools.py -q (87 passed locally)
  2. With empty defer_toolsets, classification is identical to main
  3. With the recommended list + enabled: on, infrequent core schemas leave the tools array; hot path tools remain direct; bridge can describe/call deferred tools

Checklist

  • Conventional Commits
  • Focused files only
  • Tests added
  • Docs + DEFAULT_CONFIG + cli-config example updated
  • Cross-platform: pure Python/config, no OS paths

Extend the existing tool_search/tool_describe/tool_call progressive-
disclosure bridge so named built-in toolsets can ride it when
explicitly listed in tools.tool_search.defer_toolsets.

Default remains empty (core tools never defer). Recommended hot path
(terminal/file/web/skills/clarify/todo/memory/code_execution) stays
direct when only infrequent toolsets are opted in.

Measured on a typical MCP-light install with enabled=on:
~19.9k → ~10.8k tool-schema tokens (~46% reduction) while keeping
session tool_defs byte-stable across assemblies.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/tools Tool registry, model_tools, toolsets duplicate This issue or pull request already exists labels Jul 10, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Duplicate of #60182 (feat(tool_search): defer_toolsets, open, Fixes #60181). Both add the identical tools.tool_search.defer_toolsets config key with the same mechanism (named built-in toolsets ride the existing tool_search/tool_describe/tool_call bridge); this PR describes itself as a rebased variant of #60182's design. #60182 is the earlier open PR, so it's canonical. Related cluster (competing/different knobs): #60181, #45147, #42551, #53193, #41800.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the focused opt-in design and the default-empty compatibility posture.

Problems

  • tools/tool_search.py:206 reloads defer_toolsets from persisted config when a bridge call is dispatched. The active agent’s tools are assembled at initialization (agent/agent_init.py:1159-1163), so a later config edit can make a built-in tool disappear from the model-facing tools array but no longer qualify for tool_describe or tool_call. This conflicts with the session-stable toolset/cache invariant in AGENTS.md:19-23.

Suggested changes

  • Bind the resolved deferral set to the session tool snapshot and thread it through bridge dispatch and executor unwrapping rather than reloading config on each call.
  • Add a regression test that changes effective config after assembly and verifies the original session can still describe and invoke its deferred built-in tool.

This is an automated hermes-sweeper review.

Comment thread tools/tool_search.py
return False
# Check registry toolset for MCP prefix.
if defer_toolsets is None:
defer_toolsets = load_config().defer_toolsets

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reloads persisted config after the session’s agent.tools list has already been assembled. If defer_toolsets changes mid-session, a tool absent from that list can become ineligible for tool_describe/tool_call; please use a session-bound resolved deferral set instead.

@teknium1 teknium1 added sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users labels Jul 11, 2026
@alexgunsberg

Copy link
Copy Markdown
Author

Closing under Alex's zero-review autonomous delivery policy. Upstream grants this account read-only permission, so the PR cannot be auto-merged. The exact head commit is preserved on the alexgunsberg fork; no review action is requested from Alex.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tools Tool registry, model_tools, toolsets duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have sweeper:blast-contained Sweeper blast radius: contained — one narrow path / opt-in / few users sweeper:risk-caching Sweeper risk: may break/degrade prompt caching or cache-key stability (invariant) sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants