Skip to content

feat(vrbo): add VRBO vacation-rental search skill via Patchright#19

Open
fyodoriv wants to merge 1 commit into
borski:mainfrom
fyodoriv:add-vrbo-support
Open

feat(vrbo): add VRBO vacation-rental search skill via Patchright#19
fyodoriv wants to merge 1 commit into
borski:mainfrom
fyodoriv:add-vrbo-support

Conversation

@fyodoriv
Copy link
Copy Markdown

@fyodoriv fyodoriv commented May 29, 2026

Why this is needed

The toolkit has hotel and Airbnb coverage but no VRBO source. VRBO carries professionally-managed condos and cabins (especially in resort/mountain towns) that often aren't on Airbnb, so for whole-home and group stays there's a real gap. VRBO can't be added the easy way: it sits behind Akamai Bot Manager — plain HTTP, @playwright/mcp, and curl all get a 429 Too Many Requests ("Provisioned request rate has been exceeded"), and there's no public API.

This adds a vrbo skill that beats that wall the same way the existing southwest / chase-travel / amex-travel skills beat theirs: Patchright (undetected Playwright fork), run headed, with a homepage warm-up + retry. No login required — VRBO search results are public.

What's included

  • plugins/travel-hacking-toolkit/skills/vrbo/SKILL.md, scripts/search_vrbo.py (Patchright search + 3-layer extraction: embedded state blob → data-stid lodging cards → anchor fallback), Dockerfile + scripts/entrypoint.sh (headed via Xvfb), mirroring the existing portal-skill layout.
  • SERP price parsing — splits VRBO's price string into pricePerNight + priceTotal with a priceIncludesTaxes flag (the SERP total includes taxes & fees — verified against live data).
  • Robustness — detects both Akamai flavours (hard 429 + soft interstitial) so a challenge surfaces as a clear error instead of a silent empty result; scrolls + polls for lazy-rendered cards.
  • compare-hotels — VRBO wired into the source table + workflow alongside the Airbnb MCP.
  • Unit tests — 17 stdlib unittest cases covering the pure logic (URL building, block detection, price parsing, skeleton filter, enrichment). No browser/network.

Compliance with CONTRIBUTING.md

  • Skill lives under plugins/travel-hacking-toolkit/skills/vrbo/ with the required frontmatter (category, summary, api_key) and no colons / quotes / backticks in values.
  • Row added to scripts/skill-meta.tsv; README.md + llms.txt regenerated via scripts/gen-skill-tables.sh (not hand-edited).
  • bash scripts/smoke-test.sh --quick passes every check applicable to this change. The only two red checks are pre-existing on main, not introduced here — stale data files (points-valuations / sweet-spots / transfer-bonuses past their TTL) and a timeout: command not found shim that only fails on macOS (Ubuntu CI has timeout). Both reproduce identically on a clean main checkout with no VRBO changes.

Test results

$ python3 -m unittest discover -s skills/vrbo/tests -v
...
Ran 17 tests in 0.000s

OK

Writing the tests caught a real bug — a missing import re the price-parser needed but that the one successful live run had never exercised (later runs were blocked before reaching it). Fixed in this PR.

Manual verification (browser path)

The browser-driven path can't be unit-tested without a live residential connection (Akamai IP-rate-limits datacenter / CI / VPN IPs). Verified manually:

python3 skills/vrbo/scripts/search_vrbo.py \
  --dest "Canmore, Alberta, Canada" --checkin 2026-06-26 --checkout 2026-07-02 \
  --adults 3 --json

returned real Canmore inventory with names, all-in prices (incl. taxes & fees), and booking URLs. The SKILL.md "Known fragility" section documents the IP-rate-limit reality.

Notes for the maintainer

  • No Docker image is published. The Dockerfile is included so the skill matches the southwest/amex-travel pattern and can be built locally, but I have no ghcr.io push access — so docker_image is intentionally left out of the frontmatter and setup.sh, keeping the smoke-test image-existence check green. If you want to publish ghcr.io/borski/vrbo, I'm happy to add the frontmatter + setup entries in a follow-up.
  • Unit tests are stdlib-only (no new dependencies) and run under both unittest and pytest. They're additive — the repo's smoke-test remains the CI gate; I did not add a workflow.

🤖 Written by an agent, not Fyodor. Ping me if this looks off.

VRBO sits behind Akamai Bot Manager (429 to plain HTTP, @playwright/mcp, and
curl). Add a Patchright-driven skill mirroring the southwest/amex-travel
pattern: headed browser, homepage warm-up + retry, hard-429 + soft-interstitial
detection, lazy-render scroll/poll, and SERP price parsing (per-night + all-in
total, taxes-included flag). No login required (public search results).

Complements the Airbnb MCP for whole-home and group stays — professionally
managed mountain-town condos are often on VRBO but not Airbnb. Wired into
compare-hotels (source table + workflow).

Follows CONTRIBUTING: skill under plugins/.../skills/vrbo with required
frontmatter (category/summary/api_key, no colons/quotes/backticks), row added
to scripts/skill-meta.tsv, README + llms.txt regenerated via gen-skill-tables.
scripts/smoke-test.sh --quick passes all checks applicable to this change.

Tests: 17 stdlib-unittest cases cover the pure logic (URL build, block
detection, price parse, skeleton filter, enrichment) — no browser/network.
Writing them caught a missing 'import re' the one successful live run never
exercised. Run: python3 -m unittest discover -s skills/vrbo/tests

Proven against live Canmore inventory; Akamai is IP-rate-limited so the browser
path runs best from a residential connection (documented in SKILL.md).
@fyodoriv fyodoriv force-pushed the add-vrbo-support branch from 8714505 to 3e06d35 Compare May 29, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant