example + fmt
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from wf_core import END, RuntimeContext, Workflow, execute_workflow
|
||||||
|
from wf_core.run_state import RunState
|
||||||
|
|
||||||
|
|
||||||
|
def build_raw_canonical_workflow() -> Workflow:
|
||||||
|
"""Build a raw core workflow using the canonical post-migration shape."""
|
||||||
|
return Workflow.model_validate(
|
||||||
|
{
|
||||||
|
"name": "raw_canonical_echo",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"text": {"type": "string"}},
|
||||||
|
"required": ["text"],
|
||||||
|
},
|
||||||
|
"state_schema": {
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"path": "state.message",
|
||||||
|
"schema": {"type": "string"},
|
||||||
|
"reducer": {"name": "wf.std.replace"},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"output_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"message": {"type": "string"}},
|
||||||
|
"required": ["message"],
|
||||||
|
},
|
||||||
|
"node_defs": [
|
||||||
|
{
|
||||||
|
"name": "format_text",
|
||||||
|
"input_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"text": {"type": "string"},
|
||||||
|
"prefix": {"type": "string"},
|
||||||
|
},
|
||||||
|
"required": ["text", "prefix"],
|
||||||
|
},
|
||||||
|
"output_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {"message": {"type": "string"}},
|
||||||
|
"required": ["message"],
|
||||||
|
},
|
||||||
|
"outcomes": ["ok"],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"start": "format",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "format",
|
||||||
|
"type": "node",
|
||||||
|
"node": "format_text",
|
||||||
|
"input": [
|
||||||
|
{"target": "text", "path": "input.text"},
|
||||||
|
{"target": "prefix", "value": "raw:"},
|
||||||
|
],
|
||||||
|
"output": [{"source": "message", "target": "state.message"}],
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": [{"from": "format", "outcome": "ok", "to": END}],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def build_raw_canonical_registry():
|
||||||
|
"""Return handlers for the raw canonical workflow example."""
|
||||||
|
|
||||||
|
def format_text(payload: dict[str, object], _context: RuntimeContext):
|
||||||
|
text = str(payload["text"]).upper()
|
||||||
|
prefix = str(payload["prefix"])
|
||||||
|
return {"message": f"{prefix}{text}"}
|
||||||
|
|
||||||
|
return {"format_text": format_text}
|
||||||
|
|
||||||
|
|
||||||
|
def run_raw_canonical_example(text: str = "hello") -> RunState:
|
||||||
|
workflow = build_raw_canonical_workflow()
|
||||||
|
workflow.validate_structure().raise_for_errors()
|
||||||
|
return execute_workflow(workflow, {"text": text}, build_raw_canonical_registry())
|
||||||
@@ -7,6 +7,7 @@ from fastmcp.mcp_config import MCPConfig
|
|||||||
from .models import BrokerConfig, ConnectionConfig
|
from .models import BrokerConfig, ConnectionConfig
|
||||||
from .proxy_validation import validate_proxy_config
|
from .proxy_validation import validate_proxy_config
|
||||||
|
|
||||||
|
|
||||||
def connection_to_fastmcp_server_config(
|
def connection_to_fastmcp_server_config(
|
||||||
connection: ConnectionConfig,
|
connection: ConnectionConfig,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from wf_core import RunStatus
|
||||||
|
|
||||||
|
from examples.raw_canonical_workflow import (
|
||||||
|
build_raw_canonical_workflow,
|
||||||
|
run_raw_canonical_example,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_raw_canonical_workflow_runs() -> None:
|
||||||
|
run = run_raw_canonical_example("hello")
|
||||||
|
|
||||||
|
assert run.status == RunStatus.COMPLETED
|
||||||
|
assert run.output["message"] == "raw:HELLO"
|
||||||
|
assert run.state["message"] == "raw:HELLO"
|
||||||
|
assert run.trace[0].resolved_input["text"] == "hello"
|
||||||
|
assert run.trace[0].resolved_input["prefix"] == "raw:"
|
||||||
|
|
||||||
|
|
||||||
|
def test_raw_canonical_workflow_serializes_new_shape() -> None:
|
||||||
|
workflow = build_raw_canonical_workflow()
|
||||||
|
dumped = workflow.model_dump(mode="json")
|
||||||
|
node = dumped["nodes"][0]
|
||||||
|
state_field = dumped["state_schema"]["fields"][0]
|
||||||
|
|
||||||
|
assert "input" in node
|
||||||
|
assert "output" in node
|
||||||
|
assert "in_map" not in node
|
||||||
|
assert "input_values" not in node
|
||||||
|
assert "out_map" not in node
|
||||||
|
assert node["input"][0]["path"] == "input.text"
|
||||||
|
assert node["input"][0]["target"] == "text"
|
||||||
|
assert node["input"][1]["value"] == "raw:"
|
||||||
|
assert node["output"][0]["source"] == "message"
|
||||||
|
assert node["output"][0]["target"] == "state.message"
|
||||||
|
assert state_field["path"] == "state.message"
|
||||||
|
assert state_field["schema"]["type"] == "string"
|
||||||
Reference in New Issue
Block a user