sagar007 commited on
Commit
3e34e42
·
verified ·
1 Parent(s): cde1649

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +454 -41
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
- # Below is an example of a tool that does nothing. Amaze us with your creativity!
 
 
 
11
  @tool
12
- def my_custom_tool(arg1:str, arg2:int)-> str: # it's important to specify the return type
13
- # Keep this format for the tool description / args description but feel free to modify the tool
14
- """A tool that does nothing yet
15
  Args:
16
- arg1: the first argument
17
- arg2: the second argument
18
  """
19
- return "What magic will you build ?"
 
 
 
 
 
20
 
21
  @tool
22
- def get_current_time_in_timezone(timezone: str) -> str:
23
- """A tool that fetches the current local time in a specified timezone.
 
24
  Args:
25
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
 
26
  """
27
  try:
28
- # Create timezone object
29
- tz = pytz.timezone(timezone)
30
- # Get current time in that timezone
31
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
32
- return f"The current local time in {timezone} is: {local_time}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  except Exception as e:
34
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
 
 
 
36
 
37
- final_answer = FinalAnswerTool()
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
- # Import tool from Hub
47
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
- # Load system prompt from prompt.yaml file
50
- with open("prompts.yaml", 'r') as stream:
51
- prompt_templates = yaml.safe_load(stream)
52
 
53
- agent = CodeAgent(
54
- model=model,
55
- tools=[final_answer], # add your tools here (don't remove final_answer)
56
- max_steps=6,
57
- verbosity_level=1,
58
- grammar=None,
59
- planning_interval=None,
60
- name=None,
61
- description=None,
62
- prompt_templates=prompt_templates # Pass system prompt to CodeAgent
63
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- GradioUI(agent).launch()
 
 
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()