forked from Shubhamsaboo/awesome-llm-apps
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtravel_agent.py
More file actions
158 lines (135 loc) · 6.77 KB
/
travel_agent.py
File metadata and controls
158 lines (135 loc) · 6.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
from textwrap import dedent
from agno.agent import Agent
from agno.run.agent import RunOutput
from agno.tools.serpapi import SerpApiTools
import streamlit as st
import re
from agno.models.openai import OpenAIChat
from icalendar import Calendar, Event
from datetime import datetime, timedelta
def generate_ics_content(plan_text:str, start_date: datetime = None) -> bytes:
"""
Generate an ICS calendar file from a travel itinerary text.
Args:
plan_text: The travel itinerary text
start_date: Optional start date for the itinerary (defaults to today)
Returns:
bytes: The ICS file content as bytes
"""
cal = Calendar()
cal.add('prodid','-//AI Travel Planner//github.com//' )
cal.add('version', '2.0')
if start_date is None:
start_date = datetime.today()
# Split the plan into days
day_pattern = re.compile(r'Day (\d+)[:\s]+(.*?)(?=Day \d+|$)', re.DOTALL)
days = day_pattern.findall(plan_text)
if not days: # If no day pattern found, create a single all-day event with the entire content
event = Event()
event.add('summary', "Travel Itinerary")
event.add('description', plan_text)
event.add('dtstart', start_date.date())
event.add('dtend', start_date.date())
event.add("dtstamp", datetime.now())
cal.add_component(event)
else:
# Process each day
for day_num, day_content in days:
day_num = int(day_num)
current_date = start_date + timedelta(days=day_num - 1)
# Create a single event for the entire day
event = Event()
event.add('summary', f"Day {day_num} Itinerary")
event.add('description', day_content.strip())
# Make it an all-day event
event.add('dtstart', current_date.date())
event.add('dtend', current_date.date())
event.add("dtstamp", datetime.now())
cal.add_component(event)
return cal.to_ical()
# Set up the Streamlit app
st.title("AI Travel Planner ")
st.caption("Plan your next adventure with AI Travel Planner by researching and planning a personalized itinerary on autopilot using GPT-4o")
# Initialize session state to store the generated itinerary
if 'itinerary' not in st.session_state:
st.session_state.itinerary = None
# Get OpenAI API key from user
openai_api_key = st.text_input("Enter OpenAI API Key to access GPT-4o", type="password")
# Get SerpAPI key from the user
serp_api_key = st.text_input("Enter Serp API Key for Search functionality", type="password")
if openai_api_key and serp_api_key:
researcher = Agent(
name="Researcher",
role="Searches for travel destinations, activities, and accommodations based on user preferences",
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a world-class travel researcher. Given a travel destination and the number of days the user wants to travel for,
generate a list of search terms for finding relevant travel activities and accommodations.
Then search the web for each term, analyze the results, and return the 10 most relevant results.
"""
),
instructions=[
"Given a travel destination and the number of days the user wants to travel for, first generate a list of 3 search terms related to that destination and the number of days.",
"For each search term, `search_google` and analyze the results."
"From the results of all searches, return the 10 most relevant results to the user's preferences.",
"Remember: the quality of the results is important.",
],
tools=[SerpApiTools(api_key=serp_api_key)],
add_datetime_to_context=True,
)
planner = Agent(
name="Planner",
role="Generates a draft itinerary based on user preferences and research results",
model=OpenAIChat(id="gpt-4o", api_key=openai_api_key),
description=dedent(
"""\
You are a senior travel planner. Given a travel destination, the number of days the user wants to travel for, and a list of research results,
your goal is to generate a draft itinerary that meets the user's needs and preferences.
"""
),
instructions=[
"Given a travel destination, the number of days the user wants to travel for, and a list of research results, generate a draft itinerary that includes suggested activities and accommodations.",
"Ensure the itinerary is well-structured, informative, and engaging.",
"Ensure you provide a nuanced and balanced itinerary, quoting facts where possible.",
"Remember: the quality of the itinerary is important.",
"Focus on clarity, coherence, and overall quality.",
"Never make up facts or plagiarize. Always provide proper attribution.",
],
add_datetime_to_context=True,
)
# Input fields for the user's destination and the number of days they want to travel for
destination = st.text_input("Where do you want to go?")
num_days = st.number_input("How many days do you want to travel for?", min_value=1, max_value=30, value=7)
col1, col2 = st.columns(2)
with col1:
if st.button("Generate Itinerary"):
with st.spinner("Researching your destination..."):
# First get research results
research_results: RunOutput = researcher.run(f"Research {destination} for a {num_days} day trip", stream=False)
# Show research progress
st.write(" Research completed")
with st.spinner("Creating your personalized itinerary..."):
# Pass research results to planner
prompt = f"""
Destination: {destination}
Duration: {num_days} days
Research Results: {research_results.content}
Please create a detailed itinerary based on this research.
"""
response: RunOutput = planner.run(prompt, stream=False)
# Store the response in session state
st.session_state.itinerary = response.content
st.write(response.content)
# Only show download button if there's an itinerary
with col2:
if st.session_state.itinerary:
# Generate the ICS file
ics_content = generate_ics_content(st.session_state.itinerary)
# Provide the file for download
st.download_button(
label="Download Itinerary as Calendar (.ics)",
data=ics_content,
file_name="travel_itinerary.ics",
mime="text/calendar"
)