# Where to Find the Core Logic in the RLM Codebase: A Deep Dive into the Recursive Architecture

> Discover the core logic of the RLM codebase within rlm.py and lm_handler.py. This guide explores the recursive architecture and communication layers for efficient development.

- Repository: [az/rlm](https://github.com/alexzhang13/rlm)
- Tags: deep-dive
- Published: 2026-06-18

---

**The core logic of the RLM codebase resides in two critical modules—[`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py) and [`rlm/core/lm_handler.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/lm_handler.py)—which implement the recursive orchestration engine and the socket-based language model communication layer.**

The `alexzhang13/rlm` repository implements a recursive language model framework that enables iterative code execution with sub-call capabilities. Understanding where the core logic lives in the RLM codebase is essential for debugging, extending, or integrating this system. The architecture centers on tight coordination between an orchestration class that manages the REPL loop and a handler that routes LM requests across process boundaries.

## The Two Pillars of Core Logic

### Orchestration Engine in rlm/core/rlm.py

The **`RLM`** class in [`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py) serves as the primary orchestrator. It instantiates the model, spawns dedicated handlers, and executes the iterative REPL loop that defines the recursive workflow.

Key responsibilities include:

- **`__init__`**: Parses configuration including backend, environment, limits, and tools
- **`_spawn_completion_context`**: Creates fresh `LMHandler` instances and environments (`LocalREPL`, `ModalREPL`)
- **`completion`**: Orchestrates the iteration cycle—building system prompts, invoking the handler, extracting code blocks, executing them in the environment, and terminating when `answer["ready"]` is set
- **`_subcall`**: Enables recursive `rlm_query` calls by spawning child `RLM` instances with incremented depth
- **Limit enforcement**: `_check_timeout`, `_check_iteration_limits`, and token counting ensure safe execution boundaries

### Communication Layer in rlm/core/lm_handler.py

The **`LMHandler`** class in [`rlm/core/lm_handler.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/lm_handler.py) operates a multi-threaded TCP server that bridges the REPL environment and the language model backend.

Key components include:

- **`LMRequestHandler.handle`**: Parses length-prefixed JSON payloads and routes single or batched requests
- **`_handle_single`** and **`_handle_batched`**: Process incoming LM requests from REPL subprocesses
- **`get_client`**: Implements depth-based routing logic—default client at depth 0, optional secondary client at depth 1
- **Public API**: `completion`, `start`, `stop`, and `get_usage_summary` provide the interface consumed by the `RLM` class

## Supporting Infrastructure

### Parsing and Prompt Utilities

Several utility modules feed into the core logic:

- **[`rlm/utils/parsing.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/utils/parsing.py)**: Extracts fenced code blocks from LM responses
- **[`rlm/utils/prompts.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/utils/prompts.py)**: Constructs system prompts and query metadata consumed by `RLM._setup_prompt`
- **[`rlm/utils/token_utils.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/utils/token_utils.py)**: Counts tokens and determines context limits for compaction decisions

### Environment Abstractions

The core interacts with execution environments through abstract and concrete implementations:

- **[`rlm/environments/base_env.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/environments/base_env.py)**: Defines the `BaseEnv` interface with `setup`, `execute_code`, and `cleanup` methods
- **[`rlm/environments/local_repl.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/environments/local_repl.py)**: Default non-isolated environment exposing `llm_query`, `rlm_query`, `answer`, and `SHOW_VARS()` globals to executed code
- **[`rlm/environments/modal_repl.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/environments/modal_repl.py)**: Isolated cloud-based execution backend

## Execution Flow and Code Examples

Basic invocation flows through [`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py):

```python
from rlm import RLM

# Instantiate the orchestrator defined in rlm/core/rlm.py

rlm = RLM(backend="openai", environment="local", max_depth=2)
result = rlm.completion("Write a function that returns the nth Fibonacci number.")

print(result.response)          # Final answer extracted from REPL

print(result.usage_summary)     # Token/cost data collected by LMHandler

```

Recursive sub-calls trigger `_subcall` in the same module:

```python
def my_tool(x: int) -> int:
    # Executed within LocalREPL; rlm_query triggers RLM._subcall

    answer = rlm_query(f"Compute the square of {x}.")
    return int(answer["content"])

```

When `rlm_query` executes, the `RLM._subcall` method spawns a child `RLM` instance with `depth + 1`, forwarding the request through the socket server managed by `LMHandler` in [`rlm/core/lm_handler.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/lm_handler.py).

## Summary

- The **orchestration logic** lives in [`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py), specifically within the `RLM` class that manages iteration, compaction, and recursive depth.
- The **communication backbone** resides in [`rlm/core/lm_handler.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/lm_handler.py), handling socket-based LM routing and depth-aware client selection.
- **Utility modules** ([`parsing.py`](https://github.com/alexzhang13/rlm/blob/main/parsing.py), [`prompts.py`](https://github.com/alexzhang13/rlm/blob/main/prompts.py), [`token_utils.py`](https://github.com/alexzhang13/rlm/blob/main/token_utils.py)) provide supporting functions for code extraction and prompt construction.
- **Environment implementations** ([`local_repl.py`](https://github.com/alexzhang13/rlm/blob/main/local_repl.py), [`modal_repl.py`](https://github.com/alexzhang13/rlm/blob/main/modal_repl.py)) expose the REPL interface that the core logic controls.

## Frequently Asked Questions

### What is the entry point for RLM execution?

The entry point is the `completion` method in [`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py). This method initializes the iteration cycle, constructs prompts via [`rlm/utils/prompts.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/utils/prompts.py), and coordinates with `LMHandler` to process language model responses until the environment signals completion via `answer["ready"]`.

### How does RLM handle recursive sub-calls?

Recursive sub-calls are managed by the `_subcall` method in [`rlm/core/rlm.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/rlm.py). When code executing in an environment invokes `rlm_query`, the system spawns a child `RLM` instance with incremented depth, enforcing the `max_depth` limit configured during initialization to prevent infinite recursion.

### Where is the prompt construction logic located?

Prompt construction utilities reside in [`rlm/utils/prompts.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/utils/prompts.py), which the `RLM` class imports to build system prompts and query metadata. The `_setup_prompt` method within the `RLM` class coordinates these utilities to prepare context windows for each iteration.

### How does the environment communicate with the language model?

Environments communicate through a TCP socket server implemented in [`rlm/core/lm_handler.py`](https://github.com/alexzhang13/rlm/blob/main/rlm/core/lm_handler.py). The `LMHandler` class runs a multi-threaded server that receives JSON-encoded requests from REPL subprocesses, routes them to the appropriate backend client based on recursion depth, and returns `RLMChatCompletion` objects to the calling environment.