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

The core logic of the RLM codebase resides in two critical modules—rlm/core/rlm.py and 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 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 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:

Environment Abstractions

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

Execution Flow and Code Examples

Basic invocation flows through rlm/core/rlm.py:

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:

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.

Summary

  • The orchestration logic lives in 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, handling socket-based LM routing and depth-aware client selection.
  • Utility modules (parsing.py, prompts.py, token_utils.py) provide supporting functions for code extraction and prompt construction.
  • Environment implementations (local_repl.py, 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. This method initializes the iteration cycle, constructs prompts via 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. 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, 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. 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →