Skip to content

Commit d6dc21a

Browse files
committed
Various prompt tweaks
1 parent 33d4efe commit d6dc21a

31 files changed

+259
-610
lines changed

src/core/assistant-message/presentAssistantMessage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ export async function presentAssistantMessage(cline: Task) {
189189
}
190190
return `[${block.name}]`
191191
case "search_files":
192-
return `[${block.name} for '${block.params.regex}'${
193-
block.params.file_pattern ? ` in '${block.params.file_pattern}'` : ""
192+
return `[${block.name} for '${block.params.content_regex ?? ".*"}'${
193+
block.params.file_glob ? ` in '${block.params.file_glob}'` : ""
194194
}]`
195195
case "insert_content":
196196
return `[${block.name} for '${block.params.path}']`

src/core/diff/strategies/multi-file-search-replace.ts

Lines changed: 17 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -93,141 +93,35 @@ export class MultiFileSearchReplaceDiffStrategy implements DiffStrategy {
9393
getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
9494
return `## apply_diff
9595
96-
Description: Request to apply PRECISE, TARGETED modifications to one or more files by searching for specific sections of content and replacing them. This tool is for SURGICAL EDITS ONLY - specific changes to existing code. This tool supports both single-file and multi-file operations, allowing you to make changes across multiple files in a single request.
96+
Description: Request to apply PRECISE, TARGETED modifications to one or more files by searching for specific sections of content and replacing them.
97+
This tool is for SURGICAL EDITS ONLY - specific changes to existing code. This tool supports both single-file and multi-file operations.
9798
98-
**IMPORTANT: You MUST use multiple files in a single operation whenever possible to maximize efficiency and minimize back-and-forth.**
99-
100-
You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently.
101-
102-
The SEARCH section must exactly match existing content including whitespace and indentation.
99+
The SEARCH section must exactly match existing content including whitespace and indentation. The content must be wrapped in a CDATA section to handle special characters.
103100
If you're not confident in the exact content to search for, use the read_file tool first to get the exact content.
104101
When applying the diffs, be extra careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file.
105-
ALWAYS make as many changes in a single 'apply_diff' request as possible using multiple SEARCH/REPLACE blocks
106-
107-
Parameters:
108-
- args: Contains one or more file elements, where each file contains:
109-
- path: (required) The path of the file to modify (relative to the current workspace directory ${args.cwd})
110-
- diff: (required) One or more diff elements containing:
111-
- content: (required) The search/replace block defining the changes.
112-
- start_line: (required) The line number of original content where the search block starts.
113-
114-
Diff format:
115-
\`\`\`
116-
<<<<<<< SEARCH
117-
:start_line: (required) The line number of original content where the search block starts.
118-
-------
119-
[exact content to find including whitespace]
120-
=======
121-
[new content to replace with]
122-
>>>>>>> REPLACE
123-
\`\`\`
124-
125-
Example:
126-
127-
Original file:
128-
\`\`\`
129-
1 | def calculate_total(items):
130-
2 | total = 0
131-
3 | for item in items:
132-
4 | total += item
133-
5 | return total
134-
\`\`\`
102+
You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently.
135103
136-
Search/Replace content:
137-
<apply_diff>
138-
<args>
139-
<file>
140-
<path>eg.file.py</path>
141-
<diff>
142-
<content><![CDATA[
143-
<<<<<<< SEARCH
144-
def calculate_total(items):
145-
total = 0
146-
for item in items:
147-
total += item
148-
return total
149-
=======
150-
def calculate_total(items):
151-
"""Calculate total with 10% markup"""
152-
return sum(item * 1.1 for item in items)
153-
>>>>>>> REPLACE
154-
]]></content>
155-
</diff>
156-
</file>
157-
</args>
158-
</apply_diff>
104+
XML tool Syntax:
159105
160-
Search/Replace content with multi edits across multiple files:
161106
<apply_diff>
162107
<args>
163108
<file>
164-
<path>eg.file.py</path>
165-
<diff>
166-
<content><![CDATA[
167-
<<<<<<< SEARCH
168-
def calculate_total(items):
169-
sum = 0
170-
=======
171-
def calculate_sum(items):
172-
sum = 0
173-
>>>>>>> REPLACE
174-
]]></content>
175-
</diff>
176-
<diff>
177-
<content><![CDATA[
109+
<path>(REQUIRED!) relative path to file</path>
110+
<diff>
111+
<content>
112+
<![CDATA[
178113
<<<<<<< SEARCH
179-
total += item
180-
return total
181-
=======
182-
sum += item
183-
return sum
184-
>>>>>>> REPLACE
185-
]]></content>
186-
</diff>
187-
</file>
188-
<file>
189-
<path>eg.file2.py</path>
190-
<diff>
191-
<content><![CDATA[
192-
<<<<<<< SEARCH
193-
def greet(name):
194-
return "Hello " + name
114+
:start_line: (required) The line number of original content where the search block starts.
115+
-------
116+
[exact content to find including whitespace]
195117
=======
196-
def greet(name):
197-
return f"Hello {name}!"
118+
[new content to replace with]
198119
>>>>>>> REPLACE
199-
]]></content>
200-
</diff>
201-
</file>
202-
</args>
203-
</apply_diff>
204-
205-
206-
Usage:
207-
<apply_diff>
208-
<args>
209-
<file>
210-
<path>File path here</path>
211-
<diff>
212-
<content>
213-
Your search/replace content here
214-
You can use multi search/replace block in one diff block, but make sure to include the line numbers for each block.
215-
Only use a single line of '=======' between search and replacement content, because multiple '=======' will corrupt the file.
216-
</content>
217-
<start_line>1</start_line>
218-
</diff>
219-
</file>
220-
<file>
221-
<path>Another file path</path>
222-
<diff>
223-
<content>
224-
Another search/replace content here
225-
You can apply changes to multiple files in a single request.
226-
Each file requires its own path, start_line, and diff elements.
227-
</content>
228-
<start_line>5</start_line>
229-
</diff>
120+
]]>
121+
</content>
122+
</diff>
230123
</file>
124+
<file>(optional) Multiple file edits can be appended here with the same format</file>
231125
</args>
232126
</apply_diff>`
233127
}

src/core/diff/strategies/multi-search-replace.ts

Lines changed: 21 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -92,92 +92,39 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy {
9292

9393
getToolDescription(args: { cwd: string; toolOptions?: { [key: string]: string } }): string {
9494
return `## apply_diff
95-
Description: Request to apply PRECISE, TARGETED modifications to an existing file by searching for specific sections of content and replacing them. This tool is for SURGICAL EDITS ONLY - specific changes to existing code.
96-
You can perform multiple distinct search and replace operations within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter. This is the preferred way to make several targeted changes efficiently.
97-
The SEARCH section must exactly match existing content including whitespace and indentation.
98-
If you're not confident in the exact content to search for, use the read_file tool first to get the exact content.
99-
When applying the diffs, be extra careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file.
100-
ALWAYS make as many changes in a single 'apply_diff' request as possible using multiple SEARCH/REPLACE blocks
95+
Description: Apply modifications to an existing file by searching for specific sections of content and replacing them.
10196
10297
Parameters:
103-
- path: (required) The path of the file to modify (relative to the current workspace directory ${args.cwd})
104-
- diff: (required) The search/replace block defining the changes.
98+
path (REQUIRED): relative path to file.
99+
diff (REQUIRED): search and replace blocks with start line.
105100
106-
Diff format:
107-
\`\`\`
101+
Syntax:
102+
<apply_diff>
103+
<path>src/module/index.tsx</path>
104+
<diff><![CDATA[
108105
<<<<<<< SEARCH
109106
:start_line: (required) The line number of original content where the search block starts.
110107
-------
111-
[exact content to find including whitespace]
112-
=======
113-
[new content to replace with]
114-
>>>>>>> REPLACE
115-
116-
\`\`\`
117-
118-
119-
Example:
120-
121-
Original file:
122-
\`\`\`
123-
1 | def calculate_total(items):
124-
2 | total = 0
125-
3 | for item in items:
126-
4 | total += item
127-
5 | return total
128-
\`\`\`
129-
130-
Search/Replace content:
131-
\`\`\`
132-
<<<<<<< SEARCH
133-
:start_line:1
134-
-------
135-
def calculate_total(items):
136-
total = 0
137-
for item in items:
138-
total += item
139-
return total
108+
[exact content of the first search block to find including whitespace]
140109
=======
141-
def calculate_total(items):
142-
"""Calculate total with 10% markup"""
143-
return sum(item * 1.1 for item in items)
110+
[new content to replace the first block with]
144111
>>>>>>> REPLACE
145-
146-
\`\`\`
147-
148-
Search/Replace content with multiple edits:
149-
\`\`\`
150-
<<<<<<< SEARCH
151-
:start_line:1
152-
-------
153-
def calculate_total(items):
154-
sum = 0
155-
=======
156-
def calculate_sum(items):
157-
sum = 0
158-
>>>>>>> REPLACE
159-
160112
<<<<<<< SEARCH
161-
:start_line:4
113+
:start_line: (required) The line number of original content where the next search block starts.
162114
-------
163-
total += item
164-
return total
115+
[exact content to the next search block to find, showcasing the possibility of doing multiple edits]
165116
=======
166-
sum += item
167-
return sum
117+
[new content to replace the next block with]
168118
>>>>>>> REPLACE
169-
\`\`\`
170-
171-
172-
Usage:
173-
<apply_diff>
174-
<path>File path here</path>
175-
<diff>
176-
Your search/replace content here
177-
You can use multi search/replace block in one diff block, but make sure to include the line numbers for each block.
178-
Only use a single line of '=======' between search and replacement content, because multiple '=======' will corrupt the file.
179-
</diff>
180-
</apply_diff>`
119+
]]></diff>
120+
</apply_diff>
121+
122+
Remarks:
123+
- You can (and prefer to) make one or more edits to a file within a single \`apply_diff\` call by providing multiple SEARCH/REPLACE blocks in the \`diff\` parameter.
124+
- The SEARCH section must exactly match existing content including whitespace and indentation.
125+
- Be careful to remember to change any closing brackets or other syntax that may be affected by the diff farther down in the file.
126+
- The entire diff parameter should be wrapped in CDATA open and closing tags to handle special characters.
127+
`
181128
}
182129

183130
private unescapeMarkers(content: string): string {

src/core/environment/getEnvironmentDetails.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ export async function getEnvironmentDetails(cline: Task, includeFileDetails: boo
238238
}
239239

240240
if (includeFileDetails) {
241-
details += `\n\n# Current Workspace Directory (${cline.cwd.toPosix()}) Files\n`
241+
details += `\n\n# Current workspace folder structure (${cline.cwd.toPosix()})\n`
242242
const isDesktop = arePathsEqual(cline.cwd, path.join(os.homedir(), "Desktop"))
243243

244244
if (isDesktop) {

src/core/mentions/index.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,7 @@ export async function parseMentions(
129129
return `'${mention}' (see below for site content)`
130130
} else if (mention.startsWith("/")) {
131131
const mentionPath = mention.slice(1)
132-
return mentionPath.endsWith("/")
133-
? `'${mentionPath}' (see below for folder content)`
134-
: `'${mentionPath}' (see below for file content)`
132+
return mentionPath.endsWith("/") ? `'${mentionPath}' (see below for folder content)` : `'${mentionPath}'` // (see below for file content)`
135133
} else if (mention === "problems") {
136134
return `Workspace Problems (see below for diagnostics)`
137135
} else if (mention === "git-changes") {
@@ -198,10 +196,11 @@ export async function parseMentions(
198196
if (mention.endsWith("/")) {
199197
parsedText += `\n\n<folder_content path="${mentionPath}">\n${content}\n</folder_content>`
200198
} else {
201-
parsedText += `\n\n<file_content path="${mentionPath}">\n${content}\n</file_content>`
202-
if (fileContextTracker) {
203-
await fileContextTracker.trackFileContext(mentionPath, "file_mentioned")
204-
}
199+
// Don't include mentioned file contents, LLM almost always re-reads it anyway.
200+
// parsedText += `\n\n<file_content path="${mentionPath}">\n${content}\n</file_content>`
201+
// if (fileContextTracker) {
202+
// await fileContextTracker.trackFileContext(mentionPath, "file_mentioned")
203+
// }
205204
}
206205
} catch (error) {
207206
if (mention.endsWith("/")) {

src/core/prompts/responses.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as path from "path"
33
import * as diff from "diff"
44
import { RooIgnoreController, LOCK_TEXT_SYMBOL } from "../ignore/RooIgnoreController"
55
import { RooProtectedController } from "../protect/RooProtectedController"
6+
import { MultiSearchReplaceDiffStrategy } from "../diff/strategies/multi-search-replace"
67

78
export const formatResponse = {
89
toolDenied: () => `The user denied this operation.`,
@@ -33,8 +34,20 @@ Otherwise, if you have not completed the task and do not need additional informa
3334
tooManyMistakes: (feedback?: string) =>
3435
`You seem to be having trouble proceeding. The user has provided the following feedback to help guide you:\n<feedback>\n${feedback}\n</feedback>`,
3536

36-
missingToolParameterError: (paramName: string) =>
37-
`Missing value for required parameter '${paramName}'. Please retry with complete response.\n\n${toolUseInstructionsReminder}`,
37+
missingToolParameterError: (paramName: string, toolName?: string) => {
38+
let msg = `Missing value for required parameter '${paramName}'. Please retry with complete response.\n`
39+
switch (toolName) {
40+
case "apply_diff": {
41+
const tool = new MultiSearchReplaceDiffStrategy()
42+
msg += tool.getToolDescription({ cwd: "" })
43+
break
44+
}
45+
default:
46+
msg += `\n${toolUseInstructionsReminder}`
47+
break
48+
}
49+
return msg
50+
},
3851

3952
lineCountTruncationError: (actualLineCount: number, isNewFile: boolean, diffStrategyEnabled: boolean = false) => {
4053
const truncationMessage = `Note: Your response may have been truncated because it exceeded your output limit. You wrote ${actualLineCount} lines of content, but the line_count parameter was either missing or not included in your response.`
@@ -158,9 +171,9 @@ Otherwise, if you have not completed the task and do not need additional informa
158171
if (didHitLimit) {
159172
return `${rooIgnoreParsed.join(
160173
"\n",
161-
)}\n\n(File list truncated. Use list_files on specific subdirectories if you need to explore further.)`
174+
)}\n\n(Folder list truncated and incomplete. Use search_files or list_files on specific subdirectories if you need to explore further.)`
162175
} else if (rooIgnoreParsed.length === 0 || (rooIgnoreParsed.length === 1 && rooIgnoreParsed[0] === "")) {
163-
return "No files found."
176+
return "No folders found."
164177
} else {
165178
return rooIgnoreParsed.join("\n")
166179
}

0 commit comments

Comments
 (0)