Middleware for providing filesystem tools to an agent.
Why a GlobResult is incomplete.
The distinction decides what advice is useful to the caller:
budget: the walk hit its time limit or match cap. Narrowing the pattern or
the path surfaces the rest.unreadable: a subtree could not be read (e.g. permissions). Narrowing will
never surface those files, so advising it sends the caller in a loop.transport: the sandbox transport clipped the output.Maximum raw video payload size accepted by read_file frame extraction.
Classification of a file by extension.
Classification of filesystem tools as read-only or mutating.
Reported when a read requested zero lines.
Distinct from EMPTY_CONTENT_WARNING on purpose: the read_file description
teaches the model that the empty-contents reminder means the file itself is
empty, so reusing it for a zero-line window would state something false about
the filesystem that a following write_file could act on destructively.
Backends declare the zero-line window with ReadResult.no_lines_requested,
so an inspected-but-empty file (which otherwise arrives identically: empty
content, no pagination metadata) keeps the empty-file reminder instead.
Names of the built-in filesystem tools that can be passed to FilesystemMiddleware(tools=...).
Check whether a backend class's execute accepts a timeout kwarg.
Older backend packages didn't lower-bound their SDK dependency, so they
may not accept the timeout keyword added to
SandboxBackendProtocol.
Results are cached per class to avoid repeated introspection overhead.
Check if content is empty and return warning message.
Format file content with line numbers.
Chunks lines longer than MAX_LINE_LENGTH with continuation markers
(e.g., 5.1, 5.2). Line markers are separated from source content
with two spaces so source tabs cannot be confused with a gutter separator.
Format structured grep matches using existing formatting logic.
Return a hint when a pattern looks like an (unsupported) regex.
grep matches literal text, so regex metacharacters are searched verbatim
and silently miss. Callers gate this on a no-match result; the function
itself only inspects the pattern.
Sanitize tool_call_id to prevent path traversal and separator issues.
Replaces dangerous characters (., /, ) with underscores.
Truncate list or string result if it exceeds token limit (rough estimate: 4 chars/token).
Validate and normalize file path for security.
Ensures paths are safe to use by preventing directory traversal attacks and enforcing consistent formatting. All paths are normalized to use forward slashes and start with a leading slash.
This function is designed for virtual filesystem paths and rejects
Windows absolute paths (e.g., C:/..., F:/...) to maintain consistency
and prevent path format ambiguity.
Append text to a system message.
Decode sampled frames from a video byte payload.
Return whether the optional video dependencies appear to be installed.
Uses importlib.util.find_spec, which checks that av and Pillow are
discoverable rather than performing a full import. A discoverable but
broken install (e.g. a compiled extension that fails to load) is reported as
available here and surfaces later, at actual extraction time, as a
VideoExtractionError carrying MISSING_VIDEO_HINT.
Check if a backend supports command execution.
For CompositeBackend,
checks if the default backend supports execution.
For other backends, checks if they implement
SandboxBackendProtocol.
Routes file operations to different backends by path prefix.
Matches paths against route prefixes (longest first) and delegates to the corresponding backend. Unmatched paths use the default backend.
Backend that reads and writes files directly from the filesystem.
Files are accessed using their actual filesystem paths. Relative paths are resolved relative to the current working directory. Content is read/written as plain text, and metadata (timestamps) are derived from filesystem stats.
This backend grants agents direct filesystem read/write access. Use with caution and only in appropriate environments.
Appropriate use cases:
Inappropriate use cases:
StateBackend, StoreBackend, or
SandboxBackend insteadSecurity risks:
.env files)Recommended safeguards:
StateBackend, StoreBackend or SandboxBackendIn general, we expect this backend to be used with Human-in-the-Loop (HITL) middleware, or within a properly sandboxed environment if you need to run untrusted workloads.
virtual_mode=True is primarily for virtual path semantics (for example with
CompositeBackend). It can also provide path-based guardrails by blocking
traversal (.., ~) and absolute paths outside root_dir, but it does not
provide sandboxing or process isolation. Set virtual_mode=False only for
trusted local development workflows that require unrestricted host paths.
Filesystem backend with unrestricted local shell command execution.
This backend extends FilesystemBackend to add shell command execution
capabilities. Commands are executed directly on the host system without any
sandboxing, process isolation, or security restrictions.
This backend grants agents BOTH direct filesystem access AND unrestricted shell execution on your local machine. Use with extreme caution and only in appropriate environments.
Appropriate use cases:
Inappropriate use cases:
Use StateBackend, StoreBackend, or extend BaseSandbox for production.
Security risks:
.env files, SSH keys, etc.)Recommended safeguards:
Since shell access is unrestricted and can bypass filesystem restrictions:
BaseSandbox
to create a properly isolated backend (Docker containers, VMs, or
other sandboxed execution environments)virtual_mode=True and path-based restrictions provide NO security
with shell access enabled, since commands can access any path on
the system
Backend that stores files in agent state (ephemeral).
Uses LangGraph's state management and checkpointing. Files persist within a conversation thread but not across threads. State is automatically checkpointed after each agent step.
Reads and writes go through LangGraph's CONFIG_KEY_READ /
CONFIG_KEY_SEND so that state updates are applied as channel writes
to the files state key.
Result from backend delete operations.
Result from backend edit operations.
Machine-readable metadata attached to an execute tool result.
Carried on ToolMessage.artifact alongside the model-facing content, so
callers can react to shell failures. artifact is None instead when no
command ran -- a validation or unsupported-backend error, where
ToolMessage.status is "error".
Note that status is "success" for any command that ran, including one
that exited non-zero: the model is expected to read the output and decide
what to do. Use exit_code, not status, to detect command failure.
Result of BaseSandbox.execute_with_offload.
offloaded describes the capture mechanism and is kept off ExecuteResponse
(which an ordinary execute never sets).
Result of code execution.
Simplified schema optimized for LLM consumption.
Data structure for storing file contents with metadata.
Structured file listing info.
Minimal contract used across backends. Only path is required.
Other fields are best-effort and may be absent depending on backend.
Result from backend glob operations.
A single match from a grep search.
Result from backend grep operations.
Result from backend ls operations.
Result from backend read operations.
Extension of BackendProtocol that adds shell command execution.
Designed for backends running in isolated environments (containers, VMs, remote hosts).
Adds execute()/aexecute() for shell commands and an id property.
See BaseSandbox for a base class that implements all inherited file
operations by delegating to execute().
Result from backend write operations.
Base sandbox implementation with execute() as the core abstract method.
This class provides default implementations for all protocol methods.
File listing, grep, and glob use shell commands via execute(). Read uses
a server-side Python script via execute() for paginated access. Write
delegates content transfer to upload_files(). Edit uses a server-side
script for small payloads and uploads old/new strings as temp files with
a server-side replace for large ones.
BaseSandbox does not reduce or partition the trust boundary of
execute(). Its helper methods are convenience wrappers built on top of
the subclass-provided command-execution primitive and assume callers who
can use BaseSandbox already have whatever shell-execution capability
that backend exposes.
Subclasses must implement execute(), upload_files(), download_files(),
and the id property.
Raised when PyAV cannot produce frames for the requested window.
A single access rule for filesystem operations.
State for the filesystem middleware.
Input schema for the ls tool.
Input schema for the read_file tool.
Input schema for read_file when the optional video frame extraction is available.
Identical to ReadFileSchema; only the offset/limit descriptions differ
to document their video semantics (interpreted as seconds for video reads).
Input schema for the write_file tool.
Input schema for the edit_file tool.
Input schema for the delete tool.
Input schema for the glob tool.
Input schema for the grep tool.
Input schema for the execute tool.
Middleware for providing filesystem and optional execution tools to an agent.
This middleware adds filesystem tools to the agent: ls, read_file, write_file,
edit_file, glob, and grep.
Files can be stored using any backend that implements the
BackendProtocol.
If the backend implements
SandboxBackendProtocol,
an execute tool is also added for running shell commands. Its results carry
ExecuteArtifact metadata on
ToolMessage.artifact.
This middleware also automatically evicts large tool results to the file system when they exceed a token threshold, preventing context window saturation.
Protocol for pluggable memory backends (single, unified).
Backends can store files in different locations (state, filesystem, database, etc.) and provide a uniform interface for file operations.
File operations (grep, glob, ls, read, etc.) live on this base
protocol rather than only on SandboxBackendProtocol because not every
backend has a shell. StateBackend and StoreBackend store files in
in-memory state or a remote store with no process to exec into, so they
implement grep/glob in pure Python and have no execute at all.
Even on shell-capable backends, the tools are not just convenience
wrappers around execute: they enforce literal-only matching (not
regex), return structured GrepResult/GlobResult objects, support
max_count truncation, and pass through filesystem permission rules —
none of which raw execute + shell grep/find provides. Agent-facing
prompt guidance should therefore recommend these tools only when they
are actually registered, and never assume a shell is available as a
fallback.
All file data is represented as dicts with the following structure:
{
"content": str, # Text content (utf-8) or base64-encoded binary
"encoding": str, # "utf-8" for text, "base64" for binary data
"created_at": str, # ISO format timestamp
"modified_at": str, # ISO format timestamp
}