47
47
48
48
DB_DSN = "postgresql://postgres:postgres@localhost:54320/memory_db"
49
49
# reset memory with rm ~/.fastmcp/{USER}/memory/*
50
- PROFILE_DIR = (
51
- Path .home () / ".fastmcp" / os .environ .get ("USER" , "anon" ) / "memory"
52
- ).resolve ()
50
+ PROFILE_DIR = (Path .home () / ".fastmcp" / os .environ .get ("USER" , "anon" ) / "memory" ).resolve ()
53
51
PROFILE_DIR .mkdir (parents = True , exist_ok = True )
54
52
55
53
56
54
def cosine_similarity (a : list [float ], b : list [float ]) -> float :
57
55
a_array = np .array (a , dtype = np .float64 )
58
56
b_array = np .array (b , dtype = np .float64 )
59
- return np .dot (a_array , b_array ) / (
60
- np .linalg .norm (a_array ) * np .linalg .norm (b_array )
61
- )
57
+ return np .dot (a_array , b_array ) / (np .linalg .norm (a_array ) * np .linalg .norm (b_array ))
62
58
63
59
64
60
async def do_ai [T ](
@@ -97,9 +93,7 @@ class MemoryNode(BaseModel):
97
93
summary : str = ""
98
94
importance : float = 1.0
99
95
access_count : int = 0
100
- timestamp : float = Field (
101
- default_factory = lambda : datetime .now (timezone .utc ).timestamp ()
102
- )
96
+ timestamp : float = Field (default_factory = lambda : datetime .now (timezone .utc ).timestamp ())
103
97
embedding : list [float ]
104
98
105
99
@classmethod
@@ -152,9 +146,7 @@ async def merge_with(self, other: Self, deps: Deps):
152
146
self .importance += other .importance
153
147
self .access_count += other .access_count
154
148
self .embedding = [(a + b ) / 2 for a , b in zip (self .embedding , other .embedding )]
155
- self .summary = await do_ai (
156
- self .content , "Summarize the following text concisely." , str , deps
157
- )
149
+ self .summary = await do_ai (self .content , "Summarize the following text concisely." , str , deps )
158
150
await self .save (deps )
159
151
# Delete the merged node from the database
160
152
if other .id is not None :
@@ -221,9 +213,7 @@ async def find_similar_memories(embedding: list[float], deps: Deps) -> list[Memo
221
213
222
214
async def update_importance (user_embedding : list [float ], deps : Deps ):
223
215
async with deps .pool .acquire () as conn :
224
- rows = await conn .fetch (
225
- "SELECT id, importance, access_count, embedding FROM memories"
226
- )
216
+ rows = await conn .fetch ("SELECT id, importance, access_count, embedding FROM memories" )
227
217
for row in rows :
228
218
memory_embedding = row ["embedding" ]
229
219
similarity = cosine_similarity (user_embedding , memory_embedding )
@@ -273,25 +263,19 @@ async def display_memory_tree(deps: Deps) -> str:
273
263
)
274
264
result = ""
275
265
for row in rows :
276
- effective_importance = row ["importance" ] * (
277
- 1 + math .log (row ["access_count" ] + 1 )
278
- )
266
+ effective_importance = row ["importance" ] * (1 + math .log (row ["access_count" ] + 1 ))
279
267
summary = row ["summary" ] or row ["content" ]
280
268
result += f"- { summary } (Importance: { effective_importance :.2f} )\n "
281
269
return result
282
270
283
271
284
272
@mcp .tool ()
285
273
async def remember (
286
- contents : list [str ] = Field (
287
- description = "List of observations or memories to store"
288
- ),
274
+ contents : list [str ] = Field (description = "List of observations or memories to store" ),
289
275
):
290
276
deps = Deps (openai = AsyncOpenAI (), pool = await get_db_pool ())
291
277
try :
292
- return "\n " .join (
293
- await asyncio .gather (* [add_memory (content , deps ) for content in contents ])
294
- )
278
+ return "\n " .join (await asyncio .gather (* [add_memory (content , deps ) for content in contents ]))
295
279
finally :
296
280
await deps .pool .close ()
297
281
@@ -305,9 +289,7 @@ async def read_profile() -> str:
305
289
306
290
307
291
async def initialize_database ():
308
- pool = await asyncpg .create_pool (
309
- "postgresql://postgres:postgres@localhost:54320/postgres"
310
- )
292
+ pool = await asyncpg .create_pool ("postgresql://postgres:postgres@localhost:54320/postgres" )
311
293
try :
312
294
async with pool .acquire () as conn :
313
295
await conn .execute ("""
0 commit comments