use std::path::PathBuf;
use crate::skills::Skill;
use crate::tools::Tool;
use crate::tools::files::files::{
AppendFileTool, CreateFileTool, DeleteFileTool, ListDirTool, MoveFileTool, ReadFileTool,
UpdateFileTool, WriteFileTool,
};
pub struct FileSystemSkill {
base_dir: Option<PathBuf>,
}
impl FileSystemSkill {
pub fn new() -> Self {
Self { base_dir: None }
}
pub fn with_base_dir(base: impl Into<PathBuf>) -> Self {
Self {
base_dir: Some(base.into()),
}
}
}
impl Default for FileSystemSkill {
fn default() -> Self {
Self::new()
}
}
impl Skill for FileSystemSkill {
fn name(&self) -> &str {
"filesystem"
}
fn description(&self) -> &str {
"Local filesystem read/write capability: create files, delete files, move file paths, read file content, write file content, append to files, modify file content, and list directory contents"
}
fn tools(&self) -> Vec<Box<dyn Tool>> {
let base = self.base_dir.clone();
vec![
Box::new(match &base {
Some(b) => ReadFileTool::with_base_dir(b),
None => ReadFileTool::new(),
}),
Box::new(match &base {
Some(b) => WriteFileTool::with_base_dir(b),
None => WriteFileTool::new(),
}),
Box::new(match &base {
Some(b) => AppendFileTool::with_base_dir(b),
None => AppendFileTool::new(),
}),
Box::new(match &base {
Some(b) => ListDirTool::with_base_dir(b),
None => ListDirTool::new(),
}),
Box::new(match &base {
Some(b) => CreateFileTool::with_base_dir(b),
None => CreateFileTool::new(),
}),
Box::new(match &base {
Some(b) => DeleteFileTool::with_base_dir(b),
None => DeleteFileTool::new(),
}),
Box::new(match &base {
Some(b) => UpdateFileTool::with_base_dir(b),
None => UpdateFileTool::new(),
}),
Box::new(match &base {
Some(b) => MoveFileTool::with_base_dir(b),
None => MoveFileTool::new(),
}),
]
}
fn system_prompt_injection(&self) -> Option<String> {
let restriction = if let Some(base) = &self.base_dir {
format!(" (operations restricted to '{}' directory)", base.display())
} else {
" (no path restriction, exercise caution when operating)".to_string()
};
Some(format!(
"\n\n## Filesystem Capability (FileSystem Skill){restriction}\n\
You can operate on the local filesystem. Please use the following tools appropriately:\n\
- `create_file(path)`: Create a file, suitable for creating an empty file, etc.\n\
- `delete_file(path)`: Delete a file, suitable for removing unwanted old files such as configs, logs, code, etc.\n\
- `move_file(old_path, new_path)`: Move a file path, for relocating files\n\
- `read_file(path)`: Read file content, suitable for viewing configs, logs, code, etc.\n\
- `write_file(path, content)`: Overwrite file content, clears existing content\n\
- `update_file(path, old_content, new_content)`: Modify file content, replace old content with new content (exact match, first occurrence)\n\
- `append_file(path, content)`: Append content to the end of a file, does not clear existing content\n\
- `list_dir(path)`: List files and subdirectories in a directory\n\
**Note**: write_file overwrites the original file; if you need to preserve original content, read_file first, then decide whether to use write_file or append_file."
))
}
}