Spaces:
Sleeping
Sleeping
from typing import Any, Optional | |
from smolagents.tools import Tool | |
import os | |
import requests | |
class ConvertCurrencyTool(Tool): | |
name = "convert_currency" | |
description = "Converts an amount between currencies for travel budgeting." | |
inputs = { | |
'amount': {'type': 'number', 'description': 'The amount to convert'}, | |
'from_currency': {'type': 'string', 'description': 'Source currency code (e.g., USD, EUR)'}, | |
'to_currency': {'type': 'string', 'description': 'Target currency code (e.g., JPY, GBP)'} | |
} | |
output_type = "string" | |
def __init__(self, api_key=None): | |
super().__init__() | |
# You can set an API key for a real currency API | |
self.api_key = api_key or os.environ.get("EXCHANGE_RATE_API_KEY") | |
# Common exchange rates (as of early 2025, for demo/fallback purposes) | |
self.exchange_rates = { | |
"USD": {"EUR": 0.92, "GBP": 0.79, "JPY": 149.50, "CAD": 1.35, "AUD": 1.52, "CNY": 7.20, "INR": 83.20, "MXN": 17.05}, | |
"EUR": {"USD": 1.09, "GBP": 0.86, "JPY": 163.00, "CAD": 1.47, "AUD": 1.66, "CNY": 7.85, "INR": 90.70, "MXN": 18.60}, | |
"GBP": {"USD": 1.27, "EUR": 1.16, "JPY": 189.30, "CAD": 1.71, "AUD": 1.92, "CNY": 9.10, "INR": 105.30, "MXN": 21.60}, | |
"JPY": {"USD": 0.0067, "EUR": 0.0061, "GBP": 0.0053, "CAD": 0.0090, "AUD": 0.0102, "CNY": 0.0482, "INR": 0.5565, "MXN": 0.1141}, | |
"CAD": {"USD": 0.74, "EUR": 0.68, "GBP": 0.58, "JPY": 110.70, "AUD": 1.13, "CNY": 5.33, "INR": 61.60, "MXN": 12.60}, | |
"AUD": {"USD": 0.66, "EUR": 0.60, "GBP": 0.52, "JPY": 98.40, "CAD": 0.89, "CNY": 4.73, "INR": 54.70, "MXN": 11.20}, | |
"CNY": {"USD": 0.14, "EUR": 0.13, "GBP": 0.11, "JPY": 20.80, "CAD": 0.19, "AUD": 0.21, "INR": 11.60, "MXN": 2.37}, | |
"INR": {"USD": 0.012, "EUR": 0.011, "GBP": 0.0095, "JPY": 1.80, "CAD": 0.016, "AUD": 0.018, "CNY": 0.086, "MXN": 0.205}, | |
"MXN": {"USD": 0.059, "EUR": 0.054, "GBP": 0.046, "JPY": 8.77, "CAD": 0.079, "AUD": 0.089, "CNY": 0.422, "INR": 4.88} | |
} | |
def forward(self, amount: float, from_currency: str, to_currency: str) -> str: | |
try: | |
# Normalize currency codes | |
from_currency = from_currency.upper().strip() | |
to_currency = to_currency.upper().strip() | |
# Try to use a real currency API if the API key is available | |
if self.api_key: | |
try: | |
url = f"https://v6.exchangerate-api.com/v6/{self.api_key}/pair/{from_currency}/{to_currency}/{amount}" | |
response = requests.get(url) | |
data = response.json() | |
if data.get('result') == 'success': | |
converted_amount = data.get('conversion_result') | |
rate = data.get('conversion_rate') | |
return f"💱 {amount:,.2f} {from_currency} = {converted_amount:,.2f} {to_currency}\n\nExchange rate: 1 {from_currency} = {rate} {to_currency}\n\n(Data from ExchangeRate-API)" | |
else: | |
# Fall back to stored rates if API call fails | |
return self._convert_with_stored_rates(amount, from_currency, to_currency) | |
except Exception: | |
# Fall back to stored rates if any error occurs | |
return self._convert_with_stored_rates(amount, from_currency, to_currency) | |
# If no API key is available, use the stored rates | |
return self._convert_with_stored_rates(amount, from_currency, to_currency) | |
except Exception as e: | |
return f"Error converting currency: {str(e)}" | |
def _convert_with_stored_rates(self, amount: float, from_currency: str, to_currency: str) -> str: | |
# Validate currencies | |
if from_currency not in self.exchange_rates: | |
return f"Sorry, I don't have exchange rate data for {from_currency}." | |
# If same currency, return original amount | |
if from_currency == to_currency: | |
return f"{amount} {from_currency} = {amount} {to_currency}" | |
# Direct conversion | |
if to_currency in self.exchange_rates[from_currency]: | |
rate = self.exchange_rates[from_currency][to_currency] | |
converted_amount = amount * rate | |
return f"💱 {amount:,.2f} {from_currency} = {converted_amount:,.2f} {to_currency}\n\nExchange rate: 1 {from_currency} = {rate} {to_currency}\n\n(Note: Rates are approximations for planning purposes only)" | |
# Try conversion through USD | |
if to_currency in self.exchange_rates and "USD" in self.exchange_rates[from_currency]: | |
usd_amount = amount * self.exchange_rates[from_currency]["USD"] | |
rate_to_target = self.exchange_rates["USD"].get(to_currency) | |
if rate_to_target: | |
converted_amount = usd_amount * rate_to_target | |
effective_rate = converted_amount / amount | |
return f"💱 {amount:,.2f} {from_currency} = {converted_amount:,.2f} {to_currency}\n\nExchange rate: 1 {from_currency} = {effective_rate:.4f} {to_currency}\n\n(Note: Rates are approximations for planning purposes only)" | |
return f"Sorry, I don't have exchange rate data from {from_currency} to {to_currency}." | |