matrixcode_core/tools/
read.rs1use anyhow::Result;
2use async_trait::async_trait;
3use serde_json::{Value, json};
4
5use super::{Tool, ToolDefinition};
6
7pub struct ReadTool;
8
9#[async_trait]
10impl Tool for ReadTool {
11 fn definition(&self) -> ToolDefinition {
12 ToolDefinition {
13 name: "read".to_string(),
14 description: "读取指定路径的文件内容".to_string(),
15 parameters: json!({
16 "type": "object",
17 "properties": {
18 "path": {
19 "type": "string",
20 "description": "要读取的文件路径"
21 },
22 "offset": {
23 "type": "integer",
24 "description": "起始行号(从 0 开始)"
25 },
26 "limit": {
27 "type": "integer",
28 "description": "最大读取行数"
29 }
30 },
31 "required": ["path"]
32 }),
33 }
34 }
35
36 async fn execute(&self, params: Value) -> Result<String> {
37 let path = params["path"]
41 .as_str()
42 .ok_or_else(|| anyhow::anyhow!("missing 'path'"))?;
43
44 let content = tokio::fs::read_to_string(path).await?;
48
49 let offset = params["offset"].as_u64().unwrap_or(0) as usize;
50 let limit = params["limit"].as_u64().map(|l| l as usize);
51
52 let lines: Vec<&str> = content.lines().collect();
53 let end = limit
54 .map(|l| (offset + l).min(lines.len()))
55 .unwrap_or(lines.len());
56 let selected = &lines[offset.min(lines.len())..end.min(lines.len())];
57
58 let result: String = selected
59 .iter()
60 .enumerate()
61 .map(|(i, line)| format!("{:4} | {}", offset + i + 1, line))
62 .collect::<Vec<_>>()
63 .join("\n");
64
65 Ok(result)
67 }
68}