refactor(core): Centralize tool names to avoid circular dependencies - Edit, Grep, Read (#11434)

This commit is contained in:
Abhi
2025-10-19 19:21:47 -04:00
committed by GitHub
parent 98eef9ba0c
commit 23e52f0ff3
14 changed files with 76 additions and 73 deletions
+3 -4
View File
@@ -22,7 +22,6 @@ import type { Config } from '../config/config.js';
import { ApprovalMode } from '../config/config.js';
import { ensureCorrectEdit } from '../utils/editCorrector.js';
import { DEFAULT_DIFF_OPTIONS, getDiffStat } from './diffOptions.js';
import { ReadFileTool } from './read-file.js';
import { logFileOperation } from '../telemetry/loggers.js';
import { FileOperationEvent } from '../telemetry/types.js';
import { FileOperation } from '../telemetry/metrics.js';
@@ -34,7 +33,7 @@ import type {
} from './modifiable-tool.js';
import { IdeClient } from '../ide/ide-client.js';
import { safeLiteralReplace } from '../utils/textUtils.js';
import { EDIT_TOOL_NAME } from './tool-names.js';
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
export function applyReplacement(
currentContent: string | null,
@@ -182,7 +181,7 @@ class EditToolInvocation implements ToolInvocation<EditToolParams, ToolResult> {
} else if (occurrences === 0) {
error = {
display: `Failed to edit, could not find the string to replace.`,
raw: `Failed to edit, 0 occurrences found for old_string in ${params.file_path}. No edits made. The exact text in old_string was not found. Ensure you're not escaping content incorrectly and check whitespace, indentation, and context. Use ${ReadFileTool.Name} tool to verify.`,
raw: `Failed to edit, 0 occurrences found for old_string in ${params.file_path}. No edits made. The exact text in old_string was not found. Ensure you're not escaping content incorrectly and check whitespace, indentation, and context. Use ${READ_FILE_TOOL_NAME} tool to verify.`,
type: ToolErrorType.EDIT_NO_OCCURRENCE_FOUND,
};
} else if (occurrences !== expectedReplacements) {
@@ -470,7 +469,7 @@ export class EditTool
super(
EditTool.Name,
'Edit',
`Replaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when \`expected_replacements\` is specified. This tool requires providing significant context around the change to ensure precise targeting. Always use the ${ReadFileTool.Name} tool to examine the file's current content before attempting a text replacement.
`Replaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when \`expected_replacements\` is specified. This tool requires providing significant context around the change to ensure precise targeting. Always use the ${READ_FILE_TOOL_NAME} tool to examine the file's current content before attempting a text replacement.
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.
+2 -3
View File
@@ -18,6 +18,7 @@ import { isGitRepository } from '../utils/gitUtils.js';
import type { Config } from '../config/config.js';
import type { FileExclusions } from '../utils/ignorePatterns.js';
import { ToolErrorType } from './tool-error.js';
import { GREP_TOOL_NAME } from './tool-names.js';
import { debugLogger } from '../utils/debugLogger.js';
// --- Interfaces ---
@@ -563,11 +564,9 @@ class GrepToolInvocation extends BaseToolInvocation<
* Implementation of the Grep tool logic (moved from CLI)
*/
export class GrepTool extends BaseDeclarativeTool<GrepToolParams, ToolResult> {
static readonly Name = 'search_file_content'; // Keep static name
constructor(private readonly config: Config) {
super(
GrepTool.Name,
GREP_TOOL_NAME,
'SearchText',
'Searches for a regular expression pattern within the content of files in a specified directory (or current working directory). Can filter files by a glob pattern. Returns the lines containing matches, along with their file paths and line numbers.',
Kind.Search,
+3 -4
View File
@@ -19,6 +19,7 @@ import { FileOperation } from '../telemetry/metrics.js';
import { getProgrammingLanguage } from '../telemetry/telemetry-utils.js';
import { logFileOperation } from '../telemetry/loggers.js';
import { FileOperationEvent } from '../telemetry/types.js';
import { READ_FILE_TOOL_NAME } from './tool-names.js';
/**
* Parameters for the ReadFile tool
@@ -112,7 +113,7 @@ ${result.llmContent}`;
logFileOperation(
this.config,
new FileOperationEvent(
ReadFileTool.Name,
READ_FILE_TOOL_NAME,
FileOperation.READ,
lines,
mimetype,
@@ -135,11 +136,9 @@ export class ReadFileTool extends BaseDeclarativeTool<
ReadFileToolParams,
ToolResult
> {
static readonly Name: string = 'read_file';
constructor(private config: Config) {
super(
ReadFileTool.Name,
READ_FILE_TOOL_NAME,
'ReadFile',
`Reads and returns the content of a specified file. If the file is large, the content will be truncated. The tool's response will clearly indicate if truncation has occurred and will provide details on how to read more of the file using the 'offset' and 'limit' parameters. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), and PDF files. For text files, it can read specific line ranges.`,
Kind.Read,
+3 -4
View File
@@ -27,6 +27,7 @@ import { getProgrammingLanguage } from '../telemetry/telemetry-utils.js';
import { logFileOperation } from '../telemetry/loggers.js';
import { FileOperationEvent } from '../telemetry/types.js';
import { ToolErrorType } from './tool-error.js';
import { READ_MANY_FILES_TOOL_NAME } from './tool-names.js';
/**
* Parameters for the ReadManyFilesTool.
@@ -392,7 +393,7 @@ ${finalExclusionPatternsForDescription
logFileOperation(
this.config,
new FileOperationEvent(
ReadManyFilesTool.Name,
READ_MANY_FILES_TOOL_NAME,
FileOperation.READ,
lines,
mimetype,
@@ -474,8 +475,6 @@ export class ReadManyFilesTool extends BaseDeclarativeTool<
ReadManyFilesParams,
ToolResult
> {
static readonly Name: string = 'read_many_files';
constructor(private config: Config) {
const parameterSchema = {
type: 'object',
@@ -544,7 +543,7 @@ export class ReadManyFilesTool extends BaseDeclarativeTool<
};
super(
ReadManyFilesTool.Name,
READ_MANY_FILES_TOOL_NAME,
'ReadManyFiles',
`Reads content from multiple files specified by paths or glob patterns within a configured target directory. For text files, it concatenates their content into a single string. It is primarily designed for text-based files. However, it can also process image (e.g., .png, .jpg) and PDF (.pdf) files if their file names or extensions are explicitly included in the 'paths' argument. For these explicitly requested non-text files, their data is read and included in a format suitable for model consumption (e.g., base64 encoded).
+2 -3
View File
@@ -17,6 +17,7 @@ import { getErrorMessage, isNodeError } from '../utils/errors.js';
import type { Config } from '../config/config.js';
import { fileExists } from '../utils/fileUtils.js';
import { Storage } from '../config/storage.js';
import { GREP_TOOL_NAME } from './tool-names.js';
const DEFAULT_TOTAL_MAX_MATCHES = 20000;
@@ -419,11 +420,9 @@ export class RipGrepTool extends BaseDeclarativeTool<
RipGrepToolParams,
ToolResult
> {
static readonly Name = 'search_file_content';
constructor(private readonly config: Config) {
super(
RipGrepTool.Name,
GREP_TOOL_NAME,
'SearchText',
'Searches for a regular expression pattern within the content of files in a specified directory (or current working directory). Can filter files by a glob pattern. Returns the lines containing matches, along with their file paths and line numbers. Total results limited to 20,000 matches like VSCode.',
Kind.Search,
+3 -4
View File
@@ -24,7 +24,6 @@ import { makeRelative, shortenPath } from '../utils/paths.js';
import { isNodeError } from '../utils/errors.js';
import { type Config, ApprovalMode } from '../config/config.js';
import { DEFAULT_DIFF_OPTIONS, getDiffStat } from './diffOptions.js';
import { ReadFileTool } from './read-file.js';
import {
type ModifiableDeclarativeTool,
type ModifyContext,
@@ -39,7 +38,7 @@ import { SmartEditCorrectionEvent } from '../telemetry/types.js';
import { logSmartEditCorrectionEvent } from '../telemetry/loggers.js';
import { correctPath } from '../utils/pathCorrector.js';
import { EDIT_TOOL_NAME } from './tool-names.js';
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
interface ReplacementContext {
params: EditToolParams;
currentContent: string;
@@ -303,7 +302,7 @@ export function getErrorReplaceResult(
if (occurrences === 0) {
error = {
display: `Failed to edit, could not find the string to replace.`,
raw: `Failed to edit, 0 occurrences found for old_string (${finalOldString}). Original old_string was (${params.old_string}) in ${params.file_path}. No edits made. The exact text in old_string was not found. Ensure you're not escaping content incorrectly and check whitespace, indentation, and context. Use ${ReadFileTool.Name} tool to verify.`,
raw: `Failed to edit, 0 occurrences found for old_string (${finalOldString}). Original old_string was (${params.old_string}) in ${params.file_path}. No edits made. The exact text in old_string was not found. Ensure you're not escaping content incorrectly and check whitespace, indentation, and context. Use ${READ_FILE_TOOL_NAME} tool to verify.`,
type: ToolErrorType.EDIT_NO_OCCURRENCE_FOUND,
};
} else if (occurrences !== expectedReplacements) {
@@ -822,7 +821,7 @@ export class SmartEditTool
super(
SmartEditTool.Name,
'Edit',
`Replaces text within a file. Replaces a single occurrence. This tool requires providing significant context around the change to ensure precise targeting. Always use the ${ReadFileTool.Name} tool to examine the file's current content before attempting a text replacement.
`Replaces text within a file. Replaces a single occurrence. This tool requires providing significant context around the change to ensure precise targeting. Always use the ${READ_FILE_TOOL_NAME} tool to examine the file's current content before attempting a text replacement.
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.
+3 -2
View File
@@ -15,9 +15,10 @@ export const WEB_SEARCH_TOOL_NAME = 'google_web_search';
export const WEB_FETCH_TOOL_NAME = 'web_fetch';
export const EDIT_TOOL_NAME = 'replace';
export const SHELL_TOOL_NAME = 'run_shell_command';
export const GREP_TOOL_NAME = 'search_file_content';
export const READ_MANY_FILES_TOOL_NAME = 'read_many_files';
export const READ_FILE_TOOL_NAME = 'read_file';
// TODO: Migrate other tool names here to follow this pattern and prevent future circular dependencies.
// Candidates for migration:
// - LSTool ('list_directory')
// - ReadFileTool ('read_file')
// - GrepTool ('search_file_content')