PLBot commited on
Commit
1b4e330
·
verified ·
1 Parent(s): 93f5ade

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -469
app.py CHANGED
@@ -1,488 +1,71 @@
1
- # Travel Companion AI Agent
2
  # This agent helps travelers with destination information, local time, weather forecasts,
3
- # currency conversion, language translation, and visual destination previews.
4
 
5
- from smolagents import CodeAgent, HfApiModel, load_tool, tool
6
  import datetime
7
- import requests
8
- import pytz
9
  import yaml
10
- import random
11
- import json
12
  import os
 
 
13
  from tools.final_answer import FinalAnswerTool
 
 
 
 
 
 
 
 
14
  from Gradio_UI import GradioUI
15
 
16
- # Load the image generation tool once, outside the function
17
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
18
-
19
- # ==================== ORIGINAL TOOLS (ENHANCED) ====================
20
-
21
- @tool
22
- def generate_destination_preview(destination: str) -> str:
23
- """Generates a vibrant, artistic preview image of a travel destination.
24
-
25
- Args:
26
- destination: The travel destination to visualize (e.g., 'Paris', 'Tokyo', 'Bali').
27
-
28
- Returns:
29
- A link to the generated destination preview image.
30
- """
31
- # List of visual styles for variety
32
- styles = [
33
- "sunrise golden hour",
34
- "blue hour twilight",
35
- "vibrant daytime",
36
- "dramatic sunset",
37
- "night lights"
38
- ]
39
-
40
- # Select a random style for variety
41
- style = random.choice(styles)
42
-
43
- # Construct a detailed prompt for the AI model
44
- prompt = f"A beautiful travel photograph of {destination}, {style}, photorealistic, high-resolution, travel photography, highly detailed landmark view"
45
-
46
- # Use the pre-loaded image generation tool
47
- try:
48
- image_url = image_generation_tool(prompt)
49
- return f"Here's a preview of {destination}: {image_url}"
50
- except Exception as e:
51
- return f"Error generating image of {destination}: {str(e)}"
52
-
53
-
54
- @tool
55
- def get_local_time(destination: str) -> str:
56
- """Get the current local time at a travel destination.
57
-
58
- Args:
59
- destination: A city or location name (e.g., 'Paris', 'Tokyo', 'New York').
60
-
61
- Returns:
62
- The current local time at the specified destination.
63
- """
64
- # Map of common tourist destinations to their timezones
65
- destination_timezones = {
66
- "london": "Europe/London",
67
- "paris": "Europe/Paris",
68
- "rome": "Europe/Rome",
69
- "madrid": "Europe/Madrid",
70
- "berlin": "Europe/Berlin",
71
- "amsterdam": "Europe/Amsterdam",
72
- "athens": "Europe/Athens",
73
- "istanbul": "Europe/Istanbul",
74
- "dubai": "Asia/Dubai",
75
- "new delhi": "Asia/Kolkata",
76
- "mumbai": "Asia/Kolkata",
77
- "bangkok": "Asia/Bangkok",
78
- "singapore": "Asia/Singapore",
79
- "tokyo": "Asia/Tokyo",
80
- "seoul": "Asia/Seoul",
81
- "beijing": "Asia/Shanghai",
82
- "shanghai": "Asia/Shanghai",
83
- "hong kong": "Asia/Hong_Kong",
84
- "sydney": "Australia/Sydney",
85
- "melbourne": "Australia/Melbourne",
86
- "auckland": "Pacific/Auckland",
87
- "fiji": "Pacific/Fiji",
88
- "honolulu": "Pacific/Honolulu",
89
- "anchorage": "America/Anchorage",
90
- "los angeles": "America/Los_Angeles",
91
- "san francisco": "America/Los_Angeles",
92
- "las vegas": "America/Los_Angeles",
93
- "denver": "America/Denver",
94
- "chicago": "America/Chicago",
95
- "houston": "America/Chicago",
96
- "new york": "America/New_York",
97
- "miami": "America/New_York",
98
- "toronto": "America/Toronto",
99
- "mexico city": "America/Mexico_City",
100
- "rio de janeiro": "America/Sao_Paulo",
101
- "sao paulo": "America/Sao_Paulo",
102
- "buenos aires": "America/Argentina/Buenos_Aires",
103
- "cairo": "Africa/Cairo",
104
- "cape town": "Africa/Johannesburg",
105
- "johannesburg": "Africa/Johannesburg",
106
- "nairobi": "Africa/Nairobi"
107
- }
108
-
109
- try:
110
- # Normalize the destination name
111
- normalized_dest = destination.lower().strip()
112
-
113
- # Find the closest matching timezone
114
- timezone = None
115
- for city, tz in destination_timezones.items():
116
- if city in normalized_dest or normalized_dest in city:
117
- timezone = tz
118
- break
119
-
120
- if not timezone:
121
- return f"I don't have timezone information for {destination}. Please try a major city nearby."
122
-
123
- # Get current time in that timezone
124
- tz = pytz.timezone(timezone)
125
- local_time = datetime.datetime.now(tz)
126
-
127
- # Format the result
128
- formatted_time = local_time.strftime("%I:%M %p on %A, %B %d, %Y")
129
- time_diff = local_time.utcoffset().total_seconds() / 3600
130
- sign = "+" if time_diff >= 0 else ""
131
-
132
- return f"The current local time in {destination} is {formatted_time} (UTC{sign}{int(time_diff)})"
133
-
134
- except Exception as e:
135
- return f"Error getting local time for {destination}: {str(e)}"
136
-
137
- # ==================== NEW TRAVEL-SPECIFIC TOOLS ====================
138
-
139
- @tool
140
- def get_weather_forecast(destination: str, days: int = 3) -> str:
141
- """Get the weather forecast for a travel destination.
142
-
143
- Args:
144
- destination: City or location name
145
- days: Number of days to forecast (default: 3)
146
-
147
- Returns:
148
- Weather forecast information for trip planning
149
- """
150
- try:
151
- # In a production environment, you would use a real API key
152
- API_KEY = os.environ.get("WEATHER_API_KEY", "demo_key")
153
-
154
- # For demo purposes, we'll generate simulated weather data
155
- # In a real implementation, you would call an actual weather API
156
- weather_conditions = ["Sunny", "Partly Cloudy", "Cloudy", "Light Rain", "Heavy Rain", "Thunderstorms", "Windy", "Foggy", "Snow", "Clear"]
157
-
158
- # Create a deterministic but seemingly random forecast based on destination name
159
- seed = sum(ord(c) for c in destination)
160
- random.seed(seed)
161
-
162
- # Generate forecast data
163
- forecast_text = f"🌦️ Weather forecast for {destination}:\n\n"
164
-
165
- today = datetime.datetime.now()
166
- for i in range(days):
167
- day = today + datetime.timedelta(days=i)
168
- day_name = day.strftime("%A")
169
- date = day.strftime("%b %d")
170
-
171
- # "Random" but deterministic weather for the demo
172
- condition = weather_conditions[random.randint(0, len(weather_conditions)-1)]
173
- temp_high = random.randint(15, 35) # Celsius
174
- temp_low = temp_high - random.randint(5, 15)
175
- precipitation = random.randint(0, 100) if "Rain" in condition or "Snow" in condition or "Thunder" in condition else 0
176
-
177
- forecast_text += f"• {day_name}, {date}: {condition}, {temp_low}°C to {temp_high}°C"
178
- if precipitation > 0:
179
- forecast_text += f", {precipitation}% chance of precipitation"
180
- forecast_text += "\n"
181
-
182
- # Add packing recommendations based on conditions
183
- coldest = min([forecast_text.count("Snow"), forecast_text.count("0°C")])
184
- rainiest = forecast_text.count("Rain") + forecast_text.count("Thunder")
185
-
186
- forecast_text += "\n🧳 Packing tips: "
187
- if coldest > 0:
188
- forecast_text += "Bring warm layers and a heavy jacket. "
189
- elif "5°C" in forecast_text or "6°C" in forecast_text or "7°C" in forecast_text:
190
- forecast_text += "Pack a warm jacket and layers. "
191
-
192
- if rainiest > 0:
193
- forecast_text += "Don't forget an umbrella and waterproof footwear. "
194
-
195
- if "Sunny" in forecast_text and "30°C" in forecast_text:
196
- forecast_text += "Bring sunscreen, sunglasses, and light clothing. "
197
-
198
- return forecast_text
199
-
200
- except Exception as e:
201
- return f"Error retrieving weather data for {destination}: {str(e)}"
202
-
203
-
204
- @tool
205
- def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
206
- """Convert an amount between currencies for travel budgeting.
207
-
208
- Args:
209
- amount: The amount to convert
210
- from_currency: Source currency code (e.g., USD, EUR)
211
- to_currency: Target currency code (e.g., JPY, GBP)
212
-
213
- Returns:
214
- Converted amount and exchange rate information
215
- """
216
- try:
217
- # In a production environment, you would use a real API key
218
- # For demo purposes, we'll use fixed exchange rates
219
- # In a real implementation, you would call an actual currency API
220
-
221
- # Common exchange rates (as of early 2025, for demo purposes)
222
- exchange_rates = {
223
- "USD": {"EUR": 0.92, "GBP": 0.79, "JPY": 149.50, "CAD": 1.35, "AUD": 1.52, "CNY": 7.20, "INR": 83.20, "MXN": 17.05},
224
- "EUR": {"USD": 1.09, "GBP": 0.86, "JPY": 163.00, "CAD": 1.47, "AUD": 1.66, "CNY": 7.85, "INR": 90.70, "MXN": 18.60},
225
- "GBP": {"USD": 1.27, "EUR": 1.16, "JPY": 189.30, "CAD": 1.71, "AUD": 1.92, "CNY": 9.10, "INR": 105.30, "MXN": 21.60},
226
- "JPY": {"USD": 0.0067, "EUR": 0.0061, "GBP": 0.0053, "CAD": 0.0090, "AUD": 0.0102, "CNY": 0.0482, "INR": 0.5565, "MXN": 0.1141},
227
- "CAD": {"USD": 0.74, "EUR": 0.68, "GBP": 0.58, "JPY": 110.70, "AUD": 1.13, "CNY": 5.33, "INR": 61.60, "MXN": 12.60},
228
- "AUD": {"USD": 0.66, "EUR": 0.60, "GBP": 0.52, "JPY": 98.40, "CAD": 0.89, "CNY": 4.73, "INR": 54.70, "MXN": 11.20},
229
- "CNY": {"USD": 0.14, "EUR": 0.13, "GBP": 0.11, "JPY": 20.80, "CAD": 0.19, "AUD": 0.21, "INR": 11.60, "MXN": 2.37},
230
- "INR": {"USD": 0.012, "EUR": 0.011, "GBP": 0.0095, "JPY": 1.80, "CAD": 0.016, "AUD": 0.018, "CNY": 0.086, "MXN": 0.205},
231
- "MXN": {"USD": 0.059, "EUR": 0.054, "GBP": 0.046, "JPY": 8.77, "CAD": 0.079, "AUD": 0.089, "CNY": 0.422, "INR": 4.88}
232
- }
233
-
234
- # Normalize currency codes
235
- from_currency = from_currency.upper().strip()
236
- to_currency = to_currency.upper().strip()
237
-
238
- # Validate currencies
239
- if from_currency not in exchange_rates:
240
- return f"Sorry, I don't have exchange rate data for {from_currency}."
241
-
242
- if to_currency not in exchange_rates[from_currency] and to_currency != from_currency:
243
- return f"Sorry, I don't have exchange rate data from {from_currency} to {to_currency}."
244
-
245
- # If same currency, return original amount
246
- if from_currency == to_currency:
247
- return f"{amount} {from_currency} = {amount} {to_currency}"
248
-
249
- # Get exchange rate and calculate conversion
250
- rate = exchange_rates[from_currency][to_currency]
251
- converted_amount = amount * rate
252
-
253
- # Format the result
254
- return f"💱 {amount:,.2f} {from_currency} = {converted_amount:,.2f} {to_currency}\n\nExchange rate: 1 {from_currency} = {rate} {to_currency}\n\n(Note: Actual rates may vary. For planning purposes only.)"
255
-
256
- except Exception as e:
257
- return f"Error converting currency: {str(e)}"
258
-
259
-
260
- @tool
261
- def translate_phrase(text: str, language: str) -> str:
262
- """Translate common travel phrases to a local language.
263
-
264
- Args:
265
- text: Text to translate (e.g., "Hello", "Thank you", "Where is the bathroom?")
266
- language: Target language (e.g., 'Spanish', 'Japanese', 'French')
267
-
268
- Returns:
269
- Translated text with pronunciation guide
270
- """
271
- try:
272
- # Common travel phrases in various languages
273
- # In a production environment, you would use a real translation API
274
- language = language.lower().strip()
275
- text_lower = text.lower().strip()
276
-
277
- phrase_translations = {
278
- "hello": {
279
- "spanish": {"text": "Hola", "pronunciation": "oh-lah"},
280
- "french": {"text": "Bonjour", "pronunciation": "bohn-zhoor"},
281
- "italian": {"text": "Ciao", "pronunciation": "chow"},
282
- "german": {"text": "Hallo", "pronunciation": "hah-loh"},
283
- "japanese": {"text": "こんにちは (Konnichiwa)", "pronunciation": "kohn-nee-chee-wah"},
284
- "mandarin": {"text": "你好 (Nǐ hǎo)", "pronunciation": "nee how"},
285
- "arabic": {"text": "مرحبا (Marhaba)", "pronunciation": "mar-ha-ba"},
286
- "russian": {"text": "Здравствуйте (Zdravstvuyte)", "pronunciation": "zdrah-stvooy-tye"},
287
- "portuguese": {"text": "Olá", "pronunciation": "oh-lah"},
288
- "thai": {"text": "สวัสดี (Sawatdee)", "pronunciation": "sa-wat-dee"}
289
- },
290
- "thank you": {
291
- "spanish": {"text": "Gracias", "pronunciation": "grah-see-ahs"},
292
- "french": {"text": "Merci", "pronunciation": "mair-see"},
293
- "italian": {"text": "Grazie", "pronunciation": "graht-see-eh"},
294
- "german": {"text": "Danke", "pronunciation": "dahn-kuh"},
295
- "japanese": {"text": "ありがとう (Arigatou)", "pronunciation": "ah-ree-gah-toh"},
296
- "mandarin": {"text": "谢谢 (Xièxiè)", "pronunciation": "shyeh-shyeh"},
297
- "arabic": {"text": "شكرا (Shukran)", "pronunciation": "shoo-kran"},
298
- "russian": {"text": "Спасибо (Spasibo)", "pronunciation": "spah-see-boh"},
299
- "portuguese": {"text": "Obrigado/a", "pronunciation": "oh-bree-gah-doo/dah"},
300
- "thai": {"text": "ขอบคุณ (Khop khun)", "pronunciation": "kop-koon"}
301
- },
302
- "excuse me": {
303
- "spanish": {"text": "Disculpe", "pronunciation": "dees-kool-peh"},
304
- "french": {"text": "Excusez-moi", "pronunciation": "ex-koo-zay mwah"},
305
- "italian": {"text": "Scusi", "pronunciation": "skoo-zee"},
306
- "german": {"text": "Entschuldigung", "pronunciation": "ent-shool-di-goong"},
307
- "japanese": {"text": "すみません (Sumimasen)", "pronunciation": "soo-mee-mah-sen"},
308
- "mandarin": {"text": "对不起 (Duìbùqǐ)", "pronunciation": "dway-boo-chee"},
309
- "arabic": {"text": "عفوا (Afwan)", "pronunciation": "af-wan"},
310
- "russian": {"text": "Извините (Izvinite)", "pronunciation": "eez-vee-nee-tye"},
311
- "portuguese": {"text": "Com licença", "pronunciation": "com lee-sen-sah"},
312
- "thai": {"text": "ขอโทษ (Kho thot)", "pronunciation": "kor-toht"}
313
- },
314
- "where is the bathroom": {
315
- "spanish": {"text": "¿Dónde está el baño?", "pronunciation": "don-deh es-tah el ban-yo"},
316
- "french": {"text": "Où sont les toilettes?", "pronunciation": "oo son lay twa-let"},
317
- "italian": {"text": "Dov'è il bagno?", "pronunciation": "doh-veh eel ban-yo"},
318
- "german": {"text": "Wo ist die Toilette?", "pronunciation": "vo ist dee twa-let-te"},
319
- "japanese": {"text": "トイレはどこですか (Toire wa doko desu ka)", "pronunciation": "toy-reh wah doh-koh des-kah"},
320
- "mandarin": {"text": "厕所在哪里 (Cèsuǒ zài nǎlǐ)", "pronunciation": "tsuh-swor dzeye nah-lee"},
321
- "arabic": {"text": "أين الحمام (Ayna al-hammam)", "pronunciation": "eye-nah al-ham-mam"},
322
- "russian": {"text": "Где туалет (Gde tualet)", "pronunciation": "g-dyeh too-ah-lyet"},
323
- "portuguese": {"text": "Onde fica o banheiro?", "pronunciation": "on-jee fee-ka oo ban-yay-roo"},
324
- "thai": {"text": "ห้องน้ำอยู่ที่ไหน (Hong nam yu tee nai)", "pronunciation": "hong nam yoo tee nai"}
325
- },
326
- "how much": {
327
- "spanish": {"text": "¿Cuánto cuesta?", "pronunciation": "kwan-toh kwes-tah"},
328
- "french": {"text": "Combien ça coûte?", "pronunciation": "kom-bee-en sa koot"},
329
- "italian": {"text": "Quanto costa?", "pronunciation": "kwan-toh kos-tah"},
330
- "german": {"text": "Wie viel kostet das?", "pronunciation": "vee feel kos-tet das"},
331
- "japanese": {"text": "いくらですか (Ikura desu ka)", "pronunciation": "ee-koo-rah des-kah"},
332
- "mandarin": {"text": "多少钱 (Duōshǎo qián)", "pronunciation": "dwor-shaow chyen"},
333
- "arabic": {"text": "كم الثمن (Kam althaman)", "pronunciation": "kam al-tha-man"},
334
- "russian": {"text": "Сколько это стоит (Skol'ko eto stoit)", "pronunciation": "skol-ka eh-ta stoh-eet"},
335
- "portuguese": {"text": "Quanto custa?", "pronunciation": "kwan-too koos-tah"},
336
- "thai": {"text": "ราคาเท่าไหร่ (Raka tao rai)", "pronunciation": "ra-ka tao-rai"}
337
- }
338
- }
339
-
340
- # Find the phrase key that most closely matches the input text
341
- matched_phrase = None
342
- for phrase in phrase_translations:
343
- if phrase in text_lower or text_lower in phrase:
344
- matched_phrase = phrase
345
- break
346
-
347
- if not matched_phrase:
348
- return f"I don't have a translation for '{text}'. Try common travel phrases like 'hello', 'thank you', 'excuse me', etc."
349
-
350
- # Find the language that most closely matches the input language
351
- matched_language = None
352
- for lang in phrase_translations[matched_phrase]:
353
- if lang in language or language in lang:
354
- matched_language = lang
355
- break
356
-
357
- if not matched_language:
358
- return f"I don't have translations for {language}. Try languages like Spanish, French, Italian, German, Japanese, etc."
359
-
360
- # Get the translation
361
- translation = phrase_translations[matched_phrase][matched_language]
362
-
363
- return f"🗣️ '{text}' in {matched_language.capitalize()}:\n\n{translation['text']}\n\nPronunciation: {translation['pronunciation']}"
364
-
365
- except Exception as e:
366
- return f"Error translating text: {str(e)}"
367
-
368
-
369
- @tool
370
- def get_visa_requirements(nationality: str, destination: str) -> str:
371
- """Check visa requirements for traveling to a destination.
372
-
373
- Args:
374
- nationality: Traveler's passport country (e.g., 'US', 'UK', 'Canada')
375
- destination: Country to visit (e.g., 'Japan', 'France', 'Brazil')
376
-
377
- Returns:
378
- Visa requirement information
379
- """
380
- try:
381
- # Normalize inputs
382
- nationality = nationality.lower().strip()
383
- destination = destination.lower().strip()
384
-
385
- # Map of common country names to their normalized forms
386
- country_mapping = {
387
- "us": "united states", "usa": "united states", "united states of america": "united states",
388
- "uk": "united kingdom", "britain": "united kingdom", "great britain": "united kingdom",
389
- "uae": "united arab emirates",
390
- # Add more mappings as needed
391
- }
392
-
393
- # Apply mappings if available
394
- nationality = country_mapping.get(nationality, nationality)
395
- destination = country_mapping.get(destination, destination)
396
-
397
- # Skip if same country (generally no visa needed for citizens)
398
- if nationality == destination:
399
- return f"As a citizen of {nationality.title()}, you generally don't need a visa to visit your own country."
400
-
401
- # Sample visa requirement data
402
- # In a production environment, this would be a comprehensive database or API call
403
- visa_data = {
404
- "united states": {
405
- "european union": "No visa required for stays up to 90 days",
406
- "united kingdom": "No visa required for stays up to 6 months",
407
- "japan": "No visa required for stays up to 90 days",
408
- "australia": "Electronic Travel Authority (ETA) required",
409
- "china": "Visa required, must apply in advance",
410
- "india": "e-Visa available, apply online before travel",
411
- "brazil": "No visa required for stays up to 90 days",
412
- "mexico": "No visa required for stays up to 180 days",
413
- "south africa": "No visa required for stays up to 90 days",
414
- "thailand": "No visa required for stays up to 30 days"
415
- },
416
- "united kingdom": {
417
- "european union": "No visa required for stays up to 90 days",
418
- "united states": "ESTA required for entry",
419
- "japan": "No visa required for stays up to 90 days",
420
- "australia": "eVisitor visa required",
421
- "china": "Visa required, must apply in advance",
422
- "india": "e-Visa available, apply online before travel",
423
- "brazil": "No visa required for stays up to 90 days",
424
- "mexico": "No visa required for stays up to 180 days",
425
- "south africa": "No visa required for stays up to 90 days",
426
- "thailand": "No visa required for stays up to 30 days"
427
- },
428
- # Add more countries as needed
429
- }
430
-
431
- # Check if we have data for this nationality
432
- if nationality not in visa_data:
433
- return f"I don't have specific visa information for citizens of {nationality.title()}. Please check with the embassy of {destination.title()} for accurate visa requirements."
434
-
435
- # Check if we have data for this destination
436
- if destination not in visa_data[nationality]:
437
- return f"I don't have specific visa information for {nationality.title()} citizens traveling to {destination.title()}. Please check with the embassy of {destination.title()} for accurate visa requirements."
438
-
439
- # Get the visa requirements
440
- requirements = visa_data[nationality][destination]
441
-
442
- return f"🛂 Visa requirements for {nationality.title()} citizens traveling to {destination.title()}:\n\n{requirements}\n\n(Note: Visa requirements may change. Always verify with the official embassy or consulate before travel.)"
443
-
444
- except Exception as e:
445
- return f"Error retrieving visa information: {str(e)}"
446
-
447
  # ==================== AGENT SETUP ====================
448
 
 
449
  final_answer = FinalAnswerTool()
450
-
451
- # # Model initialization
452
- # model = HfApiModel(
453
- # max_tokens=2096,
454
- # temperature=0.7, # Slightly higher temperature for more creative responses
455
- # model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
456
- # custom_role_conversions=None,
457
- # )
458
-
 
459
  model = HfApiModel(
460
  max_tokens=2096,
461
- temperature=0.7, # Slightly higher temperature for more creative responses
462
  model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud', # Use the AWS endpoint
463
  custom_role_conversions=None,
464
  )
465
 
466
-
467
  # Load prompts
468
- with open("prompts.yaml", 'r') as stream:
469
- prompt_templates = yaml.safe_load(stream)
 
 
 
 
 
470
 
471
  # Add travel companion specific instructions to the prompt templates
472
  travel_agent_prompt = """
473
- You are TravelBuddy, an AI travel companion designed to help travelers plan and navigate their journeys.
474
  Your goal is to provide helpful, accurate information about destinations, local customs, and practical travel advice.
475
 
476
  You have access to these capabilities:
477
- 1. Generate visual previews of destinations
478
- 2. Check local time at travel destinations
479
- 3. Provide weather forecasts for trip planning
480
- 4. Convert currencies for travel budgeting
481
- 5. Translate common travel phrases
482
- 6. Check visa requirements
 
 
483
 
484
  When users ask about a destination, try to provide comprehensive information by combining multiple tools.
485
- For example, if someone asks about Tokyo, consider providing the local time, weather, and a visual preview.
486
 
487
  Always be enthusiastic about travel while remaining practical and informative.
488
  Suggest off-the-beaten-path experiences when appropriate, but prioritize the specific information requested.
@@ -499,22 +82,40 @@ agent = CodeAgent(
499
  model=model,
500
  tools=[
501
  final_answer,
502
- generate_destination_preview, # Enhanced version of original image tool
503
- get_local_time, # Enhanced version of original time tool
504
- get_weather_forecast, # New travel tool
505
- convert_currency, # New travel tool
506
- translate_phrase, # New travel tool
507
- get_visa_requirements, # New travel tool
 
 
508
  ],
509
  max_steps=8, # Increased to allow for more tool usage in a single query
510
  verbosity_level=1,
511
  grammar=None,
512
  planning_interval=None,
513
- name="TravelBuddy",
514
  description="Your AI travel companion",
515
- prompt_templates=prompt_templates
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  )
517
 
518
  # Launch the UI
519
- print("Launching TravelBuddy - Your AI Travel Companion")
520
- GradioUI(agent).launch()
 
 
 
1
+ # Journi - Your AI Travel Companion
2
  # This agent helps travelers with destination information, local time, weather forecasts,
3
+ # currency conversion, language translation, and destination previews.
4
 
5
+ from smolagents import CodeAgent, HfApiModel, load_tool
6
  import datetime
 
 
7
  import yaml
 
 
8
  import os
9
+
10
+ # Import all the tool classes from their respective files
11
  from tools.final_answer import FinalAnswerTool
12
+ from tools.web_search import DuckDuckGoSearchTool
13
+ from tools.visit_webpage import VisitWebpageTool
14
+ from tools.generate_destination_preview import GenerateDestinationPreviewTool
15
+ from tools.get_local_time import GetLocalTimeTool
16
+ from tools.get_weather_forecast import GetWeatherForecastTool
17
+ from tools.convert_currency import ConvertCurrencyTool
18
+ from tools.translate_phrase import TranslatePhraseTool
19
+ from tools.get_visa_requirements import GetVisaRequirementsTool
20
  from Gradio_UI import GradioUI
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  # ==================== AGENT SETUP ====================
23
 
24
+ # Initialize all tool instances
25
  final_answer = FinalAnswerTool()
26
+ web_search = DuckDuckGoSearchTool(max_results=5) # Limit results for better readability
27
+ visit_webpage = VisitWebpageTool()
28
+ generate_destination_preview = GenerateDestinationPreviewTool()
29
+ get_local_time = GetLocalTimeTool()
30
+ get_weather_forecast = GetWeatherForecastTool()
31
+ convert_currency = ConvertCurrencyTool()
32
+ translate_phrase = TranslatePhraseTool()
33
+ get_visa_requirements = GetVisaRequirementsTool()
34
+
35
+ # Model initialization
36
  model = HfApiModel(
37
  max_tokens=2096,
38
+ temperature=0.5, # Balanced between creativity and accuracy
39
  model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud', # Use the AWS endpoint
40
  custom_role_conversions=None,
41
  )
42
 
 
43
  # Load prompts
44
+ try:
45
+ with open("prompts.yaml", 'r') as stream:
46
+ prompt_templates = yaml.safe_load(stream)
47
+ except FileNotFoundError:
48
+ # Create a basic template if file doesn't exist
49
+ prompt_templates = {}
50
+ print("Warning: prompts.yaml not found. Using default prompt templates.")
51
 
52
  # Add travel companion specific instructions to the prompt templates
53
  travel_agent_prompt = """
54
+ You are Journi, an AI travel companion designed to help travelers plan and navigate their journeys.
55
  Your goal is to provide helpful, accurate information about destinations, local customs, and practical travel advice.
56
 
57
  You have access to these capabilities:
58
+ 1. Search for travel information online
59
+ 2. Visit webpages to get detailed information
60
+ 3. Provide vivid descriptions of travel destinations
61
+ 4. Check local time at travel destinations
62
+ 5. Provide weather forecasts for trip planning
63
+ 6. Convert currencies for travel budgeting
64
+ 7. Translate common travel phrases
65
+ 8. Check visa requirements
66
 
67
  When users ask about a destination, try to provide comprehensive information by combining multiple tools.
68
+ For example, if someone asks about Tokyo, consider providing the local time, weather, and a descriptive preview.
69
 
70
  Always be enthusiastic about travel while remaining practical and informative.
71
  Suggest off-the-beaten-path experiences when appropriate, but prioritize the specific information requested.
 
82
  model=model,
83
  tools=[
84
  final_answer,
85
+ web_search,
86
+ visit_webpage,
87
+ generate_destination_preview,
88
+ get_local_time,
89
+ get_weather_forecast,
90
+ convert_currency,
91
+ translate_phrase,
92
+ get_visa_requirements,
93
  ],
94
  max_steps=8, # Increased to allow for more tool usage in a single query
95
  verbosity_level=1,
96
  grammar=None,
97
  planning_interval=None,
98
+ name="Journi",
99
  description="Your AI travel companion",
100
+ prompt_templates=prompt_templates,
101
+ authorized_imports=[
102
+ "unicodedata",
103
+ "stat",
104
+ "datetime",
105
+ "random",
106
+ "pandas",
107
+ "itertools",
108
+ "math",
109
+ "statistics",
110
+ "queue",
111
+ "time",
112
+ "collections",
113
+ "re"
114
+ ]
115
  )
116
 
117
  # Launch the UI
118
+ if __name__ == "__main__":
119
+ print("✈️ Launching Journi - Your AI Travel Companion")
120
+ print("Ask me about any destination, local time, weather, currency conversion, or travel phrases!")
121
+ GradioUI(agent).launch()