1. Competitor price & stock watch (Loop over URLs, cost-tiered extraction)
Every Monday an analyst opens the same 60 competitor product pages one by one, copies the price and the in-stock flag into a spreadsheet, colours the cells that moved, and emails the sheet to category managers. By Wednesday the sheet is already stale, and half the 'price changes' are actually the same price shown with a different currency format.
Trigger: Webhook (scheduled — weekly/daily price sweep)
How the workflow runs
- Trigger
The sweep kicks off. A scheduled Webhook trigger starts the run with the watchlist reference. The watchlist itself (SKU → competitor URL) lives in your own system and is read via a Tool (MCP) node or posted in on the Webhook — there is no first-party 'price feed' connector.
- Loop
For each watched URL. A Loop node iterates the watchlist one URL at a time. This is the node that makes 60 URLs behave exactly like 600 — same flow, same per-item cost, no unbounded prompt.
- Parallel
Fan out the fetches. Inside the loop batch, a Parallel node fires independent `http_request` fetches concurrently — with a deliberate concurrency cap and delay so the sweep stays polite rather than hammering one host.
- Agent
Economy extractor reads the page. A cheap extractor agent turns one page's fetched HTML into strict JSON {price, currency, inStock, title, capturedAt}. It runs once per URL, so its model tier is the dominant cost lever in the entire workflow.
- Code
Normalise + diff. A Code node shapes the payload — joins each extraction back to last week's stored value and computes the delta — then a user-defined SpEL tool flags the ones that matter (see tools below).
- Condition
Ambiguous record?. A Condition node routes: a clean, confidently-parsed page goes straight to the report; a page where the extractor was unsure (bundle pricing, strike-through, missing currency) escalates to the premium arbiter — and only those.
- Agent
Premium arbiter, only on the hard ones. A stronger model resolves just the ambiguous handful: which of the three numbers on the page is the actual sell price, is that 'out of stock' or 'ships in 3 weeks'.
- Approval
Repricing is human-owned. An Approval node holds any proposed repricing action. The sweep is read-only by design; the moment its output would change YOUR price, a category manager signs it off.
- Output
Deliver the movement report. An Output node posts the changed-only digest to Slack or Email, with per-SKU old → new, the flag reason, and the source URL and capture timestamp for every single number.
Channels & connectors
- Webhook
- Slack
- Tool (MCP → your catalogue / watchlist store)
- Approval / HITL
Outcome
The whole watchlist is swept on a schedule and lands as a changed-only report with a source URL and timestamp on every figure — instead of a hand-built sheet that is stale before it is read.
Why it helps
The mechanism is substitution plus attribution: a Loop does the mechanical page-by-page reading the analyst was doing, and every number carries its source URL and capture time, so a disputed price is checkable rather than arguable. The analyst's remaining work is judging the flagged movements, not producing the sheet.
Build spec
2 agents — 1 economy extractor (runs once per URL via the Loop node) + 1 premium arbiter (runs only on the Condition node's ambiguous branch). Loop, Parallel, Code, Condition and Approval are workflow nodes, not agents. · Pattern: Loop (per URL) → economy extract → Code/SpEL diff → Condition escalates only ambiguous records → premium arbiter → human approves any repricing
System prompt (paste-ready)
You extract ONE product page into strict JSON: {price (number|null), currency (ISO code|null), inStock (true|false|null), title, promoText|null, confidence (0-1), ambiguityReason|null}. Read ONLY the content supplied to you — never guess a price, never carry a value over from a previous page, and never fill a field from general knowledge about the brand. If the page shows several numbers (was/now, bundle, EMI, per-unit) and you cannot be certain which is the single sell price, do NOT pick one: set confidence below 0.6 and describe the ambiguity — the workflow escalates it. If the fetch returned a block page, a consent wall or a login wall, return {blocked: true} and stop; do not attempt to work around it.Agent roles & model tiers
Page extractor (per URL) — Economy tier — this is the volume step; it runs once per watched URL, so this single choice sets the cost of the whole sweep
Turn one fetched page into schema-valid JSON. Nulls for anything not visibly present. Self-report low confidence rather than guessing between two numbers. Never work around a block/consent/login wall — report it.
Ambiguity arbiter (only the flagged minority) — Premium tier — justified precisely because it runs on a handful of records, not the whole list
Given one low-confidence extraction plus its page context, decide the single actual sell price and true availability, and explain the reasoning in one line. If it is still genuinely undecidable, return NEEDS_HUMAN — an honest escalation beats a confident wrong price.
MCP connectors
- Your catalogue / watchlist store (SKU ↔ competitor URL, last-known price) — via a Tool (MCP) node; no first-party connector
- Browser-automation MCP (Playwright-style, registered in the MCP registry) — OPTIONAL, only for pages that will not render without JS. VegaDūta ships no built-in browser; this is the mechanism when a plain fetch is not enough
- Slack / Email — the digest channel
Built-in tools
- http_request (built-in) — the primary fetch, rate-limited and honestly identified
- web_search (built-in) — to discover a moved/renamed product page rather than silently reporting it as delisted
- User-defined tool `price_drop_flag` (SpEL): input.newPrice < input.oldPrice * 0.9 ? 'ALERT' : 'IGNORE' — the category manager encodes THEIR OWN threshold (10% here) and can change it to 5% without a developer or a redeploy
- User-defined tool `stock_state` (SpEL): input.qty > 0 ? 'IN_STOCK' : (input.qty == 0 ? 'OUT_OF_STOCK' : 'UNKNOWN') — a field normaliser that makes three sites' three conventions comparable
- User-defined tool `tax_normalised_price` (SpEL): input.taxIncluded ? input.price : input.price * 1.18 — compares like with like across sites that quote pre- and post-tax
Guardrails
- robots.txt and the site's Terms of Service are respected — the watchlist only contains pages you are permitted to fetch, and a disallowed path is dropped from the sweep rather than fetched anyway
- Rate-limited and backed off: a capped concurrency in the Parallel node, a delay between requests to the same host, exponential backoff on 429/5xx, and an honest identifying user agent — the sweep must never be indistinguishable from an attack
- Public data only. No page behind a login you do not own, no bot-detection bypass, and CAPTCHAs are NEVER solved — a block page, consent wall or login wall ends that item as {blocked: true} and is reported, not worked around
- No personal data harvesting: product/price fields only. Seller names, reviewer names and any other individual's details are dropped at the Code node — this workflow never builds a profile of a person
- No credentials, ever: no agent types a password, card number or government ID anywhere in this flow. There is nothing to log into here; if a source ever requires auth it is handled by a secrets-managed integration under your own account, not by an agent typing into a box
- Read-only by construction. This sweep submits no form and clicks no irreversible control; any proposed repricing — the one action with consequences — is held by the Approval node for a category manager
- Every reported figure carries its source URL and capture timestamp; an extraction below the confidence floor is escalated or marked NEEDS_HUMAN, never quietly published as fact
- The SpEL user-defined tools are data-transform expressions over the tool's JSON input — no method calls, no constructors, no bean or type references, and no loop in the grammar. A threshold the analyst wrote themselves therefore cannot become an execution risk; it can only compute a value
Cost strategy
This is the clearest cost-tiering story in the guide. Cost = N × (economy extractor) + a small k × (premium arbiter), where k is the ambiguous minority, not N. Put the premium model on the per-page step and a 600-URL sweep is expensive for no benefit — the per-page job is mechanical field-lifting that an economy model does well. Keep the premium tier for the genuinely undecidable record (three prices on one page, EMI vs sell price) and you pay for reasoning exactly where reasoning exists. Cap the extractor's output tokens (the schema is small), run the Parallel batch for wall-clock speed — which changes latency, not per-item cost — and set a hard per-run budget so a site redesign that breaks parsing fails loudly instead of expensively.
Output & delivery
The Loop maps the economy extractor across the watchlist → a Code node joins to last week's values and the SpEL flags fire → the Condition node escalates only the ambiguous records to the premium arbiter → any repricing proposal waits at the Approval node → an Output node posts the changed-only digest to Slack or Email with old → new, flag reason, source URL and capture timestamp per SKU.