From f79124f96ebe3e460d4854954cb4ab9503d2978d Mon Sep 17 00:00:00 2001 From: Sandy Tao Date: Wed, 21 Jan 2026 10:53:41 -0800 Subject: [PATCH] feat(core): enable disableLLMCorrection by default (#17223) --- docs/cli/settings.md | 2 +- docs/get-started/configuration.md | 2 +- packages/cli/src/config/settingsSchema.ts | 2 +- packages/core/src/config/config.ts | 2 +- .../src/tools/confirmation-policy.test.ts | 2 +- packages/core/src/tools/edit.test.ts | 21 ++++++++++++++++--- packages/core/src/tools/write-file.test.ts | 14 ++++++------- packages/core/src/utils/editCorrector.ts | 2 +- schemas/settings.schema.json | 4 ++-- 9 files changed, 33 insertions(+), 18 deletions(-) diff --git a/docs/cli/settings.md b/docs/cli/settings.md index 9c6af44ecc..de4b745722 100644 --- a/docs/cli/settings.md +++ b/docs/cli/settings.md @@ -99,7 +99,7 @@ they appear in the UI. | 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 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 diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md index d528e5398a..167a854471 100644 --- a/docs/get-started/configuration.md +++ b/docs/get-started/configuration.md @@ -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 enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. - - **Default:** `false` + - **Default:** `true` - **Requires restart:** Yes - **`tools.enableHooks`** (boolean): diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index cea502581d..d5711ca83f 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -1126,7 +1126,7 @@ const SETTINGS_SCHEMA = { label: 'Disable LLM Correction', category: 'Tools', requiresRestart: true, - default: false, + default: true, description: oneLine` 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. diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 7441f8647d..dd73dec7b5 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -634,7 +634,7 @@ export class Config { this._activeModel = params.model; this.enableAgents = params.enableAgents ?? false; this.agents = params.agents ?? {}; - this.disableLLMCorrection = params.disableLLMCorrection ?? false; + this.disableLLMCorrection = params.disableLLMCorrection ?? true; this.planEnabled = params.plan ?? false; this.enableEventDrivenScheduler = params.enableEventDrivenScheduler ?? false; diff --git a/packages/core/src/tools/confirmation-policy.test.ts b/packages/core/src/tools/confirmation-policy.test.ts index e3b87ecb59..1d04896a10 100644 --- a/packages/core/src/tools/confirmation-policy.test.ts +++ b/packages/core/src/tools/confirmation-policy.test.ts @@ -64,7 +64,7 @@ describe('Tool Confirmation Policy Updates', () => { getFileFilteringOptions: () => ({}), getGeminiClient: () => ({}), getBaseLlmClient: () => ({}), - getDisableLLMCorrection: () => false, + getDisableLLMCorrection: () => true, getIdeMode: () => false, getWorkspaceContext: () => ({ isPathWithinWorkspace: () => true, diff --git a/packages/core/src/tools/edit.test.ts b/packages/core/src/tools/edit.test.ts index 874c3e4140..142bbde364 100644 --- a/packages/core/src/tools/edit.test.ts +++ b/packages/core/src/tools/edit.test.ts @@ -120,7 +120,7 @@ describe('EditTool', () => { setGeminiMdFileCount: vi.fn(), getToolRegistry: () => ({}) as any, isInteractive: () => false, - getDisableLLMCorrection: vi.fn(() => false), + getDisableLLMCorrection: vi.fn(() => true), getExperiments: () => {}, } as unknown as Config; @@ -436,6 +436,10 @@ describe('EditTool', () => { it('should return error if old_string is not found in file', async () => { fs.writeFileSync(filePath, 'Some content.', 'utf8'); + + // Enable LLM correction for this test + (mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false); + const params: EditToolParams = { file_path: filePath, instruction: 'Replace non-existent text', @@ -455,6 +459,10 @@ describe('EditTool', () => { const initialContent = 'This is some original text.'; const finalContent = 'This is some brand new text.'; fs.writeFileSync(filePath, initialContent, 'utf8'); + + // Enable LLM correction for this test + (mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false); + const params: EditToolParams = { file_path: filePath, 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 () => { const initialContent = 'The price is $100.'; fs.writeFileSync(filePath, initialContent, 'utf8'); + + // Enable LLM correction for this test + (mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false); + const params: EditToolParams = { file_path: filePath, instruction: 'Ensure the price is $100', @@ -556,6 +568,9 @@ describe('EditTool', () => { 'This is the externally modified content.'; fs.writeFileSync(filePath, initialContent, 'utf8'); + // Enable LLM correction for this test + (mockConfig.getDisableLLMCorrection as Mock).mockReturnValue(false); + const params: EditToolParams = { file_path: filePath, instruction: @@ -882,11 +897,11 @@ describe('EditTool', () => { 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'); 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); const params: EditToolParams = { diff --git a/packages/core/src/tools/write-file.test.ts b/packages/core/src/tools/write-file.test.ts index 7a657cfc64..965656e4f8 100644 --- a/packages/core/src/tools/write-file.test.ts +++ b/packages/core/src/tools/write-file.test.ts @@ -106,7 +106,7 @@ const mockConfigInternal = { discoverTools: vi.fn(), }) as unknown as ToolRegistry, isInteractive: () => false, - getDisableLLMCorrection: vi.fn(() => false), + getDisableLLMCorrection: vi.fn(() => true), }; const mockConfig = mockConfigInternal as unknown as Config; @@ -294,7 +294,7 @@ describe('WriteFileTool', () => { proposedContent, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(mockEnsureCorrectEdit).not.toHaveBeenCalled(); expect(result.correctedContent).toBe(correctedContent); @@ -339,7 +339,7 @@ describe('WriteFileTool', () => { mockGeminiClientInstance, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(mockEnsureCorrectFileContent).not.toHaveBeenCalled(); expect(result.correctedContent).toBe(correctedProposedContent); @@ -417,7 +417,7 @@ describe('WriteFileTool', () => { proposedContent, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(confirmation).toEqual( expect.objectContaining({ @@ -468,7 +468,7 @@ describe('WriteFileTool', () => { mockGeminiClientInstance, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(confirmation).toEqual( expect.objectContaining({ @@ -663,7 +663,7 @@ describe('WriteFileTool', () => { proposedContent, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(result.llmContent).toMatch( /Successfully created and wrote to new file/, @@ -721,7 +721,7 @@ describe('WriteFileTool', () => { mockGeminiClientInstance, mockBaseLlmClientInstance, abortSignal, - false, + true, ); expect(result.llmContent).toMatch(/Successfully overwrote file/); const writtenContent = await fsService.readTextFile(filePath); diff --git a/packages/core/src/utils/editCorrector.ts b/packages/core/src/utils/editCorrector.ts index 7002114906..4762f0c91f 100644 --- a/packages/core/src/utils/editCorrector.ts +++ b/packages/core/src/utils/editCorrector.ts @@ -357,7 +357,7 @@ export async function ensureCorrectFileContent( content: string, baseLlmClient: BaseLlmClient, abortSignal: AbortSignal, - disableLLMCorrection: boolean = false, + disableLLMCorrection: boolean = true, ): Promise { const cachedResult = fileContentCorrectionCache.get(content); if (cachedResult) { diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index c94fc779c8..7b9e5a671d 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -1165,8 +1165,8 @@ "disableLLMCorrection": { "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.", - "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`", - "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": true, "type": "boolean" }, "enableHooks": {