Maheen001 commited on
Commit
7eb32cf
·
verified ·
1 Parent(s): e64b016

Create agent/memory.py

Browse files
Files changed (1) hide show
  1. agent/memory.py +265 -0
agent/memory.py ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from pathlib import Path
3
+ from typing import List, Dict, Any, Optional
4
+ from datetime import datetime
5
+ import sqlite3
6
+
7
+
8
+ class MemoryStore:
9
+ """Persistent memory store for agent context and user preferences"""
10
+
11
+ def __init__(self, db_path: str = "data/memory.db"):
12
+ """Initialize memory store with SQLite"""
13
+ Path(db_path).parent.mkdir(parents=True, exist_ok=True)
14
+ self.db_path = db_path
15
+ self._init_db()
16
+
17
+ def _init_db(self):
18
+ """Initialize database schema"""
19
+ conn = sqlite3.connect(self.db_path)
20
+ cursor = conn.cursor()
21
+
22
+ # Create memories table
23
+ cursor.execute('''
24
+ CREATE TABLE IF NOT EXISTS memories (
25
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
26
+ content TEXT NOT NULL,
27
+ memory_type TEXT,
28
+ metadata TEXT,
29
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
30
+ importance INTEGER DEFAULT 5
31
+ )
32
+ ''')
33
+
34
+ # Create user preferences table
35
+ cursor.execute('''
36
+ CREATE TABLE IF NOT EXISTS preferences (
37
+ key TEXT PRIMARY KEY,
38
+ value TEXT NOT NULL,
39
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
40
+ )
41
+ ''')
42
+
43
+ # Create context table for short-term memory
44
+ cursor.execute('''
45
+ CREATE TABLE IF NOT EXISTS context (
46
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ session_id TEXT,
48
+ content TEXT NOT NULL,
49
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
50
+ )
51
+ ''')
52
+
53
+ conn.commit()
54
+ conn.close()
55
+
56
+ def add_memory(
57
+ self,
58
+ content: str,
59
+ memory_type: str = 'general',
60
+ metadata: Dict[str, Any] = None,
61
+ importance: int = 5
62
+ ) -> int:
63
+ """
64
+ Add a memory to long-term storage
65
+
66
+ Args:
67
+ content: Memory content
68
+ memory_type: Type of memory (general, task, preference, etc.)
69
+ metadata: Additional metadata
70
+ importance: Importance score (1-10)
71
+
72
+ Returns:
73
+ Memory ID
74
+ """
75
+ conn = sqlite3.connect(self.db_path)
76
+ cursor = conn.cursor()
77
+
78
+ metadata_json = json.dumps(metadata) if metadata else '{}'
79
+
80
+ cursor.execute('''
81
+ INSERT INTO memories (content, memory_type, metadata, importance)
82
+ VALUES (?, ?, ?, ?)
83
+ ''', (content, memory_type, metadata_json, importance))
84
+
85
+ memory_id = cursor.lastrowid
86
+ conn.commit()
87
+ conn.close()
88
+
89
+ return memory_id
90
+
91
+ def get_memories(
92
+ self,
93
+ memory_type: Optional[str] = None,
94
+ limit: int = 10,
95
+ min_importance: int = 0
96
+ ) -> List[Dict[str, Any]]:
97
+ """
98
+ Retrieve memories
99
+
100
+ Args:
101
+ memory_type: Filter by memory type
102
+ limit: Maximum number of memories to return
103
+ min_importance: Minimum importance score
104
+
105
+ Returns:
106
+ List of memories
107
+ """
108
+ conn = sqlite3.connect(self.db_path)
109
+ cursor = conn.cursor()
110
+
111
+ query = '''
112
+ SELECT id, content, memory_type, metadata, created_at, importance
113
+ FROM memories
114
+ WHERE importance >= ?
115
+ '''
116
+ params = [min_importance]
117
+
118
+ if memory_type:
119
+ query += ' AND memory_type = ?'
120
+ params.append(memory_type)
121
+
122
+ query += ' ORDER BY importance DESC, created_at DESC LIMIT ?'
123
+ params.append(limit)
124
+
125
+ cursor.execute(query, params)
126
+ rows = cursor.fetchall()
127
+ conn.close()
128
+
129
+ memories = []
130
+ for row in rows:
131
+ memories.append({
132
+ 'id': row[0],
133
+ 'content': row[1],
134
+ 'memory_type': row[2],
135
+ 'metadata': json.loads(row[3]),
136
+ 'created_at': row[4],
137
+ 'importance': row[5]
138
+ })
139
+
140
+ return memories
141
+
142
+ def get_relevant_memories(self, query: str, k: int = 5) -> str:
143
+ """
144
+ Get memories relevant to a query
145
+
146
+ Args:
147
+ query: Search query
148
+ k: Number of memories to return
149
+
150
+ Returns:
151
+ Formatted string of relevant memories
152
+ """
153
+ # Simple keyword-based search (can be enhanced with embeddings)
154
+ conn = sqlite3.connect(self.db_path)
155
+ cursor = conn.cursor()
156
+
157
+ # Search for memories containing query keywords
158
+ keywords = query.lower().split()
159
+
160
+ memories = []
161
+ for keyword in keywords[:3]: # Limit to 3 keywords
162
+ cursor.execute('''
163
+ SELECT content, memory_type, importance
164
+ FROM memories
165
+ WHERE LOWER(content) LIKE ?
166
+ ORDER BY importance DESC
167
+ LIMIT ?
168
+ ''', (f'%{keyword}%', k))
169
+
170
+ memories.extend(cursor.fetchall())
171
+
172
+ conn.close()
173
+
174
+ if not memories:
175
+ return "No relevant memories found."
176
+
177
+ # Format memories
178
+ unique_memories = list({m[0]: m for m in memories}.values())[:k]
179
+ formatted = []
180
+ for content, mem_type, importance in unique_memories:
181
+ formatted.append(f"[{mem_type}] {content}")
182
+
183
+ return "\n".join(formatted)
184
+
185
+ def set_preference(self, key: str, value: Any):
186
+ """Set a user preference"""
187
+ conn = sqlite3.connect(self.db_path)
188
+ cursor = conn.cursor()
189
+
190
+ value_json = json.dumps(value)
191
+
192
+ cursor.execute('''
193
+ INSERT OR REPLACE INTO preferences (key, value, updated_at)
194
+ VALUES (?, ?, CURRENT_TIMESTAMP)
195
+ ''', (key, value_json))
196
+
197
+ conn.commit()
198
+ conn.close()
199
+
200
+ def get_preference(self, key: str, default: Any = None) -> Any:
201
+ """Get a user preference"""
202
+ conn = sqlite3.connect(self.db_path)
203
+ cursor = conn.cursor()
204
+
205
+ cursor.execute('SELECT value FROM preferences WHERE key = ?', (key,))
206
+ row = cursor.fetchone()
207
+ conn.close()
208
+
209
+ if row:
210
+ return json.loads(row[0])
211
+ return default
212
+
213
+ def get_all_preferences(self) -> Dict[str, Any]:
214
+ """Get all user preferences"""
215
+ conn = sqlite3.connect(self.db_path)
216
+ cursor = conn.cursor()
217
+
218
+ cursor.execute('SELECT key, value FROM preferences')
219
+ rows = cursor.fetchall()
220
+ conn.close()
221
+
222
+ return {key: json.loads(value) for key, value in rows}
223
+
224
+ def add_context(self, session_id: str, content: str):
225
+ """Add to short-term context"""
226
+ conn = sqlite3.connect(self.db_path)
227
+ cursor = conn.cursor()
228
+
229
+ cursor.execute('''
230
+ INSERT INTO context (session_id, content)
231
+ VALUES (?, ?)
232
+ ''', (session_id, content))
233
+
234
+ conn.commit()
235
+ conn.close()
236
+
237
+ def get_context(self, session_id: str, limit: int = 10) -> List[str]:
238
+ """Get recent context for a session"""
239
+ conn = sqlite3.connect(self.db_path)
240
+ cursor = conn.cursor()
241
+
242
+ cursor.execute('''
243
+ SELECT content FROM context
244
+ WHERE session_id = ?
245
+ ORDER BY created_at DESC
246
+ LIMIT ?
247
+ ''', (session_id, limit))
248
+
249
+ rows = cursor.fetchall()
250
+ conn.close()
251
+
252
+ return [row[0] for row in reversed(rows)]
253
+
254
+ def clear_old_context(self, days: int = 7):
255
+ """Clear context older than specified days"""
256
+ conn = sqlite3.connect(self.db_path)
257
+ cursor = conn.cursor()
258
+
259
+ cursor.execute('''
260
+ DELETE FROM context
261
+ WHERE created_at < datetime('now', ? || ' days')
262
+ ''', (f'-{days}',))
263
+
264
+ conn.commit()
265
+ conn.close()