do_memory_core/procedural/
mod.rs1mod types;
7
8pub use types::ProceduralMemory;
9
10#[cfg(test)]
11mod tests;
12
13use crate::types::TaskContext;
14use chrono::Utc;
15use uuid::Uuid;
16
17impl ProceduralMemory {
18 pub fn new(
20 name: String,
21 description: String,
22 context: TaskContext,
23 steps: Vec<crate::memory::playbook::PlaybookStep>,
24 ) -> Self {
25 let now = Utc::now();
26 Self {
27 id: Uuid::new_v4(),
28 name,
29 description,
30 context,
31 steps,
32 effectiveness: crate::patterns::PatternEffectiveness::default(),
33 source_episodes: Vec::new(),
34 source_patterns: Vec::new(),
35 created_at: now,
36 updated_at: now,
37 }
38 }
39
40 #[must_use]
42 pub fn is_relevant_to(&self, query_context: &TaskContext) -> bool {
43 if self.context.domain == query_context.domain {
45 return true;
46 }
47
48 if self.context.language == query_context.language && self.context.language.is_some() {
50 return true;
51 }
52
53 let common_tags: Vec<_> = self
55 .context
56 .tags
57 .iter()
58 .filter(|t| query_context.tags.contains(t))
59 .collect();
60
61 if !common_tags.is_empty() {
62 return true;
63 }
64
65 false
66 }
67
68 pub fn record_retrieval(&mut self) {
70 self.effectiveness.record_retrieval();
71 self.updated_at = Utc::now();
72 }
73
74 pub fn record_application(&mut self, success: bool, reward_delta: f32) {
76 self.effectiveness.record_application(success, reward_delta);
77 self.updated_at = Utc::now();
78 }
79
80 pub fn add_source_episode(&mut self, episode_id: Uuid) {
82 if !self.source_episodes.contains(&episode_id) {
83 self.source_episodes.push(episode_id);
84 self.updated_at = Utc::now();
85 }
86 }
87
88 pub fn add_source_pattern(&mut self, pattern_id: crate::episode::PatternId) {
90 if !self.source_patterns.contains(&pattern_id) {
91 self.source_patterns.push(pattern_id);
92 self.updated_at = Utc::now();
93 }
94 }
95}