Download TasteThreads on iOS: https://apps.apple.com/ca/app/tastethreads/id6755961756


Inspiration

We built TasteThreads to showcase what happens when Yelp's new conversational + agentic APIs become the brain of a group-planning app. The inspiration came from watching friends struggle with the messy "copy Yelp link → argue → open OpenTable" dance every time they wanted to plan a group dinner. We saw an opportunity to replace that friction with something conversational, verifiable, and instantly actionable.

Inspired by ChatGPT's group chat beta, we wanted to create an AI agent that feels like another teammate in the room—someone who understands context, remembers preferences, and can actually book reservations without leaving the conversation. Yelp's new AI APIs made this possible: instead of sprinkling recommendations on top of static feeds, we could route every natural-language message through Yelp AI Chat, read structured replies, and chain reservation actions seamlessly.

What it does

TasteThreads is a group-first dining planner powered by Yelp AI's conversational + agentic APIs. Here's what makes it special:

🤖 AI-Native Collaboration: Tess (our GPT-5.1 orchestrator) automatically replies when users tag @ai, @tess, or @yelp, and also jumps in after every five human-only messages to keep the flow unblocked—just like ChatGPT's group feature, but tuned for dining crews.

🗺️ Map-Centric Interface: Every Tess recommendation carries the original Yelp business payload. The iOS app drops markers onto MapKit with layered styling—AI suggestions get sparkle auras, itinerary commitments get bold pins with time labels, and saved spots get heart overlays.

📅 End-to-End Reservations: When Tess detects reservation intent, she chains openings → holds → reservations via Yelp's APIs, sending intermediate state back to the chat in under 10 seconds. Users stay inside the same thread while the AI negotiates availability directly with Yelp.

🎯 Taste Graph Context: Each user has a personalized Taste Graph built from saved places, AI discoveries, location, and preferences. Tess references individual taste profiles when making group suggestions, leading to faster consensus.

⚡ Real-Time Sync: Redis-backed WebSockets keep humans in sync (<100ms latency), while Tess streams responses via Server-Sent Events so users see "Tess is typing..." within ~500ms even when full answers take 2–5 seconds.

How we built it

Backend Architecture:

  • FastAPI orchestrator (api/routers/orchestrator.py) wraps Pydantic AI to inject per-room dependencies (user context, chat IDs, itinerary state)
  • Typed tools for each Yelp endpoint: yelp_ai_search (Chat API), yelp_reservation_openings/hold/book, yelp_fusion_business
  • PostgreSQL stores rooms, itinerary, and chat sessions with per-room chat_id continuity
  • Redis pub/sub enables horizontal scaling and instant message fan-out
  • Logfire tracing captures every tool call with latency, status, and chat_id for judge verification

Frontend Architecture:

  • SwiftUI iOS app with Combine publishers keeping chat, itinerary drawer, and map in sync
  • MapKit integration with custom markers showing Yelp business metadata
  • Firebase Auth for secure social login (email link or SMS)
  • WebSocket client connecting to /api/v1/rooms/ws/{room_id} for real-time updates

AI Orchestration:

agent = Agent(
    model="openai:gpt-5.1",
    deps=AgentDeps(chat_id=chat_session.chat_id, user_context=db_user.to_context()),
    tools=[yelp_ai_search, yelp_reservation_openings, yelp_reservation_hold, yelp_reservation_book]
)

The orchestrator maintains strict guardrails: retry budgets (max 10 per tool), structured error handling, and streaming UX so the chat never feels dead. Every turn includes the full chat transcript (summarized if >2k tokens) plus itinerary deltas so Tess speaks for the group, not just the last message.

Yelp API Integration:

  • /ai/chat/v2 for conversational discovery with per-room chat_id continuity
  • /v3/bookings/{id}/openings, /holds, /reservations for agentic booking flow
  • /v3/businesses/{id} for business enrichment (photos, hours, dietary tags)

Challenges we ran into

1. Maintaining Chat Continuity: Yelp's AI Chat API requires persistent chat_id per conversation, but we needed this per room (not per user). We solved this by storing chat_id in PostgreSQL's rooms table and injecting it into every orchestrator call, ensuring multi-turn understanding across all group members.

2. AI Latency vs UX: Yelp AI responses take 2–5 seconds, but humans expect sub-100ms chat sync. We decoupled WebSockets (for human messages) from the AI loop, streaming Tess responses via Server-Sent Events so users see typing indicators within ~500ms while humans keep chatting.

3. Reservation Flow Complexity: Booking isn't a single API call—it's a chain of openings → holds → reservations with intermediate state. We built typed Pydantic AI tools for each step, cached hold_id in Redis, and surfaced intermediate status ("Checking openings...", "Creating hold...") so the AI feels active even when Yelp takes longer.

4. GPT-5.1 Hallucinations: Small language models occasionally hallucinate tool usage. We treated Yelp as the execution engine and the LLM as a planner, restricting Tess to three tool families and handling all other behavior (room state, map updates) deterministically in FastAPI/SwiftUI.

5. Location Privacy: We needed location context for "find places near me" queries but wanted to protect user privacy. We rounded coordinates to ~100m precision, only included them in Yelp API calls when needed, and never stored exact locations in our database.

Accomplishments that we're proud of

Deep Yelp API Integration: Every recommendation traces back to real Yelp API calls—no made-up content. Judges can open Logfire and see exactly how Tess reached each decision, with spans capturing latency, chat_id, and reservation status.

<2% Tool Error Rate: Despite GPT-5.1's occasional hallucinations, our orchestration layer keeps tool retries under 2% through structured error handling and retry budgets.

Sub-100ms Human Message Sync: Redis pub/sub + WebSockets deliver human messages in 40–80ms, keeping the chat feeling instant even when Tess is processing.

End-to-End Reservation Flow: Complete openings → holds → reservations chain working in under 10 seconds, with graceful error handling when Yelp returns NO_AVAILABILITY.

Map-Centric Collaboration: Late arrivals can glance at the map and see the entire decision history—every marker links back to Yelp metadata we received, verified by judges.

Taste Graph Personalization: Tess references individual taste profiles ("Ava loves izakayas under $$") when making group suggestions, leading to faster consensus than generic recommendations.

What we learned

Yelp AI APIs are powerful but opinionated: Chat responses are natural language with embedded metadata, reservations require multi-step action calls, and everything needs to stay inside Yelp's data boundary. We learned to treat Yelp as the execution engine and the LLM as a planner—this keeps the AI focused on decisions, not mutations.

Streaming UX matters: Users see "Tess is typing..." within ~500ms even when full answers take 2–5 seconds. This makes the AI feel responsive even when Yelp takes longer, and we deliberately expose intermediate status ("Checking openings...") so Tess feels active.

Context is everything: Feeding Tess the entire chat transcript + itinerary context on every turn makes her speak for the group, not just the last message. The Taste Graph adds another layer—personalized preferences help Tess suggest compromises that actually work.

Observability enables trust: Logfire traces let judges verify every Yelp API call's provenance. This transparency was crucial for the hackathon—we can show exactly how Tess reached each recommendation or reservation, with latency and status clearly logged.

Privacy-preserving location: Rounding coordinates to ~100m precision provides useful proximity context without exact tracking. Users can revoke location access anytime, and we never store exact coordinates—only approximate values passed to Yelp's APIs.

What's next for TasteThreads - Group Dining with Yelp AI

Production Deployment: We're working toward full Yelp Reservations partner access (currently using YELP_RESERVATIONS_TEST_MODE=true for deterministic test responses). Once provisioned, the same tools will hit live endpoints with no code changes.

Enhanced Taste Graph: We want to add more preference signals—dietary restrictions, cuisine dislikes, price sensitivity—and use them to improve group consensus. The persona agent already generates nicknames and bios; we'll expand this to capture nuanced preferences.

Group Voting Features: Add in-chat voting on suggestions, with Tess summarizing consensus and highlighting popular choices. This would make TasteThreads even more collaborative.

WhatsApp Integration: We've already built a WhatsApp router (api/routers/whatsapp.py) for broader accessibility. Next step is connecting it to the orchestrator so users can plan group dinners without installing an iOS app.

Performance Optimizations: We're exploring caching strategies for Yelp Fusion metadata and optimizing the chat transcript summarization (currently triggers at >2k tokens) to reduce latency further.

Multi-Language Support: Yelp's AI Chat API supports multiple languages, and we want to enable Tess to respond in the user's preferred language based on their device settings.

TasteThreads proves that a single, well-instrumented agent plus Yelp's APIs can replace the messy "copy Yelp link → argue → open OpenTable" dance with something conversational, verifiable, and instantly actionable. We're excited to see where this goes next!


Try TasteThreads on iOS: https://apps.apple.com/ca/app/tastethreads/id6755961756

Built With

Share this project:

Updates