agent tools: Make read_file.end_line inclusive (#29524)

One motivation is that the outlines returned by `read_file` for large
files list line numbers assuming an inclusive `end_line`. As a result,
when the agent uses these outlines for `read_line` calls, it would
otherwise miss the last line.

Release Notes:

- N/A
This commit is contained in:
Oleksiy Syvokon 2025-04-28 12:37:13 +03:00 committed by GitHub
parent 4dff47ae20
commit 9bd0828303
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -40,7 +40,7 @@ pub struct ReadFileToolInput {
#[serde(default)] #[serde(default)]
pub start_line: Option<usize>, pub start_line: Option<usize>,
/// Optional line number to end reading on (1-based index) /// Optional line number to end reading on (1-based index, inclusive)
#[serde(default)] #[serde(default)]
pub end_line: Option<usize>, pub end_line: Option<usize>,
} }
@ -128,7 +128,7 @@ impl Tool for ReadFileTool {
let start = input.start_line.unwrap_or(1); let start = input.start_line.unwrap_or(1);
let lines = text.split('\n').skip(start - 1); let lines = text.split('\n').skip(start - 1);
if let Some(end) = input.end_line { if let Some(end) = input.end_line {
let count = end.saturating_sub(start).max(1); // Ensure at least 1 line let count = end.saturating_sub(start).saturating_add(1); // Ensure at least 1 line
Itertools::intersperse(lines.take(count), "\n").collect() Itertools::intersperse(lines.take(count), "\n").collect()
} else { } else {
Itertools::intersperse(lines, "\n").collect() Itertools::intersperse(lines, "\n").collect()
@ -329,7 +329,7 @@ mod test {
.output .output
}) })
.await; .await;
assert_eq!(result.unwrap(), "Line 2\nLine 3"); assert_eq!(result.unwrap(), "Line 2\nLine 3\nLine 4");
} }
fn init_test(cx: &mut TestAppContext) { fn init_test(cx: &mut TestAppContext) {