engram-memory 0.6.0

Core binary and shared infrastructure for Engram memory system
Documentation
use std::sync::Arc;

use serde::Deserialize;
use serde_json::{Value, json};

use engram_storage::ConsolidationLogEntry;

use crate::error::CoreError;
use crate::lock_helpers;
use crate::server::ServerState;

const DEFAULT_LIMIT: usize = 50;

#[derive(Deserialize)]
struct ConsolidationLogParams {
    limit: Option<usize>,
}

pub async fn handle(state: &Arc<ServerState>, params: Value) -> Result<Value, CoreError> {
    let parsed: ConsolidationLogParams = serde_json::from_value(params)
        .map_err(|error| CoreError::DispatchError(error.to_string()))?;
    let limit = parsed.limit.unwrap_or(DEFAULT_LIMIT);

    let state_clone = Arc::clone(state);
    tokio::task::spawn_blocking(move || {
        let database = lock_helpers::lock_db(&state_clone);
        let entries = database.list_consolidation_log(limit)?;
        let count = entries.len();
        let serialized: Vec<Value> = entries.iter().map(entry_to_json).collect();
        Ok::<Value, CoreError>(json!({ "log": serialized, "count": count }))
    })
    .await
    .map_err(|error| CoreError::SocketError(error.to_string()))?
}

fn entry_to_json(entry: &ConsolidationLogEntry) -> Value {
    let memory_ids = serde_json::from_str::<Value>(&entry.memory_ids_json)
        .unwrap_or_else(|_| Value::String(entry.memory_ids_json.clone()));
    json!({
        "id": entry.id,
        "action": entry.action,
        "memory_ids": memory_ids,
        "reason": entry.reason,
        "performed_at": entry.performed_at,
        "performed_by": entry.performed_by,
    })
}