2026-03-27 15:22:48 -04:00
|
|
|
// tools/read.rs — Read file contents
|
|
|
|
|
|
|
|
|
|
use anyhow::{Context, Result};
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
2026-04-04 15:50:14 -04:00
|
|
|
pub fn tool() -> super::Tool {
|
|
|
|
|
super::Tool {
|
|
|
|
|
name: "read_file",
|
|
|
|
|
description: "Read the contents of a file. Returns the file contents with line numbers.",
|
|
|
|
|
parameters_json: r#"{"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)"},"limit":{"type":"integer","description":"Maximum number of lines to read"}},"required":["file_path"]}"#,
|
2026-04-08 20:37:19 -04:00
|
|
|
handler: Arc::new(|_a, v| Box::pin(async move { read_file(&v)) }),
|
2026-04-04 15:50:14 -04:00
|
|
|
}
|
|
|
|
|
}
|
2026-03-27 15:22:48 -04:00
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
|
struct Args {
|
|
|
|
|
file_path: String,
|
|
|
|
|
#[serde(default = "default_offset")]
|
|
|
|
|
offset: usize,
|
|
|
|
|
limit: Option<usize>,
|
|
|
|
|
}
|
|
|
|
|
fn default_offset() -> usize { 1 }
|
|
|
|
|
|
2026-04-04 15:34:07 -04:00
|
|
|
fn read_file(args: &serde_json::Value) -> Result<String> {
|
2026-04-04 15:50:14 -04:00
|
|
|
let a: Args = serde_json::from_value(args.clone()).context("invalid read_file arguments")?;
|
|
|
|
|
let content = std::fs::read_to_string(&a.file_path)
|
|
|
|
|
.with_context(|| format!("Failed to read {}", a.file_path))?;
|
2026-03-27 15:22:48 -04:00
|
|
|
let lines: Vec<&str> = content.lines().collect();
|
2026-04-04 15:50:14 -04:00
|
|
|
let start = a.offset.saturating_sub(1);
|
|
|
|
|
let end = a.limit.map_or(lines.len(), |l| (start + l).min(lines.len()));
|
|
|
|
|
if start >= lines.len() {
|
|
|
|
|
return Ok(format!("(file has {} lines, offset {} is past end)", lines.len(), a.offset));
|
2026-03-27 15:22:48 -04:00
|
|
|
}
|
2026-04-04 15:50:14 -04:00
|
|
|
let mut out = String::new();
|
|
|
|
|
for (i, line) in lines[start..end].iter().enumerate() {
|
|
|
|
|
out.push_str(&format!("{}\t{}\n", start + i + 1, line));
|
2026-03-27 15:22:48 -04:00
|
|
|
}
|
2026-04-04 15:50:14 -04:00
|
|
|
Ok(out)
|
2026-03-27 15:22:48 -04:00
|
|
|
}
|