smart_search
Search InterSystems IRIS ObjectScript documentation by first checking local cache, then downloading documents if needed. Use natural language queries to find class references and official resources.
Instructions
Búsqueda inteligente: primero en caché local, luego descarga documentos si es necesario
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keys | No | KEYs específicos de documentos a descargar si no hay resultados en caché (opcional) | |
| q | Yes | Search query |
Implementation Reference
- src/search/smartSearch.ts:23-68 (handler)Core handler function implementing the smart_search tool logic: searches cache first, downloads relevant docs if needed, and formats results.export async function smartSearch( query: string, suggestedKeys?: string[] ): Promise<SmartSearchResult> { // Paso 1: Buscar en caché local const cacheResults = await searchInCache(query); const hasGoodCacheResults = cacheResults.length > 200 && !cacheResults.includes("No se encontraron resultados"); if (hasGoodCacheResults) { return { foundInCache: true, cacheResults, finalResults: `# Resultados encontrados en caché local\n\n${cacheResults}`, }; } // Paso 2: Si no hay buenos resultados en caché, intentar descargar documentos relevantes const downloadedDocs: string[] = []; const potentialKeys = suggestedKeys || generatePotentialKeys(query); // Intentar descargar documentos que podrían contener la información buscada for (const key of potentialKeys) { const doc = await fetchDocByKey(key); downloadedDocs.push(key); } // Paso 3: Buscar nuevamente en caché después de las descargas let finalResults = ""; if (downloadedDocs.length > 0) { const newCacheResults = await searchInCache(query); finalResults = `# Resultados después de descargar documentos\n\n## Documentos descargados:\n${downloadedDocs .map((key) => `- ${key}`) .join("\n")}\n\n## Resultados de búsqueda:\n\n${newCacheResults}`; } else { finalResults = `# No se encontraron resultados\n\nNo se pudieron encontrar documentos relevantes para "${query}".\n\n## Caché local:\n${cacheResults}\n\n## Sugerencias:\n- Verifica la ortografía del término\n- Intenta con términos más específicos\n- Usa las herramientas open_by_key u open_class directamente`; } return { foundInCache: false, cacheResults, downloadedDocs, finalResults, }; }
- src/tools/smart-search.tool.ts:3-26 (schema)Tool definition including input schema for 'q' (query) and optional 'keys'.export const SMART_SEARCH: Tool = { name: "smart_search", description: "Búsqueda inteligente: primero en caché local, luego descarga documentos si es necesario", inputSchema: { type: "object", properties: { q: { type: "string", description: "Search query", minLength: 2, }, keys: { type: "array", items: { type: "string", }, description: "KEYs específicos de documentos a descargar si no hay resultados en caché (opcional)", }, }, required: ["q"], }, };
- src/tools/core.tool.ts:18-22 (registration)Registration of SMART_SEARCH tool in the core tools array.export const coreTools = async () => { return { tools: [SMART_SEARCH, SEARCH_OBJECTSCRIPT, OPEN_BY_KEY, OPEN_CLASS], }; };
- src/request/call-schema.request.ts:9-26 (handler)Dispatcher handler case for 'smart_search' that calls the smartSearch function and formats MCP response.case "smart_search": { const query = args?.q as string; const suggestedKeys = args?.keys as string[] | undefined; if (!query) { throw new Error("Query is required"); } const result = await smartSearch(query, suggestedKeys); return { content: [ { type: "text", text: result.finalResults, }, ], }; }
- src/search/smartSearch.ts:130-208 (helper)Helper function to search within the local cache files.export async function searchInCache(query: string): Promise<string> { const results: SearchResult[] = []; try { const files = await readdir(cacheDir); const mdFiles = files.filter((f) => f.endsWith(".md")); for (const file of mdFiles) { const filePath = path.join(cacheDir, file); const content = await readFile(filePath, "utf-8"); // Buscar la query en el contenido (case insensitive) const lines = content.split("\n"); const matches: SearchResult["matches"] = []; lines.forEach((line, index) => { if (line.toLowerCase().includes(query.toLowerCase())) { // Agregar contexto (línea anterior y siguiente si existen) const contextLines: string[] = []; if (index > 0) contextLines.push(` ${index}: ${lines[index - 1].trim()}`); contextLines.push(`> ${index + 1}: ${line.trim()}`); if (index < lines.length - 1) contextLines.push(` ${index + 2}: ${lines[index + 1].trim()}`); matches.push({ lineNumber: index + 1, line: line.trim(), context: contextLines.join("\n"), }); } }); if (matches.length > 0) { results.push({ fileName: file .replace(".md", "") .replace("doc_", "") .replace("class_", ""), matches: matches.slice(0, 5), // Limitar a 5 coincidencias por archivo }); } } if (results.length === 0) { return `No se encontraron resultados para "${query}" en el caché local.\n\nSugerencias:\n- Verifica la ortografía\n- Intenta con términos más específicos\n- Usa las herramientas open_by_key u open_class para buscar documentación específica`; } // Formatear resultados const formattedResults: string[] = []; formattedResults.push( `Se encontraron ${results.length} archivo(s) con coincidencias para "${query}":\n` ); results.forEach((result, index) => { formattedResults.push(`## ${index + 1}. ${result.fileName}`); formattedResults.push( `Coincidencias encontradas: ${result.matches.length}\n` ); result.matches.forEach((match, matchIndex) => { formattedResults.push( `### Coincidencia ${matchIndex + 1} (Línea ${match.lineNumber})` ); if (match.context) { formattedResults.push("```"); formattedResults.push(match.context); formattedResults.push("```\n"); } }); }); return formattedResults.join("\n"); } catch (error) { return `Error al buscar en el caché: ${ error instanceof Error ? error.message : "Error desconocido" }`; } }