import streamlit as st
from datetime import datetime, timedelta
import base64
import pandas as pd
import pydeck as pdk
from geopy.geocoders import Nominatim
import qrcode
from io import BytesIO
from travel import (
destination_research_task, accommodation_task, transportation_task,
activities_task, dining_task, itinerary_task, chatbot_task,
run_task, update_llm
)
st.set_page_config(
page_title="Your Agentic AI Travelling Partner β€οΈ ",
page_icon="βοΈ Namude Yatra",
layout="wide",
initial_sidebar_state="expanded"
)
with st.sidebar:
st.image("image.png", width=250)
st.markdown("""
Namude Yatra: The beginning of your dream journey
AI-Powered Agentic Travel Planning
""", unsafe_allow_html=True)
api_key = st.text_input("Enter your GEMINI API Key", type="password")
if api_key:
from travel import init_travel_system
init_travel_system(api_key)
st.success("Travel system initialized with the provided API key!")
st.markdown("""
""", unsafe_allow_html=True)
st.markdown("""
""", unsafe_allow_html=True)
def get_download_link(text_content, filename):
b64 = base64.b64encode(text_content.encode()).decode()
return f'π₯ Save Your Itinerary'
def display_modern_progress(current_step, total_steps=6):
if 'progress_steps' not in st.session_state:
st.session_state.progress_steps = {
0: {'status': 'pending', 'name': "Trip Details"},
1: {'status': 'pending', 'name': "About"},
2: {'status': 'pending', 'name': "Travel Style"},
3: {'status': 'pending', 'name': "Live Agent Outputs"},
4: {'status': 'pending', 'name': "Download & Share"},
5: {'status': 'pending', 'name': "Full Itinerary"}
}
for i in range(total_steps):
if i < current_step:
st.session_state.progress_steps[i]['status'] = 'complete'
elif i == current_step:
st.session_state.progress_steps[i]['status'] = 'active'
else:
st.session_state.progress_steps[i]['status'] = 'pending'
progress_percentage = (current_step / total_steps) * 100
st.progress(progress_percentage / 100)
st.markdown("""
""", unsafe_allow_html=True)
for i, step_info in st.session_state.progress_steps.items():
status = step_info['status']
name = step_info['name']
if status == 'complete':
icon = "β
"
status_class = "complete"
elif status == 'active':
icon = "π"
status_class = "active"
else:
icon = "β"
status_class = "pending"
st.markdown(f"""
{icon}
{name}
""", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)
return progress_percentage
def update_step_status(step_index, status):
if 'progress_steps' in st.session_state and step_index in st.session_state.progress_steps:
st.session_state.progress_steps[step_index]['status'] = status
def run_task_with_logs(task, input_text, log_container, output_container, results_key=None):
if 'log_messages' not in st.session_state:
st.session_state.log_messages = []
log_message = f"π€ Starting {task.agent.role}..."
st.session_state.log_messages.append(log_message)
with log_container:
st.markdown("### Agent Activity")
for msg in st.session_state.log_messages:
st.markdown(msg)
result = run_task(task, input_text)
if results_key:
st.session_state.results[results_key] = result
log_message = f"β
{task.agent.role} completed!"
st.session_state.log_messages.append(log_message)
with log_container:
st.markdown("### Agent Activity")
for msg in st.session_state.log_messages:
st.markdown(msg)
with output_container:
st.markdown(f"### {task.agent.role} Output")
st.markdown("" + result + "
", unsafe_allow_html=True)
return result
if 'generated_itinerary' not in st.session_state:
st.session_state.generated_itinerary = None
if 'generation_complete' not in st.session_state:
st.session_state.generation_complete = False
if 'current_step' not in st.session_state:
st.session_state.current_step = 0
if 'results' not in st.session_state:
st.session_state.results = {
"destination_info": "",
"accommodation_info": "",
"transportation_info": "",
"activities_info": "",
"dining_info": "",
"itinerary": "",
"final_itinerary": ""
}
if 'log_messages' not in st.session_state:
st.session_state.log_messages = []
if 'current_output' not in st.session_state:
st.session_state.current_output = None
if 'form_submitted' not in st.session_state:
st.session_state.form_submitted = False
st.markdown(f"""
Your Agentic AI Travelling Partner β€οΈ
β¨ Create your personalized AI-powered travel itinerary in minutes! β¨
""", unsafe_allow_html=True)
st.markdown('
', unsafe_allow_html=True)
if not st.session_state.generation_complete:
st.markdown('', unsafe_allow_html=True)
st.markdown("
βοΈ Create Your Itinerary
", unsafe_allow_html=True)
st.markdown("""
Complete the form below for a personalized travel plan.
""", unsafe_allow_html=True)
with st.form("travel_form"):
col1, col2 = st.columns(2)
with col1:
st.markdown('
Trip Details
', unsafe_allow_html=True)
origin = st.text_input("Origin", placeholder="e.g., New York, USA")
destination = st.text_input("Destination", placeholder="e.g., Paris, France")
st.markdown('
Travel Dates
', unsafe_allow_html=True)
start_date = st.date_input("Start Date", min_value=datetime.now(), label_visibility="collapsed")
duration = st.slider("Duration (days)", min_value=1, max_value=30, value=7)
end_date = start_date + timedelta(days=duration-1)
st.markdown(f'
{start_date.strftime("%b %d")} - {end_date.strftime("%b %d, %Y")}
', unsafe_allow_html=True)
with col2:
st.markdown('
Preferences
', unsafe_allow_html=True)
travelers = st.number_input("Travelers", min_value=1, max_value=15, value=2)
budget_options = ["Budget", "Moderate", "Luxury"]
budget = st.selectbox("Budget", budget_options, help="Budget: Economy options | Moderate: Mid-range | Luxury: High-end experiences")
travel_style = st.multiselect("Travel Style", options=["Culture", "Adventure", "Relaxation", "Food & Dining", "Nature", "Shopping", "Nightlife", "Family-friendly"], default=["Culture", "Food & Dining"])
with st.expander("Additional Preferences"):
preferences = st.text_area("Interests", placeholder="History museums, local cuisine, hiking, art...")
special_requirements = st.text_area("Special Requirements", placeholder="Dietary restrictions, accessibility needs...")
submit_button = st.form_submit_button("π Create My Personal Travel Itinerary")
st.markdown('
', unsafe_allow_html=True)
if submit_button:
if not origin or not destination:
st.error("Please enter both origin and destination.")
else:
st.session_state.form_submitted = True
st.session_state.destination = destination
user_input = {
"origin": origin,
"destination": destination,
"duration": str(duration),
"travel_dates": f"{start_date.strftime('%Y-%m-%d')} to {end_date.strftime('%Y-%m-%d')}",
"travelers": str(travelers),
"budget": budget.lower(),
"travel_style": ", ".join(travel_style),
"preferences": preferences,
"special_requirements": special_requirements
}
st.session_state.user_input = user_input
input_context = f"""Travel Request Details:
Origin: {user_input['origin']}
Destination: {user_input['destination']}
Duration: {user_input['duration']} days
Travel Dates: {user_input['travel_dates']}
Travelers: {user_input['travelers']}
Budget Level: {user_input['budget']}
Travel Style: {user_input['travel_style']}
Preferences/Interests: {user_input['preferences']}
Special Requirements: {user_input['special_requirements']}
"""
modified_input_context = "Please output the response in English.\n" + input_context
# Processing Animation
st.markdown("""
""", unsafe_allow_html=True)
st.markdown('', unsafe_allow_html=True)
progress_tab, logs_tab, details_tab = st.tabs(["π Progress", "π Live Activity", "π Your Travel Request"])
with details_tab:
st.markdown("#### Your Travel Request")
st.markdown("**Destination:** " + user_input['destination'])
st.markdown("**From:** " + user_input['origin'])
st.markdown("**When:** " + user_input['travel_dates'] + " (" + user_input['duration'] + " days)")
st.markdown("**Budget:** " + user_input['budget'].title())
st.markdown("**Travel Style:** " + user_input['travel_style'])
if user_input['preferences']:
st.markdown("**Interests:** " + user_input['preferences'])
if user_input['special_requirements']:
st.markdown("**Special Requirements:** " + user_input['special_requirements'])
with progress_tab:
if 'progress_placeholder' not in st.session_state:
st.session_state.progress_placeholder = st.empty()
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
with logs_tab:
log_container = st.container()
st.session_state.log_messages = []
st.markdown('
', unsafe_allow_html=True)
output_container = st.container()
with output_container:
st.markdown('', unsafe_allow_html=True)
st.markdown("### Live Agent Outputs")
st.info("Our AI agents will show their work here as they create your itinerary")
st.markdown('
', unsafe_allow_html=True)
st.session_state.current_step = 0
# Step 1: Destination Research
update_step_status(0, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
destination_info = run_task_with_logs(
destination_research_task,
modified_input_context.format(destination=user_input['destination'], preferences=user_input['preferences']),
log_container,
output_container,
"destination_info"
)
update_step_status(0, 'complete')
st.session_state.current_step = 1
# Step 2: Accommodation
update_step_status(1, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
accommodation_info = run_task_with_logs(
accommodation_task,
modified_input_context.format(destination=user_input['destination'], budget=user_input['budget'], preferences=user_input['preferences']),
log_container,
output_container,
"accommodation_info"
)
update_step_status(1, 'complete')
st.session_state.current_step = 2
# Step 3: Transportation
update_step_status(2, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
transportation_info = run_task_with_logs(
transportation_task,
modified_input_context.format(origin=user_input['origin'], destination=user_input['destination']),
log_container,
output_container,
"transportation_info"
)
update_step_status(2, 'complete')
st.session_state.current_step = 3
# Step 4: Activities
update_step_status(3, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
activities_info = run_task_with_logs(
activities_task,
modified_input_context.format(destination=user_input['destination'], preferences=user_input['preferences']),
log_container,
output_container,
"activities_info"
)
update_step_status(3, 'complete')
st.session_state.current_step = 4
# Step 5: Dining
update_step_status(4, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
dining_info = run_task_with_logs(
dining_task,
modified_input_context.format(destination=user_input['destination'], preferences=user_input['preferences']),
log_container,
output_container,
"dining_info"
)
update_step_status(4, 'complete')
st.session_state.current_step = 5
# Step 6: Final Itinerary
update_step_status(5, 'active')
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
combined_info = f"""{input_context}
Destination Information:
{destination_info}
Accommodation Options:
{accommodation_info}
Transportation Plan:
{transportation_info}
Recommended Activities:
{activities_info}
Dining Recommendations:
{dining_info}
"""
itinerary = run_task_with_logs(
itinerary_task,
combined_info.format(duration=user_input['duration'], origin=user_input['origin'], destination=user_input['destination']),
log_container,
output_container,
"itinerary"
)
update_step_status(5, 'complete')
st.session_state.current_step = 6
with st.session_state.progress_placeholder.container():
display_modern_progress(st.session_state.current_step)
st.session_state.generated_itinerary = itinerary
st.session_state.generation_complete = True
date_str = datetime.now().strftime("%Y-%m-%d")
st.session_state.filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt"
if st.session_state.generation_complete:
st.markdown("""
Your Travel Itinerary is Ready! π
We've created a personalized travel experience just for you. Explore your itinerary below.
""", unsafe_allow_html=True)
itinerary_tab, details_tab, download_tab, map_tab, chatbot_tab = st.tabs([
"ποΈ Full Itinerary",
"πΌ Details",
"πΎ Download & Share",
"πΊοΈ Map & Visualization",
"π€ Chatbot Interface"
])
with itinerary_tab:
st.text_area("Your Itinerary", st.session_state.generated_itinerary, height=600)
with details_tab:
agent_tabs = st.tabs(["π Destination", "π¨ Accommodation", "π Transportation", "π Activities", "π½οΈ Dining"])
with agent_tabs[0]:
st.markdown("### π Destination Research")
st.markdown(st.session_state.results["destination_info"])
with agent_tabs[1]:
st.markdown("### π¨ Accommodation Options")
st.markdown(st.session_state.results["accommodation_info"])
with agent_tabs[2]:
st.markdown("### π Transportation Plan")
st.markdown(st.session_state.results["transportation_info"])
with agent_tabs[3]:
st.markdown("### π Recommended Activities")
st.markdown(st.session_state.results["activities_info"])
with agent_tabs[4]:
st.markdown("### π½οΈ Dining Recommendations")
st.markdown(st.session_state.results["dining_info"])
with download_tab:
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("### Save Your Itinerary")
st.markdown("Download your personalized travel plan to access it offline or share with your travel companions.")
st.markdown("""
Your Itinerary File
Text format - Can be opened in any text editor
""", unsafe_allow_html=True)
st.markdown(
""
+ get_download_link(st.session_state.generated_itinerary, st.session_state.filename)
+ "
",
unsafe_allow_html=True
)
st.markdown("### Share Your Itinerary")
st.markdown("*Coming soon: Additional sharing features (email, phone, etc.)*")
with col2:
st.markdown("### Save for Mobile")
st.markdown("*Coming soon: Additional mobile features such as a dedicated app or push notifications*")
with map_tab:
st.markdown("### Destination Map")
dest = st.session_state.get("destination", "Paris")
try:
geolocator = Nominatim(user_agent="travel_app")
location = geolocator.geocode(dest)
if location:
lat, lon = location.latitude, location.longitude
else:
st.error("The destination could not be found. Using default coordinates.")
lat, lon = 48.8566, 2.3522
except Exception as e:
st.error("Geocoding error: " + str(e))
lat, lon = 48.8566, 2.3522
map_data = pd.DataFrame({
"lat": [lat],
"lon": [lon],
"name": [dest]
})
st.map(map_data)
st.markdown("#### Interactive Map with Pydeck")
layer = pdk.Layer(
"ScatterplotLayer",
data=map_data,
get_position='[lon, lat]',
get_color='[200, 30, 0, 160]',
get_radius=200,
)
view_state = pdk.ViewState(
latitude=lat,
longitude=lon,
zoom=12,
pitch=50,
)
deck_chart = pdk.Deck(layers=[layer], initial_view_state=view_state)
st.pydeck_chart(deck_chart)
with chatbot_tab:
st.markdown("### AI Chatbot Interface")
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
user_message = st.text_input("Enter your message:", key="chat_input")
if st.button("Send", key="send_button"):
if user_message:
response = run_task(chatbot_task, user_message)
st.session_state.chat_history.append({
"speaker": "User",
"message": user_message,
"time": datetime.now()
})
st.session_state.chat_history.append({
"speaker": "AI",
"message": response,
"time": datetime.now()
})
st.markdown("", unsafe_allow_html=True)
for chat in st.session_state.chat_history:
time_str = chat["time"].strftime("%H:%M:%S")
st.markdown(f"**{chat['speaker']}** ({time_str}): {chat['message']}")
st.markdown("
", unsafe_allow_html=True)
st.markdown("""
Built with β€οΈ for you
""", unsafe_allow_html=True)