memo-grafter 0.2.6 → 0.2.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/USER_GUIDE.md +190 -10
- package/dist/MemoGrafter.d.ts +13 -5
- package/dist/MemoGrafter.d.ts.map +1 -1
- package/dist/MemoGrafter.js +64 -0
- package/dist/MemoGrafter.js.map +1 -1
- package/dist/MemoGrafterAgent.d.ts +9 -1
- package/dist/MemoGrafterAgent.d.ts.map +1 -1
- package/dist/MemoGrafterAgent.js +35 -2
- package/dist/MemoGrafterAgent.js.map +1 -1
- package/dist/adapters/OpenAIAdapter.d.ts +6 -1
- package/dist/adapters/OpenAIAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenAIAdapter.js +19 -1
- package/dist/adapters/OpenAIAdapter.js.map +1 -1
- package/dist/crawler/DecayScoringPass.d.ts.map +1 -1
- package/dist/crawler/DecayScoringPass.js +6 -0
- package/dist/crawler/DecayScoringPass.js.map +1 -1
- package/dist/crawler/memoryMaintenance.d.ts +1 -0
- package/dist/crawler/memoryMaintenance.d.ts.map +1 -1
- package/dist/crawler/memoryMaintenance.js +2 -1
- package/dist/crawler/memoryMaintenance.js.map +1 -1
- package/dist/crawler/types.d.ts +1 -0
- package/dist/crawler/types.d.ts.map +1 -1
- package/dist/fleet/WorkerAgent.d.ts +2 -1
- package/dist/fleet/WorkerAgent.d.ts.map +1 -1
- package/dist/fleet/WorkerAgent.js +3 -0
- package/dist/fleet/WorkerAgent.js.map +1 -1
- package/dist/fleet/types.d.ts +2 -1
- package/dist/fleet/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/pipeline/GrafterPipeline.d.ts +6 -2
- package/dist/pipeline/GrafterPipeline.d.ts.map +1 -1
- package/dist/pipeline/GrafterPipeline.js +11 -5
- package/dist/pipeline/GrafterPipeline.js.map +1 -1
- package/dist/pipeline/RetrieverPipeline.js +2 -2
- package/dist/pipeline/RetrieverPipeline.js.map +1 -1
- package/dist/store/GraphStore.d.ts +8 -1
- package/dist/store/GraphStore.d.ts.map +1 -1
- package/dist/store/postgres-pgvector/GraphStore.d.ts +19 -1
- package/dist/store/postgres-pgvector/GraphStore.d.ts.map +1 -1
- package/dist/store/postgres-pgvector/GraphStore.js +371 -16
- package/dist/store/postgres-pgvector/GraphStore.js.map +1 -1
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphStore.d.ts","sourceRoot":"","sources":["../../../src/store/postgres-pgvector/GraphStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"GraphStore.d.ts","sourceRoot":"","sources":["../../../src/store/postgres-pgvector/GraphStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,6 +52,8 @@ export class PostgresGraphStore {
|
|
|
52
52
|
agent_color TEXT,
|
|
53
53
|
fleet_id TEXT,
|
|
54
54
|
agent_id TEXT,
|
|
55
|
+
suppressed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
56
|
+
suppressed_at TIMESTAMPTZ,
|
|
55
57
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
56
58
|
UNIQUE (segment_id)
|
|
57
59
|
)
|
|
@@ -85,6 +87,8 @@ export class PostgresGraphStore {
|
|
|
85
87
|
source_title TEXT,
|
|
86
88
|
superseded_by UUID REFERENCES mg_memory_nodes(id),
|
|
87
89
|
decayed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
90
|
+
forgotten BOOLEAN NOT NULL DEFAULT FALSE,
|
|
91
|
+
forgotten_at TIMESTAMPTZ,
|
|
88
92
|
has_conflict BOOLEAN NOT NULL DEFAULT FALSE,
|
|
89
93
|
agent_color TEXT,
|
|
90
94
|
fleet_id TEXT,
|
|
@@ -102,6 +106,22 @@ export class PostgresGraphStore {
|
|
|
102
106
|
await this.sql `
|
|
103
107
|
ALTER TABLE mg_memory_nodes
|
|
104
108
|
ADD COLUMN IF NOT EXISTS has_conflict BOOLEAN NOT NULL DEFAULT FALSE
|
|
109
|
+
`;
|
|
110
|
+
await this.sql `
|
|
111
|
+
ALTER TABLE mg_memory_nodes
|
|
112
|
+
ADD COLUMN IF NOT EXISTS forgotten BOOLEAN NOT NULL DEFAULT FALSE
|
|
113
|
+
`;
|
|
114
|
+
await this.sql `
|
|
115
|
+
ALTER TABLE mg_memory_nodes
|
|
116
|
+
ADD COLUMN IF NOT EXISTS forgotten_at TIMESTAMPTZ
|
|
117
|
+
`;
|
|
118
|
+
await this.sql `
|
|
119
|
+
ALTER TABLE mg_topic_nodes
|
|
120
|
+
ADD COLUMN IF NOT EXISTS suppressed BOOLEAN NOT NULL DEFAULT FALSE
|
|
121
|
+
`;
|
|
122
|
+
await this.sql `
|
|
123
|
+
ALTER TABLE mg_topic_nodes
|
|
124
|
+
ADD COLUMN IF NOT EXISTS suppressed_at TIMESTAMPTZ
|
|
105
125
|
`;
|
|
106
126
|
await this.sql `
|
|
107
127
|
ALTER TABLE mg_topic_nodes
|
|
@@ -308,6 +328,7 @@ export class PostgresGraphStore {
|
|
|
308
328
|
JOIN mg_topic_nodes n ON n.id = e.src_id
|
|
309
329
|
WHERE n.session_id = ${sessionId}
|
|
310
330
|
AND e.type = ${type}
|
|
331
|
+
AND n.suppressed = FALSE
|
|
311
332
|
`;
|
|
312
333
|
return rows.map((row) => ({
|
|
313
334
|
srcId: row.src_id,
|
|
@@ -397,6 +418,7 @@ export class PostgresGraphStore {
|
|
|
397
418
|
SELECT COUNT(*)::int AS count
|
|
398
419
|
FROM mg_topic_nodes
|
|
399
420
|
WHERE session_id = ${sessionId}
|
|
421
|
+
AND suppressed = FALSE
|
|
400
422
|
`;
|
|
401
423
|
return rows[0]?.count ?? 0;
|
|
402
424
|
}
|
|
@@ -406,6 +428,7 @@ export class PostgresGraphStore {
|
|
|
406
428
|
const rows = await this.sql `
|
|
407
429
|
SELECT * FROM mg_topic_nodes
|
|
408
430
|
WHERE ${searchTaggedSessions ? this.sql `TRUE` : this.sql `session_id = ${sessionId}`}
|
|
431
|
+
${options.includeSuppressed ? this.sql `` : this.sql `AND suppressed = FALSE`}
|
|
409
432
|
${this.topicTagsFilterSql(tags, options.tagMode)}
|
|
410
433
|
ORDER BY session_id ASC, topic_order ASC, created_at ASC
|
|
411
434
|
`;
|
|
@@ -415,6 +438,7 @@ export class PostgresGraphStore {
|
|
|
415
438
|
const rows = await this.sql `
|
|
416
439
|
SELECT * FROM mg_topic_nodes
|
|
417
440
|
WHERE session_id = ${sessionId}
|
|
441
|
+
AND suppressed = FALSE
|
|
418
442
|
ORDER BY topic_order DESC, created_at DESC
|
|
419
443
|
LIMIT 1
|
|
420
444
|
`;
|
|
@@ -468,11 +492,15 @@ export class PostgresGraphStore {
|
|
|
468
492
|
}
|
|
469
493
|
async getMemoriesByTopic(topicNodeId) {
|
|
470
494
|
const rows = await this.sql `
|
|
471
|
-
SELECT
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
495
|
+
SELECT memory.*
|
|
496
|
+
FROM mg_memory_nodes memory
|
|
497
|
+
JOIN mg_topic_nodes topic ON topic.id = memory.topic_node_id
|
|
498
|
+
WHERE memory.topic_node_id = ${topicNodeId}
|
|
499
|
+
AND memory.decayed = false
|
|
500
|
+
AND memory.superseded_by IS NULL
|
|
501
|
+
AND memory.forgotten = false
|
|
502
|
+
AND topic.suppressed = false
|
|
503
|
+
ORDER BY memory.created_at ASC
|
|
476
504
|
`;
|
|
477
505
|
return rows.map((row) => this.rowToMemoryNode(row));
|
|
478
506
|
}
|
|
@@ -496,13 +524,136 @@ export class PostgresGraphStore {
|
|
|
496
524
|
`;
|
|
497
525
|
return rows.map((row) => this.rowToMemoryEdge(row));
|
|
498
526
|
}
|
|
527
|
+
async getMemoryHistoryById(memoryNodeId, options = {}) {
|
|
528
|
+
const anchor = await this.getMemoryNodeById(memoryNodeId, options.sessionId);
|
|
529
|
+
if (!anchor) {
|
|
530
|
+
return {
|
|
531
|
+
anchorMemoryId: memoryNodeId,
|
|
532
|
+
...(options.sessionId ? { sessionId: options.sessionId } : {}),
|
|
533
|
+
entries: [],
|
|
534
|
+
edges: [],
|
|
535
|
+
currentMemory: null,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
const memories = await this.getMemoryNodesByFactKey(anchor.subject, anchor.predicate, {
|
|
539
|
+
sessionId: options.sessionId ?? anchor.sessionId,
|
|
540
|
+
});
|
|
541
|
+
const byId = new Map(memories.map((memory) => [memory.id, memory]));
|
|
542
|
+
byId.set(anchor.id, anchor);
|
|
543
|
+
const firstPassEdges = await this.getMemoryEdgesForMemoryIds([...byId.keys()]);
|
|
544
|
+
for (const id of this.getConnectedMemoryIds(firstPassEdges)) {
|
|
545
|
+
if (!byId.has(id)) {
|
|
546
|
+
byId.set(id, null);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
const missingIds = [...byId.entries()]
|
|
550
|
+
.filter(([, memory]) => memory == null)
|
|
551
|
+
.map(([id]) => id);
|
|
552
|
+
for (const memory of await this.getMemoryNodesByIds(missingIds, options.sessionId ?? anchor.sessionId)) {
|
|
553
|
+
byId.set(memory.id, memory);
|
|
554
|
+
}
|
|
555
|
+
const historyMemories = [...byId.values()].filter((memory) => memory != null);
|
|
556
|
+
const edges = await this.getMemoryEdgesForMemoryIds(historyMemories.map((memory) => memory.id));
|
|
557
|
+
return this.buildMemoryHistoryResult(historyMemories, edges, {
|
|
558
|
+
anchorMemoryId: memoryNodeId,
|
|
559
|
+
subject: anchor.subject,
|
|
560
|
+
predicate: anchor.predicate,
|
|
561
|
+
sessionId: options.sessionId ?? anchor.sessionId,
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
async getMemoryHistoryByFact(subject, predicate, options = {}) {
|
|
565
|
+
const memories = await this.getMemoryNodesByFactKey(subject, predicate, options);
|
|
566
|
+
const edges = await this.getMemoryEdgesForMemoryIds(memories.map((memory) => memory.id));
|
|
567
|
+
return this.buildMemoryHistoryResult(memories, edges, {
|
|
568
|
+
subject,
|
|
569
|
+
predicate,
|
|
570
|
+
...(options.sessionId ? { sessionId: options.sessionId } : {}),
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
async getMemoryDiff(fromMemoryId, toMemoryId) {
|
|
574
|
+
const [from, to] = await Promise.all([
|
|
575
|
+
this.getMemoryNodeById(fromMemoryId),
|
|
576
|
+
this.getMemoryNodeById(toMemoryId),
|
|
577
|
+
]);
|
|
578
|
+
if (!from) {
|
|
579
|
+
throw new Error(`Memory ${fromMemoryId} was not found.`);
|
|
580
|
+
}
|
|
581
|
+
if (!to) {
|
|
582
|
+
throw new Error(`Memory ${toMemoryId} was not found.`);
|
|
583
|
+
}
|
|
584
|
+
const edges = (await this.getMemoryEdgesForMemoryIds([from.id, to.id]))
|
|
585
|
+
.filter((edge) => (edge.sourceId === from.id && edge.targetId === to.id)
|
|
586
|
+
|| (edge.sourceId === to.id && edge.targetId === from.id));
|
|
587
|
+
const updateEdges = edges.filter((edge) => edge.edgeType === "updates");
|
|
588
|
+
const conflictEdges = edges.filter((edge) => edge.edgeType === "conflicts");
|
|
589
|
+
const fields = this.diffMemoryFields(from, to);
|
|
590
|
+
return {
|
|
591
|
+
from,
|
|
592
|
+
to,
|
|
593
|
+
fields,
|
|
594
|
+
changedFields: fields.filter((field) => field.changed),
|
|
595
|
+
relationship: {
|
|
596
|
+
supersedes: to.supersededBy === from.id || updateEdges.some((edge) => edge.sourceId === from.id && edge.targetId === to.id),
|
|
597
|
+
supersededBy: from.supersededBy === to.id || updateEdges.some((edge) => edge.sourceId === to.id && edge.targetId === from.id),
|
|
598
|
+
conflicts: conflictEdges.length > 0,
|
|
599
|
+
updateEdges,
|
|
600
|
+
conflictEdges,
|
|
601
|
+
},
|
|
602
|
+
};
|
|
603
|
+
}
|
|
499
604
|
async listMemoryNodesForMaintenance() {
|
|
500
605
|
const rows = await this.sql `
|
|
501
|
-
SELECT
|
|
502
|
-
|
|
606
|
+
SELECT memory.*
|
|
607
|
+
FROM mg_memory_nodes memory
|
|
608
|
+
JOIN mg_topic_nodes topic ON topic.id = memory.topic_node_id
|
|
609
|
+
WHERE memory.forgotten = FALSE
|
|
610
|
+
AND topic.suppressed = FALSE
|
|
611
|
+
ORDER BY memory.session_id ASC, memory.created_at ASC, memory.id ASC
|
|
503
612
|
`;
|
|
504
613
|
return rows.map((row) => this.rowToMemoryNode(row));
|
|
505
614
|
}
|
|
615
|
+
async forgetMemory(memoryNodeId) {
|
|
616
|
+
const changed = await this.forgetMemories([memoryNodeId]);
|
|
617
|
+
return changed > 0;
|
|
618
|
+
}
|
|
619
|
+
async forgetMemories(memoryNodeIds) {
|
|
620
|
+
if (memoryNodeIds.length === 0)
|
|
621
|
+
return 0;
|
|
622
|
+
const rows = await this.sql `
|
|
623
|
+
UPDATE mg_memory_nodes
|
|
624
|
+
SET
|
|
625
|
+
forgotten = TRUE,
|
|
626
|
+
forgotten_at = COALESCE(forgotten_at, NOW())
|
|
627
|
+
WHERE id = ANY(${this.sql.array(memoryNodeIds)}::uuid[])
|
|
628
|
+
AND forgotten = FALSE
|
|
629
|
+
RETURNING id
|
|
630
|
+
`;
|
|
631
|
+
return rows.length;
|
|
632
|
+
}
|
|
633
|
+
async suppressTopic(topicNodeId) {
|
|
634
|
+
const rows = await this.sql `
|
|
635
|
+
UPDATE mg_topic_nodes
|
|
636
|
+
SET
|
|
637
|
+
suppressed = TRUE,
|
|
638
|
+
suppressed_at = COALESCE(suppressed_at, NOW())
|
|
639
|
+
WHERE id = ${topicNodeId}
|
|
640
|
+
AND suppressed = FALSE
|
|
641
|
+
RETURNING id
|
|
642
|
+
`;
|
|
643
|
+
return rows.length > 0;
|
|
644
|
+
}
|
|
645
|
+
async restoreTopic(topicNodeId) {
|
|
646
|
+
const rows = await this.sql `
|
|
647
|
+
UPDATE mg_topic_nodes
|
|
648
|
+
SET
|
|
649
|
+
suppressed = FALSE,
|
|
650
|
+
suppressed_at = NULL
|
|
651
|
+
WHERE id = ${topicNodeId}
|
|
652
|
+
AND suppressed = TRUE
|
|
653
|
+
RETURNING id
|
|
654
|
+
`;
|
|
655
|
+
return rows.length > 0;
|
|
656
|
+
}
|
|
506
657
|
async markMemoryNodesConflicting(memoryNodeIds) {
|
|
507
658
|
if (memoryNodeIds.length === 0)
|
|
508
659
|
return 0;
|
|
@@ -575,13 +726,16 @@ export class PostgresGraphStore {
|
|
|
575
726
|
const tags = normalizeTags(options.tags);
|
|
576
727
|
const searchTaggedSessions = options.scope === "tagged" && tags.length > 0;
|
|
577
728
|
const rows = await this.sql `
|
|
578
|
-
SELECT
|
|
579
|
-
FROM mg_memory_nodes
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
AND
|
|
583
|
-
|
|
584
|
-
AND
|
|
729
|
+
SELECT memory.*, 1 - (memory.embedding <=> ${toVectorLiteral(embedding)}::vector) AS similarity
|
|
730
|
+
FROM mg_memory_nodes memory
|
|
731
|
+
JOIN mg_topic_nodes topic ON topic.id = memory.topic_node_id
|
|
732
|
+
WHERE ${searchTaggedSessions ? this.sql `TRUE` : this.sql `memory.session_id = ${sessionId}`}
|
|
733
|
+
AND memory.decayed = false
|
|
734
|
+
AND memory.superseded_by IS NULL
|
|
735
|
+
AND memory.forgotten = false
|
|
736
|
+
AND topic.suppressed = false
|
|
737
|
+
${this.memoryTagsFilterSql(tags, options.tagMode, "memory")}
|
|
738
|
+
AND 1 - (memory.embedding <=> ${toVectorLiteral(embedding)}::vector) >= ${minSimilarity}
|
|
585
739
|
ORDER BY similarity DESC
|
|
586
740
|
LIMIT ${limit}
|
|
587
741
|
`;
|
|
@@ -634,6 +788,7 @@ export class PostgresGraphStore {
|
|
|
634
788
|
SELECT *, 1 - (embedding <=> ${toVectorLiteral(embedding)}::vector) AS similarity
|
|
635
789
|
FROM mg_topic_nodes
|
|
636
790
|
WHERE session_id = ${sessionId}
|
|
791
|
+
AND suppressed = FALSE
|
|
637
792
|
${options.excludeNodeId ? this.sql `AND id != ${options.excludeNodeId}` : this.sql ``}
|
|
638
793
|
${options.minSimilarity === undefined ? this.sql `` : this.sql `AND 1 - (embedding <=> ${toVectorLiteral(embedding)}::vector) >= ${options.minSimilarity}`}
|
|
639
794
|
ORDER BY embedding <=> ${toVectorLiteral(embedding)}::vector ASC
|
|
@@ -646,6 +801,7 @@ export class PostgresGraphStore {
|
|
|
646
801
|
SELECT *, 1 - (embedding <=> ${toVectorLiteral(embedding)}::vector) AS similarity
|
|
647
802
|
FROM mg_topic_nodes
|
|
648
803
|
WHERE fleet_id = ${fleetId}
|
|
804
|
+
AND suppressed = FALSE
|
|
649
805
|
${options.agentColor ? this.sql `AND agent_color = ${options.agentColor}` : this.sql ``}
|
|
650
806
|
${options.excludeNodeId ? this.sql `AND id != ${options.excludeNodeId}` : this.sql ``}
|
|
651
807
|
${options.minSimilarity === undefined ? this.sql `` : this.sql `AND 1 - (embedding <=> ${toVectorLiteral(embedding)}::vector) >= ${options.minSimilarity}`}
|
|
@@ -659,6 +815,7 @@ export class PostgresGraphStore {
|
|
|
659
815
|
SELECT * FROM mg_topic_nodes
|
|
660
816
|
WHERE fleet_id = ${fleetId}
|
|
661
817
|
AND agent_color = ${agentColor}
|
|
818
|
+
AND suppressed = FALSE
|
|
662
819
|
ORDER BY topic_order ASC, created_at ASC
|
|
663
820
|
`;
|
|
664
821
|
return rows.map((row) => this.rowToNode(row));
|
|
@@ -724,6 +881,7 @@ export class PostgresGraphStore {
|
|
|
724
881
|
FROM mg_topic_nodes
|
|
725
882
|
WHERE session_id = ${sessionId}
|
|
726
883
|
AND topic_order = ${topicOrder - 1}
|
|
884
|
+
AND suppressed = FALSE
|
|
727
885
|
LIMIT 1
|
|
728
886
|
`;
|
|
729
887
|
return rows[0] ? this.rowToNode(rows[0]) : null;
|
|
@@ -767,6 +925,7 @@ export class PostgresGraphStore {
|
|
|
767
925
|
SELECT * FROM mg_topic_nodes
|
|
768
926
|
WHERE id = ANY(${this.sql.array(ids)})
|
|
769
927
|
${sessionId ? this.sql `AND session_id = ${sessionId}` : this.sql ``}
|
|
928
|
+
AND suppressed = FALSE
|
|
770
929
|
ORDER BY topic_order ASC, created_at ASC
|
|
771
930
|
`;
|
|
772
931
|
return rows.map((row) => this.rowToNode(row));
|
|
@@ -825,7 +984,10 @@ export class PostgresGraphStore {
|
|
|
825
984
|
const copiedNodes = [];
|
|
826
985
|
const nextMessageIndex = await this.getNextMessageIndex(targetSessionId);
|
|
827
986
|
const nextTopicOrder = await this.getNextTopicOrder(targetSessionId);
|
|
828
|
-
for (const
|
|
987
|
+
for (const node of nodes) {
|
|
988
|
+
if (node.suppressed)
|
|
989
|
+
continue;
|
|
990
|
+
const index = copiedNodes.length;
|
|
829
991
|
const messageIndex = nextMessageIndex + index;
|
|
830
992
|
await this.saveMessagesAt(targetSessionId, messageIndex, [{
|
|
831
993
|
role: "assistant",
|
|
@@ -919,8 +1081,182 @@ export class PostgresGraphStore {
|
|
|
919
1081
|
AND session_id = ${sourceNode.sessionId}
|
|
920
1082
|
AND decayed = FALSE
|
|
921
1083
|
AND superseded_by IS NULL
|
|
1084
|
+
AND forgotten = FALSE
|
|
922
1085
|
`;
|
|
923
1086
|
}
|
|
1087
|
+
async getMemoryNodeById(memoryNodeId, sessionId) {
|
|
1088
|
+
if (sessionId) {
|
|
1089
|
+
const rows = await this.sql `
|
|
1090
|
+
SELECT *
|
|
1091
|
+
FROM mg_memory_nodes
|
|
1092
|
+
WHERE id = ${memoryNodeId}::uuid
|
|
1093
|
+
AND session_id = ${sessionId}
|
|
1094
|
+
LIMIT 1
|
|
1095
|
+
`;
|
|
1096
|
+
return rows[0] ? this.rowToMemoryNode(rows[0]) : null;
|
|
1097
|
+
}
|
|
1098
|
+
const rows = await this.sql `
|
|
1099
|
+
SELECT *
|
|
1100
|
+
FROM mg_memory_nodes
|
|
1101
|
+
WHERE id = ${memoryNodeId}::uuid
|
|
1102
|
+
LIMIT 1
|
|
1103
|
+
`;
|
|
1104
|
+
return rows[0] ? this.rowToMemoryNode(rows[0]) : null;
|
|
1105
|
+
}
|
|
1106
|
+
async getMemoryNodesByIds(memoryNodeIds, sessionId) {
|
|
1107
|
+
if (memoryNodeIds.length === 0)
|
|
1108
|
+
return [];
|
|
1109
|
+
if (sessionId) {
|
|
1110
|
+
const rows = await this.sql `
|
|
1111
|
+
SELECT *
|
|
1112
|
+
FROM mg_memory_nodes
|
|
1113
|
+
WHERE id = ANY(${this.sql.array(memoryNodeIds)}::uuid[])
|
|
1114
|
+
AND session_id = ${sessionId}
|
|
1115
|
+
ORDER BY created_at ASC, id ASC
|
|
1116
|
+
`;
|
|
1117
|
+
return rows.map((row) => this.rowToMemoryNode(row));
|
|
1118
|
+
}
|
|
1119
|
+
const rows = await this.sql `
|
|
1120
|
+
SELECT *
|
|
1121
|
+
FROM mg_memory_nodes
|
|
1122
|
+
WHERE id = ANY(${this.sql.array(memoryNodeIds)}::uuid[])
|
|
1123
|
+
ORDER BY created_at ASC, id ASC
|
|
1124
|
+
`;
|
|
1125
|
+
return rows.map((row) => this.rowToMemoryNode(row));
|
|
1126
|
+
}
|
|
1127
|
+
async getMemoryNodesByFactKey(subject, predicate, options = {}) {
|
|
1128
|
+
const normalizedSubject = this.normalizeMemoryHistoryPart(subject);
|
|
1129
|
+
const normalizedPredicate = this.normalizeMemoryHistoryPart(predicate);
|
|
1130
|
+
if (options.sessionId) {
|
|
1131
|
+
const rows = await this.sql `
|
|
1132
|
+
SELECT *
|
|
1133
|
+
FROM mg_memory_nodes
|
|
1134
|
+
WHERE lower(regexp_replace(trim(subject), '[[:space:]]+', ' ', 'g')) = ${normalizedSubject}
|
|
1135
|
+
AND lower(regexp_replace(trim(predicate), '[[:space:]]+', ' ', 'g')) = ${normalizedPredicate}
|
|
1136
|
+
AND session_id = ${options.sessionId}
|
|
1137
|
+
ORDER BY created_at ASC, id ASC
|
|
1138
|
+
`;
|
|
1139
|
+
return rows.map((row) => this.rowToMemoryNode(row));
|
|
1140
|
+
}
|
|
1141
|
+
const rows = await this.sql `
|
|
1142
|
+
SELECT *
|
|
1143
|
+
FROM mg_memory_nodes
|
|
1144
|
+
WHERE lower(regexp_replace(trim(subject), '[[:space:]]+', ' ', 'g')) = ${normalizedSubject}
|
|
1145
|
+
AND lower(regexp_replace(trim(predicate), '[[:space:]]+', ' ', 'g')) = ${normalizedPredicate}
|
|
1146
|
+
ORDER BY created_at ASC, id ASC
|
|
1147
|
+
`;
|
|
1148
|
+
return rows.map((row) => this.rowToMemoryNode(row));
|
|
1149
|
+
}
|
|
1150
|
+
async getMemoryEdgesForMemoryIds(memoryNodeIds) {
|
|
1151
|
+
if (memoryNodeIds.length === 0)
|
|
1152
|
+
return [];
|
|
1153
|
+
const rows = await this.sql `
|
|
1154
|
+
SELECT DISTINCT *
|
|
1155
|
+
FROM mg_memory_edges
|
|
1156
|
+
WHERE source_id = ANY(${this.sql.array(memoryNodeIds)}::uuid[])
|
|
1157
|
+
OR target_id = ANY(${this.sql.array(memoryNodeIds)}::uuid[])
|
|
1158
|
+
ORDER BY created_at ASC, id ASC
|
|
1159
|
+
`;
|
|
1160
|
+
return rows.map((row) => this.rowToMemoryEdge(row));
|
|
1161
|
+
}
|
|
1162
|
+
buildMemoryHistoryResult(memories, edges, metadata) {
|
|
1163
|
+
const memoriesById = new Map(memories.map((memory) => [memory.id, memory]));
|
|
1164
|
+
const visibleEdges = edges.filter((edge) => memoriesById.has(edge.sourceId) && memoriesById.has(edge.targetId));
|
|
1165
|
+
const sortedMemories = [...memories].sort((left, right) => left.createdAt.getTime() - right.createdAt.getTime()
|
|
1166
|
+
|| left.id.localeCompare(right.id));
|
|
1167
|
+
const entries = sortedMemories.map((memory, index) => {
|
|
1168
|
+
const updateEdges = visibleEdges.filter((edge) => edge.edgeType === "updates"
|
|
1169
|
+
&& (edge.sourceId === memory.id || edge.targetId === memory.id));
|
|
1170
|
+
const conflictEdges = visibleEdges.filter((edge) => edge.edgeType === "conflicts"
|
|
1171
|
+
&& (edge.sourceId === memory.id || edge.targetId === memory.id));
|
|
1172
|
+
const supersedes = [
|
|
1173
|
+
...sortedMemories
|
|
1174
|
+
.filter((candidate) => candidate.supersededBy === memory.id)
|
|
1175
|
+
.map((candidate) => candidate.id),
|
|
1176
|
+
...updateEdges
|
|
1177
|
+
.filter((edge) => edge.sourceId === memory.id)
|
|
1178
|
+
.map((edge) => edge.targetId),
|
|
1179
|
+
];
|
|
1180
|
+
const conflictsWith = conflictEdges.map((edge) => edge.sourceId === memory.id ? edge.targetId : edge.sourceId);
|
|
1181
|
+
return {
|
|
1182
|
+
memory,
|
|
1183
|
+
versionIndex: index,
|
|
1184
|
+
status: this.resolveMemoryHistoryStatus(memory, conflictEdges),
|
|
1185
|
+
supersedes: [...new Set(supersedes)],
|
|
1186
|
+
supersededBy: memory.supersededBy,
|
|
1187
|
+
conflictsWith: [...new Set(conflictsWith)],
|
|
1188
|
+
updateEdges,
|
|
1189
|
+
conflictEdges,
|
|
1190
|
+
createdAt: memory.createdAt,
|
|
1191
|
+
};
|
|
1192
|
+
});
|
|
1193
|
+
return {
|
|
1194
|
+
...metadata,
|
|
1195
|
+
entries,
|
|
1196
|
+
edges: visibleEdges,
|
|
1197
|
+
currentMemory: this.resolveCurrentMemory(sortedMemories),
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
resolveMemoryHistoryStatus(memory, conflictEdges) {
|
|
1201
|
+
if (memory.forgotten)
|
|
1202
|
+
return "forgotten";
|
|
1203
|
+
if (memory.decayed)
|
|
1204
|
+
return "decayed";
|
|
1205
|
+
if (memory.supersededBy != null)
|
|
1206
|
+
return "superseded";
|
|
1207
|
+
if (memory.hasConflict || conflictEdges.length > 0)
|
|
1208
|
+
return "conflicting";
|
|
1209
|
+
return "active";
|
|
1210
|
+
}
|
|
1211
|
+
resolveCurrentMemory(memories) {
|
|
1212
|
+
return [...memories]
|
|
1213
|
+
.filter((memory) => !memory.forgotten && !memory.decayed && memory.supersededBy == null)
|
|
1214
|
+
.sort((left, right) => right.createdAt.getTime() - left.createdAt.getTime()
|
|
1215
|
+
|| right.id.localeCompare(left.id))[0] ?? null;
|
|
1216
|
+
}
|
|
1217
|
+
getConnectedMemoryIds(edges) {
|
|
1218
|
+
return [...new Set(edges.flatMap((edge) => [edge.sourceId, edge.targetId]))];
|
|
1219
|
+
}
|
|
1220
|
+
diffMemoryFields(from, to) {
|
|
1221
|
+
const fields = [
|
|
1222
|
+
"sessionId",
|
|
1223
|
+
"topicNodeId",
|
|
1224
|
+
"agentId",
|
|
1225
|
+
"memoryType",
|
|
1226
|
+
"sourceType",
|
|
1227
|
+
"subject",
|
|
1228
|
+
"predicate",
|
|
1229
|
+
"value",
|
|
1230
|
+
"confidence",
|
|
1231
|
+
"tags",
|
|
1232
|
+
"source",
|
|
1233
|
+
"sourceUrl",
|
|
1234
|
+
"sourceTitle",
|
|
1235
|
+
"supersededBy",
|
|
1236
|
+
"decayed",
|
|
1237
|
+
"forgotten",
|
|
1238
|
+
"forgottenAt",
|
|
1239
|
+
"hasConflict",
|
|
1240
|
+
"agentColor",
|
|
1241
|
+
"fleetId",
|
|
1242
|
+
"createdAt",
|
|
1243
|
+
];
|
|
1244
|
+
return fields.map((field) => ({
|
|
1245
|
+
field,
|
|
1246
|
+
from: from[field],
|
|
1247
|
+
to: to[field],
|
|
1248
|
+
changed: !this.memoryDiffValuesEqual(from[field], to[field]),
|
|
1249
|
+
}));
|
|
1250
|
+
}
|
|
1251
|
+
memoryDiffValuesEqual(left, right) {
|
|
1252
|
+
if (left instanceof Date && right instanceof Date) {
|
|
1253
|
+
return left.getTime() === right.getTime();
|
|
1254
|
+
}
|
|
1255
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
1256
|
+
}
|
|
1257
|
+
normalizeMemoryHistoryPart(value) {
|
|
1258
|
+
return value.trim().toLowerCase().replace(/\s+/g, " ");
|
|
1259
|
+
}
|
|
924
1260
|
async deleteEdgesByNodeIds(nodeIds) {
|
|
925
1261
|
if (nodeIds.length === 0)
|
|
926
1262
|
return;
|
|
@@ -1016,6 +1352,11 @@ export class PostgresGraphStore {
|
|
|
1016
1352
|
await this.sql `
|
|
1017
1353
|
CREATE INDEX IF NOT EXISTS mg_nodes_session_idx
|
|
1018
1354
|
ON mg_topic_nodes(session_id, topic_order)
|
|
1355
|
+
`;
|
|
1356
|
+
await this.sql `
|
|
1357
|
+
CREATE INDEX IF NOT EXISTS idx_topic_nodes_active_lifecycle
|
|
1358
|
+
ON mg_topic_nodes(session_id, suppressed)
|
|
1359
|
+
WHERE suppressed = FALSE
|
|
1019
1360
|
`;
|
|
1020
1361
|
await this.sql `
|
|
1021
1362
|
CREATE INDEX IF NOT EXISTS mg_topic_nodes_tags_idx
|
|
@@ -1058,6 +1399,11 @@ export class PostgresGraphStore {
|
|
|
1058
1399
|
await this.sql `
|
|
1059
1400
|
CREATE INDEX IF NOT EXISTS idx_memory_nodes_session
|
|
1060
1401
|
ON mg_memory_nodes(session_id)
|
|
1402
|
+
`;
|
|
1403
|
+
await this.sql `
|
|
1404
|
+
CREATE INDEX IF NOT EXISTS idx_memory_nodes_active_lifecycle
|
|
1405
|
+
ON mg_memory_nodes(session_id, forgotten, decayed)
|
|
1406
|
+
WHERE forgotten = FALSE
|
|
1061
1407
|
`;
|
|
1062
1408
|
await this.sql `
|
|
1063
1409
|
CREATE INDEX IF NOT EXISTS idx_memory_nodes_tags
|
|
@@ -1096,9 +1442,14 @@ export class PostgresGraphStore {
|
|
|
1096
1442
|
? this.sql `AND tags && ${this.sql.array(tags)}::text[]`
|
|
1097
1443
|
: this.sql `AND tags @> ${this.sql.array(tags)}::text[]`;
|
|
1098
1444
|
}
|
|
1099
|
-
memoryTagsFilterSql(tags, tagMode = "all") {
|
|
1445
|
+
memoryTagsFilterSql(tags, tagMode = "all", tableAlias) {
|
|
1100
1446
|
if (tags.length === 0)
|
|
1101
1447
|
return this.sql ``;
|
|
1448
|
+
if (tableAlias === "memory") {
|
|
1449
|
+
return tagMode === "any"
|
|
1450
|
+
? this.sql `AND memory.tags && ${this.sql.array(tags)}::text[]`
|
|
1451
|
+
: this.sql `AND memory.tags @> ${this.sql.array(tags)}::text[]`;
|
|
1452
|
+
}
|
|
1102
1453
|
return tagMode === "any"
|
|
1103
1454
|
? this.sql `AND tags && ${this.sql.array(tags)}::text[]`
|
|
1104
1455
|
: this.sql `AND tags @> ${this.sql.array(tags)}::text[]`;
|
|
@@ -1142,6 +1493,8 @@ export class PostgresGraphStore {
|
|
|
1142
1493
|
agentColor: row.agent_color,
|
|
1143
1494
|
fleetId: row.fleet_id,
|
|
1144
1495
|
agentId: row.agent_id,
|
|
1496
|
+
suppressed: row.suppressed ?? false,
|
|
1497
|
+
suppressedAt: row.suppressed_at,
|
|
1145
1498
|
createdAt: row.created_at,
|
|
1146
1499
|
};
|
|
1147
1500
|
}
|
|
@@ -1165,6 +1518,8 @@ export class PostgresGraphStore {
|
|
|
1165
1518
|
sourceTitle: row.source_title,
|
|
1166
1519
|
supersededBy: row.superseded_by,
|
|
1167
1520
|
decayed: row.decayed,
|
|
1521
|
+
forgotten: row.forgotten ?? false,
|
|
1522
|
+
forgottenAt: row.forgotten_at,
|
|
1168
1523
|
hasConflict: row.has_conflict ?? false,
|
|
1169
1524
|
agentColor: row.agent_color,
|
|
1170
1525
|
fleetId: row.fleet_id,
|