EmincanY commited on
Commit
9e137f5
·
verified ·
1 Parent(s): f28ee69

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +28 -290
app.py CHANGED
@@ -1,309 +1,45 @@
1
- from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
2
- import datetime
3
- import requests
4
- import pytz
5
  import yaml
6
  import os
7
  from dotenv import load_dotenv
8
  from tools.final_answer import FinalAnswerTool
9
- import wikipediaapi
10
- from newsapi import NewsApiClient
11
- from forex_python.converter import CurrencyRates
12
- import sympy
13
- import random
14
- import string
 
 
 
15
  from Gradio_UI import GradioUI
16
 
17
  # Load environment variables
18
  load_dotenv()
19
 
20
- # Below is an example of a tool that does nothing. Amaze us with your creativity !
21
- @tool
22
- def my_custom_tool(arg1:str, arg2:int)-> str: #it's import to specify the return type
23
- #Keep this format for the description / args / args description but feel free to modify the tool
24
- """A tool that does nothing yet
25
- Args:
26
- arg1: the first argument
27
- arg2: the second argument
28
- """
29
- return "What magic will you build ?"
30
-
31
- @tool
32
- def get_current_time_in_timezone(timezone: str) -> str:
33
- """A tool that fetches the current local time in a specified timezone.
34
- Args:
35
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
36
- """
37
- try:
38
- # Create timezone object
39
- tz = pytz.timezone(timezone)
40
- # Get current time in that timezone
41
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
42
- return f"The current local time in {timezone} is: {local_time}"
43
- except Exception as e:
44
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
45
-
46
- @tool
47
- def get_weather(city: str) -> str:
48
- """Get current weather information for a specified city
49
- Args:
50
- city: Name of the city to get weather for
51
- """
52
- # Using OpenWeatherMap API
53
- API_KEY = os.getenv("OPENWEATHERMAP_API_KEY")
54
- if not API_KEY:
55
- return "Error: OpenWeatherMap API key not found in environment variables"
56
-
57
- base_url = "http://api.openweathermap.org/data/2.5/weather"
58
-
59
- try:
60
- params = {
61
- 'q': city,
62
- 'appid': API_KEY,
63
- 'units': 'metric' # For Celsius
64
- }
65
- response = requests.get(base_url, params=params)
66
- data = response.json()
67
-
68
- if response.status_code == 200:
69
- temp = data['main']['temp']
70
- humidity = data['main']['humidity']
71
- description = data['weather'][0]['description']
72
- return f"Weather in {city}: Temperature: {temp}°C, Humidity: {humidity}%, Conditions: {description}"
73
- else:
74
- return f"Error getting weather: {data.get('message', 'Unknown error')}"
75
- except Exception as e:
76
- return f"Error: {str(e)}"
77
-
78
- @tool
79
- def convert_currency(amount: float, from_currency: str, to_currency: str) -> str:
80
- """Convert an amount from one currency to another
81
- Args:
82
- amount: Amount to convert
83
- from_currency: Source currency code (e.g., USD)
84
- to_currency: Target currency code (e.g., EUR)
85
- """
86
- try:
87
- # Using ExchangeRate-API
88
- base_url = "https://api.exchangerate-api.com/v4/latest"
89
-
90
- # Get exchange rates for the base currency
91
- response = requests.get(f"{base_url}/{from_currency.upper()}")
92
- data = response.json()
93
-
94
- if response.status_code == 200:
95
- # Get the exchange rate for the target currency
96
- if to_currency.upper() in data['rates']:
97
- rate = data['rates'][to_currency.upper()]
98
- converted_amount = amount * rate
99
- return f"{amount} {from_currency.upper()} = {converted_amount:.2f} {to_currency.upper()} (Rate: 1 {from_currency.upper()} = {rate:.4f} {to_currency.upper()})"
100
- else:
101
- return f"Error: Target currency {to_currency.upper()} not found"
102
- else:
103
- return f"Error: {data.get('error', 'Failed to fetch exchange rates')}"
104
- except Exception as e:
105
- return f"Error converting currency: {str(e)}"
106
-
107
- @tool
108
- def get_news_headlines(topic: str, count: int = 5) -> str:
109
- """Get latest news headlines for a specific topic
110
- Args:
111
- topic: Topic to search news for
112
- count: Number of headlines to return (default: 5)
113
- """
114
- API_KEY = os.getenv("NEWSAPI_KEY")
115
- if not API_KEY:
116
- return "Error: NewsAPI key not found in environment variables"
117
-
118
- newsapi = NewsApiClient(api_key=API_KEY)
119
-
120
- try:
121
- # Define search strategies with different parameters
122
- search_strategies = [
123
- {
124
- 'query': f'"{topic}"', # Exact phrase match
125
- 'relevance': 'high'
126
- },
127
- {
128
- 'query': topic, # Normal search
129
- 'relevance': 'high'
130
- },
131
- {
132
- 'query': f"{topic} latest", # Latest news
133
- 'relevance': 'medium'
134
- }
135
- ]
136
-
137
- relevant_articles = [] # Store only relevant articles
138
- seen_titles = set()
139
- required_keywords = set(topic.lower().split())
140
-
141
- # Function to check article relevance
142
- def is_relevant(article, required_words, relevance_level):
143
- title = article['title'].lower()
144
- description = (article.get('description') or '').lower()
145
- content = (article.get('content') or '').lower()
146
-
147
- # Count how many required words appear in the article
148
- title_matches = sum(1 for word in required_words if word in title)
149
- desc_matches = sum(1 for word in required_words if word in description)
150
- content_matches = sum(1 for word in required_words if word in content)
151
-
152
- # Calculate relevance score
153
- total_score = (title_matches * 3) + (desc_matches * 2) + content_matches
154
-
155
- # For exact phrase matching
156
- if relevance_level == 'high':
157
- # Check if the exact topic phrase appears
158
- if topic.lower() in title or topic.lower() in description:
159
- return True
160
- return total_score >= len(required_words) * 2
161
- else:
162
- return total_score >= len(required_words)
163
-
164
- for strategy in search_strategies:
165
- if len(relevant_articles) >= count:
166
- break
167
-
168
- # Calculate how many more articles we need
169
- remaining_count = count - len(relevant_articles)
170
-
171
- try:
172
- news = newsapi.get_everything(
173
- q=strategy['query'],
174
- language='en',
175
- sort_by='relevancy', # Changed to relevancy sort
176
- page_size=min(50, remaining_count * 5) # Request more articles to filter through
177
- )
178
-
179
- if news['articles']:
180
- for article in news['articles']:
181
- # Skip if we've seen this title or have enough articles
182
- if article['title'] in seen_titles:
183
- continue
184
-
185
- # Check if article is relevant enough
186
- if is_relevant(article, required_keywords, strategy['relevance']):
187
- seen_titles.add(article['title'])
188
- pub_date = datetime.datetime.strptime(article['publishedAt'], '%Y-%m-%dT%H:%M:%SZ')
189
- relevant_articles.append({
190
- 'title': article['title'],
191
- 'source': article['source']['name'],
192
- 'date': pub_date,
193
- 'url': article['url'],
194
- 'relevance': strategy['relevance']
195
- })
196
-
197
- # Break if we have enough relevant articles
198
- if len(relevant_articles) >= count:
199
- break
200
- except Exception as e:
201
- continue # If one strategy fails, try the next one
202
-
203
- # Sort by date (newest first)
204
- relevant_articles.sort(key=lambda x: x['date'], reverse=True)
205
-
206
- if relevant_articles:
207
- headlines = []
208
- for idx, article in enumerate(relevant_articles, 1):
209
- date_str = article['date'].strftime('%Y-%m-%d %H:%M UTC')
210
- relevance_indicator = "🎯" if article['relevance'] == 'high' else "✓"
211
- headlines.append(f"{idx}. {relevance_indicator} [{date_str}] {article['title']} ({article['source']})")
212
-
213
- # Add a summary of how many relevant articles were found
214
- found_count = len(relevant_articles)
215
- summary = f"Found {found_count} relevant {'article' if found_count == 1 else 'articles'} out of {count} requested.\n\n"
216
- return summary + "\n".join(headlines)
217
-
218
- return f"No relevant news found for topic: {topic}"
219
- except Exception as e:
220
- return f"Error fetching news: {str(e)}"
221
-
222
- @tool
223
- def get_wikipedia_summary(topic: str) -> str:
224
- """Get a summary of a Wikipedia article
225
- Args:
226
- topic: Topic to get summary for
227
- """
228
- wiki = wikipediaapi.Wikipedia(
229
- user_agent='HuggingFaceAgent/1.0 (https://huggingface.co/; contact@huggingface.co)',
230
- language='en'
231
- )
232
- try:
233
- page = wiki.page(topic)
234
- if page.exists():
235
- # Get first two sentences or first 500 characters, whichever is shorter
236
- summary = page.summary[:500]
237
- if len(summary) == 500:
238
- summary = summary[:summary.rindex('.')] + '.'
239
- return summary
240
- return f"No Wikipedia article found for: {topic}"
241
- except Exception as e:
242
- return f"Error fetching Wikipedia summary: {str(e)}"
243
-
244
- @tool
245
- def solve_math_expression(expression: str) -> str:
246
- """Solve a mathematical expression
247
- Args:
248
- expression: Mathematical expression as string
249
- """
250
- try:
251
- # Convert string to sympy expression
252
- expr = sympy.sympify(expression)
253
- result = expr.evalf()
254
- return f"Result: {result}"
255
- except Exception as e:
256
- return f"Error solving expression: {str(e)}"
257
-
258
- @tool
259
- def generate_password(length: int = 12, include_special: bool = True) -> str:
260
- """Generate a secure random password
261
- Args:
262
- length: Length of password (default: 12)
263
- include_special: Include special characters (default: True)
264
- """
265
- try:
266
- if length < 8:
267
- return "Password length must be at least 8 characters"
268
-
269
- chars = string.ascii_letters + string.digits
270
- if include_special:
271
- chars += string.punctuation
272
-
273
- password = ''.join(random.choice(chars) for _ in range(length))
274
-
275
- # Ensure password contains at least one of each required type
276
- if not any(c.isupper() for c in password):
277
- password = random.choice(string.ascii_uppercase) + password[1:]
278
- if not any(c.islower() for c in password):
279
- password = password[:-1] + random.choice(string.ascii_lowercase)
280
- if not any(c.isdigit() for c in password):
281
- pos = random.randint(1, len(password)-2)
282
- password = password[:pos] + random.choice(string.digits) + password[pos+1:]
283
-
284
- return f"Generated password: {password}"
285
- except Exception as e:
286
- return f"Error generating password: {str(e)}"
287
-
288
- final_answer = FinalAnswerTool()
289
-
290
- # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
291
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
292
-
293
  model = HfApiModel(
294
- max_tokens=2096,
295
- temperature=0.5,
296
- model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
297
- custom_role_conversions=None,
298
  )
299
 
300
-
301
  # Import tool from Hub
302
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
303
 
 
304
  with open("prompts.yaml", 'r') as stream:
305
  prompt_templates = yaml.safe_load(stream)
 
 
 
 
 
 
 
306
 
 
307
  agent = CodeAgent(
308
  model=model,
309
  tools=[
@@ -314,7 +50,9 @@ agent = CodeAgent(
314
  get_wikipedia_summary,
315
  solve_math_expression,
316
  generate_password,
317
- get_current_time_in_timezone
 
 
318
  ],
319
  max_steps=6,
320
  verbosity_level=1,
@@ -325,5 +63,5 @@ agent = CodeAgent(
325
  prompt_templates=prompt_templates
326
  )
327
 
328
-
329
  GradioUI(agent).launch()
 
1
+ from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool
 
 
 
2
  import yaml
3
  import os
4
  from dotenv import load_dotenv
5
  from tools.final_answer import FinalAnswerTool
6
+ from tools.weather_tool import get_weather
7
+ from tools.currency_tool import convert_currency
8
+ from tools.news_tool import get_news_headlines
9
+ from tools.wikipedia_tool import get_wikipedia_summary
10
+ from tools.math_tool import solve_math_expression
11
+ from tools.password_tool import generate_password
12
+ from tools.time_tool import get_current_time_in_timezone
13
+ from tools.web_search import DuckDuckGoSearchTool
14
+ from tools.visit_webpage import VisitWebpageTool
15
  from Gradio_UI import GradioUI
16
 
17
  # Load environment variables
18
  load_dotenv()
19
 
20
+ # Initialize the model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  model = HfApiModel(
22
+ max_tokens=2096,
23
+ temperature=0.5,
24
+ model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud',
25
+ custom_role_conversions=None,
26
  )
27
 
 
28
  # Import tool from Hub
29
  image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
30
 
31
+ # Load prompt templates
32
  with open("prompts.yaml", 'r') as stream:
33
  prompt_templates = yaml.safe_load(stream)
34
+
35
+ # Initialize final answer tool
36
+ final_answer = FinalAnswerTool()
37
+
38
+ # Initialize web tools
39
+ web_search_tool = DuckDuckGoSearchTool(max_results=5)
40
+ visit_webpage_tool = VisitWebpageTool()
41
 
42
+ # Initialize the agent with all tools
43
  agent = CodeAgent(
44
  model=model,
45
  tools=[
 
50
  get_wikipedia_summary,
51
  solve_math_expression,
52
  generate_password,
53
+ get_current_time_in_timezone,
54
+ web_search_tool,
55
+ visit_webpage_tool
56
  ],
57
  max_steps=6,
58
  verbosity_level=1,
 
63
  prompt_templates=prompt_templates
64
  )
65
 
66
+ # Launch the Gradio interface
67
  GradioUI(agent).launch()