Metadata-Version: 2.5
Name: langchain-prized
Version: 0.1.0
Summary: Prized Sandboxes (Firecracker microVMs) as a sandbox backend for LangChain Deep Agents
Project-URL: Homepage, https://prized.dev/sandboxes
Project-URL: Documentation, https://prized.dev/docs/sandboxes-langchain
Project-URL: API reference, https://prized.dev/docs/sandboxes-api
Author-email: Prized <team@prized.dev>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,code-execution,dcode,deep-agents,deepagents,firecracker,langchain,microvm,prized,sandbox
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: <4.0,>=3.11
Requires-Dist: deepagents<0.8.0,>=0.7.0
Requires-Dist: httpx<1.0.0,>=0.27.0
Description-Content-Type: text/markdown

# langchain-prized

[![PyPI](https://img.shields.io/pypi/v/langchain-prized)](https://pypi.org/project/langchain-prized/) [![Python](https://img.shields.io/pypi/pyversions/langchain-prized)](https://pypi.org/project/langchain-prized/) [![License](https://img.shields.io/pypi/l/langchain-prized)](https://pypi.org/project/langchain-prized/)

[Prized Sandboxes](https://prized.dev/docs/sandboxes) as a sandbox backend for [LangChain Deep Agents](https://docs.langchain.com/oss/python/deepagents/overview). Each sandbox is its own Firecracker microVM: it boots from a template, runs your agent's commands and file edits away from your machine, and can fork into live copies.

## Install

```bash
pip install langchain-prized
```

Python 3.11 or later, with `deepagents` 0.7.

## Quickstart

For a Prized API key, [Open Sandboxes](https://prized.dev/onboarding/sandboxes) and choose **Create API key** (new to Prized, it signs you up with free credit, no card), or make one on the [API keys page](https://prized.dev/dashboard/workspace/api-keys) (Full access, or Custom with **Sandboxes: Write**). Export it with your model provider's key:

```bash
export PRIZED_API_KEY=dcp_...
export ANTHROPIC_API_KEY=sk-ant-...
```

```python
from deepagents import create_deep_agent
from langchain_prized import PrizedSandbox

task = "Write fizzbuzz.py, run it, and show me the output."
with PrizedSandbox() as sandbox:  # creates a sandbox, and deletes it on exit
    agent = create_deep_agent(model="anthropic:claude-sonnet-5-5", backend=sandbox)
    result = agent.invoke({"messages": [{"role": "user", "content": task}]})
    print(result["messages"][-1].text)
```

The agent's `execute`, `read_file`, `write_file`, `edit_file`, `ls`, `glob`, and `grep` tools all run in the sandbox.

## Use it directly

```python
from langchain_prized import PrizedSandbox

sandbox = PrizedSandbox(template="prized-agent-v1", labels={"run": "pr-1874"})
try:
    sandbox.upload_files([("/home/prized/work/app.py", b"print('hi')\n")])
    result = sandbox.execute("python3 app.py | tee out.txt", timeout=600)
    print(result.exit_code, result.output)
    print(sandbox.download_files(["/home/prized/work/out.txt"])[0].content)

    # Fork: live copies with this sandbox's memory, disk, and running processes.
    children = sandbox.fork(3)
    try:
        for child in children:
            print(child.id, child.execute("ls").output)
    finally:
        for child in children:
            child.close()  # deletes the child
finally:
    sandbox.close()  # deletes the sandbox
```

The sandbox is created on first use (or by `start()`), and `close()` deletes it. If a create's answer is lost, the next `start()` gets the sandbox it made instead of making a second, and `close()` deletes it. To use one that already exists, pass `sandbox_id="sbx_..."`; it is left running on close unless you pass `delete_on_close=True`. `pause()` keeps memory and disk and stops compute billing; the next command or file transfer wakes it.

## Options

| Argument | Default | Meaning |
| --- | --- | --- |
| `template` | `prized-base-v1` | `prized-base-v1` (Ubuntu 24.04, Python 3, Node.js 22, build tools) or `prized-agent-v1` (adds Claude Code and Codex) |
| `api_key` | `PRIZED_API_KEY` | API key (`dcp_...`) |
| `api_url` | `PRIZED_API_URL`, else `https://api.prized.dev` | API origin |
| `vcpu`, `memory_mb`, `disk_gb` | The template's (4 vCPU, 8 GB, 10 GB) | Shape of a new sandbox, up to 32 vCPU, 128 GB of memory, and 128 GB of disk |
| `env_vars` | None | Variables for every command, stored encrypted |
| `labels` | None | Labels to filter on in the dashboard and API |
| `auto_pause_min`, `auto_delete_min`, `max_runtime_min` | Off, off, 1,440 (24 hours; 60 on the free tier) | Timers: pause when idle, delete when paused, delete after this many minutes of running (up to 10,080, 7 days) |
| `timeout` | 1800 | Default command timeout in seconds; at most 3600 |
| `cwd`, `env` | `/home/prized/work`, none | Defaults for every command |
| `sandbox_id` | None | Use an existing sandbox instead of creating one |
| `delete_on_close` | `True` if created here | Whether `close()` deletes the sandbox |
| `auto_resume` | `True` | A command or transfer wakes a paused sandbox. With `False` it stays paused: attaching raises `PrizedError` until `resume()`, and a command raises `sandbox_not_running` |
| `python_alias` | `True` | Put `python` (pointing at `python3`) on every command's PATH |
| `startup_timeout` | 180 | Seconds to wait for a create, resume, or pause to finish |
| `http_client` | None | An `httpx.Client` to send requests with (proxies); never closed by the backend |

`execute()` also takes `timeout`, `cwd`, and `env` per call. Its output is stdout, then stderr inside `<stderr>` tags; a timed-out command returns exit code 124.

## Inside a sandbox

- **User.** Commands run under `bash -c` as `prized`, without sudo, in `/home/prized/work` by default.
- **Files.** Any absolute path: files under `/home/prized` go through the files API, and others (such as `/tmp`) are staged under `/home/prized/.cache/langchain-prized` and put in place. Each file is written whole or not at all, so a write that fails (a full disk) leaves the old file, and a file it replaces keeps its mode, so a script you made executable stays executable. A symlink is written through: the file it points to changes and the link stays. Up to 100 MiB per file.
- **Output.** Each stream keeps its first 4 MiB; `truncated` is set past that.
- **Lost answers.** A command whose answer is lost is never sent again, and its `PrizedAPIError` says which of three it was: it never reached the sandbox, it may or may not have run, or it ran but the answer could not be read. A file goes up under a temporary name, sent again if need be, and one step that is never sent again puts it in place; a file's `error` says the same of that step.
- **Run time.** 24 hours of running by default, up to 7 days with `max_runtime_min`. On a paid workspace the clock stops while a sandbox is paused and starts again on every resume. A running sandbox you forget is deleted when its run time ends; a paused one is kept until you delete it (on the free tier, 30 days after its last use).

## Free tier

A new workspace gets free credit, and on the free credit alone sandboxes run within these limits ([Free tier](https://prized.dev/docs/sandboxes#free-tier)):

| Free tier | Limit |
| --- | --- |
| Sandboxes at once | 10; paused ones count toward the disk instead |
| Per sandbox | 2 vCPU and 4 GB of memory (a template's larger default is capped to this) |
| Across the workspace | 20 vCPU and 40 GB running, 100 GB of disk |
| Run time | 60 minutes of running in all; a larger `max_runtime_min` is refused. A paused sandbox is kept 30 days after its last use |

Past a limit the API answers `sandbox_quota_exceeded` or `invalid_resources`, raised as `PrizedAPIError` with `code`, `status`, and the answer's `body`. A plan or a top-up lifts the workspace to the full quotas.

## Deep Agents Code

With this package installed next to `deepagents-code`, `dcode --sandbox prized` runs the session in a new Prized sandbox; `--sandbox-id sbx_...` attaches to an existing one and leaves it running.

```bash
dcode install langchain-prized --package
```

The provider reads these variables; a `DEEPAGENTS_CODE_` prefixed name wins over the plain one, as for dcode's own providers. The sandbox ones shape a new sandbox only.

| Variable | Default | Meaning |
| --- | --- | --- |
| `PRIZED_API_KEY` | None | API key (`dcp_...`), required |
| `PRIZED_API_URL` | `https://api.prized.dev` | API origin |
| `PRIZED_SANDBOX_TEMPLATE` | `prized-base-v1` | `prized-agent-v1` adds Claude Code and Codex |
| `PRIZED_SANDBOX_VCPU`, `PRIZED_SANDBOX_MEMORY_MB` | The template's | vCPUs, and memory in MiB |
| `PRIZED_SANDBOX_LABELS` | None | Labels, as `key=value,key=value` (a value may hold `=`, not `,`) |
| `PRIZED_SANDBOX_AUTO_PAUSE_MIN` | 15 | Pause after this many idle minutes; `0` is off. The session's next command wakes it |

```bash
PRIZED_SANDBOX_VCPU=2 PRIZED_SANDBOX_MEMORY_MB=4096 PRIZED_SANDBOX_LABELS=team=evals,session=s1 dcode --sandbox prized
```

To keep these settings in dcode's own config instead, declare the provider in `~/.deepagents/config.toml`. Its `params` (`template`, `vcpu`, `memory_mb`, `auto_pause_min`) win over the variables, and its `labels` are added to `PRIZED_SANDBOX_LABELS` (on a shared key, the config's wins). Keep `working_dir` as shown, since dcode tells the agent to work there.

```toml
[sandboxes.providers.prized]
class_path = "langchain_prized.provider:PrizedSandboxProvider"
working_dir = "/home/prized/work"
params = { template = "prized-agent-v1", vcpu = 2, memory_mb = 4096, auto_pause_min = 30, labels = { team = "evals" } }
```

As of `deepagents-code` 0.1.88, dcode does not delete the sandbox when the session ends. So a sandbox made for dcode pauses after 15 idle minutes by default: it keeps its memory and files and bills storage, not compute, and in a session still open the next command wakes it. A paused sandbox is kept until you delete it (on the free tier, 30 days after its last use), and its disk counts toward your workspace's disk quota; with `PRIZED_SANDBOX_AUTO_PAUSE_MIN=0` it runs instead, billing compute, until its run time ends (24 hours by default; 60 minutes on the free tier). Give each session its own label in `PRIZED_SANDBOX_LABELS`, as `session=s1` above, and delete its sandbox when you are done: `prized sandbox rm --label session=s1`, or `DELETE /api/v1/sandboxes?label=session=s1`. A label in `config.toml` is the same for every session, so deleting by it reaches the sandboxes of sessions still open.

## Development

```bash
uv sync
uv run pytest tests/unit_tests    # offline, against a fake of the API
PRIZED_LIVE_TESTS=1 PRIZED_API_KEY=dcp_... uv run pytest tests/integration_tests    # live
PRIZED_API_KEY=dcp_... uv run python scripts/live_smoke.py    # live, a Deep Agent end to end, timed
uv run ruff check . && uv run ty check langchain_prized
uv run --group release python tests/package_check.py    # the wheel and sdist as PyPI gets them
```

The unit tests include LangChain's standard sandbox suite, run against the fake; the integration tests run it against the live API. Reference: [Sandbox API](https://prized.dev/docs/sandboxes-api).

## License

Apache-2.0. The full text is in the `LICENSE` file that ships with the package.
