claude-memory-layer 1.0.44 → 1.0.45
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/index.js +747 -1414
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.js +1191 -1490
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +411 -749
- package/dist/hooks/post-tool-use.js.map +1 -1
- package/dist/hooks/semantic-daemon.js +400 -727
- package/dist/hooks/semantic-daemon.js.map +1 -1
- package/dist/hooks/session-end.js +396 -719
- package/dist/hooks/session-end.js.map +1 -1
- package/dist/hooks/session-start.js +397 -721
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/stop.js +404 -735
- package/dist/hooks/stop.js.map +1 -1
- package/dist/hooks/user-prompt-submit.js +440 -807
- package/dist/hooks/user-prompt-submit.js.map +1 -1
- package/dist/index.js +1269 -1604
- package/dist/index.js.map +4 -4
- package/dist/mcp/index.js +1443 -1637
- package/dist/mcp/index.js.map +4 -4
- package/dist/server/api/index.js +430 -785
- package/dist/server/api/index.js.map +1 -1
- package/dist/server/index.js +438 -801
- package/dist/server/index.js.map +1 -1
- package/dist/services/memory-service.js +396 -719
- package/dist/services/memory-service.js.map +1 -1
- package/package.json +15 -3
|
@@ -51,6 +51,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
51
51
|
this.options = options;
|
|
52
52
|
this.fileSystem = options.fileSystem ?? defaultFileSystem;
|
|
53
53
|
}
|
|
54
|
+
options;
|
|
54
55
|
fileSystem;
|
|
55
56
|
getEmbeddingModelName() {
|
|
56
57
|
return this.options.getEmbeddingModelName();
|
|
@@ -85,8 +86,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
85
86
|
}
|
|
86
87
|
const worker = this.options.getVectorWorker();
|
|
87
88
|
const wasRunning = worker?.isRunning() || false;
|
|
88
|
-
if (wasRunning)
|
|
89
|
-
worker?.stop();
|
|
89
|
+
if (wasRunning) worker?.stop();
|
|
90
90
|
await this.options.vectorStore.clearAll();
|
|
91
91
|
await this.options.eventStore.clearEmbeddingOutbox();
|
|
92
92
|
const enqueued = await this.reenqueueAllEvents();
|
|
@@ -103,8 +103,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
103
103
|
2
|
|
104
104
|
)
|
|
105
105
|
);
|
|
106
|
-
if (wasRunning)
|
|
107
|
-
worker?.start();
|
|
106
|
+
if (wasRunning) worker?.start();
|
|
108
107
|
return {
|
|
109
108
|
changed: true,
|
|
110
109
|
previousModel,
|
|
@@ -129,15 +128,13 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
129
128
|
let enqueued = 0;
|
|
130
129
|
while (true) {
|
|
131
130
|
const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
|
|
132
|
-
if (page.length === 0)
|
|
133
|
-
break;
|
|
131
|
+
if (page.length === 0) break;
|
|
134
132
|
for (const event of page) {
|
|
135
133
|
await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
|
|
136
134
|
enqueued += 1;
|
|
137
135
|
}
|
|
138
136
|
offset += page.length;
|
|
139
|
-
if (page.length < DEFAULT_PAGE_SIZE)
|
|
140
|
-
break;
|
|
137
|
+
if (page.length < DEFAULT_PAGE_SIZE) break;
|
|
141
138
|
}
|
|
142
139
|
return enqueued;
|
|
143
140
|
}
|
|
@@ -155,12 +152,9 @@ import { randomUUID } from "crypto";
|
|
|
155
152
|
// src/core/db-wrapper.ts
|
|
156
153
|
import BetterSqlite3 from "better-sqlite3";
|
|
157
154
|
function toDate(value) {
|
|
158
|
-
if (value instanceof Date)
|
|
159
|
-
|
|
160
|
-
if (typeof value === "
|
|
161
|
-
return new Date(value);
|
|
162
|
-
if (typeof value === "number")
|
|
163
|
-
return new Date(value);
|
|
155
|
+
if (value instanceof Date) return value;
|
|
156
|
+
if (typeof value === "string") return new Date(value);
|
|
157
|
+
if (typeof value === "number") return new Date(value);
|
|
164
158
|
return new Date(String(value));
|
|
165
159
|
}
|
|
166
160
|
function createDatabase(dbPath, options) {
|
|
@@ -184,6 +178,8 @@ var WorkingSetStore = class {
|
|
|
184
178
|
this.eventStore = eventStore;
|
|
185
179
|
this.config = config;
|
|
186
180
|
}
|
|
181
|
+
eventStore;
|
|
182
|
+
config;
|
|
187
183
|
get db() {
|
|
188
184
|
return this.eventStore.getDatabase();
|
|
189
185
|
}
|
|
@@ -269,8 +265,7 @@ var WorkingSetStore = class {
|
|
|
269
265
|
* Prune specific events from working set (after consolidation)
|
|
270
266
|
*/
|
|
271
267
|
async prune(eventIds) {
|
|
272
|
-
if (eventIds.length === 0)
|
|
273
|
-
return;
|
|
268
|
+
if (eventIds.length === 0) return;
|
|
274
269
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
275
270
|
await dbRun(
|
|
276
271
|
this.db,
|
|
@@ -340,8 +335,7 @@ var WorkingSetStore = class {
|
|
|
340
335
|
LIMIT ?`,
|
|
341
336
|
[maxEvents]
|
|
342
337
|
);
|
|
343
|
-
if (keepIds.length === 0)
|
|
344
|
-
return;
|
|
338
|
+
if (keepIds.length === 0) return;
|
|
345
339
|
const keepIdList = keepIds.map((r) => r.id);
|
|
346
340
|
const placeholders = keepIdList.map(() => "?").join(",");
|
|
347
341
|
await dbRun(
|
|
@@ -388,6 +382,7 @@ var ConsolidatedStore = class {
|
|
|
388
382
|
constructor(eventStore) {
|
|
389
383
|
this.eventStore = eventStore;
|
|
390
384
|
}
|
|
385
|
+
eventStore;
|
|
391
386
|
get db() {
|
|
392
387
|
return this.eventStore.getDatabase();
|
|
393
388
|
}
|
|
@@ -420,8 +415,7 @@ var ConsolidatedStore = class {
|
|
|
420
415
|
`SELECT * FROM consolidated_memories WHERE memory_id = ?`,
|
|
421
416
|
[memoryId]
|
|
422
417
|
);
|
|
423
|
-
if (rows.length === 0)
|
|
424
|
-
return null;
|
|
418
|
+
if (rows.length === 0) return null;
|
|
425
419
|
return this.rowToMemory(rows[0]);
|
|
426
420
|
}
|
|
427
421
|
/**
|
|
@@ -639,8 +633,7 @@ var ConsolidatedStore = class {
|
|
|
639
633
|
WHERE source_events LIKE ?`,
|
|
640
634
|
[`%"${eventId}"%`]
|
|
641
635
|
);
|
|
642
|
-
if ((result[0]?.count || 0) > 0)
|
|
643
|
-
return true;
|
|
636
|
+
if ((result[0]?.count || 0) > 0) return true;
|
|
644
637
|
}
|
|
645
638
|
return false;
|
|
646
639
|
}
|
|
@@ -654,8 +647,7 @@ var ConsolidatedStore = class {
|
|
|
654
647
|
ORDER BY created_at DESC
|
|
655
648
|
LIMIT 1`
|
|
656
649
|
);
|
|
657
|
-
if (result.length === 0)
|
|
658
|
-
return null;
|
|
650
|
+
if (result.length === 0) return null;
|
|
659
651
|
return new Date(result[0].created_at);
|
|
660
652
|
}
|
|
661
653
|
/**
|
|
@@ -685,6 +677,9 @@ var ConsolidationWorker = class {
|
|
|
685
677
|
this.consolidatedStore = consolidatedStore;
|
|
686
678
|
this.config = config;
|
|
687
679
|
}
|
|
680
|
+
workingSetStore;
|
|
681
|
+
consolidatedStore;
|
|
682
|
+
config;
|
|
688
683
|
running = false;
|
|
689
684
|
timeout = null;
|
|
690
685
|
lastActivity = /* @__PURE__ */ new Date();
|
|
@@ -692,8 +687,7 @@ var ConsolidationWorker = class {
|
|
|
692
687
|
* Start the consolidation worker
|
|
693
688
|
*/
|
|
694
689
|
start() {
|
|
695
|
-
if (this.running)
|
|
696
|
-
return;
|
|
690
|
+
if (this.running) return;
|
|
697
691
|
this.running = true;
|
|
698
692
|
this.scheduleNext();
|
|
699
693
|
}
|
|
@@ -736,8 +730,7 @@ var ConsolidationWorker = class {
|
|
|
736
730
|
* Schedule the next consolidation check
|
|
737
731
|
*/
|
|
738
732
|
scheduleNext() {
|
|
739
|
-
if (!this.running)
|
|
740
|
-
return;
|
|
733
|
+
if (!this.running) return;
|
|
741
734
|
this.timeout = setTimeout(
|
|
742
735
|
() => this.run(),
|
|
743
736
|
this.config.consolidation.triggerIntervalMs
|
|
@@ -747,8 +740,7 @@ var ConsolidationWorker = class {
|
|
|
747
740
|
* Run consolidation check
|
|
748
741
|
*/
|
|
749
742
|
async run() {
|
|
750
|
-
if (!this.running)
|
|
751
|
-
return;
|
|
743
|
+
if (!this.running) return;
|
|
752
744
|
try {
|
|
753
745
|
await this.checkAndConsolidate();
|
|
754
746
|
} catch (error) {
|
|
@@ -786,12 +778,10 @@ var ConsolidationWorker = class {
|
|
|
786
778
|
let consolidatedCount = 0;
|
|
787
779
|
const createdMemoryIds = [];
|
|
788
780
|
for (const group of groups) {
|
|
789
|
-
if (group.events.length < 3)
|
|
790
|
-
continue;
|
|
781
|
+
if (group.events.length < 3) continue;
|
|
791
782
|
const eventIds = group.events.map((e) => e.id);
|
|
792
783
|
const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
|
|
793
|
-
if (alreadyConsolidated)
|
|
794
|
-
continue;
|
|
784
|
+
if (alreadyConsolidated) continue;
|
|
795
785
|
const summary = await this.summarize(group);
|
|
796
786
|
const memoryId = await this.consolidatedStore.create({
|
|
797
787
|
summary,
|
|
@@ -807,8 +797,7 @@ var ConsolidationWorker = class {
|
|
|
807
797
|
const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
|
|
808
798
|
const oldEventIds = consolidatedEventIds.filter((id) => {
|
|
809
799
|
const event = workingSet.recentEvents.find((e) => e.id === id);
|
|
810
|
-
if (!event)
|
|
811
|
-
return false;
|
|
800
|
+
if (!event) return false;
|
|
812
801
|
const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
|
|
813
802
|
return ageHours > this.config.workingSet.timeWindowHours / 2;
|
|
814
803
|
});
|
|
@@ -823,18 +812,13 @@ var ConsolidationWorker = class {
|
|
|
823
812
|
let promoted = 0;
|
|
824
813
|
for (const memoryId of memoryIds) {
|
|
825
814
|
const memory = await this.consolidatedStore.get(memoryId);
|
|
826
|
-
if (!memory)
|
|
827
|
-
|
|
828
|
-
if (memory.
|
|
829
|
-
continue;
|
|
830
|
-
if (memory.sourceEvents.length < 4)
|
|
831
|
-
continue;
|
|
815
|
+
if (!memory) continue;
|
|
816
|
+
if (memory.confidence < 0.55) continue;
|
|
817
|
+
if (memory.sourceEvents.length < 4) continue;
|
|
832
818
|
const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
|
|
833
|
-
if (exists)
|
|
834
|
-
continue;
|
|
819
|
+
if (exists) continue;
|
|
835
820
|
const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
|
|
836
|
-
if (!rule)
|
|
837
|
-
continue;
|
|
821
|
+
if (!rule) continue;
|
|
838
822
|
await this.consolidatedStore.createRule({
|
|
839
823
|
rule,
|
|
840
824
|
topics: memory.topics,
|
|
@@ -850,8 +834,7 @@ var ConsolidationWorker = class {
|
|
|
850
834
|
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
|
|
851
835
|
const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
|
|
852
836
|
const seed = bullet || lines[0];
|
|
853
|
-
if (!seed || seed.length < 8)
|
|
854
|
-
return null;
|
|
837
|
+
if (!seed || seed.length < 8) return null;
|
|
855
838
|
const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
|
|
856
839
|
return `${topicPrefix}${seed}`;
|
|
857
840
|
}
|
|
@@ -1012,8 +995,7 @@ var ConsolidationWorker = class {
|
|
|
1012
995
|
*/
|
|
1013
996
|
extractKeyPoint(content) {
|
|
1014
997
|
const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
|
|
1015
|
-
if (sentences.length === 0)
|
|
1016
|
-
return null;
|
|
998
|
+
if (sentences.length === 0) return null;
|
|
1017
999
|
const firstSentence = sentences[0].trim();
|
|
1018
1000
|
if (firstSentence.length > 100) {
|
|
1019
1001
|
return firstSentence.slice(0, 100) + "...";
|
|
@@ -1033,8 +1015,7 @@ var ConsolidationWorker = class {
|
|
|
1033
1015
|
* Calculate time proximity score
|
|
1034
1016
|
*/
|
|
1035
1017
|
calculateTimeProximity(events) {
|
|
1036
|
-
if (events.length < 2)
|
|
1037
|
-
return 1;
|
|
1018
|
+
if (events.length < 2) return 1;
|
|
1038
1019
|
const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
|
|
1039
1020
|
const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
|
|
1040
1021
|
const avgGap = timeSpan / (events.length - 1);
|
|
@@ -1053,6 +1034,8 @@ var ContinuityManager = class {
|
|
|
1053
1034
|
this.eventStore = eventStore;
|
|
1054
1035
|
this.config = config;
|
|
1055
1036
|
}
|
|
1037
|
+
eventStore;
|
|
1038
|
+
config;
|
|
1056
1039
|
lastContext = null;
|
|
1057
1040
|
get db() {
|
|
1058
1041
|
return this.eventStore.getDatabase();
|
|
@@ -1172,8 +1155,7 @@ var ContinuityManager = class {
|
|
|
1172
1155
|
* Calculate overlap between two arrays
|
|
1173
1156
|
*/
|
|
1174
1157
|
calculateOverlap(a, b) {
|
|
1175
|
-
if (a.length === 0 || b.length === 0)
|
|
1176
|
-
return 0;
|
|
1158
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
1177
1159
|
const setA = new Set(a.map((s) => s.toLowerCase()));
|
|
1178
1160
|
const setB = new Set(b.map((s) => s.toLowerCase()));
|
|
1179
1161
|
const intersection = [...setA].filter((x) => setB.has(x));
|
|
@@ -1346,6 +1328,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1346
1328
|
this.options = options;
|
|
1347
1329
|
this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
|
|
1348
1330
|
}
|
|
1331
|
+
options;
|
|
1349
1332
|
factories;
|
|
1350
1333
|
workingSetStore = null;
|
|
1351
1334
|
consolidatedStore = null;
|
|
@@ -1360,8 +1343,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1360
1343
|
}
|
|
1361
1344
|
}
|
|
1362
1345
|
async initializeEndlessMode() {
|
|
1363
|
-
if (this.consolidationWorker)
|
|
1364
|
-
return;
|
|
1346
|
+
if (this.consolidationWorker) return;
|
|
1365
1347
|
const config = await this.getEndlessConfig();
|
|
1366
1348
|
const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
|
|
1367
1349
|
const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
|
|
@@ -1393,8 +1375,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1393
1375
|
}
|
|
1394
1376
|
async setMode(mode) {
|
|
1395
1377
|
await this.options.initialize();
|
|
1396
|
-
if (mode === this.mode)
|
|
1397
|
-
return;
|
|
1378
|
+
if (mode === this.mode) return;
|
|
1398
1379
|
this.mode = mode;
|
|
1399
1380
|
await this.options.configStore.setEndlessConfig("mode", mode);
|
|
1400
1381
|
if (mode === "endless") {
|
|
@@ -1410,33 +1391,27 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1410
1391
|
return this.mode === "endless";
|
|
1411
1392
|
}
|
|
1412
1393
|
async addToWorkingSet(eventId, relevanceScore) {
|
|
1413
|
-
if (!this.workingSetStore)
|
|
1414
|
-
return;
|
|
1394
|
+
if (!this.workingSetStore) return;
|
|
1415
1395
|
await this.workingSetStore.add(eventId, relevanceScore);
|
|
1416
1396
|
}
|
|
1417
1397
|
async getWorkingSet() {
|
|
1418
|
-
if (!this.workingSetStore)
|
|
1419
|
-
return null;
|
|
1398
|
+
if (!this.workingSetStore) return null;
|
|
1420
1399
|
return this.workingSetStore.get();
|
|
1421
1400
|
}
|
|
1422
1401
|
async searchConsolidated(query, options) {
|
|
1423
|
-
if (!this.consolidatedStore)
|
|
1424
|
-
return [];
|
|
1402
|
+
if (!this.consolidatedStore) return [];
|
|
1425
1403
|
return this.consolidatedStore.search(query, options);
|
|
1426
1404
|
}
|
|
1427
1405
|
async getConsolidatedMemories(limit) {
|
|
1428
|
-
if (!this.consolidatedStore)
|
|
1429
|
-
return [];
|
|
1406
|
+
if (!this.consolidatedStore) return [];
|
|
1430
1407
|
return this.consolidatedStore.getAll({ limit });
|
|
1431
1408
|
}
|
|
1432
1409
|
async markMemoryAccessed(memoryId) {
|
|
1433
|
-
if (!this.consolidatedStore)
|
|
1434
|
-
return;
|
|
1410
|
+
if (!this.consolidatedStore) return;
|
|
1435
1411
|
await this.consolidatedStore.markAccessed(memoryId);
|
|
1436
1412
|
}
|
|
1437
1413
|
async calculateContinuity(content, metadata) {
|
|
1438
|
-
if (!this.continuityManager)
|
|
1439
|
-
return null;
|
|
1414
|
+
if (!this.continuityManager) return null;
|
|
1440
1415
|
const snapshot = this.continuityManager.createSnapshot(
|
|
1441
1416
|
this.factories.randomUUID(),
|
|
1442
1417
|
content,
|
|
@@ -1448,8 +1423,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1448
1423
|
this.consolidationWorker?.recordActivity();
|
|
1449
1424
|
}
|
|
1450
1425
|
async forceConsolidation() {
|
|
1451
|
-
if (!this.consolidationWorker)
|
|
1452
|
-
return 0;
|
|
1426
|
+
if (!this.consolidationWorker) return 0;
|
|
1453
1427
|
return this.consolidationWorker.forceRun();
|
|
1454
1428
|
}
|
|
1455
1429
|
async getEndlessModeStatus() {
|
|
@@ -1541,8 +1515,7 @@ var Embedder = class _Embedder {
|
|
|
1541
1515
|
* Initialize the embedding pipeline
|
|
1542
1516
|
*/
|
|
1543
1517
|
async initialize() {
|
|
1544
|
-
if (this.initialized)
|
|
1545
|
-
return;
|
|
1518
|
+
if (this.initialized) return;
|
|
1546
1519
|
const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
|
|
1547
1520
|
try {
|
|
1548
1521
|
return await loadTransformersPipeline();
|
|
@@ -1659,8 +1632,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
|
|
|
1659
1632
|
originalConsoleWarn = console.warn;
|
|
1660
1633
|
console.warn = (...args) => {
|
|
1661
1634
|
const message = args.map(String).join(" ");
|
|
1662
|
-
if (isKnownBenignTransformersWarning(message))
|
|
1663
|
-
return;
|
|
1635
|
+
if (isKnownBenignTransformersWarning(message)) return;
|
|
1664
1636
|
(originalConsoleWarn ?? console.warn)(...args);
|
|
1665
1637
|
};
|
|
1666
1638
|
}
|
|
@@ -1942,8 +1914,7 @@ var GraduationPipeline = class {
|
|
|
1942
1914
|
const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
|
|
1943
1915
|
const preferences = [];
|
|
1944
1916
|
for (const event of events) {
|
|
1945
|
-
if (event.eventType !== "user_prompt")
|
|
1946
|
-
continue;
|
|
1917
|
+
if (event.eventType !== "user_prompt") continue;
|
|
1947
1918
|
const lowerContent = event.content.toLowerCase();
|
|
1948
1919
|
for (const keyword of preferenceKeywords) {
|
|
1949
1920
|
if (lowerContent.includes(keyword)) {
|
|
@@ -2109,11 +2080,9 @@ function sanitizeSegment(input, fallback) {
|
|
|
2109
2080
|
return v || fallback;
|
|
2110
2081
|
}
|
|
2111
2082
|
function getAtPath(obj, dotted) {
|
|
2112
|
-
if (!obj)
|
|
2113
|
-
return void 0;
|
|
2083
|
+
if (!obj) return void 0;
|
|
2114
2084
|
return dotted.split(".").reduce((acc, key) => {
|
|
2115
|
-
if (!acc || typeof acc !== "object")
|
|
2116
|
-
return void 0;
|
|
2085
|
+
if (!acc || typeof acc !== "object") return void 0;
|
|
2117
2086
|
return acc[key];
|
|
2118
2087
|
}, obj);
|
|
2119
2088
|
}
|
|
@@ -2133,6 +2102,7 @@ var MarkdownMirror = class {
|
|
|
2133
2102
|
constructor(rootDir) {
|
|
2134
2103
|
this.rootDir = rootDir;
|
|
2135
2104
|
}
|
|
2105
|
+
rootDir;
|
|
2136
2106
|
async append(event, eventId) {
|
|
2137
2107
|
const out = buildMirrorPath(this.rootDir, event);
|
|
2138
2108
|
fs2.mkdirSync(path2.dirname(out), { recursive: true });
|
|
@@ -2264,10 +2234,8 @@ function sqliteClose(db) {
|
|
|
2264
2234
|
db.close();
|
|
2265
2235
|
}
|
|
2266
2236
|
function toDateFromSQLite(value) {
|
|
2267
|
-
if (value instanceof Date)
|
|
2268
|
-
|
|
2269
|
-
if (typeof value === "number")
|
|
2270
|
-
return new Date(value);
|
|
2237
|
+
if (value instanceof Date) return value;
|
|
2238
|
+
if (typeof value === "number") return new Date(value);
|
|
2271
2239
|
if (typeof value === "string") {
|
|
2272
2240
|
const trimmed = value.trim();
|
|
2273
2241
|
if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
|
|
@@ -2289,8 +2257,7 @@ var DEFAULT_CATEGORY = "uncategorized";
|
|
|
2289
2257
|
function sanitizeSegment2(input, fallback) {
|
|
2290
2258
|
const raw = String(input ?? "").trim().toLowerCase();
|
|
2291
2259
|
const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2292
|
-
if (!safe || safe === "." || safe === "..")
|
|
2293
|
-
return fallback;
|
|
2260
|
+
if (!safe || safe === "." || safe === "..") return fallback;
|
|
2294
2261
|
return safe;
|
|
2295
2262
|
}
|
|
2296
2263
|
function getCategorySegments(metadata, eventType) {
|
|
@@ -2331,6 +2298,7 @@ var MarkdownMirror2 = class {
|
|
|
2331
2298
|
constructor(rootDir) {
|
|
2332
2299
|
this.rootDir = rootDir;
|
|
2333
2300
|
}
|
|
2301
|
+
rootDir;
|
|
2334
2302
|
async append(event) {
|
|
2335
2303
|
const outPath = buildMirrorPath2(this.rootDir, event);
|
|
2336
2304
|
await fs5.mkdir(path4.dirname(outPath), { recursive: true });
|
|
@@ -2353,6 +2321,7 @@ var VectorOutbox = class {
|
|
|
2353
2321
|
this.db = db;
|
|
2354
2322
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
2355
2323
|
}
|
|
2324
|
+
db;
|
|
2356
2325
|
config;
|
|
2357
2326
|
/**
|
|
2358
2327
|
* Enqueue item for vectorization (idempotent).
|
|
@@ -2449,8 +2418,7 @@ var VectorOutbox = class {
|
|
|
2449
2418
|
`SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
|
|
2450
2419
|
[jobId]
|
|
2451
2420
|
);
|
|
2452
|
-
if (rows.length === 0)
|
|
2453
|
-
return;
|
|
2421
|
+
if (rows.length === 0) return;
|
|
2454
2422
|
const retryCount = rows[0].retry_count;
|
|
2455
2423
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
2456
2424
|
await dbRun(
|
|
@@ -2470,8 +2438,7 @@ var VectorOutbox = class {
|
|
|
2470
2438
|
`SELECT * FROM vector_outbox WHERE job_id = ?`,
|
|
2471
2439
|
[jobId]
|
|
2472
2440
|
);
|
|
2473
|
-
if (rows.length === 0)
|
|
2474
|
-
return null;
|
|
2441
|
+
if (rows.length === 0) return null;
|
|
2475
2442
|
return this.rowToJob(rows[0]);
|
|
2476
2443
|
}
|
|
2477
2444
|
/**
|
|
@@ -2605,30 +2572,24 @@ function isRetrievalDebugLaneName(value) {
|
|
|
2605
2572
|
return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
|
|
2606
2573
|
}
|
|
2607
2574
|
function normalizeRetrievalDebugLanes(value, maxItems = 6) {
|
|
2608
|
-
if (!Array.isArray(value) || maxItems <= 0)
|
|
2609
|
-
return [];
|
|
2575
|
+
if (!Array.isArray(value) || maxItems <= 0) return [];
|
|
2610
2576
|
const normalized = [];
|
|
2611
2577
|
const seen = /* @__PURE__ */ new Set();
|
|
2612
2578
|
for (const item of value) {
|
|
2613
2579
|
const lane = normalizeRetrievalDebugLane(item);
|
|
2614
|
-
if (!lane)
|
|
2615
|
-
continue;
|
|
2580
|
+
if (!lane) continue;
|
|
2616
2581
|
const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
|
|
2617
|
-
if (seen.has(key))
|
|
2618
|
-
continue;
|
|
2582
|
+
if (seen.has(key)) continue;
|
|
2619
2583
|
seen.add(key);
|
|
2620
2584
|
normalized.push(lane);
|
|
2621
|
-
if (normalized.length >= maxItems)
|
|
2622
|
-
break;
|
|
2585
|
+
if (normalized.length >= maxItems) break;
|
|
2623
2586
|
}
|
|
2624
2587
|
return normalized;
|
|
2625
2588
|
}
|
|
2626
2589
|
function normalizeRetrievalDebugLane(value) {
|
|
2627
|
-
if (!value || typeof value !== "object")
|
|
2628
|
-
return null;
|
|
2590
|
+
if (!value || typeof value !== "object") return null;
|
|
2629
2591
|
const raw = value;
|
|
2630
|
-
if (!isRetrievalDebugLaneName(raw.lane))
|
|
2631
|
-
return null;
|
|
2592
|
+
if (!isRetrievalDebugLaneName(raw.lane)) return null;
|
|
2632
2593
|
const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
|
|
2633
2594
|
const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
|
|
2634
2595
|
return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
|
|
@@ -2651,27 +2612,21 @@ function normalizeRetrievalTraceDetails(details) {
|
|
|
2651
2612
|
eventId: detail.eventId,
|
|
2652
2613
|
score: detail.score
|
|
2653
2614
|
};
|
|
2654
|
-
if (detail.semanticScore !== void 0)
|
|
2655
|
-
|
|
2656
|
-
if (detail.
|
|
2657
|
-
|
|
2658
|
-
if (detail.recencyScore !== void 0)
|
|
2659
|
-
normalized.recencyScore = detail.recencyScore;
|
|
2660
|
-
if (lanes.length > 0)
|
|
2661
|
-
normalized.lanes = lanes;
|
|
2615
|
+
if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
|
|
2616
|
+
if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
|
|
2617
|
+
if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
|
|
2618
|
+
if (lanes.length > 0) normalized.lanes = lanes;
|
|
2662
2619
|
return normalized;
|
|
2663
2620
|
});
|
|
2664
2621
|
}
|
|
2665
2622
|
function parseRetrievalTraceDetails(value) {
|
|
2666
|
-
if (typeof value !== "string" || value.length === 0)
|
|
2667
|
-
return [];
|
|
2623
|
+
if (typeof value !== "string" || value.length === 0) return [];
|
|
2668
2624
|
const parsed = JSON.parse(value);
|
|
2669
2625
|
return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
|
|
2670
2626
|
}
|
|
2671
2627
|
function normalizeQueryRewriteKind(value) {
|
|
2672
2628
|
const normalized = (value || "").trim().toLowerCase();
|
|
2673
|
-
if (normalized === "follow-up-context" || normalized === "intent-rewrite")
|
|
2674
|
-
return normalized;
|
|
2629
|
+
if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
|
|
2675
2630
|
return "none";
|
|
2676
2631
|
}
|
|
2677
2632
|
var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
|
|
@@ -2689,8 +2644,7 @@ function isRecord(value) {
|
|
|
2689
2644
|
function getNestedRecord(root, path11) {
|
|
2690
2645
|
let cursor = root;
|
|
2691
2646
|
for (const key of path11) {
|
|
2692
|
-
if (!isRecord(cursor))
|
|
2693
|
-
return void 0;
|
|
2647
|
+
if (!isRecord(cursor)) return void 0;
|
|
2694
2648
|
cursor = cursor[key];
|
|
2695
2649
|
}
|
|
2696
2650
|
return isRecord(cursor) ? cursor : void 0;
|
|
@@ -2698,8 +2652,7 @@ function getNestedRecord(root, path11) {
|
|
|
2698
2652
|
function getNestedString(root, path11) {
|
|
2699
2653
|
let cursor = root;
|
|
2700
2654
|
for (const key of path11) {
|
|
2701
|
-
if (!isRecord(cursor))
|
|
2702
|
-
return void 0;
|
|
2655
|
+
if (!isRecord(cursor)) return void 0;
|
|
2703
2656
|
cursor = cursor[key];
|
|
2704
2657
|
}
|
|
2705
2658
|
return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
|
|
@@ -2715,8 +2668,7 @@ function metadataProjectPaths(metadata) {
|
|
|
2715
2668
|
];
|
|
2716
2669
|
const paths = [];
|
|
2717
2670
|
for (const value of candidates) {
|
|
2718
|
-
if (value && !paths.includes(value))
|
|
2719
|
-
paths.push(value);
|
|
2671
|
+
if (value && !paths.includes(value)) paths.push(value);
|
|
2720
2672
|
}
|
|
2721
2673
|
return paths;
|
|
2722
2674
|
}
|
|
@@ -2737,12 +2689,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
|
|
|
2737
2689
|
return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
|
|
2738
2690
|
}
|
|
2739
2691
|
function safeParseMetadataValue(value) {
|
|
2740
|
-
if (!value)
|
|
2741
|
-
|
|
2742
|
-
if (typeof value
|
|
2743
|
-
return isRecord(value) ? value : void 0;
|
|
2744
|
-
if (typeof value !== "string")
|
|
2745
|
-
return void 0;
|
|
2692
|
+
if (!value) return void 0;
|
|
2693
|
+
if (typeof value === "object") return isRecord(value) ? value : void 0;
|
|
2694
|
+
if (typeof value !== "string") return void 0;
|
|
2746
2695
|
try {
|
|
2747
2696
|
const parsed = JSON.parse(value);
|
|
2748
2697
|
return isRecord(parsed) ? parsed : void 0;
|
|
@@ -2751,16 +2700,14 @@ function safeParseMetadataValue(value) {
|
|
|
2751
2700
|
}
|
|
2752
2701
|
}
|
|
2753
2702
|
function isImportedOrLegacyScopedMetadata(metadata) {
|
|
2754
|
-
if (!metadata)
|
|
2755
|
-
return false;
|
|
2703
|
+
if (!metadata) return false;
|
|
2756
2704
|
return Boolean(
|
|
2757
2705
|
metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
|
|
2758
2706
|
);
|
|
2759
2707
|
}
|
|
2760
2708
|
function addMetadataTag(metadata, tag) {
|
|
2761
2709
|
const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
|
|
2762
|
-
if (!current.includes(tag))
|
|
2763
|
-
metadata.tags = [...current, tag];
|
|
2710
|
+
if (!current.includes(tag)) metadata.tags = [...current, tag];
|
|
2764
2711
|
}
|
|
2765
2712
|
function buildRepairResult(projectHash, dryRun) {
|
|
2766
2713
|
return {
|
|
@@ -2778,8 +2725,7 @@ function normalizeRepoName(value) {
|
|
|
2778
2725
|
return value.replace(/\.git$/i, "").trim().toLowerCase();
|
|
2779
2726
|
}
|
|
2780
2727
|
function projectBasename(projectPath) {
|
|
2781
|
-
if (!projectPath)
|
|
2782
|
-
return void 0;
|
|
2728
|
+
if (!projectPath) return void 0;
|
|
2783
2729
|
const trimmed = projectPath.replace(/[\\/]+$/, "");
|
|
2784
2730
|
const basename2 = nodePath2.basename(trimmed);
|
|
2785
2731
|
return basename2 ? normalizeRepoName(basename2) : void 0;
|
|
@@ -2792,23 +2738,19 @@ function isProjectScopeRepairExplanation(content) {
|
|
|
2792
2738
|
}
|
|
2793
2739
|
function hasConflictingContentProjectHint(content, projectPath) {
|
|
2794
2740
|
const currentName = projectBasename(projectPath);
|
|
2795
|
-
if (!currentName)
|
|
2796
|
-
|
|
2797
|
-
if (isProjectScopeRepairExplanation(content))
|
|
2798
|
-
return false;
|
|
2741
|
+
if (!currentName) return false;
|
|
2742
|
+
if (isProjectScopeRepairExplanation(content)) return false;
|
|
2799
2743
|
const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
|
|
2800
2744
|
let githubMatch;
|
|
2801
2745
|
while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
|
|
2802
2746
|
const repo = normalizeRepoName(githubMatch[2] || "");
|
|
2803
|
-
if (repo && repo !== currentName)
|
|
2804
|
-
return true;
|
|
2747
|
+
if (repo && repo !== currentName) return true;
|
|
2805
2748
|
}
|
|
2806
2749
|
const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
|
|
2807
2750
|
let workspaceMatch;
|
|
2808
2751
|
while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
|
|
2809
2752
|
const repo = normalizeRepoName(workspaceMatch[1] || "");
|
|
2810
|
-
if (repo && repo !== currentName)
|
|
2811
|
-
return true;
|
|
2753
|
+
if (repo && repo !== currentName) return true;
|
|
2812
2754
|
}
|
|
2813
2755
|
return false;
|
|
2814
2756
|
}
|
|
@@ -2828,15 +2770,12 @@ var SQLiteEventStore = class {
|
|
|
2828
2770
|
this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
|
|
2829
2771
|
}
|
|
2830
2772
|
createVectorOutbox(option) {
|
|
2831
|
-
if (this.readOnly || option === false)
|
|
2832
|
-
|
|
2833
|
-
if (option instanceof VectorOutbox)
|
|
2834
|
-
return option;
|
|
2773
|
+
if (this.readOnly || option === false) return null;
|
|
2774
|
+
if (option instanceof VectorOutbox) return option;
|
|
2835
2775
|
return new VectorOutbox(this.db, option ?? {});
|
|
2836
2776
|
}
|
|
2837
2777
|
enqueueVectorOutboxEventSync(eventId) {
|
|
2838
|
-
if (!this.vectorOutbox)
|
|
2839
|
-
return;
|
|
2778
|
+
if (!this.vectorOutbox) return;
|
|
2840
2779
|
this.vectorOutbox.enqueueSync("event", eventId);
|
|
2841
2780
|
}
|
|
2842
2781
|
async enqueueVectorOutboxEvent(eventId) {
|
|
@@ -2846,8 +2785,7 @@ var SQLiteEventStore = class {
|
|
|
2846
2785
|
* Initialize database schema
|
|
2847
2786
|
*/
|
|
2848
2787
|
async initialize() {
|
|
2849
|
-
if (this.initialized)
|
|
2850
|
-
return;
|
|
2788
|
+
if (this.initialized) return;
|
|
2851
2789
|
if (this.readOnly) {
|
|
2852
2790
|
this.initialized = true;
|
|
2853
2791
|
return;
|
|
@@ -3405,10 +3343,8 @@ var SQLiteEventStore = class {
|
|
|
3405
3343
|
try {
|
|
3406
3344
|
const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
|
|
3407
3345
|
const hasSourceAwareUnique = edgeIndexes.some((index) => {
|
|
3408
|
-
if (Number(index.unique) !== 1)
|
|
3409
|
-
|
|
3410
|
-
if (!/^[A-Za-z0-9_]+$/.test(index.name))
|
|
3411
|
-
return false;
|
|
3346
|
+
if (Number(index.unique) !== 1) return false;
|
|
3347
|
+
if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
|
|
3412
3348
|
const escapedName = index.name.replace(/"/g, '""');
|
|
3413
3349
|
const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
|
|
3414
3350
|
return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
|
|
@@ -3648,8 +3584,7 @@ var SQLiteEventStore = class {
|
|
|
3648
3584
|
`SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
|
|
3649
3585
|
[id]
|
|
3650
3586
|
);
|
|
3651
|
-
if (!row)
|
|
3652
|
-
return null;
|
|
3587
|
+
if (!row) return null;
|
|
3653
3588
|
return this.rowToEvent(row);
|
|
3654
3589
|
}
|
|
3655
3590
|
/**
|
|
@@ -3687,10 +3622,8 @@ var SQLiteEventStore = class {
|
|
|
3687
3622
|
* NOTE: This bypasses the append() id generation to preserve stable IDs.
|
|
3688
3623
|
*/
|
|
3689
3624
|
async importEvents(events) {
|
|
3690
|
-
if (events.length === 0)
|
|
3691
|
-
|
|
3692
|
-
if (this.readOnly)
|
|
3693
|
-
return { inserted: 0, skipped: events.length };
|
|
3625
|
+
if (events.length === 0) return { inserted: 0, skipped: 0 };
|
|
3626
|
+
if (this.readOnly) return { inserted: 0, skipped: events.length };
|
|
3694
3627
|
await this.initialize();
|
|
3695
3628
|
const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
|
|
3696
3629
|
const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
|
|
@@ -3808,8 +3741,7 @@ var SQLiteEventStore = class {
|
|
|
3808
3741
|
`SELECT * FROM sessions WHERE id = ?`,
|
|
3809
3742
|
[id]
|
|
3810
3743
|
);
|
|
3811
|
-
if (!row)
|
|
3812
|
-
return null;
|
|
3744
|
+
if (!row) return null;
|
|
3813
3745
|
return {
|
|
3814
3746
|
id: row.id,
|
|
3815
3747
|
startedAt: toDateFromSQLite(row.started_at),
|
|
@@ -3864,8 +3796,7 @@ var SQLiteEventStore = class {
|
|
|
3864
3796
|
LIMIT ?`,
|
|
3865
3797
|
[limit]
|
|
3866
3798
|
);
|
|
3867
|
-
if (pending.length === 0)
|
|
3868
|
-
return [];
|
|
3799
|
+
if (pending.length === 0) return [];
|
|
3869
3800
|
const ids = pending.map((r) => r.id);
|
|
3870
3801
|
const placeholders = ids.map(() => "?").join(",");
|
|
3871
3802
|
sqliteRun(
|
|
@@ -3889,8 +3820,7 @@ var SQLiteEventStore = class {
|
|
|
3889
3820
|
* Mark outbox items as done
|
|
3890
3821
|
*/
|
|
3891
3822
|
async completeOutboxItems(ids) {
|
|
3892
|
-
if (ids.length === 0)
|
|
3893
|
-
return;
|
|
3823
|
+
if (ids.length === 0) return;
|
|
3894
3824
|
const placeholders = ids.map(() => "?").join(",");
|
|
3895
3825
|
sqliteRun(
|
|
3896
3826
|
this.db,
|
|
@@ -3929,8 +3859,7 @@ var SQLiteEventStore = class {
|
|
|
3929
3859
|
* Mark outbox items as failed
|
|
3930
3860
|
*/
|
|
3931
3861
|
async failOutboxItems(ids, error) {
|
|
3932
|
-
if (ids.length === 0)
|
|
3933
|
-
return;
|
|
3862
|
+
if (ids.length === 0) return;
|
|
3934
3863
|
const placeholders = ids.map(() => "?").join(",");
|
|
3935
3864
|
sqliteRun(
|
|
3936
3865
|
this.db,
|
|
@@ -4057,8 +3986,7 @@ var SQLiteEventStore = class {
|
|
|
4057
3986
|
[]
|
|
4058
3987
|
);
|
|
4059
3988
|
const sample = (entry) => {
|
|
4060
|
-
if (result.samples.length < 20)
|
|
4061
|
-
result.samples.push(entry);
|
|
3989
|
+
if (result.samples.length < 20) result.samples.push(entry);
|
|
4062
3990
|
};
|
|
4063
3991
|
for (const row of rows) {
|
|
4064
3992
|
result.scanned++;
|
|
@@ -4185,12 +4113,10 @@ var SQLiteEventStore = class {
|
|
|
4185
4113
|
`SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
|
|
4186
4114
|
);
|
|
4187
4115
|
const processingAgeMs = (value) => {
|
|
4188
|
-
if (value === null || value === void 0)
|
|
4189
|
-
return null;
|
|
4116
|
+
if (value === null || value === void 0) return null;
|
|
4190
4117
|
const date = toDateFromSQLite(value);
|
|
4191
4118
|
const time = date.getTime();
|
|
4192
|
-
if (!Number.isFinite(time))
|
|
4193
|
-
return null;
|
|
4119
|
+
if (!Number.isFinite(time)) return null;
|
|
4194
4120
|
return Math.max(0, now.getTime() - time);
|
|
4195
4121
|
};
|
|
4196
4122
|
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
|
|
@@ -4339,8 +4265,7 @@ var SQLiteEventStore = class {
|
|
|
4339
4265
|
`SELECT value FROM endless_config WHERE key = ?`,
|
|
4340
4266
|
[key]
|
|
4341
4267
|
);
|
|
4342
|
-
if (!row)
|
|
4343
|
-
return null;
|
|
4268
|
+
if (!row) return null;
|
|
4344
4269
|
return JSON.parse(row.value);
|
|
4345
4270
|
}
|
|
4346
4271
|
/**
|
|
@@ -4359,8 +4284,7 @@ var SQLiteEventStore = class {
|
|
|
4359
4284
|
* Increment access count for events
|
|
4360
4285
|
*/
|
|
4361
4286
|
async incrementAccessCount(eventIds) {
|
|
4362
|
-
if (eventIds.length === 0 || this.readOnly)
|
|
4363
|
-
return;
|
|
4287
|
+
if (eventIds.length === 0 || this.readOnly) return;
|
|
4364
4288
|
await this.initialize();
|
|
4365
4289
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4366
4290
|
const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -4403,8 +4327,7 @@ var SQLiteEventStore = class {
|
|
|
4403
4327
|
* Record a memory retrieval for helpfulness tracking
|
|
4404
4328
|
*/
|
|
4405
4329
|
async recordRetrieval(eventId, sessionId, score, query) {
|
|
4406
|
-
if (this.readOnly)
|
|
4407
|
-
return;
|
|
4330
|
+
if (this.readOnly) return;
|
|
4408
4331
|
await this.initialize();
|
|
4409
4332
|
const id = randomUUID6();
|
|
4410
4333
|
sqliteRun(
|
|
@@ -4434,16 +4357,14 @@ var SQLiteEventStore = class {
|
|
|
4434
4357
|
* Called at session end - uses behavioral signals to compute score
|
|
4435
4358
|
*/
|
|
4436
4359
|
async evaluateSessionHelpfulness(sessionId) {
|
|
4437
|
-
if (this.readOnly)
|
|
4438
|
-
return;
|
|
4360
|
+
if (this.readOnly) return;
|
|
4439
4361
|
await this.initialize();
|
|
4440
4362
|
const retrievals = sqliteAll(
|
|
4441
4363
|
this.db,
|
|
4442
4364
|
`SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
|
|
4443
4365
|
[sessionId]
|
|
4444
4366
|
);
|
|
4445
|
-
if (retrievals.length === 0)
|
|
4446
|
-
return;
|
|
4367
|
+
if (retrievals.length === 0) return;
|
|
4447
4368
|
const sessionEvents = sqliteAll(
|
|
4448
4369
|
this.db,
|
|
4449
4370
|
`SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
|
|
@@ -4456,8 +4377,7 @@ var SQLiteEventStore = class {
|
|
|
4456
4377
|
for (const t of toolEvents) {
|
|
4457
4378
|
try {
|
|
4458
4379
|
const content = JSON.parse(t.content);
|
|
4459
|
-
if (content.success !== false)
|
|
4460
|
-
toolSuccessCount++;
|
|
4380
|
+
if (content.success !== false) toolSuccessCount++;
|
|
4461
4381
|
} catch {
|
|
4462
4382
|
toolSuccessCount++;
|
|
4463
4383
|
}
|
|
@@ -4475,8 +4395,7 @@ var SQLiteEventStore = class {
|
|
|
4475
4395
|
const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
4476
4396
|
let overlap = 0;
|
|
4477
4397
|
for (const w of queryWords) {
|
|
4478
|
-
if (pWords.has(w))
|
|
4479
|
-
overlap++;
|
|
4398
|
+
if (pWords.has(w)) overlap++;
|
|
4480
4399
|
}
|
|
4481
4400
|
if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
|
|
4482
4401
|
wasReasked = 1;
|
|
@@ -4658,8 +4577,7 @@ var SQLiteEventStore = class {
|
|
|
4658
4577
|
return this.db;
|
|
4659
4578
|
}
|
|
4660
4579
|
hasTableColumn(tableName, columnName2) {
|
|
4661
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
|
|
4662
|
-
return false;
|
|
4580
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
|
|
4663
4581
|
try {
|
|
4664
4582
|
const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
|
|
4665
4583
|
return rows.some((row) => row.name === columnName2);
|
|
@@ -4726,8 +4644,7 @@ var SQLiteEventStore = class {
|
|
|
4726
4644
|
createdAt: toDateFromSQLite(row.created_at)
|
|
4727
4645
|
}));
|
|
4728
4646
|
} catch (err) {
|
|
4729
|
-
if (err?.message?.includes("no such table"))
|
|
4730
|
-
return [];
|
|
4647
|
+
if (err?.message?.includes("no such table")) return [];
|
|
4731
4648
|
throw err;
|
|
4732
4649
|
}
|
|
4733
4650
|
}
|
|
@@ -4900,8 +4817,7 @@ var SQLiteEventStore = class {
|
|
|
4900
4817
|
`SELECT id FROM events WHERE session_id = ?`,
|
|
4901
4818
|
[sessionId]
|
|
4902
4819
|
);
|
|
4903
|
-
if (events.length === 0)
|
|
4904
|
-
return 0;
|
|
4820
|
+
if (events.length === 0) return 0;
|
|
4905
4821
|
const eventIds = events.map((e) => e.id);
|
|
4906
4822
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4907
4823
|
const ftsTriggersDropped = [];
|
|
@@ -5113,8 +5029,7 @@ function sanitizeGovernanceAuditValue(value, key) {
|
|
|
5113
5029
|
return value;
|
|
5114
5030
|
}
|
|
5115
5031
|
function sanitizeAuditJson(value) {
|
|
5116
|
-
if (value === void 0)
|
|
5117
|
-
return void 0;
|
|
5032
|
+
if (value === void 0) return void 0;
|
|
5118
5033
|
return sanitizeGovernanceAuditValue(value);
|
|
5119
5034
|
}
|
|
5120
5035
|
function normalizeSourceEventIds(sourceEventIds) {
|
|
@@ -5163,12 +5078,10 @@ async function writeGovernanceAuditEntry(db, input) {
|
|
|
5163
5078
|
|
|
5164
5079
|
// src/core/operations/facet-repository.ts
|
|
5165
5080
|
function parseStringArray(value) {
|
|
5166
|
-
if (typeof value !== "string")
|
|
5167
|
-
return [];
|
|
5081
|
+
if (typeof value !== "string") return [];
|
|
5168
5082
|
try {
|
|
5169
5083
|
const parsed = JSON.parse(value);
|
|
5170
|
-
if (!Array.isArray(parsed))
|
|
5171
|
-
return [];
|
|
5084
|
+
if (!Array.isArray(parsed)) return [];
|
|
5172
5085
|
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
5173
5086
|
} catch {
|
|
5174
5087
|
return [];
|
|
@@ -5212,6 +5125,7 @@ var FacetRepository = class {
|
|
|
5212
5125
|
constructor(db) {
|
|
5213
5126
|
this.db = db;
|
|
5214
5127
|
}
|
|
5128
|
+
db;
|
|
5215
5129
|
async assign(input) {
|
|
5216
5130
|
const assignment = parseFacetAssignmentInput(input);
|
|
5217
5131
|
const existing = this.findByUniqueKey(assignment);
|
|
@@ -5516,19 +5430,14 @@ var RetentionFacetSchema = z5.object({
|
|
|
5516
5430
|
confidence: z5.number().min(0).max(1).default(1)
|
|
5517
5431
|
});
|
|
5518
5432
|
var DateLikeSchema = z5.preprocess((value) => {
|
|
5519
|
-
if (value instanceof Date)
|
|
5520
|
-
|
|
5521
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5522
|
-
return new Date(value);
|
|
5433
|
+
if (value instanceof Date) return value;
|
|
5434
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5523
5435
|
return value;
|
|
5524
5436
|
}, z5.date());
|
|
5525
5437
|
var NullableDateLikeSchema = z5.preprocess((value) => {
|
|
5526
|
-
if (value === null || value === void 0 || value === "")
|
|
5527
|
-
|
|
5528
|
-
if (value
|
|
5529
|
-
return value;
|
|
5530
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5531
|
-
return new Date(value);
|
|
5438
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
5439
|
+
if (value instanceof Date) return value;
|
|
5440
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5532
5441
|
return value;
|
|
5533
5442
|
}, z5.date().nullable());
|
|
5534
5443
|
var OptionalTrimmedStringSchema2 = z5.preprocess(
|
|
@@ -5557,10 +5466,8 @@ import { z as z6 } from "zod";
|
|
|
5557
5466
|
var RequiredTrimmedStringSchema = z6.string().trim().min(1);
|
|
5558
5467
|
var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
|
|
5559
5468
|
var DateLikeSchema2 = z6.preprocess((value) => {
|
|
5560
|
-
if (value instanceof Date)
|
|
5561
|
-
|
|
5562
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5563
|
-
return new Date(value);
|
|
5469
|
+
if (value instanceof Date) return value;
|
|
5470
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5564
5471
|
return value;
|
|
5565
5472
|
}, z6.date());
|
|
5566
5473
|
var RetentionReasonSchema = z6.object({
|
|
@@ -5749,8 +5656,7 @@ var MemoryOperationsConfigSchema = z7.object({
|
|
|
5749
5656
|
}).default({});
|
|
5750
5657
|
var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5751
5658
|
var MemoryLessonStringArraySchema = z7.preprocess((value) => {
|
|
5752
|
-
if (!Array.isArray(value))
|
|
5753
|
-
return value;
|
|
5659
|
+
if (!Array.isArray(value)) return value;
|
|
5754
5660
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5755
5661
|
}, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
|
|
5756
5662
|
var MemoryLessonSchema = z7.object({
|
|
@@ -5795,14 +5701,12 @@ var ListMemoryLessonsInputSchema = z7.object({
|
|
|
5795
5701
|
});
|
|
5796
5702
|
var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5797
5703
|
var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
|
|
5798
|
-
if (typeof value !== "string")
|
|
5799
|
-
return value;
|
|
5704
|
+
if (typeof value !== "string") return value;
|
|
5800
5705
|
const normalized = value.trim();
|
|
5801
5706
|
return normalized.length > 0 ? normalized : void 0;
|
|
5802
5707
|
}, PerspectiveMemoryNonEmptyStringSchema.optional());
|
|
5803
5708
|
var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
|
|
5804
|
-
if (!Array.isArray(value))
|
|
5805
|
-
return value;
|
|
5709
|
+
if (!Array.isArray(value)) return value;
|
|
5806
5710
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5807
5711
|
}, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
|
|
5808
5712
|
var ActorCardSensitivePattern = /(?:\b(?:api[_-]?key|secret|password|passwd|token|access[_-]?token|client[_-]?secret|bearer)\b\s*[:=])|(?:\b(?:api[_-]?key|secret|password|passwd|token|access[_-]?token|client[_-]?secret|bearer)=)|(?:^|\s)(?:\/[A-Za-z0-9._-][^\s`'\"]*)/i;
|
|
@@ -6460,6 +6364,7 @@ var GraphPathService = class {
|
|
|
6460
6364
|
constructor(db) {
|
|
6461
6365
|
this.db = db;
|
|
6462
6366
|
}
|
|
6367
|
+
db;
|
|
6463
6368
|
expand(input) {
|
|
6464
6369
|
const graph = this.loadGraph(input.direction ?? "both");
|
|
6465
6370
|
const effectiveMaxHops = normalizeMaxHops(input.maxHops);
|
|
@@ -6477,11 +6382,9 @@ var GraphPathService = class {
|
|
|
6477
6382
|
while (queue.length > 0) {
|
|
6478
6383
|
queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
|
|
6479
6384
|
const current = queue.shift();
|
|
6480
|
-
if (current.hops >= effectiveMaxHops)
|
|
6481
|
-
continue;
|
|
6385
|
+
if (current.hops >= effectiveMaxHops) continue;
|
|
6482
6386
|
for (const edge of graph.adjacency.get(current.key) ?? []) {
|
|
6483
|
-
if (current.visited.has(edge.toKey))
|
|
6484
|
-
continue;
|
|
6387
|
+
if (current.visited.has(edge.toKey)) continue;
|
|
6485
6388
|
const nextHops = current.hops + 1;
|
|
6486
6389
|
const nextTotalCost = current.totalCost + edge.step.cost;
|
|
6487
6390
|
const nextSteps = [...current.steps, edge.step];
|
|
@@ -6561,17 +6464,13 @@ function addTraversal(adjacency, fromKey, edge) {
|
|
|
6561
6464
|
adjacency.set(fromKey, edges);
|
|
6562
6465
|
}
|
|
6563
6466
|
function normalizeMaxHops(maxHops) {
|
|
6564
|
-
if (maxHops === void 0)
|
|
6565
|
-
|
|
6566
|
-
if (!Number.isFinite(maxHops))
|
|
6567
|
-
return MAX_HOPS;
|
|
6467
|
+
if (maxHops === void 0) return 1;
|
|
6468
|
+
if (!Number.isFinite(maxHops)) return MAX_HOPS;
|
|
6568
6469
|
return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
|
|
6569
6470
|
}
|
|
6570
6471
|
function normalizeMaxResults(maxResults) {
|
|
6571
|
-
if (maxResults === void 0)
|
|
6572
|
-
|
|
6573
|
-
if (!Number.isFinite(maxResults))
|
|
6574
|
-
return DEFAULT_MAX_RESULTS;
|
|
6472
|
+
if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
|
|
6473
|
+
if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
|
|
6575
6474
|
return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
|
|
6576
6475
|
}
|
|
6577
6476
|
function isBetterPath(totalCost, hops, signature, existing) {
|
|
@@ -6583,18 +6482,15 @@ function pathSignature(steps) {
|
|
|
6583
6482
|
function edgeWeight(metaJson) {
|
|
6584
6483
|
const meta = parseMeta(metaJson);
|
|
6585
6484
|
const raw = meta.weight;
|
|
6586
|
-
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
|
|
6587
|
-
return raw;
|
|
6485
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
|
|
6588
6486
|
if (typeof raw === "string") {
|
|
6589
6487
|
const parsed = Number(raw);
|
|
6590
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
6591
|
-
return parsed;
|
|
6488
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
6592
6489
|
}
|
|
6593
6490
|
return DEFAULT_WEIGHT;
|
|
6594
6491
|
}
|
|
6595
6492
|
function parseMeta(metaJson) {
|
|
6596
|
-
if (!metaJson)
|
|
6597
|
-
return {};
|
|
6493
|
+
if (!metaJson) return {};
|
|
6598
6494
|
try {
|
|
6599
6495
|
const parsed = JSON.parse(metaJson);
|
|
6600
6496
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
@@ -6607,8 +6503,7 @@ function nodeKey(node) {
|
|
|
6607
6503
|
}
|
|
6608
6504
|
function nodeFromKey(key) {
|
|
6609
6505
|
const index = key.indexOf(":");
|
|
6610
|
-
if (index === -1)
|
|
6611
|
-
return { type: "entity", id: key };
|
|
6506
|
+
if (index === -1) return { type: "entity", id: key };
|
|
6612
6507
|
return { type: key.slice(0, index), id: key.slice(index + 1) };
|
|
6613
6508
|
}
|
|
6614
6509
|
|
|
@@ -6664,6 +6559,7 @@ var QueryEntityExtractor = class {
|
|
|
6664
6559
|
constructor(db) {
|
|
6665
6560
|
this.db = db;
|
|
6666
6561
|
}
|
|
6562
|
+
db;
|
|
6667
6563
|
extract(query, options = {}) {
|
|
6668
6564
|
const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
|
|
6669
6565
|
const candidates = [];
|
|
@@ -6685,8 +6581,7 @@ var QueryEntityExtractor = class {
|
|
|
6685
6581
|
let match;
|
|
6686
6582
|
while ((match = regex.exec(query)) !== null) {
|
|
6687
6583
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6688
|
-
if (!isUsefulCandidate(text))
|
|
6689
|
-
continue;
|
|
6584
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6690
6585
|
const start = match.index + 1;
|
|
6691
6586
|
const end = start + text.length;
|
|
6692
6587
|
ranges.push([match.index, match.index + match[0].length]);
|
|
@@ -6700,8 +6595,7 @@ var QueryEntityExtractor = class {
|
|
|
6700
6595
|
return ranges;
|
|
6701
6596
|
}
|
|
6702
6597
|
extractKnownAliases(query, candidates) {
|
|
6703
|
-
if (!this.db)
|
|
6704
|
-
return;
|
|
6598
|
+
if (!this.db) return;
|
|
6705
6599
|
const rows = sqliteAll(
|
|
6706
6600
|
this.db,
|
|
6707
6601
|
`SELECT
|
|
@@ -6725,11 +6619,9 @@ var QueryEntityExtractor = class {
|
|
|
6725
6619
|
]).filter(isUsefulCandidate);
|
|
6726
6620
|
for (const alias of aliasLabels) {
|
|
6727
6621
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6728
|
-
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
|
|
6729
|
-
continue;
|
|
6622
|
+
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
|
|
6730
6623
|
const aliasKey = `${row.entity_id}:${normalizedAlias}`;
|
|
6731
|
-
if (seenAliases.has(aliasKey))
|
|
6732
|
-
continue;
|
|
6624
|
+
if (seenAliases.has(aliasKey)) continue;
|
|
6733
6625
|
seenAliases.add(aliasKey);
|
|
6734
6626
|
const range = findRange(query, alias);
|
|
6735
6627
|
pushCandidate(candidates, {
|
|
@@ -6750,8 +6642,7 @@ var QueryEntityExtractor = class {
|
|
|
6750
6642
|
let match;
|
|
6751
6643
|
while ((match = regex.exec(query)) !== null) {
|
|
6752
6644
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6753
|
-
if (!isUsefulCandidate(text))
|
|
6754
|
-
continue;
|
|
6645
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6755
6646
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6756
6647
|
pushCandidate(candidates, {
|
|
6757
6648
|
text,
|
|
@@ -6766,8 +6657,7 @@ var QueryEntityExtractor = class {
|
|
|
6766
6657
|
let match;
|
|
6767
6658
|
while ((match = regex.exec(query)) !== null) {
|
|
6768
6659
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6769
|
-
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
|
|
6770
|
-
continue;
|
|
6660
|
+
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
|
|
6771
6661
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6772
6662
|
pushCandidate(candidates, {
|
|
6773
6663
|
text,
|
|
@@ -6786,21 +6676,17 @@ var QueryEntityExtractor = class {
|
|
|
6786
6676
|
if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
|
|
6787
6677
|
current.push(token);
|
|
6788
6678
|
} else {
|
|
6789
|
-
if (current.length > 0)
|
|
6790
|
-
groups.push(current);
|
|
6679
|
+
if (current.length > 0) groups.push(current);
|
|
6791
6680
|
current = [token];
|
|
6792
6681
|
}
|
|
6793
6682
|
}
|
|
6794
|
-
if (current.length > 0)
|
|
6795
|
-
groups.push(current);
|
|
6683
|
+
if (current.length > 0) groups.push(current);
|
|
6796
6684
|
for (const group of groups) {
|
|
6797
|
-
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
|
|
6798
|
-
continue;
|
|
6685
|
+
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
|
|
6799
6686
|
const start = group[0].start;
|
|
6800
6687
|
const end = group[group.length - 1].end;
|
|
6801
6688
|
const text = query.slice(start, end);
|
|
6802
|
-
if (!isUsefulCandidate(text))
|
|
6803
|
-
continue;
|
|
6689
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6804
6690
|
pushCandidate(candidates, {
|
|
6805
6691
|
text,
|
|
6806
6692
|
source: "capitalized_term",
|
|
@@ -6821,8 +6707,7 @@ function collectCapitalizedTokens(query) {
|
|
|
6821
6707
|
}
|
|
6822
6708
|
function pushCandidate(candidates, input) {
|
|
6823
6709
|
const text = cleanCandidateText(input.text);
|
|
6824
|
-
if (!isUsefulCandidate(text))
|
|
6825
|
-
return;
|
|
6710
|
+
if (!isUsefulCandidate(text)) return;
|
|
6826
6711
|
const source = input.source;
|
|
6827
6712
|
candidates.push({
|
|
6828
6713
|
...input,
|
|
@@ -6840,15 +6725,13 @@ function dedupeAndSort(candidates) {
|
|
|
6840
6725
|
for (const candidate of sorted) {
|
|
6841
6726
|
if (candidate.source === "entity_alias") {
|
|
6842
6727
|
const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
|
|
6843
|
-
if (seenAliasKeys.has(aliasKey))
|
|
6844
|
-
continue;
|
|
6728
|
+
if (seenAliasKeys.has(aliasKey)) continue;
|
|
6845
6729
|
seenAliasKeys.add(aliasKey);
|
|
6846
6730
|
seenNormalized.add(candidate.normalized);
|
|
6847
6731
|
result.push(candidate);
|
|
6848
6732
|
continue;
|
|
6849
6733
|
}
|
|
6850
|
-
if (seenNormalized.has(candidate.normalized))
|
|
6851
|
-
continue;
|
|
6734
|
+
if (seenNormalized.has(candidate.normalized)) continue;
|
|
6852
6735
|
seenNormalized.add(candidate.normalized);
|
|
6853
6736
|
result.push(candidate);
|
|
6854
6737
|
}
|
|
@@ -6858,8 +6741,7 @@ function compareCandidates(a, b) {
|
|
|
6858
6741
|
return a.priority - b.priority || a.start - b.start || a.end - b.end || compareStrings(a.text, b.text) || compareStrings(a.entityId ?? "", b.entityId ?? "") || compareStrings(a.matchedAlias ?? "", b.matchedAlias ?? "");
|
|
6859
6742
|
}
|
|
6860
6743
|
function compareStrings(a, b) {
|
|
6861
|
-
if (a === b)
|
|
6862
|
-
return 0;
|
|
6744
|
+
if (a === b) return 0;
|
|
6863
6745
|
return a < b ? -1 : 1;
|
|
6864
6746
|
}
|
|
6865
6747
|
function stripPriority(candidate) {
|
|
@@ -6867,10 +6749,8 @@ function stripPriority(candidate) {
|
|
|
6867
6749
|
return publicCandidate;
|
|
6868
6750
|
}
|
|
6869
6751
|
function normalizeMaxCandidates(maxCandidates) {
|
|
6870
|
-
if (maxCandidates === void 0)
|
|
6871
|
-
|
|
6872
|
-
if (!Number.isFinite(maxCandidates))
|
|
6873
|
-
return DEFAULT_MAX_CANDIDATES;
|
|
6752
|
+
if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
|
|
6753
|
+
if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
|
|
6874
6754
|
return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
|
|
6875
6755
|
}
|
|
6876
6756
|
function cleanCandidateText(text) {
|
|
@@ -6892,21 +6772,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
|
|
|
6892
6772
|
function findRange(query, alias) {
|
|
6893
6773
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6894
6774
|
const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
|
|
6895
|
-
if (directIndex >= 0)
|
|
6896
|
-
return { start: directIndex, end: directIndex + alias.length };
|
|
6775
|
+
if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
|
|
6897
6776
|
const normalizedQuery = normalizeForContainment(query);
|
|
6898
6777
|
const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
|
|
6899
|
-
if (normalizedIndex < 0)
|
|
6900
|
-
return { start: 0, end: 0 };
|
|
6778
|
+
if (normalizedIndex < 0) return { start: 0, end: 0 };
|
|
6901
6779
|
const queryLower = query.toLowerCase();
|
|
6902
6780
|
const words = normalizedAlias.split(" ").filter(Boolean);
|
|
6903
|
-
if (words.length === 0)
|
|
6904
|
-
return { start: 0, end: 0 };
|
|
6781
|
+
if (words.length === 0) return { start: 0, end: 0 };
|
|
6905
6782
|
const first = queryLower.indexOf(words[0]);
|
|
6906
6783
|
const lastWord = words[words.length - 1];
|
|
6907
6784
|
const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
|
|
6908
|
-
if (first >= 0 && last >= 0)
|
|
6909
|
-
return { start: first, end: last + lastWord.length };
|
|
6785
|
+
if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
|
|
6910
6786
|
return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
|
|
6911
6787
|
}
|
|
6912
6788
|
function isUsefulCandidate(text) {
|
|
@@ -6917,10 +6793,8 @@ function isInsideAnyRange(index, ranges) {
|
|
|
6917
6793
|
return ranges.some(([start, end]) => index >= start && index < end);
|
|
6918
6794
|
}
|
|
6919
6795
|
function isStrongSingleCapitalized(text) {
|
|
6920
|
-
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
|
|
6921
|
-
|
|
6922
|
-
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
|
|
6923
|
-
return true;
|
|
6796
|
+
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
|
|
6797
|
+
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
|
|
6924
6798
|
return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
|
|
6925
6799
|
}
|
|
6926
6800
|
function uniqueStrings(values) {
|
|
@@ -6928,8 +6802,7 @@ function uniqueStrings(values) {
|
|
|
6928
6802
|
const result = [];
|
|
6929
6803
|
for (const value of values) {
|
|
6930
6804
|
const key = normalizeForContainment(value);
|
|
6931
|
-
if (!key || seen.has(key))
|
|
6932
|
-
continue;
|
|
6805
|
+
if (!key || seen.has(key)) continue;
|
|
6933
6806
|
seen.add(key);
|
|
6934
6807
|
result.push(value);
|
|
6935
6808
|
}
|
|
@@ -6951,8 +6824,7 @@ var LessonCandidateInputSchema = z9.object({
|
|
|
6951
6824
|
import { z as z10 } from "zod";
|
|
6952
6825
|
var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
|
|
6953
6826
|
var PromotionStringArraySchema = z10.preprocess((value) => {
|
|
6954
|
-
if (!Array.isArray(value))
|
|
6955
|
-
return value;
|
|
6827
|
+
if (!Array.isArray(value)) return value;
|
|
6956
6828
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
6957
6829
|
}, z10.array(NonEmptyStringSchema5).max(100));
|
|
6958
6830
|
var ReviewedLessonCandidateSchema = z10.object({
|
|
@@ -7000,8 +6872,7 @@ function projectHashFromStorage(projectHash) {
|
|
|
7000
6872
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7001
6873
|
}
|
|
7002
6874
|
function parseJsonRecord(value) {
|
|
7003
|
-
if (!value)
|
|
7004
|
-
return void 0;
|
|
6875
|
+
if (!value) return void 0;
|
|
7005
6876
|
try {
|
|
7006
6877
|
const parsed = JSON.parse(value);
|
|
7007
6878
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7013,8 +6884,7 @@ function sanitizeString(value) {
|
|
|
7013
6884
|
return String(sanitizeGovernanceAuditValue(value)).trim();
|
|
7014
6885
|
}
|
|
7015
6886
|
function sanitizeMetadata(metadata) {
|
|
7016
|
-
if (!metadata)
|
|
7017
|
-
return void 0;
|
|
6887
|
+
if (!metadata) return void 0;
|
|
7018
6888
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7019
6889
|
}
|
|
7020
6890
|
function slugActorPart(value) {
|
|
@@ -7022,8 +6892,7 @@ function slugActorPart(value) {
|
|
|
7022
6892
|
return slug.length > 0 ? slug : "unknown";
|
|
7023
6893
|
}
|
|
7024
6894
|
function stableActorId(input) {
|
|
7025
|
-
if (input.actorId)
|
|
7026
|
-
return sanitizeString(input.actorId);
|
|
6895
|
+
if (input.actorId) return sanitizeString(input.actorId);
|
|
7027
6896
|
const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
|
|
7028
6897
|
return [
|
|
7029
6898
|
"actor",
|
|
@@ -7046,12 +6915,10 @@ function rowToActor(row) {
|
|
|
7046
6915
|
});
|
|
7047
6916
|
}
|
|
7048
6917
|
function metadataString(metadata, keys) {
|
|
7049
|
-
if (!metadata)
|
|
7050
|
-
return void 0;
|
|
6918
|
+
if (!metadata) return void 0;
|
|
7051
6919
|
for (const key of keys) {
|
|
7052
6920
|
const value = metadata[key];
|
|
7053
|
-
if (typeof value === "string" && value.trim().length > 0)
|
|
7054
|
-
return value.trim();
|
|
6921
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
7055
6922
|
}
|
|
7056
6923
|
return void 0;
|
|
7057
6924
|
}
|
|
@@ -7101,6 +6968,7 @@ var ActorRepository = class {
|
|
|
7101
6968
|
constructor(db) {
|
|
7102
6969
|
this.db = db;
|
|
7103
6970
|
}
|
|
6971
|
+
db;
|
|
7104
6972
|
async upsert(input) {
|
|
7105
6973
|
const parsed = UpsertMemoryActorInputSchema.parse(input);
|
|
7106
6974
|
const actorId = stableActorId(parsed);
|
|
@@ -7154,8 +7022,7 @@ var ActorRepository = class {
|
|
|
7154
7022
|
}
|
|
7155
7023
|
require(actorId) {
|
|
7156
7024
|
const actor = this.get(actorId);
|
|
7157
|
-
if (!actor)
|
|
7158
|
-
throw new Error(`Memory actor not found: ${actorId}`);
|
|
7025
|
+
if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
|
|
7159
7026
|
return actor;
|
|
7160
7027
|
}
|
|
7161
7028
|
async list(input = {}) {
|
|
@@ -7191,8 +7058,7 @@ function projectHashFromStorage2(projectHash) {
|
|
|
7191
7058
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7192
7059
|
}
|
|
7193
7060
|
function parseJsonRecord2(value) {
|
|
7194
|
-
if (!value)
|
|
7195
|
-
return void 0;
|
|
7061
|
+
if (!value) return void 0;
|
|
7196
7062
|
try {
|
|
7197
7063
|
const parsed = JSON.parse(value);
|
|
7198
7064
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7201,8 +7067,7 @@ function parseJsonRecord2(value) {
|
|
|
7201
7067
|
}
|
|
7202
7068
|
}
|
|
7203
7069
|
function sanitizeMetadata2(metadata) {
|
|
7204
|
-
if (!metadata)
|
|
7205
|
-
return void 0;
|
|
7070
|
+
if (!metadata) return void 0;
|
|
7206
7071
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7207
7072
|
}
|
|
7208
7073
|
function rowToSessionActor(row) {
|
|
@@ -7222,6 +7087,7 @@ var SessionActorRepository = class {
|
|
|
7222
7087
|
constructor(db) {
|
|
7223
7088
|
this.db = db;
|
|
7224
7089
|
}
|
|
7090
|
+
db;
|
|
7225
7091
|
async upsertMembership(input) {
|
|
7226
7092
|
const parsed = UpsertSessionActorInputSchema.parse(input);
|
|
7227
7093
|
const projectHash = projectHashToStorage3(parsed.projectHash);
|
|
@@ -7268,8 +7134,7 @@ var SessionActorRepository = class {
|
|
|
7268
7134
|
);
|
|
7269
7135
|
}
|
|
7270
7136
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7271
|
-
if (!saved)
|
|
7272
|
-
throw new Error("session actor membership was not saved");
|
|
7137
|
+
if (!saved) throw new Error("session actor membership was not saved");
|
|
7273
7138
|
return saved;
|
|
7274
7139
|
}
|
|
7275
7140
|
async listBySession(input) {
|
|
@@ -7305,8 +7170,7 @@ var SessionActorRepository = class {
|
|
|
7305
7170
|
]
|
|
7306
7171
|
);
|
|
7307
7172
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7308
|
-
if (!saved)
|
|
7309
|
-
throw new Error("session actor membership not found after update");
|
|
7173
|
+
if (!saved) throw new Error("session actor membership not found after update");
|
|
7310
7174
|
return saved;
|
|
7311
7175
|
}
|
|
7312
7176
|
get(projectHash, sessionId, actorId) {
|
|
@@ -7328,8 +7192,7 @@ function projectHashFromStorage3(projectHash) {
|
|
|
7328
7192
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7329
7193
|
}
|
|
7330
7194
|
function parseStringArray2(value) {
|
|
7331
|
-
if (!value)
|
|
7332
|
-
return [];
|
|
7195
|
+
if (!value) return [];
|
|
7333
7196
|
try {
|
|
7334
7197
|
const parsed = JSON.parse(value);
|
|
7335
7198
|
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
@@ -7338,8 +7201,7 @@ function parseStringArray2(value) {
|
|
|
7338
7201
|
}
|
|
7339
7202
|
}
|
|
7340
7203
|
function parseJsonRecord3(value) {
|
|
7341
|
-
if (!value)
|
|
7342
|
-
return void 0;
|
|
7204
|
+
if (!value) return void 0;
|
|
7343
7205
|
try {
|
|
7344
7206
|
const parsed = JSON.parse(value);
|
|
7345
7207
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7355,8 +7217,7 @@ function sanitizeStoredStringArray(values) {
|
|
|
7355
7217
|
return values.map(sanitizeStoredString).filter((value) => value.length > 0);
|
|
7356
7218
|
}
|
|
7357
7219
|
function sanitizeStoredRecord(value) {
|
|
7358
|
-
if (!value)
|
|
7359
|
-
return void 0;
|
|
7220
|
+
if (!value) return void 0;
|
|
7360
7221
|
return sanitizeGovernanceAuditValue(value);
|
|
7361
7222
|
}
|
|
7362
7223
|
function stableHash(value) {
|
|
@@ -7407,8 +7268,7 @@ function sanitizedObservationSnapshot(observation) {
|
|
|
7407
7268
|
});
|
|
7408
7269
|
}
|
|
7409
7270
|
function queryScore(observation, terms) {
|
|
7410
|
-
if (terms.length === 0)
|
|
7411
|
-
return 0;
|
|
7271
|
+
if (terms.length === 0) return 0;
|
|
7412
7272
|
const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
|
|
7413
7273
|
return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
|
|
7414
7274
|
}
|
|
@@ -7454,12 +7314,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7454
7314
|
this.vectorOutbox = options.vectorOutbox;
|
|
7455
7315
|
}
|
|
7456
7316
|
}
|
|
7317
|
+
db;
|
|
7457
7318
|
vectorOutbox = null;
|
|
7458
7319
|
vectorOutboxOption;
|
|
7459
7320
|
getVectorOutbox() {
|
|
7460
7321
|
const option = this.vectorOutboxOption;
|
|
7461
|
-
if (option === false)
|
|
7462
|
-
return null;
|
|
7322
|
+
if (option === false) return null;
|
|
7463
7323
|
if (option instanceof VectorOutbox) {
|
|
7464
7324
|
this.vectorOutbox = option;
|
|
7465
7325
|
return option;
|
|
@@ -7471,8 +7331,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7471
7331
|
}
|
|
7472
7332
|
enqueueObservationSync(observationId) {
|
|
7473
7333
|
const outbox = this.getVectorOutbox();
|
|
7474
|
-
if (!outbox)
|
|
7475
|
-
return;
|
|
7334
|
+
if (!outbox) return;
|
|
7476
7335
|
outbox.enqueueSync("perspective_observation", observationId);
|
|
7477
7336
|
}
|
|
7478
7337
|
async create(input) {
|
|
@@ -7534,14 +7393,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7534
7393
|
contentHash,
|
|
7535
7394
|
sourceHash
|
|
7536
7395
|
);
|
|
7537
|
-
if (!saved)
|
|
7538
|
-
throw new Error("perspective observation was not saved");
|
|
7396
|
+
if (!saved) throw new Error("perspective observation was not saved");
|
|
7539
7397
|
this.enqueueObservationSync(saved.observationId);
|
|
7540
7398
|
});
|
|
7541
7399
|
transaction();
|
|
7542
7400
|
const savedObservation = saved;
|
|
7543
|
-
if (!savedObservation)
|
|
7544
|
-
throw new Error("perspective observation was not saved");
|
|
7401
|
+
if (!savedObservation) throw new Error("perspective observation was not saved");
|
|
7545
7402
|
await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
|
|
7546
7403
|
return savedObservation;
|
|
7547
7404
|
}
|
|
@@ -7551,8 +7408,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7551
7408
|
const ftsQuery = buildObservationFtsQuery(parsed.query);
|
|
7552
7409
|
if (ftsQuery) {
|
|
7553
7410
|
const ftsResult = this.queryWithFts(parsed, ftsQuery);
|
|
7554
|
-
if (ftsResult)
|
|
7555
|
-
return ftsResult;
|
|
7411
|
+
if (ftsResult) return ftsResult;
|
|
7556
7412
|
}
|
|
7557
7413
|
}
|
|
7558
7414
|
return this.queryWithPrefetch(parsed);
|
|
@@ -7573,8 +7429,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7573
7429
|
);
|
|
7574
7430
|
return rows.map(rowToObservation);
|
|
7575
7431
|
} catch (error) {
|
|
7576
|
-
if (isFtsUnavailableError(error))
|
|
7577
|
-
return null;
|
|
7432
|
+
if (isFtsUnavailableError(error)) return null;
|
|
7578
7433
|
throw error;
|
|
7579
7434
|
}
|
|
7580
7435
|
}
|
|
@@ -7615,8 +7470,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7615
7470
|
const parsed = DeletePerspectiveObservationInputSchema.parse(input);
|
|
7616
7471
|
const projectHash = projectHashToStorage4(parsed.projectHash);
|
|
7617
7472
|
const before = this.get(projectHash, parsed.observationId);
|
|
7618
|
-
if (!before)
|
|
7619
|
-
throw new Error("perspective observation not found");
|
|
7473
|
+
if (!before) throw new Error("perspective observation not found");
|
|
7620
7474
|
const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7621
7475
|
sqliteRun(
|
|
7622
7476
|
this.db,
|
|
@@ -7626,8 +7480,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7626
7480
|
[deletedAt, deletedAt, projectHash, parsed.observationId]
|
|
7627
7481
|
);
|
|
7628
7482
|
const after = this.get(projectHash, parsed.observationId);
|
|
7629
|
-
if (!after)
|
|
7630
|
-
throw new Error("perspective observation not found after delete");
|
|
7483
|
+
if (!after) throw new Error("perspective observation not found after delete");
|
|
7631
7484
|
await writeGovernanceAuditEntry(this.db, {
|
|
7632
7485
|
operation: "perspective_observation_delete",
|
|
7633
7486
|
actor: parsed.actor,
|
|
@@ -7683,11 +7536,9 @@ var DEFAULT_CONFIG3 = {
|
|
|
7683
7536
|
var MAX_OBSERVATION_CONTENT_CHARS = 600;
|
|
7684
7537
|
var RuleBasedPerspectiveObservationExtractor = class {
|
|
7685
7538
|
async extract(event) {
|
|
7686
|
-
if (!isSupportedSourceEvent(event))
|
|
7687
|
-
return [];
|
|
7539
|
+
if (!isSupportedSourceEvent(event)) return [];
|
|
7688
7540
|
const content = normalizeObservationContent(event.content);
|
|
7689
|
-
if (!content)
|
|
7690
|
-
return [];
|
|
7541
|
+
if (!content) return [];
|
|
7691
7542
|
return [{
|
|
7692
7543
|
content,
|
|
7693
7544
|
confidence: 0.6,
|
|
@@ -7758,8 +7609,7 @@ var PerspectiveDeriver = class {
|
|
|
7758
7609
|
for (const candidate of candidates) {
|
|
7759
7610
|
const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
|
|
7760
7611
|
const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
|
|
7761
|
-
if (observers.length === 0)
|
|
7762
|
-
continue;
|
|
7612
|
+
if (observers.length === 0) continue;
|
|
7763
7613
|
for (const observerActorId of observers) {
|
|
7764
7614
|
await this.observations.create({
|
|
7765
7615
|
projectHash,
|
|
@@ -7812,28 +7662,22 @@ function normalizeConfig(config) {
|
|
|
7812
7662
|
};
|
|
7813
7663
|
}
|
|
7814
7664
|
function clampInteger(value, fallback, min, max) {
|
|
7815
|
-
if (!Number.isFinite(value))
|
|
7816
|
-
return fallback;
|
|
7665
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7817
7666
|
return Math.max(min, Math.min(max, Math.trunc(Number(value))));
|
|
7818
7667
|
}
|
|
7819
7668
|
function isSupportedSourceEvent(event) {
|
|
7820
7669
|
return event.eventType === "user_prompt" || event.eventType === "agent_response";
|
|
7821
7670
|
}
|
|
7822
7671
|
function roleForEvent(event) {
|
|
7823
|
-
if (event.eventType === "user_prompt")
|
|
7824
|
-
|
|
7825
|
-
if (event.eventType === "
|
|
7826
|
-
|
|
7827
|
-
if (event.eventType === "tool_observation")
|
|
7828
|
-
return "tool";
|
|
7829
|
-
if (event.eventType === "session_summary")
|
|
7830
|
-
return "system";
|
|
7672
|
+
if (event.eventType === "user_prompt") return "speaker";
|
|
7673
|
+
if (event.eventType === "agent_response") return "assistant";
|
|
7674
|
+
if (event.eventType === "tool_observation") return "tool";
|
|
7675
|
+
if (event.eventType === "session_summary") return "system";
|
|
7831
7676
|
return "unknown";
|
|
7832
7677
|
}
|
|
7833
7678
|
function normalizeCandidate2(candidate) {
|
|
7834
7679
|
const content = normalizeObservationContent(candidate.content);
|
|
7835
|
-
if (!content)
|
|
7836
|
-
return null;
|
|
7680
|
+
if (!content) return null;
|
|
7837
7681
|
return {
|
|
7838
7682
|
content,
|
|
7839
7683
|
confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
|
|
@@ -7845,8 +7689,7 @@ function normalizeCandidate2(candidate) {
|
|
|
7845
7689
|
}
|
|
7846
7690
|
function normalizeObservationContent(content) {
|
|
7847
7691
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
7848
|
-
if (!normalized)
|
|
7849
|
-
return null;
|
|
7692
|
+
if (!normalized) return null;
|
|
7850
7693
|
return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
|
|
7851
7694
|
}
|
|
7852
7695
|
function normalizeOptionalString2(value) {
|
|
@@ -7854,13 +7697,11 @@ function normalizeOptionalString2(value) {
|
|
|
7854
7697
|
return normalized.length > 0 ? normalized : void 0;
|
|
7855
7698
|
}
|
|
7856
7699
|
function clampNumber(value, fallback, min, max) {
|
|
7857
|
-
if (!Number.isFinite(value))
|
|
7858
|
-
return fallback;
|
|
7700
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7859
7701
|
return Math.max(min, Math.min(max, Number(value)));
|
|
7860
7702
|
}
|
|
7861
7703
|
function sanitizeCandidateMetadata(metadata) {
|
|
7862
|
-
if (!metadata)
|
|
7863
|
-
return void 0;
|
|
7704
|
+
if (!metadata) return void 0;
|
|
7864
7705
|
const result = {};
|
|
7865
7706
|
for (const [key, value] of Object.entries(metadata)) {
|
|
7866
7707
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -7873,12 +7714,9 @@ function selectObservers(members, observedActorId, maxObservers) {
|
|
|
7873
7714
|
const selected = [];
|
|
7874
7715
|
for (const member of members) {
|
|
7875
7716
|
const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
|
|
7876
|
-
if (!canObserve)
|
|
7877
|
-
|
|
7878
|
-
if (
|
|
7879
|
-
selected.push(member.actorId);
|
|
7880
|
-
if (selected.length >= maxObservers)
|
|
7881
|
-
break;
|
|
7717
|
+
if (!canObserve) continue;
|
|
7718
|
+
if (!selected.includes(member.actorId)) selected.push(member.actorId);
|
|
7719
|
+
if (selected.length >= maxObservers) break;
|
|
7882
7720
|
}
|
|
7883
7721
|
return selected;
|
|
7884
7722
|
}
|
|
@@ -7897,6 +7735,7 @@ var VectorStore = class {
|
|
|
7897
7735
|
constructor(dbPath) {
|
|
7898
7736
|
this.dbPath = dbPath;
|
|
7899
7737
|
}
|
|
7738
|
+
dbPath;
|
|
7900
7739
|
db = null;
|
|
7901
7740
|
tableCache = /* @__PURE__ */ new Map();
|
|
7902
7741
|
defaultTableName = "conversations";
|
|
@@ -7908,8 +7747,7 @@ var VectorStore = class {
|
|
|
7908
7747
|
* conversations table.
|
|
7909
7748
|
*/
|
|
7910
7749
|
async initialize() {
|
|
7911
|
-
if (this.db)
|
|
7912
|
-
return;
|
|
7750
|
+
if (this.db) return;
|
|
7913
7751
|
this.db = await lancedb.connect(this.dbPath);
|
|
7914
7752
|
}
|
|
7915
7753
|
/**
|
|
@@ -7923,8 +7761,7 @@ var VectorStore = class {
|
|
|
7923
7761
|
* Add or update multiple vector records in batch, grouped by inferred table.
|
|
7924
7762
|
*/
|
|
7925
7763
|
async upsertBatch(records) {
|
|
7926
|
-
if (records.length === 0)
|
|
7927
|
-
return;
|
|
7764
|
+
if (records.length === 0) return;
|
|
7928
7765
|
await this.initialize();
|
|
7929
7766
|
if (!this.db) {
|
|
7930
7767
|
throw new Error("Database not initialized");
|
|
@@ -7979,8 +7816,7 @@ var VectorStore = class {
|
|
|
7979
7816
|
async delete(eventId) {
|
|
7980
7817
|
await this.initialize();
|
|
7981
7818
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7982
|
-
if (!table)
|
|
7983
|
-
return;
|
|
7819
|
+
if (!table) return;
|
|
7984
7820
|
await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
|
|
7985
7821
|
}
|
|
7986
7822
|
/**
|
|
@@ -7989,8 +7825,7 @@ var VectorStore = class {
|
|
|
7989
7825
|
async count() {
|
|
7990
7826
|
await this.initialize();
|
|
7991
7827
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7992
|
-
if (!table)
|
|
7993
|
-
return 0;
|
|
7828
|
+
if (!table) return 0;
|
|
7994
7829
|
const result = await table.countRows();
|
|
7995
7830
|
return result;
|
|
7996
7831
|
}
|
|
@@ -7999,8 +7834,7 @@ var VectorStore = class {
|
|
|
7999
7834
|
*/
|
|
8000
7835
|
async clearAll() {
|
|
8001
7836
|
await this.initialize();
|
|
8002
|
-
if (!this.db)
|
|
8003
|
-
return;
|
|
7837
|
+
if (!this.db) return;
|
|
8004
7838
|
try {
|
|
8005
7839
|
if (typeof this.db.dropTable === "function") {
|
|
8006
7840
|
await this.db.dropTable(this.defaultTableName);
|
|
@@ -8017,8 +7851,7 @@ var VectorStore = class {
|
|
|
8017
7851
|
async exists(eventId) {
|
|
8018
7852
|
await this.initialize();
|
|
8019
7853
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8020
|
-
if (!table)
|
|
8021
|
-
return false;
|
|
7854
|
+
if (!table) return false;
|
|
8022
7855
|
const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
|
|
8023
7856
|
return results.length > 0;
|
|
8024
7857
|
}
|
|
@@ -8053,8 +7886,7 @@ var VectorStore = class {
|
|
|
8053
7886
|
throw new Error("Database not initialized");
|
|
8054
7887
|
}
|
|
8055
7888
|
const cached = this.tableCache.get(tableName);
|
|
8056
|
-
if (cached)
|
|
8057
|
-
return cached;
|
|
7889
|
+
if (cached) return cached;
|
|
8058
7890
|
const tableNames = await this.db.tableNames();
|
|
8059
7891
|
if (!tableNames.includes(tableName)) {
|
|
8060
7892
|
return null;
|
|
@@ -8133,12 +7965,9 @@ var IngestInterceptorRegistry = class {
|
|
|
8133
7965
|
}
|
|
8134
7966
|
};
|
|
8135
7967
|
function mergeHierarchicalMetadata(base, patch) {
|
|
8136
|
-
if (!base && !patch)
|
|
8137
|
-
|
|
8138
|
-
if (!base
|
|
8139
|
-
return patch;
|
|
8140
|
-
if (!patch)
|
|
8141
|
-
return base;
|
|
7968
|
+
if (!base && !patch) return void 0;
|
|
7969
|
+
if (!base) return patch;
|
|
7970
|
+
if (!patch) return base;
|
|
8142
7971
|
const result = { ...base };
|
|
8143
7972
|
for (const [key, value] of Object.entries(patch)) {
|
|
8144
7973
|
const current = result[key];
|
|
@@ -8168,33 +7997,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
|
|
|
8168
7997
|
function parseTag(tag) {
|
|
8169
7998
|
const value = (tag || "").trim();
|
|
8170
7999
|
const idx = value.indexOf(":");
|
|
8171
|
-
if (idx <= 0)
|
|
8172
|
-
return { value };
|
|
8000
|
+
if (idx <= 0) return { value };
|
|
8173
8001
|
const namespace = `${value.slice(0, idx)}:`;
|
|
8174
8002
|
const tagValue = value.slice(idx + 1);
|
|
8175
|
-
if (!tagValue)
|
|
8176
|
-
return { value };
|
|
8003
|
+
if (!tagValue) return { value };
|
|
8177
8004
|
return { namespace, value: tagValue };
|
|
8178
8005
|
}
|
|
8179
8006
|
function validateTag(tag) {
|
|
8180
8007
|
const normalized = (tag || "").trim();
|
|
8181
|
-
if (!normalized)
|
|
8182
|
-
return false;
|
|
8008
|
+
if (!normalized) return false;
|
|
8183
8009
|
const { namespace } = parseTag(normalized);
|
|
8184
|
-
if (!namespace)
|
|
8185
|
-
return true;
|
|
8010
|
+
if (!namespace) return true;
|
|
8186
8011
|
return VALID_TAG_NAMESPACES.has(namespace);
|
|
8187
8012
|
}
|
|
8188
8013
|
function normalizeTags(tags) {
|
|
8189
|
-
if (!Array.isArray(tags))
|
|
8190
|
-
return [];
|
|
8014
|
+
if (!Array.isArray(tags)) return [];
|
|
8191
8015
|
const dedup = /* @__PURE__ */ new Set();
|
|
8192
8016
|
for (const item of tags) {
|
|
8193
|
-
if (typeof item !== "string")
|
|
8194
|
-
continue;
|
|
8017
|
+
if (typeof item !== "string") continue;
|
|
8195
8018
|
const normalized = item.trim();
|
|
8196
|
-
if (!validateTag(normalized))
|
|
8197
|
-
continue;
|
|
8019
|
+
if (!validateTag(normalized)) continue;
|
|
8198
8020
|
dedup.add(normalized);
|
|
8199
8021
|
}
|
|
8200
8022
|
return [...dedup];
|
|
@@ -8211,10 +8033,8 @@ var SummaryDeriver = class {
|
|
|
8211
8033
|
* orchestration, while this class owns summary text and metadata decisions.
|
|
8212
8034
|
*/
|
|
8213
8035
|
deriveSessionSummary(events) {
|
|
8214
|
-
if (events.length < 3)
|
|
8215
|
-
|
|
8216
|
-
if (events.some((event) => event.eventType === "session_summary"))
|
|
8217
|
-
return null;
|
|
8036
|
+
if (events.length < 3) return null;
|
|
8037
|
+
if (events.some((event) => event.eventType === "session_summary")) return null;
|
|
8218
8038
|
const prompts = events.filter((event) => event.eventType === "user_prompt");
|
|
8219
8039
|
const toolObservations = events.filter((event) => event.eventType === "tool_observation");
|
|
8220
8040
|
const toolNames = Array.from(new Set(
|
|
@@ -8362,8 +8182,7 @@ var MemoryIngestService = class {
|
|
|
8362
8182
|
await this.initialize();
|
|
8363
8183
|
const events = await this.eventStore.getSessionEvents(sessionId);
|
|
8364
8184
|
const summary = this.summaryDeriver.deriveSessionSummary(events);
|
|
8365
|
-
if (!summary)
|
|
8366
|
-
return;
|
|
8185
|
+
if (!summary) return;
|
|
8367
8186
|
await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
|
|
8368
8187
|
}
|
|
8369
8188
|
async storeToolObservation(sessionId, payload) {
|
|
@@ -8431,10 +8250,8 @@ var MemoryIngestService = class {
|
|
|
8431
8250
|
}
|
|
8432
8251
|
}
|
|
8433
8252
|
async runPerspectiveDeriver(input, eventId, operation) {
|
|
8434
|
-
if (!this.perspectiveDeriver)
|
|
8435
|
-
|
|
8436
|
-
if (operation !== "user_prompt" && operation !== "agent_response")
|
|
8437
|
-
return;
|
|
8253
|
+
if (!this.perspectiveDeriver) return;
|
|
8254
|
+
if (operation !== "user_prompt" && operation !== "agent_response") return;
|
|
8438
8255
|
const event = {
|
|
8439
8256
|
id: eventId,
|
|
8440
8257
|
eventType: input.eventType,
|
|
@@ -8504,11 +8321,13 @@ var MemoryQueryService = class {
|
|
|
8504
8321
|
this.queryStore = queryStore;
|
|
8505
8322
|
this.deps = deps;
|
|
8506
8323
|
}
|
|
8324
|
+
initialize;
|
|
8325
|
+
queryStore;
|
|
8326
|
+
deps;
|
|
8507
8327
|
async keywordSearch(query, options) {
|
|
8508
8328
|
await this.initialize();
|
|
8509
8329
|
const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
|
|
8510
|
-
if (results.length === 0)
|
|
8511
|
-
return [];
|
|
8330
|
+
if (results.length === 0) return [];
|
|
8512
8331
|
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
8513
8332
|
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
8514
8333
|
const rankRange = maxRank - minRank || 1;
|
|
@@ -8754,55 +8573,42 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
|
|
|
8754
8573
|
]);
|
|
8755
8574
|
function isCommandArtifactQuery(query) {
|
|
8756
8575
|
const trimmed = query.trim();
|
|
8757
|
-
if (!trimmed)
|
|
8758
|
-
return false;
|
|
8576
|
+
if (!trimmed) return false;
|
|
8759
8577
|
const normalized = trimmed.toLowerCase();
|
|
8760
|
-
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
|
|
8761
|
-
|
|
8762
|
-
if (normalized.includes("command-name") || normalized.includes("command-message"))
|
|
8763
|
-
return true;
|
|
8578
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8579
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
8764
8580
|
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8765
8581
|
}
|
|
8766
8582
|
function isGenericContinuationQuery(query) {
|
|
8767
8583
|
const trimmed = query.trim();
|
|
8768
|
-
if (!trimmed)
|
|
8769
|
-
|
|
8770
|
-
if (
|
|
8771
|
-
return false;
|
|
8772
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8773
|
-
return false;
|
|
8584
|
+
if (!trimmed) return false;
|
|
8585
|
+
if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
8586
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8774
8587
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8775
|
-
if (tokens.length > 10)
|
|
8776
|
-
return false;
|
|
8588
|
+
if (tokens.length > 10) return false;
|
|
8777
8589
|
return !/[A-Za-z0-9_-]+\.[A-Za-z0-9]+/.test(trimmed) && !/(?:^|\s)(?:feat|fix|chore|refactor|docs)\/[A-Za-z0-9._-]+/.test(trimmed) && !/[A-Za-z]:?[\\/]|\/Users\/|\.\/|\.\.\//.test(trimmed);
|
|
8778
8590
|
}
|
|
8779
8591
|
function isShortRepairFollowUpQuery(query) {
|
|
8780
8592
|
const trimmed = query.trim();
|
|
8781
|
-
if (!trimmed)
|
|
8782
|
-
|
|
8783
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8784
|
-
return false;
|
|
8593
|
+
if (!trimmed) return false;
|
|
8594
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8785
8595
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8786
|
-
if (tokens.length > 8)
|
|
8787
|
-
return false;
|
|
8596
|
+
if (tokens.length > 8) return false;
|
|
8788
8597
|
return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8789
8598
|
}
|
|
8790
8599
|
function isCurrentStateQuery(query) {
|
|
8791
8600
|
const trimmed = query.trim();
|
|
8792
|
-
if (!trimmed)
|
|
8793
|
-
return false;
|
|
8601
|
+
if (!trimmed) return false;
|
|
8794
8602
|
return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8795
8603
|
}
|
|
8796
8604
|
function isStaleOrSupersededContent(content) {
|
|
8797
8605
|
const trimmed = content.trim();
|
|
8798
|
-
if (!trimmed)
|
|
8799
|
-
return false;
|
|
8606
|
+
if (!trimmed) return false;
|
|
8800
8607
|
return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8801
8608
|
}
|
|
8802
8609
|
function buildRetrievalQualityQuery(query) {
|
|
8803
8610
|
const trimmed = query.trim();
|
|
8804
|
-
if (!trimmed)
|
|
8805
|
-
return query;
|
|
8611
|
+
if (!trimmed) return query;
|
|
8806
8612
|
if (isRetrievalPrivacyDecisionQuery(trimmed)) {
|
|
8807
8613
|
return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
|
|
8808
8614
|
}
|
|
@@ -8816,12 +8622,10 @@ function buildRetrievalQualityQuery(query) {
|
|
|
8816
8622
|
}
|
|
8817
8623
|
function isRetrievalPrivacyDecisionQuery(query) {
|
|
8818
8624
|
const trimmed = query.trim();
|
|
8819
|
-
if (!trimmed)
|
|
8820
|
-
return false;
|
|
8625
|
+
if (!trimmed) return false;
|
|
8821
8626
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8822
8627
|
const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8823
|
-
if (!hasDecisionSignal)
|
|
8824
|
-
return false;
|
|
8628
|
+
if (!hasDecisionSignal) return false;
|
|
8825
8629
|
const hasRawQuerySignal = terms.has("raw") && terms.has("query");
|
|
8826
8630
|
const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
|
|
8827
8631
|
const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
|
|
@@ -8834,16 +8638,14 @@ function extractTechnicalQueryTerms(query) {
|
|
|
8834
8638
|
const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
|
|
8835
8639
|
const terms = matches.filter((term) => {
|
|
8836
8640
|
const lower = term.toLowerCase();
|
|
8837
|
-
if (GENERIC_TECHNICAL_TERMS.has(lower))
|
|
8838
|
-
return false;
|
|
8641
|
+
if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
|
|
8839
8642
|
return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
|
|
8840
8643
|
});
|
|
8841
8644
|
return Array.from(new Set(terms.map((term) => term.toLowerCase())));
|
|
8842
8645
|
}
|
|
8843
8646
|
function hasTechnicalTermOverlap(query, content) {
|
|
8844
8647
|
const terms = extractTechnicalQueryTerms(query);
|
|
8845
|
-
if (terms.length === 0)
|
|
8846
|
-
return true;
|
|
8648
|
+
if (terms.length === 0) return true;
|
|
8847
8649
|
const normalizedContent = content.toLowerCase();
|
|
8848
8650
|
return terms.some((term) => normalizedContent.includes(term));
|
|
8849
8651
|
}
|
|
@@ -8859,15 +8661,12 @@ function hasDiscriminativeTermOverlap(query, content) {
|
|
|
8859
8661
|
return topicTerms.some((term) => contentTerms.has(term));
|
|
8860
8662
|
}
|
|
8861
8663
|
}
|
|
8862
|
-
if (queryTerms.length < 3)
|
|
8863
|
-
return true;
|
|
8664
|
+
if (queryTerms.length < 3) return true;
|
|
8864
8665
|
const requiredHits = queryTerms.length >= 3 ? 2 : 1;
|
|
8865
8666
|
let hits = 0;
|
|
8866
8667
|
for (const term of queryTerms) {
|
|
8867
|
-
if (contentTerms.has(term))
|
|
8868
|
-
|
|
8869
|
-
if (hits >= requiredHits)
|
|
8870
|
-
return true;
|
|
8668
|
+
if (contentTerms.has(term)) hits += 1;
|
|
8669
|
+
if (hits >= requiredHits) return true;
|
|
8871
8670
|
}
|
|
8872
8671
|
return false;
|
|
8873
8672
|
}
|
|
@@ -8877,17 +8676,14 @@ function shouldApplyTechnicalGuard(query) {
|
|
|
8877
8676
|
function hasAnyTerm(terms, expectedTerms) {
|
|
8878
8677
|
let found = false;
|
|
8879
8678
|
expectedTerms.forEach((term) => {
|
|
8880
|
-
if (terms.has(term))
|
|
8881
|
-
found = true;
|
|
8679
|
+
if (terms.has(term)) found = true;
|
|
8882
8680
|
});
|
|
8883
8681
|
return found;
|
|
8884
8682
|
}
|
|
8885
8683
|
function shouldRequireDecisionTopicOverlap(query) {
|
|
8886
|
-
if (isRetrievalPrivacyDecisionQuery(query))
|
|
8887
|
-
return false;
|
|
8684
|
+
if (isRetrievalPrivacyDecisionQuery(query)) return false;
|
|
8888
8685
|
const trimmed = query.trim();
|
|
8889
|
-
if (!trimmed)
|
|
8890
|
-
return false;
|
|
8686
|
+
if (!trimmed) return false;
|
|
8891
8687
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8892
8688
|
return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8893
8689
|
}
|
|
@@ -8895,12 +8691,9 @@ function extractDiscriminativeQueryTerms(query) {
|
|
|
8895
8691
|
const seen = /* @__PURE__ */ new Set();
|
|
8896
8692
|
const terms = [];
|
|
8897
8693
|
for (const token of tokenizeQualityText(query)) {
|
|
8898
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token))
|
|
8899
|
-
|
|
8900
|
-
if (
|
|
8901
|
-
continue;
|
|
8902
|
-
if (seen.has(token))
|
|
8903
|
-
continue;
|
|
8694
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
|
|
8695
|
+
if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
|
|
8696
|
+
if (seen.has(token)) continue;
|
|
8904
8697
|
seen.add(token);
|
|
8905
8698
|
terms.push(token);
|
|
8906
8699
|
}
|
|
@@ -8915,14 +8708,10 @@ function tokenizeQualityText(text) {
|
|
|
8915
8708
|
return text.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^A-Za-z0-9가-힣\s_.:-]/g, " ").split(/\s+/).flatMap((token) => token.split(/(?=[._:-])|(?<=[._:-])/g)).map((token) => normalizeQualityToken(token.replace(/^[._:-]+|[._:-]+$/g, ""))).filter((token) => token.length >= 2);
|
|
8916
8709
|
}
|
|
8917
8710
|
function normalizeQualityToken(token) {
|
|
8918
|
-
if (token === "apis")
|
|
8919
|
-
|
|
8920
|
-
if (token
|
|
8921
|
-
|
|
8922
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
|
|
8923
|
-
return token;
|
|
8924
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
8925
|
-
return `${token.slice(0, -3)}y`;
|
|
8711
|
+
if (token === "apis") return "api";
|
|
8712
|
+
if (token === "ids") return "id";
|
|
8713
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
|
|
8714
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
8926
8715
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
|
|
8927
8716
|
return token.slice(0, -1);
|
|
8928
8717
|
}
|
|
@@ -9104,8 +8893,7 @@ var Retriever = class {
|
|
|
9104
8893
|
const sharedMemories = [];
|
|
9105
8894
|
for (const result of sharedVectorResults) {
|
|
9106
8895
|
const entry = await this.sharedStore.get(result.entryId);
|
|
9107
|
-
if (!entry)
|
|
9108
|
-
continue;
|
|
8896
|
+
if (!entry) continue;
|
|
9109
8897
|
if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
|
|
9110
8898
|
sharedMemories.push(entry);
|
|
9111
8899
|
await this.sharedStore.recordUsage(entry.entryId);
|
|
@@ -9186,18 +8974,15 @@ var Retriever = class {
|
|
|
9186
8974
|
(result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
|
|
9187
8975
|
);
|
|
9188
8976
|
}
|
|
9189
|
-
if (filtered.length <= 2)
|
|
9190
|
-
return filtered;
|
|
8977
|
+
if (filtered.length <= 2) return filtered;
|
|
9191
8978
|
const topScore = filtered[0].score;
|
|
9192
|
-
if (topScore < 0.8)
|
|
9193
|
-
return filtered;
|
|
8979
|
+
if (topScore < 0.8) return filtered;
|
|
9194
8980
|
const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
|
|
9195
8981
|
return filtered.filter((result) => result.score >= cliffThreshold);
|
|
9196
8982
|
}
|
|
9197
8983
|
mergeResults(primary, secondary, limit) {
|
|
9198
8984
|
const byId = /* @__PURE__ */ new Map();
|
|
9199
|
-
for (const row of primary)
|
|
9200
|
-
byId.set(row.eventId, row);
|
|
8985
|
+
for (const row of primary) byId.set(row.eventId, row);
|
|
9201
8986
|
for (const row of secondary) {
|
|
9202
8987
|
const prev = byId.get(row.eventId);
|
|
9203
8988
|
if (!prev || row.score > prev.score) {
|
|
@@ -9208,23 +8993,19 @@ var Retriever = class {
|
|
|
9208
8993
|
}
|
|
9209
8994
|
async expandGraphHops(seeds, opts) {
|
|
9210
8995
|
const byId = /* @__PURE__ */ new Map();
|
|
9211
|
-
for (const s of seeds)
|
|
9212
|
-
byId.set(s.eventId, s);
|
|
8996
|
+
for (const s of seeds) byId.set(s.eventId, s);
|
|
9213
8997
|
let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
|
|
9214
8998
|
for (let hop = 1; hop <= opts.maxHops; hop += 1) {
|
|
9215
8999
|
const next = [];
|
|
9216
9000
|
for (const f of frontier) {
|
|
9217
9001
|
const ev = await this.eventStore.getEvent(f.row.eventId);
|
|
9218
|
-
if (!ev)
|
|
9219
|
-
continue;
|
|
9002
|
+
if (!ev) continue;
|
|
9220
9003
|
const rel = ev.metadata?.relatedEventIds ?? [];
|
|
9221
9004
|
const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
|
|
9222
9005
|
for (const rid of relatedIds) {
|
|
9223
|
-
if (byId.has(rid))
|
|
9224
|
-
continue;
|
|
9006
|
+
if (byId.has(rid)) continue;
|
|
9225
9007
|
const target = await this.eventStore.getEvent(rid);
|
|
9226
|
-
if (!target)
|
|
9227
|
-
continue;
|
|
9008
|
+
if (!target) continue;
|
|
9228
9009
|
const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
|
|
9229
9010
|
const row = {
|
|
9230
9011
|
id: `hop-${hop}-${rid}`,
|
|
@@ -9238,15 +9019,12 @@ var Retriever = class {
|
|
|
9238
9019
|
};
|
|
9239
9020
|
byId.set(row.eventId, row);
|
|
9240
9021
|
next.push({ row, hop });
|
|
9241
|
-
if (byId.size >= opts.limit)
|
|
9242
|
-
break;
|
|
9022
|
+
if (byId.size >= opts.limit) break;
|
|
9243
9023
|
}
|
|
9244
|
-
if (byId.size >= opts.limit)
|
|
9245
|
-
break;
|
|
9024
|
+
if (byId.size >= opts.limit) break;
|
|
9246
9025
|
}
|
|
9247
9026
|
frontier = next;
|
|
9248
|
-
if (frontier.length === 0 || byId.size >= opts.limit)
|
|
9249
|
-
break;
|
|
9027
|
+
if (frontier.length === 0 || byId.size >= opts.limit) break;
|
|
9250
9028
|
}
|
|
9251
9029
|
if (opts.queryGraphEnabled) {
|
|
9252
9030
|
await this.expandQueryGraphPaths(opts.query, byId, opts);
|
|
@@ -9254,8 +9032,7 @@ var Retriever = class {
|
|
|
9254
9032
|
return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
|
|
9255
9033
|
}
|
|
9256
9034
|
async expandQueryGraphPaths(query, byId, opts) {
|
|
9257
|
-
if (!query.trim() || !this.eventStore.getDatabase)
|
|
9258
|
-
return;
|
|
9035
|
+
if (!query.trim() || !this.eventStore.getDatabase) return;
|
|
9259
9036
|
try {
|
|
9260
9037
|
const db = this.eventStore.getDatabase();
|
|
9261
9038
|
const extraction = new QueryEntityExtractor(db).extract(query, {
|
|
@@ -9264,8 +9041,7 @@ var Retriever = class {
|
|
|
9264
9041
|
});
|
|
9265
9042
|
const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
|
|
9266
9043
|
const startNodes = uniqueEntityStartNodes(startCandidates);
|
|
9267
|
-
if (startNodes.length === 0)
|
|
9268
|
-
return;
|
|
9044
|
+
if (startNodes.length === 0) return;
|
|
9269
9045
|
const expansion = new GraphPathService(db).expand({
|
|
9270
9046
|
startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
|
|
9271
9047
|
maxHops: opts.maxHops,
|
|
@@ -9274,11 +9050,9 @@ var Retriever = class {
|
|
|
9274
9050
|
});
|
|
9275
9051
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
9276
9052
|
for (const path11 of expansion.paths) {
|
|
9277
|
-
if (path11.target.type !== "event")
|
|
9278
|
-
continue;
|
|
9053
|
+
if (path11.target.type !== "event") continue;
|
|
9279
9054
|
const target = await this.eventStore.getEvent(path11.target.id);
|
|
9280
|
-
if (!target)
|
|
9281
|
-
continue;
|
|
9055
|
+
if (!target) continue;
|
|
9282
9056
|
const graphPath = toRetrievalGraphPathDebug(path11, titleByEntityId);
|
|
9283
9057
|
const score = graphPathScore(path11, opts.hopPenalty);
|
|
9284
9058
|
const existing = byId.get(target.id);
|
|
@@ -9304,17 +9078,14 @@ var Retriever = class {
|
|
|
9304
9078
|
lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
|
|
9305
9079
|
};
|
|
9306
9080
|
byId.set(row.eventId, row);
|
|
9307
|
-
if (byId.size >= opts.limit)
|
|
9308
|
-
break;
|
|
9081
|
+
if (byId.size >= opts.limit) break;
|
|
9309
9082
|
}
|
|
9310
9083
|
} catch {
|
|
9311
9084
|
}
|
|
9312
9085
|
}
|
|
9313
9086
|
shouldFallback(matchResult, results) {
|
|
9314
|
-
if (results.length === 0)
|
|
9315
|
-
|
|
9316
|
-
if (matchResult.confidence === "none")
|
|
9317
|
-
return true;
|
|
9087
|
+
if (results.length === 0) return true;
|
|
9088
|
+
if (matchResult.confidence === "none") return true;
|
|
9318
9089
|
return false;
|
|
9319
9090
|
}
|
|
9320
9091
|
async buildSummaryFallback(query, topK) {
|
|
@@ -9419,29 +9190,21 @@ var Retriever = class {
|
|
|
9419
9190
|
(value) => typeof value === "string" && value.length > 0
|
|
9420
9191
|
)
|
|
9421
9192
|
);
|
|
9422
|
-
if (!scope && projectScopeMode === "global" && facetFilters === null)
|
|
9423
|
-
return results;
|
|
9193
|
+
if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
|
|
9424
9194
|
const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
|
|
9425
9195
|
const filtered = [];
|
|
9426
9196
|
for (const result of results) {
|
|
9427
|
-
if (scope?.sessionId && result.sessionId !== scope.sessionId)
|
|
9428
|
-
|
|
9429
|
-
if (scope?.
|
|
9430
|
-
continue;
|
|
9431
|
-
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
|
|
9432
|
-
continue;
|
|
9197
|
+
if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
|
|
9198
|
+
if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
|
|
9199
|
+
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
|
|
9433
9200
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9434
|
-
if (!event)
|
|
9435
|
-
|
|
9436
|
-
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
|
|
9437
|
-
continue;
|
|
9201
|
+
if (!event) continue;
|
|
9202
|
+
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
|
|
9438
9203
|
if (normalizedIncludes.length > 0) {
|
|
9439
9204
|
const lc = event.content.toLowerCase();
|
|
9440
|
-
if (!normalizedIncludes.some((needle) => lc.includes(needle)))
|
|
9441
|
-
continue;
|
|
9205
|
+
if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
|
|
9442
9206
|
}
|
|
9443
|
-
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
|
|
9444
|
-
continue;
|
|
9207
|
+
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
|
|
9445
9208
|
const projectHash = this.extractProjectHash(event.metadata);
|
|
9446
9209
|
filtered.push({ result, projectHash });
|
|
9447
9210
|
}
|
|
@@ -9458,27 +9221,21 @@ var Retriever = class {
|
|
|
9458
9221
|
});
|
|
9459
9222
|
}
|
|
9460
9223
|
normalizeFacetFilters(facets) {
|
|
9461
|
-
if (!facets || facets.length === 0)
|
|
9462
|
-
return null;
|
|
9224
|
+
if (!facets || facets.length === 0) return null;
|
|
9463
9225
|
const normalized = [];
|
|
9464
9226
|
for (const facet of facets) {
|
|
9465
9227
|
const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
|
|
9466
9228
|
const value = typeof facet.value === "string" ? facet.value.trim() : "";
|
|
9467
|
-
if (!parsedDimension.success || !value)
|
|
9468
|
-
return [];
|
|
9229
|
+
if (!parsedDimension.success || !value) return [];
|
|
9469
9230
|
normalized.push({ dimension: parsedDimension.data, value });
|
|
9470
9231
|
}
|
|
9471
9232
|
return normalized;
|
|
9472
9233
|
}
|
|
9473
9234
|
async applyFacetFilters(results, options) {
|
|
9474
|
-
if (options.facets === null)
|
|
9475
|
-
|
|
9476
|
-
if (options.
|
|
9477
|
-
|
|
9478
|
-
if (!options.projectHash)
|
|
9479
|
-
return [];
|
|
9480
|
-
if (!this.eventStore.getDatabase)
|
|
9481
|
-
return [];
|
|
9235
|
+
if (options.facets === null) return results;
|
|
9236
|
+
if (options.facets.length === 0) return [];
|
|
9237
|
+
if (!options.projectHash) return [];
|
|
9238
|
+
if (!this.eventStore.getDatabase) return [];
|
|
9482
9239
|
const repo = new FacetRepository(this.eventStore.getDatabase());
|
|
9483
9240
|
const filtered = [];
|
|
9484
9241
|
for (const result of results) {
|
|
@@ -9535,14 +9292,11 @@ var Retriever = class {
|
|
|
9535
9292
|
return (result.graphPaths || []).length > 0;
|
|
9536
9293
|
}
|
|
9537
9294
|
extractProjectHash(metadata) {
|
|
9538
|
-
if (!metadata || typeof metadata !== "object")
|
|
9539
|
-
return void 0;
|
|
9295
|
+
if (!metadata || typeof metadata !== "object") return void 0;
|
|
9540
9296
|
const scope = metadata.scope;
|
|
9541
|
-
if (!scope || typeof scope !== "object")
|
|
9542
|
-
return void 0;
|
|
9297
|
+
if (!scope || typeof scope !== "object") return void 0;
|
|
9543
9298
|
const project = scope.project;
|
|
9544
|
-
if (!project || typeof project !== "object")
|
|
9545
|
-
return void 0;
|
|
9299
|
+
if (!project || typeof project !== "object") return void 0;
|
|
9546
9300
|
const hash = project.hash;
|
|
9547
9301
|
return typeof hash === "string" && hash.length > 0 ? hash : void 0;
|
|
9548
9302
|
}
|
|
@@ -9556,8 +9310,7 @@ var Retriever = class {
|
|
|
9556
9310
|
const memories = [];
|
|
9557
9311
|
for (const result of results) {
|
|
9558
9312
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9559
|
-
if (!event)
|
|
9560
|
-
continue;
|
|
9313
|
+
if (!event) continue;
|
|
9561
9314
|
if (this.graduation) {
|
|
9562
9315
|
this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
|
|
9563
9316
|
}
|
|
@@ -9572,32 +9325,27 @@ var Retriever = class {
|
|
|
9572
9325
|
async getSessionContext(sessionId, eventId) {
|
|
9573
9326
|
const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
|
|
9574
9327
|
const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
|
|
9575
|
-
if (eventIndex === -1)
|
|
9576
|
-
return void 0;
|
|
9328
|
+
if (eventIndex === -1) return void 0;
|
|
9577
9329
|
const start = Math.max(0, eventIndex - 1);
|
|
9578
9330
|
const end = Math.min(sessionEvents.length, eventIndex + 2);
|
|
9579
9331
|
const contextEvents = sessionEvents.slice(start, end);
|
|
9580
|
-
if (contextEvents.length <= 1)
|
|
9581
|
-
return void 0;
|
|
9332
|
+
if (contextEvents.length <= 1) return void 0;
|
|
9582
9333
|
return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
|
|
9583
9334
|
}
|
|
9584
9335
|
buildUnifiedContext(projectResult, sharedMemories) {
|
|
9585
9336
|
let context = projectResult.context;
|
|
9586
|
-
if (sharedMemories.length === 0)
|
|
9587
|
-
return context;
|
|
9337
|
+
if (sharedMemories.length === 0) return context;
|
|
9588
9338
|
context += "\n\n## Cross-Project Knowledge\n\n";
|
|
9589
9339
|
for (const memory of sharedMemories.slice(0, 3)) {
|
|
9590
9340
|
context += `### ${memory.title}
|
|
9591
9341
|
`;
|
|
9592
|
-
if (memory.symptoms.length > 0)
|
|
9593
|
-
context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9342
|
+
if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9594
9343
|
`;
|
|
9595
9344
|
context += `**Root Cause:** ${memory.rootCause}
|
|
9596
9345
|
`;
|
|
9597
9346
|
context += `**Solution:** ${memory.solution}
|
|
9598
9347
|
`;
|
|
9599
|
-
if (memory.technologies && memory.technologies.length > 0)
|
|
9600
|
-
context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9348
|
+
if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9601
9349
|
`;
|
|
9602
9350
|
context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
|
|
9603
9351
|
|
|
@@ -9611,13 +9359,11 @@ var Retriever = class {
|
|
|
9611
9359
|
for (const memory of memories) {
|
|
9612
9360
|
const memoryText = this.formatMemory(memory);
|
|
9613
9361
|
const memoryTokens = this.estimateTokens(memoryText);
|
|
9614
|
-
if (currentTokens + memoryTokens > maxTokens)
|
|
9615
|
-
break;
|
|
9362
|
+
if (currentTokens + memoryTokens > maxTokens) break;
|
|
9616
9363
|
parts.push(memoryText);
|
|
9617
9364
|
currentTokens += memoryTokens;
|
|
9618
9365
|
}
|
|
9619
|
-
if (parts.length === 0)
|
|
9620
|
-
return "";
|
|
9366
|
+
if (parts.length === 0) return "";
|
|
9621
9367
|
return `## Relevant Memories
|
|
9622
9368
|
|
|
9623
9369
|
${parts.join("\n\n---\n\n")}`;
|
|
@@ -9627,19 +9373,16 @@ ${parts.join("\n\n---\n\n")}`;
|
|
|
9627
9373
|
const date = event.timestamp.toISOString().split("T")[0];
|
|
9628
9374
|
let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
|
|
9629
9375
|
${event.content}`;
|
|
9630
|
-
if (sessionContext)
|
|
9631
|
-
text += `
|
|
9376
|
+
if (sessionContext) text += `
|
|
9632
9377
|
|
|
9633
9378
|
_Context:_ ${sessionContext}`;
|
|
9634
9379
|
return text;
|
|
9635
9380
|
}
|
|
9636
9381
|
matchesMetadataScope(metadata, expected) {
|
|
9637
|
-
if (!metadata)
|
|
9638
|
-
return false;
|
|
9382
|
+
if (!metadata) return false;
|
|
9639
9383
|
return Object.entries(expected).every(([path11, value]) => {
|
|
9640
9384
|
const actual = path11.split(".").reduce((acc, key) => {
|
|
9641
|
-
if (typeof acc !== "object" || acc === null)
|
|
9642
|
-
return void 0;
|
|
9385
|
+
if (typeof acc !== "object" || acc === null) return void 0;
|
|
9643
9386
|
return acc[key];
|
|
9644
9387
|
}, metadata);
|
|
9645
9388
|
return actual === value;
|
|
@@ -9649,27 +9392,20 @@ _Context:_ ${sessionContext}`;
|
|
|
9649
9392
|
return text.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, " ").split(/\s+/).map((token) => this.normalizeToken(token)).filter((t) => t.length >= 2).slice(0, 64);
|
|
9650
9393
|
}
|
|
9651
9394
|
normalizeToken(token) {
|
|
9652
|
-
if (token === "apis")
|
|
9653
|
-
|
|
9654
|
-
if (token === "
|
|
9655
|
-
|
|
9656
|
-
if (token === "does")
|
|
9657
|
-
return token;
|
|
9658
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
9659
|
-
return `${token.slice(0, -3)}y`;
|
|
9395
|
+
if (token === "apis") return "api";
|
|
9396
|
+
if (token === "ids") return "id";
|
|
9397
|
+
if (token === "does") return token;
|
|
9398
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
9660
9399
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
|
|
9661
9400
|
return token.slice(0, -1);
|
|
9662
9401
|
}
|
|
9663
9402
|
return token;
|
|
9664
9403
|
}
|
|
9665
9404
|
keywordOverlap(a, b) {
|
|
9666
|
-
if (a.length === 0 || b.length === 0)
|
|
9667
|
-
return 0;
|
|
9405
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
9668
9406
|
const bs = new Set(b);
|
|
9669
9407
|
let hit = 0;
|
|
9670
|
-
for (const t of a)
|
|
9671
|
-
if (bs.has(t))
|
|
9672
|
-
hit += 1;
|
|
9408
|
+
for (const t of a) if (bs.has(t)) hit += 1;
|
|
9673
9409
|
return hit / a.length;
|
|
9674
9410
|
}
|
|
9675
9411
|
estimateTokens(text) {
|
|
@@ -9690,8 +9426,7 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
9690
9426
|
const seen = /* @__PURE__ */ new Set();
|
|
9691
9427
|
const nodes = [];
|
|
9692
9428
|
for (const candidate of candidates) {
|
|
9693
|
-
if (!candidate.entityId || seen.has(candidate.entityId))
|
|
9694
|
-
continue;
|
|
9429
|
+
if (!candidate.entityId || seen.has(candidate.entityId)) continue;
|
|
9695
9430
|
seen.add(candidate.entityId);
|
|
9696
9431
|
nodes.push({ entityId: candidate.entityId, title: candidate.text });
|
|
9697
9432
|
}
|
|
@@ -9715,16 +9450,14 @@ function graphPathScore(path11, hopPenalty) {
|
|
|
9715
9450
|
return Math.max(0.05, base - hopPenalty * Math.max(0, path11.hops - 1));
|
|
9716
9451
|
}
|
|
9717
9452
|
function clampGraphHops(maxHops) {
|
|
9718
|
-
if (!Number.isFinite(maxHops))
|
|
9719
|
-
return 2;
|
|
9453
|
+
if (!Number.isFinite(maxHops)) return 2;
|
|
9720
9454
|
return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
|
|
9721
9455
|
}
|
|
9722
9456
|
function mergeGraphPaths(existing, incoming) {
|
|
9723
9457
|
const byKey = /* @__PURE__ */ new Map();
|
|
9724
9458
|
for (const path11 of [...existing, ...incoming]) {
|
|
9725
9459
|
const key = [path11.startEntityId, path11.targetType, path11.targetId, path11.hops, ...path11.relationPath].join("\0");
|
|
9726
|
-
if (!byKey.has(key))
|
|
9727
|
-
byKey.set(key, path11);
|
|
9460
|
+
if (!byKey.has(key)) byKey.set(key, path11);
|
|
9728
9461
|
}
|
|
9729
9462
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
9730
9463
|
}
|
|
@@ -9732,10 +9465,8 @@ function graphPathSignature(path11) {
|
|
|
9732
9465
|
return [path11.startEntityId, path11.targetType, path11.targetId, path11.hops, ...path11.relationPath].join("|");
|
|
9733
9466
|
}
|
|
9734
9467
|
function compareStable(a, b) {
|
|
9735
|
-
if (a < b)
|
|
9736
|
-
|
|
9737
|
-
if (a > b)
|
|
9738
|
-
return 1;
|
|
9468
|
+
if (a < b) return -1;
|
|
9469
|
+
if (a > b) return 1;
|
|
9739
9470
|
return 0;
|
|
9740
9471
|
}
|
|
9741
9472
|
function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
@@ -9747,6 +9478,7 @@ var RetrievalAnalyticsService = class {
|
|
|
9747
9478
|
constructor(deps) {
|
|
9748
9479
|
this.deps = deps;
|
|
9749
9480
|
}
|
|
9481
|
+
deps;
|
|
9750
9482
|
async getRetrievalTraceStats() {
|
|
9751
9483
|
await this.deps.initialize();
|
|
9752
9484
|
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
@@ -9824,6 +9556,7 @@ var RetrievalDisclosureService = class {
|
|
|
9824
9556
|
constructor(deps) {
|
|
9825
9557
|
this.deps = deps;
|
|
9826
9558
|
}
|
|
9559
|
+
deps;
|
|
9827
9560
|
async search(query, options) {
|
|
9828
9561
|
const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
|
|
9829
9562
|
const debugByEventId = this.buildDebugIndex(result);
|
|
@@ -9853,8 +9586,7 @@ var RetrievalDisclosureService = class {
|
|
|
9853
9586
|
return this.expandShared(parsedId.entryId);
|
|
9854
9587
|
}
|
|
9855
9588
|
const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9856
|
-
if (!targetEvent)
|
|
9857
|
-
return null;
|
|
9589
|
+
if (!targetEvent) return null;
|
|
9858
9590
|
const windowSize = Math.max(0, options?.windowSize ?? 3);
|
|
9859
9591
|
const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
9860
9592
|
const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
|
|
@@ -9878,8 +9610,7 @@ var RetrievalDisclosureService = class {
|
|
|
9878
9610
|
return this.sourceShared(parsedId.entryId);
|
|
9879
9611
|
}
|
|
9880
9612
|
const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9881
|
-
if (!rawEvent)
|
|
9882
|
-
return null;
|
|
9613
|
+
if (!rawEvent) return null;
|
|
9883
9614
|
return {
|
|
9884
9615
|
...this.sourceReferenceForEvent(rawEvent),
|
|
9885
9616
|
rawEvents: [rawEvent],
|
|
@@ -9888,8 +9619,7 @@ var RetrievalDisclosureService = class {
|
|
|
9888
9619
|
}
|
|
9889
9620
|
async expandShared(entryId) {
|
|
9890
9621
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9891
|
-
if (!entry)
|
|
9892
|
-
return null;
|
|
9622
|
+
if (!entry) return null;
|
|
9893
9623
|
return {
|
|
9894
9624
|
target: this.sharedToEnvelope(entry),
|
|
9895
9625
|
surroundingFacts: [],
|
|
@@ -9900,8 +9630,7 @@ var RetrievalDisclosureService = class {
|
|
|
9900
9630
|
}
|
|
9901
9631
|
async sourceShared(entryId) {
|
|
9902
9632
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9903
|
-
if (!entry)
|
|
9904
|
-
return null;
|
|
9633
|
+
if (!entry) return null;
|
|
9905
9634
|
const sourceReference = this.sourceReferenceForShared(entry);
|
|
9906
9635
|
return {
|
|
9907
9636
|
...sourceReference,
|
|
@@ -9987,38 +9716,25 @@ var RetrievalDisclosureService = class {
|
|
|
9987
9716
|
const reasons = /* @__PURE__ */ new Set();
|
|
9988
9717
|
const usedVector = this.usedVector(result);
|
|
9989
9718
|
const usedKeyword = this.usedKeyword(result);
|
|
9990
|
-
if (usedVector && (debug?.semanticScore ?? 0) > 0)
|
|
9991
|
-
|
|
9992
|
-
if ((debug?.
|
|
9993
|
-
|
|
9994
|
-
if ((debug?.
|
|
9995
|
-
|
|
9996
|
-
if (
|
|
9997
|
-
|
|
9998
|
-
if (
|
|
9999
|
-
reasons.add("entity_overlap");
|
|
10000
|
-
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
|
|
10001
|
-
reasons.add("summary_fallback");
|
|
10002
|
-
if (memory.sessionContext)
|
|
10003
|
-
reasons.add("continuity_link");
|
|
10004
|
-
if (memory.event.eventType === "tool_observation")
|
|
10005
|
-
reasons.add("tool_followup");
|
|
10006
|
-
if (reasons.size === 0)
|
|
10007
|
-
reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
9719
|
+
if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
|
|
9720
|
+
if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
|
|
9721
|
+
if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
|
|
9722
|
+
if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
|
|
9723
|
+
if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
|
|
9724
|
+
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
|
|
9725
|
+
if (memory.sessionContext) reasons.add("continuity_link");
|
|
9726
|
+
if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
|
|
9727
|
+
if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10008
9728
|
return Array.from(reasons);
|
|
10009
9729
|
}
|
|
10010
9730
|
reasonsForContextEvent(event) {
|
|
10011
|
-
if (event.eventType === "tool_observation")
|
|
10012
|
-
|
|
10013
|
-
if (event.eventType === "session_summary")
|
|
10014
|
-
return ["summary_fallback"];
|
|
9731
|
+
if (event.eventType === "tool_observation") return ["tool_followup"];
|
|
9732
|
+
if (event.eventType === "session_summary") return ["summary_fallback"];
|
|
10015
9733
|
return ["continuity_link"];
|
|
10016
9734
|
}
|
|
10017
9735
|
resultTypeForEvent(event) {
|
|
10018
|
-
if (event.eventType === "session_summary")
|
|
10019
|
-
|
|
10020
|
-
if (event.eventType === "tool_observation")
|
|
10021
|
-
return "tool_evidence";
|
|
9736
|
+
if (event.eventType === "session_summary") return "summary";
|
|
9737
|
+
if (event.eventType === "tool_observation") return "tool_evidence";
|
|
10022
9738
|
return "source";
|
|
10023
9739
|
}
|
|
10024
9740
|
sourceReferenceForEvent(event) {
|
|
@@ -10042,21 +9758,15 @@ var RetrievalDisclosureService = class {
|
|
|
10042
9758
|
}
|
|
10043
9759
|
sourceTypeForEvent(event) {
|
|
10044
9760
|
const metadata = event.metadata || {};
|
|
10045
|
-
if (event.eventType === "tool_observation")
|
|
10046
|
-
|
|
10047
|
-
if (typeof metadata.
|
|
10048
|
-
return "transcript";
|
|
10049
|
-
if (typeof metadata.importedFrom === "string")
|
|
10050
|
-
return "imported_history";
|
|
9761
|
+
if (event.eventType === "tool_observation") return "tool_output";
|
|
9762
|
+
if (typeof metadata.transcriptPath === "string") return "transcript";
|
|
9763
|
+
if (typeof metadata.importedFrom === "string") return "imported_history";
|
|
10051
9764
|
return "raw_event";
|
|
10052
9765
|
}
|
|
10053
9766
|
titleForEvent(event) {
|
|
10054
|
-
if (event.eventType === "session_summary")
|
|
10055
|
-
|
|
10056
|
-
if (event.eventType === "
|
|
10057
|
-
return "Tool evidence";
|
|
10058
|
-
if (event.eventType === "agent_response")
|
|
10059
|
-
return "Agent response";
|
|
9767
|
+
if (event.eventType === "session_summary") return "Session summary";
|
|
9768
|
+
if (event.eventType === "tool_observation") return "Tool evidence";
|
|
9769
|
+
if (event.eventType === "agent_response") return "Agent response";
|
|
10060
9770
|
return "User prompt";
|
|
10061
9771
|
}
|
|
10062
9772
|
usedVector(result) {
|
|
@@ -10082,8 +9792,7 @@ var RetrievalDisclosureService = class {
|
|
|
10082
9792
|
}
|
|
10083
9793
|
preview(content, maxLength) {
|
|
10084
9794
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
10085
|
-
if (normalized.length <= maxLength)
|
|
10086
|
-
return normalized;
|
|
9795
|
+
if (normalized.length <= maxLength) return normalized;
|
|
10087
9796
|
return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
10088
9797
|
}
|
|
10089
9798
|
};
|
|
@@ -10112,6 +9821,7 @@ var RetrievalOrchestrator = class {
|
|
|
10112
9821
|
this.deps = deps;
|
|
10113
9822
|
this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
|
|
10114
9823
|
}
|
|
9824
|
+
deps;
|
|
10115
9825
|
/**
|
|
10116
9826
|
* Retrieve relevant memories for a query.
|
|
10117
9827
|
*/
|
|
@@ -10193,8 +9903,7 @@ var RetrievalOrchestrator = class {
|
|
|
10193
9903
|
* the heavier retrieval/vector initialization path for prompt telemetry.
|
|
10194
9904
|
*/
|
|
10195
9905
|
async incrementMemoryAccess(eventIds) {
|
|
10196
|
-
if (eventIds.length === 0)
|
|
10197
|
-
return;
|
|
9906
|
+
if (eventIds.length === 0) return;
|
|
10198
9907
|
await this.deps.accessStore.incrementAccessCount(eventIds);
|
|
10199
9908
|
}
|
|
10200
9909
|
/**
|
|
@@ -10207,10 +9916,8 @@ var RetrievalOrchestrator = class {
|
|
|
10207
9916
|
resolveGraphHopOptions(callerOptions) {
|
|
10208
9917
|
const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
|
|
10209
9918
|
const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
|
|
10210
|
-
if (!callerOptions)
|
|
10211
|
-
|
|
10212
|
-
if (!graphExpansion)
|
|
10213
|
-
return callerOptions;
|
|
9919
|
+
if (!callerOptions) return durableOptions;
|
|
9920
|
+
if (!graphExpansion) return callerOptions;
|
|
10214
9921
|
if (graphExpansion.enabled !== true) {
|
|
10215
9922
|
return {
|
|
10216
9923
|
...callerOptions,
|
|
@@ -10270,12 +9977,10 @@ var RetrievalOrchestrator = class {
|
|
|
10270
9977
|
const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
|
|
10271
9978
|
const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
|
|
10272
9979
|
const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
|
|
10273
|
-
if (!allFinite)
|
|
10274
|
-
return void 0;
|
|
9980
|
+
if (!allFinite) return void 0;
|
|
10275
9981
|
const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
|
|
10276
9982
|
const total = semantic + lexical + recency;
|
|
10277
|
-
if (!nonNegative || total <= 0)
|
|
10278
|
-
return void 0;
|
|
9983
|
+
if (!nonNegative || total <= 0) return void 0;
|
|
10279
9984
|
return {
|
|
10280
9985
|
semantic: semantic / total,
|
|
10281
9986
|
lexical: lexical / total,
|
|
@@ -10284,17 +9989,14 @@ var RetrievalOrchestrator = class {
|
|
|
10284
9989
|
}
|
|
10285
9990
|
async getRerankWeights(adaptive) {
|
|
10286
9991
|
const configured = this.getConfiguredRerankWeights();
|
|
10287
|
-
if (configured)
|
|
10288
|
-
|
|
10289
|
-
if (adaptive)
|
|
10290
|
-
return this.getAdaptiveRerankWeights();
|
|
9992
|
+
if (configured) return configured;
|
|
9993
|
+
if (adaptive) return this.getAdaptiveRerankWeights();
|
|
10291
9994
|
return void 0;
|
|
10292
9995
|
}
|
|
10293
9996
|
async getAdaptiveRerankWeights() {
|
|
10294
9997
|
try {
|
|
10295
9998
|
const stats = await this.deps.traceStore.getHelpfulnessStats();
|
|
10296
|
-
if (stats.totalEvaluated < 20)
|
|
10297
|
-
return void 0;
|
|
9999
|
+
if (stats.totalEvaluated < 20) return void 0;
|
|
10298
10000
|
let semantic = 0.7;
|
|
10299
10001
|
let lexical = 0.2;
|
|
10300
10002
|
let recency = 0.1;
|
|
@@ -10316,11 +10018,9 @@ var RetrievalOrchestrator = class {
|
|
|
10316
10018
|
}
|
|
10317
10019
|
}
|
|
10318
10020
|
async rewriteQueryIntent(query) {
|
|
10319
|
-
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
|
|
10320
|
-
return null;
|
|
10021
|
+
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
|
|
10321
10022
|
const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
|
|
10322
|
-
if (!apiUrl)
|
|
10323
|
-
return null;
|
|
10023
|
+
if (!apiUrl) return null;
|
|
10324
10024
|
const controller = new AbortController();
|
|
10325
10025
|
const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
|
|
10326
10026
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10346,11 +10046,9 @@ var RetrievalOrchestrator = class {
|
|
|
10346
10046
|
signal: controller.signal
|
|
10347
10047
|
});
|
|
10348
10048
|
const text = (await res.text()).trim();
|
|
10349
|
-
if (!text)
|
|
10350
|
-
return null;
|
|
10049
|
+
if (!text) return null;
|
|
10351
10050
|
const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
|
|
10352
|
-
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
|
|
10353
|
-
return null;
|
|
10051
|
+
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
|
|
10354
10052
|
return oneLine;
|
|
10355
10053
|
} catch {
|
|
10356
10054
|
return null;
|
|
@@ -10492,8 +10190,7 @@ function createMemoryEngineServices(options) {
|
|
|
10492
10190
|
};
|
|
10493
10191
|
}
|
|
10494
10192
|
function shouldEnablePerspectiveDeriver(options) {
|
|
10495
|
-
if (options.readOnly)
|
|
10496
|
-
return false;
|
|
10193
|
+
if (options.readOnly) return false;
|
|
10497
10194
|
const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
|
|
10498
10195
|
return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
|
|
10499
10196
|
}
|
|
@@ -10527,6 +10224,9 @@ var GraduationWorker = class {
|
|
|
10527
10224
|
this.graduation = graduation;
|
|
10528
10225
|
this.config = config;
|
|
10529
10226
|
}
|
|
10227
|
+
eventStore;
|
|
10228
|
+
graduation;
|
|
10229
|
+
config;
|
|
10530
10230
|
running = false;
|
|
10531
10231
|
timeout = null;
|
|
10532
10232
|
lastEvaluated = /* @__PURE__ */ new Map();
|
|
@@ -10534,8 +10234,7 @@ var GraduationWorker = class {
|
|
|
10534
10234
|
* Start the graduation worker
|
|
10535
10235
|
*/
|
|
10536
10236
|
start() {
|
|
10537
|
-
if (this.running)
|
|
10538
|
-
return;
|
|
10237
|
+
if (this.running) return;
|
|
10539
10238
|
this.running = true;
|
|
10540
10239
|
this.scheduleNext();
|
|
10541
10240
|
}
|
|
@@ -10565,8 +10264,7 @@ var GraduationWorker = class {
|
|
|
10565
10264
|
* Schedule the next graduation check
|
|
10566
10265
|
*/
|
|
10567
10266
|
scheduleNext() {
|
|
10568
|
-
if (!this.running)
|
|
10569
|
-
return;
|
|
10267
|
+
if (!this.running) return;
|
|
10570
10268
|
this.timeout = setTimeout(
|
|
10571
10269
|
() => this.run(),
|
|
10572
10270
|
this.config.evaluationIntervalMs
|
|
@@ -10576,8 +10274,7 @@ var GraduationWorker = class {
|
|
|
10576
10274
|
* Run graduation evaluation
|
|
10577
10275
|
*/
|
|
10578
10276
|
async run() {
|
|
10579
|
-
if (!this.running)
|
|
10580
|
-
return;
|
|
10277
|
+
if (!this.running) return;
|
|
10581
10278
|
try {
|
|
10582
10279
|
await this.runGraduation();
|
|
10583
10280
|
} catch (error) {
|
|
@@ -10641,10 +10338,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
10641
10338
|
maxRetries: 3
|
|
10642
10339
|
};
|
|
10643
10340
|
function parseJsonArray(value) {
|
|
10644
|
-
if (Array.isArray(value))
|
|
10645
|
-
|
|
10646
|
-
if (typeof value !== "string" || value.trim().length === 0)
|
|
10647
|
-
return [];
|
|
10341
|
+
if (Array.isArray(value)) return value;
|
|
10342
|
+
if (typeof value !== "string" || value.trim().length === 0) return [];
|
|
10648
10343
|
try {
|
|
10649
10344
|
const parsed = JSON.parse(value);
|
|
10650
10345
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -10674,8 +10369,7 @@ var VectorWorker = class {
|
|
|
10674
10369
|
* Start the worker polling loop
|
|
10675
10370
|
*/
|
|
10676
10371
|
start() {
|
|
10677
|
-
if (this.running)
|
|
10678
|
-
return;
|
|
10372
|
+
if (this.running) return;
|
|
10679
10373
|
this.running = true;
|
|
10680
10374
|
this.stopping = false;
|
|
10681
10375
|
this.poll();
|
|
@@ -10751,8 +10445,7 @@ var VectorWorker = class {
|
|
|
10751
10445
|
* Poll for new items
|
|
10752
10446
|
*/
|
|
10753
10447
|
async poll() {
|
|
10754
|
-
if (!this.running || this.stopping)
|
|
10755
|
-
return;
|
|
10448
|
+
if (!this.running || this.stopping) return;
|
|
10756
10449
|
try {
|
|
10757
10450
|
await this.processBatch();
|
|
10758
10451
|
} catch (error) {
|
|
@@ -10797,6 +10490,7 @@ var DefaultContentProvider = class {
|
|
|
10797
10490
|
constructor(db) {
|
|
10798
10491
|
this.db = db;
|
|
10799
10492
|
}
|
|
10493
|
+
db;
|
|
10800
10494
|
async getContent(itemKind, itemId) {
|
|
10801
10495
|
switch (itemKind) {
|
|
10802
10496
|
case "entry":
|
|
@@ -10817,8 +10511,7 @@ var DefaultContentProvider = class {
|
|
|
10817
10511
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
10818
10512
|
[entryId]
|
|
10819
10513
|
);
|
|
10820
|
-
if (rows.length === 0)
|
|
10821
|
-
return null;
|
|
10514
|
+
if (rows.length === 0) return null;
|
|
10822
10515
|
const row = rows[0];
|
|
10823
10516
|
const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
|
|
10824
10517
|
return {
|
|
@@ -10837,8 +10530,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10837
10530
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
10838
10531
|
[taskId]
|
|
10839
10532
|
);
|
|
10840
|
-
if (rows.length === 0)
|
|
10841
|
-
return null;
|
|
10533
|
+
if (rows.length === 0) return null;
|
|
10842
10534
|
const row = rows[0];
|
|
10843
10535
|
return {
|
|
10844
10536
|
content: row.search_text || row.title,
|
|
@@ -10854,8 +10546,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10854
10546
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
10855
10547
|
[eventId]
|
|
10856
10548
|
);
|
|
10857
|
-
if (rows.length === 0)
|
|
10858
|
-
return null;
|
|
10549
|
+
if (rows.length === 0) return null;
|
|
10859
10550
|
const row = rows[0];
|
|
10860
10551
|
return {
|
|
10861
10552
|
content: row.content,
|
|
@@ -10883,8 +10574,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10883
10574
|
}
|
|
10884
10575
|
throw error;
|
|
10885
10576
|
}
|
|
10886
|
-
if (rows.length === 0)
|
|
10887
|
-
return null;
|
|
10577
|
+
if (rows.length === 0) return null;
|
|
10888
10578
|
const row = rows[0];
|
|
10889
10579
|
const sourceEventIds = parseJsonArray(row.source_event_ids_json);
|
|
10890
10580
|
const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
|
|
@@ -10926,8 +10616,7 @@ var VectorWorkerV2 = class {
|
|
|
10926
10616
|
* Start the worker polling loop
|
|
10927
10617
|
*/
|
|
10928
10618
|
start() {
|
|
10929
|
-
if (this.running)
|
|
10930
|
-
return;
|
|
10619
|
+
if (this.running) return;
|
|
10931
10620
|
this.running = true;
|
|
10932
10621
|
this.stopping = false;
|
|
10933
10622
|
this.poll();
|
|
@@ -10997,8 +10686,7 @@ var VectorWorkerV2 = class {
|
|
|
10997
10686
|
* Poll for new jobs
|
|
10998
10687
|
*/
|
|
10999
10688
|
async poll() {
|
|
11000
|
-
if (!this.running || this.stopping)
|
|
11001
|
-
return;
|
|
10689
|
+
if (!this.running || this.stopping) return;
|
|
11002
10690
|
try {
|
|
11003
10691
|
await this.processBatch();
|
|
11004
10692
|
} catch (error) {
|
|
@@ -11065,8 +10753,7 @@ function createMemoryRuntimeService(deps) {
|
|
|
11065
10753
|
let graduationWorker = null;
|
|
11066
10754
|
return {
|
|
11067
10755
|
async initialize() {
|
|
11068
|
-
if (initialized)
|
|
11069
|
-
return;
|
|
10756
|
+
if (initialized) return;
|
|
11070
10757
|
await deps.sqliteStore.initialize();
|
|
11071
10758
|
if (deps.lightweightMode) {
|
|
11072
10759
|
initialized = true;
|
|
@@ -11160,8 +10847,7 @@ var SharedEventStore = class {
|
|
|
11160
10847
|
this.db = createDatabase(dbPath);
|
|
11161
10848
|
}
|
|
11162
10849
|
async initialize() {
|
|
11163
|
-
if (this.initialized)
|
|
11164
|
-
return;
|
|
10850
|
+
if (this.initialized) return;
|
|
11165
10851
|
await dbRun(this.db, `
|
|
11166
10852
|
CREATE TABLE IF NOT EXISTS shared_troubleshooting (
|
|
11167
10853
|
entry_id VARCHAR PRIMARY KEY,
|
|
@@ -11251,6 +10937,10 @@ var SharedPromoter = class {
|
|
|
11251
10937
|
this.embedder = embedder;
|
|
11252
10938
|
this.config = config;
|
|
11253
10939
|
}
|
|
10940
|
+
sharedStore;
|
|
10941
|
+
sharedVectorStore;
|
|
10942
|
+
embedder;
|
|
10943
|
+
config;
|
|
11254
10944
|
/**
|
|
11255
10945
|
* Check if an entry is eligible for promotion
|
|
11256
10946
|
*/
|
|
@@ -11432,6 +11122,7 @@ var SharedStore = class {
|
|
|
11432
11122
|
constructor(sharedEventStore) {
|
|
11433
11123
|
this.sharedEventStore = sharedEventStore;
|
|
11434
11124
|
}
|
|
11125
|
+
sharedEventStore;
|
|
11435
11126
|
get db() {
|
|
11436
11127
|
return this.sharedEventStore.getDatabase();
|
|
11437
11128
|
}
|
|
@@ -11536,8 +11227,7 @@ var SharedStore = class {
|
|
|
11536
11227
|
`SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
|
|
11537
11228
|
[entryId]
|
|
11538
11229
|
);
|
|
11539
|
-
if (rows.length === 0)
|
|
11540
|
-
return null;
|
|
11230
|
+
if (rows.length === 0) return null;
|
|
11541
11231
|
return this.rowToEntry(rows[0]);
|
|
11542
11232
|
}
|
|
11543
11233
|
/**
|
|
@@ -11550,8 +11240,7 @@ var SharedStore = class {
|
|
|
11550
11240
|
WHERE source_project_hash = ? AND source_entry_id = ?`,
|
|
11551
11241
|
[projectHash, sourceEntryId]
|
|
11552
11242
|
);
|
|
11553
|
-
if (rows.length === 0)
|
|
11554
|
-
return null;
|
|
11243
|
+
if (rows.length === 0) return null;
|
|
11555
11244
|
return this.rowToEntry(rows[0]);
|
|
11556
11245
|
}
|
|
11557
11246
|
/**
|
|
@@ -11661,6 +11350,7 @@ var SharedVectorStore = class {
|
|
|
11661
11350
|
constructor(dbPath) {
|
|
11662
11351
|
this.dbPath = dbPath;
|
|
11663
11352
|
}
|
|
11353
|
+
dbPath;
|
|
11664
11354
|
db = null;
|
|
11665
11355
|
table = null;
|
|
11666
11356
|
tableName = "shared_knowledge";
|
|
@@ -11668,8 +11358,7 @@ var SharedVectorStore = class {
|
|
|
11668
11358
|
* Initialize LanceDB connection
|
|
11669
11359
|
*/
|
|
11670
11360
|
async initialize() {
|
|
11671
|
-
if (this.db)
|
|
11672
|
-
return;
|
|
11361
|
+
if (this.db) return;
|
|
11673
11362
|
this.db = await lancedb2.connect(this.dbPath);
|
|
11674
11363
|
try {
|
|
11675
11364
|
const tables = await this.db.tableNames();
|
|
@@ -11711,8 +11400,7 @@ var SharedVectorStore = class {
|
|
|
11711
11400
|
* Add multiple records in batch
|
|
11712
11401
|
*/
|
|
11713
11402
|
async upsertBatch(records) {
|
|
11714
|
-
if (records.length === 0)
|
|
11715
|
-
return;
|
|
11403
|
+
if (records.length === 0) return;
|
|
11716
11404
|
await this.initialize();
|
|
11717
11405
|
if (!this.db) {
|
|
11718
11406
|
throw new Error("Database not initialized");
|
|
@@ -11773,24 +11461,21 @@ var SharedVectorStore = class {
|
|
|
11773
11461
|
* Delete vector by entry ID
|
|
11774
11462
|
*/
|
|
11775
11463
|
async delete(entryId) {
|
|
11776
|
-
if (!this.table)
|
|
11777
|
-
return;
|
|
11464
|
+
if (!this.table) return;
|
|
11778
11465
|
await this.table.delete(`entryId = '${entryId}'`);
|
|
11779
11466
|
}
|
|
11780
11467
|
/**
|
|
11781
11468
|
* Get total count
|
|
11782
11469
|
*/
|
|
11783
11470
|
async count() {
|
|
11784
|
-
if (!this.table)
|
|
11785
|
-
return 0;
|
|
11471
|
+
if (!this.table) return 0;
|
|
11786
11472
|
return this.table.countRows();
|
|
11787
11473
|
}
|
|
11788
11474
|
/**
|
|
11789
11475
|
* Check if vector exists for entry
|
|
11790
11476
|
*/
|
|
11791
11477
|
async exists(entryId) {
|
|
11792
|
-
if (!this.table)
|
|
11793
|
-
return false;
|
|
11478
|
+
if (!this.table) return false;
|
|
11794
11479
|
try {
|
|
11795
11480
|
const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
|
|
11796
11481
|
return results.length > 0;
|
|
@@ -11808,6 +11493,7 @@ var SharedMemoryServices = class {
|
|
|
11808
11493
|
constructor(options) {
|
|
11809
11494
|
this.options = options;
|
|
11810
11495
|
}
|
|
11496
|
+
options;
|
|
11811
11497
|
sharedEventStore = null;
|
|
11812
11498
|
sharedStore = null;
|
|
11813
11499
|
sharedVectorStore = null;
|
|
@@ -11832,8 +11518,7 @@ var SharedMemoryServices = class {
|
|
|
11832
11518
|
return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
|
|
11833
11519
|
}
|
|
11834
11520
|
async initialize() {
|
|
11835
|
-
if (this.options.config?.enabled === false || this.options.readOnly)
|
|
11836
|
-
return;
|
|
11521
|
+
if (this.options.config?.enabled === false || this.options.readOnly) return;
|
|
11837
11522
|
const sharedPath = this.getSharedStoragePath();
|
|
11838
11523
|
this.ensureDirectory(sharedPath, { allowCreate: true });
|
|
11839
11524
|
const store = await this.openStore(sharedPath);
|
|
@@ -11850,14 +11535,11 @@ var SharedMemoryServices = class {
|
|
|
11850
11535
|
this.options.retriever.setSharedStores(store, this.sharedVectorStore);
|
|
11851
11536
|
}
|
|
11852
11537
|
async ensureStoreForRead() {
|
|
11853
|
-
if (this.options.config?.enabled === false)
|
|
11854
|
-
|
|
11855
|
-
if (this.sharedStore)
|
|
11856
|
-
return this.sharedStore;
|
|
11538
|
+
if (this.options.config?.enabled === false) return null;
|
|
11539
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11857
11540
|
const sharedPath = this.getSharedStoragePath();
|
|
11858
11541
|
const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
|
|
11859
|
-
if (!directoryReady)
|
|
11860
|
-
return null;
|
|
11542
|
+
if (!directoryReady) return null;
|
|
11861
11543
|
return this.openStore(sharedPath);
|
|
11862
11544
|
}
|
|
11863
11545
|
async getEntryForDisclosure(entryId) {
|
|
@@ -11874,13 +11556,11 @@ var SharedMemoryServices = class {
|
|
|
11874
11556
|
return this.sharedPromoter.promoteEntry(entry, projectHash);
|
|
11875
11557
|
}
|
|
11876
11558
|
async getStats() {
|
|
11877
|
-
if (!this.sharedStore)
|
|
11878
|
-
return null;
|
|
11559
|
+
if (!this.sharedStore) return null;
|
|
11879
11560
|
return this.sharedStore.getStats();
|
|
11880
11561
|
}
|
|
11881
11562
|
async search(query, options) {
|
|
11882
|
-
if (!this.sharedStore)
|
|
11883
|
-
return [];
|
|
11563
|
+
if (!this.sharedStore) return [];
|
|
11884
11564
|
return this.sharedStore.search(query, options);
|
|
11885
11565
|
}
|
|
11886
11566
|
async close() {
|
|
@@ -11897,8 +11577,7 @@ var SharedMemoryServices = class {
|
|
|
11897
11577
|
this.openStorePromise = null;
|
|
11898
11578
|
}
|
|
11899
11579
|
async openStore(sharedPath) {
|
|
11900
|
-
if (this.sharedStore)
|
|
11901
|
-
return this.sharedStore;
|
|
11580
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11902
11581
|
if (!this.openStorePromise) {
|
|
11903
11582
|
this.openStorePromise = this.createOpenStorePromise(sharedPath);
|
|
11904
11583
|
}
|
|
@@ -11922,10 +11601,8 @@ var SharedMemoryServices = class {
|
|
|
11922
11601
|
return this.sharedStore;
|
|
11923
11602
|
}
|
|
11924
11603
|
ensureDirectory(sharedPath, options) {
|
|
11925
|
-
if (this.factories.existsSync(sharedPath))
|
|
11926
|
-
|
|
11927
|
-
if (!options.allowCreate)
|
|
11928
|
-
return false;
|
|
11604
|
+
if (this.factories.existsSync(sharedPath)) return true;
|
|
11605
|
+
if (!options.allowCreate) return false;
|
|
11929
11606
|
this.factories.mkdirSync(sharedPath);
|
|
11930
11607
|
return true;
|
|
11931
11608
|
}
|