From 5d27a62beced1f260cde8fb37a26fe9fe2490a33 Mon Sep 17 00:00:00 2001 From: Abhi <43648792+abhipatel12@users.noreply.github.com> Date: Wed, 12 Nov 2025 21:56:37 -0500 Subject: [PATCH] refactor: remove read-many-files tool from agent (#12796) --- docs/cli/gemini-ignore.md | 4 +- docs/index.md | 2 - docs/sidebar.json | 4 - docs/tools/index.md | 3 - docs/tools/multi-file.md | 113 ------------------ packages/cli/src/ui/commands/toolsCommand.ts | 6 +- .../cli/src/ui/hooks/atCommandProcessor.ts | 3 +- packages/core/src/config/config.test.ts | 35 ------ packages/core/src/config/config.ts | 29 ----- 9 files changed, 5 insertions(+), 194 deletions(-) delete mode 100644 docs/tools/multi-file.md diff --git a/docs/cli/gemini-ignore.md b/docs/cli/gemini-ignore.md index b23f06b65a..f72bb641f2 100644 --- a/docs/cli/gemini-ignore.md +++ b/docs/cli/gemini-ignore.md @@ -13,8 +13,8 @@ Git). When you add a path to your `.geminiignore` file, tools that respect this file will exclude matching files and directories from their operations. For example, -when you use the [`read_many_files`](../tools/multi-file.md) command, any paths -in your `.geminiignore` file will be automatically excluded. +when you use the `@` command to share files, any paths in your `.geminiignore` +file will be automatically excluded. For the most part, `.geminiignore` follows the conventions of `.gitignore` files: diff --git a/docs/index.md b/docs/index.md index 48718b2233..042c9ae24b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -60,8 +60,6 @@ This documentation is organized into the following sections: - **[File System Tools](./tools/file-system.md):** Documentation for the `read_file` and `write_file` tools. - **[MCP servers](./tools/mcp-server.md):** Using MCP servers with Gemini CLI. -- **[Multi-File Read Tool](./tools/multi-file.md):** Documentation for the - `read_many_files` tool. - **[Shell Tool](./tools/shell.md):** Documentation for the `run_shell_command` tool. - **[Web Fetch Tool](./tools/web-fetch.md):** Documentation for the `web_fetch` diff --git a/docs/sidebar.json b/docs/sidebar.json index 2b9c2a905d..a4d0ba0e75 100644 --- a/docs/sidebar.json +++ b/docs/sidebar.json @@ -138,10 +138,6 @@ "label": "File System", "slug": "docs/tools/file-system" }, - { - "label": "Multi-File Read", - "slug": "docs/tools/multi-file" - }, { "label": "Shell", "slug": "docs/tools/shell" diff --git a/docs/tools/index.md b/docs/tools/index.md index c04696175c..68a7f5826a 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -82,9 +82,6 @@ Gemini CLI's built-in tools can be broadly categorized as follows: from URLs. - **[Web Search Tool](./web-search.md) (`google_web_search`):** For searching the web. -- **[Multi-File Read Tool](./multi-file.md) (`read_many_files`):** (Deprecated, - will be removed in v0.16.0) A specialized tool for reading content from - multiple files or directories. - **[Memory Tool](./memory.md) (`save_memory`):** For saving and recalling information across sessions. - **[Todo Tool](./todos.md) (`write_todos`):** For managing subtasks of complex diff --git a/docs/tools/multi-file.md b/docs/tools/multi-file.md deleted file mode 100644 index f389cc22a9..0000000000 --- a/docs/tools/multi-file.md +++ /dev/null @@ -1,113 +0,0 @@ -# Multi File Read Tool (`read_many_files`) - -> **Deprecated:** This tool is deprecated and will be removed in v0.16.0. Please -> use `read_file` instead. If you need to read multiple files, you can make -> multiple parallel calls to `read_file`. - -This document describes the `read_many_files` tool for the Gemini CLI. - -## Description - -Use `read_many_files` to read content from multiple files specified by paths or -glob patterns. The behavior of this tool depends on the provided files: - -- For text files, this tool concatenates their content into a single string. -- For image (e.g., PNG, JPEG), PDF, audio (MP3, WAV), and video (MP4, MOV) - files, it reads and returns them as base64-encoded data, provided they are - explicitly requested by name or extension. - -`read_many_files` can be used to perform tasks such as getting an overview of a -codebase, finding where specific functionality is implemented, reviewing -documentation, or gathering context from multiple configuration files. - -**Note:** `read_many_files` looks for files following the provided paths or glob -patterns. A directory path such as `"/docs"` will return an empty result; the -tool requires a pattern such as `"/docs/*"` or `"/docs/*.md"` to identify the -relevant files. - -### Arguments - -`read_many_files` takes the following arguments: - -- `paths` (list[string], required): An array of glob patterns or paths relative - to the tool's target directory (e.g., `["src/**/*.ts"]`, - `["README.md", "docs/*", "assets/logo.png"]`). -- `exclude` (list[string], optional): Glob patterns for files/directories to - exclude (e.g., `["**/*.log", "temp/"]`). These are added to default excludes - if `useDefaultExcludes` is true. -- `include` (list[string], optional): Additional glob patterns to include. These - are merged with `paths` (e.g., `["*.test.ts"]` to specifically add test files - if they were broadly excluded, or `["images/*.jpg"]` to include specific image - types). -- `recursive` (boolean, optional): Whether to search recursively. This is - primarily controlled by `**` in glob patterns. Defaults to `true`. -- `useDefaultExcludes` (boolean, optional): Whether to apply a list of default - exclusion patterns (e.g., `node_modules`, `.git`, non image/pdf binary files). - Defaults to `true`. -- `respect_git_ignore` (boolean, optional): Whether to respect .gitignore - patterns when finding files. Defaults to true. - -## How to use `read_many_files` with the Gemini CLI - -`read_many_files` searches for files matching the provided `paths` and `include` -patterns, while respecting `exclude` patterns and default excludes (if enabled). - -- For text files: it reads the content of each matched file (attempting to skip - binary files not explicitly requested as image/PDF) and concatenates it into a - single string, with a separator `--- {filePath} ---` between the content of - each file. Uses UTF-8 encoding by default. -- The tool inserts a `--- End of content ---` after the last file. -- For image and PDF files: if explicitly requested by name or extension (e.g., - `paths: ["logo.png"]` or `include: ["*.pdf"]`), the tool reads the file and - returns its content as a base64 encoded string. -- The tool attempts to detect and skip other binary files (those not matching - common image/PDF types or not explicitly requested) by checking for null bytes - in their initial content. - -Usage: - -``` -read_many_files(paths=["Your files or paths here."], include=["Additional files to include."], exclude=["Files to exclude."], recursive=False, useDefaultExcludes=false, respect_git_ignore=true) -``` - -## `read_many_files` examples - -Read all TypeScript files in the `src` directory: - -``` -read_many_files(paths=["src/**/*.ts"]) -``` - -Read the main README, all Markdown files in the `docs` directory, and a specific -logo image, excluding a specific file: - -``` -read_many_files(paths=["README.md", "docs/**/*.md", "assets/logo.png"], exclude=["docs/OLD_README.md"]) -``` - -Read all JavaScript files but explicitly include test files and all JPEGs in an -`images` folder: - -``` -read_many_files(paths=["**/*.js"], include=["**/*.test.js", "images/**/*.jpg"], useDefaultExcludes=False) -``` - -## Important notes - -- **Binary file handling:** - - **Image/PDF/Audio/Video files:** The tool can read common image types (PNG, - JPEG, etc.), PDF, audio (mp3, wav), and video (mp4, mov) files, returning - them as base64 encoded data. These files _must_ be explicitly targeted by - the `paths` or `include` patterns (e.g., by specifying the exact filename - like `video.mp4` or a pattern like `*.mov`). - - **Other binary files:** The tool attempts to detect and skip other types of - binary files by examining their initial content for null bytes. The tool - excludes these files from its output. -- **Performance:** Reading a very large number of files or very large individual - files can be resource-intensive. -- **Path specificity:** Ensure paths and glob patterns are correctly specified - relative to the tool's target directory. For image/PDF files, ensure the - patterns are specific enough to include them. -- **Default excludes:** Be aware of the default exclusion patterns (like - `node_modules`, `.git`) and use `useDefaultExcludes=False` if you need to - override them, but do so cautiously. diff --git a/packages/cli/src/ui/commands/toolsCommand.ts b/packages/cli/src/ui/commands/toolsCommand.ts index cdf17b103b..0fa40636b3 100644 --- a/packages/cli/src/ui/commands/toolsCommand.ts +++ b/packages/cli/src/ui/commands/toolsCommand.ts @@ -10,7 +10,6 @@ import { CommandKind, } from './types.js'; import { MessageType, type HistoryItemToolsList } from '../types.js'; -import { READ_MANY_FILES_TOOL_NAME } from '@google/gemini-cli-core'; export const toolsCommand: SlashCommand = { name: 'tools', @@ -45,10 +44,7 @@ export const toolsCommand: SlashCommand = { type: MessageType.TOOLS_LIST, tools: geminiTools.map((tool) => ({ name: tool.name, - displayName: - tool.name === READ_MANY_FILES_TOOL_NAME - ? `${tool.displayName} (Deprecated)` - : tool.displayName, + displayName: tool.displayName, description: tool.description, })), showDescriptions: useShowDescriptions, diff --git a/packages/cli/src/ui/hooks/atCommandProcessor.ts b/packages/cli/src/ui/hooks/atCommandProcessor.ts index a536000421..6d3e9071f8 100644 --- a/packages/cli/src/ui/hooks/atCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/atCommandProcessor.ts @@ -13,6 +13,7 @@ import { getErrorMessage, isNodeError, unescapePath, + ReadManyFilesTool, } from '@google/gemini-cli-core'; import type { HistoryItem, IndividualToolCallDisplay } from '../types.js'; import { ToolCallStatus } from '../types.js'; @@ -153,7 +154,7 @@ export async function handleAtCommand({ }; const toolRegistry = config.getToolRegistry(); - const readManyFilesTool = toolRegistry.getTool('read_many_files'); + const readManyFilesTool = new ReadManyFilesTool(config); const globTool = toolRegistry.getTool('glob'); if (!readManyFilesTool) { diff --git a/packages/core/src/config/config.test.ts b/packages/core/src/config/config.test.ts index 6cc77d3328..7be0c0456b 100644 --- a/packages/core/src/config/config.test.ts +++ b/packages/core/src/config/config.test.ts @@ -34,7 +34,6 @@ import { logRipgrepFallback } from '../telemetry/loggers.js'; import { RipgrepFallbackEvent } from '../telemetry/types.js'; import { ToolRegistry } from '../tools/tool-registry.js'; import { DEFAULT_MODEL_CONFIGS } from './defaultModelConfigs.js'; -import { READ_MANY_FILES_TOOL_NAME } from '../tools/tool-names.js'; vi.mock('fs', async (importOriginal) => { const actual = await importOriginal(); @@ -1041,40 +1040,6 @@ describe('Server Config (config.ts)', () => { expect(mockCoreEvents.emitFeedback).not.toHaveBeenCalled(); }); }); - - describe('checkDeprecatedTools', () => { - it('should emit a warning when a deprecated tool is in coreTools', async () => { - const params: ConfigParameters = { - ...baseParams, - coreTools: [READ_MANY_FILES_TOOL_NAME], - }; - const config = new Config(params); - await config.initialize(); - - expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith( - 'warning', - expect.stringContaining( - `The tool '${READ_MANY_FILES_TOOL_NAME}' (or 'ReadManyFilesTool') specified in 'tools.core' is deprecated`, - ), - ); - }); - - it('should emit a warning when a deprecated tool is in allowedTools', async () => { - const params: ConfigParameters = { - ...baseParams, - allowedTools: ['ReadManyFilesTool'], - }; - const config = new Config(params); - await config.initialize(); - - expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith( - 'warning', - expect.stringContaining( - `The tool '${READ_MANY_FILES_TOOL_NAME}' (or 'ReadManyFilesTool') specified in 'tools.allowed' is deprecated`, - ), - ); - }); - }); }); describe('setApprovalMode with folder trust', () => { diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index c4a94bcfc9..e9bf89bd75 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -28,7 +28,6 @@ import { SmartEditTool } from '../tools/smart-edit.js'; import { ShellTool } from '../tools/shell.js'; import { WriteFileTool } from '../tools/write-file.js'; import { WebFetchTool } from '../tools/web-fetch.js'; -import { ReadManyFilesTool } from '../tools/read-many-files.js'; import { MemoryTool, setGeminiMdFilename } from '../tools/memoryTool.js'; import { WebSearchTool } from '../tools/web-search.js'; import { GeminiClient } from '../core/client.js'; @@ -164,7 +163,6 @@ import { SimpleExtensionLoader, } from '../utils/extensionLoader.js'; import { McpClientManager } from '../tools/mcp-client-manager.js'; -import { READ_MANY_FILES_TOOL_NAME } from '../tools/tool-names.js'; export type { FileFilteringOptions }; export { @@ -632,32 +630,6 @@ export class Config { ]); await this.geminiClient.initialize(); - - this.checkDeprecatedTools(); - } - - private checkDeprecatedTools(): void { - const deprecatedTools = [ - { - name: READ_MANY_FILES_TOOL_NAME, - alternateName: 'ReadManyFilesTool', - }, - ]; - - const checkList = (list: string[] | undefined, listName: string) => { - if (!list) return; - for (const tool of deprecatedTools) { - if (list.includes(tool.name) || list.includes(tool.alternateName)) { - coreEvents.emitFeedback( - 'warning', - `The tool '${tool.name}' (or '${tool.alternateName}') specified in '${listName}' is deprecated and will be removed in v0.16.0.`, - ); - } - } - }; - - checkList(this.coreTools, 'tools.core'); - checkList(this.allowedTools, 'tools.allowed'); } getContentGenerator(): ContentGenerator { @@ -1396,7 +1368,6 @@ export class Config { } registerCoreTool(WriteFileTool, this); registerCoreTool(WebFetchTool, this); - registerCoreTool(ReadManyFilesTool, this); registerCoreTool(ShellTool, this); registerCoreTool(MemoryTool); registerCoreTool(WebSearchTool, this);