maf-sandbox-deepagents
Experimental. The API may change without notice. Importing the package emits
MafSandboxDeepagentsExperimentalWarning.
Use a SandboxRouter as a Deep Agents sandbox. MafSandbox connects Deep Agents' command and file tools to a backend such as Docker or ACAS. The router enforces the host's isolation floor and the spec's capabilities and network policy.
This is a third-party integration, not a product of or endorsed by LangChain, Inc. or Microsoft.
deepagents -> maf_sandbox_deepagents -> maf_sandbox (router) -> a backend -> the sandbox
Quickstart
pip install maf-sandbox-deepagents maf-sandbox-docker
from deepagents import create_deep_agent
from maf_sandbox import Isolation, SandboxKey, SandboxRouter
from maf_sandbox_deepagents import MafSandbox, deepagents_spec
from maf_sandbox_docker import DockerSandboxBackend, DockerSandboxConfig
router = SandboxRouter([DockerSandboxBackend(DockerSandboxConfig())], min_isolation=Isolation.CONTAINER)
spec = deepagents_spec("python:3.12-alpine")
# Derive these identifiers from trusted host request context.
sandbox = MafSandbox(router, SandboxKey(scope="tenant-a", thread_id="thread-1", agent_id="coder"), spec)
agent = create_deep_agent(model=..., backend=sandbox, system_prompt=f"Work under {spec.work_dir}.")
Use a host-derived key per agent and conversation. The adapter requires conversation scope and an empty key.call_id. Its default kind is deepagents, separate from packaged kinds using the same conversation.
deepagents_spec requires EXEC, FILES_IN and FILES_OUT. An empty egress_allow selects CLOSED; named hosts select ALLOWLIST. UNRESTRICTED is refused, including on a manually constructed spec.
The working directory must be an explicit absolute POSIX path. work_dir=None is refused because the host must tell the model where its files live. Construction checks the spec and router; the first operation acquires the actual sandbox.
sandbox.id identifies the adapter using the key, kind, backend and network policy. It is not the physical instance ID used by the operator console.
Commands
| Setting | Contract |
|---|---|
| Execution | Model-supplied shell string through BoundedExec.exec_bounded |
| Working directory | ".", resolved by the backend to the configured base |
| Default deadline | 120 seconds, including admission and cold acquisition |
| Default output cap | 1 MiB combined stdout/stderr, enforced by the backend before buffering |
| Result | Text with guest stderr prefixed by [stderr], or producer-owned stderr by [note]; rendering that exceeds the cap is dropped |
| Overflow | Drop the output and return truncated=True; never return a partial successful result |
A backend without BoundedExec runs no command. Provider details stay in host logs; failures returned to the model use fixed messages. A timeout means the wait ended, not that guest execution is known to have stopped.
The model controls the shell. Backend isolation and network policy apply, but the packaged kinds' fixed-command behavior does not. Keep credentials out of the image.
Files and paths
Deep Agents' file tools use absolute guest paths. Adapter uploads and downloads also accept relative paths beneath the configured base.
| Path | Upload | Download |
|---|---|---|
| Inside the base | write_file |
stat_file, then read_file |
| Outside the base | write_file_over_exec |
read_file_over_exec |
The outside-base route supports paths such as /conversation_history/ and /tmp/. It uses the same guest authority already available to execute. Uploads stage chunks in a sibling file, then move the completed file into place.
Both routes enforce spec.files_in or spec.files_out. A batch above max_files is refused whole. A file above its per-file cap or remaining total budget is refused individually. Downloads refuse oversize results rather than truncate them.
| File condition | Response |
|---|---|
| Missing file | file_not_found |
| Directory requested as a file | is_directory |
| Link under the base, invalid traversal or non-directory parent | invalid_path |
| Unsearchable parent or unreadable file | permission_denied |
A native stat/read timeout fails that file alone and leaves the sandbox available. An unfinished write or shell transfer requires disposal. An unfinished upload invalidates the batch; an unfinished shell download stops the remaining downloads.
Lifetime and cleanup
Successful operations keep the sandbox warm across conversation turns. Timeout, backend output overflow, cancellation or a missing command result queues disposal because guest completion is uncertain. Overflow caused only by formatting a completed result drops that result without requiring disposal.
The router coordinates overlapping calls. Adapter-queued deletion waits for the last call already allowed to run, and later calls wait for cleanup. A backend can independently invalidate the whole sandbox on failure; its own timeout and cancellation contract still applies.
After unfinished work, release and cleanup run on the process-owned SyncRunner loop. They can outlive the caller's loop and do not extend its response wait. Failed cleanup is not permission to reuse the instance.
await sandbox.aclose() takes exclusive admission, then disposes the exact instance this adapter acquired. It returns False when closure cannot be confirmed. Before acquisition, there is nothing to delete. Other kinds and replacements remain separate.
Wire router.dispose_scope(scope, thread_id) into the host's conversation-delete path. LangGraph thread deletion does not call it automatically. The adapter uses disposal, not per-operation reclamation or reset.
Async methods are native. Synchronous methods run the same coroutines through one shared SyncRunner thread and event loop per process. A forked child starts its own runner.
Requirements and limits
- Python 3.12–3.14 and Deep Agents 0.7.x.
- A backend declaring
EXEC,FILES_INandFILES_OUT, with bounded execution. Docker and ACAS provide this; WSLC lacks output reads. - Guest commands
sh,mkdir,mv,rm,base64andwcfor outside-base transfers. Missing commands can fail at transfer time. python3for Deep Agents' derivedls,read_file,write_file,edit_file,globandgreptools. Without it, direct execution, shell deletion and adapter uploads/downloads remain available.
This adapter does not supply MAF information-flow labels, automatic hiding, per-call guest directories, declared outputs with a landing sink, or guest-to-host tool calls. Those are the packaged kinds' contracts.
The Docker Bicep sample shows the complete integration with a model.
Release files for maf-sandbox-deepagents 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| maf_sandbox_deepagents-0.4.1.tar.gz | 17.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| maf_sandbox_deepagents-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.8 kB
Release files / maf_sandbox_deepagents-0.4.1.tar.gz
| Download URL | maf_sandbox_deepagents-0.4.1.tar.gz |
|---|---|
| Size | 17.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e3fd0c8fec6da3958bbe64e317934c7118120d710b9f8e551b1d3ae9b87d897e
|
|
BLAKE2b-256 checksum How to use checksums |
e48415c16806a5301ce68cf6c358dccbafa1a6544c62e8aec1170d770bddfda2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / maf_sandbox_deepagents-0.4.1-py3-none-any.whl
| Download URL | maf_sandbox_deepagents-0.4.1-py3-none-any.whl |
|---|---|
| Size | 18.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
81757a173b077ad952a05e97bbf55a7ed14e1643d84bdc22f83f9dec73bcbff6
|
|
BLAKE2b-256 checksum How to use checksums |
5d8c239e149db710f60a0fbe755593d09cd5a993f42e4c2e62a5411d49f84b68
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log