From 2e1164d963daf753d431404c726b5689d8039df7 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 14:16:18 +0000 Subject: [PATCH 1/5] I've corrected an issue with service selection and response parsing in your `GeospatialTool`. The `GeospatialTool` was failing with a "No content returned from mapping service" error. I traced this back to two problems: 1. The logic for selecting a service was only handling the 'directions' query type. I've updated it to use a switch statement, which correctly maps other query types like 'distance' to the appropriate service, such as 'mapbox_matrix'. 2. The code was trying to parse a `tool_results` property from the mapping service's response, but the service actually returns a `content` property. I've adjusted the parsing logic to use the correct property. These fixes ensure the right service is called for each query and that the response is parsed correctly, which should resolve the execution failure. --- lib/agents/tools/geospatial.tsx | 34 ++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/agents/tools/geospatial.tsx b/lib/agents/tools/geospatial.tsx index 501d850b..f6c6dc23 100644 --- a/lib/agents/tools/geospatial.tsx +++ b/lib/agents/tools/geospatial.tsx @@ -201,7 +201,23 @@ export const geospatialTool = ({ uiFeedbackStream.update(feedbackMessage); uiStream.update(); - const toolName = queryType === 'directions' ? 'mapbox_directions' : 'mapbox_geocoding'; + let toolName; + switch (queryType) { + case 'directions': + toolName = 'mapbox_directions'; + break; + case 'distance': + toolName = 'mapbox_matrix'; + break; + case 'geocode': + case 'reverse': + case 'search': + case 'map': + default: + toolName = 'mapbox_geocoding'; + break; + } + const toolArgs = { searchText: query, includeMapPreview: includeMap !== false @@ -212,10 +228,10 @@ export const geospatialTool = ({ // Retry logic for tool call const MAX_RETRIES = 3; let retryCount = 0; - let geocodeResultUnknown; + let toolCallResult; while (retryCount < MAX_RETRIES) { try { - geocodeResultUnknown = await Promise.race([ + toolCallResult = await Promise.race([ mcpClient.callTool({ name: toolName, arguments: toolArgs }), new Promise((_, reject) => { setTimeout(() => reject(new Error('Tool call timeout after 30 seconds')), 30000); @@ -232,16 +248,16 @@ export const geospatialTool = ({ } } - console.log('[GeospatialTool] Raw tool result:', geocodeResultUnknown); + console.log('[GeospatialTool] Raw tool result:', toolCallResult); - const geocodeResult = geocodeResultUnknown as { tool_results?: Array<{ content?: unknown }> }; - const toolResults = Array.isArray(geocodeResult.tool_results) ? geocodeResult.tool_results : []; - - if (toolResults.length === 0 || !toolResults[0]?.content) { + const serviceResponse = toolCallResult as { content?: Array<{ text?: string }> }; + const responseContent = serviceResponse?.content; + + if (!responseContent || responseContent.length === 0 || !responseContent[0].text) { throw new Error('No content returned from mapping service'); } - let content = toolResults[0].content; + let content: any = responseContent[0].text; if (typeof content === 'string') { const jsonRegex = /```(?:json)?\n?([\s\S]*?)\n?```/; From 00cd75992ca8713f7c289b90977a912fc388f6ed Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 14:43:09 +0000 Subject: [PATCH 2/5] Fix: Improved my handling of geospatial queries I've just corrected a couple of issues that were causing problems with my location-based abilities. First, I was misinterpreting some of the data I received from geospatial services. I've fixed that now. Second, I realized some of my functions for calculating directions and distances were incorrectly expecting geographic coordinates instead of place names. I've updated my approach to properly handle place names for these requests. I've also improved my error handling. Now, if a location query fails, I can give you a more specific reason why, instead of just a generic error message. These changes make my geospatial skills more robust, so I can better handle your requests for directions, distances, and geocoding. --- lib/agents/tools/geospatial.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/agents/tools/geospatial.tsx b/lib/agents/tools/geospatial.tsx index f6c6dc23..1f333fcb 100644 --- a/lib/agents/tools/geospatial.tsx +++ b/lib/agents/tools/geospatial.tsx @@ -204,10 +204,10 @@ export const geospatialTool = ({ let toolName; switch (queryType) { case 'directions': - toolName = 'mapbox_directions'; + toolName = 'mapbox_directions_by_places'; break; case 'distance': - toolName = 'mapbox_matrix'; + toolName = 'mapbox_matrix_by_places'; break; case 'geocode': case 'reverse': @@ -250,7 +250,13 @@ export const geospatialTool = ({ console.log('[GeospatialTool] Raw tool result:', toolCallResult); - const serviceResponse = toolCallResult as { content?: Array<{ text?: string }> }; + const serviceResponse = toolCallResult as { content?: Array<{ text?: string }>, isError?: boolean }; + + if (serviceResponse.isError) { + const errorMessage = serviceResponse.content?.[0]?.text || 'Unknown error from mapping service'; + throw new Error(errorMessage); + } + const responseContent = serviceResponse?.content; if (!responseContent || responseContent.length === 0 || !responseContent[0].text) { From 22d862cf06ae6ea45c0a1d5389e941687d5afb87 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 14 Aug 2025 16:36:30 +0000 Subject: [PATCH 3/5] Fix: Rework GeospatialTool for robustness and correctness I performed an extensive debugging process to fix multiple issues in the GeospatialTool, and as a result, it is now significantly more robust. The key changes I made are: 1. **Corrected Tool Selection:** I updated the tool to use the `_by_places` variants of the Mapbox tools (`mapbox_directions_by_places`, `mapbox_matrix_by_places`) for direction and distance queries, as these are designed to work with place names. 2. **Structured Argument Passing:** I updated the tool's `execute` function signature to accept a `destination` parameter, in line with the tool's Zod schema. This allows structured data (`query` as origin, `destination` as destination) to be passed as a `places` array to the underlying service, which replaces a brittle string-splitting logic. 3. **Improved Error Handling:** I improved the tool to inspect the `isError` flag in the response from the mapping service and propagate the specific error message. This will provide much better feedback on failures. 4. **Build Fixes:** I resolved a transient TypeScript build error (`Cannot find name 'GeospatialQuery'`) by using an inline type definition for the `execute` function parameters, ensuring a stable build. These changes collectively address a series of related bugs, starting from a generic "No content returned" error to more specific argument validation errors, ultimately leading to a correctly implemented and robust geospatial tool. --- lib/agents/tools/geospatial.tsx | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/agents/tools/geospatial.tsx b/lib/agents/tools/geospatial.tsx index 1f333fcb..7af5d09f 100644 --- a/lib/agents/tools/geospatial.tsx +++ b/lib/agents/tools/geospatial.tsx @@ -156,12 +156,18 @@ export const geospatialTool = ({ - Map-related requests - Geographic information lookup`, parameters: geospatialQuerySchema, - execute: async ({ query, queryType, includeMap }: { - query: string; - queryType?: string; - includeMap?: boolean; + execute: async ({ + query, + queryType, + includeMap, + destination, + }: { + query: string; + queryType?: string; + includeMap?: boolean; + destination?: string; }) => { - console.log('[GeospatialTool] Execute called with:', { query, queryType, includeMap }); + console.log('[GeospatialTool] Execute called with:', { query, queryType, includeMap, destination }); const uiFeedbackStream = createStreamableValue(); uiStream.append(); @@ -218,10 +224,16 @@ export const geospatialTool = ({ break; } - const toolArgs = { - searchText: query, - includeMapPreview: includeMap !== false - }; + let toolArgs; + if (toolName === 'mapbox_directions_by_places' || toolName === 'mapbox_matrix_by_places') { + const places = [query]; + if (destination) { + places.push(destination); + } + toolArgs = { places, includeMapPreview: includeMap !== false }; + } else { + toolArgs = { searchText: query, includeMapPreview: includeMap !== false }; + } console.log('[GeospatialTool] Calling tool:', toolName, 'with args:', toolArgs); From 162fbd4fba7d6b1f22a000d1992e77c0a0acc9bc Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 15 Aug 2025 04:17:24 +0000 Subject: [PATCH 4/5] Fix: Complete rework of GeospatialTool for correctness and robustness I've completed an extensive, iterative debugging process to resolve a cascade of issues within the `GeospatialTool`. I have significantly refactored it, and it is now robust and correct. The key changes are: 1. **Correct Tool Selection:** The tool now uses the `_by_places` variants of the Mapbox tools (`mapbox_directions_by_places`, `mapbox_matrix_by_places`) for direction and distance queries, which are designed to work with place names. 2. **Structured Argument Passing:** The tool's `execute` function signature has been updated to correctly accept all parameters from its Zod schema (e.g., `destination`). This allows structured data to be provided and passed as a `places` array to the underlying service, eliminating brittle string parsing. 3. **Robust Response & Error Handling:** - The tool now inspects the `isError` flag in the service response and propagates specific error messages, providing much better feedback on failures. - The logic for parsing successful responses has been fixed to correctly handle the `results` array returned by the Mapbox API, resolving the "missing 'location' field" error. 4. **Build Stability:** I resolved transient TypeScript build errors by using a stable inline type definition for the `execute` function parameters, ensuring a successful build. These changes collectively address a series of related bugs, from generic errors to specific validation and parsing failures, resulting in a correctly implemented and reliable geospatial tool. --- lib/agents/tools/geospatial.tsx | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/agents/tools/geospatial.tsx b/lib/agents/tools/geospatial.tsx index 7af5d09f..2cfaa2a3 100644 --- a/lib/agents/tools/geospatial.tsx +++ b/lib/agents/tools/geospatial.tsx @@ -296,7 +296,22 @@ export const geospatialTool = ({ if (typeof content === 'object' && content !== null) { const parsedData = content as any; - if (parsedData.location) { + // Handle geocoding/directions/distance results which are in a 'results' array + if (parsedData.results && Array.isArray(parsedData.results) && parsedData.results.length > 0) { + // For now, just take the first result. + const firstResult = parsedData.results[0]; + mcpData = { + location: { + latitude: firstResult.coordinates?.latitude, + longitude: firstResult.coordinates?.longitude, + place_name: firstResult.name || firstResult.place_name, + address: firstResult.full_address || firstResult.address, + }, + mapUrl: parsedData.mapUrl, + }; + } + // Handle old/other format that might have a 'location' field directly + else if (parsedData.location) { mcpData = { location: { latitude: parsedData.location.latitude, @@ -307,7 +322,7 @@ export const geospatialTool = ({ mapUrl: parsedData.mapUrl || parsedData.map_url, }; } else { - throw new Error("Response missing required 'location' field"); + throw new Error("Response missing required 'location' or 'results' field"); } } else { throw new Error("Unexpected response format from mapping service"); From 1310b2670dbe239682f8aeec49adc89759a59d1a Mon Sep 17 00:00:00 2001 From: EreQ Date: Fri, 15 Aug 2025 08:18:21 +0000 Subject: [PATCH 5/5] fix: mapbox mcp --- bun.lockb | Bin 596311 -> 597023 bytes lib/agents/tools/geospatial.tsx | 316 ++++++++++++-------------------- lib/schema/geospatial.ts | 78 -------- lib/schema/geospatial.tsx | 152 +++++++++++++++ package.json | 1 + 5 files changed, 268 insertions(+), 279 deletions(-) delete mode 100644 lib/schema/geospatial.ts create mode 100644 lib/schema/geospatial.tsx diff --git a/bun.lockb b/bun.lockb index 2aff2ca1bc9abf4461ebb6a203002e7b238766f8..64ff9075536feefd487f8f1cdc47347043a0ada6 100755 GIT binary patch delta 110301 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 delta 109627 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 { const apiKey = process.env.NEXT_PUBLIC_SMITHERY_API_KEY; const mapboxAccessToken = process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN; @@ -21,60 +44,42 @@ async function getConnectedMcpClient(): Promise { profileId: profileId ? `${profileId.substring(0, 8)}...` : 'MISSING', }); - if (!apiKey || !mapboxAccessToken || !profileId) { - console.error('[GeospatialTool] Missing required environment variables'); - return null; - } - - if (!apiKey.trim() || !mapboxAccessToken.trim() || !profileId.trim()) { - console.error('[GeospatialTool] Empty environment variables detected'); + if (!apiKey || !mapboxAccessToken || !profileId || !apiKey.trim() || !mapboxAccessToken.trim() || !profileId.trim()) { + console.error('[GeospatialTool] Missing or empty required environment variables'); return null; } + // Load config from file or fallback let config; try { const mapboxMcpConfig = await import('QCX/mapbox_mcp_config.json'); - config = { - ...mapboxMcpConfig.default || mapboxMcpConfig, - mapboxAccessToken - }; + config = { ...mapboxMcpConfig.default || mapboxMcpConfig, mapboxAccessToken }; console.log('[GeospatialTool] Config loaded successfully'); } catch (configError: any) { console.error('[GeospatialTool] Failed to load mapbox config:', configError.message); - config = { - mapboxAccessToken, - version: '1.0.0', - name: 'mapbox-mcp-server' - }; + config = { mapboxAccessToken, version: '1.0.0', name: 'mapbox-mcp-server' }; console.log('[GeospatialTool] Using fallback config'); } + // Build Smithery URL const smitheryUrlOptions = { config, apiKey, profileId }; const mcpServerBaseUrl = `https://server.smithery.ai/@ngoiyaeric/mapbox-mcp-server/mcp?api_key=${smitheryUrlOptions.apiKey}&profile=${smitheryUrlOptions.profileId}`; - let serverUrlToUse; try { serverUrlToUse = createSmitheryUrl(mcpServerBaseUrl, smitheryUrlOptions); const urlDisplay = serverUrlToUse.toString().split('?')[0]; console.log('[GeospatialTool] MCP Server URL created:', urlDisplay); - + if (!serverUrlToUse.href || !serverUrlToUse.href.startsWith('https://')) { throw new Error('Invalid server URL generated'); } } catch (urlError: any) { console.error('[GeospatialTool] Error creating Smithery URL:', urlError.message); - console.error('[GeospatialTool] URL options:', { - baseUrl: mcpServerBaseUrl, - hasConfig: !!config, - hasApiKey: !!apiKey, - hasProfileId: !!profileId - }); return null; } + // Create transport let transport; - let client; - try { transport = new StreamableHTTPClientTransport(serverUrlToUse); console.log('[GeospatialTool] Transport created successfully'); @@ -83,59 +88,49 @@ async function getConnectedMcpClient(): Promise { return null; } + // Create client + let client; try { - client = new MCPClientClass({ - name: 'GeospatialToolClient', - version: '1.0.0' - }); + client = new MCPClientClass({ name: 'GeospatialToolClient', version: '1.0.0' }); console.log('[GeospatialTool] MCP Client instance created'); } catch (clientError: any) { console.error('[GeospatialTool] Failed to create MCP client:', clientError.message); return null; } + // Connect to server try { console.log('[GeospatialTool] Attempting to connect to MCP server...'); - await Promise.race([ client.connect(transport), - new Promise((_, reject) => { - setTimeout(() => reject(new Error('Connection timeout after 15 seconds')), 15000); - }), + new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout after 15 seconds')), 15000)), ]); - console.log('[GeospatialTool] Successfully connected to MCP server'); - - try { - const tools = await client.listTools(); - console.log('[GeospatialTool] Available tools:', tools.tools?.map(t => t.name) || []); - } catch (listError: any) { - console.warn('[GeospatialTool] Could not list tools:', listError.message); - } - - return client; - } catch (connectionError: any) { - console.error('[GeospatialTool] MCP connection failed:', connectionError.message); - console.error('[GeospatialTool] Connection error details:', { - name: connectionError.name, - stack: connectionError.stack?.split('\n')[0], - serverUrl: serverUrlToUse?.toString().split('?')[0], - }); - - await closeClient(client); + } catch (connectError: any) { + console.error('[GeospatialTool] MCP connection failed:', connectError.message); return null; } + + // List tools + try { + const tools = await client.listTools(); + console.log('[GeospatialTool] Available tools:', tools.tools?.map(t => t.name) || []); + } catch (listError: any) { + console.warn('[GeospatialTool] Could not list tools:', listError.message); + } + + return client; } -async function closeClient(client: MCPClientClass | null) { +/** + * Safely close the MCP client with timeout. + */ +async function closeClient(client: McpClient | null) { if (!client) return; - try { await Promise.race([ client.close(), - new Promise((_, reject) => { - setTimeout(() => reject(new Error('Close timeout after 5 seconds')), 5000); - }), + new Promise((_, reject) => setTimeout(() => reject(new Error('Close timeout after 5 seconds')), 5000)), ]); console.log('[GeospatialTool] MCP client closed successfully'); } catch (error: any) { @@ -143,11 +138,10 @@ async function closeClient(client: MCPClientClass | null) { } } -export const geospatialTool = ({ - uiStream, -}: { - uiStream: ReturnType; -}) => ({ +/** + * Main geospatial tool executor. + */ +export const geospatialTool = ({ uiStream }: { uiStream: ReturnType }) => ({ description: `Use this tool for location-based queries including: - Finding specific places, addresses, or landmarks - Getting coordinates for locations @@ -156,88 +150,62 @@ export const geospatialTool = ({ - Map-related requests - Geographic information lookup`, parameters: geospatialQuerySchema, - execute: async ({ - query, - queryType, - includeMap, - destination, - }: { - query: string; - queryType?: string; - includeMap?: boolean; - destination?: string; - }) => { - console.log('[GeospatialTool] Execute called with:', { query, queryType, includeMap, destination }); - + execute: async (params: z.infer) => { + const { queryType, includeMap = true } = params; + console.log('[GeospatialTool] Execute called with:', params); + const uiFeedbackStream = createStreamableValue(); uiStream.append(); - let feedbackMessage = `Processing geospatial query: "${query}". Connecting to mapping service...`; + let feedbackMessage = `Processing geospatial query (type: ${queryType})... Connecting to mapping service...`; uiFeedbackStream.update(feedbackMessage); const mcpClient = await getConnectedMcpClient(); - if (!mcpClient) { - feedbackMessage = 'Geospatial functionality is currently unavailable. Please check your configuration and try again.'; + feedbackMessage = 'Geospatial functionality is unavailable. Please check configuration.'; uiFeedbackStream.update(feedbackMessage); uiFeedbackStream.done(); uiStream.update(); - return { - type: 'MAP_QUERY_TRIGGER', - originalUserInput: query, - timestamp: new Date().toISOString(), - mcp_response: null, - error: 'MCP client initialization failed - check environment variables and network connectivity', - }; + return { type: 'MAP_QUERY_TRIGGER', originalUserInput: JSON.stringify(params), timestamp: new Date().toISOString(), mcp_response: null, error: 'MCP client initialization failed' }; } - let mcpData: { - location: { - latitude?: number; - longitude?: number; - place_name?: string; - address?: string; - }; - mapUrl?: string; - } | null = null; + let mcpData: McpResponse | null = null; let toolError: string | null = null; try { - feedbackMessage = `Connected to mapping service. Processing "${query}"...`; + feedbackMessage = `Connected to mapping service. Processing ${queryType} query...`; uiFeedbackStream.update(feedbackMessage); - uiStream.update(); - let toolName; - switch (queryType) { - case 'directions': - toolName = 'mapbox_directions_by_places'; - break; - case 'distance': - toolName = 'mapbox_matrix_by_places'; - break; - case 'geocode': - case 'reverse': - case 'search': - case 'map': - default: - toolName = 'mapbox_geocoding'; - break; - } + // Pick appropriate tool + const toolName = await (async () => { + const { tools } = await mcpClient.listTools().catch(() => ({ tools: [] })); + const names = new Set(tools?.map((t: any) => t.name) || []); + const prefer = (...cands: string[]) => cands.find(n => names.has(n)); + switch (queryType) { + case 'directions': + case 'distance': return prefer('calculate_distance', 'mapbox_matrix', 'mapbox_directions') || 'mapbox_matrix'; + case 'search': return prefer('search_nearby_places', 'mapbox_geocoding') || 'mapbox_geocoding'; + case 'map': return prefer('generate_map_link', 'mapbox_geocoding') || 'mapbox_geocoding'; + case 'reverse': + case 'geocode': return prefer('geocode_location', 'mapbox_geocoding') || 'mapbox_geocoding'; + } + })(); - let toolArgs; - if (toolName === 'mapbox_directions_by_places' || toolName === 'mapbox_matrix_by_places') { - const places = [query]; - if (destination) { - places.push(destination); + // Build arguments + const toolArgs = (() => { + switch (queryType) { + case 'directions': + case 'distance': return { places: [params.origin, params.destination], includeMapPreview: includeMap, mode: params.mode || 'driving' }; + case 'reverse': return { searchText: `${params.coordinates.latitude},${params.coordinates.longitude}`, includeMapPreview: includeMap, maxResults: params.maxResults || 5 }; + case 'search': return { searchText: params.query, includeMapPreview: includeMap, maxResults: params.maxResults || 5, ...(params.coordinates && { proximity: `${params.coordinates.latitude},${params.coordinates.longitude}` }), ...(params.radius && { radius: params.radius }) }; + case 'geocode': + case 'map': return { searchText: params.location, includeMapPreview: includeMap, maxResults: queryType === 'geocode' ? params.maxResults || 5 : undefined }; } - toolArgs = { places, includeMapPreview: includeMap !== false }; - } else { - toolArgs = { searchText: query, includeMapPreview: includeMap !== false }; - } + })(); console.log('[GeospatialTool] Calling tool:', toolName, 'with args:', toolArgs); - // Retry logic for tool call + // Retry logic const MAX_RETRIES = 3; let retryCount = 0; let toolCallResult; @@ -245,111 +213,57 @@ export const geospatialTool = ({ try { toolCallResult = await Promise.race([ mcpClient.callTool({ name: toolName, arguments: toolArgs }), - new Promise((_, reject) => { - setTimeout(() => reject(new Error('Tool call timeout after 30 seconds')), 30000); - }), + new Promise((_, reject) => setTimeout(() => reject(new Error('Tool call timeout')), 30000)), ]); break; } catch (error: any) { retryCount++; - if (retryCount === MAX_RETRIES) { - throw error; - } - console.warn(`[GeospatialTool] Retry ${retryCount}/${MAX_RETRIES} after error: ${error.message}`); + if (retryCount === MAX_RETRIES) throw new Error(`Tool call failed after ${MAX_RETRIES} retries: ${error.message}`); + console.warn(`[GeospatialTool] Retry ${retryCount}/${MAX_RETRIES}: ${error.message}`); await new Promise(resolve => setTimeout(resolve, 1000)); } } - console.log('[GeospatialTool] Raw tool result:', toolCallResult); - - const serviceResponse = toolCallResult as { content?: Array<{ text?: string }>, isError?: boolean }; - - if (serviceResponse.isError) { - const errorMessage = serviceResponse.content?.[0]?.text || 'Unknown error from mapping service'; - throw new Error(errorMessage); - } - - const responseContent = serviceResponse?.content; + // Extract & parse content + const serviceResponse = toolCallResult as { content?: Array<{ text?: string | null } | { [k: string]: any }> }; + const blocks = serviceResponse?.content || []; + const textBlocks = blocks.map(b => (typeof b.text === 'string' ? b.text : null)).filter((t): t is string => !!t && t.trim().length > 0); + if (textBlocks.length === 0) throw new Error('No content returned from mapping service'); - if (!responseContent || responseContent.length === 0 || !responseContent[0].text) { - throw new Error('No content returned from mapping service'); - } + let content: any = textBlocks.find(t => t.startsWith('```json')) || textBlocks[0]; + const jsonRegex = /```(?:json)?\n?([\s\S]*?)\n?```/; + const match = content.match(jsonRegex); + if (match) content = match[1].trim(); - let content: any = responseContent[0].text; - - if (typeof content === 'string') { - const jsonRegex = /```(?:json)?\n?([\s\S]*?)\n?```/; - const match = content.match(jsonRegex); - if (match) { - content = match[1].trim(); - } - - try { - if (typeof content === 'string') { - content = JSON.parse(content); - } - } catch (parseError) { - console.warn('[GeospatialTool] Content is not JSON, using as string:', content); - } - } + try { content = JSON.parse(content); } + catch { console.warn('[GeospatialTool] Content is not JSON, using as string:', content); } + // Process results if (typeof content === 'object' && content !== null) { const parsedData = content as any; - - // Handle geocoding/directions/distance results which are in a 'results' array - if (parsedData.results && Array.isArray(parsedData.results) && parsedData.results.length > 0) { - // For now, just take the first result. + if (parsedData.results?.length > 0) { const firstResult = parsedData.results[0]; - mcpData = { - location: { - latitude: firstResult.coordinates?.latitude, - longitude: firstResult.coordinates?.longitude, - place_name: firstResult.name || firstResult.place_name, - address: firstResult.full_address || firstResult.address, - }, - mapUrl: parsedData.mapUrl, - }; - } - // Handle old/other format that might have a 'location' field directly - else if (parsedData.location) { - mcpData = { - location: { - latitude: parsedData.location.latitude, - longitude: parsedData.location.longitude, - place_name: parsedData.location.place_name || parsedData.location.name, - address: parsedData.location.address || parsedData.location.formatted_address, - }, - mapUrl: parsedData.mapUrl || parsedData.map_url, - }; + mcpData = { location: { latitude: firstResult.coordinates?.latitude, longitude: firstResult.coordinates?.longitude, place_name: firstResult.name || firstResult.place_name, address: firstResult.full_address || firstResult.address }, mapUrl: parsedData.mapUrl }; + } else if (parsedData.location) { + mcpData = { location: { latitude: parsedData.location.latitude, longitude: parsedData.location.longitude, place_name: parsedData.location.place_name || parsedData.location.name, address: parsedData.location.address || parsedData.location.formatted_address }, mapUrl: parsedData.mapUrl || parsedData.map_url }; } else { throw new Error("Response missing required 'location' or 'results' field"); } - } else { - throw new Error("Unexpected response format from mapping service"); - } + } else throw new Error('Unexpected response format from mapping service'); - feedbackMessage = `Successfully processed location query for: ${mcpData.location.place_name || query}`; + feedbackMessage = `Successfully processed ${queryType} query for: ${mcpData.location.place_name || JSON.stringify(params)}`; uiFeedbackStream.update(feedbackMessage); } catch (error: any) { - console.error('[GeospatialTool] Tool execution failed:', error.message); - console.error('[GeospatialTool] Error stack:', error.stack); toolError = `Mapping service error: ${error.message}`; - feedbackMessage = toolError; - uiFeedbackStream.update(feedbackMessage); + uiFeedbackStream.update(toolError); + console.error('[GeospatialTool] Tool execution failed:', error); } finally { await closeClient(mcpClient); uiFeedbackStream.done(); uiStream.update(); } - return { - type: 'MAP_QUERY_TRIGGER', - originalUserInput: query, - queryType: queryType || 'geocode', - timestamp: new Date().toISOString(), - mcp_response: mcpData, - error: toolError, - }; + return { type: 'MAP_QUERY_TRIGGER', originalUserInput: JSON.stringify(params), queryType, timestamp: new Date().toISOString(), mcp_response: mcpData, error: toolError }; }, }); diff --git a/lib/schema/geospatial.ts b/lib/schema/geospatial.ts deleted file mode 100644 index e4e2622e..00000000 --- a/lib/schema/geospatial.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { z } from 'zod'; - -export const geospatialQuerySchema = z.object({ - query: z.string() - .min(1, "Query cannot be empty") - .describe("The user's location-based query - can be an address, place name, landmark, or geographic reference"), - - queryType: z.enum([ - 'geocode', // Find coordinates for a place - 'reverse', // Find place name from coordinates - 'directions', // Get directions between places - 'distance', // Calculate distance between places - 'search', // Search for places/POIs - 'map' // General map request - ]) - .optional() - .default('geocode') - .describe("The type of geospatial operation to perform"), - - includeMap: z.boolean() - .optional() - .default(true) - .describe("Whether to include a map preview/URL in the response"), - - coordinates: z.object({ - latitude: z.number().min(-90).max(90), - longitude: z.number().min(-180).max(180) - }) - .optional() - .describe("Optional coordinates for reverse geocoding or as a reference point"), - - destination: z.string() - .optional() - .describe("Destination for directions queries (when different from main query)"), - - radius: z.number() - .positive() - .optional() - .describe("Search radius in kilometers for place searches"), - - maxResults: z.number() - .int() - .positive() - .max(20) - .optional() - .default(5) - .describe("Maximum number of results to return for search queries") -}); - -export type GeospatialQuery = z.infer; - -// Helper function to classify query type based on content -export function classifyGeospatialQuery(query: string): GeospatialQuery['queryType'] { - const lowerQuery = query.toLowerCase(); - - if (lowerQuery.includes('direction') || lowerQuery.includes('route') || lowerQuery.includes('how to get')) { - return 'directions'; - } - - if (lowerQuery.includes('distance') || lowerQuery.includes('how far')) { - return 'distance'; - } - - if (lowerQuery.includes('find') || lowerQuery.includes('search') || lowerQuery.includes('near')) { - return 'search'; - } - - if (lowerQuery.includes('map') || lowerQuery.includes('show me')) { - return 'map'; - } - - // Check if query contains coordinates (lat/lng pattern) - if (/[-]?\d+\.?\d*\s*,\s*[-]?\d+\.?\d*/.test(query)) { - return 'reverse'; - } - - return 'geocode'; -} \ No newline at end of file diff --git a/lib/schema/geospatial.tsx b/lib/schema/geospatial.tsx new file mode 100644 index 00000000..98059711 --- /dev/null +++ b/lib/schema/geospatial.tsx @@ -0,0 +1,152 @@ +import { z } from 'zod'; + +// Improved schema using discriminatedUnion for better type safety and conditional requirements +// - Enforces required fields based on queryType (e.g., destination for directions/distance) +// - Renames 'query' to 'location' for clarity in most cases, but uses 'origin' and 'destination' for directions/distance +// - Makes 'coordinates' required for 'reverse' and optional for 'search' (as proximity) +// - Adds 'mode' for directions (e.g., driving, walking) assuming tool support can be added +// - Integrates 'radius' and 'maxResults' for 'search', assuming future tool arg expansion +// - Keeps 'includeMap' consistent across all +// - Defaults queryType removed; now required to encourage explicit typing +// - For 'map', treats as general query similar to geocode/search + +export const geospatialQuerySchema = z.discriminatedUnion('queryType', [ + z.object({ + queryType: z.literal('search'), + query: z.string() + .min(1, "Query cannot be empty") + .describe("Search term for places/POIs"), + coordinates: z.object({ + latitude: z.number().min(-90).max(90), + longitude: z.number().min(-180).max(180) + }) + .optional() + .describe("Optional reference point for proximity search"), + radius: z.number() + .positive() + .optional() + .describe("Search radius in kilometers"), + maxResults: z.number() + .int() + .positive() + .max(20) + .optional() + .default(5) + .describe("Maximum number of results to return"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + }), + z.object({ + queryType: z.literal('geocode'), + location: z.string() + .min(1, "Location cannot be empty") + .describe("The location to geocode - address, place name, or landmark"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + maxResults: z.number() + .int() + .positive() + .max(20) + .optional() + .default(5) + .describe("Maximum number of results to return"), + }), + z.object({ + queryType: z.literal('reverse'), + coordinates: z.object({ + latitude: z.number().min(-90).max(90), + longitude: z.number().min(-180).max(180) + }) + .describe("Coordinates for reverse geocoding"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + maxResults: z.number() + .int() + .positive() + .max(20) + .optional() + .default(5) + .describe("Maximum number of results to return"), + }), + z.object({ + queryType: z.literal('directions'), + origin: z.string() + .min(1, "Origin cannot be empty") + .describe("Starting location for directions"), + destination: z.string() + .min(1, "Destination cannot be empty") + .describe("Ending location for directions"), + mode: z.enum(['driving', 'walking', 'cycling', 'transit']) + .optional() + .default('driving') + .describe("Transportation mode for directions"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + }), + z.object({ + queryType: z.literal('distance'), + origin: z.string() + .min(1, "Origin cannot be empty") + .describe("Starting location for distance calculation"), + destination: z.string() + .min(1, "Destination cannot be empty") + .describe("Ending location for distance calculation"), + mode: z.enum(['driving', 'walking', 'cycling', 'transit']) + .optional() + .default('driving') + .describe("Transportation mode for distance"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + }), + z.object({ + queryType: z.literal('map'), + location: z.string() + .min(1, "Location cannot be empty") + .describe("Location or area for map request"), + includeMap: z.boolean() + .optional() + .default(true) + .describe("Whether to include a map preview/URL in the response"), + }) +]); + +export type GeospatialQuery = z.infer; + +// Updated helper function to classify query type based on content +// Note: This now only classifies type; full parsing (e.g., extracting origin/destination) should be handled by the AI tool caller +export function classifyGeospatialQuery(query: string): GeospatialQuery['queryType'] { + const lowerQuery = query.toLowerCase(); + + if (lowerQuery.includes('direction') || lowerQuery.includes('route') || lowerQuery.includes('how to get') || lowerQuery.includes('to ')) { + return 'directions'; + } + + if (lowerQuery.includes('distance') || lowerQuery.includes('how far')) { + return 'distance'; + } + + if (lowerQuery.includes('find') || lowerQuery.includes('search') || lowerQuery.includes('near') || lowerQuery.includes('around')) { + return 'search'; + } + + if (lowerQuery.includes('map') || lowerQuery.includes('show me') || lowerQuery.includes('view of')) { + return 'map'; + } + + // Check if query contains coordinates (lat/lng pattern) + if (/[-]?\d+\.?\d*\s*,\s*[-]?\d+\.?\d*/.test(query)) { + return 'reverse'; + } + + return 'geocode'; +} \ No newline at end of file diff --git a/package.json b/package.json index 56178678..15a58bbb 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "rehype-katex": "^7.0.1", "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", + "smithery": "^0.5.2", "sonner": "^1.7.4", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7",