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.
- package/LICENSE +21 -21
- package/README.md +146 -724
- package/dist/mcp-server/config.d.ts +20 -0
- package/dist/mcp-server/config.d.ts.map +1 -0
- package/dist/mcp-server/config.js +125 -0
- package/dist/mcp-server/config.js.map +1 -0
- package/dist/mcp-server/index.d.ts +100 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +1113 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/src/adaptive.d.ts +7 -0
- package/dist/src/adaptive.d.ts.map +1 -0
- package/dist/src/adaptive.js +49 -0
- package/dist/src/adaptive.js.map +1 -0
- package/dist/src/affect.d.ts +19 -0
- package/dist/src/affect.d.ts.map +1 -0
- package/dist/src/affect.js +72 -0
- package/dist/src/affect.js.map +1 -0
- package/dist/src/audrey.d.ts +140 -0
- package/dist/src/audrey.d.ts.map +1 -0
- package/dist/src/audrey.js +564 -0
- package/dist/src/audrey.js.map +1 -0
- package/dist/src/capsule.d.ts +68 -0
- package/dist/src/capsule.d.ts.map +1 -0
- package/dist/src/capsule.js +311 -0
- package/dist/src/capsule.js.map +1 -0
- package/dist/src/causal.d.ts +28 -0
- package/dist/src/causal.d.ts.map +1 -0
- package/dist/src/causal.js +65 -0
- package/dist/src/causal.js.map +1 -0
- package/dist/src/confidence.d.ts +12 -0
- package/dist/src/confidence.d.ts.map +1 -0
- package/dist/src/confidence.js +63 -0
- package/dist/src/confidence.js.map +1 -0
- package/dist/src/consolidate.d.ts +8 -0
- package/dist/src/consolidate.d.ts.map +1 -0
- package/dist/src/consolidate.js +218 -0
- package/dist/src/consolidate.js.map +1 -0
- package/dist/src/context.d.ts +3 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +19 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/db.d.ts +12 -0
- package/dist/src/db.d.ts.map +1 -0
- package/dist/src/db.js +380 -0
- package/dist/src/db.js.map +1 -0
- package/dist/src/decay.d.ts +7 -0
- package/dist/src/decay.d.ts.map +1 -0
- package/dist/src/decay.js +68 -0
- package/dist/src/decay.js.map +1 -0
- package/dist/src/embedding.d.ts +57 -0
- package/dist/src/embedding.d.ts.map +1 -0
- package/dist/src/embedding.js +254 -0
- package/dist/src/embedding.js.map +1 -0
- package/dist/src/encode.d.ts +15 -0
- package/dist/src/encode.d.ts.map +1 -0
- package/dist/src/encode.js +36 -0
- package/dist/src/encode.js.map +1 -0
- package/dist/src/events.d.ts +69 -0
- package/dist/src/events.d.ts.map +1 -0
- package/dist/src/events.js +149 -0
- package/dist/src/events.js.map +1 -0
- package/dist/src/export.d.ts +3 -0
- package/dist/src/export.d.ts.map +1 -0
- package/dist/src/export.js +46 -0
- package/dist/src/export.js.map +1 -0
- package/dist/src/forget.d.ts +11 -0
- package/dist/src/forget.d.ts.map +1 -0
- package/dist/src/forget.js +105 -0
- package/dist/src/forget.js.map +1 -0
- package/dist/src/fts.d.ts +34 -0
- package/dist/src/fts.d.ts.map +1 -0
- package/dist/src/fts.js +117 -0
- package/dist/src/fts.js.map +1 -0
- package/dist/src/hybrid-recall.d.ts +37 -0
- package/dist/src/hybrid-recall.d.ts.map +1 -0
- package/dist/src/hybrid-recall.js +213 -0
- package/dist/src/hybrid-recall.js.map +1 -0
- package/dist/src/import.d.ts +4 -0
- package/dist/src/import.d.ts.map +1 -0
- package/dist/src/import.js +127 -0
- package/dist/src/import.js.map +1 -0
- package/dist/src/index.d.ts +22 -0
- package/dist/src/index.d.ts.map +1 -0
- package/{src → dist/src}/index.js +5 -13
- package/dist/src/index.js.map +1 -0
- package/dist/src/interference.d.ts +13 -0
- package/dist/src/interference.d.ts.map +1 -0
- package/dist/src/interference.js +45 -0
- package/dist/src/interference.js.map +1 -0
- package/dist/src/introspect.d.ts +4 -0
- package/dist/src/introspect.d.ts.map +1 -0
- package/dist/src/introspect.js +40 -0
- package/dist/src/introspect.js.map +1 -0
- package/dist/src/llm.d.ts +38 -0
- package/dist/src/llm.d.ts.map +1 -0
- package/dist/src/llm.js +167 -0
- package/dist/src/llm.js.map +1 -0
- package/dist/src/migrate.d.ts +6 -0
- package/dist/src/migrate.d.ts.map +1 -0
- package/dist/src/migrate.js +51 -0
- package/dist/src/migrate.js.map +1 -0
- package/dist/src/promote.d.ts +40 -0
- package/dist/src/promote.d.ts.map +1 -0
- package/dist/src/promote.js +200 -0
- package/dist/src/promote.js.map +1 -0
- package/dist/src/prompts.d.ts +16 -0
- package/dist/src/prompts.d.ts.map +1 -0
- package/{src → dist/src}/prompts.js +172 -203
- package/dist/src/prompts.js.map +1 -0
- package/dist/src/recall.d.ts +9 -0
- package/dist/src/recall.d.ts.map +1 -0
- package/dist/src/recall.js +432 -0
- package/dist/src/recall.js.map +1 -0
- package/dist/src/redact.d.ts +27 -0
- package/dist/src/redact.d.ts.map +1 -0
- package/dist/src/redact.js +228 -0
- package/dist/src/redact.js.map +1 -0
- package/dist/src/rollback.d.ts +8 -0
- package/dist/src/rollback.d.ts.map +1 -0
- package/dist/src/rollback.js +33 -0
- package/dist/src/rollback.js.map +1 -0
- package/dist/src/routes.d.ts +7 -0
- package/dist/src/routes.d.ts.map +1 -0
- package/dist/src/routes.js +226 -0
- package/dist/src/routes.js.map +1 -0
- package/dist/src/rules-compiler.d.ts +20 -0
- package/dist/src/rules-compiler.d.ts.map +1 -0
- package/dist/src/rules-compiler.js +143 -0
- package/dist/src/rules-compiler.js.map +1 -0
- package/dist/src/server.d.ts +12 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +22 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/tool-trace.d.ts +37 -0
- package/dist/src/tool-trace.d.ts.map +1 -0
- package/dist/src/tool-trace.js +142 -0
- package/dist/src/tool-trace.js.map +1 -0
- package/dist/src/types.d.ts +446 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +6 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/ulid.d.ts +3 -0
- package/dist/src/ulid.d.ts.map +1 -0
- package/dist/src/ulid.js +11 -0
- package/dist/src/ulid.js.map +1 -0
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/dist/src/utils.js +41 -0
- package/dist/src/utils.js.map +1 -0
- package/dist/src/validate.d.ts +22 -0
- package/dist/src/validate.d.ts.map +1 -0
- package/dist/src/validate.js +109 -0
- package/dist/src/validate.js.map +1 -0
- package/docs/assets/benchmarks/local-benchmark.svg +45 -0
- package/docs/assets/benchmarks/operations-benchmark.svg +45 -0
- package/docs/assets/benchmarks/published-memory-standards.svg +50 -0
- package/docs/benchmarking.md +151 -0
- package/docs/production-readiness.md +124 -0
- package/examples/fintech-ops-demo.js +67 -0
- package/examples/healthcare-ops-demo.js +67 -0
- package/examples/stripe-demo.js +105 -0
- package/package.json +53 -13
- package/mcp-server/config.js +0 -80
- package/mcp-server/index.js +0 -729
- package/src/adaptive.js +0 -53
- package/src/affect.js +0 -64
- package/src/audrey.js +0 -604
- package/src/causal.js +0 -95
- package/src/confidence.js +0 -120
- package/src/consolidate.js +0 -265
- package/src/context.js +0 -15
- package/src/db.js +0 -370
- package/src/decay.js +0 -84
- package/src/embedding.js +0 -256
- package/src/encode.js +0 -63
- package/src/export.js +0 -67
- package/src/forget.js +0 -111
- package/src/import.js +0 -245
- package/src/interference.js +0 -51
- package/src/introspect.js +0 -48
- package/src/llm.js +0 -246
- package/src/migrate.js +0 -58
- package/src/recall.js +0 -352
- package/src/rollback.js +0 -42
- package/src/ulid.js +0 -18
- package/src/utils.js +0 -38
- package/src/validate.js +0 -172
package/README.md
CHANGED
|
@@ -1,808 +1,230 @@
|
|
|
1
1
|
# Audrey
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/Evilander/Audrey/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/audrey)
|
|
5
|
+
[](LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Audrey is a persistent memory and continuity engine for Claude Code and AI agents.
|
|
6
8
|
|
|
7
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13
|
+
## Quick Start
|
|
15
14
|
|
|
16
|
-
|
|
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
|
|
18
|
+
npx audrey init
|
|
19
|
+
npx audrey doctor
|
|
31
20
|
```
|
|
32
21
|
|
|
33
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
29
|
+
### REST or Docker Sidecar
|
|
51
30
|
|
|
52
31
|
```bash
|
|
53
|
-
npx audrey
|
|
54
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
### SDK in Your Code
|
|
36
|
+
Then verify:
|
|
66
37
|
|
|
67
38
|
```bash
|
|
68
|
-
|
|
39
|
+
npx audrey doctor
|
|
40
|
+
curl http://localhost:3487/health
|
|
69
41
|
```
|
|
70
42
|
|
|
71
|
-
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
| `
|
|
201
|
-
| `
|
|
202
|
-
| `
|
|
203
|
-
| `
|
|
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
|
-
|
|
73
|
+
Useful checks:
|
|
431
74
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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
|
-
|
|
81
|
+
## Use Audrey From Code
|
|
448
82
|
|
|
449
|
-
|
|
83
|
+
### JavaScript
|
|
450
84
|
|
|
451
85
|
```js
|
|
452
|
-
|
|
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
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
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
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
522
|
-
|
|
523
|
-
Apply forgetting curves. Transitions low-confidence memories to dormant.
|
|
106
|
+
### Python
|
|
524
107
|
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
// { totalEvaluated, transitionedToDormant, timestamp }
|
|
108
|
+
```bash
|
|
109
|
+
pip install audrey-memory
|
|
528
110
|
```
|
|
529
111
|
|
|
530
|
-
|
|
112
|
+
```python
|
|
113
|
+
from audrey_memory import Audrey
|
|
531
114
|
|
|
532
|
-
|
|
115
|
+
brain = Audrey(
|
|
116
|
+
base_url="http://127.0.0.1:3487",
|
|
117
|
+
api_key="secret",
|
|
118
|
+
agent="support-agent",
|
|
119
|
+
)
|
|
533
120
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
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
|
-
|
|
129
|
+
## Key Commands
|
|
540
130
|
|
|
541
|
-
|
|
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
|
-
|
|
544
|
-
|
|
545
|
-
|
|
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
|
-
|
|
144
|
+
# Health and maintenance
|
|
145
|
+
npx audrey doctor
|
|
146
|
+
npx audrey status
|
|
147
|
+
npx audrey dream
|
|
148
|
+
npx audrey reembed
|
|
549
149
|
|
|
550
|
-
|
|
150
|
+
# Versioning
|
|
151
|
+
npx audrey snapshot
|
|
152
|
+
npx audrey restore backup.json --force
|
|
551
153
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
154
|
+
# Sidecar
|
|
155
|
+
npx audrey serve
|
|
156
|
+
docker compose up -d --build
|
|
555
157
|
```
|
|
556
158
|
|
|
557
|
-
|
|
159
|
+
## Benchmarks
|
|
558
160
|
|
|
559
|
-
|
|
161
|
+
Audrey ships with a benchmark harness and release gate:
|
|
560
162
|
|
|
561
|
-
```
|
|
562
|
-
|
|
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
|
-
|
|
168
|
+
The benchmark suite measures:
|
|
573
169
|
|
|
574
|
-
|
|
170
|
+
- retrieval behavior
|
|
171
|
+
- update and overwrite behavior
|
|
172
|
+
- delete and abstain behavior
|
|
173
|
+
- semantic and procedural merge behavior
|
|
575
174
|
|
|
576
|
-
|
|
175
|
+
Current repo snapshot:
|
|
577
176
|
|
|
578
|
-
|
|
177
|
+

|
|
579
178
|
|
|
580
|
-
|
|
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
|
-
|
|
181
|
+
## Production
|
|
586
182
|
|
|
587
|
-
|
|
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
|
-
|
|
185
|
+
Production guide: [docs/production-readiness.md](docs/production-readiness.md)
|
|
604
186
|
|
|
605
|
-
|
|
187
|
+
Examples:
|
|
606
188
|
|
|
607
|
-
|
|
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
|
-
|
|
197
|
+
- [.env.example](.env.example)
|
|
198
|
+
- [.env.docker.example](.env.docker.example)
|
|
647
199
|
|
|
648
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
210
|
+
## Documentation
|
|
665
211
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
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
|
-
##
|
|
217
|
+
## Development
|
|
672
218
|
|
|
673
219
|
```bash
|
|
674
|
-
|
|
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).
|