Introduce tool exposure for deferred registration (#22489)

## Why

Deferred tools were tracked with separate side-channel filtering after
tool specs had already been assembled. That made the registry
responsible for executing tools while the router/spec planner separately
decided whether those same tools should be exposed to the model up
front.

This PR makes exposure part of the tool handler contract so direct
versus deferred availability travels with the executable tool
registration.

Next step will be to simplify registration

## What Changed

- Adds `ToolExposure` to `codex-tools` and exposes it through
`ToolExecutor`, defaulting tools to `Direct`.
- Teaches dynamic tools and MCP handlers to mark deferred tools as
`Deferred` at construction time.
- Renames the registry object-safe wrapper from `AnyToolHandler` to
`RegisteredTool` and uses `ToolExposure` when deciding whether to
include a handler's spec in the initial model-visible tool list.
- Refactors tool spec planning to derive direct specs and deferred
search entries from registered handlers, removing the router's
special-case deferred dynamic tool filtering.

## Verification

- Not run.
This commit is contained in:
jif-oai
2026-05-13 18:16:51 +02:00
committed by GitHub
parent 889ee018e7
commit fdda59c00b
8 changed files with 100 additions and 105 deletions
+1
View File
@@ -79,6 +79,7 @@ pub use tool_discovery::ToolSearchSourceInfo;
pub use tool_discovery::collect_request_plugin_install_entries;
pub use tool_discovery::filter_request_plugin_install_discoverable_tools_for_client;
pub use tool_executor::ToolExecutor;
pub use tool_executor::ToolExposure;
pub use tool_output::JsonToolOutput;
pub use tool_output::ToolOutput;
pub use tool_payload::ToolPayload;
+12
View File
@@ -5,6 +5,14 @@ use crate::ToolName;
use crate::ToolOutput;
use crate::ToolSpec;
/// Controls whether a tool is exposed in the initial model-visible tool list
/// or registered for later discovery.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ToolExposure {
Direct,
Deferred,
}
/// Shared runtime contract for model-visible tools.
///
/// Implementations keep the model-visible spec tied to the executable runtime.
@@ -20,6 +28,10 @@ pub trait ToolExecutor<Invocation>: Send + Sync {
None
}
fn exposure(&self) -> ToolExposure {
ToolExposure::Direct
}
fn supports_parallel_tool_calls(&self) -> bool {
false
}