# logger


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Overview

This module provides two complementary logging mechanisms for RLM,
following the pattern established in
[rlmpaper](https://github.com/alexzhang13/rlm):

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

- [rlmpaper
  logging](https://github.com/alexzhang13/rlm/tree/main/rlm/logger) -
  Reference implementation
- [Rich library](https://github.com/Textualize/rich) - Beautiful
  terminal formatting

## 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

``` python

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:

``` python
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

``` python

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:

``` python
# 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")
```
