-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsupermemory.mnm
More file actions
264 lines (227 loc) · 6.68 KB
/
Copy pathsupermemory.mnm
File metadata and controls
264 lines (227 loc) · 6.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# supermemory.mnm
# Universal Memory Layer with Profiles and Connectors
config {
storage: sqlite("./supermemory.db")
vector: auto
graph: auto
embedding: openai("text-embedding-3-small")
extractor: openai("gpt-4o")
}
namespace supermemory {
# === MEMORY TYPES ===
# Atomic facts extracted from conversations
memory MemoryFact {
content: string
subject: string # Entity the fact is about
predicate: string # Relationship type
object: string # Related entity or value
user_id: string
container: string # Scope: "user", "project", "org"
source_type: string # "conversation", "document", "connector"
source_id: string?
confidence: float[0,1]
document_date: timestamp? # When content was authored
created_at: timestamp
accessed_at: timestamp
@index user_id
@index container
@index source_type
@index subject
}
# User profile: stable facts + dynamic context
memory UserProfile {
user_id: string
preferences: string[]
expertise: string[]
recent_topics: string[]
summary: string
last_updated: timestamp
@index user_id
}
# Chunks from documents/connectors
memory DocumentChunk {
content: string
document_id: string
document_type: string # "pdf", "notion", "gdrive", "github"
chunk_index: int
metadata: string # JSON
@index document_id
}
# Connector sync state
memory ConnectorState {
connector_type: string # "notion", "gdrive", "github"
user_id: string
last_sync: timestamp
cursor: string?
@index connector_type
@index user_id
}
# === EXTERNAL FUNCTIONS ===
@extern
fn sync_connector(connector_type: string, user_id: string): DocumentChunk[]
@extern
fn process_document(content: string, doc_type: string): DocumentChunk[]
# === HANDLERS ===
# On conversation message, extract facts and build graph
on message(user_id: string, content: string, container: string) {
content
|> extract()
|> map(f => MemoryFact {
content: f.content,
subject: f.subject,
predicate: f.predicate,
object: f.object,
user_id: user_id,
container: container,
source_type: "conversation",
confidence: f.confidence,
created_at: now(),
accessed_at: now()
})
|> store()
}
# Explicit save request from user
on save_memory(user_id: string, content: string, container: string, subject: string, predicate: string, object: string) {
store(MemoryFact {
content: content,
subject: subject,
predicate: predicate,
object: object,
user_id: user_id,
container: container,
source_type: "explicit",
confidence: 1.0,
created_at: now(),
accessed_at: now()
})
}
# Document upload
on document_upload(user_id: string, content: string, doc_type: string, doc_id: string) {
content
|> process_document(doc_type)
|> map(chunk => DocumentChunk {
content: chunk.content,
document_id: doc_id,
document_type: doc_type,
chunk_index: chunk.index,
metadata: chunk.metadata
})
|> store()
}
# Connector sync webhook
on connector_sync(connector_type: string, user_id: string) {
let chunks = sync_connector(connector_type, user_id)
chunks |> store()
# Update sync state
store(ConnectorState {
connector_type: connector_type,
user_id: user_id,
last_sync: now()
})
}
# === QUERIES ===
# Main search: combines memory + RAG
query Search(query: string, user_id: string, container: string?): MemoryFact[] {
from MemoryFact, DocumentChunk
where semantic_match(query, threshold: 0.6)
and user_id == user_id
and (container == null or container == container)
order by confidence * 0.4 + relevance * 0.4 + recency * 0.2 desc
limit 15
}
# Get user profile for context injection
query GetProfile(user_id: string): UserProfile? {
from UserProfile
where user_id == user_id
limit 1
}
# Search with temporal awareness
query TemporalSearch(query: string, user_id: string, as_of: timestamp?): MemoryFact[] {
from MemoryFact
where semantic_match(query, threshold: 0.6)
and user_id == user_id
and (as_of == null or document_date <= as_of)
order by document_date desc
limit 10
}
# Pattern matching for structured queries
query FindByPattern(pattern: string, user_id: string): MemoryFact[] {
from MemoryFact
where regex(content, pattern)
and user_id == user_id
limit 20
}
# Graph-powered: find memories connected to the input within 2 hops
query GraphSearch(query: string, user_id: string): MemoryFact[] {
from MemoryFact
where graph_match(query, hops: 2)
and user_id == user_id
order by confidence desc
limit 15
}
# Hybrid: vector similarity + graph connectivity
query DeepSearch(query: string, user_id: string): MemoryFact[] {
from MemoryFact
where semantic_match(query, threshold: 0.5)
and graph_match(query, hops: 3)
and user_id == user_id
order by confidence desc
limit 10
}
# Raw Cypher: find all entities related to a topic
query RelatedEntities(topic: string): MemoryFact[] {
from MemoryFact
where cypher("
MATCH (e:Entity {name: $topic})-[*1..2]-(related:Entity)-[:HAS_FACT]->(f:MemoryFact)
RETURN DISTINCT f._id AS id
")
limit 20
}
# === UPDATE RULES ===
update MemoryFact {
on_access {
accessed_at = now()
}
on_conflict(old, new) {
# Supermemory's disambiguation: newer document_date wins
if new.document_date > old.document_date {
supersede(old, new)
} else if new.confidence > old.confidence + 0.2 {
supersede(old, new)
} else {
discard(new)
}
}
# Automatic forgetting for low-value memories
every 24h {
if confidence < 0.3 and accessed_at < now() - 30d {
delete()
}
}
}
update UserProfile {
# Rebuild profile from facts periodically
every 6h {
let facts = from MemoryFact
where user_id == user_id
order by confidence desc
limit 100
preferences = facts |> extract_preferences()
expertise = facts |> extract_expertise()
recent_topics = facts
|> filter(f => f.created_at > now() - 7d)
|> extract_topics()
summary = facts |> summarize()
last_updated = now()
}
}
# === POLICIES ===
# Scheduled connector syncs
policy ConnectorRefresh {
every 1h {
from ConnectorState
where last_sync < now() - 1h
|> each(state => emit("connector_sync", state.connector_type, state.user_id))
}
}
}