agarwalamit081 commited on
Commit
4d246f4
·
verified ·
1 Parent(s): 0b0df6d

Update app.py

Browse files

simpler version

Files changed (1) hide show
  1. app.py +60 -146
app.py CHANGED
@@ -5,20 +5,19 @@ import requests
5
  from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
6
  from tools.final_answer import FinalAnswerTool
7
  from Gradio_UI import GradioUI
8
- import yaml
9
 
10
  # ======================
11
- # MINIMAL TRAVEL TOOLS (SMOLAGENTS-COMPLIANT)
12
  # ======================
13
 
14
  @tool
15
- def get_weather_forecast(location: str, travel_dates: str) -> str:
16
  """
17
- Get weather forecast for destination using wttr.in.
18
 
19
  Args:
20
- location: Destination city name (e.g., "Barcelona")
21
- travel_dates: Travel date range (e.g., "October 15-19")
22
 
23
  Returns:
24
  Weather summary with temperature and packing advice
@@ -26,122 +25,54 @@ def get_weather_forecast(location: str, travel_dates: str) -> str:
26
  try:
27
  clean = re.sub(r'[^a-zA-Z0-9\s]', '', location).replace(' ', '+')
28
  data = requests.get(f"http://wttr.in/{clean}?format=j1", timeout=10).json()
29
- cur = data['current_condition'][0]
30
- temp = int(cur['temp_C'])
31
- cond = cur['lang_en'][0]['value']
32
- if temp > 20:
33
- pack = "Light layers, sunscreen, hat"
34
- else:
35
- pack = "Warm layers, light jacket"
36
  if "rain" in cond.lower():
37
- pack += " + umbrella"
38
- return f"{location} weather: {temp}°C, {cond}. Packing: {pack}"
39
  except:
40
- return f"{location} typical weather: 15-25°C. Pack light layers + light jacket + umbrella."
41
 
42
 
43
  @tool
44
- def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
45
  """
46
  Convert currency using Frankfurter API.
47
 
48
  Args:
49
  amount: Amount to convert (e.g., 1200.0)
50
- from_currency: Source currency code (e.g., "USD")
51
- to_currency: Target currency code (e.g., "EUR")
52
 
53
  Returns:
54
  Formatted conversion result
55
  """
56
  try:
57
- from_currency = from_currency.upper()
58
- to_currency = to_currency.upper()
59
- if from_currency == to_currency:
60
- return f"{amount:,.0f} {from_currency}"
61
  rate = requests.get(
62
- f"https://api.frankfurter.app/latest?from={from_currency}&to={to_currency}",
63
  timeout=10
64
- ).json()['rates'][to_currency]
65
- return f"{amount:,.0f} {from_currency} = {amount*rate:,.0f} {to_currency} (1 {from_currency} = {rate:.2f} {to_currency})"
66
  except:
67
- return f"{amount:,.0f} {from_currency} (conversion unavailable)"
68
 
69
 
70
  @tool
71
- def generate_packing_list(destination: str, weather_summary: str, trip_days: int, trip_type: str) -> str:
72
  """
73
- Generate packing list based on weather and trip type.
74
-
75
- Args:
76
- destination: Destination name (e.g., "Barcelona")
77
- weather_summary: Weather conditions summary
78
- trip_days: Number of travel days (e.g., 4)
79
- trip_type: Trip type: "sightseeing", "beach", or "hiking"
80
-
81
- Returns:
82
- Formatted packing checklist
83
- """
84
- cold = "cold" in weather_summary.lower() or "jacket" in weather_summary.lower()
85
- rain = "rain" in weather_summary.lower() or "umbrella" in weather_summary.lower()
86
-
87
- tops = trip_days // 2 + 1
88
- bottoms = trip_days // 3 + 1
89
-
90
- clothes = [f"• Tops ({tops})", f"• Bottoms ({bottoms})"]
91
- if cold:
92
- clothes += ["• Warm jacket", "• Beanie + gloves"]
93
- else:
94
- clothes += ["• Light jacket (essential)"]
95
- if rain:
96
- clothes += ["• Compact umbrella", "• Waterproof jacket"]
97
- if trip_type == "beach":
98
- clothes += ["• Swimsuit", "• Flip-flops"]
99
-
100
- return (
101
- f"🎒 PACKING LIST ({trip_days}-day {trip_type})\n"
102
- "ESSENTIALS\n• Passport + copies\n• Cards + small cash\n• Power adapter\n• Phone + charger\n\n"
103
- "CLOTHING\n" + "\n".join(clothes) + "\n\n"
104
- "TOILETRIES\n• Travel toiletries\n• Medications\n• First-aid kit"
105
- )
106
-
107
-
108
- @tool
109
- def build_itinerary(destination: str, attractions: str, budget: float, days: int) -> str:
110
- """
111
- Create day-by-day itinerary.
112
-
113
- Args:
114
- destination: Destination city (e.g., "Barcelona")
115
- attractions: Comma-separated attractions list
116
- budget: Total budget in local currency
117
- days: Number of travel days
118
-
119
- Returns:
120
- Formatted itinerary with daily schedule
121
- """
122
- atts = [a.strip() for a in attractions.split(",") if a.strip()] or ["Old Town", "Museum", "Viewpoint", "Market"]
123
- daily = budget / max(days, 1)
124
- lines = [f"🗓️ {days}-DAY ITINERARY: {destination}"]
125
- for d in range(1, days+1):
126
- am = atts[(d-1) % len(atts)]
127
- pm = atts[d % len(atts)]
128
- lines += [f"DAY {d}", f" 09:00 {am}", f" 14:00 {pm}", f" 💰 Daily budget: ~{daily:,.0f}"]
129
- return "\n".join(lines)
130
-
131
-
132
- @tool
133
- def assemble_catalogue(destination: str, origin: str, dates: str, budget_str: str, weather: str, itinerary: str, packing: str, image_url_1: str, image_url_2: str) -> str:
134
- """
135
- Compile final travel catalogue with embedded images.
136
 
137
  Args:
138
  destination: Destination city (e.g., "Barcelona")
139
  origin: Home city (e.g., "New York")
140
  dates: Travel dates (e.g., "Oct 15-19")
141
- budget_str: Budget conversion result
142
  weather: Weather forecast summary
143
- itinerary: Day-by-day plan
144
- packing: Packing list
145
  image_url_1: First generated image URL from image_generation_tool
146
  image_url_2: Second generated image URL from image_generation_tool
147
 
@@ -149,89 +80,72 @@ def assemble_catalogue(destination: str, origin: str, dates: str, budget_str: st
149
  Beautiful Markdown travel catalogue with embedded images
150
  """
151
  return f"""# 🌍 {destination} Travel Catalogue
152
- *From {origin} • {dates} • Budget: {budget_str}*
153
-
154
- ---
155
 
156
  ## 🌤️ Weather
157
  {weather}
158
 
159
- ---
160
-
161
- ## 🗓️ Itinerary
162
- {itinerary}
163
-
164
- ---
165
-
166
- ## 🎒 Packing List
167
- {packing}
168
-
169
- ---
170
-
171
  ## 📸 Destination Views
172
  ![{destination} landmark]({image_url_1})
173
- *Generated view #1*
174
 
175
  ![{destination} street scene]({image_url_2})
176
- *Generated view #2*
177
-
178
- ---
179
 
180
- > 💡 Book attractions online to skip lines. Use public transport passes for savings.
181
  """
182
 
183
-
184
  # ======================
185
- # AGENT SETUP (IMAGE GENERATION FORCED)
186
  # ======================
187
 
 
188
  final_answer = FinalAnswerTool()
189
  web_search = DuckDuckGoSearchTool()
190
  image_gen = load_tool("agents-course/text-to-image", trust_remote_code=True)
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  model = HfApiModel(
193
- max_tokens=2096,
194
- temperature=0.3, # Lower temp for more reliable tool usage
195
  model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
196
  )
197
 
198
- # CRITICAL: System prompt that FORCES image generation steps
199
- prompt_templates = {
200
- "system_prompt": (
201
- "You are TravelCatalogueCreator. ALWAYS follow this EXACT workflow:\n"
202
- "1. Use DuckDuckGoSearchTool to research destination attractions\n"
203
- "2. Use get_weather_forecast for weather during travel dates\n"
204
- "3. Use convert_currency to show budget in local currency\n"
205
- "4. Use build_itinerary to create day-by-day plan\n"
206
- "5. Use generate_packing_list for packing advice\n"
207
- "6. CALL image_generation_tool EXACTLY TWICE with prompts:\n"
208
- " - First call: '{destination} landmark photorealistic travel photo'\n"
209
- " - Second call: '{destination} street scene vibrant travel photo'\n"
210
- "7. Use assemble_catalogue with BOTH image URLs from step 6\n\n"
211
- "NEVER skip image generation. NEVER call FinalAnswerTool directly. "
212
- "You MUST complete all 7 steps before finishing."
213
- )
214
- }
215
-
216
  agent = CodeAgent(
217
  model=model,
218
  tools=[
219
  final_answer,
220
  web_search,
221
- image_gen, # Must be available for step 6
222
- get_weather_forecast,
223
  convert_currency,
224
- generate_packing_list,
225
- build_itinerary,
226
- assemble_catalogue, # Requires real image URLs as inputs
227
  ],
228
- max_steps=20, # Allow room for 2 image generation steps
229
  verbosity_level=1,
230
- name="TravelCatalogueCreator",
231
- description="Creates beautiful travel catalogues with mandatory image generation",
232
- prompt_templates=prompt_templates,
233
  )
234
 
235
  if __name__ == "__main__":
236
- print("🚀 Travel Catalogue Creator with guaranteed image generation")
237
  GradioUI(agent, file_upload_folder="./uploads").launch()
 
5
  from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
6
  from tools.final_answer import FinalAnswerTool
7
  from Gradio_UI import GradioUI
 
8
 
9
  # ======================
10
+ # MINIMAL COMPLIANT TOOLS (Google-style docstrings REQUIRED)
11
  # ======================
12
 
13
  @tool
14
+ def get_weather(location: str, dates: str) -> str:
15
  """
16
+ Get weather forecast for destination.
17
 
18
  Args:
19
+ location: Destination city (e.g., "Barcelona")
20
+ dates: Travel dates (e.g., "October 15-19")
21
 
22
  Returns:
23
  Weather summary with temperature and packing advice
 
25
  try:
26
  clean = re.sub(r'[^a-zA-Z0-9\s]', '', location).replace(' ', '+')
27
  data = requests.get(f"http://wttr.in/{clean}?format=j1", timeout=10).json()
28
+ temp = int(data['current_condition'][0]['temp_C'])
29
+ cond = data['current_condition'][0]['lang_en'][0]['value']
30
+ advice = "light layers + jacket" if temp < 22 else "light clothing + sunscreen"
 
 
 
 
31
  if "rain" in cond.lower():
32
+ advice += " + umbrella"
33
+ return f"{location}: {temp}°C, {cond}. Pack: {advice}"
34
  except:
35
+ return f"{location}: Typical 18-24°C in Oct. Pack light layers + light jacket + umbrella."
36
 
37
 
38
  @tool
39
+ def convert_currency(amount: float, from_curr: str, to_curr: str) -> str:
40
  """
41
  Convert currency using Frankfurter API.
42
 
43
  Args:
44
  amount: Amount to convert (e.g., 1200.0)
45
+ from_curr: Source currency code (e.g., "USD")
46
+ to_curr: Target currency code (e.g., "EUR")
47
 
48
  Returns:
49
  Formatted conversion result
50
  """
51
  try:
52
+ from_curr = from_curr.upper()
53
+ to_curr = to_curr.upper()
54
+ if from_curr == to_curr:
55
+ return f"{amount:,.0f} {from_curr}"
56
  rate = requests.get(
57
+ f"https://api.frankfurter.app/latest?from={from_curr}&to={to_curr}",
58
  timeout=10
59
+ ).json()['rates'][to_curr]
60
+ return f"{amount:,.0f} {from_curr} = {amount*rate:,.0f} {to_curr}"
61
  except:
62
+ return f"{amount:,.0f} {from_curr} (≈{amount*0.93:,.0f} EUR est.)"
63
 
64
 
65
  @tool
66
+ def build_catalogue(destination: str, origin: str, dates: str, budget: str, weather: str, image_url_1: str, image_url_2: str) -> str:
67
  """
68
+ Assemble final travel catalogue with embedded images.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  Args:
71
  destination: Destination city (e.g., "Barcelona")
72
  origin: Home city (e.g., "New York")
73
  dates: Travel dates (e.g., "Oct 15-19")
74
+ budget: Budget conversion result (e.g., "$1,200 = €1,116")
75
  weather: Weather forecast summary
 
 
76
  image_url_1: First generated image URL from image_generation_tool
77
  image_url_2: Second generated image URL from image_generation_tool
78
 
 
80
  Beautiful Markdown travel catalogue with embedded images
81
  """
82
  return f"""# 🌍 {destination} Travel Catalogue
83
+ *From {origin} • {dates} • Budget: {budget}*
 
 
84
 
85
  ## 🌤️ Weather
86
  {weather}
87
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  ## 📸 Destination Views
89
  ![{destination} landmark]({image_url_1})
90
+ *Generated landmark view*
91
 
92
  ![{destination} street scene]({image_url_2})
93
+ *Generated street scene*
 
 
94
 
95
+ > 💡 Pro Tip: Book Sagrada Familia tickets online to skip 2-hour queues!
96
  """
97
 
 
98
  # ======================
99
+ # AGENT SETUP (CRITICAL FIXES)
100
  # ======================
101
 
102
+ # Load tools
103
  final_answer = FinalAnswerTool()
104
  web_search = DuckDuckGoSearchTool()
105
  image_gen = load_tool("agents-course/text-to-image", trust_remote_code=True)
106
 
107
+ # Use minimal system prompt that encourages CODE BLOCKS (not prose)
108
+ system_prompt = (
109
+ "You are a travel assistant. ALWAYS respond with executable Python code blocks.\n"
110
+ "Workflow:\n"
111
+ "1. Use DuckDuckGoSearchTool to find attractions\n"
112
+ "2. Use get_weather for forecast\n"
113
+ "3. Use convert_currency for budget\n"
114
+ "4. CALL image_generation_tool TWICE:\n"
115
+ " img1 = image_generation_tool('{destination} landmark photorealistic')\n"
116
+ " img2 = image_generation_tool('{destination} vibrant street scene')\n"
117
+ "5. Use build_catalogue with BOTH image URLs\n"
118
+ "NEVER output natural language steps. ONLY output:\n"
119
+ "Thoughts: ...\n"
120
+ "Code:\n"
121
+ "```py\n"
122
+ "# executable code\n"
123
+ "```"
124
+ )
125
+
126
  model = HfApiModel(
127
+ max_tokens=1500, # Prevent token exhaustion
128
+ temperature=0.2, # Lower = more deterministic code output
129
  model_id="Qwen/Qwen2.5-Coder-32B-Instruct",
130
  )
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  agent = CodeAgent(
133
  model=model,
134
  tools=[
135
  final_answer,
136
  web_search,
137
+ image_gen, # MUST be in tool list to be callable in code blocks
138
+ get_weather,
139
  convert_currency,
140
+ build_catalogue,
 
 
141
  ],
142
+ max_steps=12,
143
  verbosity_level=1,
144
+ name="TravelAgent",
145
+ description="Creates travel catalogues with images",
146
+ prompt_templates={"system_prompt": system_prompt},
147
  )
148
 
149
  if __name__ == "__main__":
150
+ print("🚀 Travel Agent with guaranteed image generation")
151
  GradioUI(agent, file_upload_folder="./uploads").launch()