mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: make start_line and end_line parsing more lenient to accept brackets
Some models send `:start_line:[245]` instead of `:start_line:245`. This updates the regex to accept optional brackets around line numbers, improving compatibility with models like MiniMax-2.1 and Gemini. Supported formats: - :start_line:253 - :start_line: 253 - :start_line:[253] - :start_line: [253] Fixes #11087
This commit is contained in:
parent
b020f6be43
commit
30c730f2b2
3 changed files with 133 additions and 5 deletions
16
.changeset/lenient-start-line-parsing.md
Normal file
16
.changeset/lenient-start-line-parsing.md
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
"roo-cline": patch
|
||||
---
|
||||
|
||||
fix: make start_line and end_line parsing more lenient to accept brackets
|
||||
|
||||
Some models send `:start_line:[245]` or `:start_line: [245]` instead of `:start_line:245`. This change updates the regex to accept optional brackets around the line number, improving compatibility with models like MiniMax-2.1 and Gemini.
|
||||
|
||||
Supported formats:
|
||||
|
||||
- `:start_line:253`
|
||||
- `:start_line: 253`
|
||||
- `:start_line:[253]`
|
||||
- `:start_line: [253]`
|
||||
|
||||
Fixes #11087
|
||||
|
|
@ -92,6 +92,30 @@ describe("MultiSearchReplaceDiffStrategy", () => {
|
|||
expect(strategy["validateMarkerSequencing"](diff).success).toBe(true)
|
||||
})
|
||||
|
||||
it("validates line numbers with brackets (model variation)", () => {
|
||||
const diff =
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line:[10]\n" +
|
||||
"-------\n" +
|
||||
"content1\n" +
|
||||
"=======\n" +
|
||||
"new1\n" +
|
||||
">>>>>>> REPLACE"
|
||||
expect(strategy["validateMarkerSequencing"](diff).success).toBe(true)
|
||||
})
|
||||
|
||||
it("validates line numbers with space and brackets (model variation)", () => {
|
||||
const diff =
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line: [10]\n" +
|
||||
"-------\n" +
|
||||
"content1\n" +
|
||||
"=======\n" +
|
||||
"new1\n" +
|
||||
">>>>>>> REPLACE"
|
||||
expect(strategy["validateMarkerSequencing"](diff).success).toBe(true)
|
||||
})
|
||||
|
||||
it("detects separator before search", () => {
|
||||
const diff = "=======\n" + "content\n" + ">>>>>>> REPLACE"
|
||||
const result = strategy["validateMarkerSequencing"](diff)
|
||||
|
|
@ -826,6 +850,92 @@ function five() {
|
|||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("bracket variations in line numbers", () => {
|
||||
let strategy: MultiSearchReplaceDiffStrategy
|
||||
|
||||
beforeEach(() => {
|
||||
strategy = new MultiSearchReplaceDiffStrategy(1.0, 5)
|
||||
})
|
||||
|
||||
it("should accept start_line with brackets around the number", async () => {
|
||||
const originalContent = 'function hello() {\n console.log("hello")\n}\n'
|
||||
const diffContent =
|
||||
"test.ts\n" +
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line:[1]\n" +
|
||||
"-------\n" +
|
||||
"function hello() {\n" +
|
||||
"=======\n" +
|
||||
"function helloWorld() {\n" +
|
||||
">>>>>>> REPLACE"
|
||||
|
||||
const result = await strategy.applyDiff(originalContent, diffContent)
|
||||
expect(result.success).toBe(true)
|
||||
if (result.success) {
|
||||
expect(result.content).toBe('function helloWorld() {\n console.log("hello")\n}\n')
|
||||
}
|
||||
})
|
||||
|
||||
it("should accept start_line with space and brackets around the number", async () => {
|
||||
const originalContent = 'function hello() {\n console.log("hello")\n}\n'
|
||||
const diffContent =
|
||||
"test.ts\n" +
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line: [1]\n" +
|
||||
"-------\n" +
|
||||
"function hello() {\n" +
|
||||
"=======\n" +
|
||||
"function helloWorld() {\n" +
|
||||
">>>>>>> REPLACE"
|
||||
|
||||
const result = await strategy.applyDiff(originalContent, diffContent)
|
||||
expect(result.success).toBe(true)
|
||||
if (result.success) {
|
||||
expect(result.content).toBe('function helloWorld() {\n console.log("hello")\n}\n')
|
||||
}
|
||||
})
|
||||
|
||||
it("should accept end_line with brackets around the number", async () => {
|
||||
const originalContent = 'function hello() {\n console.log("hello")\n}\n'
|
||||
const diffContent =
|
||||
"test.ts\n" +
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line:[1]\n" +
|
||||
":end_line:[1]\n" +
|
||||
"-------\n" +
|
||||
"function hello() {\n" +
|
||||
"=======\n" +
|
||||
"function helloWorld() {\n" +
|
||||
">>>>>>> REPLACE"
|
||||
|
||||
const result = await strategy.applyDiff(originalContent, diffContent)
|
||||
expect(result.success).toBe(true)
|
||||
if (result.success) {
|
||||
expect(result.content).toBe('function helloWorld() {\n console.log("hello")\n}\n')
|
||||
}
|
||||
})
|
||||
|
||||
it("should accept end_line with space and brackets around the number", async () => {
|
||||
const originalContent = 'function hello() {\n console.log("hello")\n}\n'
|
||||
const diffContent =
|
||||
"test.ts\n" +
|
||||
"<<<<<<< SEARCH\n" +
|
||||
":start_line: [1]\n" +
|
||||
":end_line: [1]\n" +
|
||||
"-------\n" +
|
||||
"function hello() {\n" +
|
||||
"=======\n" +
|
||||
"function helloWorld() {\n" +
|
||||
">>>>>>> REPLACE"
|
||||
|
||||
const result = await strategy.applyDiff(originalContent, diffContent)
|
||||
expect(result.success).toBe(true)
|
||||
if (result.success) {
|
||||
expect(result.content).toBe('function helloWorld() {\n console.log("hello")\n}\n')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("fuzzy matching", () => {
|
||||
|
|
|
|||
|
|
@ -265,11 +265,13 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy {
|
|||
2. (?<!\\)<<<<<<< SEARCH\s*\n
|
||||
Matches the line "<<<<<<< SEARCH" (ignoring any trailing spaces) – the negative lookbehind makes sure it isn't escaped.
|
||||
|
||||
3. ((?:\:start_line:\s*(\d+)\s*\n))?
|
||||
Optionally matches a ":start_line:" line. The outer capturing group is group 1 and the inner (\d+) is group 2.
|
||||
3. ((?:\:start_line:\s*\[?(\d+)\]?\s*\n))?
|
||||
Optionally matches a ":start_line:" line with optional brackets around the number. The outer capturing group is group 1 and the inner (\d+) is group 2.
|
||||
Accepts formats: :start_line:5, :start_line: 5, :start_line:[5], :start_line: [5]
|
||||
|
||||
4. ((?:\:end_line:\s*(\d+)\s*\n))?
|
||||
Optionally matches a ":end_line:" line. Group 3 is the whole match and group 4 is the digits.
|
||||
4. ((?:\:end_line:\s*\[?(\d+)\]?\s*\n))?
|
||||
Optionally matches a ":end_line:" line with optional brackets around the number. Group 3 is the whole match and group 4 is the digits.
|
||||
Accepts formats: :end_line:5, :end_line: 5, :end_line:[5], :end_line: [5]
|
||||
|
||||
5. ((?<!\\)-------\s*\n)?
|
||||
Optionally matches the "-------" marker line (group 5).
|
||||
|
|
@ -289,7 +291,7 @@ export class MultiSearchReplaceDiffStrategy implements DiffStrategy {
|
|||
|
||||
let matches = [
|
||||
...diffContent.matchAll(
|
||||
/(?:^|\n)(?<!\\)<<<<<<< SEARCH>?\s*\n((?:\:start_line:\s*(\d+)\s*\n))?((?:\:end_line:\s*(\d+)\s*\n))?((?<!\\)-------\s*\n)?([\s\S]*?)(?:\n)?(?:(?<=\n)(?<!\\)=======\s*\n)([\s\S]*?)(?:\n)?(?:(?<=\n)(?<!\\)>>>>>>> REPLACE)(?=\n|$)/g,
|
||||
/(?:^|\n)(?<!\\)<<<<<<< SEARCH>?\s*\n((?:\:start_line:\s*\[?(\d+)\]?\s*\n))?((?:\:end_line:\s*\[?(\d+)\]?\s*\n))?((?<!\\)-------\s*\n)?([\s\S]*?)(?:\n)?(?:(?<=\n)(?<!\\)=======\s*\n)([\s\S]*?)(?:\n)?(?:(?<=\n)(?<!\\)>>>>>>> REPLACE)(?=\n|$)/g,
|
||||
),
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue