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.
%%{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.
%%{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
%%{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
%%{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
%%{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