"""Filesystem agent — tools for reading local directories and files on Electron. These tools delegate to the Electron client via ``execute_on_client()`` using the same WS tool-call round-trip pattern as CRUD tools. The Electron app handles actual disk I/O and responds with ``tool_result`` frames. """ from __future__ import annotations from typing import Any from langchain_core.tools import tool from app.core.ws_context import execute_on_client @tool async def list_directory(path: str) -> str: """List files and folders in a local directory on the user's device. Returns a formatted listing of entries with name, type (file/directory), and full path. """ result = await execute_on_client( action="list_directory", data={"path": path}, ) entries: list[dict[str, Any]] = result.get("entries", []) if not entries: return f"Directory '{path}' is empty or does not exist." lines: list[str] = [] for entry in entries: entry_type = entry.get("type", "unknown") entry_name = entry.get("name", "") entry_path = entry.get("path", "") lines.append(f"- [{entry_type}] {entry_name} ({entry_path})") return f"Directory listing for '{path}' ({len(entries)} entries):\n" + "\n".join(lines) @tool async def read_file_content(path: str) -> str: """Read the text content of a local file on the user's device. Returns the file content as a string. Large files may be truncated by the Electron client. """ result = await execute_on_client( action="read_file_content", data={"path": path}, ) content: str = result.get("content", "") if not content: return f"File '{path}' is empty or could not be read." return content @tool async def get_file_metadata(path: str) -> str: """Get metadata for a local file: size, creation date, modification date, extension. Returns a formatted summary of the file's metadata. """ result = await execute_on_client( action="get_file_metadata", data={"path": path}, ) size = result.get("size", "unknown") created = result.get("createdAt", "unknown") modified = result.get("modifiedAt", "unknown") extension = result.get("extension", "unknown") name = result.get("name", path) return ( f"File: {name}\n" f" Extension: {extension}\n" f" Size: {size} bytes\n" f" Created: {created}\n" f" Modified: {modified}" ) FILESYSTEM_TOOLS: list[Any] = [ list_directory, read_file_content, get_file_metadata, ]