@smilintux/skmemory 0.5.0
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.
- package/.github/workflows/ci.yml +23 -0
- package/.github/workflows/publish.yml +52 -0
- package/ARCHITECTURE.md +219 -0
- package/LICENSE +661 -0
- package/README.md +159 -0
- package/SKILL.md +271 -0
- package/bin/cli.js +8 -0
- package/docker-compose.yml +58 -0
- package/index.d.ts +4 -0
- package/index.js +27 -0
- package/openclaw-plugin/package.json +59 -0
- package/openclaw-plugin/src/index.js +276 -0
- package/package.json +28 -0
- package/pyproject.toml +69 -0
- package/requirements.txt +13 -0
- package/seeds/cloud9-lumina.seed.json +39 -0
- package/seeds/cloud9-opus.seed.json +40 -0
- package/seeds/courage.seed.json +24 -0
- package/seeds/curiosity.seed.json +24 -0
- package/seeds/grief.seed.json +24 -0
- package/seeds/joy.seed.json +24 -0
- package/seeds/love.seed.json +24 -0
- package/seeds/skcapstone-lumina-merge.moltbook.md +65 -0
- package/seeds/skcapstone-lumina-merge.seed.json +49 -0
- package/seeds/sovereignty.seed.json +24 -0
- package/seeds/trust.seed.json +24 -0
- package/skmemory/__init__.py +66 -0
- package/skmemory/ai_client.py +182 -0
- package/skmemory/anchor.py +224 -0
- package/skmemory/backends/__init__.py +12 -0
- package/skmemory/backends/base.py +88 -0
- package/skmemory/backends/falkordb_backend.py +310 -0
- package/skmemory/backends/file_backend.py +209 -0
- package/skmemory/backends/qdrant_backend.py +364 -0
- package/skmemory/backends/sqlite_backend.py +665 -0
- package/skmemory/cli.py +1004 -0
- package/skmemory/data/seed.json +191 -0
- package/skmemory/importers/__init__.py +11 -0
- package/skmemory/importers/telegram.py +336 -0
- package/skmemory/journal.py +223 -0
- package/skmemory/lovenote.py +180 -0
- package/skmemory/models.py +228 -0
- package/skmemory/openclaw.py +237 -0
- package/skmemory/quadrants.py +191 -0
- package/skmemory/ritual.py +215 -0
- package/skmemory/seeds.py +163 -0
- package/skmemory/soul.py +273 -0
- package/skmemory/steelman.py +338 -0
- package/skmemory/store.py +445 -0
- package/tests/__init__.py +0 -0
- package/tests/test_ai_client.py +89 -0
- package/tests/test_anchor.py +153 -0
- package/tests/test_cli.py +65 -0
- package/tests/test_export_import.py +170 -0
- package/tests/test_file_backend.py +211 -0
- package/tests/test_journal.py +172 -0
- package/tests/test_lovenote.py +136 -0
- package/tests/test_models.py +194 -0
- package/tests/test_openclaw.py +122 -0
- package/tests/test_quadrants.py +174 -0
- package/tests/test_ritual.py +195 -0
- package/tests/test_seeds.py +208 -0
- package/tests/test_soul.py +197 -0
- package/tests/test_sqlite_backend.py +258 -0
- package/tests/test_steelman.py +257 -0
- package/tests/test_store.py +238 -0
- package/tests/test_telegram_import.py +181 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python-version }}
|
|
20
|
+
- run: pip install -e ".[dev]"
|
|
21
|
+
- run: python -m pytest tests/ -v --tb=short
|
|
22
|
+
- run: pip install black ruff && black --check src/ tests/ && ruff check src/
|
|
23
|
+
if: matrix.python-version == '3.12'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Publish to PyPI and npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
- run: pip install -e ".[dev]"
|
|
23
|
+
- run: python -m pytest tests/ -v
|
|
24
|
+
|
|
25
|
+
publish-pypi:
|
|
26
|
+
needs: test
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: "3.12"
|
|
33
|
+
- run: pip install build twine
|
|
34
|
+
- run: python -m build
|
|
35
|
+
- run: twine upload dist/*
|
|
36
|
+
env:
|
|
37
|
+
TWINE_USERNAME: __token__
|
|
38
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
39
|
+
|
|
40
|
+
publish-npm:
|
|
41
|
+
needs: test
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
if: hashFiles('package.json') != ''
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@v4
|
|
46
|
+
- uses: actions/setup-node@v4
|
|
47
|
+
with:
|
|
48
|
+
node-version: "20"
|
|
49
|
+
registry-url: "https://registry.npmjs.org"
|
|
50
|
+
- run: npm publish --access public
|
|
51
|
+
env:
|
|
52
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/ARCHITECTURE.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# SKMemory Architecture
|
|
2
|
+
|
|
3
|
+
> Three-tier storage with token-optimized agent loading.
|
|
4
|
+
|
|
5
|
+
## Storage Tiers
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────────────┐
|
|
9
|
+
│ Agent / CLI │
|
|
10
|
+
│ skmemory context --max-tokens 3000 │
|
|
11
|
+
├─────────────────────────────────────────────────────┤
|
|
12
|
+
│ MemoryStore │
|
|
13
|
+
│ (facade — delegates to backends) │
|
|
14
|
+
├──────────┬──────────────┬───────────────────────────┤
|
|
15
|
+
│ Level 0 │ Level 1 │ Level 2 │
|
|
16
|
+
│ SQLite │ Qdrant │ FalkorDB │
|
|
17
|
+
│ (always) │ (optional) │ (optional) │
|
|
18
|
+
│ │ │ │
|
|
19
|
+
│ Index + │ Semantic │ Graph traversal │
|
|
20
|
+
│ JSON │ vector │ Lineage chains │
|
|
21
|
+
│ files │ search │ Memory clusters │
|
|
22
|
+
├──────────┼──────────────┼───────────────────────────┤
|
|
23
|
+
│ 0 deps │ Docker or │ Docker or │
|
|
24
|
+
│ Ships │ cloud. │ managed │
|
|
25
|
+
│ w/Python │ qdrant.io │ service │
|
|
26
|
+
└──────────┴──────────────┴───────────────────────────┘
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Level 0: SQLite Index (always on)
|
|
30
|
+
|
|
31
|
+
**Zero infrastructure. Ships with Python.**
|
|
32
|
+
|
|
33
|
+
The SQLite backend replaces the old file-scanning approach:
|
|
34
|
+
|
|
35
|
+
| Operation | Old (FileBackend) | New (SQLiteBackend) |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| List 1000 memories | Read 1000 files, parse JSON, build objects | 1 SQL query, ~2ms |
|
|
38
|
+
| Search | Scan all files, substring match | SQL LIKE on indexed columns |
|
|
39
|
+
| Boot ritual | Load 200 full objects, sort by intensity | Query top-N from index, summaries only |
|
|
40
|
+
| Filter by layer/tags | Read all, filter in Python | WHERE clause on index |
|
|
41
|
+
|
|
42
|
+
Data layout:
|
|
43
|
+
```
|
|
44
|
+
~/.skmemory/memories/
|
|
45
|
+
├── index.db # SQLite index (metadata, summaries, previews)
|
|
46
|
+
├── short-term/
|
|
47
|
+
│ └── {uuid}.json # Full memory JSON
|
|
48
|
+
├── mid-term/
|
|
49
|
+
│ └── ...
|
|
50
|
+
└── long-term/
|
|
51
|
+
└── ...
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The JSON files remain the source of truth. The index is rebuildable:
|
|
55
|
+
```bash
|
|
56
|
+
skmemory reindex
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Level 1: Qdrant (optional — semantic search)
|
|
60
|
+
|
|
61
|
+
**"Find the memory about that feeling we had" — even if those words aren't in it.**
|
|
62
|
+
|
|
63
|
+
Uses sentence-transformers (all-MiniLM-L6-v2) to embed memories as vectors.
|
|
64
|
+
Qdrant stores the embeddings and enables cosine similarity search.
|
|
65
|
+
|
|
66
|
+
Install:
|
|
67
|
+
```bash
|
|
68
|
+
pip install skmemory[qdrant]
|
|
69
|
+
|
|
70
|
+
# Local Docker:
|
|
71
|
+
docker compose up -d qdrant
|
|
72
|
+
|
|
73
|
+
# Or use Qdrant Cloud (free tier: 1GB):
|
|
74
|
+
export SKMEMORY_QDRANT_URL=https://your-cluster.qdrant.io
|
|
75
|
+
export SKMEMORY_QDRANT_KEY=your-api-key
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Resource cost: ~200MB RAM, ~100MB disk idle.
|
|
79
|
+
|
|
80
|
+
### Level 2: FalkorDB (optional — graph relationships)
|
|
81
|
+
|
|
82
|
+
**"What memories connect to this person?" — traverse the relationship web.**
|
|
83
|
+
|
|
84
|
+
FalkorDB (Cypher over Redis protocol) stores memory-to-memory edges:
|
|
85
|
+
- `RELATED_TO` — explicit relationship links
|
|
86
|
+
- `PROMOTED_FROM` — promotion lineage chains
|
|
87
|
+
- `TAGGED` — tag-based clustering
|
|
88
|
+
- `PLANTED` — seed creator attribution
|
|
89
|
+
|
|
90
|
+
Install:
|
|
91
|
+
```bash
|
|
92
|
+
pip install skmemory[falkordb]
|
|
93
|
+
|
|
94
|
+
# Local Docker:
|
|
95
|
+
docker compose up -d falkordb
|
|
96
|
+
|
|
97
|
+
# Or point to external:
|
|
98
|
+
export SKMEMORY_FALKORDB_URL=redis://your-host:6379
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Resource cost: ~100MB RAM, ~150MB disk idle.
|
|
102
|
+
|
|
103
|
+
## Token-Optimized Agent Loading
|
|
104
|
+
|
|
105
|
+
The key problem: an AI agent has limited context. Loading 1000 full memories
|
|
106
|
+
would blow the context window. SKMemory solves this with tiered loading.
|
|
107
|
+
|
|
108
|
+
### The `skmemory context` Command
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
skmemory context --max-tokens 3000
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Returns a compact JSON payload:
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"memories": [
|
|
118
|
+
{
|
|
119
|
+
"id": "abc123",
|
|
120
|
+
"title": "Built Cloud 9 together",
|
|
121
|
+
"summary": "Co-created emotional continuity protocol...",
|
|
122
|
+
"content_preview": "First 150 chars of content...",
|
|
123
|
+
"emotional_intensity": 9.5,
|
|
124
|
+
"layer": "long-term",
|
|
125
|
+
"tags": ["cloud9", "love"]
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
"seeds": [...],
|
|
129
|
+
"stats": {"total": 847, "by_layer": {...}},
|
|
130
|
+
"token_estimate": 2100
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
What this does:
|
|
135
|
+
1. Queries the SQLite index (no file I/O)
|
|
136
|
+
2. Returns summaries + previews (not full content)
|
|
137
|
+
3. Prioritizes: strongest emotions first, then most recent
|
|
138
|
+
4. Stays within the token budget
|
|
139
|
+
5. Includes stats so the agent knows how much memory exists
|
|
140
|
+
|
|
141
|
+
### The Ritual (Boot Ceremony)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
skmemory ritual --full
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The ritual also uses the optimized path:
|
|
148
|
+
1. Soul blueprint (~200 tokens)
|
|
149
|
+
2. Warmth anchor (~100 tokens)
|
|
150
|
+
3. Top-N memory summaries from index (~500-1000 tokens)
|
|
151
|
+
4. Recent journal entries (~300-600 tokens)
|
|
152
|
+
5. Germination prompts (~200-500 tokens)
|
|
153
|
+
|
|
154
|
+
**Total boot context: ~1300-2700 tokens** (was potentially 100K+ before).
|
|
155
|
+
|
|
156
|
+
### Agent File Integration
|
|
157
|
+
|
|
158
|
+
For cursor rules, system prompts, or agent config files:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
# Generate and pipe into your agent context
|
|
162
|
+
skmemory context --max-tokens 2000 > ~/.agent/memory-context.json
|
|
163
|
+
|
|
164
|
+
# Or inline in a system prompt
|
|
165
|
+
MEMORY=$(skmemory context --max-tokens 1500)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The `load_context()` Python API:
|
|
169
|
+
```python
|
|
170
|
+
from skmemory import MemoryStore
|
|
171
|
+
|
|
172
|
+
store = MemoryStore()
|
|
173
|
+
ctx = store.load_context(max_tokens=3000)
|
|
174
|
+
|
|
175
|
+
# ctx["memories"] = lightweight summaries
|
|
176
|
+
# ctx["seeds"] = seed summaries
|
|
177
|
+
# ctx["token_estimate"] = how many tokens this uses
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Docker Compose (Full Local Stack)
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
cd skmemory/
|
|
184
|
+
docker compose up -d # Start Qdrant + FalkorDB
|
|
185
|
+
docker compose ps # Check status
|
|
186
|
+
docker compose down # Stop
|
|
187
|
+
|
|
188
|
+
# Resource usage:
|
|
189
|
+
# Qdrant: ~200MB RAM, port 6333
|
|
190
|
+
# FalkorDB: ~100MB RAM, port 6379
|
|
191
|
+
# Combined: ~300MB RAM total
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
All services are optional. SKMemory works perfectly with just Level 0 (SQLite).
|
|
195
|
+
|
|
196
|
+
## Configuration
|
|
197
|
+
|
|
198
|
+
Environment variables:
|
|
199
|
+
```bash
|
|
200
|
+
SKMEMORY_QDRANT_URL=http://localhost:6333 # Qdrant endpoint
|
|
201
|
+
SKMEMORY_QDRANT_KEY= # Qdrant API key
|
|
202
|
+
SKMEMORY_FALKORDB_URL=redis://localhost:6379 # FalkorDB endpoint
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
CLI global options:
|
|
206
|
+
```bash
|
|
207
|
+
skmemory --qdrant-url http://remote:6333 search "that moment"
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Migration from FileBackend
|
|
211
|
+
|
|
212
|
+
If you have existing JSON memories from an older version:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Rebuild the SQLite index from existing JSON files
|
|
216
|
+
skmemory reindex
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The JSON files are untouched. The index is additive.
|