From e2657f48507f233ed1c5d5b4b8b394c176633683 Mon Sep 17 00:00:00 2001 From: Stefano Fiorini Date: Mon, 30 Mar 2026 17:12:52 -0500 Subject: [PATCH] feat(flight-finder): implement milestone M3 - prompt migration and smoke test fixtures --- README.md | 1 + docs/README.md | 1 + .../examples/dfw-blq-2026-report-payload.json | 158 ++++++++++++++++++ .../examples/dfw-blq-2026-request.json | 74 ++++++++ 4 files changed, 234 insertions(+) create mode 100644 skills/flight-finder/examples/dfw-blq-2026-report-payload.json create mode 100644 skills/flight-finder/examples/dfw-blq-2026-request.json diff --git a/README.md b/README.md index 214e13f..0ae24cd 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ This repository contains practical OpenClaw skills and companion integrations. I | Skill | What it does | Path | |---|---|---| | `elevenlabs-stt` | Transcribe local audio files with ElevenLabs Speech-to-Text, with diarization, language hints, event tags, and JSON output. | `skills/elevenlabs-stt` | +| `flight-finder` | Collect structured flight-search inputs, run bounded multi-source travel searches, rank results in USD, and gate fixed-template PDF/email delivery through Luke’s sender path. | `skills/flight-finder` | | `gitea-api` | Interact with Gitea via REST API (repos, issues, PRs, releases, branches, user info). | `skills/gitea-api` | | `nordvpn-client` | Install, log in to, connect, disconnect, and verify NordVPN sessions across Linux CLI and macOS NordLynx/WireGuard backends. | `skills/nordvpn-client` | | `portainer` | Manage Portainer stacks via API (list, start/stop/restart, update, prune images). | `skills/portainer` | diff --git a/docs/README.md b/docs/README.md index dd370cd..d6c9309 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,6 +5,7 @@ This folder contains detailed docs for each skill in this repository. ## Skills - [`elevenlabs-stt`](elevenlabs-stt.md) — Local audio transcription through ElevenLabs Speech-to-Text +- [`flight-finder`](flight-finder.md) — Typed flight-search intake, bounded source orchestration, PDF report rendering, and Luke-sender email delivery - [`gitea-api`](gitea-api.md) — REST-based Gitea automation (no `tea` CLI required) - [`nordvpn-client`](nordvpn-client.md) — Cross-platform NordVPN install, login, connect, disconnect, and verification with Linux CLI and macOS NordLynx/WireGuard support - [`portainer`](portainer.md) — Portainer stack management (list, lifecycle, updates, image pruning) diff --git a/skills/flight-finder/examples/dfw-blq-2026-report-payload.json b/skills/flight-finder/examples/dfw-blq-2026-report-payload.json new file mode 100644 index 0000000..85cfbad --- /dev/null +++ b/skills/flight-finder/examples/dfw-blq-2026-report-payload.json @@ -0,0 +1,158 @@ +{ + "request": { + "tripName": "DFW ↔ BLQ flight report", + "legs": [ + { + "id": "outbound", + "origin": "DFW", + "destination": "BLQ", + "earliest": "2026-05-30", + "latest": "2026-06-07", + "label": "Outbound" + }, + { + "id": "return-pair", + "origin": "BLQ", + "destination": "DFW", + "relativeToLegId": "outbound", + "minDaysAfter": 6, + "maxDaysAfter": 10, + "label": "Return for 2 adults" + }, + { + "id": "return-solo", + "origin": "BLQ", + "destination": "DFW", + "earliest": "2026-06-28", + "latest": "2026-07-05", + "label": "Return for 1 adult" + } + ], + "passengerGroups": [ + { + "id": "pair", + "adults": 2, + "label": "2 adults traveling together" + }, + { + "id": "solo", + "adults": 1, + "label": "1 adult returning separately" + } + ], + "legAssignments": [ + { + "legId": "outbound", + "passengerGroupIds": ["pair", "solo"] + }, + { + "legId": "return-pair", + "passengerGroupIds": ["pair"] + }, + { + "legId": "return-solo", + "passengerGroupIds": ["solo"] + } + ], + "recipientEmail": "stefano@fiorinis.com", + "preferences": { + "preferOneStop": true, + "maxStops": 1, + "maxLayoverHours": 6, + "flexibleDates": true, + "excludeAirlines": ["Turkish Airlines"], + "excludeCountries": ["TR"], + "requireAirlineDirectCrossCheck": true, + "specialConstraints": [ + "Exclude itineraries operated by airlines based in Arab or Middle Eastern countries.", + "Exclude itineraries routing through airports in Arab or Middle Eastern countries.", + "Start from a fresh browser/session profile for this search." + ], + "geoPricingMarket": "Thailand", + "marketCountry": "TH", + "normalizeCurrencyTo": "USD" + } + }, + "sourceFindings": [ + { + "source": "kayak", + "status": "viable", + "checkedAt": "2026-03-30T21:00:00Z", + "notes": [ + "KAYAK returned multiple one-stop DFW -> BLQ options and exposed direct-booking hints for British Airways." + ] + }, + { + "source": "skyscanner", + "status": "viable", + "checkedAt": "2026-03-30T21:05:00Z", + "notes": [ + "Skyscanner returned one-stop and multi-stop DFW -> BLQ results with total USD pricing." + ] + }, + { + "source": "expedia", + "status": "viable", + "checkedAt": "2026-03-30T21:10:00Z", + "notes": [ + "Expedia returned one-way DFW -> BLQ options with clear per-traveler pricing." + ] + }, + { + "source": "airline-direct", + "status": "degraded", + "checkedAt": "2026-03-30T21:15:00Z", + "notes": [ + "United's direct booking shell loaded with the route/date context but failed to complete the search." + ] + } + ], + "quotes": [ + { + "id": "kayak-outbound-ba", + "source": "kayak", + "legId": "outbound", + "passengerGroupIds": ["pair", "solo"], + "bookingLink": "https://www.kayak.com/flights/DFW-BLQ/2026-05-30?adults=3&sort=bestflight_a&fs=stops=-2", + "itinerarySummary": "British Airways via London Heathrow", + "airlineName": "British Airways", + "departureTimeLocal": "10:59 PM", + "arrivalTimeLocal": "11:45 PM +1", + "stopsText": "1 stop", + "layoverText": "6h 15m in London Heathrow", + "totalDurationText": "17h 46m", + "totalPriceUsd": 2631, + "displayPriceUsd": "$2,631 total", + "directBookingUrl": "https://www.britishairways.com/", + "crossCheckStatus": "failed", + "notes": [ + "Observed on KAYAK at $877 per traveler for 3 adults.", + "Airline-direct cross-check remains degraded in this implementation pass." + ] + } + ], + "rankedOptions": [ + { + "id": "primary-outbound", + "title": "Best observed outbound baseline", + "quoteIds": ["kayak-outbound-ba"], + "totalPriceUsd": 2631, + "rationale": "Lowest observed one-stop fare in the bounded spike while still meeting the layover constraint." + } + ], + "executiveSummary": [ + "The bounded implementation-pass smoke test produced a viable report payload from real DFW -> BLQ search evidence.", + "KAYAK, Skyscanner, and Expedia all returned usable results on this machine.", + "Direct-airline cross-checking is currently best-effort and should be reported honestly when it fails." + ], + "reportWarnings": [ + "This smoke-test payload captures the bounded implementation-pass workflow, not the full old prompt's multi-leg optimization." + ], + "degradedReasons": [ + "Airline direct-booking cross-check is still degraded and must be treated as best-effort in this pass." + ], + "comparisonCurrency": "USD", + "marketCountryUsed": "TH", + "lastCompletedPhase": "ranking", + "generatedAt": "2026-03-30T21:20:00Z" +} diff --git a/skills/flight-finder/examples/dfw-blq-2026-request.json b/skills/flight-finder/examples/dfw-blq-2026-request.json new file mode 100644 index 0000000..4967ef1 --- /dev/null +++ b/skills/flight-finder/examples/dfw-blq-2026-request.json @@ -0,0 +1,74 @@ +{ + "tripName": "DFW ↔ BLQ flight report", + "legs": [ + { + "id": "outbound", + "origin": "DFW", + "destination": "BLQ", + "earliest": "2026-05-30", + "latest": "2026-06-07", + "label": "Outbound" + }, + { + "id": "return-pair", + "origin": "BLQ", + "destination": "DFW", + "relativeToLegId": "outbound", + "minDaysAfter": 6, + "maxDaysAfter": 10, + "label": "Return for 2 adults" + }, + { + "id": "return-solo", + "origin": "BLQ", + "destination": "DFW", + "earliest": "2026-06-28", + "latest": "2026-07-05", + "label": "Return for 1 adult" + } + ], + "passengerGroups": [ + { + "id": "pair", + "adults": 2, + "label": "2 adults traveling together" + }, + { + "id": "solo", + "adults": 1, + "label": "1 adult returning separately" + } + ], + "legAssignments": [ + { + "legId": "outbound", + "passengerGroupIds": ["pair", "solo"] + }, + { + "legId": "return-pair", + "passengerGroupIds": ["pair"] + }, + { + "legId": "return-solo", + "passengerGroupIds": ["solo"] + } + ], + "recipientEmail": "stefano@fiorinis.com", + "preferences": { + "preferOneStop": true, + "maxStops": 1, + "maxLayoverHours": 6, + "flexibleDates": true, + "excludeAirlines": ["Turkish Airlines"], + "excludeCountries": ["TR"], + "requireAirlineDirectCrossCheck": true, + "specialConstraints": [ + "Exclude itineraries operated by airlines based in Arab or Middle Eastern countries.", + "Exclude itineraries routing through airports in Arab or Middle Eastern countries.", + "Start from a fresh browser/session profile for this search." + ], + "geoPricingMarket": "Thailand", + "marketCountry": "TH", + "normalizeCurrencyTo": "USD" + } +}