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:

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 to max_read_bytes and 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 containing path, line, and text.

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 (standard diff -u format).
  • 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 in aisuite/toolkits/files.py creates a FileToolkit instance 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=True or writable root flags to expose write_file, apply_unified_diff, apply_patch, and replace_in_file.
  • Integration: Pass the toolkit list directly to Agent tools 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →