feat: expose draft lifecycle rpc methods

This commit is contained in:
lda
2026-07-21 20:17:05 +07:00 Verified
parent ee477c01a4
commit 4c36597f51
4 changed files with 236 additions and 2 deletions
+6
View File
@@ -13,6 +13,7 @@ from .models import (
CreateArtifactFromPlanParams,
CreateArtifactFromWorkspaceParams,
CreateDraftFromCapabilityParams,
CreateEmptyDraftWorkspaceParams,
CreateWrapperFromWorkspaceParams,
DeleteDeploymentParams,
GetDraftWorkspaceParams,
@@ -38,8 +39,10 @@ from .models import (
ResumeRunParams,
SaveArtifactParams,
SaveDeploymentParams,
SetDraftContractParams,
SetDraftNameParams,
SetDraftRouteParams,
SetDraftStartParams,
SetStepInputMapParams,
SetStepOutputMapParams,
SetWorkflowOutputMapParams,
@@ -60,6 +63,7 @@ __all__ = [
"CreateArtifactFromPlanParams",
"CreateArtifactFromWorkspaceParams",
"CreateDraftFromCapabilityParams",
"CreateEmptyDraftWorkspaceParams",
"CreateWrapperFromWorkspaceParams",
"DeleteDeploymentParams",
"GetDraftWorkspaceParams",
@@ -85,8 +89,10 @@ __all__ = [
"ResumeRunParams",
"SaveArtifactParams",
"SaveDeploymentParams",
"SetDraftContractParams",
"SetDraftNameParams",
"SetDraftRouteParams",
"SetDraftStartParams",
"SetStepInputMapParams",
"SetStepOutputMapParams",
"SetWorkflowOutputMapParams",
@@ -16,6 +16,7 @@ from ..models import (
CompileDraftWorkspaceParams,
CreateArtifactFromWorkspaceParams,
CreateDraftFromCapabilityParams,
CreateEmptyDraftWorkspaceParams,
CreateWrapperFromWorkspaceParams,
DeleteDraftWorkspaceParams,
GetDraftWorkspaceParams,
@@ -26,8 +27,10 @@ from ..models import (
RemoveDraftBindingParams,
RemoveDraftRouteParams,
RemoveDraftStepParams,
SetDraftContractParams,
SetDraftNameParams,
SetDraftRouteParams,
SetDraftStartParams,
SetStepInputMapParams,
SetStepOutputMapParams,
SetWorkflowOutputMapParams,
@@ -105,6 +108,26 @@ def register_methods(
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(
name="workflow.draft_workspaces.create_empty",
errors=[WorkflowRpcError],
)
async def workflow_draft_workspaces_create_empty(
params: CreateEmptyDraftWorkspaceParams = RpcParams(),
) -> dict[str, Any]:
try:
return await server.api.create_empty_draft_workspace(
workspace_id=params.workspace_id,
name=params.name,
title=params.title,
input_schema=params.input_schema,
state_schema=params.state_schema,
output_schema=params.output_schema,
outcomes=params.outcomes,
)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(
name="workflow.draft_workspaces.patch", errors=[WorkflowRpcError]
)
@@ -135,6 +158,39 @@ def register_methods(
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(
name="workflow.draft_workspaces.set_start", errors=[WorkflowRpcError]
)
async def workflow_draft_workspaces_set_start(
params: SetDraftStartParams = RpcParams(),
) -> dict[str, Any]:
try:
return await server.api.set_draft_start(
workspace_id=params.workspace_id,
revision=params.revision,
step_id=params.step_id,
)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(
name="workflow.draft_workspaces.set_contract", errors=[WorkflowRpcError]
)
async def workflow_draft_workspaces_set_contract(
params: SetDraftContractParams = RpcParams(),
) -> dict[str, Any]:
try:
return await server.api.set_draft_contract(
workspace_id=params.workspace_id,
revision=params.revision,
input_schema=params.input_schema,
state_schema=params.state_schema,
output_schema=params.output_schema,
outcomes=params.outcomes,
)
except (ValueError, KeyError, LookupError, FileNotFoundError) as exc:
raise_workflow_rpc_error(exc)
@entrypoint.method(
name="workflow.draft_workspaces.set_route", errors=[WorkflowRpcError]
)
+62 -2
View File
@@ -1,8 +1,8 @@
from __future__ import annotations
from typing import Any, Literal
from typing import Any, Literal, Self
from pydantic import BaseModel, ConfigDict, Field
from pydantic import BaseModel, ConfigDict, Field, model_validator
from wf_api.models import TraceRange
from wf_artifacts.drafts.models import DraftStep
@@ -80,6 +80,31 @@ class CreateDraftFromCapabilityParams(RpcParamsModel):
error_message_source: Any | None = None
def _validate_workflow_outcomes(outcomes: list[str]) -> None:
"""Reject outcome lists that cannot form a public workflow contract."""
if not outcomes:
raise ValueError("workflow outcomes must contain at least one value")
if any(not outcome.strip() for outcome in outcomes):
raise ValueError("workflow outcomes must not contain blank values")
if len(set(outcomes)) != len(outcomes):
raise ValueError("workflow outcomes must be unique")
class CreateEmptyDraftWorkspaceParams(RpcParamsModel):
workspace_id: str = Field(min_length=1)
name: str = Field(min_length=1)
title: str | None = None
input_schema: dict[str, Any] | None = None
state_schema: dict[str, Any] | None = None
output_schema: dict[str, Any] | None = None
outcomes: list[str] = Field(default_factory=lambda: ["ok"])
@model_validator(mode="after")
def validate_outcomes(self) -> Self:
_validate_workflow_outcomes(self.outcomes)
return self
class PatchDraftParams(RpcParamsModel):
draft: dict[str, Any]
patch: list[dict[str, Any]]
@@ -132,6 +157,41 @@ class SetDraftNameParams(RpcParamsModel):
name: str = Field(min_length=1)
class SetDraftStartParams(RpcParamsModel):
workspace_id: str = Field(min_length=1)
revision: int = Field(ge=1)
step_id: str = Field(min_length=1)
@model_validator(mode="after")
def validate_step_id(self) -> Self:
if not self.step_id.strip():
raise ValueError("draft start step id must not be blank")
return self
class SetDraftContractParams(RpcParamsModel):
workspace_id: str = Field(min_length=1)
revision: int = Field(ge=1)
input_schema: dict[str, Any] | None = None
state_schema: dict[str, Any] | None = None
output_schema: dict[str, Any] | None = None
outcomes: list[str] | None = None
@model_validator(mode="after")
def validate_contract_edit(self) -> Self:
fields = (
self.input_schema,
self.state_schema,
self.output_schema,
self.outcomes,
)
if all(value is None for value in fields):
raise ValueError("set_contract requires at least one contract field")
if self.outcomes is not None:
_validate_workflow_outcomes(self.outcomes)
return self
class SetDraftRouteParams(RpcParamsModel):
workspace_id: str = Field(min_length=1)
revision: int = Field(ge=1)