Skip to main content

elph_core/memz/
report.rs

1use anyhow::Result;
2
3use super::store::MemoryStore;
4use super::types::{
5    ContradictResult, EndTaskWithDecayResult, MemoryCategory, MemoryReportInput, MemoryReportType,
6    ReportCorrectionInput, ReportUserInput, TaskEndInput,
7};
8
9impl MemoryStore {
10    /// Unified memory report (correction, user input, or insight).
11    pub async fn report(&self, input: MemoryReportInput) -> Result<String> {
12        match input.report_type {
13            MemoryReportType::Correction => {
14                let what_failed = input.what_failed.unwrap_or_default();
15                let what_worked = input.what_worked.unwrap_or_default();
16                self.report_correction(ReportCorrectionInput {
17                    lesson: input.lesson,
18                    what_failed,
19                    what_worked,
20                    tokens_wasted: input.tokens_wasted,
21                    tools_wasted: input.tools_wasted,
22                })
23                .await
24            }
25            MemoryReportType::UserInput => {
26                let source = input
27                    .source
28                    .ok_or_else(|| anyhow::anyhow!("user_input report requires `source`"))?;
29                self.report_user_input(ReportUserInput {
30                    lesson: input.lesson,
31                    source,
32                })
33                .await
34            }
35            MemoryReportType::Insight => {
36                self.insert_raw_memory(&input.lesson, MemoryCategory::Insight, 1.0)
37                    .await
38            }
39        }
40    }
41
42    /// End task and run weight decay.
43    pub async fn end_task_with_decay(&self, task_id: &str, input: TaskEndInput) -> Result<EndTaskWithDecayResult> {
44        self.end_task(task_id, input).await?;
45        let decay = self.decay().await?;
46        Ok(EndTaskWithDecayResult { decay })
47    }
48
49    /// Flag a memory as wrong and optionally store a correction.
50    pub async fn contradict(&self, memory_id: &str, correction: Option<&str>) -> Result<ContradictResult> {
51        let (deleted, correction_id) = self.contradict_memory(memory_id, correction).await?;
52        Ok(ContradictResult { deleted, correction_id })
53    }
54}
55
56impl MemoryReportInput {
57    pub fn correction(
58        lesson: impl Into<String>,
59        what_failed: impl Into<String>,
60        what_worked: impl Into<String>,
61    ) -> Self {
62        Self {
63            report_type: MemoryReportType::Correction,
64            lesson: lesson.into(),
65            what_failed: Some(what_failed.into()),
66            what_worked: Some(what_worked.into()),
67            tokens_wasted: None,
68            tools_wasted: None,
69            source: None,
70        }
71    }
72
73    pub fn user_input(lesson: impl Into<String>, source: super::types::UserInputSource) -> Self {
74        Self {
75            report_type: MemoryReportType::UserInput,
76            lesson: lesson.into(),
77            what_failed: None,
78            what_worked: None,
79            tokens_wasted: None,
80            tools_wasted: None,
81            source: Some(source),
82        }
83    }
84
85    pub fn insight(lesson: impl Into<String>) -> Self {
86        Self {
87            report_type: MemoryReportType::Insight,
88            lesson: lesson.into(),
89            what_failed: None,
90            what_worked: None,
91            tokens_wasted: None,
92            tools_wasted: None,
93            source: None,
94        }
95    }
96}