Skip to content

Commit 48e0398

Browse files
pablomogamonclaude
andcommitted
Two workflows that chain primitives, composed from the skills' own commands
price-monitoring (fetch -> extract -> batch): prove the page, prove the structure, estimate before spending, run managed, retry-failed on a schedule. gated-page-extraction (fetch -> browser -> extract): the escalation-only rule end to end - the browser enters only when the cheap step failed with evidence, scripted sessions preferred because they close themselves. Every command line is lifted from the skills (protected-fetch, extract, batch-jobs, interact-browser), so the workflows cannot promise a flag the CLI does not have. Registered in registry/workflows.json; the app's Overview vendors this registry (scripts/sync-agent-catalog.mjs there), so these cards render in the product from this same source. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5e52585 commit 48e0398

3 files changed

Lines changed: 152 additions & 2 deletions

File tree

registry/workflows.json

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,58 @@
55
"type": "workflow",
66
"description": "Gather competitor pages, extract structured data, and keep it fresh.",
77
"status": "available",
8-
"requires_backend_capabilities": ["protected_fetch", "extract"],
8+
"requires_backend_capabilities": [
9+
"protected_fetch",
10+
"extract"
11+
],
912
"requires_auth": true,
1013
"version": "0.1.0",
1114
"path": "workflows/competitor-intelligence",
12-
"tags": ["competitive", "extract", "fetch"]
15+
"tags": [
16+
"competitive",
17+
"extract",
18+
"fetch"
19+
]
20+
},
21+
{
22+
"name": "price-monitoring",
23+
"type": "workflow",
24+
"description": "Watch prices across many product pages, validated once and then run as a managed batch.",
25+
"status": "available",
26+
"requires_backend_capabilities": [
27+
"protected_fetch",
28+
"extract",
29+
"batch"
30+
],
31+
"requires_auth": true,
32+
"version": "0.1.0",
33+
"path": "workflows/price-monitoring",
34+
"tags": [
35+
"pricing",
36+
"fetch",
37+
"extract",
38+
"batch"
39+
]
40+
},
41+
{
42+
"name": "gated-page-extraction",
43+
"type": "workflow",
44+
"description": "Get structured data out of pages that need interaction first, escalating to a browser only with evidence.",
45+
"status": "available",
46+
"requires_backend_capabilities": [
47+
"protected_fetch",
48+
"browser",
49+
"extract"
50+
],
51+
"requires_auth": true,
52+
"version": "0.1.0",
53+
"path": "workflows/gated-page-extraction",
54+
"tags": [
55+
"browser",
56+
"escalation",
57+
"extract",
58+
"fetch"
59+
]
1360
}
1461
]
1562
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
name: gated-page-extraction
3+
description: Get structured data out of pages that need interaction first, escalating to a browser only with evidence.
4+
requires_backend_capabilities: [protected_fetch, browser, extract]
5+
status: available
6+
---
7+
8+
# Workflow: gated-page extraction
9+
10+
Some pages only show their data after an interaction: a login, a "load more",
11+
a form. The rule from [[interact-browser]] applies end to end: **escalation
12+
only** — a browser session costs more than fetch/extract (billed by bandwidth
13+
plus session time, 15-minute cap), so it enters the flow only when the cheap
14+
step has failed with evidence.
15+
16+
## Steps
17+
18+
1. **Try the cheap primitive first** ([[protected-fetch]]):
19+
```
20+
zenrows fetch https://portal.example/reports
21+
```
22+
If the response already carries the data, stop here — the rest of this
23+
workflow is unnecessary cost. If it fails, read the trace before escalating
24+
([[trace-debug]]).
25+
2. **Escalate to a scripted session.** Put the interaction (navigate, type,
26+
click, read) in a script and let the session close itself
27+
([[interact-browser]]):
28+
```
29+
zenrows browser run script.json
30+
```
31+
Prefer the scripted form over an interactive session: interactive sessions
32+
you must `close` yourself, and every open minute bills.
33+
3. **Turn the captured page into data** ([[extract]]):
34+
```
35+
zenrows extract https://portal.example/reports --autoparse
36+
```
37+
Or a selector map when you know the shape:
38+
```
39+
zenrows extract https://portal.example/reports --css '{"report":"h2","total":".sum"}' --validate
40+
```
41+
42+
## Explain
43+
44+
```
45+
zenrows workflow explain gated-page-extraction
46+
```
47+
48+
Each step declares its capability; the toolkit refuses honestly when a required
49+
primitive is not available yet (`ASSET_REQUIRES_CAPABILITY`). Browser Sessions
50+
is GA and on by default; a workspace that opted out re-enables it with
51+
`zenrows policy set allow_browser true` ([[compliance-policy]]).
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
name: price-monitoring
3+
description: Watch prices across many product pages, validated once and then run as a managed batch.
4+
requires_backend_capabilities: [protected_fetch, extract, batch]
5+
status: available
6+
---
7+
8+
# Workflow: price monitoring
9+
10+
Three primitives in a row: prove the page with **Fetch**, prove the structure
11+
with **Extract**, then let **Batch** operate the loop. Each step is the cheapest
12+
tool that answers the next question, per [[cost-control]].
13+
14+
## Steps
15+
16+
1. **Prove the page loads with its price.** One protected fetch, waiting for
17+
the selector you care about ([[protected-fetch]]):
18+
```
19+
zenrows fetch https://shop.example/p/123 --wait-for ".price"
20+
```
21+
2. **Prove the structure once.** A selector map that must come back as valid
22+
JSON, or fail loudly ([[extract]]):
23+
```
24+
zenrows extract https://shop.example/p/123 --css '{"title":"h1","price":".price"}' --validate
25+
```
26+
3. **Estimate before spending.** Put the full URL list in `jobs.jsonl` and ask
27+
what the run would cost — this validates the spec locally and needs no key
28+
([[batch-jobs]]):
29+
```
30+
zenrows batch estimate jobs.jsonl
31+
```
32+
4. **Run it managed.** Batch submits every URL, retries transient failures and
33+
stores results, so you do not operate the loop yourself:
34+
```
35+
zenrows batch create jobs.jsonl --wait
36+
zenrows batch results <id> --status all --out results.jsonl
37+
```
38+
5. **Keep it fresh.** Rerun on a schedule (cron or CI). Failures do not restart
39+
the world:
40+
```
41+
zenrows batch retry-failed <id>
42+
```
43+
44+
## Explain
45+
46+
```
47+
zenrows workflow explain price-monitoring
48+
```
49+
50+
Each step declares its capability; the toolkit refuses honestly when a required
51+
primitive is not available yet (`ASSET_REQUIRES_CAPABILITY`). Batch is beta —
52+
`estimate` runs locally today, the cloud steps need beta access.

0 commit comments

Comments
 (0)