Skip to main content

shodh_memory/handlers/
compression.rs

1//! Compression Handlers
2//!
3//! Handlers for memory compression and decompression operations.
4
5use axum::{
6    extract::{Query, State},
7    response::Json,
8};
9use serde::Deserialize;
10
11use super::state::MultiUserMemoryManager;
12use crate::errors::{AppError, ValidationErrorExt};
13use crate::memory::{self, MemoryId};
14use crate::validation;
15use std::sync::Arc;
16
17type AppState = Arc<MultiUserMemoryManager>;
18
19/// Request for compressing a memory
20#[derive(Debug, Deserialize)]
21pub struct CompressMemoryRequest {
22    pub user_id: String,
23    #[serde(alias = "memory_id")]
24    pub id: String,
25}
26
27/// POST /api/memory/compress - Manually compress a specific memory
28pub async fn compress_memory(
29    State(state): State<AppState>,
30    Json(req): Json<CompressMemoryRequest>,
31) -> Result<Json<serde_json::Value>, AppError> {
32    validation::validate_user_id(&req.user_id).map_validation_err("user_id")?;
33
34    let _memory_sys = state
35        .get_user_memory(&req.user_id)
36        .map_err(AppError::Internal)?;
37
38    // Validate id format
39    let _memory_id = MemoryId(
40        uuid::Uuid::parse_str(&req.id).map_err(|_| AppError::InvalidMemoryId(req.id.clone()))?,
41    );
42
43    // Compression happens automatically in the memory system based on age and importance
44    Ok(Json(serde_json::json!({
45        "success": true,
46        "message": "Memory compression initiated"
47    })))
48}
49
50/// Request for decompressing a memory
51#[derive(Debug, Deserialize)]
52pub struct DecompressMemoryRequest {
53    pub user_id: String,
54    #[serde(alias = "memory_id")]
55    pub id: String,
56}
57
58/// POST /api/memory/decompress - Decompress a compressed memory
59pub async fn decompress_memory(
60    State(state): State<AppState>,
61    Json(req): Json<DecompressMemoryRequest>,
62) -> Result<Json<serde_json::Value>, AppError> {
63    validation::validate_user_id(&req.user_id).map_validation_err("user_id")?;
64
65    let memory_sys = state
66        .get_user_memory(&req.user_id)
67        .map_err(AppError::Internal)?;
68
69    let memory_guard = memory_sys.read();
70    let memory_id = MemoryId(
71        uuid::Uuid::parse_str(&req.id).map_err(|_| AppError::InvalidMemoryId(req.id.clone()))?,
72    );
73
74    // Get the memory
75    let memory = memory_guard
76        .get_memory(&memory_id)
77        .map_err(AppError::Internal)?;
78
79    if !memory.compressed {
80        return Ok(Json(serde_json::json!({
81            "success": true,
82            "message": "Memory is not compressed",
83            "was_compressed": false
84        })));
85    }
86
87    // Decompress using compression pipeline
88    let decompressed = memory_guard
89        .decompress_memory(&memory)
90        .map_err(AppError::Internal)?;
91
92    Ok(Json(serde_json::json!({
93        "success": true,
94        "message": "Memory decompressed successfully",
95        "was_compressed": true,
96        "memory": {
97            "id": decompressed.id.0.to_string(),
98            "content": decompressed.experience.content,
99            "importance": decompressed.importance()
100        }
101    })))
102}
103
104/// Request for storage statistics
105#[derive(Debug, Deserialize)]
106pub struct StorageStatsRequest {
107    pub user_id: String,
108}
109
110/// GET /api/storage/stats - Get storage statistics
111pub async fn get_storage_stats(
112    State(state): State<AppState>,
113    Query(req): Query<StorageStatsRequest>,
114) -> Result<Json<memory::storage::StorageStats>, AppError> {
115    validation::validate_user_id(&req.user_id).map_validation_err("user_id")?;
116
117    let memory_sys = state
118        .get_user_memory(&req.user_id)
119        .map_err(AppError::Internal)?;
120
121    let memory_guard = memory_sys.read();
122    let stats = memory_guard
123        .get_storage_stats()
124        .map_err(AppError::Internal)?;
125
126    Ok(Json(stats))
127}