use serde_json::{json, Value};
use super::HandlerContext;
pub fn memory_cache_stats(ctx: &HandlerContext, _params: Value) -> Value {
let stats = ctx.search_cache.stats();
json!({
"hits": stats.hits,
"misses": stats.misses,
"entries": stats.entries,
"hit_rate": stats.hit_rate
})
}
pub fn memory_cache_clear(ctx: &HandlerContext, _params: Value) -> Value {
let stats_before = ctx.search_cache.stats();
ctx.search_cache.clear();
json!({
"success": true,
"entries_cleared": stats_before.entries
})
}
pub fn memory_embedding_providers(ctx: &HandlerContext, _params: Value) -> Value {
let model_name = ctx.embedder.model_name().to_string();
let dimensions = ctx.embedder.dimensions();
json!({
"active": {
"id": model_name,
"model": model_name,
"dimensions": dimensions
},
"count": 1
})
}
pub fn memory_embedding_migrate(ctx: &HandlerContext, params: Value) -> Value {
let dry_run = params
.get("dry_run")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let target_model = params
.get("target_model")
.and_then(|v| v.as_str())
.map(str::to_string)
.unwrap_or_else(|| ctx.embedder.model_name().to_string());
if dry_run {
let count: i64 = ctx
.storage
.with_connection(|conn| {
let n: i64 = conn.query_row(
"SELECT COUNT(*) FROM memories WHERE has_embedding = 1",
[],
|row| row.get(0),
)?;
Ok(n)
})
.unwrap_or(0);
return json!({
"dry_run": true,
"memories_to_migrate": count,
"target_model": target_model
});
}
let ids: Vec<i64> = ctx
.storage
.with_connection(|conn| {
let mut stmt =
conn.prepare("SELECT id FROM memories WHERE has_embedding = 1 ORDER BY id")?;
let ids: rusqlite::Result<Vec<i64>> = stmt.query_map([], |row| row.get(0))?.collect();
Ok(ids?)
})
.unwrap_or_default();
let total = ids.len();
let mut migrated = 0usize;
let mut errors = 0usize;
for id in &ids {
let result = ctx.storage.with_connection(|conn| {
let content: String = conn.query_row(
"SELECT content FROM memories WHERE id = ?1",
rusqlite::params![id],
|row| row.get(0),
)?;
Ok(content)
});
match result {
Ok(content) => {
if let Ok(embedding) = ctx.embedder.embed(&content) {
let _ = ctx.storage.with_connection(|conn| {
conn.execute(
"UPDATE memories SET embedding_model = ?1 WHERE id = ?2",
rusqlite::params![target_model, id],
)?;
let _ = embedding; Ok(())
});
migrated += 1;
} else {
errors += 1;
}
}
Err(_) => {
errors += 1;
}
}
}
json!({
"success": true,
"total": total,
"migrated": migrated,
"errors": errors,
"target_model": target_model
})
}