summaryrefslogtreecommitdiff
path: root/packages/core/src/tools/read-many-files.ts
diff options
context:
space:
mode:
authorPyush Sinha <[email protected]>2025-07-20 00:55:33 -0700
committerGitHub <[email protected]>2025-07-20 07:55:33 +0000
commita01b1219a3e814c370f6827b81c9118f2cbc7a64 (patch)
treeb4b406518a04f3cc4fc054b3b86612bf9b1ade51 /packages/core/src/tools/read-many-files.ts
parent76b935d598b895240b9bc2b182eb9f1e1b24be0d (diff)
feat: full implementation for .geminiignore in settings and respective tool calls (#3727)
Diffstat (limited to 'packages/core/src/tools/read-many-files.ts')
-rw-r--r--packages/core/src/tools/read-many-files.ts91
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) {