@mneme-ai/core 0.22.2 → 0.24.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/dist/htc/abstract.d.ts +41 -0
- package/dist/htc/abstract.d.ts.map +1 -0
- package/dist/htc/abstract.js +97 -0
- package/dist/htc/abstract.js.map +1 -0
- package/dist/htc/abstract.test.d.ts +2 -0
- package/dist/htc/abstract.test.d.ts.map +1 -0
- package/dist/htc/abstract.test.js +169 -0
- package/dist/htc/abstract.test.js.map +1 -0
- package/dist/htc/clusters.d.ts +38 -0
- package/dist/htc/clusters.d.ts.map +1 -0
- package/dist/htc/clusters.js +103 -0
- package/dist/htc/clusters.js.map +1 -0
- package/dist/htc/clusters.test.d.ts +2 -0
- package/dist/htc/clusters.test.d.ts.map +1 -0
- package/dist/htc/clusters.test.js +128 -0
- package/dist/htc/clusters.test.js.map +1 -0
- package/dist/htc/index.d.ts +16 -0
- package/dist/htc/index.d.ts.map +1 -0
- package/dist/htc/index.js +16 -0
- package/dist/htc/index.js.map +1 -0
- package/dist/htc/memoir.d.ts +27 -0
- package/dist/htc/memoir.d.ts.map +1 -0
- package/dist/htc/memoir.js +50 -0
- package/dist/htc/memoir.js.map +1 -0
- package/dist/htc/memoir.test.d.ts +2 -0
- package/dist/htc/memoir.test.d.ts.map +1 -0
- package/dist/htc/memoir.test.js +87 -0
- package/dist/htc/memoir.test.js.map +1 -0
- package/dist/htc/storage.d.ts +24 -0
- package/dist/htc/storage.d.ts.map +1 -0
- package/dist/htc/storage.js +170 -0
- package/dist/htc/storage.js.map +1 -0
- package/dist/htc/storage.test.d.ts +2 -0
- package/dist/htc/storage.test.d.ts.map +1 -0
- package/dist/htc/storage.test.js +327 -0
- package/dist/htc/storage.test.js.map +1 -0
- package/dist/htc/types.d.ts +86 -0
- package/dist/htc/types.d.ts.map +1 -0
- package/dist/htc/types.js +22 -0
- package/dist/htc/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/retrieve/ddtree.d.ts +67 -0
- package/dist/retrieve/ddtree.d.ts.map +1 -0
- package/dist/retrieve/ddtree.js +156 -0
- package/dist/retrieve/ddtree.js.map +1 -0
- package/dist/retrieve/ddtree.test.d.ts +2 -0
- package/dist/retrieve/ddtree.test.d.ts.map +1 -0
- package/dist/retrieve/ddtree.test.js +181 -0
- package/dist/retrieve/ddtree.test.js.map +1 -0
- package/dist/retrieve/index.d.ts +3 -0
- package/dist/retrieve/index.d.ts.map +1 -1
- package/dist/retrieve/index.js +3 -0
- package/dist/retrieve/index.js.map +1 -1
- package/dist/retrieve/leviathan.d.ts +68 -0
- package/dist/retrieve/leviathan.d.ts.map +1 -0
- package/dist/retrieve/leviathan.js +192 -0
- package/dist/retrieve/leviathan.js.map +1 -0
- package/dist/retrieve/leviathan.test.d.ts +2 -0
- package/dist/retrieve/leviathan.test.d.ts.map +1 -0
- package/dist/retrieve/leviathan.test.js +124 -0
- package/dist/retrieve/leviathan.test.js.map +1 -0
- package/dist/retrieve/search.d.ts +7 -0
- package/dist/retrieve/search.d.ts.map +1 -1
- package/dist/retrieve/search.js +31 -3
- package/dist/retrieve/search.js.map +1 -1
- package/dist/retrieve/stream.d.ts +93 -0
- package/dist/retrieve/stream.d.ts.map +1 -0
- package/dist/retrieve/stream.js +52 -0
- package/dist/retrieve/stream.js.map +1 -0
- package/dist/retrieve/stream.test.d.ts +2 -0
- package/dist/retrieve/stream.test.d.ts.map +1 -0
- package/dist/retrieve/stream.test.js +118 -0
- package/dist/retrieve/stream.test.js.map +1 -0
- package/dist/retrieve/synthesize.d.ts +7 -0
- package/dist/retrieve/synthesize.d.ts.map +1 -1
- package/dist/retrieve/synthesize.js +48 -2
- package/dist/retrieve/synthesize.js.map +1 -1
- package/dist/store/schema.d.ts +3 -2
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +42 -1
- package/dist/store/schema.js.map +1 -1
- package/dist/store/sqlite.test.js +1 -1
- package/dist/util/constraint-pruner.d.ts +76 -0
- package/dist/util/constraint-pruner.d.ts.map +1 -0
- package/dist/util/constraint-pruner.js +89 -0
- package/dist/util/constraint-pruner.js.map +1 -0
- package/dist/util/constraint-pruner.test.d.ts +2 -0
- package/dist/util/constraint-pruner.test.d.ts.map +1 -0
- package/dist/util/constraint-pruner.test.js +101 -0
- package/dist/util/constraint-pruner.test.js.map +1 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +1 -0
- package/dist/util/index.js.map +1 -1
- package/dist/wisdom/index.d.ts +2 -0
- package/dist/wisdom/index.d.ts.map +1 -1
- package/dist/wisdom/index.js +2 -0
- package/dist/wisdom/index.js.map +1 -1
- package/dist/wisdom/mutant-adapt.d.ts +69 -0
- package/dist/wisdom/mutant-adapt.d.ts.map +1 -0
- package/dist/wisdom/mutant-adapt.js +216 -0
- package/dist/wisdom/mutant-adapt.js.map +1 -0
- package/dist/wisdom/mutant-adapt.test.d.ts +2 -0
- package/dist/wisdom/mutant-adapt.test.d.ts.map +1 -0
- package/dist/wisdom/mutant-adapt.test.js +184 -0
- package/dist/wisdom/mutant-adapt.test.js.map +1 -0
- package/dist/wisdom/session.d.ts +60 -0
- package/dist/wisdom/session.d.ts.map +1 -0
- package/dist/wisdom/session.js +193 -0
- package/dist/wisdom/session.js.map +1 -0
- package/dist/wisdom/session.test.d.ts +2 -0
- package/dist/wisdom/session.test.d.ts.map +1 -0
- package/dist/wisdom/session.test.js +161 -0
- package/dist/wisdom/session.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { MnemeStore } from "../store/sqlite.js";
|
|
6
|
+
import { upsertAbstract, upsertAbstracts, getAbstract, getAllAbstracts, deleteOldAbstracts, upsertClusterSummary, getAllClusterSummaries, upsertMemoir, getMemoir, getHtcStats, } from "./storage.js";
|
|
7
|
+
let tmpDir;
|
|
8
|
+
let store;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tmpDir = mkdtempSync(join(tmpdir(), "mneme-htc-storage-"));
|
|
11
|
+
store = new MnemeStore(join(tmpDir, "mneme.db"));
|
|
12
|
+
});
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
store.close();
|
|
15
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
16
|
+
});
|
|
17
|
+
const seedCommit = (over = {}) => ({
|
|
18
|
+
hash: "c".repeat(40),
|
|
19
|
+
shortHash: "ccccccc",
|
|
20
|
+
authorName: "Alice",
|
|
21
|
+
authorEmail: "a@x.io",
|
|
22
|
+
authorDate: "2025-01-01T00:00:00Z",
|
|
23
|
+
committerDate: "2025-01-01T00:00:00Z",
|
|
24
|
+
subject: "test commit",
|
|
25
|
+
body: "some body text",
|
|
26
|
+
parents: [],
|
|
27
|
+
files: ["src/foo.ts"],
|
|
28
|
+
...over,
|
|
29
|
+
});
|
|
30
|
+
describe("HTC storage — schema migration", () => {
|
|
31
|
+
it("bumps schema_version to 4", () => {
|
|
32
|
+
expect(store.getMeta("schema_version")).toBe("4");
|
|
33
|
+
});
|
|
34
|
+
it("creates htc_abstracts, htc_clusters, htc_memoir tables", () => {
|
|
35
|
+
const tables = store.db
|
|
36
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
|
|
37
|
+
.all();
|
|
38
|
+
const names = tables.map((t) => t.name);
|
|
39
|
+
expect(names).toContain("htc_abstracts");
|
|
40
|
+
expect(names).toContain("htc_clusters");
|
|
41
|
+
expect(names).toContain("htc_memoir");
|
|
42
|
+
});
|
|
43
|
+
it("migration is idempotent — re-opening doesn't error or duplicate", () => {
|
|
44
|
+
store.close();
|
|
45
|
+
// Re-open same DB; should succeed without throwing.
|
|
46
|
+
store = new MnemeStore(join(tmpDir, "mneme.db"));
|
|
47
|
+
expect(store.getMeta("schema_version")).toBe("4");
|
|
48
|
+
// Re-open AGAIN to be sure.
|
|
49
|
+
store.close();
|
|
50
|
+
store = new MnemeStore(join(tmpDir, "mneme.db"));
|
|
51
|
+
expect(store.getMeta("schema_version")).toBe("4");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe("HTC storage — Layer 1 abstracts", () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
store.upsertCommits([seedCommit({ hash: "a".repeat(40) })]);
|
|
57
|
+
});
|
|
58
|
+
it("upsertAbstract round-trips", () => {
|
|
59
|
+
upsertAbstract(store, {
|
|
60
|
+
hash: "a".repeat(40),
|
|
61
|
+
abstract: "auth: replaced session cookies with JWT for stateless deploys",
|
|
62
|
+
tokenCount: 12,
|
|
63
|
+
generationMs: 350,
|
|
64
|
+
generator: "ollama:qwen2.5:3b",
|
|
65
|
+
generatedAt: "2025-05-01T00:00:00.000Z",
|
|
66
|
+
});
|
|
67
|
+
const got = getAbstract(store, "a".repeat(40));
|
|
68
|
+
expect(got).not.toBeNull();
|
|
69
|
+
expect(got.abstract).toContain("JWT");
|
|
70
|
+
expect(got.tokenCount).toBe(12);
|
|
71
|
+
expect(got.generator).toBe("ollama:qwen2.5:3b");
|
|
72
|
+
expect(got.generatedAt).toBe("2025-05-01T00:00:00.000Z");
|
|
73
|
+
});
|
|
74
|
+
it("upsertAbstract is idempotent (re-insert overwrites)", () => {
|
|
75
|
+
const base = {
|
|
76
|
+
hash: "a".repeat(40),
|
|
77
|
+
abstract: "first version",
|
|
78
|
+
tokenCount: 2,
|
|
79
|
+
generationMs: 100,
|
|
80
|
+
generator: "ollama:qwen2.5:3b",
|
|
81
|
+
generatedAt: "2025-05-01T00:00:00.000Z",
|
|
82
|
+
};
|
|
83
|
+
upsertAbstract(store, base);
|
|
84
|
+
upsertAbstract(store, { ...base, abstract: "second version", tokenCount: 3 });
|
|
85
|
+
const got = getAbstract(store, "a".repeat(40));
|
|
86
|
+
expect(got.abstract).toBe("second version");
|
|
87
|
+
expect(got.tokenCount).toBe(3);
|
|
88
|
+
// Still only one row.
|
|
89
|
+
const count = store.db.prepare("SELECT COUNT(*) AS n FROM htc_abstracts").get().n;
|
|
90
|
+
expect(count).toBe(1);
|
|
91
|
+
});
|
|
92
|
+
it("upsertAbstracts batch round-trips", () => {
|
|
93
|
+
store.upsertCommits([
|
|
94
|
+
seedCommit({ hash: "b".repeat(40) }),
|
|
95
|
+
seedCommit({ hash: "d".repeat(40) }),
|
|
96
|
+
]);
|
|
97
|
+
upsertAbstracts(store, [
|
|
98
|
+
{
|
|
99
|
+
hash: "a".repeat(40),
|
|
100
|
+
abstract: "alpha",
|
|
101
|
+
tokenCount: 1,
|
|
102
|
+
generationMs: 10,
|
|
103
|
+
generator: "test",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
hash: "b".repeat(40),
|
|
107
|
+
abstract: "bravo",
|
|
108
|
+
tokenCount: 1,
|
|
109
|
+
generationMs: 10,
|
|
110
|
+
generator: "test",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
hash: "d".repeat(40),
|
|
114
|
+
abstract: "delta",
|
|
115
|
+
tokenCount: 1,
|
|
116
|
+
generationMs: 10,
|
|
117
|
+
generator: "test",
|
|
118
|
+
},
|
|
119
|
+
]);
|
|
120
|
+
const all = getAllAbstracts(store);
|
|
121
|
+
expect(all.size).toBe(3);
|
|
122
|
+
expect(all.get("b".repeat(40)).abstract).toBe("bravo");
|
|
123
|
+
});
|
|
124
|
+
it("getAbstract returns null for missing commit", () => {
|
|
125
|
+
expect(getAbstract(store, "f".repeat(40))).toBeNull();
|
|
126
|
+
});
|
|
127
|
+
it("deleteOldAbstracts removes rows older than cutoff", () => {
|
|
128
|
+
upsertAbstract(store, {
|
|
129
|
+
hash: "a".repeat(40),
|
|
130
|
+
abstract: "old",
|
|
131
|
+
tokenCount: 1,
|
|
132
|
+
generationMs: 1,
|
|
133
|
+
generator: "test",
|
|
134
|
+
generatedAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
135
|
+
});
|
|
136
|
+
const removed = deleteOldAbstracts(store, 7);
|
|
137
|
+
expect(removed).toBe(1);
|
|
138
|
+
expect(getAbstract(store, "a".repeat(40))).toBeNull();
|
|
139
|
+
});
|
|
140
|
+
it("deleteOldAbstracts keeps fresh rows", () => {
|
|
141
|
+
upsertAbstract(store, {
|
|
142
|
+
hash: "a".repeat(40),
|
|
143
|
+
abstract: "fresh",
|
|
144
|
+
tokenCount: 1,
|
|
145
|
+
generationMs: 1,
|
|
146
|
+
generator: "test",
|
|
147
|
+
generatedAt: new Date().toISOString(),
|
|
148
|
+
});
|
|
149
|
+
expect(deleteOldAbstracts(store, 7)).toBe(0);
|
|
150
|
+
});
|
|
151
|
+
it("ON DELETE CASCADE removes abstracts when commit is deleted", () => {
|
|
152
|
+
upsertAbstract(store, {
|
|
153
|
+
hash: "a".repeat(40),
|
|
154
|
+
abstract: "x",
|
|
155
|
+
tokenCount: 1,
|
|
156
|
+
generationMs: 1,
|
|
157
|
+
generator: "test",
|
|
158
|
+
});
|
|
159
|
+
store.db.prepare("DELETE FROM commits WHERE hash = ?").run("a".repeat(40));
|
|
160
|
+
expect(getAbstract(store, "a".repeat(40))).toBeNull();
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe("HTC storage — Layer 2 clusters", () => {
|
|
164
|
+
it("upsertClusterSummary round-trips with JSON memberHashes", () => {
|
|
165
|
+
upsertClusterSummary(store, {
|
|
166
|
+
clusterId: "c1",
|
|
167
|
+
label: "auth refactor",
|
|
168
|
+
summary: "Group of auth-related commits…",
|
|
169
|
+
memberHashes: ["aaa", "bbb", "ccc"],
|
|
170
|
+
tokenCount: 50,
|
|
171
|
+
generationMs: 1200,
|
|
172
|
+
generator: "groq:llama-3.3-70b",
|
|
173
|
+
generatedAt: "2025-05-01T00:00:00.000Z",
|
|
174
|
+
});
|
|
175
|
+
const all = getAllClusterSummaries(store);
|
|
176
|
+
expect(all).toHaveLength(1);
|
|
177
|
+
expect(all[0].label).toBe("auth refactor");
|
|
178
|
+
expect(all[0].memberHashes).toEqual(["aaa", "bbb", "ccc"]);
|
|
179
|
+
});
|
|
180
|
+
it("upsertClusterSummary is idempotent on cluster_id", () => {
|
|
181
|
+
upsertClusterSummary(store, {
|
|
182
|
+
clusterId: "c1",
|
|
183
|
+
label: "first",
|
|
184
|
+
summary: "v1",
|
|
185
|
+
memberHashes: ["a"],
|
|
186
|
+
tokenCount: 1,
|
|
187
|
+
generationMs: 1,
|
|
188
|
+
generator: "test",
|
|
189
|
+
});
|
|
190
|
+
upsertClusterSummary(store, {
|
|
191
|
+
clusterId: "c1",
|
|
192
|
+
label: "second",
|
|
193
|
+
summary: "v2",
|
|
194
|
+
memberHashes: ["a", "b"],
|
|
195
|
+
tokenCount: 2,
|
|
196
|
+
generationMs: 1,
|
|
197
|
+
generator: "test",
|
|
198
|
+
});
|
|
199
|
+
const all = getAllClusterSummaries(store);
|
|
200
|
+
expect(all).toHaveLength(1);
|
|
201
|
+
expect(all[0].label).toBe("second");
|
|
202
|
+
expect(all[0].memberHashes).toEqual(["a", "b"]);
|
|
203
|
+
});
|
|
204
|
+
it("getAllClusterSummaries returns [] when none stored", () => {
|
|
205
|
+
expect(getAllClusterSummaries(store)).toEqual([]);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
describe("HTC storage — Layer 3 memoir", () => {
|
|
209
|
+
it("upsertMemoir round-trips on singleton id=1", () => {
|
|
210
|
+
upsertMemoir(store, {
|
|
211
|
+
narrative: "This repo is a TypeScript library that…",
|
|
212
|
+
totalCommits: 1234,
|
|
213
|
+
totalClusters: 27,
|
|
214
|
+
tokenCount: 500,
|
|
215
|
+
generationMs: 4200,
|
|
216
|
+
generator: "groq:llama-3.3-70b",
|
|
217
|
+
generatedAt: "2025-05-07T00:00:00.000Z",
|
|
218
|
+
});
|
|
219
|
+
const m = getMemoir(store);
|
|
220
|
+
expect(m).not.toBeNull();
|
|
221
|
+
expect(m.totalCommits).toBe(1234);
|
|
222
|
+
expect(m.totalClusters).toBe(27);
|
|
223
|
+
expect(m.narrative).toContain("TypeScript");
|
|
224
|
+
});
|
|
225
|
+
it("upsertMemoir replaces previous memoir (single row)", () => {
|
|
226
|
+
upsertMemoir(store, {
|
|
227
|
+
narrative: "v1",
|
|
228
|
+
totalCommits: 10,
|
|
229
|
+
totalClusters: 2,
|
|
230
|
+
tokenCount: 1,
|
|
231
|
+
generationMs: 1,
|
|
232
|
+
generator: "test",
|
|
233
|
+
});
|
|
234
|
+
upsertMemoir(store, {
|
|
235
|
+
narrative: "v2",
|
|
236
|
+
totalCommits: 20,
|
|
237
|
+
totalClusters: 4,
|
|
238
|
+
tokenCount: 1,
|
|
239
|
+
generationMs: 1,
|
|
240
|
+
generator: "test",
|
|
241
|
+
});
|
|
242
|
+
const count = store.db.prepare("SELECT COUNT(*) AS n FROM htc_memoir").get().n;
|
|
243
|
+
expect(count).toBe(1);
|
|
244
|
+
expect(getMemoir(store).narrative).toBe("v2");
|
|
245
|
+
});
|
|
246
|
+
it("getMemoir returns null when none stored", () => {
|
|
247
|
+
expect(getMemoir(store)).toBeNull();
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
describe("HTC storage — getHtcStats", () => {
|
|
251
|
+
it("returns zeros for empty store", () => {
|
|
252
|
+
const s = getHtcStats(store);
|
|
253
|
+
expect(s.totalCommits).toBe(0);
|
|
254
|
+
expect(s.abstractsGenerated).toBe(0);
|
|
255
|
+
expect(s.abstractsCoverage).toBe(0);
|
|
256
|
+
expect(s.clustersGenerated).toBe(0);
|
|
257
|
+
expect(s.memoirGenerated).toBe(false);
|
|
258
|
+
expect(s.totalCachedTokens).toBe(0);
|
|
259
|
+
expect(s.compressionRatio).toBe(0);
|
|
260
|
+
});
|
|
261
|
+
it("computes coverage = abstracts / commits", () => {
|
|
262
|
+
store.upsertCommits([
|
|
263
|
+
seedCommit({ hash: "a".repeat(40), subject: "one" }),
|
|
264
|
+
seedCommit({ hash: "b".repeat(40), subject: "two" }),
|
|
265
|
+
seedCommit({ hash: "d".repeat(40), subject: "three" }),
|
|
266
|
+
seedCommit({ hash: "e".repeat(40), subject: "four" }),
|
|
267
|
+
]);
|
|
268
|
+
upsertAbstract(store, {
|
|
269
|
+
hash: "a".repeat(40),
|
|
270
|
+
abstract: "abstract one",
|
|
271
|
+
tokenCount: 30,
|
|
272
|
+
generationMs: 1,
|
|
273
|
+
generator: "test",
|
|
274
|
+
});
|
|
275
|
+
upsertAbstract(store, {
|
|
276
|
+
hash: "b".repeat(40),
|
|
277
|
+
abstract: "abstract two",
|
|
278
|
+
tokenCount: 30,
|
|
279
|
+
generationMs: 1,
|
|
280
|
+
generator: "test",
|
|
281
|
+
});
|
|
282
|
+
const s = getHtcStats(store);
|
|
283
|
+
expect(s.totalCommits).toBe(4);
|
|
284
|
+
expect(s.abstractsGenerated).toBe(2);
|
|
285
|
+
expect(s.abstractsCoverage).toBeCloseTo(0.5, 4);
|
|
286
|
+
expect(s.totalCachedTokens).toBe(60);
|
|
287
|
+
});
|
|
288
|
+
it("sums tokens across all three layers + compression ratio is raw/cached", () => {
|
|
289
|
+
store.upsertCommits([
|
|
290
|
+
seedCommit({ hash: "a".repeat(40), subject: "x".repeat(100), body: "y".repeat(300) }),
|
|
291
|
+
]);
|
|
292
|
+
upsertAbstract(store, {
|
|
293
|
+
hash: "a".repeat(40),
|
|
294
|
+
abstract: "tiny abstract",
|
|
295
|
+
tokenCount: 30,
|
|
296
|
+
generationMs: 1,
|
|
297
|
+
generator: "test",
|
|
298
|
+
});
|
|
299
|
+
upsertClusterSummary(store, {
|
|
300
|
+
clusterId: "c1",
|
|
301
|
+
label: "x",
|
|
302
|
+
summary: "y",
|
|
303
|
+
memberHashes: ["a".repeat(40)],
|
|
304
|
+
tokenCount: 100,
|
|
305
|
+
generationMs: 1,
|
|
306
|
+
generator: "test",
|
|
307
|
+
});
|
|
308
|
+
upsertMemoir(store, {
|
|
309
|
+
narrative: "memoir",
|
|
310
|
+
totalCommits: 1,
|
|
311
|
+
totalClusters: 1,
|
|
312
|
+
tokenCount: 500,
|
|
313
|
+
generationMs: 1,
|
|
314
|
+
generator: "test",
|
|
315
|
+
});
|
|
316
|
+
const s = getHtcStats(store);
|
|
317
|
+
expect(s.totalCachedTokens).toBe(630);
|
|
318
|
+
// Raw = 400 chars / 4 = 100 tokens. Cached = 630. Ratio raw/cached < 1
|
|
319
|
+
// (i.e. the cache here is bigger than the raw — synthetic test). Just
|
|
320
|
+
// assert the formula is applied.
|
|
321
|
+
expect(s.compressionRatio).toBeCloseTo(100 / 630, 2);
|
|
322
|
+
expect(s.memoirGenerated).toBe(true);
|
|
323
|
+
expect(s.memoirAgeDays).toBeDefined();
|
|
324
|
+
expect(s.memoirAgeDays).toBeGreaterThanOrEqual(0);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
//# sourceMappingURL=storage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.test.js","sourceRoot":"","sources":["../../src/htc/storage.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EACL,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,SAAS,EACT,WAAW,GACZ,MAAM,cAAc,CAAC;AAEtB,IAAI,MAAc,CAAC;AACnB,IAAI,KAAiB,CAAC;AAEtB,UAAU,CAAC,GAAG,EAAE;IACd,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;IAC3D,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,CAAC,OAAwB,EAAE,EAAU,EAAE,CAAC,CAAC;IAC1D,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACpB,SAAS,EAAE,SAAS;IACpB,UAAU,EAAE,OAAO;IACnB,WAAW,EAAE,QAAQ;IACrB,UAAU,EAAE,sBAAsB;IAClC,aAAa,EAAE,sBAAsB;IACrC,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,CAAC,YAAY,CAAC;IACrB,GAAG,IAAI;CACR,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE;aACpB,OAAO,CAAC,iEAAiE,CAAC;aAC1E,GAAG,EAA6B,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;QACzC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,oDAAoD;QACpD,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClD,4BAA4B;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,UAAU,CAAC,GAAG,EAAE;QACd,KAAK,CAAC,aAAa,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,+DAA+D;YACzE,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,GAAG;YACjB,SAAS,EAAE,mBAAmB;YAC9B,WAAW,EAAE,0BAA0B;SACxC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAI,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,CAAC,GAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,CAAC,GAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjD,MAAM,CAAC,GAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,eAAe;YACzB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,GAAG;YACjB,SAAS,EAAE,mBAAmB;YAC9B,WAAW,EAAE,0BAA0B;SACxC,CAAC;QACF,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5B,cAAc,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAE,CAAC;QAChD,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,sBAAsB;QACtB,MAAM,KAAK,GAAI,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;QACrG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,KAAK,CAAC,aAAa,CAAC;YAClB,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC;QACH,eAAe,CAAC,KAAK,EAAE;YACrB;gBACE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpB,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,CAAC;gBACb,YAAY,EAAE,EAAE;gBAChB,SAAS,EAAE,MAAM;aAClB;YACD;gBACE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpB,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,CAAC;gBACb,YAAY,EAAE,EAAE;gBAChB,SAAS,EAAE,MAAM;aAClB;YACD;gBACE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpB,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,CAAC;gBACb,YAAY,EAAE,EAAE;gBAChB,SAAS,EAAE,MAAM;aAClB;SACF,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;SAC3E,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACtC,CAAC,CAAC;QACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,GAAG;YACb,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,oBAAoB,CAAC,KAAK,EAAE;YAC1B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,eAAe;YACtB,OAAO,EAAE,gCAAgC;YACzC,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;YACnC,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,oBAAoB;YAC/B,WAAW,EAAE,0BAA0B;SACxC,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,oBAAoB,CAAC,KAAK,EAAE;YAC1B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,CAAC,GAAG,CAAC;YACnB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,oBAAoB,CAAC,KAAK,EAAE;YAC1B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;YACxB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,sBAAsB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,YAAY,CAAC,KAAK,EAAE;YAClB,SAAS,EAAE,yCAAyC;YACpD,YAAY,EAAE,IAAI;YAClB,aAAa,EAAE,EAAE;YACjB,UAAU,EAAE,GAAG;YACf,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,oBAAoB;YAC/B,WAAW,EAAE,0BAA0B;SACxC,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,CAAE,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,CAAE,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,CAAC,CAAE,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,YAAY,CAAC,KAAK,EAAE;YAClB,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,EAAE;YAChB,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,YAAY,CAAC,KAAK,EAAE;YAClB,SAAS,EAAE,IAAI;YACf,YAAY,EAAE,EAAE;YAChB,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,CAAC;YACb,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,MAAM,KAAK,GAAI,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;QAClG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,KAAK,CAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,KAAK,CAAC,aAAa,CAAC;YAClB,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACpD,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;YACpD,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;YACtD,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;SACtD,CAAC,CAAC;QACH,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,KAAK,CAAC,aAAa,CAAC;YAClB,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;SACtF,CAAC,CAAC;QACH,cAAc,CAAC,KAAK,EAAE;YACpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,QAAQ,EAAE,eAAe;YACzB,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,oBAAoB,CAAC,KAAK,EAAE;YAC1B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,GAAG;YACV,OAAO,EAAE,GAAG;YACZ,YAAY,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9B,UAAU,EAAE,GAAG;YACf,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,YAAY,CAAC,KAAK,EAAE;YAClB,SAAS,EAAE,QAAQ;YACnB,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,UAAU,EAAE,GAAG;YACf,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,MAAM;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,uEAAuE;QACvE,sEAAsE;QACtE,iCAAiC;QACjC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,WAAW,CAAC,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QACrD,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,CAAC,CAAC,CAAC,aAAc,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchical Token Cache (HTC) — shared types.
|
|
3
|
+
*
|
|
4
|
+
* The big idea: Mneme pre-compresses an entire codebase's git history into
|
|
5
|
+
* LLM-consumable form at index-time. 50,000 commits fit in one Claude prompt.
|
|
6
|
+
* Token cost paid ONCE; reused forever.
|
|
7
|
+
*
|
|
8
|
+
* Three layers:
|
|
9
|
+
* Layer 1 — Semantic abstracts (~30 tok/commit, LLM-generated once, cached)
|
|
10
|
+
* Layer 2 — Topic clusters (~100 tok/cluster, summarized from Layer 1)
|
|
11
|
+
* Layer 3 — Repo memoir (~500 tok, generated from Layer 2)
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Subset of EnricherProvider needed by HTC. We avoid a hard dependency on
|
|
15
|
+
* @mneme-ai/embeddings to keep core dep-free; callers pass an enricher in.
|
|
16
|
+
*/
|
|
17
|
+
export interface HtcEnricher {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
enrich(input: {
|
|
20
|
+
system: string;
|
|
21
|
+
user: string;
|
|
22
|
+
temperature?: number;
|
|
23
|
+
maxTokens?: number;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
text: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/** Layer 1 result: ~30-token abstract for a single commit. */
|
|
29
|
+
export interface AbstractResult {
|
|
30
|
+
hash: string;
|
|
31
|
+
/** ~30-token plain-English condensation of WHAT changed + WHY. */
|
|
32
|
+
abstract: string;
|
|
33
|
+
/** Estimated token count (text.split / words × 1.3). */
|
|
34
|
+
tokenCount: number;
|
|
35
|
+
generationMs: number;
|
|
36
|
+
/** Provider name + model for provenance, e.g. "ollama:qwen2.5:3b". */
|
|
37
|
+
generator: string;
|
|
38
|
+
/** ISO timestamp; populated by storage layer when reading back. */
|
|
39
|
+
generatedAt?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Layer 2 result: ~100-token summary for a group of related commits. */
|
|
42
|
+
export interface ClusterSummary {
|
|
43
|
+
clusterId: string;
|
|
44
|
+
/** Short topic name, e.g. "auth refactor". */
|
|
45
|
+
label: string;
|
|
46
|
+
/** ~100-token paragraph: topic + major changes + sequence. */
|
|
47
|
+
summary: string;
|
|
48
|
+
memberHashes: string[];
|
|
49
|
+
tokenCount: number;
|
|
50
|
+
generationMs: number;
|
|
51
|
+
generator: string;
|
|
52
|
+
generatedAt?: string;
|
|
53
|
+
}
|
|
54
|
+
/** Layer 3 result: ~500-token narrative of the entire repo. */
|
|
55
|
+
export interface Memoir {
|
|
56
|
+
/** ~500-token plain-English narrative covering opening, topics, current state. */
|
|
57
|
+
narrative: string;
|
|
58
|
+
totalCommits: number;
|
|
59
|
+
totalClusters: number;
|
|
60
|
+
tokenCount: number;
|
|
61
|
+
generationMs: number;
|
|
62
|
+
generator: string;
|
|
63
|
+
generatedAt?: string;
|
|
64
|
+
}
|
|
65
|
+
/** Aggregate stats / coverage for the HTC across all three layers. */
|
|
66
|
+
export interface HtcStats {
|
|
67
|
+
totalCommits: number;
|
|
68
|
+
abstractsGenerated: number;
|
|
69
|
+
/** Fraction of commits with a Layer-1 abstract (0..1). */
|
|
70
|
+
abstractsCoverage: number;
|
|
71
|
+
clustersGenerated: number;
|
|
72
|
+
memoirGenerated: boolean;
|
|
73
|
+
/** Days since the memoir was last generated; undefined when no memoir exists. */
|
|
74
|
+
memoirAgeDays?: number;
|
|
75
|
+
/** Sum of token_count across abstracts + clusters + memoir. */
|
|
76
|
+
totalCachedTokens: number;
|
|
77
|
+
/** Estimated tokens of raw commit bodies+subjects — for compression comparison. */
|
|
78
|
+
estimatedRawTokens: number;
|
|
79
|
+
/** estimatedRawTokens / totalCachedTokens; 0 when nothing cached yet. */
|
|
80
|
+
compressionRatio: number;
|
|
81
|
+
}
|
|
82
|
+
/** Estimate token count without pulling a tokenizer dependency.
|
|
83
|
+
* Heuristic: words × 1.3 (rounds up sub-word breaks for typical English/code).
|
|
84
|
+
*/
|
|
85
|
+
export declare function estimateTokens(text: string): number;
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/htc/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,KAAK,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/B;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,MAAM;IACrB,kFAAkF;IAClF,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hierarchical Token Cache (HTC) — shared types.
|
|
3
|
+
*
|
|
4
|
+
* The big idea: Mneme pre-compresses an entire codebase's git history into
|
|
5
|
+
* LLM-consumable form at index-time. 50,000 commits fit in one Claude prompt.
|
|
6
|
+
* Token cost paid ONCE; reused forever.
|
|
7
|
+
*
|
|
8
|
+
* Three layers:
|
|
9
|
+
* Layer 1 — Semantic abstracts (~30 tok/commit, LLM-generated once, cached)
|
|
10
|
+
* Layer 2 — Topic clusters (~100 tok/cluster, summarized from Layer 1)
|
|
11
|
+
* Layer 3 — Repo memoir (~500 tok, generated from Layer 2)
|
|
12
|
+
*/
|
|
13
|
+
/** Estimate token count without pulling a tokenizer dependency.
|
|
14
|
+
* Heuristic: words × 1.3 (rounds up sub-word breaks for typical English/code).
|
|
15
|
+
*/
|
|
16
|
+
export function estimateTokens(text) {
|
|
17
|
+
if (!text)
|
|
18
|
+
return 0;
|
|
19
|
+
const words = text.trim().split(/\s+/).filter(Boolean).length;
|
|
20
|
+
return Math.ceil(words * 1.3);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/htc/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA0EH;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC9D,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;AAChC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ export * as insights from "./insights/index.js";
|
|
|
12
12
|
export * as quant from "./quant/index.js";
|
|
13
13
|
export * as guardian from "./guardian/index.js";
|
|
14
14
|
export * as forensics from "./forensics/index.js";
|
|
15
|
+
export * as htc from "./htc/index.js";
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,4 +12,5 @@ export * as insights from "./insights/index.js";
|
|
|
12
12
|
export * as quant from "./quant/index.js";
|
|
13
13
|
export * as guardian from "./guardian/index.js";
|
|
14
14
|
export * as forensics from "./forensics/index.js";
|
|
15
|
+
export * as htc from "./htc/index.js";
|
|
15
16
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DDTree — Best-First Search through a commit ancestor tree.
|
|
3
|
+
*
|
|
4
|
+
* Inspired by KAT-0B's DDTree (a BinaryHeap-driven candidate exploration
|
|
5
|
+
* loop bounded by an exploration budget). Mneme uses it under `mneme why`
|
|
6
|
+
* to walk *back* through parent commits looking for the deepest plausible
|
|
7
|
+
* "this is why X exists" answer — strictly better than flat semantic
|
|
8
|
+
* retrieval, which can't follow causal ancestry.
|
|
9
|
+
*
|
|
10
|
+
* Semantics:
|
|
11
|
+
* 1. Caller supplies a `scoreFn(commit, depth, parentScore)` — typically
|
|
12
|
+
* relevance × depth-decay × parent-score.
|
|
13
|
+
* 2. We maintain a max-heap keyed by score and pop the best candidate
|
|
14
|
+
* until either the budget is exhausted or the heap is empty.
|
|
15
|
+
* 3. Each pop is classified: accepted, pruned-floor, pruned-depth, or
|
|
16
|
+
* pruned-budget (for nodes still on the heap when budget runs out).
|
|
17
|
+
* 4. Parents of an accepted node are scored and pushed back in.
|
|
18
|
+
*
|
|
19
|
+
* Heap implementation: a simple binary max-heap on a flat array. We avoid
|
|
20
|
+
* Node v22's experimental `node:priority-queue` for portability — Mneme
|
|
21
|
+
* supports Node 18+. See `MaxHeap` below.
|
|
22
|
+
*
|
|
23
|
+
* Cycle handling: merge commits can — in theory — produce diamond-shaped
|
|
24
|
+
* ancestry where the same hash appears twice. We track a `visited` Set so
|
|
25
|
+
* each commit is processed at most once (the first/highest-score path wins).
|
|
26
|
+
*/
|
|
27
|
+
import type { Commit } from "../types.js";
|
|
28
|
+
export interface DDTreeOptions {
|
|
29
|
+
/** Max nodes to explore (controls cost). Default 32. */
|
|
30
|
+
budget?: number;
|
|
31
|
+
/** Max depth from root before pruning. Default 6. */
|
|
32
|
+
maxDepth?: number;
|
|
33
|
+
/** Score floor — nodes below this are pruned. Default 0.05. */
|
|
34
|
+
scoreFloor?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface DDTreeNode {
|
|
37
|
+
commit: Commit;
|
|
38
|
+
depth: number;
|
|
39
|
+
/** Combined score: relevance × decay-by-depth × parent score. */
|
|
40
|
+
score: number;
|
|
41
|
+
/** Parent commit hash (the *child* in graph terms — i.e. the node we
|
|
42
|
+
* expanded from to reach this commit). Undefined for root nodes. */
|
|
43
|
+
parent?: string;
|
|
44
|
+
/** Why this node was pruned, or "accepted". */
|
|
45
|
+
status: "accepted" | "pruned-floor" | "pruned-depth" | "pruned-budget";
|
|
46
|
+
}
|
|
47
|
+
export interface DDTreeResult {
|
|
48
|
+
/** All explored nodes with verdict (in pop order). */
|
|
49
|
+
visited: DDTreeNode[];
|
|
50
|
+
/** Accepted nodes only, sorted by score (highest first). */
|
|
51
|
+
accepted: DDTreeNode[];
|
|
52
|
+
budgetUsed: number;
|
|
53
|
+
}
|
|
54
|
+
/** Score function: relevance × decay-by-depth × log_priors etc. Caller provides. */
|
|
55
|
+
export type ScoreFn = (commit: Commit, depth: number, parentScore: number) => number;
|
|
56
|
+
/** Look up a commit's parent hashes. Caller provides (typically from store). */
|
|
57
|
+
export type ParentResolver = (hash: string) => string[];
|
|
58
|
+
/** Look up a commit by hash. Caller provides. */
|
|
59
|
+
export type CommitResolver = (hash: string) => Commit | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Best-First Search through commit ancestors. See module docstring.
|
|
62
|
+
*
|
|
63
|
+
* Returns every node we touched (with verdict), the sorted list of
|
|
64
|
+
* accepted nodes, and how much of the budget we consumed.
|
|
65
|
+
*/
|
|
66
|
+
export declare function exploreDDTree(rootHashes: string[], scoreFn: ScoreFn, parents: ParentResolver, commits: CommitResolver, opts?: DDTreeOptions): DDTreeResult;
|
|
67
|
+
//# sourceMappingURL=ddtree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ddtree.d.ts","sourceRoot":"","sources":["../../src/retrieve/ddtree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd;yEACqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,GAAG,eAAe,CAAC;CACxE;AAED,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,oFAAoF;AACpF,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;AAErF,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;AAExD,iDAAiD;AACjD,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAqElE;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,aAAkB,GACvB,YAAY,CA+Fd"}
|