claude-memory-layer 1.0.44 → 1.0.46
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/README.md +1 -0
- package/dist/cli/index.js +801 -1421
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +1319 -1501
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +465 -756
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +454 -734
- package/dist/hooks/semantic-daemon.js.map +2 -2
- package/dist/hooks/session-end.js +450 -726
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +451 -728
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +458 -742
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +494 -814
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/index.js +1397 -1615
- package/dist/index.js.map +4 -4
- package/dist/mcp/index.js +1587 -1655
- package/dist/mcp/index.js.map +4 -4
- package/dist/server/api/index.js +484 -792
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +492 -808
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +450 -726
- package/dist/services/memory-service.js.map +2 -2
- package/package.json +15 -3
|
@@ -50,6 +50,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
50
50
|
this.options = options;
|
|
51
51
|
this.fileSystem = options.fileSystem ?? defaultFileSystem;
|
|
52
52
|
}
|
|
53
|
+
options;
|
|
53
54
|
fileSystem;
|
|
54
55
|
getEmbeddingModelName() {
|
|
55
56
|
return this.options.getEmbeddingModelName();
|
|
@@ -84,8 +85,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
84
85
|
}
|
|
85
86
|
const worker = this.options.getVectorWorker();
|
|
86
87
|
const wasRunning = worker?.isRunning() || false;
|
|
87
|
-
if (wasRunning)
|
|
88
|
-
worker?.stop();
|
|
88
|
+
if (wasRunning) worker?.stop();
|
|
89
89
|
await this.options.vectorStore.clearAll();
|
|
90
90
|
await this.options.eventStore.clearEmbeddingOutbox();
|
|
91
91
|
const enqueued = await this.reenqueueAllEvents();
|
|
@@ -102,8 +102,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
102
102
|
2
|
|
103
103
|
)
|
|
104
104
|
);
|
|
105
|
-
if (wasRunning)
|
|
106
|
-
worker?.start();
|
|
105
|
+
if (wasRunning) worker?.start();
|
|
107
106
|
return {
|
|
108
107
|
changed: true,
|
|
109
108
|
previousModel,
|
|
@@ -128,15 +127,13 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
128
127
|
let enqueued = 0;
|
|
129
128
|
while (true) {
|
|
130
129
|
const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
|
|
131
|
-
if (page.length === 0)
|
|
132
|
-
break;
|
|
130
|
+
if (page.length === 0) break;
|
|
133
131
|
for (const event of page) {
|
|
134
132
|
await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
|
|
135
133
|
enqueued += 1;
|
|
136
134
|
}
|
|
137
135
|
offset += page.length;
|
|
138
|
-
if (page.length < DEFAULT_PAGE_SIZE)
|
|
139
|
-
break;
|
|
136
|
+
if (page.length < DEFAULT_PAGE_SIZE) break;
|
|
140
137
|
}
|
|
141
138
|
return enqueued;
|
|
142
139
|
}
|
|
@@ -154,12 +151,9 @@ import { randomUUID } from "crypto";
|
|
|
154
151
|
// src/core/db-wrapper.ts
|
|
155
152
|
import BetterSqlite3 from "better-sqlite3";
|
|
156
153
|
function toDate(value) {
|
|
157
|
-
if (value instanceof Date)
|
|
158
|
-
|
|
159
|
-
if (typeof value === "
|
|
160
|
-
return new Date(value);
|
|
161
|
-
if (typeof value === "number")
|
|
162
|
-
return new Date(value);
|
|
154
|
+
if (value instanceof Date) return value;
|
|
155
|
+
if (typeof value === "string") return new Date(value);
|
|
156
|
+
if (typeof value === "number") return new Date(value);
|
|
163
157
|
return new Date(String(value));
|
|
164
158
|
}
|
|
165
159
|
function createDatabase(dbPath, options) {
|
|
@@ -183,6 +177,8 @@ var WorkingSetStore = class {
|
|
|
183
177
|
this.eventStore = eventStore;
|
|
184
178
|
this.config = config;
|
|
185
179
|
}
|
|
180
|
+
eventStore;
|
|
181
|
+
config;
|
|
186
182
|
get db() {
|
|
187
183
|
return this.eventStore.getDatabase();
|
|
188
184
|
}
|
|
@@ -268,8 +264,7 @@ var WorkingSetStore = class {
|
|
|
268
264
|
* Prune specific events from working set (after consolidation)
|
|
269
265
|
*/
|
|
270
266
|
async prune(eventIds) {
|
|
271
|
-
if (eventIds.length === 0)
|
|
272
|
-
return;
|
|
267
|
+
if (eventIds.length === 0) return;
|
|
273
268
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
274
269
|
await dbRun(
|
|
275
270
|
this.db,
|
|
@@ -339,8 +334,7 @@ var WorkingSetStore = class {
|
|
|
339
334
|
LIMIT ?`,
|
|
340
335
|
[maxEvents]
|
|
341
336
|
);
|
|
342
|
-
if (keepIds.length === 0)
|
|
343
|
-
return;
|
|
337
|
+
if (keepIds.length === 0) return;
|
|
344
338
|
const keepIdList = keepIds.map((r) => r.id);
|
|
345
339
|
const placeholders = keepIdList.map(() => "?").join(",");
|
|
346
340
|
await dbRun(
|
|
@@ -387,6 +381,7 @@ var ConsolidatedStore = class {
|
|
|
387
381
|
constructor(eventStore) {
|
|
388
382
|
this.eventStore = eventStore;
|
|
389
383
|
}
|
|
384
|
+
eventStore;
|
|
390
385
|
get db() {
|
|
391
386
|
return this.eventStore.getDatabase();
|
|
392
387
|
}
|
|
@@ -419,8 +414,7 @@ var ConsolidatedStore = class {
|
|
|
419
414
|
`SELECT * FROM consolidated_memories WHERE memory_id = ?`,
|
|
420
415
|
[memoryId]
|
|
421
416
|
);
|
|
422
|
-
if (rows.length === 0)
|
|
423
|
-
return null;
|
|
417
|
+
if (rows.length === 0) return null;
|
|
424
418
|
return this.rowToMemory(rows[0]);
|
|
425
419
|
}
|
|
426
420
|
/**
|
|
@@ -638,8 +632,7 @@ var ConsolidatedStore = class {
|
|
|
638
632
|
WHERE source_events LIKE ?`,
|
|
639
633
|
[`%"${eventId}"%`]
|
|
640
634
|
);
|
|
641
|
-
if ((result[0]?.count || 0) > 0)
|
|
642
|
-
return true;
|
|
635
|
+
if ((result[0]?.count || 0) > 0) return true;
|
|
643
636
|
}
|
|
644
637
|
return false;
|
|
645
638
|
}
|
|
@@ -653,8 +646,7 @@ var ConsolidatedStore = class {
|
|
|
653
646
|
ORDER BY created_at DESC
|
|
654
647
|
LIMIT 1`
|
|
655
648
|
);
|
|
656
|
-
if (result.length === 0)
|
|
657
|
-
return null;
|
|
649
|
+
if (result.length === 0) return null;
|
|
658
650
|
return new Date(result[0].created_at);
|
|
659
651
|
}
|
|
660
652
|
/**
|
|
@@ -684,6 +676,9 @@ var ConsolidationWorker = class {
|
|
|
684
676
|
this.consolidatedStore = consolidatedStore;
|
|
685
677
|
this.config = config;
|
|
686
678
|
}
|
|
679
|
+
workingSetStore;
|
|
680
|
+
consolidatedStore;
|
|
681
|
+
config;
|
|
687
682
|
running = false;
|
|
688
683
|
timeout = null;
|
|
689
684
|
lastActivity = /* @__PURE__ */ new Date();
|
|
@@ -691,8 +686,7 @@ var ConsolidationWorker = class {
|
|
|
691
686
|
* Start the consolidation worker
|
|
692
687
|
*/
|
|
693
688
|
start() {
|
|
694
|
-
if (this.running)
|
|
695
|
-
return;
|
|
689
|
+
if (this.running) return;
|
|
696
690
|
this.running = true;
|
|
697
691
|
this.scheduleNext();
|
|
698
692
|
}
|
|
@@ -735,8 +729,7 @@ var ConsolidationWorker = class {
|
|
|
735
729
|
* Schedule the next consolidation check
|
|
736
730
|
*/
|
|
737
731
|
scheduleNext() {
|
|
738
|
-
if (!this.running)
|
|
739
|
-
return;
|
|
732
|
+
if (!this.running) return;
|
|
740
733
|
this.timeout = setTimeout(
|
|
741
734
|
() => this.run(),
|
|
742
735
|
this.config.consolidation.triggerIntervalMs
|
|
@@ -746,8 +739,7 @@ var ConsolidationWorker = class {
|
|
|
746
739
|
* Run consolidation check
|
|
747
740
|
*/
|
|
748
741
|
async run() {
|
|
749
|
-
if (!this.running)
|
|
750
|
-
return;
|
|
742
|
+
if (!this.running) return;
|
|
751
743
|
try {
|
|
752
744
|
await this.checkAndConsolidate();
|
|
753
745
|
} catch (error) {
|
|
@@ -785,12 +777,10 @@ var ConsolidationWorker = class {
|
|
|
785
777
|
let consolidatedCount = 0;
|
|
786
778
|
const createdMemoryIds = [];
|
|
787
779
|
for (const group of groups) {
|
|
788
|
-
if (group.events.length < 3)
|
|
789
|
-
continue;
|
|
780
|
+
if (group.events.length < 3) continue;
|
|
790
781
|
const eventIds = group.events.map((e) => e.id);
|
|
791
782
|
const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
|
|
792
|
-
if (alreadyConsolidated)
|
|
793
|
-
continue;
|
|
783
|
+
if (alreadyConsolidated) continue;
|
|
794
784
|
const summary = await this.summarize(group);
|
|
795
785
|
const memoryId = await this.consolidatedStore.create({
|
|
796
786
|
summary,
|
|
@@ -806,8 +796,7 @@ var ConsolidationWorker = class {
|
|
|
806
796
|
const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
|
|
807
797
|
const oldEventIds = consolidatedEventIds.filter((id) => {
|
|
808
798
|
const event = workingSet.recentEvents.find((e) => e.id === id);
|
|
809
|
-
if (!event)
|
|
810
|
-
return false;
|
|
799
|
+
if (!event) return false;
|
|
811
800
|
const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
|
|
812
801
|
return ageHours > this.config.workingSet.timeWindowHours / 2;
|
|
813
802
|
});
|
|
@@ -822,18 +811,13 @@ var ConsolidationWorker = class {
|
|
|
822
811
|
let promoted = 0;
|
|
823
812
|
for (const memoryId of memoryIds) {
|
|
824
813
|
const memory = await this.consolidatedStore.get(memoryId);
|
|
825
|
-
if (!memory)
|
|
826
|
-
|
|
827
|
-
if (memory.
|
|
828
|
-
continue;
|
|
829
|
-
if (memory.sourceEvents.length < 4)
|
|
830
|
-
continue;
|
|
814
|
+
if (!memory) continue;
|
|
815
|
+
if (memory.confidence < 0.55) continue;
|
|
816
|
+
if (memory.sourceEvents.length < 4) continue;
|
|
831
817
|
const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
|
|
832
|
-
if (exists)
|
|
833
|
-
continue;
|
|
818
|
+
if (exists) continue;
|
|
834
819
|
const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
|
|
835
|
-
if (!rule)
|
|
836
|
-
continue;
|
|
820
|
+
if (!rule) continue;
|
|
837
821
|
await this.consolidatedStore.createRule({
|
|
838
822
|
rule,
|
|
839
823
|
topics: memory.topics,
|
|
@@ -849,8 +833,7 @@ var ConsolidationWorker = class {
|
|
|
849
833
|
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
|
|
850
834
|
const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
|
|
851
835
|
const seed = bullet || lines[0];
|
|
852
|
-
if (!seed || seed.length < 8)
|
|
853
|
-
return null;
|
|
836
|
+
if (!seed || seed.length < 8) return null;
|
|
854
837
|
const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
|
|
855
838
|
return `${topicPrefix}${seed}`;
|
|
856
839
|
}
|
|
@@ -1011,8 +994,7 @@ var ConsolidationWorker = class {
|
|
|
1011
994
|
*/
|
|
1012
995
|
extractKeyPoint(content) {
|
|
1013
996
|
const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
|
|
1014
|
-
if (sentences.length === 0)
|
|
1015
|
-
return null;
|
|
997
|
+
if (sentences.length === 0) return null;
|
|
1016
998
|
const firstSentence = sentences[0].trim();
|
|
1017
999
|
if (firstSentence.length > 100) {
|
|
1018
1000
|
return firstSentence.slice(0, 100) + "...";
|
|
@@ -1032,8 +1014,7 @@ var ConsolidationWorker = class {
|
|
|
1032
1014
|
* Calculate time proximity score
|
|
1033
1015
|
*/
|
|
1034
1016
|
calculateTimeProximity(events) {
|
|
1035
|
-
if (events.length < 2)
|
|
1036
|
-
return 1;
|
|
1017
|
+
if (events.length < 2) return 1;
|
|
1037
1018
|
const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
|
|
1038
1019
|
const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
|
|
1039
1020
|
const avgGap = timeSpan / (events.length - 1);
|
|
@@ -1052,6 +1033,8 @@ var ContinuityManager = class {
|
|
|
1052
1033
|
this.eventStore = eventStore;
|
|
1053
1034
|
this.config = config;
|
|
1054
1035
|
}
|
|
1036
|
+
eventStore;
|
|
1037
|
+
config;
|
|
1055
1038
|
lastContext = null;
|
|
1056
1039
|
get db() {
|
|
1057
1040
|
return this.eventStore.getDatabase();
|
|
@@ -1171,8 +1154,7 @@ var ContinuityManager = class {
|
|
|
1171
1154
|
* Calculate overlap between two arrays
|
|
1172
1155
|
*/
|
|
1173
1156
|
calculateOverlap(a, b) {
|
|
1174
|
-
if (a.length === 0 || b.length === 0)
|
|
1175
|
-
return 0;
|
|
1157
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
1176
1158
|
const setA = new Set(a.map((s) => s.toLowerCase()));
|
|
1177
1159
|
const setB = new Set(b.map((s) => s.toLowerCase()));
|
|
1178
1160
|
const intersection = [...setA].filter((x) => setB.has(x));
|
|
@@ -1345,6 +1327,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1345
1327
|
this.options = options;
|
|
1346
1328
|
this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
|
|
1347
1329
|
}
|
|
1330
|
+
options;
|
|
1348
1331
|
factories;
|
|
1349
1332
|
workingSetStore = null;
|
|
1350
1333
|
consolidatedStore = null;
|
|
@@ -1359,8 +1342,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1359
1342
|
}
|
|
1360
1343
|
}
|
|
1361
1344
|
async initializeEndlessMode() {
|
|
1362
|
-
if (this.consolidationWorker)
|
|
1363
|
-
return;
|
|
1345
|
+
if (this.consolidationWorker) return;
|
|
1364
1346
|
const config = await this.getEndlessConfig();
|
|
1365
1347
|
const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
|
|
1366
1348
|
const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
|
|
@@ -1392,8 +1374,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1392
1374
|
}
|
|
1393
1375
|
async setMode(mode) {
|
|
1394
1376
|
await this.options.initialize();
|
|
1395
|
-
if (mode === this.mode)
|
|
1396
|
-
return;
|
|
1377
|
+
if (mode === this.mode) return;
|
|
1397
1378
|
this.mode = mode;
|
|
1398
1379
|
await this.options.configStore.setEndlessConfig("mode", mode);
|
|
1399
1380
|
if (mode === "endless") {
|
|
@@ -1409,33 +1390,27 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1409
1390
|
return this.mode === "endless";
|
|
1410
1391
|
}
|
|
1411
1392
|
async addToWorkingSet(eventId, relevanceScore) {
|
|
1412
|
-
if (!this.workingSetStore)
|
|
1413
|
-
return;
|
|
1393
|
+
if (!this.workingSetStore) return;
|
|
1414
1394
|
await this.workingSetStore.add(eventId, relevanceScore);
|
|
1415
1395
|
}
|
|
1416
1396
|
async getWorkingSet() {
|
|
1417
|
-
if (!this.workingSetStore)
|
|
1418
|
-
return null;
|
|
1397
|
+
if (!this.workingSetStore) return null;
|
|
1419
1398
|
return this.workingSetStore.get();
|
|
1420
1399
|
}
|
|
1421
1400
|
async searchConsolidated(query, options) {
|
|
1422
|
-
if (!this.consolidatedStore)
|
|
1423
|
-
return [];
|
|
1401
|
+
if (!this.consolidatedStore) return [];
|
|
1424
1402
|
return this.consolidatedStore.search(query, options);
|
|
1425
1403
|
}
|
|
1426
1404
|
async getConsolidatedMemories(limit) {
|
|
1427
|
-
if (!this.consolidatedStore)
|
|
1428
|
-
return [];
|
|
1405
|
+
if (!this.consolidatedStore) return [];
|
|
1429
1406
|
return this.consolidatedStore.getAll({ limit });
|
|
1430
1407
|
}
|
|
1431
1408
|
async markMemoryAccessed(memoryId) {
|
|
1432
|
-
if (!this.consolidatedStore)
|
|
1433
|
-
return;
|
|
1409
|
+
if (!this.consolidatedStore) return;
|
|
1434
1410
|
await this.consolidatedStore.markAccessed(memoryId);
|
|
1435
1411
|
}
|
|
1436
1412
|
async calculateContinuity(content, metadata) {
|
|
1437
|
-
if (!this.continuityManager)
|
|
1438
|
-
return null;
|
|
1413
|
+
if (!this.continuityManager) return null;
|
|
1439
1414
|
const snapshot = this.continuityManager.createSnapshot(
|
|
1440
1415
|
this.factories.randomUUID(),
|
|
1441
1416
|
content,
|
|
@@ -1447,8 +1422,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1447
1422
|
this.consolidationWorker?.recordActivity();
|
|
1448
1423
|
}
|
|
1449
1424
|
async forceConsolidation() {
|
|
1450
|
-
if (!this.consolidationWorker)
|
|
1451
|
-
return 0;
|
|
1425
|
+
if (!this.consolidationWorker) return 0;
|
|
1452
1426
|
return this.consolidationWorker.forceRun();
|
|
1453
1427
|
}
|
|
1454
1428
|
async getEndlessModeStatus() {
|
|
@@ -1540,8 +1514,7 @@ var Embedder = class _Embedder {
|
|
|
1540
1514
|
* Initialize the embedding pipeline
|
|
1541
1515
|
*/
|
|
1542
1516
|
async initialize() {
|
|
1543
|
-
if (this.initialized)
|
|
1544
|
-
return;
|
|
1517
|
+
if (this.initialized) return;
|
|
1545
1518
|
const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
|
|
1546
1519
|
try {
|
|
1547
1520
|
return await loadTransformersPipeline();
|
|
@@ -1658,8 +1631,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
|
|
|
1658
1631
|
originalConsoleWarn = console.warn;
|
|
1659
1632
|
console.warn = (...args) => {
|
|
1660
1633
|
const message = args.map(String).join(" ");
|
|
1661
|
-
if (isKnownBenignTransformersWarning(message))
|
|
1662
|
-
return;
|
|
1634
|
+
if (isKnownBenignTransformersWarning(message)) return;
|
|
1663
1635
|
(originalConsoleWarn ?? console.warn)(...args);
|
|
1664
1636
|
};
|
|
1665
1637
|
}
|
|
@@ -1941,8 +1913,7 @@ var GraduationPipeline = class {
|
|
|
1941
1913
|
const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
|
|
1942
1914
|
const preferences = [];
|
|
1943
1915
|
for (const event of events) {
|
|
1944
|
-
if (event.eventType !== "user_prompt")
|
|
1945
|
-
continue;
|
|
1916
|
+
if (event.eventType !== "user_prompt") continue;
|
|
1946
1917
|
const lowerContent = event.content.toLowerCase();
|
|
1947
1918
|
for (const keyword of preferenceKeywords) {
|
|
1948
1919
|
if (lowerContent.includes(keyword)) {
|
|
@@ -2108,11 +2079,9 @@ function sanitizeSegment(input, fallback) {
|
|
|
2108
2079
|
return v || fallback;
|
|
2109
2080
|
}
|
|
2110
2081
|
function getAtPath(obj, dotted) {
|
|
2111
|
-
if (!obj)
|
|
2112
|
-
return void 0;
|
|
2082
|
+
if (!obj) return void 0;
|
|
2113
2083
|
return dotted.split(".").reduce((acc, key) => {
|
|
2114
|
-
if (!acc || typeof acc !== "object")
|
|
2115
|
-
return void 0;
|
|
2084
|
+
if (!acc || typeof acc !== "object") return void 0;
|
|
2116
2085
|
return acc[key];
|
|
2117
2086
|
}, obj);
|
|
2118
2087
|
}
|
|
@@ -2132,6 +2101,7 @@ var MarkdownMirror = class {
|
|
|
2132
2101
|
constructor(rootDir) {
|
|
2133
2102
|
this.rootDir = rootDir;
|
|
2134
2103
|
}
|
|
2104
|
+
rootDir;
|
|
2135
2105
|
async append(event, eventId) {
|
|
2136
2106
|
const out = buildMirrorPath(this.rootDir, event);
|
|
2137
2107
|
fs2.mkdirSync(path2.dirname(out), { recursive: true });
|
|
@@ -2263,10 +2233,8 @@ function sqliteClose(db) {
|
|
|
2263
2233
|
db.close();
|
|
2264
2234
|
}
|
|
2265
2235
|
function toDateFromSQLite(value) {
|
|
2266
|
-
if (value instanceof Date)
|
|
2267
|
-
|
|
2268
|
-
if (typeof value === "number")
|
|
2269
|
-
return new Date(value);
|
|
2236
|
+
if (value instanceof Date) return value;
|
|
2237
|
+
if (typeof value === "number") return new Date(value);
|
|
2270
2238
|
if (typeof value === "string") {
|
|
2271
2239
|
const trimmed = value.trim();
|
|
2272
2240
|
if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
|
|
@@ -2288,8 +2256,7 @@ var DEFAULT_CATEGORY = "uncategorized";
|
|
|
2288
2256
|
function sanitizeSegment2(input, fallback) {
|
|
2289
2257
|
const raw = String(input ?? "").trim().toLowerCase();
|
|
2290
2258
|
const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2291
|
-
if (!safe || safe === "." || safe === "..")
|
|
2292
|
-
return fallback;
|
|
2259
|
+
if (!safe || safe === "." || safe === "..") return fallback;
|
|
2293
2260
|
return safe;
|
|
2294
2261
|
}
|
|
2295
2262
|
function getCategorySegments(metadata, eventType) {
|
|
@@ -2330,6 +2297,7 @@ var MarkdownMirror2 = class {
|
|
|
2330
2297
|
constructor(rootDir) {
|
|
2331
2298
|
this.rootDir = rootDir;
|
|
2332
2299
|
}
|
|
2300
|
+
rootDir;
|
|
2333
2301
|
async append(event) {
|
|
2334
2302
|
const outPath = buildMirrorPath2(this.rootDir, event);
|
|
2335
2303
|
await fs5.mkdir(path4.dirname(outPath), { recursive: true });
|
|
@@ -2352,6 +2320,7 @@ var VectorOutbox = class {
|
|
|
2352
2320
|
this.db = db;
|
|
2353
2321
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
2354
2322
|
}
|
|
2323
|
+
db;
|
|
2355
2324
|
config;
|
|
2356
2325
|
/**
|
|
2357
2326
|
* Enqueue item for vectorization (idempotent).
|
|
@@ -2448,8 +2417,7 @@ var VectorOutbox = class {
|
|
|
2448
2417
|
`SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
|
|
2449
2418
|
[jobId]
|
|
2450
2419
|
);
|
|
2451
|
-
if (rows.length === 0)
|
|
2452
|
-
return;
|
|
2420
|
+
if (rows.length === 0) return;
|
|
2453
2421
|
const retryCount = rows[0].retry_count;
|
|
2454
2422
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
2455
2423
|
await dbRun(
|
|
@@ -2469,8 +2437,7 @@ var VectorOutbox = class {
|
|
|
2469
2437
|
`SELECT * FROM vector_outbox WHERE job_id = ?`,
|
|
2470
2438
|
[jobId]
|
|
2471
2439
|
);
|
|
2472
|
-
if (rows.length === 0)
|
|
2473
|
-
return null;
|
|
2440
|
+
if (rows.length === 0) return null;
|
|
2474
2441
|
return this.rowToJob(rows[0]);
|
|
2475
2442
|
}
|
|
2476
2443
|
/**
|
|
@@ -2604,30 +2571,24 @@ function isRetrievalDebugLaneName(value) {
|
|
|
2604
2571
|
return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
|
|
2605
2572
|
}
|
|
2606
2573
|
function normalizeRetrievalDebugLanes(value, maxItems = 6) {
|
|
2607
|
-
if (!Array.isArray(value) || maxItems <= 0)
|
|
2608
|
-
return [];
|
|
2574
|
+
if (!Array.isArray(value) || maxItems <= 0) return [];
|
|
2609
2575
|
const normalized = [];
|
|
2610
2576
|
const seen = /* @__PURE__ */ new Set();
|
|
2611
2577
|
for (const item of value) {
|
|
2612
2578
|
const lane = normalizeRetrievalDebugLane(item);
|
|
2613
|
-
if (!lane)
|
|
2614
|
-
continue;
|
|
2579
|
+
if (!lane) continue;
|
|
2615
2580
|
const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
|
|
2616
|
-
if (seen.has(key))
|
|
2617
|
-
continue;
|
|
2581
|
+
if (seen.has(key)) continue;
|
|
2618
2582
|
seen.add(key);
|
|
2619
2583
|
normalized.push(lane);
|
|
2620
|
-
if (normalized.length >= maxItems)
|
|
2621
|
-
break;
|
|
2584
|
+
if (normalized.length >= maxItems) break;
|
|
2622
2585
|
}
|
|
2623
2586
|
return normalized;
|
|
2624
2587
|
}
|
|
2625
2588
|
function normalizeRetrievalDebugLane(value) {
|
|
2626
|
-
if (!value || typeof value !== "object")
|
|
2627
|
-
return null;
|
|
2589
|
+
if (!value || typeof value !== "object") return null;
|
|
2628
2590
|
const raw = value;
|
|
2629
|
-
if (!isRetrievalDebugLaneName(raw.lane))
|
|
2630
|
-
return null;
|
|
2591
|
+
if (!isRetrievalDebugLaneName(raw.lane)) return null;
|
|
2631
2592
|
const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
|
|
2632
2593
|
const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
|
|
2633
2594
|
return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
|
|
@@ -2650,27 +2611,21 @@ function normalizeRetrievalTraceDetails(details) {
|
|
|
2650
2611
|
eventId: detail.eventId,
|
|
2651
2612
|
score: detail.score
|
|
2652
2613
|
};
|
|
2653
|
-
if (detail.semanticScore !== void 0)
|
|
2654
|
-
|
|
2655
|
-
if (detail.
|
|
2656
|
-
|
|
2657
|
-
if (detail.recencyScore !== void 0)
|
|
2658
|
-
normalized.recencyScore = detail.recencyScore;
|
|
2659
|
-
if (lanes.length > 0)
|
|
2660
|
-
normalized.lanes = lanes;
|
|
2614
|
+
if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
|
|
2615
|
+
if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
|
|
2616
|
+
if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
|
|
2617
|
+
if (lanes.length > 0) normalized.lanes = lanes;
|
|
2661
2618
|
return normalized;
|
|
2662
2619
|
});
|
|
2663
2620
|
}
|
|
2664
2621
|
function parseRetrievalTraceDetails(value) {
|
|
2665
|
-
if (typeof value !== "string" || value.length === 0)
|
|
2666
|
-
return [];
|
|
2622
|
+
if (typeof value !== "string" || value.length === 0) return [];
|
|
2667
2623
|
const parsed = JSON.parse(value);
|
|
2668
2624
|
return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
|
|
2669
2625
|
}
|
|
2670
2626
|
function normalizeQueryRewriteKind(value) {
|
|
2671
2627
|
const normalized = (value || "").trim().toLowerCase();
|
|
2672
|
-
if (normalized === "follow-up-context" || normalized === "intent-rewrite")
|
|
2673
|
-
return normalized;
|
|
2628
|
+
if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
|
|
2674
2629
|
return "none";
|
|
2675
2630
|
}
|
|
2676
2631
|
var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
|
|
@@ -2688,8 +2643,7 @@ function isRecord(value) {
|
|
|
2688
2643
|
function getNestedRecord(root, path11) {
|
|
2689
2644
|
let cursor = root;
|
|
2690
2645
|
for (const key of path11) {
|
|
2691
|
-
if (!isRecord(cursor))
|
|
2692
|
-
return void 0;
|
|
2646
|
+
if (!isRecord(cursor)) return void 0;
|
|
2693
2647
|
cursor = cursor[key];
|
|
2694
2648
|
}
|
|
2695
2649
|
return isRecord(cursor) ? cursor : void 0;
|
|
@@ -2697,8 +2651,7 @@ function getNestedRecord(root, path11) {
|
|
|
2697
2651
|
function getNestedString(root, path11) {
|
|
2698
2652
|
let cursor = root;
|
|
2699
2653
|
for (const key of path11) {
|
|
2700
|
-
if (!isRecord(cursor))
|
|
2701
|
-
return void 0;
|
|
2654
|
+
if (!isRecord(cursor)) return void 0;
|
|
2702
2655
|
cursor = cursor[key];
|
|
2703
2656
|
}
|
|
2704
2657
|
return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
|
|
@@ -2714,8 +2667,7 @@ function metadataProjectPaths(metadata) {
|
|
|
2714
2667
|
];
|
|
2715
2668
|
const paths = [];
|
|
2716
2669
|
for (const value of candidates) {
|
|
2717
|
-
if (value && !paths.includes(value))
|
|
2718
|
-
paths.push(value);
|
|
2670
|
+
if (value && !paths.includes(value)) paths.push(value);
|
|
2719
2671
|
}
|
|
2720
2672
|
return paths;
|
|
2721
2673
|
}
|
|
@@ -2736,12 +2688,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
|
|
|
2736
2688
|
return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
|
|
2737
2689
|
}
|
|
2738
2690
|
function safeParseMetadataValue(value) {
|
|
2739
|
-
if (!value)
|
|
2740
|
-
|
|
2741
|
-
if (typeof value
|
|
2742
|
-
return isRecord(value) ? value : void 0;
|
|
2743
|
-
if (typeof value !== "string")
|
|
2744
|
-
return void 0;
|
|
2691
|
+
if (!value) return void 0;
|
|
2692
|
+
if (typeof value === "object") return isRecord(value) ? value : void 0;
|
|
2693
|
+
if (typeof value !== "string") return void 0;
|
|
2745
2694
|
try {
|
|
2746
2695
|
const parsed = JSON.parse(value);
|
|
2747
2696
|
return isRecord(parsed) ? parsed : void 0;
|
|
@@ -2750,16 +2699,14 @@ function safeParseMetadataValue(value) {
|
|
|
2750
2699
|
}
|
|
2751
2700
|
}
|
|
2752
2701
|
function isImportedOrLegacyScopedMetadata(metadata) {
|
|
2753
|
-
if (!metadata)
|
|
2754
|
-
return false;
|
|
2702
|
+
if (!metadata) return false;
|
|
2755
2703
|
return Boolean(
|
|
2756
2704
|
metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
|
|
2757
2705
|
);
|
|
2758
2706
|
}
|
|
2759
2707
|
function addMetadataTag(metadata, tag) {
|
|
2760
2708
|
const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
|
|
2761
|
-
if (!current.includes(tag))
|
|
2762
|
-
metadata.tags = [...current, tag];
|
|
2709
|
+
if (!current.includes(tag)) metadata.tags = [...current, tag];
|
|
2763
2710
|
}
|
|
2764
2711
|
function buildRepairResult(projectHash, dryRun) {
|
|
2765
2712
|
return {
|
|
@@ -2777,8 +2724,7 @@ function normalizeRepoName(value) {
|
|
|
2777
2724
|
return value.replace(/\.git$/i, "").trim().toLowerCase();
|
|
2778
2725
|
}
|
|
2779
2726
|
function projectBasename(projectPath) {
|
|
2780
|
-
if (!projectPath)
|
|
2781
|
-
return void 0;
|
|
2727
|
+
if (!projectPath) return void 0;
|
|
2782
2728
|
const trimmed = projectPath.replace(/[\\/]+$/, "");
|
|
2783
2729
|
const basename2 = nodePath2.basename(trimmed);
|
|
2784
2730
|
return basename2 ? normalizeRepoName(basename2) : void 0;
|
|
@@ -2791,23 +2737,19 @@ function isProjectScopeRepairExplanation(content) {
|
|
|
2791
2737
|
}
|
|
2792
2738
|
function hasConflictingContentProjectHint(content, projectPath) {
|
|
2793
2739
|
const currentName = projectBasename(projectPath);
|
|
2794
|
-
if (!currentName)
|
|
2795
|
-
|
|
2796
|
-
if (isProjectScopeRepairExplanation(content))
|
|
2797
|
-
return false;
|
|
2740
|
+
if (!currentName) return false;
|
|
2741
|
+
if (isProjectScopeRepairExplanation(content)) return false;
|
|
2798
2742
|
const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
|
|
2799
2743
|
let githubMatch;
|
|
2800
2744
|
while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
|
|
2801
2745
|
const repo = normalizeRepoName(githubMatch[2] || "");
|
|
2802
|
-
if (repo && repo !== currentName)
|
|
2803
|
-
return true;
|
|
2746
|
+
if (repo && repo !== currentName) return true;
|
|
2804
2747
|
}
|
|
2805
2748
|
const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
|
|
2806
2749
|
let workspaceMatch;
|
|
2807
2750
|
while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
|
|
2808
2751
|
const repo = normalizeRepoName(workspaceMatch[1] || "");
|
|
2809
|
-
if (repo && repo !== currentName)
|
|
2810
|
-
return true;
|
|
2752
|
+
if (repo && repo !== currentName) return true;
|
|
2811
2753
|
}
|
|
2812
2754
|
return false;
|
|
2813
2755
|
}
|
|
@@ -2827,15 +2769,12 @@ var SQLiteEventStore = class {
|
|
|
2827
2769
|
this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
|
|
2828
2770
|
}
|
|
2829
2771
|
createVectorOutbox(option) {
|
|
2830
|
-
if (this.readOnly || option === false)
|
|
2831
|
-
|
|
2832
|
-
if (option instanceof VectorOutbox)
|
|
2833
|
-
return option;
|
|
2772
|
+
if (this.readOnly || option === false) return null;
|
|
2773
|
+
if (option instanceof VectorOutbox) return option;
|
|
2834
2774
|
return new VectorOutbox(this.db, option ?? {});
|
|
2835
2775
|
}
|
|
2836
2776
|
enqueueVectorOutboxEventSync(eventId) {
|
|
2837
|
-
if (!this.vectorOutbox)
|
|
2838
|
-
return;
|
|
2777
|
+
if (!this.vectorOutbox) return;
|
|
2839
2778
|
this.vectorOutbox.enqueueSync("event", eventId);
|
|
2840
2779
|
}
|
|
2841
2780
|
async enqueueVectorOutboxEvent(eventId) {
|
|
@@ -2845,8 +2784,7 @@ var SQLiteEventStore = class {
|
|
|
2845
2784
|
* Initialize database schema
|
|
2846
2785
|
*/
|
|
2847
2786
|
async initialize() {
|
|
2848
|
-
if (this.initialized)
|
|
2849
|
-
return;
|
|
2787
|
+
if (this.initialized) return;
|
|
2850
2788
|
if (this.readOnly) {
|
|
2851
2789
|
this.initialized = true;
|
|
2852
2790
|
return;
|
|
@@ -3404,10 +3342,8 @@ var SQLiteEventStore = class {
|
|
|
3404
3342
|
try {
|
|
3405
3343
|
const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
|
|
3406
3344
|
const hasSourceAwareUnique = edgeIndexes.some((index) => {
|
|
3407
|
-
if (Number(index.unique) !== 1)
|
|
3408
|
-
|
|
3409
|
-
if (!/^[A-Za-z0-9_]+$/.test(index.name))
|
|
3410
|
-
return false;
|
|
3345
|
+
if (Number(index.unique) !== 1) return false;
|
|
3346
|
+
if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
|
|
3411
3347
|
const escapedName = index.name.replace(/"/g, '""');
|
|
3412
3348
|
const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
|
|
3413
3349
|
return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
|
|
@@ -3647,8 +3583,7 @@ var SQLiteEventStore = class {
|
|
|
3647
3583
|
`SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
|
|
3648
3584
|
[id]
|
|
3649
3585
|
);
|
|
3650
|
-
if (!row)
|
|
3651
|
-
return null;
|
|
3586
|
+
if (!row) return null;
|
|
3652
3587
|
return this.rowToEvent(row);
|
|
3653
3588
|
}
|
|
3654
3589
|
/**
|
|
@@ -3686,10 +3621,8 @@ var SQLiteEventStore = class {
|
|
|
3686
3621
|
* NOTE: This bypasses the append() id generation to preserve stable IDs.
|
|
3687
3622
|
*/
|
|
3688
3623
|
async importEvents(events) {
|
|
3689
|
-
if (events.length === 0)
|
|
3690
|
-
|
|
3691
|
-
if (this.readOnly)
|
|
3692
|
-
return { inserted: 0, skipped: events.length };
|
|
3624
|
+
if (events.length === 0) return { inserted: 0, skipped: 0 };
|
|
3625
|
+
if (this.readOnly) return { inserted: 0, skipped: events.length };
|
|
3693
3626
|
await this.initialize();
|
|
3694
3627
|
const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
|
|
3695
3628
|
const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
|
|
@@ -3807,8 +3740,7 @@ var SQLiteEventStore = class {
|
|
|
3807
3740
|
`SELECT * FROM sessions WHERE id = ?`,
|
|
3808
3741
|
[id]
|
|
3809
3742
|
);
|
|
3810
|
-
if (!row)
|
|
3811
|
-
return null;
|
|
3743
|
+
if (!row) return null;
|
|
3812
3744
|
return {
|
|
3813
3745
|
id: row.id,
|
|
3814
3746
|
startedAt: toDateFromSQLite(row.started_at),
|
|
@@ -3863,8 +3795,7 @@ var SQLiteEventStore = class {
|
|
|
3863
3795
|
LIMIT ?`,
|
|
3864
3796
|
[limit]
|
|
3865
3797
|
);
|
|
3866
|
-
if (pending.length === 0)
|
|
3867
|
-
return [];
|
|
3798
|
+
if (pending.length === 0) return [];
|
|
3868
3799
|
const ids = pending.map((r) => r.id);
|
|
3869
3800
|
const placeholders = ids.map(() => "?").join(",");
|
|
3870
3801
|
sqliteRun(
|
|
@@ -3888,8 +3819,7 @@ var SQLiteEventStore = class {
|
|
|
3888
3819
|
* Mark outbox items as done
|
|
3889
3820
|
*/
|
|
3890
3821
|
async completeOutboxItems(ids) {
|
|
3891
|
-
if (ids.length === 0)
|
|
3892
|
-
return;
|
|
3822
|
+
if (ids.length === 0) return;
|
|
3893
3823
|
const placeholders = ids.map(() => "?").join(",");
|
|
3894
3824
|
sqliteRun(
|
|
3895
3825
|
this.db,
|
|
@@ -3928,8 +3858,7 @@ var SQLiteEventStore = class {
|
|
|
3928
3858
|
* Mark outbox items as failed
|
|
3929
3859
|
*/
|
|
3930
3860
|
async failOutboxItems(ids, error) {
|
|
3931
|
-
if (ids.length === 0)
|
|
3932
|
-
return;
|
|
3861
|
+
if (ids.length === 0) return;
|
|
3933
3862
|
const placeholders = ids.map(() => "?").join(",");
|
|
3934
3863
|
sqliteRun(
|
|
3935
3864
|
this.db,
|
|
@@ -4056,8 +3985,7 @@ var SQLiteEventStore = class {
|
|
|
4056
3985
|
[]
|
|
4057
3986
|
);
|
|
4058
3987
|
const sample = (entry) => {
|
|
4059
|
-
if (result.samples.length < 20)
|
|
4060
|
-
result.samples.push(entry);
|
|
3988
|
+
if (result.samples.length < 20) result.samples.push(entry);
|
|
4061
3989
|
};
|
|
4062
3990
|
for (const row of rows) {
|
|
4063
3991
|
result.scanned++;
|
|
@@ -4184,12 +4112,10 @@ var SQLiteEventStore = class {
|
|
|
4184
4112
|
`SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
|
|
4185
4113
|
);
|
|
4186
4114
|
const processingAgeMs = (value) => {
|
|
4187
|
-
if (value === null || value === void 0)
|
|
4188
|
-
return null;
|
|
4115
|
+
if (value === null || value === void 0) return null;
|
|
4189
4116
|
const date = toDateFromSQLite(value);
|
|
4190
4117
|
const time = date.getTime();
|
|
4191
|
-
if (!Number.isFinite(time))
|
|
4192
|
-
return null;
|
|
4118
|
+
if (!Number.isFinite(time)) return null;
|
|
4193
4119
|
return Math.max(0, now.getTime() - time);
|
|
4194
4120
|
};
|
|
4195
4121
|
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
|
|
@@ -4338,8 +4264,7 @@ var SQLiteEventStore = class {
|
|
|
4338
4264
|
`SELECT value FROM endless_config WHERE key = ?`,
|
|
4339
4265
|
[key]
|
|
4340
4266
|
);
|
|
4341
|
-
if (!row)
|
|
4342
|
-
return null;
|
|
4267
|
+
if (!row) return null;
|
|
4343
4268
|
return JSON.parse(row.value);
|
|
4344
4269
|
}
|
|
4345
4270
|
/**
|
|
@@ -4358,8 +4283,7 @@ var SQLiteEventStore = class {
|
|
|
4358
4283
|
* Increment access count for events
|
|
4359
4284
|
*/
|
|
4360
4285
|
async incrementAccessCount(eventIds) {
|
|
4361
|
-
if (eventIds.length === 0 || this.readOnly)
|
|
4362
|
-
return;
|
|
4286
|
+
if (eventIds.length === 0 || this.readOnly) return;
|
|
4363
4287
|
await this.initialize();
|
|
4364
4288
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4365
4289
|
const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -4402,8 +4326,7 @@ var SQLiteEventStore = class {
|
|
|
4402
4326
|
* Record a memory retrieval for helpfulness tracking
|
|
4403
4327
|
*/
|
|
4404
4328
|
async recordRetrieval(eventId, sessionId, score, query) {
|
|
4405
|
-
if (this.readOnly)
|
|
4406
|
-
return;
|
|
4329
|
+
if (this.readOnly) return;
|
|
4407
4330
|
await this.initialize();
|
|
4408
4331
|
const id = randomUUID6();
|
|
4409
4332
|
sqliteRun(
|
|
@@ -4433,16 +4356,14 @@ var SQLiteEventStore = class {
|
|
|
4433
4356
|
* Called at session end - uses behavioral signals to compute score
|
|
4434
4357
|
*/
|
|
4435
4358
|
async evaluateSessionHelpfulness(sessionId) {
|
|
4436
|
-
if (this.readOnly)
|
|
4437
|
-
return;
|
|
4359
|
+
if (this.readOnly) return;
|
|
4438
4360
|
await this.initialize();
|
|
4439
4361
|
const retrievals = sqliteAll(
|
|
4440
4362
|
this.db,
|
|
4441
4363
|
`SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
|
|
4442
4364
|
[sessionId]
|
|
4443
4365
|
);
|
|
4444
|
-
if (retrievals.length === 0)
|
|
4445
|
-
return;
|
|
4366
|
+
if (retrievals.length === 0) return;
|
|
4446
4367
|
const sessionEvents = sqliteAll(
|
|
4447
4368
|
this.db,
|
|
4448
4369
|
`SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
|
|
@@ -4455,8 +4376,7 @@ var SQLiteEventStore = class {
|
|
|
4455
4376
|
for (const t of toolEvents) {
|
|
4456
4377
|
try {
|
|
4457
4378
|
const content = JSON.parse(t.content);
|
|
4458
|
-
if (content.success !== false)
|
|
4459
|
-
toolSuccessCount++;
|
|
4379
|
+
if (content.success !== false) toolSuccessCount++;
|
|
4460
4380
|
} catch {
|
|
4461
4381
|
toolSuccessCount++;
|
|
4462
4382
|
}
|
|
@@ -4474,8 +4394,7 @@ var SQLiteEventStore = class {
|
|
|
4474
4394
|
const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
4475
4395
|
let overlap = 0;
|
|
4476
4396
|
for (const w of queryWords) {
|
|
4477
|
-
if (pWords.has(w))
|
|
4478
|
-
overlap++;
|
|
4397
|
+
if (pWords.has(w)) overlap++;
|
|
4479
4398
|
}
|
|
4480
4399
|
if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
|
|
4481
4400
|
wasReasked = 1;
|
|
@@ -4657,8 +4576,7 @@ var SQLiteEventStore = class {
|
|
|
4657
4576
|
return this.db;
|
|
4658
4577
|
}
|
|
4659
4578
|
hasTableColumn(tableName, columnName2) {
|
|
4660
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
|
|
4661
|
-
return false;
|
|
4579
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
|
|
4662
4580
|
try {
|
|
4663
4581
|
const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
|
|
4664
4582
|
return rows.some((row) => row.name === columnName2);
|
|
@@ -4725,8 +4643,7 @@ var SQLiteEventStore = class {
|
|
|
4725
4643
|
createdAt: toDateFromSQLite(row.created_at)
|
|
4726
4644
|
}));
|
|
4727
4645
|
} catch (err) {
|
|
4728
|
-
if (err?.message?.includes("no such table"))
|
|
4729
|
-
return [];
|
|
4646
|
+
if (err?.message?.includes("no such table")) return [];
|
|
4730
4647
|
throw err;
|
|
4731
4648
|
}
|
|
4732
4649
|
}
|
|
@@ -4899,8 +4816,7 @@ var SQLiteEventStore = class {
|
|
|
4899
4816
|
`SELECT id FROM events WHERE session_id = ?`,
|
|
4900
4817
|
[sessionId]
|
|
4901
4818
|
);
|
|
4902
|
-
if (events.length === 0)
|
|
4903
|
-
return 0;
|
|
4819
|
+
if (events.length === 0) return 0;
|
|
4904
4820
|
const eventIds = events.map((e) => e.id);
|
|
4905
4821
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4906
4822
|
const ftsTriggersDropped = [];
|
|
@@ -5112,8 +5028,7 @@ function sanitizeGovernanceAuditValue(value, key) {
|
|
|
5112
5028
|
return value;
|
|
5113
5029
|
}
|
|
5114
5030
|
function sanitizeAuditJson(value) {
|
|
5115
|
-
if (value === void 0)
|
|
5116
|
-
return void 0;
|
|
5031
|
+
if (value === void 0) return void 0;
|
|
5117
5032
|
return sanitizeGovernanceAuditValue(value);
|
|
5118
5033
|
}
|
|
5119
5034
|
function normalizeSourceEventIds(sourceEventIds) {
|
|
@@ -5162,12 +5077,10 @@ async function writeGovernanceAuditEntry(db, input) {
|
|
|
5162
5077
|
|
|
5163
5078
|
// src/core/operations/facet-repository.ts
|
|
5164
5079
|
function parseStringArray(value) {
|
|
5165
|
-
if (typeof value !== "string")
|
|
5166
|
-
return [];
|
|
5080
|
+
if (typeof value !== "string") return [];
|
|
5167
5081
|
try {
|
|
5168
5082
|
const parsed = JSON.parse(value);
|
|
5169
|
-
if (!Array.isArray(parsed))
|
|
5170
|
-
return [];
|
|
5083
|
+
if (!Array.isArray(parsed)) return [];
|
|
5171
5084
|
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
5172
5085
|
} catch {
|
|
5173
5086
|
return [];
|
|
@@ -5211,6 +5124,7 @@ var FacetRepository = class {
|
|
|
5211
5124
|
constructor(db) {
|
|
5212
5125
|
this.db = db;
|
|
5213
5126
|
}
|
|
5127
|
+
db;
|
|
5214
5128
|
async assign(input) {
|
|
5215
5129
|
const assignment = parseFacetAssignmentInput(input);
|
|
5216
5130
|
const existing = this.findByUniqueKey(assignment);
|
|
@@ -5515,19 +5429,14 @@ var RetentionFacetSchema = z5.object({
|
|
|
5515
5429
|
confidence: z5.number().min(0).max(1).default(1)
|
|
5516
5430
|
});
|
|
5517
5431
|
var DateLikeSchema = z5.preprocess((value) => {
|
|
5518
|
-
if (value instanceof Date)
|
|
5519
|
-
|
|
5520
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5521
|
-
return new Date(value);
|
|
5432
|
+
if (value instanceof Date) return value;
|
|
5433
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5522
5434
|
return value;
|
|
5523
5435
|
}, z5.date());
|
|
5524
5436
|
var NullableDateLikeSchema = z5.preprocess((value) => {
|
|
5525
|
-
if (value === null || value === void 0 || value === "")
|
|
5526
|
-
|
|
5527
|
-
if (value
|
|
5528
|
-
return value;
|
|
5529
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5530
|
-
return new Date(value);
|
|
5437
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
5438
|
+
if (value instanceof Date) return value;
|
|
5439
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5531
5440
|
return value;
|
|
5532
5441
|
}, z5.date().nullable());
|
|
5533
5442
|
var OptionalTrimmedStringSchema2 = z5.preprocess(
|
|
@@ -5556,10 +5465,8 @@ import { z as z6 } from "zod";
|
|
|
5556
5465
|
var RequiredTrimmedStringSchema = z6.string().trim().min(1);
|
|
5557
5466
|
var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
|
|
5558
5467
|
var DateLikeSchema2 = z6.preprocess((value) => {
|
|
5559
|
-
if (value instanceof Date)
|
|
5560
|
-
|
|
5561
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5562
|
-
return new Date(value);
|
|
5468
|
+
if (value instanceof Date) return value;
|
|
5469
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5563
5470
|
return value;
|
|
5564
5471
|
}, z6.date());
|
|
5565
5472
|
var RetentionReasonSchema = z6.object({
|
|
@@ -5748,8 +5655,7 @@ var MemoryOperationsConfigSchema = z7.object({
|
|
|
5748
5655
|
}).default({});
|
|
5749
5656
|
var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5750
5657
|
var MemoryLessonStringArraySchema = z7.preprocess((value) => {
|
|
5751
|
-
if (!Array.isArray(value))
|
|
5752
|
-
return value;
|
|
5658
|
+
if (!Array.isArray(value)) return value;
|
|
5753
5659
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5754
5660
|
}, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
|
|
5755
5661
|
var MemoryLessonSchema = z7.object({
|
|
@@ -5794,14 +5700,12 @@ var ListMemoryLessonsInputSchema = z7.object({
|
|
|
5794
5700
|
});
|
|
5795
5701
|
var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5796
5702
|
var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
|
|
5797
|
-
if (typeof value !== "string")
|
|
5798
|
-
return value;
|
|
5703
|
+
if (typeof value !== "string") return value;
|
|
5799
5704
|
const normalized = value.trim();
|
|
5800
5705
|
return normalized.length > 0 ? normalized : void 0;
|
|
5801
5706
|
}, PerspectiveMemoryNonEmptyStringSchema.optional());
|
|
5802
5707
|
var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
|
|
5803
|
-
if (!Array.isArray(value))
|
|
5804
|
-
return value;
|
|
5708
|
+
if (!Array.isArray(value)) return value;
|
|
5805
5709
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5806
5710
|
}, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
|
|
5807
5711
|
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;
|
|
@@ -6459,6 +6363,7 @@ var GraphPathService = class {
|
|
|
6459
6363
|
constructor(db) {
|
|
6460
6364
|
this.db = db;
|
|
6461
6365
|
}
|
|
6366
|
+
db;
|
|
6462
6367
|
expand(input) {
|
|
6463
6368
|
const graph = this.loadGraph(input.direction ?? "both");
|
|
6464
6369
|
const effectiveMaxHops = normalizeMaxHops(input.maxHops);
|
|
@@ -6476,11 +6381,9 @@ var GraphPathService = class {
|
|
|
6476
6381
|
while (queue.length > 0) {
|
|
6477
6382
|
queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
|
|
6478
6383
|
const current = queue.shift();
|
|
6479
|
-
if (current.hops >= effectiveMaxHops)
|
|
6480
|
-
continue;
|
|
6384
|
+
if (current.hops >= effectiveMaxHops) continue;
|
|
6481
6385
|
for (const edge of graph.adjacency.get(current.key) ?? []) {
|
|
6482
|
-
if (current.visited.has(edge.toKey))
|
|
6483
|
-
continue;
|
|
6386
|
+
if (current.visited.has(edge.toKey)) continue;
|
|
6484
6387
|
const nextHops = current.hops + 1;
|
|
6485
6388
|
const nextTotalCost = current.totalCost + edge.step.cost;
|
|
6486
6389
|
const nextSteps = [...current.steps, edge.step];
|
|
@@ -6560,17 +6463,13 @@ function addTraversal(adjacency, fromKey, edge) {
|
|
|
6560
6463
|
adjacency.set(fromKey, edges);
|
|
6561
6464
|
}
|
|
6562
6465
|
function normalizeMaxHops(maxHops) {
|
|
6563
|
-
if (maxHops === void 0)
|
|
6564
|
-
|
|
6565
|
-
if (!Number.isFinite(maxHops))
|
|
6566
|
-
return MAX_HOPS;
|
|
6466
|
+
if (maxHops === void 0) return 1;
|
|
6467
|
+
if (!Number.isFinite(maxHops)) return MAX_HOPS;
|
|
6567
6468
|
return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
|
|
6568
6469
|
}
|
|
6569
6470
|
function normalizeMaxResults(maxResults) {
|
|
6570
|
-
if (maxResults === void 0)
|
|
6571
|
-
|
|
6572
|
-
if (!Number.isFinite(maxResults))
|
|
6573
|
-
return DEFAULT_MAX_RESULTS;
|
|
6471
|
+
if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
|
|
6472
|
+
if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
|
|
6574
6473
|
return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
|
|
6575
6474
|
}
|
|
6576
6475
|
function isBetterPath(totalCost, hops, signature, existing) {
|
|
@@ -6582,18 +6481,15 @@ function pathSignature(steps) {
|
|
|
6582
6481
|
function edgeWeight(metaJson) {
|
|
6583
6482
|
const meta = parseMeta(metaJson);
|
|
6584
6483
|
const raw = meta.weight;
|
|
6585
|
-
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
|
|
6586
|
-
return raw;
|
|
6484
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
|
|
6587
6485
|
if (typeof raw === "string") {
|
|
6588
6486
|
const parsed = Number(raw);
|
|
6589
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
6590
|
-
return parsed;
|
|
6487
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
6591
6488
|
}
|
|
6592
6489
|
return DEFAULT_WEIGHT;
|
|
6593
6490
|
}
|
|
6594
6491
|
function parseMeta(metaJson) {
|
|
6595
|
-
if (!metaJson)
|
|
6596
|
-
return {};
|
|
6492
|
+
if (!metaJson) return {};
|
|
6597
6493
|
try {
|
|
6598
6494
|
const parsed = JSON.parse(metaJson);
|
|
6599
6495
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
@@ -6606,8 +6502,7 @@ function nodeKey(node) {
|
|
|
6606
6502
|
}
|
|
6607
6503
|
function nodeFromKey(key) {
|
|
6608
6504
|
const index = key.indexOf(":");
|
|
6609
|
-
if (index === -1)
|
|
6610
|
-
return { type: "entity", id: key };
|
|
6505
|
+
if (index === -1) return { type: "entity", id: key };
|
|
6611
6506
|
return { type: key.slice(0, index), id: key.slice(index + 1) };
|
|
6612
6507
|
}
|
|
6613
6508
|
|
|
@@ -6663,6 +6558,7 @@ var QueryEntityExtractor = class {
|
|
|
6663
6558
|
constructor(db) {
|
|
6664
6559
|
this.db = db;
|
|
6665
6560
|
}
|
|
6561
|
+
db;
|
|
6666
6562
|
extract(query, options = {}) {
|
|
6667
6563
|
const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
|
|
6668
6564
|
const candidates = [];
|
|
@@ -6684,8 +6580,7 @@ var QueryEntityExtractor = class {
|
|
|
6684
6580
|
let match;
|
|
6685
6581
|
while ((match = regex.exec(query)) !== null) {
|
|
6686
6582
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6687
|
-
if (!isUsefulCandidate(text))
|
|
6688
|
-
continue;
|
|
6583
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6689
6584
|
const start = match.index + 1;
|
|
6690
6585
|
const end = start + text.length;
|
|
6691
6586
|
ranges.push([match.index, match.index + match[0].length]);
|
|
@@ -6699,8 +6594,7 @@ var QueryEntityExtractor = class {
|
|
|
6699
6594
|
return ranges;
|
|
6700
6595
|
}
|
|
6701
6596
|
extractKnownAliases(query, candidates) {
|
|
6702
|
-
if (!this.db)
|
|
6703
|
-
return;
|
|
6597
|
+
if (!this.db) return;
|
|
6704
6598
|
const rows = sqliteAll(
|
|
6705
6599
|
this.db,
|
|
6706
6600
|
`SELECT
|
|
@@ -6724,11 +6618,9 @@ var QueryEntityExtractor = class {
|
|
|
6724
6618
|
]).filter(isUsefulCandidate);
|
|
6725
6619
|
for (const alias of aliasLabels) {
|
|
6726
6620
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6727
|
-
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
|
|
6728
|
-
continue;
|
|
6621
|
+
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
|
|
6729
6622
|
const aliasKey = `${row.entity_id}:${normalizedAlias}`;
|
|
6730
|
-
if (seenAliases.has(aliasKey))
|
|
6731
|
-
continue;
|
|
6623
|
+
if (seenAliases.has(aliasKey)) continue;
|
|
6732
6624
|
seenAliases.add(aliasKey);
|
|
6733
6625
|
const range = findRange(query, alias);
|
|
6734
6626
|
pushCandidate(candidates, {
|
|
@@ -6749,8 +6641,7 @@ var QueryEntityExtractor = class {
|
|
|
6749
6641
|
let match;
|
|
6750
6642
|
while ((match = regex.exec(query)) !== null) {
|
|
6751
6643
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6752
|
-
if (!isUsefulCandidate(text))
|
|
6753
|
-
continue;
|
|
6644
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6754
6645
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6755
6646
|
pushCandidate(candidates, {
|
|
6756
6647
|
text,
|
|
@@ -6765,8 +6656,7 @@ var QueryEntityExtractor = class {
|
|
|
6765
6656
|
let match;
|
|
6766
6657
|
while ((match = regex.exec(query)) !== null) {
|
|
6767
6658
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6768
|
-
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
|
|
6769
|
-
continue;
|
|
6659
|
+
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
|
|
6770
6660
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6771
6661
|
pushCandidate(candidates, {
|
|
6772
6662
|
text,
|
|
@@ -6785,21 +6675,17 @@ var QueryEntityExtractor = class {
|
|
|
6785
6675
|
if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
|
|
6786
6676
|
current.push(token);
|
|
6787
6677
|
} else {
|
|
6788
|
-
if (current.length > 0)
|
|
6789
|
-
groups.push(current);
|
|
6678
|
+
if (current.length > 0) groups.push(current);
|
|
6790
6679
|
current = [token];
|
|
6791
6680
|
}
|
|
6792
6681
|
}
|
|
6793
|
-
if (current.length > 0)
|
|
6794
|
-
groups.push(current);
|
|
6682
|
+
if (current.length > 0) groups.push(current);
|
|
6795
6683
|
for (const group of groups) {
|
|
6796
|
-
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
|
|
6797
|
-
continue;
|
|
6684
|
+
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
|
|
6798
6685
|
const start = group[0].start;
|
|
6799
6686
|
const end = group[group.length - 1].end;
|
|
6800
6687
|
const text = query.slice(start, end);
|
|
6801
|
-
if (!isUsefulCandidate(text))
|
|
6802
|
-
continue;
|
|
6688
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6803
6689
|
pushCandidate(candidates, {
|
|
6804
6690
|
text,
|
|
6805
6691
|
source: "capitalized_term",
|
|
@@ -6820,8 +6706,7 @@ function collectCapitalizedTokens(query) {
|
|
|
6820
6706
|
}
|
|
6821
6707
|
function pushCandidate(candidates, input) {
|
|
6822
6708
|
const text = cleanCandidateText(input.text);
|
|
6823
|
-
if (!isUsefulCandidate(text))
|
|
6824
|
-
return;
|
|
6709
|
+
if (!isUsefulCandidate(text)) return;
|
|
6825
6710
|
const source = input.source;
|
|
6826
6711
|
candidates.push({
|
|
6827
6712
|
...input,
|
|
@@ -6839,15 +6724,13 @@ function dedupeAndSort(candidates) {
|
|
|
6839
6724
|
for (const candidate of sorted) {
|
|
6840
6725
|
if (candidate.source === "entity_alias") {
|
|
6841
6726
|
const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
|
|
6842
|
-
if (seenAliasKeys.has(aliasKey))
|
|
6843
|
-
continue;
|
|
6727
|
+
if (seenAliasKeys.has(aliasKey)) continue;
|
|
6844
6728
|
seenAliasKeys.add(aliasKey);
|
|
6845
6729
|
seenNormalized.add(candidate.normalized);
|
|
6846
6730
|
result.push(candidate);
|
|
6847
6731
|
continue;
|
|
6848
6732
|
}
|
|
6849
|
-
if (seenNormalized.has(candidate.normalized))
|
|
6850
|
-
continue;
|
|
6733
|
+
if (seenNormalized.has(candidate.normalized)) continue;
|
|
6851
6734
|
seenNormalized.add(candidate.normalized);
|
|
6852
6735
|
result.push(candidate);
|
|
6853
6736
|
}
|
|
@@ -6857,8 +6740,7 @@ function compareCandidates(a, b) {
|
|
|
6857
6740
|
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 ?? "");
|
|
6858
6741
|
}
|
|
6859
6742
|
function compareStrings(a, b) {
|
|
6860
|
-
if (a === b)
|
|
6861
|
-
return 0;
|
|
6743
|
+
if (a === b) return 0;
|
|
6862
6744
|
return a < b ? -1 : 1;
|
|
6863
6745
|
}
|
|
6864
6746
|
function stripPriority(candidate) {
|
|
@@ -6866,10 +6748,8 @@ function stripPriority(candidate) {
|
|
|
6866
6748
|
return publicCandidate;
|
|
6867
6749
|
}
|
|
6868
6750
|
function normalizeMaxCandidates(maxCandidates) {
|
|
6869
|
-
if (maxCandidates === void 0)
|
|
6870
|
-
|
|
6871
|
-
if (!Number.isFinite(maxCandidates))
|
|
6872
|
-
return DEFAULT_MAX_CANDIDATES;
|
|
6751
|
+
if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
|
|
6752
|
+
if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
|
|
6873
6753
|
return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
|
|
6874
6754
|
}
|
|
6875
6755
|
function cleanCandidateText(text) {
|
|
@@ -6891,21 +6771,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
|
|
|
6891
6771
|
function findRange(query, alias) {
|
|
6892
6772
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6893
6773
|
const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
|
|
6894
|
-
if (directIndex >= 0)
|
|
6895
|
-
return { start: directIndex, end: directIndex + alias.length };
|
|
6774
|
+
if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
|
|
6896
6775
|
const normalizedQuery = normalizeForContainment(query);
|
|
6897
6776
|
const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
|
|
6898
|
-
if (normalizedIndex < 0)
|
|
6899
|
-
return { start: 0, end: 0 };
|
|
6777
|
+
if (normalizedIndex < 0) return { start: 0, end: 0 };
|
|
6900
6778
|
const queryLower = query.toLowerCase();
|
|
6901
6779
|
const words = normalizedAlias.split(" ").filter(Boolean);
|
|
6902
|
-
if (words.length === 0)
|
|
6903
|
-
return { start: 0, end: 0 };
|
|
6780
|
+
if (words.length === 0) return { start: 0, end: 0 };
|
|
6904
6781
|
const first = queryLower.indexOf(words[0]);
|
|
6905
6782
|
const lastWord = words[words.length - 1];
|
|
6906
6783
|
const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
|
|
6907
|
-
if (first >= 0 && last >= 0)
|
|
6908
|
-
return { start: first, end: last + lastWord.length };
|
|
6784
|
+
if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
|
|
6909
6785
|
return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
|
|
6910
6786
|
}
|
|
6911
6787
|
function isUsefulCandidate(text) {
|
|
@@ -6916,10 +6792,8 @@ function isInsideAnyRange(index, ranges) {
|
|
|
6916
6792
|
return ranges.some(([start, end]) => index >= start && index < end);
|
|
6917
6793
|
}
|
|
6918
6794
|
function isStrongSingleCapitalized(text) {
|
|
6919
|
-
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
|
|
6920
|
-
|
|
6921
|
-
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
|
|
6922
|
-
return true;
|
|
6795
|
+
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
|
|
6796
|
+
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
|
|
6923
6797
|
return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
|
|
6924
6798
|
}
|
|
6925
6799
|
function uniqueStrings(values) {
|
|
@@ -6927,8 +6801,7 @@ function uniqueStrings(values) {
|
|
|
6927
6801
|
const result = [];
|
|
6928
6802
|
for (const value of values) {
|
|
6929
6803
|
const key = normalizeForContainment(value);
|
|
6930
|
-
if (!key || seen.has(key))
|
|
6931
|
-
continue;
|
|
6804
|
+
if (!key || seen.has(key)) continue;
|
|
6932
6805
|
seen.add(key);
|
|
6933
6806
|
result.push(value);
|
|
6934
6807
|
}
|
|
@@ -6950,8 +6823,7 @@ var LessonCandidateInputSchema = z9.object({
|
|
|
6950
6823
|
import { z as z10 } from "zod";
|
|
6951
6824
|
var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
|
|
6952
6825
|
var PromotionStringArraySchema = z10.preprocess((value) => {
|
|
6953
|
-
if (!Array.isArray(value))
|
|
6954
|
-
return value;
|
|
6826
|
+
if (!Array.isArray(value)) return value;
|
|
6955
6827
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
6956
6828
|
}, z10.array(NonEmptyStringSchema5).max(100));
|
|
6957
6829
|
var ReviewedLessonCandidateSchema = z10.object({
|
|
@@ -6999,8 +6871,7 @@ function projectHashFromStorage(projectHash) {
|
|
|
6999
6871
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7000
6872
|
}
|
|
7001
6873
|
function parseJsonRecord(value) {
|
|
7002
|
-
if (!value)
|
|
7003
|
-
return void 0;
|
|
6874
|
+
if (!value) return void 0;
|
|
7004
6875
|
try {
|
|
7005
6876
|
const parsed = JSON.parse(value);
|
|
7006
6877
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7012,8 +6883,7 @@ function sanitizeString(value) {
|
|
|
7012
6883
|
return String(sanitizeGovernanceAuditValue(value)).trim();
|
|
7013
6884
|
}
|
|
7014
6885
|
function sanitizeMetadata(metadata) {
|
|
7015
|
-
if (!metadata)
|
|
7016
|
-
return void 0;
|
|
6886
|
+
if (!metadata) return void 0;
|
|
7017
6887
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7018
6888
|
}
|
|
7019
6889
|
function slugActorPart(value) {
|
|
@@ -7021,8 +6891,7 @@ function slugActorPart(value) {
|
|
|
7021
6891
|
return slug.length > 0 ? slug : "unknown";
|
|
7022
6892
|
}
|
|
7023
6893
|
function stableActorId(input) {
|
|
7024
|
-
if (input.actorId)
|
|
7025
|
-
return sanitizeString(input.actorId);
|
|
6894
|
+
if (input.actorId) return sanitizeString(input.actorId);
|
|
7026
6895
|
const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
|
|
7027
6896
|
return [
|
|
7028
6897
|
"actor",
|
|
@@ -7045,12 +6914,10 @@ function rowToActor(row) {
|
|
|
7045
6914
|
});
|
|
7046
6915
|
}
|
|
7047
6916
|
function metadataString(metadata, keys) {
|
|
7048
|
-
if (!metadata)
|
|
7049
|
-
return void 0;
|
|
6917
|
+
if (!metadata) return void 0;
|
|
7050
6918
|
for (const key of keys) {
|
|
7051
6919
|
const value = metadata[key];
|
|
7052
|
-
if (typeof value === "string" && value.trim().length > 0)
|
|
7053
|
-
return value.trim();
|
|
6920
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
7054
6921
|
}
|
|
7055
6922
|
return void 0;
|
|
7056
6923
|
}
|
|
@@ -7100,6 +6967,7 @@ var ActorRepository = class {
|
|
|
7100
6967
|
constructor(db) {
|
|
7101
6968
|
this.db = db;
|
|
7102
6969
|
}
|
|
6970
|
+
db;
|
|
7103
6971
|
async upsert(input) {
|
|
7104
6972
|
const parsed = UpsertMemoryActorInputSchema.parse(input);
|
|
7105
6973
|
const actorId = stableActorId(parsed);
|
|
@@ -7153,8 +7021,7 @@ var ActorRepository = class {
|
|
|
7153
7021
|
}
|
|
7154
7022
|
require(actorId) {
|
|
7155
7023
|
const actor = this.get(actorId);
|
|
7156
|
-
if (!actor)
|
|
7157
|
-
throw new Error(`Memory actor not found: ${actorId}`);
|
|
7024
|
+
if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
|
|
7158
7025
|
return actor;
|
|
7159
7026
|
}
|
|
7160
7027
|
async list(input = {}) {
|
|
@@ -7190,8 +7057,7 @@ function projectHashFromStorage2(projectHash) {
|
|
|
7190
7057
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7191
7058
|
}
|
|
7192
7059
|
function parseJsonRecord2(value) {
|
|
7193
|
-
if (!value)
|
|
7194
|
-
return void 0;
|
|
7060
|
+
if (!value) return void 0;
|
|
7195
7061
|
try {
|
|
7196
7062
|
const parsed = JSON.parse(value);
|
|
7197
7063
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7200,8 +7066,7 @@ function parseJsonRecord2(value) {
|
|
|
7200
7066
|
}
|
|
7201
7067
|
}
|
|
7202
7068
|
function sanitizeMetadata2(metadata) {
|
|
7203
|
-
if (!metadata)
|
|
7204
|
-
return void 0;
|
|
7069
|
+
if (!metadata) return void 0;
|
|
7205
7070
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7206
7071
|
}
|
|
7207
7072
|
function rowToSessionActor(row) {
|
|
@@ -7221,6 +7086,7 @@ var SessionActorRepository = class {
|
|
|
7221
7086
|
constructor(db) {
|
|
7222
7087
|
this.db = db;
|
|
7223
7088
|
}
|
|
7089
|
+
db;
|
|
7224
7090
|
async upsertMembership(input) {
|
|
7225
7091
|
const parsed = UpsertSessionActorInputSchema.parse(input);
|
|
7226
7092
|
const projectHash = projectHashToStorage3(parsed.projectHash);
|
|
@@ -7267,8 +7133,7 @@ var SessionActorRepository = class {
|
|
|
7267
7133
|
);
|
|
7268
7134
|
}
|
|
7269
7135
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7270
|
-
if (!saved)
|
|
7271
|
-
throw new Error("session actor membership was not saved");
|
|
7136
|
+
if (!saved) throw new Error("session actor membership was not saved");
|
|
7272
7137
|
return saved;
|
|
7273
7138
|
}
|
|
7274
7139
|
async listBySession(input) {
|
|
@@ -7304,8 +7169,7 @@ var SessionActorRepository = class {
|
|
|
7304
7169
|
]
|
|
7305
7170
|
);
|
|
7306
7171
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7307
|
-
if (!saved)
|
|
7308
|
-
throw new Error("session actor membership not found after update");
|
|
7172
|
+
if (!saved) throw new Error("session actor membership not found after update");
|
|
7309
7173
|
return saved;
|
|
7310
7174
|
}
|
|
7311
7175
|
get(projectHash, sessionId, actorId) {
|
|
@@ -7327,8 +7191,7 @@ function projectHashFromStorage3(projectHash) {
|
|
|
7327
7191
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7328
7192
|
}
|
|
7329
7193
|
function parseStringArray2(value) {
|
|
7330
|
-
if (!value)
|
|
7331
|
-
return [];
|
|
7194
|
+
if (!value) return [];
|
|
7332
7195
|
try {
|
|
7333
7196
|
const parsed = JSON.parse(value);
|
|
7334
7197
|
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
@@ -7337,8 +7200,7 @@ function parseStringArray2(value) {
|
|
|
7337
7200
|
}
|
|
7338
7201
|
}
|
|
7339
7202
|
function parseJsonRecord3(value) {
|
|
7340
|
-
if (!value)
|
|
7341
|
-
return void 0;
|
|
7203
|
+
if (!value) return void 0;
|
|
7342
7204
|
try {
|
|
7343
7205
|
const parsed = JSON.parse(value);
|
|
7344
7206
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7354,8 +7216,7 @@ function sanitizeStoredStringArray(values) {
|
|
|
7354
7216
|
return values.map(sanitizeStoredString).filter((value) => value.length > 0);
|
|
7355
7217
|
}
|
|
7356
7218
|
function sanitizeStoredRecord(value) {
|
|
7357
|
-
if (!value)
|
|
7358
|
-
return void 0;
|
|
7219
|
+
if (!value) return void 0;
|
|
7359
7220
|
return sanitizeGovernanceAuditValue(value);
|
|
7360
7221
|
}
|
|
7361
7222
|
function stableHash(value) {
|
|
@@ -7406,8 +7267,7 @@ function sanitizedObservationSnapshot(observation) {
|
|
|
7406
7267
|
});
|
|
7407
7268
|
}
|
|
7408
7269
|
function queryScore(observation, terms) {
|
|
7409
|
-
if (terms.length === 0)
|
|
7410
|
-
return 0;
|
|
7270
|
+
if (terms.length === 0) return 0;
|
|
7411
7271
|
const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
|
|
7412
7272
|
return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
|
|
7413
7273
|
}
|
|
@@ -7453,12 +7313,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7453
7313
|
this.vectorOutbox = options.vectorOutbox;
|
|
7454
7314
|
}
|
|
7455
7315
|
}
|
|
7316
|
+
db;
|
|
7456
7317
|
vectorOutbox = null;
|
|
7457
7318
|
vectorOutboxOption;
|
|
7458
7319
|
getVectorOutbox() {
|
|
7459
7320
|
const option = this.vectorOutboxOption;
|
|
7460
|
-
if (option === false)
|
|
7461
|
-
return null;
|
|
7321
|
+
if (option === false) return null;
|
|
7462
7322
|
if (option instanceof VectorOutbox) {
|
|
7463
7323
|
this.vectorOutbox = option;
|
|
7464
7324
|
return option;
|
|
@@ -7470,8 +7330,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7470
7330
|
}
|
|
7471
7331
|
enqueueObservationSync(observationId) {
|
|
7472
7332
|
const outbox = this.getVectorOutbox();
|
|
7473
|
-
if (!outbox)
|
|
7474
|
-
return;
|
|
7333
|
+
if (!outbox) return;
|
|
7475
7334
|
outbox.enqueueSync("perspective_observation", observationId);
|
|
7476
7335
|
}
|
|
7477
7336
|
async create(input) {
|
|
@@ -7533,14 +7392,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7533
7392
|
contentHash,
|
|
7534
7393
|
sourceHash
|
|
7535
7394
|
);
|
|
7536
|
-
if (!saved)
|
|
7537
|
-
throw new Error("perspective observation was not saved");
|
|
7395
|
+
if (!saved) throw new Error("perspective observation was not saved");
|
|
7538
7396
|
this.enqueueObservationSync(saved.observationId);
|
|
7539
7397
|
});
|
|
7540
7398
|
transaction();
|
|
7541
7399
|
const savedObservation = saved;
|
|
7542
|
-
if (!savedObservation)
|
|
7543
|
-
throw new Error("perspective observation was not saved");
|
|
7400
|
+
if (!savedObservation) throw new Error("perspective observation was not saved");
|
|
7544
7401
|
await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
|
|
7545
7402
|
return savedObservation;
|
|
7546
7403
|
}
|
|
@@ -7550,8 +7407,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7550
7407
|
const ftsQuery = buildObservationFtsQuery(parsed.query);
|
|
7551
7408
|
if (ftsQuery) {
|
|
7552
7409
|
const ftsResult = this.queryWithFts(parsed, ftsQuery);
|
|
7553
|
-
if (ftsResult)
|
|
7554
|
-
return ftsResult;
|
|
7410
|
+
if (ftsResult) return ftsResult;
|
|
7555
7411
|
}
|
|
7556
7412
|
}
|
|
7557
7413
|
return this.queryWithPrefetch(parsed);
|
|
@@ -7572,8 +7428,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7572
7428
|
);
|
|
7573
7429
|
return rows.map(rowToObservation);
|
|
7574
7430
|
} catch (error) {
|
|
7575
|
-
if (isFtsUnavailableError(error))
|
|
7576
|
-
return null;
|
|
7431
|
+
if (isFtsUnavailableError(error)) return null;
|
|
7577
7432
|
throw error;
|
|
7578
7433
|
}
|
|
7579
7434
|
}
|
|
@@ -7614,8 +7469,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7614
7469
|
const parsed = DeletePerspectiveObservationInputSchema.parse(input);
|
|
7615
7470
|
const projectHash = projectHashToStorage4(parsed.projectHash);
|
|
7616
7471
|
const before = this.get(projectHash, parsed.observationId);
|
|
7617
|
-
if (!before)
|
|
7618
|
-
throw new Error("perspective observation not found");
|
|
7472
|
+
if (!before) throw new Error("perspective observation not found");
|
|
7619
7473
|
const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7620
7474
|
sqliteRun(
|
|
7621
7475
|
this.db,
|
|
@@ -7625,8 +7479,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7625
7479
|
[deletedAt, deletedAt, projectHash, parsed.observationId]
|
|
7626
7480
|
);
|
|
7627
7481
|
const after = this.get(projectHash, parsed.observationId);
|
|
7628
|
-
if (!after)
|
|
7629
|
-
throw new Error("perspective observation not found after delete");
|
|
7482
|
+
if (!after) throw new Error("perspective observation not found after delete");
|
|
7630
7483
|
await writeGovernanceAuditEntry(this.db, {
|
|
7631
7484
|
operation: "perspective_observation_delete",
|
|
7632
7485
|
actor: parsed.actor,
|
|
@@ -7682,11 +7535,9 @@ var DEFAULT_CONFIG3 = {
|
|
|
7682
7535
|
var MAX_OBSERVATION_CONTENT_CHARS = 600;
|
|
7683
7536
|
var RuleBasedPerspectiveObservationExtractor = class {
|
|
7684
7537
|
async extract(event) {
|
|
7685
|
-
if (!isSupportedSourceEvent(event))
|
|
7686
|
-
return [];
|
|
7538
|
+
if (!isSupportedSourceEvent(event)) return [];
|
|
7687
7539
|
const content = normalizeObservationContent(event.content);
|
|
7688
|
-
if (!content)
|
|
7689
|
-
return [];
|
|
7540
|
+
if (!content) return [];
|
|
7690
7541
|
return [{
|
|
7691
7542
|
content,
|
|
7692
7543
|
confidence: 0.6,
|
|
@@ -7757,8 +7608,7 @@ var PerspectiveDeriver = class {
|
|
|
7757
7608
|
for (const candidate of candidates) {
|
|
7758
7609
|
const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
|
|
7759
7610
|
const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
|
|
7760
|
-
if (observers.length === 0)
|
|
7761
|
-
continue;
|
|
7611
|
+
if (observers.length === 0) continue;
|
|
7762
7612
|
for (const observerActorId of observers) {
|
|
7763
7613
|
await this.observations.create({
|
|
7764
7614
|
projectHash,
|
|
@@ -7811,28 +7661,22 @@ function normalizeConfig(config) {
|
|
|
7811
7661
|
};
|
|
7812
7662
|
}
|
|
7813
7663
|
function clampInteger(value, fallback, min, max) {
|
|
7814
|
-
if (!Number.isFinite(value))
|
|
7815
|
-
return fallback;
|
|
7664
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7816
7665
|
return Math.max(min, Math.min(max, Math.trunc(Number(value))));
|
|
7817
7666
|
}
|
|
7818
7667
|
function isSupportedSourceEvent(event) {
|
|
7819
7668
|
return event.eventType === "user_prompt" || event.eventType === "agent_response";
|
|
7820
7669
|
}
|
|
7821
7670
|
function roleForEvent(event) {
|
|
7822
|
-
if (event.eventType === "user_prompt")
|
|
7823
|
-
|
|
7824
|
-
if (event.eventType === "
|
|
7825
|
-
|
|
7826
|
-
if (event.eventType === "tool_observation")
|
|
7827
|
-
return "tool";
|
|
7828
|
-
if (event.eventType === "session_summary")
|
|
7829
|
-
return "system";
|
|
7671
|
+
if (event.eventType === "user_prompt") return "speaker";
|
|
7672
|
+
if (event.eventType === "agent_response") return "assistant";
|
|
7673
|
+
if (event.eventType === "tool_observation") return "tool";
|
|
7674
|
+
if (event.eventType === "session_summary") return "system";
|
|
7830
7675
|
return "unknown";
|
|
7831
7676
|
}
|
|
7832
7677
|
function normalizeCandidate2(candidate) {
|
|
7833
7678
|
const content = normalizeObservationContent(candidate.content);
|
|
7834
|
-
if (!content)
|
|
7835
|
-
return null;
|
|
7679
|
+
if (!content) return null;
|
|
7836
7680
|
return {
|
|
7837
7681
|
content,
|
|
7838
7682
|
confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
|
|
@@ -7844,8 +7688,7 @@ function normalizeCandidate2(candidate) {
|
|
|
7844
7688
|
}
|
|
7845
7689
|
function normalizeObservationContent(content) {
|
|
7846
7690
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
7847
|
-
if (!normalized)
|
|
7848
|
-
return null;
|
|
7691
|
+
if (!normalized) return null;
|
|
7849
7692
|
return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
|
|
7850
7693
|
}
|
|
7851
7694
|
function normalizeOptionalString2(value) {
|
|
@@ -7853,13 +7696,11 @@ function normalizeOptionalString2(value) {
|
|
|
7853
7696
|
return normalized.length > 0 ? normalized : void 0;
|
|
7854
7697
|
}
|
|
7855
7698
|
function clampNumber(value, fallback, min, max) {
|
|
7856
|
-
if (!Number.isFinite(value))
|
|
7857
|
-
return fallback;
|
|
7699
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7858
7700
|
return Math.max(min, Math.min(max, Number(value)));
|
|
7859
7701
|
}
|
|
7860
7702
|
function sanitizeCandidateMetadata(metadata) {
|
|
7861
|
-
if (!metadata)
|
|
7862
|
-
return void 0;
|
|
7703
|
+
if (!metadata) return void 0;
|
|
7863
7704
|
const result = {};
|
|
7864
7705
|
for (const [key, value] of Object.entries(metadata)) {
|
|
7865
7706
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -7872,12 +7713,9 @@ function selectObservers(members, observedActorId, maxObservers) {
|
|
|
7872
7713
|
const selected = [];
|
|
7873
7714
|
for (const member of members) {
|
|
7874
7715
|
const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
|
|
7875
|
-
if (!canObserve)
|
|
7876
|
-
|
|
7877
|
-
if (
|
|
7878
|
-
selected.push(member.actorId);
|
|
7879
|
-
if (selected.length >= maxObservers)
|
|
7880
|
-
break;
|
|
7716
|
+
if (!canObserve) continue;
|
|
7717
|
+
if (!selected.includes(member.actorId)) selected.push(member.actorId);
|
|
7718
|
+
if (selected.length >= maxObservers) break;
|
|
7881
7719
|
}
|
|
7882
7720
|
return selected;
|
|
7883
7721
|
}
|
|
@@ -7896,6 +7734,7 @@ var VectorStore = class {
|
|
|
7896
7734
|
constructor(dbPath) {
|
|
7897
7735
|
this.dbPath = dbPath;
|
|
7898
7736
|
}
|
|
7737
|
+
dbPath;
|
|
7899
7738
|
db = null;
|
|
7900
7739
|
tableCache = /* @__PURE__ */ new Map();
|
|
7901
7740
|
defaultTableName = "conversations";
|
|
@@ -7907,8 +7746,7 @@ var VectorStore = class {
|
|
|
7907
7746
|
* conversations table.
|
|
7908
7747
|
*/
|
|
7909
7748
|
async initialize() {
|
|
7910
|
-
if (this.db)
|
|
7911
|
-
return;
|
|
7749
|
+
if (this.db) return;
|
|
7912
7750
|
this.db = await lancedb.connect(this.dbPath);
|
|
7913
7751
|
}
|
|
7914
7752
|
/**
|
|
@@ -7922,8 +7760,7 @@ var VectorStore = class {
|
|
|
7922
7760
|
* Add or update multiple vector records in batch, grouped by inferred table.
|
|
7923
7761
|
*/
|
|
7924
7762
|
async upsertBatch(records) {
|
|
7925
|
-
if (records.length === 0)
|
|
7926
|
-
return;
|
|
7763
|
+
if (records.length === 0) return;
|
|
7927
7764
|
await this.initialize();
|
|
7928
7765
|
if (!this.db) {
|
|
7929
7766
|
throw new Error("Database not initialized");
|
|
@@ -7978,8 +7815,7 @@ var VectorStore = class {
|
|
|
7978
7815
|
async delete(eventId) {
|
|
7979
7816
|
await this.initialize();
|
|
7980
7817
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7981
|
-
if (!table)
|
|
7982
|
-
return;
|
|
7818
|
+
if (!table) return;
|
|
7983
7819
|
await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
|
|
7984
7820
|
}
|
|
7985
7821
|
/**
|
|
@@ -7988,8 +7824,7 @@ var VectorStore = class {
|
|
|
7988
7824
|
async count() {
|
|
7989
7825
|
await this.initialize();
|
|
7990
7826
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7991
|
-
if (!table)
|
|
7992
|
-
return 0;
|
|
7827
|
+
if (!table) return 0;
|
|
7993
7828
|
const result = await table.countRows();
|
|
7994
7829
|
return result;
|
|
7995
7830
|
}
|
|
@@ -7998,8 +7833,7 @@ var VectorStore = class {
|
|
|
7998
7833
|
*/
|
|
7999
7834
|
async clearAll() {
|
|
8000
7835
|
await this.initialize();
|
|
8001
|
-
if (!this.db)
|
|
8002
|
-
return;
|
|
7836
|
+
if (!this.db) return;
|
|
8003
7837
|
try {
|
|
8004
7838
|
if (typeof this.db.dropTable === "function") {
|
|
8005
7839
|
await this.db.dropTable(this.defaultTableName);
|
|
@@ -8016,8 +7850,7 @@ var VectorStore = class {
|
|
|
8016
7850
|
async exists(eventId) {
|
|
8017
7851
|
await this.initialize();
|
|
8018
7852
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8019
|
-
if (!table)
|
|
8020
|
-
return false;
|
|
7853
|
+
if (!table) return false;
|
|
8021
7854
|
const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
|
|
8022
7855
|
return results.length > 0;
|
|
8023
7856
|
}
|
|
@@ -8052,8 +7885,7 @@ var VectorStore = class {
|
|
|
8052
7885
|
throw new Error("Database not initialized");
|
|
8053
7886
|
}
|
|
8054
7887
|
const cached = this.tableCache.get(tableName);
|
|
8055
|
-
if (cached)
|
|
8056
|
-
return cached;
|
|
7888
|
+
if (cached) return cached;
|
|
8057
7889
|
const tableNames = await this.db.tableNames();
|
|
8058
7890
|
if (!tableNames.includes(tableName)) {
|
|
8059
7891
|
return null;
|
|
@@ -8132,12 +7964,9 @@ var IngestInterceptorRegistry = class {
|
|
|
8132
7964
|
}
|
|
8133
7965
|
};
|
|
8134
7966
|
function mergeHierarchicalMetadata(base, patch) {
|
|
8135
|
-
if (!base && !patch)
|
|
8136
|
-
|
|
8137
|
-
if (!base
|
|
8138
|
-
return patch;
|
|
8139
|
-
if (!patch)
|
|
8140
|
-
return base;
|
|
7967
|
+
if (!base && !patch) return void 0;
|
|
7968
|
+
if (!base) return patch;
|
|
7969
|
+
if (!patch) return base;
|
|
8141
7970
|
const result = { ...base };
|
|
8142
7971
|
for (const [key, value] of Object.entries(patch)) {
|
|
8143
7972
|
const current = result[key];
|
|
@@ -8167,33 +7996,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
|
|
|
8167
7996
|
function parseTag(tag) {
|
|
8168
7997
|
const value = (tag || "").trim();
|
|
8169
7998
|
const idx = value.indexOf(":");
|
|
8170
|
-
if (idx <= 0)
|
|
8171
|
-
return { value };
|
|
7999
|
+
if (idx <= 0) return { value };
|
|
8172
8000
|
const namespace = `${value.slice(0, idx)}:`;
|
|
8173
8001
|
const tagValue = value.slice(idx + 1);
|
|
8174
|
-
if (!tagValue)
|
|
8175
|
-
return { value };
|
|
8002
|
+
if (!tagValue) return { value };
|
|
8176
8003
|
return { namespace, value: tagValue };
|
|
8177
8004
|
}
|
|
8178
8005
|
function validateTag(tag) {
|
|
8179
8006
|
const normalized = (tag || "").trim();
|
|
8180
|
-
if (!normalized)
|
|
8181
|
-
return false;
|
|
8007
|
+
if (!normalized) return false;
|
|
8182
8008
|
const { namespace } = parseTag(normalized);
|
|
8183
|
-
if (!namespace)
|
|
8184
|
-
return true;
|
|
8009
|
+
if (!namespace) return true;
|
|
8185
8010
|
return VALID_TAG_NAMESPACES.has(namespace);
|
|
8186
8011
|
}
|
|
8187
8012
|
function normalizeTags(tags) {
|
|
8188
|
-
if (!Array.isArray(tags))
|
|
8189
|
-
return [];
|
|
8013
|
+
if (!Array.isArray(tags)) return [];
|
|
8190
8014
|
const dedup = /* @__PURE__ */ new Set();
|
|
8191
8015
|
for (const item of tags) {
|
|
8192
|
-
if (typeof item !== "string")
|
|
8193
|
-
continue;
|
|
8016
|
+
if (typeof item !== "string") continue;
|
|
8194
8017
|
const normalized = item.trim();
|
|
8195
|
-
if (!validateTag(normalized))
|
|
8196
|
-
continue;
|
|
8018
|
+
if (!validateTag(normalized)) continue;
|
|
8197
8019
|
dedup.add(normalized);
|
|
8198
8020
|
}
|
|
8199
8021
|
return [...dedup];
|
|
@@ -8210,10 +8032,8 @@ var SummaryDeriver = class {
|
|
|
8210
8032
|
* orchestration, while this class owns summary text and metadata decisions.
|
|
8211
8033
|
*/
|
|
8212
8034
|
deriveSessionSummary(events) {
|
|
8213
|
-
if (events.length < 3)
|
|
8214
|
-
|
|
8215
|
-
if (events.some((event) => event.eventType === "session_summary"))
|
|
8216
|
-
return null;
|
|
8035
|
+
if (events.length < 3) return null;
|
|
8036
|
+
if (events.some((event) => event.eventType === "session_summary")) return null;
|
|
8217
8037
|
const prompts = events.filter((event) => event.eventType === "user_prompt");
|
|
8218
8038
|
const toolObservations = events.filter((event) => event.eventType === "tool_observation");
|
|
8219
8039
|
const toolNames = Array.from(new Set(
|
|
@@ -8361,8 +8181,7 @@ var MemoryIngestService = class {
|
|
|
8361
8181
|
await this.initialize();
|
|
8362
8182
|
const events = await this.eventStore.getSessionEvents(sessionId);
|
|
8363
8183
|
const summary = this.summaryDeriver.deriveSessionSummary(events);
|
|
8364
|
-
if (!summary)
|
|
8365
|
-
return;
|
|
8184
|
+
if (!summary) return;
|
|
8366
8185
|
await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
|
|
8367
8186
|
}
|
|
8368
8187
|
async storeToolObservation(sessionId, payload) {
|
|
@@ -8430,10 +8249,8 @@ var MemoryIngestService = class {
|
|
|
8430
8249
|
}
|
|
8431
8250
|
}
|
|
8432
8251
|
async runPerspectiveDeriver(input, eventId, operation) {
|
|
8433
|
-
if (!this.perspectiveDeriver)
|
|
8434
|
-
|
|
8435
|
-
if (operation !== "user_prompt" && operation !== "agent_response")
|
|
8436
|
-
return;
|
|
8252
|
+
if (!this.perspectiveDeriver) return;
|
|
8253
|
+
if (operation !== "user_prompt" && operation !== "agent_response") return;
|
|
8437
8254
|
const event = {
|
|
8438
8255
|
id: eventId,
|
|
8439
8256
|
eventType: input.eventType,
|
|
@@ -8503,11 +8320,13 @@ var MemoryQueryService = class {
|
|
|
8503
8320
|
this.queryStore = queryStore;
|
|
8504
8321
|
this.deps = deps;
|
|
8505
8322
|
}
|
|
8323
|
+
initialize;
|
|
8324
|
+
queryStore;
|
|
8325
|
+
deps;
|
|
8506
8326
|
async keywordSearch(query, options) {
|
|
8507
8327
|
await this.initialize();
|
|
8508
8328
|
const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
|
|
8509
|
-
if (results.length === 0)
|
|
8510
|
-
return [];
|
|
8329
|
+
if (results.length === 0) return [];
|
|
8511
8330
|
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
8512
8331
|
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
8513
8332
|
const rankRange = maxRank - minRank || 1;
|
|
@@ -8602,6 +8421,18 @@ var COMMAND_ARTIFACT_PATTERNS = [
|
|
|
8602
8421
|
/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/i,
|
|
8603
8422
|
/<local-command-stderr>[\s\S]*?<\/local-command-stderr>/i
|
|
8604
8423
|
];
|
|
8424
|
+
var LOW_SIGNAL_CONTEXT_PATTERNS = [
|
|
8425
|
+
/<environment_context\b[\s\S]*<\/environment_context>/i,
|
|
8426
|
+
/<turn_aborted>/i,
|
|
8427
|
+
/^#\s*AGENTS\.md\s+instructions\b[\s\S]*<INSTRUCTIONS>/i,
|
|
8428
|
+
/^\s*(?:understood[,\s.]*)?(?:stopping|stopped|pausing|paused)\s+here\b[\s\S]{0,180}\blet\s+me\s+know\s+when\s+you(?:'d|\s+would)?\s+like\s+to\s+continue\b/i,
|
|
8429
|
+
/^\s*\[?CONTEXT\s+COMPACTION\s*[—-]\s*REFERENCE\s+ONLY\]?\b[\s\S]{0,600}\b(?:earlier\s+turns\s+were\s+compacted|handoff\s+from\s+a\s+previous\s+context\s+window|active\s+task)\b/i,
|
|
8430
|
+
/^\s*Summary\s+generation\s+was\s+unavailable\.\s*\d+\s+message\(s\)\s+were\s+removed\s+to\s+free\s+context\s+space\b/i,
|
|
8431
|
+
/^\s*---\s*END\s+OF\s+CONTEXT\s+SUMMARY\b/i,
|
|
8432
|
+
/^\s*\[Your\s+active\s+task\s+list\s+was\s+preserved\s+across\s+context\s+compression\]/i,
|
|
8433
|
+
/^➜\s+\S+\s+git:\([^)]*\)\s+/i,
|
|
8434
|
+
/^\$\s+\S+/i
|
|
8435
|
+
];
|
|
8605
8436
|
var CONTINUATION_QUERY_PATTERNS = [
|
|
8606
8437
|
/^\s*(?:continue|resume|next|what(?:'s| is)? next|next\s+(?:step|task|action)|recommended\s+(?:next\s+)?(?:step|task|action)|what should (?:we|i) do next)\??\s*$/i,
|
|
8607
8438
|
/^\s*(?:응\s*)?(?:이어서(?:\s*진행(?:해줘)?)?|계속(?:\s*해줘)?|다음\s*(?:단계|작업|추천\s*작업|추천|할\s*일)?(?:은|는)?(?:\s*(?:뭐야|진행(?:해줘)?))?\??|남은\s*(?:추가(?:로)?\s*)?(?:(?:할\s*만한\s*)?(?:작업|일)|할\s*일)?(?:은|는)?\s*(?:있어|있나|있나요|뭐야)\??|추천\s*작업(?:은|는)?(?:\s*뭐야)?\??|진행해줘)\s*$/i
|
|
@@ -8613,7 +8444,7 @@ var SHORT_REPAIR_FOLLOW_UP_PATTERNS = [
|
|
|
8613
8444
|
var CURRENT_STATE_QUERY_PATTERNS = [
|
|
8614
8445
|
/\bcurrent\b.*\b(?:state|status|deployment|blocker|pr|pull request)\b/i,
|
|
8615
8446
|
/\b(?:still|as current|current)\b.*\b(?:unresolved|open|pending|not completed)\b/i,
|
|
8616
|
-
/\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|
|
|
8447
|
+
/\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|status)\b/i,
|
|
8617
8448
|
/(?:현재|아직|이전|오래된|해결된).*(?:상태|미해결|열린|블로커|PR|풀리퀘스트)/i
|
|
8618
8449
|
];
|
|
8619
8450
|
var STALE_CONTENT_PATTERNS = [
|
|
@@ -8753,55 +8584,67 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
|
|
|
8753
8584
|
]);
|
|
8754
8585
|
function isCommandArtifactQuery(query) {
|
|
8755
8586
|
const trimmed = query.trim();
|
|
8756
|
-
if (!trimmed)
|
|
8757
|
-
return false;
|
|
8587
|
+
if (!trimmed) return false;
|
|
8758
8588
|
const normalized = trimmed.toLowerCase();
|
|
8759
|
-
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8589
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8590
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
8591
|
+
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8592
|
+
}
|
|
8593
|
+
function isCommandArtifactContent(content) {
|
|
8594
|
+
const trimmed = content.trim();
|
|
8595
|
+
if (!trimmed) return false;
|
|
8596
|
+
const normalized = trimmed.toLowerCase();
|
|
8597
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8598
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
8763
8599
|
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8764
8600
|
}
|
|
8601
|
+
function isLowSignalContextContent(content) {
|
|
8602
|
+
const trimmed = content.trim();
|
|
8603
|
+
if (!trimmed) return true;
|
|
8604
|
+
if (isCommandArtifactContent(trimmed)) return true;
|
|
8605
|
+
if (LOW_SIGNAL_CONTEXT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
8606
|
+
return false;
|
|
8607
|
+
}
|
|
8765
8608
|
function isGenericContinuationQuery(query) {
|
|
8766
8609
|
const trimmed = query.trim();
|
|
8767
|
-
if (!trimmed)
|
|
8768
|
-
|
|
8769
|
-
if (
|
|
8770
|
-
return false;
|
|
8771
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8772
|
-
return false;
|
|
8610
|
+
if (!trimmed) return false;
|
|
8611
|
+
if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
8612
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8773
8613
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8774
|
-
if (tokens.length > 10)
|
|
8775
|
-
return false;
|
|
8614
|
+
if (tokens.length > 10) return false;
|
|
8776
8615
|
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);
|
|
8777
8616
|
}
|
|
8778
8617
|
function isShortRepairFollowUpQuery(query) {
|
|
8779
8618
|
const trimmed = query.trim();
|
|
8780
|
-
if (!trimmed)
|
|
8781
|
-
|
|
8782
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8783
|
-
return false;
|
|
8619
|
+
if (!trimmed) return false;
|
|
8620
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8784
8621
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8785
|
-
if (tokens.length > 8)
|
|
8786
|
-
return false;
|
|
8622
|
+
if (tokens.length > 8) return false;
|
|
8787
8623
|
return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8788
8624
|
}
|
|
8625
|
+
function isLowConfidenceContextFallbackQuery(query) {
|
|
8626
|
+
const trimmed = query.trim();
|
|
8627
|
+
if (!trimmed) return false;
|
|
8628
|
+
if (isGenericContinuationQuery(trimmed) || isShortRepairFollowUpQuery(trimmed)) return true;
|
|
8629
|
+
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8630
|
+
if ((terms.has("compacted") || terms.has("compaction")) && terms.has("handoff")) return false;
|
|
8631
|
+
const hasContinuationRecall = /^(?:continue|resume)\b/i.test(trimmed) && (terms.has("work") || terms.has("step") || terms.has("task") || terms.has("last") || terms.has("completed"));
|
|
8632
|
+
const hasValidationGateRecall = terms.has("validation") && (terms.has("gate") || terms.has("check")) && (terms.has("run") || terms.has("before") || terms.has("commit") || terms.has("committing") || terms.has("change"));
|
|
8633
|
+
return hasContinuationRecall || hasValidationGateRecall;
|
|
8634
|
+
}
|
|
8789
8635
|
function isCurrentStateQuery(query) {
|
|
8790
8636
|
const trimmed = query.trim();
|
|
8791
|
-
if (!trimmed)
|
|
8792
|
-
return false;
|
|
8637
|
+
if (!trimmed) return false;
|
|
8793
8638
|
return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8794
8639
|
}
|
|
8795
8640
|
function isStaleOrSupersededContent(content) {
|
|
8796
8641
|
const trimmed = content.trim();
|
|
8797
|
-
if (!trimmed)
|
|
8798
|
-
return false;
|
|
8642
|
+
if (!trimmed) return false;
|
|
8799
8643
|
return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8800
8644
|
}
|
|
8801
8645
|
function buildRetrievalQualityQuery(query) {
|
|
8802
8646
|
const trimmed = query.trim();
|
|
8803
|
-
if (!trimmed)
|
|
8804
|
-
return query;
|
|
8647
|
+
if (!trimmed) return query;
|
|
8805
8648
|
if (isRetrievalPrivacyDecisionQuery(trimmed)) {
|
|
8806
8649
|
return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
|
|
8807
8650
|
}
|
|
@@ -8815,12 +8658,10 @@ function buildRetrievalQualityQuery(query) {
|
|
|
8815
8658
|
}
|
|
8816
8659
|
function isRetrievalPrivacyDecisionQuery(query) {
|
|
8817
8660
|
const trimmed = query.trim();
|
|
8818
|
-
if (!trimmed)
|
|
8819
|
-
return false;
|
|
8661
|
+
if (!trimmed) return false;
|
|
8820
8662
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8821
8663
|
const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8822
|
-
if (!hasDecisionSignal)
|
|
8823
|
-
return false;
|
|
8664
|
+
if (!hasDecisionSignal) return false;
|
|
8824
8665
|
const hasRawQuerySignal = terms.has("raw") && terms.has("query");
|
|
8825
8666
|
const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
|
|
8826
8667
|
const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
|
|
@@ -8833,16 +8674,14 @@ function extractTechnicalQueryTerms(query) {
|
|
|
8833
8674
|
const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
|
|
8834
8675
|
const terms = matches.filter((term) => {
|
|
8835
8676
|
const lower = term.toLowerCase();
|
|
8836
|
-
if (GENERIC_TECHNICAL_TERMS.has(lower))
|
|
8837
|
-
return false;
|
|
8677
|
+
if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
|
|
8838
8678
|
return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
|
|
8839
8679
|
});
|
|
8840
8680
|
return Array.from(new Set(terms.map((term) => term.toLowerCase())));
|
|
8841
8681
|
}
|
|
8842
8682
|
function hasTechnicalTermOverlap(query, content) {
|
|
8843
8683
|
const terms = extractTechnicalQueryTerms(query);
|
|
8844
|
-
if (terms.length === 0)
|
|
8845
|
-
return true;
|
|
8684
|
+
if (terms.length === 0) return true;
|
|
8846
8685
|
const normalizedContent = content.toLowerCase();
|
|
8847
8686
|
return terms.some((term) => normalizedContent.includes(term));
|
|
8848
8687
|
}
|
|
@@ -8858,15 +8697,12 @@ function hasDiscriminativeTermOverlap(query, content) {
|
|
|
8858
8697
|
return topicTerms.some((term) => contentTerms.has(term));
|
|
8859
8698
|
}
|
|
8860
8699
|
}
|
|
8861
|
-
if (queryTerms.length < 3)
|
|
8862
|
-
return true;
|
|
8700
|
+
if (queryTerms.length < 3) return true;
|
|
8863
8701
|
const requiredHits = queryTerms.length >= 3 ? 2 : 1;
|
|
8864
8702
|
let hits = 0;
|
|
8865
8703
|
for (const term of queryTerms) {
|
|
8866
|
-
if (contentTerms.has(term))
|
|
8867
|
-
|
|
8868
|
-
if (hits >= requiredHits)
|
|
8869
|
-
return true;
|
|
8704
|
+
if (contentTerms.has(term)) hits += 1;
|
|
8705
|
+
if (hits >= requiredHits) return true;
|
|
8870
8706
|
}
|
|
8871
8707
|
return false;
|
|
8872
8708
|
}
|
|
@@ -8876,17 +8712,14 @@ function shouldApplyTechnicalGuard(query) {
|
|
|
8876
8712
|
function hasAnyTerm(terms, expectedTerms) {
|
|
8877
8713
|
let found = false;
|
|
8878
8714
|
expectedTerms.forEach((term) => {
|
|
8879
|
-
if (terms.has(term))
|
|
8880
|
-
found = true;
|
|
8715
|
+
if (terms.has(term)) found = true;
|
|
8881
8716
|
});
|
|
8882
8717
|
return found;
|
|
8883
8718
|
}
|
|
8884
8719
|
function shouldRequireDecisionTopicOverlap(query) {
|
|
8885
|
-
if (isRetrievalPrivacyDecisionQuery(query))
|
|
8886
|
-
return false;
|
|
8720
|
+
if (isRetrievalPrivacyDecisionQuery(query)) return false;
|
|
8887
8721
|
const trimmed = query.trim();
|
|
8888
|
-
if (!trimmed)
|
|
8889
|
-
return false;
|
|
8722
|
+
if (!trimmed) return false;
|
|
8890
8723
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8891
8724
|
return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8892
8725
|
}
|
|
@@ -8894,12 +8727,9 @@ function extractDiscriminativeQueryTerms(query) {
|
|
|
8894
8727
|
const seen = /* @__PURE__ */ new Set();
|
|
8895
8728
|
const terms = [];
|
|
8896
8729
|
for (const token of tokenizeQualityText(query)) {
|
|
8897
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token))
|
|
8898
|
-
|
|
8899
|
-
if (
|
|
8900
|
-
continue;
|
|
8901
|
-
if (seen.has(token))
|
|
8902
|
-
continue;
|
|
8730
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
|
|
8731
|
+
if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
|
|
8732
|
+
if (seen.has(token)) continue;
|
|
8903
8733
|
seen.add(token);
|
|
8904
8734
|
terms.push(token);
|
|
8905
8735
|
}
|
|
@@ -8914,14 +8744,10 @@ function tokenizeQualityText(text) {
|
|
|
8914
8744
|
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);
|
|
8915
8745
|
}
|
|
8916
8746
|
function normalizeQualityToken(token) {
|
|
8917
|
-
if (token === "apis")
|
|
8918
|
-
|
|
8919
|
-
if (token
|
|
8920
|
-
|
|
8921
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
|
|
8922
|
-
return token;
|
|
8923
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
8924
|
-
return `${token.slice(0, -3)}y`;
|
|
8747
|
+
if (token === "apis") return "api";
|
|
8748
|
+
if (token === "ids") return "id";
|
|
8749
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
|
|
8750
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
8925
8751
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
|
|
8926
8752
|
return token.slice(0, -1);
|
|
8927
8753
|
}
|
|
@@ -9073,7 +8899,14 @@ var Retriever = class {
|
|
|
9073
8899
|
};
|
|
9074
8900
|
fallbackTrace.push("fallback:summary");
|
|
9075
8901
|
}
|
|
9076
|
-
const
|
|
8902
|
+
const selectedResults = current.results.slice(0, opts.topK).filter((result) => {
|
|
8903
|
+
if (current.matchResult.confidence !== "none") return true;
|
|
8904
|
+
if (isLowConfidenceContextFallbackQuery(query)) {
|
|
8905
|
+
return (result.semanticScore ?? result.score) >= 0.5 || result.score >= 0.5;
|
|
8906
|
+
}
|
|
8907
|
+
return (result.semanticScore ?? result.score) >= 0.62 || result.score >= 0.62;
|
|
8908
|
+
});
|
|
8909
|
+
const memories = await this.enrichResults(selectedResults, opts, query);
|
|
9077
8910
|
const context = this.buildContext(memories, opts.maxTokens);
|
|
9078
8911
|
return {
|
|
9079
8912
|
memories,
|
|
@@ -9081,7 +8914,7 @@ var Retriever = class {
|
|
|
9081
8914
|
totalTokens: this.estimateTokens(context),
|
|
9082
8915
|
context,
|
|
9083
8916
|
fallbackTrace,
|
|
9084
|
-
selectedDebug:
|
|
8917
|
+
selectedDebug: selectedResults.map((r) => this.debugDetailForResult(r)),
|
|
9085
8918
|
candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r) => this.debugDetailForResult(r)),
|
|
9086
8919
|
rawQueryText: current.queryRewriteKind ? query : void 0,
|
|
9087
8920
|
effectiveQueryText: current.effectiveQueryText,
|
|
@@ -9103,8 +8936,7 @@ var Retriever = class {
|
|
|
9103
8936
|
const sharedMemories = [];
|
|
9104
8937
|
for (const result of sharedVectorResults) {
|
|
9105
8938
|
const entry = await this.sharedStore.get(result.entryId);
|
|
9106
|
-
if (!entry)
|
|
9107
|
-
continue;
|
|
8939
|
+
if (!entry) continue;
|
|
9108
8940
|
if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
|
|
9109
8941
|
sharedMemories.push(entry);
|
|
9110
8942
|
await this.sharedStore.recordUsage(entry.entryId);
|
|
@@ -9177,6 +9009,7 @@ var Retriever = class {
|
|
|
9177
9009
|
if (isCurrentStateQuery(options.query)) {
|
|
9178
9010
|
filtered = filtered.filter((result) => !isStaleOrSupersededContent(result.content));
|
|
9179
9011
|
}
|
|
9012
|
+
filtered = filtered.filter((result) => !isLowSignalContextContent(result.content));
|
|
9180
9013
|
filtered = filtered.filter(
|
|
9181
9014
|
(result) => this.isGraphPathResult(result) || hasDiscriminativeTermOverlap(options.query, result.content)
|
|
9182
9015
|
);
|
|
@@ -9185,18 +9018,15 @@ var Retriever = class {
|
|
|
9185
9018
|
(result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
|
|
9186
9019
|
);
|
|
9187
9020
|
}
|
|
9188
|
-
if (filtered.length <= 2)
|
|
9189
|
-
return filtered;
|
|
9021
|
+
if (filtered.length <= 2) return filtered;
|
|
9190
9022
|
const topScore = filtered[0].score;
|
|
9191
|
-
if (topScore < 0.8)
|
|
9192
|
-
return filtered;
|
|
9023
|
+
if (topScore < 0.8) return filtered;
|
|
9193
9024
|
const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
|
|
9194
9025
|
return filtered.filter((result) => result.score >= cliffThreshold);
|
|
9195
9026
|
}
|
|
9196
9027
|
mergeResults(primary, secondary, limit) {
|
|
9197
9028
|
const byId = /* @__PURE__ */ new Map();
|
|
9198
|
-
for (const row of primary)
|
|
9199
|
-
byId.set(row.eventId, row);
|
|
9029
|
+
for (const row of primary) byId.set(row.eventId, row);
|
|
9200
9030
|
for (const row of secondary) {
|
|
9201
9031
|
const prev = byId.get(row.eventId);
|
|
9202
9032
|
if (!prev || row.score > prev.score) {
|
|
@@ -9207,23 +9037,19 @@ var Retriever = class {
|
|
|
9207
9037
|
}
|
|
9208
9038
|
async expandGraphHops(seeds, opts) {
|
|
9209
9039
|
const byId = /* @__PURE__ */ new Map();
|
|
9210
|
-
for (const s of seeds)
|
|
9211
|
-
byId.set(s.eventId, s);
|
|
9040
|
+
for (const s of seeds) byId.set(s.eventId, s);
|
|
9212
9041
|
let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
|
|
9213
9042
|
for (let hop = 1; hop <= opts.maxHops; hop += 1) {
|
|
9214
9043
|
const next = [];
|
|
9215
9044
|
for (const f of frontier) {
|
|
9216
9045
|
const ev = await this.eventStore.getEvent(f.row.eventId);
|
|
9217
|
-
if (!ev)
|
|
9218
|
-
continue;
|
|
9046
|
+
if (!ev) continue;
|
|
9219
9047
|
const rel = ev.metadata?.relatedEventIds ?? [];
|
|
9220
9048
|
const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
|
|
9221
9049
|
for (const rid of relatedIds) {
|
|
9222
|
-
if (byId.has(rid))
|
|
9223
|
-
continue;
|
|
9050
|
+
if (byId.has(rid)) continue;
|
|
9224
9051
|
const target = await this.eventStore.getEvent(rid);
|
|
9225
|
-
if (!target)
|
|
9226
|
-
continue;
|
|
9052
|
+
if (!target) continue;
|
|
9227
9053
|
const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
|
|
9228
9054
|
const row = {
|
|
9229
9055
|
id: `hop-${hop}-${rid}`,
|
|
@@ -9237,15 +9063,12 @@ var Retriever = class {
|
|
|
9237
9063
|
};
|
|
9238
9064
|
byId.set(row.eventId, row);
|
|
9239
9065
|
next.push({ row, hop });
|
|
9240
|
-
if (byId.size >= opts.limit)
|
|
9241
|
-
break;
|
|
9066
|
+
if (byId.size >= opts.limit) break;
|
|
9242
9067
|
}
|
|
9243
|
-
if (byId.size >= opts.limit)
|
|
9244
|
-
break;
|
|
9068
|
+
if (byId.size >= opts.limit) break;
|
|
9245
9069
|
}
|
|
9246
9070
|
frontier = next;
|
|
9247
|
-
if (frontier.length === 0 || byId.size >= opts.limit)
|
|
9248
|
-
break;
|
|
9071
|
+
if (frontier.length === 0 || byId.size >= opts.limit) break;
|
|
9249
9072
|
}
|
|
9250
9073
|
if (opts.queryGraphEnabled) {
|
|
9251
9074
|
await this.expandQueryGraphPaths(opts.query, byId, opts);
|
|
@@ -9253,8 +9076,7 @@ var Retriever = class {
|
|
|
9253
9076
|
return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
|
|
9254
9077
|
}
|
|
9255
9078
|
async expandQueryGraphPaths(query, byId, opts) {
|
|
9256
|
-
if (!query.trim() || !this.eventStore.getDatabase)
|
|
9257
|
-
return;
|
|
9079
|
+
if (!query.trim() || !this.eventStore.getDatabase) return;
|
|
9258
9080
|
try {
|
|
9259
9081
|
const db = this.eventStore.getDatabase();
|
|
9260
9082
|
const extraction = new QueryEntityExtractor(db).extract(query, {
|
|
@@ -9263,8 +9085,7 @@ var Retriever = class {
|
|
|
9263
9085
|
});
|
|
9264
9086
|
const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
|
|
9265
9087
|
const startNodes = uniqueEntityStartNodes(startCandidates);
|
|
9266
|
-
if (startNodes.length === 0)
|
|
9267
|
-
return;
|
|
9088
|
+
if (startNodes.length === 0) return;
|
|
9268
9089
|
const expansion = new GraphPathService(db).expand({
|
|
9269
9090
|
startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
|
|
9270
9091
|
maxHops: opts.maxHops,
|
|
@@ -9273,11 +9094,9 @@ var Retriever = class {
|
|
|
9273
9094
|
});
|
|
9274
9095
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
9275
9096
|
for (const path11 of expansion.paths) {
|
|
9276
|
-
if (path11.target.type !== "event")
|
|
9277
|
-
continue;
|
|
9097
|
+
if (path11.target.type !== "event") continue;
|
|
9278
9098
|
const target = await this.eventStore.getEvent(path11.target.id);
|
|
9279
|
-
if (!target)
|
|
9280
|
-
continue;
|
|
9099
|
+
if (!target) continue;
|
|
9281
9100
|
const graphPath = toRetrievalGraphPathDebug(path11, titleByEntityId);
|
|
9282
9101
|
const score = graphPathScore(path11, opts.hopPenalty);
|
|
9283
9102
|
const existing = byId.get(target.id);
|
|
@@ -9303,17 +9122,14 @@ var Retriever = class {
|
|
|
9303
9122
|
lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
|
|
9304
9123
|
};
|
|
9305
9124
|
byId.set(row.eventId, row);
|
|
9306
|
-
if (byId.size >= opts.limit)
|
|
9307
|
-
break;
|
|
9125
|
+
if (byId.size >= opts.limit) break;
|
|
9308
9126
|
}
|
|
9309
9127
|
} catch {
|
|
9310
9128
|
}
|
|
9311
9129
|
}
|
|
9312
9130
|
shouldFallback(matchResult, results) {
|
|
9313
|
-
if (results.length === 0)
|
|
9314
|
-
|
|
9315
|
-
if (matchResult.confidence === "none")
|
|
9316
|
-
return true;
|
|
9131
|
+
if (results.length === 0) return true;
|
|
9132
|
+
if (matchResult.confidence === "none") return true;
|
|
9317
9133
|
return false;
|
|
9318
9134
|
}
|
|
9319
9135
|
async buildSummaryFallback(query, topK) {
|
|
@@ -9418,29 +9234,21 @@ var Retriever = class {
|
|
|
9418
9234
|
(value) => typeof value === "string" && value.length > 0
|
|
9419
9235
|
)
|
|
9420
9236
|
);
|
|
9421
|
-
if (!scope && projectScopeMode === "global" && facetFilters === null)
|
|
9422
|
-
return results;
|
|
9237
|
+
if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
|
|
9423
9238
|
const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
|
|
9424
9239
|
const filtered = [];
|
|
9425
9240
|
for (const result of results) {
|
|
9426
|
-
if (scope?.sessionId && result.sessionId !== scope.sessionId)
|
|
9427
|
-
|
|
9428
|
-
if (scope?.
|
|
9429
|
-
continue;
|
|
9430
|
-
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
|
|
9431
|
-
continue;
|
|
9241
|
+
if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
|
|
9242
|
+
if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
|
|
9243
|
+
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
|
|
9432
9244
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9433
|
-
if (!event)
|
|
9434
|
-
|
|
9435
|
-
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
|
|
9436
|
-
continue;
|
|
9245
|
+
if (!event) continue;
|
|
9246
|
+
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
|
|
9437
9247
|
if (normalizedIncludes.length > 0) {
|
|
9438
9248
|
const lc = event.content.toLowerCase();
|
|
9439
|
-
if (!normalizedIncludes.some((needle) => lc.includes(needle)))
|
|
9440
|
-
continue;
|
|
9249
|
+
if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
|
|
9441
9250
|
}
|
|
9442
|
-
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
|
|
9443
|
-
continue;
|
|
9251
|
+
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
|
|
9444
9252
|
const projectHash = this.extractProjectHash(event.metadata);
|
|
9445
9253
|
filtered.push({ result, projectHash });
|
|
9446
9254
|
}
|
|
@@ -9457,27 +9265,21 @@ var Retriever = class {
|
|
|
9457
9265
|
});
|
|
9458
9266
|
}
|
|
9459
9267
|
normalizeFacetFilters(facets) {
|
|
9460
|
-
if (!facets || facets.length === 0)
|
|
9461
|
-
return null;
|
|
9268
|
+
if (!facets || facets.length === 0) return null;
|
|
9462
9269
|
const normalized = [];
|
|
9463
9270
|
for (const facet of facets) {
|
|
9464
9271
|
const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
|
|
9465
9272
|
const value = typeof facet.value === "string" ? facet.value.trim() : "";
|
|
9466
|
-
if (!parsedDimension.success || !value)
|
|
9467
|
-
return [];
|
|
9273
|
+
if (!parsedDimension.success || !value) return [];
|
|
9468
9274
|
normalized.push({ dimension: parsedDimension.data, value });
|
|
9469
9275
|
}
|
|
9470
9276
|
return normalized;
|
|
9471
9277
|
}
|
|
9472
9278
|
async applyFacetFilters(results, options) {
|
|
9473
|
-
if (options.facets === null)
|
|
9474
|
-
|
|
9475
|
-
if (options.
|
|
9476
|
-
|
|
9477
|
-
if (!options.projectHash)
|
|
9478
|
-
return [];
|
|
9479
|
-
if (!this.eventStore.getDatabase)
|
|
9480
|
-
return [];
|
|
9279
|
+
if (options.facets === null) return results;
|
|
9280
|
+
if (options.facets.length === 0) return [];
|
|
9281
|
+
if (!options.projectHash) return [];
|
|
9282
|
+
if (!this.eventStore.getDatabase) return [];
|
|
9481
9283
|
const repo = new FacetRepository(this.eventStore.getDatabase());
|
|
9482
9284
|
const filtered = [];
|
|
9483
9285
|
for (const result of results) {
|
|
@@ -9534,14 +9336,11 @@ var Retriever = class {
|
|
|
9534
9336
|
return (result.graphPaths || []).length > 0;
|
|
9535
9337
|
}
|
|
9536
9338
|
extractProjectHash(metadata) {
|
|
9537
|
-
if (!metadata || typeof metadata !== "object")
|
|
9538
|
-
return void 0;
|
|
9339
|
+
if (!metadata || typeof metadata !== "object") return void 0;
|
|
9539
9340
|
const scope = metadata.scope;
|
|
9540
|
-
if (!scope || typeof scope !== "object")
|
|
9541
|
-
return void 0;
|
|
9341
|
+
if (!scope || typeof scope !== "object") return void 0;
|
|
9542
9342
|
const project = scope.project;
|
|
9543
|
-
if (!project || typeof project !== "object")
|
|
9544
|
-
return void 0;
|
|
9343
|
+
if (!project || typeof project !== "object") return void 0;
|
|
9545
9344
|
const hash = project.hash;
|
|
9546
9345
|
return typeof hash === "string" && hash.length > 0 ? hash : void 0;
|
|
9547
9346
|
}
|
|
@@ -9551,52 +9350,48 @@ var Retriever = class {
|
|
|
9551
9350
|
async retrieveRecent(limit = 100) {
|
|
9552
9351
|
return this.eventStore.getRecentEvents(limit);
|
|
9553
9352
|
}
|
|
9554
|
-
async enrichResults(results, options) {
|
|
9353
|
+
async enrichResults(results, options, query) {
|
|
9555
9354
|
const memories = [];
|
|
9556
9355
|
for (const result of results) {
|
|
9557
9356
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9558
|
-
if (!event)
|
|
9559
|
-
continue;
|
|
9357
|
+
if (!event) continue;
|
|
9560
9358
|
if (this.graduation) {
|
|
9561
9359
|
this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
|
|
9562
9360
|
}
|
|
9563
9361
|
let sessionContext;
|
|
9564
9362
|
if (options.includeSessionContext) {
|
|
9565
|
-
sessionContext = await this.getSessionContext(event.sessionId, event.id);
|
|
9363
|
+
sessionContext = await this.getSessionContext(event.sessionId, event.id, query);
|
|
9566
9364
|
}
|
|
9567
9365
|
memories.push({ event, score: result.score, sessionContext });
|
|
9568
9366
|
}
|
|
9569
9367
|
return memories;
|
|
9570
9368
|
}
|
|
9571
|
-
async getSessionContext(sessionId, eventId) {
|
|
9369
|
+
async getSessionContext(sessionId, eventId, query) {
|
|
9572
9370
|
const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
|
|
9573
9371
|
const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
|
|
9574
|
-
if (eventIndex === -1)
|
|
9575
|
-
return void 0;
|
|
9372
|
+
if (eventIndex === -1) return void 0;
|
|
9576
9373
|
const start = Math.max(0, eventIndex - 1);
|
|
9577
9374
|
const end = Math.min(sessionEvents.length, eventIndex + 2);
|
|
9578
9375
|
const contextEvents = sessionEvents.slice(start, end);
|
|
9579
|
-
if (contextEvents.length <= 1)
|
|
9580
|
-
|
|
9581
|
-
|
|
9376
|
+
if (contextEvents.length <= 1) return void 0;
|
|
9377
|
+
const suppressStaleState = isCurrentStateQuery(query);
|
|
9378
|
+
const contextLines = contextEvents.filter((e) => e.id !== eventId).filter((e) => !isLowSignalContextContent(e.content)).filter((e) => !(suppressStaleState && isStaleOrSupersededContent(e.content))).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`);
|
|
9379
|
+
return contextLines.length > 0 ? contextLines.join("\n") : void 0;
|
|
9582
9380
|
}
|
|
9583
9381
|
buildUnifiedContext(projectResult, sharedMemories) {
|
|
9584
9382
|
let context = projectResult.context;
|
|
9585
|
-
if (sharedMemories.length === 0)
|
|
9586
|
-
return context;
|
|
9383
|
+
if (sharedMemories.length === 0) return context;
|
|
9587
9384
|
context += "\n\n## Cross-Project Knowledge\n\n";
|
|
9588
9385
|
for (const memory of sharedMemories.slice(0, 3)) {
|
|
9589
9386
|
context += `### ${memory.title}
|
|
9590
9387
|
`;
|
|
9591
|
-
if (memory.symptoms.length > 0)
|
|
9592
|
-
context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9388
|
+
if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9593
9389
|
`;
|
|
9594
9390
|
context += `**Root Cause:** ${memory.rootCause}
|
|
9595
9391
|
`;
|
|
9596
9392
|
context += `**Solution:** ${memory.solution}
|
|
9597
9393
|
`;
|
|
9598
|
-
if (memory.technologies && memory.technologies.length > 0)
|
|
9599
|
-
context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9394
|
+
if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9600
9395
|
`;
|
|
9601
9396
|
context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
|
|
9602
9397
|
|
|
@@ -9610,13 +9405,11 @@ var Retriever = class {
|
|
|
9610
9405
|
for (const memory of memories) {
|
|
9611
9406
|
const memoryText = this.formatMemory(memory);
|
|
9612
9407
|
const memoryTokens = this.estimateTokens(memoryText);
|
|
9613
|
-
if (currentTokens + memoryTokens > maxTokens)
|
|
9614
|
-
break;
|
|
9408
|
+
if (currentTokens + memoryTokens > maxTokens) break;
|
|
9615
9409
|
parts.push(memoryText);
|
|
9616
9410
|
currentTokens += memoryTokens;
|
|
9617
9411
|
}
|
|
9618
|
-
if (parts.length === 0)
|
|
9619
|
-
return "";
|
|
9412
|
+
if (parts.length === 0) return "";
|
|
9620
9413
|
return `## Relevant Memories
|
|
9621
9414
|
|
|
9622
9415
|
${parts.join("\n\n---\n\n")}`;
|
|
@@ -9626,19 +9419,16 @@ ${parts.join("\n\n---\n\n")}`;
|
|
|
9626
9419
|
const date = event.timestamp.toISOString().split("T")[0];
|
|
9627
9420
|
let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
|
|
9628
9421
|
${event.content}`;
|
|
9629
|
-
if (sessionContext)
|
|
9630
|
-
text += `
|
|
9422
|
+
if (sessionContext) text += `
|
|
9631
9423
|
|
|
9632
9424
|
_Context:_ ${sessionContext}`;
|
|
9633
9425
|
return text;
|
|
9634
9426
|
}
|
|
9635
9427
|
matchesMetadataScope(metadata, expected) {
|
|
9636
|
-
if (!metadata)
|
|
9637
|
-
return false;
|
|
9428
|
+
if (!metadata) return false;
|
|
9638
9429
|
return Object.entries(expected).every(([path11, value]) => {
|
|
9639
9430
|
const actual = path11.split(".").reduce((acc, key) => {
|
|
9640
|
-
if (typeof acc !== "object" || acc === null)
|
|
9641
|
-
return void 0;
|
|
9431
|
+
if (typeof acc !== "object" || acc === null) return void 0;
|
|
9642
9432
|
return acc[key];
|
|
9643
9433
|
}, metadata);
|
|
9644
9434
|
return actual === value;
|
|
@@ -9648,27 +9438,20 @@ _Context:_ ${sessionContext}`;
|
|
|
9648
9438
|
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);
|
|
9649
9439
|
}
|
|
9650
9440
|
normalizeToken(token) {
|
|
9651
|
-
if (token === "apis")
|
|
9652
|
-
|
|
9653
|
-
if (token === "
|
|
9654
|
-
|
|
9655
|
-
if (token === "does")
|
|
9656
|
-
return token;
|
|
9657
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
9658
|
-
return `${token.slice(0, -3)}y`;
|
|
9441
|
+
if (token === "apis") return "api";
|
|
9442
|
+
if (token === "ids") return "id";
|
|
9443
|
+
if (token === "does") return token;
|
|
9444
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
9659
9445
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
|
|
9660
9446
|
return token.slice(0, -1);
|
|
9661
9447
|
}
|
|
9662
9448
|
return token;
|
|
9663
9449
|
}
|
|
9664
9450
|
keywordOverlap(a, b) {
|
|
9665
|
-
if (a.length === 0 || b.length === 0)
|
|
9666
|
-
return 0;
|
|
9451
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
9667
9452
|
const bs = new Set(b);
|
|
9668
9453
|
let hit = 0;
|
|
9669
|
-
for (const t of a)
|
|
9670
|
-
if (bs.has(t))
|
|
9671
|
-
hit += 1;
|
|
9454
|
+
for (const t of a) if (bs.has(t)) hit += 1;
|
|
9672
9455
|
return hit / a.length;
|
|
9673
9456
|
}
|
|
9674
9457
|
estimateTokens(text) {
|
|
@@ -9689,8 +9472,7 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
9689
9472
|
const seen = /* @__PURE__ */ new Set();
|
|
9690
9473
|
const nodes = [];
|
|
9691
9474
|
for (const candidate of candidates) {
|
|
9692
|
-
if (!candidate.entityId || seen.has(candidate.entityId))
|
|
9693
|
-
continue;
|
|
9475
|
+
if (!candidate.entityId || seen.has(candidate.entityId)) continue;
|
|
9694
9476
|
seen.add(candidate.entityId);
|
|
9695
9477
|
nodes.push({ entityId: candidate.entityId, title: candidate.text });
|
|
9696
9478
|
}
|
|
@@ -9714,16 +9496,14 @@ function graphPathScore(path11, hopPenalty) {
|
|
|
9714
9496
|
return Math.max(0.05, base - hopPenalty * Math.max(0, path11.hops - 1));
|
|
9715
9497
|
}
|
|
9716
9498
|
function clampGraphHops(maxHops) {
|
|
9717
|
-
if (!Number.isFinite(maxHops))
|
|
9718
|
-
return 2;
|
|
9499
|
+
if (!Number.isFinite(maxHops)) return 2;
|
|
9719
9500
|
return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
|
|
9720
9501
|
}
|
|
9721
9502
|
function mergeGraphPaths(existing, incoming) {
|
|
9722
9503
|
const byKey = /* @__PURE__ */ new Map();
|
|
9723
9504
|
for (const path11 of [...existing, ...incoming]) {
|
|
9724
9505
|
const key = [path11.startEntityId, path11.targetType, path11.targetId, path11.hops, ...path11.relationPath].join("\0");
|
|
9725
|
-
if (!byKey.has(key))
|
|
9726
|
-
byKey.set(key, path11);
|
|
9506
|
+
if (!byKey.has(key)) byKey.set(key, path11);
|
|
9727
9507
|
}
|
|
9728
9508
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
9729
9509
|
}
|
|
@@ -9731,10 +9511,8 @@ function graphPathSignature(path11) {
|
|
|
9731
9511
|
return [path11.startEntityId, path11.targetType, path11.targetId, path11.hops, ...path11.relationPath].join("|");
|
|
9732
9512
|
}
|
|
9733
9513
|
function compareStable(a, b) {
|
|
9734
|
-
if (a < b)
|
|
9735
|
-
|
|
9736
|
-
if (a > b)
|
|
9737
|
-
return 1;
|
|
9514
|
+
if (a < b) return -1;
|
|
9515
|
+
if (a > b) return 1;
|
|
9738
9516
|
return 0;
|
|
9739
9517
|
}
|
|
9740
9518
|
function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
@@ -9746,6 +9524,7 @@ var RetrievalAnalyticsService = class {
|
|
|
9746
9524
|
constructor(deps) {
|
|
9747
9525
|
this.deps = deps;
|
|
9748
9526
|
}
|
|
9527
|
+
deps;
|
|
9749
9528
|
async getRetrievalTraceStats() {
|
|
9750
9529
|
await this.deps.initialize();
|
|
9751
9530
|
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
@@ -9823,6 +9602,7 @@ var RetrievalDisclosureService = class {
|
|
|
9823
9602
|
constructor(deps) {
|
|
9824
9603
|
this.deps = deps;
|
|
9825
9604
|
}
|
|
9605
|
+
deps;
|
|
9826
9606
|
async search(query, options) {
|
|
9827
9607
|
const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
|
|
9828
9608
|
const debugByEventId = this.buildDebugIndex(result);
|
|
@@ -9852,8 +9632,7 @@ var RetrievalDisclosureService = class {
|
|
|
9852
9632
|
return this.expandShared(parsedId.entryId);
|
|
9853
9633
|
}
|
|
9854
9634
|
const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9855
|
-
if (!targetEvent)
|
|
9856
|
-
return null;
|
|
9635
|
+
if (!targetEvent) return null;
|
|
9857
9636
|
const windowSize = Math.max(0, options?.windowSize ?? 3);
|
|
9858
9637
|
const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
9859
9638
|
const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
|
|
@@ -9877,8 +9656,7 @@ var RetrievalDisclosureService = class {
|
|
|
9877
9656
|
return this.sourceShared(parsedId.entryId);
|
|
9878
9657
|
}
|
|
9879
9658
|
const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9880
|
-
if (!rawEvent)
|
|
9881
|
-
return null;
|
|
9659
|
+
if (!rawEvent) return null;
|
|
9882
9660
|
return {
|
|
9883
9661
|
...this.sourceReferenceForEvent(rawEvent),
|
|
9884
9662
|
rawEvents: [rawEvent],
|
|
@@ -9887,8 +9665,7 @@ var RetrievalDisclosureService = class {
|
|
|
9887
9665
|
}
|
|
9888
9666
|
async expandShared(entryId) {
|
|
9889
9667
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9890
|
-
if (!entry)
|
|
9891
|
-
return null;
|
|
9668
|
+
if (!entry) return null;
|
|
9892
9669
|
return {
|
|
9893
9670
|
target: this.sharedToEnvelope(entry),
|
|
9894
9671
|
surroundingFacts: [],
|
|
@@ -9899,8 +9676,7 @@ var RetrievalDisclosureService = class {
|
|
|
9899
9676
|
}
|
|
9900
9677
|
async sourceShared(entryId) {
|
|
9901
9678
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9902
|
-
if (!entry)
|
|
9903
|
-
return null;
|
|
9679
|
+
if (!entry) return null;
|
|
9904
9680
|
const sourceReference = this.sourceReferenceForShared(entry);
|
|
9905
9681
|
return {
|
|
9906
9682
|
...sourceReference,
|
|
@@ -9986,38 +9762,25 @@ var RetrievalDisclosureService = class {
|
|
|
9986
9762
|
const reasons = /* @__PURE__ */ new Set();
|
|
9987
9763
|
const usedVector = this.usedVector(result);
|
|
9988
9764
|
const usedKeyword = this.usedKeyword(result);
|
|
9989
|
-
if (usedVector && (debug?.semanticScore ?? 0) > 0)
|
|
9990
|
-
|
|
9991
|
-
if ((debug?.
|
|
9992
|
-
|
|
9993
|
-
if ((debug?.
|
|
9994
|
-
|
|
9995
|
-
if (
|
|
9996
|
-
|
|
9997
|
-
if (
|
|
9998
|
-
reasons.add("entity_overlap");
|
|
9999
|
-
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
|
|
10000
|
-
reasons.add("summary_fallback");
|
|
10001
|
-
if (memory.sessionContext)
|
|
10002
|
-
reasons.add("continuity_link");
|
|
10003
|
-
if (memory.event.eventType === "tool_observation")
|
|
10004
|
-
reasons.add("tool_followup");
|
|
10005
|
-
if (reasons.size === 0)
|
|
10006
|
-
reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
9765
|
+
if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
|
|
9766
|
+
if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
|
|
9767
|
+
if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
|
|
9768
|
+
if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
|
|
9769
|
+
if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
|
|
9770
|
+
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
|
|
9771
|
+
if (memory.sessionContext) reasons.add("continuity_link");
|
|
9772
|
+
if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
|
|
9773
|
+
if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10007
9774
|
return Array.from(reasons);
|
|
10008
9775
|
}
|
|
10009
9776
|
reasonsForContextEvent(event) {
|
|
10010
|
-
if (event.eventType === "tool_observation")
|
|
10011
|
-
|
|
10012
|
-
if (event.eventType === "session_summary")
|
|
10013
|
-
return ["summary_fallback"];
|
|
9777
|
+
if (event.eventType === "tool_observation") return ["tool_followup"];
|
|
9778
|
+
if (event.eventType === "session_summary") return ["summary_fallback"];
|
|
10014
9779
|
return ["continuity_link"];
|
|
10015
9780
|
}
|
|
10016
9781
|
resultTypeForEvent(event) {
|
|
10017
|
-
if (event.eventType === "session_summary")
|
|
10018
|
-
|
|
10019
|
-
if (event.eventType === "tool_observation")
|
|
10020
|
-
return "tool_evidence";
|
|
9782
|
+
if (event.eventType === "session_summary") return "summary";
|
|
9783
|
+
if (event.eventType === "tool_observation") return "tool_evidence";
|
|
10021
9784
|
return "source";
|
|
10022
9785
|
}
|
|
10023
9786
|
sourceReferenceForEvent(event) {
|
|
@@ -10041,21 +9804,15 @@ var RetrievalDisclosureService = class {
|
|
|
10041
9804
|
}
|
|
10042
9805
|
sourceTypeForEvent(event) {
|
|
10043
9806
|
const metadata = event.metadata || {};
|
|
10044
|
-
if (event.eventType === "tool_observation")
|
|
10045
|
-
|
|
10046
|
-
if (typeof metadata.
|
|
10047
|
-
return "transcript";
|
|
10048
|
-
if (typeof metadata.importedFrom === "string")
|
|
10049
|
-
return "imported_history";
|
|
9807
|
+
if (event.eventType === "tool_observation") return "tool_output";
|
|
9808
|
+
if (typeof metadata.transcriptPath === "string") return "transcript";
|
|
9809
|
+
if (typeof metadata.importedFrom === "string") return "imported_history";
|
|
10050
9810
|
return "raw_event";
|
|
10051
9811
|
}
|
|
10052
9812
|
titleForEvent(event) {
|
|
10053
|
-
if (event.eventType === "session_summary")
|
|
10054
|
-
|
|
10055
|
-
if (event.eventType === "
|
|
10056
|
-
return "Tool evidence";
|
|
10057
|
-
if (event.eventType === "agent_response")
|
|
10058
|
-
return "Agent response";
|
|
9813
|
+
if (event.eventType === "session_summary") return "Session summary";
|
|
9814
|
+
if (event.eventType === "tool_observation") return "Tool evidence";
|
|
9815
|
+
if (event.eventType === "agent_response") return "Agent response";
|
|
10059
9816
|
return "User prompt";
|
|
10060
9817
|
}
|
|
10061
9818
|
usedVector(result) {
|
|
@@ -10081,8 +9838,7 @@ var RetrievalDisclosureService = class {
|
|
|
10081
9838
|
}
|
|
10082
9839
|
preview(content, maxLength) {
|
|
10083
9840
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
10084
|
-
if (normalized.length <= maxLength)
|
|
10085
|
-
return normalized;
|
|
9841
|
+
if (normalized.length <= maxLength) return normalized;
|
|
10086
9842
|
return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
10087
9843
|
}
|
|
10088
9844
|
};
|
|
@@ -10111,6 +9867,7 @@ var RetrievalOrchestrator = class {
|
|
|
10111
9867
|
this.deps = deps;
|
|
10112
9868
|
this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
|
|
10113
9869
|
}
|
|
9870
|
+
deps;
|
|
10114
9871
|
/**
|
|
10115
9872
|
* Retrieve relevant memories for a query.
|
|
10116
9873
|
*/
|
|
@@ -10192,8 +9949,7 @@ var RetrievalOrchestrator = class {
|
|
|
10192
9949
|
* the heavier retrieval/vector initialization path for prompt telemetry.
|
|
10193
9950
|
*/
|
|
10194
9951
|
async incrementMemoryAccess(eventIds) {
|
|
10195
|
-
if (eventIds.length === 0)
|
|
10196
|
-
return;
|
|
9952
|
+
if (eventIds.length === 0) return;
|
|
10197
9953
|
await this.deps.accessStore.incrementAccessCount(eventIds);
|
|
10198
9954
|
}
|
|
10199
9955
|
/**
|
|
@@ -10206,10 +9962,8 @@ var RetrievalOrchestrator = class {
|
|
|
10206
9962
|
resolveGraphHopOptions(callerOptions) {
|
|
10207
9963
|
const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
|
|
10208
9964
|
const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
|
|
10209
|
-
if (!callerOptions)
|
|
10210
|
-
|
|
10211
|
-
if (!graphExpansion)
|
|
10212
|
-
return callerOptions;
|
|
9965
|
+
if (!callerOptions) return durableOptions;
|
|
9966
|
+
if (!graphExpansion) return callerOptions;
|
|
10213
9967
|
if (graphExpansion.enabled !== true) {
|
|
10214
9968
|
return {
|
|
10215
9969
|
...callerOptions,
|
|
@@ -10269,12 +10023,10 @@ var RetrievalOrchestrator = class {
|
|
|
10269
10023
|
const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
|
|
10270
10024
|
const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
|
|
10271
10025
|
const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
|
|
10272
|
-
if (!allFinite)
|
|
10273
|
-
return void 0;
|
|
10026
|
+
if (!allFinite) return void 0;
|
|
10274
10027
|
const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
|
|
10275
10028
|
const total = semantic + lexical + recency;
|
|
10276
|
-
if (!nonNegative || total <= 0)
|
|
10277
|
-
return void 0;
|
|
10029
|
+
if (!nonNegative || total <= 0) return void 0;
|
|
10278
10030
|
return {
|
|
10279
10031
|
semantic: semantic / total,
|
|
10280
10032
|
lexical: lexical / total,
|
|
@@ -10283,17 +10035,14 @@ var RetrievalOrchestrator = class {
|
|
|
10283
10035
|
}
|
|
10284
10036
|
async getRerankWeights(adaptive) {
|
|
10285
10037
|
const configured = this.getConfiguredRerankWeights();
|
|
10286
|
-
if (configured)
|
|
10287
|
-
|
|
10288
|
-
if (adaptive)
|
|
10289
|
-
return this.getAdaptiveRerankWeights();
|
|
10038
|
+
if (configured) return configured;
|
|
10039
|
+
if (adaptive) return this.getAdaptiveRerankWeights();
|
|
10290
10040
|
return void 0;
|
|
10291
10041
|
}
|
|
10292
10042
|
async getAdaptiveRerankWeights() {
|
|
10293
10043
|
try {
|
|
10294
10044
|
const stats = await this.deps.traceStore.getHelpfulnessStats();
|
|
10295
|
-
if (stats.totalEvaluated < 20)
|
|
10296
|
-
return void 0;
|
|
10045
|
+
if (stats.totalEvaluated < 20) return void 0;
|
|
10297
10046
|
let semantic = 0.7;
|
|
10298
10047
|
let lexical = 0.2;
|
|
10299
10048
|
let recency = 0.1;
|
|
@@ -10315,11 +10064,9 @@ var RetrievalOrchestrator = class {
|
|
|
10315
10064
|
}
|
|
10316
10065
|
}
|
|
10317
10066
|
async rewriteQueryIntent(query) {
|
|
10318
|
-
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
|
|
10319
|
-
return null;
|
|
10067
|
+
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
|
|
10320
10068
|
const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
|
|
10321
|
-
if (!apiUrl)
|
|
10322
|
-
return null;
|
|
10069
|
+
if (!apiUrl) return null;
|
|
10323
10070
|
const controller = new AbortController();
|
|
10324
10071
|
const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
|
|
10325
10072
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10345,11 +10092,9 @@ var RetrievalOrchestrator = class {
|
|
|
10345
10092
|
signal: controller.signal
|
|
10346
10093
|
});
|
|
10347
10094
|
const text = (await res.text()).trim();
|
|
10348
|
-
if (!text)
|
|
10349
|
-
return null;
|
|
10095
|
+
if (!text) return null;
|
|
10350
10096
|
const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
|
|
10351
|
-
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
|
|
10352
|
-
return null;
|
|
10097
|
+
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
|
|
10353
10098
|
return oneLine;
|
|
10354
10099
|
} catch {
|
|
10355
10100
|
return null;
|
|
@@ -10491,8 +10236,7 @@ function createMemoryEngineServices(options) {
|
|
|
10491
10236
|
};
|
|
10492
10237
|
}
|
|
10493
10238
|
function shouldEnablePerspectiveDeriver(options) {
|
|
10494
|
-
if (options.readOnly)
|
|
10495
|
-
return false;
|
|
10239
|
+
if (options.readOnly) return false;
|
|
10496
10240
|
const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
|
|
10497
10241
|
return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
|
|
10498
10242
|
}
|
|
@@ -10526,6 +10270,9 @@ var GraduationWorker = class {
|
|
|
10526
10270
|
this.graduation = graduation;
|
|
10527
10271
|
this.config = config;
|
|
10528
10272
|
}
|
|
10273
|
+
eventStore;
|
|
10274
|
+
graduation;
|
|
10275
|
+
config;
|
|
10529
10276
|
running = false;
|
|
10530
10277
|
timeout = null;
|
|
10531
10278
|
lastEvaluated = /* @__PURE__ */ new Map();
|
|
@@ -10533,8 +10280,7 @@ var GraduationWorker = class {
|
|
|
10533
10280
|
* Start the graduation worker
|
|
10534
10281
|
*/
|
|
10535
10282
|
start() {
|
|
10536
|
-
if (this.running)
|
|
10537
|
-
return;
|
|
10283
|
+
if (this.running) return;
|
|
10538
10284
|
this.running = true;
|
|
10539
10285
|
this.scheduleNext();
|
|
10540
10286
|
}
|
|
@@ -10564,8 +10310,7 @@ var GraduationWorker = class {
|
|
|
10564
10310
|
* Schedule the next graduation check
|
|
10565
10311
|
*/
|
|
10566
10312
|
scheduleNext() {
|
|
10567
|
-
if (!this.running)
|
|
10568
|
-
return;
|
|
10313
|
+
if (!this.running) return;
|
|
10569
10314
|
this.timeout = setTimeout(
|
|
10570
10315
|
() => this.run(),
|
|
10571
10316
|
this.config.evaluationIntervalMs
|
|
@@ -10575,8 +10320,7 @@ var GraduationWorker = class {
|
|
|
10575
10320
|
* Run graduation evaluation
|
|
10576
10321
|
*/
|
|
10577
10322
|
async run() {
|
|
10578
|
-
if (!this.running)
|
|
10579
|
-
return;
|
|
10323
|
+
if (!this.running) return;
|
|
10580
10324
|
try {
|
|
10581
10325
|
await this.runGraduation();
|
|
10582
10326
|
} catch (error) {
|
|
@@ -10640,10 +10384,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
10640
10384
|
maxRetries: 3
|
|
10641
10385
|
};
|
|
10642
10386
|
function parseJsonArray(value) {
|
|
10643
|
-
if (Array.isArray(value))
|
|
10644
|
-
|
|
10645
|
-
if (typeof value !== "string" || value.trim().length === 0)
|
|
10646
|
-
return [];
|
|
10387
|
+
if (Array.isArray(value)) return value;
|
|
10388
|
+
if (typeof value !== "string" || value.trim().length === 0) return [];
|
|
10647
10389
|
try {
|
|
10648
10390
|
const parsed = JSON.parse(value);
|
|
10649
10391
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -10673,8 +10415,7 @@ var VectorWorker = class {
|
|
|
10673
10415
|
* Start the worker polling loop
|
|
10674
10416
|
*/
|
|
10675
10417
|
start() {
|
|
10676
|
-
if (this.running)
|
|
10677
|
-
return;
|
|
10418
|
+
if (this.running) return;
|
|
10678
10419
|
this.running = true;
|
|
10679
10420
|
this.stopping = false;
|
|
10680
10421
|
this.poll();
|
|
@@ -10750,8 +10491,7 @@ var VectorWorker = class {
|
|
|
10750
10491
|
* Poll for new items
|
|
10751
10492
|
*/
|
|
10752
10493
|
async poll() {
|
|
10753
|
-
if (!this.running || this.stopping)
|
|
10754
|
-
return;
|
|
10494
|
+
if (!this.running || this.stopping) return;
|
|
10755
10495
|
try {
|
|
10756
10496
|
await this.processBatch();
|
|
10757
10497
|
} catch (error) {
|
|
@@ -10796,6 +10536,7 @@ var DefaultContentProvider = class {
|
|
|
10796
10536
|
constructor(db) {
|
|
10797
10537
|
this.db = db;
|
|
10798
10538
|
}
|
|
10539
|
+
db;
|
|
10799
10540
|
async getContent(itemKind, itemId) {
|
|
10800
10541
|
switch (itemKind) {
|
|
10801
10542
|
case "entry":
|
|
@@ -10816,8 +10557,7 @@ var DefaultContentProvider = class {
|
|
|
10816
10557
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
10817
10558
|
[entryId]
|
|
10818
10559
|
);
|
|
10819
|
-
if (rows.length === 0)
|
|
10820
|
-
return null;
|
|
10560
|
+
if (rows.length === 0) return null;
|
|
10821
10561
|
const row = rows[0];
|
|
10822
10562
|
const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
|
|
10823
10563
|
return {
|
|
@@ -10836,8 +10576,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10836
10576
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
10837
10577
|
[taskId]
|
|
10838
10578
|
);
|
|
10839
|
-
if (rows.length === 0)
|
|
10840
|
-
return null;
|
|
10579
|
+
if (rows.length === 0) return null;
|
|
10841
10580
|
const row = rows[0];
|
|
10842
10581
|
return {
|
|
10843
10582
|
content: row.search_text || row.title,
|
|
@@ -10853,8 +10592,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10853
10592
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
10854
10593
|
[eventId]
|
|
10855
10594
|
);
|
|
10856
|
-
if (rows.length === 0)
|
|
10857
|
-
return null;
|
|
10595
|
+
if (rows.length === 0) return null;
|
|
10858
10596
|
const row = rows[0];
|
|
10859
10597
|
return {
|
|
10860
10598
|
content: row.content,
|
|
@@ -10882,8 +10620,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10882
10620
|
}
|
|
10883
10621
|
throw error;
|
|
10884
10622
|
}
|
|
10885
|
-
if (rows.length === 0)
|
|
10886
|
-
return null;
|
|
10623
|
+
if (rows.length === 0) return null;
|
|
10887
10624
|
const row = rows[0];
|
|
10888
10625
|
const sourceEventIds = parseJsonArray(row.source_event_ids_json);
|
|
10889
10626
|
const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
|
|
@@ -10925,8 +10662,7 @@ var VectorWorkerV2 = class {
|
|
|
10925
10662
|
* Start the worker polling loop
|
|
10926
10663
|
*/
|
|
10927
10664
|
start() {
|
|
10928
|
-
if (this.running)
|
|
10929
|
-
return;
|
|
10665
|
+
if (this.running) return;
|
|
10930
10666
|
this.running = true;
|
|
10931
10667
|
this.stopping = false;
|
|
10932
10668
|
this.poll();
|
|
@@ -10996,8 +10732,7 @@ var VectorWorkerV2 = class {
|
|
|
10996
10732
|
* Poll for new jobs
|
|
10997
10733
|
*/
|
|
10998
10734
|
async poll() {
|
|
10999
|
-
if (!this.running || this.stopping)
|
|
11000
|
-
return;
|
|
10735
|
+
if (!this.running || this.stopping) return;
|
|
11001
10736
|
try {
|
|
11002
10737
|
await this.processBatch();
|
|
11003
10738
|
} catch (error) {
|
|
@@ -11064,8 +10799,7 @@ function createMemoryRuntimeService(deps) {
|
|
|
11064
10799
|
let graduationWorker = null;
|
|
11065
10800
|
return {
|
|
11066
10801
|
async initialize() {
|
|
11067
|
-
if (initialized)
|
|
11068
|
-
return;
|
|
10802
|
+
if (initialized) return;
|
|
11069
10803
|
await deps.sqliteStore.initialize();
|
|
11070
10804
|
if (deps.lightweightMode) {
|
|
11071
10805
|
initialized = true;
|
|
@@ -11159,8 +10893,7 @@ var SharedEventStore = class {
|
|
|
11159
10893
|
this.db = createDatabase(dbPath);
|
|
11160
10894
|
}
|
|
11161
10895
|
async initialize() {
|
|
11162
|
-
if (this.initialized)
|
|
11163
|
-
return;
|
|
10896
|
+
if (this.initialized) return;
|
|
11164
10897
|
await dbRun(this.db, `
|
|
11165
10898
|
CREATE TABLE IF NOT EXISTS shared_troubleshooting (
|
|
11166
10899
|
entry_id VARCHAR PRIMARY KEY,
|
|
@@ -11250,6 +10983,10 @@ var SharedPromoter = class {
|
|
|
11250
10983
|
this.embedder = embedder;
|
|
11251
10984
|
this.config = config;
|
|
11252
10985
|
}
|
|
10986
|
+
sharedStore;
|
|
10987
|
+
sharedVectorStore;
|
|
10988
|
+
embedder;
|
|
10989
|
+
config;
|
|
11253
10990
|
/**
|
|
11254
10991
|
* Check if an entry is eligible for promotion
|
|
11255
10992
|
*/
|
|
@@ -11431,6 +11168,7 @@ var SharedStore = class {
|
|
|
11431
11168
|
constructor(sharedEventStore) {
|
|
11432
11169
|
this.sharedEventStore = sharedEventStore;
|
|
11433
11170
|
}
|
|
11171
|
+
sharedEventStore;
|
|
11434
11172
|
get db() {
|
|
11435
11173
|
return this.sharedEventStore.getDatabase();
|
|
11436
11174
|
}
|
|
@@ -11535,8 +11273,7 @@ var SharedStore = class {
|
|
|
11535
11273
|
`SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
|
|
11536
11274
|
[entryId]
|
|
11537
11275
|
);
|
|
11538
|
-
if (rows.length === 0)
|
|
11539
|
-
return null;
|
|
11276
|
+
if (rows.length === 0) return null;
|
|
11540
11277
|
return this.rowToEntry(rows[0]);
|
|
11541
11278
|
}
|
|
11542
11279
|
/**
|
|
@@ -11549,8 +11286,7 @@ var SharedStore = class {
|
|
|
11549
11286
|
WHERE source_project_hash = ? AND source_entry_id = ?`,
|
|
11550
11287
|
[projectHash, sourceEntryId]
|
|
11551
11288
|
);
|
|
11552
|
-
if (rows.length === 0)
|
|
11553
|
-
return null;
|
|
11289
|
+
if (rows.length === 0) return null;
|
|
11554
11290
|
return this.rowToEntry(rows[0]);
|
|
11555
11291
|
}
|
|
11556
11292
|
/**
|
|
@@ -11660,6 +11396,7 @@ var SharedVectorStore = class {
|
|
|
11660
11396
|
constructor(dbPath) {
|
|
11661
11397
|
this.dbPath = dbPath;
|
|
11662
11398
|
}
|
|
11399
|
+
dbPath;
|
|
11663
11400
|
db = null;
|
|
11664
11401
|
table = null;
|
|
11665
11402
|
tableName = "shared_knowledge";
|
|
@@ -11667,8 +11404,7 @@ var SharedVectorStore = class {
|
|
|
11667
11404
|
* Initialize LanceDB connection
|
|
11668
11405
|
*/
|
|
11669
11406
|
async initialize() {
|
|
11670
|
-
if (this.db)
|
|
11671
|
-
return;
|
|
11407
|
+
if (this.db) return;
|
|
11672
11408
|
this.db = await lancedb2.connect(this.dbPath);
|
|
11673
11409
|
try {
|
|
11674
11410
|
const tables = await this.db.tableNames();
|
|
@@ -11710,8 +11446,7 @@ var SharedVectorStore = class {
|
|
|
11710
11446
|
* Add multiple records in batch
|
|
11711
11447
|
*/
|
|
11712
11448
|
async upsertBatch(records) {
|
|
11713
|
-
if (records.length === 0)
|
|
11714
|
-
return;
|
|
11449
|
+
if (records.length === 0) return;
|
|
11715
11450
|
await this.initialize();
|
|
11716
11451
|
if (!this.db) {
|
|
11717
11452
|
throw new Error("Database not initialized");
|
|
@@ -11772,24 +11507,21 @@ var SharedVectorStore = class {
|
|
|
11772
11507
|
* Delete vector by entry ID
|
|
11773
11508
|
*/
|
|
11774
11509
|
async delete(entryId) {
|
|
11775
|
-
if (!this.table)
|
|
11776
|
-
return;
|
|
11510
|
+
if (!this.table) return;
|
|
11777
11511
|
await this.table.delete(`entryId = '${entryId}'`);
|
|
11778
11512
|
}
|
|
11779
11513
|
/**
|
|
11780
11514
|
* Get total count
|
|
11781
11515
|
*/
|
|
11782
11516
|
async count() {
|
|
11783
|
-
if (!this.table)
|
|
11784
|
-
return 0;
|
|
11517
|
+
if (!this.table) return 0;
|
|
11785
11518
|
return this.table.countRows();
|
|
11786
11519
|
}
|
|
11787
11520
|
/**
|
|
11788
11521
|
* Check if vector exists for entry
|
|
11789
11522
|
*/
|
|
11790
11523
|
async exists(entryId) {
|
|
11791
|
-
if (!this.table)
|
|
11792
|
-
return false;
|
|
11524
|
+
if (!this.table) return false;
|
|
11793
11525
|
try {
|
|
11794
11526
|
const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
|
|
11795
11527
|
return results.length > 0;
|
|
@@ -11807,6 +11539,7 @@ var SharedMemoryServices = class {
|
|
|
11807
11539
|
constructor(options) {
|
|
11808
11540
|
this.options = options;
|
|
11809
11541
|
}
|
|
11542
|
+
options;
|
|
11810
11543
|
sharedEventStore = null;
|
|
11811
11544
|
sharedStore = null;
|
|
11812
11545
|
sharedVectorStore = null;
|
|
@@ -11831,8 +11564,7 @@ var SharedMemoryServices = class {
|
|
|
11831
11564
|
return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
|
|
11832
11565
|
}
|
|
11833
11566
|
async initialize() {
|
|
11834
|
-
if (this.options.config?.enabled === false || this.options.readOnly)
|
|
11835
|
-
return;
|
|
11567
|
+
if (this.options.config?.enabled === false || this.options.readOnly) return;
|
|
11836
11568
|
const sharedPath = this.getSharedStoragePath();
|
|
11837
11569
|
this.ensureDirectory(sharedPath, { allowCreate: true });
|
|
11838
11570
|
const store = await this.openStore(sharedPath);
|
|
@@ -11849,14 +11581,11 @@ var SharedMemoryServices = class {
|
|
|
11849
11581
|
this.options.retriever.setSharedStores(store, this.sharedVectorStore);
|
|
11850
11582
|
}
|
|
11851
11583
|
async ensureStoreForRead() {
|
|
11852
|
-
if (this.options.config?.enabled === false)
|
|
11853
|
-
|
|
11854
|
-
if (this.sharedStore)
|
|
11855
|
-
return this.sharedStore;
|
|
11584
|
+
if (this.options.config?.enabled === false) return null;
|
|
11585
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11856
11586
|
const sharedPath = this.getSharedStoragePath();
|
|
11857
11587
|
const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
|
|
11858
|
-
if (!directoryReady)
|
|
11859
|
-
return null;
|
|
11588
|
+
if (!directoryReady) return null;
|
|
11860
11589
|
return this.openStore(sharedPath);
|
|
11861
11590
|
}
|
|
11862
11591
|
async getEntryForDisclosure(entryId) {
|
|
@@ -11873,13 +11602,11 @@ var SharedMemoryServices = class {
|
|
|
11873
11602
|
return this.sharedPromoter.promoteEntry(entry, projectHash);
|
|
11874
11603
|
}
|
|
11875
11604
|
async getStats() {
|
|
11876
|
-
if (!this.sharedStore)
|
|
11877
|
-
return null;
|
|
11605
|
+
if (!this.sharedStore) return null;
|
|
11878
11606
|
return this.sharedStore.getStats();
|
|
11879
11607
|
}
|
|
11880
11608
|
async search(query, options) {
|
|
11881
|
-
if (!this.sharedStore)
|
|
11882
|
-
return [];
|
|
11609
|
+
if (!this.sharedStore) return [];
|
|
11883
11610
|
return this.sharedStore.search(query, options);
|
|
11884
11611
|
}
|
|
11885
11612
|
async close() {
|
|
@@ -11896,8 +11623,7 @@ var SharedMemoryServices = class {
|
|
|
11896
11623
|
this.openStorePromise = null;
|
|
11897
11624
|
}
|
|
11898
11625
|
async openStore(sharedPath) {
|
|
11899
|
-
if (this.sharedStore)
|
|
11900
|
-
return this.sharedStore;
|
|
11626
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11901
11627
|
if (!this.openStorePromise) {
|
|
11902
11628
|
this.openStorePromise = this.createOpenStorePromise(sharedPath);
|
|
11903
11629
|
}
|
|
@@ -11921,10 +11647,8 @@ var SharedMemoryServices = class {
|
|
|
11921
11647
|
return this.sharedStore;
|
|
11922
11648
|
}
|
|
11923
11649
|
ensureDirectory(sharedPath, options) {
|
|
11924
|
-
if (this.factories.existsSync(sharedPath))
|
|
11925
|
-
|
|
11926
|
-
if (!options.allowCreate)
|
|
11927
|
-
return false;
|
|
11650
|
+
if (this.factories.existsSync(sharedPath)) return true;
|
|
11651
|
+
if (!options.allowCreate) return false;
|
|
11928
11652
|
this.factories.mkdirSync(sharedPath);
|
|
11929
11653
|
return true;
|
|
11930
11654
|
}
|