Skip to content

Commit a7c73cf

Browse files
committed
Make write_file completely deterministic. No edit snippet
1 parent 004811b commit a7c73cf

File tree

20 files changed

+126
-1931
lines changed

20 files changed

+126
-1931
lines changed

.agents/types/tools.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ export interface ProposeWriteFileParams {
178178
path: string
179179
/** What the change is intended to do in only one sentence. */
180180
instructions: string
181-
/** Edit snippet to apply to the file. */
181+
/** Complete file content to write to the file. */
182182
content: string
183183
}
184184

@@ -319,14 +319,14 @@ export interface WebSearchParams {
319319
}
320320

321321
/**
322-
* Create or edit a file with the given content.
322+
* Create or overwrite a file with the given content.
323323
*/
324324
export interface WriteFileParams {
325325
/** Path to the file relative to the **project root** */
326326
path: string
327327
/** What the change is intended to do in only one sentence. */
328328
instructions: string
329-
/** Edit snippet to apply to the file. */
329+
/** Complete file content to write to the file. */
330330
content: string
331331
}
332332

agents/editor/best-of-n/editor-implementor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ OR for new files or major rewrites:
6464
"cb_tool_name": "propose_write_file",
6565
"path": "path/to/file",
6666
"instructions": "What the change does",
67-
"content": "Complete file content or edit snippet"
67+
"content": "Complete file content"
6868
}
6969
</codebuff_tool_call>
7070
${isGpt5 || isGemini

agents/editor/editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ OR for new files or major rewrites:
5656
"cb_tool_name": "write_file",
5757
"path": "path/to/file",
5858
"instructions": "What the change does",
59-
"content": "Complete file content or edit snippet"
59+
"content": "Complete file content"
6060
}
6161
</codebuff_tool_call>
6262

common/src/constants/paths.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export const STOP_MARKER = '[' + 'END]'
22
export const FIND_FILES_MARKER = '[' + 'FIND_FILES_PLEASE]'
3-
export const EXISTING_CODE_MARKER = '[[**REPLACE_WITH_EXISTING_CODE**]]'
43

54
// Directory where agent template override files are stored
65
export const AGENT_TEMPLATES_DIR = '.agents/'

common/src/tools/params/tool/write-file.ts

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,13 @@ const inputSchema = z
1616
instructions: z
1717
.string()
1818
.describe('What the change is intended to do in only one sentence.'),
19-
content: z.string().describe(`Edit snippet to apply to the file.`),
19+
content: z.string().describe(`Complete file content to write to the file.`),
2020
})
21-
.describe(`Create or edit a file with the given content.`)
21+
.describe(`Create or overwrite a file with the given content.`)
2222
const description = `
2323
Create or replace a file with the given content.
2424
25-
#### Edit Snippet
26-
27-
Format the \`content\` parameter with the entire content of the file or as an edit snippet that describes how you would like to modify the provided existing code.
28-
29-
You may abbreviate any sections of the code in your response that will remain the same with placeholder comments: "// ... existing code ...". Abbreviate as much as possible to save the user credits!
30-
31-
If you don't use any placeholder comments, the entire file will be replaced. E.g. don't write out a single function without using placeholder comments unless you want to replace the entire file with that function.
25+
Format the \`content\` parameter with the entire content of the file.
3226
3327
#### Additional Info
3428
@@ -50,28 +44,21 @@ ${$getNativeToolCallExampleString({
5044
endsAgentStep,
5145
})}
5246
53-
Example 2 - Editing with placeholder comments:
47+
Example 2 - Overwriting a file:
5448
${$getNativeToolCallExampleString({
5549
toolName,
5650
inputSchema,
5751
input: {
5852
path: 'foo.ts',
59-
instructions: 'Update foo and remove console.log',
60-
content: `// ... existing code ...
61-
62-
function foo() {
63-
console.log('foo');
64-
for (let i = 0; i < 10; i++) {
65-
console.log(i);
66-
}
67-
doSomething();
68-
69-
// Delete the console.log line from here
70-
71-
doSomethingElse();
53+
instructions: 'Update foo function',
54+
content: `function foo() {
55+
doSomethingNew();
7256
}
73-
74-
// ... existing code ...`,
57+
58+
function bar() {
59+
doSomethingOld();
60+
}
61+
`,
7562
},
7663
endsAgentStep,
7764
})}

common/src/util/__tests__/string.test.ts

Lines changed: 1 addition & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { describe, expect, it } from 'bun:test'
22

3-
import { EXISTING_CODE_MARKER } from '../../old-constants'
4-
import { pluralize, replaceNonStandardPlaceholderComments } from '../string'
3+
import { pluralize } from '../string'
54

65
describe('pluralize', () => {
76
it('should handle singular and plural cases correctly', () => {
@@ -238,90 +237,3 @@ describe('pluralize', () => {
238237
})
239238
})
240239

241-
describe('replaceNonStandardPlaceholderComments', () => {
242-
it('should replace C-style comments', () => {
243-
const input = `
244-
function example() {
245-
// ... some code ...
246-
console.log('Hello');
247-
// ... rest of the function ...
248-
}
249-
`
250-
const expected = `
251-
function example() {
252-
${EXISTING_CODE_MARKER}
253-
console.log('Hello');
254-
${EXISTING_CODE_MARKER}
255-
}
256-
`
257-
expect(
258-
replaceNonStandardPlaceholderComments(input, EXISTING_CODE_MARKER),
259-
).toBe(expected)
260-
})
261-
262-
it('should replace multi-line C-style comments', () => {
263-
const input = `
264-
function example() {
265-
/* ... some code ... */
266-
console.log('Hello');
267-
/* ... rest of the function ... */
268-
}
269-
`
270-
const expected = `
271-
function example() {
272-
${EXISTING_CODE_MARKER}
273-
console.log('Hello');
274-
${EXISTING_CODE_MARKER}
275-
}
276-
`
277-
expect(
278-
replaceNonStandardPlaceholderComments(input, EXISTING_CODE_MARKER),
279-
).toBe(expected)
280-
})
281-
282-
it('should replace Python-style comments', () => {
283-
const input = `
284-
def example():
285-
# ... some code ...
286-
print('Hello')
287-
# ... rest of the function ...
288-
`
289-
const expected = `
290-
def example():
291-
${EXISTING_CODE_MARKER}
292-
print('Hello')
293-
${EXISTING_CODE_MARKER}
294-
`
295-
expect(
296-
replaceNonStandardPlaceholderComments(input, EXISTING_CODE_MARKER),
297-
).toBe(expected)
298-
})
299-
300-
it('should replace JSX comments', () => {
301-
const input = `
302-
function Example() {
303-
return (
304-
<div>
305-
{/* ... existing code ... */}
306-
<p>Hello, World!</p>
307-
{/* ...rest of component... */}
308-
</div>
309-
);
310-
}
311-
`
312-
const expected = `
313-
function Example() {
314-
return (
315-
<div>
316-
${EXISTING_CODE_MARKER}
317-
<p>Hello, World!</p>
318-
${EXISTING_CODE_MARKER}
319-
</div>
320-
);
321-
}
322-
`
323-
expect(
324-
replaceNonStandardPlaceholderComments(input, EXISTING_CODE_MARKER),
325-
).toBe(expected)
326-
})
327-
})

common/src/util/string.ts

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -45,63 +45,6 @@ export const truncateStringWithMessage = ({
4545
*/
4646
export const isWhitespace = (character: string) => /\s/.test(character)
4747

48-
export const replaceNonStandardPlaceholderComments = (
49-
content: string,
50-
replacement: string,
51-
): string => {
52-
const commentPatterns = [
53-
// JSX comments (match this first)
54-
{
55-
regex:
56-
/{\s*\/\*\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?\s*\*\/\s*}/gi,
57-
placeholder: replacement,
58-
},
59-
// C-style comments (C, C++, Java, JavaScript, TypeScript, etc.)
60-
{
61-
regex:
62-
/\/\/\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?/gi,
63-
placeholder: replacement,
64-
},
65-
{
66-
regex:
67-
/\/\*\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?\s*\*\//gi,
68-
placeholder: replacement,
69-
},
70-
// Python, Ruby, R comments
71-
{
72-
regex:
73-
/#\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?/gi,
74-
placeholder: replacement,
75-
},
76-
// HTML-style comments
77-
{
78-
regex:
79-
/<!--\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?\s*-->/gi,
80-
placeholder: replacement,
81-
},
82-
// SQL, Haskell, Lua comments
83-
{
84-
regex:
85-
/--\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?/gi,
86-
placeholder: replacement,
87-
},
88-
// MATLAB comments
89-
{
90-
regex:
91-
/%\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\s*\.{3})?/gi,
92-
placeholder: replacement,
93-
},
94-
]
95-
96-
let updatedContent = content
97-
98-
for (const { regex, placeholder } of commentPatterns) {
99-
updatedContent = updatedContent.replaceAll(regex, placeholder)
100-
}
101-
102-
return updatedContent
103-
}
104-
10548
export const randBoolFromStr = (str: string) => {
10649
return sumBy(str.split(''), (char) => char.charCodeAt(0)) % 2 === 0
10750
}
@@ -352,37 +295,6 @@ export const safeReplace = (
352295
return content.replace(searchStr, escapedReplaceStr)
353296
}
354297

355-
export const hasLazyEdit = (content: string) => {
356-
const cleanedContent = content.toLowerCase().trim()
357-
return (
358-
cleanedContent.includes('... existing code ...') ||
359-
cleanedContent.includes('// rest of the') ||
360-
cleanedContent.includes('# rest of the') ||
361-
// Match various comment styles with ellipsis and specific words
362-
/\/\/\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?/.test(
363-
cleanedContent,
364-
) || // C-style single line
365-
/\/\*\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?\s*\*\//.test(
366-
cleanedContent,
367-
) || // C-style multi-line
368-
/#\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?/.test(
369-
cleanedContent,
370-
) || // Python/Ruby style
371-
/<!--\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?\s*-->/.test(
372-
cleanedContent,
373-
) || // HTML style
374-
/--\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?/.test(
375-
cleanedContent,
376-
) || // SQL/Haskell style
377-
/%\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?/.test(
378-
cleanedContent,
379-
) || // MATLAB style
380-
/{\s*\/\*\s*\.{3}.*(?:rest|unchanged|keep|file|existing|some).*(?:\.{3})?\s*\*\/\s*}/.test(
381-
cleanedContent,
382-
) // JSX style
383-
)
384-
}
385-
386298
/**
387299
* Extracts a JSON field from a string, transforms it, and puts it back.
388300
* Handles both array and object JSON values.

packages/agent-runtime/src/__tests__/fast-rewrite.test.ts

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)