audrey 0.5.0 → 0.5.1
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/README.md +8 -3
- package/mcp-server/config.js +1 -1
- package/mcp-server/index.js +1 -1
- package/package.json +1 -1
- package/src/audrey.js +17 -2
- package/src/db.js +17 -7
- package/src/index.js +1 -0
- package/src/migrate.js +32 -0
package/README.md
CHANGED
|
@@ -398,6 +398,7 @@ brain.on('contradiction', ({ episodeId, contradictionId, semanticId, resolution
|
|
|
398
398
|
brain.on('consolidation', ({ runId, principlesExtracted }) => { ... });
|
|
399
399
|
brain.on('decay', ({ totalEvaluated, transitionedToDormant }) => { ... });
|
|
400
400
|
brain.on('rollback', ({ runId, rolledBackMemories }) => { ... });
|
|
401
|
+
brain.on('migration', ({ episodes, semantics, procedures }) => { ... });
|
|
401
402
|
brain.on('error', (err) => { ... });
|
|
402
403
|
```
|
|
403
404
|
|
|
@@ -429,10 +430,14 @@ src/
|
|
|
429
430
|
rollback.js Undo consolidation runs.
|
|
430
431
|
utils.js Date math, safe JSON parse.
|
|
431
432
|
validate.js KNN validation + LLM contradiction detection.
|
|
433
|
+
migrate.js Dimension migration re-embedding.
|
|
434
|
+
adaptive.js Adaptive consolidation parameter suggestions.
|
|
435
|
+
export.js Memory export (JSON snapshots).
|
|
436
|
+
import.js Memory import with re-embedding.
|
|
432
437
|
index.js Barrel export.
|
|
433
438
|
|
|
434
439
|
mcp-server/
|
|
435
|
-
index.js MCP tool server (
|
|
440
|
+
index.js MCP tool server (7 tools, stdio transport) + CLI subcommands.
|
|
436
441
|
config.js Shared config (env var parsing, install arg builder).
|
|
437
442
|
```
|
|
438
443
|
|
|
@@ -456,7 +461,7 @@ All mutations use SQLite transactions. CHECK constraints enforce valid states an
|
|
|
456
461
|
## Running Tests
|
|
457
462
|
|
|
458
463
|
```bash
|
|
459
|
-
npm test #
|
|
464
|
+
npm test # 243 tests across 22 files
|
|
460
465
|
npm run test:watch
|
|
461
466
|
```
|
|
462
467
|
|
|
@@ -544,7 +549,7 @@ Demonstrates the full pipeline: encode 3 rate-limit observations → consolidate
|
|
|
544
549
|
- [x] Auto-consolidation scheduling (`startAutoConsolidate` / `stopAutoConsolidate`)
|
|
545
550
|
- [x] Consolidation metrics tracking (per-run params and results)
|
|
546
551
|
- [x] Adaptive consolidation parameter suggestions based on historical yield
|
|
547
|
-
- [x]
|
|
552
|
+
- [x] 243 tests across 22 test files
|
|
548
553
|
|
|
549
554
|
### v0.4.0 — Type Safety & Developer Experience
|
|
550
555
|
|
package/mcp-server/config.js
CHANGED
package/mcp-server/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "audrey",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Biological memory architecture for AI agents — encode, consolidate, and recall memories with confidence decay, contradiction detection, and causal graphs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/audrey.js
CHANGED
|
@@ -13,6 +13,7 @@ import { buildContextResolutionPrompt } from './prompts.js';
|
|
|
13
13
|
import { exportMemories } from './export.js';
|
|
14
14
|
import { importMemories } from './import.js';
|
|
15
15
|
import { suggestConsolidationParams as suggestParamsFn } from './adaptive.js';
|
|
16
|
+
import { reembedAll } from './migrate.js';
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* @typedef {'direct-observation' | 'told-by-user' | 'tool-result' | 'inference' | 'model-generated'} SourceType
|
|
@@ -99,7 +100,9 @@ export class Audrey extends EventEmitter {
|
|
|
99
100
|
this.agent = agent;
|
|
100
101
|
this.dataDir = dataDir;
|
|
101
102
|
this.embeddingProvider = createEmbeddingProvider(embedding);
|
|
102
|
-
|
|
103
|
+
const { db, migrated } = createDatabase(dataDir, { dimensions: this.embeddingProvider.dimensions });
|
|
104
|
+
this.db = db;
|
|
105
|
+
this._migrationPending = migrated;
|
|
103
106
|
this.llmProvider = llm ? createLLMProvider(llm) : null;
|
|
104
107
|
this.confidenceConfig = {
|
|
105
108
|
weights: confidence.weights,
|
|
@@ -113,6 +116,13 @@ export class Audrey extends EventEmitter {
|
|
|
113
116
|
this._autoConsolidateTimer = null;
|
|
114
117
|
}
|
|
115
118
|
|
|
119
|
+
async _ensureMigrated() {
|
|
120
|
+
if (!this._migrationPending) return;
|
|
121
|
+
const counts = await reembedAll(this.db, this.embeddingProvider);
|
|
122
|
+
this._migrationPending = false;
|
|
123
|
+
this.emit('migration', counts);
|
|
124
|
+
}
|
|
125
|
+
|
|
116
126
|
_emitValidation(id, params) {
|
|
117
127
|
validateMemory(this.db, this.embeddingProvider, { id, ...params }, {
|
|
118
128
|
llmProvider: this.llmProvider,
|
|
@@ -142,6 +152,7 @@ export class Audrey extends EventEmitter {
|
|
|
142
152
|
* @returns {Promise<string>}
|
|
143
153
|
*/
|
|
144
154
|
async encode(params) {
|
|
155
|
+
await this._ensureMigrated();
|
|
145
156
|
const id = await encodeEpisode(this.db, this.embeddingProvider, params);
|
|
146
157
|
this.emit('encode', { id, ...params });
|
|
147
158
|
this._emitValidation(id, params);
|
|
@@ -153,6 +164,7 @@ export class Audrey extends EventEmitter {
|
|
|
153
164
|
* @returns {Promise<string[]>}
|
|
154
165
|
*/
|
|
155
166
|
async encodeBatch(paramsList) {
|
|
167
|
+
await this._ensureMigrated();
|
|
156
168
|
const ids = [];
|
|
157
169
|
for (const params of paramsList) {
|
|
158
170
|
const id = await encodeEpisode(this.db, this.embeddingProvider, params);
|
|
@@ -172,7 +184,8 @@ export class Audrey extends EventEmitter {
|
|
|
172
184
|
* @param {RecallOptions} [options]
|
|
173
185
|
* @returns {Promise<RecallResult[]>}
|
|
174
186
|
*/
|
|
175
|
-
recall(query, options = {}) {
|
|
187
|
+
async recall(query, options = {}) {
|
|
188
|
+
await this._ensureMigrated();
|
|
176
189
|
return recallFn(this.db, this.embeddingProvider, query, {
|
|
177
190
|
...options,
|
|
178
191
|
confidenceConfig: options.confidenceConfig ?? this.confidenceConfig,
|
|
@@ -185,6 +198,7 @@ export class Audrey extends EventEmitter {
|
|
|
185
198
|
* @returns {AsyncGenerator<RecallResult>}
|
|
186
199
|
*/
|
|
187
200
|
async *recallStream(query, options = {}) {
|
|
201
|
+
await this._ensureMigrated();
|
|
188
202
|
yield* recallStreamFn(this.db, this.embeddingProvider, query, {
|
|
189
203
|
...options,
|
|
190
204
|
confidenceConfig: options.confidenceConfig ?? this.confidenceConfig,
|
|
@@ -196,6 +210,7 @@ export class Audrey extends EventEmitter {
|
|
|
196
210
|
* @returns {Promise<ConsolidationResult>}
|
|
197
211
|
*/
|
|
198
212
|
async consolidate(options = {}) {
|
|
213
|
+
await this._ensureMigrated();
|
|
199
214
|
const result = await runConsolidation(this.db, this.embeddingProvider, {
|
|
200
215
|
minClusterSize: options.minClusterSize || this.consolidationConfig.minEpisodes,
|
|
201
216
|
similarityThreshold: options.similarityThreshold || 0.80,
|
package/src/db.js
CHANGED
|
@@ -150,6 +150,12 @@ function createVec0Tables(db, dimensions) {
|
|
|
150
150
|
`);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
function dropVec0Tables(db) {
|
|
154
|
+
db.exec('DROP TABLE IF EXISTS vec_episodes');
|
|
155
|
+
db.exec('DROP TABLE IF EXISTS vec_semantics');
|
|
156
|
+
db.exec('DROP TABLE IF EXISTS vec_procedures');
|
|
157
|
+
}
|
|
158
|
+
|
|
153
159
|
function migrateTable(db, { source, target, selectCols, insertCols, placeholders, transform }) {
|
|
154
160
|
const count = db.prepare(`SELECT COUNT(*) as c FROM ${target}`).get().c;
|
|
155
161
|
if (count > 0) return;
|
|
@@ -198,10 +204,11 @@ function migrateEmbeddingsToVec0(db) {
|
|
|
198
204
|
/**
|
|
199
205
|
* @param {string} dataDir
|
|
200
206
|
* @param {{ dimensions?: number }} [options]
|
|
201
|
-
* @returns {import('better-sqlite3').Database}
|
|
207
|
+
* @returns {{ db: import('better-sqlite3').Database, migrated: boolean }}
|
|
202
208
|
*/
|
|
203
209
|
export function createDatabase(dataDir, options = {}) {
|
|
204
210
|
const { dimensions } = options;
|
|
211
|
+
let migrated = false;
|
|
205
212
|
|
|
206
213
|
mkdirSync(dataDir, { recursive: true });
|
|
207
214
|
const dbPath = join(dataDir, 'audrey.db');
|
|
@@ -225,10 +232,11 @@ export function createDatabase(dataDir, options = {}) {
|
|
|
225
232
|
if (existing) {
|
|
226
233
|
const storedDims = parseInt(existing.value, 10);
|
|
227
234
|
if (storedDims !== dimensions) {
|
|
228
|
-
db
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
);
|
|
235
|
+
dropVec0Tables(db);
|
|
236
|
+
db.prepare(
|
|
237
|
+
"UPDATE audrey_config SET value = ? WHERE key = 'dimensions'"
|
|
238
|
+
).run(String(dimensions));
|
|
239
|
+
migrated = true;
|
|
232
240
|
}
|
|
233
241
|
} else {
|
|
234
242
|
db.prepare(
|
|
@@ -238,10 +246,12 @@ export function createDatabase(dataDir, options = {}) {
|
|
|
238
246
|
|
|
239
247
|
createVec0Tables(db, dimensions);
|
|
240
248
|
|
|
241
|
-
|
|
249
|
+
if (!migrated) {
|
|
250
|
+
migrateEmbeddingsToVec0(db);
|
|
251
|
+
}
|
|
242
252
|
}
|
|
243
253
|
|
|
244
|
-
return db;
|
|
254
|
+
return { db, migrated };
|
|
245
255
|
}
|
|
246
256
|
|
|
247
257
|
export function readStoredDimensions(dataDir) {
|
package/src/index.js
CHANGED
package/src/migrate.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export async function reembedAll(db, embeddingProvider) {
|
|
2
|
+
const episodes = db.prepare('SELECT id, content, source FROM episodes').all();
|
|
3
|
+
const semantics = db.prepare('SELECT id, content, state FROM semantics').all();
|
|
4
|
+
const procedures = db.prepare('SELECT id, content, state FROM procedures').all();
|
|
5
|
+
|
|
6
|
+
for (const ep of episodes) {
|
|
7
|
+
const vector = await embeddingProvider.embed(ep.content);
|
|
8
|
+
const buffer = embeddingProvider.vectorToBuffer(vector);
|
|
9
|
+
db.prepare('UPDATE episodes SET embedding = ? WHERE id = ?').run(buffer, ep.id);
|
|
10
|
+
db.prepare('INSERT INTO vec_episodes(id, embedding, source, consolidated) VALUES (?, ?, ?, ?)').run(ep.id, buffer, ep.source, BigInt(0));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
for (const sem of semantics) {
|
|
14
|
+
const vector = await embeddingProvider.embed(sem.content);
|
|
15
|
+
const buffer = embeddingProvider.vectorToBuffer(vector);
|
|
16
|
+
db.prepare('UPDATE semantics SET embedding = ? WHERE id = ?').run(buffer, sem.id);
|
|
17
|
+
db.prepare('INSERT INTO vec_semantics(id, embedding, state) VALUES (?, ?, ?)').run(sem.id, buffer, sem.state);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for (const proc of procedures) {
|
|
21
|
+
const vector = await embeddingProvider.embed(proc.content);
|
|
22
|
+
const buffer = embeddingProvider.vectorToBuffer(vector);
|
|
23
|
+
db.prepare('UPDATE procedures SET embedding = ? WHERE id = ?').run(buffer, proc.id);
|
|
24
|
+
db.prepare('INSERT INTO vec_procedures(id, embedding, state) VALUES (?, ?, ?)').run(proc.id, buffer, proc.state);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
episodes: episodes.length,
|
|
29
|
+
semantics: semantics.length,
|
|
30
|
+
procedures: procedures.length,
|
|
31
|
+
};
|
|
32
|
+
}
|