Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
4ae9ab8
skills: add webwright.skills memory/skill-library module + skill_use …
DEM1TASSE Jun 30, 2026
91a2090
skills: prompt hint helper + skill_mode overlay; env-based model for …
DEM1TASSE Jun 30, 2026
a96336b
skills: README for the module + env-based model for bare CLI
DEM1TASSE Jun 30, 2026
82fe0ba
docs+tests: README skill-library section + skills unit tests
DEM1TASSE Jun 30, 2026
05aab3a
skills: translate all comments/docstrings to English
DEM1TASSE Jun 30, 2026
bb0d0cd
skills: drop dead code in update (grow path superseded by evolve)
DEM1TASSE Jun 30, 2026
ba4fa2a
skills: fix refine truncation + timeout + fence stripping (found in e…
DEM1TASSE Jul 2, 2026
2784fc6
skills README: add end-to-end How-to-use (manifest schema, params, so…
DEM1TASSE Jul 3, 2026
c293a48
skills README: batch pipeline example (tasks.json -> solve loop -> ga…
DEM1TASSE Jul 3, 2026
7deab76
skills README: manifest field-by-field table; Results summary with We…
DEM1TASSE Jul 3, 2026
f7b0779
skills: harden pipeline entry points (review findings)
DEM1TASSE Jul 3, 2026
d0c6d84
skills: manifest 'admit' must be a JSON boolean (hand-written "false"…
DEM1TASSE Jul 3, 2026
6060bd5
skills: fix cleanroom-repro findings (silent empty-library skip, rela…
DEM1TASSE Jul 8, 2026
4682a47
skills: add examples/ — a real evolve-produced skill, measured saving…
DEM1TASSE Jul 8, 2026
1234788
skills README: narrative intro (programs not notes, gate, aggregation…
DEM1TASSE Jul 8, 2026
3612e89
skills: friendly entry — 'learn' turns a folder of runs into skills (…
DEM1TASSE Jul 8, 2026
b656e6c
skills: fix learn-interface test findings (silent-reuse-off, tracebac…
DEM1TASSE Jul 8, 2026
5cac233
skills README: env exports at the top of Quickstart (step-1-only read…
DEM1TASSE Jul 8, 2026
64a4feb
skills: release-gap fixes — gate honesty, aggregation showcase, regre…
DEM1TASSE Jul 8, 2026
ddca588
ci: run skills unit tests + wrapper usage check on module changes
DEM1TASSE Jul 8, 2026
06d72b3
evals: make the WebArena numbers reproducible (evals/webarena/)
DEM1TASSE Jul 9, 2026
6513d87
skills: address Copilot review findings
DEM1TASSE Jul 9, 2026
8ea59be
skills: address review — complete Quickstart, drop skill_mode.yaml, c…
DEM1TASSE Jul 10, 2026
7acbdd4
skills: Quickstart on Google Flights — Webwright's own example task
DEM1TASSE Jul 11, 2026
223597a
skills: record the three-way consistency check on the held-out route
DEM1TASSE Jul 11, 2026
9286493
skills: measured cost table in Quickstart; single flights example
DEM1TASSE Jul 11, 2026
bb67e3e
skills: trim Quickstart cost table to steps + wall time
DEM1TASSE Jul 11, 2026
b9b95e2
skills: step savings scale with unfamiliarity/variance, not zero
DEM1TASSE Jul 11, 2026
b32cc76
skills: self_verify also honors the agent's own final report (free si…
DEM1TASSE Jul 11, 2026
3dfdfd0
skills: end-to-end regression for the status-aware self_verify gate
DEM1TASSE Jul 11, 2026
4a6036b
skills: one-command quickstart.sh — every parameter pre-filled
DEM1TASSE Jul 11, 2026
c8b27c5
skills: quickstart.sh usage path robust to caller cwd
DEM1TASSE Jul 11, 2026
dc8c870
evals: collapse 100 per-task result files into one results.json
DEM1TASSE Jul 11, 2026
f729099
evals: drop the WebArena repro package from the PR (kept locally)
DEM1TASSE Jul 11, 2026
7afb6c0
skills: skills never write artifacts next to __file__; gateway solve-…
DEM1TASSE Jul 11, 2026
c34eb9b
skills: docs run standalone skills from scratch dirs, not repo dirs
DEM1TASSE Jul 11, 2026
f8d047d
skills: pipeline diagram shows evolve's code input and template bucke…
DEM1TASSE Jul 11, 2026
9786424
skills: replay-verify distilled skills before they enter the library
DEM1TASSE Jul 11, 2026
0c29b9f
skills: replay comparator normalizes scalars; manifest carries creden…
DEM1TASSE Jul 11, 2026
693d816
skills: rejected skills leave their runs un-learned (retry possible)
DEM1TASSE Jul 11, 2026
0b74074
skills: standalone-reproduces-its-answers is now the default bar
DEM1TASSE Jul 11, 2026
bcd8210
skills: two skill grades + regression-checked incremental refine
DEM1TASSE Jul 11, 2026
c3331c4
rename: webwright.skills -> webwright.skill_lab (Webwright Skill Lab)
DEM1TASSE Jul 11, 2026
9859176
rename: final name Web Skill Factory (module webwright.skill_factory)
DEM1TASSE Jul 11, 2026
aaf9f99
examples: single checked-in library, diagram moved to assets/
DEM1TASSE Jul 11, 2026
aefbd53
README: tight overview, details pushed down, demo shipped in assets
DEM1TASSE Jul 11, 2026
fb9aa04
Revise README for skill factory module
DEM1TASSE Jul 11, 2026
325994a
README: landing page in the parent repo's register; reference into docs/
DEM1TASSE Jul 12, 2026
cbd7db4
docs: three references; full eval table and design move into the README
DEM1TASSE Jul 12, 2026
d12cee0
README: cost table to quickstart doc, richer Design; diagram gains re…
DEM1TASSE Jul 12, 2026
36c5780
quickstart: close the gateway traps from the external repro
DEM1TASSE Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/skills-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: skills-tests
on:
push:
paths: ["src/webwright/skill_factory/**", "src/webwright/tools/skill_use.py", "tests/skill_factory/**"]
pull_request:
paths: ["src/webwright/skill_factory/**", "src/webwright/tools/skill_use.py", "tests/skill_factory/**"]
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install httpx pyyaml jinja2 pydantic
- name: skills unit tests (LLM-free)
run: |
set -e
for t in tests/skill_factory/test_*.py; do
echo "== $t"; PYTHONPATH=src python "$t"
done
- name: wrapper usage check (F6)
run: |
set +e
bash src/webwright/skill_factory/examples/solve_with_library.sh > /dev/null 2>&1
[ $? -eq 1 ] && echo "usage-exit OK" || { echo "wrapper must exit 1 on missing args"; exit 1; }
bash -n src/webwright/skill_factory/examples/quickstart.sh || exit 1
bash src/webwright/skill_factory/examples/quickstart.sh badmode > /dev/null 2>&1
[ $? -eq 1 ] && echo "quickstart usage-exit OK" || { echo "quickstart must exit 1 on bad mode"; exit 1; }
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,25 @@ python assets/task_showcase/app.py \

---

## 🧠 Skill Library (reuse solved tasks across tasks)

[`webwright.skills`](src/webwright/skills/) turns solved tasks into **reusable, executable code
skills**, retrieves and judges them at solve time, gates what enters the library, and grows the
library incrementally — a self-evolving *store → retrieve → use/adapt → gate → evolve* loop on top
of Webwright's code-as-action solves. Plugs in with **no change to the agent loop**:

- **Reuse** — the agent calls `python -m webwright.tools.skill_use --task "..." --library ...`
(like `self_reflection`/`image_qa`); it returns `{verdict: use|adapt|skip, source_path}`.
- **Grow** — `python -m webwright.skills.update --manifest batch.json --library ./library`
distills a batch of gate-passed solves into a parameterized, primitive-decomposed skill.

Validated end-to-end on a real public website (read-only GitHub): solve two repos from scratch →
`update` builds a parameterized skill → a held-out repo is solved by reusing it (agent calls
`skill_use`, verdict `use`, answer correct); a wrong solve is kept out by the gate; a second batch
improves the existing skill in place. See [`src/webwright/skills/README.md`](src/webwright/skills/README.md).

---

## 🚀 Quick Start

### Prerequisites
Expand Down
Binary file added assets/skill_factory_demo.mp4
Binary file not shown.
Binary file added assets/skill_factory_pipeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
174 changes: 174 additions & 0 deletions assets/skill_factory_pipeline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
129 changes: 129 additions & 0 deletions src/webwright/skill_factory/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Web Skill Factory

**Most agent skills are context the model refers to. Ours are programs.**

Each solved task becomes runnable, parameterized code — verify it, run it without the
model, and import it into the next task instead of re-exploring.

Module: `webwright.skill_factory`, built on Webwright.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DEM1TASSE It is better to add the complete example in the quick start session.
It needs to additionally include how to use the skill library.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8ea59be — the Quickstart is now the complete loop on a copy-pasteable example (public GitHub): solve 3 instances -> learn -> an unseen instance reuses the skill (with the expected skill_decision.json shown), plus how to use the library without the agent (querying skill_use directly, and running the learned skill standalone with no model — verified pandas-dev/pandas -> v3.0.4). The same loop's output is checked in at examples/learned_library/.

## 🎥 Demo

https://github.com/user-attachments/assets/d15b1f83-2c8d-4f2d-bbc5-be365c0bcf4e

## ✨ Why

- 🧩 **Import, don't just refer** — skills are executable code; a learned skill re-runs
standalone in ~30 s with **no model in the loop**
- 🌱 **Self-evolving** — each batch of solves is gated, grouped by template, distilled;
wrong answers never enter, working skills never break
-**Replay-verified** — a skill must reproduce its own training answers standalone
before it may land
- 💸 **Cheap to adopt** — one tool + one CLI, zero agent-loop changes

## 🗺️ How it works

![data flow & interfaces](../../../assets/skill_factory_pipeline.png)

```
solve → gate → group by template → distill → replay-verify → library → next solve reuses
```

At solve time the agent asks the library once and gets `use` / `adapt` / `skip`
reuse never blocks solving.

## 🚀 Quick Start

```bash
cd src/webwright/skill_factory/examples
./quickstart.sh # a learned skill drives a live site — no model, no API key needed
```

<details>
<summary><b>More modes</b> — reuse with the agent, or rebuild the library yourself</summary>

<br>

```bash
export OPENAI_API_KEY=...
./quickstart.sh ask # ask the library about a task it has never seen
./quickstart.sh solve # the agent REUSES the checked-in skill on a new route
./quickstart.sh full # the whole loop: 3 solves -> learn -> reuse (~30 min)
```

On a custom OpenAI-compatible gateway, also `export OPENAI_ENDPOINT=... OPENAI_MODEL=...`
(for learn / skill_use; the endpoint is the FULL `.../responses` URL, not a base path) and
`export MODEL_CFG=...` pointing at a copy of `examples/model_gateway.example.yaml` (for the
agent — it reads a yaml, not these env vars).

</details>

Full tutorial — the loop spelled out, gateway setup, running skills without the agent:
**[docs/quickstart.md](docs/quickstart.md)**

## 📊 Results

**Setting** — WebArena, 10 retrieve-type task templates across 3 self-hosted sites
(shopping-admin, gitlab, map). Per template: 3 train solves build the library
(gold-gated), 2 held-out instances measure reuse; every held-out task is solved both
WITH the library and from scratch. Same model, same budget, 100 solves total.

| | WITH library | from scratch | Δ |
|-------------------------|--------------|--------------|---------|
| held-out accuracy (20) | **70%** | 55% | **+15 pp** |
| held-out avg steps | **14.7** | 17.1 | −2.4 |
| train accuracy (30) | **86.7%** | 76.7% | +10 pp |
| train avg steps | **13.7** | 15.9 | −2.2 |

- **4 held-out tasks rescued** (wrong → correct); net reuse-wins vs regressions **7 : 1**;
biggest win **33 → 10 steps**
- retrieval stayed reliable as the library grew: all 20 held-out solves picked the right
skill, including two near-duplicate templates
- mixed-template batches evolve safely: adds, refines and keeps with zero cross-contamination

## 🧠 Design

**Actions are already code.** Webwright solves by writing code — every solve leaves a
working script behind, so skills are a byproduct, not an instrumentation layer. It
complements `crafted_cli`: craft parameterizes one script by *anticipating* what might
vary; the factory parameterizes across solves from the differences *actually observed*.

**One solve isn't a skill yet.** A single script is correct but narrow. Aggregating
verified solves of the same template turns observed differences into parameters and
recurring patterns into primitives — different runs' strategies become fallbacks, and
what lands is the best algorithm the solves discovered.

**Parameters are evidence, primitives are the product.** Parameters aren't guessed up
front — they are the differences actually observed between solves. The expensive core is
factored into named primitives (`login()`, `open_grid()`, `extract_rows()`) with a thin
task layer on top, so future tasks can reuse and compose the pieces even when the final
step differs.

**Nothing lands unproven.** The admission gate checks the *inputs*, but distillation
itself can introduce bugs — and an agent reading a broken skill as source will quietly
work around them, so agent-in-loop numbers alone can't certify a library. The proof is
model-free execution: a skill must replay its own training taskspecs standalone and
reproduce the answers before it lands, and every skill carries its grade —
`executable` (proved) or `reference` (a prior the agent may still read).

**Growth never breaks what works.** New templates add skills, new solves refine existing
ones in place (regression-replayed against their stored training examples), untouched
skills stay byte-identical.

## 🔌 Plugs into Webwright

Two touch points, no agent-loop changes:

```bash
python -m webwright.tools.skill_use --task "<task>" --library ./library # reuse at solve time
python -m webwright.skill_factory learn outputs/ --library ./library # grow it afterwards
```

## 📚 Documentation

| doc | what's in it |
|---|---|
| [docs/quickstart.md](docs/quickstart.md) | the complete tutorial: the flights loop, gateway knobs, standalone usage, measured costs |
| [docs/manual.md](docs/manual.md) | manual mode: manifests field by field, gold gates, the batch pipeline |
| [docs/reference.md](docs/reference.md) | verification & grades, every flag and env var, component map, backend |
| [examples/README.md](examples/README.md) | the checked-in skill and the example inputs |
Loading