Skip to main content

tycode_core/modules/memory/
context.rs

1//! Memory context component for rendering memories in AI context.
2
3use std::sync::Arc;
4
5use crate::module::{ContextComponent, ContextComponentId};
6use crate::settings::manager::SettingsManager;
7
8use super::config::MemoryConfig;
9
10use super::log::MemoryLog;
11
12pub const ID: ContextComponentId = ContextComponentId("memories");
13
14/// Renders recent memories in the context section.
15pub struct MemoriesManager {
16    memory_log: Arc<MemoryLog>,
17    settings: SettingsManager,
18}
19
20impl MemoriesManager {
21    pub fn new(memory_log: Arc<MemoryLog>, settings: SettingsManager) -> Self {
22        Self {
23            memory_log,
24            settings,
25        }
26    }
27
28    pub fn memory_log(&self) -> &Arc<MemoryLog> {
29        &self.memory_log
30    }
31}
32
33#[async_trait::async_trait(?Send)]
34impl ContextComponent for MemoriesManager {
35    fn id(&self) -> ContextComponentId {
36        ID
37    }
38
39    async fn build_context_section(&self) -> Option<String> {
40        let memories = self.memory_log.read_all().ok()?;
41        if memories.is_empty() {
42            return None;
43        }
44
45        let config: MemoryConfig = self.settings.get_module_config(MemoryConfig::NAMESPACE);
46        let max_recent = config.recent_memories_count;
47        let recent: Vec<_> = memories.iter().rev().take(max_recent).collect();
48
49        if recent.is_empty() {
50            return None;
51        }
52
53        let mut output = String::from("Recent Memories:\n");
54        for memory in recent.iter().rev() {
55            let source_info = memory
56                .source
57                .as_ref()
58                .map(|s| format!(" [{}]", s))
59                .unwrap_or_default();
60            output.push_str(&format!("- {}{}", memory.content, source_info));
61            output.push('\n');
62        }
63        Some(output)
64    }
65}