fix(navi): format tool output as human-readable directions

This commit is contained in:
Matt 2026-04-19 22:42:17 +00:00
commit 9841c38011

View file

@ -1,7 +1,7 @@
""" """
title: Navigation title: Navigation
author: Echo6 author: Echo6
version: 1.0.0 version: 1.1.0
description: Turn-by-turn directions and geocoding via Photon + Valhalla on recon-vm. Supports driving, walking, cycling, and truck routing with worldwide coverage (281M places). description: Turn-by-turn directions and geocoding via Photon + Valhalla on recon-vm. Supports driving, walking, cycling, and truck routing with worldwide coverage (281M places).
""" """
@ -57,28 +57,24 @@ class Tools:
mode: str = "auto", mode: str = "auto",
) -> str: ) -> str:
""" """
Get turn-by-turn driving, walking, or cycling directions between two locations. Get turn-by-turn directions between two locations. When this tool returns results, present the directions exactly as returned do not summarize or rephrase. Include all steps.
Use this when someone asks how to get somewhere, asks for directions, or wants to know distance/time between places.
:param origin: Starting location address, place name, or lat,lon coordinates :param origin: Starting location address, place name, or lat,lon coordinates
:param destination: Destination address, place name, or lat,lon coordinates :param destination: Destination address, place name, or lat,lon coordinates
:param mode: Travel mode: auto, pedestrian, bicycle, or truck (default: auto) :param mode: Travel mode: auto, pedestrian, bicycle, or truck (default: auto)
:return: Directions with distance, time, and turn-by-turn maneuvers :return: Formatted turn-by-turn directions
""" """
if mode not in ("auto", "pedestrian", "bicycle", "truck"): if mode not in ("auto", "pedestrian", "bicycle", "truck"):
mode = "auto" mode = "auto"
# Geocode origin
orig_lat, orig_lon, orig_name = self._geocode(origin) orig_lat, orig_lon, orig_name = self._geocode(origin)
if orig_lat is None: if orig_lat is None:
return json.dumps({"error": f"Could not find location: {origin}"}) return f"Could not find location: {origin}"
# Geocode destination
dest_lat, dest_lon, dest_name = self._geocode(destination) dest_lat, dest_lon, dest_name = self._geocode(destination)
if dest_lat is None: if dest_lat is None:
return json.dumps({"error": f"Could not find location: {destination}"}) return f"Could not find location: {destination}"
# Route via Valhalla
try: try:
resp = requests.post( resp = requests.post(
f"{self.valves.valhalla_url}/route", f"{self.valves.valhalla_url}/route",
@ -93,30 +89,29 @@ class Tools:
timeout=30, timeout=30,
) )
except requests.RequestException: except requests.RequestException:
return json.dumps({"error": "Navigation service unavailable"}) return "Navigation service unavailable"
if resp.status_code != 200: if resp.status_code != 200:
return json.dumps({"error": "No route found between locations"}) return "No route found between locations"
trip = resp.json()["trip"] trip = resp.json()["trip"]
summary = trip["summary"] summary = trip["summary"]
maneuvers = [] legs = trip["legs"][0]["maneuvers"]
for m in trip["legs"][0]["maneuvers"]:
streets = m.get("street_names", [])
entry = {
"instruction": m["instruction"],
"distance_miles": round(m.get("length", 0), 2),
}
if streets:
entry["street"] = streets[0]
maneuvers.append(entry)
result = { miles = round(summary["length"], 1)
"origin": orig_name, minutes = round(summary["time"] / 60, 1)
"destination": dest_name,
"distance_miles": round(summary["length"], 1), lines = [
"time_minutes": round(summary["time"] / 60, 1), f"Directions from {orig_name} to {dest_name} ({mode}):",
"mode": mode, f"Distance: {miles} miles | Time: {minutes} minutes",
"maneuvers": maneuvers, "",
} ]
return json.dumps(result) for i, m in enumerate(legs, 1):
inst = m["instruction"]
dist = m.get("length", 0)
if dist > 0:
lines.append(f"{i}. {inst}{round(dist, 1)} mi")
else:
lines.append(f"{i}. {inst}")
return "\n".join(lines)