diff --git a/src/core/diff/strategies/multi-file-search-replace.ts b/src/core/diff/strategies/multi-file-search-replace.ts index c71d3c3807d..f247edd7a2c 100644 --- a/src/core/diff/strategies/multi-file-search-replace.ts +++ b/src/core/diff/strategies/multi-file-search-replace.ts @@ -105,42 +105,31 @@ When applying the diffs, be extra careful to remember to change any closing brac ALWAYS make as many changes in a single 'apply_diff' request as possible using multiple SEARCH/REPLACE blocks Parameters: -- args: Contains one or more file elements, where each file contains: +- file: One or more file elements, where each file contains: - path: (required) The path of the file to modify (relative to the current workspace directory ${args.cwd}) - - diff: (required) One or more diff elements containing: - - content: (required) The search/replace block defining the changes. - - start_line: (required) The line number of original content where the search block starts. + - diff: (required) One or more diff elements containing the search/replace blocks directly (no content wrapper needed) Diff format: -\`\`\` <<<<<<< SEARCH -:start_line: (required) The line number of original content where the search block starts. -------- [exact content to find including whitespace] ======= [new content to replace with] >>>>>>> REPLACE -\`\`\` Example: Original file: -\`\`\` 1 | def calculate_total(items): 2 | total = 0 3 | for item in items: 4 | total += item 5 | return total -\`\`\` Search/Replace content: - eg.file.py - -\`\`\` <<<<<<< SEARCH def calculate_total(items): total = 0 @@ -152,21 +141,15 @@ def calculate_total(items): """Calculate total with 10% markup""" return sum(item * 1.1 for item in items) >>>>>>> REPLACE -\`\`\` - - Search/Replace content with multi edits across multiple files: - eg.file.py - -\`\`\` <<<<<<< SEARCH def calculate_total(items): sum = 0 @@ -174,12 +157,8 @@ def calculate_total(items): def calculate_sum(items): sum = 0 >>>>>>> REPLACE -\`\`\` - - -\`\`\` <<<<<<< SEARCH total += item return total @@ -187,15 +166,11 @@ def calculate_sum(items): sum += item return sum >>>>>>> REPLACE -\`\`\` - eg.file2.py - -\`\`\` <<<<<<< SEARCH def greet(name): return "Hello " + name @@ -203,40 +178,33 @@ def greet(name): def greet(name): return f"Hello {name}!" >>>>>>> REPLACE -\`\`\` - - Usage: - File path here - -Your search/replace content here -You can use multi search/replace block in one diff block, but make sure to include the line numbers for each block. -Only use a single line of '=======' between search and replacement content, because multiple '=======' will corrupt the file. - - 1 +<<<<<<< SEARCH +Your exact search content here +======= +Your replacement content here +>>>>>>> REPLACE Another file path - -Another search/replace content here -You can apply changes to multiple files in a single request. -Each file requires its own path, start_line, and diff elements. - - 5 +<<<<<<< SEARCH +Another search content here +======= +Another replacement content here +>>>>>>> REPLACE - ` } diff --git a/src/core/tools/multiApplyDiffTool.ts b/src/core/tools/multiApplyDiffTool.ts index db514d2b642..f3e2e4f418f 100644 --- a/src/core/tools/multiApplyDiffTool.ts +++ b/src/core/tools/multiApplyDiffTool.ts @@ -106,9 +106,10 @@ export async function applyDiffTool( } if (argsXmlTag) { - // Parse file entries from XML (new way) + // Parse file entries from XML try { - const parsed = parseXml(argsXmlTag, ["file.diff.content"]) as ParsedXmlResult + // Try parsing with simplified schema (no content wrapper) + const parsed = parseXml(argsXmlTag, ["file.diff"]) as ParsedXmlResult const files = Array.isArray(parsed.file) ? parsed.file : [parsed.file].filter(Boolean) for (const file of files) { @@ -132,8 +133,19 @@ export async function applyDiffTool( let diffContent: string let startLine: number | undefined - diffContent = diff.content - startLine = diff.start_line ? parseInt(diff.start_line) : undefined + // For simplified format, diff is the content directly + // For legacy format, diff has content and start_line properties + if (typeof diff === "object" && diff.content) { + // Legacy format with content wrapper + diffContent = diff.content + startLine = diff.start_line ? parseInt(diff.start_line) : undefined + } else { + // New simplified format - diff is the content string directly + diffContent = String(diff) + // Extract start_line from the diff content if present + const startLineMatch = diffContent.match(/:start_line:\s*(\d+)/) + startLine = startLineMatch ? parseInt(startLineMatch[1]) : undefined + } operationsMap[filePath].diff.push({ content: diffContent, @@ -148,16 +160,17 @@ export async function applyDiffTool( 2. Missing required , , or tags 3. Invalid characters or encoding in the XML -Expected structure: - - - relative/path/to/file.ext - - diff content here - line number - - - +Expected structure (simplified): + + relative/path/to/file.ext + +<<<<<<< SEARCH +exact content to find +======= +replacement content +>>>>>>> REPLACE + + Original error: ${errorMessage}` cline.consecutiveMistakeCount++