refactor: remove read-many-files tool from agent (#12796)

This commit is contained in:
Abhi
2025-11-12 21:56:37 -05:00
committed by GitHub
parent a05e0ea3a4
commit 5d27a62bec
9 changed files with 5 additions and 194 deletions

View File

@@ -13,8 +13,8 @@ Git).
When you add a path to your `.geminiignore` file, tools that respect this file 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, 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 when you use the `@` command to share files, any paths in your `.geminiignore`
in your `.geminiignore` file will be automatically excluded. file will be automatically excluded.
For the most part, `.geminiignore` follows the conventions of `.gitignore` For the most part, `.geminiignore` follows the conventions of `.gitignore`
files: files:

View File

@@ -60,8 +60,6 @@ This documentation is organized into the following sections:
- **[File System Tools](./tools/file-system.md):** Documentation for the - **[File System Tools](./tools/file-system.md):** Documentation for the
`read_file` and `write_file` tools. `read_file` and `write_file` tools.
- **[MCP servers](./tools/mcp-server.md):** Using MCP servers with Gemini CLI. - **[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` - **[Shell Tool](./tools/shell.md):** Documentation for the `run_shell_command`
tool. tool.
- **[Web Fetch Tool](./tools/web-fetch.md):** Documentation for the `web_fetch` - **[Web Fetch Tool](./tools/web-fetch.md):** Documentation for the `web_fetch`

View File

@@ -138,10 +138,6 @@
"label": "File System", "label": "File System",
"slug": "docs/tools/file-system" "slug": "docs/tools/file-system"
}, },
{
"label": "Multi-File Read",
"slug": "docs/tools/multi-file"
},
{ {
"label": "Shell", "label": "Shell",
"slug": "docs/tools/shell" "slug": "docs/tools/shell"

View File

@@ -82,9 +82,6 @@ Gemini CLI's built-in tools can be broadly categorized as follows:
from URLs. from URLs.
- **[Web Search Tool](./web-search.md) (`google_web_search`):** For searching - **[Web Search Tool](./web-search.md) (`google_web_search`):** For searching
the web. 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 - **[Memory Tool](./memory.md) (`save_memory`):** For saving and recalling
information across sessions. information across sessions.
- **[Todo Tool](./todos.md) (`write_todos`):** For managing subtasks of complex - **[Todo Tool](./todos.md) (`write_todos`):** For managing subtasks of complex

View File

@@ -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.

View File

@@ -10,7 +10,6 @@ import {
CommandKind, CommandKind,
} from './types.js'; } from './types.js';
import { MessageType, type HistoryItemToolsList } 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 = { export const toolsCommand: SlashCommand = {
name: 'tools', name: 'tools',
@@ -45,10 +44,7 @@ export const toolsCommand: SlashCommand = {
type: MessageType.TOOLS_LIST, type: MessageType.TOOLS_LIST,
tools: geminiTools.map((tool) => ({ tools: geminiTools.map((tool) => ({
name: tool.name, name: tool.name,
displayName: displayName: tool.displayName,
tool.name === READ_MANY_FILES_TOOL_NAME
? `${tool.displayName} (Deprecated)`
: tool.displayName,
description: tool.description, description: tool.description,
})), })),
showDescriptions: useShowDescriptions, showDescriptions: useShowDescriptions,

View File

@@ -13,6 +13,7 @@ import {
getErrorMessage, getErrorMessage,
isNodeError, isNodeError,
unescapePath, unescapePath,
ReadManyFilesTool,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import type { HistoryItem, IndividualToolCallDisplay } from '../types.js'; import type { HistoryItem, IndividualToolCallDisplay } from '../types.js';
import { ToolCallStatus } from '../types.js'; import { ToolCallStatus } from '../types.js';
@@ -153,7 +154,7 @@ export async function handleAtCommand({
}; };
const toolRegistry = config.getToolRegistry(); const toolRegistry = config.getToolRegistry();
const readManyFilesTool = toolRegistry.getTool('read_many_files'); const readManyFilesTool = new ReadManyFilesTool(config);
const globTool = toolRegistry.getTool('glob'); const globTool = toolRegistry.getTool('glob');
if (!readManyFilesTool) { if (!readManyFilesTool) {

View File

@@ -34,7 +34,6 @@ import { logRipgrepFallback } from '../telemetry/loggers.js';
import { RipgrepFallbackEvent } from '../telemetry/types.js'; import { RipgrepFallbackEvent } from '../telemetry/types.js';
import { ToolRegistry } from '../tools/tool-registry.js'; import { ToolRegistry } from '../tools/tool-registry.js';
import { DEFAULT_MODEL_CONFIGS } from './defaultModelConfigs.js'; import { DEFAULT_MODEL_CONFIGS } from './defaultModelConfigs.js';
import { READ_MANY_FILES_TOOL_NAME } from '../tools/tool-names.js';
vi.mock('fs', async (importOriginal) => { vi.mock('fs', async (importOriginal) => {
const actual = await importOriginal<typeof import('fs')>(); const actual = await importOriginal<typeof import('fs')>();
@@ -1041,40 +1040,6 @@ describe('Server Config (config.ts)', () => {
expect(mockCoreEvents.emitFeedback).not.toHaveBeenCalled(); 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', () => { describe('setApprovalMode with folder trust', () => {

View File

@@ -28,7 +28,6 @@ import { SmartEditTool } from '../tools/smart-edit.js';
import { ShellTool } from '../tools/shell.js'; import { ShellTool } from '../tools/shell.js';
import { WriteFileTool } from '../tools/write-file.js'; import { WriteFileTool } from '../tools/write-file.js';
import { WebFetchTool } from '../tools/web-fetch.js'; import { WebFetchTool } from '../tools/web-fetch.js';
import { ReadManyFilesTool } from '../tools/read-many-files.js';
import { MemoryTool, setGeminiMdFilename } from '../tools/memoryTool.js'; import { MemoryTool, setGeminiMdFilename } from '../tools/memoryTool.js';
import { WebSearchTool } from '../tools/web-search.js'; import { WebSearchTool } from '../tools/web-search.js';
import { GeminiClient } from '../core/client.js'; import { GeminiClient } from '../core/client.js';
@@ -164,7 +163,6 @@ import {
SimpleExtensionLoader, SimpleExtensionLoader,
} from '../utils/extensionLoader.js'; } from '../utils/extensionLoader.js';
import { McpClientManager } from '../tools/mcp-client-manager.js'; import { McpClientManager } from '../tools/mcp-client-manager.js';
import { READ_MANY_FILES_TOOL_NAME } from '../tools/tool-names.js';
export type { FileFilteringOptions }; export type { FileFilteringOptions };
export { export {
@@ -632,32 +630,6 @@ export class Config {
]); ]);
await this.geminiClient.initialize(); 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 { getContentGenerator(): ContentGenerator {
@@ -1396,7 +1368,6 @@ export class Config {
} }
registerCoreTool(WriteFileTool, this); registerCoreTool(WriteFileTool, this);
registerCoreTool(WebFetchTool, this); registerCoreTool(WebFetchTool, this);
registerCoreTool(ReadManyFilesTool, this);
registerCoreTool(ShellTool, this); registerCoreTool(ShellTool, this);
registerCoreTool(MemoryTool); registerCoreTool(MemoryTool);
registerCoreTool(WebSearchTool, this); registerCoreTool(WebSearchTool, this);