audrey 0.17.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +129 -374
  2. package/dist/mcp-server/config.d.ts +20 -0
  3. package/dist/mcp-server/config.d.ts.map +1 -0
  4. package/dist/mcp-server/config.js +125 -0
  5. package/dist/mcp-server/config.js.map +1 -0
  6. package/dist/mcp-server/index.d.ts +100 -0
  7. package/dist/mcp-server/index.d.ts.map +1 -0
  8. package/dist/mcp-server/index.js +1113 -0
  9. package/dist/mcp-server/index.js.map +1 -0
  10. package/dist/src/adaptive.d.ts +7 -0
  11. package/dist/src/adaptive.d.ts.map +1 -0
  12. package/dist/src/adaptive.js +49 -0
  13. package/dist/src/adaptive.js.map +1 -0
  14. package/dist/src/affect.d.ts +19 -0
  15. package/dist/src/affect.d.ts.map +1 -0
  16. package/dist/src/affect.js +72 -0
  17. package/dist/src/affect.js.map +1 -0
  18. package/dist/src/audrey.d.ts +140 -0
  19. package/dist/src/audrey.d.ts.map +1 -0
  20. package/dist/src/audrey.js +564 -0
  21. package/dist/src/audrey.js.map +1 -0
  22. package/dist/src/capsule.d.ts +68 -0
  23. package/dist/src/capsule.d.ts.map +1 -0
  24. package/dist/src/capsule.js +311 -0
  25. package/dist/src/capsule.js.map +1 -0
  26. package/dist/src/causal.d.ts +28 -0
  27. package/dist/src/causal.d.ts.map +1 -0
  28. package/dist/src/causal.js +65 -0
  29. package/dist/src/causal.js.map +1 -0
  30. package/dist/src/confidence.d.ts +12 -0
  31. package/dist/src/confidence.d.ts.map +1 -0
  32. package/dist/src/confidence.js +63 -0
  33. package/dist/src/confidence.js.map +1 -0
  34. package/dist/src/consolidate.d.ts +8 -0
  35. package/dist/src/consolidate.d.ts.map +1 -0
  36. package/dist/src/consolidate.js +218 -0
  37. package/dist/src/consolidate.js.map +1 -0
  38. package/dist/src/context.d.ts +3 -0
  39. package/dist/src/context.d.ts.map +1 -0
  40. package/dist/src/context.js +19 -0
  41. package/dist/src/context.js.map +1 -0
  42. package/dist/src/db.d.ts +12 -0
  43. package/dist/src/db.d.ts.map +1 -0
  44. package/dist/src/db.js +380 -0
  45. package/dist/src/db.js.map +1 -0
  46. package/dist/src/decay.d.ts +7 -0
  47. package/dist/src/decay.d.ts.map +1 -0
  48. package/dist/src/decay.js +68 -0
  49. package/dist/src/decay.js.map +1 -0
  50. package/dist/src/embedding.d.ts +57 -0
  51. package/dist/src/embedding.d.ts.map +1 -0
  52. package/dist/src/embedding.js +254 -0
  53. package/dist/src/embedding.js.map +1 -0
  54. package/dist/src/encode.d.ts +15 -0
  55. package/dist/src/encode.d.ts.map +1 -0
  56. package/dist/src/encode.js +36 -0
  57. package/dist/src/encode.js.map +1 -0
  58. package/dist/src/events.d.ts +69 -0
  59. package/dist/src/events.d.ts.map +1 -0
  60. package/dist/src/events.js +149 -0
  61. package/dist/src/events.js.map +1 -0
  62. package/dist/src/export.d.ts +3 -0
  63. package/dist/src/export.d.ts.map +1 -0
  64. package/dist/src/export.js +46 -0
  65. package/dist/src/export.js.map +1 -0
  66. package/dist/src/forget.d.ts +11 -0
  67. package/dist/src/forget.d.ts.map +1 -0
  68. package/dist/src/forget.js +105 -0
  69. package/dist/src/forget.js.map +1 -0
  70. package/dist/src/fts.d.ts +34 -0
  71. package/dist/src/fts.d.ts.map +1 -0
  72. package/dist/src/fts.js +117 -0
  73. package/dist/src/fts.js.map +1 -0
  74. package/dist/src/hybrid-recall.d.ts +37 -0
  75. package/dist/src/hybrid-recall.d.ts.map +1 -0
  76. package/dist/src/hybrid-recall.js +213 -0
  77. package/dist/src/hybrid-recall.js.map +1 -0
  78. package/dist/src/import.d.ts +4 -0
  79. package/dist/src/import.d.ts.map +1 -0
  80. package/dist/src/import.js +127 -0
  81. package/dist/src/import.js.map +1 -0
  82. package/dist/src/index.d.ts +22 -0
  83. package/dist/src/index.d.ts.map +1 -0
  84. package/{src → dist/src}/index.js +5 -13
  85. package/dist/src/index.js.map +1 -0
  86. package/dist/src/interference.d.ts +13 -0
  87. package/dist/src/interference.d.ts.map +1 -0
  88. package/dist/src/interference.js +45 -0
  89. package/dist/src/interference.js.map +1 -0
  90. package/dist/src/introspect.d.ts +4 -0
  91. package/dist/src/introspect.d.ts.map +1 -0
  92. package/dist/src/introspect.js +40 -0
  93. package/dist/src/introspect.js.map +1 -0
  94. package/dist/src/llm.d.ts +38 -0
  95. package/dist/src/llm.d.ts.map +1 -0
  96. package/dist/src/llm.js +167 -0
  97. package/dist/src/llm.js.map +1 -0
  98. package/dist/src/migrate.d.ts +6 -0
  99. package/dist/src/migrate.d.ts.map +1 -0
  100. package/dist/src/migrate.js +51 -0
  101. package/dist/src/migrate.js.map +1 -0
  102. package/dist/src/promote.d.ts +40 -0
  103. package/dist/src/promote.d.ts.map +1 -0
  104. package/dist/src/promote.js +200 -0
  105. package/dist/src/promote.js.map +1 -0
  106. package/dist/src/prompts.d.ts +16 -0
  107. package/dist/src/prompts.d.ts.map +1 -0
  108. package/{src → dist/src}/prompts.js +172 -203
  109. package/dist/src/prompts.js.map +1 -0
  110. package/dist/src/recall.d.ts +9 -0
  111. package/dist/src/recall.d.ts.map +1 -0
  112. package/dist/src/recall.js +432 -0
  113. package/dist/src/recall.js.map +1 -0
  114. package/dist/src/redact.d.ts +27 -0
  115. package/dist/src/redact.d.ts.map +1 -0
  116. package/dist/src/redact.js +228 -0
  117. package/dist/src/redact.js.map +1 -0
  118. package/dist/src/rollback.d.ts +8 -0
  119. package/dist/src/rollback.d.ts.map +1 -0
  120. package/dist/src/rollback.js +33 -0
  121. package/dist/src/rollback.js.map +1 -0
  122. package/dist/src/routes.d.ts +7 -0
  123. package/dist/src/routes.d.ts.map +1 -0
  124. package/dist/src/routes.js +226 -0
  125. package/dist/src/routes.js.map +1 -0
  126. package/dist/src/rules-compiler.d.ts +20 -0
  127. package/dist/src/rules-compiler.d.ts.map +1 -0
  128. package/dist/src/rules-compiler.js +143 -0
  129. package/dist/src/rules-compiler.js.map +1 -0
  130. package/dist/src/server.d.ts +12 -0
  131. package/dist/src/server.d.ts.map +1 -0
  132. package/dist/src/server.js +22 -0
  133. package/dist/src/server.js.map +1 -0
  134. package/dist/src/tool-trace.d.ts +37 -0
  135. package/dist/src/tool-trace.d.ts.map +1 -0
  136. package/dist/src/tool-trace.js +142 -0
  137. package/dist/src/tool-trace.js.map +1 -0
  138. package/dist/src/types.d.ts +446 -0
  139. package/dist/src/types.d.ts.map +1 -0
  140. package/dist/src/types.js +6 -0
  141. package/dist/src/types.js.map +1 -0
  142. package/dist/src/ulid.d.ts +3 -0
  143. package/dist/src/ulid.d.ts.map +1 -0
  144. package/dist/src/ulid.js +11 -0
  145. package/dist/src/ulid.js.map +1 -0
  146. package/dist/src/utils.d.ts +10 -0
  147. package/dist/src/utils.d.ts.map +1 -0
  148. package/dist/src/utils.js +41 -0
  149. package/dist/src/utils.js.map +1 -0
  150. package/dist/src/validate.d.ts +22 -0
  151. package/dist/src/validate.d.ts.map +1 -0
  152. package/dist/src/validate.js +109 -0
  153. package/dist/src/validate.js.map +1 -0
  154. package/docs/production-readiness.md +28 -0
  155. package/examples/fintech-ops-demo.js +1 -1
  156. package/examples/healthcare-ops-demo.js +1 -1
  157. package/examples/stripe-demo.js +1 -1
  158. package/package.json +34 -13
  159. package/benchmarks/baselines.js +0 -169
  160. package/benchmarks/cases.js +0 -421
  161. package/benchmarks/reference-results.js +0 -70
  162. package/benchmarks/report.js +0 -255
  163. package/benchmarks/run.js +0 -514
  164. package/mcp-server/config.js +0 -133
  165. package/mcp-server/index.js +0 -1265
  166. package/mcp-server/serve.js +0 -482
  167. package/src/adaptive.js +0 -53
  168. package/src/affect.js +0 -64
  169. package/src/audrey.js +0 -642
  170. package/src/causal.js +0 -95
  171. package/src/confidence.js +0 -120
  172. package/src/consolidate.js +0 -281
  173. package/src/context.js +0 -15
  174. package/src/db.js +0 -391
  175. package/src/decay.js +0 -84
  176. package/src/embedding.js +0 -260
  177. package/src/encode.js +0 -69
  178. package/src/export.js +0 -67
  179. package/src/forget.js +0 -111
  180. package/src/fts.js +0 -134
  181. package/src/import.js +0 -273
  182. package/src/interference.js +0 -51
  183. package/src/introspect.js +0 -48
  184. package/src/llm.js +0 -249
  185. package/src/migrate.js +0 -58
  186. package/src/recall.js +0 -573
  187. package/src/rollback.js +0 -42
  188. package/src/ulid.js +0 -18
  189. package/src/utils.js +0 -63
  190. package/src/validate.js +0 -172
  191. package/types/index.d.ts +0 -434
package/src/causal.js DELETED
@@ -1,95 +0,0 @@
1
- import { generateId } from './ulid.js';
2
- import { buildCausalArticulationPrompt } from './prompts.js';
3
-
4
- /**
5
- * @param {import('better-sqlite3').Database} db
6
- * @param {{ causeId: string, effectId: string, linkType?: string, mechanism?: string, confidence?: number }} params
7
- * @returns {string}
8
- */
9
- export function addCausalLink(db, { causeId, effectId, linkType = 'causal', mechanism, confidence }) {
10
- const id = generateId();
11
- const now = new Date().toISOString();
12
-
13
- db.prepare(`
14
- INSERT INTO causal_links (id, cause_id, effect_id, link_type, mechanism, confidence, created_at)
15
- VALUES (?, ?, ?, ?, ?, ?, ?)
16
- `).run(id, causeId, effectId, linkType, mechanism, confidence, now);
17
-
18
- return id;
19
- }
20
-
21
- /**
22
- * @param {import('better-sqlite3').Database} db
23
- * @param {string} memoryId
24
- * @param {{ depth?: number }} [options]
25
- * @returns {Object[]}
26
- */
27
- export function getCausalChain(db, memoryId, options = {}) {
28
- const { depth = 10 } = options;
29
- const results = [];
30
- const visited = new Set();
31
- const queue = [memoryId];
32
- let currentDepth = 0;
33
-
34
- while (queue.length > 0 && currentDepth < depth) {
35
- const nextQueue = [];
36
- for (const nodeId of queue) {
37
- if (visited.has(nodeId)) continue;
38
- visited.add(nodeId);
39
-
40
- const links = db.prepare(
41
- 'SELECT * FROM causal_links WHERE cause_id = ?'
42
- ).all(nodeId);
43
-
44
- for (const link of links) {
45
- if (!visited.has(link.effect_id)) {
46
- results.push(link);
47
- nextQueue.push(link.effect_id);
48
- }
49
- }
50
- }
51
- queue.length = 0;
52
- queue.push(...nextQueue);
53
- currentDepth++;
54
- }
55
-
56
- return results;
57
- }
58
-
59
- /**
60
- * @param {import('better-sqlite3').Database} db
61
- * @param {import('./llm.js').LLMProvider} llmProvider
62
- * @param {{ id: string, content: string, source: string }} cause
63
- * @param {{ id: string, content: string, source: string }} effect
64
- * @returns {Promise<{ linkId: string|null, mechanism: string, linkType: string, confidence: number, spurious: boolean }>}
65
- */
66
- export async function articulateCausalLink(db, llmProvider, cause, effect) {
67
- const messages = buildCausalArticulationPrompt(cause, effect);
68
- const result = await llmProvider.json(messages);
69
-
70
- if (result.spurious) {
71
- return {
72
- linkId: null,
73
- mechanism: result.mechanism,
74
- linkType: result.linkType,
75
- confidence: result.confidence,
76
- spurious: true,
77
- };
78
- }
79
-
80
- const linkId = addCausalLink(db, {
81
- causeId: cause.id,
82
- effectId: effect.id,
83
- linkType: result.linkType || 'correlational',
84
- mechanism: result.mechanism,
85
- confidence: result.confidence,
86
- });
87
-
88
- return {
89
- linkId,
90
- mechanism: result.mechanism,
91
- linkType: result.linkType,
92
- confidence: result.confidence,
93
- spurious: false,
94
- };
95
- }
package/src/confidence.js DELETED
@@ -1,120 +0,0 @@
1
- /** @type {Record<string, number>} */
2
- export const DEFAULT_SOURCE_RELIABILITY = {
3
- 'direct-observation': 0.95,
4
- 'told-by-user': 0.90,
5
- 'tool-result': 0.85,
6
- 'inference': 0.60,
7
- 'model-generated': 0.40,
8
- };
9
-
10
- /** @type {{ source: number, evidence: number, recency: number, retrieval: number }} */
11
- export const DEFAULT_WEIGHTS = {
12
- source: 0.30,
13
- evidence: 0.35,
14
- recency: 0.20,
15
- retrieval: 0.15,
16
- };
17
-
18
- /** @type {{ episodic: number, semantic: number, procedural: number }} */
19
- export const DEFAULT_HALF_LIVES = {
20
- episodic: 7,
21
- semantic: 30,
22
- procedural: 90,
23
- };
24
-
25
- /** @type {number} */
26
- export const MODEL_GENERATED_CONFIDENCE_CAP = 0.6;
27
-
28
- /**
29
- * @param {string} sourceType
30
- * @param {Record<string, number>} [customReliability]
31
- * @returns {number}
32
- */
33
- export function sourceReliability(sourceType, customReliability) {
34
- const table = customReliability || DEFAULT_SOURCE_RELIABILITY;
35
- const value = table[sourceType];
36
- if (value === undefined) {
37
- throw new Error(`Unknown source type: ${sourceType}. Valid types: ${Object.keys(table).join(', ')}`);
38
- }
39
- return value;
40
- }
41
-
42
- /**
43
- * @param {number} supportingCount
44
- * @param {number} contradictingCount
45
- * @returns {number}
46
- */
47
- export function evidenceAgreement(supportingCount, contradictingCount) {
48
- const total = supportingCount + contradictingCount;
49
- if (total === 0) return 1.0;
50
- return supportingCount / total;
51
- }
52
-
53
- /**
54
- * @param {number} ageDays
55
- * @param {number} halfLifeDays
56
- * @returns {number}
57
- */
58
- export function recencyDecay(ageDays, halfLifeDays) {
59
- const lambda = Math.LN2 / halfLifeDays;
60
- return Math.exp(-lambda * ageDays);
61
- }
62
-
63
- /**
64
- * @param {number} retrievalCount
65
- * @param {number} daysSinceRetrieval
66
- * @returns {number}
67
- */
68
- export function retrievalReinforcement(retrievalCount, daysSinceRetrieval) {
69
- if (retrievalCount === 0) return 0;
70
- const lambdaRet = Math.LN2 / 14;
71
- const baseReinforcement = 0.3 * Math.log(1 + retrievalCount);
72
- const recencyWeight = Math.exp(-lambdaRet * daysSinceRetrieval);
73
- const spacedBonus = Math.min(0.15, 0.02 * Math.log(1 + daysSinceRetrieval));
74
- return Math.min(1.0, baseReinforcement * recencyWeight + spacedBonus);
75
- }
76
-
77
- export function salienceModifier(salience) {
78
- const s = salience ?? 0.5;
79
- return 0.5 + s;
80
- }
81
-
82
- /**
83
- * @param {object} params
84
- * @param {string} params.sourceType
85
- * @param {number} params.supportingCount
86
- * @param {number} params.contradictingCount
87
- * @param {number} params.ageDays
88
- * @param {number} params.halfLifeDays
89
- * @param {number} params.retrievalCount
90
- * @param {number} params.daysSinceRetrieval
91
- * @param {{ source: number, evidence: number, recency: number, retrieval: number }} [params.weights]
92
- * @param {Record<string, number>} [params.customSourceReliability]
93
- * @returns {number}
94
- */
95
- export function computeConfidence({
96
- sourceType,
97
- supportingCount,
98
- contradictingCount,
99
- ageDays,
100
- halfLifeDays,
101
- retrievalCount,
102
- daysSinceRetrieval,
103
- weights,
104
- customSourceReliability,
105
- }) {
106
- const w = weights || DEFAULT_WEIGHTS;
107
-
108
- const s = sourceReliability(sourceType, customSourceReliability);
109
- const e = evidenceAgreement(supportingCount, contradictingCount);
110
- const r = recencyDecay(ageDays, halfLifeDays);
111
- const ret = retrievalReinforcement(retrievalCount, daysSinceRetrieval);
112
-
113
- let confidence = w.source * s + w.evidence * e + w.recency * r + w.retrieval * ret;
114
-
115
- if (sourceType === 'model-generated') {
116
- confidence = Math.min(confidence, MODEL_GENERATED_CONFIDENCE_CAP);
117
- }
118
-
119
- return Math.max(0, Math.min(1, confidence));
120
- }
@@ -1,281 +0,0 @@
1
- import { generateId } from './ulid.js';
2
- import { buildPrincipleExtractionPrompt } from './prompts.js';
3
-
4
- function clusterViaKNN(db, episodes, similarityThreshold, minClusterSize) {
5
- const n = episodes.length;
6
- const k = Math.min(50, n);
7
- const idToIndex = new Map(episodes.map((ep, i) => [ep.id, i]));
8
-
9
- const parent = new Array(n);
10
- for (let i = 0; i < n; i++) parent[i] = i;
11
-
12
- function find(x) {
13
- while (parent[x] !== x) {
14
- parent[x] = parent[parent[x]];
15
- x = parent[x];
16
- }
17
- return x;
18
- }
19
-
20
- function union(a, b) {
21
- const ra = find(a);
22
- const rb = find(b);
23
- if (ra !== rb) parent[ra] = rb;
24
- }
25
-
26
- const getEmbedding = db.prepare('SELECT embedding FROM vec_episodes WHERE id = ?');
27
- const knnQuery = db.prepare(`
28
- SELECT id, distance
29
- FROM vec_episodes
30
- WHERE embedding MATCH ? AND k = ? AND consolidated = 0
31
- `);
32
-
33
- for (let i = 0; i < n; i++) {
34
- const ep = episodes[i];
35
- const vecRow = getEmbedding.get(ep.id);
36
- if (!vecRow) continue;
37
-
38
- const neighbors = knnQuery.all(vecRow.embedding, k);
39
- for (const neighbor of neighbors) {
40
- if (neighbor.id === ep.id) continue;
41
- const j = idToIndex.get(neighbor.id);
42
- if (j === undefined) continue;
43
- const similarity = 1.0 - neighbor.distance;
44
- if (similarity >= similarityThreshold) {
45
- union(i, j);
46
- }
47
- }
48
- }
49
-
50
- const groups = new Map();
51
- for (let i = 0; i < n; i++) {
52
- const root = find(i);
53
- if (!groups.has(root)) groups.set(root, []);
54
- groups.get(root).push(episodes[i]);
55
- }
56
-
57
- const clusters = [];
58
- for (const group of groups.values()) {
59
- if (group.length >= minClusterSize) {
60
- clusters.push(group);
61
- }
62
- }
63
- return clusters;
64
- }
65
-
66
- /**
67
- * @param {import('better-sqlite3').Database} db
68
- * @param {import('./embedding.js').EmbeddingProvider} embeddingProvider
69
- * @param {{ similarityThreshold?: number, minClusterSize?: number }} [options]
70
- * @returns {Array<Array<Object>>}
71
- */
72
- export function clusterEpisodes(db, embeddingProvider, options = {}) {
73
- const {
74
- similarityThreshold = 0.85,
75
- minClusterSize = 3,
76
- } = options;
77
-
78
- const episodes = db.prepare(
79
- 'SELECT * FROM episodes WHERE consolidated = 0 AND superseded_by IS NULL AND embedding IS NOT NULL'
80
- ).all();
81
-
82
- if (episodes.length === 0) return [];
83
-
84
- return clusterViaKNN(db, episodes, similarityThreshold, minClusterSize);
85
- }
86
-
87
- function defaultExtractPrinciple(episodes) {
88
- const uniqueContents = [...new Set(episodes.map(e => e.content))];
89
- return {
90
- content: `Recurring pattern: ${uniqueContents.join('; ')}`,
91
- type: 'semantic',
92
- };
93
- }
94
-
95
- async function llmExtractPrinciple(llmProvider, episodes) {
96
- const messages = buildPrincipleExtractionPrompt(episodes);
97
- return llmProvider.json(messages);
98
- }
99
-
100
- function inClause(ids) {
101
- return ids.map(() => '?').join(',');
102
- }
103
-
104
- /**
105
- * @param {import('better-sqlite3').Database} db
106
- * @param {import('./embedding.js').EmbeddingProvider} embeddingProvider
107
- * @param {{ similarityThreshold?: number, minClusterSize?: number, extractPrinciple?: function, llmProvider?: Object }} [options]
108
- * @returns {Promise<{ runId: string, episodesEvaluated: number, clustersFound: number, principlesExtracted: number }>}
109
- */
110
- export async function runConsolidation(db, embeddingProvider, options = {}) {
111
- const {
112
- similarityThreshold = 0.85,
113
- minClusterSize = 3,
114
- extractPrinciple,
115
- llmProvider,
116
- } = options;
117
-
118
- const runId = generateId();
119
- const now = new Date().toISOString();
120
-
121
- db.prepare(`
122
- INSERT INTO consolidation_runs (
123
- id, started_at, status, input_episode_ids, output_memory_ids, consolidation_model, checkpoint_cursor
124
- )
125
- VALUES (?, ?, 'running', '[]', '[]', ?, ?)
126
- `).run(runId, now, llmProvider?.modelName || null, now);
127
-
128
- try {
129
- const clusters = clusterEpisodes(db, embeddingProvider, { similarityThreshold, minClusterSize });
130
-
131
- const episodesEvaluated = db.prepare(
132
- 'SELECT COUNT(*) as count FROM episodes WHERE consolidated = 0 AND superseded_by IS NULL AND embedding IS NOT NULL'
133
- ).get().count;
134
-
135
- const allInputIds = [];
136
- const allOutputIds = [];
137
- let principlesExtracted = 0;
138
- let proceduresExtracted = 0;
139
- const preparedClusters = [];
140
- const insertProcedure = db.prepare(`
141
- INSERT INTO procedures (
142
- id, content, embedding, state, trigger_conditions,
143
- evidence_episode_ids, success_count, failure_count,
144
- embedding_model, embedding_version, created_at, salience
145
- ) VALUES (?, ?, ?, 'active', ?, ?, 0, 0, ?, ?, ?, ?)
146
- `);
147
- const insertVecProcedure = db.prepare('INSERT INTO vec_procedures(id, embedding, state) VALUES (?, ?, ?)');
148
- const insertSemantic = db.prepare(`
149
- INSERT INTO semantics (
150
- id, content, embedding, state, evidence_episode_ids,
151
- evidence_count, supporting_count, source_type_diversity,
152
- consolidation_checkpoint, embedding_model, embedding_version,
153
- consolidation_model, created_at, salience
154
- ) VALUES (?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
155
- `);
156
- const insertVecSemantic = db.prepare('INSERT INTO vec_semantics(id, embedding, state) VALUES (?, ?, ?)');
157
- const updateRunCompleted = db.prepare(`
158
- UPDATE consolidation_runs
159
- SET status = 'completed',
160
- completed_at = ?,
161
- input_episode_ids = ?,
162
- output_memory_ids = ?
163
- WHERE id = ?
164
- `);
165
- const insertMetrics = db.prepare(`
166
- INSERT INTO consolidation_metrics (id, run_id, min_cluster_size, similarity_threshold,
167
- episodes_evaluated, clusters_found, principles_extracted, created_at)
168
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
169
- `);
170
-
171
- for (const cluster of clusters) {
172
- let principle;
173
- if (extractPrinciple) {
174
- principle = await extractPrinciple(cluster);
175
- } else if (llmProvider) {
176
- principle = await llmExtractPrinciple(llmProvider, cluster);
177
- } else {
178
- principle = defaultExtractPrinciple(cluster);
179
- }
180
-
181
- if (!principle || !principle.content) continue;
182
-
183
- const vector = await embeddingProvider.embed(principle.content);
184
- const clusterIds = cluster.map(ep => ep.id);
185
- preparedClusters.push({
186
- principle,
187
- clusterIds,
188
- sourceTypeDiversity: new Set(cluster.map(ep => ep.source)).size,
189
- embeddingBuffer: embeddingProvider.vectorToBuffer(vector),
190
- memoryId: generateId(),
191
- createdAt: new Date().toISOString(),
192
- maxSalience: Math.max(...cluster.map(ep => ep.salience ?? 0.5)),
193
- });
194
- }
195
-
196
- const writeConsolidation = db.transaction(() => {
197
- for (const prepared of preparedClusters) {
198
- const placeholders = inClause(prepared.clusterIds);
199
- const eligibleCount = db.prepare(`
200
- SELECT COUNT(*) AS count
201
- FROM episodes
202
- WHERE id IN (${placeholders})
203
- AND consolidated = 0
204
- AND superseded_by IS NULL
205
- `).get(...prepared.clusterIds).count;
206
-
207
- if (eligibleCount !== prepared.clusterIds.length) {
208
- continue;
209
- }
210
-
211
- if (prepared.principle.type === 'procedural') {
212
- insertProcedure.run(
213
- prepared.memoryId,
214
- prepared.principle.content,
215
- prepared.embeddingBuffer,
216
- prepared.principle.conditions ? JSON.stringify(prepared.principle.conditions) : null,
217
- JSON.stringify(prepared.clusterIds),
218
- embeddingProvider.modelName,
219
- embeddingProvider.modelVersion,
220
- prepared.createdAt,
221
- prepared.maxSalience,
222
- );
223
- insertVecProcedure.run(prepared.memoryId, prepared.embeddingBuffer, 'active');
224
- proceduresExtracted++;
225
- } else {
226
- insertSemantic.run(
227
- prepared.memoryId,
228
- prepared.principle.content,
229
- prepared.embeddingBuffer,
230
- JSON.stringify(prepared.clusterIds),
231
- prepared.clusterIds.length,
232
- prepared.clusterIds.length,
233
- prepared.sourceTypeDiversity,
234
- runId,
235
- embeddingProvider.modelName,
236
- embeddingProvider.modelVersion,
237
- llmProvider?.modelName || null,
238
- prepared.createdAt,
239
- prepared.maxSalience,
240
- );
241
- insertVecSemantic.run(prepared.memoryId, prepared.embeddingBuffer, 'active');
242
- }
243
-
244
- db.prepare(`UPDATE episodes SET consolidated = 1 WHERE id IN (${placeholders})`).run(...prepared.clusterIds);
245
- db.prepare(`UPDATE vec_episodes SET consolidated = ? WHERE id IN (${placeholders})`).run(
246
- BigInt(1),
247
- ...prepared.clusterIds,
248
- );
249
-
250
- allInputIds.push(...prepared.clusterIds);
251
- allOutputIds.push(prepared.memoryId);
252
- principlesExtracted++;
253
- }
254
-
255
- const completedAt = new Date().toISOString();
256
- updateRunCompleted.run(completedAt, JSON.stringify(allInputIds), JSON.stringify(allOutputIds), runId);
257
- insertMetrics.run(
258
- generateId(), runId, minClusterSize, similarityThreshold,
259
- episodesEvaluated, clusters.length, principlesExtracted, completedAt,
260
- );
261
- });
262
- writeConsolidation.immediate();
263
-
264
- return {
265
- runId,
266
- episodesEvaluated,
267
- clustersFound: clusters.length,
268
- principlesExtracted,
269
- semanticsCreated: principlesExtracted - proceduresExtracted,
270
- proceduresCreated: proceduresExtracted,
271
- };
272
- } catch (err) {
273
- const failedAt = new Date().toISOString();
274
- db.prepare(`
275
- UPDATE consolidation_runs
276
- SET status = 'failed', completed_at = ?
277
- WHERE id = ?
278
- `).run(failedAt, runId);
279
- throw err;
280
- }
281
- }
package/src/context.js DELETED
@@ -1,15 +0,0 @@
1
- export function contextMatchRatio(encodingContext, retrievalContext) {
2
- if (!encodingContext || !retrievalContext) return 0;
3
- const retrievalKeys = Object.keys(retrievalContext);
4
- if (retrievalKeys.length === 0) return 0;
5
- const sharedKeys = retrievalKeys.filter(k => k in encodingContext);
6
- if (sharedKeys.length === 0) return 0;
7
- const matches = sharedKeys.filter(k => encodingContext[k] === retrievalContext[k]).length;
8
- return matches / retrievalKeys.length;
9
- }
10
-
11
- export function contextModifier(encodingContext, retrievalContext, weight = 0.3) {
12
- if (!encodingContext || !retrievalContext) return 1.0;
13
- const ratio = contextMatchRatio(encodingContext, retrievalContext);
14
- return 1.0 + (weight * ratio);
15
- }