feat: authorize workflow contract authoring

This commit is contained in:
lda
2026-08-14 17:43:14 +07:00 Verified
parent bc23a722c3
commit bd226a2fa7
20 changed files with 1506 additions and 14 deletions
+251
View File
@@ -246,6 +246,198 @@
], ],
"type": "object" "type": "object"
}, },
"AuthoringContractInventoryPayload": {
"description": "Revision-scoped readable sources and writable authoring targets.",
"properties": {
"entry_steps": {
"items": {
"$ref": "#/components/schemas/AuthoringStepContractPayload"
},
"type": "array"
},
"readable_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"revision": {
"type": "integer"
},
"selected_step_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"state_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_input_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_output_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
},
"workflow_outcomes": {
"items": {
"type": "string"
},
"type": "array"
},
"workflow_output_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"workspace_id": {
"type": "string"
}
},
"required": [
"workspace_id",
"revision",
"selected_step_id",
"readable_sources",
"step_input_targets",
"step_output_sources",
"state_targets",
"workflow_output_targets",
"entry_steps",
"workflow_outcomes",
"warnings"
],
"type": "object"
},
"AuthoringPathAvailability": {
"enum": [
"available",
"conditional"
],
"type": "string"
},
"AuthoringPathOptionPayload": {
"description": "One schema-derived source or target available to an author.",
"properties": {
"availability": {
"$ref": "#/components/schemas/AuthoringPathAvailability"
},
"description": {
"type": "string"
},
"label": {
"type": "string"
},
"origin": {
"$ref": "#/components/schemas/AuthoringPathOrigin"
},
"path": {
"type": "string"
},
"reason": {
"type": "string"
},
"required": {
"type": "boolean"
},
"schema": {
"$ref": "#/components/schemas/JsonObject"
},
"uses": {
"items": {
"$ref": "#/components/schemas/AuthoringPathUse"
},
"type": "array"
}
},
"required": [
"path",
"label",
"origin",
"schema",
"required",
"availability",
"uses"
],
"type": "object"
},
"AuthoringPathOrigin": {
"enum": [
"workflow_input",
"workflow_state",
"runtime_context",
"step_input",
"step_output",
"workflow_output"
],
"type": "string"
},
"AuthoringPathUse": {
"enum": [
"step_input",
"step_output_source",
"state_target",
"workflow_output"
],
"type": "string"
},
"AuthoringStepContractPayload": {
"description": "Compact executable-step choice used by authoring inventories.",
"properties": {
"description": {
"type": "string"
},
"input_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"label": {
"type": "string"
},
"outcomes": {
"items": {
"type": "string"
},
"type": "array"
},
"output_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_id": {
"type": "string"
}
},
"required": [
"step_id",
"label"
],
"type": "object"
},
"BinaryCondition": { "BinaryCondition": {
"description": "Condition that compares two operands.", "description": "Condition that compares two operands.",
"properties": { "properties": {
@@ -6953,6 +7145,65 @@
} }
} }
}, },
{
"action": "inspect_authoring_contract",
"errors": [
{
"$ref": "#/components/errors/5000"
}
],
"method": "workflow.draft_workspaces.inspect_authoring_contract",
"namespace": [
"workflow",
"draft_workspaces"
],
"params": [
{
"name": "workspace_id",
"required": true,
"schema": {
"minLength": 1,
"type": "string"
}
},
{
"name": "revision",
"required": true,
"schema": {
"minimum": 1,
"type": "integer"
}
},
{
"name": "selected_step_id",
"required": false,
"schema": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
}
],
"result": {
"schema": {
"anyOf": [
{
"$ref": "#/components/schemas/AuthoringContractInventoryPayload"
},
{
"$ref": "#/components/schemas/DraftWorkspaceResult"
}
]
}
}
},
{ {
"action": "list", "action": "list",
"errors": [ "errors": [
+15 -8
View File
@@ -255,9 +255,7 @@ def manifest_from_openrpc(document: Mapping[str, object]) -> ContractManifest:
params.append( params.append(
{ {
"name": _string(parameter.get("name"), f"{parameter_path}.name"), "name": _string(parameter.get("name"), f"{parameter_path}.name"),
"required": _boolean( "required": _boolean(raw_required, f"{parameter_path}.required"),
raw_required, f"{parameter_path}.required"
),
"schema": _schema( "schema": _schema(
parameter.get("schema"), f"{parameter_path}.schema" parameter.get("schema"), f"{parameter_path}.schema"
), ),
@@ -271,12 +269,21 @@ def manifest_from_openrpc(document: Mapping[str, object]) -> ContractManifest:
f"{result_path}.schema", "missing success result schema" f"{result_path}.schema", "missing success result schema"
) )
raw_result_schema = result["schema"] raw_result_schema = result["schema"]
if not isinstance(raw_result_schema, Mapping) or ( if not isinstance(raw_result_schema, Mapping):
set(raw_result_schema) != {"$ref"} raise ManifestError(
or not ( f"{result_path}.schema",
isinstance(raw_result_schema.get("$ref"), str) "success result must be a schema object",
and raw_result_schema["$ref"].startswith("#/components/schemas/")
) )
named_result = (
set(raw_result_schema) == {"$ref"}
and isinstance(raw_result_schema.get("$ref"), str)
and raw_result_schema["$ref"].startswith("#/components/schemas/")
)
# This inspection RPC returns either its inventory or the standard
# revision-conflict workspace payload, so its OpenRPC result is a union.
if (
not named_result
and method_name != "workflow.draft_workspaces.inspect_authoring_contract"
): ):
raise ManifestError( raise ManifestError(
f"{result_path}.schema", f"{result_path}.schema",
+24 -3
View File
@@ -89,14 +89,24 @@ def test_generates_the_complete_real_workflow_contract() -> None:
manifest = generate_manifest() manifest = generate_manifest()
schemas = manifest["components"]["schemas"] schemas = manifest["components"]["schemas"]
assert len(manifest["operations"]) == 70 assert len(manifest["operations"]) == 71
assert len({operation["method"] for operation in manifest["operations"]}) == 70 assert len({operation["method"] for operation in manifest["operations"]}) == 71
assert len(schemas) == 134 assert len(schemas) == 140
assert len(manifest["components"]["errors"]) == 1 assert len(manifest["components"]["errors"]) == 1
assert all( assert all(
set(operation["result"]["schema"]) == {"$ref"} set(operation["result"]["schema"]) == {"$ref"}
or operation["method"] == "workflow.draft_workspaces.inspect_authoring_contract"
for operation in manifest["operations"] for operation in manifest["operations"]
) )
inspection = next(
operation
for operation in manifest["operations"]
if operation["method"] == "workflow.draft_workspaces.inspect_authoring_contract"
)
assert inspection["result"]["schema"]["anyOf"] == [
{"$ref": "#/components/schemas/AuthoringContractInventoryPayload"},
{"$ref": "#/components/schemas/DraftWorkspaceResult"},
]
assert {name for name in UNION_RESULTS if "anyOf" in schemas[name]} == UNION_RESULTS assert {name for name in UNION_RESULTS if "anyOf" in schemas[name]} == UNION_RESULTS
@@ -175,6 +185,17 @@ def test_manifest_contains_the_two_focused_step_binding_operations() -> None:
} <= methods } <= methods
def test_manifest_contains_the_four_browser_authoring_operations() -> None:
methods = {operation["method"] for operation in generate_manifest()["operations"]}
assert {
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_workflow_output_bindings",
} <= methods
def test_generated_contract_preserves_security_and_extension_boundaries() -> None: def test_generated_contract_preserves_security_and_extension_boundaries() -> None:
manifest = generate_manifest() manifest = generate_manifest()
schemas = manifest["components"]["schemas"] schemas = manifest["components"]["schemas"]
@@ -48,14 +48,18 @@ const OperationNameSchema = v.union([
v.literal("workflow.capabilities.call"), v.literal("workflow.capabilities.call"),
v.literal("workflow.draft_workspaces.list"), v.literal("workflow.draft_workspaces.list"),
v.literal("workflow.draft_workspaces.get"), v.literal("workflow.draft_workspaces.get"),
v.literal("workflow.draft_workspaces.inspect_authoring_contract"),
v.literal("workflow.draft_workspaces.create_empty"), v.literal("workflow.draft_workspaces.create_empty"),
v.literal("workflow.draft_workspaces.create_from_capability"), v.literal("workflow.draft_workspaces.create_from_capability"),
v.literal("workflow.draft_workspaces.add_step_from_capability"), v.literal("workflow.draft_workspaces.add_step_from_capability"),
v.literal("workflow.draft_workspaces.update_capability_step"), v.literal("workflow.draft_workspaces.update_capability_step"),
v.literal("workflow.draft_workspaces.set_route"), v.literal("workflow.draft_workspaces.set_route"),
v.literal("workflow.draft_workspaces.set_contract"),
v.literal("workflow.draft_workspaces.set_start"),
v.literal("workflow.draft_workspaces.set_step_input_bindings"), v.literal("workflow.draft_workspaces.set_step_input_bindings"),
v.literal("workflow.draft_workspaces.set_step_output_bindings"), v.literal("workflow.draft_workspaces.set_step_output_bindings"),
v.literal("workflow.draft_workspaces.validate"), v.literal("workflow.draft_workspaces.validate"),
v.literal("workflow.draft_workspaces.set_workflow_output_bindings"),
v.literal("workflow.artifacts.list"), v.literal("workflow.artifacts.list"),
v.literal("workflow.artifacts.inspect"), v.literal("workflow.artifacts.inspect"),
v.literal("workflow.deployments.list"), v.literal("workflow.deployments.list"),
+38
View File
@@ -260,6 +260,10 @@ describe("POST /api/rpc", () => {
operation: "workflow.draft_workspaces.get", operation: "workflow.draft_workspaces.get",
params: { workspace_id: "draft-1" }, params: { workspace_id: "draft-1" },
}, },
{
operation: "workflow.draft_workspaces.inspect_authoring_contract",
params: { workspace_id: "draft-1", revision: 1 },
},
{ {
operation: "workflow.draft_workspaces.create_empty", operation: "workflow.draft_workspaces.create_empty",
params: { workspace_id: "draft-1", name: "draft.workflow" }, params: { workspace_id: "draft-1", name: "draft.workflow" },
@@ -299,6 +303,14 @@ describe("POST /api/rpc", () => {
target: "__end__", target: "__end__",
}, },
}, },
{
operation: "workflow.draft_workspaces.set_contract",
params: { workspace_id: "draft-1", revision: 1, outcomes: ["ok"] },
},
{
operation: "workflow.draft_workspaces.set_start",
params: { workspace_id: "draft-1", revision: 1, step_id: "echo" },
},
{ {
operation: "workflow.draft_workspaces.set_step_input_bindings", operation: "workflow.draft_workspaces.set_step_input_bindings",
params: { params: {
@@ -321,6 +333,14 @@ describe("POST /api/rpc", () => {
operation: "workflow.draft_workspaces.validate", operation: "workflow.draft_workspaces.validate",
params: { workspace_id: "draft-1" }, params: { workspace_id: "draft-1" },
}, },
{
operation: "workflow.draft_workspaces.set_workflow_output_bindings",
params: {
workspace_id: "draft-1",
revision: 1,
bindings: [{ source: "result", target: "state.result" }],
},
},
{ operation: "workflow.runs.start", params: {} }, { operation: "workflow.runs.start", params: {} },
{ operation: "workflow.runs.resume", params: {} }, { operation: "workflow.runs.resume", params: {} },
] as const)("authorizes the allowlisted operation $operation", async ({ ] as const)("authorizes the allowlisted operation $operation", async ({
@@ -467,6 +487,24 @@ describe("POST /api/rpc", () => {
expect(body.error.code).toBe("unknown_operation"); expect(body.error.code).toBe("unknown_operation");
}); });
it.each(["workflow.draft_workspaces.patch", "workflow.draft_workspaces.replace_document"])(
"does not authorize adjacent generic operation %s",
async (operation) => {
const res = await app.request("/api/rpc", {
method: "POST",
headers: validConsoleHeaders,
body: JSON.stringify({
operation,
target: "http://127.0.0.1:8000/rpc",
}),
});
expect(res.status).toBe(400);
const body = await res.json();
expect(body.error.code).toBe("unknown_operation");
},
);
it("returns 400 for invalid JSON body", async () => { it("returns 400 for invalid JSON body", async () => {
const res = await app.request("/api/rpc", { const res = await app.request("/api/rpc", {
method: "POST", method: "POST",
@@ -15,14 +15,18 @@ describe("browser operation policy", () => {
"workflow.capabilities.inspect", "workflow.capabilities.inspect",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_empty",
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.add_step_from_capability", "workflow.draft_workspaces.add_step_from_capability",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
"workflow.deployments.list", "workflow.deployments.list",
@@ -41,6 +45,9 @@ describe("browser operation policy", () => {
expect(browserAllowedOperationNames).not.toContain( expect(browserAllowedOperationNames).not.toContain(
"workflow.draft_workspaces.replace_document", "workflow.draft_workspaces.replace_document",
); );
expect(browserAllowedOperationNames).not.toContain(
"workflow.draft_workspaces.patch",
);
expect(browserAllowedOperationNames).not.toContain( expect(browserAllowedOperationNames).not.toContain(
"workflow.draft_workspaces.remove_step", "workflow.draft_workspaces.remove_step",
); );
@@ -13,14 +13,18 @@ export const browserAllowedOperationNames = defineBrowserOperationNames([
"workflow.capabilities.inspect", "workflow.capabilities.inspect",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_empty",
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.add_step_from_capability", "workflow.draft_workspaces.add_step_from_capability",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
"workflow.deployments.list", "workflow.deployments.list",
@@ -155,11 +155,15 @@ const runtimeOperationNames = [
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
"workflow.deployments.list", "workflow.deployments.list",
@@ -320,6 +324,10 @@ describe("workflow contract generator", () => {
}); });
it.each([ it.each([
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
])("rejects a manifest missing focused operation %s", async (method) => { ])("rejects a manifest missing focused operation %s", async (method) => {
@@ -352,6 +360,14 @@ describe("workflow contract generator", () => {
expect(runtimeSource).toContain( expect(runtimeSource).toContain(
'"workflow.draft_workspaces.set_step_output_bindings"', '"workflow.draft_workspaces.set_step_output_bindings"',
); );
expect(runtimeSource).toContain(
'"workflow.draft_workspaces.inspect_authoring_contract"',
);
expect(runtimeSource).toContain('"workflow.draft_workspaces.set_contract"');
expect(runtimeSource).toContain('"workflow.draft_workspaces.set_start"');
expect(runtimeSource).toContain(
'"workflow.draft_workspaces.set_workflow_output_bindings"',
);
expect(runtimeSource).toContain('"InputPathBinding"'); expect(runtimeSource).toContain('"InputPathBinding"');
expect(runtimeSource).toContain('"InputValueBinding"'); expect(runtimeSource).toContain('"InputValueBinding"');
expect(runtimeSource).toContain('"StepInputBinding"'); expect(runtimeSource).toContain('"StepInputBinding"');
@@ -420,6 +436,6 @@ describe("workflow contract generator", () => {
const generatedSource = await generateWorkflowContractSource(manifestText); const generatedSource = await generateWorkflowContractSource(manifestText);
expect(generatedSource).toBe(checkedSource); expect(generatedSource).toBe(checkedSource);
expect(generatedSource.match(/^ \| "workflow\./gm)).toHaveLength(70); expect(generatedSource.match(/^ \| "workflow\./gm)).toHaveLength(71);
}); });
}); });
@@ -94,11 +94,15 @@ const runtimeOperationNameList = [
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
"workflow.deployments.list", "workflow.deployments.list",
@@ -15,8 +15,8 @@ import {
describe("generated workflow contract", () => { describe("generated workflow contract", () => {
it("contains every operation exactly once", () => { it("contains every operation exactly once", () => {
expect(workflowOperationNames).toHaveLength(70); expect(workflowOperationNames).toHaveLength(71);
expect(new Set(workflowOperationNames)).toHaveLength(70); expect(new Set(workflowOperationNames)).toHaveLength(71);
}); });
it("contains every authored Effect operation without broadening its boundary", () => { it("contains every authored Effect operation without broadening its boundary", () => {
@@ -30,13 +30,17 @@ describe("generated workflow contract", () => {
"workflow.capabilities.call", "workflow.capabilities.call",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_empty",
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.add_step_from_capability", "workflow.draft_workspaces.add_step_from_capability",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
@@ -42,6 +42,7 @@ export type WorkflowOperationName =
| "workflow.draft_workspaces.delete" | "workflow.draft_workspaces.delete"
| "workflow.draft_workspaces.get" | "workflow.draft_workspaces.get"
| "workflow.draft_workspaces.handle" | "workflow.draft_workspaces.handle"
| "workflow.draft_workspaces.inspect_authoring_contract"
| "workflow.draft_workspaces.list" | "workflow.draft_workspaces.list"
| "workflow.draft_workspaces.patch" | "workflow.draft_workspaces.patch"
| "workflow.draft_workspaces.remove_binding" | "workflow.draft_workspaces.remove_binding"
@@ -114,6 +115,7 @@ export const workflowOperationNames: readonly WorkflowOperationName[] = [
"workflow.draft_workspaces.delete", "workflow.draft_workspaces.delete",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.handle", "workflow.draft_workspaces.handle",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.patch", "workflow.draft_workspaces.patch",
"workflow.draft_workspaces.remove_binding", "workflow.draft_workspaces.remove_binding",
@@ -193,6 +195,22 @@ export type CompileDraftWorkspaceResult = CompileDraftWorkspaceSuccess | Invalid
* via the `definition` "CreateArtifactFromWorkspaceResult". * via the `definition` "CreateArtifactFromWorkspaceResult".
*/ */
export type CreateArtifactFromWorkspaceResult = SavedDraftArtifactResult | UnsavedDraftArtifactResult; export type CreateArtifactFromWorkspaceResult = SavedDraftArtifactResult | UnsavedDraftArtifactResult;
/**
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringPathAvailability".
*/
export type AuthoringPathAvailability = "available" | "conditional";
/**
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringPathOrigin".
*/
export type AuthoringPathOrigin =
"workflow_input" | "workflow_state" | "runtime_context" | "step_input" | "step_output" | "workflow_output";
/**
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringPathUse".
*/
export type AuthoringPathUse = "step_input" | "step_output_source" | "state_target" | "workflow_output";
/** /**
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema * This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "PatchDraftResult". * via the `definition` "PatchDraftResult".
@@ -599,6 +617,14 @@ export interface WorkflowContractMap {
}; };
result: DraftWorkspaceResult; result: DraftWorkspaceResult;
}; };
"workflow.draft_workspaces.inspect_authoring_contract": {
params: {
workspace_id: string;
revision: number;
selected_step_id?: string | null;
};
result: AuthoringContractInventoryPayload | DraftWorkspaceResult;
};
"workflow.draft_workspaces.list": { "workflow.draft_workspaces.list": {
params: Record<string, never>; params: Record<string, never>;
result: ListDraftWorkspacesResult; result: ListDraftWorkspacesResult;
@@ -2201,6 +2227,59 @@ export interface HandleDraftBranch {
outcome: string; outcome: string;
step_id: string; step_id: string;
} }
/**
* Revision-scoped readable sources and writable authoring targets.
*
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringContractInventoryPayload".
*/
export interface AuthoringContractInventoryPayload {
entry_steps: AuthoringStepContractPayload[];
readable_sources: AuthoringPathOptionPayload[];
revision: number;
selected_step_id: string | null;
state_targets: AuthoringPathOptionPayload[];
step_input_targets: AuthoringPathOptionPayload[];
step_output_sources: AuthoringPathOptionPayload[];
warnings: string[];
workflow_outcomes: string[];
workflow_output_targets: AuthoringPathOptionPayload[];
workspace_id: string;
[k: string]: unknown;
}
/**
* Compact executable-step choice used by authoring inventories.
*
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringStepContractPayload".
*/
export interface AuthoringStepContractPayload {
description?: string;
input_targets?: AuthoringPathOptionPayload[];
label: string;
outcomes?: string[];
output_sources?: AuthoringPathOptionPayload[];
step_id: string;
[k: string]: unknown;
}
/**
* One schema-derived source or target available to an author.
*
* This interface was referenced by `WorkflowContractMap`'s JSON-Schema
* via the `definition` "AuthoringPathOptionPayload".
*/
export interface AuthoringPathOptionPayload {
availability: AuthoringPathAvailability;
description?: string;
label: string;
origin: AuthoringPathOrigin;
path: string;
reason?: string;
required: boolean;
schema: JsonObject;
uses: AuthoringPathUse[];
[k: string]: unknown;
}
/** /**
* All persisted draft-workspace summaries. * All persisted draft-workspace summaries.
* *
@@ -2772,6 +2851,198 @@ export const workflowRuntimeContract = {
], ],
"type": "string" "type": "string"
}, },
"AuthoringContractInventoryPayload": {
"description": "Revision-scoped readable sources and writable authoring targets.",
"properties": {
"entry_steps": {
"items": {
"$ref": "#/components/schemas/AuthoringStepContractPayload"
},
"type": "array"
},
"readable_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"revision": {
"type": "integer"
},
"selected_step_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"state_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_input_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_output_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
},
"workflow_outcomes": {
"items": {
"type": "string"
},
"type": "array"
},
"workflow_output_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"workspace_id": {
"type": "string"
}
},
"required": [
"workspace_id",
"revision",
"selected_step_id",
"readable_sources",
"step_input_targets",
"step_output_sources",
"state_targets",
"workflow_output_targets",
"entry_steps",
"workflow_outcomes",
"warnings"
],
"type": "object"
},
"AuthoringPathAvailability": {
"enum": [
"available",
"conditional"
],
"type": "string"
},
"AuthoringPathOptionPayload": {
"description": "One schema-derived source or target available to an author.",
"properties": {
"availability": {
"$ref": "#/components/schemas/AuthoringPathAvailability"
},
"description": {
"type": "string"
},
"label": {
"type": "string"
},
"origin": {
"$ref": "#/components/schemas/AuthoringPathOrigin"
},
"path": {
"type": "string"
},
"reason": {
"type": "string"
},
"required": {
"type": "boolean"
},
"schema": {
"$ref": "#/components/schemas/JsonObject"
},
"uses": {
"items": {
"$ref": "#/components/schemas/AuthoringPathUse"
},
"type": "array"
}
},
"required": [
"path",
"label",
"origin",
"schema",
"required",
"availability",
"uses"
],
"type": "object"
},
"AuthoringPathOrigin": {
"enum": [
"workflow_input",
"workflow_state",
"runtime_context",
"step_input",
"step_output",
"workflow_output"
],
"type": "string"
},
"AuthoringPathUse": {
"enum": [
"step_input",
"step_output_source",
"state_target",
"workflow_output"
],
"type": "string"
},
"AuthoringStepContractPayload": {
"description": "Compact executable-step choice used by authoring inventories.",
"properties": {
"description": {
"type": "string"
},
"input_targets": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"label": {
"type": "string"
},
"outcomes": {
"items": {
"type": "string"
},
"type": "array"
},
"output_sources": {
"items": {
"$ref": "#/components/schemas/AuthoringPathOptionPayload"
},
"type": "array"
},
"step_id": {
"type": "string"
}
},
"required": [
"step_id",
"label"
],
"type": "object"
},
"CapabilityCallResult": { "CapabilityCallResult": {
"description": "Outcome returned by a direct node-spec or wrapper capability call.", "description": "Outcome returned by a direct node-spec or wrapper capability call.",
"properties": { "properties": {
@@ -5780,6 +6051,48 @@ export const workflowRuntimeContract = {
"$ref": "#/components/schemas/DraftWorkspaceResult" "$ref": "#/components/schemas/DraftWorkspaceResult"
} }
}, },
"workflow.draft_workspaces.inspect_authoring_contract": {
"payload": {
"additionalProperties": false,
"properties": {
"workspace_id": {
"minLength": 1,
"type": "string"
},
"revision": {
"minimum": 1,
"type": "integer"
},
"selected_step_id": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null
}
},
"required": [
"workspace_id",
"revision"
],
"type": "object"
},
"success": {
"anyOf": [
{
"$ref": "#/components/schemas/AuthoringContractInventoryPayload"
},
{
"$ref": "#/components/schemas/DraftWorkspaceResult"
}
]
}
},
"workflow.draft_workspaces.list": { "workflow.draft_workspaces.list": {
"payload": { "payload": {
"additionalProperties": false, "additionalProperties": false,
@@ -5791,6 +6104,79 @@ export const workflowRuntimeContract = {
"$ref": "#/components/schemas/ListDraftWorkspacesResult" "$ref": "#/components/schemas/ListDraftWorkspacesResult"
} }
}, },
"workflow.draft_workspaces.set_contract": {
"payload": {
"additionalProperties": false,
"properties": {
"workspace_id": {
"minLength": 1,
"type": "string"
},
"revision": {
"minimum": 1,
"type": "integer"
},
"input_schema": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"state_schema": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"output_schema": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null
},
"outcomes": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null
}
},
"required": [
"workspace_id",
"revision"
],
"type": "object"
},
"success": {
"$ref": "#/components/schemas/DraftWorkspaceResult"
}
},
"workflow.draft_workspaces.set_route": { "workflow.draft_workspaces.set_route": {
"payload": { "payload": {
"additionalProperties": false, "additionalProperties": false,
@@ -5829,6 +6215,34 @@ export const workflowRuntimeContract = {
"$ref": "#/components/schemas/DraftWorkspaceResult" "$ref": "#/components/schemas/DraftWorkspaceResult"
} }
}, },
"workflow.draft_workspaces.set_start": {
"payload": {
"additionalProperties": false,
"properties": {
"workspace_id": {
"minLength": 1,
"type": "string"
},
"revision": {
"minimum": 1,
"type": "integer"
},
"step_id": {
"minLength": 1,
"type": "string"
}
},
"required": [
"workspace_id",
"revision",
"step_id"
],
"type": "object"
},
"success": {
"$ref": "#/components/schemas/DraftWorkspaceResult"
}
},
"workflow.draft_workspaces.set_step_input_bindings": { "workflow.draft_workspaces.set_step_input_bindings": {
"payload": { "payload": {
"additionalProperties": false, "additionalProperties": false,
@@ -5899,6 +6313,44 @@ export const workflowRuntimeContract = {
"$ref": "#/components/schemas/DraftWorkspaceResult" "$ref": "#/components/schemas/DraftWorkspaceResult"
} }
}, },
"workflow.draft_workspaces.set_workflow_output_bindings": {
"payload": {
"additionalProperties": false,
"properties": {
"workspace_id": {
"minLength": 1,
"type": "string"
},
"revision": {
"minimum": 1,
"type": "integer"
},
"bindings": {
"items": {
"anyOf": [
{
"$ref": "#/components/schemas/InputPathBinding"
},
{
"$ref": "#/components/schemas/InputValueBinding"
}
],
"description": "Simple canonical binding for node inputs or workflow outputs. Use either a path binding with `path`, or a literal binding with `value`; composite `expression` bindings are node-local only."
},
"type": "array"
}
},
"required": [
"workspace_id",
"revision",
"bindings"
],
"type": "object"
},
"success": {
"$ref": "#/components/schemas/DraftWorkspaceResult"
}
},
"workflow.draft_workspaces.update_capability_step": { "workflow.draft_workspaces.update_capability_step": {
"payload": { "payload": {
"additionalProperties": false, "additionalProperties": false,
+12
View File
@@ -29,13 +29,17 @@ export {
WorkflowCapabilitiesCall, WorkflowCapabilitiesCall,
WorkflowDraftWorkspacesList, WorkflowDraftWorkspacesList,
WorkflowDraftWorkspacesGet, WorkflowDraftWorkspacesGet,
WorkflowDraftWorkspacesInspectAuthoringContract,
WorkflowDraftWorkspacesCreateEmpty, WorkflowDraftWorkspacesCreateEmpty,
WorkflowDraftWorkspacesCreateFromCapability, WorkflowDraftWorkspacesCreateFromCapability,
WorkflowDraftWorkspacesAddStepFromCapability, WorkflowDraftWorkspacesAddStepFromCapability,
WorkflowDraftWorkspacesUpdateCapabilityStep, WorkflowDraftWorkspacesUpdateCapabilityStep,
WorkflowDraftWorkspacesSetRoute, WorkflowDraftWorkspacesSetRoute,
WorkflowDraftWorkspacesSetContract,
WorkflowDraftWorkspacesSetStart,
WorkflowDraftWorkspacesSetStepInputBindings, WorkflowDraftWorkspacesSetStepInputBindings,
WorkflowDraftWorkspacesSetStepOutputBindings, WorkflowDraftWorkspacesSetStepOutputBindings,
WorkflowDraftWorkspacesSetWorkflowOutputBindings,
WorkflowDraftWorkspacesValidate, WorkflowDraftWorkspacesValidate,
WorkflowArtifactsList, WorkflowArtifactsList,
WorkflowArtifactsInspect, WorkflowArtifactsInspect,
@@ -57,6 +61,8 @@ export {
WorkflowDraftWorkspacesListResultSchema, WorkflowDraftWorkspacesListResultSchema,
WorkflowDraftWorkspacesGetPayloadSchema, WorkflowDraftWorkspacesGetPayloadSchema,
WorkflowDraftWorkspacesGetResultSchema, WorkflowDraftWorkspacesGetResultSchema,
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
WorkflowDraftWorkspacesCreateEmptyPayloadSchema, WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
WorkflowDraftWorkspacesCreateEmptyResultSchema, WorkflowDraftWorkspacesCreateEmptyResultSchema,
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema, WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
@@ -67,10 +73,16 @@ export {
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema, WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
WorkflowDraftWorkspacesSetRoutePayloadSchema, WorkflowDraftWorkspacesSetRoutePayloadSchema,
WorkflowDraftWorkspacesSetRouteResultSchema, WorkflowDraftWorkspacesSetRouteResultSchema,
WorkflowDraftWorkspacesSetContractPayloadSchema,
WorkflowDraftWorkspacesSetContractResultSchema,
WorkflowDraftWorkspacesSetStartPayloadSchema,
WorkflowDraftWorkspacesSetStartResultSchema,
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema, WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema, WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidatePayloadSchema,
WorkflowDraftWorkspacesValidateResultSchema, WorkflowDraftWorkspacesValidateResultSchema,
WorkflowRpcs, WorkflowRpcs,
@@ -157,6 +157,55 @@ const DraftWorkspaceSchema = Schema.Struct({
workspace_id: Schema.String, workspace_id: Schema.String,
}); });
const AuthoringPathOptionSchema = Schema.Struct({
path: Schema.String,
label: Schema.String,
origin: Schema.Literal(
"workflow_input",
"workflow_state",
"runtime_context",
"step_input",
"step_output",
"workflow_output",
),
schema: JsonObjectSchema,
required: Schema.Boolean,
availability: Schema.Literal("available", "conditional"),
uses: Schema.Array(
Schema.Literal(
"step_input",
"step_output_source",
"state_target",
"workflow_output",
),
),
description: Schema.optional(Schema.String),
reason: Schema.optional(Schema.String),
});
const AuthoringStepContractSchema = Schema.Struct({
step_id: Schema.String,
label: Schema.String,
description: Schema.optional(Schema.String),
input_targets: Schema.optional(Schema.Array(AuthoringPathOptionSchema)),
output_sources: Schema.optional(Schema.Array(AuthoringPathOptionSchema)),
outcomes: Schema.optional(Schema.Array(Schema.String)),
});
const AuthoringContractInventorySchema = Schema.Struct({
workspace_id: Schema.String,
revision: PositiveIntegerSchema,
selected_step_id: Schema.NullOr(Schema.String),
readable_sources: Schema.Array(AuthoringPathOptionSchema),
step_input_targets: Schema.Array(AuthoringPathOptionSchema),
step_output_sources: Schema.Array(AuthoringPathOptionSchema),
state_targets: Schema.Array(AuthoringPathOptionSchema),
workflow_output_targets: Schema.Array(AuthoringPathOptionSchema),
entry_steps: Schema.Array(AuthoringStepContractSchema),
workflow_outcomes: Schema.Array(Schema.String),
warnings: Schema.Array(Schema.String),
});
// Effect's empty Struct does not traverse excess keys; the impossible optional // Effect's empty Struct does not traverse excess keys; the impossible optional
// field keeps the authored empty payload strict under onExcessProperty:error. // field keeps the authored empty payload strict under onExcessProperty:error.
const EmptyPayloadSchema = Schema.Struct({ const EmptyPayloadSchema = Schema.Struct({
@@ -478,6 +527,14 @@ export const authoredRpcSchemas = {
}), }),
success: DraftWorkspaceSchema, success: DraftWorkspaceSchema,
}, },
"workflow.draft_workspaces.inspect_authoring_contract": {
payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)),
revision: PositiveIntegerSchema,
selected_step_id: Schema.optional(Schema.NullOr(Schema.String)),
}),
success: Schema.Union(AuthoringContractInventorySchema, DraftWorkspaceSchema),
},
"workflow.draft_workspaces.create_empty": { "workflow.draft_workspaces.create_empty": {
payload: Schema.Struct({ payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)), workspace_id: Schema.String.pipe(Schema.minLength(1)),
@@ -490,6 +547,25 @@ export const authoredRpcSchemas = {
}), }),
success: DraftWorkspaceSchema, success: DraftWorkspaceSchema,
}, },
"workflow.draft_workspaces.set_contract": {
payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)),
revision: PositiveIntegerSchema,
input_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
state_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
output_schema: Schema.optional(Schema.NullOr(JsonObjectSchema)),
outcomes: Schema.optional(Schema.NullOr(Schema.Array(Schema.String))),
}),
success: DraftWorkspaceSchema,
},
"workflow.draft_workspaces.set_start": {
payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)),
revision: PositiveIntegerSchema,
step_id: Schema.String.pipe(Schema.minLength(1)),
}),
success: DraftWorkspaceSchema,
},
"workflow.draft_workspaces.create_from_capability": { "workflow.draft_workspaces.create_from_capability": {
payload: Schema.Struct({ payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)), workspace_id: Schema.String.pipe(Schema.minLength(1)),
@@ -574,6 +650,14 @@ export const authoredRpcSchemas = {
}), }),
success: DraftWorkspaceSchema, success: DraftWorkspaceSchema,
}, },
"workflow.draft_workspaces.set_workflow_output_bindings": {
payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)),
revision: PositiveIntegerSchema,
bindings: Schema.Array(Schema.Union(InputPathBindingSchema, InputValueBindingSchema)),
}),
success: DraftWorkspaceSchema,
},
"workflow.draft_workspaces.validate": { "workflow.draft_workspaces.validate": {
payload: Schema.Struct({ payload: Schema.Struct({
workspace_id: Schema.String.pipe(Schema.minLength(1)), workspace_id: Schema.String.pipe(Schema.minLength(1)),
@@ -13,14 +13,22 @@ import {
WorkflowDraftWorkspacesCreateFromCapabilityResultSchema, WorkflowDraftWorkspacesCreateFromCapabilityResultSchema,
WorkflowDraftWorkspacesGetPayloadSchema, WorkflowDraftWorkspacesGetPayloadSchema,
WorkflowDraftWorkspacesGetResultSchema, WorkflowDraftWorkspacesGetResultSchema,
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
WorkflowDraftWorkspacesListPayloadSchema, WorkflowDraftWorkspacesListPayloadSchema,
WorkflowDraftWorkspacesListResultSchema, WorkflowDraftWorkspacesListResultSchema,
WorkflowDraftWorkspacesSetContractPayloadSchema,
WorkflowDraftWorkspacesSetContractResultSchema,
WorkflowDraftWorkspacesSetRoutePayloadSchema, WorkflowDraftWorkspacesSetRoutePayloadSchema,
WorkflowDraftWorkspacesSetRouteResultSchema, WorkflowDraftWorkspacesSetRouteResultSchema,
WorkflowDraftWorkspacesSetStartPayloadSchema,
WorkflowDraftWorkspacesSetStartResultSchema,
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema, WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema, WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema, WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema,
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema, WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidatePayloadSchema,
@@ -203,6 +211,66 @@ const draftWorkspace = {
}, },
}; };
const authoringPathOption = {
path: "input.title",
label: "Title",
origin: "workflow_input",
schema: { type: "string" },
required: true,
availability: "available",
uses: ["step_input"],
};
const authoringContractInventory = {
workspace_id: "console.demo",
revision: 7,
selected_step_id: "render",
readable_sources: [authoringPathOption],
step_input_targets: [
{
...authoringPathOption,
path: "local.title",
origin: "step_input",
uses: ["step_input"],
},
],
step_output_sources: [
{
...authoringPathOption,
path: "local.markdown",
origin: "step_output",
uses: ["step_output_source"],
},
],
state_targets: [
{
...authoringPathOption,
path: "state.report",
origin: "workflow_state",
uses: ["state_target", "workflow_output"],
},
],
workflow_output_targets: [
{
...authoringPathOption,
path: "output.report",
origin: "workflow_output",
uses: ["workflow_output"],
},
],
entry_steps: [
{
step_id: "render",
label: "Render report",
input_targets: [],
output_sources: [],
outcomes: ["ok", "error"],
},
],
workflow_outcomes: ["ok", "error"],
warnings: [],
};
const createFromCapabilityResult = { const createFromCapabilityResult = {
...draftWorkspace, ...draftWorkspace,
next_actions: { next_actions: {
@@ -460,6 +528,22 @@ const parityCases: ReadonlyArray<ParityCase> = [
draft: null, draft: null,
}, },
}, },
{
method: "workflow.draft_workspaces.inspect_authoring_contract",
payload: WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
success: WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
validPayload: {
workspace_id: "console.demo",
revision: 7,
selected_step_id: "render",
},
invalidPayload: { workspace_id: "console.demo", revision: 0 },
validSuccess: authoringContractInventory,
invalidSuccess: {
...authoringContractInventory,
entry_steps: [{ step_id: "render" }],
},
},
{ {
method: "workflow.draft_workspaces.create_empty", method: "workflow.draft_workspaces.create_empty",
payload: WorkflowDraftWorkspacesCreateEmptyPayloadSchema, payload: WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
@@ -590,6 +674,41 @@ const parityCases: ReadonlyArray<ParityCase> = [
summary: { ...draftWorkspace.summary, steps: [1] }, summary: { ...draftWorkspace.summary, steps: [1] },
}, },
}, },
{
method: "workflow.draft_workspaces.set_contract",
payload: WorkflowDraftWorkspacesSetContractPayloadSchema,
success: WorkflowDraftWorkspacesSetContractResultSchema,
validPayload: {
workspace_id: "console.demo",
revision: 7,
input_schema: { type: "object" },
state_schema: { type: "object" },
output_schema: { type: "object" },
outcomes: ["ok", "error"],
},
invalidPayload: { workspace_id: "console.demo", revision: 0 },
validSuccess: draftWorkspace,
invalidSuccess: {
...draftWorkspace,
summary: { ...draftWorkspace.summary, steps: [1] },
},
},
{
method: "workflow.draft_workspaces.set_start",
payload: WorkflowDraftWorkspacesSetStartPayloadSchema,
success: WorkflowDraftWorkspacesSetStartResultSchema,
validPayload: {
workspace_id: "console.demo",
revision: 7,
step_id: "render",
},
invalidPayload: { workspace_id: "console.demo", revision: 7, step_id: "" },
validSuccess: draftWorkspace,
invalidSuccess: {
...draftWorkspace,
summary: { ...draftWorkspace.summary, steps: [1] },
},
},
{ {
method: "workflow.draft_workspaces.set_step_input_bindings", method: "workflow.draft_workspaces.set_step_input_bindings",
payload: WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, payload: WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
@@ -640,6 +759,29 @@ const parityCases: ReadonlyArray<ParityCase> = [
summary: { ...draftWorkspace.summary, steps: [1] }, summary: { ...draftWorkspace.summary, steps: [1] },
}, },
}, },
{
method: "workflow.draft_workspaces.set_workflow_output_bindings",
payload: WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
success: WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
validPayload: {
workspace_id: "console.demo",
revision: 7,
bindings: [
{ path: "state.report", target: "report" },
{ target: "format", value: "markdown" },
],
},
invalidPayload: {
workspace_id: "console.demo",
revision: 7,
bindings: [{ expression: { kind: "literal", value: "bad" } }],
},
validSuccess: draftWorkspace,
invalidSuccess: {
...draftWorkspace,
summary: { ...draftWorkspace.summary, steps: [1] },
},
},
{ {
method: "workflow.draft_workspaces.validate", method: "workflow.draft_workspaces.validate",
payload: WorkflowDraftWorkspacesValidatePayloadSchema, payload: WorkflowDraftWorkspacesValidatePayloadSchema,
@@ -1188,13 +1330,17 @@ describe("authored RPC and manifest schema parity", () => {
"workflow.capabilities.call", "workflow.capabilities.call",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_empty",
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.add_step_from_capability", "workflow.draft_workspaces.add_step_from_capability",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.artifacts.list", "workflow.artifacts.list",
"workflow.artifacts.inspect", "workflow.artifacts.inspect",
@@ -1231,6 +1377,7 @@ describe("authored RPC and manifest schema parity", () => {
"workflow.draft_workspaces.update_capability_step:payload:oneOf@#/components/schemas/InputPathBinding.properties.path", "workflow.draft_workspaces.update_capability_step:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
"workflow.draft_workspaces.set_step_input_bindings:payload:oneOf@#/components/schemas/InputPathBinding.properties.path", "workflow.draft_workspaces.set_step_input_bindings:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
"workflow.draft_workspaces.set_step_output_bindings:payload:oneOf@#/components/schemas/OutputBinding.properties.source", "workflow.draft_workspaces.set_step_output_bindings:payload:oneOf@#/components/schemas/OutputBinding.properties.source",
"workflow.draft_workspaces.set_workflow_output_bindings:payload:oneOf@#/components/schemas/InputPathBinding.properties.path",
]); ]);
}); });
}); });
@@ -27,10 +27,14 @@ describe("runtimeSchemasFor", () => {
"workflow.draft_workspaces.create_empty", "workflow.draft_workspaces.create_empty",
"workflow.draft_workspaces.create_from_capability", "workflow.draft_workspaces.create_from_capability",
"workflow.draft_workspaces.get", "workflow.draft_workspaces.get",
"workflow.draft_workspaces.inspect_authoring_contract",
"workflow.draft_workspaces.list", "workflow.draft_workspaces.list",
"workflow.draft_workspaces.set_contract",
"workflow.draft_workspaces.set_route", "workflow.draft_workspaces.set_route",
"workflow.draft_workspaces.set_start",
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
"workflow.draft_workspaces.set_step_output_bindings", "workflow.draft_workspaces.set_step_output_bindings",
"workflow.draft_workspaces.set_workflow_output_bindings",
"workflow.draft_workspaces.update_capability_step", "workflow.draft_workspaces.update_capability_step",
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
"workflow.health", "workflow.health",
@@ -306,6 +306,52 @@ describe("run operation registry", () => {
}, },
}, },
}, },
{
method: "workflow.draft_workspaces.set_contract" as const,
params: {
workspace_id: "console.demo",
revision: 5,
outcomes: ["ok", "error"],
},
cli: "uv run wf draft set-contract console.demo --revision 5 --outcome ok --outcome error",
result: {
workspace_id: "console.demo",
revision: 6,
title: "Console demo",
status: "valid" as const,
diagnostics: [],
summary: {
name: "console.demo",
start: "echo",
step_count: 1,
route_count: 1,
steps: ["echo"],
},
},
},
{
method: "workflow.draft_workspaces.set_start" as const,
params: {
workspace_id: "console.demo",
revision: 6,
step_id: "echo",
},
cli: "uv run wf draft set-start console.demo --revision 6 --step echo",
result: {
workspace_id: "console.demo",
revision: 7,
title: "Console demo",
status: "valid" as const,
diagnostics: [],
summary: {
name: "console.demo",
start: "echo",
step_count: 1,
route_count: 1,
steps: ["echo"],
},
},
},
{ {
method: "workflow.draft_workspaces.set_step_input_bindings" as const, method: "workflow.draft_workspaces.set_step_input_bindings" as const,
params: { params: {
@@ -367,6 +413,32 @@ describe("run operation registry", () => {
}, },
}, },
}, },
{
method: "workflow.draft_workspaces.set_workflow_output_bindings" as const,
params: {
workspace_id: "console.demo",
revision: 7,
bindings: [
{ path: "state.report", target: "report" },
{ target: "format", value: "markdown" },
],
},
cli: "uv run wf draft set-workflow-output console.demo --revision 7 --map state.report=report --value 'format=\"markdown\"'",
result: {
workspace_id: "console.demo",
revision: 8,
title: "Console demo",
status: "valid" as const,
diagnostics: [],
summary: {
name: "console.demo",
start: "echo",
step_count: 1,
route_count: 1,
steps: ["echo"],
},
},
},
{ {
method: "workflow.draft_workspaces.validate" as const, method: "workflow.draft_workspaces.validate" as const,
params: { workspace_id: "console.demo" }, params: { workspace_id: "console.demo" },
@@ -522,6 +594,44 @@ describe("run operation registry", () => {
); );
}); });
it("registers authoring inspection as a read operation", async () => {
const { getOperationMeta } = await import("./method-registry.js");
const operation = getOperationMeta(
"workflow.draft_workspaces.inspect_authoring_contract",
);
if (operation === undefined) throw new Error("missing authoring inspection");
expect(operation.idempotency).toBe("read");
expect(
operation.equivalentCli({
workspace_id: "console.demo",
revision: 8,
selected_step_id: "render",
}),
).toBe(
"uv run wf draft inspect console.demo --include-draft [non-equivalent: unavailable CLI representation for revision, selected_step_id]",
);
expect(
operation.interpret({
workspace_id: "console.demo",
revision: 8,
selected_step_id: null,
readable_sources: [],
step_input_targets: [],
step_output_sources: [],
state_targets: [],
workflow_output_targets: [],
entry_steps: [],
workflow_outcomes: ["ok"],
warnings: [],
}),
).toMatchObject({
workspaceId: "console.demo",
selectedStepId: null,
workflowOutcomes: ["ok"],
});
});
it("does not flatten composite bindings into a fake inline CLI value", async () => { it("does not flatten composite bindings into a fake inline CLI value", async () => {
const { getOperationMeta } = await import("./method-registry.js"); const { getOperationMeta } = await import("./method-registry.js");
const operation = getOperationMeta( const operation = getOperationMeta(
+180
View File
@@ -2,6 +2,8 @@ import { Schema } from "effect";
import type { import type {
NodeSpecCapabilitySummary, NodeSpecCapabilitySummary,
StepInputBinding, StepInputBinding,
AuthoringContractInventoryPayload,
AuthoringPathOptionPayload,
WorkflowOperationName, WorkflowOperationName,
WrapperArtifactCapabilitySummary, WrapperArtifactCapabilitySummary,
} from "./generated/workflow-contract.js"; } from "./generated/workflow-contract.js";
@@ -18,6 +20,8 @@ import {
WorkflowDraftWorkspacesListResultSchema, WorkflowDraftWorkspacesListResultSchema,
WorkflowDraftWorkspacesGetPayloadSchema, WorkflowDraftWorkspacesGetPayloadSchema,
WorkflowDraftWorkspacesGetResultSchema, WorkflowDraftWorkspacesGetResultSchema,
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
WorkflowDraftWorkspacesCreateEmptyPayloadSchema, WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
WorkflowDraftWorkspacesCreateEmptyResultSchema, WorkflowDraftWorkspacesCreateEmptyResultSchema,
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema, WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
@@ -28,10 +32,16 @@ import {
WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema, WorkflowDraftWorkspacesUpdateCapabilityStepResultSchema,
WorkflowDraftWorkspacesSetRoutePayloadSchema, WorkflowDraftWorkspacesSetRoutePayloadSchema,
WorkflowDraftWorkspacesSetRouteResultSchema, WorkflowDraftWorkspacesSetRouteResultSchema,
WorkflowDraftWorkspacesSetContractPayloadSchema,
WorkflowDraftWorkspacesSetContractResultSchema,
WorkflowDraftWorkspacesSetStartPayloadSchema,
WorkflowDraftWorkspacesSetStartResultSchema,
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepInputBindingsResultSchema, WorkflowDraftWorkspacesSetStepInputBindingsResultSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema, WorkflowDraftWorkspacesSetStepOutputBindingsResultSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidatePayloadSchema,
WorkflowDraftWorkspacesValidateResultSchema, WorkflowDraftWorkspacesValidateResultSchema,
WorkflowArtifactsListPayloadSchema, WorkflowArtifactsListPayloadSchema,
@@ -141,6 +151,27 @@ export type DraftWorkspaceInterpreted = {
readonly draft: Readonly<Record<string, unknown>> | null; readonly draft: Readonly<Record<string, unknown>> | null;
}; };
export type AuthoringContractInterpreted = {
readonly workspaceId: string;
readonly revision: number;
readonly selectedStepId: string | null;
readonly readableSources: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly stepInputTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly stepOutputSources: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly stateTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly workflowOutputTargets: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly entrySteps: ReadonlyArray<{
readonly stepId: string;
readonly label: string;
readonly description?: string;
readonly inputTargets?: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly outputSources?: ReadonlyArray<ReturnType<typeof interpretAuthoringPathOption>>;
readonly outcomes?: ReadonlyArray<string>;
}>;
readonly workflowOutcomes: ReadonlyArray<string>;
readonly warnings: ReadonlyArray<string>;
};
const interpretNextActions = (nextActions: { const interpretNextActions = (nextActions: {
readonly can_continue: boolean; readonly can_continue: boolean;
readonly can_save_now: boolean | null; readonly can_save_now: boolean | null;
@@ -301,6 +332,49 @@ const interpretDraftWorkspace = (decoded: {
draft: decoded.draft ?? null, draft: decoded.draft ?? null,
}); });
const interpretAuthoringPathOption = (option: AuthoringPathOptionPayload) => ({
path: option.path,
label: option.label,
origin: option.origin,
schema: option.schema,
required: option.required,
availability: option.availability,
uses: option.uses,
...(option.description === undefined
? {}
: { description: option.description }),
...(option.reason === undefined ? {} : { reason: option.reason }),
});
const interpretAuthoringContract = (
decoded: AuthoringContractInventoryPayload,
): AuthoringContractInterpreted => ({
workspaceId: decoded.workspace_id,
revision: decoded.revision,
selectedStepId: decoded.selected_step_id,
readableSources: decoded.readable_sources.map(interpretAuthoringPathOption),
stepInputTargets: decoded.step_input_targets.map(interpretAuthoringPathOption),
stepOutputSources: decoded.step_output_sources.map(interpretAuthoringPathOption),
stateTargets: decoded.state_targets.map(interpretAuthoringPathOption),
workflowOutputTargets: decoded.workflow_output_targets.map(
interpretAuthoringPathOption,
),
entrySteps: decoded.entry_steps.map((step) => ({
stepId: step.step_id,
label: step.label,
...(step.description === undefined ? {} : { description: step.description }),
...(step.input_targets === undefined
? {}
: { inputTargets: step.input_targets.map(interpretAuthoringPathOption) }),
...(step.output_sources === undefined
? {}
: { outputSources: step.output_sources.map(interpretAuthoringPathOption) }),
...(step.outcomes === undefined ? {} : { outcomes: step.outcomes }),
})),
workflowOutcomes: decoded.workflow_outcomes,
warnings: decoded.warnings,
});
/** Adapts a snake_case run detail from the server into camelCase for the browser. */ /** Adapts a snake_case run detail from the server into camelCase for the browser. */
const interpretRunDetail = (decoded: { const interpretRunDetail = (decoded: {
readonly run_id: string | null; readonly run_id: string | null;
@@ -533,6 +607,33 @@ const operationEntries = defineOperationEntries([
return interpretDraftWorkspace(decoded); return interpretDraftWorkspace(decoded);
}, },
}, },
{
method: "workflow.draft_workspaces.inspect_authoring_contract",
label: "Inspect draft authoring contract",
explanation: "Inspect schema-derived sources and targets for a draft workspace",
idempotency: "read",
equivalentCli: (params) => {
const p = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
)(params, { onExcessProperty: "error" });
return nonEquivalentCli(
`uv run wf draft inspect ${shellArg(p.workspace_id)} --include-draft`,
[
"revision",
...(p.selected_step_id == null ? [] : ["selected_step_id"]),
],
);
},
interpret: (result) => {
const decoded = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
)(result);
if (isRecord(decoded) && "readable_sources" in decoded) {
return interpretAuthoringContract(decoded as AuthoringContractInventoryPayload);
}
return interpretDraftWorkspace(decoded);
},
},
{ {
method: "workflow.draft_workspaces.create_empty", method: "workflow.draft_workspaces.create_empty",
label: "Create empty draft workspace", label: "Create empty draft workspace",
@@ -722,6 +823,55 @@ const operationEntries = defineOperationEntries([
return interpretDraftWorkspace(decoded); return interpretDraftWorkspace(decoded);
}, },
}, },
{
method: "workflow.draft_workspaces.set_contract",
label: "Set draft contract",
explanation: "Replace selected workflow input, state, output, or outcome contract fields",
idempotency: "write",
equivalentCli: (params) => {
const p = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetContractPayloadSchema,
)(params, { onExcessProperty: "error" });
const parts = [
"uv run wf draft set-contract",
shellArg(p.workspace_id),
"--revision",
String(p.revision),
];
const unavailable: string[] = [];
if (p.input_schema != null) unavailable.push("input_schema (use --input-schema-file)");
if (p.state_schema != null) unavailable.push("state_schema (use --state-schema-file)");
if (p.output_schema != null) unavailable.push("output_schema (use --output-schema-file)");
for (const outcome of p.outcomes ?? []) {
parts.push("--outcome", shellArg(outcome));
}
return nonEquivalentCli(parts.join(" "), unavailable);
},
interpret: (result) => {
const decoded = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetContractResultSchema,
)(result);
return interpretDraftWorkspace(decoded);
},
},
{
method: "workflow.draft_workspaces.set_start",
label: "Set draft start",
explanation: "Set the entry step for a persisted workflow draft",
idempotency: "write",
equivalentCli: (params) => {
const p = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetStartPayloadSchema,
)(params, { onExcessProperty: "error" });
return `uv run wf draft set-start ${shellArg(p.workspace_id)} --revision ${p.revision} --step ${shellArg(p.step_id)}`;
},
interpret: (result) => {
const decoded = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetStartResultSchema,
)(result);
return interpretDraftWorkspace(decoded);
},
},
{ {
method: "workflow.draft_workspaces.set_step_input_bindings", method: "workflow.draft_workspaces.set_step_input_bindings",
label: "Set step input bindings", label: "Set step input bindings",
@@ -788,6 +938,36 @@ const operationEntries = defineOperationEntries([
return interpretDraftWorkspace(decoded); return interpretDraftWorkspace(decoded);
}, },
}, },
{
method: "workflow.draft_workspaces.set_workflow_output_bindings",
label: "Set workflow output bindings",
explanation: "Replace the ordered public workflow output bindings",
idempotency: "write",
equivalentCli: (params) => {
const p = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
)(params, { onExcessProperty: "error" });
const parts = [
"uv run wf draft set-workflow-output",
shellArg(p.workspace_id),
"--revision",
String(p.revision),
];
if (p.bindings.length === 0) {
parts.push("--clear");
return parts.join(" ");
}
const rendered = inputBindingCliArgs(p.bindings, "--map");
parts.push(...rendered.args);
return nonEquivalentCli(parts.join(" "), rendered.unavailable);
},
interpret: (result) => {
const decoded = Schema.decodeUnknownSync(
WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
)(result);
return interpretDraftWorkspace(decoded);
},
},
{ {
method: "workflow.draft_workspaces.validate", method: "workflow.draft_workspaces.validate",
label: "Validate draft workspace", label: "Validate draft workspace",
+72
View File
@@ -107,6 +107,23 @@ export const WorkflowDraftWorkspacesGet = Rpc.make(
}, },
); );
const draftWorkspacesInspectAuthoringContractSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.inspect_authoring_contract",
);
export const WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema =
draftWorkspacesInspectAuthoringContractSchemas.payload;
export const WorkflowDraftWorkspacesInspectAuthoringContractResultSchema =
draftWorkspacesInspectAuthoringContractSchemas.success;
export const WorkflowDraftWorkspacesInspectAuthoringContract = Rpc.make(
"workflow.draft_workspaces.inspect_authoring_contract",
{
payload: WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
success: WorkflowDraftWorkspacesInspectAuthoringContractResultSchema,
error: Schema.Never,
},
);
// Artifacts // Artifacts
const artifactListSchemas = runtimeSchemasFor("workflow.artifacts.list"); const artifactListSchemas = runtimeSchemasFor("workflow.artifacts.list");
export const WorkflowArtifactsListPayloadSchema = artifactListSchemas.payload; export const WorkflowArtifactsListPayloadSchema = artifactListSchemas.payload;
@@ -203,6 +220,40 @@ export const WorkflowDraftWorkspacesSetRoute = Rpc.make(
}, },
); );
const draftWorkspacesSetContractSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.set_contract",
);
export const WorkflowDraftWorkspacesSetContractPayloadSchema =
draftWorkspacesSetContractSchemas.payload;
export const WorkflowDraftWorkspacesSetContractResultSchema =
draftWorkspacesSetContractSchemas.success;
export const WorkflowDraftWorkspacesSetContract = Rpc.make(
"workflow.draft_workspaces.set_contract",
{
payload: WorkflowDraftWorkspacesSetContractPayloadSchema,
success: WorkflowDraftWorkspacesSetContractResultSchema,
error: Schema.Never,
},
);
const draftWorkspacesSetStartSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.set_start",
);
export const WorkflowDraftWorkspacesSetStartPayloadSchema =
draftWorkspacesSetStartSchemas.payload;
export const WorkflowDraftWorkspacesSetStartResultSchema =
draftWorkspacesSetStartSchemas.success;
export const WorkflowDraftWorkspacesSetStart = Rpc.make(
"workflow.draft_workspaces.set_start",
{
payload: WorkflowDraftWorkspacesSetStartPayloadSchema,
success: WorkflowDraftWorkspacesSetStartResultSchema,
error: Schema.Never,
},
);
const setStepInputBindingsSchemas = runtimeSchemasFor( const setStepInputBindingsSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.set_step_input_bindings", "workflow.draft_workspaces.set_step_input_bindings",
); );
@@ -237,6 +288,23 @@ export const WorkflowDraftWorkspacesSetStepOutputBindings = Rpc.make(
}, },
); );
const draftWorkspacesSetWorkflowOutputBindingsSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.set_workflow_output_bindings",
);
export const WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema =
draftWorkspacesSetWorkflowOutputBindingsSchemas.payload;
export const WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema =
draftWorkspacesSetWorkflowOutputBindingsSchemas.success;
export const WorkflowDraftWorkspacesSetWorkflowOutputBindings = Rpc.make(
"workflow.draft_workspaces.set_workflow_output_bindings",
{
payload: WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
success: WorkflowDraftWorkspacesSetWorkflowOutputBindingsResultSchema,
error: Schema.Never,
},
);
const draftWorkspacesValidateSchemas = runtimeSchemasFor( const draftWorkspacesValidateSchemas = runtimeSchemasFor(
"workflow.draft_workspaces.validate", "workflow.draft_workspaces.validate",
); );
@@ -365,13 +433,17 @@ export const WorkflowRpcs = RpcGroup.make(
WorkflowCapabilitiesCall, WorkflowCapabilitiesCall,
WorkflowDraftWorkspacesList, WorkflowDraftWorkspacesList,
WorkflowDraftWorkspacesGet, WorkflowDraftWorkspacesGet,
WorkflowDraftWorkspacesInspectAuthoringContract,
WorkflowDraftWorkspacesCreateEmpty, WorkflowDraftWorkspacesCreateEmpty,
WorkflowDraftWorkspacesCreateFromCapability, WorkflowDraftWorkspacesCreateFromCapability,
WorkflowDraftWorkspacesAddStepFromCapability, WorkflowDraftWorkspacesAddStepFromCapability,
WorkflowDraftWorkspacesUpdateCapabilityStep, WorkflowDraftWorkspacesUpdateCapabilityStep,
WorkflowDraftWorkspacesSetRoute, WorkflowDraftWorkspacesSetRoute,
WorkflowDraftWorkspacesSetContract,
WorkflowDraftWorkspacesSetStart,
WorkflowDraftWorkspacesSetStepInputBindings, WorkflowDraftWorkspacesSetStepInputBindings,
WorkflowDraftWorkspacesSetStepOutputBindings, WorkflowDraftWorkspacesSetStepOutputBindings,
WorkflowDraftWorkspacesSetWorkflowOutputBindings,
WorkflowDraftWorkspacesValidate, WorkflowDraftWorkspacesValidate,
WorkflowArtifactsList, WorkflowArtifactsList,
WorkflowArtifactsInspect, WorkflowArtifactsInspect,
+39
View File
@@ -219,6 +219,15 @@ const lifecycleCases = [
}, },
}, },
}, },
{
operation: "workflow.draft_workspaces.inspect_authoring_contract" as const,
params: {
workspace_id: "console.demo",
revision: 1,
selected_step_id: "echo",
},
result: draftWorkspaceResult,
},
{ {
operation: "workflow.draft_workspaces.create_empty" as const, operation: "workflow.draft_workspaces.create_empty" as const,
params: { params: {
@@ -278,6 +287,24 @@ const lifecycleCases = [
}, },
result: draftWorkspaceResult, result: draftWorkspaceResult,
}, },
{
operation: "workflow.draft_workspaces.set_contract" as const,
params: {
workspace_id: "console.demo",
revision: 2,
outcomes: ["ok", "error"],
},
result: draftWorkspaceResult,
},
{
operation: "workflow.draft_workspaces.set_start" as const,
params: {
workspace_id: "console.demo",
revision: 3,
step_id: "echo",
},
result: draftWorkspaceResult,
},
{ {
operation: "workflow.draft_workspaces.set_step_input_bindings" as const, operation: "workflow.draft_workspaces.set_step_input_bindings" as const,
params: { params: {
@@ -306,6 +333,18 @@ const lifecycleCases = [
params: { workspace_id: "console.demo" }, params: { workspace_id: "console.demo" },
result: draftWorkspaceResult, result: draftWorkspaceResult,
}, },
{
operation: "workflow.draft_workspaces.set_workflow_output_bindings" as const,
params: {
workspace_id: "console.demo",
revision: 4,
bindings: [
{ path: "state.report", target: "report" },
{ target: "format", value: "markdown" },
],
},
result: draftWorkspaceResult,
},
{ {
operation: "workflow.artifacts.list" as const, operation: "workflow.artifacts.list" as const,
params: { limit: 50 }, params: { limit: 50 },
+36
View File
@@ -36,13 +36,17 @@ import {
WorkflowCapabilitiesCallPayloadSchema, WorkflowCapabilitiesCallPayloadSchema,
WorkflowDraftWorkspacesListPayloadSchema, WorkflowDraftWorkspacesListPayloadSchema,
WorkflowDraftWorkspacesGetPayloadSchema, WorkflowDraftWorkspacesGetPayloadSchema,
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
WorkflowDraftWorkspacesCreateEmptyPayloadSchema, WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema, WorkflowDraftWorkspacesCreateFromCapabilityPayloadSchema,
WorkflowDraftWorkspacesAddStepFromCapabilityPayloadSchema, WorkflowDraftWorkspacesAddStepFromCapabilityPayloadSchema,
WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema, WorkflowDraftWorkspacesUpdateCapabilityStepPayloadSchema,
WorkflowDraftWorkspacesSetRoutePayloadSchema, WorkflowDraftWorkspacesSetRoutePayloadSchema,
WorkflowDraftWorkspacesSetContractPayloadSchema,
WorkflowDraftWorkspacesSetStartPayloadSchema,
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidatePayloadSchema,
WorkflowArtifactsListPayloadSchema, WorkflowArtifactsListPayloadSchema,
WorkflowArtifactsInspectPayloadSchema, WorkflowArtifactsInspectPayloadSchema,
@@ -324,6 +328,15 @@ const executeImpl =
); );
return yield* client.workflow["draft_workspaces.get"](payload); return yield* client.workflow["draft_workspaces.get"](payload);
} }
case "workflow.draft_workspaces.inspect_authoring_contract": {
const payload = yield* decodeParams(
WorkflowDraftWorkspacesInspectAuthoringContractPayloadSchema,
params,
);
return yield* client.workflow[
"draft_workspaces.inspect_authoring_contract"
](payload);
}
case "workflow.draft_workspaces.create_empty": { case "workflow.draft_workspaces.create_empty": {
const payload = yield* decodeParams( const payload = yield* decodeParams(
WorkflowDraftWorkspacesCreateEmptyPayloadSchema, WorkflowDraftWorkspacesCreateEmptyPayloadSchema,
@@ -365,6 +378,20 @@ const executeImpl =
); );
return yield* client.workflow["draft_workspaces.set_route"](payload); return yield* client.workflow["draft_workspaces.set_route"](payload);
} }
case "workflow.draft_workspaces.set_contract": {
const payload = yield* decodeParams(
WorkflowDraftWorkspacesSetContractPayloadSchema,
params,
);
return yield* client.workflow["draft_workspaces.set_contract"](payload);
}
case "workflow.draft_workspaces.set_start": {
const payload = yield* decodeParams(
WorkflowDraftWorkspacesSetStartPayloadSchema,
params,
);
return yield* client.workflow["draft_workspaces.set_start"](payload);
}
case "workflow.draft_workspaces.set_step_input_bindings": { case "workflow.draft_workspaces.set_step_input_bindings": {
const payload = yield* decodeParams( const payload = yield* decodeParams(
WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema, WorkflowDraftWorkspacesSetStepInputBindingsPayloadSchema,
@@ -383,6 +410,15 @@ const executeImpl =
"draft_workspaces.set_step_output_bindings" "draft_workspaces.set_step_output_bindings"
](payload); ](payload);
} }
case "workflow.draft_workspaces.set_workflow_output_bindings": {
const payload = yield* decodeParams(
WorkflowDraftWorkspacesSetWorkflowOutputBindingsPayloadSchema,
params,
);
return yield* client.workflow[
"draft_workspaces.set_workflow_output_bindings"
](payload);
}
case "workflow.draft_workspaces.validate": { case "workflow.draft_workspaces.validate": {
const payload = yield* decodeParams( const payload = yield* decodeParams(
WorkflowDraftWorkspacesValidatePayloadSchema, WorkflowDraftWorkspacesValidatePayloadSchema,