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;
14
15pub struct ListTool<B: FileBackend>(pub Arc<B>);
16
17#[derive(Deserialize, JsonSchema)]
18struct ListArgs {
19 path: String,
21}
22
23#[async_trait::async_trait]
24impl<B: FileBackend> Tool for ListTool<B> {
25 fn name(&self) -> &str {
26 "list"
27 }
28 fn description(&self) -> &str {
29 "List directory contents"
30 }
31 fn is_read_only(&self) -> bool {
32 true
33 }
34 fn parameters_schema(&self) -> Value {
35 json_schema_for::<ListArgs>()
36 }
37 async fn execute(&self, args: Value, _ctx: &mut AgentContext) -> Result<ToolOutput, ToolError> {
38 let a: ListArgs = parse_args(&args)?;
39 self.0
40 .list(&a.path)
41 .await
42 .map(ToolOutput::text)
43 .map_err(backend_err)
44 }
45 async fn execute_readonly(
46 &self,
47 args: Value,
48 _ctx: &AgentContext,
49 ) -> Result<ToolOutput, ToolError> {
50 let a: ListArgs = parse_args(&args)?;
51 self.0
52 .list(&a.path)
53 .await
54 .map(ToolOutput::text)
55 .map_err(backend_err)
56 }
57}