fix(plan): sandbox path resolution in Plan Mode to prevent hallucinations (#22737)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Adib234
2026-03-24 09:19:29 -04:00
committed by GitHub
parent 46fd7b4864
commit dcedc42979
22 changed files with 193 additions and 111 deletions

View File

@@ -131,8 +131,10 @@ describe('EditTool', () => {
isInteractive: () => false,
getDisableLLMCorrection: vi.fn(() => true),
getExperiments: () => {},
isPlanMode: vi.fn(() => false),
storage: {
getProjectTempDir: vi.fn().mockReturnValue('/tmp/project'),
getPlansDir: vi.fn().mockReturnValue('/tmp/plans'),
},
isPathAllowed(this: Config, absolutePath: string): boolean {
const workspaceContext = this.getWorkspaceContext();
@@ -1299,4 +1301,42 @@ function doIt() {
);
});
});
describe('plan mode', () => {
it('should allow edits to plans directory when isPlanMode is true', async () => {
const mockProjectTempDir = path.join(tempDir, 'project');
fs.mkdirSync(mockProjectTempDir);
vi.mocked(mockConfig.storage.getProjectTempDir).mockReturnValue(
mockProjectTempDir,
);
const plansDir = path.join(mockProjectTempDir, 'plans');
fs.mkdirSync(plansDir);
vi.mocked(mockConfig.isPlanMode).mockReturnValue(true);
vi.mocked(mockConfig.storage.getPlansDir).mockReturnValue(plansDir);
const filePath = path.join(rootDir, 'test-file.txt');
const planFilePath = path.join(plansDir, 'test-file.txt');
const initialContent = 'some initial content';
fs.writeFileSync(planFilePath, initialContent, 'utf8');
const params: EditToolParams = {
file_path: filePath,
instruction: 'Replace initial with new',
old_string: 'initial',
new_string: 'new',
};
const invocation = tool.build(params);
const result = await invocation.execute(new AbortController().signal);
expect(result.llmContent).toMatch(/Successfully modified file/);
// Verify plan file is written with new content
expect(fs.readFileSync(planFilePath, 'utf8')).toBe('some new content');
fs.rmSync(plansDir, { recursive: true, force: true });
});
});
});