audrey 0.16.1 → 0.20.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.
Files changed (188) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +146 -724
  3. package/dist/mcp-server/config.d.ts +20 -0
  4. package/dist/mcp-server/config.d.ts.map +1 -0
  5. package/dist/mcp-server/config.js +125 -0
  6. package/dist/mcp-server/config.js.map +1 -0
  7. package/dist/mcp-server/index.d.ts +100 -0
  8. package/dist/mcp-server/index.d.ts.map +1 -0
  9. package/dist/mcp-server/index.js +1113 -0
  10. package/dist/mcp-server/index.js.map +1 -0
  11. package/dist/src/adaptive.d.ts +7 -0
  12. package/dist/src/adaptive.d.ts.map +1 -0
  13. package/dist/src/adaptive.js +49 -0
  14. package/dist/src/adaptive.js.map +1 -0
  15. package/dist/src/affect.d.ts +19 -0
  16. package/dist/src/affect.d.ts.map +1 -0
  17. package/dist/src/affect.js +72 -0
  18. package/dist/src/affect.js.map +1 -0
  19. package/dist/src/audrey.d.ts +140 -0
  20. package/dist/src/audrey.d.ts.map +1 -0
  21. package/dist/src/audrey.js +564 -0
  22. package/dist/src/audrey.js.map +1 -0
  23. package/dist/src/capsule.d.ts +68 -0
  24. package/dist/src/capsule.d.ts.map +1 -0
  25. package/dist/src/capsule.js +311 -0
  26. package/dist/src/capsule.js.map +1 -0
  27. package/dist/src/causal.d.ts +28 -0
  28. package/dist/src/causal.d.ts.map +1 -0
  29. package/dist/src/causal.js +65 -0
  30. package/dist/src/causal.js.map +1 -0
  31. package/dist/src/confidence.d.ts +12 -0
  32. package/dist/src/confidence.d.ts.map +1 -0
  33. package/dist/src/confidence.js +63 -0
  34. package/dist/src/confidence.js.map +1 -0
  35. package/dist/src/consolidate.d.ts +8 -0
  36. package/dist/src/consolidate.d.ts.map +1 -0
  37. package/dist/src/consolidate.js +218 -0
  38. package/dist/src/consolidate.js.map +1 -0
  39. package/dist/src/context.d.ts +3 -0
  40. package/dist/src/context.d.ts.map +1 -0
  41. package/dist/src/context.js +19 -0
  42. package/dist/src/context.js.map +1 -0
  43. package/dist/src/db.d.ts +12 -0
  44. package/dist/src/db.d.ts.map +1 -0
  45. package/dist/src/db.js +380 -0
  46. package/dist/src/db.js.map +1 -0
  47. package/dist/src/decay.d.ts +7 -0
  48. package/dist/src/decay.d.ts.map +1 -0
  49. package/dist/src/decay.js +68 -0
  50. package/dist/src/decay.js.map +1 -0
  51. package/dist/src/embedding.d.ts +57 -0
  52. package/dist/src/embedding.d.ts.map +1 -0
  53. package/dist/src/embedding.js +254 -0
  54. package/dist/src/embedding.js.map +1 -0
  55. package/dist/src/encode.d.ts +15 -0
  56. package/dist/src/encode.d.ts.map +1 -0
  57. package/dist/src/encode.js +36 -0
  58. package/dist/src/encode.js.map +1 -0
  59. package/dist/src/events.d.ts +69 -0
  60. package/dist/src/events.d.ts.map +1 -0
  61. package/dist/src/events.js +149 -0
  62. package/dist/src/events.js.map +1 -0
  63. package/dist/src/export.d.ts +3 -0
  64. package/dist/src/export.d.ts.map +1 -0
  65. package/dist/src/export.js +46 -0
  66. package/dist/src/export.js.map +1 -0
  67. package/dist/src/forget.d.ts +11 -0
  68. package/dist/src/forget.d.ts.map +1 -0
  69. package/dist/src/forget.js +105 -0
  70. package/dist/src/forget.js.map +1 -0
  71. package/dist/src/fts.d.ts +34 -0
  72. package/dist/src/fts.d.ts.map +1 -0
  73. package/dist/src/fts.js +117 -0
  74. package/dist/src/fts.js.map +1 -0
  75. package/dist/src/hybrid-recall.d.ts +37 -0
  76. package/dist/src/hybrid-recall.d.ts.map +1 -0
  77. package/dist/src/hybrid-recall.js +213 -0
  78. package/dist/src/hybrid-recall.js.map +1 -0
  79. package/dist/src/import.d.ts +4 -0
  80. package/dist/src/import.d.ts.map +1 -0
  81. package/dist/src/import.js +127 -0
  82. package/dist/src/import.js.map +1 -0
  83. package/dist/src/index.d.ts +22 -0
  84. package/dist/src/index.d.ts.map +1 -0
  85. package/{src → dist/src}/index.js +5 -13
  86. package/dist/src/index.js.map +1 -0
  87. package/dist/src/interference.d.ts +13 -0
  88. package/dist/src/interference.d.ts.map +1 -0
  89. package/dist/src/interference.js +45 -0
  90. package/dist/src/interference.js.map +1 -0
  91. package/dist/src/introspect.d.ts +4 -0
  92. package/dist/src/introspect.d.ts.map +1 -0
  93. package/dist/src/introspect.js +40 -0
  94. package/dist/src/introspect.js.map +1 -0
  95. package/dist/src/llm.d.ts +38 -0
  96. package/dist/src/llm.d.ts.map +1 -0
  97. package/dist/src/llm.js +167 -0
  98. package/dist/src/llm.js.map +1 -0
  99. package/dist/src/migrate.d.ts +6 -0
  100. package/dist/src/migrate.d.ts.map +1 -0
  101. package/dist/src/migrate.js +51 -0
  102. package/dist/src/migrate.js.map +1 -0
  103. package/dist/src/promote.d.ts +40 -0
  104. package/dist/src/promote.d.ts.map +1 -0
  105. package/dist/src/promote.js +200 -0
  106. package/dist/src/promote.js.map +1 -0
  107. package/dist/src/prompts.d.ts +16 -0
  108. package/dist/src/prompts.d.ts.map +1 -0
  109. package/{src → dist/src}/prompts.js +172 -203
  110. package/dist/src/prompts.js.map +1 -0
  111. package/dist/src/recall.d.ts +9 -0
  112. package/dist/src/recall.d.ts.map +1 -0
  113. package/dist/src/recall.js +432 -0
  114. package/dist/src/recall.js.map +1 -0
  115. package/dist/src/redact.d.ts +27 -0
  116. package/dist/src/redact.d.ts.map +1 -0
  117. package/dist/src/redact.js +228 -0
  118. package/dist/src/redact.js.map +1 -0
  119. package/dist/src/rollback.d.ts +8 -0
  120. package/dist/src/rollback.d.ts.map +1 -0
  121. package/dist/src/rollback.js +33 -0
  122. package/dist/src/rollback.js.map +1 -0
  123. package/dist/src/routes.d.ts +7 -0
  124. package/dist/src/routes.d.ts.map +1 -0
  125. package/dist/src/routes.js +226 -0
  126. package/dist/src/routes.js.map +1 -0
  127. package/dist/src/rules-compiler.d.ts +20 -0
  128. package/dist/src/rules-compiler.d.ts.map +1 -0
  129. package/dist/src/rules-compiler.js +143 -0
  130. package/dist/src/rules-compiler.js.map +1 -0
  131. package/dist/src/server.d.ts +12 -0
  132. package/dist/src/server.d.ts.map +1 -0
  133. package/dist/src/server.js +22 -0
  134. package/dist/src/server.js.map +1 -0
  135. package/dist/src/tool-trace.d.ts +37 -0
  136. package/dist/src/tool-trace.d.ts.map +1 -0
  137. package/dist/src/tool-trace.js +142 -0
  138. package/dist/src/tool-trace.js.map +1 -0
  139. package/dist/src/types.d.ts +446 -0
  140. package/dist/src/types.d.ts.map +1 -0
  141. package/dist/src/types.js +6 -0
  142. package/dist/src/types.js.map +1 -0
  143. package/dist/src/ulid.d.ts +3 -0
  144. package/dist/src/ulid.d.ts.map +1 -0
  145. package/dist/src/ulid.js +11 -0
  146. package/dist/src/ulid.js.map +1 -0
  147. package/dist/src/utils.d.ts +10 -0
  148. package/dist/src/utils.d.ts.map +1 -0
  149. package/dist/src/utils.js +41 -0
  150. package/dist/src/utils.js.map +1 -0
  151. package/dist/src/validate.d.ts +22 -0
  152. package/dist/src/validate.d.ts.map +1 -0
  153. package/dist/src/validate.js +109 -0
  154. package/dist/src/validate.js.map +1 -0
  155. package/docs/assets/benchmarks/local-benchmark.svg +45 -0
  156. package/docs/assets/benchmarks/operations-benchmark.svg +45 -0
  157. package/docs/assets/benchmarks/published-memory-standards.svg +50 -0
  158. package/docs/benchmarking.md +151 -0
  159. package/docs/production-readiness.md +124 -0
  160. package/examples/fintech-ops-demo.js +67 -0
  161. package/examples/healthcare-ops-demo.js +67 -0
  162. package/examples/stripe-demo.js +105 -0
  163. package/package.json +53 -13
  164. package/mcp-server/config.js +0 -80
  165. package/mcp-server/index.js +0 -729
  166. package/src/adaptive.js +0 -53
  167. package/src/affect.js +0 -64
  168. package/src/audrey.js +0 -604
  169. package/src/causal.js +0 -95
  170. package/src/confidence.js +0 -120
  171. package/src/consolidate.js +0 -265
  172. package/src/context.js +0 -15
  173. package/src/db.js +0 -370
  174. package/src/decay.js +0 -84
  175. package/src/embedding.js +0 -256
  176. package/src/encode.js +0 -63
  177. package/src/export.js +0 -67
  178. package/src/forget.js +0 -111
  179. package/src/import.js +0 -245
  180. package/src/interference.js +0 -51
  181. package/src/introspect.js +0 -48
  182. package/src/llm.js +0 -246
  183. package/src/migrate.js +0 -58
  184. package/src/recall.js +0 -352
  185. package/src/rollback.js +0 -42
  186. package/src/ulid.js +0 -18
  187. package/src/utils.js +0 -38
  188. package/src/validate.js +0 -172
package/README.md CHANGED
@@ -1,808 +1,230 @@
1
1
  # Audrey
2
2
 
3
- Biological memory architecture for AI agents. Memory that decays, consolidates, feels, and learns — not just a database.
3
+ [![CI](https://github.com/Evilander/Audrey/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Evilander/Audrey/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/audrey.svg)](https://www.npmjs.com/package/audrey)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
6
 
5
- ## Why Audrey Exists
7
+ Audrey is a persistent memory and continuity engine for Claude Code and AI agents.
6
8
 
7
- Every AI memory tool today (Mem0, Zep, LangChain Memory) is a filing cabinet. Store stuff, retrieve stuff. None of them do what biological memory actually does:
9
+ It gives an agent a local memory store, durable recall, consolidation, contradiction handling, a REST sidecar, MCP tools, and benchmark gates without adding external infrastructure.
8
10
 
9
- - Memories don't decay. A fact from 6 months ago has the same weight as one from today.
10
- - No consolidation. Raw events never become general principles.
11
- - No contradiction detection. Conflicting facts coexist silently.
12
- - No self-defense. If an agent hallucinates and encodes the hallucination, it becomes "truth."
11
+ Requires Node.js 20+.
13
12
 
14
- Audrey fixes all of this by modeling memory the way the brain does:
13
+ ## Quick Start
15
14
 
16
- | Brain Structure | Audrey Component | What It Does |
17
- |---|---|---|
18
- | Hippocampus | Episodic Memory | Fast capture of raw events and observations |
19
- | Neocortex | Semantic Memory | Consolidated principles and patterns |
20
- | Cerebellum | Procedural Memory | Learned workflows and conditional behaviors |
21
- | Sleep Replay | Dream Cycle | Consolidates episodes into principles, applies decay |
22
- | Prefrontal Cortex | Validation Engine | Truth-checking, contradiction detection |
23
- | Amygdala | Affect System | Emotional encoding, arousal-salience coupling, mood-congruent recall |
24
-
25
- ## Install
26
-
27
- ### MCP Server for Claude Code (one command)
15
+ ### Claude Code
28
16
 
29
17
  ```bash
30
- npx audrey install
18
+ npx audrey init
19
+ npx audrey doctor
31
20
  ```
32
21
 
33
- That's it. Audrey auto-detects API keys from your environment:
34
-
35
- - `GOOGLE_API_KEY` or `GEMINI_API_KEY` set? Uses Gemini embeddings (3072d).
36
- - Neither? Runs with local embeddings (384d, MiniLM via @huggingface/transformers — zero API key, works offline).
37
- - `AUDREY_EMBEDDING_PROVIDER=openai` for explicit OpenAI embeddings (1536d).
38
- - `ANTHROPIC_API_KEY` set? Enables LLM-powered consolidation, contradiction detection, and reflection.
39
-
40
- ```bash
41
- # Check status
42
- npx audrey status
43
-
44
- # Uninstall
45
- npx audrey uninstall
46
- ```
22
+ This uses the default `local-offline` preset:
47
23
 
48
- Every Claude Code session now has 13 memory tools: `memory_encode`, `memory_recall`, `memory_consolidate`, `memory_dream`, `memory_introspect`, `memory_resolve_truth`, `memory_export`, `memory_import`, `memory_forget`, `memory_decay`, `memory_status`, `memory_reflect`, `memory_greeting`.
24
+ - registers Audrey with Claude Code
25
+ - installs hooks for automatic recall and reflection
26
+ - uses local embeddings by default
27
+ - stores memory in one local SQLite-backed data directory
49
28
 
50
- ### CLI Subcommands
29
+ ### REST or Docker Sidecar
51
30
 
52
31
  ```bash
53
- npx audrey install # Register MCP server with Claude Code
54
- npx audrey uninstall # Remove MCP server registration
55
- npx audrey status # Show memory store health and stats
56
- npx audrey greeting # Output session briefing (mood, principles, recent memories)
57
- npx audrey greeting "auth" # Briefing + context-relevant memories for "auth"
58
- npx audrey reflect # Reflect on conversation + dream cycle (reads turns from stdin)
59
- npx audrey dream # Run consolidation + decay cycle
60
- npx audrey reembed # Re-embed all memories with current provider
32
+ npx audrey init sidecar-prod
33
+ docker compose up -d --build
61
34
  ```
62
35
 
63
- `greeting` and `reflect` are designed for Claude Code hooks — wire them into SessionStart and Stop events for automatic memory lifecycle.
64
-
65
- ### SDK in Your Code
36
+ Then verify:
66
37
 
67
38
  ```bash
68
- npm install audrey
39
+ npx audrey doctor
40
+ curl http://localhost:3487/health
69
41
  ```
70
42
 
71
- Zero external infrastructure. One SQLite file.
72
-
73
- ## Usage
74
-
75
- ```js
76
- import { Audrey } from 'audrey';
77
-
78
- // 1. Create a brain
79
- const brain = new Audrey({
80
- dataDir: './agent-memory',
81
- agent: 'my-agent',
82
- embedding: { provider: 'local', dimensions: 384 }, // or 'gemini', 'openai'
83
- });
84
-
85
- // 2. Encode observations — with optional emotional context
86
- await brain.encode({
87
- content: 'Stripe API returns 429 above 100 req/s',
88
- source: 'direct-observation',
89
- tags: ['stripe', 'rate-limit'],
90
- affect: { valence: -0.4, arousal: 0.7, label: 'frustration' },
91
- });
92
-
93
- // 3. Recall what you know — mood-congruent retrieval
94
- const memories = await brain.recall('stripe rate limits', {
95
- limit: 5,
96
- mood: { valence: -0.3 }, // frustrated right now? memories encoded in frustration surface first
97
- });
98
-
99
- // 4. Filtered recall — by tag, source, or date range
100
- const recent = await brain.recall('stripe', {
101
- tags: ['rate-limit'],
102
- sources: ['direct-observation'],
103
- after: '2026-02-01T00:00:00Z',
104
- context: { task: 'debugging', domain: 'payments' }, // context-dependent retrieval
105
- });
43
+ ## Why Audrey
106
44
 
107
- // 5. Dream the biological sleep cycle
108
- const dream = await brain.dream();
109
- // Consolidates episodes into principles, applies forgetting curves, reports health
45
+ - Local-first: memory lives in SQLite with `sqlite-vec`, not a hosted vector database.
46
+ - Practical: MCP, CLI, REST, JavaScript, Python, and Docker are all first-class.
47
+ - Durable: snapshot, restore, health checks, benchmark gates, and graceful shutdown are built in.
48
+ - Structured: Audrey does more than save notes. It consolidates, decays, tracks contradictions, and supports procedural memory.
110
49
 
111
- // 6. Reflect on a conversation — form lasting memories
112
- const result = await brain.reflect([
113
- { role: 'user', content: 'How do I handle rate limits?' },
114
- { role: 'assistant', content: 'Use exponential backoff with jitter...' },
115
- ]);
116
- // LLM extracts what matters, encodes it as lasting memories
50
+ ## What Ships
117
51
 
118
- // 7. Session greeting wake up with context
119
- const briefing = await brain.greeting({ context: 'debugging stripe' });
120
- // Returns mood, principles, recent memories, identity, unresolved threads
52
+ - Claude Code MCP server with 13 memory tools
53
+ - Automatic hook-based recall and reflection for Claude Code sessions
54
+ - JavaScript SDK
55
+ - Python SDK packaged as `audrey-memory`
56
+ - REST API for sidecar deployment
57
+ - Docker and Compose deployment path
58
+ - Snapshot and restore for portable memory state
59
+ - Machine-readable health and benchmark gates
60
+ - Local benchmark harness with retrieval and lifecycle-operation tracks
121
61
 
122
- // 8. Forget something
123
- brain.forget(memoryId); // soft-delete
124
- brain.forget(memoryId, { purge: true }); // hard-delete
125
- await brain.forgetByQuery('old API endpoint', { minSimilarity: 0.9 });
62
+ ## Setup Presets
126
63
 
127
- // 9. Check brain health
128
- const stats = brain.introspect();
129
- // { episodic: 47, semantic: 12, procedural: 3, dormant: 8, ... }
64
+ `npx audrey init` supports four named presets:
130
65
 
131
- // 10. Clean up
132
- brain.close();
133
- ```
134
-
135
- ### Configuration
136
-
137
- ```js
138
- const brain = new Audrey({
139
- dataDir: './audrey-data', // SQLite database directory
140
- agent: 'my-agent', // Agent identifier
141
-
142
- // Embedding provider (required)
143
- embedding: {
144
- provider: 'local', // 'mock' (test), 'local' (384d MiniLM), 'gemini' (3072d), 'openai' (1536d)
145
- dimensions: 384, // Must match provider
146
- apiKey: '...', // Required for gemini/openai
147
- device: 'gpu', // 'gpu' or 'cpu' — for local provider only
148
- },
149
-
150
- // LLM provider (optional — enables smart consolidation + contradiction detection + reflection)
151
- llm: {
152
- provider: 'anthropic', // 'mock', 'anthropic', or 'openai'
153
- apiKey: '...', // Required for anthropic/openai
154
- model: 'claude-sonnet-4-6', // Optional model override
155
- },
156
-
157
- // Consolidation settings
158
- consolidation: {
159
- minEpisodes: 3, // Minimum cluster size for principle extraction
160
- },
161
-
162
- // Context-dependent retrieval
163
- context: {
164
- enabled: true, // Enable encoding-specificity principle
165
- weight: 0.3, // Max 30% confidence boost on full context match
166
- },
167
-
168
- // Emotional memory
169
- affect: {
170
- enabled: true, // Enable affect system
171
- weight: 0.2, // Max 20% mood-congruence boost
172
- arousalWeight: 0.3, // Yerkes-Dodson arousal-salience coupling
173
- resonance: { // Detect emotional echoes across experiences
174
- enabled: true,
175
- k: 5, // How many past episodes to check
176
- threshold: 0.5, // Semantic similarity threshold
177
- affectThreshold: 0.6, // Emotional similarity threshold
178
- },
179
- },
180
-
181
- // Interference-based forgetting
182
- interference: {
183
- enabled: true, // New episodes suppress similar existing memories
184
- weight: 0.15, // Suppression strength
185
- },
186
-
187
- // Decay settings
188
- decay: {
189
- dormantThreshold: 0.1, // Below this confidence = dormant
190
- },
191
- });
192
- ```
193
-
194
- **Without an LLM provider**, consolidation uses a default text-based extractor and contradiction detection is similarity-only. **With an LLM provider**, Audrey extracts real generalized principles (semantic and procedural), detects semantic contradictions, resolves context-dependent truths, and reflects on conversations to form lasting memories.
195
-
196
- ### Environment Variables (MCP Server)
197
-
198
- | Variable | Default | Purpose |
66
+ | Preset | Best For | Behavior |
199
67
  |---|---|---|
200
- | `AUDREY_DATA_DIR` | `~/.audrey/data` | SQLite database directory |
201
- | `AUDREY_AGENT` | `claude-code` | Agent identifier |
202
- | `AUDREY_EMBEDDING_PROVIDER` | auto-detect | `local`, `gemini`, `openai`, or `mock` |
203
- | `AUDREY_LLM_PROVIDER` | auto-detect | `anthropic`, `openai`, or `mock` |
204
- | `AUDREY_DEVICE` | `gpu` | Device for local embedding provider |
205
- | `GOOGLE_API_KEY` | — | Gemini embeddings (auto-selected when present) |
206
- | `ANTHROPIC_API_KEY` | — | Anthropic LLM (consolidation, reflection, contradiction detection) |
207
- | `OPENAI_API_KEY` | — | OpenAI embeddings/LLM (must be explicitly selected for embeddings) |
208
-
209
- ## Core Concepts
210
-
211
- ### Four Memory Types
212
-
213
- **Episodic** (hot, fast decay) — Raw events. "Stripe returned 429 at 3pm." Immutable. Append-only. Never modified.
214
-
215
- **Semantic** (warm, slow decay) — Consolidated principles. "Stripe enforces 100 req/s rate limit." Extracted automatically from clusters of episodic memories.
216
-
217
- **Procedural** (cold, slowest decay) — Learned workflows. "When Stripe rate-limits, implement exponential backoff." Skills the agent has acquired. Routed automatically when the LLM identifies a principle as procedural.
218
-
219
- **Causal** — Why things happened. Not just "A then B" but "A caused B because of mechanism C." Prevents correlation-as-causation.
220
-
221
- ### Confidence Formula
222
-
223
- Every memory has a compositional confidence score:
224
-
225
- ```
226
- C(m, t) = w_s * S + w_e * E + w_r * R(t) + w_ret * Ret(t)
227
- ```
228
-
229
- | Component | What It Measures | Default Weight |
230
- |---|---|---|
231
- | **S** — Source reliability | How trustworthy is the origin? | 0.30 |
232
- | **E** — Evidence agreement | Do observations agree or contradict? | 0.35 |
233
- | **R(t)** — Recency decay | How old is the memory? (Ebbinghaus curve) | 0.20 |
234
- | **Ret(t)** — Retrieval reinforcement | How often is this memory accessed? | 0.15 |
235
-
236
- Source reliability hierarchy:
237
-
238
- | Source Type | Reliability |
239
- |---|---|
240
- | `direct-observation` | 0.95 |
241
- | `told-by-user` | 0.90 |
242
- | `tool-result` | 0.85 |
243
- | `inference` | 0.60 |
244
- | `model-generated` | 0.40 (capped at 0.6 confidence) |
245
-
246
- The `model-generated` cap prevents circular self-confirmation — an agent can't boost its own hallucinations into high-confidence "facts."
247
-
248
- ### Decay (Forgetting Curves)
249
-
250
- Unreinforced memories lose confidence over time following Ebbinghaus exponential decay:
251
-
252
- | Memory Type | Half-Life | Rationale |
253
- |---|---|---|
254
- | Episodic | 7 days | Raw events go stale fast |
255
- | Semantic | 30 days | Principles are hard-won |
256
- | Procedural | 90 days | Skills are slowest to forget |
257
-
258
- Retrieval resets the decay clock. Frequently accessed memories persist. Memories below the dormant threshold (0.1) become dormant — still searchable with `includeDormant: true`, but excluded from default recall.
259
-
260
- ### Dream Cycle (The "Sleep" Cycle)
261
-
262
- `brain.dream()` runs the full biological sleep analog:
263
-
264
- 1. **Consolidate** — Cluster similar episodic memories via KNN, extract principles via LLM, route to semantic or procedural tables
265
- 2. **Decay** — Apply forgetting curves, transition low-confidence memories to dormant
266
- 3. **Introspect** — Report memory system health
267
-
268
- The pipeline is fully transactional — if any cluster fails mid-run, all writes roll back. Consolidation is idempotent. Re-running on the same data produces no duplicates.
269
-
270
- ### Consolidation Routing
271
-
272
- When the LLM extracts a principle, it classifies it:
273
-
274
- - `type: 'semantic'` → goes to the `semantics` table (general knowledge)
275
- - `type: 'procedural'` → goes to the `procedures` table with `trigger_conditions` (actionable skills)
276
-
277
- ### Contradiction Handling
278
-
279
- When memories conflict, Audrey doesn't force a winner. Contradictions have a lifecycle:
280
-
281
- ```
282
- open -> resolved | context_dependent | reopened
283
- ```
284
-
285
- Context-dependent truths are modeled explicitly:
286
-
287
- ```js
288
- // "Stripe rate limit is 100 req/s" (live keys)
289
- // "Stripe rate limit is 25 req/s" (test keys)
290
- // Both true — under different conditions
291
- ```
292
-
293
- New high-confidence evidence can reopen resolved disputes.
294
-
295
- ### Forget and Purge
296
-
297
- Memories can be explicitly forgotten — by ID or by semantic query:
298
-
299
- **Soft-delete** (default) — Marks the memory as forgotten/superseded and removes its vector index. The record stays in the database but is excluded from recall. Reversible via direct database access.
300
-
301
- **Hard-delete** (`purge: true`) — Permanently removes the memory from both the main table and the vector index. Irreversible.
302
-
303
- **Bulk purge** — Removes all forgotten, dormant, superseded, and rolled-back memories in one operation. Useful for GDPR compliance or storage cleanup.
304
-
305
- ### Rollback
306
-
307
- Bad consolidation? Undo it:
308
-
309
- ```js
310
- const history = brain.consolidationHistory();
311
- brain.rollback(history[0].id);
312
- // Semantic memories -> rolled_back state
313
- // Source episodes -> un-consolidated
314
- // Full audit trail preserved
315
- ```
316
-
317
- ### Circular Self-Confirmation Defense
318
-
319
- The most dangerous exploit in AI memory: agent hallucinates X, encodes it, later retrieves it, "reinforcement" boosts confidence, X eventually consolidates as "established truth."
320
-
321
- Audrey's defenses:
322
-
323
- 1. **Source diversity requirement** — Consolidation requires evidence from 2+ distinct source types
324
- 2. **Model-generated cap** — Memories from `model-generated` sources are capped at 0.6 confidence
325
- 3. **Source lineage tracking** — Provenance chains detect when all evidence traces back to a single inference
326
- 4. **Source diversity score** — Every semantic memory tracks how many different source types contributed
327
-
328
- ## API Reference
329
-
330
- ### `new Audrey(config)`
331
-
332
- See [Configuration](#configuration) above for all options.
333
-
334
- ### `brain.encode(params)` -> `Promise<string>`
335
-
336
- Encode an episodic memory. Returns the memory ID.
337
-
338
- ```js
339
- const id = await brain.encode({
340
- content: 'What happened', // Required. Non-empty string, max 50000 chars.
341
- source: 'direct-observation', // Required. See source types above.
342
- salience: 0.8, // Optional. 0-1. Default: 0.5
343
- causal: { // Optional. What caused this / what it caused.
344
- trigger: 'batch-processing',
345
- consequence: 'queue-backed-up',
346
- },
347
- tags: ['stripe', 'production'], // Optional. Array of strings.
348
- supersedes: 'previous-id', // Optional. ID of episode this corrects.
349
- context: { task: 'debugging' }, // Optional. Situational context for retrieval.
350
- affect: { // Optional. Emotional context.
351
- valence: -0.5, // -1 (negative) to 1 (positive)
352
- arousal: 0.7, // 0 (calm) to 1 (activated)
353
- label: 'frustration', // Human-readable emotion label
354
- },
355
- private: true, // Optional. If true, excluded from public recall.
356
- });
357
- ```
358
-
359
- Episodes are **immutable**. Corrections create new records with `supersedes` links. The original is preserved.
360
-
361
- ### `brain.encodeBatch(paramsList)` -> `Promise<string[]>`
362
-
363
- Encode multiple episodes in one call. Same params as `encode()`, but as an array.
364
-
365
- ```js
366
- const ids = await brain.encodeBatch([
367
- { content: 'Stripe returned 429', source: 'direct-observation' },
368
- { content: 'Redis timed out', source: 'tool-result' },
369
- { content: 'User reports slow checkout', source: 'told-by-user' },
370
- ]);
371
- ```
372
-
373
- ### `brain.recall(query, options)` -> `Promise<Memory[]>`
374
-
375
- Retrieve memories ranked by `similarity * confidence`.
376
-
377
- ```js
378
- const memories = await brain.recall('stripe rate limits', {
379
- limit: 5, // Max results (default 10, max 50)
380
- minConfidence: 0.5, // Filter below this confidence
381
- types: ['semantic'], // Filter by memory type
382
- includeProvenance: true, // Include evidence chains
383
- includeDormant: false, // Include dormant memories
384
- tags: ['rate-limit'], // Only episodic memories with these tags
385
- sources: ['direct-observation'], // Only episodic memories from these sources
386
- after: '2026-02-01T00:00:00Z', // Only memories created after this date
387
- before: '2026-03-01T00:00:00Z', // Only memories created before this date
388
- context: { task: 'debugging' }, // Boost memories encoded in matching context
389
- mood: { valence: -0.3, arousal: 0.5 }, // Mood-congruent retrieval
390
- });
391
- ```
392
-
393
- Tag and source filters only apply to episodic memories (semantic and procedural memories don't have tags or sources). Date filters apply to all memory types. Recall gracefully degrades — if one memory type's vector search fails, the others still return results.
394
-
395
- Each result:
396
-
397
- ```js
398
- {
399
- id: '01ABC...',
400
- content: 'Stripe enforces ~100 req/s rate limit',
401
- type: 'semantic',
402
- confidence: 0.87,
403
- score: 0.74, // similarity * confidence
404
- source: 'consolidation',
405
- state: 'active',
406
- contextMatch: 0.8, // When retrieval context provided
407
- moodCongruence: 0.7, // When mood provided
408
- provenance: { // When includeProvenance: true
409
- evidenceEpisodeIds: ['01XYZ...', '01DEF...'],
410
- evidenceCount: 3,
411
- supportingCount: 3,
412
- contradictingCount: 0,
413
- },
414
- }
415
- ```
416
-
417
- Retrieval automatically reinforces matched memories (boosts confidence, resets decay clock).
418
-
419
- ### `brain.recallStream(query, options)` -> `AsyncGenerator<Memory>`
420
-
421
- Streaming version of `recall()`. Yields results one at a time. Supports early `break`. Same options as `recall()`.
422
-
423
- ```js
424
- for await (const memory of brain.recallStream('stripe issues', { limit: 10 })) {
425
- console.log(memory.content, memory.score);
426
- if (memory.score > 0.9) break;
427
- }
428
- ```
68
+ | `local-offline` | Claude Code on one machine | Local embeddings, MCP install, hooks install |
69
+ | `hosted-fast` | Claude Code with provider keys already present | Auto-picks hosted providers from env, MCP install, hooks install |
70
+ | `ci-mock` | CI and smoke tests | Mock embedding + LLM providers, no Claude-specific setup |
71
+ | `sidecar-prod` | REST API and Docker deployment | Sidecar-oriented defaults, no Claude-specific setup |
429
72
 
430
- ### `brain.dream(options)` -> `Promise<DreamResult>`
73
+ Useful checks:
431
74
 
432
- Run the full biological sleep cycle: consolidate + decay + introspect.
433
-
434
- ```js
435
- const result = await brain.dream({
436
- minClusterSize: 3, // Min episodes per cluster
437
- similarityThreshold: 0.85, // KNN clustering threshold
438
- dormantThreshold: 0.1, // Below this = dormant
439
- });
440
- // {
441
- // consolidation: { episodesEvaluated, clustersFound, principlesExtracted, semanticsCreated, proceduresCreated },
442
- // decay: { totalEvaluated, transitionedToDormant },
443
- // stats: { episodic, semantic, procedural, ... },
444
- // }
75
+ ```bash
76
+ npx audrey doctor
77
+ npx audrey status
78
+ npx audrey status --json --fail-on-unhealthy
445
79
  ```
446
80
 
447
- ### `brain.reflect(turns)` -> `Promise<ReflectResult>`
81
+ ## Use Audrey From Code
448
82
 
449
- Feed a conversation to the LLM and extract lasting memories. Requires an LLM provider.
83
+ ### JavaScript
450
84
 
451
85
  ```js
452
- const result = await brain.reflect([
453
- { role: 'user', content: 'How do I handle rate limits?' },
454
- { role: 'assistant', content: 'Use exponential backoff...' },
455
- ]);
456
- // { encoded: 2, memories: [...] }
457
- ```
458
-
459
- ### `brain.greeting(options)` -> `Promise<GreetingResult>`
460
-
461
- Session-start briefing. Returns mood, principles, identity, recent memories, and unresolved threads.
86
+ import { Audrey } from 'audrey';
462
87
 
463
- ```js
464
- const briefing = await brain.greeting({
465
- context: 'debugging stripe', // Optional — also returns relevant memories
466
- recentLimit: 10,
467
- principleLimit: 5,
468
- identityLimit: 5,
88
+ const brain = new Audrey({
89
+ dataDir: './audrey-data',
90
+ agent: 'support-agent',
91
+ embedding: { provider: 'local', dimensions: 384 },
469
92
  });
470
- // { recent, principles, mood, unresolved, identity, contextual }
471
- ```
472
-
473
- ### `brain.forget(id, options)` -> `ForgetResult`
474
-
475
- Forget a memory by ID. Works on any memory type (episodic, semantic, procedural).
476
93
 
477
- ```js
478
- brain.forget(memoryId); // soft-delete
479
- brain.forget(memoryId, { purge: true }); // hard-delete (permanent)
480
- // { id, type: 'episodic', purged: false }
481
- ```
482
-
483
- ### `brain.forgetByQuery(query, options)` -> `Promise<ForgetResult | null>`
484
-
485
- Find the closest matching memory by semantic search and forget it. Searches all three memory types, picks the best match.
486
-
487
- ```js
488
- const result = await brain.forgetByQuery('old API endpoint', {
489
- minSimilarity: 0.9, // Threshold for match (default 0.9)
490
- purge: false, // Hard-delete? (default false)
94
+ await brain.encode({
95
+ content: 'Stripe returns HTTP 429 above 100 req/s',
96
+ source: 'direct-observation',
97
+ tags: ['stripe', 'rate-limit'],
491
98
  });
492
- // null if no match above threshold
493
- ```
494
-
495
- ### `brain.purge()` -> `PurgeCounts`
496
99
 
497
- Bulk hard-delete all dead memories: forgotten episodes, dormant/superseded/rolled-back semantics and procedures.
498
-
499
- ```js
500
- const counts = brain.purge();
501
- // { episodes: 12, semantics: 3, procedures: 0 }
502
- ```
100
+ const memories = await brain.recall('stripe rate limit');
503
101
 
504
- ### `brain.consolidate(options)` -> `Promise<ConsolidationResult>`
505
-
506
- Run the consolidation engine manually. Fully transactional — if any cluster fails, all writes roll back.
507
-
508
- ```js
509
- const result = await brain.consolidate({
510
- minClusterSize: 3,
511
- similarityThreshold: 0.80,
512
- extractPrinciple: (episodes) => ({ // Optional LLM callback
513
- content: 'Extracted principle text',
514
- type: 'semantic', // or 'procedural'
515
- conditions: ['trigger conditions'], // for procedural only
516
- }),
517
- });
518
- // { runId, status, episodesEvaluated, clustersFound, principlesExtracted, semanticsCreated, proceduresCreated }
102
+ await brain.waitForIdle();
103
+ brain.close();
519
104
  ```
520
105
 
521
- ### `brain.decay(options)` -> `DecayResult`
522
-
523
- Apply forgetting curves. Transitions low-confidence memories to dormant.
106
+ ### Python
524
107
 
525
- ```js
526
- const result = brain.decay({ dormantThreshold: 0.1 });
527
- // { totalEvaluated, transitionedToDormant, timestamp }
108
+ ```bash
109
+ pip install audrey-memory
528
110
  ```
529
111
 
530
- ### `brain.memoryStatus()` -> `HealthStatus`
112
+ ```python
113
+ from audrey_memory import Audrey
531
114
 
532
- Check brain health: vector index sync, dimension consistency, re-embed recommendations.
115
+ brain = Audrey(
116
+ base_url="http://127.0.0.1:3487",
117
+ api_key="secret",
118
+ agent="support-agent",
119
+ )
533
120
 
534
- ```js
535
- brain.memoryStatus();
536
- // { healthy, vec_episodes, searchable_episodes, vec_semantics, ..., reembed_recommended }
121
+ memory_id = brain.encode(
122
+ "Stripe returns HTTP 429 above 100 req/s",
123
+ source="direct-observation",
124
+ )
125
+ results = brain.recall("stripe rate limit", limit=5)
126
+ brain.close()
537
127
  ```
538
128
 
539
- ### `brain.rollback(runId)` -> `RollbackResult`
129
+ ## Key Commands
540
130
 
541
- Undo a consolidation run.
131
+ ```bash
132
+ # Setup
133
+ npx audrey init
134
+ npx audrey init hosted-fast
135
+ npx audrey init ci-mock
136
+ npx audrey init sidecar-prod
542
137
 
543
- ```js
544
- brain.rollback('01ABC...');
545
- // { rolledBackMemories: 3, restoredEpisodes: 9 }
546
- ```
138
+ # Claude Code integration
139
+ npx audrey install
140
+ npx audrey hooks install
141
+ npx audrey hooks uninstall
142
+ npx audrey uninstall
547
143
 
548
- ### `brain.resolveTruth(contradictionId)` -> `Promise<Resolution>`
144
+ # Health and maintenance
145
+ npx audrey doctor
146
+ npx audrey status
147
+ npx audrey dream
148
+ npx audrey reembed
549
149
 
550
- Resolve an open contradiction using LLM reasoning. Requires an LLM provider configured.
150
+ # Versioning
151
+ npx audrey snapshot
152
+ npx audrey restore backup.json --force
551
153
 
552
- ```js
553
- const resolution = await brain.resolveTruth('contradiction-id');
554
- // { resolution: 'context_dependent', conditions: { a: 'live keys', b: 'test keys' }, explanation: '...' }
154
+ # Sidecar
155
+ npx audrey serve
156
+ docker compose up -d --build
555
157
  ```
556
158
 
557
- ### `brain.introspect()` -> `Stats`
159
+ ## Benchmarks
558
160
 
559
- Get memory system health stats.
161
+ Audrey ships with a benchmark harness and release gate:
560
162
 
561
- ```js
562
- brain.introspect();
563
- // {
564
- // episodic: 247, semantic: 31, procedural: 8,
565
- // causalLinks: 42, dormant: 15,
566
- // contradictions: { open: 2, resolved: 7, context_dependent: 3, reopened: 0 },
567
- // lastConsolidation: '2026-02-18T22:00:00Z',
568
- // totalConsolidationRuns: 14,
569
- // }
163
+ ```bash
164
+ npm run bench:memory
165
+ npm run bench:memory:check
570
166
  ```
571
167
 
572
- ### `brain.consolidationHistory()` -> `ConsolidationRun[]`
168
+ The benchmark suite measures:
573
169
 
574
- Full audit trail of all consolidation runs.
170
+ - retrieval behavior
171
+ - update and overwrite behavior
172
+ - delete and abstain behavior
173
+ - semantic and procedural merge behavior
575
174
 
576
- ### `brain.export()` / `brain.import(snapshot)`
175
+ Current repo snapshot:
577
176
 
578
- Export all memories as a JSON snapshot, or import from one. Full-fidelity: preserves consolidation metrics, run metadata, and config. Import re-embeds everything with the current provider in a single atomic transaction.
177
+ ![Audrey local benchmark](docs/assets/benchmarks/local-benchmark.svg)
579
178
 
580
- ```js
581
- const snapshot = brain.export(); // { version, episodes, semantics, procedures, consolidationMetrics, ... }
582
- await brain.import(snapshot); // Re-embeds everything with current provider
583
- ```
179
+ For detailed methodology, published comparison anchors, and generated reports, see [docs/benchmarking.md](docs/benchmarking.md).
584
180
 
585
- ### Events
181
+ ## Production
586
182
 
587
- ```js
588
- brain.on('encode', ({ id, content, source }) => { ... });
589
- brain.on('reinforcement', ({ episodeId, targetId, similarity }) => { ... });
590
- brain.on('contradiction', ({ episodeId, contradictionId, semanticId, resolution }) => { ... });
591
- brain.on('consolidation', ({ runId, principlesExtracted }) => { ... });
592
- brain.on('decay', ({ totalEvaluated, transitionedToDormant }) => { ... });
593
- brain.on('dream', ({ consolidation, decay, stats }) => { ... });
594
- brain.on('rollback', ({ runId, rolledBackMemories }) => { ... });
595
- brain.on('forget', ({ id, type, purged }) => { ... });
596
- brain.on('purge', ({ episodes, semantics, procedures }) => { ... });
597
- brain.on('interference', ({ newEpisodeId, suppressedId, similarity }) => { ... });
598
- brain.on('resonance', ({ episodeId, resonances }) => { ... });
599
- brain.on('migration', ({ episodes, semantics, procedures }) => { ... });
600
- brain.on('error', (err) => { ... });
601
- ```
183
+ Audrey is strongest in workflows where memory must stay local, reviewable, and durable. It already fits well as a sidecar for internal agents in operational domains like financial services and healthcare operations, but it is a memory layer, not a compliance boundary.
602
184
 
603
- ### `brain.close()`
185
+ Production guide: [docs/production-readiness.md](docs/production-readiness.md)
604
186
 
605
- Close the database connection.
187
+ Examples:
606
188
 
607
- ## Architecture
189
+ - [examples/fintech-ops-demo.js](examples/fintech-ops-demo.js)
190
+ - [examples/healthcare-ops-demo.js](examples/healthcare-ops-demo.js)
191
+ - [examples/stripe-demo.js](examples/stripe-demo.js)
608
192
 
609
- ```
610
- audrey-data/
611
- audrey.db <- Single SQLite file. WAL mode. That's your brain.
612
- ```
193
+ ## Environment
613
194
 
614
- ```
615
- src/
616
- audrey.js Main class. EventEmitter. Public API surface.
617
- causal.js Causal graph management. LLM-powered mechanism articulation.
618
- confidence.js Compositional confidence formula. Pure math.
619
- consolidate.js "Sleep" cycle. KNN clustering -> LLM extraction -> promote.
620
- db.js SQLite + sqlite-vec. Schema, vec0 tables, migrations.
621
- decay.js Ebbinghaus forgetting curves.
622
- embedding.js Pluggable providers (Mock, Local/MiniLM, Gemini, OpenAI). Batch embedding.
623
- encode.js Immutable episodic memory creation + vec0 writes.
624
- affect.js Emotional memory: arousal-salience coupling, mood-congruent recall, resonance.
625
- context.js Context-dependent retrieval modifier (encoding specificity).
626
- interference.js Competitive memory suppression (engram competition).
627
- forget.js Soft-delete, hard-delete, query-based forget, bulk purge.
628
- introspect.js Health dashboard queries.
629
- llm.js Pluggable LLM providers (Mock, Anthropic, OpenAI).
630
- prompts.js Structured prompt templates for LLM operations.
631
- recall.js KNN retrieval + confidence scoring + filtered recall + streaming.
632
- rollback.js Undo consolidation runs.
633
- utils.js Date math, safe JSON parse.
634
- validate.js KNN validation + LLM contradiction detection.
635
- migrate.js Dimension migration re-embedding.
636
- adaptive.js Adaptive consolidation parameter suggestions.
637
- export.js Memory export (JSON snapshots with consolidation metrics).
638
- import.js Memory import with batch re-embedding in atomic transactions.
639
- index.js SDK barrel export (all providers, database utilities).
640
-
641
- mcp-server/
642
- index.js MCP tool server (13 tools, stdio transport) + CLI subcommands.
643
- config.js Shared config (env var parsing, provider resolution, install arg builder).
644
- ```
195
+ Starter config:
645
196
 
646
- ### Database Schema
197
+ - [.env.example](.env.example)
198
+ - [.env.docker.example](.env.docker.example)
647
199
 
648
- | Table | Purpose |
649
- |---|---|
650
- | `episodes` | Immutable raw events (content, source, salience, causal context, affect, private flag) |
651
- | `semantics` | Consolidated principles (content, state, evidence chain) |
652
- | `procedures` | Learned workflows (trigger conditions, success/failure counts) |
653
- | `causal_links` | Causal relationships (cause, effect, mechanism, link type) |
654
- | `contradictions` | Dispute tracking (claims, state, resolution) |
655
- | `consolidation_runs` | Audit trail (inputs, outputs, status, checkpoint cursor) |
656
- | `consolidation_metrics` | Per-run metrics and confidence deltas |
657
- | `vec_episodes` | sqlite-vec KNN index for episode embeddings |
658
- | `vec_semantics` | sqlite-vec KNN index for semantic embeddings |
659
- | `vec_procedures` | sqlite-vec KNN index for procedural embeddings |
660
- | `audrey_config` | Dimension configuration, embedding model info, metadata |
200
+ Key environment variables:
661
201
 
662
- All mutations use SQLite transactions. CHECK constraints enforce valid states and source types. Vector search uses sqlite-vec with cosine distance.
202
+ - `AUDREY_DATA_DIR`
203
+ - `AUDREY_EMBEDDING_PROVIDER`
204
+ - `AUDREY_LLM_PROVIDER`
205
+ - `AUDREY_DEVICE`
206
+ - `AUDREY_API_KEY`
207
+ - `AUDREY_HOST`
208
+ - `AUDREY_PORT`
663
209
 
664
- ## Running Tests
210
+ ## Documentation
665
211
 
666
- ```bash
667
- npm test # 463 tests across 29 files
668
- npm run test:watch
669
- ```
212
+ - [docs/benchmarking.md](docs/benchmarking.md)
213
+ - [docs/production-readiness.md](docs/production-readiness.md)
214
+ - [CONTRIBUTING.md](CONTRIBUTING.md)
215
+ - [SECURITY.md](SECURITY.md)
670
216
 
671
- ## Running the Demo
217
+ ## Development
672
218
 
673
219
  ```bash
674
- node examples/stripe-demo.js
220
+ npm ci
221
+ npm test
222
+ npm run bench:memory:check
223
+ npm run pack:check
224
+ python -m unittest discover -s python/tests -v
225
+ python -m build --no-isolation python
675
226
  ```
676
227
 
677
- Demonstrates the full pipeline: encode 3 rate-limit observations, consolidate into principle, recall proactively.
678
-
679
- ---
680
-
681
- ## Changelog
682
-
683
- ### v0.16.0 (current)
684
-
685
- - Version bump for npm publish with all v0.15.0 features included
686
- - 463 tests across 29 test files
687
-
688
- ### v0.15.0 — Production Hardening + Dream Cycle
689
-
690
- - `dream()` method: consolidation + decay + introspect (biological sleep analog)
691
- - `memory_dream` MCP tool with configurable thresholds
692
- - `greeting` and `reflect` CLI subcommands for hook integration
693
- - Consolidation routes procedural principles to `procedures` table (previously all went to semantics)
694
- - Fully transactional consolidation — mid-run failures roll back all writes
695
- - Recall gracefully degrades per memory type (independent try/catch per KNN search)
696
- - sqlite-vec crash guard for empty vector tables
697
- - LLM JSON parsing strips markdown code fences from any provider
698
- - Input validation: empty content rejected, 50K char limit, forget requires exactly one target
699
- - Full-fidelity export/import: preserves consolidation metrics, run metadata, config
700
- - Import uses batch embedding in a single atomic transaction
701
- - Expanded SDK exports: all embedding/LLM providers, database utilities
702
- - Shared `resolveLLMConfig()` for CLI commands
703
- - 463 tests across 29 test files
704
-
705
- ### v0.14.0 — Memory Intelligence
706
-
707
- - `memory_reflect` MCP tool — form lasting memories from conversation turns
708
- - `memory_greeting` MCP tool — session-start context briefing
709
- - `greeting()` method: mood, principles, identity, recent memories, unresolved threads
710
- - `reflect()` method: LLM-powered conversation analysis and memory formation
711
- - Rewritten consolidation prompt for deeper principle extraction
712
- - Rewritten reflection prompt for relational and emotional depth
713
- - `npx audrey status` shows last consolidation time
714
-
715
- ### v0.13.0 — GPU-Accelerated Embeddings
716
-
717
- - GPU device configuration for LocalEmbeddingProvider
718
- - True single-forward-pass batch embedding for LocalEmbeddingProvider
719
- - Gemini `batchEmbedContents` API for batch embedding
720
- - `reembedAll` uses `embedBatch` for performance
721
- - `AUDREY_DEVICE` env var, `memoryStatus` reports device
722
-
723
- ### v0.11.0 — Multi-Provider Embeddings + Privacy
724
-
725
- - `LocalEmbeddingProvider` — 384d MiniLM via @huggingface/transformers (zero API key, works offline)
726
- - `GeminiEmbeddingProvider` — 3072d via Google text-embedding-004
727
- - `private: true` memory flag — memories visible to AI only, excluded from public recall
728
- - Auto-select embedding provider: local -> gemini (if API key present) -> explicit openai
729
- - `npx audrey reembed` CLI subcommand for provider migration
730
- - `reflect()` method for post-conversation memory formation
731
- - 409 tests across 29 test files
732
-
733
- ### v0.9.0 — Emotional Memory
734
-
735
- - Valence-arousal affect model (Russell's circumplex) on every episode
736
- - Arousal-salience coupling via Yerkes-Dodson inverted-U curve
737
- - Mood-congruent recall — matching emotional state boosts retrieval confidence
738
- - Emotional resonance detection — new experiences that echo past emotional patterns emit events
739
- - MCP server: `memory_encode` accepts `affect`, `memory_recall` accepts `mood`
740
-
741
- ### v0.8.0 — Context-Dependent Retrieval
742
-
743
- - Encoding specificity principle: context stored with memory, matching context boosts recall
744
- - MCP server: `memory_encode` and `memory_recall` accept `context`
745
-
746
- ### v0.7.0 — Interference + Salience
747
-
748
- - Interference-based forgetting: new memories competitively suppress similar existing ones
749
- - Salience-weighted confidence: high-salience memories resist decay
750
- - Spaced-repetition reconsolidation: retrieval intervals affect reinforcement strength
751
-
752
- ### v0.6.0 — Filtered Recall + Forget
753
-
754
- - Filtered recall: tag, source, and date-range filters on `recall()` and `recallStream()`
755
- - `forget()`, `forgetByQuery()`, `purge()`
756
- - `memory_forget` and `memory_decay` MCP tools
757
-
758
- ### v0.5.0 — Feature Depth
759
-
760
- - Configurable confidence weights and decay rates per instance
761
- - Memory export/import (JSON snapshots with re-embedding)
762
- - `memory_export` and `memory_import` MCP tools
763
- - Auto-consolidation scheduling
764
- - Adaptive consolidation parameter suggestions
765
-
766
- ### v0.3.1 — MCP Server
767
-
768
- - MCP tool server via `@modelcontextprotocol/sdk` with stdio transport
769
- - One-command install: `npx audrey install` (auto-detects API keys)
770
- - CLI subcommands: `install`, `uninstall`, `status`
771
-
772
- ### v0.3.0 — Vector Performance
773
-
774
- - sqlite-vec native vector indexing (vec0 virtual tables with cosine distance)
775
- - KNN queries for recall, validation, and consolidation clustering
776
- - Batch encoding API and streaming recall with async generators
777
-
778
- ### v0.2.0 — LLM Integration
779
-
780
- - LLM-powered principle extraction, contradiction detection, causal articulation
781
- - Context-dependent truth resolution
782
- - Configurable LLM providers (Mock, Anthropic, OpenAI)
783
-
784
- ### v0.1.0 — Foundation
785
-
786
- - Immutable episodic memory, compositional confidence, Ebbinghaus forgetting curves
787
- - Consolidation engine, contradiction lifecycle, rollback
788
- - Circular self-confirmation defense, causal context, introspection
789
-
790
- ## Design Decisions
791
-
792
- **Why SQLite, not Postgres?** Zero infrastructure. `npm install` and you have a brain. The adapter pattern means you can migrate to pgvector when you need to scale.
793
-
794
- **Why append-only episodes?** Immutability creates a reliable audit trail. Corrections use `supersedes` links rather than mutations. You can always trace back to what actually happened.
795
-
796
- **Why Ebbinghaus curves?** Biological forgetting is an adaptive feature, not a bug. It prevents cognitive overload, maintains relevance, and enables generalization. Audrey's forgetting works the same way.
797
-
798
- **Why model-generated cap at 0.6?** Prevents the most dangerous exploit in AI memory: circular self-confirmation where an agent's own inferences bootstrap themselves into high-confidence "facts" through repeated retrieval.
799
-
800
- **Why soft-delete by default?** Hard-deletes are irreversible. Soft-delete preserves data integrity and audit trails while excluding the memory from recall. Use `purge: true` or `brain.purge()` when you need permanent removal (GDPR, storage cleanup).
801
-
802
- **Why emotional memory?** Every memory system stores facts. Biological memory stores facts with emotional context — and that context changes how memories are retrieved. Emotional arousal modulates encoding strength (amygdala-hippocampal interaction). Current mood biases which memories surface (Bower, 1981). This isn't a novelty feature — it's the foundation for AI that remembers like it cares.
803
-
804
- **Why a dream cycle?** Biological sleep isn't downtime — it's when the brain consolidates episodic memories into long-term semantic knowledge, prunes weak connections, and strengthens important ones. Audrey's `dream()` does the same: cluster episodes, extract principles, apply decay, report health. Wire it into session hooks and your agent gets smarter every time it sleeps.
805
-
806
228
  ## License
807
229
 
808
- MIT
230
+ MIT. See [LICENSE](LICENSE).