Spaces:
Sleeping
Sleeping
Update app.py
Browse filesFixed Image Tool
app.py
CHANGED
|
@@ -100,6 +100,12 @@ def get_time_difference(origin_city: str, destination_city: str) -> str:
|
|
| 100 |
"shanghai": 8, "hong kong": 8, "manila": 8, "kuala lumpur": 8,
|
| 101 |
"jakarta": 7, "delhi": 5.5, "rio de janeiro": -3, "sao paulo": -3,
|
| 102 |
"buenos aires": -3, "mexico city": -6, "toronto": -5, "vancouver": -8,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
}
|
| 104 |
|
| 105 |
origin_key = origin_city.lower().strip()
|
|
@@ -214,25 +220,25 @@ def generate_travel_images(destination: str) -> str:
|
|
| 214 |
Generate two realistic placeholder image URLs for the destination using Unsplash API (no key required).
|
| 215 |
|
| 216 |
Args:
|
| 217 |
-
destination: Destination city name (e.g., "
|
| 218 |
|
| 219 |
Returns:
|
| 220 |
-
JSON-formatted string containing two image URLs
|
| 221 |
"""
|
| 222 |
try:
|
| 223 |
-
# Clean destination name for URL
|
| 224 |
-
clean_dest = re.sub(r"[^a-zA-Z\s]", "", destination).strip()
|
| 225 |
|
| 226 |
-
# Landmark image
|
| 227 |
-
landmark_url = f"https://source.unsplash.com/800x600/?{clean_dest},landmark,architecture"
|
| 228 |
|
| 229 |
-
# Street scene image
|
| 230 |
-
street_url = f"https://source.unsplash.com/800x600/?{clean_dest},street,people,culture"
|
| 231 |
|
| 232 |
return f'{{"landmark_image": "{landmark_url}", "street_scene_image": "{street_url}"}}'
|
| 233 |
-
except Exception
|
| 234 |
-
# Fallback generic travel images
|
| 235 |
-
return '{"landmark_image": "https://source.unsplash.com/800x600/?
|
| 236 |
|
| 237 |
@tool
|
| 238 |
def assemble_catalogue(
|
|
@@ -250,9 +256,9 @@ def assemble_catalogue(
|
|
| 250 |
Compile all travel research into a beautiful, structured Markdown travel catalogue.
|
| 251 |
|
| 252 |
Args:
|
| 253 |
-
destination: Destination city name (e.g., "
|
| 254 |
-
origin: Traveler's home city (e.g., "
|
| 255 |
-
dates: Travel date range (e.g., "
|
| 256 |
budget_summary: Formatted budget conversion string
|
| 257 |
weather: Weather forecast with packing advice
|
| 258 |
timezone_info: Time difference and jet lag guidance
|
|
@@ -266,12 +272,16 @@ def assemble_catalogue(
|
|
| 266 |
import json
|
| 267 |
try:
|
| 268 |
images = json.loads(image_urls_json)
|
| 269 |
-
img1 = images.get("landmark_image", "https://source.unsplash.com/800x600/?travel")
|
| 270 |
-
img2 = images.get("street_scene_image", "https://source.unsplash.com/800x600/?street")
|
| 271 |
except:
|
| 272 |
img1 = "https://source.unsplash.com/800x600/?travel,landmark"
|
| 273 |
img2 = "https://source.unsplash.com/800x600/?travel,street"
|
| 274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
return f"""# 🌍 {destination} Travel Catalogue
|
| 276 |
*Planned from {origin} • {dates} • {budget_summary}*
|
| 277 |
|
|
@@ -287,7 +297,7 @@ def assemble_catalogue(
|
|
| 287 |
|
| 288 |
---
|
| 289 |
|
| 290 |
-
## 🗓️ Your Personalized {
|
| 291 |
{itinerary}
|
| 292 |
|
| 293 |
---
|
|
@@ -327,7 +337,7 @@ def assemble_catalogue(
|
|
| 327 |
if __name__ == "__main__":
|
| 328 |
print("🚀 Initializing Travel Catalogue Creator...")
|
| 329 |
|
| 330 |
-
# Load tools
|
| 331 |
web_search = DuckDuckGoSearchTool()
|
| 332 |
|
| 333 |
model = HfApiModel(
|
|
@@ -336,9 +346,9 @@ if __name__ == "__main__":
|
|
| 336 |
model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
|
| 337 |
)
|
| 338 |
|
| 339 |
-
#
|
| 340 |
system_prompt = """
|
| 341 |
-
You are TravelCatalogueCreator, an expert travel planner.
|
| 342 |
|
| 343 |
1. RESEARCH: Use DuckDuckGoSearchTool to find:
|
| 344 |
- Top 4-5 attractions in {destination}
|
|
@@ -368,18 +378,19 @@ You are TravelCatalogueCreator, an expert travel planner. ALWAYS follow this EXA
|
|
| 368 |
- trip_type="city" (default unless beach/mountain specified)
|
| 369 |
|
| 370 |
7. IMAGES: CALL generate_travel_images EXACTLY ONCE with {destination}
|
| 371 |
-
→ Returns JSON with
|
| 372 |
→ CRITICAL: You MUST use this tool - do not skip image generation
|
| 373 |
|
| 374 |
8. ASSEMBLE: Use assemble_catalogue with ALL previous outputs including image URLs JSON
|
| 375 |
|
| 376 |
-
|
| 377 |
-
• NEVER
|
| 378 |
• NEVER call final_answer directly – always use assemble_catalogue first
|
| 379 |
-
•
|
| 380 |
-
•
|
| 381 |
-
• Budget must be converted to local currency before itinerary planning
|
| 382 |
• You MUST complete all 8 steps before finishing
|
|
|
|
|
|
|
| 383 |
"""
|
| 384 |
|
| 385 |
agent = CodeAgent(
|
|
|
|
| 100 |
"shanghai": 8, "hong kong": 8, "manila": 8, "kuala lumpur": 8,
|
| 101 |
"jakarta": 7, "delhi": 5.5, "rio de janeiro": -3, "sao paulo": -3,
|
| 102 |
"buenos aires": -3, "mexico city": -6, "toronto": -5, "vancouver": -8,
|
| 103 |
+
"lisbon": 0, "porto": 0, "brussels": 1, "zurich": 1, "geneva": 1,
|
| 104 |
+
"milan": 1, "florence": 1, "venice": 1, "naples": 1, "dublin": 0,
|
| 105 |
+
"edinburgh": 0, "glasgow": 0, "manchester": 0, "birmingham": 0,
|
| 106 |
+
"krakow": 1, "gdansk": 1, "wroclaw": 1, "riga": 2, "vilnius": 2,
|
| 107 |
+
"tallinn": 2, "sofia": 2, "bucharest": 2, "zagreb": 1, "ljubljana": 1,
|
| 108 |
+
"belgrade": 1, "sarajevo": 1, "nicosia": 2, "valletta": 1, "reykjavik": 0,
|
| 109 |
}
|
| 110 |
|
| 111 |
origin_key = origin_city.lower().strip()
|
|
|
|
| 220 |
Generate two realistic placeholder image URLs for the destination using Unsplash API (no key required).
|
| 221 |
|
| 222 |
Args:
|
| 223 |
+
destination: Destination city name (e.g., "Lisbon")
|
| 224 |
|
| 225 |
Returns:
|
| 226 |
+
JSON-formatted string containing two image URLs with keys "landmark_image" and "street_scene_image"
|
| 227 |
"""
|
| 228 |
try:
|
| 229 |
+
# Clean destination name for URL (remove special chars, keep spaces for Unsplash)
|
| 230 |
+
clean_dest = re.sub(r"[^a-zA-Z\s]", "", destination).strip()
|
| 231 |
|
| 232 |
+
# Landmark image - use landmark/architecture keywords
|
| 233 |
+
landmark_url = f"https://source.unsplash.com/800x600/?{clean_dest},landmark,architecture,travel"
|
| 234 |
|
| 235 |
+
# Street scene image - use street/people/culture keywords
|
| 236 |
+
street_url = f"https://source.unsplash.com/800x600/?{clean_dest},street,people,culture,travel"
|
| 237 |
|
| 238 |
return f'{{"landmark_image": "{landmark_url}", "street_scene_image": "{street_url}"}}'
|
| 239 |
+
except Exception:
|
| 240 |
+
# Fallback generic travel images with correct JSON keys
|
| 241 |
+
return '{"landmark_image": "https://source.unsplash.com/800x600/?europe,landmark,travel", "street_scene_image": "https://source.unsplash.com/800x600/?europe,street,people"}'
|
| 242 |
|
| 243 |
@tool
|
| 244 |
def assemble_catalogue(
|
|
|
|
| 256 |
Compile all travel research into a beautiful, structured Markdown travel catalogue.
|
| 257 |
|
| 258 |
Args:
|
| 259 |
+
destination: Destination city name (e.g., "Lisbon")
|
| 260 |
+
origin: Traveler's home city (e.g., "London")
|
| 261 |
+
dates: Travel date range (e.g., "Sep 20-22, 2026")
|
| 262 |
budget_summary: Formatted budget conversion string
|
| 263 |
weather: Weather forecast with packing advice
|
| 264 |
timezone_info: Time difference and jet lag guidance
|
|
|
|
| 272 |
import json
|
| 273 |
try:
|
| 274 |
images = json.loads(image_urls_json)
|
| 275 |
+
img1 = images.get("landmark_image", "https://source.unsplash.com/800x600/?travel,landmark")
|
| 276 |
+
img2 = images.get("street_scene_image", "https://source.unsplash.com/800x600/?travel,street")
|
| 277 |
except:
|
| 278 |
img1 = "https://source.unsplash.com/800x600/?travel,landmark"
|
| 279 |
img2 = "https://source.unsplash.com/800x600/?travel,street"
|
| 280 |
|
| 281 |
+
# Count days from itinerary for header
|
| 282 |
+
import re
|
| 283 |
+
day_count = len(re.findall(r'DAY\s+\d+', itinerary))
|
| 284 |
+
|
| 285 |
return f"""# 🌍 {destination} Travel Catalogue
|
| 286 |
*Planned from {origin} • {dates} • {budget_summary}*
|
| 287 |
|
|
|
|
| 297 |
|
| 298 |
---
|
| 299 |
|
| 300 |
+
## 🗓️ Your Personalized {day_count}-Day Itinerary
|
| 301 |
{itinerary}
|
| 302 |
|
| 303 |
---
|
|
|
|
| 337 |
if __name__ == "__main__":
|
| 338 |
print("🚀 Initializing Travel Catalogue Creator...")
|
| 339 |
|
| 340 |
+
# Load tools
|
| 341 |
web_search = DuckDuckGoSearchTool()
|
| 342 |
|
| 343 |
model = HfApiModel(
|
|
|
|
| 346 |
model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
|
| 347 |
)
|
| 348 |
|
| 349 |
+
# ENHANCED SYSTEM PROMPT: Prevent code generation, enforce pure tool usage
|
| 350 |
system_prompt = """
|
| 351 |
+
You are TravelCatalogueCreator, an expert travel planner. You MUST follow this EXACT 8-step workflow using ONLY tool calls - NEVER write Python code:
|
| 352 |
|
| 353 |
1. RESEARCH: Use DuckDuckGoSearchTool to find:
|
| 354 |
- Top 4-5 attractions in {destination}
|
|
|
|
| 378 |
- trip_type="city" (default unless beach/mountain specified)
|
| 379 |
|
| 380 |
7. IMAGES: CALL generate_travel_images EXACTLY ONCE with {destination}
|
| 381 |
+
→ Returns JSON with "landmark_image" and "street_scene_image" keys
|
| 382 |
→ CRITICAL: You MUST use this tool - do not skip image generation
|
| 383 |
|
| 384 |
8. ASSEMBLE: Use assemble_catalogue with ALL previous outputs including image URLs JSON
|
| 385 |
|
| 386 |
+
RULES YOU MUST FOLLOW:
|
| 387 |
+
• NEVER write Python code blocks - ONLY use tool calls
|
| 388 |
• NEVER call final_answer directly – always use assemble_catalogue first
|
| 389 |
+
• ALWAYS extract concrete values (temps, rates, times) from tool outputs before next step
|
| 390 |
+
• Budget must be converted to local currency BEFORE itinerary planning
|
|
|
|
| 391 |
• You MUST complete all 8 steps before finishing
|
| 392 |
+
• If a tool fails, retry ONCE with simplified parameters before proceeding
|
| 393 |
+
• Keep responses concise and focused on travel planning
|
| 394 |
"""
|
| 395 |
|
| 396 |
agent = CodeAgent(
|