mod libsql_store;
pub use libsql_store::LibsqlMemoryStore;
use basemyai_core::Metric;
use crate::cognition::Reached;
use crate::temporal::Validity;
use crate::{AgentId, AgentStats, MemoryLayer, Record, Result};
#[derive(Debug, Clone)]
pub struct NewMemory<'a> {
pub id: String,
pub layer: MemoryLayer,
pub text: &'a str,
pub validity: Validity,
pub vector: &'a [f32],
pub source: &'a str,
}
#[derive(Debug, Clone)]
pub struct HydratedRecord {
pub id: String,
pub text: String,
pub layer: MemoryLayer,
}
#[async_trait::async_trait]
pub trait MemoryStore: Send + Sync {
#[allow(clippy::too_many_arguments)]
async fn put_memory(
&self,
id: &str,
agent: &AgentId,
layer: MemoryLayer,
text: &str,
validity: Validity,
vector: &[f32],
source: &str,
) -> Result<()>;
async fn put_memory_batch(&self, agent: &AgentId, items: &[NewMemory<'_>]) -> Result<()>;
async fn recall_vector(
&self,
agent: &AgentId,
query: &[f32],
k: usize,
layer: Option<MemoryLayer>,
metric: Metric,
now: i64,
) -> Result<Vec<Record>>;
async fn recall_graph_filtered(&self, agent: &AgentId, query: &[f32], k: usize, now: i64) -> Result<Vec<Record>>;
async fn vector_ranking_ids(&self, agent: &AgentId, query: &[f32], k: usize, now: i64) -> Result<Vec<String>>;
async fn keyword_ranking_ids(&self, agent: &AgentId, match_expr: &str, k: usize, now: i64) -> Result<Vec<String>>;
async fn hydrate(&self, agent: &AgentId, ids: &[String], now: i64) -> Result<Vec<HydratedRecord>>;
async fn invalidate(&self, agent: &AgentId, id: &str, now: i64) -> Result<()>;
async fn forget(&self, agent: &AgentId, id: &str) -> Result<()>;
async fn purge_agent(&self, agent: &AgentId) -> Result<()>;
async fn agent_stats(&self, agent: &AgentId, now: i64) -> Result<AgentStats>;
async fn graph_upsert_entity(
&self,
agent: &AgentId,
id: &str,
kind: &str,
label: &str,
validity: Validity,
) -> Result<()>;
async fn graph_upsert_edge(
&self,
agent: &AgentId,
src: &str,
relation: &str,
dst: &str,
weight: f64,
now: i64,
) -> Result<()>;
async fn graph_traverse(&self, agent: &AgentId, start: &str, max_depth: u32, now: i64) -> Result<Vec<Reached>>;
async fn recent_episodes(&self, agent: &AgentId, limit: usize, now: i64) -> Result<Vec<String>>;
async fn exact_fact_exists(&self, agent: &AgentId, content: &str) -> Result<bool>;
}