@hasna/mementos 0.14.64 → 0.14.65
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/cli/commands/io-clean.d.ts.map +1 -1
- package/dist/cli/index.js +46 -17
- package/dist/db/entities.d.ts.map +1 -1
- package/dist/index.js +36 -15
- package/dist/lib/retention.d.ts.map +1 -1
- package/dist/mcp/index.js +36 -15
- package/dist/server/index.js +194 -14
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io-clean.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/io-clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"io-clean.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/io-clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwC3D"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5422,7 +5422,8 @@ function getEntity(id, db) {
|
|
|
5422
5422
|
return data;
|
|
5423
5423
|
}
|
|
5424
5424
|
const d = db || getDatabase();
|
|
5425
|
-
const
|
|
5425
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
5426
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
5426
5427
|
if (!row)
|
|
5427
5428
|
throw new EntityNotFoundError(id);
|
|
5428
5429
|
return parseEntityRow(row);
|
|
@@ -5517,19 +5518,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
5517
5518
|
return data;
|
|
5518
5519
|
}
|
|
5519
5520
|
const d = db || getDatabase();
|
|
5520
|
-
getEntity(sourceId, d);
|
|
5521
|
-
getEntity(targetId, d);
|
|
5522
|
-
d.run(`
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
d.run(
|
|
5531
|
-
d.run(
|
|
5532
|
-
|
|
5521
|
+
const src = getEntity(sourceId, d).id;
|
|
5522
|
+
const tgt = getEntity(targetId, d).id;
|
|
5523
|
+
d.run(`DELETE FROM relations
|
|
5524
|
+
WHERE source_entity_id = ?
|
|
5525
|
+
AND EXISTS (
|
|
5526
|
+
SELECT 1 FROM relations e
|
|
5527
|
+
WHERE e.source_entity_id = ?
|
|
5528
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
5529
|
+
AND e.relation_type = relations.relation_type
|
|
5530
|
+
)`, [src, tgt]);
|
|
5531
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
5532
|
+
d.run(`DELETE FROM relations
|
|
5533
|
+
WHERE target_entity_id = ?
|
|
5534
|
+
AND EXISTS (
|
|
5535
|
+
SELECT 1 FROM relations e
|
|
5536
|
+
WHERE e.target_entity_id = ?
|
|
5537
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
5538
|
+
AND e.relation_type = relations.relation_type
|
|
5539
|
+
)`, [src, tgt]);
|
|
5540
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
5541
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
5542
|
+
d.run(`DELETE FROM entity_memories
|
|
5543
|
+
WHERE entity_id = ?
|
|
5544
|
+
AND EXISTS (
|
|
5545
|
+
SELECT 1 FROM entity_memories e
|
|
5546
|
+
WHERE e.entity_id = ?
|
|
5547
|
+
AND e.memory_id = entity_memories.memory_id
|
|
5548
|
+
)`, [src, tgt]);
|
|
5549
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
5550
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
5551
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
5552
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now2(), tgt]);
|
|
5553
|
+
return getEntity(tgt, d);
|
|
5533
5554
|
}
|
|
5534
5555
|
var init_entities = __esm(() => {
|
|
5535
5556
|
init_database();
|
|
@@ -62230,7 +62251,7 @@ function deprioritizeStale(days, db) {
|
|
|
62230
62251
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
62231
62252
|
if (count > 0) {
|
|
62232
62253
|
d.run(`UPDATE memories
|
|
62233
|
-
SET importance =
|
|
62254
|
+
SET importance = importance - 1,
|
|
62234
62255
|
version = version + 1,
|
|
62235
62256
|
updated_at = ?
|
|
62236
62257
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
@@ -62248,14 +62269,22 @@ function runCleanup(config, db) {
|
|
|
62248
62269
|
}
|
|
62249
62270
|
|
|
62250
62271
|
// src/cli/commands/io-clean.ts
|
|
62272
|
+
init_api_mode();
|
|
62251
62273
|
init_helpers();
|
|
62274
|
+
function runCleanupViaApi() {
|
|
62275
|
+
const empty = { expired: 0, evicted: 0, archived: 0, unused_archived: 0, deprioritized: 0 };
|
|
62276
|
+
const { status, data } = apiJson("POST", "/maintenance/cleanup");
|
|
62277
|
+
if (status !== 404 && data)
|
|
62278
|
+
return { ...empty, ...data };
|
|
62279
|
+
const legacy = apiJson("POST", "/memories/clean");
|
|
62280
|
+
return { ...empty, expired: legacy.data?.cleaned ?? 0 };
|
|
62281
|
+
}
|
|
62252
62282
|
function registerCleanCommand(program2) {
|
|
62253
62283
|
const handleError = makeHandleError(program2);
|
|
62254
62284
|
program2.command("clean").description("Remove expired memories and enforce quotas").action(() => {
|
|
62255
62285
|
try {
|
|
62256
62286
|
const globalOpts = program2.opts();
|
|
62257
|
-
const
|
|
62258
|
-
const result = runCleanup(config);
|
|
62287
|
+
const result = isApiMode() ? runCleanupViaApi() : runCleanup(loadConfig());
|
|
62259
62288
|
if (globalOpts.json) {
|
|
62260
62289
|
outputJson(result);
|
|
62261
62290
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/db/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACX,MAAM,mBAAmB,CAAC;AAQ3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAWnE;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAmE5E;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/db/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACX,MAAM,mBAAmB,CAAC;AAQ3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAWnE;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAmE5E;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAkB3D;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,GAAG,IAAI,CAgCf;AAMD,wBAAgB,YAAY,CAC1B,MAAM,GAAE;IACN,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,EACN,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,EAAE,CA+CV;AAMD,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAsCR;AAMD,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAS5D;AAMD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAyER;AAgCD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,MAAY,EACvB,EAAE,CAAC,EAAE,QAAQ,GACZ,mBAAmB,EAAE,CA2CvB;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,gBAAgB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CACX,EACN,EAAE,CAAC,EAAE,QAAQ,GACZ,oBAAoB,CA4JtB"}
|
package/dist/index.js
CHANGED
|
@@ -51318,7 +51318,8 @@ function getEntity(id, db) {
|
|
|
51318
51318
|
return data;
|
|
51319
51319
|
}
|
|
51320
51320
|
const d = db || getDatabase();
|
|
51321
|
-
const
|
|
51321
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
51322
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
51322
51323
|
if (!row)
|
|
51323
51324
|
throw new EntityNotFoundError(id);
|
|
51324
51325
|
return parseEntityRow2(row);
|
|
@@ -51446,19 +51447,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
51446
51447
|
return data;
|
|
51447
51448
|
}
|
|
51448
51449
|
const d = db || getDatabase();
|
|
51449
|
-
getEntity(sourceId, d);
|
|
51450
|
-
getEntity(targetId, d);
|
|
51451
|
-
d.run(`
|
|
51452
|
-
|
|
51453
|
-
|
|
51454
|
-
|
|
51455
|
-
|
|
51456
|
-
|
|
51457
|
-
|
|
51458
|
-
|
|
51459
|
-
d.run(
|
|
51460
|
-
d.run(
|
|
51461
|
-
|
|
51450
|
+
const src = getEntity(sourceId, d).id;
|
|
51451
|
+
const tgt = getEntity(targetId, d).id;
|
|
51452
|
+
d.run(`DELETE FROM relations
|
|
51453
|
+
WHERE source_entity_id = ?
|
|
51454
|
+
AND EXISTS (
|
|
51455
|
+
SELECT 1 FROM relations e
|
|
51456
|
+
WHERE e.source_entity_id = ?
|
|
51457
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
51458
|
+
AND e.relation_type = relations.relation_type
|
|
51459
|
+
)`, [src, tgt]);
|
|
51460
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
51461
|
+
d.run(`DELETE FROM relations
|
|
51462
|
+
WHERE target_entity_id = ?
|
|
51463
|
+
AND EXISTS (
|
|
51464
|
+
SELECT 1 FROM relations e
|
|
51465
|
+
WHERE e.target_entity_id = ?
|
|
51466
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
51467
|
+
AND e.relation_type = relations.relation_type
|
|
51468
|
+
)`, [src, tgt]);
|
|
51469
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
51470
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
51471
|
+
d.run(`DELETE FROM entity_memories
|
|
51472
|
+
WHERE entity_id = ?
|
|
51473
|
+
AND EXISTS (
|
|
51474
|
+
SELECT 1 FROM entity_memories e
|
|
51475
|
+
WHERE e.entity_id = ?
|
|
51476
|
+
AND e.memory_id = entity_memories.memory_id
|
|
51477
|
+
)`, [src, tgt]);
|
|
51478
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
51479
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
51480
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
51481
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
51482
|
+
return getEntity(tgt, d);
|
|
51462
51483
|
}
|
|
51463
51484
|
|
|
51464
51485
|
// src/lib/decay.ts
|
|
@@ -52827,7 +52848,7 @@ function deprioritizeStale(days, db) {
|
|
|
52827
52848
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
52828
52849
|
if (count > 0) {
|
|
52829
52850
|
d.run(`UPDATE memories
|
|
52830
|
-
SET importance =
|
|
52851
|
+
SET importance = importance - 1,
|
|
52831
52852
|
version = version + 1,
|
|
52832
52853
|
updated_at = ?
|
|
52833
52854
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/lib/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAC;AAUrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0C3E;AAMD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAwBrE;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAoBjE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/lib/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAC;AAUrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0C3E;AAMD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAwBrE;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAoBjE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAgCrE;AAMD,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,EACtB,EAAE,CAAC,EAAE,QAAQ,GACZ;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAgBxG;AAOD,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuEtB"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -3591,7 +3591,8 @@ function getEntity(id, db) {
|
|
|
3591
3591
|
return data;
|
|
3592
3592
|
}
|
|
3593
3593
|
const d = db || getDatabase();
|
|
3594
|
-
const
|
|
3594
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
3595
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
3595
3596
|
if (!row)
|
|
3596
3597
|
throw new EntityNotFoundError(id);
|
|
3597
3598
|
return parseEntityRow2(row);
|
|
@@ -3719,19 +3720,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
3719
3720
|
return data;
|
|
3720
3721
|
}
|
|
3721
3722
|
const d = db || getDatabase();
|
|
3722
|
-
getEntity(sourceId, d);
|
|
3723
|
-
getEntity(targetId, d);
|
|
3724
|
-
d.run(`
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
d.run(
|
|
3733
|
-
d.run(
|
|
3734
|
-
|
|
3723
|
+
const src = getEntity(sourceId, d).id;
|
|
3724
|
+
const tgt = getEntity(targetId, d).id;
|
|
3725
|
+
d.run(`DELETE FROM relations
|
|
3726
|
+
WHERE source_entity_id = ?
|
|
3727
|
+
AND EXISTS (
|
|
3728
|
+
SELECT 1 FROM relations e
|
|
3729
|
+
WHERE e.source_entity_id = ?
|
|
3730
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
3731
|
+
AND e.relation_type = relations.relation_type
|
|
3732
|
+
)`, [src, tgt]);
|
|
3733
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
3734
|
+
d.run(`DELETE FROM relations
|
|
3735
|
+
WHERE target_entity_id = ?
|
|
3736
|
+
AND EXISTS (
|
|
3737
|
+
SELECT 1 FROM relations e
|
|
3738
|
+
WHERE e.target_entity_id = ?
|
|
3739
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
3740
|
+
AND e.relation_type = relations.relation_type
|
|
3741
|
+
)`, [src, tgt]);
|
|
3742
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
3743
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
3744
|
+
d.run(`DELETE FROM entity_memories
|
|
3745
|
+
WHERE entity_id = ?
|
|
3746
|
+
AND EXISTS (
|
|
3747
|
+
SELECT 1 FROM entity_memories e
|
|
3748
|
+
WHERE e.entity_id = ?
|
|
3749
|
+
AND e.memory_id = entity_memories.memory_id
|
|
3750
|
+
)`, [src, tgt]);
|
|
3751
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
3752
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
3753
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
3754
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
3755
|
+
return getEntity(tgt, d);
|
|
3735
3756
|
}
|
|
3736
3757
|
function trigramSimilarity(a, b) {
|
|
3737
3758
|
const trigramsOf = (s) => {
|
|
@@ -11746,7 +11767,7 @@ function deprioritizeStale(days, db) {
|
|
|
11746
11767
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
11747
11768
|
if (count > 0) {
|
|
11748
11769
|
d.run(`UPDATE memories
|
|
11749
|
-
SET importance =
|
|
11770
|
+
SET importance = importance - 1,
|
|
11750
11771
|
version = version + 1,
|
|
11751
11772
|
updated_at = ?
|
|
11752
11773
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
package/dist/server/index.js
CHANGED
|
@@ -3132,7 +3132,8 @@ function getEntity(id, db) {
|
|
|
3132
3132
|
return data;
|
|
3133
3133
|
}
|
|
3134
3134
|
const d = db || getDatabase();
|
|
3135
|
-
const
|
|
3135
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
3136
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
3136
3137
|
if (!row)
|
|
3137
3138
|
throw new EntityNotFoundError(id);
|
|
3138
3139
|
return parseEntityRow2(row);
|
|
@@ -3260,19 +3261,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
3260
3261
|
return data;
|
|
3261
3262
|
}
|
|
3262
3263
|
const d = db || getDatabase();
|
|
3263
|
-
getEntity(sourceId, d);
|
|
3264
|
-
getEntity(targetId, d);
|
|
3265
|
-
d.run(`
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
d.run(
|
|
3274
|
-
d.run(
|
|
3275
|
-
|
|
3264
|
+
const src = getEntity(sourceId, d).id;
|
|
3265
|
+
const tgt = getEntity(targetId, d).id;
|
|
3266
|
+
d.run(`DELETE FROM relations
|
|
3267
|
+
WHERE source_entity_id = ?
|
|
3268
|
+
AND EXISTS (
|
|
3269
|
+
SELECT 1 FROM relations e
|
|
3270
|
+
WHERE e.source_entity_id = ?
|
|
3271
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
3272
|
+
AND e.relation_type = relations.relation_type
|
|
3273
|
+
)`, [src, tgt]);
|
|
3274
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
3275
|
+
d.run(`DELETE FROM relations
|
|
3276
|
+
WHERE target_entity_id = ?
|
|
3277
|
+
AND EXISTS (
|
|
3278
|
+
SELECT 1 FROM relations e
|
|
3279
|
+
WHERE e.target_entity_id = ?
|
|
3280
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
3281
|
+
AND e.relation_type = relations.relation_type
|
|
3282
|
+
)`, [src, tgt]);
|
|
3283
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
3284
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
3285
|
+
d.run(`DELETE FROM entity_memories
|
|
3286
|
+
WHERE entity_id = ?
|
|
3287
|
+
AND EXISTS (
|
|
3288
|
+
SELECT 1 FROM entity_memories e
|
|
3289
|
+
WHERE e.entity_id = ?
|
|
3290
|
+
AND e.memory_id = entity_memories.memory_id
|
|
3291
|
+
)`, [src, tgt]);
|
|
3292
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
3293
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
3294
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
3295
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
3296
|
+
return getEntity(tgt, d);
|
|
3276
3297
|
}
|
|
3277
3298
|
function graphTraverse(startEntityId, options = {}, db) {
|
|
3278
3299
|
if (!db && isApiMode()) {
|
|
@@ -53407,6 +53428,88 @@ function isInMemoryDb(path) {
|
|
|
53407
53428
|
function homeDir() {
|
|
53408
53429
|
return process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
53409
53430
|
}
|
|
53431
|
+
var DEFAULT_CONFIG = {
|
|
53432
|
+
default_scope: "private",
|
|
53433
|
+
default_category: "knowledge",
|
|
53434
|
+
default_importance: 5,
|
|
53435
|
+
max_entries: 1000,
|
|
53436
|
+
max_entries_per_scope: {
|
|
53437
|
+
global: 500,
|
|
53438
|
+
shared: 300,
|
|
53439
|
+
private: 200,
|
|
53440
|
+
working: 100
|
|
53441
|
+
},
|
|
53442
|
+
injection: {
|
|
53443
|
+
max_tokens: 500,
|
|
53444
|
+
min_importance: 5,
|
|
53445
|
+
categories: ["preference", "fact"],
|
|
53446
|
+
refresh_interval: 5
|
|
53447
|
+
},
|
|
53448
|
+
extraction: {
|
|
53449
|
+
enabled: true,
|
|
53450
|
+
min_confidence: 0.5
|
|
53451
|
+
},
|
|
53452
|
+
sync_agents: ["claude", "codex", "gemini"],
|
|
53453
|
+
auto_cleanup: {
|
|
53454
|
+
enabled: true,
|
|
53455
|
+
expired_check_interval: 3600,
|
|
53456
|
+
unused_archive_days: 7,
|
|
53457
|
+
stale_deprioritize_days: 14
|
|
53458
|
+
}
|
|
53459
|
+
};
|
|
53460
|
+
function deepMerge(target, source) {
|
|
53461
|
+
const result = { ...target };
|
|
53462
|
+
for (const key of Object.keys(source)) {
|
|
53463
|
+
const sourceVal = source[key];
|
|
53464
|
+
const targetVal = result[key];
|
|
53465
|
+
if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
|
|
53466
|
+
result[key] = deepMerge(targetVal, sourceVal);
|
|
53467
|
+
} else {
|
|
53468
|
+
result[key] = sourceVal;
|
|
53469
|
+
}
|
|
53470
|
+
}
|
|
53471
|
+
return result;
|
|
53472
|
+
}
|
|
53473
|
+
var VALID_SCOPES = ["global", "shared", "private", "working"];
|
|
53474
|
+
var VALID_CATEGORIES = [
|
|
53475
|
+
"preference",
|
|
53476
|
+
"fact",
|
|
53477
|
+
"knowledge",
|
|
53478
|
+
"history"
|
|
53479
|
+
];
|
|
53480
|
+
function isValidScope(value) {
|
|
53481
|
+
return VALID_SCOPES.includes(value);
|
|
53482
|
+
}
|
|
53483
|
+
function isValidCategory(value) {
|
|
53484
|
+
return VALID_CATEGORIES.includes(value);
|
|
53485
|
+
}
|
|
53486
|
+
function loadConfig() {
|
|
53487
|
+
const configPath = join(homeDir(), ".hasna", "mementos", "config.json");
|
|
53488
|
+
let fileConfig = {};
|
|
53489
|
+
if (existsSync(configPath)) {
|
|
53490
|
+
try {
|
|
53491
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
53492
|
+
fileConfig = JSON.parse(raw);
|
|
53493
|
+
} catch {}
|
|
53494
|
+
}
|
|
53495
|
+
const merged = deepMerge(DEFAULT_CONFIG, fileConfig);
|
|
53496
|
+
const envScope = process.env["MEMENTOS_DEFAULT_SCOPE"];
|
|
53497
|
+
if (envScope && isValidScope(envScope)) {
|
|
53498
|
+
merged.default_scope = envScope;
|
|
53499
|
+
}
|
|
53500
|
+
const envCategory = process.env["MEMENTOS_DEFAULT_CATEGORY"];
|
|
53501
|
+
if (envCategory && isValidCategory(envCategory)) {
|
|
53502
|
+
merged.default_category = envCategory;
|
|
53503
|
+
}
|
|
53504
|
+
const envImportance = process.env["MEMENTOS_DEFAULT_IMPORTANCE"];
|
|
53505
|
+
if (envImportance) {
|
|
53506
|
+
const parsed = parseInt(envImportance, 10);
|
|
53507
|
+
if (!Number.isNaN(parsed) && parsed >= 1 && parsed <= 10) {
|
|
53508
|
+
merged.default_importance = parsed;
|
|
53509
|
+
}
|
|
53510
|
+
}
|
|
53511
|
+
return merged;
|
|
53512
|
+
}
|
|
53410
53513
|
function findFileWalkingUp(filename) {
|
|
53411
53514
|
let dir = process.cwd();
|
|
53412
53515
|
const legacyHomeMementosDb = resolve(homeDir(), ".mementos", "mementos.db");
|
|
@@ -56417,6 +56520,79 @@ addRoute("POST", "/api/memories/bulk-upsert", async (req) => {
|
|
|
56417
56520
|
// src/server/routes/memories-misc.ts
|
|
56418
56521
|
init_memories();
|
|
56419
56522
|
|
|
56523
|
+
// src/lib/retention.ts
|
|
56524
|
+
init_database();
|
|
56525
|
+
init_memories();
|
|
56526
|
+
function enforceQuotas(config, db) {
|
|
56527
|
+
const d = db || getDatabase();
|
|
56528
|
+
let totalEvicted = 0;
|
|
56529
|
+
const scopes = ["global", "shared", "private", "working"];
|
|
56530
|
+
for (const scope of scopes) {
|
|
56531
|
+
const limit = config.max_entries_per_scope[scope];
|
|
56532
|
+
if (!limit || limit <= 0)
|
|
56533
|
+
continue;
|
|
56534
|
+
const countRow = d.query("SELECT COUNT(*) as cnt FROM memories WHERE scope = ? AND status = 'active'").get(scope);
|
|
56535
|
+
const count = countRow.cnt;
|
|
56536
|
+
if (count <= limit)
|
|
56537
|
+
continue;
|
|
56538
|
+
const excess = count - limit;
|
|
56539
|
+
const subquery = `SELECT id FROM memories
|
|
56540
|
+
WHERE scope = ? AND status = 'active' AND pinned = 0
|
|
56541
|
+
ORDER BY importance ASC, created_at ASC
|
|
56542
|
+
LIMIT ?`;
|
|
56543
|
+
const delCount = d.query(`SELECT COUNT(*) as c FROM (${subquery})`).get(scope, excess).c;
|
|
56544
|
+
d.run(`DELETE FROM memories WHERE id IN (${subquery})`, [scope, excess]);
|
|
56545
|
+
totalEvicted += delCount;
|
|
56546
|
+
}
|
|
56547
|
+
return totalEvicted;
|
|
56548
|
+
}
|
|
56549
|
+
function archiveStale(staleDays, db) {
|
|
56550
|
+
const d = db || getDatabase();
|
|
56551
|
+
const timestamp = now();
|
|
56552
|
+
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000).toISOString();
|
|
56553
|
+
const archiveWhere = `status = 'active' AND pinned = 0 AND COALESCE(accessed_at, created_at) < ?`;
|
|
56554
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${archiveWhere}`).get(cutoff).c;
|
|
56555
|
+
if (count > 0) {
|
|
56556
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [timestamp, cutoff]);
|
|
56557
|
+
}
|
|
56558
|
+
return count;
|
|
56559
|
+
}
|
|
56560
|
+
function archiveUnused(days, db) {
|
|
56561
|
+
const d = db || getDatabase();
|
|
56562
|
+
const timestamp = now();
|
|
56563
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
56564
|
+
const unusedWhere = `status = 'active' AND pinned = 0 AND access_count = 0 AND created_at < ?`;
|
|
56565
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${unusedWhere}`).get(cutoff).c;
|
|
56566
|
+
if (count > 0) {
|
|
56567
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [timestamp, cutoff]);
|
|
56568
|
+
}
|
|
56569
|
+
return count;
|
|
56570
|
+
}
|
|
56571
|
+
function deprioritizeStale(days, db) {
|
|
56572
|
+
const d = db || getDatabase();
|
|
56573
|
+
const timestamp = now();
|
|
56574
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
56575
|
+
const deprioWhere = `status = 'active' AND pinned = 0 AND importance > 1 AND COALESCE(accessed_at, updated_at) < ?`;
|
|
56576
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
56577
|
+
if (count > 0) {
|
|
56578
|
+
d.run(`UPDATE memories
|
|
56579
|
+
SET importance = importance - 1,
|
|
56580
|
+
version = version + 1,
|
|
56581
|
+
updated_at = ?
|
|
56582
|
+
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
56583
|
+
}
|
|
56584
|
+
return count;
|
|
56585
|
+
}
|
|
56586
|
+
function runCleanup(config, db) {
|
|
56587
|
+
const d = db || getDatabase();
|
|
56588
|
+
const expired = cleanExpiredMemories(d);
|
|
56589
|
+
const evicted = enforceQuotas(config, d);
|
|
56590
|
+
const archived = archiveStale(90, d);
|
|
56591
|
+
const unused_archived = archiveUnused(config.auto_cleanup.unused_archive_days ?? 7, d);
|
|
56592
|
+
const deprioritized = deprioritizeStale(config.auto_cleanup.stale_deprioritize_days ?? 14, d);
|
|
56593
|
+
return { expired, evicted, archived, unused_archived, deprioritized };
|
|
56594
|
+
}
|
|
56595
|
+
|
|
56420
56596
|
// src/lib/machine-visibility.ts
|
|
56421
56597
|
function resolveVisibleMachineId(machineId, db) {
|
|
56422
56598
|
if (machineId !== undefined) {
|
|
@@ -56539,6 +56715,10 @@ addRoute("POST", "/api/memories/clean", () => {
|
|
|
56539
56715
|
const cleaned = cleanExpiredMemories();
|
|
56540
56716
|
return json({ cleaned });
|
|
56541
56717
|
});
|
|
56718
|
+
addRoute("POST", "/api/maintenance/cleanup", () => {
|
|
56719
|
+
const result = runCleanup(loadConfig());
|
|
56720
|
+
return json(result);
|
|
56721
|
+
});
|
|
56542
56722
|
addRoute("GET", "/api/inject", (_req, url) => {
|
|
56543
56723
|
const q = getSearchParams(url);
|
|
56544
56724
|
const maxTokens = q["max_tokens"] ? parseInt(q["max_tokens"], 10) : 500;
|