Skip to main content

lean_ctx/core/
query_aware.rs

1//! Query-aware adaptive compression (#1312).
2//!
3//! Match compression level to task intent: exploration tasks get
4//! aggressive compression, implementation tasks get full detail.
5//! Based on SeleCom (arXiv 2602.15856): query-conditioned selective
6//! compression outperforms full-context RAG.
7
8/// Task intent classification for compression decisions.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum TaskIntent {
11    /// Exploring / understanding the codebase. High compression is safe.
12    Explore,
13    /// Implementing / editing specific code. Full detail needed.
14    Implement,
15    /// Debugging a specific issue. Targeted detail needed.
16    Debug,
17    /// Reviewing code. Moderate compression acceptable.
18    Review,
19    /// Unknown intent. Default to moderate compression.
20    Unknown,
21}
22
23impl TaskIntent {
24    /// Classify intent from a task description string.
25    pub fn classify(task: &str) -> Self {
26        let lower = task.to_lowercase();
27
28        if contains_any(
29            &lower,
30            &["implement", "add feature", "create", "build", "write"],
31        ) {
32            return Self::Implement;
33        }
34        if contains_any(
35            &lower,
36            &["fix", "debug", "error", "bug", "crash", "failing"],
37        ) {
38            return Self::Debug;
39        }
40        if contains_any(&lower, &["review", "audit", "check", "verify", "inspect"]) {
41            return Self::Review;
42        }
43        if contains_any(
44            &lower,
45            &[
46                "explore",
47                "understand",
48                "how does",
49                "what is",
50                "find",
51                "search",
52                "where",
53            ],
54        ) {
55            return Self::Explore;
56        }
57
58        Self::Unknown
59    }
60
61    /// Recommended compression level for this intent.
62    pub fn compression_level(&self) -> CompressionLevel {
63        match self {
64            TaskIntent::Explore => CompressionLevel::High,
65            TaskIntent::Review | TaskIntent::Unknown => CompressionLevel::Medium,
66            TaskIntent::Debug => CompressionLevel::Low,
67            TaskIntent::Implement => CompressionLevel::Minimal,
68        }
69    }
70
71    /// Suggested read mode for auto-mode resolution.
72    pub fn suggested_read_mode(&self) -> &'static str {
73        match self {
74            TaskIntent::Explore => "map",
75            TaskIntent::Review => "signatures",
76            TaskIntent::Debug | TaskIntent::Implement => "full",
77            TaskIntent::Unknown => "auto",
78        }
79    }
80}
81
82/// Compression intensity levels.
83#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
84pub enum CompressionLevel {
85    /// No compression — full content.
86    Minimal,
87    /// Light compression (remove blanks, trailing whitespace).
88    Low,
89    /// Moderate compression (signatures + key implementations).
90    Medium,
91    /// Aggressive compression (outline only).
92    High,
93}
94
95fn contains_any(text: &str, keywords: &[&str]) -> bool {
96    keywords.iter().any(|kw| text.contains(kw))
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102
103    #[test]
104    fn classify_explore() {
105        assert_eq!(
106            TaskIntent::classify("how does the cache work?"),
107            TaskIntent::Explore
108        );
109        assert_eq!(
110            TaskIntent::classify("find the database module"),
111            TaskIntent::Explore
112        );
113    }
114
115    #[test]
116    fn classify_implement() {
117        assert_eq!(
118            TaskIntent::classify("implement user authentication"),
119            TaskIntent::Implement
120        );
121        assert_eq!(
122            TaskIntent::classify("add feature for dark mode"),
123            TaskIntent::Implement
124        );
125    }
126
127    #[test]
128    fn classify_debug() {
129        assert_eq!(
130            TaskIntent::classify("fix the null pointer error"),
131            TaskIntent::Debug
132        );
133        assert_eq!(
134            TaskIntent::classify("debug why tests are failing"),
135            TaskIntent::Debug
136        );
137    }
138
139    #[test]
140    fn classify_review() {
141        assert_eq!(
142            TaskIntent::classify("review this pull request"),
143            TaskIntent::Review
144        );
145    }
146
147    #[test]
148    fn classification_drives_compression() {
149        assert_eq!(
150            TaskIntent::Explore.compression_level(),
151            CompressionLevel::High
152        );
153        assert_eq!(
154            TaskIntent::Implement.compression_level(),
155            CompressionLevel::Minimal
156        );
157        assert_eq!(TaskIntent::Debug.compression_level(), CompressionLevel::Low);
158    }
159
160    #[test]
161    fn classification_drives_read_mode() {
162        assert_eq!(TaskIntent::Explore.suggested_read_mode(), "map");
163        assert_eq!(TaskIntent::Implement.suggested_read_mode(), "full");
164        assert_eq!(TaskIntent::Debug.suggested_read_mode(), "full");
165    }
166}