List all files in a directory with metadata.
Async version of ls.
Read file content for the requested line range.
Implementations must tolerate degenerate windows rather than raising:
a negative offset reads from the first line, and a non-positive
limit returns empty content with every pagination field unset.
deepagents.backends.utils.normalize_read_bounds clamps both bounds for
implementations that slice in Python.
Implementations must also set start_line whenever they return
line-numberable text. The middleware falls back to deriving the gutter
from offset when start_line is unset, which only yields a valid
1-indexed gutter for windows the backend actually sliced.
Async version of read.
Search for a literal text pattern in files.
Async version of grep.
Wraps the sync call with an async timeout as a safety net. The timeout
bounds how long the caller waits; it does not stop the worker thread
created by asyncio.to_thread.
max_count is forwarded when the concrete grep accepts it (so the
search can bound itself); backends that don't accept it run uncapped and
are trimmed afterward. Either way the return value is always passed
through _apply_grep_max_count (a no-op when already within the cap), so
callers get the same guarantee regardless of which path runs.
Find files matching a glob pattern.
Pattern matching follows the shared backend contract (aligned with grep include-glob, not classic non-recursive shell globbing):
Patterns without / match the basename at any depth under path.
Example: *.py matches src/app/main.py.
Patterns containing / match paths relative to the search root, with
** support.
Example: src/**/*.py matches src/app/main.py.
A leading / anchors the pattern to the search root; it narrows the
match rather than widening it.
Example: /*.py matches top.py but not src/app/main.py.
Leading-dot names match only when the pattern segment itself starts
with .. Since ** will not descend into dot-directories, a bare
pattern is broader than its **/ form.
Example: *.yml matches .github/workflows/ci.yml; **/*.yml
does not. .env matches .env; * does not.
Only regular files are returned; directories are never matched.
Async version of glob.
Write content to a file, creating it or overwriting it if it already exists.
Async version of write.
Perform exact string replacements in an existing file.
Async version of edit.
Delete a path, recursively removing anything nested under it.
This method is optional. Backends that do not implement it inherit this
default, which raises NotImplementedError. Callers that need to support
a mix of backends should guard with
supports_delete before
calling, or catch NotImplementedError.
Deletion is recursive: it removes file_path plus everything nested
under it. On hierarchical backends (e.g.
FilesystemBackend)
that means a directory and its contents; on key-value backends it means
the exact key plus every key sharing the file_path + "/" prefix.
Async version of delete.
Upload multiple files to the sandbox.
This API is designed to allow developers to use it either directly or by exposing it to LLMs via custom tools.
Async version of upload_files.
Download multiple files from the sandbox.
This API is designed to allow developers to use it either directly or by exposing it to LLMs via custom tools.
Async version of download_files.
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
}