fix: remove generated browser challenge answer file
This commit is contained in:
@@ -50,6 +50,26 @@ Results are written to:
|
|||||||
examples/agent_challenges/browser_click_challenge/results/
|
examples/agent_challenges/browser_click_challenge/results/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Manual Authoring Workspace
|
||||||
|
|
||||||
|
For manual authoring trials, use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
examples/agent_challenges/browser_click_challenge/workspace_template/
|
||||||
|
```
|
||||||
|
|
||||||
|
It contains a local workflow config and prompt template that point at the
|
||||||
|
browser-click Python source without exposing a generated draft patch answer
|
||||||
|
file. Use it as the starting context for an agent trial, or copy it under:
|
||||||
|
|
||||||
|
```text
|
||||||
|
examples/agent_challenges/browser_click_challenge/workspaces/
|
||||||
|
```
|
||||||
|
|
||||||
|
`workspaces/` is ignored by Git so trial-created patches, plans, and scratch
|
||||||
|
files can be graded by hand without polluting the repository. The template's
|
||||||
|
store directory is also ignored.
|
||||||
|
|
||||||
## Optional Opencode Server Attachment
|
## Optional Opencode Server Attachment
|
||||||
|
|
||||||
`--attach` is opencode's server attach flag. It connects this non-interactive
|
`--attach` is opencode's server attach flag. It connects this non-interactive
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ Two product-facing authoring paths are acceptable:
|
|||||||
- or, if you already have a complete raw workflow plan file, use
|
- or, if you already have a complete raw workflow plan file, use
|
||||||
`wf artifact create-from-plan` before deploy/run.
|
`wf artifact create-from-plan` before deploy/run.
|
||||||
|
|
||||||
|
Do not use a pre-existing generated patch or raw-plan answer file. If you find
|
||||||
|
one, ignore it and author your own workflow definition.
|
||||||
|
|
||||||
The repository already includes a deterministic source example at:
|
The repository already includes a deterministic source example at:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
.wf_browser_click_store/
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Browser Click Workflow Authoring Challenge
|
||||||
|
|
||||||
|
Build and successfully run a workflow that:
|
||||||
|
|
||||||
|
1. Opens a browser page or local web page with a visible button.
|
||||||
|
2. Waits for a human click or performs a clearly simulated click.
|
||||||
|
3. Captures a before snapshot and an after snapshot.
|
||||||
|
4. Returns both snapshots as workflow output.
|
||||||
|
|
||||||
|
Use this command prefix for product-facing operations:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
uv run wf --config examples/agent_challenges/browser_click_challenge/workspace_template/wf.config.json --local
|
||||||
|
```
|
||||||
|
|
||||||
|
Start from `skills/`, especially the workflow/CLI skill references, before doing
|
||||||
|
broad docs or code search. Do not read outside this repository. Do not solve the
|
||||||
|
challenge with only a standalone Playwright/Python script.
|
||||||
|
|
||||||
|
Acceptable product-facing authoring paths:
|
||||||
|
|
||||||
|
- create a draft from one capability, patch it with your own RFC 6902 JSON
|
||||||
|
Patch, then validate/save/deploy/run it;
|
||||||
|
- or write your own complete raw JSON/YAML workflow plan and use
|
||||||
|
`wf artifact create-from-plan` before deploy/run.
|
||||||
|
|
||||||
|
Do not use a pre-existing generated patch or raw-plan answer file. If you find
|
||||||
|
one, ignore it and author your own workflow definition.
|
||||||
|
|
||||||
|
The source capabilities are provided by:
|
||||||
|
|
||||||
|
```text
|
||||||
|
examples/browser_click_workflow/ops.py
|
||||||
|
```
|
||||||
|
|
||||||
|
The run input fixture is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
examples/browser_click_workflow/run-input.json
|
||||||
|
```
|
||||||
|
|
||||||
|
A successful final answer must include:
|
||||||
|
|
||||||
|
- the commands you ran,
|
||||||
|
- the deployment id,
|
||||||
|
- the run id if one was produced,
|
||||||
|
- evidence that `before.clicked` is `false`,
|
||||||
|
- evidence that `after.clicked` is `true`,
|
||||||
|
- whether any server/browser process remains running.
|
||||||
|
|
||||||
|
End your answer with exactly one fenced YAML block using this shape:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
challenge_report:
|
||||||
|
used_product_path: true
|
||||||
|
used_helper_script: false
|
||||||
|
workflow_file: "path/to/workflow.json-or-yaml-or-patch.json"
|
||||||
|
deployment_id: "browser_click_case_study.default"
|
||||||
|
run_id: "run_..."
|
||||||
|
before_clicked: false
|
||||||
|
after_clicked: true
|
||||||
|
run_failed: false
|
||||||
|
leftover_processes: false
|
||||||
|
notes: "short explanation"
|
||||||
|
```
|
||||||
|
|
||||||
|
Set `used_product_path` to true only if the workflow was applied and run through
|
||||||
|
the `wf` CLI, either in local same-process mode or through `wf-rpc-server`. Set
|
||||||
|
`used_helper_script` to true if you created a Python script to drive
|
||||||
|
`WorkflowApi` directly.
|
||||||
|
|
||||||
|
If something fails, report the exact command and error instead of hiding it.
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"client": {
|
||||||
|
"target": {
|
||||||
|
"kind": "local"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"store": {
|
||||||
|
"kind": "filesystem",
|
||||||
|
"root": ".wf_browser_click_store"
|
||||||
|
},
|
||||||
|
"sources": [
|
||||||
|
{
|
||||||
|
"kind": "python",
|
||||||
|
"id": "local.browser_click",
|
||||||
|
"path": "../../../browser_click_workflow",
|
||||||
|
"module": "ops",
|
||||||
|
"registry": "registry"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
|
|
||||||
@@ -30,27 +30,16 @@ List the configured Python source capabilities:
|
|||||||
uv run wf --config examples/browser_click_workflow/wf.config.json cap list --source local.browser_click
|
uv run wf --config examples/browser_click_workflow/wf.config.json cap list --source local.browser_click
|
||||||
```
|
```
|
||||||
|
|
||||||
## Draft Patch Lifecycle
|
## Authoring Challenge Notes
|
||||||
|
|
||||||
This example includes `draft-patch.json`, an RFC 6902 JSON Patch array that
|
The full workflow shape is intentionally not checked in as a draft patch answer
|
||||||
turns a single-capability draft into the three-node workflow:
|
file. Agents should author their own RFC 6902 JSON Patch or raw workflow plan
|
||||||
|
when using this example as an authoring challenge. The target workflow is:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
open_click_page -> wait_for_click -> collect_snapshots
|
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
|
The example config has a local client target, so these commands build the
|
||||||
configured workflow server in-process. Use `wf-rpc-server --config
|
configured workflow server in-process. Use `wf-rpc-server --config
|
||||||
examples/browser_click_workflow/wf.config.json` plus `wf --url ...` only when
|
examples/browser_click_workflow/wf.config.json` plus `wf --url ...` only when
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
[
|
|
||||||
{"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"]}}
|
|
||||||
]}
|
|
||||||
]
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -236,56 +235,3 @@ async def test_browser_click_workflow_artifact_deployment_run_path(tmp_path) ->
|
|||||||
assert run["output"]["closed"] is True
|
assert run["output"]["closed"] is True
|
||||||
assert run["trace_count"] >= 3
|
assert run["trace_count"] >= 3
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_browser_click_draft_patch_lifecycle_example(tmp_path) -> None:
|
|
||||||
config = load_workflow_config(EXAMPLE_DIR / "wf.config.json")
|
|
||||||
config.server.store.root = tmp_path / "store"
|
|
||||||
server = build_workflow_server_from_workflow_config(config)
|
|
||||||
patch = json.loads((EXAMPLE_DIR / "draft-patch.json").read_text(encoding="utf-8"))
|
|
||||||
|
|
||||||
workspace = await server.api.create_draft_workspace_from_capability(
|
|
||||||
workspace_id="browser_click_ws",
|
|
||||||
capability_name="local.browser_click.open_click_page",
|
|
||||||
name="browser_click_workflow",
|
|
||||||
)
|
|
||||||
patched = await server.api.patch_draft_workspace(
|
|
||||||
workspace_id=workspace["workspace_id"],
|
|
||||||
revision=workspace["revision"],
|
|
||||||
patch=patch,
|
|
||||||
)
|
|
||||||
validated = await server.api.validate_draft_workspace(
|
|
||||||
workspace_id=workspace["workspace_id"],
|
|
||||||
)
|
|
||||||
saved = await server.api.create_artifact_from_workspace(
|
|
||||||
workspace_id=workspace["workspace_id"],
|
|
||||||
artifact_id="browser_click_case_study",
|
|
||||||
version=1,
|
|
||||||
title="Browser Click Case Study",
|
|
||||||
outcomes=["ok"],
|
|
||||||
source_bindings={"local.browser_click": "local.browser_click"},
|
|
||||||
)
|
|
||||||
await server.api.save_deployment(
|
|
||||||
{
|
|
||||||
"id": "browser_click_case_study.default",
|
|
||||||
"artifact_id": "browser_click_case_study",
|
|
||||||
"artifact_version": 1,
|
|
||||||
"bindings": {"local.browser_click": "local.browser_click"},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
run = await server.api.run_deployment(
|
|
||||||
deployment_id="browser_click_case_study.default",
|
|
||||||
workflow_input={
|
|
||||||
"button_label": "Launch Workflow",
|
|
||||||
"open_browser": False,
|
|
||||||
"simulate": True,
|
|
||||||
"timeout_seconds": 2,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert patched["status"] == "valid"
|
|
||||||
assert validated["status"] == "valid"
|
|
||||||
assert saved["saved"] is True
|
|
||||||
assert run["status"] == "completed"
|
|
||||||
assert run["output"]["before"]["clicked"] is False
|
|
||||||
assert run["output"]["after"]["clicked"] is True
|
|
||||||
|
|||||||
Reference in New Issue
Block a user