offline_intelligence/cache_management/
cache_bridge.rs1use tracing::debug;
3
4pub struct CacheContextBridge {
6 cache_history: Vec<CacheTransition>,
7 _max_history: usize, max_transition_history: usize,
10}
11
12#[derive(Debug, Clone)]
13pub struct CacheTransition {
14 pub transition_type: TransitionType,
15 pub preserved_entries: usize,
16 pub retrieved_entries: usize,
17 pub timestamp: chrono::DateTime<chrono::Utc>,
18 pub keywords: Vec<String>,
19}
20
21#[derive(Debug, Clone)]
22pub enum TransitionType {
23 CacheCleared,
24 CacheRetrieved,
25 CacheRestored,
26 CacheExtended,
27}
28
29#[derive(Debug, Clone)]
30pub struct CacheBridgeStats {
31 pub total_transitions: usize,
32 pub avg_preserved_entries: f32,
33 pub avg_retrieved_entries: f32,
34 pub last_transition_type: Option<TransitionType>,
35}
36
37impl CacheContextBridge {
38 pub fn new(max_history: usize) -> Self {
40 Self {
41 cache_history: Vec::new(),
42 _max_history: max_history,
43 max_transition_history: 50,
44 }
45 }
46
47 pub fn create_clear_bridge(
49 &mut self,
50 cleared_count: usize,
51 preserved_count: usize,
52 keywords: &[String],
53 ) -> String {
54 self.record_transition(
55 TransitionType::CacheCleared,
56 preserved_count,
57 0,
58 keywords,
59 );
60
61 let keyword_list = if keywords.is_empty() {
62 "various topics".to_string()
63 } else {
64 keywords.iter().take(3).cloned().collect::<Vec<_>>().join(", ")
65 };
66
67 format!(
68 "[Cache Management] Cleared {} entries from cache, preserved {} important entries related to: {}. Continuing with optimized context.",
69 cleared_count, preserved_count, keyword_list
70 )
71 }
72
73 pub fn create_retrieval_bridge(
75 &mut self,
76 retrieved_count: usize,
77 source_tier: u8,
78 keywords: &[String],
79 similarity_score: Option<f32>,
80 ) -> String {
81 self.record_transition(
82 TransitionType::CacheRetrieved,
83 0,
84 retrieved_count,
85 keywords,
86 );
87
88 let source_desc = match source_tier {
89 1 => "active cache",
90 2 => "recent snapshots",
91 3 => "long-term memory",
92 _ => "storage",
93 };
94
95 let similarity_text = similarity_score
96 .map(|s| format!(" (similarity: {:.2})", s))
97 .unwrap_or_default();
98
99 let keyword_list = if keywords.is_empty() {
100 "relevant context".to_string()
101 } else {
102 format!("'{}'", keywords.iter().take(3).cloned().collect::<Vec<_>>().join("', '"))
103 };
104
105 format!(
106 "[Memory Retrieval] Retrieved {} entries from {} for {}{}. Integrating into current context.",
107 retrieved_count, source_desc, keyword_list, similarity_text
108 )
109 }
110
111 pub fn create_restore_bridge(
113 &mut self,
114 restored_count: usize,
115 snapshot_age: Option<std::time::Duration>,
116 ) -> String {
117 self.record_transition(
118 TransitionType::CacheRestored,
119 restored_count,
120 0,
121 &[],
122 );
123
124 let age_text = snapshot_age
125 .map(|d| {
126 let minutes = d.as_secs() / 60;
127 if minutes > 0 {
128 format!(" ({} minutes old)", minutes)
129 } else {
130 String::new()
131 }
132 })
133 .unwrap_or_default();
134
135 format!(
136 "[Cache Restoration] Restored {} entries from previous snapshot{}. Context has been expanded.",
137 restored_count, age_text
138 )
139 }
140
141 fn record_transition(
142 &mut self,
143 transition_type: TransitionType,
144 preserved: usize,
145 retrieved: usize,
146 keywords: &[String],
147 ) {
148 let transition = CacheTransition {
149 transition_type: transition_type.clone(),
150 preserved_entries: preserved,
151 retrieved_entries: retrieved,
152 timestamp: chrono::Utc::now(),
153 keywords: keywords.to_vec(),
154 };
155
156 self.cache_history.push(transition);
157
158 if self.cache_history.len() > self.max_transition_history {
160 let excess = self.cache_history.len() - self.max_transition_history;
161 self.cache_history.drain(0..excess);
162 }
163
164 debug!("Recorded cache transition: {:?}", transition_type);
165 }
166
167 pub fn get_stats(&self) -> CacheBridgeStats {
169 let total = self.cache_history.len();
170 let avg_preserved = if total > 0 {
171 self.cache_history.iter().map(|t| t.preserved_entries).sum::<usize>() as f32 / total as f32
172 } else { 0.0 };
173 let avg_retrieved = if total > 0 {
174 self.cache_history.iter().map(|t| t.retrieved_entries).sum::<usize>() as f32 / total as f32
175 } else { 0.0 };
176
177 CacheBridgeStats {
178 total_transitions: total,
179 avg_preserved_entries: avg_preserved,
180 avg_retrieved_entries: avg_retrieved,
181 last_transition_type: self.cache_history.last().map(|t| t.transition_type.clone()),
182 }
183 }
184
185 pub fn clear_history(&mut self) {
187 self.cache_history.clear();
188 self.cache_history.shrink_to_fit();
189 }
190}