5.6 KiB
Draft Bind From/To Design
Status
Implemented. This design replaces bind-output-to-state with the general
bind --from ... --to ... operation. bind-output-to-state was introduced
recently as an incomplete narrow helper and should be removed rather than
preserved as compatibility.
Problem
Agents authoring drafts repeatedly hit the same boundary: step input/output bindings are not just path edits. They often require workflow-level schema declarations too.
Today:
wf draft set-inputedits a step input map, but it does not declareinput_schema.properties.<field>.wf draft bind-output-to-statedeclares one root state field and writes a step output binding, but only coverslocal.output -> state.field. It is too narrow now that input-side schema projection is needed too.- Agents interpret this split inconsistently, then fall back to raw JSON Patch.
The product needs one capability-aware operation with the mental model:
bind <destination> from <source>
User-Facing Shape
Primary CLI:
wf draft bind <workspace_id> `
--revision <n> `
--step <step_id> `
--from <path> `
--to <path>
Examples:
# Workflow input into a capability input.
wf draft bind browser_ws --revision 2 --step click `
--from input.simulate `
--to local.simulate
# Capability output into workflow state.
wf draft bind browser_ws --revision 3 --step click `
--from local.after `
--to state.after
# Capability output into final workflow output.
wf draft bind report_ws --revision 7 --step render `
--from local.markdown `
--to output.markdown
Semantics
bind is capability-aware and step-scoped. The step must be a capability-backed
draft step with a use field.
Supported directions:
| From | To | Draft edit | Schema projection |
|---|---|---|---|
input.* |
local.* |
add/merge step input binding | copy capability input schema for local.* into workflow input_schema at input.* |
state.* |
local.* |
add/merge step input binding | copy capability input schema for local.* into workflow state_schema at state.* |
local.* |
state.* |
add/merge step output binding | copy capability output schema for local.* into workflow state_schema at state.* |
local.* |
output.* |
add/merge step output binding | copy capability output schema for local.* into workflow output_schema at output.* |
Unsupported directions should fail clearly:
local.* -> local.*input.* -> state.*state.* -> output.*output.* -> local.*- Any path root outside
input,state,output, orlocal
Schema Projection
The schema projection helper should be generalized from the current output-to-state helper.
Requirements:
- Use
jsonschema.Draft202012Validator.check_schemato validate input schemas and projected schemas. Do not hand-roll JSON Schema validation. - Copy the selected local field schema from the capability input/output schema.
- Preserve
$defsanddefinitions, rejecting conflicting definitions. - Insert the copied field schema at the target workflow path.
- Support nested target paths such as
state.options.timeout_seconds. - Create missing ancestor object schemas only when the ancestor does not exist.
- Reject inserting through an existing non-object ancestor.
- Reject overwriting an existing target property by default.
Nested insertion example:
{
"type": "object",
"properties": {
"options": {
"type": "object",
"properties": {
"timeout_seconds": { "type": "number" }
}
}
}
}
This is a schema projection operation, not a general JSON Schema editor. It only copies one capability local input/output field schema to one workflow graph path.
API Shape
Add the general method:
async def bind_draft(
self,
*,
workspace_id: str,
revision: int,
step_id: str,
source_path: str,
target_path: str,
) -> dict[str, Any]: ...
Name notes:
- User-facing CLI says
bind --from ... --to .... - Python/RPC names should avoid reserved words and use
source_path/target_path. - Remove
bind_output_to_stateend-to-end. It has no long-lived compatibility contract and is replaced bybind_draft.
RPC And MCP
New JSON-RPC method:
workflow.draft_workspaces.bind
Params:
{
"workspace_id": "browser_ws",
"revision": 3,
"step_id": "click",
"source_path": "local.after",
"target_path": "state.after"
}
New MCP tool:
wf.workflow.bind
Remove existing RPC/MCP bind_output_to_state surfaces during this slice.
Repair Hints
Existing invalid-destination hints currently recommend:
wf draft bind-output-to-state ...
They should instead recommend:
wf draft bind <workspace_id> --revision <n> --step <step_id> --from local.<field> --to state.<field>
Future missing-input-schema diagnostics can also point to:
wf draft bind <workspace_id> --revision <n> --step <step_id> --from input.<field> --to local.<field>
Non-Goals
- Do not preserve
bind-output-to-stateas a compatibility alias. - Do not add arbitrary schema editing commands.
- Do not support array item schema projection.
- Do not infer routes.
- Do not mutate bindings without revision checks.
Acceptance Criteria
- Agents can fix browser-click input schema issues with
wf draft bind --from input.simulate --to local.simulateinstead of raw JSON Patch. - Agents can bind outputs with
wf draft bind --from local.after --to state.after; the oldbind-output-to-statecommand/method/tool is gone. - Nested target paths are handled safely or rejected with clear errors.