use async_trait::async_trait;
use crate::types::{ChannelVisibility, FactPrivacy};
#[async_trait]
pub trait MessageStore: Send + Sync {
async fn append_message(&self, msg: &super::Message) -> anyhow::Result<()>;
async fn get_history(
&self,
session_id: &str,
limit: usize,
) -> anyhow::Result<Vec<super::Message>>;
async fn get_context(
&self,
session_id: &str,
_query: &str,
limit: usize,
) -> anyhow::Result<Vec<super::Message>> {
self.get_history(session_id, limit).await
}
async fn clear_session(&self, session_id: &str) -> anyhow::Result<()>;
}
#[async_trait]
pub trait FactStore: Send + Sync {
async fn upsert_fact(
&self,
category: &str,
key: &str,
value: &str,
source: &str,
channel_id: Option<&str>,
privacy: FactPrivacy,
) -> anyhow::Result<()>;
async fn get_facts(&self, category: Option<&str>) -> anyhow::Result<Vec<super::Fact>>;
async fn get_relevant_facts(
&self,
_query: &str,
max: usize,
) -> anyhow::Result<Vec<super::Fact>> {
let mut facts = self.get_facts(None).await?;
facts.truncate(max);
Ok(facts)
}
async fn get_relevant_facts_for_channel(
&self,
query: &str,
max: usize,
_channel_id: Option<&str>,
_visibility: ChannelVisibility,
) -> anyhow::Result<Vec<super::Fact>> {
self.get_relevant_facts(query, max).await
}
async fn get_cross_channel_hints(
&self,
_query: &str,
_current_channel_id: &str,
_max: usize,
) -> anyhow::Result<Vec<super::Fact>> {
Ok(vec![])
}
async fn update_fact_privacy(
&self,
_fact_id: i64,
_privacy: FactPrivacy,
) -> anyhow::Result<()> {
Ok(())
}
async fn delete_fact(&self, _fact_id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn delete_fact_by_key(&self, _category: &str, _key: &str) -> anyhow::Result<bool> {
Ok(false)
}
async fn get_all_facts_with_provenance(&self) -> anyhow::Result<Vec<super::Fact>> {
self.get_facts(None).await
}
}
#[async_trait]
pub trait EpisodeStore: Send + Sync {
async fn get_relevant_episodes(
&self,
_query: &str,
_limit: usize,
) -> anyhow::Result<Vec<super::Episode>> {
Ok(vec![])
}
async fn get_relevant_episodes_for_channel(
&self,
_query: &str,
_limit: usize,
_channel_id: Option<&str>,
) -> anyhow::Result<Vec<super::Episode>> {
Ok(vec![])
}
}
#[async_trait]
pub trait TokenUsageStore: Send + Sync {
async fn record_token_usage(
&self,
_session_id: &str,
_usage: &super::TokenUsage,
) -> anyhow::Result<()> {
Ok(()) }
async fn get_token_usage_since(
&self,
_since: &str,
) -> anyhow::Result<Vec<super::TokenUsageRecord>> {
Ok(vec![]) }
#[allow(dead_code)] async fn get_token_usage_by_session(
&self,
_since: &str,
) -> anyhow::Result<Vec<(String, i64, i64, i64)>> {
Ok(vec![]) }
}
#[async_trait]
pub trait LearningStore: Send + Sync {
async fn get_behavior_patterns(
&self,
_min_confidence: f32,
) -> anyhow::Result<Vec<super::BehaviorPattern>> {
Ok(vec![])
}
async fn record_behavior_pattern(
&self,
_pattern_type: &str,
_description: &str,
_trigger_context: Option<&str>,
_action: Option<&str>,
_confidence_hint: f32,
_occurrence_delta: i32,
) -> anyhow::Result<()> {
Ok(())
}
async fn get_relevant_procedures(
&self,
_query: &str,
_limit: usize,
) -> anyhow::Result<Vec<super::Procedure>> {
Ok(vec![])
}
async fn get_relevant_error_solutions(
&self,
_error: &str,
_limit: usize,
) -> anyhow::Result<Vec<super::ErrorSolution>> {
Ok(vec![])
}
async fn get_all_expertise(&self) -> anyhow::Result<Vec<super::Expertise>> {
Ok(vec![])
}
async fn get_user_profile(&self) -> anyhow::Result<Option<super::UserProfile>> {
Ok(None)
}
async fn get_trusted_command_patterns(&self) -> anyhow::Result<Vec<(String, i32)>> {
Ok(vec![])
}
async fn increment_expertise(
&self,
_domain: &str,
_success: bool,
_error: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
async fn upsert_procedure(&self, _procedure: &super::Procedure) -> anyhow::Result<i64> {
Ok(0)
}
#[allow(dead_code)] async fn update_procedure_outcome(
&self,
_procedure_id: i64,
_success: bool,
_duration: Option<f32>,
) -> anyhow::Result<()> {
Ok(())
}
async fn insert_error_solution(&self, _solution: &super::ErrorSolution) -> anyhow::Result<i64> {
Ok(0)
}
#[allow(dead_code)] async fn update_error_solution_outcome(
&self,
_solution_id: i64,
_success: bool,
) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait SkillStore: Send + Sync {
#[allow(dead_code)]
async fn add_dynamic_skill(&self, _skill: &super::DynamicSkill) -> anyhow::Result<i64> {
Ok(0)
}
async fn get_dynamic_skills(&self) -> anyhow::Result<Vec<super::DynamicSkill>> {
Ok(vec![])
}
#[allow(dead_code)]
async fn delete_dynamic_skill(&self, _id: i64) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)]
async fn update_dynamic_skill_enabled(&self, _id: i64, _enabled: bool) -> anyhow::Result<()> {
Ok(())
}
async fn get_promotable_procedures(
&self,
_min_success: i32,
_min_rate: f32,
) -> anyhow::Result<Vec<super::Procedure>> {
Ok(vec![])
}
async fn add_skill_draft(&self, _draft: &super::SkillDraft) -> anyhow::Result<i64> {
Ok(0)
}
async fn get_pending_skill_drafts(&self) -> anyhow::Result<Vec<super::SkillDraft>> {
Ok(vec![])
}
async fn get_skill_draft(&self, _id: i64) -> anyhow::Result<Option<super::SkillDraft>> {
Ok(None)
}
async fn update_skill_draft_status(&self, _id: i64, _status: &str) -> anyhow::Result<()> {
Ok(())
}
async fn skill_draft_exists_for_procedure(
&self,
_procedure_name: &str,
) -> anyhow::Result<bool> {
Ok(false)
}
}
#[async_trait]
pub trait DynamicBotStore: Send + Sync {
async fn add_dynamic_bot(&self, _bot: &super::DynamicBot) -> anyhow::Result<i64> {
Ok(0)
}
async fn get_dynamic_bots(&self) -> anyhow::Result<Vec<super::DynamicBot>> {
Ok(vec![])
}
#[allow(dead_code)]
async fn update_dynamic_bot_allowed_users(
&self,
_bot_token: &str,
_allowed_user_ids: &[String],
) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)]
async fn delete_dynamic_bot(&self, _id: i64) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait SessionChannelStore: Send + Sync {
async fn save_session_channel(
&self,
_session_id: &str,
_channel_name: &str,
) -> anyhow::Result<()> {
Ok(())
}
async fn load_session_channels(&self) -> anyhow::Result<Vec<(String, String)>> {
Ok(vec![])
}
}
#[async_trait]
pub trait DynamicMcpServerStore: Send + Sync {
async fn save_dynamic_mcp_server(
&self,
_server: &super::DynamicMcpServer,
) -> anyhow::Result<i64> {
Ok(0)
}
async fn list_dynamic_mcp_servers(&self) -> anyhow::Result<Vec<super::DynamicMcpServer>> {
Ok(vec![])
}
async fn delete_dynamic_mcp_server(&self, _id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn update_dynamic_mcp_server(
&self,
_server: &super::DynamicMcpServer,
) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait DynamicCliAgentStore: Send + Sync {
async fn save_dynamic_cli_agent(&self, _agent: &super::DynamicCliAgent) -> anyhow::Result<i64> {
Ok(0)
}
async fn list_dynamic_cli_agents(&self) -> anyhow::Result<Vec<super::DynamicCliAgent>> {
Ok(vec![])
}
async fn delete_dynamic_cli_agent(&self, _id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn update_dynamic_cli_agent(
&self,
_agent: &super::DynamicCliAgent,
) -> anyhow::Result<()> {
Ok(())
}
async fn log_cli_agent_start(
&self,
_session_id: &str,
_agent_name: &str,
_prompt_summary: &str,
_working_dir: Option<&str>,
) -> anyhow::Result<i64> {
Ok(0)
}
async fn log_cli_agent_complete(
&self,
_id: i64,
_exit_code: Option<i32>,
_output_summary: &str,
_success: bool,
_duration_secs: f64,
) -> anyhow::Result<()> {
Ok(())
}
async fn get_cli_agent_invocations(
&self,
_limit: usize,
) -> anyhow::Result<Vec<super::CliAgentInvocation>> {
Ok(vec![])
}
async fn cleanup_stale_cli_agent_invocations(
&self,
_max_age_hours: i64,
) -> anyhow::Result<u64> {
Ok(0)
}
}
#[async_trait]
pub trait SettingsStore: Send + Sync {
async fn get_setting(&self, _key: &str) -> anyhow::Result<Option<String>> {
Ok(None)
}
async fn set_setting(&self, _key: &str, _value: &str) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait PeopleStore: Send + Sync {
async fn upsert_person(&self, _person: &super::Person) -> anyhow::Result<i64> {
Ok(0)
}
async fn get_person(&self, _id: i64) -> anyhow::Result<Option<super::Person>> {
Ok(None)
}
async fn get_person_by_platform_id(
&self,
_platform_id: &str,
) -> anyhow::Result<Option<super::Person>> {
Ok(None)
}
async fn find_person_by_name(&self, _name: &str) -> anyhow::Result<Option<super::Person>> {
Ok(None)
}
async fn get_all_people(&self) -> anyhow::Result<Vec<super::Person>> {
Ok(vec![])
}
async fn delete_person(&self, _id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn link_platform_id(
&self,
_person_id: i64,
_platform_id: &str,
_display_name: &str,
) -> anyhow::Result<()> {
Ok(())
}
async fn touch_person_interaction(&self, _person_id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn upsert_person_fact(
&self,
_person_id: i64,
_category: &str,
_key: &str,
_value: &str,
_source: &str,
_confidence: f32,
) -> anyhow::Result<()> {
Ok(())
}
async fn get_person_facts(
&self,
_person_id: i64,
_category: Option<&str>,
) -> anyhow::Result<Vec<super::PersonFact>> {
Ok(vec![])
}
async fn delete_person_fact(&self, _fact_id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn confirm_person_fact(&self, _fact_id: i64) -> anyhow::Result<()> {
Ok(())
}
async fn get_people_with_upcoming_dates(
&self,
_within_days: i32,
) -> anyhow::Result<Vec<(super::Person, super::PersonFact)>> {
Ok(vec![])
}
async fn prune_stale_person_facts(&self, _retention_days: u32) -> anyhow::Result<u64> {
Ok(0)
}
async fn get_people_needing_reconnect(
&self,
_inactive_days: u32,
) -> anyhow::Result<Vec<super::Person>> {
Ok(vec![])
}
}
#[async_trait]
pub trait OAuthStore: Send + Sync {
async fn save_oauth_connection(&self, _conn: &super::OAuthConnection) -> anyhow::Result<i64> {
Ok(0)
}
async fn save_pending_oauth_flow(&self, _flow: &super::PendingOAuthFlow) -> anyhow::Result<()> {
Ok(())
}
async fn get_oauth_connection(
&self,
_service: &str,
) -> anyhow::Result<Option<super::OAuthConnection>> {
Ok(None)
}
async fn list_oauth_connections(&self) -> anyhow::Result<Vec<super::OAuthConnection>> {
Ok(vec![])
}
async fn get_pending_oauth_flow(
&self,
_state: &str,
) -> anyhow::Result<Option<super::PendingOAuthFlow>> {
Ok(None)
}
async fn list_pending_oauth_flows(&self) -> anyhow::Result<Vec<super::PendingOAuthFlow>> {
Ok(vec![])
}
async fn delete_oauth_connection(&self, _service: &str) -> anyhow::Result<()> {
Ok(())
}
async fn delete_pending_oauth_flow(&self, _state: &str) -> anyhow::Result<()> {
Ok(())
}
async fn update_oauth_token_expiry(
&self,
_service: &str,
_expires_at: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait GoalStore: Send + Sync {
async fn create_goal(&self, _goal: &super::Goal) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_goal(&self, _id: &str) -> anyhow::Result<Option<super::Goal>> {
Ok(None)
}
#[allow(dead_code)] async fn update_goal(&self, _goal: &super::Goal) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_active_goals(&self) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn get_active_personal_goals(&self, _limit: i64) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn update_personal_goal(
&self,
_goal_id: &str,
_status: Option<&str>,
_progress_note: Option<&str>,
) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_goals_for_session(&self, _session_id: &str) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn get_pending_confirmation_goals(
&self,
_session_id: &str,
) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn activate_goal(&self, _goal_id: &str) -> anyhow::Result<bool> {
Ok(false)
}
#[allow(dead_code)] async fn create_task(&self, _task: &super::Task) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_task(&self, _id: &str) -> anyhow::Result<Option<super::Task>> {
Ok(None)
}
#[allow(dead_code)] async fn update_task(&self, _task: &super::Task) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_tasks_for_goal(&self, _goal_id: &str) -> anyhow::Result<Vec<super::Task>> {
Ok(vec![])
}
async fn count_completed_tasks_for_goal(&self, _goal_id: &str) -> anyhow::Result<i64> {
Ok(0)
}
#[allow(dead_code)] async fn claim_task(&self, _task_id: &str, _agent_id: &str) -> anyhow::Result<bool> {
Ok(false)
}
#[allow(dead_code)] async fn log_task_activity(&self, _activity: &super::TaskActivity) -> anyhow::Result<()> {
Ok(())
}
#[allow(dead_code)] async fn get_task_activities(
&self,
_task_id: &str,
) -> anyhow::Result<Vec<super::TaskActivity>> {
Ok(vec![])
}
async fn create_goal_schedule(&self, _schedule: &super::GoalSchedule) -> anyhow::Result<()> {
Ok(())
}
async fn get_goal_schedule(
&self,
_schedule_id: &str,
) -> anyhow::Result<Option<super::GoalSchedule>> {
Ok(None)
}
async fn get_schedules_for_goal(
&self,
_goal_id: &str,
) -> anyhow::Result<Vec<super::GoalSchedule>> {
Ok(vec![])
}
async fn get_due_goal_schedules(
&self,
_limit: i64,
) -> anyhow::Result<Vec<super::GoalSchedule>> {
Ok(vec![])
}
async fn update_goal_schedule(&self, _schedule: &super::GoalSchedule) -> anyhow::Result<()> {
Ok(())
}
async fn delete_goal_schedule(&self, _schedule_id: &str) -> anyhow::Result<bool> {
Ok(false)
}
async fn cancel_stale_pending_confirmation_goals(
&self,
_max_age_secs: i64,
) -> anyhow::Result<u64> {
Ok(0)
}
async fn get_scheduled_goals(&self) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn reset_daily_token_budgets(&self) -> anyhow::Result<u64> {
Ok(0)
}
async fn set_goal_budgets(
&self,
_goal_id: &str,
_budget_per_check: Option<i64>,
_budget_daily: Option<i64>,
) -> anyhow::Result<()> {
Ok(())
}
async fn add_goal_tokens_and_get_budget_status(
&self,
_goal_id: &str,
_delta_tokens: i64,
) -> anyhow::Result<Option<super::GoalTokenBudgetStatus>> {
Ok(None)
}
async fn upsert_scheduled_run_state(
&self,
_state: &super::ScheduledRunState,
) -> anyhow::Result<()> {
Ok(())
}
async fn get_scheduled_run_state(
&self,
_goal_id: &str,
) -> anyhow::Result<Option<super::ScheduledRunState>> {
Ok(None)
}
async fn delete_scheduled_run_state(&self, _goal_id: &str) -> anyhow::Result<bool> {
Ok(false)
}
async fn get_pending_tasks_by_priority(&self, _limit: i64) -> anyhow::Result<Vec<super::Task>> {
Ok(vec![])
}
async fn get_stuck_tasks(&self, _timeout_secs: i64) -> anyhow::Result<Vec<super::Task>> {
Ok(vec![])
}
#[allow(dead_code)]
async fn get_recently_completed_tasks(&self, _since: &str) -> anyhow::Result<Vec<super::Task>> {
Ok(vec![])
}
async fn mark_task_interrupted(&self, _task_id: &str) -> anyhow::Result<bool> {
Ok(false)
}
async fn count_active_evergreen_goals(&self) -> anyhow::Result<i64> {
Ok(0)
}
async fn get_goals_needing_notification(&self) -> anyhow::Result<Vec<super::Goal>> {
Ok(vec![])
}
async fn mark_goal_notified(&self, _goal_id: &str) -> anyhow::Result<()> {
Ok(())
}
async fn cleanup_stale_goals(&self, _stale_hours: i64) -> anyhow::Result<u64> {
Ok(0)
}
}
#[async_trait]
pub trait ConversationSummaryStore: Send + Sync {
async fn get_conversation_summary(
&self,
_session_id: &str,
) -> anyhow::Result<Option<super::ConversationSummary>> {
Ok(None)
}
async fn upsert_conversation_summary(
&self,
_summary: &super::ConversationSummary,
) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait HealthCheckStore: Send + Sync {
async fn health_check(&self) -> anyhow::Result<()> {
Ok(())
}
}
#[async_trait]
pub trait NotificationStore: Send + Sync {
async fn enqueue_notification(&self, _entry: &super::NotificationEntry) -> anyhow::Result<()> {
Ok(())
}
async fn get_pending_notifications(
&self,
_limit: i64,
) -> anyhow::Result<Vec<super::NotificationEntry>> {
Ok(vec![])
}
async fn mark_notification_delivered(&self, _notification_id: &str) -> anyhow::Result<()> {
Ok(())
}
async fn increment_notification_attempt(&self, _notification_id: &str) -> anyhow::Result<()> {
Ok(())
}
async fn cleanup_expired_notifications(&self) -> anyhow::Result<i64> {
Ok(0)
}
}
pub trait StateStore:
Send
+ Sync
+ MessageStore
+ FactStore
+ EpisodeStore
+ TokenUsageStore
+ LearningStore
+ SkillStore
+ DynamicBotStore
+ SessionChannelStore
+ DynamicMcpServerStore
+ DynamicCliAgentStore
+ SettingsStore
+ PeopleStore
+ OAuthStore
+ GoalStore
+ ConversationSummaryStore
+ HealthCheckStore
+ NotificationStore
{
}
impl<T> StateStore for T where
T: Send
+ Sync
+ MessageStore
+ FactStore
+ EpisodeStore
+ TokenUsageStore
+ LearningStore
+ SkillStore
+ DynamicBotStore
+ SessionChannelStore
+ DynamicMcpServerStore
+ DynamicCliAgentStore
+ SettingsStore
+ PeopleStore
+ OAuthStore
+ GoalStore
+ ConversationSummaryStore
+ HealthCheckStore
+ NotificationStore
{
}