diff --git a/src/extension/prompts/node/agent/agentInstructions.tsx b/src/extension/prompts/node/agent/agentInstructions.tsx index 1e7039256..cbd26e139 100644 --- a/src/extension/prompts/node/agent/agentInstructions.tsx +++ b/src/extension/prompts/node/agent/agentInstructions.tsx @@ -327,24 +327,27 @@ export class SweBenchAgentPrompt extends PromptElement Before using {ToolName.ReplaceString} tool, you must use {ToolName.ReadFile} tool to understand the file's contents and context you want to edit
To make a file edit, provide the following:
1. filePath: The absolute path to the file to modify (must be absolute, not relative)
- 2. oldString: The text to replace (must be unique within the file, and must match the file contents exactly, including all whitespace and indentation)
+ 2. oldString: The text to replace (must be unique within the file, and must match the file contents exactly, including all whitespace, indentation, existing escaping, and unicode characters)
3. newString: The edited text to replace the oldString
The tool will only replace ONE occurrence of oldString with newString in the specified file.
CRITICAL REQUIREMENTS FOR USING THIS TOOL:
1. UNIQUENESS: The oldString MUST uniquely identify the specific instance you want to change. This means:
- - Include AT LEAST 3-5 lines of context BEFORE the change point
- - Include AT LEAST 3-5 lines of context AFTER the change point
- - Include all whitespace, indentation, and surrounding code exactly as it appears in the file
+ - Include AT LEAST 3-5 lines of exact current context BEFORE the change point
+ - Include AT LEAST 3-5 lines of exact current context AFTER the change point
+ - Include all whitespace, indentation, existing escaping, unicode characters, and surrounding code exactly as it appears in the file
2. SINGLE INSTANCE: This tool can only change ONE instance at a time. If you need to change multiple instances:
- Make separate calls to this tool for each instance
- - Each call must uniquely identify its specific instance using extensive context
+ - Each call must uniquely identify its specific instance using extensive context and exact lines from {ToolName.ReadFile}
3. VERIFICATION: Before using this tool:
- Check how many instances of the target text exist in the file
- If multiple instances exist, gather enough context to uniquely identify each one
- Plan separate tool calls for each instance
+ WARNING: {ToolName.ReplaceString} calls will update the current content of the file.
+ - Any subsequent overlapping {ToolName.ReplaceString} calls require {ToolName.ReadFile} tool call, otherwise the tool will fail
WARNING: If you do not follow these requirements:
- The tool will fail if oldString matches multiple locations
- - The tool will fail if oldString doesn't match exactly (including whitespace)
+ - The tool will fail if oldString doesn't match exactly the current content from the file character-for-character (including indentation, whitespace, existing escaping, exact same unicode characters)
+ - The tool will fail if oldString matches newString exactly
- You may change the wrong instance if you don't include enough context
When making edits:
- Ensure the edit results in idiomatic, correct code
@@ -493,3 +496,20 @@ class TodoListToolInstructions extends PromptElement { ; } } + +export class ReplaceStringInFileToolInstructions extends PromptElement { + render() { + return + When using the {ToolName.ReplaceString} tool:
+ - Include 3-5 lines of the exact current content from the file, character-for-character (including indentation, whitespace, existing escaping, exact same unicode characters), before and after the string you want to replace, to make it unambiguous which part of the file should be edited.
+ - Never construct or assume existing content, it must come from the file. You must use the {ToolName.ReadFile} tool to understand the file's existing content and content you want to edit.
+ WARNING: {ToolName.ReplaceString} calls will update the current content of the file.
+ - Any subsequent overlapping {ToolName.ReplaceString} calls require {ToolName.ReadFile} tool call, otherwise the tool will fail
+ WARNING: If you do not follow these requirements:
+ - The tool will fail if oldString matches multiple locations
+ - The tool will fail if oldString doesn't match exactly the current content from the file character-for-character (including indentation, whitespace, existing escaping, exact same unicode characters)
+ - The tool will fail if oldString matches newString exactly
+ - You may change the wrong instance if you don't include enough context +
; + } +} diff --git a/src/extension/prompts/node/agent/agentPrompt.tsx b/src/extension/prompts/node/agent/agentPrompt.tsx index bfea5b797..cd59fe4f2 100644 --- a/src/extension/prompts/node/agent/agentPrompt.tsx +++ b/src/extension/prompts/node/agent/agentPrompt.tsx @@ -44,7 +44,7 @@ import { UserPreferences } from '../panel/preferences'; import { ChatToolCalls } from '../panel/toolCalling'; import { MultirootWorkspaceStructure } from '../panel/workspace/workspaceStructure'; import { AgentConversationHistory } from './agentConversationHistory'; -import { DefaultAgentPrompt, SweBenchAgentPrompt } from './agentInstructions'; +import { DefaultAgentPrompt, ReplaceStringInFileToolInstructions, SweBenchAgentPrompt } from './agentInstructions'; import { SummarizedConversationHistory } from './summarizedConversationHistory'; export interface AgentPromptProps extends GenericBasePromptElementProps { @@ -626,7 +626,7 @@ export function getEditingReminder(hasEditFileTool: boolean, hasReplaceStringToo lines.push(<>When using the {ToolName.EditFile} tool, avoid repeating existing code, instead use a line comment with \`{EXISTING_CODE_MARKER}\` to represent regions of unchanged code.
); } if (hasReplaceStringTool) { - lines.push(<>When using the {ToolName.ReplaceString} tool, include 3-5 lines of unchanged code before and after the string you want to replace, to make it unambiguous which part of the file should be edited.
); + lines.push(); } if (hasEditFileTool && hasReplaceStringTool) { if (useStrongReplaceStringHint) { diff --git a/src/extension/prompts/node/agent/test/__snapshots__/agentPrompt.spec.tsx.snap b/src/extension/prompts/node/agent/test/__snapshots__/agentPrompt.spec.tsx.snap index 14c5f6fc9..6f44ef979 100644 --- a/src/extension/prompts/node/agent/test/__snapshots__/agentPrompt.spec.tsx.snap +++ b/src/extension/prompts/node/agent/test/__snapshots__/agentPrompt.spec.tsx.snap @@ -256,7 +256,18 @@ copilot_cache_control: { type: 'ephemeral' } When using the insert_edit_into_file tool, avoid repeating existing code, instead use a line comment with /\`...existing code.../\` to represent regions of unchanged code. -When using the replace_string_in_file tool, include 3-5 lines of unchanged code before and after the string you want to replace, to make it unambiguous which part of the file should be edited. + +When using the replace_string_in_file tool: +- Include 3-5 lines of the exact current content from the file, character-for-character (including indentation, whitespace, existing escaping, exact same unicode characters), before and after the string you want to replace, to make it unambiguous which part of the file should be edited. +- Never construct or assume existing content, it must come from the file. You must use the read_file tool to understand the file's existing content and content you want to edit. +WARNING: replace_string_in_file calls will update the current content of the file. +- Any subsequent overlapping replace_string_in_file calls require read_file tool call, otherwise the tool will fail +WARNING: If you do not follow these requirements: +- The tool will fail if oldString matches multiple locations +- The tool will fail if oldString doesn't match exactly the current content from the file character-for-character (including indentation, whitespace, existing escaping, exact same unicode characters) +- The tool will fail if oldString matches newString exactly +- You may change the wrong instance if you don't include enough context + It is much faster to edit using the replace_string_in_file tool. Prefer replace_string_in_file for making edits and only fall back to insert_edit_into_file if it fails.