Skip to main content

engram_core/
export_handler.rs

1use std::sync::Arc;
2
3use serde_json::{Value, json};
4
5use engram_storage::Memory;
6
7use crate::error::CoreError;
8use crate::server::ServerState;
9use crate::timestamp::current_utc_timestamp;
10
11pub async fn handle(state: &Arc<ServerState>, _params: Value) -> Result<Value, CoreError> {
12    let state_clone = Arc::clone(state);
13    tokio::task::spawn_blocking(move || {
14        let database = state_clone.database.lock().unwrap();
15        let memories = query_active_memories(&database)?;
16        let exported_at = current_utc_timestamp();
17        let count = memories.len();
18        let serialized: Vec<Value> = memories.iter().map(memory_to_portable_json).collect();
19        Ok::<Value, CoreError>(json!({
20            "version": 1,
21            "memories": serialized,
22            "exported_at": exported_at,
23            "count": count,
24        }))
25    })
26    .await
27    .map_err(|error| CoreError::SocketError(error.to_string()))?
28}
29
30fn query_active_memories(database: &engram_storage::Database) -> Result<Vec<Memory>, CoreError> {
31    let mut statement = database
32        .connection()
33        .prepare("SELECT * FROM memories WHERE superseded_by IS NULL")
34        .map_err(|error| CoreError::ExportFailed(error.to_string()))?;
35    let rows = statement
36        .query_map([], engram_storage::row_to_memory)
37        .map_err(|error| CoreError::ExportFailed(error.to_string()))?;
38    let mut memories = Vec::new();
39    for row in rows {
40        memories.push(row.map_err(|error| CoreError::ExportFailed(error.to_string()))?);
41    }
42    Ok(memories)
43}
44
45pub fn memory_to_portable_json(memory: &Memory) -> Value {
46    json!({
47        "id": memory.id,
48        "memory_type": memory.memory_type,
49        "context": memory.context,
50        "action": memory.action,
51        "result": memory.result,
52        "score": memory.score,
53        "tags": memory.tags,
54        "project": memory.project,
55        "parent_id": memory.parent_id,
56        "source_ids": memory.source_ids,
57        "insight_type": memory.insight_type,
58        "created_at": memory.created_at,
59        "updated_at": memory.updated_at,
60        "used_count": memory.used_count,
61        "last_used_at": memory.last_used_at,
62    })
63}