Skyguy - Your Travel Buddy
Inspiration
Trip planning is a tab nightmare. Flights here, hotels there, a spreadsheet to track which combo fits the budget. We wanted to kill that completely. Describe your trip in one message, get a real bookable plan back. That's Skyguy.
What it does
Skyguy is a conversational travel agent that handles the full pre-booking flow in one shot:
- One sentence, full trip. "5 days in Tokyo in April for two, around €3k" returns flights, hotel, and a rental car as one priced bundle.
- Parallel search, unified reasoning. Flights, hotels, and cars are fetched together. Swap the hotel neighborhood and it knows the car pickup might need to move too.
- Persistent preferences. Cabin class, hotel stars, bags, transmission, avoided airlines. Set once, applied everywhere.
- Saved trips and conversations. Pick up last week's half-planned trip exactly where you left it.
- Voice input for planning on the go.
How we built it
- Frontend: React 18 + Vite + TypeScript, Fully themed with CSS variables, no hardcoded colors. Built with partially coding assistant for frontend.
- Backend: Supabase for auth, Postgres, RLS, and edge functions. Conversations, messages, favorites, and travel preferences all live in typed tables with row-level security.
- Travel data: Skyscanner API handles flight search. Hotels and car rentals run through a seeded catalog with real-shaped availability data so results always feel complete.
- AI orchestration: A
travel-chatedge function with tool-calling across flights, hotels, and cars. The model decides which tools to call, we execute them server-side, then stream a structured bundle back to the chat. - Voice: A
transcribe-audioedge function handles speech-to-text in the composer.
Challenges
- Bundling async results. Flights, hotels, and cars return with different shapes and currencies. Collapsing that into one trip card with a single total was harder than expected.
- Currency handling. Every supplier returns its own currency. We convert on the fly to the user's preferred one.
- RLS without recursion. Roles in a separate table with a
SECURITY DEFINERhas_role()function keeps policies clean.
What we're proud of
- A full Tokyo trip (flights + hotel + car, €2,765) generated from a single chat message.
- Zero hardcoded colors anywhere. Light and dark mode just works.
- Typed, CORS-strict edge functions with graceful fallbacks.
- Preferences that actually change results. Set "direct flights only" once and every future search respects it.
What's next
Real bookings, group trip planning, price drop alerts, day-by-day itineraries, and more transport types like trains, ferries, and transfers. All in the same bundle.
Built With
- mistral
- react
- supabase
- typescript
Log in or sign up for Devpost to join the conversation.