#![cfg_attr(test, allow(clippy::unwrap_used, clippy::expect_used))]
use std::sync::Arc;
use std::time::SystemTime;
use async_trait::async_trait;
use crate::error::MemoryError;
use crate::observation::{Observation, ObservationType, SaveEntry};
use crate::store::{DueTask, Store, TaskRunRecord, UsageSummary};
use crate::types::{HistoryRow, MessageRow};
#[async_trait]
pub trait MemoryStore: Send + Sync {
async fn close_current_conversation(
&self,
channel: &str,
sender_id: &str,
project: &str,
) -> Result<bool, MemoryError>;
async fn get_memory_stats(&self, sender_id: &str) -> Result<(i64, i64, i64, i64), MemoryError>;
async fn db_size(&self) -> Result<u64, MemoryError>;
async fn get_total_usage(&self) -> Result<UsageSummary, MemoryError>;
async fn get_history(
&self,
channel: &str,
sender_id: &str,
limit: i64,
) -> Result<Vec<HistoryRow>, MemoryError>;
async fn search_messages(
&self,
query: &str,
exclude_conversation_id: &str,
sender_id: &str,
limit: i64,
since: Option<SystemTime>,
) -> Result<Vec<MessageRow>, MemoryError>;
async fn get_message_by_id(&self, id: &str) -> Result<Option<MessageRow>, MemoryError>;
async fn store_fact(&self, sender_id: &str, key: &str, value: &str) -> Result<(), MemoryError>;
async fn get_fact(&self, sender_id: &str, key: &str) -> Result<Option<String>, MemoryError>;
async fn get_facts(&self, sender_id: &str) -> Result<Vec<(String, String)>, MemoryError>;
async fn soft_delete_fact(&self, sender_id: &str, key: &str) -> Result<bool, MemoryError>;
async fn soft_delete_facts(
&self,
sender_id: &str,
key: Option<&str>,
) -> Result<u64, MemoryError>;
async fn list_soft_deleted_facts(
&self,
sender_id: &str,
) -> Result<Vec<(String, String, String)>, MemoryError>;
async fn save_observation(&self, entry: SaveEntry) -> Result<Observation, MemoryError>;
async fn get_observation_by_id(&self, id: &str) -> Result<Option<Observation>, MemoryError>;
async fn search_observations(
&self,
query: &str,
sender_id: &str,
limit: i64,
since: Option<SystemTime>,
kind: Option<ObservationType>,
) -> Result<Vec<Observation>, MemoryError>;
async fn soft_delete_observation(&self, id: &str) -> Result<bool, MemoryError>;
async fn list_soft_deleted_observations(
&self,
sender_id: &str,
) -> Result<Vec<Observation>, MemoryError>;
#[allow(clippy::too_many_arguments)]
async fn create_task(
&self,
channel: &str,
sender_id: &str,
reply_target: &str,
description: &str,
due_at: &str,
repeat: Option<&str>,
task_type: &str,
project: &str,
) -> Result<String, MemoryError>;
async fn get_tasks_for_sender(
&self,
sender_id: &str,
) -> Result<Vec<(String, String, String, Option<String>, String, String)>, MemoryError>;
async fn complete_task(&self, id: &str, repeat: Option<&str>) -> Result<(), MemoryError>;
async fn fail_task(&self, id: &str, error: &str, max_retries: u32)
-> Result<bool, MemoryError>;
async fn cancel_task(&self, id_prefix: &str, sender_id: &str) -> Result<bool, MemoryError>;
async fn get_due_tasks(&self) -> Result<Vec<DueTask>, MemoryError>;
async fn claim_due_tasks(&self) -> Result<Vec<DueTask>, MemoryError>;
#[allow(clippy::too_many_arguments)]
async fn record_task_run(
&self,
task_id: &str,
started_at: &str,
status: &str,
result: Option<&str>,
error: Option<&str>,
tokens_used: Option<u64>,
) -> Result<String, MemoryError>;
async fn list_task_runs(
&self,
task_id_prefix: &str,
limit: u32,
) -> Result<Vec<TaskRunRecord>, MemoryError>;
}
#[async_trait]
impl MemoryStore for Store {
async fn close_current_conversation(
&self,
channel: &str,
sender_id: &str,
project: &str,
) -> Result<bool, MemoryError> {
Store::close_current_conversation(self, channel, sender_id, project).await
}
async fn get_memory_stats(&self, sender_id: &str) -> Result<(i64, i64, i64, i64), MemoryError> {
Store::get_memory_stats(self, sender_id).await
}
async fn db_size(&self) -> Result<u64, MemoryError> {
Store::db_size(self).await
}
async fn get_total_usage(&self) -> Result<UsageSummary, MemoryError> {
Store::get_total_usage(self).await
}
async fn get_history(
&self,
channel: &str,
sender_id: &str,
limit: i64,
) -> Result<Vec<HistoryRow>, MemoryError> {
Store::get_history(self, channel, sender_id, limit).await
}
async fn search_messages(
&self,
query: &str,
exclude_conversation_id: &str,
sender_id: &str,
limit: i64,
since: Option<SystemTime>,
) -> Result<Vec<MessageRow>, MemoryError> {
Store::search_messages(
self,
query,
exclude_conversation_id,
sender_id,
limit,
since,
)
.await
}
async fn get_message_by_id(&self, id: &str) -> Result<Option<MessageRow>, MemoryError> {
Store::get_message_by_id(self, id).await
}
async fn store_fact(&self, sender_id: &str, key: &str, value: &str) -> Result<(), MemoryError> {
Store::store_fact(self, sender_id, key, value).await
}
async fn get_fact(&self, sender_id: &str, key: &str) -> Result<Option<String>, MemoryError> {
Store::get_fact(self, sender_id, key).await
}
async fn get_facts(&self, sender_id: &str) -> Result<Vec<(String, String)>, MemoryError> {
Store::get_facts(self, sender_id).await
}
async fn soft_delete_fact(&self, sender_id: &str, key: &str) -> Result<bool, MemoryError> {
Store::soft_delete_fact(self, sender_id, key).await
}
async fn soft_delete_facts(
&self,
sender_id: &str,
key: Option<&str>,
) -> Result<u64, MemoryError> {
Store::soft_delete_facts(self, sender_id, key).await
}
async fn list_soft_deleted_facts(
&self,
sender_id: &str,
) -> Result<Vec<(String, String, String)>, MemoryError> {
Store::list_soft_deleted_facts(self, sender_id).await
}
async fn save_observation(&self, entry: SaveEntry) -> Result<Observation, MemoryError> {
Store::save_observation(self, entry).await
}
async fn get_observation_by_id(&self, id: &str) -> Result<Option<Observation>, MemoryError> {
Store::get_observation_by_id(self, id).await
}
async fn search_observations(
&self,
query: &str,
sender_id: &str,
limit: i64,
since: Option<SystemTime>,
kind: Option<ObservationType>,
) -> Result<Vec<Observation>, MemoryError> {
Store::search_observations(self, query, sender_id, limit, since, kind).await
}
async fn soft_delete_observation(&self, id: &str) -> Result<bool, MemoryError> {
Store::soft_delete_observation(self, id).await
}
async fn list_soft_deleted_observations(
&self,
sender_id: &str,
) -> Result<Vec<Observation>, MemoryError> {
Store::list_soft_deleted_observations(self, sender_id).await
}
async fn create_task(
&self,
channel: &str,
sender_id: &str,
reply_target: &str,
description: &str,
due_at: &str,
repeat: Option<&str>,
task_type: &str,
project: &str,
) -> Result<String, MemoryError> {
Store::create_task(
self,
channel,
sender_id,
reply_target,
description,
due_at,
repeat,
task_type,
project,
)
.await
}
async fn get_tasks_for_sender(
&self,
sender_id: &str,
) -> Result<Vec<(String, String, String, Option<String>, String, String)>, MemoryError> {
Store::get_tasks_for_sender(self, sender_id).await
}
async fn complete_task(&self, id: &str, repeat: Option<&str>) -> Result<(), MemoryError> {
Store::complete_task(self, id, repeat).await
}
async fn fail_task(
&self,
id: &str,
error: &str,
max_retries: u32,
) -> Result<bool, MemoryError> {
Store::fail_task(self, id, error, max_retries).await
}
async fn cancel_task(&self, id_prefix: &str, sender_id: &str) -> Result<bool, MemoryError> {
Store::cancel_task(self, id_prefix, sender_id).await
}
async fn get_due_tasks(&self) -> Result<Vec<DueTask>, MemoryError> {
Store::get_due_tasks(self).await
}
async fn claim_due_tasks(&self) -> Result<Vec<DueTask>, MemoryError> {
Store::claim_due_tasks(self).await
}
async fn record_task_run(
&self,
task_id: &str,
started_at: &str,
status: &str,
result: Option<&str>,
error: Option<&str>,
tokens_used: Option<u64>,
) -> Result<String, MemoryError> {
Store::record_task_run(
self,
task_id,
started_at,
status,
result,
error,
tokens_used,
)
.await
}
async fn list_task_runs(
&self,
task_id_prefix: &str,
limit: u32,
) -> Result<Vec<TaskRunRecord>, MemoryError> {
Store::list_task_runs(self, task_id_prefix, limit).await
}
}
pub fn into_handle(store: Store) -> Arc<dyn MemoryStore> {
Arc::new(store)
}