Travel / app.py
SatyamSinghal's picture
Upload 3 files
8a40016 verified
import streamlit as st
import os
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process
from crewai import LLM
import litellm
from crewai_tools import SerperDevTool
from typing import Any, Dict
import sys
from datetime import datetime
from queue import Queue
import threading
from referral_codes import validate_referral_code
# Page config
st.set_page_config(
page_title="Travel Planning Agent",
page_icon="🌍",
layout="wide"
)
# Load environment variables
load_dotenv()
def initialize_llm():
# Get API key
api_key = os.getenv("GEMINI_API_KEY")
if not api_key:
raise ValueError("GEMINI_API_KEY not found in environment variables")
st.write(f"Debug: API Key found: {api_key[:10]}...")
# Initialize Gemini LLM with API Key
return LLM(
model="gemini/gemini-1.5-pro-latest",
api_key=api_key,
temperature=0.7
)
def create_travel_agent(llm):
return Agent(
role="Elite AI Travel Strategist",
goal=(
"Design the most optimized, personalized, and budget-conscious travel plans based on the user's unique preferences, "
"including origin, destination, budget, travel dates, group size, preferred activities, and travel style. "
"Leverage cutting-edge AI with real-time data from flights, hotels, transport services, local attractions, and events "
"to craft seamless, time-efficient, and experience-rich itineraries. "
"Ensure dynamic adaptability to handle disruptions, availability changes, and user modifications, creating a hassle-free travel experience."
),
backstory=(
"I am an AI-powered **Master Travel Architect** with deep expertise in curating extraordinary journeys tailored to individual tastes, "
"whether for solo travelers, families, business professionals, or adventure seekers. "
"With an extensive knowledge of global destinations, cultural insights, seasonal trends, and logistical intricacies, "
"I meticulously craft itineraries that blend adventure, relaxation, and cultural immersion. "
"By integrating real-time APIs for flights, accommodations, activities, and local events, "
"I ensure each recommendation is accurate, cost-effective, and aligned with the traveler’s needs."
),
personality=(
"Hyper-intelligent, intuitive, and proactive. I am a meticulous planner with a deep understanding of travel logistics, "
"capable of anticipating potential issues before they arise. "
"I balance **comfort, adventure, and budget efficiency**, ensuring every itinerary is customized for a truly unique experience. "
"I dynamically adjust plans based on live travel updates, offer personalized recommendations based on user preferences, "
"and present a seamless blend of structured scheduling with flexibility. "
"Whether it’s a luxury escape, an immersive cultural journey, or an action-packed adventure, I craft the **perfect** travel blueprint."
),
tools=[SerperDevTool()],
allow_delegation=True,
humaninput=True,
llm=llm,
verbose=True
)
def create_travel_task(agent, user_inputs):
return Task(
description=f"""
You are an **AI Travel Planner** responsible for crafting a **personalized, budget-conscious, and time-efficient travel plan** using advanced tools for data retrieval, analysis, and real-time updates.
The user has provided the following details:
- **Origin:** {user_inputs['origin']}
- **Destination:** {user_inputs['destination']}
- **Budget:** {user_inputs['budget']} (in local currency)
- **Preferred Activities:** {user_inputs['activities']}
- **Transport Preference:** {user_inputs['transport']}
- **Time Available:** {user_inputs['time']}
## **Step 1: Generate an Optimized Itinerary**
- **Retrieve real-time data** (e.g., weather, crowd levels, and local events) to suggest the best times to visit attractions.
- Create a **structured, multi-day travel plan** that maximizes available time while balancing **sightseeing, relaxation, and local experiences**.
- Incorporate **seasonal and cultural insights** to enhance the travel experience.
- Prioritize **time-efficient routes** using mapping tools.
## **Step 2: Smart Transport & Accommodation Planning**
- Suggest the most **efficient transport options** based on {user_inputs['transport']}.
- Compare **flights, trains, buses, or car rentals** for cost, duration, and convenience.
- Recommend **accommodations** within budget, balancing comfort, location, and safety.
- Provide estimated travel times and **real-time availability** for transport & hotels.
- Include **relevant booking links** for:
- **Flights:** Skyscanner, Google Flights, Kayak
- **Trains & Buses:** Omio, Rail Europe, FlixBus
- **Car Rentals:** Rentalcars, Turo, Enterprise
- **Hotels & Stays:** Booking.com, Airbnb, Agoda
## **Step 3: Cost Estimation & Budgeting**
- **Break down estimated costs** for:
- **Transport:** (flights, public transport, or car rentals)
- **Accommodation:** (hotels, hostels, or rentals)
- **Meals & Dining:** (local food spots vs. premium dining)
- **Activities & Attractions:** (ticket prices, entry fees, and reservations)
- Offer **budget-friendly vs. premium options** while ensuring the plan stays within {user_inputs['budget']}.
- Suggest **discount passes, travel cards, and best booking platforms** for savings.
- Provide **direct booking links for tours, attractions, and dining** using:
- **Attractions & Tours:** GetYourGuide, Viator, Klook
- **Restaurant Reservations:** OpenTable, TheFork, Zomato
## **Step 4: Flexibility & Real-Time Adjustments**
- **Retrieve live updates** on:
- **Transport delays, strikes, or disruptions.**
- **Weather conditions affecting travel plans.**
- **Local event schedules & closures.**
- Include **alternative activity suggestions** in case of last-minute changes.
- Provide **emergency contacts, visa requirements, safety tips**, and **last-minute booking options**.
- Offer a **summary dashboard** with real-time insights for easy decision-making.
## **Step 5: AI-Powered Personalized Enhancements**
- Utilize **LLM-based recommendation engines** to personalize the itinerary based on travel history, reviews, and preferences.
- Suggest **AI-curated food experiences, offbeat destinations, and hidden gems**.
- Implement **interactive chatbot support** for instant Q&A and local guides.
""",
agent=agent,
expected_output="""
A structured, **highly optimized travel plan**, including:
- **Day-by-day itinerary** tailored to user preferences.
- **Real-time transport & accommodation recommendations** with direct booking links.
- **Estimated cost breakdown** with budget-conscious choices.
- **Dining & event recommendations** with reservation links.
- **Alternative options & live travel insights** for flexibility.
- **Safety, visa, and emergency contact details.**
- **Interactive AI-driven suggestions for a hassle-free experience.**
-**Links to the booking webistes for travel and hotel returned from the serperDevtool**
"""
)
def log_status(container, message):
"""Simple function to log status messages using Streamlit's native components"""
timestamp = datetime.now().strftime("%H:%M:%S")
container.info(f"[{timestamp}] {message}")
def main():
# Ensure environment variables are loaded
load_dotenv()
st.title("🌍 AI Travel Planning Assistant")
# Session state for referral code validation
if 'referral_validated' not in st.session_state:
st.session_state.referral_validated = False
st.session_state.user_type = None
# Debug information in sidebar
st.sidebar.title("Debug Information")
st.sidebar.write(f"GEMINI_API_KEY present: {bool(os.getenv('GEMINI_API_KEY'))}")
# Referral code validation
if not st.session_state.referral_validated:
st.write("Welcome! Please enter your referral code to access the travel planner.")
with st.form("referral_form"):
referral_code = st.text_input("Referral Code", key="referral_input")
submit_code = st.form_submit_button("Submit")
if submit_code:
is_valid, user_type, message = validate_referral_code(referral_code)
if is_valid:
st.session_state.referral_validated = True
st.session_state.user_type = user_type
st.success(f"Welcome! You have {user_type.title()} access.")
st.experimental_rerun()
else:
st.error(message)
return
# Show user type in sidebar
st.sidebar.write(f"Access Level: {st.session_state.user_type.title()}")
st.write("Let me help you plan your perfect trip!")
# Input form
with st.form("travel_form"):
col1, col2 = st.columns(2)
with col1:
origin = st.text_input("Origin", placeholder="e.g., New York")
destination = st.text_input("Destination", placeholder="e.g., Paris")
budget = st.number_input("Budget (in local currency)", min_value=0.0, value=1000.0, step=100.0)
with col2:
activities = st.text_input("Preferred Activities", placeholder="e.g., cultural, adventure, leisure")
transport = st.text_input("Preferred Transport", placeholder="e.g., flight, train, bus")
time = st.text_input("Time Available", placeholder="e.g., 5 days")
submit_button = st.form_submit_button("Generate Travel Plan")
if submit_button:
if not all([origin, destination, activities, transport, time]):
st.error("Please fill in all the fields!")
return
user_inputs = {
"origin": origin,
"destination": destination,
"budget": budget,
"activities": activities,
"transport": transport,
"time": time
}
with st.spinner("🤖 Generating your personalized travel plan... This may take a few minutes."):
try:
# Create an expander for logs
with st.expander("Progress Updates", expanded=True):
status_container = st.empty()
# Initialize components
log_status(status_container, "Initializing LLM...")
llm = initialize_llm()
log_status(status_container, "Creating travel agent...")
travel_agent = create_travel_agent(llm)
log_status(status_container, "Creating travel task...")
travel_task = create_travel_task(travel_agent, user_inputs)
log_status(status_container, "Setting up crew...")
crew = Crew(
agents=[travel_agent],
tasks=[travel_task],
verbose=True,
process=Process.sequential
)
log_status(status_container, "Starting travel plan generation...")
results = crew.kickoff()
log_status(status_container, "✨ Travel plan generation completed!")
# Display results
st.success("✨ Your travel plan is ready!")
st.markdown(results)
except Exception as e:
st.error(f"An error occurred: {str(e)}")
st.error("Please try again or contact support if the problem persists.")
if __name__ == "__main__":
main()