Skip to content

feat(tool): add on-demand tool search with native provider loading - #3680

Merged
jujn merged 3 commits into
agentscope-ai:mainfrom
iluv7:feat/tool-search
Oct 28, 2026
Merged

jujn merged 3 commits into
agentscope-ai:mainfrom
iluv7:feat/tool-search

Conversation

@iluv7

@iluv7 iluv7 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.1.0-SNAPSHOT

Description

Closes #3622.

Agents with many registered tools currently expose their full tool catalog to the model. This PR adds opt-in tool discovery: the model first searches for the capability it needs, then calls a discovered tool through the existing execution and permission path.

Search and provider-specific loading are separate. The default search runs locally using keywords; OpenAI Responses and Anthropic receive the results through their native client-side loading protocols. Other models use ordinary function calling.

Search API and default strategy

ToolSearchMiddleware registers the read-only tool_search tool, with a required query and an optional positive limit (default 5). Applications enable discovery on an existing toolkit:

Toolkit toolkit = new Toolkit();
toolkit.registerTool(new OrderTools());

ReActAgent agent = ReActAgent.builder()
        .name("orders")
        .model(model)
        .toolkit(toolkit)
        .middleware(new ToolSearchMiddleware(toolkit))
        .build();

KeywordToolSearchStrategy provides dependency-free, case-insensitive matching over tool names and descriptions. Name matches receive a higher score; results are ordered by relevance and limited to the requested count.

Applications can supply a ToolSearchStrategy returning Mono<ToolSearchResult>. Its request contains the current eligible tool schemas, conversation messages, query, and limit. This allows vector search, a remote index, or a JEV-backed implementation without coupling core to those dependencies. This PR implements only the keyword strategy.

Visibility, session state, and permissions

Initially, only search and configured always-visible tools are available for model use. Structured-output and explicitly forced tools remain visible. Discovered names accumulate in ToolContextState and survive state serialization without changing the serialized form of empty legacy state.

Candidates respect the current request's tool groups and overrides. Strategy results are validated against that catalog, deduplicated, and limited before updating session state. Native search history is revalidated against current schemas so removed tools are excluded and overrides take effect without modifying stored messages. Previously discovered tools remain available after history compaction or a change of loading protocol.

Discovery does not bypass permission checks or replace tool execution. Searches retain reactive cancellation, and session discoveries remain in call-scoped state.

Native provider loading

Model Loading behavior
OpenAI Responses Declares client-executed native search, handles tool_search_call locally, and returns discovered definitions in tool_search_output. Streaming and non-streaming calls use the same representation.
Anthropic Sends eligible definitions with defer_loading and returns matches as tool_reference blocks. The full catalog is still sent in requests; deferred definitions enter model context when loaded.
Other models Adds discovered schemas to subsequent requests through ordinary function calling.

Native loading can be disabled through the middleware constructor. The adapters reuse the existing official Java SDK dependencies; no new dependencies or version changes are required.

OpenAI's existing hosted search remains a separate option and cannot be combined with client-executed search in one request. This contribution does not add provider-hosted search algorithms as local strategies. Anthropic prompt-cache markers are placed on the last non-deferred client tool. Native loading avoids routinely appending each discovery to the top-level tool declarations, but does not guarantee provider cache hits.

Documentation and validation

The PR adds an executable offline discovery-to-execution example and updates the English and Chinese tool, OpenAI, and Anthropic guides.

  • Added 16 test cases covering ranking, validation, session isolation and restoration, catalog changes, history compaction, permission allow/deny behavior, native request/response mapping, streaming, and discovery followed by execution through a real ReAct loop with mocked models.
  • Full 97-module reactor: mvn -B -T1 verify -fae passed. After the final history and strict-schema adjustments, spotless:apply verify passed again for core and both affected provider modules with -am: 3,283 test cases, 12 conditional skips, zero failures or errors.
  • Documentation tests (13 tests), validation, and broken-link checks passed. The offline example was compiled and run on Java 17. git diff --check passed.

An earlier clean verification hit an unrelated Harness session-writer fencing failure; its isolated test passed on rerun, followed by the successful full reactor verification above. Live provider API calls have not been exercised; provider protocol coverage uses SDK objects and local mocks.

@mintlify

mintlify Bot commented Oct 28, 2026

Copy link
Copy Markdown

Preview approval required

This pull request comes from a fork, so Mintlify won't build a preview until someone with write access approves commit 3aeed87.

Approve preview

@jujn
jujn merged commit 4b6c59a into agentscope-ai:main Oct 28, 2026
5 of 6 checks passed
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.

[Feature]: Support built-in tool_search tool

2 participants