amormorri-memory-kernel 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.
- amormorri_memory_kernel-0.1.0.dist-info/METADATA +284 -0
- amormorri_memory_kernel-0.1.0.dist-info/RECORD +8 -0
- amormorri_memory_kernel-0.1.0.dist-info/WHEEL +4 -0
- amormorri_memory_kernel-0.1.0.dist-info/entry_points.txt +2 -0
- memory_kernel/__init__.py +3 -0
- memory_kernel/accelerator.py +30 -0
- memory_kernel/cli.py +366 -0
- memory_kernel/store.py +1667 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amormorri-memory-kernel
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Focused local memory for AI agents with SQLite FTS5 and deterministic context packing.
|
|
5
|
+
Project-URL: Homepage, https://github.com/Artem362/memory-kernel
|
|
6
|
+
Project-URL: Repository, https://github.com/Artem362/memory-kernel
|
|
7
|
+
Author-email: AmorMorri <amormorri21@gmail.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: agents,ai,context,fts5,llm,memory,sqlite
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Provides-Extra: accelerator
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest<9,>=8.0; extra == 'dev'
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# Memory Kernel
|
|
25
|
+
|
|
26
|
+
`Memory Kernel` is a lightweight local-first memory core for AI agents.
|
|
27
|
+
|
|
28
|
+
Practical guide in Ukrainian, including the operating principle and architecture/data-flow schemas:
|
|
29
|
+
[docs/OPERATING_GUIDE_UK.md](docs/OPERATING_GUIDE_UK.md)
|
|
30
|
+
|
|
31
|
+
It was built with the same useful instinct behind MemPalace in mind: keep memory on the user's machine and retrieve exact context when needed. The difference is that this project deliberately avoids a heavy vector stack and fuzzy always-on retrieval. Instead, it uses:
|
|
32
|
+
|
|
33
|
+
- explicit memory kinds: `decision`, `constraint`, `preference`, `task`, `fact`, `note`
|
|
34
|
+
- `SQLite` + `FTS5` for cheap local full-text search
|
|
35
|
+
- deterministic ranking that favors actionable memories over vague notes
|
|
36
|
+
- deterministic transcript ingestion with duplicate-aware updates
|
|
37
|
+
- optional `Rust` accelerator for ingest, duplicate-aware upsert heuristics, and retrieval hot paths
|
|
38
|
+
- context packs with a hard character budget so only useful memory reaches the model
|
|
39
|
+
|
|
40
|
+
For embedded Python usage, `MemoryStore` keeps a long-lived SQLite connection for throughput. Prefer `with MemoryStore(...) as store:` or call `store.close()` when you're done.
|
|
41
|
+
|
|
42
|
+
## Start In 5 Minutes
|
|
43
|
+
|
|
44
|
+
If you do not want to learn the internals first, use it like this:
|
|
45
|
+
|
|
46
|
+
1. Install it: `pip install -e .`
|
|
47
|
+
2. Create the local memory database: `memory-kernel init`
|
|
48
|
+
3. Save one important thing:
|
|
49
|
+
`memory-kernel remember --scope my.project --kind decision --title "What we decided" --content "We will keep memory local on the user's machine."`
|
|
50
|
+
4. Ask for it back later:
|
|
51
|
+
`memory-kernel search "local memory"`
|
|
52
|
+
5. Export a backup:
|
|
53
|
+
`memory-kernel export --format json --output exports\memory.json`
|
|
54
|
+
|
|
55
|
+
That is enough to start using the project without understanding `FTS5`, ranking formulas, or context packing.
|
|
56
|
+
|
|
57
|
+
## Project Status
|
|
58
|
+
|
|
59
|
+
Current stage: working alpha.
|
|
60
|
+
|
|
61
|
+
- the package layout, CLI, docs, tests, export/import, and optional Rust accelerator already exist
|
|
62
|
+
- the Python fallback works without Rust
|
|
63
|
+
- the core workflows are usable today for local experimentation and integration
|
|
64
|
+
- packaging for easy end-user distribution is not finished yet
|
|
65
|
+
|
|
66
|
+
Near-term product gaps:
|
|
67
|
+
|
|
68
|
+
- prebuilt wheels for major platforms
|
|
69
|
+
- a simpler guided ingest flow for non-technical users
|
|
70
|
+
- lighter onboarding for people who do not care about implementation details
|
|
71
|
+
|
|
72
|
+
## Who This Is For
|
|
73
|
+
|
|
74
|
+
This is a good fit when the end user wants:
|
|
75
|
+
|
|
76
|
+
- local-first memory on their own machine
|
|
77
|
+
- exact, inspectable records instead of a black-box memory layer
|
|
78
|
+
- small, controlled context instead of always sending a large memory dump
|
|
79
|
+
- backup and restore through plain export files
|
|
80
|
+
|
|
81
|
+
This is a weaker fit when the end user mainly wants:
|
|
82
|
+
|
|
83
|
+
- a fully hosted managed memory platform
|
|
84
|
+
- plug-and-play onboarding with no local setup
|
|
85
|
+
- automatic structure from messy notes without reviewing what was saved
|
|
86
|
+
|
|
87
|
+
## Why this direction
|
|
88
|
+
|
|
89
|
+
Most AI memory systems fail in two ways:
|
|
90
|
+
|
|
91
|
+
- they are fuzzy, so low-signal notes come back with the important ones
|
|
92
|
+
- they are heavy, so the memory layer becomes more expensive than the work it is meant to support
|
|
93
|
+
|
|
94
|
+
This project pushes in the opposite direction:
|
|
95
|
+
|
|
96
|
+
- store exact text locally
|
|
97
|
+
- require clear scope and kind for every memory
|
|
98
|
+
- rank by lexical match, actionability, certainty, importance, recency, and reuse
|
|
99
|
+
- build small context packs instead of dumping everything into the prompt
|
|
100
|
+
|
|
101
|
+
## End-User Positioning
|
|
102
|
+
|
|
103
|
+
For an end user, the value proposition is simple:
|
|
104
|
+
|
|
105
|
+
- your memory stays on your machine
|
|
106
|
+
- you can inspect what was saved
|
|
107
|
+
- you can export it and move it
|
|
108
|
+
- retrieval is intentionally small and predictable
|
|
109
|
+
|
|
110
|
+
The tradeoff is also simple:
|
|
111
|
+
|
|
112
|
+
- this product currently expects a bit more structure and discipline than a consumer-first app
|
|
113
|
+
- the best experience today is for teams and advanced users who want control, not maximum automation
|
|
114
|
+
|
|
115
|
+
## Quick Start
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
python -m venv .venv
|
|
119
|
+
.venv\Scripts\activate
|
|
120
|
+
pip install -e .[dev]
|
|
121
|
+
|
|
122
|
+
memory-kernel init
|
|
123
|
+
|
|
124
|
+
memory-kernel remember ^
|
|
125
|
+
--scope project.ai-memory ^
|
|
126
|
+
--kind decision ^
|
|
127
|
+
--title "Switch to SQLite FTS5" ^
|
|
128
|
+
--content "We are replacing a heavier vector stack with SQLite FTS5 because memory retrieval must stay local, fast, and predictable." ^
|
|
129
|
+
--tags sqlite performance retrieval ^
|
|
130
|
+
--importance 0.95 ^
|
|
131
|
+
--certainty 0.95
|
|
132
|
+
|
|
133
|
+
memory-kernel search "sqlite retrieval performance"
|
|
134
|
+
memory-kernel context "How should the agent remember architecture decisions?"
|
|
135
|
+
memory-kernel wake-up
|
|
136
|
+
memory-kernel stats
|
|
137
|
+
memory-kernel export --format json --output exports\memory.json
|
|
138
|
+
memory-kernel import --file exports\memory.json
|
|
139
|
+
|
|
140
|
+
memory-kernel ingest ^
|
|
141
|
+
--scope project.ai-memory ^
|
|
142
|
+
--file notes.txt ^
|
|
143
|
+
--source sprint-review ^
|
|
144
|
+
--tags transcript planning
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## CLI
|
|
148
|
+
|
|
149
|
+
### `init`
|
|
150
|
+
|
|
151
|
+
Create the local database in `.memory-kernel/memory.db`.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
memory-kernel init
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### `remember`
|
|
158
|
+
|
|
159
|
+
Store one memory record.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
memory-kernel remember \
|
|
163
|
+
--scope project.ai-memory \
|
|
164
|
+
--kind constraint \
|
|
165
|
+
--title "Prompt budget stays small" \
|
|
166
|
+
--content "The agent should load a tiny wake-up pack and fetch deeper memory only when the current task requires it." \
|
|
167
|
+
--tags prompt context-budget
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `search`
|
|
171
|
+
|
|
172
|
+
Find the most relevant exact memories for a query.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
memory-kernel search "context budget for the agent"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### `ingest`
|
|
179
|
+
|
|
180
|
+
Turn raw text, notes, or transcript fragments into structured memories without using an LLM.
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
memory-kernel ingest \
|
|
184
|
+
--scope project.ai-memory \
|
|
185
|
+
--file notes.txt \
|
|
186
|
+
--source sprint-review \
|
|
187
|
+
--tags transcript planning
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### `context`
|
|
191
|
+
|
|
192
|
+
Build a small pack for an agent prompt with a hard budget.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
memory-kernel context "How do we keep memory cheap?" --budget-chars 700
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### `wake-up`
|
|
199
|
+
|
|
200
|
+
Return the currently hottest memories without a search query.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
memory-kernel wake-up --budget-chars 500
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `export`
|
|
207
|
+
|
|
208
|
+
Export memories for backup, migration, or offline inspection.
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
memory-kernel export --format json --output exports\memory.json
|
|
212
|
+
memory-kernel export --scope project.ai-memory --format jsonl --output exports\ai-memory.jsonl
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`json` writes one structured export document with metadata and filters.
|
|
216
|
+
`jsonl` writes one memory per line and is convenient for pipelines or later processing.
|
|
217
|
+
|
|
218
|
+
### `import`
|
|
219
|
+
|
|
220
|
+
Restore memories from a previous export.
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
memory-kernel import --file exports\memory.json
|
|
224
|
+
memory-kernel import --file exports\ai-memory.jsonl
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
`import` is idempotent for the same exported records because it upserts by memory `id`.
|
|
228
|
+
|
|
229
|
+
## Typical Workflow
|
|
230
|
+
|
|
231
|
+
1. Run `memory-kernel init` once for a new database.
|
|
232
|
+
2. Save precise decisions with `remember`, or large raw notes with `ingest`.
|
|
233
|
+
3. Before an agent task, use `search`, `context`, or `wake-up` to fetch only the needed memory.
|
|
234
|
+
4. Periodically run `export` to keep a portable backup of the memory base.
|
|
235
|
+
5. On another machine or a fresh database, run `import` to restore the exported memory.
|
|
236
|
+
|
|
237
|
+
## Schema
|
|
238
|
+
|
|
239
|
+
Each memory has:
|
|
240
|
+
|
|
241
|
+
- `scope`: where it belongs, for example `project.ai-memory` or `team.core`
|
|
242
|
+
- `kind`: one of the supported kinds
|
|
243
|
+
- `title`: short stable label
|
|
244
|
+
- `content`: exact source text
|
|
245
|
+
- `summary`: short deterministic summary
|
|
246
|
+
- `tags`: searchable labels
|
|
247
|
+
- `importance`: how important this memory is to outcomes
|
|
248
|
+
- `certainty`: how reliable the memory is
|
|
249
|
+
|
|
250
|
+
Those fields are intentional. They make retrieval sharper than a flat blob store while staying much lighter than a full vector database.
|
|
251
|
+
|
|
252
|
+
## Tests
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pytest
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Native Accelerator
|
|
259
|
+
|
|
260
|
+
The Python core is the stable fallback. When you want lower overhead on the ingest and heuristic ranking path, build the optional `Rust` module:
|
|
261
|
+
|
|
262
|
+
```powershell
|
|
263
|
+
.\scripts\build_native.ps1
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
After that, `memory-kernel stats` will report `accelerator: rust` and show which ranking/upsert engines are active.
|
|
267
|
+
|
|
268
|
+
By default, the `Rust` path accelerates ingest and text heuristics. Experimental native ranking / pack rendering is available, but kept off by default because the current JSON bridge is only worth profiling on larger candidate batches:
|
|
269
|
+
|
|
270
|
+
```powershell
|
|
271
|
+
$env:MEMORY_KERNEL_EXPERIMENTAL_NATIVE_RANK=1
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
To compare the heuristic ingest path against the Python fallback:
|
|
275
|
+
|
|
276
|
+
```powershell
|
|
277
|
+
python .\scripts\benchmark_ingest.py
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
To benchmark duplicate-aware upsert throughput:
|
|
281
|
+
|
|
282
|
+
```powershell
|
|
283
|
+
python .\scripts\benchmark_upsert.py
|
|
284
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
memory_kernel/__init__.py,sha256=tr2-zP7nAwYvPIwHWMSf1BmGnXbB-5N7mN_ONxhPZAw,49
|
|
2
|
+
memory_kernel/accelerator.py,sha256=OK8dYTy3RXJHndzmBuaKoxtreY5VKWAlG5JrHFltWEY,747
|
|
3
|
+
memory_kernel/cli.py,sha256=l_m3utywiTkxunDdz2UfmiPCu047sYmo63ZnsaUKtNA,13344
|
|
4
|
+
memory_kernel/store.py,sha256=UC98udeuK6g98sNrtP7RFMMmmVvWed0_uy4x5rG3DfM,52502
|
|
5
|
+
amormorri_memory_kernel-0.1.0.dist-info/METADATA,sha256=pGr8SzetBxKBHxvI2zJtnRzA6mmvygDQ_p-P_UDCOU0,9255
|
|
6
|
+
amormorri_memory_kernel-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
7
|
+
amormorri_memory_kernel-0.1.0.dist-info/entry_points.txt,sha256=Q89yFo1kxs4jbWw1IN-6prJA5qiU8nIbBRkCWMMD0AA,57
|
|
8
|
+
amormorri_memory_kernel-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def _native_disabled() -> bool:
|
|
7
|
+
value = os.getenv("MEMORY_KERNEL_DISABLE_NATIVE", "")
|
|
8
|
+
return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _experimental_native_rank_enabled() -> bool:
|
|
12
|
+
value = os.getenv("MEMORY_KERNEL_EXPERIMENTAL_NATIVE_RANK", "")
|
|
13
|
+
return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
if _native_disabled():
|
|
17
|
+
native_accel = None
|
|
18
|
+
else:
|
|
19
|
+
try:
|
|
20
|
+
from . import _native as native_accel
|
|
21
|
+
except ImportError:
|
|
22
|
+
native_accel = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def has_native_acceleration() -> bool:
|
|
26
|
+
return native_accel is not None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def has_experimental_native_ranking() -> bool:
|
|
30
|
+
return native_accel is not None and _experimental_native_rank_enabled()
|