LangChain DeepAgents¶
The SDK provides deepagents BaseSandbox implementations for command execution
and file transfer. Use ContreeSandbox with a sync executor, or
ContreeAsyncSandbox with an async executor. A session implements the matching contract.
Note
Async snippets with top-level await run inside an async function or a notebook
that supports it. For a standalone script, use the asyncio.run(main()) structure
from Your first sandbox.
The examples use the default sandbox from create_sandbox_session. Commands and
uploads use the same VM. Downloads automatically save its current filesystem
before reading; this stops the VM. The next command starts from the saved image.
The factory handles connection setup and cleanup.
Install and test the backend¶
This integration requires Python 3.11 or newer. Install the development API from the repository root, as in Your first sandbox:
pip install -e ".[langchain,async]"
The extra pins deepagents 0.7.10, the version tested with this SDK. Its async file
tools delegate to aexecute and aupload_files. Version 0.6.8 instead calls sync
methods from those tools and is incompatible with ContreeAsyncSandbox.
The sandbox image needs a POSIX shell, Python 3, and the file utilities used by
deepagents, including grep for search. Replace the example
tag:python:3.12-alpine with an image available on your endpoint.
Configure a connection as described in Connection sources. This example exercises the backend directly, so no model credentials are needed.
from contree_sdk import create_sandbox_session
from contree_sdk.langchain import ContreeSandbox
with create_sandbox_session(image="tag:python:3.12-alpine") as session:
sandbox = ContreeSandbox(session)
result = sandbox.execute("echo hello")
print(result.output)
print("exit:", result.exit_code)
from contree_sdk import create_sandbox_session
from contree_sdk.langchain import ContreeAsyncSandbox
async with create_sandbox_session(image="tag:python:3.12-alpine") as session:
sandbox = ContreeAsyncSandbox(session)
result = await sandbox.aexecute("echo hello")
print(result.output)
print("exit:", result.exit_code)
The adapter runs commands with disposable=False. Its next tool call sees the
filesystem changes. It does not close the session, client, or store. Use SQLite
when the agent needs to resume after a Python restart.
Connect the backend to an agent¶
Pass the sandbox as backend= to deepagents.create_deep_agent. Supply the model
configured by your application. Keep the client open for the entire agent invocation.
The following function accepts that model and uses the connection configured in
Connection sources:
from deepagents import create_deep_agent
from contree_sdk import create_sandbox_session
from contree_sdk.langchain import ContreeSandbox
def ask_agent(model):
with create_sandbox_session(image="tag:python:3.12-alpine") as session:
agent = create_deep_agent(model=model, backend=ContreeSandbox(session))
request = {"messages": [{"role": "user", "content": "Create a calculator script and run it."}]}
return agent.invoke(request)
from deepagents import create_deep_agent
from contree_sdk import create_sandbox_session
from contree_sdk.langchain import ContreeAsyncSandbox
async def ask_agent(model):
async with create_sandbox_session(image="tag:python:3.12-alpine") as session:
agent = create_deep_agent(model=model, backend=ContreeAsyncSandbox(session))
request = {"messages": [{"role": "user", "content": "Create a calculator script and run it."}]}
return await agent.ainvoke(request)
Model-provider installation, credentials, and model selection belong to the agent application. The SDK does not choose a provider or supply a model key.
Advanced: file transfers and executor contracts¶
Uploads call session.write_file(path, content). Its default implementation writes
binary stdin with cat, creates parent directories, and requests no snapshot.
Custom executors can override write_file without changing this adapter.
Downloads call session.read_file(). Lazy sessions read the active VM through
live inspect, so downloads preserve running processes and do not force a snapshot.
Sync sandbox |
Async sandbox |
|---|---|
|
|
|
|
|
|
File paths must be absolute. Transfers return per-file responses; inspect error
before reading their content. The async adapter’s synchronous methods raise
NotImplementedError. Each adapter serializes its own calls, but callers sharing
an executor must coordinate other mutations themselves.
To use another backend implementation, follow Customize the SDK. See deepagents sandboxes for API signatures.