MHamdan's picture
Upload tool
52f892f verified
raw
history blame
3.85 kB
from smolagents import Tool
from typing import Any, Optional
class SimpleTool(Tool):
name = "calculate_journey_metrics"
description = "Calculates journey metrics including distance and time."
inputs = {"start_location":{"type":"string","description":"The starting point of the journey."},"destination_location":{"type":"string","description":"The endpoint of the journey."},"transportation_mode":{"type":"string","nullable":True,"description":"Mode of transport ('driving', 'walking', 'bicycling', 'transit', or 'plane'). Defaults to 'driving'."}}
output_type = "string"
def forward(self, start_location: str, destination_location: str, transportation_mode: Optional[str] = None) -> str:
"""Calculates journey metrics including distance and time.
Args:
start_location: The starting point of the journey.
destination_location: The endpoint of the journey.
transportation_mode: Mode of transport ('driving', 'walking', 'bicycling', 'transit', or 'plane').
Defaults to 'driving'.
Returns:
str: Journey distance and estimated time.
"""
from geopy.geocoders import Nominatim
from geopy.distance import geodesic
try:
geolocator = Nominatim(user_agent="journey_metrics_calculator")
start = geolocator.geocode(start_location)
end = geolocator.geocode(destination_location)
if not start or not end:
return "Could not find one or both locations"
distance_km = geodesic(
(start.latitude, start.longitude),
(end.latitude, end.longitude)
).kilometers
speeds = {
'driving': {'urban': 30, 'highway': 100, 'average': 80},
'walking': {'average': 5},
'bicycling': {'casual': 12, 'average': 20},
'transit': {'urban': 30, 'intercity': 60},
'plane': {
'short_haul': 500,
'medium_haul': 700,
'long_haul': 800
}
}
if transportation_mode == 'plane':
if distance_km < 500:
speed = speeds['plane']['short_haul']
elif distance_km < 3000:
speed = speeds['plane']['medium_haul']
else:
speed = speeds['plane']['long_haul']
additional_time = 2
else:
mode = transportation_mode or 'driving'
speed = speeds.get(mode, speeds['driving'])['average']
additional_time = 0
travel_time = distance_km / speed
total_hours = travel_time + additional_time
if total_hours < 1:
time_str = f"{int(total_hours * 60)} minutes"
elif total_hours < 24:
hrs = int(total_hours)
mins = int((total_hours - hrs) * 60)
time_str = f"{hrs} hours and {mins} minutes"
else:
days = total_hours / 24
time_str = f"{days:.1f} days"
if transportation_mode == 'plane':
return (
f"Journey metrics:\n"
f"Distance: {distance_km:.1f} kilometers\n"
f"Flight time: {int(travel_time * 60)} minutes\n"
f"Total estimated time (including airport procedures): {time_str}"
)
return (
f"Journey metrics:\n"
f"Distance: {distance_km:.1f} kilometers\n"
f"Estimated time by {transportation_mode or 'driving'}: {time_str}"
)
except Exception as e:
return f"Error calculating journey metrics: {str(e)}"