openfree commited on
Commit
e5027a8
·
verified ·
1 Parent(s): e3d9538

Update travel.py

Browse files
Files changed (1) hide show
  1. travel.py +215 -265
travel.py CHANGED
@@ -1,38 +1,49 @@
1
  import os
2
  import json
 
3
  from datetime import datetime, timedelta
4
  from langchain_google_genai import ChatGoogleGenerativeAI
5
  from langchain.schema import SystemMessage, HumanMessage
6
 
7
- # ------------------------------------------------------------------------------
8
- # Agent and Task Classes
9
- # ------------------------------------------------------------------------------
 
 
 
10
  class Agent:
11
- def __init__(self, role, goal, backstory, personality="", llm=None):
 
 
 
12
  self.role = role
13
  self.goal = goal
14
  self.backstory = backstory
15
  self.personality = personality
16
- self.tools = [] # Initialize with empty list
17
  self.llm = llm
18
 
19
  class Task:
20
- def __init__(self, description, agent, expected_output, context=None):
 
 
 
21
  self.description = description
22
  self.agent = agent
23
  self.expected_output = expected_output
24
  self.context = context or []
25
 
26
- # ------------------------------------------------------------------------------
27
  # Initialize LLM
28
- # ------------------------------------------------------------------------------
29
- google_api_key = os.getenv("GEMINI_API_KEY") # Replace with your actual Google API key
 
 
30
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", google_api_key=google_api_key)
31
 
32
- # ------------------------------------------------------------------------------
33
  # Define Travel Agents
34
- # ------------------------------------------------------------------------------
35
- # 1. Destination Research Agent
36
  destination_research_agent = Agent(
37
  role="Destination Research Agent",
38
  goal=(
@@ -47,7 +58,6 @@ destination_research_agent = Agent(
47
  llm=llm,
48
  )
49
 
50
- # 2. Accommodation Agent
51
  accommodation_agent = Agent(
52
  role="Accommodation Agent",
53
  goal="Find and recommend suitable accommodations based on the traveler's preferences, budget, and location requirements.",
@@ -56,7 +66,6 @@ accommodation_agent = Agent(
56
  llm=llm,
57
  )
58
 
59
- # 3. Transportation Agent
60
  transportation_agent = Agent(
61
  role="Transportation Agent",
62
  goal="Plan efficient transportation between the origin, destination, and all points of interest in the itinerary.",
@@ -65,7 +74,6 @@ transportation_agent = Agent(
65
  llm=llm,
66
  )
67
 
68
- # 4. Activities & Attractions Agent
69
  activities_agent = Agent(
70
  role="Activities & Attractions Agent",
71
  goal="Curate personalized activities and attractions that align with the traveler's interests, preferences, and time constraints.",
@@ -74,7 +82,6 @@ activities_agent = Agent(
74
  llm=llm,
75
  )
76
 
77
- # 5. Dining & Culinary Agent
78
  dining_agent = Agent(
79
  role="Dining & Culinary Agent",
80
  goal="Recommend dining experiences that showcase local cuisine while accommodating dietary preferences and budget considerations.",
@@ -83,7 +90,6 @@ dining_agent = Agent(
83
  llm=llm,
84
  )
85
 
86
- # 6. Itinerary Integration Agent
87
  itinerary_agent = Agent(
88
  role="Itinerary Integration Agent",
89
  goal="Compile all recommendations into a cohesive, day-by-day itinerary that optimizes time, minimizes travel fatigue, and maximizes enjoyment.",
@@ -92,52 +98,48 @@ itinerary_agent = Agent(
92
  llm=llm,
93
  )
94
 
95
-
96
-
97
- # ------------------------------------------------------------------------------
98
  # Define Tasks
99
- # ------------------------------------------------------------------------------
100
  destination_research_task = Task(
101
  description="""Research {destination} thoroughly, considering the traveler's interests in {preferences}.
102
 
103
- Efficient research parameters:
104
- - Prioritize research in these critical categories:
105
- * Top attractions that match specific {preferences} (not generic lists)
106
- * Local transportation systems with cost-efficiency analysis
107
- * Neighborhood breakdown with accommodation recommendations by budget tier
108
- * Seasonal considerations for the specific travel dates
109
- * Safety assessment with specific areas to embrace or avoid
110
- * Cultural norms that impact visitor experience (dress codes, tipping, etiquette)
111
-
112
- - Apply efficiency filters:
113
- * Focus exclusively on verified information from official tourism boards, recent travel guides, and reliable local sources
114
- * Analyze recent visitor reviews (< 6 months old) to identify changing conditions
115
- * Evaluate price-to-experience value for attractions instead of just popularity
116
- * Identify logistical clusters where multiple interests can be satisfied efficiently
117
- * Research off-peak times for popular attractions to minimize waiting
118
- * Evaluate digital tools (apps, passes, reservation systems) that streamline the visit
119
-
120
- - Create practical knowledge matrices:
121
- * Transportation method comparison (cost vs. time vs. convenience)
122
- * Weather impact on specific activities
123
- * Budget allocation recommendations based on preference priorities
124
- * Time-saving opportunity identification""",
125
-
126
  agent=destination_research_agent,
127
-
128
  expected_output="""Targeted destination brief containing:
129
- 1. Executive summary highlighting the 5 most relevant aspects based on {preferences}
130
- 2. Neighborhood analysis with accommodation recommendations mapped to specific interests
131
- 3. Transportation efficiency guide with cost/convenience matrix
132
- 4. Cultural briefing focusing only on need-to-know information that impacts daily activities
133
- 5. Seasonal advantages and challenges specific to travel dates
134
- 6. Digital resource toolkit (essential apps, websites, reservation systems)
135
- 7. Budget optimization strategies with price ranges for key experiences
136
- 8. Safety and health quick-reference including emergency contacts
137
- 9. Logistics efficiency map showing optimal activity clustering
138
- 10. Local insider advantage recommendations that save time or money
139
-
140
- Format should prioritize scannable information with bullet points, comparison tables, and decision matrices rather than lengthy prose."""
141
  )
142
 
143
  accommodation_task = Task(
@@ -155,45 +157,43 @@ transportation_task = Task(
155
  activities_task = Task(
156
  description="""Suggest activities and attractions in {destination} that align with interests in {preferences}.
157
 
158
- Detailed requirements:
159
- - Categorize activities into: Cultural Experiences, Outdoor Adventures, Culinary Experiences,
160
- Entertainment & Nightlife, Family-Friendly Activities, and Local Hidden Gems
161
- - For each activity, include:
162
- * Detailed description with historical/cultural context where relevant
163
- * Precise location with neighborhood information
164
- * Operating hours with seasonal variations noted
165
- * Pricing information with different ticket options/packages
166
- * Accessibility considerations for travelers with mobility limitations
167
- * Recommended duration for the activity (minimum and ideal time)
168
- * Best time of day/week/year to visit
169
- * Crowd levels by season
170
- * Photography opportunities and restrictions
171
- * Required reservations or booking windows
172
- - Include a mix of iconic must-see attractions and off-the-beaten-path experiences
173
- - Consider weather patterns in {destination} during travel period
174
- - Analyze the {preferences} to match specific personality types and interest levels
175
- - Include at least 2-3 rainy day alternatives for outdoor activities
176
- - Provide local transportation options to reach each attraction
177
- - Note authentic local experiences that provide cultural immersion
178
- - Flag any activities requiring special equipment, permits, or physical fitness levels""",
179
-
180
  agent=activities_agent,
181
-
182
  expected_output="""Comprehensive curated list of activities and attractions with:
183
- 1. Clear categorization by type (cultural, outdoor, culinary, entertainment, family-friendly, hidden gems)
184
- 2. Detailed descriptions that include historical and cultural context
185
- 3. Complete practical information (hours, pricing, location, accessibility)
186
- 4. Time optimization recommendations (best time to visit, how to avoid crowds)
187
- 5. Personalized matches explaining why each activity aligns with specific {preferences}
188
- 6. Local transportation details to reach each attraction
189
- 7. Alternative options for inclement weather or unexpected closures
190
- 8. Insider tips from locals that enhance the experience
191
- 9. Suggested combinations of nearby activities for efficient itinerary planning
192
- 10. Risk level assessment and safety considerations where applicable
193
- 11. Sustainability impact and responsible tourism notes
194
- 12. Photographic highlights and optimal viewing points
195
-
196
- Format should include a summary table for quick reference followed by detailed cards for each activity."""
197
  )
198
 
199
  dining_task = Task(
@@ -205,80 +205,77 @@ dining_task = Task(
205
  itinerary_task = Task(
206
  description="""Create a day-by-day itinerary for a {duration} trip to {destination} from {origin}, incorporating all recommendations.
207
 
208
- Detailed requirements:
209
- - Begin with arrival logistics including airport transfer options, check-in times, and first-day orientation activities
210
- - Structure each day with:
211
- * Morning, afternoon, and evening activity blocks with precise timing
212
- * Estimated travel times between locations using various transportation methods
213
- * Buffer time for rest, spontaneous exploration, and unexpected delays
214
- * Meal recommendations with reservation details and backup options
215
- * Sunset/sunrise opportunities for optimal photography or experiences
216
- - Apply intelligent sequencing to:
217
- * Group attractions by geographic proximity to minimize transit time
218
- * Schedule indoor activities strategically for predicted weather patterns
219
- * Balance high-energy activities with relaxation periods
220
- * Alternate between cultural immersion and entertainment experiences
221
- * Account for opening days/hours of attractions and potential closures
222
- - Include practical timing considerations:
223
- * Museum/attraction fatigue limitations
224
- * Jet lag recovery for first 1-2 days
225
- * Time zone adjustment strategies
226
- * Local rush hours and traffic patterns to avoid
227
- * Cultural norms for meal times and business hours
228
- - End with departure logistics including check-out procedures, airport transfer timing, and luggage considerations
229
- - Add specialized planning elements:
230
- * Local festivals or events coinciding with the travel dates
231
- * Free time blocks for personal exploration or shopping
232
- * Contingency recommendations for weather disruptions
233
- * Early booking requirements for popular attractions/restaurants
234
- * Local emergency contacts and nearby medical facilities""",
235
-
236
  agent=itinerary_agent,
237
-
238
  expected_output="""Comprehensive day-by-day itinerary featuring:
239
- 1. Detailed timeline for each day with hour-by-hour scheduling and transit times
240
- 2. Color-coded activity blocks that visually distinguish between types of activities
241
- 3. Intelligent geographic clustering to minimize transportation time
242
- 4. Strategic meal placements with both reservation-required and casual options
243
- 5. Built-in flexibility with free time blocks and alternative suggestions
244
- 6. Weather-adaptive scheduling with indoor/outdoor activity balance
245
- 7. Energy level considerations throughout the trip arc
246
- 8. Cultural timing adaptations (accommodating local siesta times, religious observances, etc.)
247
- 9. Practical logistical details (bag storage options, dress code reminders, etc.)
248
- 10. Local transportation guidance including transit cards, apps, and pre-booking requirements
249
- 11. Visual map representation showing daily movement patterns
250
- 12. Key phrases in local language for each day's activities
251
-
252
- Format should include both a condensed overview calendar and detailed daily breakdowns with time, activity, location, notes, and contingency plans."""
253
  )
254
 
255
-
256
-
257
- # ------------------------------------------------------------------------------
258
  # Helper Function to Run a Task with Full Agent & Task Information
259
- # ------------------------------------------------------------------------------
260
- def run_task(task, input_text):
 
 
 
261
  try:
262
- # Ensure 'task' is an instance of the Task class
263
  if not isinstance(task, Task):
264
- raise ValueError(f"Expected 'task' to be an instance of Task class, but got {type(task)}")
265
-
266
- # Ensure 'task.agent' exists and is an instance of Agent
267
  if not hasattr(task, 'agent') or not isinstance(task.agent, Agent):
268
- raise ValueError(f"Task must contain a valid 'agent' attribute that is an instance of Agent class.")
269
-
270
- system_input = f"""Agent Details:
271
- Role: {task.agent.role}
272
- Goal: {task.agent.goal}
273
- Backstory: {task.agent.backstory}
274
- Personality: {task.agent.personality}
275
- """
276
- task_input = f"""Task Details:
277
- Task Description: {task.description}
278
- Expected Output: {task.expected_output}
279
- Input for Task:
280
- {input_text}
281
- """
 
282
  messages = [
283
  SystemMessage(content=system_input),
284
  HumanMessage(content=task_input)
@@ -288,13 +285,16 @@ Input for Task:
288
  raise ValueError("Empty response from LLM.")
289
  return response.content
290
  except Exception as e:
291
- print(f"Error in task '{task.agent.role}': {e}")
292
  return f"Error in {task.agent.role}: {e}"
293
 
294
- # ------------------------------------------------------------------------------
295
  # User Input Functions
296
- # ------------------------------------------------------------------------------
297
- def get_user_input():
 
 
 
298
  print("\n=== Travel Itinerary Generator ===\n")
299
  origin = input("Enter your origin city/country: ")
300
  destination = input("Enter your destination city/country: ")
@@ -316,132 +316,85 @@ def get_user_input():
316
  "special_requirements": special_requirements
317
  }
318
 
319
- # ------------------------------------------------------------------------------
320
  # Main Function to Generate Travel Itinerary
321
- # ------------------------------------------------------------------------------
322
- def generate_travel_itinerary(user_input):
 
 
 
323
  print("\nGenerating your personalized travel itinerary...\n")
324
 
325
- # Format the user input for tasks
326
- input_context = f"""Travel Request Details:
327
- Origin: {user_input['origin']}
328
- Destination: {user_input['destination']}
329
- Duration: {user_input['duration']} days
330
- Budget Level: {user_input['budget']}
331
- Preferences/Interests: {user_input['preferences']}
332
- Special Requirements: {user_input['special_requirements']}
333
- """
 
334
 
335
  # Step 1: Destination Research
336
  print("Researching your destination...")
337
- destination_info = run_task(
338
- destination_research_task,
339
- input_context.format(
340
- destination=user_input['destination'],
341
- preferences=user_input['preferences']
342
- )
343
- )
344
  print("✓ Destination research completed")
345
 
346
  # Step 2: Accommodation Recommendations
347
  print("Finding ideal accommodations...")
348
- accommodation_info = run_task(
349
- accommodation_task,
350
- input_context.format(
351
- destination=user_input['destination'],
352
- budget=user_input['budget'],
353
- preferences=user_input['preferences']
354
- )
355
- )
356
  print("✓ Accommodation recommendations completed")
357
 
358
  # Step 3: Transportation Planning
359
  print("Planning transportation...")
360
- transportation_info = run_task(
361
- transportation_task,
362
- input_context.format(
363
- origin=user_input['origin'],
364
- destination=user_input['destination']
365
- )
366
- )
367
  print("✓ Transportation planning completed")
368
 
369
  # Step 4: Activities & Attractions
370
  print("Curating activities and attractions...")
371
- activities_info = run_task(
372
- activities_task,
373
- input_context.format(
374
- destination=user_input['destination'],
375
- preferences=user_input['preferences']
376
- )
377
- )
378
  print("✓ Activities and attractions curated")
379
 
380
  # Step 5: Dining Recommendations
381
  print("Finding dining experiences...")
382
- dining_info = run_task(
383
- dining_task,
384
- input_context.format(
385
- destination=user_input['destination'],
386
- preferences=user_input['preferences']
387
- )
388
- )
389
  print("✓ Dining recommendations completed")
390
 
391
  # Step 6: Create Day-by-Day Itinerary
392
  print("Creating your day-by-day itinerary...")
393
- combined_info = f"""{input_context}
394
-
395
- Destination Information:
396
- {destination_info}
397
-
398
- Accommodation Options:
399
- {accommodation_info}
400
-
401
- Transportation Plan:
402
- {transportation_info}
403
-
404
- Recommended Activities:
405
- {activities_info}
406
-
407
- Dining Recommendations:
408
- {dining_info}
409
- """
410
-
411
- itinerary = run_task(
412
- itinerary_task,
413
- combined_info.format(
414
- duration=user_input['duration'],
415
- origin=user_input['origin'],
416
- destination=user_input['destination']
417
- )
418
  )
 
419
  print("✓ Itinerary creation completed")
420
-
421
- # Return the completed itinerary
422
  print("✓ Itinerary generation completed")
423
 
424
  return itinerary
425
 
426
- # ------------------------------------------------------------------------------
427
  # Save Itinerary to File
428
- # ------------------------------------------------------------------------------
429
- def save_itinerary_to_file(itinerary, user_input, output_dir=None):
430
- # Create a filename based on the destination and date
 
 
431
  date_str = datetime.now().strftime("%Y-%m-%d")
432
  filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt"
433
 
434
- # If output directory is specified, ensure it exists and use it
435
  if output_dir:
436
  if not os.path.exists(output_dir):
437
  try:
438
  os.makedirs(output_dir)
439
- print(f"Created output directory: {output_dir}")
440
  except Exception as e:
441
- print(f"Error creating directory {output_dir}: {e}")
442
- return None
443
-
444
- # Combine the output directory with the filename
445
  filepath = os.path.join(output_dir, filename)
446
  else:
447
  filepath = filename
@@ -449,37 +402,34 @@ def save_itinerary_to_file(itinerary, user_input, output_dir=None):
449
  try:
450
  with open(filepath, "w", encoding="utf-8") as f:
451
  f.write(itinerary)
452
- print(f"\nYour itinerary has been saved as: {filepath}")
453
  return filepath
454
  except Exception as e:
455
- print(f"Error saving itinerary: {e}")
456
- return None
457
 
458
- # ------------------------------------------------------------------------------
459
  # Main Function
460
- # ------------------------------------------------------------------------------
461
- def main():
 
 
 
462
  print("Welcome to BlockX Travel Itinerary Generator!")
463
  print("This AI-powered tool will create a personalized travel itinerary based on your preferences.")
464
 
465
  user_input = get_user_input()
466
 
467
- # Ask for output directory
468
  print("\nWhere would you like to save the itinerary?")
469
  print("Press Enter to save in the current directory, or specify a path:")
470
- output_dir = input("> ").strip()
471
-
472
- # If empty, use current directory
473
- if not output_dir:
474
- output_dir = None
475
- print("Will save in the current directory.")
476
 
477
  itinerary = generate_travel_itinerary(user_input)
478
 
479
- filename = save_itinerary_to_file(itinerary, user_input, output_dir)
480
 
481
- if filename:
482
- print(f"\nYour personalized travel itinerary is ready! Open {filename} to view it.")
483
  print("Thank you for using BlockX Travel Itinerary Generator!")
484
 
485
  if __name__ == "__main__":
 
1
  import os
2
  import json
3
+ import logging
4
  from datetime import datetime, timedelta
5
  from langchain_google_genai import ChatGoogleGenerativeAI
6
  from langchain.schema import SystemMessage, HumanMessage
7
 
8
+ # Setup logging configuration
9
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
10
+
11
+ # -------------------------------------------------------------------------------
12
+ # Agent and Task Classes with Type Hints and Docstrings
13
+ # -------------------------------------------------------------------------------
14
  class Agent:
15
+ def __init__(self, role: str, goal: str, backstory: str, personality: str = "", llm=None) -> None:
16
+ """
17
+ Initialize an Agent with role, goal, backstory, personality, and assigned LLM.
18
+ """
19
  self.role = role
20
  self.goal = goal
21
  self.backstory = backstory
22
  self.personality = personality
23
+ self.tools = [] # Initialize with empty list for future tool integrations
24
  self.llm = llm
25
 
26
  class Task:
27
+ def __init__(self, description: str, agent: Agent, expected_output: str, context=None) -> None:
28
+ """
29
+ Initialize a Task with its description, the responsible agent, expected output, and optional context.
30
+ """
31
  self.description = description
32
  self.agent = agent
33
  self.expected_output = expected_output
34
  self.context = context or []
35
 
36
+ # -------------------------------------------------------------------------------
37
  # Initialize LLM
38
+ # -------------------------------------------------------------------------------
39
+ google_api_key = os.getenv("GEMINI_API_KEY") # 실제 Google API 키 사용
40
+ if not google_api_key:
41
+ logging.error("GEMINI_API_KEY is not set in the environment variables.")
42
  llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", google_api_key=google_api_key)
43
 
44
+ # -------------------------------------------------------------------------------
45
  # Define Travel Agents
46
+ # -------------------------------------------------------------------------------
 
47
  destination_research_agent = Agent(
48
  role="Destination Research Agent",
49
  goal=(
 
58
  llm=llm,
59
  )
60
 
 
61
  accommodation_agent = Agent(
62
  role="Accommodation Agent",
63
  goal="Find and recommend suitable accommodations based on the traveler's preferences, budget, and location requirements.",
 
66
  llm=llm,
67
  )
68
 
 
69
  transportation_agent = Agent(
70
  role="Transportation Agent",
71
  goal="Plan efficient transportation between the origin, destination, and all points of interest in the itinerary.",
 
74
  llm=llm,
75
  )
76
 
 
77
  activities_agent = Agent(
78
  role="Activities & Attractions Agent",
79
  goal="Curate personalized activities and attractions that align with the traveler's interests, preferences, and time constraints.",
 
82
  llm=llm,
83
  )
84
 
 
85
  dining_agent = Agent(
86
  role="Dining & Culinary Agent",
87
  goal="Recommend dining experiences that showcase local cuisine while accommodating dietary preferences and budget considerations.",
 
90
  llm=llm,
91
  )
92
 
 
93
  itinerary_agent = Agent(
94
  role="Itinerary Integration Agent",
95
  goal="Compile all recommendations into a cohesive, day-by-day itinerary that optimizes time, minimizes travel fatigue, and maximizes enjoyment.",
 
98
  llm=llm,
99
  )
100
 
101
+ # -------------------------------------------------------------------------------
 
 
102
  # Define Tasks
103
+ # -------------------------------------------------------------------------------
104
  destination_research_task = Task(
105
  description="""Research {destination} thoroughly, considering the traveler's interests in {preferences}.
106
 
107
+ Efficient research parameters:
108
+ - Prioritize research in these critical categories:
109
+ * Top attractions that match specific {preferences} (not generic lists)
110
+ * Local transportation systems with cost-efficiency analysis
111
+ * Neighborhood breakdown with accommodation recommendations by budget tier
112
+ * Seasonal considerations for the specific travel dates
113
+ * Safety assessment with specific areas to embrace or avoid
114
+ * Cultural norms that impact visitor experience (dress codes, tipping, etiquette)
115
+
116
+ - Apply efficiency filters:
117
+ * Focus exclusively on verified information from official tourism boards, recent travel guides, and reliable local sources
118
+ * Analyze recent visitor reviews (< 6 months old) to identify changing conditions
119
+ * Evaluate price-to-experience value for attractions instead of just popularity
120
+ * Identify logistical clusters where multiple interests can be satisfied efficiently
121
+ * Research off-peak times for popular attractions to minimize waiting
122
+ * Evaluate digital tools (apps, passes, reservation systems) that streamline the visit
123
+
124
+ - Create practical knowledge matrices:
125
+ * Transportation method comparison (cost vs. time vs. convenience)
126
+ * Weather impact on specific activities
127
+ * Budget allocation recommendations based on preference priorities
128
+ * Time-saving opportunity identification""",
 
129
  agent=destination_research_agent,
 
130
  expected_output="""Targeted destination brief containing:
131
+ 1. Executive summary highlighting the 5 most relevant aspects based on {preferences}
132
+ 2. Neighborhood analysis with accommodation recommendations mapped to specific interests
133
+ 3. Transportation efficiency guide with cost/convenience matrix
134
+ 4. Cultural briefing focusing only on need-to-know information that impacts daily activities
135
+ 5. Seasonal advantages and challenges specific to travel dates
136
+ 6. Digital resource toolkit (essential apps, websites, reservation systems)
137
+ 7. Budget optimization strategies with price ranges for key experiences
138
+ 8. Safety and health quick-reference including emergency contacts
139
+ 9. Logistics efficiency map showing optimal activity clustering
140
+ 10. Local insider advantage recommendations that save time or money
141
+
142
+ Format should prioritize scannable information with bullet points, comparison tables, and decision matrices rather than lengthy prose."""
143
  )
144
 
145
  accommodation_task = Task(
 
157
  activities_task = Task(
158
  description="""Suggest activities and attractions in {destination} that align with interests in {preferences}.
159
 
160
+ Detailed requirements:
161
+ - Categorize activities into: Cultural Experiences, Outdoor Adventures, Culinary Experiences,
162
+ Entertainment & Nightlife, Family-Friendly Activities, and Local Hidden Gems
163
+ - For each activity, include:
164
+ * Detailed description with historical/cultural context where relevant
165
+ * Precise location with neighborhood information
166
+ * Operating hours with seasonal variations noted
167
+ * Pricing information with different ticket options/packages
168
+ * Accessibility considerations for travelers with mobility limitations
169
+ * Recommended duration for the activity (minimum and ideal time)
170
+ * Best time of day/week/year to visit
171
+ * Crowd levels by season
172
+ * Photography opportunities and restrictions
173
+ * Required reservations or booking windows
174
+ - Include a mix of iconic must-see attractions and off-the-beaten-path experiences
175
+ - Consider weather patterns in {destination} during travel period
176
+ - Analyze the {preferences} to match specific personality types and interest levels
177
+ - Include at least 2-3 rainy day alternatives for outdoor activities
178
+ - Provide local transportation options to reach each attraction
179
+ - Note authentic local experiences that provide cultural immersion
180
+ - Flag any activities requiring special equipment, permits, or physical fitness levels""",
 
181
  agent=activities_agent,
 
182
  expected_output="""Comprehensive curated list of activities and attractions with:
183
+ 1. Clear categorization by type (cultural, outdoor, culinary, entertainment, family-friendly, hidden gems)
184
+ 2. Detailed descriptions that include historical and cultural context
185
+ 3. Complete practical information (hours, pricing, location, accessibility)
186
+ 4. Time optimization recommendations (best time to visit, how to avoid crowds)
187
+ 5. Personalized matches explaining why each activity aligns with specific {preferences}
188
+ 6. Local transportation details to reach each attraction
189
+ 7. Alternative options for inclement weather or unexpected closures
190
+ 8. Insider tips from locals that enhance the experience
191
+ 9. Suggested combinations of nearby activities for efficient itinerary planning
192
+ 10. Risk level assessment and safety considerations where applicable
193
+ 11. Sustainability impact and responsible tourism notes
194
+ 12. Photographic highlights and optimal viewing points
195
+
196
+ Format should include a summary table for quick reference followed by detailed cards for each activity."""
197
  )
198
 
199
  dining_task = Task(
 
205
  itinerary_task = Task(
206
  description="""Create a day-by-day itinerary for a {duration} trip to {destination} from {origin}, incorporating all recommendations.
207
 
208
+ Detailed requirements:
209
+ - Begin with arrival logistics including airport transfer options, check-in times, and first-day orientation activities
210
+ - Structure each day with:
211
+ * Morning, afternoon, and evening activity blocks with precise timing
212
+ * Estimated travel times between locations using various transportation methods
213
+ * Buffer time for rest, spontaneous exploration, and unexpected delays
214
+ * Meal recommendations with reservation details and backup options
215
+ * Sunset/sunrise opportunities for optimal photography or experiences
216
+ - Apply intelligent sequencing to:
217
+ * Group attractions by geographic proximity to minimize transit time
218
+ * Schedule indoor activities strategically for predicted weather patterns
219
+ * Balance high-energy activities with relaxation periods
220
+ * Alternate between cultural immersion and entertainment experiences
221
+ * Account for opening days/hours of attractions and potential closures
222
+ - Include practical timing considerations:
223
+ * Museum/attraction fatigue limitations
224
+ * Jet lag recovery for first 1-2 days
225
+ * Time zone adjustment strategies
226
+ * Local rush hours and traffic patterns to avoid
227
+ * Cultural norms for meal times and business hours
228
+ - End with departure logistics including check-out procedures, airport transfer timing, and luggage considerations
229
+ - Add specialized planning elements:
230
+ * Local festivals or events coinciding with the travel dates
231
+ * Free time blocks for personal exploration or shopping
232
+ * Contingency recommendations for weather disruptions
233
+ * Early booking requirements for popular attractions/restaurants
234
+ * Local emergency contacts and nearby medical facilities""",
 
235
  agent=itinerary_agent,
 
236
  expected_output="""Comprehensive day-by-day itinerary featuring:
237
+ 1. Detailed timeline for each day with hour-by-hour scheduling and transit times
238
+ 2. Color-coded activity blocks that visually distinguish between types of activities
239
+ 3. Intelligent geographic clustering to minimize transportation time
240
+ 4. Strategic meal placements with both reservation-required and casual options
241
+ 5. Built-in flexibility with free time blocks and alternative suggestions
242
+ 6. Weather-adaptive scheduling with indoor/outdoor activity balance
243
+ 7. Energy level considerations throughout the trip arc
244
+ 8. Cultural timing adaptations (accommodating local siesta times, religious observances, etc.)
245
+ 9. Practical logistical details (bag storage options, dress code reminders, etc.)
246
+ 10. Local transportation guidance including transit cards, apps, and pre-booking requirements
247
+ 11. Visual map representation showing daily movement patterns
248
+ 12. Key phrases in local language for each day's activities
249
+
250
+ Format should include both a condensed overview calendar and detailed daily breakdowns with time, activity, location, notes, and contingency plans."""
251
  )
252
 
253
+ # -------------------------------------------------------------------------------
 
 
254
  # Helper Function to Run a Task with Full Agent & Task Information
255
+ # -------------------------------------------------------------------------------
256
+ def run_task(task: Task, input_text: str) -> str:
257
+ """
258
+ Executes the given task using the associated agent's LLM and returns the response content.
259
+ """
260
  try:
 
261
  if not isinstance(task, Task):
262
+ raise ValueError(f"Expected 'task' to be an instance of Task, got {type(task)}")
 
 
263
  if not hasattr(task, 'agent') or not isinstance(task.agent, Agent):
264
+ raise ValueError("Task must have a valid 'agent' attribute of type Agent.")
265
+
266
+ system_input = (
267
+ f"Agent Details:\n"
268
+ f"Role: {task.agent.role}\n"
269
+ f"Goal: {task.agent.goal}\n"
270
+ f"Backstory: {task.agent.backstory}\n"
271
+ f"Personality: {task.agent.personality}\n"
272
+ )
273
+ task_input = (
274
+ f"Task Details:\n"
275
+ f"Task Description: {task.description}\n"
276
+ f"Expected Output: {task.expected_output}\n"
277
+ f"Input for Task:\n{input_text}\n"
278
+ )
279
  messages = [
280
  SystemMessage(content=system_input),
281
  HumanMessage(content=task_input)
 
285
  raise ValueError("Empty response from LLM.")
286
  return response.content
287
  except Exception as e:
288
+ logging.error(f"Error in task '{task.agent.role}': {e}")
289
  return f"Error in {task.agent.role}: {e}"
290
 
291
+ # -------------------------------------------------------------------------------
292
  # User Input Functions
293
+ # -------------------------------------------------------------------------------
294
+ def get_user_input() -> dict:
295
+ """
296
+ Collects user input for travel itinerary generation.
297
+ """
298
  print("\n=== Travel Itinerary Generator ===\n")
299
  origin = input("Enter your origin city/country: ")
300
  destination = input("Enter your destination city/country: ")
 
316
  "special_requirements": special_requirements
317
  }
318
 
319
+ # -------------------------------------------------------------------------------
320
  # Main Function to Generate Travel Itinerary
321
+ # -------------------------------------------------------------------------------
322
+ def generate_travel_itinerary(user_input: dict) -> str:
323
+ """
324
+ Generates a personalized travel itinerary by sequentially running defined tasks.
325
+ """
326
  print("\nGenerating your personalized travel itinerary...\n")
327
 
328
+ # Create input context using f-string formatting
329
+ input_context = (
330
+ f"Travel Request Details:\n"
331
+ f"Origin: {user_input['origin']}\n"
332
+ f"Destination: {user_input['destination']}\n"
333
+ f"Duration: {user_input['duration']} days\n"
334
+ f"Budget Level: {user_input['budget']}\n"
335
+ f"Preferences/Interests: {user_input['preferences']}\n"
336
+ f"Special Requirements: {user_input['special_requirements']}\n"
337
+ )
338
 
339
  # Step 1: Destination Research
340
  print("Researching your destination...")
341
+ destination_info = run_task(destination_research_task, input_context)
 
 
 
 
 
 
342
  print("✓ Destination research completed")
343
 
344
  # Step 2: Accommodation Recommendations
345
  print("Finding ideal accommodations...")
346
+ accommodation_info = run_task(accommodation_task, input_context)
 
 
 
 
 
 
 
347
  print("✓ Accommodation recommendations completed")
348
 
349
  # Step 3: Transportation Planning
350
  print("Planning transportation...")
351
+ transportation_info = run_task(transportation_task, input_context)
 
 
 
 
 
 
352
  print("✓ Transportation planning completed")
353
 
354
  # Step 4: Activities & Attractions
355
  print("Curating activities and attractions...")
356
+ activities_info = run_task(activities_task, input_context)
 
 
 
 
 
 
357
  print("✓ Activities and attractions curated")
358
 
359
  # Step 5: Dining Recommendations
360
  print("Finding dining experiences...")
361
+ dining_info = run_task(dining_task, input_context)
 
 
 
 
 
 
362
  print("✓ Dining recommendations completed")
363
 
364
  # Step 6: Create Day-by-Day Itinerary
365
  print("Creating your day-by-day itinerary...")
366
+ combined_info = (
367
+ input_context + "\n"
368
+ "Destination Information:\n" + destination_info + "\n"
369
+ "Accommodation Options:\n" + accommodation_info + "\n"
370
+ "Transportation Plan:\n" + transportation_info + "\n"
371
+ "Recommended Activities:\n" + activities_info + "\n"
372
+ "Dining Recommendations:\n" + dining_info + "\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  )
374
+ itinerary = run_task(itinerary_task, combined_info)
375
  print("✓ Itinerary creation completed")
 
 
376
  print("✓ Itinerary generation completed")
377
 
378
  return itinerary
379
 
380
+ # -------------------------------------------------------------------------------
381
  # Save Itinerary to File
382
+ # -------------------------------------------------------------------------------
383
+ def save_itinerary_to_file(itinerary: str, user_input: dict, output_dir: str = None) -> str:
384
+ """
385
+ Saves the generated itinerary to a text file and returns the filepath.
386
+ """
387
  date_str = datetime.now().strftime("%Y-%m-%d")
388
  filename = f"{user_input['destination'].replace(' ', '_')}_{date_str}_itinerary.txt"
389
 
 
390
  if output_dir:
391
  if not os.path.exists(output_dir):
392
  try:
393
  os.makedirs(output_dir)
394
+ logging.info(f"Created output directory: {output_dir}")
395
  except Exception as e:
396
+ logging.error(f"Error creating directory {output_dir}: {e}")
397
+ return ""
 
 
398
  filepath = os.path.join(output_dir, filename)
399
  else:
400
  filepath = filename
 
402
  try:
403
  with open(filepath, "w", encoding="utf-8") as f:
404
  f.write(itinerary)
405
+ logging.info(f"Your itinerary has been saved as: {filepath}")
406
  return filepath
407
  except Exception as e:
408
+ logging.error(f"Error saving itinerary: {e}")
409
+ return ""
410
 
411
+ # -------------------------------------------------------------------------------
412
  # Main Function
413
+ # -------------------------------------------------------------------------------
414
+ def main() -> None:
415
+ """
416
+ Main entry point for the travel itinerary generator application.
417
+ """
418
  print("Welcome to BlockX Travel Itinerary Generator!")
419
  print("This AI-powered tool will create a personalized travel itinerary based on your preferences.")
420
 
421
  user_input = get_user_input()
422
 
 
423
  print("\nWhere would you like to save the itinerary?")
424
  print("Press Enter to save in the current directory, or specify a path:")
425
+ output_dir = input("> ").strip() or None
 
 
 
 
 
426
 
427
  itinerary = generate_travel_itinerary(user_input)
428
 
429
+ filepath = save_itinerary_to_file(itinerary, user_input, output_dir)
430
 
431
+ if filepath:
432
+ print(f"\nYour personalized travel itinerary is ready! Open {filepath} to view it.")
433
  print("Thank you for using BlockX Travel Itinerary Generator!")
434
 
435
  if __name__ == "__main__":