Skip to content

Commit f8ba2dd

Browse files
feat: Implement semantic search tool for codebase with result grouping and error handling
1 parent 0af29e7 commit f8ba2dd

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

src/api/agents/tools.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { z } from 'zod';
33
import { fileLockManager } from './file-lock-manager';
44
import { fileSnapshotManager } from './file-snapshot-manager';
55
import { agentDB } from './database';
6+
import { SmartIndexService } from '../../helpers/ipc/index/smart-index-service';
7+
import { SearchResult } from '../../helpers/ipc/index/index-context';
68
import fs from 'fs';
79
import path from 'path';
810
import { promisify } from 'util';
@@ -11,6 +13,16 @@ import { promisify } from 'util';
1113
let currentSessionId: string | null = null;
1214
let currentProjectPath: string | null = null;
1315

16+
// Initialize smart index service instance
17+
let smartIndexService: SmartIndexService | null = null;
18+
19+
function getSmartIndexService(): SmartIndexService {
20+
if (!smartIndexService) {
21+
smartIndexService = new SmartIndexService();
22+
}
23+
return smartIndexService;
24+
}
25+
1426
export function setCurrentSessionId(sessionId: string): void {
1527
currentSessionId = sessionId;
1628

@@ -568,6 +580,75 @@ export const requireClarification = tool({
568580
},
569581
});
570582

583+
// Search Codebase Tool - Search through the project using semantic search
584+
const searchCodebaseParams = z.object({
585+
query: z.string().describe('The search query to find relevant code snippets'),
586+
limit: z.number().optional().describe('Maximum number of results to return (default: 20)')
587+
});
588+
589+
export const searchCodebase = tool({
590+
description: 'Search through the project codebase using semantic search to find relevant code snippets and files',
591+
parameters: searchCodebaseParams,
592+
execute: async ({ query, limit = 20 }) => {
593+
addProgress(`Searching codebase for: ${query}`, 'running');
594+
595+
try {
596+
const indexService = getSmartIndexService();
597+
598+
// Check if index is available
599+
const status = indexService.getStatus();
600+
if (!status.isBuilt) {
601+
addProgress(`Codebase search completed (no index)`, 'completed', 'Index not built');
602+
return {
603+
success: true,
604+
results: [],
605+
message: 'Smart index not available. No results returned.'
606+
};
607+
}
608+
609+
// Perform the search
610+
const searchResults = await indexService.search(query, limit);
611+
612+
// Group results by file and limit to 4 files max, 3 results per file max
613+
const fileResultsMap = new Map<string, SearchResult[]>();
614+
615+
for (const result of searchResults) {
616+
if (!fileResultsMap.has(result.filePath)) {
617+
fileResultsMap.set(result.filePath, []);
618+
}
619+
620+
const fileResults = fileResultsMap.get(result.filePath)!;
621+
if (fileResults.length < 3) { // Max 3 results per file
622+
fileResults.push(result);
623+
}
624+
}
625+
626+
// Limit to 4 files maximum
627+
const limitedFiles = Array.from(fileResultsMap.entries()).slice(0, 4);
628+
const limitedResults = limitedFiles.flatMap(([, results]) => results);
629+
630+
addProgress(`Codebase search completed`, 'completed', `Found ${limitedResults.length} results in ${limitedFiles.length} files`);
631+
632+
return {
633+
success: true,
634+
results: limitedResults,
635+
totalFiles: limitedFiles.length,
636+
totalResults: limitedResults.length
637+
};
638+
639+
} catch (error) {
640+
// Don't fail on search errors, just return empty results
641+
console.warn('Search codebase error:', error);
642+
addProgress(`Codebase search completed (error)`, 'completed', 'Search service unavailable');
643+
return {
644+
success: true,
645+
results: [],
646+
message: 'Search service unavailable. No results returned.'
647+
};
648+
}
649+
},
650+
});
651+
571652
export const agentTools = {
572653
readFile,
573654
writeFile,
@@ -577,6 +658,8 @@ export const agentTools = {
577658
searchFiles,
578659
getProjectInfo,
579660
finishWork,
661+
requireClarification,
662+
searchCodebase,
580663
};
581664

582665
export type ToolName = keyof typeof agentTools;

0 commit comments

Comments
 (0)