diff --git a/src/core/tools/WriteToFileTool.ts b/src/core/tools/WriteToFileTool.ts index f1bae7ff2fc..7caaeb6d55d 100644 --- a/src/core/tools/WriteToFileTool.ts +++ b/src/core/tools/WriteToFileTool.ts @@ -11,7 +11,6 @@ import { fileExistsAtPath, createDirectoriesForFile } from "../../utils/fs" import { stripLineNumbers, everyLineHasLineNumbers } from "../../integrations/misc/extract-text" import { getReadablePath } from "../../utils/path" import { isPathOutsideWorkspace } from "../../utils/pathUtils" -import { detectCodeOmission } from "../../integrations/editor/detect-omission" import { unescapeHtmlEntities } from "../../utils/text-normalization" import { DEFAULT_WRITE_DELAY_MS } from "@roo-code/types" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" @@ -125,32 +124,6 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> { task.diffViewProvider.originalContent = "" } - if (detectCodeOmission(task.diffViewProvider.originalContent || "", newContent)) { - if (task.diffStrategy) { - pushToolResult( - formatResponse.toolError( - `Content appears to contain comments indicating omitted code (e.g., '// rest of code unchanged', '/* previous code */'). Please provide the complete file content without any omissions if possible, or otherwise use the 'apply_diff' tool to apply the diff to the original file.`, - ), - ) - return - } else { - vscode.window - .showWarningMessage( - "Potential code truncation detected. This happens when the AI reaches its max output limit.", - "Follow guide to fix the issue", - ) - .then((selection) => { - if (selection === "Follow guide to fix the issue") { - vscode.env.openExternal( - vscode.Uri.parse( - "https://github.com/cline/cline/wiki/Troubleshooting-%E2%80%90-Cline-Deleting-Code-with-%22Rest-of-Code-Here%22-Comments", - ), - ) - } - }) - } - } - let unified = fileExists ? formatResponse.createPrettyPatch(relPath, task.diffViewProvider.originalContent, newContent) : convertNewFileToUnifiedDiff(newContent, relPath) @@ -183,34 +156,6 @@ export class WriteToFileTool extends BaseTool<"write_to_file"> { await delay(300) task.diffViewProvider.scrollToFirstDiff() - if (detectCodeOmission(task.diffViewProvider.originalContent || "", newContent)) { - if (task.diffStrategy) { - await task.diffViewProvider.revertChanges() - - pushToolResult( - formatResponse.toolError( - `Content appears to contain comments indicating omitted code (e.g., '// rest of code unchanged', '/* previous code */'). Please provide the complete file content without any omissions if possible, or otherwise use the 'apply_diff' tool to apply the diff to the original file.`, - ), - ) - return - } else { - vscode.window - .showWarningMessage( - "Potential code truncation detected. This happens when the AI reaches its max output limit.", - "Follow guide to fix the issue", - ) - .then((selection) => { - if (selection === "Follow guide to fix the issue") { - vscode.env.openExternal( - vscode.Uri.parse( - "https://github.com/cline/cline/wiki/Troubleshooting-%E2%80%90-Cline-Deleting-Code-with-%22Rest-of-Code-Here%22-Comments", - ), - ) - } - }) - } - } - let unified = fileExists ? formatResponse.createPrettyPatch(relPath, task.diffViewProvider.originalContent, newContent) : convertNewFileToUnifiedDiff(newContent, relPath) diff --git a/src/core/tools/__tests__/writeToFileTool.spec.ts b/src/core/tools/__tests__/writeToFileTool.spec.ts index ff9ad76dade..3970a99f066 100644 --- a/src/core/tools/__tests__/writeToFileTool.spec.ts +++ b/src/core/tools/__tests__/writeToFileTool.spec.ts @@ -3,7 +3,6 @@ import * as path from "path" import type { MockedFunction } from "vitest" import { fileExistsAtPath, createDirectoriesForFile } from "../../../utils/fs" -import { detectCodeOmission } from "../../../integrations/editor/detect-omission" import { isPathOutsideWorkspace } from "../../../utils/pathUtils" import { getReadablePath } from "../../../utils/path" import { unescapeHtmlEntities } from "../../../utils/text-normalization" @@ -40,10 +39,6 @@ vi.mock("../../prompts/responses", () => ({ }, })) -vi.mock("../../../integrations/editor/detect-omission", () => ({ - detectCodeOmission: vi.fn().mockReturnValue(false), -})) - vi.mock("../../../utils/pathUtils", () => ({ isPathOutsideWorkspace: vi.fn().mockReturnValue(false), })) @@ -100,7 +95,6 @@ describe("writeToFileTool", () => { // Mocked functions with correct types const mockedFileExistsAtPath = fileExistsAtPath as MockedFunction const mockedCreateDirectoriesForFile = createDirectoriesForFile as MockedFunction - const mockedDetectCodeOmission = detectCodeOmission as MockedFunction const mockedIsPathOutsideWorkspace = isPathOutsideWorkspace as MockedFunction const mockedGetReadablePath = getReadablePath as MockedFunction const mockedUnescapeHtmlEntities = unescapeHtmlEntities as MockedFunction @@ -120,7 +114,6 @@ describe("writeToFileTool", () => { mockedPathResolve.mockReturnValue(absoluteFilePath) mockedFileExistsAtPath.mockResolvedValue(false) - mockedDetectCodeOmission.mockReturnValue(false) mockedIsPathOutsideWorkspace.mockReturnValue(false) mockedGetReadablePath.mockReturnValue("test/path.txt") mockedUnescapeHtmlEntities.mockImplementation((content) => content) diff --git a/src/integrations/editor/__tests__/detect-omission.spec.ts b/src/integrations/editor/__tests__/detect-omission.spec.ts deleted file mode 100644 index 6ff31c390a5..00000000000 --- a/src/integrations/editor/__tests__/detect-omission.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { detectCodeOmission } from "../detect-omission" - -describe("detectCodeOmission", () => { - const originalContent = `function example() { - // Some code - const x = 1; - const y = 2; - return x + y; -}` - - // Generate content with a specified number of lines (100+ lines triggers detection) - const generateLongContent = (commentLine: string, length: number = 110) => { - return `${commentLine} - ${Array.from({ length }, (_, i) => `const x${i} = ${i};`).join("\n")} - const y = 2;` - } - - it("should skip comment checks for files under 100 lines", () => { - const newContent = `// Lines 1-50 remain unchanged -const z = 3;` - expect(detectCodeOmission(originalContent, newContent)).toBe(false) - }) - - it("should not detect regular comments without omission keywords", () => { - const newContent = generateLongContent("// Adding new functionality") - expect(detectCodeOmission(originalContent, newContent)).toBe(false) - }) - - it("should not detect when comment is part of original content", () => { - const originalWithComment = `// Content remains unchanged -${originalContent}` - const newContent = generateLongContent("// Content remains unchanged") - expect(detectCodeOmission(originalWithComment, newContent)).toBe(false) - }) - - it("should not detect code that happens to contain omission keywords", () => { - const newContent = generateLongContent(`const remains = 'some value'; -const unchanged = true;`) - expect(detectCodeOmission(originalContent, newContent)).toBe(false) - }) - - it("should detect suspicious single-line comment for files with 100+ lines", () => { - const newContent = generateLongContent("// Previous content remains here\nconst x = 1;") - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should detect suspicious Python-style comment for files with 100+ lines", () => { - const newContent = generateLongContent("# Previous content remains here\nconst x = 1;") - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should detect suspicious multi-line comment for files with 100+ lines", () => { - const newContent = generateLongContent("/* Previous content remains the same */\nconst x = 1;") - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should detect suspicious JSX comment for files with 100+ lines", () => { - const newContent = generateLongContent("{/* Rest of the code remains the same */}\nconst x = 1;") - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should detect suspicious HTML comment for files with 100+ lines", () => { - const newContent = generateLongContent("\nconst x = 1;") - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should detect suspicious square bracket notation for files with 100+ lines", () => { - const newContent = generateLongContent( - "[Previous content from line 1-305 remains exactly the same]\nconst x = 1;", - ) - expect(detectCodeOmission(originalContent, newContent)).toBe(true) - }) - - it("should not flag legitimate comments in files with 100+ lines when in original", () => { - const originalWithComment = `// This is a legitimate comment that remains here -${originalContent}` - const newContent = generateLongContent("// This is a legitimate comment that remains here") - expect(detectCodeOmission(originalWithComment, newContent)).toBe(false) - }) -}) diff --git a/src/integrations/editor/detect-omission.ts b/src/integrations/editor/detect-omission.ts deleted file mode 100644 index d55acd4183c..00000000000 --- a/src/integrations/editor/detect-omission.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Detects potential AI-generated code omissions in the given file content. - * Looks for comments containing omission keywords that weren't in the original file. - * @param originalFileContent The original content of the file. - * @param newFileContent The new content of the file to check. - * @returns True if a potential omission is detected, false otherwise. - */ -export function detectCodeOmission(originalFileContent: string, newFileContent: string): boolean { - const actualLineCount = newFileContent.split("\n").length - - // Skip checks for small files (less than 100 lines) - if (actualLineCount < 100) { - return false - } - - const originalLines = originalFileContent.split("\n") - const newLines = newFileContent.split("\n") - const omissionKeywords = [ - "remain", - "remains", - "unchanged", - "rest", - "previous", - "existing", - "content", - "same", - "...", - ] - - const commentPatterns = [ - /^\s*\/\//, // Single-line comment for most languages - /^\s*#/, // Single-line comment for Python, Ruby, etc. - /^\s*\/\*/, // Multi-line comment opening - /^\s*{\s*\/\*/, // JSX comment opening - /^\s*