Skip to content

Commit 03f9d4d

Browse files
committed
fix(read_file): enhance legacy path handling and remove duplicate parameters
1 parent 789a352 commit 03f9d4d

File tree

4 files changed

+65
-37
lines changed

4 files changed

+65
-37
lines changed

src/core/tools/readFileTool.ts

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,21 @@ export async function readFileTool(
4848
_removeClosingTag: RemoveClosingTag,
4949
) {
5050
const argsXmlTag: string | undefined = block.params.args
51+
const legacyPath: string | undefined = block.params.path
52+
const legacyStartLineStr: string | undefined = block.params.start_line
53+
const legacyEndLineStr: string | undefined = block.params.end_line
5154

5255
// Handle partial message first
5356
if (block.partial) {
5457
let filePath = ""
58+
// Prioritize args for partial, then legacy path
5559
if (argsXmlTag) {
5660
const match = argsXmlTag.match(/<file>.*?<path>([^<]+)<\/path>/s)
57-
if (match) {
58-
filePath = match[1]
59-
}
61+
if (match) filePath = match[1]
62+
}
63+
if (!filePath && legacyPath) {
64+
// If args didn't yield a path, try legacy
65+
filePath = legacyPath
6066
}
6167

6268
const fullPath = filePath ? path.resolve(cline.cwd, filePath) : ""
@@ -73,52 +79,70 @@ export async function readFileTool(
7379
return
7480
}
7581

76-
if (!argsXmlTag) {
77-
cline.consecutiveMistakeCount++
78-
cline.recordToolError("read_file")
79-
const errorMsg = await cline.sayAndCreateMissingParamError("read_file", "args")
80-
pushToolResult(`<files><error>${errorMsg}</error></files>`)
81-
return
82-
}
83-
84-
// Parse file entries from XML
8582
const fileEntries: FileEntry[] = []
86-
try {
87-
const parsed = parseXml(argsXmlTag) as any
88-
const files = Array.isArray(parsed.file) ? parsed.file : [parsed.file].filter(Boolean)
8983

90-
for (const file of files) {
91-
if (!file.path) continue
84+
if (argsXmlTag) {
85+
// Parse file entries from XML (new multi-file format)
86+
try {
87+
const parsed = parseXml(argsXmlTag) as any
88+
const files = Array.isArray(parsed.file) ? parsed.file : [parsed.file].filter(Boolean)
9289

93-
const fileEntry: FileEntry = {
94-
path: file.path,
95-
lineRanges: [],
96-
}
90+
for (const file of files) {
91+
if (!file.path) continue // Skip if no path in a file entry
92+
93+
const fileEntry: FileEntry = {
94+
path: file.path,
95+
lineRanges: [],
96+
}
9797

98-
// Handle line ranges
99-
if (file.line_range) {
100-
const ranges = Array.isArray(file.line_range) ? file.line_range : [file.line_range]
101-
for (const range of ranges) {
102-
const match = range.match(/(\d+)-(\d+)/)
103-
if (match) {
104-
const [, start, end] = match.map(Number)
105-
if (!isNaN(start) && !isNaN(end)) {
106-
fileEntry.lineRanges?.push({ start, end })
98+
if (file.line_range) {
99+
const ranges = Array.isArray(file.line_range) ? file.line_range : [file.line_range]
100+
for (const range of ranges) {
101+
const match = String(range).match(/(\d+)-(\d+)/) // Ensure range is treated as string
102+
if (match) {
103+
const [, start, end] = match.map(Number)
104+
if (!isNaN(start) && !isNaN(end)) {
105+
fileEntry.lineRanges?.push({ start, end })
106+
}
107107
}
108108
}
109109
}
110+
fileEntries.push(fileEntry)
110111
}
112+
} catch (error) {
113+
const errorMessage = `Failed to parse read_file XML args: ${error instanceof Error ? error.message : String(error)}`
114+
await handleError("parsing read_file args", new Error(errorMessage))
115+
pushToolResult(`<files><error>${errorMessage}</error></files>`)
116+
return
117+
}
118+
} else if (legacyPath) {
119+
// Handle legacy single file path as a fallback
120+
console.warn("[readFileTool] Received legacy 'path' parameter. Consider updating to use 'args' structure.")
111121

112-
fileEntries.push(fileEntry)
122+
const fileEntry: FileEntry = {
123+
path: legacyPath,
124+
lineRanges: [],
113125
}
114-
} catch (error) {
115-
throw new Error(`Failed to parse read_file XML: ${error instanceof Error ? error.message : String(error)}`)
126+
127+
if (legacyStartLineStr && legacyEndLineStr) {
128+
const start = parseInt(legacyStartLineStr, 10)
129+
const end = parseInt(legacyEndLineStr, 10)
130+
if (!isNaN(start) && !isNaN(end) && start > 0 && end > 0) {
131+
fileEntry.lineRanges?.push({ start, end })
132+
} else {
133+
console.warn(
134+
`[readFileTool] Invalid legacy line range for ${legacyPath}: start='${legacyStartLineStr}', end='${legacyEndLineStr}'`,
135+
)
136+
}
137+
}
138+
fileEntries.push(fileEntry)
116139
}
117140

141+
// If, after trying both new and legacy, no valid file entries are found.
118142
if (fileEntries.length === 0) {
119143
cline.consecutiveMistakeCount++
120144
cline.recordToolError("read_file")
121-
const errorMsg = await cline.sayAndCreateMissingParamError("read_file", "args")
145+
const errorMsg = await cline.sayAndCreateMissingParamError("read_file", "args (containing valid file paths)")
122146
pushToolResult(`<files><error>${errorMsg}</error></files>`)
123147
return
124148
}

src/exports/roo-code.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ type IpcMessage =
776776
maxWorkspaceFiles?: number | undefined
777777
showRooIgnoredFiles?: boolean | undefined
778778
maxReadFileLine?: number | undefined
779+
maxConcurrentFileReads?: number | undefined
779780
terminalOutputLineLimit?: number | undefined
780781
terminalShellIntegrationTimeout?: number | undefined
781782
terminalShellIntegrationDisabled?: boolean | undefined
@@ -1239,6 +1240,7 @@ type TaskCommand =
12391240
maxWorkspaceFiles?: number | undefined
12401241
showRooIgnoredFiles?: boolean | undefined
12411242
maxReadFileLine?: number | undefined
1243+
maxConcurrentFileReads?: number | undefined
12421244
terminalOutputLineLimit?: number | undefined
12431245
terminalShellIntegrationTimeout?: number | undefined
12441246
terminalShellIntegrationDisabled?: boolean | undefined

src/exports/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ type IpcMessage =
788788
maxWorkspaceFiles?: number | undefined
789789
showRooIgnoredFiles?: boolean | undefined
790790
maxReadFileLine?: number | undefined
791+
maxConcurrentFileReads?: number | undefined
791792
terminalOutputLineLimit?: number | undefined
792793
terminalShellIntegrationTimeout?: number | undefined
793794
terminalShellIntegrationDisabled?: boolean | undefined
@@ -1253,6 +1254,7 @@ type TaskCommand =
12531254
maxWorkspaceFiles?: number | undefined
12541255
showRooIgnoredFiles?: boolean | undefined
12551256
maxReadFileLine?: number | undefined
1257+
maxConcurrentFileReads?: number | undefined
12561258
terminalOutputLineLimit?: number | undefined
12571259
terminalShellIntegrationTimeout?: number | undefined
12581260
terminalShellIntegrationDisabled?: boolean | undefined

src/shared/tools.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ export const toolParamNames = [
4545
"question",
4646
"result",
4747
"diff",
48-
"start_line",
49-
"end_line",
48+
// "start_line", // Removed duplicate, kept the ones at the end of the list from the original commit
49+
// "end_line", // Removed duplicate
5050
"mode_slug",
5151
"reason",
5252
"line",
@@ -83,7 +83,7 @@ export interface ExecuteCommandToolUse extends ToolUse {
8383

8484
export interface ReadFileToolUse extends ToolUse {
8585
name: "read_file"
86-
params: Partial<Pick<Record<ToolParamName, string>, "args">>
86+
params: Partial<Pick<Record<ToolParamName, string>, "args" | "path" | "start_line" | "end_line">>
8787
}
8888

8989
export interface FetchInstructionsToolUse extends ToolUse {

0 commit comments

Comments
 (0)