logger

Logging for RLM iterations - structured JSON-lines and Rich console output

Overview

This module provides two complementary logging mechanisms for RLM, following the pattern established in rlmpaper:

  1. RLMLogger: Structured JSON-lines logging for analysis and debugging
  2. VerbosePrinter: Beautiful console output using Rich for real-time visibility

Design Principles

  • Optional: Both logger and verbose mode are opt-in
  • Non-invasive: Minimal coupling to core RLM logic
  • Dual output: Machine-readable JSONL + human-readable Rich output
  • Aligned with rlmpaper: Same concepts, adapted for claudette backend

References

Imports

RLMLogger - Structured JSON-Lines Logging

Writes iteration data to JSON-lines files for post-hoc analysis.

Each line is a JSON object representing either: - Metadata (first line): Configuration and setup - Iteration: Complete iteration with prompt, response, code blocks, results


RLMLogger


def RLMLogger(
    log_dir:str | pathlib.Path, file_name:str='rlm'
):

Logger that writes RLM iteration data to JSON-lines files.

Creates timestamped JSONL files with complete iteration history. Following rlmpaper’s logging pattern.

Example: logger = RLMLogger(log_dir=‘./logs’) logger.log_metadata({‘query’: ‘What is X?’, ‘max_iters’: 5}) logger.log(iteration)

Test RLMLogger:

import tempfile

# Create logger in temp directory
with tempfile.TemporaryDirectory() as tmpdir:
    logger = RLMLogger(tmpdir, file_name='test')
    
    # Log metadata
    logger.log_metadata({'query': 'Test query', 'max_iters': 5})
    
    # Create mock iteration
    result = REPLResult(stdout='Hello', stderr='', locals={}, execution_time=0.1)
    block = CodeBlock(code='print("Hello")', result=result)
    iteration = RLMIteration(prompt='Test prompt', response='Test response', code_blocks=[block])
    
    # Log iteration
    logger.log(iteration, 1)
    
    # Verify file exists and has content
    assert logger.log_file_path.exists()
    
    # Read and parse
    lines = logger.log_file_path.read_text().strip().split('\n')
    assert len(lines) == 2  # metadata + 1 iteration
    
    metadata_entry = json.loads(lines[0])
    assert metadata_entry['type'] == 'metadata'
    assert metadata_entry['query'] == 'Test query'
    
    iteration_entry = json.loads(lines[1])
    assert iteration_entry['type'] == 'iteration'
    assert iteration_entry['iteration'] == 1
    assert iteration_entry['response'] == 'Test response'
    assert len(iteration_entry['code_blocks']) == 1
    
    print(f"✓ RLMLogger works: {logger.log_file_path.name}")
    print(f"  Logged {logger.iteration_count} iteration(s)")
✓ RLMLogger works: test_2026-01-29_18-45-55_e9bae748.jsonl
  Logged 1 iteration(s)

VerbosePrinter - Rich Console Output

Beautiful, human-readable terminal output for debugging.

Simplified from rlmpaper’s version - focuses on core visibility without heavy styling.


VerbosePrinter


def VerbosePrinter(
    enabled:bool=True
):

Console printer for RLM verbose output using Rich.

Provides real-time visibility into RLM execution with beautiful formatting. Falls back to simple print if Rich is not installed.

Example: verbose = VerbosePrinter(enabled=True) verbose.print_header(query=‘What is X?’, max_iters=5) verbose.print_iteration(iteration, 1)

Test VerbosePrinter:

# Test with Rich if available
verbose = VerbosePrinter(enabled=True)

verbose.print_header(
    query="What is the Activity class in PROV?",
    context="PROV ontology loaded",
    max_iters=3
)

# Mock iteration
result = REPLResult(
    stdout="Activity: http://www.w3.org/ns/prov#Activity",
    stderr="",
    locals={},
    execution_time=0.05
)
block = CodeBlock(code="search_by_label(prov_meta, 'Activity')", result=result)
iteration = RLMIteration(
    prompt="Find Activity class",
    response="Let me search for the Activity class",
    code_blocks=[block]
)

verbose.print_iteration(iteration, 1)
verbose.print_final_answer("The Activity class represents processes in PROV.")
verbose.print_summary(total_iterations=1, total_time=1.5)

print("\n✓ VerbosePrinter works")