pub mod circuit_breaker;
use crate::episode::{
CleanupResult, Direction, EpisodeRelationship, EpisodeRetentionPolicy, PatternId,
RelationshipType,
};
use crate::memory::attribution::{
RecommendationFeedback, RecommendationSession, RecommendationStats,
};
use crate::{Episode, Heuristic, Pattern, Result};
use async_trait::async_trait;
use uuid::Uuid;
pub const DEFAULT_QUERY_LIMIT: usize = 100;
pub const MAX_QUERY_LIMIT: usize = 1000;
#[must_use]
#[inline]
pub fn apply_query_limit(limit: Option<usize>) -> usize {
match limit {
Some(l) => l.min(MAX_QUERY_LIMIT),
None => DEFAULT_QUERY_LIMIT,
}
}
#[async_trait]
pub trait StorageBackend: Send + Sync {
async fn store_episode(&self, episode: &Episode) -> Result<()>;
async fn get_episode(&self, id: Uuid) -> Result<Option<Episode>>;
async fn delete_episode(&self, id: Uuid) -> Result<()>;
async fn store_pattern(&self, pattern: &Pattern) -> Result<()>;
async fn get_pattern(&self, id: PatternId) -> Result<Option<Pattern>>;
async fn store_heuristic(&self, heuristic: &Heuristic) -> Result<()>;
async fn get_heuristic(&self, id: Uuid) -> Result<Option<Heuristic>>;
async fn query_episodes_since(
&self,
since: chrono::DateTime<chrono::Utc>,
limit: Option<usize>,
) -> Result<Vec<Episode>>;
async fn query_episodes_by_metadata(
&self,
key: &str,
value: &str,
limit: Option<usize>,
) -> Result<Vec<Episode>>;
async fn store_embedding(&self, id: &str, embedding: Vec<f32>) -> Result<()>;
async fn get_embedding(&self, id: &str) -> Result<Option<Vec<f32>>>;
async fn delete_embedding(&self, id: &str) -> Result<bool>;
async fn store_embeddings_batch(&self, embeddings: Vec<(String, Vec<f32>)>) -> Result<()>;
async fn get_embeddings_batch(&self, ids: &[String]) -> Result<Vec<Option<Vec<f32>>>>;
async fn store_relationship(&self, relationship: &EpisodeRelationship) -> Result<()> {
let _ = relationship;
Ok(())
}
async fn remove_relationship(&self, relationship_id: Uuid) -> Result<()> {
let _ = relationship_id;
Ok(())
}
async fn get_relationships(
&self,
episode_id: Uuid,
direction: Direction,
) -> Result<Vec<EpisodeRelationship>> {
let _ = (episode_id, direction);
Ok(Vec::new())
}
async fn relationship_exists(
&self,
from_episode_id: Uuid,
to_episode_id: Uuid,
relationship_type: RelationshipType,
) -> Result<bool> {
let _ = (from_episode_id, to_episode_id, relationship_type);
Ok(false)
}
async fn store_recommendation_session(&self, session: &RecommendationSession) -> Result<()> {
let _ = session;
Ok(())
}
async fn get_recommendation_session(
&self,
session_id: Uuid,
) -> Result<Option<RecommendationSession>> {
let _ = session_id;
Ok(None)
}
async fn get_recommendation_session_for_episode(
&self,
episode_id: Uuid,
) -> Result<Option<RecommendationSession>> {
let _ = episode_id;
Ok(None)
}
async fn store_recommendation_feedback(&self, feedback: &RecommendationFeedback) -> Result<()> {
let _ = feedback;
Ok(())
}
async fn get_recommendation_feedback(
&self,
session_id: Uuid,
) -> Result<Option<RecommendationFeedback>> {
let _ = session_id;
Ok(None)
}
async fn get_recommendation_stats(&self) -> Result<RecommendationStats> {
Ok(RecommendationStats::default())
}
async fn cleanup_episodes(&self, policy: &EpisodeRetentionPolicy) -> Result<CleanupResult> {
let _ = policy;
Ok(CleanupResult::new())
}
async fn count_cleanup_candidates(&self, policy: &EpisodeRetentionPolicy) -> Result<usize> {
let _ = policy;
Ok(0)
}
}