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/import.js DELETED
@@ -1,273 +0,0 @@
1
- function jsonOrNull(value) {
2
- return value == null ? null : JSON.stringify(value);
3
- }
4
-
5
- function isDatabaseEmpty(db) {
6
- const tables = [
7
- 'episodes',
8
- 'semantics',
9
- 'procedures',
10
- 'causal_links',
11
- 'contradictions',
12
- 'consolidation_runs',
13
- 'consolidation_metrics',
14
- ];
15
-
16
- return tables.every(table => db.prepare(`SELECT COUNT(*) AS c FROM ${table}`).get().c === 0);
17
- }
18
-
19
- const VALID_SOURCES = new Set(['direct-observation', 'told-by-user', 'tool-result', 'inference', 'model-generated']);
20
-
21
- function validateSnapshot(snapshot) {
22
- const errors = [];
23
- for (let i = 0; i < (snapshot.episodes || []).length; i++) {
24
- const ep = snapshot.episodes[i];
25
- if (!ep.id) errors.push(`episodes[${i}]: missing id`);
26
- if (!ep.content) errors.push(`episodes[${i}]: missing content`);
27
- if (!ep.source || !VALID_SOURCES.has(ep.source)) errors.push(`episodes[${i}]: invalid source "${ep.source}"`);
28
- }
29
- for (let i = 0; i < (snapshot.semantics || []).length; i++) {
30
- const sem = snapshot.semantics[i];
31
- if (!sem.id) errors.push(`semantics[${i}]: missing id`);
32
- if (!sem.content) errors.push(`semantics[${i}]: missing content`);
33
- }
34
- for (let i = 0; i < (snapshot.procedures || []).length; i++) {
35
- const proc = snapshot.procedures[i];
36
- if (!proc.id) errors.push(`procedures[${i}]: missing id`);
37
- if (!proc.content) errors.push(`procedures[${i}]: missing content`);
38
- }
39
- return errors;
40
- }
41
-
42
- export async function importMemories(db, embeddingProvider, snapshot) {
43
- if (!isDatabaseEmpty(db)) {
44
- throw new Error('Cannot import into a database that is not empty');
45
- }
46
-
47
- const validationErrors = validateSnapshot(snapshot);
48
- if (validationErrors.length > 0) {
49
- throw new Error(`Invalid snapshot: ${validationErrors.join('; ')}`);
50
- }
51
-
52
- const episodes = snapshot.episodes || [];
53
- const semantics = snapshot.semantics || [];
54
- const procedures = snapshot.procedures || [];
55
- const causalLinks = snapshot.causalLinks || [];
56
- const contradictions = snapshot.contradictions || [];
57
- const consolidationRuns = snapshot.consolidationRuns || [];
58
- const consolidationMetrics = snapshot.consolidationMetrics || [];
59
-
60
- const episodeVectors = episodes.length > 0
61
- ? await embeddingProvider.embedBatch(episodes.map(ep => ep.content))
62
- : [];
63
- const semanticVectors = semantics.length > 0
64
- ? await embeddingProvider.embedBatch(semantics.map(sem => sem.content))
65
- : [];
66
- const procedureVectors = procedures.length > 0
67
- ? await embeddingProvider.embedBatch(procedures.map(proc => proc.content))
68
- : [];
69
-
70
- const insertEpisode = db.prepare(`
71
- INSERT INTO episodes (id, content, embedding, source, source_reliability, salience, context, affect, tags,
72
- causal_trigger, causal_consequence, created_at, embedding_model, embedding_version,
73
- supersedes, superseded_by, consolidated, "private")
74
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
75
- `);
76
- const insertVecEpisode = db.prepare(
77
- 'INSERT INTO vec_episodes(id, embedding, source, consolidated) VALUES (?, ?, ?, ?)'
78
- );
79
-
80
- const insertSemantic = db.prepare(`
81
- INSERT INTO semantics (id, content, embedding, state, conditions, evidence_episode_ids,
82
- evidence_count, supporting_count, contradicting_count, source_type_diversity,
83
- consolidation_checkpoint, embedding_model, embedding_version, consolidation_model,
84
- consolidation_prompt_hash, created_at, last_reinforced_at, retrieval_count, challenge_count,
85
- interference_count, salience)
86
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
87
- `);
88
- const insertVecSemantic = db.prepare(
89
- 'INSERT INTO vec_semantics(id, embedding, state) VALUES (?, ?, ?)'
90
- );
91
-
92
- const insertProcedure = db.prepare(`
93
- INSERT INTO procedures (id, content, embedding, state, trigger_conditions, evidence_episode_ids,
94
- success_count, failure_count, embedding_model, embedding_version, created_at, last_reinforced_at,
95
- retrieval_count, interference_count, salience)
96
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
97
- `);
98
- const insertVecProcedure = db.prepare(
99
- 'INSERT INTO vec_procedures(id, embedding, state) VALUES (?, ?, ?)'
100
- );
101
-
102
- const insertCausalLink = db.prepare(`
103
- INSERT INTO causal_links (id, cause_id, effect_id, link_type, mechanism, confidence, evidence_count, created_at)
104
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
105
- `);
106
-
107
- const insertContradiction = db.prepare(`
108
- INSERT INTO contradictions (id, claim_a_id, claim_a_type, claim_b_id, claim_b_type,
109
- state, resolution, resolved_at, reopened_at, reopen_evidence_id, created_at)
110
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
111
- `);
112
-
113
- const insertConsolidationRun = db.prepare(`
114
- INSERT INTO consolidation_runs (id, checkpoint_cursor, input_episode_ids, output_memory_ids,
115
- confidence_deltas, consolidation_model, consolidation_prompt_hash, started_at, completed_at, status)
116
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
117
- `);
118
-
119
- const insertConsolidationMetric = db.prepare(`
120
- INSERT INTO consolidation_metrics (id, run_id, min_cluster_size, similarity_threshold,
121
- episodes_evaluated, clusters_found, principles_extracted, created_at)
122
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)
123
- `);
124
-
125
- const upsertConfig = db.prepare(`
126
- INSERT INTO audrey_config (key, value) VALUES (?, ?)
127
- ON CONFLICT(key) DO UPDATE SET value = excluded.value
128
- `);
129
-
130
- const writeImport = db.transaction(() => {
131
- for (let i = 0; i < episodes.length; i++) {
132
- const ep = episodes[i];
133
- const embeddingBuffer = embeddingProvider.vectorToBuffer(episodeVectors[i]);
134
- insertEpisode.run(
135
- ep.id,
136
- ep.content,
137
- embeddingBuffer,
138
- ep.source,
139
- ep.source_reliability,
140
- ep.salience ?? 0.5,
141
- jsonOrNull(ep.context ?? {}),
142
- jsonOrNull(ep.affect ?? {}),
143
- jsonOrNull(ep.tags),
144
- ep.causal_trigger ?? null,
145
- ep.causal_consequence ?? null,
146
- ep.created_at,
147
- embeddingProvider.modelName,
148
- embeddingProvider.modelVersion,
149
- ep.supersedes ?? null,
150
- ep.superseded_by ?? null,
151
- ep.consolidated ?? 0,
152
- ep.private ?? 0,
153
- );
154
- insertVecEpisode.run(ep.id, embeddingBuffer, ep.source, BigInt(ep.consolidated ?? 0));
155
- }
156
-
157
- for (let i = 0; i < semantics.length; i++) {
158
- const sem = semantics[i];
159
- const embeddingBuffer = embeddingProvider.vectorToBuffer(semanticVectors[i]);
160
- insertSemantic.run(
161
- sem.id,
162
- sem.content,
163
- embeddingBuffer,
164
- sem.state,
165
- sem.conditions ?? null,
166
- jsonOrNull(sem.evidence_episode_ids || []),
167
- sem.evidence_count ?? 0,
168
- sem.supporting_count ?? 0,
169
- sem.contradicting_count ?? 0,
170
- sem.source_type_diversity ?? 0,
171
- sem.consolidation_checkpoint ?? null,
172
- embeddingProvider.modelName,
173
- embeddingProvider.modelVersion,
174
- sem.consolidation_model ?? null,
175
- sem.consolidation_prompt_hash ?? null,
176
- sem.created_at,
177
- sem.last_reinforced_at ?? null,
178
- sem.retrieval_count ?? 0,
179
- sem.challenge_count ?? 0,
180
- sem.interference_count ?? 0,
181
- sem.salience ?? 0.5,
182
- );
183
- insertVecSemantic.run(sem.id, embeddingBuffer, sem.state);
184
- }
185
-
186
- for (let i = 0; i < procedures.length; i++) {
187
- const proc = procedures[i];
188
- const embeddingBuffer = embeddingProvider.vectorToBuffer(procedureVectors[i]);
189
- insertProcedure.run(
190
- proc.id,
191
- proc.content,
192
- embeddingBuffer,
193
- proc.state,
194
- proc.trigger_conditions ?? null,
195
- jsonOrNull(proc.evidence_episode_ids || []),
196
- proc.success_count ?? 0,
197
- proc.failure_count ?? 0,
198
- embeddingProvider.modelName,
199
- embeddingProvider.modelVersion,
200
- proc.created_at,
201
- proc.last_reinforced_at ?? null,
202
- proc.retrieval_count ?? 0,
203
- proc.interference_count ?? 0,
204
- proc.salience ?? 0.5,
205
- );
206
- insertVecProcedure.run(proc.id, embeddingBuffer, proc.state);
207
- }
208
-
209
- for (const link of causalLinks) {
210
- insertCausalLink.run(
211
- link.id,
212
- link.cause_id,
213
- link.effect_id,
214
- link.link_type ?? 'causal',
215
- link.mechanism ?? null,
216
- link.confidence ?? null,
217
- link.evidence_count ?? 1,
218
- link.created_at,
219
- );
220
- }
221
-
222
- for (const contradiction of contradictions) {
223
- insertContradiction.run(
224
- contradiction.id,
225
- contradiction.claim_a_id,
226
- contradiction.claim_a_type,
227
- contradiction.claim_b_id,
228
- contradiction.claim_b_type,
229
- contradiction.state,
230
- contradiction.resolution ?? null,
231
- contradiction.resolved_at ?? null,
232
- contradiction.reopened_at ?? null,
233
- contradiction.reopen_evidence_id ?? null,
234
- contradiction.created_at,
235
- );
236
- }
237
-
238
- for (const run of consolidationRuns) {
239
- insertConsolidationRun.run(
240
- run.id,
241
- run.checkpoint_cursor ?? null,
242
- jsonOrNull(run.input_episode_ids || []),
243
- jsonOrNull(run.output_memory_ids || []),
244
- jsonOrNull(run.confidence_deltas),
245
- run.consolidation_model ?? null,
246
- run.consolidation_prompt_hash ?? null,
247
- run.started_at ?? null,
248
- run.completed_at ?? null,
249
- run.status,
250
- );
251
- }
252
-
253
- for (const metric of consolidationMetrics) {
254
- insertConsolidationMetric.run(
255
- metric.id,
256
- metric.run_id,
257
- metric.min_cluster_size,
258
- metric.similarity_threshold,
259
- metric.episodes_evaluated,
260
- metric.clusters_found,
261
- metric.principles_extracted,
262
- metric.created_at,
263
- );
264
- }
265
-
266
- for (const [key, value] of Object.entries(snapshot.config || {})) {
267
- if (key === 'dimensions') continue;
268
- upsertConfig.run(key, String(value));
269
- }
270
- });
271
-
272
- writeImport();
273
- }
@@ -1,51 +0,0 @@
1
- export function interferenceModifier(interferenceCount, weight = 0.1) {
2
- return 1 / (1 + weight * interferenceCount);
3
- }
4
-
5
- export async function applyInterference(db, embeddingProvider, episodeId, { content }, config = {}) {
6
- const { enabled = true, k = 5, threshold = 0.6, weight = 0.1 } = config;
7
-
8
- if (!enabled) return [];
9
-
10
- const vector = await embeddingProvider.embed(content);
11
- const buffer = embeddingProvider.vectorToBuffer(vector);
12
-
13
- const semanticHits = db.prepare(`
14
- SELECT s.id, s.interference_count, (1.0 - v.distance) AS similarity
15
- FROM vec_semantics v
16
- JOIN semantics s ON s.id = v.id
17
- WHERE v.embedding MATCH ?
18
- AND k = ?
19
- AND (v.state = 'active' OR v.state = 'context_dependent')
20
- `).all(buffer, k);
21
-
22
- const proceduralHits = db.prepare(`
23
- SELECT p.id, p.interference_count, (1.0 - v.distance) AS similarity
24
- FROM vec_procedures v
25
- JOIN procedures p ON p.id = v.id
26
- WHERE v.embedding MATCH ?
27
- AND k = ?
28
- AND (v.state = 'active' OR v.state = 'context_dependent')
29
- `).all(buffer, k);
30
-
31
- const affected = [];
32
-
33
- const updateSemantic = db.prepare('UPDATE semantics SET interference_count = ? WHERE id = ?');
34
- const updateProcedural = db.prepare('UPDATE procedures SET interference_count = ? WHERE id = ?');
35
-
36
- for (const hit of semanticHits) {
37
- if (hit.similarity < threshold) continue;
38
- const newCount = hit.interference_count + 1;
39
- updateSemantic.run(newCount, hit.id);
40
- affected.push({ id: hit.id, type: 'semantic', newCount, similarity: hit.similarity });
41
- }
42
-
43
- for (const hit of proceduralHits) {
44
- if (hit.similarity < threshold) continue;
45
- const newCount = hit.interference_count + 1;
46
- updateProcedural.run(newCount, hit.id);
47
- affected.push({ id: hit.id, type: 'procedural', newCount, similarity: hit.similarity });
48
- }
49
-
50
- return affected;
51
- }
package/src/introspect.js DELETED
@@ -1,48 +0,0 @@
1
- import { safeJsonParse } from './utils.js';
2
-
3
- /**
4
- * @param {import('better-sqlite3').Database} db
5
- * @returns {{ episodic: number, semantic: number, procedural: number, causalLinks: number, dormant: number, contradictions: { open: number, resolved: number, context_dependent: number, reopened: number }, lastConsolidation: string|null, totalConsolidationRuns: number }}
6
- */
7
- export function introspect(db) {
8
- const counts = db.prepare(`
9
- SELECT
10
- (SELECT COUNT(*) FROM episodes) as episodic,
11
- (SELECT COUNT(*) FROM semantics WHERE state != 'rolled_back') as semantic,
12
- (SELECT COUNT(*) FROM procedures WHERE state != 'rolled_back') as procedural,
13
- (SELECT COUNT(*) FROM causal_links) as causal_links,
14
- (SELECT COUNT(*) FROM semantics WHERE state = 'dormant')
15
- + (SELECT COUNT(*) FROM procedures WHERE state = 'dormant') as dormant
16
- `).get();
17
-
18
- const contradictions = db.prepare(`
19
- SELECT
20
- SUM(CASE WHEN state = 'open' THEN 1 ELSE 0 END) as open,
21
- SUM(CASE WHEN state = 'resolved' THEN 1 ELSE 0 END) as resolved,
22
- SUM(CASE WHEN state = 'context_dependent' THEN 1 ELSE 0 END) as context_dependent,
23
- SUM(CASE WHEN state = 'reopened' THEN 1 ELSE 0 END) as reopened
24
- FROM contradictions
25
- `).get();
26
-
27
- const lastRun = db.prepare(`
28
- SELECT completed_at FROM consolidation_runs
29
- WHERE status = 'completed' ORDER BY completed_at DESC LIMIT 1
30
- `).get();
31
- const totalRuns = db.prepare('SELECT COUNT(*) as count FROM consolidation_runs').get().count;
32
-
33
- return {
34
- episodic: counts.episodic,
35
- semantic: counts.semantic,
36
- procedural: counts.procedural,
37
- causalLinks: counts.causal_links,
38
- dormant: counts.dormant,
39
- contradictions: {
40
- open: contradictions?.open || 0,
41
- resolved: contradictions?.resolved || 0,
42
- context_dependent: contradictions?.context_dependent || 0,
43
- reopened: contradictions?.reopened || 0,
44
- },
45
- lastConsolidation: lastRun?.completed_at || null,
46
- totalConsolidationRuns: totalRuns,
47
- };
48
- }
package/src/llm.js DELETED
@@ -1,249 +0,0 @@
1
- /**
2
- * @typedef {Object} ChatMessage
3
- * @property {'system' | 'user' | 'assistant'} role
4
- * @property {string} content
5
- */
6
-
7
- import { describeHttpError, requireApiKey } from './utils.js';
8
-
9
- function extractJSON(text) {
10
- const fenced = text.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
11
- return fenced ? fenced[1].trim() : text.trim();
12
- }
13
-
14
- /**
15
- * @typedef {Object} LLMCompletionResult
16
- * @property {string} content
17
- */
18
-
19
- /**
20
- * @typedef {Object} LLMCompletionOptions
21
- * @property {number} [maxTokens]
22
- */
23
-
24
- /**
25
- * @typedef {Object} LLMProvider
26
- * @property {string} modelName
27
- * @property {string} modelVersion
28
- * @property {(messages: ChatMessage[], options?: LLMCompletionOptions) => Promise<LLMCompletionResult>} complete
29
- * @property {(messages: ChatMessage[], options?: LLMCompletionOptions) => Promise<Object>} json
30
- */
31
-
32
- /**
33
- * @typedef {Object} MockLLMConfig
34
- * @property {'mock'} provider
35
- * @property {Record<string, Object>} [responses={}]
36
- */
37
-
38
- /**
39
- * @typedef {Object} AnthropicLLMConfig
40
- * @property {'anthropic'} provider
41
- * @property {string} [apiKey]
42
- * @property {string} [model='claude-sonnet-4-6']
43
- * @property {number} [maxTokens=1024]
44
- */
45
-
46
- /**
47
- * @typedef {Object} OpenAILLMConfig
48
- * @property {'openai'} provider
49
- * @property {string} [apiKey]
50
- * @property {string} [model='gpt-4o']
51
- * @property {number} [maxTokens=1024]
52
- */
53
-
54
- const PROMPT_TYPE_KEYS = [
55
- 'principleExtraction',
56
- 'contradictionDetection',
57
- 'causalArticulation',
58
- 'contextResolution',
59
- ];
60
-
61
- /** @implements {LLMProvider} */
62
- export class MockLLMProvider {
63
- /** @param {Partial<MockLLMConfig>} [config={}] */
64
- constructor({ responses = {} } = {}) {
65
- this.responses = responses;
66
- this.modelName = 'mock-llm';
67
- this.modelVersion = '1.0.0';
68
- }
69
-
70
- _matchPromptType(messages) {
71
- const systemMsg = messages.find(m => m.role === 'system')?.content || '';
72
- for (const key of PROMPT_TYPE_KEYS) {
73
- if (systemMsg.includes(key)) return key;
74
- }
75
- return null;
76
- }
77
-
78
- /**
79
- * @param {ChatMessage[]} messages
80
- * @returns {Promise<LLMCompletionResult>}
81
- */
82
- async complete(messages) {
83
- const promptType = this._matchPromptType(messages);
84
- const cannedResponse = promptType ? this.responses[promptType] : undefined;
85
- return { content: cannedResponse !== undefined ? JSON.stringify(cannedResponse) : '{}' };
86
- }
87
-
88
- /**
89
- * @param {ChatMessage[]} messages
90
- * @returns {Promise<Object>}
91
- */
92
- async json(messages) {
93
- const promptType = this._matchPromptType(messages);
94
- const cannedResponse = promptType ? this.responses[promptType] : undefined;
95
- return cannedResponse !== undefined ? cannedResponse : {};
96
- }
97
- }
98
-
99
- /** @implements {LLMProvider} */
100
- export class AnthropicLLMProvider {
101
- /** @param {Partial<AnthropicLLMConfig>} [config={}] */
102
- constructor({ apiKey, model = 'claude-sonnet-4-6', maxTokens = 1024, timeout = 30000 } = {}) {
103
- this.apiKey = apiKey || process.env.ANTHROPIC_API_KEY;
104
- this.model = model;
105
- this.maxTokens = maxTokens;
106
- this.timeout = timeout;
107
- this.modelName = model;
108
- this.modelVersion = 'latest';
109
- }
110
-
111
- /**
112
- * @param {ChatMessage[]} messages
113
- * @param {LLMCompletionOptions} [options={}]
114
- * @returns {Promise<LLMCompletionResult>}
115
- */
116
- async complete(messages, options = {}) {
117
- requireApiKey(this.apiKey, 'Anthropic LLM', 'ANTHROPIC_API_KEY');
118
- const systemMsg = messages.find(m => m.role === 'system')?.content;
119
- const nonSystemMsgs = messages.filter(m => m.role !== 'system');
120
-
121
- const body = {
122
- model: this.model,
123
- max_tokens: options.maxTokens || this.maxTokens,
124
- messages: nonSystemMsgs,
125
- };
126
- if (systemMsg) body.system = systemMsg;
127
-
128
- const controller = new AbortController();
129
- const timer = setTimeout(() => controller.abort(), this.timeout);
130
- try {
131
- const response = await fetch('https://api.anthropic.com/v1/messages', {
132
- method: 'POST',
133
- headers: {
134
- 'x-api-key': this.apiKey,
135
- 'anthropic-version': '2023-06-01',
136
- 'content-type': 'application/json',
137
- },
138
- body: JSON.stringify(body),
139
- signal: controller.signal,
140
- });
141
-
142
- if (!response.ok) {
143
- throw new Error(`Anthropic API error: ${await describeHttpError(response)}`);
144
- }
145
-
146
- const data = await response.json();
147
- const text = data.content?.[0]?.text || '';
148
- return { content: text };
149
- } finally {
150
- clearTimeout(timer);
151
- }
152
- }
153
-
154
- /**
155
- * @param {ChatMessage[]} messages
156
- * @param {LLMCompletionOptions} [options={}]
157
- * @returns {Promise<Object>}
158
- */
159
- async json(messages, options = {}) {
160
- const result = await this.complete(messages, options);
161
- try {
162
- return JSON.parse(extractJSON(result.content));
163
- } catch {
164
- throw new Error(`Failed to parse LLM response as JSON: ${result.content.slice(0, 200)}`);
165
- }
166
- }
167
- }
168
-
169
- /** @implements {LLMProvider} */
170
- export class OpenAILLMProvider {
171
- /** @param {Partial<OpenAILLMConfig>} [config={}] */
172
- constructor({ apiKey, model = 'gpt-4o', maxTokens = 1024, timeout = 30000 } = {}) {
173
- this.apiKey = apiKey || process.env.OPENAI_API_KEY;
174
- this.model = model;
175
- this.maxTokens = maxTokens;
176
- this.timeout = timeout;
177
- this.modelName = model;
178
- this.modelVersion = 'latest';
179
- }
180
-
181
- /**
182
- * @param {ChatMessage[]} messages
183
- * @param {LLMCompletionOptions} [options={}]
184
- * @returns {Promise<LLMCompletionResult>}
185
- */
186
- async complete(messages, options = {}) {
187
- requireApiKey(this.apiKey, 'OpenAI LLM', 'OPENAI_API_KEY');
188
- const body = {
189
- model: this.model,
190
- max_tokens: options.maxTokens || this.maxTokens,
191
- messages,
192
- };
193
-
194
- const controller = new AbortController();
195
- const timer = setTimeout(() => controller.abort(), this.timeout);
196
- try {
197
- const response = await fetch('https://api.openai.com/v1/chat/completions', {
198
- method: 'POST',
199
- headers: {
200
- 'Authorization': `Bearer ${this.apiKey}`,
201
- 'Content-Type': 'application/json',
202
- },
203
- body: JSON.stringify(body),
204
- signal: controller.signal,
205
- });
206
-
207
- if (!response.ok) {
208
- throw new Error(`OpenAI API error: ${await describeHttpError(response)}`);
209
- }
210
-
211
- const data = await response.json();
212
- const text = data.choices?.[0]?.message?.content || '';
213
- return { content: text };
214
- } finally {
215
- clearTimeout(timer);
216
- }
217
- }
218
-
219
- /**
220
- * @param {ChatMessage[]} messages
221
- * @param {LLMCompletionOptions} [options={}]
222
- * @returns {Promise<Object>}
223
- */
224
- async json(messages, options = {}) {
225
- const result = await this.complete(messages, options);
226
- try {
227
- return JSON.parse(extractJSON(result.content));
228
- } catch {
229
- throw new Error(`Failed to parse LLM response as JSON: ${result.content.slice(0, 200)}`);
230
- }
231
- }
232
- }
233
-
234
- /**
235
- * @param {MockLLMConfig | AnthropicLLMConfig | OpenAILLMConfig} config
236
- * @returns {MockLLMProvider | AnthropicLLMProvider | OpenAILLMProvider}
237
- */
238
- export function createLLMProvider(config) {
239
- switch (config.provider) {
240
- case 'mock':
241
- return new MockLLMProvider(config);
242
- case 'anthropic':
243
- return new AnthropicLLMProvider(config);
244
- case 'openai':
245
- return new OpenAILLMProvider(config);
246
- default:
247
- throw new Error(`Unknown LLM provider: ${config.provider}. Valid: mock, anthropic, openai`);
248
- }
249
- }
package/src/migrate.js DELETED
@@ -1,58 +0,0 @@
1
- import { dropVec0Tables, createVec0Tables } from './db.js';
2
-
3
- export async function reembedAll(db, embeddingProvider, { dropAndRecreate = false } = {}) {
4
- if (dropAndRecreate) {
5
- dropVec0Tables(db);
6
- createVec0Tables(db, embeddingProvider.dimensions);
7
- }
8
-
9
- const episodes = db.prepare('SELECT id, content, source, consolidated FROM episodes').all();
10
- const semantics = db.prepare('SELECT id, content, state FROM semantics').all();
11
- const procedures = db.prepare('SELECT id, content, state FROM procedures').all();
12
-
13
- const episodeVectors = episodes.length > 0
14
- ? await embeddingProvider.embedBatch(episodes.map(ep => ep.content))
15
- : [];
16
- const semanticVectors = semantics.length > 0
17
- ? await embeddingProvider.embedBatch(semantics.map(s => s.content))
18
- : [];
19
- const procedureVectors = procedures.length > 0
20
- ? await embeddingProvider.embedBatch(procedures.map(p => p.content))
21
- : [];
22
-
23
- const updateEpLegacy = db.prepare('UPDATE episodes SET embedding = ? WHERE id = ?');
24
- const deleteVecEp = db.prepare('DELETE FROM vec_episodes WHERE id = ?');
25
- const insertVecEp = db.prepare('INSERT INTO vec_episodes(id, embedding, source, consolidated) VALUES (?, ?, ?, ?)');
26
-
27
- const updateSemLegacy = db.prepare('UPDATE semantics SET embedding = ? WHERE id = ?');
28
- const deleteVecSem = db.prepare('DELETE FROM vec_semantics WHERE id = ?');
29
- const insertVecSem = db.prepare('INSERT INTO vec_semantics(id, embedding, state) VALUES (?, ?, ?)');
30
-
31
- const updateProcLegacy = db.prepare('UPDATE procedures SET embedding = ? WHERE id = ?');
32
- const deleteVecProc = db.prepare('DELETE FROM vec_procedures WHERE id = ?');
33
- const insertVecProc = db.prepare('INSERT INTO vec_procedures(id, embedding, state) VALUES (?, ?, ?)');
34
-
35
- const writeTx = db.transaction(() => {
36
- for (let i = 0; i < episodes.length; i++) {
37
- const buf = embeddingProvider.vectorToBuffer(episodeVectors[i]);
38
- updateEpLegacy.run(buf, episodes[i].id);
39
- deleteVecEp.run(episodes[i].id);
40
- insertVecEp.run(episodes[i].id, buf, episodes[i].source, BigInt(episodes[i].consolidated ?? 0));
41
- }
42
- for (let i = 0; i < semantics.length; i++) {
43
- const buf = embeddingProvider.vectorToBuffer(semanticVectors[i]);
44
- updateSemLegacy.run(buf, semantics[i].id);
45
- deleteVecSem.run(semantics[i].id);
46
- insertVecSem.run(semantics[i].id, buf, semantics[i].state);
47
- }
48
- for (let i = 0; i < procedures.length; i++) {
49
- const buf = embeddingProvider.vectorToBuffer(procedureVectors[i]);
50
- updateProcLegacy.run(buf, procedures[i].id);
51
- deleteVecProc.run(procedures[i].id);
52
- insertVecProc.run(procedures[i].id, buf, procedures[i].state);
53
- }
54
- });
55
- writeTx();
56
-
57
- return { episodes: episodes.length, semantics: semantics.length, procedures: procedures.length };
58
- }