use serde_json::json;
use super::{
ToolRuntime,
args::ListFilesArgs,
contract::{metadata_key as meta, tool_name},
result::{ToolResult, ToolResultDisplay},
};
const MAX_FILES: usize = 1000;
impl ToolRuntime {
pub(super) fn list_files(&self, args: ListFilesArgs) -> anyhow::Result<ToolResult> {
let path = self.resolve_existing_path(
&args.path,
super::fs::ExistingPathPolicy::list_files(self.list_files_absolute_paths),
)?;
if !path.is_dir() {
anyhow::bail!("list_files path must be a directory");
}
let listing = self.fs_cache.read_dir_listing(&path)?;
let mut entries = Vec::new();
let mut file_count = 0usize;
let mut directory_count = 0usize;
let mut truncated = false;
for entry in listing.entries.iter() {
if entry.file_type.is_file() || (args.include_directories && entry.file_type.is_dir()) {
if entries.len() == MAX_FILES {
truncated = true;
break;
}
if entry.file_type.is_dir() {
directory_count += 1;
} else {
file_count += 1;
}
entries.push(entry.name.clone());
}
}
entries.sort();
Ok(ToolResult {
tool_name: tool_name::LIST_FILES.to_string(),
success: true,
content: entries.join("\n"),
metadata: json!({
(meta::PATH): args.path,
(meta::FILES): file_count,
(meta::DIRECTORIES): directory_count,
(meta::TRUNCATED): truncated
}),
display: ToolResultDisplay::default(),
})
}
}