openclaw-cortex-memory 0.1.0-Alpha.3 → 0.1.0-Alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +101 -18
  2. package/SKILL.md +79 -9
  3. package/dist/index.d.ts +18 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +159 -7
  6. package/dist/index.js.map +1 -1
  7. package/dist/openclaw.plugin.json +101 -1
  8. package/dist/src/dedup/three_stage_deduplicator.d.ts +25 -0
  9. package/dist/src/dedup/three_stage_deduplicator.d.ts.map +1 -0
  10. package/dist/src/dedup/three_stage_deduplicator.js +225 -0
  11. package/dist/src/dedup/three_stage_deduplicator.js.map +1 -0
  12. package/dist/src/engine/ts_engine.d.ts +36 -0
  13. package/dist/src/engine/ts_engine.d.ts.map +1 -1
  14. package/dist/src/engine/ts_engine.js +197 -32
  15. package/dist/src/engine/ts_engine.js.map +1 -1
  16. package/dist/src/engine/types.d.ts +4 -0
  17. package/dist/src/engine/types.d.ts.map +1 -1
  18. package/dist/src/graph/ontology.d.ts +53 -0
  19. package/dist/src/graph/ontology.d.ts.map +1 -0
  20. package/dist/src/graph/ontology.js +252 -0
  21. package/dist/src/graph/ontology.js.map +1 -0
  22. package/dist/src/reflect/reflector.d.ts +7 -0
  23. package/dist/src/reflect/reflector.d.ts.map +1 -1
  24. package/dist/src/reflect/reflector.js +75 -1
  25. package/dist/src/reflect/reflector.js.map +1 -1
  26. package/dist/src/session/session_end.d.ts +55 -0
  27. package/dist/src/session/session_end.d.ts.map +1 -1
  28. package/dist/src/session/session_end.js +237 -51
  29. package/dist/src/session/session_end.js.map +1 -1
  30. package/dist/src/store/archive_store.d.ts +89 -0
  31. package/dist/src/store/archive_store.d.ts.map +1 -0
  32. package/dist/src/store/archive_store.js +242 -0
  33. package/dist/src/store/archive_store.js.map +1 -0
  34. package/dist/src/store/read_store.d.ts +39 -0
  35. package/dist/src/store/read_store.d.ts.map +1 -1
  36. package/dist/src/store/read_store.js +796 -15
  37. package/dist/src/store/read_store.js.map +1 -1
  38. package/dist/src/store/vector_store.d.ts +30 -0
  39. package/dist/src/store/vector_store.d.ts.map +1 -0
  40. package/dist/src/store/vector_store.js +127 -0
  41. package/dist/src/store/vector_store.js.map +1 -0
  42. package/dist/src/store/write_store.d.ts +8 -0
  43. package/dist/src/store/write_store.d.ts.map +1 -1
  44. package/dist/src/store/write_store.js +70 -0
  45. package/dist/src/store/write_store.js.map +1 -1
  46. package/dist/src/sync/session_sync.d.ts +7 -0
  47. package/dist/src/sync/session_sync.d.ts.map +1 -1
  48. package/dist/src/sync/session_sync.js +120 -10
  49. package/dist/src/sync/session_sync.js.map +1 -1
  50. package/openclaw.plugin.json +101 -1
  51. package/package.json +16 -5
  52. package/scripts/cli.js +6 -1
  53. package/scripts/uninstall.js +15 -4
  54. package/index.ts +0 -2142
  55. package/scripts/install.js +0 -27
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createThreeStageDeduplicator = createThreeStageDeduplicator;
37
+ const crypto = __importStar(require("crypto"));
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ function tokenize(text) {
41
+ return text
42
+ .toLowerCase()
43
+ .replace(/[^\p{L}\p{N}\s]/gu, " ")
44
+ .split(/\s+/)
45
+ .filter(Boolean);
46
+ }
47
+ function buildShingles(tokens, size) {
48
+ if (tokens.length < size) {
49
+ return [tokens.join(" ")].filter(Boolean);
50
+ }
51
+ const result = [];
52
+ for (let i = 0; i <= tokens.length - size; i += 1) {
53
+ result.push(tokens.slice(i, i + size).join(" "));
54
+ }
55
+ return result;
56
+ }
57
+ function hashToken(value) {
58
+ const digest = crypto.createHash("sha1").update(value).digest();
59
+ let output = 0n;
60
+ for (let i = 0; i < 8; i += 1) {
61
+ output = (output << 8n) + BigInt(digest[i]);
62
+ }
63
+ return output;
64
+ }
65
+ function computeSimhash(text) {
66
+ const tokens = tokenize(text);
67
+ const vector = Array.from({ length: 64 }, () => 0);
68
+ for (const token of tokens) {
69
+ const hash = hashToken(token);
70
+ for (let bit = 0; bit < 64; bit += 1) {
71
+ const mask = 1n << BigInt(bit);
72
+ vector[bit] += (hash & mask) !== 0n ? 1 : -1;
73
+ }
74
+ }
75
+ let result = 0n;
76
+ for (let bit = 0; bit < 64; bit += 1) {
77
+ if (vector[bit] >= 0) {
78
+ result |= 1n << BigInt(bit);
79
+ }
80
+ }
81
+ return result;
82
+ }
83
+ function hammingDistance(left, right) {
84
+ let value = left ^ right;
85
+ let count = 0;
86
+ while (value > 0n) {
87
+ count += Number(value & 1n);
88
+ value >>= 1n;
89
+ }
90
+ return count;
91
+ }
92
+ function seedHash(seed, token) {
93
+ const digest = crypto.createHash("sha1").update(`${seed}:${token}`).digest();
94
+ return digest.readUInt32BE(0);
95
+ }
96
+ function computeMinhash(text, signatures = 64) {
97
+ const tokens = tokenize(text);
98
+ const shingles = buildShingles(tokens, 2);
99
+ if (shingles.length === 0) {
100
+ return Array.from({ length: signatures }, () => 0);
101
+ }
102
+ const output = [];
103
+ for (let seed = 0; seed < signatures; seed += 1) {
104
+ let min = Number.MAX_SAFE_INTEGER;
105
+ for (const shingle of shingles) {
106
+ const value = seedHash(seed, shingle);
107
+ if (value < min) {
108
+ min = value;
109
+ }
110
+ }
111
+ output.push(min === Number.MAX_SAFE_INTEGER ? 0 : min);
112
+ }
113
+ return output;
114
+ }
115
+ function minhashSimilarity(left, right) {
116
+ if (left.length === 0 || right.length === 0) {
117
+ return 0;
118
+ }
119
+ const size = Math.min(left.length, right.length);
120
+ let same = 0;
121
+ for (let i = 0; i < size; i += 1) {
122
+ if (left[i] === right[i]) {
123
+ same += 1;
124
+ }
125
+ }
126
+ return same / size;
127
+ }
128
+ function cosineSimilarity(left, right) {
129
+ if (!left.length || !right.length) {
130
+ return 0;
131
+ }
132
+ const size = Math.min(left.length, right.length);
133
+ let dot = 0;
134
+ let normLeft = 0;
135
+ let normRight = 0;
136
+ for (let i = 0; i < size; i += 1) {
137
+ dot += left[i] * right[i];
138
+ normLeft += left[i] * left[i];
139
+ normRight += right[i] * right[i];
140
+ }
141
+ if (normLeft === 0 || normRight === 0) {
142
+ return 0;
143
+ }
144
+ return dot / (Math.sqrt(normLeft) * Math.sqrt(normRight));
145
+ }
146
+ function readState(filePath) {
147
+ try {
148
+ if (!fs.existsSync(filePath)) {
149
+ return { items: [] };
150
+ }
151
+ const content = fs.readFileSync(filePath, "utf-8").trim();
152
+ if (!content) {
153
+ return { items: [] };
154
+ }
155
+ const parsed = JSON.parse(content);
156
+ if (!Array.isArray(parsed.items)) {
157
+ return { items: [] };
158
+ }
159
+ return parsed;
160
+ }
161
+ catch {
162
+ return { items: [] };
163
+ }
164
+ }
165
+ function writeState(filePath, state) {
166
+ const dir = path.dirname(filePath);
167
+ if (!fs.existsSync(dir)) {
168
+ fs.mkdirSync(dir, { recursive: true });
169
+ }
170
+ fs.writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
171
+ }
172
+ function createThreeStageDeduplicator(options) {
173
+ const statePath = path.join(options.memoryRoot, ".dedup_index.json");
174
+ const maxItems = 8000;
175
+ function check(input) {
176
+ const state = readState(statePath);
177
+ const simhash = computeSimhash(input.summary);
178
+ const minhash = computeMinhash(input.summary);
179
+ const recent = state.items.slice(-2000);
180
+ for (const item of recent) {
181
+ const distance = hammingDistance(simhash, BigInt(`0x${item.simhash}`));
182
+ if (distance <= 3) {
183
+ return { duplicate: true, stage: "simhash", matchedId: item.id };
184
+ }
185
+ }
186
+ for (const item of recent) {
187
+ const similarity = minhashSimilarity(minhash, item.minhash);
188
+ if (similarity >= 0.88) {
189
+ return { duplicate: true, stage: "minhash", matchedId: item.id };
190
+ }
191
+ }
192
+ if (input.embedding && input.embedding.length > 0) {
193
+ for (const item of recent) {
194
+ if (!item.embedding || item.embedding.length === 0) {
195
+ continue;
196
+ }
197
+ const similarity = cosineSimilarity(input.embedding, item.embedding);
198
+ if (similarity >= 0.95) {
199
+ return { duplicate: true, stage: "vector", matchedId: item.id };
200
+ }
201
+ }
202
+ }
203
+ return { duplicate: false };
204
+ }
205
+ function append(input) {
206
+ const state = readState(statePath);
207
+ const item = {
208
+ id: input.id,
209
+ summary: input.summary.slice(0, 500),
210
+ simhash: computeSimhash(input.summary).toString(16).padStart(16, "0"),
211
+ minhash: computeMinhash(input.summary),
212
+ embedding: input.embedding && input.embedding.length > 0 ? input.embedding : undefined,
213
+ createdAt: new Date().toISOString(),
214
+ };
215
+ state.items.push(item);
216
+ if (state.items.length > maxItems) {
217
+ state.items = state.items.slice(state.items.length - maxItems);
218
+ }
219
+ writeState(statePath, state);
220
+ options.logger.debug(`ThreeStageDeduplicator indexed event ${input.id}`);
221
+ }
222
+ options.logger.info(`ThreeStageDeduplicator initialized at ${statePath}`);
223
+ return { check, append };
224
+ }
225
+ //# sourceMappingURL=three_stage_deduplicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"three_stage_deduplicator.js","sourceRoot":"","sources":["../../../src/dedup/three_stage_deduplicator.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,34 @@ interface TsEngineDeps {
12
12
  sessionId: string;
13
13
  }): Promise<WriteMemoryResult>;
14
14
  };
15
+ archiveStore: {
16
+ storeEvents(events: Array<{
17
+ event_type: string;
18
+ summary: string;
19
+ entities?: string[];
20
+ relations?: Array<{
21
+ source: string;
22
+ target: string;
23
+ type: string;
24
+ }>;
25
+ entity_types?: Record<string, string>;
26
+ outcome?: string;
27
+ session_id: string;
28
+ source_file: string;
29
+ confidence?: number;
30
+ source_event_id?: string;
31
+ actor?: string;
32
+ canonical_id?: string;
33
+ }>): Promise<{
34
+ stored: Array<{
35
+ id: string;
36
+ }>;
37
+ skipped: Array<{
38
+ summary: string;
39
+ reason: string;
40
+ }>;
41
+ }>;
42
+ };
15
43
  sessionSync: {
16
44
  syncMemory(): Promise<{
17
45
  imported: number;
@@ -23,6 +51,13 @@ interface TsEngineDeps {
23
51
  onSessionEnd(args: {
24
52
  sessionId: string;
25
53
  syncRecords: boolean;
54
+ messages?: Array<{
55
+ id?: string;
56
+ session_id?: string;
57
+ role?: string;
58
+ content?: string;
59
+ timestamp?: string;
60
+ }>;
26
61
  }): Promise<{
27
62
  events_generated: number;
28
63
  sync_result?: {
@@ -44,6 +79,7 @@ interface TsEngineDeps {
44
79
  }>;
45
80
  };
46
81
  memoryRoot: string;
82
+ projectRoot: string;
47
83
  getCachedAutoSearch: (sessionId: string) => {
48
84
  query: string;
49
85
  results: unknown[];
@@ -1 +1 @@
1
- {"version":3,"file":"ts_engine.d.ts","sourceRoot":"","sources":["../../../src/engine/ts_engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAQV,WAAW,EAGZ,MAAM,SAAS,CAAC;AAEjB,UAAU,YAAY;IACpB,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE;QACV,WAAW,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;KAClH,CAAC;IACF,WAAW,EAAE;QACX,UAAU,IAAI,OAAO,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACtF,CAAC;IACF,UAAU,EAAE;QACV,YAAY,CAAC,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC;YACvE,gBAAgB,EAAE,MAAM,CAAC;YACzB,WAAW,CAAC,EAAE;gBAAE,QAAQ,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAC;gBAAC,cAAc,EAAE,MAAM,CAAA;aAAE,CAAC;SAC7E,CAAC,CAAC;KACJ,CAAC;IACF,SAAS,EAAE;QACT,aAAa,IAAI,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACvF,aAAa,IAAI,OAAO,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACtE,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7G,gBAAgB,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACtE,wBAAwB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACtG,yBAAyB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC1F,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE;QACN,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QACrD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;KACrD,CAAC;CACH;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,YAAY,CAwW/D"}
1
+ {"version":3,"file":"ts_engine.d.ts","sourceRoot":"","sources":["../../../src/engine/ts_engine.ts"],"names":[],"mappings":"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"}
@@ -36,7 +36,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createTsEngine = createTsEngine;
37
37
  const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
+ const ontology_1 = require("../graph/ontology");
39
40
  function createTsEngine(deps) {
41
+ const graphSchema = (0, ontology_1.loadGraphSchema)(deps.projectRoot);
42
+ const sessionMessageBuffer = new Map();
43
+ const maxMessagesPerSession = 500;
44
+ const maxBufferedSessions = 500;
45
+ function pushSessionMessage(sessionId, message) {
46
+ const current = sessionMessageBuffer.get(sessionId) || [];
47
+ current.push({
48
+ id: `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
49
+ session_id: sessionId,
50
+ role: message.role,
51
+ content: message.text,
52
+ timestamp: new Date().toISOString(),
53
+ });
54
+ if (current.length > maxMessagesPerSession) {
55
+ sessionMessageBuffer.set(sessionId, current.slice(current.length - maxMessagesPerSession));
56
+ }
57
+ else {
58
+ sessionMessageBuffer.set(sessionId, current);
59
+ }
60
+ if (sessionMessageBuffer.size > maxBufferedSessions) {
61
+ const first = sessionMessageBuffer.keys().next().value;
62
+ if (first) {
63
+ sessionMessageBuffer.delete(first);
64
+ }
65
+ }
66
+ }
40
67
  function asRecord(value) {
41
68
  if (typeof value === "object" && value !== null) {
42
69
  return value;
@@ -76,20 +103,49 @@ function createTsEngine(deps) {
76
103
  if (!args.summary?.trim()) {
77
104
  return { success: false, error: "Invalid input provided. Missing 'summary' parameter." };
78
105
  }
79
- const { archivePath } = memoryFiles();
80
- const records = readJsonl(archivePath);
81
- const id = `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
82
- records.push({
83
- id,
84
- timestamp: new Date().toISOString(),
85
- summary: args.summary.trim(),
86
- entities: args.entities ?? [],
87
- outcome: args.outcome ?? "",
88
- relations: args.relations ?? [],
89
- source_file: "ts_store_event",
90
- });
91
- writeJsonl(archivePath, records);
92
- return { success: true, data: { event_id: id } };
106
+ const entities = Array.isArray(args.entities)
107
+ ? args.entities.map(item => {
108
+ if (item && typeof item === "object") {
109
+ const value = (item.name || item.id || "");
110
+ return typeof value === "string" ? value.trim() : "";
111
+ }
112
+ return "";
113
+ }).filter(Boolean)
114
+ : [];
115
+ const relations = Array.isArray(args.relations)
116
+ ? args.relations
117
+ .map(item => {
118
+ if (!item || typeof item !== "object")
119
+ return null;
120
+ const relation = item;
121
+ if (!relation.source || !relation.target)
122
+ return null;
123
+ return {
124
+ source: relation.source.trim(),
125
+ target: relation.target.trim(),
126
+ type: (0, ontology_1.normalizeRelationType)(relation.type || "related_to", graphSchema),
127
+ };
128
+ })
129
+ .filter((item) => Boolean(item))
130
+ : [];
131
+ const result = await deps.archiveStore.storeEvents([
132
+ {
133
+ event_type: "manual_event",
134
+ summary: args.summary.trim(),
135
+ entities,
136
+ relations,
137
+ outcome: args.outcome ?? "",
138
+ session_id: "manual",
139
+ source_file: "ts_store_event",
140
+ confidence: 1,
141
+ source_event_id: "",
142
+ actor: "manual_tool",
143
+ },
144
+ ]);
145
+ if (result.stored.length === 0) {
146
+ return { success: false, error: result.skipped[0]?.reason || "store_event_skipped" };
147
+ }
148
+ return { success: true, data: { event_id: result.stored[0].id } };
93
149
  }
94
150
  catch (error) {
95
151
  return { success: false, error: String(error) };
@@ -100,13 +156,95 @@ function createTsEngine(deps) {
100
156
  if (!entity) {
101
157
  return { success: false, error: "Invalid input provided. Missing 'entity' parameter." };
102
158
  }
159
+ const relFilter = typeof args.rel === "string" && args.rel.trim()
160
+ ? (0, ontology_1.normalizeRelationType)(args.rel, graphSchema)
161
+ : "";
162
+ const direction = args.dir === "incoming" || args.dir === "outgoing" || args.dir === "both"
163
+ ? args.dir
164
+ : "both";
165
+ const pathTo = typeof args.path_to === "string" && args.path_to.trim() ? args.path_to.trim() : "";
166
+ const maxDepth = Math.max(2, Math.min(4, typeof args.max_depth === "number" ? Math.floor(args.max_depth) : 3));
103
167
  const { archivePath } = memoryFiles();
104
168
  const records = readJsonl(archivePath);
105
169
  const nodes = new Map();
106
170
  const edges = [];
171
+ const adjacency = new Map();
172
+ const pathAdjacency = new Map();
173
+ const relationTypeDistribution = new Map();
174
+ const edgeKeySet = new Set();
175
+ function pushEdge(source, target, type) {
176
+ const key = `${source}|${type}|${target}`;
177
+ if (edgeKeySet.has(key)) {
178
+ return;
179
+ }
180
+ edgeKeySet.add(key);
181
+ edges.push({ source, target, type });
182
+ relationTypeDistribution.set(type, (relationTypeDistribution.get(type) || 0) + 1);
183
+ if (!adjacency.has(source)) {
184
+ adjacency.set(source, []);
185
+ }
186
+ adjacency.get(source)?.push({ next: target, edge: { source, target, type } });
187
+ if (!adjacency.has(target)) {
188
+ adjacency.set(target, []);
189
+ }
190
+ adjacency.get(target)?.push({ next: source, edge: { source, target, type } });
191
+ }
192
+ function pushPathEdge(source, target, type) {
193
+ if (!pathAdjacency.has(source)) {
194
+ pathAdjacency.set(source, []);
195
+ }
196
+ if (!pathAdjacency.has(target)) {
197
+ pathAdjacency.set(target, []);
198
+ }
199
+ if (direction === "incoming") {
200
+ pathAdjacency.get(target)?.push({ next: source, edge: { source, target, type } });
201
+ }
202
+ else if (direction === "outgoing") {
203
+ pathAdjacency.get(source)?.push({ next: target, edge: { source, target, type } });
204
+ }
205
+ else {
206
+ pathAdjacency.get(source)?.push({ next: target, edge: { source, target, type } });
207
+ pathAdjacency.get(target)?.push({ next: source, edge: { source, target, type } });
208
+ }
209
+ }
107
210
  for (const record of records) {
108
211
  const entities = Array.isArray(record.entities) ? record.entities : [];
109
212
  const named = entities.map(e => (typeof e === "string" ? e.trim() : "")).filter(Boolean);
213
+ const relations = Array.isArray(record.relations) ? record.relations : [];
214
+ let explicitMatched = false;
215
+ for (const relationRaw of relations) {
216
+ if (typeof relationRaw !== "object" || relationRaw === null) {
217
+ continue;
218
+ }
219
+ const relation = relationRaw;
220
+ const source = typeof relation.source === "string" ? relation.source.trim() : "";
221
+ const target = typeof relation.target === "string" ? relation.target.trim() : "";
222
+ const type = (0, ontology_1.normalizeRelationType)(typeof relation.type === "string" && relation.type.trim() ? relation.type.trim() : "related_to", graphSchema);
223
+ if (!source || !target) {
224
+ continue;
225
+ }
226
+ if (relFilter && type !== relFilter) {
227
+ continue;
228
+ }
229
+ pushPathEdge(source, target, type);
230
+ const outgoingMatch = source === entity;
231
+ const incomingMatch = target === entity;
232
+ const directionMatched = direction === "both" ? (outgoingMatch || incomingMatch)
233
+ : direction === "outgoing" ? outgoingMatch
234
+ : incomingMatch;
235
+ if (!directionMatched) {
236
+ continue;
237
+ }
238
+ explicitMatched = true;
239
+ if (!nodes.has(source))
240
+ nodes.set(source, { id: source, type: "entity" });
241
+ if (!nodes.has(target))
242
+ nodes.set(target, { id: target, type: "entity" });
243
+ pushEdge(source, target, type);
244
+ }
245
+ if (explicitMatched) {
246
+ continue;
247
+ }
110
248
  if (!named.includes(entity)) {
111
249
  continue;
112
250
  }
@@ -117,7 +255,40 @@ function createTsEngine(deps) {
117
255
  }
118
256
  for (const name of named) {
119
257
  if (name !== entity) {
120
- edges.push({ source: entity, target: name, type: "co_occurrence" });
258
+ if (!relFilter || relFilter === "co_occurrence") {
259
+ pushEdge(entity, name, "co_occurrence");
260
+ }
261
+ }
262
+ }
263
+ }
264
+ let path = [];
265
+ if (pathTo) {
266
+ const visited = new Set();
267
+ const queue = [
268
+ { node: entity, depth: 0, pathEdges: [] },
269
+ ];
270
+ while (queue.length > 0) {
271
+ const current = queue.shift();
272
+ if (!current)
273
+ break;
274
+ if (current.node === pathTo) {
275
+ path = current.pathEdges;
276
+ break;
277
+ }
278
+ if (current.depth >= maxDepth) {
279
+ continue;
280
+ }
281
+ const visitKey = `${current.node}:${current.depth}`;
282
+ if (visited.has(visitKey)) {
283
+ continue;
284
+ }
285
+ visited.add(visitKey);
286
+ for (const next of pathAdjacency.get(current.node) || []) {
287
+ queue.push({
288
+ node: next.next,
289
+ depth: current.depth + 1,
290
+ pathEdges: [...current.pathEdges, next.edge],
291
+ });
121
292
  }
122
293
  }
123
294
  }
@@ -125,8 +296,14 @@ function createTsEngine(deps) {
125
296
  success: true,
126
297
  data: {
127
298
  entity,
299
+ rel: relFilter || "",
300
+ dir: direction,
128
301
  nodes: [...nodes.values()],
129
302
  edges,
303
+ path_to: pathTo || "",
304
+ max_depth: maxDepth,
305
+ path,
306
+ relation_type_distribution: [...relationTypeDistribution.entries()].map(([type, count]) => ({ type, count })),
130
307
  },
131
308
  };
132
309
  }
@@ -305,12 +482,15 @@ function createTsEngine(deps) {
305
482
  const sessionId = deps.resolveSessionId(context, payload);
306
483
  const syncRecordsRaw = payloadObj?.sync_records;
307
484
  const syncRecords = typeof syncRecordsRaw === "boolean" ? syncRecordsRaw : deps.defaultAutoSync;
485
+ const bufferedMessages = sessionMessageBuffer.get(sessionId) || [];
308
486
  try {
309
487
  const result = await deps.sessionEnd.onSessionEnd({
310
488
  sessionId,
311
489
  syncRecords,
490
+ messages: bufferedMessages,
312
491
  });
313
492
  deps.logger.info(`TS session_end completed for ${sessionId}, events=${result.events_generated}`);
493
+ sessionMessageBuffer.delete(sessionId);
314
494
  }
315
495
  catch (error) {
316
496
  deps.logger.warn(`TS session_end failed for ${sessionId}: ${error}`);
@@ -323,23 +503,8 @@ function createTsEngine(deps) {
323
503
  }
324
504
  const { text, role, source } = normalized;
325
505
  const sessionId = deps.resolveSessionId(context, payload);
326
- try {
327
- const writeResult = await deps.writeStore.writeMemory({
328
- text,
329
- role,
330
- source,
331
- sessionId,
332
- });
333
- if (writeResult.status === "ok") {
334
- deps.logger.info(`TS write stored ${role} message for session ${sessionId}`);
335
- }
336
- else {
337
- deps.logger.debug(`TS write skipped for session ${sessionId}: ${writeResult.reason || "unknown"}`);
338
- }
339
- }
340
- catch (error) {
341
- deps.logger.warn(`TS write failed for session ${sessionId}: ${error}`);
342
- }
506
+ pushSessionMessage(sessionId, { role, text });
507
+ deps.logger.debug(`TS buffered ${role} message for session ${sessionId} source=${source}`);
343
508
  if (role === "user" && text.length > 5) {
344
509
  try {
345
510
  const searchResult = await deps.readStore.searchMemory({ query: text, topK: 3 });