Repository navigation
feat: load deferred tools on demand via tool.describe - #344
Merged
Merged
Conversation
Replace the tool_sources/known_tools/tool_providers mechanism from #339 with a deferred flag on Tool. Deferred tools are listed by name in the system prompt and loaded through tool.describe, which records a tool.loaded tape event; each request appends loaded tools after the direct tools. Code mode sees every allowed tool, deferred ones included. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bub | 71f6bf7 | Commit Preview URL Branch Preview URL |
Oct 07 2026, 11:15 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed and why
Progressive tool loading: tools are either loaded directly or deferred (loaded on demand). This replaces the
tool_sources/known_tools/tool_providersmechanism merged in #339 with a singledeferredflag onTool.Tool.deferred(also on@toolandTool.from_callable) marks a tool as loaded on demand.<deferred_tools>block.tool.describe(names)returns tool definitions and appends atool.loadedtape event with the newly loaded runtime names. It is exposed only when an allowed deferred tool exists.tool.loadedevents from the tape and appends those tools, in load order, after the direct tools.allowed_toolsfilters direct and deferred tools alike._run_once_stream, with code mode first. Non-preserved deferred tools go into the stub without loading, and deferral applies only to the remaining model-facing tools.before_tool_callrecovery checks the model-facing tools of the current request (plus code tools) and tells the model to calltool_describewhen it calls an unloaded deferred tool.Impacted modules
src/bub/tools.py:Tool.deferred; removedToolProvidersrc/bub/builtin/agent.py: removedtool_sources,known_tools,tool_providers,REQUEST_TOOLS_STATE_KEY; added_allowed_toolsand_prepare_deferred_toolssrc/bub/builtin/tools.py:tool.describe,loaded_tool_names,render_deferred_tools_promptsrc/bub/builtin/hook_impl.py: unknown-tool recovery scoped to the request toolsetbuild/tools.mdx(en and zh-cn)Breaking: plugins that use
Agent.tool_providers,Agent.tool_sourcesorAgent.known_toolsneed to register tools inAgent.toolswithdeferred=Trueinstead.Verification
uv run ruff check src tests: passeduv run mypy src: passeduv run pytest -q: 598 passed, 1 skippedtests/test_tool_providers.pyis replaced bytests/test_tool_loading.py, which covers loading and persistence across turns,allowed_toolsfiltering, hidingtool_describewhen there are no deferred tools, guidance for unloaded tools, and code-mode exposure.🤖 Generated with Claude Code