this is finally goodbye. use the new one.

This commit is contained in:
lda
2026-05-17 00:41:20 +07:00 Verified
parent 16591f3560
commit a55879ea2b
10 changed files with 61 additions and 214 deletions
+2 -2
View File
@@ -8,8 +8,8 @@ _WORKFLOW_AUTHORING_GUIDE = """\
Build workflows from current capabilities instead of assuming a stale catalog.
Use `get_planner_catalog` when you need the current workflow-capability view.
Use `list_sources` and `list_spec_sources` when you need to understand what is
available and which sources are planner-visible.
Use `list_sources` when you need to understand source ownership, visibility,
and capability kinds.
Use `call_broker_tool` to test an upstream MCP tool manually before wrapping it
into a workflow.
+20 -10
View File
@@ -23,7 +23,12 @@ from wf_authoring import (
truthy,
)
from .sources import SpecSource
from .capability_sources import (
CapabilityBuckets,
CapabilitySource,
SourcePermissions,
SourceVisibility,
)
from .specs import qualify_spec
BUILTIN_CONNECTION_ID = "wf.std"
@@ -121,22 +126,27 @@ def mcp_specs(service: ToolCaller) -> dict[str, NodeSpec[Any, Any]]:
return {spec.name: spec for spec in qualified_specs}
def builtin_sources(service: ToolCaller) -> dict[str, SpecSource]:
"""Return all broker-local spec sources."""
def builtin_sources(service: ToolCaller) -> dict[str, CapabilitySource]:
"""Return all broker-local capability sources."""
return {
BUILTIN_CONNECTION_ID: SpecSource(
BUILTIN_CONNECTION_ID: CapabilitySource(
id=BUILTIN_CONNECTION_ID,
kind="system",
specs=builtin_specs(),
mcp_client_visible=True,
safe_for_workflow=True,
capabilities=CapabilityBuckets(node_specs=builtin_specs()),
visibility=SourceVisibility(
planner=True,
mcp_client=True,
admin_dashboard=True,
),
permissions=SourcePermissions(safe_for_workflow=True),
description="Workflow standard-library nodes.",
),
MCP_SOURCE_ID: SpecSource(
MCP_SOURCE_ID: CapabilitySource(
id=MCP_SOURCE_ID,
kind="system",
specs=mcp_specs(service),
calls_upstream=True,
capabilities=CapabilityBuckets(node_specs=mcp_specs(service)),
visibility=SourceVisibility(planner=True, admin_dashboard=True),
permissions=SourcePermissions(calls_upstream=True),
description="Broker MCP utility nodes.",
),
}
+11 -57
View File
@@ -44,7 +44,6 @@ from .capability_sources import (
SourcePermissions,
SourceVisibility,
)
from .sources import SpecSource
from .specs import get_qualified_spec, qualify_spec
@@ -71,41 +70,9 @@ class WfMcpService:
self.artifact_store = FileWorkflowArtifactStore(_store_root(self.store))
if self.include_builtin_specs:
for source in builtin_sources(self).values():
self.register_spec_source(source)
self.register_capability_source(source)
self.register_capability_source(admin_source())
@property
def spec_sources(self) -> dict[str, SpecSource]:
"""Compatibility view of node-spec capability sources."""
return {
source.id: SpecSource(
id=source.id,
kind=source.kind,
specs=dict(source.capabilities.node_specs),
visible=source.enabled and source.visibility.planner,
mcp_client_visible=source.enabled and source.visibility.mcp_client,
admin_dashboard_visible=(
source.enabled and source.visibility.admin_dashboard
),
safe_for_workflow=source.permissions.safe_for_workflow,
calls_upstream=source.permissions.calls_upstream,
mutates_config=source.permissions.mutates_config,
mutates_auth=source.permissions.mutates_auth,
description=source.description,
)
for source in self.capability_sources.values()
if source.capabilities.node_specs
}
@property
def specs_by_connection(self) -> dict[str, dict[str, NodeSpec[Any, Any]]]:
"""Compatibility view of source specs keyed by source id."""
return {
source.id: dict(source.capabilities.node_specs)
for source in self.capability_sources.values()
if source.capabilities.node_specs
}
def register_connection(self, connection: ConnectionConfig) -> None:
parse_connection_id(connection.id)
if connection.id in RESERVED_CONNECTION_IDS:
@@ -155,14 +122,18 @@ class WfMcpService:
# Catalog refreshes replace discovered specs, not operator policy.
existing_source.capabilities.node_specs = qualified_specs
else:
self.register_spec_source(
SpecSource(
self.register_capability_source(
CapabilitySource(
id=connection_id,
kind="connection",
specs=qualified_specs,
capabilities=CapabilityBuckets(node_specs=qualified_specs),
enabled=self.connections.get(connection_id).enabled,
mcp_client_visible=True,
calls_upstream=True,
visibility=SourceVisibility(
planner=True,
mcp_client=True,
admin_dashboard=True,
),
permissions=SourcePermissions(calls_upstream=True),
description=(
f"Specs discovered or registered for {connection_id}."
),
@@ -237,19 +208,6 @@ class WfMcpService:
snapshots[source.id].prompts = list(stored_snapshot.prompts)
return CombinedCatalog(snapshots=snapshots)
def list_spec_sources(self) -> list[dict[str, Any]]:
"""Return planner spec sources without expanding every node schema."""
return [
source.as_status()
for source in sorted(
self.capability_sources.values(),
key=lambda source: source.id,
)
if source.capabilities.node_specs
and source.enabled
and source.visibility.planner
]
def list_sources(self) -> list[dict[str, Any]]:
"""Return every capability source with the names it currently owns."""
return [
@@ -525,7 +483,7 @@ class WfMcpService:
)
snapshot = snapshot_from_specs(
connection_id,
specs=self.specs_by_connection.get(connection_id, {}),
specs=self.capability_sources[connection_id].capabilities.node_specs,
tool_display_names={
tool.name: tool.title for tool in capabilities.tools
},
@@ -619,10 +577,6 @@ class WfMcpService:
"""Register a capability source as canonical service state."""
self.capability_sources[source.id] = source
def register_spec_source(self, source: SpecSource) -> None:
"""Register a legacy spec source through the capability model."""
self.register_capability_source(source.as_capability_source())
def _hydrate_connection_source_from_snapshot(
self,
connection: ConnectionConfig,
-59
View File
@@ -1,59 +0,0 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
from wf_authoring import NodeSpec
from .capability_sources import (
CapabilityBuckets,
CapabilitySource,
SourceKind,
SourcePermissions,
SourceVisibility,
)
@dataclass(slots=True)
class SpecSource:
"""Compatibility wrapper for planner node specs.
Visibility and permissions stay explicit so callers do not infer source
semantics from the legacy ``kind`` field during the capability-source move.
"""
id: str
kind: SourceKind
specs: dict[str, NodeSpec[Any, Any]] = field(default_factory=dict)
enabled: bool = True
visible: bool = True
mcp_client_visible: bool = False
admin_dashboard_visible: bool = True
safe_for_workflow: bool = False
calls_upstream: bool = False
mutates_config: bool = False
mutates_auth: bool = False
description: str | None = None
def as_capability_source(self) -> CapabilitySource:
return CapabilitySource(
id=self.id,
kind=self.kind,
capabilities=CapabilityBuckets(node_specs=dict(self.specs)),
enabled=self.enabled,
visibility=SourceVisibility(
planner=self.visible,
mcp_client=self.mcp_client_visible,
admin_dashboard=self.admin_dashboard_visible,
),
permissions=SourcePermissions(
safe_for_workflow=self.safe_for_workflow,
calls_upstream=self.calls_upstream,
mutates_config=self.mutates_config,
mutates_auth=self.mutates_auth,
),
description=self.description,
)
def as_status(self) -> dict[str, Any]:
return self.as_capability_source().as_status()