Skip to content

Commit ee149fc

Browse files
alt-glitchalexzhang13claude
authored
feat: add E2B sandbox support (#35)
* feat: add E2B sandbox support Add a new E2BREPL environment that runs Python code in E2B sandboxes, following the same HTTP broker pattern as ModalREPL and PrimeREPL. Changes: - Add rlm/environments/e2b_repl.py with E2BREPL class - Add examples/e2b_repl_example.py demonstrating usage - Register "e2b" environment in environments/__init__.py - Add "e2b" to EnvironmentType in core/types.py - Add e2b optional dependency to pyproject.toml Key implementation details: - Uses e2b-code-interpreter SDK with Sandbox.create() API - Runs Flask broker on port 8889 (8888 is used by E2B's Jupyter) - Uses sandbox.get_host(port) for public URL access - Supports llm_query(), llm_query_batched(), FINAL_VAR() * update e2b example to use real LLM backend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(e2b): add persistent parameter for SupportsPersistence protocol Align E2BREPL with other environments (DockerREPL, ModalREPL, PrimeREPL) by adding the persistent parameter introduced in PR #40. Raises NotImplementedError when persistent=True since E2BREPL doesn't yet implement the SupportsPersistence protocol. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: az <alex.lx.zhang@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 015061e commit ee149fc

5 files changed

Lines changed: 543 additions & 4 deletions

File tree

‎examples/e2b_repl_example.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
3+
from dotenv import load_dotenv
4+
5+
from rlm import RLM
6+
from rlm.logger import RLMLogger
7+
8+
load_dotenv()
9+
10+
logger = RLMLogger(log_dir="./logs")
11+
12+
rlm = RLM(
13+
backend="openai",
14+
backend_kwargs={
15+
"api_key": os.getenv("OPENAI_API_KEY"),
16+
"model_name": "gpt-5-nano",
17+
},
18+
environment="e2b",
19+
environment_kwargs={
20+
"timeout": 300,
21+
},
22+
max_depth=1,
23+
logger=logger,
24+
verbose=True,
25+
)
26+
27+
result = rlm.completion("Using your code, solve 2^(2^(2^(2))). Show your work in Python.")
28+
print(result.response)

‎pyproject.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Issues = "https://github.com/alexzhang13/rlm/issues"
3636

3737
[project.optional-dependencies]
3838
modal = ["modal>=0.73.0", "dill>=0.3.7"]
39+
e2b = ["e2b-code-interpreter>=0.0.11", "dill>=0.3.7"]
3940
daytona = ["daytona>=0.128.1", "dill>=0.3.7"]
4041
prime = ["prime-sandboxes>=0.2.0", "dill>=0.3.7"]
4142

‎rlm/core/types.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"azure_openai",
1414
"gemini",
1515
]
16-
EnvironmentType = Literal["local", "docker", "modal", "prime", "daytona"]
16+
EnvironmentType = Literal["local", "docker", "modal", "prime", "daytona", "e2b"]
1717

1818

1919
def _serialize_value(value: Any) -> Any:

‎rlm/environments/__init__.py‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88

99
def get_environment(
10-
environment: Literal["local", "modal", "docker", "daytona", "prime"],
10+
environment: Literal["local", "modal", "docker", "daytona", "prime", "e2b"],
1111
environment_kwargs: dict[str, Any],
1212
) -> BaseEnv:
1313
"""
1414
Routes a specific environment and the args (as a dict) to the appropriate environment if supported.
15-
Currently supported environments: ['local', 'modal', 'docker', 'daytona', 'prime']
15+
Currently supported environments: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b']
1616
"""
1717
if environment == "local":
1818
return LocalREPL(**environment_kwargs)
@@ -32,7 +32,11 @@ def get_environment(
3232
from rlm.environments.prime_repl import PrimeREPL
3333

3434
return PrimeREPL(**environment_kwargs)
35+
elif environment == "e2b":
36+
from rlm.environments.e2b_repl import E2BREPL
37+
38+
return E2BREPL(**environment_kwargs)
3539
else:
3640
raise ValueError(
37-
f"Unknown environment: {environment}. Supported: ['local', 'modal', 'docker', 'daytona', 'prime']"
41+
f"Unknown environment: {environment}. Supported: ['local', 'modal', 'docker', 'daytona', 'prime', 'e2b']"
3842
)

0 commit comments

Comments
 (0)