tools: add cd tool for changing working directory
Uses std::env::set_current_dir() syscall so the change affects all subsequent tool invocations. Supports absolute paths, relative paths, and ~ expansion. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
0612e1bc41
commit
ab0f16a3b5
2 changed files with 43 additions and 3 deletions
39
src/agent/tools/cd.rs
Normal file
39
src/agent/tools/cd.rs
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
// tools/cd.rs — Change working directory
|
||||||
|
//
|
||||||
|
// Uses the chdir syscall so it affects all tools.
|
||||||
|
|
||||||
|
pub fn tool() -> super::Tool {
|
||||||
|
super::Tool {
|
||||||
|
name: "cd",
|
||||||
|
description: "Change the current working directory.",
|
||||||
|
parameters_json: r#"{"type":"object","properties":{"path":{"type":"string","description":"The directory to change to (absolute or relative)"}},"required":["path"]}"#,
|
||||||
|
handler: Arc::new(|_agent, v| Box::pin(async move {
|
||||||
|
let path = v.get("path").and_then(|v| v.as_str())
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("'path' parameter is required"))?;
|
||||||
|
if path.is_empty() { anyhow::bail!("'path' parameter cannot be empty"); }
|
||||||
|
|
||||||
|
// Resolve ~ to home directory
|
||||||
|
let resolved = if path.starts_with('~') {
|
||||||
|
let home = dirs::home_dir()
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("could not determine home directory"))?;
|
||||||
|
home.join(path.strip_prefix("~/").unwrap_or(path))
|
||||||
|
} else {
|
||||||
|
PathBuf::from(path)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Change directory (this is the actual chdir syscall)
|
||||||
|
std::env::set_current_dir(&resolved)
|
||||||
|
.map_err(|e| anyhow::anyhow!("cd: {}: {}", path, e))?;
|
||||||
|
|
||||||
|
// Return the canonical path
|
||||||
|
let canonical = std::env::current_dir()
|
||||||
|
.map(|p| p.display().to_string())
|
||||||
|
.unwrap_or_else(|_| resolved.display().to_string());
|
||||||
|
|
||||||
|
Ok(canonical)
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,13 +6,14 @@
|
||||||
|
|
||||||
// Core tools
|
// Core tools
|
||||||
mod ast_grep;
|
mod ast_grep;
|
||||||
pub mod lsp;
|
|
||||||
pub mod mcp_client;
|
|
||||||
mod bash;
|
mod bash;
|
||||||
|
mod cd;
|
||||||
pub mod channels;
|
pub mod channels;
|
||||||
mod edit;
|
mod edit;
|
||||||
mod glob;
|
mod glob;
|
||||||
mod grep;
|
mod grep;
|
||||||
|
pub mod lsp;
|
||||||
|
pub mod mcp_client;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
mod read;
|
mod read;
|
||||||
mod web;
|
mod web;
|
||||||
|
|
@ -177,7 +178,7 @@ pub async fn dispatch_with_agent(
|
||||||
pub fn tools() -> Vec<Tool> {
|
pub fn tools() -> Vec<Tool> {
|
||||||
let mut all = vec![
|
let mut all = vec![
|
||||||
read::tool(), write::tool(), edit::tool(),
|
read::tool(), write::tool(), edit::tool(),
|
||||||
grep::tool(), glob::tool(), bash::tool(),
|
grep::tool(), glob::tool(), bash::tool(), cd::tool(),
|
||||||
ast_grep::tool(), vision::tool(),
|
ast_grep::tool(), vision::tool(),
|
||||||
];
|
];
|
||||||
all.extend(web::tools());
|
all.extend(web::tools());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue