From 82bde578682fcd88b1ee9df053c9dd51c7b74522 Mon Sep 17 00:00:00 2001 From: Jacob Richman Date: Fri, 11 Jul 2025 17:49:26 -0700 Subject: Fix issues that resulted in Gemini trying to use relative paths where absolute paths were required (#3938) --- packages/core/src/tools/read-file.ts | 6 +--- packages/core/src/tools/read-many-files.test.ts | 41 +++++++++++++++++++------ packages/core/src/tools/read-many-files.ts | 2 +- 3 files changed, 33 insertions(+), 16 deletions(-) (limited to 'packages/core/src/tools') diff --git a/packages/core/src/tools/read-file.ts b/packages/core/src/tools/read-file.ts index dd173813..5c37f45b 100644 --- a/packages/core/src/tools/read-file.ts +++ b/packages/core/src/tools/read-file.ts @@ -101,11 +101,7 @@ export class ReadFileTool extends BaseTool { const fileService = this.config.getFileService(); if (fileService.shouldGeminiIgnoreFile(params.absolute_path)) { - const relativePath = makeRelative( - params.absolute_path, - this.rootDirectory, - ); - return `File path '${shortenPath(relativePath)}' is ignored by .geminiignore pattern(s).`; + return `File path '${filePath}' is ignored by .geminiignore pattern(s).`; } return null; diff --git a/packages/core/src/tools/read-many-files.test.ts b/packages/core/src/tools/read-many-files.test.ts index ef42d8b6..d2591a8b 100644 --- a/packages/core/src/tools/read-many-files.test.ts +++ b/packages/core/src/tools/read-many-files.test.ts @@ -195,8 +195,9 @@ describe('ReadManyFilesTool', () => { createFile('file1.txt', 'Content of file1'); const params = { paths: ['file1.txt'] }; const result = await tool.execute(params, new AbortController().signal); + const expectedPath = path.join(tempRootDir, 'file1.txt'); expect(result.llmContent).toEqual([ - '--- file1.txt ---\n\nContent of file1\n\n', + `--- ${expectedPath} ---\n\nContent of file1\n\n`, ]); expect(result.returnDisplay).toContain( 'Successfully read and concatenated content from **1 file(s)**', @@ -209,12 +210,16 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['file1.txt', 'subdir/file2.js'] }; const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; + const expectedPath1 = path.join(tempRootDir, 'file1.txt'); + const expectedPath2 = path.join(tempRootDir, 'subdir/file2.js'); expect( - content.some((c) => c.includes('--- file1.txt ---\n\nContent1\n\n')), + content.some((c) => + c.includes(`--- ${expectedPath1} ---\n\nContent1\n\n`), + ), ).toBe(true); expect( content.some((c) => - c.includes('--- subdir/file2.js ---\n\nContent2\n\n'), + c.includes(`--- ${expectedPath2} ---\n\nContent2\n\n`), ), ).toBe(true); expect(result.returnDisplay).toContain( @@ -229,12 +234,16 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['*.txt'] }; const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; + const expectedPath1 = path.join(tempRootDir, 'file.txt'); + const expectedPath2 = path.join(tempRootDir, 'another.txt'); expect( - content.some((c) => c.includes('--- file.txt ---\n\nText file\n\n')), + content.some((c) => + c.includes(`--- ${expectedPath1} ---\n\nText file\n\n`), + ), ).toBe(true); expect( content.some((c) => - c.includes('--- another.txt ---\n\nAnother text\n\n'), + c.includes(`--- ${expectedPath2} ---\n\nAnother text\n\n`), ), ).toBe(true); expect(content.find((c) => c.includes('sub/data.json'))).toBeUndefined(); @@ -249,7 +258,8 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['src/**/*.ts'], exclude: ['**/*.test.ts'] }; const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; - expect(content).toEqual(['--- src/main.ts ---\n\nMain content\n\n']); + const expectedPath = path.join(tempRootDir, 'src/main.ts'); + expect(content).toEqual([`--- ${expectedPath} ---\n\nMain content\n\n`]); expect( content.find((c) => c.includes('src/main.test.ts')), ).toBeUndefined(); @@ -275,7 +285,8 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['**/*.js'] }; const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; - expect(content).toEqual(['--- src/app.js ---\n\napp code\n\n']); + const expectedPath = path.join(tempRootDir, 'src/app.js'); + expect(content).toEqual([`--- ${expectedPath} ---\n\napp code\n\n`]); expect( content.find((c) => c.includes('node_modules/some-lib/index.js')), ).toBeUndefined(); @@ -290,13 +301,20 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['**/*.js'], useDefaultExcludes: false }; const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; + const expectedPath1 = path.join( + tempRootDir, + 'node_modules/some-lib/index.js', + ); + const expectedPath2 = path.join(tempRootDir, 'src/app.js'); expect( content.some((c) => - c.includes('--- node_modules/some-lib/index.js ---\n\nlib code\n\n'), + c.includes(`--- ${expectedPath1} ---\n\nlib code\n\n`), ), ).toBe(true); expect( - content.some((c) => c.includes('--- src/app.js ---\n\napp code\n\n')), + content.some((c) => + c.includes(`--- ${expectedPath2} ---\n\napp code\n\n`), + ), ).toBe(true); expect(result.returnDisplay).toContain( 'Successfully read and concatenated content from **2 file(s)**', @@ -350,9 +368,12 @@ describe('ReadManyFilesTool', () => { const params = { paths: ['*'] }; // Generic glob, not specific to .pdf const result = await tool.execute(params, new AbortController().signal); const content = result.llmContent as string[]; + const expectedPath = path.join(tempRootDir, 'notes.txt'); expect( content.some( - (c) => typeof c === 'string' && c.includes('--- notes.txt ---'), + (c) => + typeof c === 'string' && + c.includes(`--- ${expectedPath} ---\n\ntext notes\n\n`), ), ).toBe(true); expect(result.returnDisplay).toContain('**Skipped 1 item(s):**'); diff --git a/packages/core/src/tools/read-many-files.ts b/packages/core/src/tools/read-many-files.ts index 38cecc16..5557dc43 100644 --- a/packages/core/src/tools/read-many-files.ts +++ b/packages/core/src/tools/read-many-files.ts @@ -390,7 +390,7 @@ Use this tool when the user's query implies needing the content of several files if (typeof fileReadResult.llmContent === 'string') { const separator = DEFAULT_OUTPUT_SEPARATOR_FORMAT.replace( '{filePath}', - relativePathForDisplay, + filePath, ); contentParts.push(`${separator}\n\n${fileReadResult.llmContent}\n\n`); } else { -- cgit v1.2.3