formative-memory 0.1.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/LICENSE +21 -0
- package/README.md +246 -0
- package/dist/cli.js +520 -0
- package/dist/db-D2pzT6fw.js +629 -0
- package/dist/index.js +11181 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jari Mustonen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Formative Memory
|
|
2
|
+
|
|
3
|
+
**Memory that forgets, so it remembers better what matters. It forms with you and your needs.**
|
|
4
|
+
|
|
5
|
+
Formative Memory is an open source memory plugin for [OpenClaw](https://openclaw.ai). Memories form associations, strengthen through use, decay without reinforcement, and consolidate during sleep.
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Why
|
|
15
|
+
|
|
16
|
+
Traditional memory systems treat all information equally and rely on recency to decide what's relevant. Over time, noise accumulates: duplicates pile up, outdated facts coexist with corrections, and important patterns get buried under recent but trivial details. The more you use memory, the harder it becomes to find what matters. You end up teaching the same lessons over and over.
|
|
17
|
+
|
|
18
|
+
Formative Memory inverts this. Memories that prove useful get stronger. Unused ones fade. Related memories form connections. The system maintains itself through automatic consolidation — no manual curation needed.
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install formative-memory
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Add to your OpenClaw configuration:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"extensions": ["formative-memory"]
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
That's it. The plugin works automatically:
|
|
35
|
+
|
|
36
|
+
- **Auto-recall** surfaces relevant memories before every response
|
|
37
|
+
- **Agent tools** let the agent store, search, and rate memories
|
|
38
|
+
- **Consolidation** runs automatically to maintain memory quality
|
|
39
|
+
|
|
40
|
+
No configuration needed — sensible defaults are built in.
|
|
41
|
+
|
|
42
|
+
## How It Works
|
|
43
|
+
|
|
44
|
+
### Store
|
|
45
|
+
|
|
46
|
+
When your agent learns something, it creates a content-addressed memory object. Same content always produces the same ID — no duplicates by design.
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
Agent: "I'll remember that."
|
|
50
|
+
→ memory_store(content: "Project uses Tailwind, not styled-components", type: "preference")
|
|
51
|
+
→ id: a3f2c9e1, strength: 1.0, type: preference
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Associate
|
|
55
|
+
|
|
56
|
+
Memories don't exist in isolation. When two memories are retrieved together, they form a weighted bidirectional link. The more often they co-occur, the stronger the connection.
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
"Tailwind preference" ←0.7→ "Tailwind v4 migration"
|
|
60
|
+
"Tailwind preference" ←0.4→ "tailwind.config.ts in project root"
|
|
61
|
+
"Tailwind v4 migration" ←0.3→ "CSS specificity bug"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Recall
|
|
65
|
+
|
|
66
|
+
Retrieval combines semantic similarity and keyword matching, weighted by memory strength. Important memories surface first. Every retrieval makes the memory stronger. Every miss lets it fade.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Agent thinking: "What CSS framework do we use?"
|
|
70
|
+
→ memory_search(query: "CSS framework")
|
|
71
|
+
→ 1. "Project uses Tailwind exclusively" (strength: 0.92, score: 0.87)
|
|
72
|
+
2. "Migrated to Tailwind v4 last week" (strength: 0.71, score: 0.64)
|
|
73
|
+
3. "tailwind.config.ts in project root" (strength: 0.68, score: 0.51)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Consolidate
|
|
77
|
+
|
|
78
|
+
A background consolidation process maintains the memory system automatically:
|
|
79
|
+
|
|
80
|
+
| Step | What happens |
|
|
81
|
+
|------|-------------|
|
|
82
|
+
| **Reinforce** | Memories that influenced responses gain strength |
|
|
83
|
+
| **Decay** | All strengths decrease — working memory fades faster than consolidated |
|
|
84
|
+
| **Associate** | Co-retrieved memories form or strengthen links; transitive paths are discovered |
|
|
85
|
+
| **Temporal shift** | Future memories transition to present or past based on anchor dates |
|
|
86
|
+
| **Prune** | Very weak memories and associations are deleted |
|
|
87
|
+
| **Merge** | Similar memories are combined via LLM into coherent summaries |
|
|
88
|
+
| **Cleanup** | Old provenance records are garbage collected |
|
|
89
|
+
|
|
90
|
+
Live chat stays fast and predictable. All mutation happens during consolidation.
|
|
91
|
+
|
|
92
|
+
## Memory Tools
|
|
93
|
+
|
|
94
|
+
The plugin registers five tools the agent can use during conversation:
|
|
95
|
+
|
|
96
|
+
| Tool | What it does |
|
|
97
|
+
|------|-------------|
|
|
98
|
+
| `memory_store` | Store a new memory with type and optional temporal anchor |
|
|
99
|
+
| `memory_search` | Search by meaning and keywords, ranked by relevance × strength |
|
|
100
|
+
| `memory_get` | Retrieve a specific memory by ID |
|
|
101
|
+
| `memory_feedback` | Rate a memory's usefulness — feeds into reinforcement |
|
|
102
|
+
| `memory_browse` | Browse all memories sorted by importance |
|
|
103
|
+
|
|
104
|
+
Memory types: `fact`, `preference`, `decision`, `plan`, `observation`.
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
All settings are optional:
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"memory-associative": {
|
|
113
|
+
"autoRecall": true,
|
|
114
|
+
"autoCapture": false,
|
|
115
|
+
"embedding": {
|
|
116
|
+
"provider": "auto",
|
|
117
|
+
"model": null
|
|
118
|
+
},
|
|
119
|
+
"dbPath": "~/.openclaw/memory/associative",
|
|
120
|
+
"verbose": false,
|
|
121
|
+
"logQueries": false
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
| Key | Default | Description |
|
|
127
|
+
|-----|---------|-------------|
|
|
128
|
+
| `autoRecall` | `true` | Inject relevant memories into context before every response |
|
|
129
|
+
| `autoCapture` | `false` | Automatically capture conversations for consolidation |
|
|
130
|
+
| `embedding.provider` | `"auto"` | Embedding provider: `auto`, `openai`, `gemini`, `voyage`, `mistral`, `ollama` |
|
|
131
|
+
| `embedding.model` | — | Override the provider's default embedding model |
|
|
132
|
+
| `dbPath` | `~/.openclaw/memory/associative` | SQLite database location |
|
|
133
|
+
| `verbose` | `false` | Enable debug-level logging (also via `FORMATIVE_MEMORY_DEBUG=1`) |
|
|
134
|
+
| `logQueries` | `false` | Include raw query text in debug logs (disabled by default for privacy) |
|
|
135
|
+
|
|
136
|
+
The `"auto"` provider selects the best available embedding provider from your configured API keys. If no provider is available, the plugin degrades gracefully to keyword-only search.
|
|
137
|
+
|
|
138
|
+
### Logging
|
|
139
|
+
|
|
140
|
+
The plugin has centralized logging with configurable verbosity. By default only significant events are logged (info level): memory stores, context injection, and circuit breaker state changes.
|
|
141
|
+
|
|
142
|
+
Enable debug logging for full diagnostics:
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
{ "verbose": true }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Or via environment variable (no config change needed):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
FORMATIVE_MEMORY_DEBUG=1
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**What gets logged at each level:**
|
|
155
|
+
|
|
156
|
+
| Level | What |
|
|
157
|
+
|-------|------|
|
|
158
|
+
| **info** | Memory stored, memories injected into context, circuit breaker state changes |
|
|
159
|
+
| **debug** | Search result count and top score, embedding fallback reasons, cache hit/miss, consolidation timing, provenance counts, duplicate store skips |
|
|
160
|
+
| **warn** | Circuit breaker opening (degraded to keyword-only), recall failures, migration issues |
|
|
161
|
+
|
|
162
|
+
All log lines are prefixed with `[formative-memory] [level]` for easy filtering.
|
|
163
|
+
|
|
164
|
+
**Privacy:** Query text is never included in logs by default. Set `logQueries: true` to opt in — useful for debugging retrieval quality, but queries may contain personal data.
|
|
165
|
+
|
|
166
|
+
## Architecture
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
OpenClaw Runtime
|
|
170
|
+
│
|
|
171
|
+
├── Context Engine ─── assemble() → auto-recall into context
|
|
172
|
+
│ (budget-aware) afterTurn() → log exposures + attributions
|
|
173
|
+
│
|
|
174
|
+
├── Memory Tools ───── memory_store — create memory
|
|
175
|
+
│ (agent-initiated) memory_search — hybrid search
|
|
176
|
+
│ memory_get — lookup by ID
|
|
177
|
+
│ memory_feedback — rate usefulness
|
|
178
|
+
│ memory_browse — browse by importance
|
|
179
|
+
│
|
|
180
|
+
└── Consolidation ──── reinforce → decay → associate → transition
|
|
181
|
+
(automatic) → prune → merge (LLM) → cleanup
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Storage:** SQLite with FTS5 for full-text search. Single file, no external services.
|
|
185
|
+
|
|
186
|
+
**Embedding:** Auto-detected from configured API keys. Supports OpenAI, Gemini, Voyage, Mistral, Ollama. Circuit breaker with graceful fallback to keyword-only search.
|
|
187
|
+
|
|
188
|
+
**Consolidation LLM:** Uses Anthropic (Claude) or OpenAI for memory merging. Runs only during consolidation, not during normal chat.
|
|
189
|
+
|
|
190
|
+
## Trust & Security
|
|
191
|
+
|
|
192
|
+
Automatically recalled memories are framed as reference data, not instructions. This reduces prompt injection risk from stored memory content, but memory remains untrusted input — the framing is probabilistic, not a hard security boundary.
|
|
193
|
+
|
|
194
|
+
Do not store secrets (API keys, passwords) in memories. They will be surfaced to the model during recall.
|
|
195
|
+
|
|
196
|
+
## CLI
|
|
197
|
+
|
|
198
|
+
A standalone diagnostic CLI operates directly on the SQLite database — no OpenClaw runtime needed:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
memory stats <memory-dir> # Database overview
|
|
202
|
+
memory list <memory-dir> # List memories (filterable)
|
|
203
|
+
memory inspect <memory-dir> <id> # Detailed view of a single memory
|
|
204
|
+
memory search <memory-dir> <q> # Search by content
|
|
205
|
+
memory export <memory-dir> # Export to JSON
|
|
206
|
+
memory history <memory-dir> # Retrieval history
|
|
207
|
+
memory graph <memory-dir> # Association graph
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Roadmap
|
|
211
|
+
|
|
212
|
+
- [ ] Association-boosted retrieval (graph structure influences search ranking)
|
|
213
|
+
- [ ] Memory-type-specific search strategies
|
|
214
|
+
- [ ] Visual memory graph explorer
|
|
215
|
+
- [ ] Cross-project memory sharing
|
|
216
|
+
|
|
217
|
+
## Documentation
|
|
218
|
+
|
|
219
|
+
- [How Associative Memory Works](docs/how-memory-works.md) — conceptual guide
|
|
220
|
+
- [Architecture](docs/architecture.md) — storage, retrieval, provenance, consolidation
|
|
221
|
+
- [Comparison with OpenClaw built-in memory](docs/comparison-openclaw-memory.md) — technical comparison
|
|
222
|
+
- [Glossary](docs/glossary.md) — terminology
|
|
223
|
+
|
|
224
|
+
## Development
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pnpm install # Install dependencies
|
|
228
|
+
pnpm build # Build (tsdown)
|
|
229
|
+
pnpm test # Run tests (vitest)
|
|
230
|
+
pnpm lint # Lint (oxlint)
|
|
231
|
+
pnpm check # Full check (format + typecheck + lint)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Requires Node.js >= 22.12.0, pnpm 10.x.
|
|
235
|
+
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
Contributions welcome. Areas where help is especially useful:
|
|
239
|
+
|
|
240
|
+
- Consolidation algorithm tuning and evaluation
|
|
241
|
+
- Embedding model benchmarks
|
|
242
|
+
- Documentation and examples
|
|
243
|
+
|
|
244
|
+
## License
|
|
245
|
+
|
|
246
|
+
[MIT](LICENSE)
|