1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "snake_case")]
7pub enum MemoryType {
8 Episodic,
9 Semantic,
10 Procedural,
11 Decision,
12 Architecture,
13 Debugging,
14 Task,
15 Question,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Memory {
20 pub id: Uuid,
21 pub content: String,
22 pub embedding: Vec<f32>,
23 pub memory_type: MemoryType,
24 pub confidence: f32,
25 pub created_at: DateTime<Utc>,
26 pub last_accessed: DateTime<Utc>,
27 pub access_count: u32,
28 pub source: String,
29 pub source_id: String,
30 #[serde(default)]
31 pub project_path: Option<String>,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct Entity {
36 pub id: Uuid,
37 pub name: String,
38 pub entity_type: String,
39 pub embedding: Vec<f32>,
40 pub aliases: Vec<String>,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Conversation {
45 pub id: Uuid,
46 pub source: String,
47 pub machine_id: String,
48 pub started_at: DateTime<Utc>,
49 pub project_path: Option<String>,
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
53#[serde(rename_all = "snake_case")]
54pub enum RelationType {
55 RelatesTo,
56 Mentions,
57 DerivedFrom,
58 Contradicts,
59 Reinforces,
60 Supersedes,
61 DistilledFrom,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct Relation {
66 pub from_id: Uuid,
67 pub to_id: Uuid,
68 pub relation_type: RelationType,
69 pub strength: f32,
70 pub context: Option<String>,
71}
72
73impl Memory {
74 pub fn new(
75 content: String,
76 memory_type: MemoryType,
77 source: String,
78 source_id: String,
79 ) -> Self {
80 let now = Utc::now();
81 Self {
82 id: Uuid::new_v4(),
83 content,
84 embedding: Vec::new(),
85 memory_type,
86 confidence: 1.0,
87 created_at: now,
88 last_accessed: now,
89 access_count: 0,
90 source,
91 source_id,
92 project_path: None,
93 }
94 }
95
96 pub fn with_project_path(mut self, path: Option<String>) -> Self {
97 self.project_path = path;
98 self
99 }
100
101 pub fn reinforce(&mut self) {
102 self.access_count += 1;
103 self.last_accessed = Utc::now();
104 self.confidence = (self.confidence + 0.1).min(1.0);
105 }
106}
107
108impl Entity {
109 pub fn new(name: String, entity_type: String) -> Self {
110 Self {
111 id: Uuid::new_v4(),
112 name,
113 entity_type,
114 embedding: Vec::new(),
115 aliases: Vec::new(),
116 }
117 }
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
121#[serde(rename_all = "snake_case")]
122pub enum SyncOp {
123 Create,
124 Update,
125 Delete,
126}
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
129#[serde(rename_all = "snake_case")]
130pub enum SyncNodeType {
131 Memory,
132 Entity,
133 Conversation,
134 Relation,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct SyncEntry {
139 pub seq: u64,
140 pub op: SyncOp,
141 pub node_type: SyncNodeType,
142 pub node_id: String,
143 pub machine_id: String,
144 pub timestamp: DateTime<Utc>,
145 pub data: Option<String>,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct SyncState {
150 pub peer_id: String,
151 pub last_seq: u64,
152 pub last_sync_at: DateTime<Utc>,
153}