Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ make quickstart
</details>

## REPL Environments
We support two types of REPL environments -- isolated, and non-isolated. Non-isolated environments (default) run code execution on the same machine as the RLM (e.g. through `exec`), which is pretty reasonable for some local low-risk tasks, like simple benchmarking, but can be problematic if the prompts or tool calls can interact with malicious users. Fully isolated environments use cloud-based sandboxes (e.g. Prime Sandboxes, [Modal Sandboxes](https://modal.com/docs/guide/sandboxes)) to run code generated by the RLM, ensuring complete isolation from the host process. Environments can be added, but we natively support the following: `local` (default), `docker`, `modal`, `prime`, `daytona`, `e2b`.
We support two types of REPL environments -- isolated, and non-isolated. Non-isolated environments (default) run code execution on the same machine as the RLM (e.g. through `exec`), which is pretty reasonable for some local low-risk tasks, like simple benchmarking, but can be problematic if the prompts or tool calls can interact with malicious users. Fully isolated environments use cloud-based sandboxes (e.g. Prime Sandboxes, [Modal Sandboxes](https://modal.com/docs/guide/sandboxes), [Vercel Sandboxes](https://vercel.com/docs/vercel-sandbox)) to run code generated by the RLM, ensuring complete isolation from the host process. Environments can be added, but we natively support the following: `local` (default), `docker`, `modal`, `prime`, `daytona`, `e2b`, `vercel`.

```python
rlm = RLM(
environment="...", # "local", "docker", "modal", "prime", "daytona", "e2b"
environment="...", # "local", "docker", "modal", "prime", "daytona", "e2b", "vercel"
environment_kwargs={...},
)
```
Expand Down Expand Up @@ -113,6 +113,21 @@ uv pip install -e ".[prime]"
export PRIME_API_KEY=...
```

#### Vercel Sandboxes
To use [Vercel Sandboxes](https://vercel.com/docs/vercel-sandbox), install the SDK and authenticate with Vercel:
```bash
uv pip install -e ".[vercel]"
vercel link
vercel env pull
```

The Vercel SDK uses credentials stored in `.env.local` for local development. In Python examples, load it explicitly with `load_dotenv(".env.local")`.

> [!NOTE]
> `backend="vercel"` and `environment="vercel"` are different features:
> - `backend="vercel"` uses the Vercel AI Gateway as an LM provider.
> - `environment="vercel"` runs generated Python code inside Vercel Sandboxes.


### Model Providers
We currently support most major clients (OpenAI, Anthropic), as well as the router platforms (OpenRouter, Portkey). For local models, we recommend using vLLM (which interfaces with the [OpenAI client](https://github.com/alexzhang13/rlm/blob/main/rlm/clients/openai.py)). To view or add support for more clients, start by looking at [`rlm/clients/`](https://github.com/alexzhang13/rlm/tree/main/rlm/clients).
Expand Down
31 changes: 31 additions & 0 deletions examples/vercel_repl_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os

from dotenv import load_dotenv

from rlm import RLM
from rlm.logger import RLMLogger

# Vercel Sandboxes local auth typically lives in .env.local after:
# vercel link
# vercel env pull
load_dotenv(".env.local")

logger = RLMLogger(log_dir="./logs")

rlm = RLM(
backend="openai",
backend_kwargs={
"api_key": os.getenv("OPENAI_API_KEY"),
"model_name": "gpt-5-nano",
},
environment="vercel",
environment_kwargs={
"timeout": 300,
},
max_depth=1,
logger=logger,
verbose=True,
)

result = rlm.completion("Using your code, solve 2^(2^(2^(2))). Show your work in Python.")
print(result.response)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ modal = ["modal>=0.73.0", "dill>=0.3.7"]
e2b = ["e2b-code-interpreter>=0.0.11", "dill>=0.3.7"]
daytona = ["daytona>=0.128.1", "dill>=0.3.7"]
prime = ["prime-sandboxes>=0.2.0", "dill>=0.3.7"]
vercel = ["vercel>=0.4.0"]

[build-system]
requires = ["setuptools>=61.0"]
Expand Down
2 changes: 1 addition & 1 deletion rlm/core/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"azure_openai",
"gemini",
]
EnvironmentType = Literal["local", "docker", "modal", "prime", "daytona", "e2b"]
EnvironmentType = Literal["local", "docker", "modal", "prime", "daytona", "e2b", "vercel"]


def _serialize_value(value: Any) -> Any:
Expand Down
10 changes: 7 additions & 3 deletions rlm/environments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@


def get_environment(
environment: Literal["local", "modal", "docker", "daytona", "prime", "e2b"],
environment: Literal["local", "modal", "docker", "daytona", "prime", "e2b", "vercel"],
environment_kwargs: dict[str, Any],
) -> BaseEnv:
"""
Routes a specific environment and the args (as a dict) to the appropriate environment if supported.
Currently supported environments: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b']
Currently supported environments: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b', 'vercel']
"""
if environment == "local":
return LocalREPL(**environment_kwargs)
Expand All @@ -60,7 +60,11 @@ def get_environment(
from rlm.environments.e2b_repl import E2BREPL

return E2BREPL(**environment_kwargs)
elif environment == "vercel":
from rlm.environments.vercel_repl import VercelREPL

return VercelREPL(**environment_kwargs)
else:
raise ValueError(
f"Unknown environment: {environment}. Supported: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b']"
f"Unknown environment: {environment}. Supported: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b', 'vercel']"
)
Loading
Loading