zeroclaw_runtime/agent/
memory_strategy.rs1use std::sync::Arc;
2use zeroclaw_api::memory_traits::{Memory, MemoryStrategy};
3use zeroclaw_api::model_provider::ModelProvider;
4
5use crate::agent::memory_loader::{DefaultMemoryLoader, MemoryLoader};
6
7pub struct DefaultMemoryStrategy {
14 memory: Arc<dyn Memory>,
15 limit: usize,
16 min_relevance_score: f64,
17 memory_config: zeroclaw_config::schema::MemoryConfig,
18 workspace_dir: std::path::PathBuf,
19}
20
21impl DefaultMemoryStrategy {
22 pub fn new(
23 memory: Arc<dyn Memory>,
24 memory_config: zeroclaw_config::schema::MemoryConfig,
25 workspace_dir: impl Into<std::path::PathBuf>,
26 ) -> Self {
27 if memory_config.rerank_enabled {
32 ::zeroclaw_log::record!(
33 WARN,
34 ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)
35 .with_outcome(::zeroclaw_log::EventOutcome::Unknown)
36 .with_attrs(::serde_json::json!({
37 "rerank_enabled": true,
38 "rerank_threshold": memory_config.rerank_threshold,
39 })),
40 "memory.rerank_enabled is set but the rerank stage is not yet implemented; this setting currently has no effect"
41 );
42 }
43 Self {
44 memory,
45 limit: 5,
46 min_relevance_score: memory_config.min_relevance_score,
47 memory_config,
48 workspace_dir: workspace_dir.into(),
49 }
50 }
51
52 pub fn with_config(
56 memory: Arc<dyn Memory>,
57 memory_config: zeroclaw_config::schema::MemoryConfig,
58 workspace_dir: impl Into<std::path::PathBuf>,
59 ) -> Self {
60 Self::new(memory, memory_config, workspace_dir)
61 }
62
63 pub fn with_config_and_limit(
66 memory: Arc<dyn Memory>,
67 memory_config: zeroclaw_config::schema::MemoryConfig,
68 workspace_dir: impl Into<std::path::PathBuf>,
69 limit: usize,
70 ) -> Self {
71 let mut strategy = Self::new(memory, memory_config, workspace_dir);
72 strategy.limit = limit.max(1);
73 strategy
74 }
75}
76
77#[async_trait::async_trait]
78impl MemoryStrategy for DefaultMemoryStrategy {
79 async fn load_context(&self, query: &str, session_id: Option<&str>) -> anyhow::Result<String> {
80 let loader = DefaultMemoryLoader::new(self.limit, self.min_relevance_score);
81 loader
82 .load_context(self.memory.as_ref(), query, session_id)
83 .await
84 }
85
86 async fn consolidate_turn(
87 &self,
88 user_message: &str,
89 assistant_response: &str,
90 provider: &dyn ModelProvider,
91 model: &str,
92 temperature: Option<f64>,
93 ) -> anyhow::Result<()> {
94 zeroclaw_memory::consolidation::consolidate_turn(
95 provider,
96 model,
97 temperature,
98 self.memory.as_ref(),
99 user_message,
100 assistant_response,
101 )
102 .await
103 }
104
105 async fn run_governance(&self) -> anyhow::Result<()> {
106 zeroclaw_memory::hygiene::run_if_due(&self.memory_config, &self.workspace_dir)
111 }
112}