use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::{CodememError, Edge, GraphNode, MemoryNode, NodeKind, RelationshipType, Session};
pub trait VectorBackend: Send + Sync {
fn insert(&mut self, id: &str, embedding: &[f32]) -> Result<(), CodememError>;
fn insert_batch(&mut self, items: &[(String, Vec<f32>)]) -> Result<(), CodememError>;
fn search(&self, query: &[f32], k: usize) -> Result<Vec<(String, f32)>, CodememError>;
fn remove(&mut self, id: &str) -> Result<bool, CodememError>;
fn save(&self, path: &std::path::Path) -> Result<(), CodememError>;
fn load(&mut self, path: &std::path::Path) -> Result<(), CodememError>;
fn stats(&self) -> VectorStats;
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct VectorStats {
pub count: usize,
pub dimensions: usize,
pub metric: String,
pub memory_bytes: usize,
}
pub trait GraphBackend: Send + Sync {
fn add_node(&mut self, node: GraphNode) -> Result<(), CodememError>;
fn get_node(&self, id: &str) -> Result<Option<GraphNode>, CodememError>;
fn remove_node(&mut self, id: &str) -> Result<bool, CodememError>;
fn add_edge(&mut self, edge: Edge) -> Result<(), CodememError>;
fn get_edges(&self, node_id: &str) -> Result<Vec<Edge>, CodememError>;
fn remove_edge(&mut self, id: &str) -> Result<bool, CodememError>;
fn bfs(&self, start_id: &str, max_depth: usize) -> Result<Vec<GraphNode>, CodememError>;
fn dfs(&self, start_id: &str, max_depth: usize) -> Result<Vec<GraphNode>, CodememError>;
fn bfs_filtered(
&self,
start_id: &str,
max_depth: usize,
exclude_kinds: &[NodeKind],
include_relationships: Option<&[RelationshipType]>,
) -> Result<Vec<GraphNode>, CodememError> {
let _ = (exclude_kinds, include_relationships);
self.bfs(start_id, max_depth)
}
fn dfs_filtered(
&self,
start_id: &str,
max_depth: usize,
exclude_kinds: &[NodeKind],
include_relationships: Option<&[RelationshipType]>,
) -> Result<Vec<GraphNode>, CodememError> {
let _ = (exclude_kinds, include_relationships);
self.dfs(start_id, max_depth)
}
fn shortest_path(&self, from: &str, to: &str) -> Result<Vec<String>, CodememError>;
fn stats(&self) -> GraphStats;
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GraphStats {
pub node_count: usize,
pub edge_count: usize,
pub node_kind_counts: HashMap<String, usize>,
pub relationship_type_counts: HashMap<String, usize>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StorageStats {
pub memory_count: usize,
pub embedding_count: usize,
pub node_count: usize,
pub edge_count: usize,
}
#[derive(Debug, Clone)]
pub struct ConsolidationLogEntry {
pub cycle_type: String,
pub run_at: i64,
pub affected_count: usize,
}
pub trait StorageBackend: Send + Sync {
fn insert_memory(&self, memory: &MemoryNode) -> Result<(), CodememError>;
fn get_memory(&self, id: &str) -> Result<Option<MemoryNode>, CodememError>;
fn get_memories_batch(&self, ids: &[&str]) -> Result<Vec<MemoryNode>, CodememError>;
fn update_memory(
&self,
id: &str,
content: &str,
importance: Option<f64>,
) -> Result<(), CodememError>;
fn delete_memory(&self, id: &str) -> Result<bool, CodememError>;
fn list_memory_ids(&self) -> Result<Vec<String>, CodememError>;
fn list_memory_ids_for_namespace(&self, namespace: &str) -> Result<Vec<String>, CodememError>;
fn list_namespaces(&self) -> Result<Vec<String>, CodememError>;
fn memory_count(&self) -> Result<usize, CodememError>;
fn store_embedding(&self, memory_id: &str, embedding: &[f32]) -> Result<(), CodememError>;
fn get_embedding(&self, memory_id: &str) -> Result<Option<Vec<f32>>, CodememError>;
fn delete_embedding(&self, memory_id: &str) -> Result<bool, CodememError>;
fn list_all_embeddings(&self) -> Result<Vec<(String, Vec<f32>)>, CodememError>;
fn insert_graph_node(&self, node: &GraphNode) -> Result<(), CodememError>;
fn get_graph_node(&self, id: &str) -> Result<Option<GraphNode>, CodememError>;
fn delete_graph_node(&self, id: &str) -> Result<bool, CodememError>;
fn all_graph_nodes(&self) -> Result<Vec<GraphNode>, CodememError>;
fn insert_graph_edge(&self, edge: &Edge) -> Result<(), CodememError>;
fn get_edges_for_node(&self, node_id: &str) -> Result<Vec<Edge>, CodememError>;
fn all_graph_edges(&self) -> Result<Vec<Edge>, CodememError>;
fn delete_graph_edges_for_node(&self, node_id: &str) -> Result<usize, CodememError>;
fn delete_graph_nodes_by_prefix(&self, prefix: &str) -> Result<usize, CodememError>;
fn start_session(&self, id: &str, namespace: Option<&str>) -> Result<(), CodememError>;
fn end_session(&self, id: &str, summary: Option<&str>) -> Result<(), CodememError>;
fn list_sessions(
&self,
namespace: Option<&str>,
limit: usize,
) -> Result<Vec<Session>, CodememError>;
fn insert_consolidation_log(
&self,
cycle_type: &str,
affected_count: usize,
) -> Result<(), CodememError>;
fn last_consolidation_runs(&self) -> Result<Vec<ConsolidationLogEntry>, CodememError>;
fn get_repeated_searches(
&self,
min_count: usize,
namespace: Option<&str>,
) -> Result<Vec<(String, usize, Vec<String>)>, CodememError>;
fn get_file_hotspots(
&self,
min_count: usize,
namespace: Option<&str>,
) -> Result<Vec<(String, usize, Vec<String>)>, CodememError>;
fn get_tool_usage_stats(
&self,
namespace: Option<&str>,
) -> Result<Vec<(String, usize)>, CodememError>;
fn get_decision_chains(
&self,
min_count: usize,
namespace: Option<&str>,
) -> Result<Vec<(String, usize, Vec<String>)>, CodememError>;
fn decay_stale_memories(
&self,
threshold_ts: i64,
decay_factor: f64,
) -> Result<usize, CodememError>;
fn list_memories_for_creative(
&self,
) -> Result<Vec<(String, String, Vec<String>)>, CodememError>;
fn find_cluster_duplicates(&self) -> Result<Vec<(String, String, f64)>, CodememError>;
fn find_forgettable(&self, importance_threshold: f64) -> Result<Vec<String>, CodememError>;
fn insert_memories_batch(&self, memories: &[MemoryNode]) -> Result<(), CodememError> {
for memory in memories {
self.insert_memory(memory)?;
}
Ok(())
}
fn store_embeddings_batch(&self, items: &[(&str, &[f32])]) -> Result<(), CodememError> {
for (id, embedding) in items {
self.store_embedding(id, embedding)?;
}
Ok(())
}
fn insert_graph_nodes_batch(&self, nodes: &[GraphNode]) -> Result<(), CodememError> {
for node in nodes {
self.insert_graph_node(node)?;
}
Ok(())
}
fn insert_graph_edges_batch(&self, edges: &[Edge]) -> Result<(), CodememError> {
for edge in edges {
self.insert_graph_edge(edge)?;
}
Ok(())
}
fn find_unembedded_memories(&self) -> Result<Vec<(String, String)>, CodememError>;
fn search_graph_nodes(
&self,
query: &str,
namespace: Option<&str>,
limit: usize,
) -> Result<Vec<GraphNode>, CodememError>;
fn list_memories_filtered(
&self,
namespace: Option<&str>,
memory_type: Option<&str>,
) -> Result<Vec<MemoryNode>, CodememError>;
fn graph_edges_for_namespace(&self, namespace: &str) -> Result<Vec<Edge>, CodememError>;
fn get_edges_at_time(&self, node_id: &str, _timestamp: i64) -> Result<Vec<Edge>, CodememError> {
self.get_edges_for_node(node_id)
}
fn get_stale_memories_for_decay(
&self,
threshold_ts: i64,
) -> Result<Vec<(String, f64, u32, i64)>, CodememError>;
fn batch_update_importance(&self, updates: &[(String, f64)]) -> Result<usize, CodememError>;
fn session_count(&self, namespace: Option<&str>) -> Result<usize, CodememError>;
fn load_file_hashes(&self) -> Result<HashMap<String, String>, CodememError>;
fn save_file_hashes(&self, hashes: &HashMap<String, String>) -> Result<(), CodememError>;
fn record_session_activity(
&self,
session_id: &str,
tool_name: &str,
file_path: Option<&str>,
directory: Option<&str>,
pattern: Option<&str>,
) -> Result<(), CodememError>;
fn get_session_activity_summary(
&self,
session_id: &str,
) -> Result<crate::SessionActivitySummary, CodememError>;
fn get_session_hot_directories(
&self,
session_id: &str,
limit: usize,
) -> Result<Vec<(String, usize)>, CodememError>;
fn has_auto_insight(&self, session_id: &str, dedup_tag: &str) -> Result<bool, CodememError>;
fn count_directory_reads(
&self,
session_id: &str,
directory: &str,
) -> Result<usize, CodememError>;
fn was_file_read_in_session(
&self,
session_id: &str,
file_path: &str,
) -> Result<bool, CodememError>;
fn count_search_pattern_in_session(
&self,
session_id: &str,
pattern: &str,
) -> Result<usize, CodememError>;
fn stats(&self) -> Result<StorageStats, CodememError>;
}