refactor: move mcp adapter helper to wf_sources_mcp

This commit is contained in:
lda
2026-06-08 11:18:56 +07:00 Verified
parent ec3414c1cb
commit 8cab3bcf10
10 changed files with 820 additions and 17 deletions
+13
View File
@@ -42,8 +42,11 @@ if TYPE_CHECKING:
)
__all__ = [
"AdapterLookupRef",
"AuthRecord",
"DiscoveredConnectionCapabilities",
"LegacyAdapterRef",
"SourceAdapterRef",
"FileSourceRegistryStore",
"HttpSourceTransport",
"McpSourceConnection",
@@ -65,6 +68,7 @@ __all__ = [
"model_from_schema",
"neutral_auth_from_mcp",
"registry_entry_to_connection_config",
"require_adapter",
"specs_from_discovered_tools",
"tool_call_completed_event",
"tool_call_started_event",
@@ -76,6 +80,15 @@ __all__ = [
def __getattr__(name: str) -> object:
if name in {
"AdapterLookupRef",
"LegacyAdapterRef",
"SourceAdapterRef",
"require_adapter",
}:
from . import adapters
return getattr(adapters, name)
if name in {
"McpSourceConnection",
"mcp_source_connection_from_connection_config",
+62
View File
@@ -0,0 +1,62 @@
"""Canonical adapter lookup for MCP upstream source providers.
``SourceAdapterRef`` and ``LegacyAdapterRef`` document the expected shape of
source objects passed to ``require_adapter``. Runtime validation uses
duck-typing via ``_adapter_key`` because ``McpSourceConnection.server`` is a
``@property`` that conflicts with Protocol structural typing.
"""
from __future__ import annotations
from collections.abc import Mapping
from typing import Protocol
from wf_sources_mcp.sdk import BackendAdapter
class SourceAdapterRef(Protocol):
"""Typed source identity used by `McpSourceConnection`."""
provider: str
class LegacyAdapterRef(Protocol):
"""Legacy broker source identity used by `ConnectionConfig`."""
server: str
type AdapterLookupRef = SourceAdapterRef | LegacyAdapterRef
def _adapter_key(source: object) -> str:
"""Resolve adapter lookup key from a source reference.
Checks ``server`` first (legacy broker ``ConnectionConfig``), then
``provider`` (typed ``McpSourceConnection``). The values are identical
for ``McpSourceConnection`` (which exposes ``server`` as a property
alias), but ``server`` is checked first for legacy compatibility.
"""
server = getattr(source, "server", None)
if isinstance(server, str):
return server
provider = getattr(source, "provider", None)
if isinstance(provider, str):
return provider
raise TypeError("source must expose a string 'server' or 'provider' attribute")
def require_adapter(
source: object, # duck-typed, not AdapterLookupRef — McpSourceConnection.server
# is a @property which conflicts with Protocol structural typing.
adapters: Mapping[str, BackendAdapter],
) -> BackendAdapter:
"""Return the adapter for a source or raise a useful lookup error."""
key = _adapter_key(source)
adapter = adapters.get(key)
if adapter is None:
raise KeyError(f"no adapter registered for source {key!r}")
return adapter
__all__ = ["AdapterLookupRef", "LegacyAdapterRef", "SourceAdapterRef", "require_adapter"]