use serde::{Deserialize, Serialize}; /// 全局统一的记忆 scope_key,所有渠道共享同一份记忆空间 pub const GLOBAL_SCOPE_KEY: &str = "default"; /// 允许的记忆命名空间列表 /// /// 每个命名空间代表一类记忆内容,用于分类管理和检索。 /// 禁止使用未在此列表中的 namespace 创建记忆。 pub const ALLOWED_MEMORY_NAMESPACES: &[(&str, &str)] = &[ ( "user", "用户记忆:存储用户长期偏好、身份背景和历史协作信息,实现跨会话的个性化服务与持续协作", ), ( "semantic", "语义记忆:存储结构化或非结构化知识内容,支持知识检索、问答增强和长期知识积累", ), ( "episodic", "情景记忆:记录历史对话、任务执行过程及关键事件,支持经验回溯、案例复用和行为追踪", ), ( "skill", "技能记忆:存储技能定义、工作流、工具调用策略及最佳实践,支持能力复用与自动化执行", ), ( "environment", "环境记忆:存储外部系统状态、运行环境配置和实时资源信息,为智能决策提供环境感知能力", ), ( "reflection", "反思记忆:沉淀任务执行过程中的成功经验、失败原因和优化建议,支持智能体持续学习与自我改进", ), ("other", "其他记忆:不属于以上分类的其他记忆内容"), ]; /// 验证 namespace 是否在允许列表中 pub fn is_valid_namespace(namespace: &str) -> bool { ALLOWED_MEMORY_NAMESPACES .iter() .any(|(name, _)| *name == namespace) } /// 获取 namespace 的中文描述 pub fn get_namespace_description(namespace: &str) -> Option<&'static str> { ALLOWED_MEMORY_NAMESPACES .iter() .find(|(name, _)| *name == namespace) .map(|(_, desc)| *desc) } /// 获取所有允许的 namespace 名称列表(用于 JSON schema enum) pub fn allowed_namespace_names() -> Vec<&'static str> { ALLOWED_MEMORY_NAMESPACES .iter() .map(|(name, _)| *name) .collect() } #[derive(Debug, Clone)] pub struct TodoRecord { pub id: String, pub scope_key: String, pub session_id: String, pub topic_id: Option, pub content: String, pub status: String, pub priority: String, pub created_at: i64, pub updated_at: i64, pub created_by_message_id: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SkillEventRecord { pub id: String, pub session_id: Option, pub event_type: String, pub skill_name: Option, pub payload: serde_json::Value, pub created_at: i64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SessionRecord { pub id: String, pub title: String, pub channel_name: String, pub chat_id: String, pub summary: Option, pub created_at: i64, pub updated_at: i64, pub last_active_at: i64, pub archived_at: Option, pub deleted_at: Option, pub message_count: i64, pub user_turn_count: i64, pub agent_prompt_reinjection_count: i64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TopicRecord { pub id: String, pub session_id: String, pub title: String, pub description: Option, pub created_at: i64, pub updated_at: i64, pub last_active_at: i64, pub message_count: i64, /// 话题级用户模型选择(NULL 表示无显式选择,运行时按继承链解析) pub provider: Option, pub model: Option, } /// pending_subagents 表的记录,跟踪异步子代理执行状态。 /// /// 生命周期:task 工具 spawn 时插入(status=running), /// 子代理完成时更新为 completed/failed/timeout, /// 进程重启时 running 状态被标记为 interrupted。 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PendingSubagentRecord { /// 子代理 task_id(主键,与 TaskSession.id 一致) pub task_id: String, /// 父会话 session_id pub parent_session_id: String, /// 父会话 topic_id(用于按 topic 查询未完成子代理) pub parent_topic_id: String, /// 父会话 chat_id pub parent_chat_id: String, /// 父会话 channel_name pub parent_channel: String, /// 子代理定义名称(可选,用于诊断) pub def_name: Option, /// 子代理启动时间戳 pub spawned_at: i64, /// 执行状态:running / completed / failed / interrupted / cancelled / timeout pub status: String, } /// 单个 session 的 token 用量统计(聚合结果)。 #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct SessionTokenStats { pub prompt_tokens: u64, pub completion_tokens: u64, pub total_tokens: u64, /// 累计缓存命中的输入 tokens 数(老数据为 0) pub cached_tokens: u64, pub last_prompt_tokens: Option, pub context_window_tokens: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct MemoryRecord { pub id: String, pub scope_kind: String, pub scope_key: String, pub namespace: String, pub memory_key: String, pub content: String, pub source_type: String, pub source_session_id: Option, pub source_message_id: Option, pub source_message_seq: Option, pub source_channel_name: Option, pub source_chat_id: Option, pub created_at: i64, pub updated_at: i64, } #[derive(Debug, Clone)] pub struct MemoryUpsert { pub scope_kind: String, pub scope_key: String, pub namespace: String, pub memory_key: String, pub content: String, pub source_type: String, pub source_session_id: Option, pub source_message_id: Option, pub source_message_seq: Option, pub source_channel_name: Option, pub source_chat_id: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum SchedulerJobState { Scheduled, Running, Paused, Completed, } impl SchedulerJobState { pub fn as_str(&self) -> &'static str { match self { SchedulerJobState::Scheduled => "scheduled", SchedulerJobState::Running => "running", SchedulerJobState::Paused => "paused", SchedulerJobState::Completed => "completed", } } pub fn from_str(value: &str) -> Option { match value { "scheduled" => Some(Self::Scheduled), "running" => Some(Self::Running), "paused" => Some(Self::Paused), "completed" => Some(Self::Completed), _ => None, } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum SchedulerJobStatus { Ok, Error, Skipped, } impl SchedulerJobStatus { pub fn as_str(&self) -> &'static str { match self { SchedulerJobStatus::Ok => "ok", SchedulerJobStatus::Error => "error", SchedulerJobStatus::Skipped => "skipped", } } pub fn from_str(value: &str) -> Option { match value { "ok" => Some(Self::Ok), "error" => Some(Self::Error), "skipped" => Some(Self::Skipped), _ => None, } } } impl Default for SchedulerJobState { fn default() -> Self { Self::Scheduled } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SchedulerJobRecord { pub id: String, pub kind: String, pub schedule: serde_json::Value, pub interval_secs: i64, pub startup_delay_secs: i64, pub target: serde_json::Value, pub payload: serde_json::Value, pub enabled: bool, pub state: SchedulerJobState, pub last_status: Option, pub last_error: Option, pub run_count: i64, pub max_runs: Option, pub last_fired_at: Option, pub next_fire_at: Option, pub paused_at: Option, pub completed_at: Option, pub created_at: i64, pub updated_at: i64, } #[derive(Debug, Clone)] pub struct SchedulerJobUpsert { pub id: String, pub kind: String, pub schedule: serde_json::Value, pub interval_secs: i64, pub startup_delay_secs: i64, pub target: serde_json::Value, pub payload: serde_json::Value, pub enabled: bool, pub state: SchedulerJobState, pub last_status: Option, pub last_error: Option, pub run_count: i64, pub max_runs: Option, pub last_fired_at: Option, pub next_fire_at: Option, pub paused_at: Option, pub completed_at: Option, }