|
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__() |
|
|
|
self.api_key = api_key or os.environ.get("EXCHANGE_RATE_API_KEY") |
|
|
|
|
|
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: |
|
|
|
from_currency = from_currency.upper().strip() |
|
to_currency = to_currency.upper().strip() |
|
|
|
|
|
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: |
|
|
|
return self._convert_with_stored_rates(amount, from_currency, to_currency) |
|
|
|
except Exception: |
|
|
|
return self._convert_with_stored_rates(amount, from_currency, to_currency) |
|
|
|
|
|
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: |
|
|
|
if from_currency not in self.exchange_rates: |
|
return f"Sorry, I don't have exchange rate data for {from_currency}." |
|
|
|
|
|
if from_currency == to_currency: |
|
return f"{amount} {from_currency} = {amount} {to_currency}" |
|
|
|
|
|
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)" |
|
|
|
|
|
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}." |
|
|