Journi / tools /convert_currency.py
PLBot's picture
Rename tools/currency_converter_tool.py to tools/convert_currency.py
50c4bdf verified
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}."