1use std::sync::Arc;
4
5use schemars::JsonSchema;
6use serde::Deserialize;
7use serde_json::Value;
8use sgr_agent_core::agent_tool::{Tool, ToolError, ToolOutput, parse_args};
9use sgr_agent_core::context::AgentContext;
10use sgr_agent_core::schema::json_schema_for;
11
12use crate::backend::FileBackend;
13use crate::helpers::{backend_err, def_level, def_root};
14
15pub struct TreeTool<B: FileBackend>(pub Arc<B>);
16
17#[derive(Deserialize, JsonSchema)]
18struct TreeArgs {
19 #[serde(default = "def_root")]
21 root: String,
22 #[serde(default = "def_level")]
24 level: i32,
25}
26
27#[async_trait::async_trait]
28impl<B: FileBackend> Tool for TreeTool<B> {
29 fn name(&self) -> &str {
30 "tree"
31 }
32 fn description(&self) -> &str {
33 "Show directory tree structure"
34 }
35 fn is_read_only(&self) -> bool {
36 true
37 }
38 fn parameters_schema(&self) -> Value {
39 json_schema_for::<TreeArgs>()
40 }
41 async fn execute(&self, args: Value, _ctx: &mut AgentContext) -> Result<ToolOutput, ToolError> {
42 let a: TreeArgs = parse_args(&args)?;
43 self.0
44 .tree(&a.root, a.level)
45 .await
46 .map(ToolOutput::text)
47 .map_err(backend_err)
48 }
49 async fn execute_readonly(
50 &self,
51 args: Value,
52 _ctx: &AgentContext,
53 ) -> Result<ToolOutput, ToolError> {
54 let a: TreeArgs = parse_args(&args)?;
55 self.0
56 .tree(&a.root, a.level)
57 .await
58 .map(ToolOutput::text)
59 .map_err(backend_err)
60 }
61}