refactor: move mcp auth record ownership
This commit is contained in:
@@ -2,10 +2,10 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from wf_api.models import RawWorkflowPlan
|
||||
from wf_authoring import node
|
||||
from wf_core import END
|
||||
from wf_mcp.capabilities import DiscoveredTool
|
||||
from wf_api.models import RawWorkflowPlan
|
||||
from wf_mcp.models import AuthRecord, ConnectionConfig
|
||||
from wf_mcp.sdk import ToolCallResult
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ async def test_service_catalog_preserves_json_schema_description_metadata() -> N
|
||||
assert node["input_schema"]["properties"]["text"]["description"] == "Text to echo"
|
||||
|
||||
|
||||
async def test_service_preserves_content_only_tool_output_schema_for_workflows() -> None:
|
||||
async def test_service_preserves_content_only_tool_output_schema_for_workflows() -> (
|
||||
None
|
||||
):
|
||||
service = WfMcpService(store=FileStore(local_temp_root() / "content_only_store"))
|
||||
service.register_connection(
|
||||
ConnectionConfig(
|
||||
@@ -42,7 +44,9 @@ async def test_service_preserves_content_only_tool_output_schema_for_workflows()
|
||||
assert node["output_schema"]["required"] == ["content"]
|
||||
|
||||
|
||||
async def test_service_wrapped_tool_adapter_model_validates_simple_schema_types() -> None:
|
||||
async def test_service_wrapped_tool_adapter_model_validates_simple_schema_types() -> (
|
||||
None
|
||||
):
|
||||
service = WfMcpService(store=FileStore(local_temp_root() / "adapter_model_store"))
|
||||
service.register_connection(
|
||||
ConnectionConfig(id="demo.personal", server="demo", account="personal")
|
||||
|
||||
@@ -409,7 +409,9 @@ def test_source_catalog_service_excludes_hidden_sources_from_planner_catalog() -
|
||||
assert "hidden.source.echo_tool" not in planner_names
|
||||
|
||||
|
||||
async def test_source_catalog_hydrates_connection_source_from_snapshot_directly() -> None:
|
||||
async def test_source_catalog_hydrates_connection_source_from_snapshot_directly() -> (
|
||||
None
|
||||
):
|
||||
root = local_temp_root() / "source_catalog_hydrate_direct"
|
||||
shutil.rmtree(root, ignore_errors=True)
|
||||
first_service = WfMcpService(store=FileStore(root))
|
||||
|
||||
@@ -53,7 +53,9 @@ def test_connection_service_rejects_reserved_connection_ids(tmp_path: Path) -> N
|
||||
raise AssertionError(f"expected {connection_id!r} to be rejected")
|
||||
|
||||
|
||||
def test_connection_service_registers_connection_and_empty_source(tmp_path: Path) -> None:
|
||||
def test_connection_service_registers_connection_and_empty_source(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
|
||||
catalog = _source_catalog(service, tmp_path)
|
||||
|
||||
@@ -70,7 +72,9 @@ def test_connection_service_registers_connection_and_empty_source(tmp_path: Path
|
||||
assert service.events.list_events()[0].connection_id == "demo.personal"
|
||||
|
||||
|
||||
def test_connection_service_sync_removes_retired_connections_and_sources(tmp_path: Path) -> None:
|
||||
def test_connection_service_sync_removes_retired_connections_and_sources(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
|
||||
catalog = _source_catalog(service, tmp_path)
|
||||
service.register_connection(
|
||||
@@ -90,7 +94,9 @@ def test_connection_service_sync_removes_retired_connections_and_sources(tmp_pat
|
||||
assert removed.payload["account"] == "personal"
|
||||
|
||||
|
||||
def test_connection_service_sync_updates_existing_source_enabled_flag(tmp_path: Path) -> None:
|
||||
def test_connection_service_sync_updates_existing_source_enabled_flag(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
|
||||
catalog = _source_catalog(service, tmp_path)
|
||||
service.register_connection(
|
||||
@@ -119,7 +125,9 @@ def test_connection_service_sync_updates_existing_source_enabled_flag(tmp_path:
|
||||
assert updated.payload["enabled"] is False
|
||||
|
||||
|
||||
def test_connection_service_sync_registers_new_connections_with_event(tmp_path: Path) -> None:
|
||||
def test_connection_service_sync_registers_new_connections_with_event(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = ConnectionService(events=BrokerEventRecorder(EventBus()))
|
||||
catalog = _source_catalog(service, tmp_path)
|
||||
|
||||
@@ -143,7 +151,9 @@ def test_connection_service_sync_registers_new_connections_with_event(tmp_path:
|
||||
assert registered.connection_id == "demo.personal"
|
||||
|
||||
|
||||
def test_wfmcpservice_exposes_connection_registry_from_connection_service(tmp_path: Path) -> None:
|
||||
def test_wfmcpservice_exposes_connection_registry_from_connection_service(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = WfMcpService(store=FileStore(tmp_path / "connection_facade"))
|
||||
|
||||
service.register_connection(
|
||||
@@ -155,7 +165,9 @@ def test_wfmcpservice_exposes_connection_registry_from_connection_service(tmp_pa
|
||||
assert "demo.personal" in service.capability_sources
|
||||
|
||||
|
||||
def test_wfmcpservice_sync_connections_delegates_to_connection_service(tmp_path: Path) -> None:
|
||||
def test_wfmcpservice_sync_connections_delegates_to_connection_service(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
service = WfMcpService(store=FileStore(tmp_path / "connection_sync"))
|
||||
service.register_connection(
|
||||
ConnectionConfig(id="demo.personal", server="demo", account="personal")
|
||||
@@ -328,8 +340,7 @@ def test_connection_service_sync_seed_config_materializes_registry_entry(
|
||||
assert service.get("demo.default").metadata["source_registry"] is True
|
||||
all_events = service.events.list_events()
|
||||
assert any(
|
||||
event.kind == "source_registry_seeded_from_config"
|
||||
for event in all_events
|
||||
event.kind == "source_registry_seeded_from_config" for event in all_events
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@ from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from wf_mcp.broker.service.content_access import ContentAccessService
|
||||
from wf_mcp.broker import WfMcpService
|
||||
from wf_mcp.broker.service.connection_service import ConnectionService
|
||||
from wf_mcp.broker.service.content_access import ContentAccessService
|
||||
from wf_mcp.broker.service.events import BrokerEventRecorder
|
||||
from wf_mcp.broker.service.source_catalog import SourceCatalogService
|
||||
from wf_mcp.broker.service.upstream_transport import UpstreamTransportService
|
||||
from wf_mcp.events import EventBus
|
||||
from wf_mcp.models import ConnectionConfig
|
||||
from wf_mcp.storage import FileStore
|
||||
from wf_platform import (
|
||||
CapabilityBuckets,
|
||||
@@ -17,9 +19,6 @@ from wf_platform import (
|
||||
SourceVisibility,
|
||||
)
|
||||
|
||||
from wf_mcp.broker import WfMcpService
|
||||
from wf_mcp.models import ConnectionConfig
|
||||
|
||||
from ..test_support import FakeAdapter, local_temp_root
|
||||
|
||||
|
||||
@@ -105,7 +104,9 @@ async def test_content_access_reads_upstream_resource_with_events() -> None:
|
||||
service.register_adapter("demo", FakeAdapter())
|
||||
await service.refresh_connection_catalog("demo.personal")
|
||||
|
||||
result = await service.content_access.read_resource("demo.personal.resource.welcome")
|
||||
result = await service.content_access.read_resource(
|
||||
"demo.personal.resource.welcome"
|
||||
)
|
||||
|
||||
assert result["contents"][0]["text"] == "Welcome from the fake adapter resource."
|
||||
event_kinds = [e.kind for e in service.list_events()]
|
||||
|
||||
@@ -275,9 +275,7 @@ async def test_generated_specs_use_injected_tool_executor() -> None:
|
||||
spec = service._get_qualified_spec("demo.personal.echo_tool")
|
||||
handler = build_async_registry(spec)[spec.name]
|
||||
|
||||
result = await handler(
|
||||
{"text": "hello"}, RuntimeContext(current_node_id="echo")
|
||||
)
|
||||
result = await handler({"text": "hello"}, RuntimeContext(current_node_id="echo"))
|
||||
|
||||
assert result["outcome"] == "ok"
|
||||
assert result["output"]["echoed"] == "hello"
|
||||
|
||||
@@ -314,7 +314,9 @@ def test_source_registry_apply_materializes_registry_connection(tmp_path: Path)
|
||||
assert source_catalog.capability_sources["dynamic.default"].enabled is True
|
||||
|
||||
|
||||
def test_source_registry_apply_removes_deleted_registry_connection(tmp_path: Path) -> None:
|
||||
def test_source_registry_apply_removes_deleted_registry_connection(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
entry = _entry("dynamic.default", provider="dynamic", account="default")
|
||||
provider, connection_service, source_catalog = _apply_provider(
|
||||
tmp_path,
|
||||
|
||||
@@ -168,9 +168,7 @@ async def test_service_runs_logical_source_plan_with_dotted_local_name() -> None
|
||||
id="logical_dotted.personal",
|
||||
artifact_id="logical_dotted",
|
||||
artifact_version=1,
|
||||
bindings=[
|
||||
{"logical_source": "demo", "concrete_source": "demo.personal"}
|
||||
],
|
||||
bindings=[{"logical_source": "demo", "concrete_source": "demo.personal"}],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -3,16 +3,14 @@ from __future__ import annotations
|
||||
from pathlib import Path
|
||||
|
||||
from wf_artifacts import WorkflowDeployment
|
||||
from wf_platform import CapabilityBuckets, CapabilitySource, SourcePermissions
|
||||
|
||||
from wf_mcp.broker import WfMcpService
|
||||
from wf_mcp.broker.service.source_catalog import SourceCatalogService
|
||||
from wf_mcp.broker.service.upstream_transport import UpstreamTransportService
|
||||
from wf_mcp.connections import ConnectionRegistry
|
||||
from wf_mcp.events import McpEvent
|
||||
from wf_mcp.models import AuthRecord, ConnectionConfig
|
||||
from wf_mcp.storage import FileStore
|
||||
|
||||
from wf_mcp.broker import WfMcpService
|
||||
from wf_platform import CapabilityBuckets, CapabilitySource, SourcePermissions
|
||||
|
||||
from ..test_support import FakeAdapter, local_temp_root
|
||||
from ..workflow_surface.conftest import echo_artifact
|
||||
|
||||
Reference in New Issue
Block a user