claude-memory-layer 1.0.7 → 1.0.8
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/.claude/settings.local.json +4 -1
- package/.history/package_20260201192048.json +47 -0
- package/dist/cli/index.js +569 -39
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +192 -5
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/session-end.js +262 -18
- package/dist/hooks/session-end.js.map +4 -4
- package/dist/hooks/session-start.js +262 -18
- package/dist/hooks/session-start.js.map +4 -4
- package/dist/hooks/stop.js +262 -18
- package/dist/hooks/stop.js.map +4 -4
- package/dist/hooks/user-prompt-submit.js +262 -18
- package/dist/hooks/user-prompt-submit.js.map +4 -4
- package/dist/server/api/index.js +404 -39
- package/dist/server/api/index.js.map +4 -4
- package/dist/server/index.js +413 -46
- package/dist/server/index.js.map +4 -4
- package/dist/services/memory-service.js +269 -18
- package/dist/services/memory-service.js.map +4 -4
- package/dist/ui/index.html +495 -15
- package/package.json +2 -1
- package/scripts/build.ts +3 -2
- package/src/cli/index.ts +226 -0
- package/src/core/db-wrapper.ts +8 -1
- package/src/core/event-store.ts +52 -3
- package/src/core/graduation-worker.ts +171 -0
- package/src/core/graduation.ts +15 -2
- package/src/core/index.ts +1 -0
- package/src/core/retriever.ts +18 -0
- package/src/server/api/citations.ts +7 -3
- package/src/server/api/events.ts +7 -3
- package/src/server/api/search.ts +7 -3
- package/src/server/api/sessions.ts +7 -3
- package/src/server/api/stats.ts +129 -12
- package/src/server/index.ts +18 -9
- package/src/services/memory-service.ts +107 -19
- package/src/ui/index.html +495 -15
package/dist/core/index.js
CHANGED
|
@@ -639,7 +639,10 @@ function toDate(value) {
|
|
|
639
639
|
return new Date(value);
|
|
640
640
|
return new Date(String(value));
|
|
641
641
|
}
|
|
642
|
-
function createDatabase(path) {
|
|
642
|
+
function createDatabase(path, options) {
|
|
643
|
+
if (options?.readOnly) {
|
|
644
|
+
return new duckdb.Database(path, { access_mode: "READ_ONLY" });
|
|
645
|
+
}
|
|
643
646
|
return new duckdb.Database(path);
|
|
644
647
|
}
|
|
645
648
|
function dbRun(db, sql, params = []) {
|
|
@@ -693,18 +696,24 @@ function dbClose(db) {
|
|
|
693
696
|
|
|
694
697
|
// src/core/event-store.ts
|
|
695
698
|
var EventStore = class {
|
|
696
|
-
constructor(dbPath) {
|
|
699
|
+
constructor(dbPath, options) {
|
|
697
700
|
this.dbPath = dbPath;
|
|
698
|
-
this.
|
|
701
|
+
this.readOnly = options?.readOnly ?? false;
|
|
702
|
+
this.db = createDatabase(dbPath, { readOnly: this.readOnly });
|
|
699
703
|
}
|
|
700
704
|
db;
|
|
701
705
|
initialized = false;
|
|
706
|
+
readOnly;
|
|
702
707
|
/**
|
|
703
708
|
* Initialize database schema
|
|
704
709
|
*/
|
|
705
710
|
async initialize() {
|
|
706
711
|
if (this.initialized)
|
|
707
712
|
return;
|
|
713
|
+
if (this.readOnly) {
|
|
714
|
+
this.initialized = true;
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
708
717
|
await dbRun(this.db, `
|
|
709
718
|
CREATE TABLE IF NOT EXISTS events (
|
|
710
719
|
id VARCHAR PRIMARY KEY,
|
|
@@ -1181,6 +1190,36 @@ var EventStore = class {
|
|
|
1181
1190
|
);
|
|
1182
1191
|
return rows;
|
|
1183
1192
|
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Get events by memory level
|
|
1195
|
+
*/
|
|
1196
|
+
async getEventsByLevel(level, options) {
|
|
1197
|
+
await this.initialize();
|
|
1198
|
+
const limit = options?.limit || 50;
|
|
1199
|
+
const offset = options?.offset || 0;
|
|
1200
|
+
const rows = await dbAll(
|
|
1201
|
+
this.db,
|
|
1202
|
+
`SELECT e.* FROM events e
|
|
1203
|
+
INNER JOIN memory_levels ml ON e.id = ml.event_id
|
|
1204
|
+
WHERE ml.level = ?
|
|
1205
|
+
ORDER BY e.timestamp DESC
|
|
1206
|
+
LIMIT ? OFFSET ?`,
|
|
1207
|
+
[level, limit, offset]
|
|
1208
|
+
);
|
|
1209
|
+
return rows.map((row) => this.rowToEvent(row));
|
|
1210
|
+
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Get memory level for a specific event
|
|
1213
|
+
*/
|
|
1214
|
+
async getEventLevel(eventId) {
|
|
1215
|
+
await this.initialize();
|
|
1216
|
+
const rows = await dbAll(
|
|
1217
|
+
this.db,
|
|
1218
|
+
`SELECT level FROM memory_levels WHERE event_id = ?`,
|
|
1219
|
+
[eventId]
|
|
1220
|
+
);
|
|
1221
|
+
return rows.length > 0 ? rows[0].level : null;
|
|
1222
|
+
}
|
|
1184
1223
|
// ============================================================
|
|
1185
1224
|
// Endless Mode Helper Methods
|
|
1186
1225
|
// ============================================================
|
|
@@ -3167,6 +3206,7 @@ var Retriever = class {
|
|
|
3167
3206
|
matcher;
|
|
3168
3207
|
sharedStore;
|
|
3169
3208
|
sharedVectorStore;
|
|
3209
|
+
graduation;
|
|
3170
3210
|
constructor(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
3171
3211
|
this.eventStore = eventStore;
|
|
3172
3212
|
this.vectorStore = vectorStore;
|
|
@@ -3175,6 +3215,12 @@ var Retriever = class {
|
|
|
3175
3215
|
this.sharedStore = sharedOptions?.sharedStore;
|
|
3176
3216
|
this.sharedVectorStore = sharedOptions?.sharedVectorStore;
|
|
3177
3217
|
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Set graduation pipeline for access tracking
|
|
3220
|
+
*/
|
|
3221
|
+
setGraduationPipeline(graduation) {
|
|
3222
|
+
this.graduation = graduation;
|
|
3223
|
+
}
|
|
3178
3224
|
/**
|
|
3179
3225
|
* Set shared stores after construction
|
|
3180
3226
|
*/
|
|
@@ -3297,6 +3343,13 @@ var Retriever = class {
|
|
|
3297
3343
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
3298
3344
|
if (!event)
|
|
3299
3345
|
continue;
|
|
3346
|
+
if (this.graduation) {
|
|
3347
|
+
this.graduation.recordAccess(
|
|
3348
|
+
event.id,
|
|
3349
|
+
options.sessionId || "unknown",
|
|
3350
|
+
result.score
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3300
3353
|
let sessionContext;
|
|
3301
3354
|
if (options.includeSessionContext) {
|
|
3302
3355
|
sessionContext = await this.getSessionContext(event.sessionId, event.id);
|
|
@@ -3418,15 +3471,26 @@ var GraduationPipeline = class {
|
|
|
3418
3471
|
L3toL4: { ...DEFAULT_CRITERIA.L3toL4, ...criteria.L3toL4 }
|
|
3419
3472
|
};
|
|
3420
3473
|
}
|
|
3474
|
+
// Track which sessions have accessed each event
|
|
3475
|
+
sessionAccesses = /* @__PURE__ */ new Map();
|
|
3421
3476
|
/**
|
|
3422
3477
|
* Record an access to an event (used for graduation scoring)
|
|
3423
3478
|
*/
|
|
3424
3479
|
recordAccess(eventId, fromSessionId, confidence = 1) {
|
|
3425
3480
|
const existing = this.metrics.get(eventId);
|
|
3481
|
+
if (!this.sessionAccesses.has(eventId)) {
|
|
3482
|
+
this.sessionAccesses.set(eventId, /* @__PURE__ */ new Set());
|
|
3483
|
+
}
|
|
3484
|
+
const sessions = this.sessionAccesses.get(eventId);
|
|
3485
|
+
const isNewSession = !sessions.has(fromSessionId);
|
|
3486
|
+
sessions.add(fromSessionId);
|
|
3426
3487
|
if (existing) {
|
|
3427
3488
|
existing.accessCount++;
|
|
3428
3489
|
existing.lastAccessed = /* @__PURE__ */ new Date();
|
|
3429
3490
|
existing.confidence = Math.max(existing.confidence, confidence);
|
|
3491
|
+
if (isNewSession && sessions.size > 1) {
|
|
3492
|
+
existing.crossSessionRefs = sessions.size - 1;
|
|
3493
|
+
}
|
|
3430
3494
|
} else {
|
|
3431
3495
|
this.metrics.set(eventId, {
|
|
3432
3496
|
eventId,
|
|
@@ -3631,8 +3695,129 @@ function createGraduationPipeline(eventStore) {
|
|
|
3631
3695
|
return new GraduationPipeline(eventStore);
|
|
3632
3696
|
}
|
|
3633
3697
|
|
|
3634
|
-
// src/core/
|
|
3698
|
+
// src/core/graduation-worker.ts
|
|
3635
3699
|
var DEFAULT_CONFIG4 = {
|
|
3700
|
+
evaluationIntervalMs: 3e5,
|
|
3701
|
+
// 5 minutes
|
|
3702
|
+
batchSize: 50,
|
|
3703
|
+
cooldownMs: 36e5
|
|
3704
|
+
// 1 hour cooldown between evaluations
|
|
3705
|
+
};
|
|
3706
|
+
var GraduationWorker = class {
|
|
3707
|
+
constructor(eventStore, graduation, config = DEFAULT_CONFIG4) {
|
|
3708
|
+
this.eventStore = eventStore;
|
|
3709
|
+
this.graduation = graduation;
|
|
3710
|
+
this.config = config;
|
|
3711
|
+
}
|
|
3712
|
+
running = false;
|
|
3713
|
+
timeout = null;
|
|
3714
|
+
lastEvaluated = /* @__PURE__ */ new Map();
|
|
3715
|
+
/**
|
|
3716
|
+
* Start the graduation worker
|
|
3717
|
+
*/
|
|
3718
|
+
start() {
|
|
3719
|
+
if (this.running)
|
|
3720
|
+
return;
|
|
3721
|
+
this.running = true;
|
|
3722
|
+
this.scheduleNext();
|
|
3723
|
+
}
|
|
3724
|
+
/**
|
|
3725
|
+
* Stop the graduation worker
|
|
3726
|
+
*/
|
|
3727
|
+
stop() {
|
|
3728
|
+
this.running = false;
|
|
3729
|
+
if (this.timeout) {
|
|
3730
|
+
clearTimeout(this.timeout);
|
|
3731
|
+
this.timeout = null;
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
/**
|
|
3735
|
+
* Check if currently running
|
|
3736
|
+
*/
|
|
3737
|
+
isRunning() {
|
|
3738
|
+
return this.running;
|
|
3739
|
+
}
|
|
3740
|
+
/**
|
|
3741
|
+
* Force a graduation evaluation run
|
|
3742
|
+
*/
|
|
3743
|
+
async forceRun() {
|
|
3744
|
+
return await this.runGraduation();
|
|
3745
|
+
}
|
|
3746
|
+
/**
|
|
3747
|
+
* Schedule the next graduation check
|
|
3748
|
+
*/
|
|
3749
|
+
scheduleNext() {
|
|
3750
|
+
if (!this.running)
|
|
3751
|
+
return;
|
|
3752
|
+
this.timeout = setTimeout(
|
|
3753
|
+
() => this.run(),
|
|
3754
|
+
this.config.evaluationIntervalMs
|
|
3755
|
+
);
|
|
3756
|
+
}
|
|
3757
|
+
/**
|
|
3758
|
+
* Run graduation evaluation
|
|
3759
|
+
*/
|
|
3760
|
+
async run() {
|
|
3761
|
+
if (!this.running)
|
|
3762
|
+
return;
|
|
3763
|
+
try {
|
|
3764
|
+
await this.runGraduation();
|
|
3765
|
+
} catch (error) {
|
|
3766
|
+
console.error("Graduation error:", error);
|
|
3767
|
+
}
|
|
3768
|
+
this.scheduleNext();
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Perform graduation evaluation across all levels
|
|
3772
|
+
*/
|
|
3773
|
+
async runGraduation() {
|
|
3774
|
+
const result = {
|
|
3775
|
+
evaluated: 0,
|
|
3776
|
+
graduated: 0,
|
|
3777
|
+
byLevel: {}
|
|
3778
|
+
};
|
|
3779
|
+
const levels = ["L0", "L1", "L2", "L3"];
|
|
3780
|
+
const now = Date.now();
|
|
3781
|
+
for (const level of levels) {
|
|
3782
|
+
const events = await this.eventStore.getEventsByLevel(level, {
|
|
3783
|
+
limit: this.config.batchSize
|
|
3784
|
+
});
|
|
3785
|
+
let levelGraduated = 0;
|
|
3786
|
+
for (const event of events) {
|
|
3787
|
+
const lastEval = this.lastEvaluated.get(event.id);
|
|
3788
|
+
if (lastEval && now - lastEval < this.config.cooldownMs) {
|
|
3789
|
+
continue;
|
|
3790
|
+
}
|
|
3791
|
+
result.evaluated++;
|
|
3792
|
+
this.lastEvaluated.set(event.id, now);
|
|
3793
|
+
const gradResult = await this.graduation.evaluateGraduation(event.id, level);
|
|
3794
|
+
if (gradResult.success) {
|
|
3795
|
+
result.graduated++;
|
|
3796
|
+
levelGraduated++;
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
if (levelGraduated > 0) {
|
|
3800
|
+
result.byLevel[level] = levelGraduated;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
if (this.lastEvaluated.size > 1e3) {
|
|
3804
|
+
const entries = Array.from(this.lastEvaluated.entries());
|
|
3805
|
+
entries.sort((a, b) => b[1] - a[1]);
|
|
3806
|
+
this.lastEvaluated = new Map(entries.slice(0, 1e3));
|
|
3807
|
+
}
|
|
3808
|
+
return result;
|
|
3809
|
+
}
|
|
3810
|
+
};
|
|
3811
|
+
function createGraduationWorker(eventStore, graduation, config) {
|
|
3812
|
+
return new GraduationWorker(
|
|
3813
|
+
eventStore,
|
|
3814
|
+
graduation,
|
|
3815
|
+
{ ...DEFAULT_CONFIG4, ...config }
|
|
3816
|
+
);
|
|
3817
|
+
}
|
|
3818
|
+
|
|
3819
|
+
// src/core/task/task-matcher.ts
|
|
3820
|
+
var DEFAULT_CONFIG5 = {
|
|
3636
3821
|
minCombinedScore: MATCH_THRESHOLDS.minCombinedScore,
|
|
3637
3822
|
minGap: MATCH_THRESHOLDS.minGap,
|
|
3638
3823
|
suggestionThreshold: MATCH_THRESHOLDS.suggestionThreshold,
|
|
@@ -3641,7 +3826,7 @@ var DEFAULT_CONFIG4 = {
|
|
|
3641
3826
|
var TaskMatcher = class {
|
|
3642
3827
|
constructor(db, config) {
|
|
3643
3828
|
this.db = db;
|
|
3644
|
-
this.config = { ...
|
|
3829
|
+
this.config = { ...DEFAULT_CONFIG5, ...config };
|
|
3645
3830
|
}
|
|
3646
3831
|
config;
|
|
3647
3832
|
/**
|
|
@@ -5291,6 +5476,7 @@ export {
|
|
|
5291
5476
|
FullDetailSchema,
|
|
5292
5477
|
GraduationPipeline,
|
|
5293
5478
|
GraduationResultSchema,
|
|
5479
|
+
GraduationWorker,
|
|
5294
5480
|
InsightSchema,
|
|
5295
5481
|
InsightTypeSchema,
|
|
5296
5482
|
MATCH_THRESHOLDS,
|
|
@@ -5341,6 +5527,7 @@ export {
|
|
|
5341
5527
|
VectorWorkerV2,
|
|
5342
5528
|
WorkingSetItemSchema,
|
|
5343
5529
|
createGraduationPipeline,
|
|
5530
|
+
createGraduationWorker,
|
|
5344
5531
|
createRetriever,
|
|
5345
5532
|
createSharedEventStore,
|
|
5346
5533
|
createSharedPromoter,
|