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)