rename
This commit is contained in:
@@ -59,10 +59,10 @@ provider/proxy unmount lifecycle that we can rely on for safe per-connection
|
||||
teardown. Until that exists, reload should be treated as best-effort remounting,
|
||||
not a fully safe session/subscription lifecycle.
|
||||
|
||||
Unified mode currently reuses this runtime as its proxy mounting engine. The
|
||||
Unified mode currently reuses `ProxyRuntime` as its proxy mounting engine. The
|
||||
`transparent_proxy` package name is therefore partly legacy: the code is still
|
||||
the place where configured upstream MCP connections become mounted FastMCP
|
||||
providers.
|
||||
providers. `TransparentProxyRuntime` remains a compatibility alias.
|
||||
|
||||
After a successful reload, the runtime publishes local `tools_changed`,
|
||||
`resources_changed`, `prompts_changed`, and `catalog_changed` events when an
|
||||
|
||||
@@ -10,7 +10,7 @@ from fastmcp.client.transports.memory import FastMCPTransport
|
||||
from ..broker.config import build_service_from_config
|
||||
from ..broker.transport import normalize_transport
|
||||
from ..models import BrokerConfig
|
||||
from ..transparent_proxy.runtime import TransparentProxyRuntime
|
||||
from ..transparent_proxy.runtime import ProxyRuntime
|
||||
from ..workflow_surface import WorkflowSurfaceHandlers
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ def create_unified_proxy_server(
|
||||
) -> FastMCP[Any]:
|
||||
"""Create one MCP server with upstream proxy, admin, and workflow tools."""
|
||||
service = build_service_from_config(config)
|
||||
runtime = TransparentProxyRuntime(
|
||||
runtime = ProxyRuntime(
|
||||
config,
|
||||
config_path=config_path,
|
||||
resources_as_tools=resources_as_tools,
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from .admin import create_proxy_admin_server
|
||||
from .runtime import (
|
||||
ProxyRuntime,
|
||||
TransparentProxyRuntime,
|
||||
create_transparent_proxy_client,
|
||||
create_transparent_proxy_server,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"ProxyRuntime",
|
||||
"TransparentProxyRuntime",
|
||||
"create_proxy_admin_server",
|
||||
"create_transparent_proxy_client",
|
||||
|
||||
@@ -40,7 +40,13 @@ _ADMIN_TOOL_NAMES = [
|
||||
]
|
||||
|
||||
|
||||
class TransparentProxyRuntime:
|
||||
class ProxyRuntime:
|
||||
"""Mount configured upstream MCP connections into one FastMCP server.
|
||||
|
||||
The `transparent_proxy` package name is compatibility history. This runtime
|
||||
is now the shared proxy mounting engine used by unified mode too.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
config: BrokerConfig,
|
||||
@@ -176,6 +182,9 @@ class TransparentProxyRuntime:
|
||||
raise KeyError(proxy_name)
|
||||
|
||||
|
||||
TransparentProxyRuntime = ProxyRuntime
|
||||
|
||||
|
||||
def create_transparent_proxy_server(
|
||||
config: BrokerConfig,
|
||||
*,
|
||||
@@ -191,7 +200,7 @@ def create_transparent_proxy_server(
|
||||
resources_as_tools=resources_as_tools,
|
||||
prompts_as_tools=prompts_as_tools,
|
||||
)
|
||||
return TransparentProxyRuntime(
|
||||
return ProxyRuntime(
|
||||
config,
|
||||
config_path=config_path,
|
||||
resources_as_tools=resources_as_tools,
|
||||
@@ -225,4 +234,3 @@ def create_transparent_proxy_client(
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -29,8 +29,10 @@ def test_concern_package_imports_resolve() -> None:
|
||||
from wf_mcp.broker import WfMcpService, load_broker_config
|
||||
from wf_mcp.sdk import McpSdkAdapter
|
||||
from wf_mcp.storage import FileStore
|
||||
from wf_mcp.transparent_proxy import ProxyRuntime, TransparentProxyRuntime
|
||||
|
||||
assert FileStore.__name__ == "FileStore"
|
||||
assert McpSdkAdapter.__name__ == "McpSdkAdapter"
|
||||
assert WfMcpService.__name__ == "WfMcpService"
|
||||
assert callable(load_broker_config)
|
||||
assert TransparentProxyRuntime is ProxyRuntime
|
||||
|
||||
@@ -11,7 +11,7 @@ import pytest
|
||||
from wf_mcp.events import EventBus, InMemoryEventSink
|
||||
from wf_mcp.models import BrokerConfig, ConnectionConfig
|
||||
from wf_mcp.proxy_validation import ProxyConfigError, validate_transparent_proxy_config
|
||||
from wf_mcp.transparent_proxy import TransparentProxyRuntime, create_transparent_proxy_client
|
||||
from wf_mcp.transparent_proxy import ProxyRuntime, create_transparent_proxy_client
|
||||
from wf_mcp.broker import load_broker_config
|
||||
|
||||
from .test_support import fixture_server_path, local_temp_root
|
||||
@@ -484,6 +484,56 @@ def test_transparent_proxy_admin_reload_sends_list_changed_notifications() -> No
|
||||
assert "notifications/prompts/list_changed" in methods
|
||||
|
||||
|
||||
def test_transparent_proxy_config_mutation_does_not_notify_before_reload() -> None:
|
||||
tmp_path = local_temp_root() / "transparent_proxy_staged_notification_store"
|
||||
tmp_path.mkdir(parents=True, exist_ok=True)
|
||||
config_path = tmp_path / "wf_mcp.config.json"
|
||||
config_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"store_root": ".wf_mcp_store",
|
||||
"connections": [],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
config = load_broker_config(config_path)
|
||||
notifications: list[mcp_types.ServerNotification] = []
|
||||
|
||||
async def message_handler(message: object) -> None:
|
||||
if isinstance(message, mcp_types.ServerNotification):
|
||||
notifications.append(message)
|
||||
|
||||
async def run_proxy() -> None:
|
||||
client = create_transparent_proxy_client(config, config_path=config_path)
|
||||
client._session_kwargs["message_handler"] = message_handler
|
||||
async with client:
|
||||
add_result = await client.call_tool(
|
||||
"wf.admin.add_connection",
|
||||
{
|
||||
"connection_id": "fixture.personal",
|
||||
"server": "fixture",
|
||||
"account": "personal",
|
||||
"metadata": {
|
||||
"transport": "stdio",
|
||||
"command": sys.executable,
|
||||
"args": [fixture_server_path()],
|
||||
},
|
||||
},
|
||||
)
|
||||
assert _structured(add_result)["requires_reload"] is True
|
||||
assert notifications == []
|
||||
|
||||
await client.call_tool("wf.admin.reload_config")
|
||||
|
||||
asyncio.run(run_proxy())
|
||||
|
||||
methods = [notification.root.method for notification in notifications]
|
||||
assert "notifications/tools/list_changed" in methods
|
||||
assert "notifications/resources/list_changed" in methods
|
||||
assert "notifications/prompts/list_changed" in methods
|
||||
|
||||
|
||||
def test_transparent_proxy_runtime_reload_publishes_local_change_events() -> None:
|
||||
sink = InMemoryEventSink()
|
||||
event_bus = EventBus(sink)
|
||||
@@ -491,7 +541,7 @@ def test_transparent_proxy_runtime_reload_publishes_local_change_events() -> Non
|
||||
store_root=local_temp_root() / "transparent_proxy_event_store",
|
||||
connections=[],
|
||||
)
|
||||
runtime = TransparentProxyRuntime(config, event_bus=event_bus)
|
||||
runtime = ProxyRuntime(config, event_bus=event_bus)
|
||||
initial_event_count = len(sink.list_events())
|
||||
|
||||
result = runtime.reload()
|
||||
|
||||
Reference in New Issue
Block a user