Files
secure-agent/tools/files.py
T

79 lines
2.2 KiB
Python

import asyncio
from pathlib import Path
async def read_file(filepath: str, sandbox=None) -> str:
"""Read a file from workspace."""
if sandbox is None:
return "Error: No sandbox available"
try:
result = await asyncio.to_thread(sandbox.run, f"cat {filepath}")
return result
except Exception as e:
return f"Error reading file: {e}"
async def write_file(filepath: str, content: str, sandbox=None) -> str:
"""Write content to a file."""
if sandbox is None:
return "Error: No sandbox available"
# Validate path
if filepath.startswith("/") or ".." in filepath:
return f"Error: Invalid path '{filepath}'. Use relative paths within workspace."
try:
# Escape content for shell
escaped = content.replace("'", "'\\''")
# Create parent dirs if needed
parent = str(Path(filepath).parent)
if parent and parent != ".":
await asyncio.to_thread(sandbox.run, f"mkdir -p {parent}")
# Write file
await asyncio.to_thread(
sandbox.run, f"cat > {filepath} << 'EOF'\n{content}\nEOF"
)
return f"✓ Wrote {filepath}"
except Exception as e:
return f"Error writing file: {e}"
# Schemas
READ_FILE_SCHEMA = {
"name": "read_file",
"description": "Read the contents of a file from the workspace",
"input_schema": {
"type": "object",
"properties": {
"filepath": {
"type": "string",
"description": "Path to file relative to workspace (e.g., 'app.py', 'src/utils.py')",
}
},
"required": ["filepath"],
},
}
WRITE_FILE_SCHEMA = {
"name": "write_file",
"description": "Write content to a file in the workspace. Creates parent directories if needed.",
"input_schema": {
"type": "object",
"properties": {
"filepath": {
"type": "string",
"description": "Path to file relative to workspace (e.g., 'app.py', 'data/config.json')",
},
"content": {
"type": "string",
"description": "Content to write to the file",
},
},
"required": ["filepath", "content"],
},
}