mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-08-14 19:05:17 +00:00
Fix MCP lookup for Responses tool aliases
Resolve provider-safe Responses tool names back to their canonical MCP names inside the MCP handler before dispatch. Preserve canonical lookups and reject stale or unrelated aliases so local tool resolution can continue. Add regression coverage for Google Workspace-style names and document the lookup contract.
This commit is contained in:
parent
e2fd320ac6
commit
6a7178af91
3 changed files with 47 additions and 1 deletions
|
|
@ -45,6 +45,7 @@ from helpers import dirty_json, media_artifacts
|
|||
from helpers.print_style import PrintStyle
|
||||
from helpers.tool import Tool, Response
|
||||
from helpers.defer import DeferredTask
|
||||
from helpers.responses_tools import original_tool_name
|
||||
|
||||
|
||||
MCP_MEDIA_TOKENS_ESTIMATE = 1500
|
||||
|
|
@ -1211,7 +1212,16 @@ class MCPConfig(BaseModel):
|
|||
if effective_config is not self:
|
||||
return effective_config.get_tool(agent, tool_name)
|
||||
if not self.has_tool(tool_name):
|
||||
return None
|
||||
get_data = getattr(agent, "get_data", None)
|
||||
name_map_key = getattr(agent, "DATA_NAME_RESPONSES_TOOL_NAME_MAP", "")
|
||||
tool_name = original_tool_name(
|
||||
tool_name,
|
||||
get_data(name_map_key)
|
||||
if name_map_key and callable(get_data)
|
||||
else None,
|
||||
)
|
||||
if not self.has_tool(tool_name):
|
||||
return None
|
||||
return MCPTool(agent=agent, name=tool_name, method=None, args={}, message="", loop_data=None)
|
||||
|
||||
async def call_tool(
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
- Project-scoped MCP servers overlay global servers by normalized name. The resulting `MCPConfig` cache key is derived from both config strings so project instances refresh when either scope changes.
|
||||
- Server status and detail responses include `scope`, and MCP tools resolve through `MCPConfig.get_for_agent(agent)` before execution.
|
||||
- MCP tool names are qualified as `server_name.tool_name`; server names are normalized without dots, and the tool portion may contain dots.
|
||||
- `MCPConfig.get_tool()` tries the supplied qualified name first, then restores an advertised Responses alias from the calling agent's name map; names that still do not identify an MCP tool return `None` unchanged for downstream local-tool resolution.
|
||||
- Servers may define `disabled_tools` as a list of MCP tool names. Disabled tools are omitted from agent-facing prompts, status counts, `has_tool`, and calls, while detail views can still retrieve them through `get_all_tools()` with a `disabled` flag so users can re-enable them.
|
||||
- Server-specific `init_timeout` and `tool_timeout` override global MCP client timeout settings for list-tools and call-tool operations.
|
||||
- Local stdio server configs accept either strict MCP JSON (`command: "uvx", args: [...]`) or manager-style command lines (`command: "uvx package"`) and normalize them before spawning the process.
|
||||
|
|
|
|||
|
|
@ -212,6 +212,41 @@ def test_mcp_config_preserves_dotted_tool_names(mcp_handler_module):
|
|||
assert called == [("alpha.beta", {"value": 7})]
|
||||
|
||||
|
||||
def test_mcp_config_resolves_advertised_responses_alias(
|
||||
mcp_handler_module, monkeypatch
|
||||
):
|
||||
module, _tmp_path = mcp_handler_module
|
||||
canonical_name = "google_workspace.search_gmail_messages"
|
||||
native_name = "google_workspace_search_gmail_messages_ecb900b9"
|
||||
|
||||
class _FakeServer:
|
||||
name = "google_workspace"
|
||||
|
||||
def has_tool(self, tool_name):
|
||||
return tool_name == "search_gmail_messages"
|
||||
|
||||
config = module.MCPConfig(servers_list=[])
|
||||
config.servers = [_FakeServer()]
|
||||
monkeypatch.setattr(
|
||||
module.MCPConfig,
|
||||
"get_for_agent",
|
||||
classmethod(lambda cls, _agent: config),
|
||||
)
|
||||
|
||||
agent = SimpleNamespace(
|
||||
DATA_NAME_RESPONSES_TOOL_NAME_MAP="responses_tool_name_map",
|
||||
get_data=lambda key: (
|
||||
{native_name: canonical_name}
|
||||
if key == "responses_tool_name_map"
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
assert config.get_tool(agent, canonical_name).name == canonical_name
|
||||
assert config.get_tool(agent, native_name).name == canonical_name
|
||||
assert config.get_tool(agent, "local_tool") is None
|
||||
|
||||
|
||||
def test_mcp_config_call_tool_releases_config_lock_before_await(
|
||||
mcp_handler_module, monkeypatch
|
||||
):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue