Skip to content

Commit 919f879

Browse files
committed
perf: reduce token consumption in search tool outputs
- Add truncateContent helper to cap code blocks at 30 lines - Apply truncation to codebase_search and find_similar outputs - Reduce default limit for codebase_search from 10 to 5 results - Estimated 80% token reduction for queries hitting large functions
1 parent 216ed3e commit 919f879

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

src/tools/index.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ import type { LogLevel } from "../config/schema.js";
77

88
const z = tool.schema;
99

10+
const MAX_CONTENT_LINES = 30;
11+
12+
function truncateContent(content: string): string {
13+
const lines = content.split("\n");
14+
if (lines.length <= MAX_CONTENT_LINES) return content;
15+
return (
16+
lines.slice(0, MAX_CONTENT_LINES).join("\n") +
17+
`\n// ... (${lines.length - MAX_CONTENT_LINES} more lines)`
18+
);
19+
}
20+
1021
let sharedIndexer: Indexer | null = null;
1122

1223
export function initializeTools(projectRoot: string, config: ParsedCodebaseIndexConfig): void {
@@ -25,15 +36,15 @@ export const codebase_search: ToolDefinition = tool({
2536
"Search codebase by MEANING, not keywords. Returns full code content. Use when you need to see actual implementation. For just finding WHERE code is (saves ~90% tokens), use codebase_peek instead. For known identifiers like 'validateToken', use grep - it's faster.",
2637
args: {
2738
query: z.string().describe("Natural language description of what code you're looking for. Describe behavior, not syntax."),
28-
limit: z.number().optional().default(10).describe("Maximum number of results to return"),
39+
limit: z.number().optional().default(5).describe("Maximum number of results to return"),
2940
fileType: z.string().optional().describe("Filter by file extension (e.g., 'ts', 'py', 'rs')"),
3041
directory: z.string().optional().describe("Filter by directory path (e.g., 'src/utils', 'lib')"),
3142
chunkType: z.enum(["function", "class", "method", "interface", "type", "enum", "struct", "impl", "trait", "module", "other"]).optional().describe("Filter by code chunk type"),
3243
contextLines: z.number().optional().describe("Number of extra lines to include before/after each match (default: 0)"),
3344
},
3445
async execute(args) {
3546
const indexer = getIndexer();
36-
const results = await indexer.search(args.query, args.limit ?? 10, {
47+
const results = await indexer.search(args.query, args.limit ?? 5, {
3748
fileType: args.fileType,
3849
directory: args.directory,
3950
chunkType: args.chunkType,
@@ -49,7 +60,7 @@ export const codebase_search: ToolDefinition = tool({
4960
? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}`
5061
: `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
5162

52-
return `${header} (score: ${r.score.toFixed(2)})\n\`\`\`\n${r.content}\n\`\`\``;
63+
return `${header} (score: ${r.score.toFixed(2)})\n\`\`\`\n${truncateContent(r.content)}\n\`\`\``;
5364
});
5465

5566
return `Found ${results.length} results for "${args.query}":\n\n${formatted.join("\n\n")}`;
@@ -256,7 +267,7 @@ export const find_similar: ToolDefinition = tool({
256267
? `[${idx + 1}] ${r.chunkType} "${r.name}" in ${r.filePath}:${r.startLine}-${r.endLine}`
257268
: `[${idx + 1}] ${r.chunkType} in ${r.filePath}:${r.startLine}-${r.endLine}`;
258269

259-
return `${header} (similarity: ${(r.score * 100).toFixed(1)}%)\n\`\`\`\n${r.content}\n\`\`\``;
270+
return `${header} (similarity: ${(r.score * 100).toFixed(1)}%)\n\`\`\`\n${truncateContent(r.content)}\n\`\`\``;
260271
});
261272

262273
return `Found ${results.length} similar code blocks:\n\n${formatted.join("\n\n")}`;

0 commit comments

Comments
 (0)