8.5 KiB
Draft Workspaces Reference
Use draft workspaces for iterative workflow authoring. They are mutable and revisioned; artifacts are immutable and versioned.
Before writing or patching a draft, inspect the current public shape:
wf schema draft
wf schema DraftUseStep
Draft Shape
A draft has:
nameinput_schemastate_schemaoutput_schemastartstepsroutes- optional top-level
output
steps are keyed by stable ids. routes map outcomes to another step id or
__end__.
Mapping Rules
Step input bindings read graph values into node-local input:
{
"target": "text",
"path": "input.text"
}
Step output bindings write node-local output into workflow state:
{
"source": "echoed",
"target": "state.echoed"
}
Top-level workflow output uses path / target, not step-level
source / target:
{
"path": "state.echoed",
"target": "echoed"
}
Workspace Flow
- Create workspace from capability.
- Get workspace with
include_draft=truebefore patching. - Patch with current
revision. - Validate workspace.
- Save artifact or wrapper from workspace.
Capability-backed creation auto-binds required capability inputs only. Optional inputs remain declared by the capability but are omitted from the initial step input map. Add one deliberately when the workflow should expose it:
wf draft bind report_ws --revision 2 --step call --from input.path --to local.path
If a patch returns revision_conflict, fetch the workspace again and retry
against the latest revision.
Forward routes in drafts are allowed as invalid intermediate state. If
wf draft add-step --route ok=collect returns status: invalid, add the
missing collect step next, then run wf draft validate. Do not save or
compile until validation is valid.
Focused Helpers
Prefer focused helpers over JSON Patch for common edits:
set_draft_nameset_draft_routeset_step_input_mapset_step_output_mapset_workflow_output_mapbind_draftadd_step_from_capabilitybranch_drafthandle_draftcompile_draft_workspace
CLI equivalents:
wf draft set-name <workspace_id> --revision <n> --name <name>
wf draft set-route <workspace_id> --revision <n> --step <step_id> --outcome ok --to <target>
wf draft set-input <workspace_id> --revision <n> --step <step_id> --map input.text=text
wf draft set-input <workspace_id> --revision <n> --step <step_id> --merge --map input.other=other
wf draft set-output <workspace_id> --revision <n> --step <step_id> --map text=state.text
wf draft set-output <workspace_id> --revision <n> --step <step_id> --merge --map other=state.other
wf draft set-workflow-output <workspace_id> --revision <n> --map state.value=result
wf draft set-workflow-output <workspace_id> --revision <n> --merge --map state.other=other
wf draft branch <workspace_id> --revision <n> --step <step_id> --route ok=__end__ --route error=fail
wf draft handle <workspace_id> --revision <n> --to fail --branch lookup:error --branch transform:error
wf draft compile <workspace_id>
wf draft bind <workspace_id> --revision <n> --step <step_id> --from local.<field> --to state.<field>
wf draft bind <workspace_id> --revision <n> --step <step_id> --from input.<field> --to local.<field>
wf draft add-step <workspace_id> --revision <n> --step <step_id> --capability <qualified_name> --from-step <prev> --from-outcome ok --route ok=__end__ --route error=fail --input input.text=text --bind-output result=state.result
set-workflow-output maps a graph source path (input.*, state.*, or
context.*) to one public workflow output field. It edits top-level
WorkflowDraft.output; set-output edits one step's local-to-state bindings.
For single-field input.* and state.* sources, missing public output schema
fields are projected automatically from the source schema.
set-input direction: input.text=text means graph source input.text maps to
node-local target local.text. Targets are bare node-local field names; never
prefix the target with local..
set-output direction: text=state.text means node-local source local.text
maps to graph target state.text.
Without --merge, set-input, set-output, and set-workflow-output replace
the whole map for that step or output scope. Use repeated --map flags in one
command for a complete replacement. Use --merge only when adding/updating
entries over multiple revisions.
bind input.x -> local.x is schema-aware and idempotent when input.x is
already declared. Use it for repair hints or schema projection. Use
set-input --merge --map input.x=x when you only need to update a step input
map.
-
bind_draftDeclares a workflow input/state/output schema field from a capability local input/output schema and merges the matching step binding. Use
input/state -> localfor step inputs andlocal -> state/outputfor step outputs. Prefer this over manual JSON Patch when validation says a target schema field is missing. The selected step must haveuseso the helper can find the capability schema. It intentionally rejects non-capability/control steps instead of guessing. Alocal.x -> output.ybind is atomic: it projects the capability field schema into both workflow state and output schemas, writeslocal.x -> state.yon the step, and publishesstate.y -> output.yat the workflow boundary.
wf draft bind <workspace_id> --revision <n> --step <step_id> --from local.<field> --to state.<field>
wf draft bind <workspace_id> --revision <n> --step <step_id> --from input.<field> --to local.<field>
wf draft bind <workspace_id> --revision <n> --step <step_id> --from local.<field> --to output.<field>
wf draft validate <workspace_id>
-
add_step_from_capabilityAdds a new capability-backed step with explicit route, input bindings, and output-to-state schema/binding wiring in one revision. It can set the incoming edge, outgoing edges, input map, and output-to-state schema/binding. Use
--route OUTCOME=TARGETfor each outcome; when omitted and the capability declares a single outcome, that outcome routes to__end__. Multi-outcome capabilities require exact route coverage; missing or unknown outcomes are rejected before mutation. Whenadd-step --routerejects an outcome, the error reports declared outcomes and direct add/remove repair guidance. Remove unknown route entries and add one route for each missing declared outcome. It still requires explicit choices; if you do not know a map, inspect the capability or run validation rather than guessing. Explicit top-level--input input.x=xand--input state.x=xmappings project the corresponding workflow input/state schema fields from the capability input schema.
wf draft add-step <workspace_id> --revision <n> --step <step_id> --capability <qualified_name> --from-step <prev> --from-outcome ok --route ok=__end__ --route error=fail --input input.text=text --input input.other=other --bind-output result=state.result --bind-output title=state.title
wf draft validate <workspace_id>
Repeat --input and --bind-output once per mapping. Do not write
--bind-output title=state.title summary=state.summary; the second mapping is
an unexpected extra argument because it is not attached to its own flag.
-
branch_draftUpdates routes for an existing step in one revision without rewriting the full routes object. Supply
--route OUTCOME=TARGETfor each outcome to set or update. -
handle_draftRoutes multiple source step outcomes to a common target. Supply
--branch STEP:OUTCOMEfor each source outcome and--to TARGETfor the shared destination. -
compile_draft_workspaceAPI/RPC/MCP returns the compiled raw plan plus required capabilities without mutating or saving the draft workspace. The CLI prints only the raw plan JSON on success. On invalid draft status, it returns structured diagnostics without a
compiled_plan.
Validation repair hints are product guidance. If a diagnostic suggests
wf draft bind, run that exact focused command before hand-editing schemas or
step bindings, then validate the new revision.
Remove commands are for recovery. They do not delete schema fields and
remove-step does not remove inbound routes. Validate after removal and repair
the resulting diagnostics explicitly.
Use JSON Patch for structural edits the helpers do not cover.
For larger patches, write a JSON Patch array to a file and pass it with
--input-file:
wf draft patch <workspace_id> --revision <n> --input-file draft-patch.json
The patch file must be an RFC 6902 JSON Patch array, not a full draft object.