unofficially add wf.std as source
This commit is contained in:
@@ -55,11 +55,19 @@ async def run_example() -> dict[str, object]:
|
||||
"node": "fixture.personal.echo_tool",
|
||||
"in_map": {"input.text": "text"},
|
||||
"out_map": {"echoed": "state.echoed"},
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "raise_mcp_error",
|
||||
"type": "node",
|
||||
"node": "wf.std.runtime_error",
|
||||
"in_map": {"input.text": "message"},
|
||||
"out_map": {},
|
||||
},
|
||||
],
|
||||
edges=[
|
||||
{"from": "echo", "outcome": "ok", "to": END},
|
||||
{"from": "echo", "outcome": "error", "to": END}, # workaround for now; i need wf_authoring.ops::runtime_error
|
||||
{"from": "echo", "outcome": "error", "to": "raise_mcp_error"},
|
||||
{"from": "raise_mcp_error", "outcome": "ok", "to": END},
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -101,6 +101,8 @@ def node(
|
||||
description=description or fn.description,
|
||||
is_async=is_async if is_async is not None else fn.is_async,
|
||||
accepts_context=fn.accepts_context,
|
||||
input_schema_contract=fn.input_schema_contract,
|
||||
output_schema_contract=fn.output_schema_contract,
|
||||
)
|
||||
|
||||
inferred_input_model: type[BaseModel] | None = input_model
|
||||
|
||||
@@ -61,7 +61,9 @@ class NodeSpec(Generic[InputT, OutputT]):
|
||||
is_async: bool = False
|
||||
accepts_context: bool = True
|
||||
input_schema_contract: dict[str, Any] | None = None
|
||||
"enforced schema, if None use input_model"
|
||||
output_schema_contract: dict[str, Any] | None = None
|
||||
"enforced schema, if None use output_model"
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from wf_authoring import NodeSpec, node, runtime_error
|
||||
|
||||
from .specs import qualify_spec
|
||||
|
||||
BUILTIN_CONNECTION_ID = "wf.std"
|
||||
"""Internal source id for workflow standard-library node specs."""
|
||||
|
||||
|
||||
def builtin_specs() -> dict[str, NodeSpec[Any, Any]]:
|
||||
"""Return built-in NodeSpecs available to raw broker workflow plans."""
|
||||
specs = [
|
||||
node(
|
||||
runtime_error,
|
||||
name="runtime_error",
|
||||
description="Fail the current workflow branch with a runtime error.",
|
||||
)
|
||||
]
|
||||
qualified_specs = [qualify_spec(BUILTIN_CONNECTION_ID, spec) for spec in specs]
|
||||
return {spec.name: spec for spec in qualified_specs}
|
||||
@@ -23,6 +23,7 @@ from ..catalog import CombinedCatalog, snapshot_from_specs
|
||||
from ..discovery import discover_connection_capabilities, specs_from_discovered_tools
|
||||
from ..events import McpEvent, make_event
|
||||
from .adapters import require_adapter
|
||||
from .builtins import BUILTIN_CONNECTION_ID, builtin_specs
|
||||
from .specs import get_qualified_spec, qualify_spec
|
||||
|
||||
|
||||
@@ -36,6 +37,12 @@ class WfMcpService:
|
||||
default_factory=dict
|
||||
)
|
||||
events: list[McpEvent] = field(default_factory=list)
|
||||
include_builtin_specs: bool = True
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""Install broker-local standard-library specs when enabled."""
|
||||
if self.include_builtin_specs:
|
||||
self.specs_by_connection.setdefault(BUILTIN_CONNECTION_ID, builtin_specs())
|
||||
|
||||
def register_connection(self, connection: ConnectionConfig) -> None:
|
||||
parse_connection_id(connection.id)
|
||||
|
||||
Vendored
+2
@@ -8,9 +8,11 @@ from pydantic import Field
|
||||
|
||||
server = FastMCP("echo-fixture")
|
||||
|
||||
|
||||
class EchoToolResult(TypedDict):
|
||||
echoed: str
|
||||
|
||||
|
||||
@server.tool(title="Echo tool")
|
||||
async def echo_tool(
|
||||
text: Annotated[str, Field(description="Text to echo")],
|
||||
|
||||
@@ -67,7 +67,7 @@ class Context(TypedDict): # dataclass support? no. i mean langgraph doesnt.
|
||||
### what about us? how should we handle context?
|
||||
#
|
||||
# in the future if wed like, we could handle context. This could be useful for lda.chat!
|
||||
# i want lda.chat to be/have a meta-agent. So i could spin up ideas! a
|
||||
# i want lda.chat to be/have a meta-agent. So i could spin up ideas! a
|
||||
|
||||
|
||||
class ContextInput(BaseModel):
|
||||
|
||||
@@ -34,6 +34,22 @@ def test_service_builds_namespaced_catalog() -> None:
|
||||
]
|
||||
|
||||
|
||||
def test_service_installs_builtin_stdlib_specs_by_default() -> None:
|
||||
service = WfMcpService(store=FileStore(local_temp_root() / "builtin_store"))
|
||||
|
||||
assert "wf.std" in service.specs_by_connection
|
||||
assert "wf.std.runtime_error" in service.specs_by_connection["wf.std"]
|
||||
|
||||
|
||||
def test_service_can_disable_builtin_stdlib_specs() -> None:
|
||||
service = WfMcpService(
|
||||
store=FileStore(local_temp_root() / "no_builtin_store"),
|
||||
include_builtin_specs=False,
|
||||
)
|
||||
|
||||
assert "wf.std" not in service.specs_by_connection
|
||||
|
||||
|
||||
def test_service_compiles_and_runs_raw_plan() -> None:
|
||||
service = WfMcpService(store=FileStore(local_temp_root() / "run_store"))
|
||||
service.register_connection(
|
||||
|
||||
Reference in New Issue
Block a user