langchain-opensandbox
OpenSandbox backend for LangChain deep agents.
OpenSandbox is an Apache-2.0 sandbox runtime for AI agents that you host yourself — Docker or
Kubernetes, your hardware, no per-second billing and no account. This package makes one usable as a
deep agent's filesystem and shell, the same way langchain-e2b, langchain-modal and
langchain-daytona do for their hosted providers.
pip install langchain-opensandbox
Quickstart
from deepagents import create_deep_agent
from opensandbox.sync.sandbox import SandboxSync
from langchain_opensandbox import OpenSandboxSandbox
sandbox = SandboxSync.create("python:3.11-slim")
agent = create_deep_agent(
model="anthropic:claude-sonnet-4-5",
backend=OpenSandboxSandbox(sandbox=sandbox),
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Write fib.py and run it for n=30."}]}
)
OpenSandboxSandbox implements deepagents' SandboxBackendProtocol by subclassing BaseSandbox, so
the agent gets ls / read_file / write_file / edit_file / grep / glob and the execute
shell tool. You own the sandbox's lifetime: create it, and kill() it when you're done.
Managed sandboxes for LangGraph
The above leaves sandbox lifecycle to you, which is awkward in a server where each conversation
should get its own container. langchain_opensandbox.factory handles that: it tags a sandbox with
the current LangGraph thread_id at creation and finds it again on every later call, so one
conversation reuses one container and parallel conversations stay isolated.
from langchain_opensandbox.factory import get_backend
agent = create_deep_agent(model=model, backend=get_backend)
get_backend performs no I/O. That matters more than it sounds: deepagents resolves the backend
on every model call — FilesystemMiddleware has to know whether to expose the execute tool — so a
factory that connects eagerly pays a sandbox lookup per model call, synchronously, on the event loop.
(ASGI servers object, correctly: langgraph dev refuses the blocking socket.connect unless you pass
--allow-blocking.) What you get back is a LazyOpenSandboxSandbox, which connects on the first
operation the agent actually performs, and serves the async half of the protocol from the async
OpenSandbox client rather than a worker thread. A model call that never touches the sandbox costs
nothing at all.
If the sandbox has since died (timeout, crash) a fresh one is created transparently on the next call. In-sandbox state — installed packages, written files — does not survive that.
For a plain ReAct agent that wants code execution without adopting the deep-agent filesystem, there is also a standalone tool driving the same thread-scoped sandbox:
from langchain.agents import create_agent
from langchain_opensandbox.tools import execute_python
agent = create_agent(model, tools=[execute_python])
Settings
factory resolves connection settings per call. For each field the first value found wins: the
environment variable, then the same lower-cased key in the run's config["configurable"], then the
default.
| Env var | Default | Meaning |
|---|---|---|
OPENSANDBOX_URL |
localhost:8080 |
Server address (host:port). |
OPENSANDBOX_API_KEY |
— | API key; omit if the server has no auth. |
OPENSANDBOX_IMAGE |
python:3.11-slim |
Image for new containers. Use one with your libraries pre-installed for faster startup. |
OPENSANDBOX_USE_SERVER_PROXY |
true |
Route sandbox traffic through the server rather than dialling container ports directly. Keep it on for Docker Swarm / bridge-network deployments where those ports are unreachable; set false only for host/flat networks, where direct is faster. |
This package does not read .env files — that is an application's decision. Load one in your own
entrypoint if you want it.
Package layout
backend.py and config.py are provider-neutral: they take no LangGraph runtime, config or thread,
so the backend is drivable from a plain script or a test — LazyOpenSandboxSandbox takes two plain
connect callables, not a runtime. factory.py and tools.py are the LangGraph-specific half and are
imported explicitly rather than re-exported from the package root.
tests/test_package_boundary.py enforces the split.
(LangGraph is imported into your process either way — deepagents depends on langchain, which
depends on langgraph. The boundary is about API surface, not about saving a dependency.)
Compatibility
- Python ≥ 3.11 (deepagents' floor).
- deepagents
>=0.6.12,<0.7. The cap is load-bearing forfactory.pyonly:get_backendis aBackendFactory(deepagents.backends.protocol.BackendFactory), a type alias that deepagentsmainhas since dropped.backend.pydepends on nothing butBaseSandboxand will outlive it. - opensandbox
>=0.1.15.
Development
pip install -e ".[dev]"
ruff check src/ tests/ && ruff format --check src/ tests/
mypy src/
pytest
The suite mocks the OpenSandbox client, so it needs no server. To exercise the wire protocol, run a
server (docker run -d -p 8080:8080 ghcr.io/alibaba/opensandbox/server:latest) and drive an agent
against it.
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langchain_opensandbox-0.1.0.tar.gz.
File metadata
- Download URL: langchain_opensandbox-0.1.0.tar.gz
- Upload date:
- Size: 24.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
135b489040f6d151b3ace09a125c427d129f56fa442621d160490d88bdaeb214
|
|
| MD5 |
2c1042c4df56dfddbf239e05ac6cb6f9
|
|
| BLAKE2b-256 |
09f03865907bb45139211afb0937ce2176283bb48acb717a8154a5f0aec9bff5
|
Provenance
The following attestation bundles were made for langchain_opensandbox-0.1.0.tar.gz:
Publisher:
release.yml on gururafiki/langchain-opensandbox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_opensandbox-0.1.0.tar.gz -
Subject digest:
135b489040f6d151b3ace09a125c427d129f56fa442621d160490d88bdaeb214 - Sigstore transparency entry: 2387457383
- Sigstore integration time:
-
Permalink:
gururafiki/langchain-opensandbox@d2ffed25378a3648e2899486de22b7454c2e1374 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/gururafiki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d2ffed25378a3648e2899486de22b7454c2e1374 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file langchain_opensandbox-0.1.0-py3-none-any.whl.
File metadata
- Download URL: langchain_opensandbox-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00d46c413b62c4b1f8ad5c8e220768e9411124cf3a898f42f49f17b94fc8bc97
|
|
| MD5 |
1b834386295ace6c4a7bba7b4a6b8521
|
|
| BLAKE2b-256 |
4b95d1c4f0fd65ba2b540c989bda7d8a003dd37d29f0960e0149c0efb4409873
|
Provenance
The following attestation bundles were made for langchain_opensandbox-0.1.0-py3-none-any.whl:
Publisher:
release.yml on gururafiki/langchain-opensandbox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
langchain_opensandbox-0.1.0-py3-none-any.whl -
Subject digest:
00d46c413b62c4b1f8ad5c8e220768e9411124cf3a898f42f49f17b94fc8bc97 - Sigstore transparency entry: 2387457390
- Sigstore integration time:
-
Permalink:
gururafiki/langchain-opensandbox@d2ffed25378a3648e2899486de22b7454c2e1374 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/gururafiki
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@d2ffed25378a3648e2899486de22b7454c2e1374 -
Trigger Event:
workflow_dispatch
-
Statement type: