docs: add draft patch and plan artifact workflow guidance
This commit is contained in:
@@ -30,6 +30,13 @@ If you need to write a workflow definition, write a declarative JSON/YAML file
|
||||
and then apply/run it through the product-facing workflow tools. Do not hide the
|
||||
workflow construction inside a Python script.
|
||||
|
||||
Two product-facing authoring paths are acceptable:
|
||||
|
||||
- create a draft from one capability, patch it with RFC 6902 JSON Patch, then
|
||||
validate/save/deploy/run it;
|
||||
- or, if you already have a complete raw workflow plan file, use
|
||||
`wf artifact create-from-plan` before deploy/run.
|
||||
|
||||
The repository already includes a deterministic source example at:
|
||||
|
||||
```text
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
.wf_browser_click_store/
|
||||
|
||||
@@ -21,16 +21,41 @@ From the repository root:
|
||||
|
||||
```powershell
|
||||
uv run wf config validate examples/browser_click_workflow/wf.config.json
|
||||
uv run wf-rpc-server --config examples/browser_click_workflow/wf.config.json
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json --local status
|
||||
```
|
||||
|
||||
In another terminal:
|
||||
List the configured Python source capabilities:
|
||||
|
||||
```powershell
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json status
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json cap list --source local.browser_click
|
||||
```
|
||||
|
||||
## Draft Patch Lifecycle
|
||||
|
||||
This example includes `draft-patch.json`, an RFC 6902 JSON Patch array that
|
||||
turns a single-capability draft into the three-node workflow:
|
||||
|
||||
```text
|
||||
open_click_page -> wait_for_click -> collect_snapshots
|
||||
```
|
||||
|
||||
Apply and run it through the product-facing CLI:
|
||||
|
||||
```powershell
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json draft create-from-capability browser_click_ws local.browser_click.open_click_page --name browser_click_workflow
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json draft patch browser_click_ws --revision 1 --input-file examples/browser_click_workflow/draft-patch.json
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json draft validate browser_click_ws
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json draft save browser_click_ws --artifact browser_click_case_study --version 1 --title "Browser Click Case Study" --outcome ok
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json deploy save browser_click_case_study.default --artifact browser_click_case_study --version 1 --binding local.browser_click=local.browser_click
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json deploy validate browser_click_case_study.default
|
||||
uv run wf --config examples/browser_click_workflow/wf.config.json run start browser_click_case_study.default --input-file examples/browser_click_workflow/run-input.json
|
||||
```
|
||||
|
||||
The example config has a local client target, so these commands build the
|
||||
configured workflow server in-process. Use `wf-rpc-server --config
|
||||
examples/browser_click_workflow/wf.config.json` plus `wf --url ...` only when
|
||||
you specifically want to exercise the JSON-RPC server path.
|
||||
|
||||
The full artifact/deployment/run lifecycle is covered by:
|
||||
|
||||
```powershell
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
[
|
||||
{"op": "replace", "path": "/name", "value": "browser_click_case_study"},
|
||||
{"op": "replace", "path": "/start", "value": "open"},
|
||||
{"op": "replace", "path": "/input_schema", "value": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"button_label": {"type": "string"},
|
||||
"open_browser": {"type": "boolean"},
|
||||
"simulate": {"type": "boolean"},
|
||||
"timeout_seconds": {"type": "number"}
|
||||
},
|
||||
"required": ["button_label", "open_browser", "simulate", "timeout_seconds"]
|
||||
}},
|
||||
{"op": "replace", "path": "/state_schema", "value": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"opened": {"type": "object", "reducer": "wf.std.replace"},
|
||||
"clicked": {"type": "object", "reducer": "wf.std.replace"},
|
||||
"result": {"type": "object", "reducer": "wf.std.replace"}
|
||||
}
|
||||
}},
|
||||
{"op": "replace", "path": "/output_schema", "value": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"before": {"type": "object"},
|
||||
"after": {"type": "object"},
|
||||
"closed": {"type": "boolean"}
|
||||
},
|
||||
"required": ["before", "after", "closed"]
|
||||
}},
|
||||
{"op": "replace", "path": "/routes", "value": {
|
||||
"open": {"ok": "wait"},
|
||||
"wait": {"ok": "collect"},
|
||||
"collect": {"ok": "__end__"}
|
||||
}},
|
||||
{"op": "replace", "path": "/steps", "value": {
|
||||
"open": {
|
||||
"use": "local.browser_click.open_click_page",
|
||||
"input": [
|
||||
{"path": {"root": "input", "parts": ["button_label"]}, "target": {"root": "local", "parts": ["button_label"]}},
|
||||
{"path": {"root": "input", "parts": ["open_browser"]}, "target": {"root": "local", "parts": ["open_browser"]}}
|
||||
],
|
||||
"output": [
|
||||
{"source": {"root": "local", "parts": []}, "target": {"root": "state", "parts": ["opened"]}}
|
||||
]
|
||||
},
|
||||
"wait": {
|
||||
"use": "local.browser_click.wait_for_click",
|
||||
"input": [
|
||||
{"path": {"root": "state", "parts": ["opened", "session_id"]}, "target": {"root": "local", "parts": ["session_id"]}},
|
||||
{"path": {"root": "input", "parts": ["simulate"]}, "target": {"root": "local", "parts": ["simulate"]}},
|
||||
{"path": {"root": "input", "parts": ["timeout_seconds"]}, "target": {"root": "local", "parts": ["timeout_seconds"]}}
|
||||
],
|
||||
"output": [
|
||||
{"source": {"root": "local", "parts": []}, "target": {"root": "state", "parts": ["clicked"]}}
|
||||
]
|
||||
},
|
||||
"collect": {
|
||||
"use": "local.browser_click.collect_snapshots",
|
||||
"input": [
|
||||
{"path": {"root": "state", "parts": ["opened", "session_id"]}, "target": {"root": "local", "parts": ["session_id"]}},
|
||||
{"path": {"root": "state", "parts": ["opened", "before"]}, "target": {"root": "local", "parts": ["before"]}},
|
||||
{"path": {"root": "state", "parts": ["clicked", "after"]}, "target": {"root": "local", "parts": ["after"]}}
|
||||
],
|
||||
"output": [
|
||||
{"source": {"root": "local", "parts": []}, "target": {"root": "state", "parts": ["result"]}}
|
||||
]
|
||||
}
|
||||
}},
|
||||
{"op": "replace", "path": "/output", "value": [
|
||||
{"path": {"root": "state", "parts": ["result", "before"]}, "target": {"root": "local", "parts": ["before"]}},
|
||||
{"path": {"root": "state", "parts": ["result", "after"]}, "target": {"root": "local", "parts": ["after"]}},
|
||||
{"path": {"root": "state", "parts": ["result", "closed"]}, "target": {"root": "local", "parts": ["closed"]}}
|
||||
]}
|
||||
]
|
||||
Reference in New Issue
Block a user