diff options
Diffstat (limited to 'packages/core/src/tools/read-many-files.ts')
| -rw-r--r-- | packages/core/src/tools/read-many-files.ts | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/packages/core/src/tools/read-many-files.ts b/packages/core/src/tools/read-many-files.ts index 1c01ee9f..7c3be6e3 100644 --- a/packages/core/src/tools/read-many-files.ts +++ b/packages/core/src/tools/read-many-files.ts @@ -17,7 +17,7 @@ import { getSpecificMimeType, } from '../utils/fileUtils.js'; import { PartListUnion, Schema, Type } from '@google/genai'; -import { Config } from '../config/config.js'; +import { Config, DEFAULT_FILE_FILTERING_OPTIONS } from '../config/config.js'; import { recordFileOperationMetric, FileOperation, @@ -62,9 +62,12 @@ export interface ReadManyFilesParams { useDefaultExcludes?: boolean; /** - * Optional. Whether to respect .gitignore patterns. Defaults to true. + * Whether to respect .gitignore and .geminiignore patterns (optional, defaults to true) */ - respect_git_ignore?: boolean; + file_filtering_options?: { + respect_git_ignore?: boolean; + respect_gemini_ignore?: boolean; + }; } /** @@ -173,11 +176,22 @@ export class ReadManyFilesTool extends BaseTool< 'Optional. Whether to apply a list of default exclusion patterns (e.g., node_modules, .git, binary files). Defaults to true.', default: true, }, - respect_git_ignore: { - type: Type.BOOLEAN, + file_filtering_options: { description: - 'Optional. Whether to respect .gitignore patterns when discovering files. Only available in git repositories. Defaults to true.', - default: true, + 'Whether to respect ignore patterns from .gitignore or .geminiignore', + type: Type.OBJECT, + properties: { + respect_git_ignore: { + description: + 'Optional: Whether to respect .gitignore patterns when listing files. Only available in git repositories. Defaults to true.', + type: Type.BOOLEAN, + }, + respect_gemini_ignore: { + description: + 'Optional: Whether to respect .geminiignore patterns when listing files. Defaults to true.', + type: Type.BOOLEAN, + }, + }, }, }, required: ['paths'], @@ -257,12 +271,19 @@ Use this tool when the user's query implies needing the content of several files include = [], exclude = [], useDefaultExcludes = true, - respect_git_ignore = true, } = params; - const respectGitIgnore = - respect_git_ignore ?? this.config.getFileFilteringRespectGitIgnore(); + const defaultFileIgnores = + this.config.getFileFilteringOptions() ?? DEFAULT_FILE_FILTERING_OPTIONS; + const fileFilteringOptions = { + respectGitIgnore: + params.file_filtering_options?.respect_git_ignore ?? + defaultFileIgnores.respectGitIgnore, // Use the property from the returned object + respectGeminiIgnore: + params.file_filtering_options?.respect_gemini_ignore ?? + defaultFileIgnores.respectGeminiIgnore, // Use the property from the returned object + }; // Get centralized file discovery service const fileDiscovery = this.config.getFileService(); @@ -272,8 +293,8 @@ Use this tool when the user's query implies needing the content of several files const contentParts: PartListUnion = []; const effectiveExcludes = useDefaultExcludes - ? [...DEFAULT_EXCLUDES, ...exclude, ...this.geminiIgnorePatterns] - : [...exclude, ...this.geminiIgnorePatterns]; + ? [...DEFAULT_EXCLUDES, ...exclude] + : [...exclude]; const searchPatterns = [...inputPatterns, ...include]; if (searchPatterns.length === 0) { @@ -294,18 +315,36 @@ Use this tool when the user's query implies needing the content of several files signal, }); - const filteredEntries = respectGitIgnore + const gitFilteredEntries = fileFilteringOptions.respectGitIgnore ? fileDiscovery .filterFiles( entries.map((p) => path.relative(this.config.getTargetDir(), p)), { - respectGitIgnore, + respectGitIgnore: true, + respectGeminiIgnore: false, }, ) .map((p) => path.resolve(this.config.getTargetDir(), p)) : entries; + // Apply gemini ignore filtering if enabled + const finalFilteredEntries = fileFilteringOptions.respectGeminiIgnore + ? fileDiscovery + .filterFiles( + gitFilteredEntries.map((p) => + path.relative(this.config.getTargetDir(), p), + ), + { + respectGitIgnore: false, + respectGeminiIgnore: true, + }, + ) + .map((p) => path.resolve(this.config.getTargetDir(), p)) + : gitFilteredEntries; + let gitIgnoredCount = 0; + let geminiIgnoredCount = 0; + for (const absoluteFilePath of entries) { // Security check: ensure the glob library didn't return something outside targetDir. if (!absoluteFilePath.startsWith(this.config.getTargetDir())) { @@ -317,11 +356,23 @@ Use this tool when the user's query implies needing the content of several files } // Check if this file was filtered out by git ignore - if (respectGitIgnore && !filteredEntries.includes(absoluteFilePath)) { + if ( + fileFilteringOptions.respectGitIgnore && + !gitFilteredEntries.includes(absoluteFilePath) + ) { gitIgnoredCount++; continue; } + // Check if this file was filtered out by gemini ignore + if ( + fileFilteringOptions.respectGeminiIgnore && + !finalFilteredEntries.includes(absoluteFilePath) + ) { + geminiIgnoredCount++; + continue; + } + filesToConsider.add(absoluteFilePath); } @@ -329,7 +380,15 @@ Use this tool when the user's query implies needing the content of several files if (gitIgnoredCount > 0) { skippedFiles.push({ path: `${gitIgnoredCount} file(s)`, - reason: 'ignored', + reason: 'git ignored', + }); + } + + // Add info about gemini-ignored files if any were filtered + if (geminiIgnoredCount > 0) { + skippedFiles.push({ + path: `${geminiIgnoredCount} file(s)`, + reason: 'gemini ignored', }); } } catch (error) { |
