Skip to content

Python: accept newly discovered tools in client search results - #2768

Draft
adityachaudhry wants to merge 2 commits into
github:mainfrom
adityachaudhry:codex/client-tool-search-plumbing
Draft

adityachaudhry wants to merge 2 commits into
github:mainfrom
adityachaudhry:codex/client-tool-search-plumbing

Conversation

@adityachaudhry

@adityachaudhry adityachaudhry commented Sep 24, 2026 •

Copy link
Copy Markdown

Draft scope note: this prototype still requires an initialized deferred inventory and calls session.tools.set internally. It does not implement descriptor-only startup or carry new definitions directly in the pending search result. The intended no-startup-discovery, no-replacement-RPC flow requires changes to the CLI/runtime Responses provider, result schema, and dispatch registry before this is the complete solution.

A Python tool_search_tool override can discover tools that were not registered when the session started, but returning their names in tool_references does not register their definitions or handlers. Applications currently have to replace the external tool catalog through the low-level RPC and handle the new calls themselves.

This adds ToolResult(tools=[...]) for successful search overrides. The SDK preserves the existing catalog, registers new definitions and handlers before completing the search call, and forwards their names as tool references. The CLI can then emit a client tool_search_output and dispatch the discovered tools through the usual Python handlers.

async def search(invocation):
    discovered = await discover_tools(invocation.arguments)
    return ToolResult(tools=discovered)

Returned names must be new and unique; existing tools can be referenced with tool_references. Registration is serialized, definitions are JSON-validated before publishing local state, and an explicit RPC rejection rolls back the new handlers. Ambiguous transport failures retain handlers because the runtime may already have applied the update.

This uses the existing experimental session.tools.set RPC internally. It does not change the runtime's search activation rules: the CLI must already have an active deferred inventory. Descriptor-only startup without any initialized tools is a separate runtime limitation. Direct session.tools.set calls must not be mixed with this SDK-owned catalog.

Validation:

  • npm run check:python passed; 585 Python unit tests passed.
  • The callback/registration regression fails against unmodified main and passes with this change.
  • Live gpt-5.6-sol Responses runs on Copilot CLI 1.0.89-1 selected two different MCP servers from a five-server catalog. Each produced a client tool_search_call, callback-driven MCP discovery, a matching client tool_search_output with new function definitions, and SDK-dispatched MCP execution.
  • The personal POC uses normal MCP session configuration and the existing HTTP request hook to add native deferred MCP descriptors. Copilot initializes its MCP inventories at startup and applies its normal provider schema normalization. There is no unrelated activator server. The POC and logs are excluded from this PR.

Related to #1896. Python-only draft for API review and cross-language alignment.

@adityachaudhry adityachaudhry changed the title Python: register tools returned by tool search handlers Python: accept newly discovered tools in client search results Sep 24, 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.

1 participant