135 lines
6.5 KiB
Markdown
135 lines
6.5 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.
|
||
|
||
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.
|
||
|
||
## 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
|
||
|
||
## 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 the execution engine. Convert its hardcoded logic into the typed request model and run the skill workflow instead.
|