Skip to main content
Glama
cleanResponseData.ts7.71 kB
import { z } from 'zod'; import { DirectionsInputSchema } from './DirectionsTool.js'; /** * Cleans up the API response to reduce token count while preserving useful data. * * @param input The original input parameters used for the request * @param data The raw response data from the Mapbox Directions API * @returns Cleaned data with reduced token count */ export function cleanResponseData( input: z.infer<typeof DirectionsInputSchema>, data: any ): any { // Remove unnecessary keys to reduce token count if ('uuid' in data) { delete data.uuid; } if ('code' in data) { delete data.code; } if ('waypoints' in data) { // rename each waypoint's location to `snap_location` and distance to `snap_distance` // this is not really necessary, but hopefully agents will find this more obvious that we have snapping data.waypoints = data.waypoints.map((waypoint: any) => { const updatedWaypoint = { ...waypoint }; if ('location' in updatedWaypoint) { updatedWaypoint.snap_location = updatedWaypoint.location; delete updatedWaypoint.location; } if ('distance' in updatedWaypoint) { updatedWaypoint.snap_distance = Math.round(updatedWaypoint.distance); delete updatedWaypoint.distance; } return updatedWaypoint; }); } if (!('routes' in data)) { // lets return early because there is nothing more we could do here return data; } data.routes.forEach((route: any) => { // Round duration and distance to integers if they exist if (route.duration !== undefined) { route.duration = Math.round(route.duration); } if (route.distance !== undefined) { route.distance = Math.round(route.distance); } delete route.weight_name; delete route.weight; // Handle the case where geometry is not included (when geometries='none') if (input.geometries === 'none' && route.geometry) { delete route.geometry; } route.leg_summaries = route.legs.map((leg: any) => leg.summary); // Collect all unique admins across all legs of this route const routeUniqueIsoCodes = new Set<string>(); // Collect all unique notification messages across all legs of this route const routeUniqueNotificationMessages = new Set<string>(); // Collect all incidents across all legs of this route const routeIncidents: any[] = []; // Collect voice instruction announcements from all steps const routeAnnouncements: string[] = []; let totalDistanceWeightedSpeed = 0; // Sum of (speed × distance) for each segment let sumDistanceMeters = 0; // Object to track distance by congestion type const congestionTypeToDistance = { severe: 0, heavy: 0, moderate: 0, low: 0 }; route.legs.forEach((leg: any) => { if (leg.annotation && leg.annotation.speed && leg.annotation.distance) { leg.annotation.speed.forEach((speed: number, index: number) => { const speedValue = parseFloat(String(speed)); const distance = parseFloat(String(leg.annotation.distance[index])); // Calculate the weighted speed (speed * distance) totalDistanceWeightedSpeed += speedValue * distance; sumDistanceMeters += distance; }); } if ( leg.annotation && leg.annotation.congestion && leg.annotation.distance ) { // iterate every congestion string in leg.annotation.congestion // each string is one of `severe, heavy, moderate, low, unknown` // keep track of total distance by type of congestion leg.annotation.congestion.forEach( (congestion: string, index: number) => { const distance = parseFloat(String(leg.annotation.distance[index])); if ( congestion === 'severe' || congestion === 'heavy' || congestion === 'moderate' || congestion === 'low' ) { congestionTypeToDistance[congestion] += distance; } // Skip 'unknown' congestion type } ); } if (leg.admins && Array.isArray(leg.admins)) { // Extract unique ISO codes from this leg leg.admins.forEach((admin: any) => { if (admin.iso_3166_1_alpha3) { routeUniqueIsoCodes.add(admin.iso_3166_1_alpha3); } }); } // Process notifications if they exist if (leg.notifications && Array.isArray(leg.notifications)) { // Extract unique notification messages from this leg leg.notifications.forEach((notification: any) => { if (notification.details && notification.details.message) { routeUniqueNotificationMessages.add(notification.details.message); } }); } // Process incidents if they exist if (leg.incidents && Array.isArray(leg.incidents)) { leg.incidents.forEach((incident: any) => { // Extract only the specified fields for each incident routeIncidents.push({ type: incident.type, end_time: incident.end_time, long_description: incident.long_description, impact: incident.impact, affected_road_names: incident.affected_road_names, length: incident.length }); }); } // Process steps if they exist to collect voice instructions if (leg.steps && Array.isArray(leg.steps)) { leg.steps.forEach((step: any) => { if (step.voiceInstructions && Array.isArray(step.voiceInstructions)) { step.voiceInstructions.forEach((instruction: any) => { if (instruction.announcement) { routeAnnouncements.push(instruction.announcement); } }); } }); } }); // Add all unique admins as a new property on the route route.intersecting_admins = Array.from(routeUniqueIsoCodes); // Add all unique notification messages as a new property on the route route.notifications_summary = Array.from(routeUniqueNotificationMessages); // Add all incidents with the specified fields as a new property on the route route.incidents_summary = routeIncidents; // Add voice instruction announcements only if there are 1 to 10 of them // If there are more than 10, it's just too many, and if there is 0 then we don't have them. if (routeAnnouncements.length >= 1 && routeAnnouncements.length <= 10) { route.instructions = routeAnnouncements; } route.num_legs = route.legs.length; // Add congestion distance information to route route.congestion_information = { length_low: Math.round(congestionTypeToDistance.low), length_moderate: Math.round(congestionTypeToDistance.moderate), length_heavy: Math.round(congestionTypeToDistance.heavy), length_severe: Math.round(congestionTypeToDistance.severe) }; // Calculate and add average speed in km/h if (sumDistanceMeters > 0 && totalDistanceWeightedSpeed > 0) { // Calculate distance-weighted average speed const averageMetersPerSecond = totalDistanceWeightedSpeed / sumDistanceMeters; // Convert m/s to km/h (multiply by 3.6) and round to integer route.average_speed_kph = Math.round(averageMetersPerSecond * 3.6); } if (route.duration_typical) { route.duration_under_typical_traffic_conditions = Math.round( route.duration_typical ); delete route.duration_typical; } if (route.weight_typical) { delete route.weight_typical; } delete route.legs; }); return data; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Waldzell-Agentics/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server