Skip to content

Commit 75d351a

Browse files
authored
Merge pull request #6206 from continuedev/dallin/limit-grep-output
Limit and Truncate Grep Search output
2 parents 613ce91 + 275c903 commit 75d351a

File tree

20 files changed

+364
-29
lines changed

20 files changed

+364
-29
lines changed

core/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ declare global {
719719
720720
getPinnedFiles(): Promise<string[]>;
721721
722-
getSearchResults(query: string): Promise<string>;
722+
getSearchResults(query: string, maxResults?: number): Promise<string>;
723723
724724
subprocess(command: string, cwd?: string): Promise<[string, string]>;
725725

core/context/providers/SearchContextProvider.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
import { formatGrepSearchResults } from "../../util/grepSearch.js";
77
import { BaseContextProvider } from "../index.js";
88

9+
const DEFAULT_MAX_SEARCH_CONTEXT_RESULTS = 200;
910
class SearchContextProvider extends BaseContextProvider {
1011
static description: ContextProviderDescription = {
1112
title: "search",
@@ -19,8 +20,12 @@ class SearchContextProvider extends BaseContextProvider {
1920
query: string,
2021
extras: ContextProviderExtras,
2122
): Promise<ContextItem[]> {
22-
const results = await extras.ide.getSearchResults(query);
23-
const formatted = formatGrepSearchResults(results);
23+
const results = await extras.ide.getSearchResults(
24+
query,
25+
this.options?.maxResults ?? DEFAULT_MAX_SEARCH_CONTEXT_RESULTS,
26+
);
27+
// Note, search context provider will not truncate result chars, but will limit number of results
28+
const { formatted } = formatGrepSearchResults(results);
2429
return [
2530
{
2631
description: "Search results",

core/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ export interface IDE {
781781

782782
getPinnedFiles(): Promise<string[]>;
783783

784-
getSearchResults(query: string): Promise<string>;
784+
getSearchResults(query: string, maxResults?: number): Promise<string>;
785785

786786
getFileResults(pattern: string): Promise<string[]>;
787787

core/protocol/ide.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export type ToIdeFromWebviewOrCoreProtocol = {
2929
openFile: [{ path: string }, void];
3030
openUrl: [string, void];
3131
runCommand: [{ command: string; options?: TerminalOptions }, void];
32-
getSearchResults: [{ query: string }, string];
32+
getSearchResults: [{ query: string; maxResults?: number }, string];
3333
getFileResults: [{ pattern: string }, string[]];
3434
subprocess: [{ command: string; cwd?: string }, [string, string]];
3535
saveFile: [{ filepath: string }, void];

core/protocol/messenger/messageIde.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ export class MessageIde implements IDE {
185185
return this.request("getPinnedFiles", undefined);
186186
}
187187

188-
getSearchResults(query: string): Promise<string> {
189-
return this.request("getSearchResults", { query });
188+
getSearchResults(query: string, maxResults?: number): Promise<string> {
189+
return this.request("getSearchResults", { query, maxResults });
190190
}
191191

192192
getFileResults(pattern: string): Promise<string[]> {

core/protocol/messenger/reverseMessageIde.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ export class ReverseMessageIde {
159159
});
160160

161161
this.on("getSearchResults", (data) => {
162-
return this.ide.getSearchResults(data.query);
162+
return this.ide.getSearchResults(data.query, data.maxResults);
163163
});
164164

165165
this.on("getFileResults", (data) => {

core/tools/definitions/grepSearch.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ export const grepSearchTool: Tool = {
1212
group: BUILT_IN_GROUP_NAME,
1313
function: {
1414
name: BuiltInToolNames.GrepSearch,
15-
description: "Perform a search over the repository using ripgrep.",
15+
description:
16+
"Perform a search over the repository using ripgrep. Output may be truncated, so use targeted queries",
1617
parameters: {
1718
type: "object",
1819
required: ["query"],
Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,44 @@
11
import { ToolImpl } from ".";
2+
import { ContextItem } from "../..";
23
import { formatGrepSearchResults } from "../../util/grepSearch";
34

5+
const DEFAULT_GREP_SEARCH_RESULTS_LIMIT = 100;
6+
const DEFAULT_GREP_SEARCH_CHAR_LIMIT = 5000; // ~1000 tokens, will keep truncation simply for now
7+
48
export const grepSearchImpl: ToolImpl = async (args, extras) => {
5-
const results = await extras.ide.getSearchResults(args.query);
6-
return [
9+
const results = await extras.ide.getSearchResults(
10+
args.query,
11+
DEFAULT_GREP_SEARCH_RESULTS_LIMIT,
12+
);
13+
const { formatted, numResults, truncated } = formatGrepSearchResults(
14+
results,
15+
DEFAULT_GREP_SEARCH_CHAR_LIMIT,
16+
);
17+
const truncationReasons: string[] = [];
18+
if (numResults === DEFAULT_GREP_SEARCH_RESULTS_LIMIT) {
19+
truncationReasons.push(
20+
`the number of results exceeded ${DEFAULT_GREP_SEARCH_RESULTS_LIMIT}`,
21+
);
22+
}
23+
if (truncated) {
24+
truncationReasons.push(
25+
`the number of characters exceeded ${DEFAULT_GREP_SEARCH_CHAR_LIMIT}`,
26+
);
27+
}
28+
29+
const contextItems: ContextItem[] = [
730
{
831
name: "Search results",
932
description: "Results from grep search",
10-
content: formatGrepSearchResults(results),
33+
content: formatted,
1134
},
1235
];
36+
if (truncationReasons.length > 0) {
37+
contextItems.push({
38+
name: "Search truncation warning",
39+
description: "Informs the model that search results were truncated",
40+
content: `The above search results were truncated because ${truncationReasons.join(" and ")}. If the results are not satisfactory, try refining your search query.`,
41+
});
42+
}
43+
return contextItems;
1344
};

core/util/filesystem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ class FileSystemIde implements IDE {
234234
return Promise.resolve([]);
235235
}
236236

237-
async getSearchResults(query: string): Promise<string> {
237+
async getSearchResults(query: string, maxResults?: number): Promise<string> {
238238
return "";
239239
}
240240

core/util/grepSearch.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
1-
export function formatGrepSearchResults(results: string): string {
1+
/*
2+
Formats the output of a grep search to reduce unnecessary indentation, lines, etc
3+
Assumes a command with these params
4+
ripgrep -i --ignore-file .continueignore --ignore-file .gitignore -C 2 --heading -m 100 -e <query> .
5+
6+
Also can truncate the output to a specified number of characters
7+
*/
8+
export function formatGrepSearchResults(
9+
results: string,
10+
maxChars?: number,
11+
): {
12+
formatted: string;
13+
numResults: number;
14+
truncated: boolean;
15+
} {
16+
let numResults = 0;
217
const keepLines: string[] = [];
318

419
function countLeadingSpaces(line: string) {
@@ -45,6 +60,7 @@ export function formatGrepSearchResults(results: string): string {
4560
if (line.startsWith("./") || line === "--") {
4661
processResult(resultLines); // process previous result
4762
resultLines = [line];
63+
numResults++;
4864
continue;
4965
}
5066

@@ -57,5 +73,18 @@ export function formatGrepSearchResults(results: string): string {
5773
}
5874
processResult(resultLines);
5975

60-
return keepLines.join("\n");
76+
const formatted = keepLines.join("\n");
77+
if (maxChars && formatted.length > maxChars) {
78+
return {
79+
formatted: formatted.substring(0, maxChars),
80+
numResults,
81+
truncated: true,
82+
};
83+
} else {
84+
return {
85+
formatted,
86+
numResults,
87+
truncated: false,
88+
};
89+
}
6190
}

0 commit comments

Comments
 (0)