ainl_compression/
adaptive.rs1use crate::EfficientMode;
6
7#[derive(Debug, Clone, PartialEq)]
9pub struct AdaptiveRecommendation {
10 pub mode: EfficientMode,
11 pub confidence: f32,
13 pub reasons: Vec<&'static str>,
14}
15
16fn est_tokens(text: &str) -> usize {
17 text.len() / 4 + 1
18}
19
20fn structure_density(text: &str) -> f32 {
22 let len = text.len().max(1) as f32;
23 let mut score = 0.0_f32;
24 score += text.matches("```").count() as f32 * 0.08;
25 score += text.matches("http://").count() as f32 * 0.04;
26 score += text.matches("https://").count() as f32 * 0.04;
27 score += text.matches("::").count() as f32 * 0.01;
28 score += text.matches("R ").count() as f32 * 0.02;
29 score += text.matches(".ainl").count() as f32 * 0.03;
30 (score / len * 600.0).clamp(0.0, 1.0)
31}
32
33#[must_use]
35pub fn recommend_mode_for_content(text: &str) -> AdaptiveRecommendation {
36 let tokens = est_tokens(text);
37 let density = structure_density(text);
38 let mut reasons: Vec<&'static str> = Vec::new();
39
40 if tokens < 80 {
41 reasons.push("below_compression_floor");
42 return AdaptiveRecommendation {
43 mode: EfficientMode::Off,
44 confidence: 0.88,
45 reasons,
46 };
47 }
48
49 if density > 0.32 {
50 reasons.push("structured_or_code_heavy");
51 return AdaptiveRecommendation {
52 mode: EfficientMode::Balanced,
53 confidence: 0.72,
54 reasons,
55 };
56 }
57
58 if tokens > 420 {
59 reasons.push("long_prose_budget_pressure");
60 return AdaptiveRecommendation {
61 mode: EfficientMode::Aggressive,
62 confidence: 0.58,
63 reasons,
64 };
65 }
66
67 reasons.push("general_prompt");
68 AdaptiveRecommendation {
69 mode: EfficientMode::Balanced,
70 confidence: 0.62,
71 reasons,
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn short_is_off() {
81 let r = recommend_mode_for_content("Hello.");
82 assert_eq!(r.mode, EfficientMode::Off);
83 }
84
85 #[test]
86 fn code_fence_prefers_balanced() {
87 let filler = "y".repeat(400);
88 let r = recommend_mode_for_content(&(filler + "\n```rust\nfn main(){}\n```"));
89 assert_eq!(r.mode, EfficientMode::Balanced);
90 }
91}