Skip to main content

codetether_agent/rlm/
mod.rs

1//! Recursive Language Model (RLM) processing
2//!
3//! Handles large contexts that exceed model context windows by:
4//! 1. Loading context into a REPL environment as a variable
5//! 2. Having the LLM write code to analyze it
6//! 3. Supporting recursive sub-LM calls for semantic analysis
7//!
8//! Based on "Recursive Language Models" (Zhang et al. 2025)
9
10pub mod chunker;
11pub mod repl;
12pub mod router;
13pub mod tools;
14
15pub use chunker::{Chunk, ChunkOptions, ContentType, RlmChunker};
16pub use repl::{ReplRuntime, RlmAnalysisResult, RlmExecutor, RlmRepl, SubQuery};
17pub use router::{RlmRouter, RoutingContext, RoutingResult};
18pub use tools::{RlmToolResult, dispatch_tool_call, rlm_tool_definitions};
19
20use serde::{Deserialize, Serialize};
21
22/// RLM processing statistics
23#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct RlmStats {
25    pub input_tokens: usize,
26    pub output_tokens: usize,
27    pub iterations: usize,
28    pub subcalls: usize,
29    pub elapsed_ms: u64,
30    pub compression_ratio: f64,
31}
32
33/// RLM processing result
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct RlmResult {
36    pub processed: String,
37    pub stats: RlmStats,
38    pub success: bool,
39    pub error: Option<String>,
40}
41
42/// RLM configuration
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct RlmConfig {
45    /// Mode: "auto", "off", or "always"
46    #[serde(default = "default_mode")]
47    pub mode: String,
48
49    /// Threshold ratio of context window to trigger RLM (0.0-1.0)
50    #[serde(default = "default_threshold")]
51    pub threshold: f64,
52
53    /// Maximum iterations for RLM processing
54    #[serde(default = "default_max_iterations")]
55    pub max_iterations: usize,
56
57    /// Maximum recursive sub-calls
58    #[serde(default = "default_max_subcalls")]
59    pub max_subcalls: usize,
60
61    /// Preferred runtime: "rust", "bun", or "python"
62    #[serde(default = "default_runtime")]
63    pub runtime: String,
64
65    /// Model reference for root processing (provider:model)
66    pub root_model: Option<String>,
67
68    /// Model reference for subcalls (provider:model)
69    pub subcall_model: Option<String>,
70}
71
72fn default_mode() -> String {
73    "auto".to_string()
74}
75
76fn default_threshold() -> f64 {
77    0.35
78}
79
80fn default_max_iterations() -> usize {
81    15
82}
83
84fn default_max_subcalls() -> usize {
85    50
86}
87
88fn default_runtime() -> String {
89    "rust".to_string()
90}
91
92impl Default for RlmConfig {
93    fn default() -> Self {
94        Self {
95            mode: default_mode(),
96            threshold: default_threshold(),
97            max_iterations: default_max_iterations(),
98            max_subcalls: default_max_subcalls(),
99            runtime: default_runtime(),
100            root_model: None,
101            subcall_model: None,
102        }
103    }
104}