@aman_asmuei/amem 0.19.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 (85) hide show
  1. package/dist/cli.js +6 -7
  2. package/dist/cli.js.map +1 -1
  3. package/dist/dashboard.d.ts +1 -1
  4. package/dist/dashboard.js +1 -1
  5. package/dist/dashboard.js.map +1 -1
  6. package/dist/index.js +3 -7
  7. package/dist/index.js.map +1 -1
  8. package/dist/tools/advanced.d.ts +1 -1
  9. package/dist/tools/advanced.js +1 -5
  10. package/dist/tools/advanced.js.map +1 -1
  11. package/dist/tools/graph.d.ts +1 -1
  12. package/dist/tools/graph.js +1 -2
  13. package/dist/tools/graph.js.map +1 -1
  14. package/dist/tools/index.d.ts +2 -2
  15. package/dist/tools/index.js +2 -2
  16. package/dist/tools/index.js.map +1 -1
  17. package/dist/tools/log.d.ts +1 -1
  18. package/dist/tools/log.js +1 -2
  19. package/dist/tools/log.js.map +1 -1
  20. package/dist/tools/memory.d.ts +1 -2
  21. package/dist/tools/memory.js +16 -22
  22. package/dist/tools/memory.js.map +1 -1
  23. package/dist/tools/reminders.d.ts +1 -1
  24. package/dist/tools/reminders.js +4 -5
  25. package/dist/tools/reminders.js.map +1 -1
  26. package/dist/tools/versions.d.ts +1 -1
  27. package/dist/tools/versions.js +3 -4
  28. package/dist/tools/versions.js.map +1 -1
  29. package/dist/tools.test.js +1 -2
  30. package/dist/tools.test.js.map +1 -1
  31. package/package.json +3 -9
  32. package/dist/ann.d.ts +0 -26
  33. package/dist/ann.js +0 -155
  34. package/dist/ann.js.map +0 -1
  35. package/dist/auto-relate.d.ts +0 -14
  36. package/dist/auto-relate.js +0 -47
  37. package/dist/auto-relate.js.map +0 -1
  38. package/dist/config.d.ts +0 -51
  39. package/dist/config.js +0 -130
  40. package/dist/config.js.map +0 -1
  41. package/dist/database.d.ts +0 -165
  42. package/dist/database.js +0 -831
  43. package/dist/database.js.map +0 -1
  44. package/dist/database.test.d.ts +0 -1
  45. package/dist/database.test.js +0 -275
  46. package/dist/database.test.js.map +0 -1
  47. package/dist/doctor.d.ts +0 -23
  48. package/dist/doctor.js +0 -107
  49. package/dist/doctor.js.map +0 -1
  50. package/dist/embeddings.d.ts +0 -38
  51. package/dist/embeddings.js +0 -251
  52. package/dist/embeddings.js.map +0 -1
  53. package/dist/embeddings.test.d.ts +0 -1
  54. package/dist/embeddings.test.js +0 -106
  55. package/dist/embeddings.test.js.map +0 -1
  56. package/dist/extractor.d.ts +0 -13
  57. package/dist/extractor.js +0 -89
  58. package/dist/extractor.js.map +0 -1
  59. package/dist/memory.d.ts +0 -134
  60. package/dist/memory.js +0 -432
  61. package/dist/memory.js.map +0 -1
  62. package/dist/memory.test.d.ts +0 -1
  63. package/dist/memory.test.js +0 -172
  64. package/dist/memory.test.js.map +0 -1
  65. package/dist/query-expand.d.ts +0 -9
  66. package/dist/query-expand.js +0 -71
  67. package/dist/query-expand.js.map +0 -1
  68. package/dist/reflection.d.ts +0 -82
  69. package/dist/reflection.js +0 -414
  70. package/dist/reflection.js.map +0 -1
  71. package/dist/reflection.test.d.ts +0 -1
  72. package/dist/reflection.test.js +0 -453
  73. package/dist/reflection.test.js.map +0 -1
  74. package/dist/repair.d.ts +0 -8
  75. package/dist/repair.js +0 -90
  76. package/dist/repair.js.map +0 -1
  77. package/dist/schemas.d.ts +0 -1075
  78. package/dist/schemas.js +0 -311
  79. package/dist/schemas.js.map +0 -1
  80. package/dist/sync.d.ts +0 -85
  81. package/dist/sync.js +0 -304
  82. package/dist/sync.js.map +0 -1
  83. package/dist/tools/helpers.d.ts +0 -7
  84. package/dist/tools/helpers.js +0 -23
  85. package/dist/tools/helpers.js.map +0 -1
@@ -1,251 +0,0 @@
1
- export function cosineSimilarity(a, b) {
2
- let dot = 0;
3
- let normA = 0;
4
- let normB = 0;
5
- for (let i = 0; i < a.length; i++) {
6
- dot += a[i] * b[i];
7
- normA += a[i] * a[i];
8
- normB += b[i] * b[i];
9
- }
10
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
11
- if (denom === 0)
12
- return 0;
13
- return dot / denom;
14
- }
15
- export function findTopK(query, candidates, k) {
16
- const scored = candidates.map((c) => ({
17
- id: c.id,
18
- similarity: cosineSimilarity(query, c.embedding),
19
- data: c.data,
20
- }));
21
- scored.sort((a, b) => b.similarity - a.similarity);
22
- return scored.slice(0, k);
23
- }
24
- let pipelineInstance = null;
25
- let pipelineLoading = null;
26
- // LRU-style embedding cache to avoid recomputing identical queries
27
- const EMBEDDING_CACHE_MAX = 128;
28
- const embeddingCache = new Map();
29
- function cacheGet(key) {
30
- const val = embeddingCache.get(key);
31
- if (val) {
32
- // Move to end (most recently used)
33
- embeddingCache.delete(key);
34
- embeddingCache.set(key, val);
35
- }
36
- return val;
37
- }
38
- function cachePut(key, val) {
39
- if (embeddingCache.size >= EMBEDDING_CACHE_MAX) {
40
- // Evict oldest (first) entry
41
- const oldest = embeddingCache.keys().next().value;
42
- if (oldest !== undefined)
43
- embeddingCache.delete(oldest);
44
- }
45
- embeddingCache.set(key, val);
46
- }
47
- /** Skip embedding loading entirely (useful for CLI commands that need fast exit). */
48
- let embeddingDisabled = false;
49
- export function disableEmbeddings() {
50
- embeddingDisabled = true;
51
- }
52
- async function getEmbeddingPipeline() {
53
- if (embeddingDisabled)
54
- return null;
55
- if (pipelineInstance)
56
- return pipelineInstance;
57
- if (pipelineLoading)
58
- return pipelineLoading;
59
- pipelineLoading = (async () => {
60
- const LOAD_TIMEOUT_MS = 120000;
61
- async function attemptLoad() {
62
- console.error("[amem] Loading embedding model — this may take a moment on first run (downloading model)...");
63
- const startTime = Date.now();
64
- const loadPromise = (async () => {
65
- const { loadConfig } = await import("./config.js");
66
- const config = loadConfig();
67
- const mod = await import("@huggingface/transformers");
68
- return await mod.pipeline("feature-extraction", config.embeddingModel);
69
- })();
70
- // Log progress so the user knows we're still working
71
- const progressInterval = setInterval(() => {
72
- const elapsed = Math.round((Date.now() - startTime) / 1000);
73
- console.error(`[amem] Still loading embedding model... (${elapsed}s elapsed)`);
74
- }, 15000);
75
- try {
76
- return await Promise.race([
77
- loadPromise,
78
- new Promise((resolve) => setTimeout(() => resolve(null), LOAD_TIMEOUT_MS)),
79
- ]);
80
- }
81
- finally {
82
- clearInterval(progressInterval);
83
- }
84
- }
85
- try {
86
- const result = await attemptLoad();
87
- if (result) {
88
- pipelineInstance = result;
89
- console.error("[amem] Embedding model loaded — semantic search enabled");
90
- return pipelineInstance;
91
- }
92
- console.error("[amem] Embedding model load timed out after 120s — using keyword matching. Try running again once download completes.");
93
- return null;
94
- }
95
- catch (error) {
96
- const msg = error instanceof Error ? error.message : String(error);
97
- // If the cached model is corrupted, clear it and retry once
98
- if (msg.includes("Protobuf parsing failed") || msg.includes("invalid model")) {
99
- console.error("[amem] Corrupted model cache detected — clearing and retrying...");
100
- try {
101
- const fs = await import("node:fs");
102
- const path = await import("node:path");
103
- const os = await import("node:os");
104
- const { loadConfig } = await import("./config.js");
105
- const cfg = loadConfig();
106
- const modelParts = cfg.embeddingModel.split("/");
107
- const modelOrg = modelParts[0] ?? "Xenova";
108
- const modelName = modelParts[1] ?? cfg.embeddingModel;
109
- // Clear the HuggingFace cache for this model
110
- const cacheLocations = [
111
- path.join(os.homedir(), ".cache", "huggingface", "transformers", modelOrg, modelName),
112
- ];
113
- // Also try to find the cache inside node_modules
114
- try {
115
- const modPath = import.meta.resolve?.("@huggingface/transformers") ?? "";
116
- if (modPath) {
117
- const modDir = path.dirname(modPath.replace("file://", ""));
118
- cacheLocations.push(path.join(modDir, ".cache", modelOrg, modelName));
119
- }
120
- }
121
- catch { }
122
- for (const loc of cacheLocations) {
123
- if (fs.existsSync(loc)) {
124
- fs.rmSync(loc, { recursive: true, force: true });
125
- console.error(`[amem] Cleared cache: ${loc}`);
126
- }
127
- }
128
- // Retry once
129
- const retryResult = await attemptLoad();
130
- if (retryResult) {
131
- pipelineInstance = retryResult;
132
- console.error("[amem] Model re-downloaded successfully — semantic search enabled");
133
- return pipelineInstance;
134
- }
135
- }
136
- catch (retryError) {
137
- console.error("[amem] Cache recovery failed:", retryError instanceof Error ? retryError.message : String(retryError));
138
- }
139
- }
140
- console.error("[amem] Embeddings unavailable — using keyword matching (still works great!):", msg);
141
- console.error("[amem] To enable semantic search: npm install @huggingface/transformers");
142
- return null;
143
- }
144
- })();
145
- return pipelineLoading;
146
- }
147
- /**
148
- * Pre-warm the embedding pipeline in the background.
149
- * Call this at startup so the model is ready when the first query arrives.
150
- */
151
- export function preloadEmbeddings() {
152
- // Fire-and-forget — don't block startup
153
- getEmbeddingPipeline().catch(() => { });
154
- }
155
- export async function generateEmbedding(text) {
156
- // Check cache first
157
- const cached = cacheGet(text);
158
- if (cached)
159
- return cached;
160
- const extractor = await getEmbeddingPipeline();
161
- if (!extractor)
162
- return null;
163
- const result = await extractor(text, { pooling: "mean", normalize: true });
164
- const embedding = new Float32Array(result.data);
165
- cachePut(text, embedding);
166
- return embedding;
167
- }
168
- export async function isEmbeddingAvailable() {
169
- const extractor = await getEmbeddingPipeline();
170
- return extractor !== null;
171
- }
172
- let rerankerInstance = null;
173
- let rerankerLoading = null;
174
- let rerankerFailed = false;
175
- async function getCrossEncoderPipeline() {
176
- if (rerankerInstance)
177
- return rerankerInstance;
178
- if (rerankerFailed)
179
- return null;
180
- if (rerankerLoading)
181
- return rerankerLoading;
182
- rerankerLoading = (async () => {
183
- try {
184
- const mod = await import("@huggingface/transformers");
185
- const classifier = await mod.pipeline("text-classification", "Xenova/ms-marco-MiniLM-L-6-v2");
186
- rerankerInstance = async (texts) => {
187
- const results = [];
188
- // Process one at a time to avoid memory spikes
189
- for (const pair of texts) {
190
- const result = await classifier(pair.text, { text_pair: pair.text_pair, topk: 1 });
191
- const arr = Array.isArray(result) ? result : [result];
192
- results.push(arr);
193
- }
194
- return results;
195
- };
196
- return rerankerInstance;
197
- }
198
- catch (error) {
199
- console.error("[amem] Cross-encoder reranker unavailable — skipping rerank step:", error instanceof Error ? error.message : String(error));
200
- rerankerFailed = true;
201
- return null;
202
- }
203
- })();
204
- return rerankerLoading;
205
- }
206
- /**
207
- * Cross-encoder reranking: takes a query and a list of candidates,
208
- * scores each (query, candidate) pair with a cross-encoder model,
209
- * and returns candidates re-sorted by cross-encoder score.
210
- *
211
- * This is the final pass in the retrieval pipeline — after semantic + FTS + graph
212
- * have produced candidates, the cross-encoder provides the most accurate scoring
213
- * by attending to the full (query, document) pair jointly.
214
- *
215
- * Falls back to original scores if the cross-encoder model isn't available.
216
- */
217
- export async function rerankWithCrossEncoder(query, candidates, topK) {
218
- if (candidates.length === 0)
219
- return [];
220
- if (candidates.length <= 1)
221
- return candidates;
222
- const scorer = await getCrossEncoderPipeline();
223
- if (!scorer) {
224
- // Fallback: return candidates as-is (already sorted by multi-strategy score)
225
- return candidates.slice(0, topK);
226
- }
227
- try {
228
- const pairs = candidates.map(c => ({
229
- text: query,
230
- text_pair: c.content.slice(0, 512), // Truncate long docs for cross-encoder
231
- }));
232
- const scores = await scorer(pairs);
233
- // Merge cross-encoder scores with candidates
234
- const reranked = candidates.map((c, i) => {
235
- // Cross-encoder outputs relevance score; higher = more relevant
236
- const ceScore = scores[i]?.[0]?.score ?? 0;
237
- return { ...c, score: ceScore };
238
- });
239
- reranked.sort((a, b) => b.score - a.score);
240
- return reranked.slice(0, topK);
241
- }
242
- catch (error) {
243
- console.error("[amem] Cross-encoder reranking failed, using original scores:", error instanceof Error ? error.message : String(error));
244
- return candidates.slice(0, topK);
245
- }
246
- }
247
- export async function isRerankerAvailable() {
248
- const scorer = await getCrossEncoderPipeline();
249
- return scorer !== null;
250
- }
251
- //# sourceMappingURL=embeddings.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embeddings.js","sourceRoot":"","sources":["../src/embeddings.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,106 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { cosineSimilarity, findTopK } from "./embeddings.js";
3
- describe("cosineSimilarity", () => {
4
- it("returns 1.0 for identical normalized vectors", () => {
5
- const v = new Float32Array([1 / Math.sqrt(2), 1 / Math.sqrt(2)]);
6
- expect(cosineSimilarity(v, v)).toBeCloseTo(1.0, 5);
7
- });
8
- it("returns 0 for orthogonal vectors", () => {
9
- const a = new Float32Array([1, 0]);
10
- const b = new Float32Array([0, 1]);
11
- expect(cosineSimilarity(a, b)).toBeCloseTo(0, 5);
12
- });
13
- it("returns -1 for opposite vectors", () => {
14
- const a = new Float32Array([1, 0]);
15
- const b = new Float32Array([-1, 0]);
16
- expect(cosineSimilarity(a, b)).toBeCloseTo(-1.0, 5);
17
- });
18
- it("returns 0 when a is a zero vector", () => {
19
- const a = new Float32Array([0, 0, 0]);
20
- const b = new Float32Array([1, 2, 3]);
21
- expect(cosineSimilarity(a, b)).toBe(0);
22
- });
23
- it("returns 0 when b is a zero vector", () => {
24
- const a = new Float32Array([1, 2, 3]);
25
- const b = new Float32Array([0, 0, 0]);
26
- expect(cosineSimilarity(a, b)).toBe(0);
27
- });
28
- it("returns 0 when both are zero vectors", () => {
29
- const a = new Float32Array([0, 0]);
30
- const b = new Float32Array([0, 0]);
31
- expect(cosineSimilarity(a, b)).toBe(0);
32
- });
33
- it("computes correct similarity for known vectors", () => {
34
- // [1, 2, 3] and [4, 5, 6]
35
- // dot = 4+10+18 = 32, normA = sqrt(14), normB = sqrt(77)
36
- // similarity = 32 / (sqrt(14) * sqrt(77)) = 32 / sqrt(1078)
37
- const a = new Float32Array([1, 2, 3]);
38
- const b = new Float32Array([4, 5, 6]);
39
- const expected = 32 / (Math.sqrt(14) * Math.sqrt(77));
40
- expect(cosineSimilarity(a, b)).toBeCloseTo(expected, 5);
41
- });
42
- it("is symmetric: sim(a,b) === sim(b,a)", () => {
43
- const a = new Float32Array([0.3, 0.7, 0.1]);
44
- const b = new Float32Array([0.5, 0.2, 0.9]);
45
- expect(cosineSimilarity(a, b)).toBeCloseTo(cosineSimilarity(b, a), 10);
46
- });
47
- it("handles single-element vectors", () => {
48
- const a = new Float32Array([3]);
49
- const b = new Float32Array([5]);
50
- expect(cosineSimilarity(a, b)).toBeCloseTo(1.0, 5);
51
- });
52
- it("handles negative values correctly", () => {
53
- const a = new Float32Array([-1, -2]);
54
- const b = new Float32Array([-1, -2]);
55
- expect(cosineSimilarity(a, b)).toBeCloseTo(1.0, 5);
56
- });
57
- });
58
- describe("findTopK", () => {
59
- it("returns top K most similar candidates", () => {
60
- const query = new Float32Array([1, 0, 0]);
61
- const candidates = [
62
- { id: "a", embedding: new Float32Array([1, 0, 0]), data: "exact" },
63
- { id: "b", embedding: new Float32Array([0, 1, 0]), data: "orthogonal" },
64
- { id: "c", embedding: new Float32Array([0.9, 0.1, 0]), data: "close" },
65
- ];
66
- const results = findTopK(query, candidates, 2);
67
- expect(results).toHaveLength(2);
68
- expect(results[0].id).toBe("a"); // exact match
69
- expect(results[1].id).toBe("c"); // close match
70
- expect(results[0].similarity).toBeGreaterThan(results[1].similarity);
71
- });
72
- it("returns all candidates when k > candidates.length", () => {
73
- const query = new Float32Array([1, 0]);
74
- const candidates = [
75
- { id: "a", embedding: new Float32Array([1, 0]), data: "x" },
76
- ];
77
- const results = findTopK(query, candidates, 5);
78
- expect(results).toHaveLength(1);
79
- });
80
- it("returns empty array for empty candidates", () => {
81
- const query = new Float32Array([1, 0]);
82
- const results = findTopK(query, [], 5);
83
- expect(results).toHaveLength(0);
84
- });
85
- it("preserves data field in results", () => {
86
- const query = new Float32Array([1, 0]);
87
- const candidates = [
88
- { id: "a", embedding: new Float32Array([1, 0]), data: { foo: "bar" } },
89
- ];
90
- const results = findTopK(query, candidates, 1);
91
- expect(results[0].data).toEqual({ foo: "bar" });
92
- });
93
- it("sorts results by descending similarity", () => {
94
- const query = new Float32Array([1, 0, 0]);
95
- const candidates = [
96
- { id: "low", embedding: new Float32Array([0, 0, 1]), data: 1 },
97
- { id: "high", embedding: new Float32Array([1, 0, 0]), data: 2 },
98
- { id: "mid", embedding: new Float32Array([0.7, 0.7, 0]), data: 3 },
99
- ];
100
- const results = findTopK(query, candidates, 3);
101
- for (let i = 0; i < results.length - 1; i++) {
102
- expect(results[i].similarity).toBeGreaterThanOrEqual(results[i + 1].similarity);
103
- }
104
- });
105
- });
106
- //# sourceMappingURL=embeddings.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embeddings.test.js","sourceRoot":"","sources":["../src/embeddings.test.ts"],"names":[],"mappings":"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"}
@@ -1,13 +0,0 @@
1
- import type { MemoryTypeValue } from "./memory.js";
2
- export interface ConversationTurn {
3
- role: "user" | "assistant" | "system";
4
- content: string;
5
- }
6
- export interface ExtractedMemory {
7
- content: string;
8
- type: MemoryTypeValue;
9
- confidence: number;
10
- tags: string[];
11
- source: string;
12
- }
13
- export declare function extractMemories(turns: ConversationTurn[]): ExtractedMemory[];
package/dist/extractor.js DELETED
@@ -1,89 +0,0 @@
1
- const EXTRACTION_PATTERNS = [
2
- // Corrections — user telling the AI "don't do X" or "always do Y"
3
- {
4
- type: "correction",
5
- patterns: [
6
- /\b(?:don'?t|never|stop|no,?\s+(?:don'?t|never|not))\b.*\b(?:use|do|add|include|write|put|make|create)\b/i,
7
- /\b(?:always|must|should always|never ever)\b.*\b(?:use|do|add|include|write|make)\b/i,
8
- /\bthat'?s (?:wrong|incorrect|not right)\b/i,
9
- /\bno,?\s+(?:that|this|it) (?:should|needs to|must)\b/i,
10
- ],
11
- confidence: 0.95,
12
- roles: ["user"],
13
- },
14
- // Decisions — "we decided", "let's go with", "the approach is"
15
- {
16
- type: "decision",
17
- patterns: [
18
- /\b(?:we (?:decided|chose|agreed)|let'?s (?:go with|use|stick with))\b/i,
19
- /\b(?:the (?:decision|approach|plan|strategy) is)\b/i,
20
- /\b(?:we'?re (?:going to|gonna)|we'll)\b.*\b(?:use|switch to|migrate to|adopt)\b/i,
21
- ],
22
- confidence: 0.85,
23
- roles: ["user"],
24
- },
25
- // Preferences — "I prefer", "I like to", "I want"
26
- {
27
- type: "preference",
28
- patterns: [
29
- /\bi (?:prefer|like to|want(?:ed)? to|tend to)\b/i,
30
- /\bmy (?:preference|style|approach|convention) is\b/i,
31
- /\bplease (?:always|use|keep|make sure)\b/i,
32
- ],
33
- confidence: 0.8,
34
- roles: ["user"],
35
- },
36
- // Patterns — "in this project we", "our convention is"
37
- {
38
- type: "pattern",
39
- patterns: [
40
- /\b(?:in this (?:project|repo|codebase)|our (?:convention|standard|pattern|practice))\b/i,
41
- /\bwe (?:usually|typically|always|normally)\b/i,
42
- /\bthe (?:convention|standard|pattern|practice) (?:here |in this )?is\b/i,
43
- ],
44
- confidence: 0.7,
45
- roles: ["user"],
46
- },
47
- // Topology — "X is in", "you can find X at"
48
- {
49
- type: "topology",
50
- patterns: [
51
- /\b(?:you(?:'ll| can| will)? find|(?:it|that|the \w+) (?:is|lives|sits) (?:in|at|under))\b.*(?:src\/|lib\/|config\/|\.\w+)/i,
52
- /\b(?:the (?:config|settings|env|database|api|routes?) (?:is|are|lives?) (?:in|at))\b/i,
53
- ],
54
- confidence: 0.7,
55
- roles: ["user"],
56
- },
57
- ];
58
- export function extractMemories(turns) {
59
- const extracted = [];
60
- for (const turn of turns) {
61
- const text = turn.content.trim();
62
- // Skip questions — they express uncertainty, not assertions
63
- if (text.endsWith("?"))
64
- continue;
65
- // Skip very short messages — not enough signal
66
- if (text.length < 15)
67
- continue;
68
- for (const pattern of EXTRACTION_PATTERNS) {
69
- if (!pattern.roles.includes(turn.role))
70
- continue;
71
- for (const regex of pattern.patterns) {
72
- if (regex.test(text)) {
73
- if (extracted.some(e => e.content === text))
74
- break;
75
- extracted.push({
76
- content: text,
77
- type: pattern.type,
78
- confidence: pattern.confidence,
79
- tags: ["auto-extracted"],
80
- source: "conversation-extractor",
81
- });
82
- break;
83
- }
84
- }
85
- }
86
- }
87
- return extracted;
88
- }
89
- //# sourceMappingURL=extractor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAsBA,MAAM,mBAAmB,GAAc;IACrC,kEAAkE;IAClE;QACE,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,0GAA0G;YAC1G,sFAAsF;YACtF,4CAA4C;YAC5C,uDAAuD;SACxD;QACD,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,CAAC,MAAM,CAAC;KAChB;IACD,+DAA+D;IAC/D;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,wEAAwE;YACxE,qDAAqD;YACrD,kFAAkF;SACnF;QACD,UAAU,EAAE,IAAI;QAChB,KAAK,EAAE,CAAC,MAAM,CAAC;KAChB;IACD,kDAAkD;IAClD;QACE,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE;YACR,kDAAkD;YAClD,qDAAqD;YACrD,2CAA2C;SAC5C;QACD,UAAU,EAAE,GAAG;QACf,KAAK,EAAE,CAAC,MAAM,CAAC;KAChB;IACD,uDAAuD;IACvD;QACE,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE;YACR,yFAAyF;YACzF,+CAA+C;YAC/C,yEAAyE;SAC1E;QACD,UAAU,EAAE,GAAG;QACf,KAAK,EAAE,CAAC,MAAM,CAAC;KAChB;IACD,4CAA4C;IAC5C;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,4HAA4H;YAC5H,uFAAuF;SACxF;QACD,UAAU,EAAE,GAAG;QACf,KAAK,EAAE,CAAC,MAAM,CAAC;KAChB;CACF,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAAyB;IACvD,MAAM,SAAS,GAAsB,EAAE,CAAC;IAExC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,4DAA4D;QAC5D,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,+CAA+C;QAC/C,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;YAAE,SAAS;QAE/B,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;YAC1C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEjD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrB,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC;wBAAE,MAAM;oBAEnD,SAAS,CAAC,IAAI,CAAC;wBACb,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE,OAAO,CAAC,IAAI;wBAClB,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC9B,IAAI,EAAE,CAAC,gBAAgB,CAAC;wBACxB,MAAM,EAAE,wBAAwB;qBACjC,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/dist/memory.d.ts DELETED
@@ -1,134 +0,0 @@
1
- import type { AmemDatabase } from "./database.js";
2
- import { VectorIndex } from "./ann.js";
3
- export declare const MemoryType: {
4
- readonly CORRECTION: "correction";
5
- readonly DECISION: "decision";
6
- readonly PATTERN: "pattern";
7
- readonly PREFERENCE: "preference";
8
- readonly TOPOLOGY: "topology";
9
- readonly FACT: "fact";
10
- };
11
- export type MemoryTypeValue = (typeof MemoryType)[keyof typeof MemoryType];
12
- export declare const IMPORTANCE_WEIGHTS: Record<MemoryTypeValue, number>;
13
- export interface Memory {
14
- id: string;
15
- content: string;
16
- type: MemoryTypeValue;
17
- tags: string[];
18
- confidence: number;
19
- accessCount: number;
20
- createdAt: number;
21
- lastAccessed: number;
22
- source: string;
23
- embedding: Float32Array | null;
24
- scope: string;
25
- validFrom: number;
26
- validUntil: number | null;
27
- tier: 'core' | 'working' | 'archival';
28
- utilityScore: number;
29
- }
30
- export interface ScoreInput {
31
- relevance: number;
32
- confidence: number;
33
- lastAccessed: number;
34
- importance: number;
35
- now: number;
36
- }
37
- export declare function computeScore(input: ScoreInput): number;
38
- export interface ConflictResult {
39
- isConflict: boolean;
40
- similarity: number;
41
- }
42
- export declare function detectConflict(newContent: string, existingContent: string, similarity: number): ConflictResult;
43
- export interface RecallOptions {
44
- query: string | null;
45
- queryEmbedding?: Float32Array | null;
46
- limit: number;
47
- type?: MemoryTypeValue;
48
- tag?: string;
49
- minConfidence?: number;
50
- scope?: string;
51
- explain?: boolean;
52
- /** Filter out expired memories (valid_until < now). Default: true */
53
- filterExpired?: boolean;
54
- /** Only return memories from this tier */
55
- tier?: Memory["tier"];
56
- }
57
- export interface RecalledMemory extends Memory {
58
- score: number;
59
- }
60
- export interface ScoreExplanation {
61
- relevance: number;
62
- relevanceSource: "semantic" | "keyword" | "default";
63
- recency: number;
64
- hoursSinceAccess: number;
65
- confidence: number;
66
- importance: number;
67
- importanceLabel: string;
68
- finalScore: number;
69
- }
70
- export interface ExplainedMemory extends RecalledMemory {
71
- explanation: ScoreExplanation;
72
- }
73
- export declare function recallMemories(db: AmemDatabase, options: RecallOptions): (RecalledMemory | ExplainedMemory)[];
74
- export interface ConsolidationOptions {
75
- maxStaleDays: number;
76
- minConfidence: number;
77
- minAccessCount: number;
78
- dryRun: boolean;
79
- enableDecay?: boolean;
80
- decayFactor?: number;
81
- }
82
- export interface ConsolidationAction {
83
- action: "merged" | "pruned" | "promoted" | "decayed";
84
- memoryIds: string[];
85
- description: string;
86
- }
87
- export interface ConsolidationReport {
88
- merged: number;
89
- pruned: number;
90
- promoted: number;
91
- decayed: number;
92
- actions: ConsolidationAction[];
93
- healthScore: number;
94
- before: {
95
- total: number;
96
- };
97
- after: {
98
- total: number;
99
- };
100
- }
101
- export declare function consolidateMemories(db: AmemDatabase, cosineSim: (a: Float32Array, b: Float32Array) => number, options: ConsolidationOptions): ConsolidationReport;
102
- export declare function buildVectorIndex(db: AmemDatabase): VectorIndex;
103
- export declare function getVectorIndex(): VectorIndex | null;
104
- export interface MultiStrategyOptions {
105
- query: string;
106
- queryEmbedding: Float32Array | null;
107
- limit: number;
108
- scope?: string;
109
- weights?: {
110
- semantic: number;
111
- fts: number;
112
- graph: number;
113
- temporal: number;
114
- };
115
- /** Enable cross-encoder reranking as the final pass. Default: false (uses config). */
116
- rerank?: boolean;
117
- /** How many candidates to feed to the reranker. Default: 20. */
118
- rerankerTopK?: number;
119
- }
120
- /**
121
- * Multi-strategy retrieval: combines semantic search, FTS5, knowledge graph traversal,
122
- * and temporal recency into a unified ranking. Each strategy votes independently,
123
- * then scores are merged with configurable weights.
124
- */
125
- export declare function multiStrategyRecall(db: AmemDatabase, options: MultiStrategyOptions): Promise<RecalledMemory[]>;
126
- /**
127
- * When storing a new memory that contradicts an existing one,
128
- * auto-expire the old memory instead of requiring manual consolidation.
129
- */
130
- export declare function autoExpireContradictions(db: AmemDatabase, newContent: string, newEmbedding: Float32Array | null, newType: MemoryTypeValue): {
131
- expired: string[];
132
- reason: string;
133
- };
134
- export { sanitizeContent } from "./config.js";