Skip to content

Commit 203f805

Browse files
pashpashpashCline Evaluation
andauthored
Claude 4 - experimental flag - defaults to classic function calling with some minor changes to system prompt (RooCodeInc#3994)
* adding modularized flag for new claude4 experimental tools, default OFF * diff.ts * responses.ts * system.ts * tests and prompt * forgot some chars --------- Co-authored-by: Cline Evaluation <[email protected]>
1 parent c91ec4c commit 203f805

File tree

9 files changed

+1038
-315
lines changed

9 files changed

+1038
-315
lines changed

src/core/assistant-message/diff.test.ts

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,128 +11,128 @@ describe("constructNewFileContent", () => {
1111
{
1212
name: "empty file",
1313
original: "",
14-
diff: `<<<<<<< SEARCH
14+
diff: `------- SEARCH
1515
=======
1616
new content
17-
>>>>>>> REPLACE`,
17+
+++++++ REPLACE`,
1818
expected: "new content\n",
1919
isFinal: true,
2020
},
2121
{
2222
name: "full file replacement",
2323
original: "old content",
24-
diff: `<<<<<<< SEARCH
24+
diff: `------- SEARCH
2525
=======
2626
new content
27-
>>>>>>> REPLACE`,
27+
+++++++ REPLACE`,
2828
expected: "new content\n",
2929
isFinal: true,
3030
},
3131
{
3232
name: "exact match replacement",
3333
original: "line1\nline2\nline3",
34-
diff: `<<<<<<< SEARCH
34+
diff: `------- SEARCH
3535
line2
3636
=======
3737
replaced
38-
>>>>>>> REPLACE`,
38+
+++++++ REPLACE`,
3939
expected: "line1\nreplaced\nline3",
4040
isFinal: true,
4141
},
4242
{
4343
name: "line-trimmed match replacement",
4444
original: "line1\n line2 \nline3",
45-
diff: `<<<<<<< SEARCH
45+
diff: `------- SEARCH
4646
line2
4747
=======
4848
replaced
49-
>>>>>>> REPLACE`,
49+
+++++++ REPLACE`,
5050
expected: "line1\nreplaced\nline3",
5151
isFinal: true,
5252
},
5353
{
5454
name: "block anchor match replacement",
5555
original: "line1\nstart\nmiddle\nend\nline5",
56-
diff: `<<<<<<< SEARCH
56+
diff: `------- SEARCH
5757
start
5858
middle
5959
end
6060
=======
6161
replaced
62-
>>>>>>> REPLACE`,
62+
+++++++ REPLACE`,
6363
expected: "line1\nreplaced\nline5",
6464
isFinal: true,
6565
},
6666
{
6767
name: "incremental processing",
6868
original: "line1\nline2\nline3",
6969
diff: [
70-
`<<<<<<< SEARCH
70+
`------- SEARCH
7171
line2
7272
=======`,
7373
"replaced\n",
74-
">>>>>>> REPLACE",
74+
"+++++++ REPLACE",
7575
].join("\n"),
7676
expected: "line1\nreplaced\n\nline3",
7777
isFinal: true,
7878
},
7979
{
8080
name: "final chunk with remaining content",
8181
original: "line1\nline2\nline3",
82-
diff: `<<<<<<< SEARCH
82+
diff: `------- SEARCH
8383
line2
8484
=======
8585
replaced
86-
>>>>>>> REPLACE`,
86+
+++++++ REPLACE`,
8787
expected: "line1\nreplaced\nline3",
8888
isFinal: true,
8989
},
9090
{
9191
name: "multiple ordered replacements",
9292
original: "First\nSecond\nThird\nFourth",
93-
diff: `<<<<<<< SEARCH
93+
diff: `------- SEARCH
9494
First
9595
=======
9696
1st
97-
>>>>>>> REPLACE
97+
+++++++ REPLACE
9898
99-
<<<<<<< SEARCH
99+
------- SEARCH
100100
Third
101101
=======
102102
3rd
103-
>>>>>>> REPLACE`,
103+
+++++++ REPLACE`,
104104
expected: "1st\nSecond\n3rd\nFourth",
105105
isFinal: true,
106106
},
107107
{
108108
name: "replace then delete",
109109
original: "line1\nline2\nline3\nline4",
110-
diff: `<<<<<<< SEARCH
110+
diff: `------- SEARCH
111111
line2
112112
=======
113113
replaced
114-
>>>>>>> REPLACE
114+
+++++++ REPLACE
115115
116-
<<<<<<< SEARCH
116+
------- SEARCH
117117
line4
118118
=======
119-
>>>>>>> REPLACE`,
119+
+++++++ REPLACE`,
120120
expected: "line1\nreplaced\nline3\n",
121121
isFinal: true,
122122
},
123123
{
124124
name: "delete then replace",
125125
original: "line1\nline2\nline3\nline4",
126-
diff: `<<<<<<< SEARCH
126+
diff: `------- SEARCH
127127
line1
128128
=======
129-
>>>>>>> REPLACE
129+
+++++++ REPLACE
130130
131-
<<<<<<< SEARCH
131+
------- SEARCH
132132
line3
133133
=======
134134
replaced
135-
>>>>>>> REPLACE`,
135+
+++++++ REPLACE`,
136136
expected: "line2\nreplaced\nline4",
137137
isFinal: true,
138138
},
@@ -155,11 +155,11 @@ replaced
155155

156156
it("should throw error when no match found", async () => {
157157
const original = "line1\nline2\nline3"
158-
const diff = `<<<<<<< SEARCH
158+
const diff = `------- SEARCH
159159
non-existent
160160
=======
161161
replaced
162-
>>>>>>> REPLACE`
162+
+++++++ REPLACE`
163163

164164
try {
165165
await cnfc(diff, original, true)

src/core/assistant-message/diff.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
const SEARCH_BLOCK_START = "------- SEARCH"
2+
const SEARCH_BLOCK_END = "======="
3+
const REPLACE_BLOCK_END = "+++++++ REPLACE"
4+
5+
const SEARCH_BLOCK_CHAR = "-"
6+
const REPLACE_BLOCK_CHAR = "+"
7+
18
/**
29
* Attempts a line-trimmed fallback match for the given search content in the original content.
310
* It tries to match `searchContent` lines against a block of lines in `originalContent` starting
@@ -150,11 +157,11 @@ function blockAnchorFallbackMatch(originalContent: string, searchContent: string
150157
*
151158
* The diff format is a custom structure that uses three markers to define changes:
152159
*
153-
* <<<<<<< SEARCH
160+
* ------- SEARCH
154161
* [Exact content to find in the original file]
155162
* =======
156163
* [Content to replace with]
157-
* >>>>>>> REPLACE
164+
* +++++++ REPLACE
158165
*
159166
* Behavior and Assumptions:
160167
* 1. The file is processed chunk-by-chunk. Each chunk of `diffContent` may contain
@@ -243,23 +250,23 @@ async function constructNewFileContentV1(diffContent: string, originalContent: s
243250
const lastLine = lines[lines.length - 1]
244251
if (
245252
lines.length > 0 &&
246-
(lastLine.startsWith("<") || lastLine.startsWith("=") || lastLine.startsWith(">")) &&
247-
lastLine !== "<<<<<<< SEARCH" &&
248-
lastLine !== "=======" &&
249-
lastLine !== ">>>>>>> REPLACE"
253+
(lastLine.startsWith(SEARCH_BLOCK_CHAR) || lastLine.startsWith("=") || lastLine.startsWith(REPLACE_BLOCK_CHAR)) &&
254+
lastLine !== SEARCH_BLOCK_START &&
255+
lastLine !== SEARCH_BLOCK_END &&
256+
lastLine !== REPLACE_BLOCK_END
250257
) {
251258
lines.pop()
252259
}
253260

254261
for (const line of lines) {
255-
if (line === "<<<<<<< SEARCH") {
262+
if (line === SEARCH_BLOCK_START) {
256263
inSearch = true
257264
currentSearchContent = ""
258265
currentReplaceContent = ""
259266
continue
260267
}
261268

262-
if (line === "=======") {
269+
if (line === SEARCH_BLOCK_END) {
263270
inSearch = false
264271
inReplace = true
265272

@@ -320,7 +327,7 @@ async function constructNewFileContentV1(diffContent: string, originalContent: s
320327
continue
321328
}
322329

323-
if (line === ">>>>>>> REPLACE") {
330+
if (line === REPLACE_BLOCK_END) {
324331
// Finished one replace block
325332

326333
// // Remove the artificially added linebreak in the last line of the REPLACE block
@@ -480,7 +487,7 @@ class NewFileContentConstructor {
480487
pendingNonStandardLineLimit: number,
481488
): number {
482489
let removeLineCount = 0
483-
if (line === "<<<<<<< SEARCH") {
490+
if (line === SEARCH_BLOCK_START) {
484491
removeLineCount = this.trimPendingNonStandardTrailingEmptyLines(pendingNonStandardLineLimit)
485492
if (removeLineCount > 0) {
486493
pendingNonStandardLineLimit = pendingNonStandardLineLimit - removeLineCount
@@ -490,15 +497,15 @@ class NewFileContentConstructor {
490497
canWritependingNonStandardLines && (this.pendingNonStandardLines.length = 0)
491498
}
492499
this.activateSearchState()
493-
} else if (line === "=======") {
500+
} else if (line === SEARCH_BLOCK_END) {
494501
// 校验非标内容
495502
if (!this.isSearchingActive()) {
496503
this.tryFixSearchBlock(pendingNonStandardLineLimit)
497504
canWritependingNonStandardLines && (this.pendingNonStandardLines.length = 0)
498505
}
499506
this.activateReplaceState()
500507
this.beforeReplace()
501-
} else if (line === ">>>>>>> REPLACE") {
508+
} else if (line === REPLACE_BLOCK_END) {
502509
if (!this.isReplacingActive()) {
503510
this.tryFixReplaceBlock(pendingNonStandardLineLimit)
504511
canWritependingNonStandardLines && (this.pendingNonStandardLines.length = 0)
@@ -606,11 +613,11 @@ class NewFileContentConstructor {
606613
if (!lineLimit) {
607614
throw new Error("Invalid SEARCH/REPLACE block structure - no lines available to process")
608615
}
609-
let searchTagRegexp = /^[<]{3,} SEARCH$/
616+
let searchTagRegexp = /^[-]{3,} SEARCH$/
610617
const searchTagIndex = this.findLastMatchingLineIndex(searchTagRegexp, lineLimit)
611618
if (searchTagIndex !== -1) {
612619
let fixLines = this.pendingNonStandardLines.slice(searchTagIndex, lineLimit)
613-
fixLines[0] = "<<<<<<< SEARCH"
620+
fixLines[0] = SEARCH_BLOCK_START
614621
for (const line of fixLines) {
615622
removeLineCount += this.internalProcessLine(line, false, searchTagIndex)
616623
}
@@ -638,7 +645,7 @@ class NewFileContentConstructor {
638645
// removeLineCount += this.tryFixSearchBlock(replaceBeginTagIndex)
639646
// }
640647
let fixLines = this.pendingNonStandardLines.slice(replaceBeginTagIndex - removeLineCount, lineLimit - removeLineCount)
641-
fixLines[0] = "======="
648+
fixLines[0] = SEARCH_BLOCK_END
642649
for (const line of fixLines) {
643650
removeLineCount += this.internalProcessLine(line, false, replaceBeginTagIndex - removeLineCount)
644651
}
@@ -657,7 +664,7 @@ class NewFileContentConstructor {
657664
throw new Error()
658665
}
659666

660-
let replaceEndTagRegexp = /^[>]{3,} REPLACE$/
667+
let replaceEndTagRegexp = /^[+]{3,} REPLACE$/
661668
const replaceEndTagIndex = this.findLastMatchingLineIndex(replaceEndTagRegexp, lineLimit)
662669
const likeReplaceEndTag = replaceEndTagIndex === lineLimit - 1
663670
if (likeReplaceEndTag) {
@@ -666,7 +673,7 @@ class NewFileContentConstructor {
666673
// removeLineCount += this.tryFixReplaceBlock(replaceEndTagIndex)
667674
// }
668675
let fixLines = this.pendingNonStandardLines.slice(replaceEndTagIndex - removeLineCount, lineLimit - removeLineCount)
669-
fixLines[fixLines.length - 1] = ">>>>>>> REPLACE"
676+
fixLines[fixLines.length - 1] = REPLACE_BLOCK_END
670677
for (const line of fixLines) {
671678
removeLineCount += this.internalProcessLine(line, false, replaceEndTagIndex - removeLineCount)
672679
}
@@ -706,10 +713,10 @@ export async function constructNewFileContentV2(diffContent: string, originalCon
706713
const lastLine = lines[lines.length - 1]
707714
if (
708715
lines.length > 0 &&
709-
(lastLine.startsWith("<") || lastLine.startsWith("=") || lastLine.startsWith(">")) &&
710-
lastLine !== "<<<<<<< SEARCH" &&
711-
lastLine !== "=======" &&
712-
lastLine !== ">>>>>>> REPLACE"
716+
(lastLine.startsWith(SEARCH_BLOCK_CHAR) || lastLine.startsWith("=") || lastLine.startsWith(REPLACE_BLOCK_CHAR)) &&
717+
lastLine !== SEARCH_BLOCK_START &&
718+
lastLine !== SEARCH_BLOCK_END &&
719+
lastLine !== REPLACE_BLOCK_END
713720
) {
714721
lines.pop()
715722
}

0 commit comments

Comments
 (0)