@xynehq/jaf
Version:
Juspay Agent Framework - A purely functional agent framework with immutable state and composable tools
200 lines • 7.85 kB
JavaScript
/**
* JAF ADK - Production Geocoding Tool
*
* Real geocoding using OpenStreetMap Nominatim API (no key required)
*/
import { createFunctionTool } from '../tools';
import { ToolParameterType } from '../types';
/**
* Create a production geocoding tool using OpenStreetMap Nominatim API
* No API key required - uses public Nominatim service
*/
export const createGeocodingTool = () => {
return createFunctionTool({
name: 'geocode',
description: 'Convert addresses to coordinates or vice versa',
execute: async (params) => {
const { address, latitude, longitude, reverse = false } = params;
try {
if (reverse && latitude !== undefined && longitude !== undefined) {
// Reverse geocoding: coordinates to address
const url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json`;
const response = await fetch(url, {
headers: {
'User-Agent': 'JAF-Framework/1.0'
}
});
if (!response.ok) {
throw new Error(`Geocoding API error: ${response.status}`);
}
const data = await response.json();
return {
type: 'reverse',
latitude,
longitude,
display_name: data.display_name,
address: {
house_number: data.address?.house_number,
road: data.address?.road,
suburb: data.address?.suburb,
city: data.address?.city || data.address?.town || data.address?.village,
state: data.address?.state,
postcode: data.address?.postcode,
country: data.address?.country,
country_code: data.address?.country_code
},
place_id: data.place_id,
osm_id: data.osm_id,
osm_type: data.osm_type
};
}
else if (address) {
// Forward geocoding: address to coordinates
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(address)}&format=json&limit=5`;
const response = await fetch(url, {
headers: {
'User-Agent': 'JAF-Framework/1.0'
}
});
if (!response.ok) {
throw new Error(`Geocoding API error: ${response.status}`);
}
const data = await response.json();
if (data.length === 0) {
throw new Error(`No results found for address: ${address}`);
}
// Return top results
return {
type: 'forward',
query: address,
results: data.map((result) => ({
display_name: result.display_name,
latitude: parseFloat(result.lat),
longitude: parseFloat(result.lon),
importance: result.importance,
place_id: result.place_id,
osm_id: result.osm_id,
osm_type: result.osm_type,
class: result.class,
type: result.type,
boundingbox: result.boundingbox?.map((b) => parseFloat(b))
}))
};
}
else {
throw new Error('Either address or latitude/longitude must be provided');
}
}
catch (error) {
// Fallback to mock data on error
console.warn('Geocoding API error, using mock data:', error);
return getMockGeocodingData(address, latitude, longitude, reverse);
}
},
parameters: [
{
name: 'address',
type: ToolParameterType.STRING,
description: 'Address to geocode (for forward geocoding)',
required: false
},
{
name: 'latitude',
type: ToolParameterType.NUMBER,
description: 'Latitude (for reverse geocoding)',
required: false
},
{
name: 'longitude',
type: ToolParameterType.NUMBER,
description: 'Longitude (for reverse geocoding)',
required: false
},
{
name: 'reverse',
type: ToolParameterType.BOOLEAN,
description: 'Set to true for reverse geocoding',
required: false,
default: false
}
]
});
};
/**
* Fallback mock geocoding data for development/testing
*/
const getMockGeocodingData = (address, latitude, longitude, reverse) => {
if (reverse && latitude !== undefined && longitude !== undefined) {
return {
type: 'reverse',
latitude,
longitude,
display_name: '123 Main Street, New York, NY 10001, USA',
address: {
house_number: '123',
road: 'Main Street',
city: 'New York',
state: 'New York',
postcode: '10001',
country: 'United States',
country_code: 'us'
},
place_id: 'mock_place_123',
osm_id: 'mock_osm_123',
osm_type: 'way',
mock: true
};
}
else if (address) {
const mockLocations = {
'new york': {
display_name: 'New York, United States',
latitude: 40.7128,
longitude: -74.0060
},
'london': {
display_name: 'London, United Kingdom',
latitude: 51.5074,
longitude: -0.1278
},
'tokyo': {
display_name: 'Tokyo, Japan',
latitude: 35.6762,
longitude: 139.6503
},
'sydney': {
display_name: 'Sydney, Australia',
latitude: -33.8688,
longitude: 151.2093
}
};
const location = mockLocations[address.toLowerCase()] || {
display_name: address,
latitude: 0,
longitude: 0
};
return {
type: 'forward',
query: address,
results: [{
...location,
importance: 0.8,
place_id: 'mock_place_' + Math.random(),
osm_id: 'mock_osm_' + Math.random(),
osm_type: 'relation',
class: 'place',
type: 'city',
boundingbox: [
location.latitude - 0.1,
location.latitude + 0.1,
location.longitude - 0.1,
location.longitude + 0.1
]
}],
mock: true
};
}
throw new Error('Either address or latitude/longitude must be provided');
};
export default createGeocodingTool;
//# sourceMappingURL=geocoding.js.map