Remove unavailable MCP placeholder tool backfill (#22439)

## Why

`UnavailableDummyTools` kept synthetic placeholder tools alive for
historical tool calls whose backing MCP tool was no longer available.
That path adds stale model-visible tool specs and special routing at the
point where unavailable MCP calls should use ordinary current-tool
handling. This removes the runtime backfill instead of preserving a
second compatibility lane.

## Is it safe to remove?

The unavailable tools were added in #17853 after a CS issue when a
previously-called MCP tool failed to load and was omitted from the CS
spec. Now that we have tool search, I think this is resolved:
- API merges tools from previous TST output into effective tool set so
theyre always in CS spec
- if an MCP tool surfaced by TST later becomes unavailable, the model
can still call it and it will just return model-visible error
- both TST output and function call output are dropped on compaction so
model will not remember old calls to MCP post compaction

## What changed

- Delete unavailable-tool collection, placeholder handler, router/spec
plumbing, and obsolete placeholder coverage.
- Keep `features.unavailable_dummy_tools` as a removed no-op feature
tombstone so existing configs still parse cleanly.
- Add an integration-style `tool_search` regression test showing that a
deferred MCP tool surfaced through `tool_search` still routes through
MCP and returns a model-visible tool-call error rather than `unsupported
call`.

## Verification

- `cargo test -p codex-core tool_search`
This commit is contained in:
sayan-oai authored and GitHub committed 2026-05-12 23:30:13 -07:00
1 parent 2630a6ca35
commit 2304ec45ca
14 files changed
+161 -502

No files matched your search

-5
View File
@@ -97,7 +97,6 @@ async fn parallel_support_does_not_match_namespaced_local_tool_names() -> anyhow
ToolRouterParams {
deferred_mcp_tools: None,
mcp_tools: Some(mcp_tools),
unavailable_called_tools: Vec::new(),
discoverable_tools: None,
extension_tool_bundles: Vec::new(),
dynamic_tools: turn.dynamic_tools.as_slice(),
@@ -177,7 +176,6 @@ async fn mcp_parallel_support_uses_handler_data() -> anyhow::Result<()> {
"query_with_delay",
),
]),
unavailable_called_tools: Vec::new(),
discoverable_tools: None,
extension_tool_bundles: Vec::new(),
dynamic_tools: turn.dynamic_tools.as_slice(),
@@ -213,7 +211,6 @@ async fn tools_without_handlers_do_not_support_parallel() -> anyhow::Result<()>
ToolRouterParams {
deferred_mcp_tools: None,
mcp_tools: None,
unavailable_called_tools: Vec::new(),
discoverable_tools: None,
extension_tool_bundles: Vec::new(),
dynamic_tools: turn.dynamic_tools.as_slice(),
@@ -266,7 +263,6 @@ async fn specs_filter_deferred_dynamic_tools() -> anyhow::Result<()> {
ToolRouterParams {
deferred_mcp_tools: None,
mcp_tools: None,
unavailable_called_tools: Vec::new(),
discoverable_tools: None,
extension_tool_bundles: Vec::new(),
dynamic_tools: &dynamic_tools,
@@ -323,7 +319,6 @@ async fn extension_tool_bundles_are_model_visible_and_dispatchable() -> anyhow::
ToolRouterParams {
deferred_mcp_tools: None,
mcp_tools: None,
unavailable_called_tools: Vec::new(),
discoverable_tools: None,
extension_tool_bundles: extension_tool_bundles(&session),
dynamic_tools: turn.dynamic_tools.as_slice(),