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
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { generateId } from './ulid.js';
|
|
2
|
+
import { safeJsonParse } from './utils.js';
|
|
3
|
+
import { buildContradictionDetectionPrompt } from './prompts.js';
|
|
4
|
+
const REINFORCEMENT_THRESHOLD = 0.85;
|
|
5
|
+
const CONTRADICTION_THRESHOLD = 0.60;
|
|
6
|
+
export async function validateMemory(db, embeddingProvider, episode, options = {}) {
|
|
7
|
+
const { threshold = REINFORCEMENT_THRESHOLD, contradictionThreshold = CONTRADICTION_THRESHOLD, llmProvider, } = options;
|
|
8
|
+
const episodeVector = await embeddingProvider.embed(episode.content);
|
|
9
|
+
const episodeBuffer = embeddingProvider.vectorToBuffer(episodeVector);
|
|
10
|
+
const nearestSemantic = db.prepare(`
|
|
11
|
+
SELECT s.*, (1.0 - v.distance) AS similarity
|
|
12
|
+
FROM vec_semantics v
|
|
13
|
+
JOIN semantics s ON s.id = v.id
|
|
14
|
+
WHERE v.embedding MATCH ?
|
|
15
|
+
AND k = 1
|
|
16
|
+
AND (v.state = 'active' OR v.state = 'context_dependent')
|
|
17
|
+
`).get(episodeBuffer);
|
|
18
|
+
let bestMatch = null;
|
|
19
|
+
let bestSimilarity = 0;
|
|
20
|
+
if (nearestSemantic) {
|
|
21
|
+
bestMatch = nearestSemantic;
|
|
22
|
+
bestSimilarity = nearestSemantic.similarity;
|
|
23
|
+
}
|
|
24
|
+
if (bestMatch && bestSimilarity >= threshold) {
|
|
25
|
+
const evidenceIds = safeJsonParse(bestMatch.evidence_episode_ids, []);
|
|
26
|
+
if (!evidenceIds.includes(episode.id)) {
|
|
27
|
+
evidenceIds.push(episode.id);
|
|
28
|
+
}
|
|
29
|
+
const diversity = computeSourceDiversity(db, evidenceIds, episode);
|
|
30
|
+
const now = new Date().toISOString();
|
|
31
|
+
db.prepare(`
|
|
32
|
+
UPDATE semantics SET
|
|
33
|
+
supporting_count = supporting_count + 1,
|
|
34
|
+
evidence_episode_ids = ?,
|
|
35
|
+
evidence_count = ?,
|
|
36
|
+
source_type_diversity = ?,
|
|
37
|
+
last_reinforced_at = ?
|
|
38
|
+
WHERE id = ?
|
|
39
|
+
`).run(JSON.stringify(evidenceIds), evidenceIds.length, diversity, now, bestMatch.id);
|
|
40
|
+
return {
|
|
41
|
+
action: 'reinforced',
|
|
42
|
+
semanticId: bestMatch.id,
|
|
43
|
+
similarity: bestSimilarity,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (bestMatch && bestSimilarity >= contradictionThreshold && llmProvider) {
|
|
47
|
+
const messages = buildContradictionDetectionPrompt(episode.content, bestMatch.content);
|
|
48
|
+
const verdict = await llmProvider.json(messages);
|
|
49
|
+
if (verdict.contradicts) {
|
|
50
|
+
const resolution = verdict.resolution === 'context_dependent'
|
|
51
|
+
? { type: 'context_dependent', conditions: verdict.conditions, explanation: verdict.explanation }
|
|
52
|
+
: verdict.resolution
|
|
53
|
+
? { type: verdict.resolution, explanation: verdict.explanation }
|
|
54
|
+
: null;
|
|
55
|
+
const contradictionId = createContradiction(db, bestMatch.id, 'semantic', episode.id, 'episodic', resolution);
|
|
56
|
+
if (verdict.resolution === 'new_wins') {
|
|
57
|
+
db.prepare("UPDATE semantics SET state = 'disputed' WHERE id = ?").run(bestMatch.id);
|
|
58
|
+
}
|
|
59
|
+
else if (verdict.resolution === 'context_dependent' && verdict.conditions) {
|
|
60
|
+
db.prepare("UPDATE semantics SET state = 'context_dependent', conditions = ? WHERE id = ?")
|
|
61
|
+
.run(JSON.stringify(verdict.conditions), bestMatch.id);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
action: 'contradiction',
|
|
65
|
+
contradictionId,
|
|
66
|
+
semanticId: bestMatch.id,
|
|
67
|
+
similarity: bestSimilarity,
|
|
68
|
+
resolution: verdict.resolution || null,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { action: 'none' };
|
|
73
|
+
}
|
|
74
|
+
function computeSourceDiversity(db, evidenceIds, currentEpisode) {
|
|
75
|
+
const sourceTypes = new Set();
|
|
76
|
+
sourceTypes.add(currentEpisode.source);
|
|
77
|
+
if (evidenceIds.length > 0) {
|
|
78
|
+
const placeholders = evidenceIds.map(() => '?').join(',');
|
|
79
|
+
const rows = db.prepare(`SELECT DISTINCT source FROM episodes WHERE id IN (${placeholders})`).all(...evidenceIds);
|
|
80
|
+
for (const row of rows) {
|
|
81
|
+
sourceTypes.add(row.source);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return sourceTypes.size;
|
|
85
|
+
}
|
|
86
|
+
export function createContradiction(db, claimAId, claimAType, claimBId, claimBType, resolution) {
|
|
87
|
+
const id = generateId();
|
|
88
|
+
const now = new Date().toISOString();
|
|
89
|
+
const state = resolution ? 'resolved' : 'open';
|
|
90
|
+
const resolvedAt = resolution ? now : null;
|
|
91
|
+
const resolutionJson = resolution ? JSON.stringify(resolution) : null;
|
|
92
|
+
db.prepare(`
|
|
93
|
+
INSERT INTO contradictions (id, claim_a_id, claim_a_type, claim_b_id, claim_b_type,
|
|
94
|
+
state, resolution, resolved_at, created_at)
|
|
95
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
96
|
+
`).run(id, claimAId, claimAType, claimBId, claimBType, state, resolutionJson, resolvedAt, now);
|
|
97
|
+
return id;
|
|
98
|
+
}
|
|
99
|
+
export function reopenContradiction(db, contradictionId, newEvidenceId) {
|
|
100
|
+
const now = new Date().toISOString();
|
|
101
|
+
db.prepare(`
|
|
102
|
+
UPDATE contradictions SET
|
|
103
|
+
state = 'reopened',
|
|
104
|
+
reopen_evidence_id = ?,
|
|
105
|
+
reopened_at = ?
|
|
106
|
+
WHERE id = ?
|
|
107
|
+
`).run(newEvidenceId, now, contradictionId);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Audrey vs Local Memory Baselines">
|
|
3
|
+
<rect width="100%" height="100%" fill="white" />
|
|
4
|
+
<text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Audrey vs Local Memory Baselines</text>
|
|
5
|
+
|
|
6
|
+
<line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
7
|
+
<text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
11
|
+
<text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
15
|
+
<text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
19
|
+
<text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
23
|
+
<text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
<rect x="64" y="56" width="198" height="276" rx="8" fill="#0f766e" />
|
|
27
|
+
<text x="163" y="46" text-anchor="middle" font-size="15" fill="#111827">100.0%</text>
|
|
28
|
+
<text x="163" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Audrey</text>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
<rect x="286" y="217" width="198" height="115.00000000000001" rx="8" fill="#0369a1" />
|
|
32
|
+
<text x="385" y="207" text-anchor="middle" font-size="15" fill="#111827">41.7%</text>
|
|
33
|
+
<text x="385" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Vector Only</text>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
<rect x="508" y="217" width="198" height="115.00000000000001" rx="8" fill="#6d28d9" />
|
|
37
|
+
<text x="607" y="207" text-anchor="middle" font-size="15" fill="#111827">41.7%</text>
|
|
38
|
+
<text x="607" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Keyword + Recency</text>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<rect x="730" y="228.5" width="198" height="103.5" rx="8" fill="#b45309" />
|
|
42
|
+
<text x="829" y="218.5" text-anchor="middle" font-size="15" fill="#111827">37.5%</text>
|
|
43
|
+
<text x="829" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Recent Window</text>
|
|
44
|
+
|
|
45
|
+
</svg>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Audrey Memory Operations Benchmark">
|
|
3
|
+
<rect width="100%" height="100%" fill="white" />
|
|
4
|
+
<text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Audrey Memory Operations Benchmark</text>
|
|
5
|
+
|
|
6
|
+
<line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
7
|
+
<text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
11
|
+
<text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
15
|
+
<text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
19
|
+
<text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
23
|
+
<text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
<rect x="64" y="56" width="198" height="276" rx="8" fill="#0f766e" />
|
|
27
|
+
<text x="163" y="46" text-anchor="middle" font-size="15" fill="#111827">100.0%</text>
|
|
28
|
+
<text x="163" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Audrey</text>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
<rect x="286" y="263" width="198" height="69" rx="8" fill="#6d28d9" />
|
|
32
|
+
<text x="385" y="253" text-anchor="middle" font-size="15" fill="#111827">25.0%</text>
|
|
33
|
+
<text x="385" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Keyword + Recency</text>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
<rect x="508" y="297.5" width="198" height="34.5" rx="8" fill="#0369a1" />
|
|
37
|
+
<text x="607" y="287.5" text-anchor="middle" font-size="15" fill="#111827">12.5%</text>
|
|
38
|
+
<text x="607" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Vector Only</text>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<rect x="730" y="297.5" width="198" height="34.5" rx="8" fill="#b45309" />
|
|
42
|
+
<text x="829" y="287.5" text-anchor="middle" font-size="15" fill="#111827">12.5%</text>
|
|
43
|
+
<text x="829" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Recent Window</text>
|
|
44
|
+
|
|
45
|
+
</svg>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Published LLM Memory Standards (LoCoMo)">
|
|
3
|
+
<rect width="100%" height="100%" fill="white" />
|
|
4
|
+
<text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Published LLM Memory Standards (LoCoMo)</text>
|
|
5
|
+
|
|
6
|
+
<line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
7
|
+
<text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
11
|
+
<text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
<line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
15
|
+
<text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
<line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
19
|
+
<text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
<line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
|
|
23
|
+
<text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
<rect x="64" y="96.29599999999996" width="154" height="235.70400000000004" rx="8" fill="#1d4ed8" />
|
|
27
|
+
<text x="141" y="86.29599999999996" text-anchor="middle" font-size="15" fill="#111827">85.4%</text>
|
|
28
|
+
<text x="141" y="378" text-anchor="middle" font-size="14" fill="#6b7280">MIRIX</text>
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
<rect x="241.5" y="127.75999999999999" width="154" height="204.24" rx="8" fill="#1d4ed8" />
|
|
32
|
+
<text x="318.5" y="117.75999999999999" text-anchor="middle" font-size="15" fill="#111827">74.0%</text>
|
|
33
|
+
<text x="318.5" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Letta Filesystem</text>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
<rect x="419" y="142.94" width="154" height="189.06" rx="8" fill="#1d4ed8" />
|
|
37
|
+
<text x="496" y="132.94" text-anchor="middle" font-size="15" fill="#111827">68.5%</text>
|
|
38
|
+
<text x="496" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Mem0 Graph Memory</text>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
<rect x="596.5" y="147.356" width="154" height="184.644" rx="8" fill="#1d4ed8" />
|
|
42
|
+
<text x="673.5" y="137.356" text-anchor="middle" font-size="15" fill="#111827">66.9%</text>
|
|
43
|
+
<text x="673.5" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Mem0</text>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<rect x="774" y="185.99599999999998" width="154" height="146.00400000000002" rx="8" fill="#1d4ed8" />
|
|
47
|
+
<text x="851" y="175.99599999999998" text-anchor="middle" font-size="15" fill="#111827">52.9%</text>
|
|
48
|
+
<text x="851" y="378" text-anchor="middle" font-size="14" fill="#6b7280">OpenAI Memory</text>
|
|
49
|
+
|
|
50
|
+
</svg>
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Benchmarking Audrey
|
|
2
|
+
|
|
3
|
+
Audrey now ships with a memory benchmark harness that does three different jobs:
|
|
4
|
+
|
|
5
|
+
1. It runs Audrey against a local retrieval suite inspired by LongMemEval, plus privacy and abstention checks that matter in production.
|
|
6
|
+
2. It runs Audrey against an operation-level suite for update, overwrite, delete, merge, and abstain behavior.
|
|
7
|
+
3. It overlays published leaderboard numbers from leading memory systems on LoCoMo so you can place Audrey in the current market and research landscape without pretending the measurements are identical.
|
|
8
|
+
|
|
9
|
+
That split is deliberate. A lot of memory tooling mixes internal demos with external benchmark claims. Audrey should not do that.
|
|
10
|
+
|
|
11
|
+
## Run It
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run bench:memory
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The package script is the intended operator entrypoint:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm run bench:memory
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Artifacts are written to `benchmarks/output/`:
|
|
24
|
+
|
|
25
|
+
- `summary.json`
|
|
26
|
+
- `report.html`
|
|
27
|
+
- `local-overall.svg`
|
|
28
|
+
- `retrieval-overall.svg`
|
|
29
|
+
- `operations-overall.svg`
|
|
30
|
+
- `published-locomo.svg`
|
|
31
|
+
|
|
32
|
+
For CI, JSON-only output is available:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run bench:memory:json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For regression gating, use:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm run bench:memory:check
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
That command fails if Audrey falls below its minimum local score, pass rate, or required lead over the strongest naive baseline.
|
|
45
|
+
|
|
46
|
+
To refresh the committed SVGs used in the README:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run bench:memory:readme-assets
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
That writes stable chart assets to `docs/assets/benchmarks/` so the GitHub repo surface shows the same benchmark posture as the generated report.
|
|
53
|
+
|
|
54
|
+
To run a single local track:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npm run bench:memory:retrieval
|
|
58
|
+
npm run bench:memory:operations
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## What The Local Retrieval Benchmark Measures
|
|
62
|
+
|
|
63
|
+
The retrieval suite covers eight memory families:
|
|
64
|
+
|
|
65
|
+
- `information_extraction`
|
|
66
|
+
- `knowledge_updates`
|
|
67
|
+
- `multi_session_reasoning`
|
|
68
|
+
- `temporal_reasoning`
|
|
69
|
+
- `abstention`
|
|
70
|
+
- `conflict_resolution`
|
|
71
|
+
- `procedural_learning`
|
|
72
|
+
- `privacy_boundary`
|
|
73
|
+
|
|
74
|
+
This is intentionally closer to how operators evaluate memory in production than a single retrieval-accuracy number. Audrey should not only retrieve facts. It should:
|
|
75
|
+
|
|
76
|
+
- prefer fresh state over stale state
|
|
77
|
+
- avoid leaking private memory
|
|
78
|
+
- consolidate repeated episodes into reusable procedures
|
|
79
|
+
- handle conflict without amplifying low-reliability noise
|
|
80
|
+
|
|
81
|
+
## What The Local Operations Benchmark Measures
|
|
82
|
+
|
|
83
|
+
The operations suite covers four lifecycle families:
|
|
84
|
+
|
|
85
|
+
- `update_overwrite`
|
|
86
|
+
- `delete_and_abstain`
|
|
87
|
+
- `semantic_merge`
|
|
88
|
+
- `procedural_merge`
|
|
89
|
+
|
|
90
|
+
This suite exists because leading memory systems are often compared on offline recall, while real agent memory succeeds or fails on memory operations:
|
|
91
|
+
|
|
92
|
+
- can a newer fact overwrite stale state without leaking both
|
|
93
|
+
- can a delete actually prevent future recall
|
|
94
|
+
- can repeated raw events merge into reusable semantic knowledge
|
|
95
|
+
- can repeated events merge into an actionable procedure instead of another inert blob of text
|
|
96
|
+
|
|
97
|
+
Those are not implementation details. They are the actual product surface of memory.
|
|
98
|
+
|
|
99
|
+
## What The Published Leaderboard Means
|
|
100
|
+
|
|
101
|
+
The LoCoMo chart in the generated report is a research context layer, not a claim that Audrey has already reproduced those exact scores.
|
|
102
|
+
|
|
103
|
+
Current published anchors included in the report:
|
|
104
|
+
|
|
105
|
+
- MIRIX: LoCoMo `85.4` from the MIRIX paper
|
|
106
|
+
- Letta Filesystem: LoCoMo `74.0` from Letta's benchmark write-up
|
|
107
|
+
- Mem0 Graph Memory: LoCoMo `68.5` from the Mem0 paper
|
|
108
|
+
- Mem0: LoCoMo `66.9` from the Mem0 paper
|
|
109
|
+
- OpenAI Memory baseline: LoCoMo `52.9` as reported in the Mem0 paper
|
|
110
|
+
|
|
111
|
+
Use this chart to answer: "Where is the frontier today?" not "Has Audrey already matched that exact benchmark protocol?"
|
|
112
|
+
|
|
113
|
+
## March 23, 2026 Research Readout
|
|
114
|
+
|
|
115
|
+
The most important memory trends right now:
|
|
116
|
+
|
|
117
|
+
1. Typed memory systems are replacing flat retrieval.
|
|
118
|
+
MemOS frames memory as an operating system concern with scheduling and memory-object abstractions, not just vector lookup.
|
|
119
|
+
|
|
120
|
+
2. Realistic long-horizon benchmarks are replacing toy recall tests.
|
|
121
|
+
LongMemEval emphasizes multi-session reasoning, temporal updates, abstraction, and knowledge revision.
|
|
122
|
+
|
|
123
|
+
3. Context engineering is now a first-class competitor to retrieval-only memory.
|
|
124
|
+
Letta's filesystem and memory-block work argues that editable context structure can outperform simpler retrieval-only designs.
|
|
125
|
+
|
|
126
|
+
4. Production memory is now judged on latency and token cost too.
|
|
127
|
+
Mem0 explicitly reports quality alongside lower token and latency overhead.
|
|
128
|
+
|
|
129
|
+
5. Temporal and multimodal memory are moving into the frontier.
|
|
130
|
+
MIRIX pushes beyond text-only episodic recall into typed multimodal memory with compression.
|
|
131
|
+
|
|
132
|
+
## What Audrey Should Do Next
|
|
133
|
+
|
|
134
|
+
The benchmark highlights the next credible roadmap for Audrey:
|
|
135
|
+
|
|
136
|
+
- first-party LoCoMo and LongMemEval adapters so Audrey can publish directly reproducible external benchmark numbers
|
|
137
|
+
- contradiction-state and truth-resolution benchmark cases, not just retrieval outcomes
|
|
138
|
+
- cost, latency, and storage curves against long-context baselines and simpler memory systems
|
|
139
|
+
- a typed memory graph layer for cross-memory state transitions and time-aware reasoning
|
|
140
|
+
|
|
141
|
+
## Source Links
|
|
142
|
+
|
|
143
|
+
- LongMemEval: [arXiv 2410.10813](https://arxiv.org/abs/2410.10813)
|
|
144
|
+
- Mem0: [arXiv 2504.19413](https://arxiv.org/abs/2504.19413)
|
|
145
|
+
- MIRIX: [arXiv 2507.07957](https://arxiv.org/abs/2507.07957)
|
|
146
|
+
- MemOS: [arXiv 2507.03724](https://arxiv.org/abs/2507.03724)
|
|
147
|
+
- MemGPT: [arXiv 2310.08560](https://arxiv.org/abs/2310.08560)
|
|
148
|
+
- Letta memory blocks: [Letta blog](https://www.letta.com/blog/memory-blocks)
|
|
149
|
+
- Letta benchmarking: [Letta benchmark write-up](https://www.letta.com/blog/benchmarking-ai-agent-memory)
|
|
150
|
+
- LoCoMo benchmark repo: [snap-research/locomo](https://github.com/snap-research/locomo)
|
|
151
|
+
- LongMemEval repo: [xiaowu0162/LongMemEval](https://github.com/xiaowu0162/LongMemEval)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Audrey Production Readiness
|
|
2
|
+
|
|
3
|
+
Audrey is ready to be the memory layer inside a production agent system, but it is not a complete regulated-platform package by itself. Treat it as stateful infrastructure: pin providers, isolate tenants, monitor health, and wrap it with the controls your environment requires.
|
|
4
|
+
|
|
5
|
+
First contact should now go through `npx audrey init sidecar-prod` for the sidecar path or `npx audrey init` for the default Claude Code path, then `npx audrey doctor` before exposing Audrey to real traffic.
|
|
6
|
+
|
|
7
|
+
## Best Vertical Fit
|
|
8
|
+
|
|
9
|
+
### 1. Financial Services Operations
|
|
10
|
+
|
|
11
|
+
Best fit:
|
|
12
|
+
|
|
13
|
+
- Payments operations copilots
|
|
14
|
+
- Fraud and dispute investigation agents
|
|
15
|
+
- KYC/KYB review assistants
|
|
16
|
+
- Internal support agents that need durable incident and policy memory
|
|
17
|
+
|
|
18
|
+
Why Audrey fits:
|
|
19
|
+
|
|
20
|
+
- Contradiction tracking helps surface conflicting customer, tool, and policy evidence.
|
|
21
|
+
- Confidence scoring and source lineage make escalations more reviewable.
|
|
22
|
+
- Local SQLite storage keeps memory close to the application boundary.
|
|
23
|
+
- Dream-cycle consolidation turns repeated incidents into reusable operational principles.
|
|
24
|
+
|
|
25
|
+
Guardrails:
|
|
26
|
+
|
|
27
|
+
- Do not store PAN, CVV, raw bank credentials, or secrets in memory.
|
|
28
|
+
- Isolate memory stores by environment, customer, and business unit.
|
|
29
|
+
- Keep export and purge paths in your incident-response runbook.
|
|
30
|
+
- Add encryption at rest and backup retention outside Audrey.
|
|
31
|
+
|
|
32
|
+
### 2. Healthcare Operations
|
|
33
|
+
|
|
34
|
+
Best fit:
|
|
35
|
+
|
|
36
|
+
- Care coordination assistants
|
|
37
|
+
- Prior-authorization workflow agents
|
|
38
|
+
- Intake, referral, and scheduling copilots
|
|
39
|
+
- Internal knowledge assistants for clinical operations teams
|
|
40
|
+
|
|
41
|
+
Why Audrey fits:
|
|
42
|
+
|
|
43
|
+
- Longitudinal recall preserves operational context across multi-step handoffs.
|
|
44
|
+
- Private memories support role-specific context without making it part of public recall.
|
|
45
|
+
- Contradiction detection helps catch conflicting workflow instructions and stale operating assumptions.
|
|
46
|
+
- Local embeddings allow offline-first or reduced-data-egress deployments.
|
|
47
|
+
|
|
48
|
+
Guardrails:
|
|
49
|
+
|
|
50
|
+
- Audrey is not a medical device and should not be treated as a clinical decision engine.
|
|
51
|
+
- Use de-identified or minimum-necessary data unless the full deployment boundary is HIPAA-ready.
|
|
52
|
+
- Enforce access controls and audit logging in the host application, not just in Audrey.
|
|
53
|
+
- Separate patient-facing and staff-only memory scopes.
|
|
54
|
+
|
|
55
|
+
## Production Checklist
|
|
56
|
+
|
|
57
|
+
1. Pin `AUDREY_EMBEDDING_PROVIDER` and `AUDREY_LLM_PROVIDER` explicitly. Do not rely on key-based auto-detection in production.
|
|
58
|
+
2. Set a dedicated `AUDREY_DATA_DIR` per environment and per tenant boundary.
|
|
59
|
+
3. Add a health check that runs `npx audrey status --json --fail-on-unhealthy`.
|
|
60
|
+
4. Alert on `health.healthy=false` or `health.reembed_recommended=true`.
|
|
61
|
+
5. Schedule `npx audrey dream` during low-traffic windows so consolidation and decay stay current.
|
|
62
|
+
6. Backup the SQLite data directory before changing embedding dimensions or providers.
|
|
63
|
+
7. Treat re-embedding as a controlled maintenance action and validate with `npx audrey status`.
|
|
64
|
+
8. Keep API keys, bearer tokens, and raw credentials out of encoded memory content.
|
|
65
|
+
9. Decide whether `private` memories are allowed for your use case and document who can create them.
|
|
66
|
+
10. Add application-level encryption, access control, logging, and retention policies around Audrey.
|
|
67
|
+
11. On graceful shutdown paths, call `await brain.waitForIdle()` before `brain.close()` so tracked background work drains cleanly.
|
|
68
|
+
|
|
69
|
+
## Operations Commands
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Human-readable health
|
|
73
|
+
npx audrey status
|
|
74
|
+
|
|
75
|
+
# Monitoring-friendly health
|
|
76
|
+
npx audrey status --json
|
|
77
|
+
|
|
78
|
+
# Fail the process if the index is unhealthy or unreadable
|
|
79
|
+
npx audrey status --json --fail-on-unhealthy
|
|
80
|
+
|
|
81
|
+
# Nightly memory maintenance
|
|
82
|
+
npx audrey dream
|
|
83
|
+
|
|
84
|
+
# Repair vector/index drift after provider or dimension changes
|
|
85
|
+
npx audrey reembed
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Example Deployment Pattern
|
|
89
|
+
|
|
90
|
+
Use Audrey as a local sidecar to the agent service:
|
|
91
|
+
|
|
92
|
+
- One Audrey data directory per tenant or deployment shard
|
|
93
|
+
- Health checks wired to `status --json`
|
|
94
|
+
- Scheduled dream/reembed jobs
|
|
95
|
+
- Backups handled by the host platform
|
|
96
|
+
- Regulated-data filtering handled before `memory_encode`
|
|
97
|
+
|
|
98
|
+
That keeps Audrey focused on memory integrity while the host system owns compliance, tenancy, and transport security.
|
|
99
|
+
|
|
100
|
+
## Docker Deployment
|
|
101
|
+
|
|
102
|
+
Audrey now ships with a first-party container path for the REST API:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npx audrey init sidecar-prod
|
|
106
|
+
docker compose up -d --build
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Operational notes:
|
|
110
|
+
|
|
111
|
+
- The container persists SQLite data in the named volume `audrey-data`.
|
|
112
|
+
- Set `AUDREY_API_KEY` before exposing the service beyond localhost.
|
|
113
|
+
- For CI or very fast smoke checks, prefer `AUDREY_EMBEDDING_PROVIDER=mock` and `AUDREY_LLM_PROVIDER=mock`.
|
|
114
|
+
- For stable local/offline container use, keep `AUDREY_EMBEDDING_PROVIDER=local` and `AUDREY_DEVICE=cpu`.
|
|
115
|
+
- If you map the service to a different host port, keep the container port at `3487`.
|
|
116
|
+
|
|
117
|
+
Suggested smoke check:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
AUDREY_API_KEY=secret docker compose up -d --build
|
|
121
|
+
curl -H "Authorization: Bearer secret" http://localhost:3487/health
|
|
122
|
+
curl -H "Authorization: Bearer secret" http://localhost:3487/status
|
|
123
|
+
docker compose logs --tail=100 audrey
|
|
124
|
+
```
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Audrey } from '../dist/src/index.js';
|
|
2
|
+
|
|
3
|
+
async function demo() {
|
|
4
|
+
console.log('=== Audrey Demo: Financial Services Operations ===\n');
|
|
5
|
+
|
|
6
|
+
const brain = new Audrey({
|
|
7
|
+
dataDir: './fintech-demo-data',
|
|
8
|
+
agent: 'payments-ops-agent',
|
|
9
|
+
embedding: { provider: 'mock', dimensions: 64 },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log('--- Encoding payment-operations incidents ---');
|
|
13
|
+
await brain.encode({
|
|
14
|
+
content: 'Processor X returned HTTP 429 when payout retries exceeded 120 requests per minute for marketplace merchants.',
|
|
15
|
+
source: 'direct-observation',
|
|
16
|
+
salience: 0.9,
|
|
17
|
+
tags: ['payments', 'payouts', 'rate-limit'],
|
|
18
|
+
context: { domain: 'finserv', workflow: 'payout-incident' },
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await brain.encode({
|
|
22
|
+
content: 'On-call notes show payout incident volume drops after retry batches are capped at 50 merchants per worker.',
|
|
23
|
+
source: 'tool-result',
|
|
24
|
+
salience: 0.8,
|
|
25
|
+
tags: ['payments', 'payouts', 'ops'],
|
|
26
|
+
context: { domain: 'finserv', workflow: 'payout-incident' },
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await brain.encode({
|
|
30
|
+
content: 'Risk operations requested automatic escalation when payout failures affect more than three merchants in the same hour.',
|
|
31
|
+
source: 'told-by-user',
|
|
32
|
+
salience: 0.7,
|
|
33
|
+
tags: ['payments', 'escalation', 'risk'],
|
|
34
|
+
context: { domain: 'finserv', workflow: 'payout-incident' },
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
console.log('\n--- Consolidating incidents into an ops principle ---');
|
|
38
|
+
await brain.consolidate({
|
|
39
|
+
minClusterSize: 3,
|
|
40
|
+
similarityThreshold: -0.3,
|
|
41
|
+
extractPrinciple: () => ({
|
|
42
|
+
content: 'When payout retries spike, cap retry batches and escalate once multiple merchants are affected in the same hour.',
|
|
43
|
+
type: 'procedural',
|
|
44
|
+
conditions: ['payout failures > 3 merchants per hour', 'processor returns 429 or throttling errors'],
|
|
45
|
+
}),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
console.log('\n--- Recalling during a live payout incident ---');
|
|
49
|
+
const recalled = await brain.recall('payout retries throttled by processor', {
|
|
50
|
+
limit: 5,
|
|
51
|
+
context: { domain: 'finserv', workflow: 'payout-incident' },
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
for (const memory of recalled) {
|
|
55
|
+
console.log(`[${memory.type}] ${memory.content}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
brain.close();
|
|
59
|
+
|
|
60
|
+
const { rmSync } = await import('node:fs');
|
|
61
|
+
rmSync('./fintech-demo-data', { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
demo().catch(err => {
|
|
65
|
+
console.error(err);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
});
|