Skip to main content

sgr_agent_tools/
tree.rs

1//! TreeTool — show directory tree structure.
2
3use 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    /// Directory path (default: workspace root)
20    #[serde(default = "def_root")]
21    root: String,
22    /// Max depth (default: 2)
23    #[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}