mirror of
https://github.com/openai/codex.git
synced 2026-10-21 09:54:56 +00:00
Reserve the tool_search namespace for the search tool (#37188)
## What changed - Remove namespace tools named `tool_search` before registering the built-in search tool, preventing them from sharing its model-visible surface. - Record removed namespace tools as collisions so strict collision handling reports their qualified tool names. ## Testing - Cover direct and deferred MCP tools that use the reserved namespace. - Cover strict collision errors for both direct and deferred conflicts. GitOrigin-RevId: 28fff918b4358a67b167467d92728fa545b951d7
This commit is contained in:
@@ -342,7 +342,23 @@ pub(crate) fn finalize_tool_router(
|
||||
})
|
||||
{
|
||||
if registry.remove(&tool_search_name).is_some() {
|
||||
registry.record_collision(tool_search_name);
|
||||
registry.record_collision(tool_search_name.clone());
|
||||
}
|
||||
// Special model tools own the namespace matching their wire identity, so
|
||||
// regular namespace tools cannot advertise that same model-visible surface.
|
||||
let conflicting_tool_names = registry
|
||||
.entries()
|
||||
.filter_map(|tool| {
|
||||
let ToolSpec::Namespace(namespace) = tool.runtime.spec() else {
|
||||
return None;
|
||||
};
|
||||
(namespace.name == tool_search_name.name).then(|| tool.runtime.tool_name())
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
for tool_name in conflicting_tool_names {
|
||||
if registry.remove(&tool_name).is_some() {
|
||||
registry.record_collision(tool_name);
|
||||
}
|
||||
}
|
||||
append_tool_search_executor(turn_context, &mut registry, tool_search_handler_cache);
|
||||
}
|
||||
|
||||
@@ -1161,6 +1161,50 @@ async fn mcp_and_tool_search_follow_direct_and_deferred_tool_exposure() {
|
||||
"tool_search",
|
||||
&ToolName::namespaced("mcp__searchable", "lookup").to_string(),
|
||||
]);
|
||||
|
||||
let reserved_namespace = probe_with(
|
||||
|turn| {
|
||||
set_feature(turn, Feature::CodeMode, /*enabled*/ true);
|
||||
turn.model_info.supports_search_tool = true;
|
||||
},
|
||||
ToolPlanInputs {
|
||||
tool_runtimes: vec![
|
||||
mcp_runtime(
|
||||
"reserved_direct",
|
||||
"tool_search",
|
||||
"inspect",
|
||||
ToolExposure::Direct,
|
||||
),
|
||||
mcp_runtime(
|
||||
"reserved_deferred",
|
||||
"tool_search",
|
||||
"tool_search_tool",
|
||||
ToolExposure::Deferred,
|
||||
),
|
||||
mcp_runtime(
|
||||
"searchable",
|
||||
"mcp__searchable",
|
||||
"lookup",
|
||||
ToolExposure::Deferred,
|
||||
),
|
||||
],
|
||||
..ToolPlanInputs::default()
|
||||
},
|
||||
)
|
||||
.await;
|
||||
reserved_namespace.assert_visible_contains(&["tool_search"]);
|
||||
reserved_namespace.assert_registered_contains(&[
|
||||
"tool_search",
|
||||
&ToolName::namespaced("mcp__searchable", "lookup").to_string(),
|
||||
]);
|
||||
reserved_namespace.assert_registered_lacks(&[
|
||||
&ToolName::namespaced("tool_search", "inspect").to_string(),
|
||||
&ToolName::namespaced("tool_search", "tool_search_tool").to_string(),
|
||||
]);
|
||||
assert!(matches!(
|
||||
reserved_namespace.visible_spec("tool_search"),
|
||||
ToolSpec::ToolSearch { .. }
|
||||
));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -1301,6 +1345,37 @@ async fn strict_tool_collisions_reject_external_and_synthetic_duplicates() {
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"tool_search.tool_search_tool",
|
||||
ToolPlanInputs {
|
||||
tool_runtimes: vec![mcp_runtime(
|
||||
"reserved",
|
||||
"tool_search",
|
||||
"tool_search_tool",
|
||||
ToolExposure::Deferred,
|
||||
)],
|
||||
..ToolPlanInputs::default()
|
||||
},
|
||||
false,
|
||||
true,
|
||||
),
|
||||
(
|
||||
"tool_search.inspect",
|
||||
ToolPlanInputs {
|
||||
tool_runtimes: vec![
|
||||
mcp_runtime("reserved", "tool_search", "inspect", ToolExposure::Direct),
|
||||
mcp_runtime(
|
||||
"searchable",
|
||||
"mcp__searchable",
|
||||
"lookup",
|
||||
ToolExposure::Deferred,
|
||||
),
|
||||
],
|
||||
..ToolPlanInputs::default()
|
||||
},
|
||||
false,
|
||||
true,
|
||||
),
|
||||
];
|
||||
|
||||
let namespace_cases = [
|
||||
|
||||
Reference in New Issue
Block a user