Spaces:
Sleeping
Sleeping
File size: 5,629 Bytes
18d57bd 9b5b26a 18d57bd 9b5b26a c19d193 18d57bd 6aae614 9b5b26a e0373a0 9b5b26a 18d57bd 9b5b26a b6d734e 18d57bd 9b5b26a b6d734e 9b5b26a b6d734e 8c01ffb 0fda2d7 18d57bd bf7cbcc 18d57bd 7401736 18d57bd 6086f1e 3525044 e0373a0 6086f1e 0d1d031 6086f1e 18d57bd 6086f1e 18d57bd 6086f1e 7401736 6086f1e 18d57bd 3b3ac4f 18d57bd 3b3ac4f 8c01ffb 7401736 9b5b26a 8c01ffb 861422e 18d57bd 8c01ffb 8fe992b 18d57bd 8c01ffb 861422e 8fe992b 8c01ffb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
import datetime
import time
import requests
import pytz
import yaml
import random
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
import os
# Global cache for forecasts per city to avoid refetching within a certain duration (10 minutes)
cached_forecasts = {} # Dictionary mapping city name -> { "data": str, "timestamp": int }
CACHE_DURATION_MS = 10 * 60 * 1000 # 10 minutes in milliseconds
@tool
def get_current_time_in_timezone(timezone: str = "UTC") -> str:
"""
A tool to get the current time in a specific timezone.
Args:
timezone (str): The timezone string. E.g., 'America/New_York'
Returns:
str: The local time in the specified timezone.
"""
try:
tz = pytz.timezone(timezone)
now = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return f"Local time in {timezone}: {now}"
except Exception:
return "Invalid timezone"
@tool
def get_weather_forecast(city: str = "New York", days: int = 7) -> str:
"""
A tool to fetch a weekly weather forecast for a specified city.
This function first checks for a cached forecast for the given city. If the cached
data is older than 10 minutes, it attempts to fetch new data from OpenWeatherMap.
If a valid API key is not provided or an error occurs during the API call,
a mock forecast is generated.
Args:
city (str): The city name for which to get the weather.
days (int): Number of days to forecast (maximum of 7).
Returns:
str: A formatted summary forecast with daily averages.
"""
global cached_forecasts
now_ms = int(time.time() * 1000)
# Check for a valid cache
if city in cached_forecasts and now_ms - cached_forecasts[city]["timestamp"] < CACHE_DURATION_MS:
return cached_forecasts[city]["data"]
# Use a real API key in production
api_key = os.environ.get("OPENWEATHER_API", None) # This should be defined/assigned earlier
# For debugging: print the API key value (remove or secure in production)
print("DEBUG: API key used =", api_key)
# Validate API key before proceeding
if not api_key:
return "Error: Invalid or missing OpenWeather API key. Please configure a valid API key."
url = f"http://api.openweathermap.org/data/2.5/forecast?q={city}&appid={api_key}&units=metric"
try:
response = requests.get(url)
data = response.json()
if data.get("cod") != "200":
raise ValueError(data.get("message", "Error fetching weather data"))
# Process and group forecast items by day (format: YYYY-MM-DD)
forecast_by_day = {}
for item in data.get("list", []):
dt = datetime.datetime.utcfromtimestamp(item["dt"])
day_str = dt.strftime("%Y-%m-%d")
forecast_by_day.setdefault(day_str, []).append(item)
# Build forecast for up to 'days' days
sorted_days = sorted(forecast_by_day.keys())[:min(days, 7)]
daily_forecasts = []
for day_str in sorted_days:
day_items = forecast_by_day[day_str]
date_obj = datetime.datetime.strptime(day_str, "%Y-%m-%d")
day_name = date_obj.strftime("%A")
date_display = date_obj.strftime("%b %d")
total_temp = total_humidity = total_pressure = total_wind = 0
condition_counts = {}
for item in day_items:
total_temp += item["main"]["temp"]
total_humidity += item["main"]["humidity"]
total_pressure += item["main"]["pressure"]
total_wind += item["wind"]["speed"]
condition = item["weather"][0]["description"]
condition_counts[condition] = condition_counts.get(condition, 0) + 1
count = len(day_items)
avg_temp = round(total_temp / count)
avg_humidity = round(total_humidity / count)
avg_pressure = round(total_pressure / count)
avg_wind = round((total_wind / count) * 3.6) # Convert m/s to km/h
most_common_condition = max(condition_counts.items(), key=lambda x: x[1])[0]
daily_forecasts.append(
f"{day_name}, {date_display}: {avg_temp}°C, {most_common_condition} | Humidity: {avg_humidity}% | Pressure: {avg_pressure} hPa | Wind: {avg_wind} km/h"
)
forecast_data = "\n".join(daily_forecasts)
except Exception as error:
# Log the error and return an error message
print("Error fetching forecast from API:", error)
return f"Error: Unable to fetch weather data. Reason: {error}"
# Cache the forecast data
cached_forecasts[city] = {
"data": forecast_data,
"timestamp": now_ms
}
return forecast_data
final_answer = FinalAnswerTool()
model = HfApiModel(
max_tokens=2096,
temperature=0.5,
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
custom_role_conversions=None,
)
# Import a text-to-image tool from the hub, if desired.
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
with open("prompts.yaml", 'r') as stream:
prompt_templates = yaml.safe_load(stream)
agent = CodeAgent(
model=model,
tools=[final_answer, get_current_time_in_timezone, get_weather_forecast],
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name=None,
description=None,
prompt_templates=prompt_templates
)
GradioUI(agent).launch() |