feat: expose composite step inputs
This commit is contained in:
@@ -11,7 +11,7 @@ from wf_artifacts import (
|
||||
)
|
||||
from wf_authoring import build_async_registry
|
||||
from wf_core import RuntimeContext
|
||||
from wf_core.models.steps import InputBinding, OutputBinding
|
||||
from wf_core.models.steps import OutputBinding, StepInputBinding
|
||||
from wf_core.paths import GraphSourcePath
|
||||
from wf_platform import CapabilitySource
|
||||
|
||||
@@ -389,7 +389,7 @@ class WorkflowCapabilityApi:
|
||||
input_schema: dict[str, Any] | None = None,
|
||||
state_schema: dict[str, Any] | None = None,
|
||||
output_schema: dict[str, Any] | None = None,
|
||||
input: Sequence[InputBinding] | None = None,
|
||||
input: Sequence[StepInputBinding] | None = None,
|
||||
output: Sequence[OutputBinding] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
output_map: dict[str, str] | None = None,
|
||||
|
||||
@@ -30,6 +30,7 @@ from wf_core.models.steps import (
|
||||
InputPathBinding,
|
||||
InputValueBinding,
|
||||
OutputBinding,
|
||||
StepInputBinding,
|
||||
)
|
||||
from wf_core.paths import (
|
||||
GraphSourcePath,
|
||||
@@ -54,11 +55,7 @@ from .draft_payloads import (
|
||||
state_root_field,
|
||||
)
|
||||
from .draft_updates import CapabilityStepUpdate
|
||||
from .drafts import (
|
||||
WorkflowDraftApi,
|
||||
_draft_input_maps,
|
||||
_draft_output_map,
|
||||
)
|
||||
from .drafts import WorkflowDraftApi, _draft_output_map
|
||||
from .input_expressions import (
|
||||
validate_and_project_input_expression,
|
||||
validate_schema_references,
|
||||
@@ -101,7 +98,7 @@ def _upsert_input_path_binding(
|
||||
step_id: str,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Update one graph source without lowering unrelated canonical bindings."""
|
||||
bindings = TypeAdapter(list[InputBinding]).validate_python(payload)
|
||||
bindings = TypeAdapter(list[StepInputBinding]).validate_python(payload)
|
||||
matching = [
|
||||
index
|
||||
for index, existing in enumerate(bindings)
|
||||
@@ -208,7 +205,7 @@ def _rebind_workflow_output(
|
||||
|
||||
|
||||
def _overlapping_input_binding_targets_error(
|
||||
bindings: Sequence[InputBinding],
|
||||
bindings: Sequence[StepInputBinding],
|
||||
) -> ValueError:
|
||||
"""Describe the first overlapping input-shaped target pair."""
|
||||
for left_index, left in enumerate(bindings):
|
||||
@@ -473,7 +470,7 @@ class WorkflowDraftAuthoringApi:
|
||||
input_schema: dict[str, Any],
|
||||
state_schema: dict[str, Any],
|
||||
output_schema: dict[str, Any],
|
||||
input: Sequence[InputBinding] | None = None,
|
||||
input: Sequence[StepInputBinding] | None = None,
|
||||
output: Sequence[OutputBinding] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
output_map: dict[str, str] | None = None,
|
||||
@@ -481,9 +478,12 @@ class WorkflowDraftAuthoringApi:
|
||||
title: str | None = None,
|
||||
) -> DraftWorkspaceResult:
|
||||
"""Bootstrap the smallest patchable draft around one workflow capability."""
|
||||
draft_input, draft_with = _draft_input_maps(
|
||||
input=input,
|
||||
input_map=input_map,
|
||||
if input is not None and input_map is not None:
|
||||
raise ValueError("cannot mix canonical input bindings with input_map")
|
||||
input_payload = (
|
||||
[binding.model_dump(mode="json") for binding in input]
|
||||
if input is not None
|
||||
else input_bindings_payload(input_map or {}, {})
|
||||
)
|
||||
draft_output = _draft_output_map(output=output, output_map=output_map)
|
||||
outcomes = self._outcomes_for_capability(capability_name) or (
|
||||
@@ -492,7 +492,7 @@ class WorkflowDraftAuthoringApi:
|
||||
steps: dict[str, Any] = {
|
||||
DEFAULT_CALL_STEP_ID: {
|
||||
"use": capability_name,
|
||||
"input": input_bindings_payload(draft_input, draft_with),
|
||||
"input": input_payload,
|
||||
"output": output_bindings_payload(draft_output),
|
||||
}
|
||||
}
|
||||
@@ -537,7 +537,7 @@ class WorkflowDraftAuthoringApi:
|
||||
workspace_id: str,
|
||||
revision: int,
|
||||
step_id: str,
|
||||
bindings: Sequence[InputBinding],
|
||||
bindings: Sequence[StepInputBinding],
|
||||
) -> DraftWorkspaceResult:
|
||||
"""Replace one capability step's canonical input bindings atomically."""
|
||||
checked = self._workspace_if_revision_matches(
|
||||
@@ -604,7 +604,7 @@ class WorkflowDraftAuthoringApi:
|
||||
*,
|
||||
workspace: WorkflowDraftWorkspace,
|
||||
capability_name: str,
|
||||
bindings: Sequence[InputBinding],
|
||||
bindings: Sequence[StepInputBinding],
|
||||
) -> _ProjectedStepInputBindings:
|
||||
"""Validate canonical inputs and project missing workflow source schemas."""
|
||||
spec = self.context.specs.get_qualified_spec(capability_name)
|
||||
@@ -1259,7 +1259,7 @@ class WorkflowDraftAuthoringApi:
|
||||
route_from_outcome: str = DEFAULT_OK_OUTCOME,
|
||||
routes: dict[str, str] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
input_bindings: Sequence[InputBinding] | None = None,
|
||||
input_bindings: Sequence[StepInputBinding] | None = None,
|
||||
bind_outputs: dict[str, str] | None = None,
|
||||
desc: str | None = None,
|
||||
retry: int | None = None,
|
||||
@@ -1349,7 +1349,7 @@ class WorkflowDraftAuthoringApi:
|
||||
)
|
||||
|
||||
if input_bindings is None:
|
||||
canonical_inputs = TypeAdapter(list[InputBinding]).validate_python(
|
||||
canonical_inputs = TypeAdapter(list[StepInputBinding]).validate_python(
|
||||
input_bindings_payload(input_map or {}, {})
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Self
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
|
||||
from wf_core.models.steps import InputBinding
|
||||
from wf_core.models.steps import StepInputBinding
|
||||
|
||||
|
||||
class CapabilityStepUpdate(BaseModel):
|
||||
@@ -15,7 +15,7 @@ class CapabilityStepUpdate(BaseModel):
|
||||
desc: str | None = Field(default=None, min_length=1)
|
||||
retry: int | None = Field(default=None, ge=0)
|
||||
timeout_seconds: int | None = Field(default=None, gt=0)
|
||||
input: list[InputBinding] | None = None
|
||||
input: list[StepInputBinding] | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_patch_shape(self) -> Self:
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any
|
||||
|
||||
from wf_artifacts import ArtifactKind
|
||||
from wf_artifacts.drafts.models import DraftStep
|
||||
from wf_core.models.steps import InputBinding, OutputBinding
|
||||
from wf_core.models.steps import InputBinding, OutputBinding, StepInputBinding
|
||||
|
||||
from .artifacts import WorkflowArtifactApi
|
||||
from .capabilities import WorkflowCapabilityApi
|
||||
@@ -457,7 +457,7 @@ class WorkflowApi:
|
||||
workspace_id: str,
|
||||
revision: int,
|
||||
step_id: str,
|
||||
bindings: Sequence[InputBinding],
|
||||
bindings: Sequence[StepInputBinding],
|
||||
) -> DraftWorkspaceResult:
|
||||
return await self.draft_authoring.set_step_input_bindings(
|
||||
workspace_id=workspace_id,
|
||||
@@ -570,7 +570,7 @@ class WorkflowApi:
|
||||
route_from_outcome: str = "ok",
|
||||
routes: dict[str, str] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
input_bindings: Sequence[InputBinding] | None = None,
|
||||
input_bindings: Sequence[StepInputBinding] | None = None,
|
||||
bind_outputs: dict[str, str] | None = None,
|
||||
desc: str | None = None,
|
||||
retry: int | None = None,
|
||||
@@ -653,8 +653,8 @@ class WorkflowApi:
|
||||
input_schema: dict[str, Any],
|
||||
state_schema: dict[str, Any],
|
||||
output_schema: dict[str, Any],
|
||||
input: Sequence[Any] | None = None,
|
||||
output: Sequence[Any] | None = None,
|
||||
input: Sequence[StepInputBinding] | None = None,
|
||||
output: Sequence[OutputBinding] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
output_map: dict[str, str] | None = None,
|
||||
error_message_source: Any | None = None,
|
||||
@@ -730,8 +730,8 @@ class WorkflowApi:
|
||||
input_schema: dict[str, Any] | None = None,
|
||||
state_schema: dict[str, Any] | None = None,
|
||||
output_schema: dict[str, Any] | None = None,
|
||||
input: Sequence[Any] | None = None,
|
||||
output: Sequence[Any] | None = None,
|
||||
input: Sequence[StepInputBinding] | None = None,
|
||||
output: Sequence[OutputBinding] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
output_map: dict[str, str] | None = None,
|
||||
error_message_source: Any | None = None,
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any, Protocol
|
||||
|
||||
from wf_artifacts import ArtifactKind
|
||||
from wf_artifacts.drafts.models import DraftStep
|
||||
from wf_core.models.steps import InputBinding, OutputBinding
|
||||
from wf_core.models.steps import InputBinding, OutputBinding, StepInputBinding
|
||||
|
||||
from .draft_authoring import RouteSource
|
||||
from .draft_updates import CapabilityStepUpdate
|
||||
@@ -117,8 +117,8 @@ class WorkflowDraftSurface(Protocol):
|
||||
input_schema: dict[str, Any] | None = None,
|
||||
state_schema: dict[str, Any] | None = None,
|
||||
output_schema: dict[str, Any] | None = None,
|
||||
input: Sequence[Any] | None = None,
|
||||
output: Sequence[Any] | None = None,
|
||||
input: Sequence[StepInputBinding] | None = None,
|
||||
output: Sequence[OutputBinding] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
output_map: dict[str, str] | None = None,
|
||||
error_message_source: Any | None = None,
|
||||
@@ -207,7 +207,7 @@ class WorkflowDraftSurface(Protocol):
|
||||
workspace_id: str,
|
||||
revision: int,
|
||||
step_id: str,
|
||||
bindings: Sequence[InputBinding],
|
||||
bindings: Sequence[StepInputBinding],
|
||||
) -> DraftWorkspaceResult: ...
|
||||
|
||||
async def set_step_output_bindings(
|
||||
@@ -276,7 +276,7 @@ class WorkflowDraftSurface(Protocol):
|
||||
route_from_outcome: str = "ok",
|
||||
routes: dict[str, str] | None = None,
|
||||
input_map: dict[str, str] | None = None,
|
||||
input_bindings: Sequence[InputBinding] | None = None,
|
||||
input_bindings: Sequence[StepInputBinding] | None = None,
|
||||
bind_outputs: dict[str, str] | None = None,
|
||||
desc: str | None = None,
|
||||
retry: int | None = None,
|
||||
|
||||
Reference in New Issue
Block a user