use own layer for tool discovery
This commit is contained in:
@@ -136,13 +136,10 @@ class ProxyRuntime:
|
|||||||
self,
|
self,
|
||||||
) -> list[ProxyToolPayload]:
|
) -> list[ProxyToolPayload]:
|
||||||
config = self.current_config()
|
config = self.current_config()
|
||||||
connection_ids = {
|
tools = await self._list_active_mount_tools(config)
|
||||||
connection.id for connection in config.connections if connection.enabled
|
|
||||||
}
|
|
||||||
tools = await self.server.list_tools()
|
|
||||||
return collect_proxy_tools(
|
return collect_proxy_tools(
|
||||||
tools=tools,
|
tools=tools,
|
||||||
connection_ids=connection_ids,
|
connection_ids=self._enabled_connection_ids(config),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def list_proxy_tools_page(
|
async def list_proxy_tools_page(
|
||||||
@@ -163,19 +160,34 @@ class ProxyRuntime:
|
|||||||
|
|
||||||
async def get_proxy_tool(self, proxy_name: str) -> dict[str, Any]:
|
async def get_proxy_tool(self, proxy_name: str) -> dict[str, Any]:
|
||||||
config = self.current_config()
|
config = self.current_config()
|
||||||
connection_ids = {
|
tools = await self._list_active_mount_tools(config)
|
||||||
connection.id for connection in config.connections if connection.enabled
|
|
||||||
}
|
|
||||||
tools = await self.server.list_tools()
|
|
||||||
payloads = collect_proxy_tools(
|
payloads = collect_proxy_tools(
|
||||||
tools=tools,
|
tools=tools,
|
||||||
connection_ids=connection_ids,
|
connection_ids=self._enabled_connection_ids(config),
|
||||||
)
|
)
|
||||||
for tool in payloads:
|
for tool in payloads:
|
||||||
if tool.proxy_name == proxy_name:
|
if tool.proxy_name == proxy_name:
|
||||||
return tool.to_payload(include_schema=True)
|
return tool.to_payload(include_schema=True)
|
||||||
raise KeyError(proxy_name)
|
raise KeyError(proxy_name)
|
||||||
|
|
||||||
|
async def _list_active_mount_tools(self, config: BrokerConfig) -> list[Any]:
|
||||||
|
"""Return mounted upstream tools without top-level client transforms.
|
||||||
|
|
||||||
|
Per-mount namespace transforms are part of our proxy contract, but
|
||||||
|
top-level transforms such as BM25 search are only presentation layers
|
||||||
|
for MCP clients. Admin inventory must inspect the mounted proxies
|
||||||
|
directly so hidden-but-mounted tools remain discoverable here.
|
||||||
|
"""
|
||||||
|
tools: list[Any] = []
|
||||||
|
for mount in self.mounts.active_mounts_for(config):
|
||||||
|
tools.extend(await mount.proxy.list_tools())
|
||||||
|
return tools
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _enabled_connection_ids(config: BrokerConfig) -> set[str]:
|
||||||
|
"""Return connection ids that currently contribute mounted proxies."""
|
||||||
|
return {connection.id for connection in config.connections if connection.enabled}
|
||||||
|
|
||||||
|
|
||||||
TransparentProxyRuntime = ProxyRuntime
|
TransparentProxyRuntime = ProxyRuntime
|
||||||
|
|
||||||
|
|||||||
@@ -279,6 +279,45 @@ def test_transparent_proxy_can_collapse_upstream_tools_behind_search() -> None:
|
|||||||
asyncio.run(run_proxy())
|
asyncio.run(run_proxy())
|
||||||
|
|
||||||
|
|
||||||
|
def test_transparent_proxy_admin_inventory_ignores_search_visibility() -> None:
|
||||||
|
config = BrokerConfig(
|
||||||
|
store_root=local_temp_root() / "transparent_proxy_admin_inventory_store",
|
||||||
|
connections=[
|
||||||
|
ConnectionConfig(
|
||||||
|
id="fixture.personal",
|
||||||
|
server="fixture",
|
||||||
|
account="personal",
|
||||||
|
metadata={
|
||||||
|
"transport": "stdio",
|
||||||
|
"command": sys.executable,
|
||||||
|
"args": [fixture_server_path()],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
async def run_proxy() -> None:
|
||||||
|
client = create_transparent_proxy_client(config, search_tools=True)
|
||||||
|
async with client:
|
||||||
|
visible_names = [tool.name for tool in await client.list_tools()]
|
||||||
|
assert "fixture.personal.echo_tool" not in visible_names
|
||||||
|
|
||||||
|
listed = await client.call_tool("wf.admin.list_proxy_tools", {})
|
||||||
|
payload = listed.data
|
||||||
|
assert isinstance(payload, dict)
|
||||||
|
assert payload["tools"][0]["proxy_name"] == "fixture.personal.echo_tool"
|
||||||
|
|
||||||
|
inspected = await client.call_tool(
|
||||||
|
"wf.admin.get_proxy_tool",
|
||||||
|
{"proxy_name": "fixture.personal.echo_tool"},
|
||||||
|
)
|
||||||
|
inspected_payload = inspected.data
|
||||||
|
assert isinstance(inspected_payload, dict)
|
||||||
|
assert inspected_payload["proxy_name"] == "fixture.personal.echo_tool"
|
||||||
|
|
||||||
|
asyncio.run(run_proxy())
|
||||||
|
|
||||||
|
|
||||||
def test_transparent_proxy_proxy_tool_listing_supports_filters_and_cursor() -> None:
|
def test_transparent_proxy_proxy_tool_listing_supports_filters_and_cursor() -> None:
|
||||||
config = BrokerConfig(
|
config = BrokerConfig(
|
||||||
store_root=local_temp_root() / "transparent_proxy_paged_tools_store",
|
store_root=local_temp_root() / "transparent_proxy_paged_tools_store",
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@
|
|||||||
"id": "playwright.default",
|
"id": "playwright.default",
|
||||||
"server": "playwright",
|
"server": "playwright",
|
||||||
"account": "default",
|
"account": "default",
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"transport": "stdio",
|
"transport": "stdio",
|
||||||
"command": "pnpx",
|
"command": "pnpx",
|
||||||
|
|||||||
Reference in New Issue
Block a user