mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-08 07:44:33 +01:00
Clarify regex vs literal text in search result messages (#1757)
* Initial plan * Improve presentation of regex-based searches in agent mode - Updated FindTextInFilesTool to indicate "regex" vs "text" in search messages - Updated Claude grep tool formatter to show "Searched for regex" - Added test for literal text search message format - Updated existing test to match new regex message format Co-authored-by: roblourens <323878+roblourens@users.noreply.github.com> * Make regex/text keywords localizable via l10n - Moved 'regex' and 'text' keywords inside l10n.t() calls - This allows localization system to translate or keep terms as appropriate per language - Addresses localization concern about whether 'regex' should be localized Co-authored-by: roblourens <323878+roblourens@users.noreply.github.com> * Refactor nested ternary operators into helper method - Extract message generation logic into getResultMessage helper - Improves code readability and maintainability - All tests passing Co-authored-by: roblourens <323878+roblourens@users.noreply.github.com> * Update ChatSessionContentProvider test snapshot - Updated snapshot to reflect new grep message format - Changed from "Searched text for" to "Searched for regex" - All tests now passing (8/8) Co-authored-by: roblourens <323878+roblourens@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: roblourens <323878+roblourens@users.noreply.github.com>
This commit is contained in:
@@ -75,7 +75,7 @@ function formatGlobInvocation(invocation: ChatToolInvocationPart, toolUse: Anthr
|
||||
|
||||
function formatGrepInvocation(invocation: ChatToolInvocationPart, toolUse: Anthropic.ToolUseBlock): void {
|
||||
const pattern: string = (toolUse.input as any)?.pattern ?? '';
|
||||
invocation.invocationMessage = new MarkdownString(l10n.t("Searched text for `{0}`", pattern));
|
||||
invocation.invocationMessage = new MarkdownString(l10n.t("Searched for regex `{0}`", pattern));
|
||||
}
|
||||
|
||||
function formatLSInvocation(invocation: ChatToolInvocationPart, toolUse: Anthropic.ToolUseBlock): void {
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ exports[`ChatSessionContentProvider > loads real fixture file with tool invocati
|
||||
{
|
||||
"parts": [
|
||||
{
|
||||
"invocationMessage": "Searched text for \`ClaudeAgentManager\`",
|
||||
"invocationMessage": "Searched for regex \`ClaudeAgentManager\`",
|
||||
"isError": undefined,
|
||||
"toolCallId": "toolu_01FqdrDGdxXUWRRLziM7gS2R",
|
||||
"toolName": "Grep",
|
||||
|
||||
@@ -95,16 +95,28 @@ export class FindTextInFilesTool implements ICopilotTool<IFindTextInFilesToolPar
|
||||
return [];
|
||||
}).slice(0, maxResults);
|
||||
const query = this.formatQueryString(options.input);
|
||||
result.toolResultMessage = textMatches.length === 0 ?
|
||||
new MarkdownString(l10n.t`Searched text for ${query}, no results`) :
|
||||
textMatches.length === 1 ?
|
||||
new MarkdownString(l10n.t`Searched text for ${query}, 1 result`) :
|
||||
new MarkdownString(l10n.t`Searched text for ${query}, ${textMatches.length} results`);
|
||||
result.toolResultMessage = this.getResultMessage(isRegExp, query, textMatches.length);
|
||||
|
||||
result.toolResultDetails = textMatches;
|
||||
return result;
|
||||
}
|
||||
|
||||
private getResultMessage(isRegExp: boolean, query: string, count: number): MarkdownString {
|
||||
if (count === 0) {
|
||||
return isRegExp
|
||||
? new MarkdownString(l10n.t`Searched for regex ${query}, no results`)
|
||||
: new MarkdownString(l10n.t`Searched for text ${query}, no results`);
|
||||
} else if (count === 1) {
|
||||
return isRegExp
|
||||
? new MarkdownString(l10n.t`Searched for regex ${query}, 1 result`)
|
||||
: new MarkdownString(l10n.t`Searched for text ${query}, 1 result`);
|
||||
} else {
|
||||
return isRegExp
|
||||
? new MarkdownString(l10n.t`Searched for regex ${query}, ${count} results`)
|
||||
: new MarkdownString(l10n.t`Searched for text ${query}, ${count} results`);
|
||||
}
|
||||
}
|
||||
|
||||
private isValidRegex(pattern: string): boolean {
|
||||
try {
|
||||
new RegExp(pattern);
|
||||
@@ -138,8 +150,12 @@ export class FindTextInFilesTool implements ICopilotTool<IFindTextInFilesToolPar
|
||||
}
|
||||
|
||||
prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions<IFindTextInFilesToolParams>, token: vscode.CancellationToken): vscode.ProviderResult<vscode.PreparedToolInvocation> {
|
||||
const isRegExp = options.input.isRegexp ?? true;
|
||||
const query = this.formatQueryString(options.input);
|
||||
return {
|
||||
invocationMessage: new MarkdownString(l10n.t`Searching text for ${this.formatQueryString(options.input)}`),
|
||||
invocationMessage: isRegExp ?
|
||||
new MarkdownString(l10n.t`Searching for regex ${query}`) :
|
||||
new MarkdownString(l10n.t`Searching for text ${query}`),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,15 @@ suite('FindTextInFiles', () => {
|
||||
|
||||
const tool = accessor.get(IInstantiationService).createInstance(FindTextInFilesTool);
|
||||
const prepared = await tool.prepareInvocation({ input: { query: 'hello `world`' }, }, CancellationToken.None);
|
||||
expect((prepared?.invocationMessage as any as MarkdownString).value).toMatchInlineSnapshot(`"Searching text for \`\` hello \`world\` \`\`"`);
|
||||
expect((prepared?.invocationMessage as any as MarkdownString).value).toMatchInlineSnapshot(`"Searching for regex \`\` hello \`world\` \`\`"`);
|
||||
});
|
||||
|
||||
test('prepares invocation message with text for literal search', async () => {
|
||||
setup(new RelativePattern(URI.file(workspaceFolder), ''), false);
|
||||
|
||||
const tool = accessor.get(IInstantiationService).createInstance(FindTextInFilesTool);
|
||||
const prepared = await tool.prepareInvocation({ input: { query: 'hello', isRegexp: false }, }, CancellationToken.None);
|
||||
expect((prepared?.invocationMessage as any as MarkdownString).value).toMatchInlineSnapshot(`"Searching for text \`hello\`"`);
|
||||
});
|
||||
|
||||
test('retries with plain text when regex yields no results', async () => {
|
||||
|
||||
Reference in New Issue
Block a user