get end node support in builder and drafts

This commit is contained in:
lda
2026-05-26 00:59:29 +07:00 Verified
parent 6846c649b6
commit 95532b1cf9
7 changed files with 115 additions and 2 deletions
+28 -1
View File
@@ -5,7 +5,7 @@ from pydantic import ValidationError
from wf_artifacts.drafts import WorkflowDraft
from wf_artifacts.drafts.api import compile_workflow_draft, validate_workflow_draft
from wf_artifacts.drafts.adapter import build_workflow_from_draft
from wf_core import ConditionNode, ForeachNode, NodeUse
from wf_core import ConditionNode, EndNode, ForeachNode, NodeUse
from wf_core.models.steps import InputValueBinding
@@ -213,6 +213,33 @@ def test_adapter_lowers_when_step_through_builder() -> None:
]
def test_adapter_lowers_explicit_end_step() -> None:
draft = WorkflowDraft.model_validate(
{
"name": "end_example",
"input_schema": {},
"state_schema": {"fields": {}},
"output_schema": {},
"outcomes": ["ok", "error"],
"start": "echo",
"steps": {
"echo": {"use": "demo.echo"},
"end_error": {"end": {"outcome": "error"}},
},
"routes": {"echo": {"error": "end_error"}},
}
)
workflow = build_workflow_from_draft(draft)
terminal = workflow.nodes[1]
assert isinstance(terminal, EndNode)
assert terminal.id == "end_error"
assert terminal.outcome == "error"
assert workflow.outcomes == ["ok", "error"]
assert workflow.edges[0].to == "end_error"
def test_adapter_lowers_choose_step_through_builder() -> None:
draft = WorkflowDraft.model_validate(
{
+20
View File
@@ -7,6 +7,7 @@ from pydantic import ValidationError
from wf_artifacts.drafts import (
DraftChooseStep,
DraftEndStep,
DraftForeachStep,
DraftMatchStep,
DraftUseStep,
@@ -135,6 +136,25 @@ def test_workflow_draft_accepts_when_step() -> None:
assert isinstance(draft.steps["decide"], DraftWhenStep)
def test_workflow_draft_accepts_explicit_end_step() -> None:
draft = WorkflowDraft.model_validate(
{
**_keyed_echo_draft(),
"outcomes": ["ok", "error"],
"steps": {
**_keyed_echo_draft()["steps"],
"end_error": {"end": {"outcome": "error"}},
},
"routes": {"echo": {"error": "end_error"}},
}
)
terminal = draft.steps["end_error"]
assert isinstance(terminal, DraftEndStep)
assert terminal.end.outcome == "error"
def test_workflow_draft_accepts_choose_step() -> None:
draft = WorkflowDraft.model_validate(
{
+20 -1
View File
@@ -14,7 +14,7 @@ from wf_authoring import (
state,
state_path,
)
from wf_core import END, RunStatus, WorkflowExecutionError
from wf_core import END, EndNode, RunStatus, WorkflowExecutionError
from wf_core.models.steps import InputPathBinding, InputValueBinding
from wf_core.paths import GraphSourcePath, LocalPath, StatePath
from wf_platform import CapabilityRef
@@ -455,6 +455,25 @@ def test_builder_rejects_mixed_canonical_and_deprecated_output_styles() -> None:
)
def test_builder_adds_explicit_end_node() -> None:
builder = WorkflowBuilder(
name="explicit_end",
input_schema={},
state_schema={"fields": {}},
output_schema={},
outcomes=["ok", "error"],
)
terminal = builder.end("error", id="end_error")
assert isinstance(terminal, EndNode)
assert terminal.id == "end_error"
assert terminal.outcome == "error"
assert builder.nodes[-1] is terminal
builder.set_entry_point(terminal)
assert builder.compile().outcomes == ["ok", "error"]
class _StructuralKeyMap(Mapping[object, object]):
def __getitem__(self, key: object) -> object:
raise KeyError(key)