neural-memory 0.1.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.
Files changed (55) hide show
  1. neural_memory/__init__.py +38 -0
  2. neural_memory/cli/__init__.py +15 -0
  3. neural_memory/cli/__main__.py +6 -0
  4. neural_memory/cli/config.py +176 -0
  5. neural_memory/cli/main.py +2702 -0
  6. neural_memory/cli/storage.py +169 -0
  7. neural_memory/cli/tui.py +471 -0
  8. neural_memory/core/__init__.py +52 -0
  9. neural_memory/core/brain.py +301 -0
  10. neural_memory/core/brain_mode.py +273 -0
  11. neural_memory/core/fiber.py +236 -0
  12. neural_memory/core/memory_types.py +331 -0
  13. neural_memory/core/neuron.py +168 -0
  14. neural_memory/core/project.py +257 -0
  15. neural_memory/core/synapse.py +215 -0
  16. neural_memory/engine/__init__.py +15 -0
  17. neural_memory/engine/activation.py +335 -0
  18. neural_memory/engine/encoder.py +391 -0
  19. neural_memory/engine/retrieval.py +440 -0
  20. neural_memory/extraction/__init__.py +42 -0
  21. neural_memory/extraction/entities.py +547 -0
  22. neural_memory/extraction/parser.py +337 -0
  23. neural_memory/extraction/router.py +396 -0
  24. neural_memory/extraction/temporal.py +428 -0
  25. neural_memory/mcp/__init__.py +9 -0
  26. neural_memory/mcp/__main__.py +6 -0
  27. neural_memory/mcp/server.py +621 -0
  28. neural_memory/py.typed +0 -0
  29. neural_memory/safety/__init__.py +31 -0
  30. neural_memory/safety/freshness.py +238 -0
  31. neural_memory/safety/sensitive.py +304 -0
  32. neural_memory/server/__init__.py +5 -0
  33. neural_memory/server/app.py +99 -0
  34. neural_memory/server/dependencies.py +33 -0
  35. neural_memory/server/models.py +138 -0
  36. neural_memory/server/routes/__init__.py +7 -0
  37. neural_memory/server/routes/brain.py +221 -0
  38. neural_memory/server/routes/memory.py +169 -0
  39. neural_memory/server/routes/sync.py +387 -0
  40. neural_memory/storage/__init__.py +17 -0
  41. neural_memory/storage/base.py +441 -0
  42. neural_memory/storage/factory.py +329 -0
  43. neural_memory/storage/memory_store.py +896 -0
  44. neural_memory/storage/shared_store.py +650 -0
  45. neural_memory/storage/sqlite_store.py +1613 -0
  46. neural_memory/sync/__init__.py +5 -0
  47. neural_memory/sync/client.py +435 -0
  48. neural_memory/unified_config.py +315 -0
  49. neural_memory/utils/__init__.py +5 -0
  50. neural_memory/utils/config.py +98 -0
  51. neural_memory-0.1.0.dist-info/METADATA +314 -0
  52. neural_memory-0.1.0.dist-info/RECORD +55 -0
  53. neural_memory-0.1.0.dist-info/WHEEL +4 -0
  54. neural_memory-0.1.0.dist-info/entry_points.txt +4 -0
  55. neural_memory-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,441 @@
1
+ """Abstract base class for neural storage backends."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from datetime import datetime
7
+ from typing import TYPE_CHECKING, Literal
8
+
9
+ if TYPE_CHECKING:
10
+ from neural_memory.core.brain import Brain, BrainSnapshot
11
+ from neural_memory.core.fiber import Fiber
12
+ from neural_memory.core.neuron import Neuron, NeuronState, NeuronType
13
+ from neural_memory.core.synapse import Synapse, SynapseType
14
+
15
+
16
+ class NeuralStorage(ABC):
17
+ """
18
+ Abstract interface for neural graph storage.
19
+
20
+ Implementations must provide all methods for storing and
21
+ retrieving neurons, synapses, fibers, and brain metadata.
22
+ """
23
+
24
+ # ========== Neuron Operations ==========
25
+
26
+ @abstractmethod
27
+ async def add_neuron(self, neuron: Neuron) -> str:
28
+ """
29
+ Add a neuron to storage.
30
+
31
+ Args:
32
+ neuron: The neuron to add
33
+
34
+ Returns:
35
+ The neuron ID
36
+
37
+ Raises:
38
+ ValueError: If neuron with same ID already exists
39
+ """
40
+ ...
41
+
42
+ @abstractmethod
43
+ async def get_neuron(self, neuron_id: str) -> Neuron | None:
44
+ """
45
+ Get a neuron by ID.
46
+
47
+ Args:
48
+ neuron_id: The neuron ID
49
+
50
+ Returns:
51
+ The neuron if found, None otherwise
52
+ """
53
+ ...
54
+
55
+ @abstractmethod
56
+ async def find_neurons(
57
+ self,
58
+ type: NeuronType | None = None,
59
+ content_contains: str | None = None,
60
+ content_exact: str | None = None,
61
+ time_range: tuple[datetime, datetime] | None = None,
62
+ limit: int = 100,
63
+ ) -> list[Neuron]:
64
+ """
65
+ Find neurons matching criteria.
66
+
67
+ Args:
68
+ type: Filter by neuron type
69
+ content_contains: Filter by content substring (case-insensitive)
70
+ content_exact: Filter by exact content match
71
+ time_range: Filter by created_at within range
72
+ limit: Maximum results to return
73
+
74
+ Returns:
75
+ List of matching neurons
76
+ """
77
+ ...
78
+
79
+ @abstractmethod
80
+ async def update_neuron(self, neuron: Neuron) -> None:
81
+ """
82
+ Update an existing neuron.
83
+
84
+ Args:
85
+ neuron: The updated neuron (must have existing ID)
86
+
87
+ Raises:
88
+ ValueError: If neuron doesn't exist
89
+ """
90
+ ...
91
+
92
+ @abstractmethod
93
+ async def delete_neuron(self, neuron_id: str) -> bool:
94
+ """
95
+ Delete a neuron and its connected synapses.
96
+
97
+ Args:
98
+ neuron_id: The neuron ID to delete
99
+
100
+ Returns:
101
+ True if deleted, False if not found
102
+ """
103
+ ...
104
+
105
+ # ========== Neuron State Operations ==========
106
+
107
+ @abstractmethod
108
+ async def get_neuron_state(self, neuron_id: str) -> NeuronState | None:
109
+ """
110
+ Get the activation state for a neuron.
111
+
112
+ Args:
113
+ neuron_id: The neuron ID
114
+
115
+ Returns:
116
+ The state if found, None otherwise
117
+ """
118
+ ...
119
+
120
+ @abstractmethod
121
+ async def update_neuron_state(self, state: NeuronState) -> None:
122
+ """
123
+ Update or create neuron activation state.
124
+
125
+ Args:
126
+ state: The state to save
127
+ """
128
+ ...
129
+
130
+ # ========== Synapse Operations ==========
131
+
132
+ @abstractmethod
133
+ async def add_synapse(self, synapse: Synapse) -> str:
134
+ """
135
+ Add a synapse to storage.
136
+
137
+ Args:
138
+ synapse: The synapse to add
139
+
140
+ Returns:
141
+ The synapse ID
142
+
143
+ Raises:
144
+ ValueError: If synapse with same ID exists, or neurons don't exist
145
+ """
146
+ ...
147
+
148
+ @abstractmethod
149
+ async def get_synapse(self, synapse_id: str) -> Synapse | None:
150
+ """
151
+ Get a synapse by ID.
152
+
153
+ Args:
154
+ synapse_id: The synapse ID
155
+
156
+ Returns:
157
+ The synapse if found, None otherwise
158
+ """
159
+ ...
160
+
161
+ @abstractmethod
162
+ async def get_synapses(
163
+ self,
164
+ source_id: str | None = None,
165
+ target_id: str | None = None,
166
+ type: SynapseType | None = None,
167
+ min_weight: float | None = None,
168
+ ) -> list[Synapse]:
169
+ """
170
+ Find synapses matching criteria.
171
+
172
+ Args:
173
+ source_id: Filter by source neuron
174
+ target_id: Filter by target neuron
175
+ type: Filter by synapse type
176
+ min_weight: Filter by minimum weight
177
+
178
+ Returns:
179
+ List of matching synapses
180
+ """
181
+ ...
182
+
183
+ @abstractmethod
184
+ async def update_synapse(self, synapse: Synapse) -> None:
185
+ """
186
+ Update an existing synapse.
187
+
188
+ Args:
189
+ synapse: The updated synapse
190
+
191
+ Raises:
192
+ ValueError: If synapse doesn't exist
193
+ """
194
+ ...
195
+
196
+ @abstractmethod
197
+ async def delete_synapse(self, synapse_id: str) -> bool:
198
+ """
199
+ Delete a synapse.
200
+
201
+ Args:
202
+ synapse_id: The synapse ID to delete
203
+
204
+ Returns:
205
+ True if deleted, False if not found
206
+ """
207
+ ...
208
+
209
+ # ========== Graph Traversal ==========
210
+
211
+ @abstractmethod
212
+ async def get_neighbors(
213
+ self,
214
+ neuron_id: str,
215
+ direction: Literal["out", "in", "both"] = "both",
216
+ synapse_types: list[SynapseType] | None = None,
217
+ min_weight: float | None = None,
218
+ ) -> list[tuple[Neuron, Synapse]]:
219
+ """
220
+ Get neighboring neurons connected by synapses.
221
+
222
+ Args:
223
+ neuron_id: The central neuron ID
224
+ direction: Which direction to traverse
225
+ - "out": Only follow outgoing synapses
226
+ - "in": Only follow incoming synapses
227
+ - "both": Follow both directions
228
+ synapse_types: Only follow these synapse types
229
+ min_weight: Only follow synapses with weight >= this
230
+
231
+ Returns:
232
+ List of (neighbor_neuron, connecting_synapse) tuples
233
+ """
234
+ ...
235
+
236
+ @abstractmethod
237
+ async def get_path(
238
+ self,
239
+ source_id: str,
240
+ target_id: str,
241
+ max_hops: int = 4,
242
+ ) -> list[tuple[Neuron, Synapse]] | None:
243
+ """
244
+ Find shortest path between two neurons.
245
+
246
+ Args:
247
+ source_id: Starting neuron ID
248
+ target_id: Target neuron ID
249
+ max_hops: Maximum path length
250
+
251
+ Returns:
252
+ List of (neuron, synapse) pairs representing path, or None if no path
253
+ """
254
+ ...
255
+
256
+ # ========== Fiber Operations ==========
257
+
258
+ @abstractmethod
259
+ async def add_fiber(self, fiber: Fiber) -> str:
260
+ """
261
+ Add a fiber to storage.
262
+
263
+ Args:
264
+ fiber: The fiber to add
265
+
266
+ Returns:
267
+ The fiber ID
268
+
269
+ Raises:
270
+ ValueError: If fiber with same ID exists
271
+ """
272
+ ...
273
+
274
+ @abstractmethod
275
+ async def get_fiber(self, fiber_id: str) -> Fiber | None:
276
+ """
277
+ Get a fiber by ID.
278
+
279
+ Args:
280
+ fiber_id: The fiber ID
281
+
282
+ Returns:
283
+ The fiber if found, None otherwise
284
+ """
285
+ ...
286
+
287
+ @abstractmethod
288
+ async def find_fibers(
289
+ self,
290
+ contains_neuron: str | None = None,
291
+ time_overlaps: tuple[datetime, datetime] | None = None,
292
+ tags: set[str] | None = None,
293
+ min_salience: float | None = None,
294
+ limit: int = 100,
295
+ ) -> list[Fiber]:
296
+ """
297
+ Find fibers matching criteria.
298
+
299
+ Args:
300
+ contains_neuron: Filter by containing this neuron ID
301
+ time_overlaps: Filter by time range overlap
302
+ tags: Filter by having all these tags
303
+ min_salience: Filter by minimum salience
304
+ limit: Maximum results
305
+
306
+ Returns:
307
+ List of matching fibers
308
+ """
309
+ ...
310
+
311
+ @abstractmethod
312
+ async def update_fiber(self, fiber: Fiber) -> None:
313
+ """
314
+ Update an existing fiber.
315
+
316
+ Args:
317
+ fiber: The updated fiber
318
+
319
+ Raises:
320
+ ValueError: If fiber doesn't exist
321
+ """
322
+ ...
323
+
324
+ @abstractmethod
325
+ async def delete_fiber(self, fiber_id: str) -> bool:
326
+ """
327
+ Delete a fiber.
328
+
329
+ Args:
330
+ fiber_id: The fiber ID to delete
331
+
332
+ Returns:
333
+ True if deleted, False if not found
334
+ """
335
+ ...
336
+
337
+ @abstractmethod
338
+ async def get_fibers(
339
+ self,
340
+ limit: int = 10,
341
+ order_by: Literal["created_at", "salience", "frequency"] = "created_at",
342
+ descending: bool = True,
343
+ ) -> list[Fiber]:
344
+ """
345
+ Get fibers with ordering.
346
+
347
+ Args:
348
+ limit: Maximum results
349
+ order_by: Field to order by
350
+ descending: Sort descending if True
351
+
352
+ Returns:
353
+ List of fibers
354
+ """
355
+ ...
356
+
357
+ # ========== Brain Operations ==========
358
+
359
+ @abstractmethod
360
+ async def save_brain(self, brain: Brain) -> None:
361
+ """
362
+ Save or update brain metadata.
363
+
364
+ Args:
365
+ brain: The brain to save
366
+ """
367
+ ...
368
+
369
+ @abstractmethod
370
+ async def get_brain(self, brain_id: str) -> Brain | None:
371
+ """
372
+ Get brain metadata by ID.
373
+
374
+ Args:
375
+ brain_id: The brain ID
376
+
377
+ Returns:
378
+ The brain if found, None otherwise
379
+ """
380
+ ...
381
+
382
+ @abstractmethod
383
+ async def export_brain(self, brain_id: str) -> BrainSnapshot:
384
+ """
385
+ Export entire brain as a snapshot.
386
+
387
+ Args:
388
+ brain_id: The brain ID to export
389
+
390
+ Returns:
391
+ Complete snapshot of the brain
392
+
393
+ Raises:
394
+ ValueError: If brain doesn't exist
395
+ """
396
+ ...
397
+
398
+ @abstractmethod
399
+ async def import_brain(
400
+ self,
401
+ snapshot: BrainSnapshot,
402
+ target_brain_id: str | None = None,
403
+ ) -> str:
404
+ """
405
+ Import a brain snapshot.
406
+
407
+ Args:
408
+ snapshot: The snapshot to import
409
+ target_brain_id: Optional ID for the imported brain
410
+
411
+ Returns:
412
+ The ID of the imported brain
413
+ """
414
+ ...
415
+
416
+ # ========== Statistics ==========
417
+
418
+ @abstractmethod
419
+ async def get_stats(self, brain_id: str) -> dict[str, int]:
420
+ """
421
+ Get statistics for a brain.
422
+
423
+ Args:
424
+ brain_id: The brain ID
425
+
426
+ Returns:
427
+ Dict with keys: neuron_count, synapse_count, fiber_count
428
+ """
429
+ ...
430
+
431
+ # ========== Cleanup ==========
432
+
433
+ @abstractmethod
434
+ async def clear(self, brain_id: str) -> None:
435
+ """
436
+ Clear all data for a brain.
437
+
438
+ Args:
439
+ brain_id: The brain ID to clear
440
+ """
441
+ ...