How to Use the File Toolkit in aisuite: A Complete Guide to Filesystem Tools
The aisuite file toolkit is a collection of filesystem tools that enables agents to read, list, search, and modify files within sandboxed root directories through the files() function in aisuite/toolkits/files.py.
The aisuite file toolkit provides controlled filesystem access for LLM-driven agents, allowing safe interaction with directories and files while enforcing strict security boundaries. As implemented in the andrewyng/aisuite repository, this toolkit wraps filesystem operations with safety guards and metadata, making it suitable for production agent workflows.
Core Concepts and Configuration
Root Directory Configuration
The entry point for the file toolkit is the public function files() defined in aisuite/toolkits/files.py【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L22-L31】. This function requires either a single root path or a list of roots where each entry can be a path string or a dictionary specifying {"path": "...", "writable": bool}.
The first root in the list serves as the primary root used for relative path resolution. According to the source code, the FileToolkit stores a reference to the supplied roots and recomputes resolved paths on each call, allowing dynamic modification of the root list without rebuilding the toolkit【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L39-L45】.
Read-Only vs. Writable Operations
By default, the file toolkit exposes only read-only tools. Write-related tools—including write_file, apply_unified_diff, apply_patch, and replace_in_file—become available only when allow_write=True or when any supplied root is marked writable【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L27-L38】【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L48-L51】.
Safety Guards and Limits
The toolkit implements multiple security measures to prevent abuse:
- Path traversal protection: Every access is resolved against declared roots and rejected if it escapes them【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L75-L85】.
- Read size limits: Reads are capped at
max_read_bytes(default 200 kB) and searches atmax_search_bytes(default 1 MB) to prevent denial-of-service attacks. - Ignore list filtering: A default ignore list automatically excludes noisy directories like
git, caches, andnode_modules【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L9-L19】.
Available File Tools
The files() function returns a list of callables wrapped as aisuite-compatible tools, each carrying ToolMetadata describing category, risk level, and capabilities【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L94-L108】.
Listing and Reading Files
list_files(path=".", pattern="*", recursive=True, max_results=100): Returns a sorted list of relative file paths matching the glob pattern.read_file(path): Reads a UTF-8 text file up tomax_read_bytesand returns contents as a string.read_file_lines(path, start_line=1, max_lines=100): Returns a dictionary with selected line range, total line count, and extracted text.
Searching File Contents
search_files(query, path=".", pattern="*", max_results=50): Performs grep-style search across UTF-8 files under the root, returning a list of dictionaries containingpath,line, andtext.
Writing and Modifying Files
These tools require writable roots:
write_file(path, content, overwrite=True): Writes or overwrites UTF-8 files within writable root boundaries.apply_unified_diff(diff): Applies classic unified-diff patches (standarddiff -uformat).apply_patch(patch): Applies Codex-style patches using BEGIN/END markers supporting add, delete, and update operations.replace_in_file(path, old, new, expected_replacements=1): Performs string replacement, rejecting operations where match counts differ from expectations.
Integration with aisuite Agents
Attaching Tools to an Agent
When creating an Agent instance, pass the toolkit as the tools parameter:
import aisuite as ai
agent = ai.Agent(
model="openai:gpt-4",
tools=ai.toolkits.files(root="/my/project", allow_write=True)
)
The Agent (or ai.Client) surfaces these wrapped callables to the LLM and enforces approval flows for write operations.
Tool Metadata and Approval Flows
Each tool carries metadata including category (filesystem), risk level (low or medium), and capability lists. The tracing subsystem uses this metadata to surface tool usage in the UI and determine whether human approval is required before execution【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L120-L138】.
Practical Code Examples
Example 1: Read-Only File Operations
from aisuite import toolkits
# Create a read-only toolkit rooted at /tmp/project
fs_tools = toolkits.files(root="/tmp/project")
# Access specific tools by name
list_files = next(t for t in fs_tools if t.__name__ == "list_files")
read_file = next(t for t in fs_tools if t.__name__ == "read_file")
# List all Python files under the root
py_files = list_files(pattern="*.py")
print("Python files:", py_files)
# Read the first file
content = read_file(py_files[0])
print("First file content:", content[:200])
Example 2: Writable File Operations with Multiple Roots
from aisuite import toolkits
# Configure two roots, one writable, one read-only
roots = [
{"path": "/tmp/project", "writable": False},
{"path": "/tmp/project/generated", "writable": True},
]
# Build the toolkit (write tools exposed because at least one root is writable)
fs_tools = toolkits.files(roots=roots, allow_write=True)
# Grab the write tool
write_file = next(t for t in fs_tools if t.__name__ == "write_file")
# Write a new file
new_path = write_file("generated/hello.txt", "Hello, aisuite!", overwrite=False)
print("Created:", new_path)
Example 3: Applying a Unified Diff
from aisuite import toolkits
fs = toolkits.files(root="/tmp/project", allow_write=True)
apply_diff = next(t for t in fs if t.__name__ == "apply_unified_diff")
# Simple diff that adds a line to README.md
diff = """--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
# Project
Some description
+Additional line added by diff
"""
result = apply_diff(diff)
print("Patch result:", result)
Summary
- Entry point: The
files()function inaisuite/toolkits/files.pycreates aFileToolkitinstance and wraps methods as aisuite-compatible tools. - Root configuration: Supports single paths or multiple roots with writable flags; first root is primary for relative path resolution.
- Security: Path traversal prevention, size limits (200 kB read, 1 MB search), and automatic filtering of ignored directories protect against abuse.
- Write access: Disabled by default; enable via
allow_write=Trueor writable root flags to exposewrite_file,apply_unified_diff,apply_patch, andreplace_in_file. - Integration: Pass the toolkit list directly to
Agenttools parameter; metadata automatically handles risk classification and approval flows.
Frequently Asked Questions
How do I enable write access in the aisuite file toolkit?
Write access is enabled by either setting allow_write=True when calling files() or by marking at least one root as writable using {"path": "...", "writable": True}. When enabled, the toolkit exposes write_file, apply_unified_diff, apply_patch, and replace_in_file tools with appropriate metadata flags for approval workflows.
What prevents the file toolkit from accessing files outside the root directory?
The toolkit implements path traversal protection in the _resolve method within aisuite/toolkits/files.py, which validates every path against declared roots and rejects operations that attempt to escape the sandbox boundaries【https://github.com/andrewyng/aisuite/blob/main/aisuite/toolkits/files.py#L75-L85】.
How do I apply a unified diff using the file toolkit?
First, create a writable toolkit instance with allow_write=True, then retrieve the apply_unified_diff tool from the returned list. Pass a valid unified diff string (standard diff -u format) to the tool, and it will apply the changes to the specified files under the root directory.
What is the maximum file size the toolkit will read?
By default, the toolkit limits individual file reads to 200 kB via max_read_bytes, while search operations are limited to 1 MB via max_search_bytes. These defaults prevent memory exhaustion and can be adjusted by passing alternative values to the files() constructor when creating the toolkit.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →