TRAVEL THREADS

2 Squirrels AI

Technology Stack

Multi-agent travel planning assistant powered by LangGraph state machines, Google Gemini, and web scraping via BrightData MCP. Features intelligent flight and hotel search with automated email reporting.

LLM Google Gemini 2.0
Orchestration LangGraph
Backend FastAPI
Web Scraping BrightData MCP
Email SendGrid

Workflow 1: LangGraph Travel Agent State Machine

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#C17852', 'primaryTextColor': '#F0F6FC', 'primaryBorderColor': '#4A5E32', 'lineColor': '#E6C98F', 'secondaryColor': '#161B22', 'tertiaryColor': '#0D1117', 'background': '#0D1117', 'mainBkg': '#161B22', 'nodeBorder': '#4A5E32', 'clusterBkg': '#161B22', 'clusterBorder': '#4A5E32', 'titleColor': '#E6C98F', 'edgeLabelBackground': '#161B22'}}}%%
flowchart TB
    subgraph Input["📥 USER REQUEST"]
        REQ[/"🗺️ Travel Request
Origin, Destination, Dates"/] end subgraph StateGraph["🔄 LANGGRAPH STATE MACHINE"] direction TB STATE[("📊 TravelAgentState
Shared Memory")] subgraph Nodes["Graph Nodes"] N1["✈️ find_flights"] N2["🏨 find_hotels"] N3["📧 send_email"] end subgraph Edges["Conditional Edges"] E1{"flights_searched?"} E2{"hotels_searched?"} end end subgraph Checkpointing["💾 PERSISTENCE"] MEM["🧠 MemorySaver
Thread Checkpoints"] end subgraph Output["📤 RESULTS"] END1(("🏁 END")) end REQ --> STATE STATE --> N1 N1 --> E1 E1 -->|"Yes"| N2 E1 -->|"No + Error"| N3 N2 --> E2 E2 -->|"Yes"| N3 E2 -->|"Error"| END1 N3 --> END1 N1 -.-> MEM N2 -.-> MEM N3 -.-> MEM

State Management: LangGraph maintains TravelAgentState across nodes, enabling conditional routing based on search completion flags (flights_searched, hotels_searched). MemorySaver provides thread-safe checkpointing.

Workflow 2: Flight Search ReAct Agent

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#C17852', 'primaryTextColor': '#F0F6FC', 'primaryBorderColor': '#4A5E32', 'lineColor': '#E6C98F', 'secondaryColor': '#161B22', 'tertiaryColor': '#0D1117', 'background': '#0D1117', 'mainBkg': '#161B22', 'nodeBorder': '#4A5E32', 'clusterBkg': '#161B22', 'clusterBorder': '#4A5E32', 'titleColor': '#E6C98F', 'edgeLabelBackground': '#161B22'}}}%%
flowchart TB
    subgraph Input["📥 SEARCH PARAMS"]
        P1["🛫 Origin"]
        P2["🛬 Destination"]
        P3["📅 Dates"]
        P4["👥 Travelers"]
    end

    subgraph ParamExtraction["🔍 PARAM EXTRACTION"]
        LLM1["🧠 Gemini LLM
Natural Language → Structured"] EXTRACT["📋 Extract:
Airport Codes, Dates, Count"] end subgraph MCPClient["🌐 BRIGHTDATA MCP CLIENT"] CONFIG["⚙️ MCP Server Config
API Token, Zones"] ADAPTER["🔌 LangChain Adapter"] TOOLS["🛠️ Scraping Tools
search_engine, scrape_as_markdown"] end subgraph ReActAgent["🤖 REACT AGENT"] AGENT["🎯 create_react_agent()
Gemini + MCP Tools"] SEARCH["🔎 Search Sites:
Google Flights, Expedia, Kayak"] RAW["📄 Raw Results"] end subgraph Structuring["📊 RESULT STRUCTURING"] PROMPT["📝 Structure Prompt"] STRUCT_LLM["🧠 with_structured_output()"] FLIGHT_OBJ["✈️ FlightSearchResults
Pydantic Model"] end subgraph Output["📤 STATE UPDATE"] FLIGHTS[("✈️ flights: List[FlightResult]")] FLAG["🚩 flights_searched: True"] end P1 & P2 & P3 & P4 --> LLM1 LLM1 --> EXTRACT EXTRACT --> CONFIG CONFIG --> ADAPTER ADAPTER --> TOOLS TOOLS --> AGENT AGENT --> SEARCH SEARCH --> RAW RAW --> PROMPT PROMPT --> STRUCT_LLM STRUCT_LLM --> FLIGHT_OBJ FLIGHT_OBJ --> FLIGHTS FLIGHT_OBJ --> FLAG

Workflow 3: Hotel Search ReAct Agent

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#C17852', 'primaryTextColor': '#F0F6FC', 'primaryBorderColor': '#4A5E32', 'lineColor': '#E6C98F', 'secondaryColor': '#161B22', 'tertiaryColor': '#0D1117', 'background': '#0D1117', 'mainBkg': '#161B22', 'nodeBorder': '#4A5E32', 'clusterBkg': '#161B22', 'clusterBorder': '#4A5E32', 'titleColor': '#E6C98F', 'edgeLabelBackground': '#161B22'}}}%%
flowchart LR
    subgraph State["📊 FROM STATE"]
        DEST["📍 Destination"]
        DATES["📅 Check-in/out"]
        STARS["⭐ Star Rating"]
        BUDGET["💰 Budget"]
    end

    subgraph Calculation["🧮 PREPARATION"]
        NIGHTS["🌙 Calculate Nights"]
        FILTER["🔧 Build Filters"]
    end

    subgraph Agent["🤖 HOTEL REACT AGENT"]
        direction TB
        MCP["🌐 BrightData MCP"]
        SCRAPE["🔍 Scrape Hotel Sites:
Booking.com, Hotels.com"] EXTRACT["📋 Extract Data"] end subgraph Structuring["📊 STRUCTURING"] STRUCT["🧠 HotelSearchResults
Pydantic Model"] VALIDATE["✅ Validate Fields"] end subgraph Output["📤 STATE UPDATE"] HOTELS[("🏨 hotels: List[HotelResult]")] FLAG["🚩 hotels_searched: True"] end DEST & DATES --> NIGHTS STARS & BUDGET --> FILTER NIGHTS --> MCP FILTER --> MCP MCP --> SCRAPE SCRAPE --> EXTRACT EXTRACT --> STRUCT STRUCT --> VALIDATE VALIDATE --> HOTELS VALIDATE --> FLAG

Workflow 4: AI-Powered Email Report Generation

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#C17852', 'primaryTextColor': '#F0F6FC', 'primaryBorderColor': '#4A5E32', 'lineColor': '#E6C98F', 'secondaryColor': '#161B22', 'tertiaryColor': '#0D1117', 'background': '#0D1117', 'mainBkg': '#161B22', 'nodeBorder': '#4A5E32', 'clusterBkg': '#161B22', 'clusterBorder': '#4A5E32', 'titleColor': '#E6C98F', 'edgeLabelBackground': '#161B22'}}}%%
flowchart TB
    subgraph State["📊 AGGREGATE FROM STATE"]
        FLIGHTS["✈️ Flight Results"]
        HOTELS["🏨 Hotel Results"]
        PARAMS["🗺️ Trip Parameters"]
    end

    subgraph ContentBuild["📝 CONTENT BUILDING"]
        BUILD["🔧 _build_email_content()"]
        FORMAT["📋 Format Flight & Hotel
Details as Text"] end subgraph LLMGeneration["🧠 LLM HTML GENERATION"] PROMPT["📝 Email System Prompt:
Convert to Beautiful HTML"] CHAIN["⛓️ ChatPromptTemplate | LLM"] HTML["📄 Generated HTML Email"] end subgraph SendGrid["📧 SENDGRID DELIVERY"] MAIL["📬 Mail Object:
from, to, subject, html"] API["🌐 SendGrid API"] SEND["📤 sg.send()"] end subgraph Output["📤 STATE UPDATE"] SUCCESS["✅ email_sent: True"] STATUS["📊 email_status"] end FLIGHTS --> BUILD HOTELS --> BUILD PARAMS --> BUILD BUILD --> FORMAT FORMAT --> PROMPT PROMPT --> CHAIN CHAIN --> HTML HTML --> MAIL MAIL --> API API --> SEND SEND --> SUCCESS SEND --> STATUS

Workflow 5: Complete System Architecture

%%{init: {'theme': 'dark', 'themeVariables': { 'primaryColor': '#C17852', 'primaryTextColor': '#F0F6FC', 'primaryBorderColor': '#4A5E32', 'lineColor': '#E6C98F', 'secondaryColor': '#161B22', 'tertiaryColor': '#0D1117', 'background': '#0D1117', 'mainBkg': '#161B22', 'nodeBorder': '#4A5E32', 'clusterBkg': '#161B22', 'clusterBorder': '#4A5E32', 'titleColor': '#E6C98F', 'edgeLabelBackground': '#161B22'}}}%%
flowchart TB
    subgraph Frontend["🖥️ REACT FRONTEND"]
        UI["💻 Trip Planner UI"]
        WS["🔌 WebSocket Client"]
    end

    subgraph Backend["⚙️ FASTAPI BACKEND"]
        REST["🌐 POST /travel"]
        WSEND["🔌 WS /ws/thread_id"]
        DOCS["📚 /docs (Swagger)"]
    end

    subgraph LangGraph["🔄 LANGGRAPH ENGINE"]
        GRAPH["📊 StateGraph"]
        NODES["🔲 Nodes: flights, hotels, email"]
        MEMORY["💾 MemorySaver"]
    end

    subgraph Agents["🤖 REACT AGENTS"]
        FLIGHT_AGENT["✈️ Flight Agent"]
        HOTEL_AGENT["🏨 Hotel Agent"]
    end

    subgraph External["🌐 EXTERNAL SERVICES"]
        GEMINI["🧠 Google Gemini API"]
        BRIGHT["🔍 BrightData MCP"]
        SEND["📧 SendGrid API"]
    end

    subgraph DataSources["🌍 TRAVEL DATA SOURCES"]
        GF["Google Flights"]
        EXP["Expedia"]
        BOOK["Booking.com"]
        KAYAK["Kayak"]
    end

    UI <-->|"HTTP/WS"| REST
    UI <-->|"Real-time"| WSEND
    REST --> GRAPH
    GRAPH --> NODES
    NODES --> MEMORY
    NODES --> FLIGHT_AGENT
    NODES --> HOTEL_AGENT
    FLIGHT_AGENT --> GEMINI
    HOTEL_AGENT --> GEMINI
    FLIGHT_AGENT --> BRIGHT
    HOTEL_AGENT --> BRIGHT
    BRIGHT --> GF & EXP & KAYAK
    BRIGHT --> BOOK
    NODES --> SEND