Clarify how outlining works in read_file_tool description (#43929)

Richard Feldman created

<img width="698" height="218" alt="Screenshot 2025-12-01 at 1 27 02 PM"
src="https://github.com/user-attachments/assets/a5d9e121-4e68-40d0-a346-4dd39e77233b"
/>

Closes #419

Release Notes:

- Revise tool call description for read file tool to explain outlining
behavior

Change summary

crates/agent/src/outline.rs              |  6 ++----
crates/agent/src/tools/read_file_tool.rs | 20 +++++++++++---------
2 files changed, 13 insertions(+), 13 deletions(-)

Detailed changes

crates/agent/src/outline.rs 🔗

@@ -66,11 +66,9 @@ pub async fn get_buffer_content_or_outline(
         let outline_text = render_outline(outline_items, None, 0, usize::MAX).await?;
 
         let text = if let Some(path) = path {
-            format!(
-                "# File outline for {path} (file too large to show full content)\n\n{outline_text}",
-            )
+            format!("# File outline for {path}\n\n{outline_text}",)
         } else {
-            format!("# File outline (file too large to show full content)\n\n{outline_text}",)
+            format!("# File outline\n\n{outline_text}",)
         };
         Ok(BufferContent {
             text,

crates/agent/src/tools/read_file_tool.rs 🔗

@@ -17,6 +17,9 @@ use crate::{AgentTool, Thread, ToolCallEventStream, outline};
 /// Reads the content of the given file in the project.
 ///
 /// - Never attempt to read a path that hasn't been previously mentioned.
+/// - For large files, this tool returns a file outline with symbol names and line numbers instead of the full content.
+///   This outline IS a successful response - use the line numbers to read specific sections with start_line/end_line.
+///   Do NOT retry reading the same file without line numbers if you receive an outline.
 #[derive(Debug, Serialize, Deserialize, JsonSchema)]
 pub struct ReadFileToolInput {
     /// The relative path of the file to read.
@@ -254,16 +257,15 @@ impl AgentTool for ReadFileTool {
 
                 if buffer_content.is_outline {
                     Ok(formatdoc! {"
-                        This file was too big to read all at once.
+                        SUCCESS: File outline retrieved. This file is too large to read all at once, so the outline below shows the file's structure with line numbers.
 
-                        {}
+                        IMPORTANT: Do NOT retry this call without line numbers - you will get the same outline.
+                        Instead, use the line numbers below to read specific sections by calling this tool again with start_line and end_line parameters.
 
-                        Using the line numbers in this outline, you can call this tool again
-                        while specifying the start_line and end_line fields to see the
-                        implementations of symbols in the outline.
+                        {}
 
-                        Alternatively, you can fall back to the `grep` tool (if available)
-                        to search the file for specific content.", buffer_content.text
+                        NEXT STEPS: To read a specific symbol's implementation, call read_file with the same path plus start_line and end_line from the outline above.
+                        For example, to read a function shown as [L100-150], use start_line: 100 and end_line: 150.", buffer_content.text
                     }
                     .into())
                 } else {
@@ -440,7 +442,7 @@ mod test {
         let content = result.to_str().unwrap();
 
         assert_eq!(
-            content.lines().skip(4).take(6).collect::<Vec<_>>(),
+            content.lines().skip(7).take(6).collect::<Vec<_>>(),
             vec![
                 "struct Test0 [L1-4]",
                 " a [L2]",
@@ -475,7 +477,7 @@ mod test {
         pretty_assertions::assert_eq!(
             content
                 .lines()
-                .skip(4)
+                .skip(7)
                 .take(expected_content.len())
                 .collect::<Vec<_>>(),
             expected_content