UNPKG

codevault

Version:

AI-powered semantic code search via Model Context Protocol

125 lines 5.53 kB
import { z } from 'zod'; import { synthesizeAnswer } from '../../synthesis/synthesizer.js'; import { formatSynthesisResult, formatErrorMessage, formatNoResultsMessage } from '../../synthesis/markdown-formatter.js'; export const askCodebaseInputSchema = z.object({ question: z.string().min(1, 'Question is required'), provider: z.string().optional().default('auto'), chat_provider: z.string().optional().default('auto'), path: z.string().optional().default('.'), max_chunks: z.number().optional().default(10), path_glob: z.union([z.string(), z.array(z.string())]).optional(), tags: z.union([z.string(), z.array(z.string())]).optional(), lang: z.union([z.string(), z.array(z.string())]).optional(), reranker: z.enum(['on', 'off']).optional().default('on'), multi_query: z.boolean().optional().default(false), temperature: z.number().min(0).max(2).optional().default(0.7) }); export const askCodebaseResultSchema = z.object({ success: z.boolean(), answer: z.string().optional(), query: z.string(), queriesUsed: z.array(z.string()).optional(), chunksAnalyzed: z.number(), chatProvider: z.string(), embeddingProvider: z.string(), error: z.string().optional() }); export function createAskCodebaseHandler(options = {}) { const { sessionPack, errorLogger } = options; return async (params) => { const { question, provider = 'auto', chat_provider = 'auto', path: workingPath = '.', max_chunks = 10, path_glob, tags, lang, reranker = 'on', multi_query = false, temperature = 0.7 } = params; try { const scopeFilters = { path_glob: Array.isArray(path_glob) ? path_glob : path_glob ? [path_glob] : undefined, tags: Array.isArray(tags) ? tags : tags ? [tags] : undefined, lang: Array.isArray(lang) ? lang : lang ? [lang] : undefined }; if (errorLogger?.debugLog) { errorLogger.debugLog('ask_codebase called', { question, provider, chat_provider, workingPath, max_chunks }); } const result = await synthesizeAnswer(question, { provider, chatProvider: chat_provider, workingPath, scope: scopeFilters, maxChunks: max_chunks, useReranking: reranker === 'on', useMultiQuery: multi_query, temperature }); if (!result.success) { if (result.error === 'no_results') { return { success: false, content: formatNoResultsMessage(result.query, result.queriesUsed) }; } return { success: false, content: formatErrorMessage(result.error || 'Unknown error', result.query) }; } const formattedResult = formatSynthesisResult(result, { includeMetadata: true, includeStats: true }); return { success: true, content: formattedResult, metadata: { chunksAnalyzed: result.chunksAnalyzed, queriesUsed: result.queriesUsed, chatProvider: result.chatProvider, embeddingProvider: result.embeddingProvider } }; } catch (error) { if (errorLogger?.log) { errorLogger.log(error, { operation: 'ask_codebase', question, path: workingPath }); } return { success: false, content: formatErrorMessage(error.message, question) }; } }; } export function registerAskCodebaseTool(server, options = {}) { const handler = createAskCodebaseHandler(options); server.tool('ask_codebase', { question: z.string().min(1).describe('Natural language question about the codebase'), provider: z.string().optional().describe('Embedding provider (auto|openai)'), chat_provider: z.string().optional().describe('Chat LLM provider (auto|openai)'), path: z.string().optional().describe('Project root directory (default: ".")'), max_chunks: z.number().optional().describe('Maximum code chunks to analyze (default: 10)'), path_glob: z.union([z.string(), z.array(z.string())]).optional().describe('File patterns to filter'), tags: z.union([z.string(), z.array(z.string())]).optional().describe('Tags to filter'), lang: z.union([z.string(), z.array(z.string())]).optional().describe('Languages to filter'), reranker: z.enum(['on', 'off']).optional().describe('Use API reranking (default: on)'), multi_query: z.boolean().optional().describe('Break complex questions into sub-queries'), temperature: z.number().min(0).max(2).optional().describe('LLM temperature (default: 0.7)') }, async (params) => { const result = await handler(params); return { content: [ { type: 'text', text: result.content } ] }; }); return handler; } //# sourceMappingURL=ask-codebase.js.map