from smolagents import DuckDuckGoSearchTool from smolagents import Tool import requests from huggingface_hub import list_models from dotenv import find_dotenv, load_dotenv import os from datetime import datetime, timedelta class WeatherInfoTool(Tool): name = "weather_info" description = "Fetches weather information for a specified location." inputs = { "location": { "type": "string", "description": "The location to get weather information for. If a user specifies a state, remove it." }, "units": { "type": "string", "description": """units specify measuring units. Two are accepted \"metric\" meaning Celcius and \"imperial\" meaning Fahrenheit. The default value is \"imperial\".""", "nullable": True } } output_type = "string" def forward(self, location:str, units:str="imperial")->str: # Weather from openweather api #load_dotenv(find_dotenv()) weather_api_key = os.getenv("WEATHER_API") url = f"http://api.openweathermap.org/geo/1.0/direct?limit=5" params = { "q": location, "appid": weather_api_key, } # retrieve latitude and longuitude response = requests.get(url, params=params) resp = response.json() params = { "lat": resp[0]['lat'], "appid": weather_api_key, "units": units, "lon": resp[0]['lon'] } weather_url = f'https://api.openweathermap.org/data/2.5/weather?' response_weather = requests.get(weather_url, params=params) resp_weather = response_weather.json() combined_dictionary = {'description': resp_weather['weather'][0]['description']} result = {key: resp_weather['main'][key] for key in resp_weather['main'].keys() if key not in ['grnd_level', 'sea_level']} combined_dictionary.update({'units': units}) combined_dictionary.update(result) result = f"""The weather in {location} is {combined_dictionary['description']}. The temperature is {combined_dictionary['temp']}, feels like {combined_dictionary['feels_like']}""" return result class LatestNewsTool(Tool): name = "latest_news" description = "Fetches latest news on a specified topic." inputs = { "topic": { "type": "string", "description": "Topic for which to get the latest news." } } output_type = "string" def forward(self, topic:str)->str: # news from newsapi load_dotenv(find_dotenv()) news_api_key = os.getenv("NEWS_API") today = datetime.now() yesterday = today - timedelta(days=1) yesterday = str(yesterday.date()) url = ('https://newsapi.org/v2/everything?' f'q={topic}&' f'from={yesterday}&' 'sortBy=popularity&' f'apiKey={news_api_key}') response = requests.get(url) resp = response.json() results = [f'Title: {el["title"]}. Description: {el["description"]}' for el in resp["articles"]][:10] results_str = ' '.join(el for el in results) return results_str class HubStatsTool(Tool): name = "hub_stats" description = "Fetches the most downloaded model from a specific author on the Hugging Face Hub." inputs = { "author": { "type": "string", "description": "The username of the model author/organization to find models from." } } output_type = "string" def forward(self, author: str): try: # List models from the specified author, sorted by downloads models = list(list_models(author=author, sort="downloads", direction=-1, limit=1)) if models: model = models[0] return f"The most downloaded model by {author} is {model.id} with {model.downloads:,} downloads." else: return f"No models found for author {author}." except Exception as e: return f"Error fetching models for {author}: {str(e)}"