Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -3,64 +3,477 @@ import datetime
|
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
|
|
|
|
|
|
|
|
|
|
6 |
from tools.final_answer import FinalAnswerTool
|
7 |
-
|
8 |
from Gradio_UI import GradioUI
|
9 |
|
10 |
-
#
|
|
|
|
|
|
|
11 |
@tool
|
12 |
-
def
|
13 |
-
|
14 |
-
|
15 |
Args:
|
16 |
-
|
17 |
-
arg2: the second argument
|
18 |
"""
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
@tool
|
22 |
-
def
|
23 |
-
"""
|
|
|
24 |
Args:
|
25 |
-
|
|
|
26 |
"""
|
27 |
try:
|
28 |
-
#
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
except Exception as e:
|
34 |
-
return f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
|
|
|
|
|
|
36 |
|
37 |
-
|
38 |
-
model = InferenceClientModel(
|
39 |
-
max_tokens=2096,
|
40 |
-
temperature=0.5,
|
41 |
-
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
|
42 |
-
custom_role_conversions=None,
|
43 |
-
)
|
44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
-
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
|
|
|
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
6 |
+
import json
|
7 |
+
import os
|
8 |
+
import math
|
9 |
+
import re
|
10 |
+
from typing import Dict, List, Any, Optional
|
11 |
from tools.final_answer import FinalAnswerTool
|
|
|
12 |
from Gradio_UI import GradioUI
|
13 |
|
14 |
+
# =============================================================================
|
15 |
+
# CUSTOM TOOLS COLLECTION
|
16 |
+
# =============================================================================
|
17 |
+
|
18 |
@tool
|
19 |
+
def get_current_time_in_timezone(timezone: str) -> str:
|
20 |
+
"""Get the current local time in a specified timezone.
|
21 |
+
|
22 |
Args:
|
23 |
+
timezone: A string representing a valid timezone (e.g., 'America/New_York', 'Europe/London', 'Asia/Tokyo')
|
|
|
24 |
"""
|
25 |
+
try:
|
26 |
+
tz = pytz.timezone(timezone)
|
27 |
+
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S %Z")
|
28 |
+
return f"Current time in {timezone}: {local_time}"
|
29 |
+
except Exception as e:
|
30 |
+
return f"Error: Invalid timezone '{timezone}'. Please use format like 'America/New_York'"
|
31 |
|
32 |
@tool
|
33 |
+
def weather_forecast(city: str, country_code: str = "") -> str:
|
34 |
+
"""Get current weather information for a city.
|
35 |
+
|
36 |
Args:
|
37 |
+
city: Name of the city
|
38 |
+
country_code: Optional 2-letter country code (e.g., 'US', 'UK', 'CA')
|
39 |
"""
|
40 |
try:
|
41 |
+
# Using OpenWeatherMap API (you'll need to get a free API key)
|
42 |
+
api_key = os.getenv('OPENWEATHER_API_KEY', 'demo_key')
|
43 |
+
|
44 |
+
if country_code:
|
45 |
+
query = f"{city},{country_code}"
|
46 |
+
else:
|
47 |
+
query = city
|
48 |
+
|
49 |
+
url = f"http://api.openweathermap.org/data/2.5/weather?q={query}&appid={api_key}&units=metric"
|
50 |
+
|
51 |
+
if api_key == 'demo_key':
|
52 |
+
return f"Weather service unavailable. Please set OPENWEATHER_API_KEY environment variable."
|
53 |
+
|
54 |
+
response = requests.get(url, timeout=10)
|
55 |
+
data = response.json()
|
56 |
+
|
57 |
+
if response.status_code == 200:
|
58 |
+
temp = data['main']['temp']
|
59 |
+
feels_like = data['main']['feels_like']
|
60 |
+
humidity = data['main']['humidity']
|
61 |
+
description = data['weather'][0]['description']
|
62 |
+
wind_speed = data['wind']['speed']
|
63 |
+
|
64 |
+
return f"Weather in {city}: {description.title()}, {temp}°C (feels like {feels_like}°C), Humidity: {humidity}%, Wind: {wind_speed} m/s"
|
65 |
+
else:
|
66 |
+
return f"Could not fetch weather for {city}. Error: {data.get('message', 'Unknown error')}"
|
67 |
+
|
68 |
except Exception as e:
|
69 |
+
return f"Weather service error: {str(e)}"
|
70 |
+
|
71 |
+
@tool
|
72 |
+
def calculate_advanced_math(expression: str) -> str:
|
73 |
+
"""Safely evaluate mathematical expressions including advanced functions.
|
74 |
+
|
75 |
+
Args:
|
76 |
+
expression: Mathematical expression (e.g., 'sqrt(16)', 'sin(pi/2)', '2**3 + log(10)')
|
77 |
+
"""
|
78 |
+
try:
|
79 |
+
# Safe math evaluation with common functions
|
80 |
+
safe_dict = {
|
81 |
+
'__builtins__': {},
|
82 |
+
'abs': abs, 'round': round, 'min': min, 'max': max,
|
83 |
+
'sum': sum, 'pow': pow,
|
84 |
+
'sqrt': math.sqrt, 'sin': math.sin, 'cos': math.cos, 'tan': math.tan,
|
85 |
+
'log': math.log, 'log10': math.log10, 'exp': math.exp,
|
86 |
+
'pi': math.pi, 'e': math.e,
|
87 |
+
'ceil': math.ceil, 'floor': math.floor,
|
88 |
+
'factorial': math.factorial,
|
89 |
+
'degrees': math.degrees, 'radians': math.radians
|
90 |
+
}
|
91 |
+
|
92 |
+
result = eval(expression, safe_dict)
|
93 |
+
return f"Result: {result}"
|
94 |
+
|
95 |
+
except Exception as e:
|
96 |
+
return f"Math error: {str(e)}. Please check your expression syntax."
|
97 |
+
|
98 |
+
@tool
|
99 |
+
def text_analyzer(text: str) -> str:
|
100 |
+
"""Analyze text for various metrics and insights.
|
101 |
+
|
102 |
+
Args:
|
103 |
+
text: The text to analyze
|
104 |
+
"""
|
105 |
+
try:
|
106 |
+
# Basic text statistics
|
107 |
+
word_count = len(text.split())
|
108 |
+
char_count = len(text)
|
109 |
+
char_count_no_spaces = len(text.replace(' ', ''))
|
110 |
+
sentence_count = len([s for s in re.split(r'[.!?]+', text) if s.strip()])
|
111 |
+
paragraph_count = len([p for p in text.split('\n\n') if p.strip()])
|
112 |
+
|
113 |
+
# Average metrics
|
114 |
+
avg_words_per_sentence = word_count / max(sentence_count, 1)
|
115 |
+
avg_chars_per_word = char_count_no_spaces / max(word_count, 1)
|
116 |
+
|
117 |
+
# Reading time estimate (average 200 words per minute)
|
118 |
+
reading_time_minutes = word_count / 200
|
119 |
+
|
120 |
+
# Most common words (excluding common stop words)
|
121 |
+
stop_words = {'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by', 'is', 'are', 'was', 'were', 'be', 'been', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'this', 'that', 'these', 'those'}
|
122 |
+
words = [word.lower().strip('.,!?";()[]{}') for word in text.split()]
|
123 |
+
content_words = [word for word in words if word not in stop_words and len(word) > 2]
|
124 |
+
word_freq = {}
|
125 |
+
for word in content_words:
|
126 |
+
word_freq[word] = word_freq.get(word, 0) + 1
|
127 |
+
|
128 |
+
top_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)[:5]
|
129 |
+
|
130 |
+
analysis = f"""Text Analysis Results:
|
131 |
+
|
132 |
+
📊 Basic Statistics:
|
133 |
+
• Words: {word_count}
|
134 |
+
• Characters: {char_count} (with spaces), {char_count_no_spaces} (without spaces)
|
135 |
+
• Sentences: {sentence_count}
|
136 |
+
• Paragraphs: {paragraph_count}
|
137 |
|
138 |
+
📈 Averages:
|
139 |
+
• Words per sentence: {avg_words_per_sentence:.1f}
|
140 |
+
• Characters per word: {avg_chars_per_word:.1f}
|
141 |
|
142 |
+
⏱️ Reading Time: {reading_time_minutes:.1f} minutes
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
|
144 |
+
🔤 Most Common Words:
|
145 |
+
{chr(10).join([f"• {word}: {count}" for word, count in top_words])}
|
146 |
+
"""
|
147 |
+
|
148 |
+
return analysis
|
149 |
+
|
150 |
+
except Exception as e:
|
151 |
+
return f"Text analysis error: {str(e)}"
|
152 |
|
153 |
+
@tool
|
154 |
+
def url_shortener(url: str, custom_alias: str = "") -> str:
|
155 |
+
"""Create a shortened URL using TinyURL service.
|
156 |
+
|
157 |
+
Args:
|
158 |
+
url: The URL to shorten
|
159 |
+
custom_alias: Optional custom alias for the shortened URL
|
160 |
+
"""
|
161 |
+
try:
|
162 |
+
if not url.startswith(('http://', 'https://')):
|
163 |
+
url = 'https://' + url
|
164 |
+
|
165 |
+
api_url = "http://tinyurl.com/api-create.php"
|
166 |
+
params = {'url': url}
|
167 |
+
|
168 |
+
if custom_alias:
|
169 |
+
params['alias'] = custom_alias
|
170 |
+
|
171 |
+
response = requests.get(api_url, params=params, timeout=10)
|
172 |
+
|
173 |
+
if response.status_code == 200:
|
174 |
+
short_url = response.text.strip()
|
175 |
+
if short_url.startswith('http'):
|
176 |
+
return f"Shortened URL: {short_url}"
|
177 |
+
else:
|
178 |
+
return f"Error: {short_url}"
|
179 |
+
else:
|
180 |
+
return f"URL shortening failed with status code: {response.status_code}"
|
181 |
+
|
182 |
+
except Exception as e:
|
183 |
+
return f"URL shortening error: {str(e)}"
|
184 |
|
185 |
+
@tool
|
186 |
+
def password_generator(length: int = 12, include_symbols: bool = True, include_numbers: bool = True) -> str:
|
187 |
+
"""Generate a secure random password.
|
188 |
|
189 |
+
Args:
|
190 |
+
length: Length of the password (default: 12)
|
191 |
+
include_symbols: Whether to include special characters (default: True)
|
192 |
+
include_numbers: Whether to include numbers (default: True)
|
193 |
+
"""
|
194 |
+
try:
|
195 |
+
import random
|
196 |
+
import string
|
197 |
+
|
198 |
+
if length < 4:
|
199 |
+
return "Error: Password length must be at least 4 characters"
|
200 |
+
|
201 |
+
if length > 128:
|
202 |
+
return "Error: Password length cannot exceed 128 characters"
|
203 |
+
|
204 |
+
# Base character set
|
205 |
+
chars = string.ascii_letters
|
206 |
+
|
207 |
+
if include_numbers:
|
208 |
+
chars += string.digits
|
209 |
+
|
210 |
+
if include_symbols:
|
211 |
+
chars += "!@#$%^&*()_+-=[]{}|;:,.<>?"
|
212 |
+
|
213 |
+
# Ensure at least one character from each selected category
|
214 |
+
password = []
|
215 |
+
|
216 |
+
# Add at least one lowercase and uppercase letter
|
217 |
+
password.append(random.choice(string.ascii_lowercase))
|
218 |
+
password.append(random.choice(string.ascii_uppercase))
|
219 |
+
|
220 |
+
if include_numbers:
|
221 |
+
password.append(random.choice(string.digits))
|
222 |
+
|
223 |
+
if include_symbols:
|
224 |
+
password.append(random.choice("!@#$%^&*()_+-=[]{}|;:,.<>?"))
|
225 |
+
|
226 |
+
# Fill the rest with random characters
|
227 |
+
for _ in range(length - len(password)):
|
228 |
+
password.append(random.choice(chars))
|
229 |
+
|
230 |
+
# Shuffle the password
|
231 |
+
random.shuffle(password)
|
232 |
+
|
233 |
+
generated_password = ''.join(password)
|
234 |
+
|
235 |
+
return f"Generated password: {generated_password}\n\nSecurity tips:\n• Store in a password manager\n• Don't reuse across sites\n• Change regularly for sensitive accounts"
|
236 |
+
|
237 |
+
except Exception as e:
|
238 |
+
return f"Password generation error: {str(e)}"
|
239 |
|
240 |
+
@tool
|
241 |
+
def unit_converter(value: float, from_unit: str, to_unit: str) -> str:
|
242 |
+
"""Convert between different units of measurement.
|
243 |
+
|
244 |
+
Args:
|
245 |
+
value: The numeric value to convert
|
246 |
+
from_unit: Source unit (e.g., 'km', 'miles', 'kg', 'lbs', 'celsius', 'fahrenheit')
|
247 |
+
to_unit: Target unit
|
248 |
+
"""
|
249 |
+
try:
|
250 |
+
# Conversion factors to base units
|
251 |
+
conversions = {
|
252 |
+
# Length (to meters)
|
253 |
+
'mm': 0.001, 'cm': 0.01, 'm': 1, 'km': 1000,
|
254 |
+
'inch': 0.0254, 'ft': 0.3048, 'yard': 0.9144, 'mile': 1609.34,
|
255 |
+
|
256 |
+
# Weight (to kg)
|
257 |
+
'mg': 0.000001, 'g': 0.001, 'kg': 1,
|
258 |
+
'oz': 0.0283495, 'lb': 0.453592, 'stone': 6.35029,
|
259 |
+
|
260 |
+
# Temperature (special handling)
|
261 |
+
'celsius': 'celsius', 'fahrenheit': 'fahrenheit', 'kelvin': 'kelvin',
|
262 |
+
|
263 |
+
# Volume (to liters)
|
264 |
+
'ml': 0.001, 'l': 1, 'gallon': 3.78541, 'quart': 0.946353,
|
265 |
+
'pint': 0.473176, 'cup': 0.236588, 'fl_oz': 0.0295735
|
266 |
+
}
|
267 |
+
|
268 |
+
from_unit = from_unit.lower()
|
269 |
+
to_unit = to_unit.lower()
|
270 |
+
|
271 |
+
# Handle temperature conversions separately
|
272 |
+
if from_unit in ['celsius', 'fahrenheit', 'kelvin'] or to_unit in ['celsius', 'fahrenheit', 'kelvin']:
|
273 |
+
if from_unit == 'celsius' and to_unit == 'fahrenheit':
|
274 |
+
result = (value * 9/5) + 32
|
275 |
+
elif from_unit == 'fahrenheit' and to_unit == 'celsius':
|
276 |
+
result = (value - 32) * 5/9
|
277 |
+
elif from_unit == 'celsius' and to_unit == 'kelvin':
|
278 |
+
result = value + 273.15
|
279 |
+
elif from_unit == 'kelvin' and to_unit == 'celsius':
|
280 |
+
result = value - 273.15
|
281 |
+
elif from_unit == 'fahrenheit' and to_unit == 'kelvin':
|
282 |
+
result = (value - 32) * 5/9 + 273.15
|
283 |
+
elif from_unit == 'kelvin' and to_unit == 'fahrenheit':
|
284 |
+
result = (value - 273.15) * 9/5 + 32
|
285 |
+
else:
|
286 |
+
return f"Error: Cannot convert from {from_unit} to {to_unit}"
|
287 |
+
|
288 |
+
return f"{value}° {from_unit.title()} = {result:.2f}° {to_unit.title()}"
|
289 |
+
|
290 |
+
# Handle other unit conversions
|
291 |
+
if from_unit not in conversions or to_unit not in conversions:
|
292 |
+
available_units = list(conversions.keys())
|
293 |
+
return f"Error: Unsupported unit. Available units: {', '.join(available_units)}"
|
294 |
+
|
295 |
+
# Convert to base unit, then to target unit
|
296 |
+
base_value = value * conversions[from_unit]
|
297 |
+
result = base_value / conversions[to_unit]
|
298 |
+
|
299 |
+
return f"{value} {from_unit} = {result:.6f} {to_unit}"
|
300 |
+
|
301 |
+
except Exception as e:
|
302 |
+
return f"Unit conversion error: {str(e)}"
|
303 |
+
|
304 |
+
@tool
|
305 |
+
def json_formatter(json_string: str) -> str:
|
306 |
+
"""Format and validate JSON strings.
|
307 |
+
|
308 |
+
Args:
|
309 |
+
json_string: The JSON string to format
|
310 |
+
"""
|
311 |
+
try:
|
312 |
+
# Parse the JSON to validate it
|
313 |
+
parsed = json.loads(json_string)
|
314 |
+
|
315 |
+
# Format with proper indentation
|
316 |
+
formatted = json.dumps(parsed, indent=2, ensure_ascii=False)
|
317 |
+
|
318 |
+
return f"✅ Valid JSON - Formatted:\n\n{formatted}"
|
319 |
+
|
320 |
+
except json.JSONDecodeError as e:
|
321 |
+
return f"❌ Invalid JSON - Error: {str(e)}"
|
322 |
+
except Exception as e:
|
323 |
+
return f"JSON formatting error: {str(e)}"
|
324 |
+
|
325 |
+
@tool
|
326 |
+
def base64_encoder_decoder(text: str, operation: str = "encode") -> str:
|
327 |
+
"""Encode or decode base64 strings.
|
328 |
+
|
329 |
+
Args:
|
330 |
+
text: The text to encode/decode
|
331 |
+
operation: Either 'encode' or 'decode'
|
332 |
+
"""
|
333 |
+
try:
|
334 |
+
import base64
|
335 |
+
|
336 |
+
if operation.lower() == "encode":
|
337 |
+
encoded = base64.b64encode(text.encode('utf-8')).decode('utf-8')
|
338 |
+
return f"Base64 Encoded: {encoded}"
|
339 |
+
|
340 |
+
elif operation.lower() == "decode":
|
341 |
+
decoded = base64.b64decode(text.encode('utf-8')).decode('utf-8')
|
342 |
+
return f"Base64 Decoded: {decoded}"
|
343 |
+
|
344 |
+
else:
|
345 |
+
return "Error: Operation must be 'encode' or 'decode'"
|
346 |
+
|
347 |
+
except Exception as e:
|
348 |
+
return f"Base64 operation error: {str(e)}"
|
349 |
+
|
350 |
+
@tool
|
351 |
+
def hash_generator(text: str, algorithm: str = "sha256") -> str:
|
352 |
+
"""Generate hash for text using various algorithms.
|
353 |
+
|
354 |
+
Args:
|
355 |
+
text: The text to hash
|
356 |
+
algorithm: Hash algorithm ('md5', 'sha1', 'sha256', 'sha512')
|
357 |
+
"""
|
358 |
+
try:
|
359 |
+
import hashlib
|
360 |
+
|
361 |
+
algorithm = algorithm.lower()
|
362 |
+
|
363 |
+
if algorithm == "md5":
|
364 |
+
hash_obj = hashlib.md5(text.encode())
|
365 |
+
elif algorithm == "sha1":
|
366 |
+
hash_obj = hashlib.sha1(text.encode())
|
367 |
+
elif algorithm == "sha256":
|
368 |
+
hash_obj = hashlib.sha256(text.encode())
|
369 |
+
elif algorithm == "sha512":
|
370 |
+
hash_obj = hashlib.sha512(text.encode())
|
371 |
+
else:
|
372 |
+
return "Error: Supported algorithms are 'md5', 'sha1', 'sha256', 'sha512'"
|
373 |
+
|
374 |
+
hash_value = hash_obj.hexdigest()
|
375 |
+
return f"{algorithm.upper()} hash: {hash_value}"
|
376 |
+
|
377 |
+
except Exception as e:
|
378 |
+
return f"Hash generation error: {str(e)}"
|
379 |
+
|
380 |
+
# =============================================================================
|
381 |
+
# MAIN APPLICATION SETUP
|
382 |
+
# =============================================================================
|
383 |
+
|
384 |
+
def main():
|
385 |
+
"""Initialize and launch the AI agent application."""
|
386 |
+
|
387 |
+
# Initialize core tools
|
388 |
+
final_answer = FinalAnswerTool()
|
389 |
+
search_tool = DuckDuckGoSearchTool()
|
390 |
+
|
391 |
+
# Initialize the language model
|
392 |
+
model = InferenceClientModel(
|
393 |
+
max_tokens=2096,
|
394 |
+
temperature=0.5,
|
395 |
+
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
|
396 |
+
custom_role_conversions=None,
|
397 |
+
)
|
398 |
+
|
399 |
+
# Try to load image generation tool
|
400 |
+
try:
|
401 |
+
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
402 |
+
print("✅ Image generation tool loaded successfully")
|
403 |
+
except Exception as e:
|
404 |
+
print(f"⚠️ Could not load image generation tool: {e}")
|
405 |
+
image_generation_tool = None
|
406 |
+
|
407 |
+
# Collect all tools
|
408 |
+
tools = [
|
409 |
+
final_answer,
|
410 |
+
search_tool,
|
411 |
+
get_current_time_in_timezone,
|
412 |
+
weather_forecast,
|
413 |
+
calculate_advanced_math,
|
414 |
+
text_analyzer,
|
415 |
+
url_shortener,
|
416 |
+
password_generator,
|
417 |
+
unit_converter,
|
418 |
+
json_formatter,
|
419 |
+
base64_encoder_decoder,
|
420 |
+
hash_generator,
|
421 |
+
]
|
422 |
+
|
423 |
+
# Add image generation tool if available
|
424 |
+
if image_generation_tool:
|
425 |
+
tools.append(image_generation_tool)
|
426 |
+
|
427 |
+
# Load system prompt templates
|
428 |
+
try:
|
429 |
+
with open("prompts.yaml", 'r') as stream:
|
430 |
+
prompt_templates = yaml.safe_load(stream)
|
431 |
+
print("✅ System prompts loaded successfully")
|
432 |
+
except FileNotFoundError:
|
433 |
+
print("⚠️ prompts.yaml not found, using default prompts")
|
434 |
+
prompt_templates = None
|
435 |
+
except Exception as e:
|
436 |
+
print(f"⚠️ Error loading prompts.yaml: {e}")
|
437 |
+
prompt_templates = None
|
438 |
+
|
439 |
+
# Initialize the CodeAgent
|
440 |
+
agent = CodeAgent(
|
441 |
+
model=model,
|
442 |
+
tools=tools,
|
443 |
+
max_steps=10, # Increased for more complex tasks
|
444 |
+
verbosity_level=1,
|
445 |
+
grammar=None,
|
446 |
+
planning_interval=3, # Plan every 3 steps
|
447 |
+
name="SuperAgent",
|
448 |
+
description="An advanced AI agent capable of solving complex tasks using code and various tools",
|
449 |
+
prompt_templates=prompt_templates
|
450 |
+
)
|
451 |
+
|
452 |
+
print("🚀 SuperAgent initialized with the following capabilities:")
|
453 |
+
print(" • Web search and information retrieval")
|
454 |
+
print(" • Advanced mathematical calculations")
|
455 |
+
print(" • Text analysis and processing")
|
456 |
+
print(" • Time zone and weather information")
|
457 |
+
print(" • URL shortening and web utilities")
|
458 |
+
print(" • Security tools (password generation, hashing)")
|
459 |
+
print(" • Data conversion and formatting")
|
460 |
+
if image_generation_tool:
|
461 |
+
print(" • Image generation from text")
|
462 |
+
print(" • Code execution and problem solving")
|
463 |
+
print()
|
464 |
+
|
465 |
+
# Launch the Gradio interface
|
466 |
+
try:
|
467 |
+
ui = GradioUI(agent)
|
468 |
+
ui.launch(
|
469 |
+
share=False, # Set to True to create a public link
|
470 |
+
inbrowser=True, # Open in browser automatically
|
471 |
+
server_name="0.0.0.0", # Allow access from other devices on network
|
472 |
+
server_port=7860, # Default Gradio port
|
473 |
+
)
|
474 |
+
except Exception as e:
|
475 |
+
print(f"❌ Failed to launch Gradio UI: {e}")
|
476 |
+
print("Make sure you have gradio installed and Gradio_UI module is available")
|
477 |
|
478 |
+
if __name__ == "__main__":
|
479 |
+
main()
|