refactor(backend): alihkan Memory ke zesdex-cms MarkdownMemoryRepository
Ganti semua pemanggilan Memory::read/write/remove/list di zesdex-backend dengan MarkdownMemoryRepository dari zesdex-cms. Hapus re-export model::memory yang sudah tidak dipakai. Method mapping: read -> load, write -> save, remove -> delete, list -> list. Import trait MemoryRepository untuk method resolution. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
dc9fd4dbd1
commit
0ad3b0e539
@@ -1,4 +1,5 @@
|
||||
use crate::app::state::rest::AppStateRest;
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
|
||||
/// A unified representation of a lesson item for the interactive TUI overlay.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -53,9 +54,9 @@ pub fn get_learning_items(state: &AppStateRest) -> Vec<LearningItem> {
|
||||
}
|
||||
|
||||
// 2. Load stored memory lessons from long-term memory directory
|
||||
let names = crate::model::memory::Memory::list(&state.memory_dir);
|
||||
let names = zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository::new().list(&state.memory_dir).unwrap_or_default();
|
||||
for name in names {
|
||||
if let Ok(mem) = crate::model::memory::Memory::read(&state.memory_dir, &name) {
|
||||
if let Ok(mem) = zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository::new().load(&state.memory_dir, &name) {
|
||||
if mem.kind == "lesson" {
|
||||
items.push(LearningItem::Stored {
|
||||
name: mem.name,
|
||||
|
||||
@@ -9,6 +9,9 @@ use crate::app::subagent::context::build_subagent_context;
|
||||
use crate::app::subagent::engine::run_subagent;
|
||||
use crate::app::subagent::spawn::AgentDefinition;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zesdex_cms::domain::memory::Memory;
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
use zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository;
|
||||
|
||||
/// How much trust a lesson's origin/verification warrants.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
@@ -484,14 +487,15 @@ const STALE_AFTER_DAYS: i64 = 60;
|
||||
/// `mem.write`.
|
||||
pub fn run_staleness_sweep(memory_dir: &std::path::Path) -> std::io::Result<Vec<String>> {
|
||||
let mut flagged = Vec::new();
|
||||
let names = crate::model::memory::Memory::list(memory_dir);
|
||||
let names = MarkdownMemoryRepository::new().list(memory_dir).unwrap_or_default();
|
||||
let now = chrono::Utc::now().timestamp_millis();
|
||||
let cutoff = now - STALE_AFTER_DAYS * 24 * 3600 * 1000;
|
||||
for name in names {
|
||||
if let Ok(mut mem) = crate::model::memory::Memory::read(memory_dir, &name) {
|
||||
if let Ok(mut mem) = MarkdownMemoryRepository::new().load(memory_dir, &name) {
|
||||
if mem.updated_at < cutoff && mem.lifecycle != "stale" {
|
||||
mem.lifecycle = "stale".to_string();
|
||||
mem.write(memory_dir)?;
|
||||
MarkdownMemoryRepository::new().save(memory_dir, &mem)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
|
||||
flagged.push(name);
|
||||
}
|
||||
}
|
||||
@@ -581,7 +585,7 @@ pub fn process_pending_lessons(session_dir: &std::path::Path, memory_dir: &std::
|
||||
}
|
||||
}
|
||||
for lesson in &to_keep {
|
||||
let mem = crate::model::memory::Memory {
|
||||
let mem = Memory {
|
||||
name: lesson.name.clone(),
|
||||
description: lesson.content.chars().take(80).collect(),
|
||||
content: lesson.content.clone(),
|
||||
@@ -595,7 +599,8 @@ pub fn process_pending_lessons(session_dir: &std::path::Path, memory_dir: &std::
|
||||
after_snippet: None,
|
||||
provenances: vec![],
|
||||
};
|
||||
mem.write(memory_dir)?;
|
||||
MarkdownMemoryRepository::new().save(memory_dir, &mem)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
|
||||
}
|
||||
|
||||
save_pending_lessons(session_dir, &remaining)?;
|
||||
@@ -625,7 +630,7 @@ pub fn resolve_pending_lesson(
|
||||
for p in pending {
|
||||
if p.lesson.name == lesson_name {
|
||||
if keep {
|
||||
let mem = crate::model::memory::Memory {
|
||||
let mem = Memory {
|
||||
name: p.lesson.name.clone(),
|
||||
description: p.lesson.content.chars().take(80).collect(),
|
||||
content: p.lesson.content.clone(),
|
||||
@@ -639,7 +644,8 @@ pub fn resolve_pending_lesson(
|
||||
after_snippet: None,
|
||||
provenances: vec![],
|
||||
};
|
||||
mem.write(memory_dir)?;
|
||||
MarkdownMemoryRepository::new().save(memory_dir, &mem)
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
|
||||
}
|
||||
} else {
|
||||
remaining.push(p);
|
||||
|
||||
@@ -29,6 +29,8 @@ use crate::app::state::rest::{AppStateRest, ChatMessageDisplay};
|
||||
use crate::app::state::runtime::TurnEvent;
|
||||
use crate::app::state::types::{Origin, Overlay, Toast, ToastKind};
|
||||
use crate::dto::chat::message::{ChatMessage, Role};
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
use zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository;
|
||||
|
||||
/// A single, well-typed event in the app — produced by key input, the
|
||||
/// streaming pipeline, or subagent threads — that mutates `AppStateRest`
|
||||
@@ -589,7 +591,7 @@ pub fn apply_action(state: &mut AppStateRest, action: Action) {
|
||||
state.dirty = true;
|
||||
}
|
||||
Action::LessonDelete { name } => {
|
||||
let _ = crate::model::memory::Memory::remove(&state.memory_dir, &name);
|
||||
let _ = MarkdownMemoryRepository::new().delete(&state.memory_dir, &name);
|
||||
if let Some(ref mut rt) = state.session_runtime {
|
||||
refresh_lesson_counters(&state.memory_dir, rt);
|
||||
}
|
||||
@@ -795,7 +797,7 @@ fn generate_workspace_tree(roots: &[std::path::PathBuf]) -> String {
|
||||
///
|
||||
/// Return: a formatted string (may be empty if no memory entries exist).
|
||||
fn build_memory_section(memory_dir: &std::path::Path) -> String {
|
||||
let names = crate::model::memory::Memory::list(memory_dir);
|
||||
let names = MarkdownMemoryRepository::new().list(memory_dir).unwrap_or_default();
|
||||
if names.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
@@ -808,7 +810,7 @@ fn build_memory_section(memory_dir: &std::path::Path) -> String {
|
||||
section.push_str("... (more entries omitted, use recall() to see all)\n");
|
||||
break;
|
||||
}
|
||||
if let Ok(mem) = crate::model::memory::Memory::read(memory_dir, name) {
|
||||
if let Ok(mem) = MarkdownMemoryRepository::new().load(memory_dir, name) {
|
||||
if mem.lifecycle == "stale" {
|
||||
continue;
|
||||
}
|
||||
@@ -831,7 +833,7 @@ fn build_memory_section(memory_dir: &std::path::Path) -> String {
|
||||
/// breakdown counters. This runs on every user submit so the dashboard
|
||||
/// reflects actual memory state.
|
||||
fn refresh_lesson_counters(memory_dir: &std::path::Path, rt: &mut crate::app::state::runtime::SessionRuntime) {
|
||||
let names = crate::model::memory::Memory::list(memory_dir);
|
||||
let names = MarkdownMemoryRepository::new().list(memory_dir).unwrap_or_default();
|
||||
rt.lesson_count = 0;
|
||||
rt.lessons_user = 0;
|
||||
rt.lessons_feedback = 0;
|
||||
@@ -841,7 +843,7 @@ fn refresh_lesson_counters(memory_dir: &std::path::Path, rt: &mut crate::app::st
|
||||
rt.lessons_stale = 0;
|
||||
rt.lessons_contradicted = 0;
|
||||
for name in &names {
|
||||
if let Ok(mem) = crate::model::memory::Memory::read(memory_dir, name) {
|
||||
if let Ok(mem) = MarkdownMemoryRepository::new().load(memory_dir, name) {
|
||||
rt.lesson_count += 1;
|
||||
match mem.kind.as_str() {
|
||||
"user" => rt.lessons_user += 1,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! Core Intelligence can omit or reshape — and always runs after any
|
||||
//! hive-mind convergence completes.
|
||||
use crate::app::workflow::hive_mind::NodeReport;
|
||||
use crate::model::memory::Memory;
|
||||
use zesdex_cms::domain::memory::Memory;
|
||||
use std::fmt::Write as _;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ pub mod store {
|
||||
pub mod editlog {
|
||||
pub use zesdex_entities::seaorm::common::edit_log::*;
|
||||
}
|
||||
pub mod memory {
|
||||
pub use zesdex_entities::seaorm::common::memory::*;
|
||||
}
|
||||
/// Local modules not extracted to workspace crates
|
||||
pub mod msglog;
|
||||
pub mod agent_def;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! Tool for deleting a persisted memory entry by name.
|
||||
use super::super::Tool;
|
||||
use super::super::ToolCtx;
|
||||
use crate::model::memory::Memory;
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
use zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository;
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
@@ -42,7 +43,7 @@ impl Tool for Forget {
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow!("missing required argument: name"))?;
|
||||
|
||||
Memory::remove(&ctx.memory_dir, name)
|
||||
MarkdownMemoryRepository::new().delete(&ctx.memory_dir, name)
|
||||
.map_err(|e| anyhow!("failed to remove memory '{name}': {e}"))?;
|
||||
|
||||
Ok(format!("removed memory '{name}'"))
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! Tool for reading a single memory entry or listing the whole memory index.
|
||||
use super::super::Tool;
|
||||
use super::super::ToolCtx;
|
||||
use crate::model::memory::Memory;
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
use zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository;
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde_json::{json, Value};
|
||||
use std::fmt::Write;
|
||||
@@ -41,7 +42,7 @@ impl Tool for Recall {
|
||||
if name.is_empty() {
|
||||
return Ok(list_all(ctx));
|
||||
}
|
||||
let memory = Memory::read(&ctx.memory_dir, name)
|
||||
let memory = MarkdownMemoryRepository::new().load(&ctx.memory_dir, name)
|
||||
.map_err(|e| anyhow!("memory '{name}' not found: {e}"))?;
|
||||
Ok(format!(
|
||||
"---\nname: {}\ndescription: {}\nkind: {}\nlifecycle: {}\n---\n\n{}",
|
||||
@@ -60,13 +61,13 @@ impl Tool for Recall {
|
||||
///
|
||||
/// Return: `Ok` with the formatted index (never fails; missing dir yields "(no memory entries)").
|
||||
fn list_all(ctx: &ToolCtx) -> String {
|
||||
let names = Memory::list(&ctx.memory_dir);
|
||||
let names = MarkdownMemoryRepository::new().list(&ctx.memory_dir).unwrap_or_default();
|
||||
if names.is_empty() {
|
||||
return "(no memory entries)".to_string();
|
||||
}
|
||||
let mut lines = String::new();
|
||||
for name in &names {
|
||||
if let Ok(mem) = Memory::read(&ctx.memory_dir, name) {
|
||||
if let Ok(mem) = MarkdownMemoryRepository::new().load(&ctx.memory_dir, name) {
|
||||
let _ = writeln!(lines, "- {} [{}]: {}", name, mem.kind, mem.description);
|
||||
} else {
|
||||
let _ = writeln!(lines, "- {name}");
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
//! Tool for saving a new memory entry to persistent project memory.
|
||||
use super::super::Tool;
|
||||
use super::super::ToolCtx;
|
||||
use crate::model::memory::Memory;
|
||||
use zesdex_cms::domain::memory::Memory;
|
||||
use zesdex_cms::domain::repository::MemoryRepository;
|
||||
use zesdex_cms::infrastructure::persistence::memory_repo::MarkdownMemoryRepository;
|
||||
use anyhow::{anyhow, Result};
|
||||
use serde_json::{json, Value};
|
||||
|
||||
@@ -91,9 +93,8 @@ impl Tool for Remember {
|
||||
provenances: vec![],
|
||||
};
|
||||
|
||||
memory
|
||||
.write(&ctx.memory_dir)
|
||||
.map_err(|e| anyhow!("failed to write memory '{name}': {e}"))?;
|
||||
MarkdownMemoryRepository::new().save(&ctx.memory_dir, &memory)
|
||||
.map_err(|e| anyhow!("failed to save memory '{name}': {e}"))?;
|
||||
|
||||
Ok(format!("saved memory '{name}' ({kind})"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user