Skip to content

refactor: separate tool discovery from request preparation - #339

Open
PsiACE wants to merge 7 commits into
mainfrom
refactor/unified-tool-catalogs
Open

PsiACE wants to merge 7 commits into
mainfrom
refactor/unified-tool-catalogs

Conversation

@PsiACE

@PsiACE PsiACE commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Keep the existing ToolProvider abstraction and call signatures. Register discovery inventories separately, resolve allowlists against known names, run caller providers in supplied order, and prepare builtin code mode last. Source registration determines duplicate-name precedence independently of provider order.

Register selected original declarations for execution while using provider-transformed definitions for each request. Builtins stay immediate; commands and subagents can resolve unloaded tools.

Relative to main, production changes are limited to builtin/agent.py and the subagent resolver (26 additions, 6 deletions). ToolProvider, code-mode implementation, skills and system prompt remain unchanged. Independent prompt/cache experiments are excluded.

Validation: 572 core tests, 701 contrib tests against this core, Ruff, mypy, lock validation and EN/ZH docs build passed. Behavioral ablations cover discovery, execution registration, final builtin preparation and transformed provider definitions.

Companion: bubbuild/bub-contrib#74.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bub 9865408 Commit Preview URL

Branch Preview URL
Oct 04 2026, 01:20 AM

@PsiACE
PsiACE marked this pull request as ready for review October 1, 2026 18:23
@frostming

Copy link
Copy Markdown
Collaborator

I suggest keeping the original ToolProvider abstraction for request-time tool preparation:

ToolProvider = Callable[[list[Tool], Tape], Awaitable[tuple[list[Tool], str]]]

ToolCatalog currently combines two responsibilities: declaring tools for discovery/allowlist resolution, and transforming the scoped tools for a model request. DirectToolCatalog only supplies definitions and has a no-op prepare(), while CodeModeCatalog only transforms the toolset and declares an empty tools mapping. These implementations suggest that the two responsibilities do not need one shared abstraction.

Knowing tool names before allowed_tools filtering is useful, especially for MCP and deferred exposure. Please keep that capability through an explicit tool-registration/discovery mechanism, while using ToolProvider for selection, deferred exposure, and prompt fragments. Providers should continue to respect the filtered scope.

For preparation order, run caller-supplied providers in their supplied order, then the builtin preparation (including code mode) last. Keep duplicate-name precedence separate from preparation order. This preserves the simpler extension API and lets builtin preparation operate on the final toolset without introducing catalogs for every processing stage.

@PsiACE PsiACE changed the title refactor: unify tool discovery and preparation in catalogs refactor: separate tool discovery from request preparation Oct 4, 2026

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants