66 lines
1.8 KiB
Rust
66 lines
1.8 KiB
Rust
|
|
// tools/read.rs — Read file contents
|
||
|
|
|
||
|
|
use anyhow::{Context, Result};
|
||
|
|
use serde::Deserialize;
|
||
|
|
use serde_json::json;
|
||
|
|
|
||
|
|
use super::ToolDef;
|
||
|
|
|
||
|
|
#[derive(Deserialize)]
|
||
|
|
struct Args {
|
||
|
|
file_path: String,
|
||
|
|
#[serde(default = "default_offset")]
|
||
|
|
offset: usize,
|
||
|
|
limit: Option<usize>,
|
||
|
|
}
|
||
|
|
|
||
|
|
fn default_offset() -> usize { 1 }
|
||
|
|
|
||
|
|
pub fn definition() -> ToolDef {
|
||
|
|
ToolDef::new(
|
||
|
|
"read_file",
|
||
|
|
"Read the contents of a file. Returns the file contents with line numbers.",
|
||
|
|
json!({
|
||
|
|
"type": "object",
|
||
|
|
"properties": {
|
||
|
|
"file_path": {
|
||
|
|
"type": "string",
|
||
|
|
"description": "Absolute path to the file to read"
|
||
|
|
},
|
||
|
|
"offset": {
|
||
|
|
"type": "integer",
|
||
|
|
"description": "Line number to start reading from (1-based). Optional."
|
||
|
|
},
|
||
|
|
"limit": {
|
||
|
|
"type": "integer",
|
||
|
|
"description": "Maximum number of lines to read. Optional."
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"required": ["file_path"]
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn read_file(args: &serde_json::Value) -> Result<String> {
|
||
|
|
let args: Args = serde_json::from_value(args.clone())
|
||
|
|
.context("invalid read_file arguments")?;
|
||
|
|
|
||
|
|
let content = std::fs::read_to_string(&args.file_path)
|
||
|
|
.with_context(|| format!("Failed to read {}", args.file_path))?;
|
||
|
|
|
||
|
|
let lines: Vec<&str> = content.lines().collect();
|
||
|
|
let offset = args.offset.max(1) - 1;
|
||
|
|
let limit = args.limit.unwrap_or(lines.len());
|
||
|
|
|
||
|
|
let mut output = String::new();
|
||
|
|
for (i, line) in lines.iter().skip(offset).take(limit).enumerate() {
|
||
|
|
output.push_str(&format!("{:>6}\t{}\n", offset + i + 1, line));
|
||
|
|
}
|
||
|
|
|
||
|
|
if output.is_empty() {
|
||
|
|
output = "(empty file)\n".to_string();
|
||
|
|
}
|
||
|
|
|
||
|
|
Ok(output)
|
||
|
|
}
|