File size: 4,580 Bytes
efa8259
 
 
 
 
841e77b
77b0ccb
efa8259
 
 
841e77b
efa8259
 
 
 
77b0ccb
efa8259
 
 
841e77b
efa8259
841e77b
efa8259
139193c
efa8259
 
139193c
 
 
 
 
841e77b
139193c
841e77b
 
 
139193c
efa8259
139193c
841e77b
 
 
 
efa8259
139193c
efa8259
139193c
77b0ccb
139193c
77b0ccb
 
139193c
 
 
77b0ccb
efa8259
 
139193c
77b0ccb
139193c
77b0ccb
 
 
 
 
 
139193c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77b0ccb
139193c
77b0ccb
139193c
 
 
 
 
 
 
 
 
efa8259
77b0ccb
 
 
139193c
77b0ccb
 
efa8259
139193c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
        import time

        try:
            # Initialize geocoder with increased timeout
            geolocator = Nominatim(user_agent="journey_metrics_calculator", timeout=10)

            # Add delay between requests to avoid rate limiting
            time.sleep(1)
            start = geolocator.geocode(start_location)
            time.sleep(1)
            end = geolocator.geocode(destination_location)

            if not start or not end:
                return "Could not find one or both locations. Please check spelling and try again."

            # Calculate distance
            distance_km = geodesic(
                (start.latitude, start.longitude),
                (end.latitude, end.longitude)
            ).kilometers

            # Define speeds (km/h) with more realistic values
            speeds = {
                'driving': {'urban': 50, 'highway': 100, 'average': 80},
                'walking': {'average': 5},
                'bicycling': {'casual': 15, 'average': 20},
                'transit': {'urban': 30, 'intercity': 60},
                'plane': {
                    'short_haul': 500,  # <500km
                    'medium_haul': 700, # 500-3000km
                    'long_haul': 850    # >3000km
                }
            }

            # Calculate time based on mode and distance
            if transportation_mode == 'plane':
                # Select appropriate plane speed based on distance
                if distance_km < 500:
                    speed = speeds['plane']['short_haul']
                elif distance_km < 3000:
                    speed = speeds['plane']['medium_haul']
                else:
                    speed = speeds['plane']['long_haul']

                # Calculate flight time
                flight_hours = distance_km / speed

                # Add airport procedures time (2 hours total)
                total_hours = flight_hours + 2

                # Format the response for plane travel
                flight_minutes = int(flight_hours * 60)
                total_hrs = int(total_hours)
                total_mins = int((total_hours - total_hrs) * 60)

                return (
                    f"Journey metrics:\n"
                    f"Distance: {distance_km:.1f} kilometers\n"
                    f"Flight time: {flight_minutes} minutes\n"
                    f"Total estimated time (including airport procedures): "
                    f"{total_hrs} hours and {total_mins} minutes"
                )
            else:
                # Get speed for other modes
                mode = transportation_mode or 'driving'
                if mode not in speeds:
                    return f"Unsupported transportation mode: {mode}"

                speed = speeds[mode]['average']
                hours = distance_km / speed

                # Format time string
                hrs = int(hours)
                mins = int((hours - hrs) * 60)

                return (
                    f"Journey metrics:\n"
                    f"Distance: {distance_km:.1f} kilometers\n"
                    f"Estimated time by {mode}: {hrs} hours and {mins} minutes"
                )

        except Exception as e:
            return f"Error calculating journey metrics: Please try again with more specific location names. Error: {str(e)}"