JimmyBhoy's picture
Upload 7 files
0ef94af verified
@tool
def get_weather_info(location: str = "New York") -> str:
"""
Get current weather information for a location.
Args:
location: Location to get weather for (default: New York)
Returns:
Current weather information
"""
try:
# Using a free weather API (OpenWeatherMap)
api_key = os.getenv('OPENWEATHER_API_KEY')
if not api_key:
# Fallback to mock data for demo
return f"""
🌤️ **Weather for {location}** (Demo Data)
Temperature: 22°C (72°F)
Condition: Partly Cloudy
Humidity: 65%
Wind: 8 mph NW
*Note: This is demo data. Set OPENWEATHER_API_KEY for real weather data.*
"""
# Real API call
base_url = "https://api.openweathermap.org/data/2.5/weather"
params = {
'q': location,
'appid': api_key,
'units': 'metric'
}
response = requests.get(base_url, params=params, timeout=5)
response.raise_for_status()
data = response.json()
weather_info = f"""
🌤️ **Weather for {data['name']}, {data['sys']['country']}**
Temperature: {data['main']['temp']:.1f}°C ({data['main']['temp'] * 9/5 + 32:.1f}°F)
Feels like: {data['main']['feels_like']:.1f}°C
Condition: {data['weather'][0]['description'].title()}
Humidity: {data['main']['humidity']}%
Pressure: {data['main']['pressure']} hPa
Wind: {data['wind']['speed']} m/s
Last updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
return weather_info
except requests.exceptions.RequestException as e:
logger.error(f"Weather API error: {e}")
return f"Unable to fetch weather data for {location}. API error: {str(e)}"
except Exception as e:
logger.error(f"Weather tool error: {e}")
return f"Error getting weather information: {str(e)}"
@tool
def calculate_math(expression: str) -> str:
"""
Safely evaluate mathematical expressions.
Args:
expression: Mathematical expression to evaluate (e.g., "2 + 2 * 3")
Returns:
Result of the mathematical calculation
"""
try:
# Simple evaluation for basic math operations
# In production, you might want to use a more sophisticated math parser
# Remove any potentially dangerous characters
allowed_chars = "0123456789+-*/()., "
cleaned_expression = ''.join(c for c in expression if c in allowed_chars)
if cleaned_expression != expression:
return f"Expression contains invalid characters. Cleaned: {cleaned_expression}"
# Evaluate the expression
result = eval(cleaned_expression)
return f"""
🧮 **Mathematical Calculation**
Expression: {expression}
Result: {result}
Calculated at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
except ZeroDivisionError:
return "Error: Division by zero is not allowed."
except Exception as e:
logger.error(f"Math calculation error: {e}")
return f"Error calculating expression '{expression}': {str(e)}"
@tool
def get_current_time(timezone: str = "UTC") -> str:
"""
Get current time for a specific timezone.
Args:
timezone: Timezone (default: UTC)
Returns:
Current date and time information
"""
try:
from datetime import datetime
try:
import pytz
if timezone == "UTC":
current_time = datetime.utcnow()
tz_info = "UTC"
else:
try:
tz = pytz.timezone(timezone)
current_time = datetime.now(tz)
tz_info = timezone
except:
# Fallback to UTC
current_time = datetime.utcnow()
tz_info = "UTC (fallback - invalid timezone provided)"
except ImportError:
# Fallback without pytz
current_time = datetime.now()
tz_info = "Local System Time"
time_info = f"""
🕒 **Current Time Information**
Date: {current_time.strftime('%A, %B %d, %Y')}
Time: {current_time.strftime('%H:%M:%S')}
Timezone: {tz_info}
ISO Format: {current_time.isoformat()}
"""
return time_info
except Exception as e:
logger.error(f"Time tool error: {e}")
return f"Error getting current time: {str(e)}"
@tool
def text_summarizer(text: str, max_sentences: int = 3) -> str:
"""
Summarize a given text to specified number of sentences.
Args:
text: Text to summarize
max_sentences: Maximum number of sentences in summary (default: 3)
Returns:
Summarized text
"""
try:
import re
if not text.strip():
return "No text provided to summarize."
# Simple extractive summarization
# Split into sentences
sentences = re.split(r'[.!?]+', text.strip())
sentences = [s.strip() for s in sentences if s.strip()]
if len(sentences) <= max_sentences:
return f"**Summary:** {text[:500]}..." if len(text) > 500 else text
# Simple scoring based on sentence length and position
scored_sentences = []
for i, sentence in enumerate(sentences):
# Prefer sentences of medium length and earlier position
length_score = min(len(sentence.split()) / 15, 1.0) # Normalize to words
position_score = 1.0 - (i / len(sentences)) # Earlier sentences get higher score
total_score = length_score * 0.7 + position_score * 0.3
scored_sentences.append((sentence, total_score))
# Sort by score and take top sentences
scored_sentences.sort(key=lambda x: x[1], reverse=True)
summary_sentences = [s[0] for s in scored_sentences[:max_sentences]]
# Maintain original order
final_summary = []
for sentence in sentences:
if sentence in summary_sentences:
final_summary.append(sentence)
if len(final_summary) == max_sentences:
break
summary = '. '.join(final_summary) + '.'
return f"""
📄 **Text Summary**
Original length: {len(text)} characters
Summary length: {len(summary)} characters
Sentences: {max_sentences}
**Summary:** {summary}
"""
except Exception as e:
logger.error(f"Text summarization error: {e}")
return f"Error summarizing text: {str(e)}"
# List of all available tools for easy import
AVAILABLE_TOOLS = [
web_search,
get_weather_info,
calculate_math,
get_current_time,
text_summarizer
]