160 lines
8.2 KiB
Markdown
160 lines
8.2 KiB
Markdown
---
|
||
name: flight-finder
|
||
description: Use when a user wants a flight-search report with explicit trip constraints, ranked options, and PDF/email delivery. Prefer when the request may include split returns, flexible dates, passenger groups, market-localized pricing, or a WhatsApp-safe workflow that should keep going after status nudges instead of hanging behind a long inline prompt.
|
||
---
|
||
|
||
# Flight Finder
|
||
|
||
Use this skill instead of the old `docs/prompts/dfw-blq-2026.md` prompt when the user wants a flight-search report.
|
||
|
||
The deliverable target is always a PDF report plus email delivery when the report is complete.
|
||
|
||
PDF output rule:
|
||
|
||
- Render aggregator booking links for every quoted fare.
|
||
- Render direct-airline booking links when they were actually captured.
|
||
- If a direct-airline link was not captured for a quote, say so explicitly in the report instead of implying one exists.
|
||
|
||
Freshness rule:
|
||
|
||
- Never reuse cached flight-search captures, prior same-day report payloads, earlier workspace artifacts, or previously rendered PDFs as the primary evidence for a new run.
|
||
- Every flight-finder run must execute a fresh bounded search before ranking, PDF render, or email delivery.
|
||
- If a fresh search cannot be completed, say so clearly and stop with a degraded/incomplete outcome instead of silently reusing old captures.
|
||
|
||
## Inputs
|
||
|
||
Accept either:
|
||
|
||
- a natural-language trip request
|
||
- a structured helper payload
|
||
- a route plus partial constraints that still need follow-up questions
|
||
|
||
Collect these explicitly when missing:
|
||
|
||
- origin and destination
|
||
- outbound date window
|
||
- whether there are one or more return legs
|
||
- passenger groups
|
||
- which passenger groups travel on which legs
|
||
- flexibility rules
|
||
- cabin / stop / layover preferences when relevant
|
||
- exclusions such as airlines, countries, or airports when relevant
|
||
- recipient email before final render/send
|
||
|
||
Optional explicit input:
|
||
|
||
- `marketCountry`
|
||
- if present, it must be a validated ISO 3166-1 alpha-2 uppercase country code such as `TH` or `DE`
|
||
- if present, it activates the VPN / market-localized search path for the bounded search phase only
|
||
- if absent, do not change VPN in this implementation pass
|
||
|
||
Do not silently infer or reuse missing trip-shape details from earlier runs just because the route looks similar.
|
||
If the user already explicitly said where to email the finished PDF, that counts as delivery authorization once the report is complete. Do not ask for a second send confirmation unless the destination changed or the user sounded uncertain.
|
||
|
||
## Core workflow
|
||
|
||
1. Normalize the trip request into typed legs, passenger groups, assignments, and preferences.
|
||
2. Ask targeted follow-up questions for missing search-critical inputs.
|
||
3. Run the bounded search phase across the configured travel sources.
|
||
4. Rank the viable combinations in USD.
|
||
5. Assemble the final report payload.
|
||
6. Render the PDF.
|
||
7. Send the email from Luke to the user-specified recipient.
|
||
|
||
Completion rule:
|
||
|
||
- A partial source result is not completion.
|
||
- A partial helper result is not completion.
|
||
- The workflow is complete only when the final report payload exists, the PDF is rendered, the email was sent, and any VPN cleanup required by the run has been attempted.
|
||
- An interim commentary/status line is not completion.
|
||
- For isolated cron-style runs, do not leave the run with only a phase-update summary. If PDF render or email send did not happen, the terminal result must say so explicitly as a failed or incomplete outcome.
|
||
|
||
## WhatsApp-safe behavior
|
||
|
||
Follow the same operational style as `property-assessor`:
|
||
|
||
- missing required input should trigger a direct question, not an invented assumption
|
||
- `update?`, `status?`, `and?`, and similar nudges mean “report status and keep going”
|
||
- a silent helper/source path is a failed path and should be abandoned quickly
|
||
- previously saved workspace captures are not a fallback; they are stale evidence and must not be reused for a new report
|
||
- keep progress state by phase so a dropped session can resume or at least report the last completed phase
|
||
- do not start email-tool exploration before the report payload is complete and the PDF is ready to render
|
||
- if PDF render fails, return the completed report summary in chat and report delivery failure separately
|
||
- if email send fails after render, say so clearly and keep the rendered PDF path
|
||
|
||
## Long-running command rule
|
||
|
||
- Do not fire a long-running local command and then abandon it.
|
||
- If an `exec` call returns a running session/process handle instead of a completed result, immediately follow it with the relevant process polling/log calls until the command finishes, fails, or times out.
|
||
- Treat VPN connect, fresh search sweeps, PDF render, and Gmail send as critical-path commands. They must be observed to completion; do not assume they succeeded just because the process started.
|
||
- If a critical-path command cannot be observed to completion, stop claiming progress and report the run as incomplete.
|
||
|
||
## Isolated cron rule
|
||
|
||
- In isolated cron runs, success means all of the following are true:
|
||
- fresh search artifacts exist for the current run
|
||
- final `report-payload.json` exists for the current run
|
||
- PDF render completed
|
||
- Gmail send completed to the requested recipient
|
||
- If the model/provider times out, the VPN step flakes, or the run ends before those artifacts exist, report a failure/incomplete outcome rather than an `ok`-sounding completion summary.
|
||
- Do not end an isolated cron run on the VPN/connect phase alone.
|
||
|
||
## Search-source contract
|
||
|
||
Use the proven travel-source order from the local viability findings:
|
||
|
||
1. KAYAK
|
||
2. Skyscanner
|
||
3. Expedia
|
||
4. airline direct-booking cross-check
|
||
|
||
Rules:
|
||
|
||
- treat source viability as evidence-based, not assumed
|
||
- if a source is blocked or degraded, continue with the remaining sources and record the issue in the report
|
||
- keep the bounded search phase observable with concise updates
|
||
- normalize compared prices to USD before ranking
|
||
- do not claim market-localized pricing succeeded unless VPN connect and post-connect verification succeeded
|
||
- do not inspect prior `workspace/reports` flight artifacts as reusable search input for a new run
|
||
|
||
## VPN / market-country rules
|
||
|
||
- Use VPN only when `marketCountry` is explicitly provided in the typed request for this implementation pass.
|
||
- Connect VPN only for the bounded search phase.
|
||
- Bounded search phase means: from first travel-site navigation until the last search-result capture for the report.
|
||
- If VPN connect or verification fails within the configured timeout, continue on the default market and mark the report as degraded.
|
||
- Disconnect VPN immediately after the bounded search phase, before ranking/render/delivery.
|
||
- On rollback or failure, attempt disconnect immediately.
|
||
|
||
## Delivery rules
|
||
|
||
- Sender must be Luke: `luke@fiorinis.com`
|
||
- Delivery path must be Luke’s wrapper:
|
||
- `zsh ~/.openclaw/workspace/bin/gog-luke gmail send --to "<target>" --subject "<subject>" --body "<body>" --attach "<pdf-path>"`
|
||
- If recipient email is missing, ask for it before the render/send phase.
|
||
- If the user already provided the recipient email, do not ask for a redundant “send it” confirmation.
|
||
|
||
## Helper commands
|
||
|
||
From `~/.openclaw/workspace/skills/flight-finder/` or the repo mirror copy:
|
||
|
||
```bash
|
||
npm run normalize-request -- --legacy-dfw-blq
|
||
npm run normalize-request -- --input "<request.json>"
|
||
npm run report-status -- --input "<report-payload.json>"
|
||
npm run render-report -- --input "<report-payload.json>" --output "<report.pdf>"
|
||
npm run delivery-plan -- --to "<recipient@example.com>" --subject "<subject>" --body "<body>" --attach "<report.pdf>"
|
||
```
|
||
|
||
Rules:
|
||
|
||
- `normalize-request` should report missing search inputs separately from delivery-only email gaps
|
||
- `report-status` should expose whether the run is ready to search, ready for a chat summary, ready to render a PDF, or ready to email
|
||
- `render-report` must reject incomplete report payloads
|
||
- `render-report` must reject payloads that are not explicitly marked as the output of a fresh search run
|
||
- `delivery-plan` must stay on the Luke sender path and must not silently fall back to another sender
|
||
|
||
## Prompt migration rule
|
||
|
||
The old DFW↔BLQ prompt is legacy input only. Do not treat it as freeform execution prose. Its file should contain a literal `use flight finder skill with the following json payload` request so manual runs and scheduled runs stay aligned.
|