Places Tools
The @openassistant/places package provides location intelligence with place search and geotagging capabilities using the Foursquare Places API.
Installation
bash
npm install @openassistant/placesAvailable Tools
placeSearch- Search for places using Foursquare Places APIgeoTagging- Add geographic context to textwebSearch- Web search with location context
Basic Usage
Place Search with Assistant
typescript
import { placeSearch } from '@openassistant/places';
import { Assistant, type AssistantOptions } from '@openassistant/assistant';
import { ToolCache } from '@openassistant/utils';
const toolResultCache = ToolCache.getInstance();
const placeSearchTool = {
...placeSearch,
context: {
getFsqToken: () => process.env.FSQ_TOKEN!,
},
onToolCompleted: (toolCallId: string, additionalData?: unknown) => {
// Cache place search results for use with other tools
toolResultCache.addDataset(toolCallId, additionalData);
},
};
const config: AssistantOptions = {
ai: {
getInstructions: () => `
You can search for places using the Foursquare Places API.
Help users find restaurants, coffee shops, hotels, and other points of interest.
`,
tools: {
placeSearch: placeSearchTool,
},
},
};
export function App() {
return <Assistant options={config} />;
}Usage with Vercel AI SDK
typescript
import { placeSearch } from '@openassistant/places';
import { convertToVercelAiTool } from '@openassistant/utils';
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const placeSearchTool = {
...placeSearch,
context: {
getFsqToken: () => process.env.FSQ_TOKEN!,
},
};
const result = await generateText({
model: openai('gpt-4'),
prompt: 'Find coffee shops near Times Square',
tools: {
placeSearch: convertToVercelAiTool(placeSearchTool),
},
});
console.log(result.text);Advanced Usage
Combining with Geocoding
Combine place search with geocoding to search by address:
typescript
import { placeSearch } from '@openassistant/places';
import { geocoding } from '@openassistant/osm';
import { Assistant } from '@openassistant/assistant';
const config = {
ai: {
getInstructions: () => `
You can search for places and geocode addresses.
Use geocoding first to get coordinates, then search for places nearby.
`,
tools: {
geocoding: { ...geocoding },
placeSearch: {
...placeSearch,
context: {
getFsqToken: () => process.env.FSQ_TOKEN!,
},
},
},
},
};
export function App() {
return <Assistant options={config} />;
}Combining with Map Visualization
typescript
import { placeSearch } from '@openassistant/places';
import { keplergl } from '@openassistant/map';
import { KeplerGlComponent } from '@openassistant/keplergl';
import { ToolCache } from '@openassistant/utils';
import { Assistant } from '@openassistant/assistant';
const toolResultCache = ToolCache.getInstance();
const placeSearchTool = {
...placeSearch,
context: {
getFsqToken: () => process.env.FSQ_TOKEN!,
},
onToolCompleted: (toolCallId, additionalData) => {
toolResultCache.addDataset(toolCallId, additionalData);
},
};
const keplerglTool = {
...keplergl,
context: {
getDataset: async (datasetName: string) => {
if (toolResultCache.hasDataset(datasetName)) {
return toolResultCache.getDataset(datasetName);
}
throw new Error(`Dataset ${datasetName} not found`);
},
},
component: KeplerGlComponent,
};
const config = {
ai: {
getInstructions: () => `
You can search for places and visualize them on a map.
First search for places, then create a map using the results.
`,
tools: {
placeSearch: placeSearchTool,
keplergl: keplerglTool,
},
},
};
export function App() {
return <Assistant options={config} />;
}With Isochrone Filtering
Search for places within a travel time area:
typescript
import { placeSearch } from '@openassistant/places';
import { isochrone } from '@openassistant/osm';
import { ToolCache } from '@openassistant/utils';
import { Assistant } from '@openassistant/assistant';
const toolResultCache = ToolCache.getInstance();
const isochroneTool = {
...isochrone,
context: {
getMapboxToken: () => process.env.MAPBOX_TOKEN!,
},
onToolCompleted: (toolCallId, additionalData) => {
toolResultCache.addDataset(toolCallId, additionalData);
},
};
const placeSearchTool = {
...placeSearch,
context: {
getFsqToken: () => process.env.FSQ_TOKEN!,
getGeometries: async (datasetName: string) => {
// Return isochrone polygon for filtering
if (toolResultCache.hasDataset(datasetName)) {
const data = toolResultCache.getDataset(datasetName);
return [data.content];
}
throw new Error(`Dataset ${datasetName} not found`);
},
},
};
const config = {
ai: {
getInstructions: () => `
You can search for places within a travel time area.
First create an isochrone, then search for places within it.
`,
tools: {
isochrone: isochroneTool,
placeSearch: placeSearchTool,
},
},
};Tool Parameters
Place Search Parameters
typescript
{
query?: string; // Search query (e.g., "coffee", "restaurant")
location?: {
longitude: number;
latitude: number;
radius?: number; // Search radius in meters (0-100000)
};
near?: string; // Geocodable locality (e.g., "New York, NY")
categories?: string[]; // Array of category IDs
chains?: string[]; // Array of chain IDs to filter by
exclude_chains?: string[]; // Array of chain IDs to exclude
exclude_all_chains?: boolean; // Exclude all chain locations
min_price?: number; // Minimum price range (1-4)
max_price?: number; // Maximum price range (1-4)
open_now?: boolean; // Only return places currently open
open_at?: string; // Open at specific time (format: "DOWTHHMM")
limit?: number; // Maximum results (1-50, default: 10)
sort?: 'relevance' | 'rating' | 'distance'; // Sort order (default: 'relevance')
// Advanced filtering
ne?: { latitude: number; longitude: number }; // North-east corner for bounds
sw?: { latitude: number; longitude: number }; // South-west corner for bounds
isochroneDatasetName?: string; // Dataset name of isochrone polygon
super_venue_id?: string; // Foursquare Venue ID for search bounds
}Context Options
typescript
type FoursquareToolContext = {
// Required: Get Foursquare API token
getFsqToken: () => string;
// Optional: Get geometries for polygon filtering (isochrone)
getGeometries?: (datasetName: string) => Promise<GeoJSON.FeatureCollection[]>;
};Getting a Foursquare API Token
- Sign up at foursquare.com/developers
- Create a new project
- Get your API key
- Provide it via the
getFsqTokencontext method
Example User Prompts
The AI can respond to prompts like:
- "Find coffee shops near Times Square"
- "Search for restaurants within 2km of the Eiffel Tower"
- "What are the best rated hotels in San Francisco?"
- "Find expensive restaurants in Manhattan that are open now"
- "Show me gas stations within a 10-minute drive from here"
- "Find vegetarian restaurants near me"
Search Features
Category Filtering
Search by Foursquare category IDs for specific types of places:
typescript
// Example: Search for restaurants (category: 13065)
{
query: "restaurants",
categories: ["13065"],
location: { latitude: 40.7589, longitude: -73.9851 }
}Price Filtering
Filter by price range (1 = most affordable, 4 = most expensive):
typescript
{
query: "restaurants",
location: { latitude: 40.7589, longitude: -73.9851 },
min_price: 3,
max_price: 4
}Opening Hours
Search for places that are currently open or open at specific times:
typescript
// Currently open
{
query: "restaurants",
location: { latitude: 40.7589, longitude: -73.9851 },
open_now: true
}
// Open on Monday at 9:30 PM
{
query: "restaurants",
location: { latitude: 40.7589, longitude: -73.9851 },
open_at: "1T2130"
}Response Data
The place search tool returns GeoJSON FeatureCollection with rich place data:
- Basic info: name, address, phone, website
- Categories and chains
- Distance from search center
- Ratings and pricing
- Opening hours
- Photos
- Tips and reviews
- Social media links
- And more...
Rate Limiting
The place search tool includes built-in rate limiting to comply with Foursquare API usage policies.
API Reference
For detailed API documentation, see the Places API Reference.
Next Steps
- OSM Tools - Geocoding and routing
- Map Tools - Visualize place search results
- DuckDB Tools - Query and analyze place data
