partial readfile support

This commit is contained in:
Dhanji Prasanna
2025-10-09 11:08:02 +11:00
parent 0973b83d3a
commit cd489fb235

View File

@@ -634,9 +634,10 @@ The tool will execute immediately and you'll receive the result (success or erro
- Format: {\"tool\": \"shell\", \"args\": {\"command\": \"your_command_here\"}} - Format: {\"tool\": \"shell\", \"args\": {\"command\": \"your_command_here\"}}
- Example: {\"tool\": \"shell\", \"args\": {\"command\": \"ls ~/Downloads\"}} - Example: {\"tool\": \"shell\", \"args\": {\"command\": \"ls ~/Downloads\"}}
- **read_file**: Read the contents of a file - **read_file**: Read the contents of a file (supports partial reads via start/end)
- Format: {\"tool\": \"read_file\", \"args\": {\"file_path\": \"path/to/file\"}} - Format: {\"tool\": \"read_file\", \"args\": {\"file_path\": \"path/to/file\", \"start\": 0, \"end\": 100}}
- Example: {\"tool\": \"read_file\", \"args\": {\"file_path\": \"src/main.rs\"}} - Example: {\"tool\": \"read_file\", \"args\": {\"file_path\": \"src/main.rs\"}}
- Example (partial): {\"tool\": \"read_file\", \"args\": {\"file_path\": \"large.log\", \"start\": 0, \"end\": 1000}}
- **write_file**: Write content to a file (creates or overwrites) - **write_file**: Write content to a file (creates or overwrites)
- Format: {\"tool\": \"write_file\", \"args\": {\"file_path\": \"path/to/file\", \"content\": \"file content\"}} - Format: {\"tool\": \"write_file\", \"args\": {\"file_path\": \"path/to/file\", \"content\": \"file content\"}}
@@ -882,13 +883,21 @@ The tool will execute immediately and you'll receive the result (success or erro
}, },
Tool { Tool {
name: "read_file".to_string(), name: "read_file".to_string(),
description: "Read the contents of a file".to_string(), description: "Read the contents of a file. Optionally read a specific character range.".to_string(),
input_schema: json!({ input_schema: json!({
"type": "object", "type": "object",
"properties": { "properties": {
"file_path": { "file_path": {
"type": "string", "type": "string",
"description": "The path to the file to read" "description": "The path to the file to read"
},
"start": {
"type": "integer",
"description": "Starting character position (0-indexed, inclusive). If omitted, reads from beginning."
},
"end": {
"type": "integer",
"description": "Ending character position (0-indexed, EXCLUSIVE). If omitted, reads to end of file."
} }
}, },
"required": ["file_path"] "required": ["file_path"]
@@ -1726,14 +1735,47 @@ The tool will execute immediately and you'll receive the result (success or erro
debug!("Processing read_file tool call"); debug!("Processing read_file tool call");
if let Some(file_path) = tool_call.args.get("file_path") { if let Some(file_path) = tool_call.args.get("file_path") {
if let Some(path_str) = file_path.as_str() { if let Some(path_str) = file_path.as_str() {
debug!("Reading file: {}", path_str); // Extract optional start and end positions
let start_char = tool_call.args.get("start")
.and_then(|v| v.as_u64())
.map(|n| n as usize);
let end_char = tool_call.args.get("end")
.and_then(|v| v.as_u64())
.map(|n| n as usize);
debug!("Reading file: {}, start={:?}, end={:?}", path_str, start_char, end_char);
match std::fs::read_to_string(path_str) { match std::fs::read_to_string(path_str) {
Ok(content) => { Ok(content) => {
let line_count = content.lines().count(); // Validate and apply range if specified
Ok(format!( let start = start_char.unwrap_or(0);
"📄 File content ({} lines):\n{}", let end = end_char.unwrap_or(content.len());
line_count, content
)) // Validation
if start > content.len() {
return Ok(format!("❌ Start position {} exceeds file length {}", start, content.len()));
}
if end > content.len() {
return Ok(format!("❌ End position {} exceeds file length {}", end, content.len()));
}
if start > end {
return Ok(format!("❌ Start position {} is greater than end position {}", start, end));
}
// Extract the requested portion
let partial_content = &content[start..end];
let line_count = partial_content.lines().count();
let total_lines = content.lines().count();
// Format output with range info if partial
if start_char.is_some() || end_char.is_some() {
Ok(format!(
"📄 File content (chars {}-{}, {} lines of {} total):\n{}",
start, end, line_count, total_lines, partial_content
))
} else {
Ok(format!("📄 File content ({} lines):\n{}", line_count, content))
}
} }
Err(e) => Ok(format!("❌ Failed to read file '{}': {}", path_str, e)), Err(e) => Ok(format!("❌ Failed to read file '{}': {}", path_str, e)),
} }