alma-memory 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
alma/storage/base.py ADDED
@@ -0,0 +1,372 @@
1
+ """
2
+ ALMA Storage Backend Interface.
3
+
4
+ Abstract base class that all storage backends must implement.
5
+ """
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import Optional, List, Dict, Any
9
+ from datetime import datetime
10
+
11
+ from alma.types import (
12
+ Heuristic,
13
+ Outcome,
14
+ UserPreference,
15
+ DomainKnowledge,
16
+ AntiPattern,
17
+ MemoryType,
18
+ )
19
+
20
+
21
+ class StorageBackend(ABC):
22
+ """
23
+ Abstract base class for ALMA storage backends.
24
+
25
+ Implementations:
26
+ - FileBasedStorage: JSON files (testing/fallback)
27
+ - SQLiteStorage: Local SQLite + FAISS vectors
28
+ - AzureCosmosStorage: Production Azure Cosmos DB
29
+ """
30
+
31
+ # ==================== WRITE OPERATIONS ====================
32
+
33
+ @abstractmethod
34
+ def save_heuristic(self, heuristic: Heuristic) -> str:
35
+ """Save a heuristic, return its ID."""
36
+ pass
37
+
38
+ @abstractmethod
39
+ def save_outcome(self, outcome: Outcome) -> str:
40
+ """Save an outcome, return its ID."""
41
+ pass
42
+
43
+ @abstractmethod
44
+ def save_user_preference(self, preference: UserPreference) -> str:
45
+ """Save a user preference, return its ID."""
46
+ pass
47
+
48
+ @abstractmethod
49
+ def save_domain_knowledge(self, knowledge: DomainKnowledge) -> str:
50
+ """Save domain knowledge, return its ID."""
51
+ pass
52
+
53
+ @abstractmethod
54
+ def save_anti_pattern(self, anti_pattern: AntiPattern) -> str:
55
+ """Save an anti-pattern, return its ID."""
56
+ pass
57
+
58
+ # ==================== READ OPERATIONS ====================
59
+
60
+ @abstractmethod
61
+ def get_heuristics(
62
+ self,
63
+ project_id: str,
64
+ agent: Optional[str] = None,
65
+ embedding: Optional[List[float]] = None,
66
+ top_k: int = 5,
67
+ min_confidence: float = 0.0,
68
+ ) -> List[Heuristic]:
69
+ """
70
+ Get heuristics, optionally filtered by agent and similarity.
71
+
72
+ Args:
73
+ project_id: Project to query
74
+ agent: Filter by agent name
75
+ embedding: Query embedding for semantic search
76
+ top_k: Max results to return
77
+ min_confidence: Minimum confidence threshold
78
+
79
+ Returns:
80
+ List of matching heuristics
81
+ """
82
+ pass
83
+
84
+ @abstractmethod
85
+ def get_outcomes(
86
+ self,
87
+ project_id: str,
88
+ agent: Optional[str] = None,
89
+ task_type: Optional[str] = None,
90
+ embedding: Optional[List[float]] = None,
91
+ top_k: int = 5,
92
+ success_only: bool = False,
93
+ ) -> List[Outcome]:
94
+ """
95
+ Get outcomes, optionally filtered.
96
+
97
+ Args:
98
+ project_id: Project to query
99
+ agent: Filter by agent name
100
+ task_type: Filter by task type
101
+ embedding: Query embedding for semantic search
102
+ top_k: Max results
103
+ success_only: Only return successful outcomes
104
+
105
+ Returns:
106
+ List of matching outcomes
107
+ """
108
+ pass
109
+
110
+ @abstractmethod
111
+ def get_user_preferences(
112
+ self,
113
+ user_id: str,
114
+ category: Optional[str] = None,
115
+ ) -> List[UserPreference]:
116
+ """
117
+ Get user preferences.
118
+
119
+ Args:
120
+ user_id: User to query
121
+ category: Optional category filter
122
+
123
+ Returns:
124
+ List of user preferences
125
+ """
126
+ pass
127
+
128
+ @abstractmethod
129
+ def get_domain_knowledge(
130
+ self,
131
+ project_id: str,
132
+ agent: Optional[str] = None,
133
+ domain: Optional[str] = None,
134
+ embedding: Optional[List[float]] = None,
135
+ top_k: int = 5,
136
+ ) -> List[DomainKnowledge]:
137
+ """
138
+ Get domain knowledge.
139
+
140
+ Args:
141
+ project_id: Project to query
142
+ agent: Filter by agent
143
+ domain: Filter by domain
144
+ embedding: Query embedding for semantic search
145
+ top_k: Max results
146
+
147
+ Returns:
148
+ List of domain knowledge items
149
+ """
150
+ pass
151
+
152
+ @abstractmethod
153
+ def get_anti_patterns(
154
+ self,
155
+ project_id: str,
156
+ agent: Optional[str] = None,
157
+ embedding: Optional[List[float]] = None,
158
+ top_k: int = 5,
159
+ ) -> List[AntiPattern]:
160
+ """
161
+ Get anti-patterns.
162
+
163
+ Args:
164
+ project_id: Project to query
165
+ agent: Filter by agent
166
+ embedding: Query embedding for semantic search
167
+ top_k: Max results
168
+
169
+ Returns:
170
+ List of anti-patterns
171
+ """
172
+ pass
173
+
174
+ # ==================== UPDATE OPERATIONS ====================
175
+
176
+ @abstractmethod
177
+ def update_heuristic(
178
+ self,
179
+ heuristic_id: str,
180
+ updates: Dict[str, Any],
181
+ ) -> bool:
182
+ """
183
+ Update a heuristic's fields.
184
+
185
+ Args:
186
+ heuristic_id: ID of heuristic to update
187
+ updates: Dict of field->value updates
188
+
189
+ Returns:
190
+ True if updated, False if not found
191
+ """
192
+ pass
193
+
194
+ @abstractmethod
195
+ def increment_heuristic_occurrence(
196
+ self,
197
+ heuristic_id: str,
198
+ success: bool,
199
+ ) -> bool:
200
+ """
201
+ Increment heuristic occurrence count.
202
+
203
+ Args:
204
+ heuristic_id: ID of heuristic
205
+ success: Whether this occurrence was successful
206
+
207
+ Returns:
208
+ True if updated
209
+ """
210
+ pass
211
+
212
+ @abstractmethod
213
+ def update_heuristic_confidence(
214
+ self,
215
+ heuristic_id: str,
216
+ new_confidence: float,
217
+ ) -> bool:
218
+ """
219
+ Update a heuristic's confidence value.
220
+
221
+ Args:
222
+ heuristic_id: ID of heuristic to update
223
+ new_confidence: New confidence value (0.0 - 1.0)
224
+
225
+ Returns:
226
+ True if updated, False if not found
227
+ """
228
+ pass
229
+
230
+ @abstractmethod
231
+ def update_knowledge_confidence(
232
+ self,
233
+ knowledge_id: str,
234
+ new_confidence: float,
235
+ ) -> bool:
236
+ """
237
+ Update domain knowledge confidence value.
238
+
239
+ Args:
240
+ knowledge_id: ID of knowledge to update
241
+ new_confidence: New confidence value (0.0 - 1.0)
242
+
243
+ Returns:
244
+ True if updated, False if not found
245
+ """
246
+ pass
247
+
248
+ # ==================== DELETE OPERATIONS ====================
249
+
250
+ @abstractmethod
251
+ def delete_heuristic(self, heuristic_id: str) -> bool:
252
+ """
253
+ Delete a heuristic by ID.
254
+
255
+ Args:
256
+ heuristic_id: ID of heuristic to delete
257
+
258
+ Returns:
259
+ True if deleted, False if not found
260
+ """
261
+ pass
262
+
263
+ @abstractmethod
264
+ def delete_outcome(self, outcome_id: str) -> bool:
265
+ """
266
+ Delete an outcome by ID.
267
+
268
+ Args:
269
+ outcome_id: ID of outcome to delete
270
+
271
+ Returns:
272
+ True if deleted, False if not found
273
+ """
274
+ pass
275
+
276
+ @abstractmethod
277
+ def delete_domain_knowledge(self, knowledge_id: str) -> bool:
278
+ """
279
+ Delete domain knowledge by ID.
280
+
281
+ Args:
282
+ knowledge_id: ID of knowledge to delete
283
+
284
+ Returns:
285
+ True if deleted, False if not found
286
+ """
287
+ pass
288
+
289
+ @abstractmethod
290
+ def delete_anti_pattern(self, anti_pattern_id: str) -> bool:
291
+ """
292
+ Delete an anti-pattern by ID.
293
+
294
+ Args:
295
+ anti_pattern_id: ID of anti-pattern to delete
296
+
297
+ Returns:
298
+ True if deleted, False if not found
299
+ """
300
+ pass
301
+
302
+ @abstractmethod
303
+ def delete_outcomes_older_than(
304
+ self,
305
+ project_id: str,
306
+ older_than: datetime,
307
+ agent: Optional[str] = None,
308
+ ) -> int:
309
+ """
310
+ Delete old outcomes.
311
+
312
+ Args:
313
+ project_id: Project to prune
314
+ older_than: Delete outcomes older than this
315
+ agent: Optional agent filter
316
+
317
+ Returns:
318
+ Number of items deleted
319
+ """
320
+ pass
321
+
322
+ @abstractmethod
323
+ def delete_low_confidence_heuristics(
324
+ self,
325
+ project_id: str,
326
+ below_confidence: float,
327
+ agent: Optional[str] = None,
328
+ ) -> int:
329
+ """
330
+ Delete low-confidence heuristics.
331
+
332
+ Args:
333
+ project_id: Project to prune
334
+ below_confidence: Delete below this threshold
335
+ agent: Optional agent filter
336
+
337
+ Returns:
338
+ Number of items deleted
339
+ """
340
+ pass
341
+
342
+ # ==================== STATS ====================
343
+
344
+ @abstractmethod
345
+ def get_stats(
346
+ self,
347
+ project_id: str,
348
+ agent: Optional[str] = None,
349
+ ) -> Dict[str, Any]:
350
+ """
351
+ Get memory statistics.
352
+
353
+ Returns:
354
+ Dict with counts per memory type, total size, etc.
355
+ """
356
+ pass
357
+
358
+ # ==================== UTILITY ====================
359
+
360
+ @classmethod
361
+ @abstractmethod
362
+ def from_config(cls, config: Dict[str, Any]) -> "StorageBackend":
363
+ """
364
+ Create instance from configuration dict.
365
+
366
+ Args:
367
+ config: Configuration dictionary
368
+
369
+ Returns:
370
+ Configured storage backend instance
371
+ """
372
+ pass