content access

This commit is contained in:
lda
2026-06-03 00:32:50 +07:00 Verified
parent 6563ac9caf
commit 5af3f4428a
8 changed files with 298 additions and 128 deletions
+162
View File
@@ -0,0 +1,162 @@
from __future__ import annotations
import asyncio
from wf_mcp.broker.service.content_access import ContentAccessService
from wf_mcp.broker.service.connection_service import ConnectionService
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.storage import FileStore
from wf_platform import (
CapabilityBuckets,
CapabilitySource,
DocumentationPrompt,
DocumentationResource,
SourceVisibility,
)
from wf_mcp.broker import WfMcpService
from wf_mcp.models import ConnectionConfig
from ..test_support import FakeAdapter, local_temp_root
def _make_content_access(
*,
store_root: str = "content_access_default",
) -> tuple[ContentAccessService, BrokerEventRecorder]:
store = FileStore(local_temp_root() / store_root)
events = BrokerEventRecorder(EventBus())
connection_service = ConnectionService(events=events)
upstream = UpstreamTransportService(
store=store,
event_sink=events.record_event,
)
source_catalog = SourceCatalogService(
store=store,
connection_lookup=connection_service.get,
connection_list_enabled=connection_service.list_enabled,
connection_list_all=connection_service.list_all,
tool_executor_for=upstream.tool_executor_for,
load_auth=upstream.load_auth,
emit_event=events.record_event,
)
connection_service.bind_source_catalog(source_catalog)
_register_local_docs(source_catalog)
content_access = ContentAccessService(
source_catalog=source_catalog,
upstream=upstream,
connection_service=connection_service,
event_sink=events.record_event,
)
return content_access, events
def _register_local_docs(source_catalog: SourceCatalogService) -> None:
"""Install deterministic local docs without depending on repo Markdown files."""
source_catalog.register_capability_source(
CapabilitySource(
id="test.docs",
kind="system",
capabilities=CapabilityBuckets(
resources={
"test.docs.example": DocumentationResource(
name="test.docs.example",
uri="wf://docs/example",
title="Example Doc",
description="Test documentation resource.",
mime_type="text/markdown",
text="# Example",
)
},
prompts={
"test.docs.guide": DocumentationPrompt(
name="test.docs.guide",
title="Guide Prompt",
description="Test documentation prompt.",
text="Use the test docs.",
)
},
),
visibility=SourceVisibility(planner=True),
)
)
def test_content_access_reads_local_documentation_resource() -> None:
content_access, events = _make_content_access()
result = asyncio.run(content_access.read_resource("test.docs.example"))
assert result["contents"][0]["uri"] == "wf://docs/example"
assert result["contents"][0]["text"] == "# Example"
assert "resource_read_completed" in [e.kind for e in events.list_events()]
def test_content_access_reads_upstream_resource_with_events() -> None:
service = WfMcpService(
store=FileStore(local_temp_root() / "content_upstream_resource")
)
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
service.register_adapter("demo", FakeAdapter())
asyncio.run(service.refresh_connection_catalog("demo.personal"))
result = asyncio.run(
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()]
assert "resource_read_started" in event_kinds
assert "resource_read_completed" in event_kinds
def test_content_access_renders_upstream_prompt_with_events() -> None:
service = WfMcpService(
store=FileStore(local_temp_root() / "content_upstream_prompt")
)
service.register_connection(
ConnectionConfig(id="demo.personal", server="demo", account="personal")
)
service.register_adapter("demo", FakeAdapter())
asyncio.run(service.refresh_connection_catalog("demo.personal"))
result = asyncio.run(
service.content_access.render_prompt(
"demo.personal.prompt.summarize",
arguments={"text": "hello world"},
)
)
assert "hello world" in result["messages"][0]["content"]["text"]
event_kinds = [e.kind for e in service.list_events()]
assert "prompt_get_started" in event_kinds
assert "prompt_get_completed" in event_kinds
def test_content_access_renders_local_documentation_prompt() -> None:
content_access, events = _make_content_access(
store_root="content_access_local_prompt"
)
result = asyncio.run(content_access.render_prompt("test.docs.guide"))
assert result["description"] == "Test documentation prompt."
assert result["messages"][0]["role"] == "user"
assert result["messages"][0]["content"]["text"] == "Use the test docs."
assert "prompt_get_completed" in [e.kind for e in events.list_events()]
def test_content_access_raises_on_unknown_resource() -> None:
import pytest
content_access, _ = _make_content_access(
store_root="content_access_missing_resource"
)
with pytest.raises(KeyError):
asyncio.run(content_access.read_resource("nonexistent.resource"))