fix(mcp): resolve aliases that collide with built-in toolsets
This commit is contained in:
parent
c896c09c42
commit
fa79e52bec
|
|
@ -55,6 +55,22 @@ class TestGetToolset:
|
|||
assert ts is not None
|
||||
assert set(ts["tools"]) == {"web_search", "web_extract", "web_search_plus"}
|
||||
|
||||
def test_merges_colliding_mcp_alias_into_builtin_toolset(self, monkeypatch):
|
||||
reg = ToolRegistry()
|
||||
reg.register(
|
||||
name="mcp__memory__read_graph",
|
||||
toolset="mcp-memory",
|
||||
schema=_make_schema("mcp__memory__read_graph", "Read graph"),
|
||||
handler=_dummy_handler,
|
||||
)
|
||||
reg.register_toolset_alias("memory", "mcp-memory")
|
||||
|
||||
monkeypatch.setattr("tools.registry.registry", reg)
|
||||
|
||||
tools = resolve_toolset("memory")
|
||||
assert "memory" in tools
|
||||
assert "mcp__memory__read_graph" in tools
|
||||
|
||||
|
||||
|
||||
class TestResolveToolset:
|
||||
|
|
|
|||
|
|
@ -460,6 +460,43 @@ class TestRegression_ToolsetScoping:
|
|||
# core tools are never deferrable
|
||||
assert "terminal" not in names
|
||||
|
||||
def test_builtin_name_collision_keeps_mcp_alias_searchable(self):
|
||||
from tools.registry import registry
|
||||
import model_tools
|
||||
|
||||
self._register("mcp__memory__read_graph", "mcp-memory")
|
||||
registry.register_toolset_alias("memory", "mcp-memory")
|
||||
|
||||
source_result = model_tools.handle_function_call(
|
||||
function_name="tool_search",
|
||||
function_args={"query": "unrelated capability", "limit": 5},
|
||||
enabled_toolsets=["memory"],
|
||||
)
|
||||
|
||||
source_payload = json.loads(source_result)
|
||||
assert {source["name"] for source in source_payload["available_sources"]} == {
|
||||
"memory"
|
||||
}
|
||||
|
||||
match_result = model_tools.handle_function_call(
|
||||
function_name="tool_search",
|
||||
function_args={"query": "read graph", "limit": 5},
|
||||
enabled_toolsets=["memory"],
|
||||
)
|
||||
assert "mcp__memory__read_graph" in {
|
||||
match["name"] for match in json.loads(match_result)["matches"]
|
||||
}
|
||||
|
||||
call_result = model_tools.handle_function_call(
|
||||
function_name="tool_call",
|
||||
function_args={"name": "mcp__memory__read_graph", "arguments": {}},
|
||||
enabled_toolsets=["memory"],
|
||||
)
|
||||
assert json.loads(call_result) == {
|
||||
"ok": True,
|
||||
"tool": "mcp__memory__read_graph",
|
||||
}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Catalog listing (skills-style progressive disclosure)
|
||||
|
|
|
|||
12
toolsets.py
12
toolsets.py
|
|
@ -693,9 +693,17 @@ def get_toolset(name: str, *, include_registry: bool = True) -> Optional[Dict[st
|
|||
return toolset if toolset else None
|
||||
|
||||
if toolset:
|
||||
registry_toolsets = {name}
|
||||
alias_target = registry.get_toolset_alias_target(name)
|
||||
if alias_target:
|
||||
registry_toolsets.add(alias_target)
|
||||
merged_tools = sorted(
|
||||
set(toolset.get("tools", []))
|
||||
| set(registry.get_tool_names_for_toolset(name))
|
||||
set(toolset.get("tools", [])).union(
|
||||
*(
|
||||
registry.get_tool_names_for_toolset(toolset_name)
|
||||
for toolset_name in registry_toolsets
|
||||
)
|
||||
)
|
||||
)
|
||||
return {**toolset, "tools": merged_tools}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue