Spaces:
Runtime error
Runtime error
| 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)}" | |
| 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)}" | |
| 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)}" | |
| 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 | |
| ] |