Skip to content

rlm_repl

rlm_repl

Sandboxed REPL environment for the RLM agent.

Provides a persistent Python namespace with injected helper functions (llm_query, llm_batch, FINAL, FINAL_VAR) that the RLM agent's generated code uses to decompose context and make recursive sub-LM calls.

Classes

RLMRepl

RLMRepl(llm_query_fn: Optional[Callable[[str], str]] = None, llm_batch_fn: Optional[Callable[[List[str]], List[str]]] = None, *, max_output_chars: int = 10000)

Sandboxed Python REPL with persistent namespace for the RLM agent.

PARAMETER DESCRIPTION
llm_query_fn

Callback invoked when REPL code calls llm_query(prompt).

TYPE: Optional[Callable[[str], str]] DEFAULT: None

llm_batch_fn

Callback invoked when REPL code calls llm_batch(prompts).

TYPE: Optional[Callable[[List[str]], List[str]]] DEFAULT: None

max_output_chars

Maximum characters captured from stdout per execution.

TYPE: int DEFAULT: 10000

Source code in src/openjarvis/agents/rlm_repl.py
def __init__(
    self,
    llm_query_fn: Optional[Callable[[str], str]] = None,
    llm_batch_fn: Optional[Callable[[List[str]], List[str]]] = None,
    *,
    max_output_chars: int = 10000,
) -> None:
    self._max_output_chars = max_output_chars
    self._terminated = False
    self._final_value: Any = None

    # Build namespace
    self._namespace: Dict[str, Any] = {}

    # Inject safe stdlib modules
    for mod_name in _SAFE_MODULES:
        try:
            import importlib

            self._namespace[mod_name] = importlib.import_module(mod_name)
        except ImportError:
            pass

    # answer dict — code can set answer["ready"] = True, answer["value"] = ...
    self._namespace["answer"] = {"ready": False, "value": None}

    # Inject FINAL / FINAL_VAR
    self._namespace["FINAL"] = self._final
    self._namespace["FINAL_VAR"] = self._final_var

    # Inject llm_query / llm_batch
    if llm_query_fn is not None:
        self._namespace["llm_query"] = llm_query_fn
    if llm_batch_fn is not None:
        self._namespace["llm_batch"] = llm_batch_fn
Attributes
is_terminated property
is_terminated: bool

Check if FINAL/FINAL_VAR was called or answer["ready"] is True.

final_answer property
final_answer: Any

Return the termination value.

Functions
security_check
security_check(code: str) -> Optional[str]

Check code for dangerous patterns. Returns error message or None.

Source code in src/openjarvis/agents/rlm_repl.py
def security_check(self, code: str) -> Optional[str]:
    """Check code for dangerous patterns. Returns error message or None."""
    for pattern in _BLOCKED_PATTERNS:
        if pattern in code:
            return f"Blocked: code contains prohibited pattern '{pattern}'"
    return None
execute
execute(code: str) -> str

Execute code in the persistent namespace and return captured stdout.

Raises are caught and returned as error strings.

Source code in src/openjarvis/agents/rlm_repl.py
def execute(self, code: str) -> str:
    """Execute *code* in the persistent namespace and return captured stdout.

    Raises are caught and returned as error strings.
    """
    # Security check
    violation = self.security_check(code)
    if violation is not None:
        return f"Error: {violation}"

    stdout_buf = io.StringIO()
    stderr_buf = io.StringIO()

    try:
        with redirect_stdout(stdout_buf), redirect_stderr(stderr_buf):
            exec(code, self._namespace)  # noqa: S102
    except Exception as exc:
        error_msg = f"{type(exc).__name__}: {exc}"
        return error_msg

    output = stdout_buf.getvalue()
    err_output = stderr_buf.getvalue()
    if err_output:
        output += ("\n" if output else "") + err_output

    # Truncate if needed
    if len(output) > self._max_output_chars:
        output = output[: self._max_output_chars] + "\n... (output truncated)"

    return output
set_variable
set_variable(name: str, value: Any) -> None

Set a variable in the REPL namespace.

Source code in src/openjarvis/agents/rlm_repl.py
def set_variable(self, name: str, value: Any) -> None:
    """Set a variable in the REPL namespace."""
    self._namespace[name] = value
get_variable
get_variable(name: str) -> Any

Get a variable from the REPL namespace.

Source code in src/openjarvis/agents/rlm_repl.py
def get_variable(self, name: str) -> Any:
    """Get a variable from the REPL namespace."""
    return self._namespace.get(name)