Added many tools
This commit is contained in:
@@ -13,146 +13,110 @@ class FilesystemTool(BaseTool):
|
||||
name = "filesystem"
|
||||
description = "Safe filesystem operations"
|
||||
|
||||
MAX_READ_BYTES = 5_000_000
|
||||
MAX_LIST_ENTRIES = 5000
|
||||
|
||||
# =========================
|
||||
# EXECUTE
|
||||
# EXECUTE ROUTER
|
||||
# =========================
|
||||
|
||||
def execute(
|
||||
self,
|
||||
payload: dict[str, Any],
|
||||
ctx: ToolContext
|
||||
):
|
||||
def execute(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
action = str(payload.get("action", "")).strip()
|
||||
|
||||
bus.log(
|
||||
"FILESYSTEM",
|
||||
"filesystem_execute",
|
||||
"INFO",
|
||||
{
|
||||
"action": action
|
||||
}
|
||||
{"action": action}
|
||||
)
|
||||
|
||||
match action:
|
||||
case "read_file":
|
||||
return self.read_file(payload)
|
||||
handlers = {
|
||||
"read_file": self.read_file,
|
||||
"write_file": self.write_file,
|
||||
"list_dir": self.list_dir,
|
||||
"exists": self.exists,
|
||||
"mkdir": self.mkdir,
|
||||
}
|
||||
|
||||
case "write_file":
|
||||
return self.write_file(payload)
|
||||
handler = handlers.get(action)
|
||||
if not handler:
|
||||
raise ValueError(f"Unknown filesystem action: {action}")
|
||||
|
||||
case "list_dir":
|
||||
return self.list_dir(payload)
|
||||
return handler(payload, ctx)
|
||||
|
||||
case "exists":
|
||||
return self.exists(payload)
|
||||
# =========================
|
||||
# PATH HELPERS
|
||||
# =========================
|
||||
|
||||
case "mkdir":
|
||||
return self.mkdir(payload)
|
||||
def _get_path(self, payload: dict[str, Any]) -> Path:
|
||||
path_value = payload.get("path")
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError("path must be string")
|
||||
|
||||
case _:
|
||||
raise ValueError(
|
||||
f"Unknown filesystem action: {action}"
|
||||
)
|
||||
return safety.validate_path(path_value)
|
||||
|
||||
# =========================
|
||||
# READ FILE
|
||||
# =========================
|
||||
|
||||
def read_file(
|
||||
self,
|
||||
payload: dict[str, Any]
|
||||
):
|
||||
path_value = payload.get("path")
|
||||
def read_file(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
path = self._get_path(payload)
|
||||
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError("path must be string")
|
||||
data = path.read_text(encoding="utf-8")
|
||||
|
||||
path = safety.validate_path(path_value)
|
||||
if len(data.encode("utf-8")) > self.MAX_READ_BYTES:
|
||||
raise ValueError("File exceeds read size limit")
|
||||
|
||||
return {
|
||||
"path": str(path),
|
||||
"content": path.read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
}
|
||||
return {"path": str(path), "content": data}
|
||||
|
||||
# =========================
|
||||
# WRITE FILE
|
||||
# =========================
|
||||
|
||||
def write_file(
|
||||
self,
|
||||
payload: dict[str, Any]
|
||||
):
|
||||
path_value = payload.get("path")
|
||||
content_value = payload.get("content")
|
||||
def write_file(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
path = self._get_path(payload)
|
||||
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError("path must be string")
|
||||
content = payload.get("content")
|
||||
if not isinstance(content, str):
|
||||
raise ValueError("content must be string")
|
||||
|
||||
if not isinstance(content_value, str):
|
||||
raise ValueError(
|
||||
"content must be string"
|
||||
)
|
||||
safety.check_file_write(path, content)
|
||||
|
||||
path = safety.validate_path(path_value)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
safety.check_file_write(
|
||||
path,
|
||||
content_value
|
||||
)
|
||||
if path.exists():
|
||||
backup = path.with_suffix(path.suffix + ".bak")
|
||||
try:
|
||||
backup.write_text(path.read_text(encoding="utf-8"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
path.parent.mkdir(
|
||||
parents=True,
|
||||
exist_ok=True
|
||||
)
|
||||
|
||||
path.write_text(
|
||||
content_value,
|
||||
encoding="utf-8"
|
||||
)
|
||||
path.write_text(content, encoding="utf-8")
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
"path": str(path),
|
||||
"bytes_written": len(
|
||||
content_value.encode("utf-8")
|
||||
)
|
||||
"bytes_written": len(content.encode("utf-8"))
|
||||
}
|
||||
|
||||
# =========================
|
||||
# LIST DIRECTORY
|
||||
# =========================
|
||||
|
||||
def list_dir(
|
||||
self,
|
||||
payload: dict[str, Any]
|
||||
):
|
||||
path_value = payload.get(
|
||||
"path",
|
||||
"."
|
||||
)
|
||||
def list_dir(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
path = self._get_path(payload)
|
||||
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError(
|
||||
"path must be string"
|
||||
)
|
||||
entries = []
|
||||
for i, item in enumerate(path.iterdir()):
|
||||
if i >= self.MAX_LIST_ENTRIES:
|
||||
break
|
||||
|
||||
path = safety.validate_path(
|
||||
path_value
|
||||
)
|
||||
|
||||
entries: list[dict[str, Any]] = []
|
||||
|
||||
for item in path.iterdir():
|
||||
entries.append(
|
||||
{
|
||||
"name": item.name,
|
||||
"path": str(item),
|
||||
"is_dir": item.is_dir(),
|
||||
"is_file": item.is_file()
|
||||
}
|
||||
)
|
||||
entries.append({
|
||||
"name": item.name,
|
||||
"path": str(item),
|
||||
"is_dir": item.is_dir(),
|
||||
"is_file": item.is_file()
|
||||
})
|
||||
|
||||
return {
|
||||
"path": str(path),
|
||||
@@ -164,20 +128,8 @@ class FilesystemTool(BaseTool):
|
||||
# EXISTS
|
||||
# =========================
|
||||
|
||||
def exists(
|
||||
self,
|
||||
payload: dict[str, Any]
|
||||
):
|
||||
path_value = payload.get("path")
|
||||
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError(
|
||||
"path must be string"
|
||||
)
|
||||
|
||||
path = safety.validate_path(
|
||||
path_value
|
||||
)
|
||||
def exists(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
path = self._get_path(payload)
|
||||
|
||||
return {
|
||||
"path": str(path),
|
||||
@@ -190,25 +142,10 @@ class FilesystemTool(BaseTool):
|
||||
# MKDIR
|
||||
# =========================
|
||||
|
||||
def mkdir(
|
||||
self,
|
||||
payload: dict[str, Any]
|
||||
):
|
||||
path_value = payload.get("path")
|
||||
def mkdir(self, payload: dict[str, Any], ctx: ToolContext):
|
||||
path = self._get_path(payload)
|
||||
|
||||
if not isinstance(path_value, str):
|
||||
raise ValueError(
|
||||
"path must be string"
|
||||
)
|
||||
|
||||
path = safety.validate_path(
|
||||
path_value
|
||||
)
|
||||
|
||||
path.mkdir(
|
||||
parents=True,
|
||||
exist_ok=True
|
||||
)
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
return {
|
||||
"ok": True,
|
||||
@@ -216,10 +153,4 @@ class FilesystemTool(BaseTool):
|
||||
}
|
||||
|
||||
|
||||
# =========================
|
||||
# SELF REGISTER
|
||||
# =========================
|
||||
|
||||
registry.register(
|
||||
FilesystemTool()
|
||||
)
|
||||
registry.register(FilesystemTool())
|
||||
Reference in New Issue
Block a user
