mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
feat(core): enable disableLLMCorrection by default (#17223)
This commit is contained in:
@@ -99,7 +99,7 @@ they appear in the UI.
|
|||||||
| Enable Tool Output Truncation | `tools.enableToolOutputTruncation` | Enable truncation of large tool outputs. | `true` |
|
| Enable Tool Output Truncation | `tools.enableToolOutputTruncation` | Enable truncation of large tool outputs. | `true` |
|
||||||
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Truncate tool output if it is larger than this many characters. Set to -1 to disable. | `4000000` |
|
| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Truncate tool output if it is larger than this many characters. Set to -1 to disable. | `4000000` |
|
||||||
| Tool Output Truncation Lines | `tools.truncateToolOutputLines` | The number of lines to keep when truncating tool output. | `1000` |
|
| Tool Output Truncation Lines | `tools.truncateToolOutputLines` | The number of lines to keep when truncating tool output. | `1000` |
|
||||||
| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `false` |
|
| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` |
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|||||||
@@ -707,7 +707,7 @@ their corresponding top-level category object in your `settings.json` file.
|
|||||||
- **Description:** Disable LLM-based error correction for edit tools. When
|
- **Description:** Disable LLM-based error correction for edit tools. When
|
||||||
enabled, tools will fail immediately if exact string matches are not found,
|
enabled, tools will fail immediately if exact string matches are not found,
|
||||||
instead of attempting to self-correct.
|
instead of attempting to self-correct.
|
||||||
- **Default:** `false`
|
- **Default:** `true`
|
||||||
- **Requires restart:** Yes
|
- **Requires restart:** Yes
|
||||||
|
|
||||||
- **`tools.enableHooks`** (boolean):
|
- **`tools.enableHooks`** (boolean):
|
||||||
|
|||||||
@@ -1126,7 +1126,7 @@ const SETTINGS_SCHEMA = {
|
|||||||
label: 'Disable LLM Correction',
|
label: 'Disable LLM Correction',
|
||||||
category: 'Tools',
|
category: 'Tools',
|
||||||
requiresRestart: true,
|
requiresRestart: true,
|
||||||
default: false,
|
default: true,
|
||||||
description: oneLine`
|
description: oneLine`
|
||||||
Disable LLM-based error correction for edit tools.
|
Disable LLM-based error correction for edit tools.
|
||||||
When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.
|
When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ export class Config {
|
|||||||
this._activeModel = params.model;
|
this._activeModel = params.model;
|
||||||
this.enableAgents = params.enableAgents ?? false;
|
this.enableAgents = params.enableAgents ?? false;
|
||||||
this.agents = params.agents ?? {};
|
this.agents = params.agents ?? {};
|
||||||
this.disableLLMCorrection = params.disableLLMCorrection ?? false;
|
this.disableLLMCorrection = params.disableLLMCorrection ?? true;
|
||||||
this.planEnabled = params.plan ?? false;
|
this.planEnabled = params.plan ?? false;
|
||||||
this.enableEventDrivenScheduler =
|
this.enableEventDrivenScheduler =
|
||||||
params.enableEventDrivenScheduler ?? false;
|
params.enableEventDrivenScheduler ?? false;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ describe('Tool Confirmation Policy Updates', () => {
|
|||||||
getFileFilteringOptions: () => ({}),
|
getFileFilteringOptions: () => ({}),
|
||||||
getGeminiClient: () => ({}),
|
getGeminiClient: () => ({}),
|
||||||
getBaseLlmClient: () => ({}),
|
getBaseLlmClient: () => ({}),
|
||||||
getDisableLLMCorrection: () => false,
|
getDisableLLMCorrection: () => true,
|
||||||
getIdeMode: () => false,
|
getIdeMode: () => false,
|
||||||
getWorkspaceContext: () => ({
|
getWorkspaceContext: () => ({
|
||||||
isPathWithinWorkspace: () => true,
|
isPathWithinWorkspace: () => true,
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ describe('EditTool', () => {
|
|||||||
setGeminiMdFileCount: vi.fn(),
|
setGeminiMdFileCount: vi.fn(),
|
||||||
getToolRegistry: () => ({}) as any,
|
getToolRegistry: () => ({}) as any,
|
||||||
isInteractive: () => false,
|
isInteractive: () => false,
|
||||||
getDisableLLMCorrection: vi.fn(() => false),
|
getDisableLLMCorrection: vi.fn(() => true),
|
||||||
getExperiments: () => {},
|
getExperiments: () => {},
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
|
|
||||||
@@ -436,6 +436,10 @@ describe('EditTool', () => {
|
|||||||
|
|
||||||
it('should return error if old_string is not found in file', async () => {
|
it('should return error if old_string is not found in file', async () => {
|
||||||
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
||||||
|
|
||||||
|
// Enable LLM correction for this test
|
||||||
|
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
||||||
|
|
||||||
const params: EditToolParams = {
|
const params: EditToolParams = {
|
||||||
file_path: filePath,
|
file_path: filePath,
|
||||||
instruction: 'Replace non-existent text',
|
instruction: 'Replace non-existent text',
|
||||||
@@ -455,6 +459,10 @@ describe('EditTool', () => {
|
|||||||
const initialContent = 'This is some original text.';
|
const initialContent = 'This is some original text.';
|
||||||
const finalContent = 'This is some brand new text.';
|
const finalContent = 'This is some brand new text.';
|
||||||
fs.writeFileSync(filePath, initialContent, 'utf8');
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
||||||
|
|
||||||
|
// Enable LLM correction for this test
|
||||||
|
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
||||||
|
|
||||||
const params: EditToolParams = {
|
const params: EditToolParams = {
|
||||||
file_path: filePath,
|
file_path: filePath,
|
||||||
instruction: 'Replace original with brand new',
|
instruction: 'Replace original with brand new',
|
||||||
@@ -515,6 +523,10 @@ describe('EditTool', () => {
|
|||||||
it('should return NO_CHANGE if FixLLMEditWithInstruction determines no changes are needed', async () => {
|
it('should return NO_CHANGE if FixLLMEditWithInstruction determines no changes are needed', async () => {
|
||||||
const initialContent = 'The price is $100.';
|
const initialContent = 'The price is $100.';
|
||||||
fs.writeFileSync(filePath, initialContent, 'utf8');
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
||||||
|
|
||||||
|
// Enable LLM correction for this test
|
||||||
|
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
||||||
|
|
||||||
const params: EditToolParams = {
|
const params: EditToolParams = {
|
||||||
file_path: filePath,
|
file_path: filePath,
|
||||||
instruction: 'Ensure the price is $100',
|
instruction: 'Ensure the price is $100',
|
||||||
@@ -556,6 +568,9 @@ describe('EditTool', () => {
|
|||||||
'This is the externally modified content.';
|
'This is the externally modified content.';
|
||||||
fs.writeFileSync(filePath, initialContent, 'utf8');
|
fs.writeFileSync(filePath, initialContent, 'utf8');
|
||||||
|
|
||||||
|
// Enable LLM correction for this test
|
||||||
|
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
||||||
|
|
||||||
const params: EditToolParams = {
|
const params: EditToolParams = {
|
||||||
file_path: filePath,
|
file_path: filePath,
|
||||||
instruction:
|
instruction:
|
||||||
@@ -882,11 +897,11 @@ describe('EditTool', () => {
|
|||||||
expect(mockFixLLMEditWithInstruction).not.toHaveBeenCalled();
|
expect(mockFixLLMEditWithInstruction).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call FixLLMEditWithInstruction when disableLLMCorrection is false (default)', async () => {
|
it('should call FixLLMEditWithInstruction when disableLLMCorrection is false', async () => {
|
||||||
const filePath = path.join(rootDir, 'enable_llm_test.txt');
|
const filePath = path.join(rootDir, 'enable_llm_test.txt');
|
||||||
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
fs.writeFileSync(filePath, 'Some content.', 'utf8');
|
||||||
|
|
||||||
// Default is false, but being explicit
|
// Now explicit as it's not the default anymore
|
||||||
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
(mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false);
|
||||||
|
|
||||||
const params: EditToolParams = {
|
const params: EditToolParams = {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ const mockConfigInternal = {
|
|||||||
discoverTools: vi.fn(),
|
discoverTools: vi.fn(),
|
||||||
}) as unknown as ToolRegistry,
|
}) as unknown as ToolRegistry,
|
||||||
isInteractive: () => false,
|
isInteractive: () => false,
|
||||||
getDisableLLMCorrection: vi.fn(() => false),
|
getDisableLLMCorrection: vi.fn(() => true),
|
||||||
};
|
};
|
||||||
const mockConfig = mockConfigInternal as unknown as Config;
|
const mockConfig = mockConfigInternal as unknown as Config;
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ describe('WriteFileTool', () => {
|
|||||||
proposedContent,
|
proposedContent,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(mockEnsureCorrectEdit).not.toHaveBeenCalled();
|
expect(mockEnsureCorrectEdit).not.toHaveBeenCalled();
|
||||||
expect(result.correctedContent).toBe(correctedContent);
|
expect(result.correctedContent).toBe(correctedContent);
|
||||||
@@ -339,7 +339,7 @@ describe('WriteFileTool', () => {
|
|||||||
mockGeminiClientInstance,
|
mockGeminiClientInstance,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(mockEnsureCorrectFileContent).not.toHaveBeenCalled();
|
expect(mockEnsureCorrectFileContent).not.toHaveBeenCalled();
|
||||||
expect(result.correctedContent).toBe(correctedProposedContent);
|
expect(result.correctedContent).toBe(correctedProposedContent);
|
||||||
@@ -417,7 +417,7 @@ describe('WriteFileTool', () => {
|
|||||||
proposedContent,
|
proposedContent,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(confirmation).toEqual(
|
expect(confirmation).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@@ -468,7 +468,7 @@ describe('WriteFileTool', () => {
|
|||||||
mockGeminiClientInstance,
|
mockGeminiClientInstance,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(confirmation).toEqual(
|
expect(confirmation).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
@@ -663,7 +663,7 @@ describe('WriteFileTool', () => {
|
|||||||
proposedContent,
|
proposedContent,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(result.llmContent).toMatch(
|
expect(result.llmContent).toMatch(
|
||||||
/Successfully created and wrote to new file/,
|
/Successfully created and wrote to new file/,
|
||||||
@@ -721,7 +721,7 @@ describe('WriteFileTool', () => {
|
|||||||
mockGeminiClientInstance,
|
mockGeminiClientInstance,
|
||||||
mockBaseLlmClientInstance,
|
mockBaseLlmClientInstance,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
false,
|
true,
|
||||||
);
|
);
|
||||||
expect(result.llmContent).toMatch(/Successfully overwrote file/);
|
expect(result.llmContent).toMatch(/Successfully overwrote file/);
|
||||||
const writtenContent = await fsService.readTextFile(filePath);
|
const writtenContent = await fsService.readTextFile(filePath);
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ export async function ensureCorrectFileContent(
|
|||||||
content: string,
|
content: string,
|
||||||
baseLlmClient: BaseLlmClient,
|
baseLlmClient: BaseLlmClient,
|
||||||
abortSignal: AbortSignal,
|
abortSignal: AbortSignal,
|
||||||
disableLLMCorrection: boolean = false,
|
disableLLMCorrection: boolean = true,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const cachedResult = fileContentCorrectionCache.get(content);
|
const cachedResult = fileContentCorrectionCache.get(content);
|
||||||
if (cachedResult) {
|
if (cachedResult) {
|
||||||
|
|||||||
@@ -1165,8 +1165,8 @@
|
|||||||
"disableLLMCorrection": {
|
"disableLLMCorrection": {
|
||||||
"title": "Disable LLM Correction",
|
"title": "Disable LLM Correction",
|
||||||
"description": "Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.",
|
"description": "Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.",
|
||||||
"markdownDescription": "Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.\n\n- Category: `Tools`\n- Requires restart: `yes`\n- Default: `false`",
|
"markdownDescription": "Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct.\n\n- Category: `Tools`\n- Requires restart: `yes`\n- Default: `true`",
|
||||||
"default": false,
|
"default": true,
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"enableHooks": {
|
"enableHooks": {
|
||||||
|
|||||||
Reference in New Issue
Block a user