REPL Environments

REPL environments are sandboxed Python execution contexts where the LM can write and execute code to analyze the input context. These environments provide the LM with programmatic access to computation, data processing, and the ability to make sub-LM calls.

When you call rlm.completion(prompt), your prompt becomes the context variable in a Python REPL. The LM can then write Python code to examine this context, decompose complex tasks, and recursively call itself via llm_query()to handle sub-problems.

Isolation Levels

RLM supports two types of environments based on their isolation level:

Non-Isolated Environments

Run code on the same machine as the RLM process (or in a container on the same host).

  • Faster execution — No network overhead
  • Shared resources — Access to host filesystem, network, and memory
  • Lower security — Code runs with host process privileges
  • Use cases: Development, testing, trusted code

Isolated Environments

Run code on completely separate machines (cloud VMs), guaranteeing full isolation.

  • Full isolation — No access to host resources
  • Higher security — Code cannot affect host system
  • Network overhead — Communication via HTTP tunnels
  • Use cases: Production, untrusted code, sensitive data

Why this matters: The isolation level determines the security and trust model of your RLM application. Non-isolated environments are faster and simpler, but code execution shares the host's resources and privileges. Isolated environments provide complete separation, making them essential for production deployments or when executing untrusted LM-generated code.

Available Environments

EnvironmentIsolationBest For
localNon-isolatedDevelopment
dockerNon-isolatedCI/CD, reproducibility
modalIsolatedProduction

REPL Globals

These variables and functions are available inside code executed in the REPL environment:

NameDescription
contextYour input prompt, available as a variable in the REPL
llm_query(prompt, model=None)Single LM completion call. Returns the completion string. Does not have tool access.
llm_query_batched(prompts, model=None)Concurrent single LM completion calls. Returns a list of completion strings. Does not have tool access.
FINAL_VAR(var_name)Mark a variable as the final answer to return from the RLM
custom_toolsAny custom functions or data you provide via the custom_tools parameter
# Example usage in REPL
context = "Your input here"

# Query a sub-LM
result = llm_query("Summarize the context", model="gpt-5-mini")

# Use a custom tool(if provided)
data = fetch_data(context["url"])  # Custom function

# Process the result
summary = process(result)

# Return final answer
FINAL_VAR(summary)

Custom Tools

You can provide custom functions and data that the RLM can use in its REPL environment via the custom_tools parameter:

from rlm import RLM

def fetch_weather(city: str) -> str:
    """Fetch weather data for a city."""
    return f"Weather in {city}: Sunny, 72°F"

rlm = RLM(
    backend="openai",
    backend_kwargs={"model_name": "gpt-4o"},
    custom_tools={
        # Plain format(no description)
        "fetch_weather": fetch_weather,
        
        # Dict format with description(recommended)
        "calculate_tip": {"tool": lambda x: x * 0.2, "description": "Calculate 20% tip for a bill amount"},
        "API_KEY": {"tool": "your-key", "description": "API key for external services"},
    },
)

# The model can now call fetch_weather() in its REPL code

Tool descriptions: Use the dict format{"tool": value, "description": "..."} to provide descriptions that help the model understand what each tool does. Descriptions are automatically included in the system prompt.

Note: llm_query() calls are single LM completions and do not have access to custom tools. Only the main RLM execution context has tool access.

Architecture

Non-Isolated (local, docker)

Direct TCP socket communication:

┌────────────┐   Socket   ┌────────────┐
│ Environment│◄──────────►│ LM Handler │
│ llm_query()│            │            │
└────────────┘            └────────────┘

Isolated (modal)

HTTP broker pattern for cloud sandboxes:

┌─────────────────────────────────────┐
│ Host                                │
│  ┌──────────┐       ┌────────────┐ │
│  │ ModalREPL│◄─────►│ LM Handler │ │
│  │ (polls)  │Socket └────────────┘ │
│  └────┬─────┘                      │
│       │ HTTP                       │
└───────┼────────────────────────────┘
        ▼
┌───────────────────────────────────────┐
│ Modal Sandbox                         │
│  ┌────────────┐     ┌──────────────┐ │
│  │   Broker   │◄───►│ Code Exec    │ │
│  │  (Flask)   │     │ llm_query()  │ │
│  └────────────┘     └──────────────┘ │
└───────────────────────────────────────┘

The broker queues llm_query() requests, host polls for pending requests, forwards them to the LM Handler, and posts responses back.