claude-memory-layer 1.0.43 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/cli/index.js +940 -1480
- package/dist/cli/index.js.map +4 -4
- package/dist/core/index.js +1191 -1490
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +411 -749
- package/dist/hooks/post-tool-use.js.map +1 -1
- package/dist/hooks/semantic-daemon.js +400 -727
- package/dist/hooks/semantic-daemon.js.map +1 -1
- package/dist/hooks/session-end.js +396 -719
- package/dist/hooks/session-end.js.map +1 -1
- package/dist/hooks/session-start.js +397 -721
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/stop.js +404 -735
- package/dist/hooks/stop.js.map +1 -1
- package/dist/hooks/user-prompt-submit.js +440 -807
- package/dist/hooks/user-prompt-submit.js.map +1 -1
- package/dist/index.js +1269 -1604
- package/dist/index.js.map +4 -4
- package/dist/mcp/index.js +1443 -1637
- package/dist/mcp/index.js.map +4 -4
- package/dist/server/api/index.js +430 -785
- package/dist/server/api/index.js.map +1 -1
- package/dist/server/index.js +438 -801
- package/dist/server/index.js.map +1 -1
- package/dist/services/memory-service.js +396 -719
- package/dist/services/memory-service.js.map +1 -1
- package/package.json +15 -3
|
@@ -57,6 +57,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
57
57
|
this.options = options;
|
|
58
58
|
this.fileSystem = options.fileSystem ?? defaultFileSystem;
|
|
59
59
|
}
|
|
60
|
+
options;
|
|
60
61
|
fileSystem;
|
|
61
62
|
getEmbeddingModelName() {
|
|
62
63
|
return this.options.getEmbeddingModelName();
|
|
@@ -91,8 +92,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
91
92
|
}
|
|
92
93
|
const worker = this.options.getVectorWorker();
|
|
93
94
|
const wasRunning = worker?.isRunning() || false;
|
|
94
|
-
if (wasRunning)
|
|
95
|
-
worker?.stop();
|
|
95
|
+
if (wasRunning) worker?.stop();
|
|
96
96
|
await this.options.vectorStore.clearAll();
|
|
97
97
|
await this.options.eventStore.clearEmbeddingOutbox();
|
|
98
98
|
const enqueued = await this.reenqueueAllEvents();
|
|
@@ -109,8 +109,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
109
109
|
2
|
|
110
110
|
)
|
|
111
111
|
);
|
|
112
|
-
if (wasRunning)
|
|
113
|
-
worker?.start();
|
|
112
|
+
if (wasRunning) worker?.start();
|
|
114
113
|
return {
|
|
115
114
|
changed: true,
|
|
116
115
|
previousModel,
|
|
@@ -135,15 +134,13 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
135
134
|
let enqueued = 0;
|
|
136
135
|
while (true) {
|
|
137
136
|
const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
|
|
138
|
-
if (page.length === 0)
|
|
139
|
-
break;
|
|
137
|
+
if (page.length === 0) break;
|
|
140
138
|
for (const event of page) {
|
|
141
139
|
await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
|
|
142
140
|
enqueued += 1;
|
|
143
141
|
}
|
|
144
142
|
offset += page.length;
|
|
145
|
-
if (page.length < DEFAULT_PAGE_SIZE)
|
|
146
|
-
break;
|
|
143
|
+
if (page.length < DEFAULT_PAGE_SIZE) break;
|
|
147
144
|
}
|
|
148
145
|
return enqueued;
|
|
149
146
|
}
|
|
@@ -161,12 +158,9 @@ import { randomUUID } from "crypto";
|
|
|
161
158
|
// src/core/db-wrapper.ts
|
|
162
159
|
import BetterSqlite3 from "better-sqlite3";
|
|
163
160
|
function toDate(value) {
|
|
164
|
-
if (value instanceof Date)
|
|
165
|
-
|
|
166
|
-
if (typeof value === "
|
|
167
|
-
return new Date(value);
|
|
168
|
-
if (typeof value === "number")
|
|
169
|
-
return new Date(value);
|
|
161
|
+
if (value instanceof Date) return value;
|
|
162
|
+
if (typeof value === "string") return new Date(value);
|
|
163
|
+
if (typeof value === "number") return new Date(value);
|
|
170
164
|
return new Date(String(value));
|
|
171
165
|
}
|
|
172
166
|
function createDatabase(dbPath, options) {
|
|
@@ -190,6 +184,8 @@ var WorkingSetStore = class {
|
|
|
190
184
|
this.eventStore = eventStore;
|
|
191
185
|
this.config = config;
|
|
192
186
|
}
|
|
187
|
+
eventStore;
|
|
188
|
+
config;
|
|
193
189
|
get db() {
|
|
194
190
|
return this.eventStore.getDatabase();
|
|
195
191
|
}
|
|
@@ -275,8 +271,7 @@ var WorkingSetStore = class {
|
|
|
275
271
|
* Prune specific events from working set (after consolidation)
|
|
276
272
|
*/
|
|
277
273
|
async prune(eventIds) {
|
|
278
|
-
if (eventIds.length === 0)
|
|
279
|
-
return;
|
|
274
|
+
if (eventIds.length === 0) return;
|
|
280
275
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
281
276
|
await dbRun(
|
|
282
277
|
this.db,
|
|
@@ -346,8 +341,7 @@ var WorkingSetStore = class {
|
|
|
346
341
|
LIMIT ?`,
|
|
347
342
|
[maxEvents]
|
|
348
343
|
);
|
|
349
|
-
if (keepIds.length === 0)
|
|
350
|
-
return;
|
|
344
|
+
if (keepIds.length === 0) return;
|
|
351
345
|
const keepIdList = keepIds.map((r) => r.id);
|
|
352
346
|
const placeholders = keepIdList.map(() => "?").join(",");
|
|
353
347
|
await dbRun(
|
|
@@ -394,6 +388,7 @@ var ConsolidatedStore = class {
|
|
|
394
388
|
constructor(eventStore) {
|
|
395
389
|
this.eventStore = eventStore;
|
|
396
390
|
}
|
|
391
|
+
eventStore;
|
|
397
392
|
get db() {
|
|
398
393
|
return this.eventStore.getDatabase();
|
|
399
394
|
}
|
|
@@ -426,8 +421,7 @@ var ConsolidatedStore = class {
|
|
|
426
421
|
`SELECT * FROM consolidated_memories WHERE memory_id = ?`,
|
|
427
422
|
[memoryId]
|
|
428
423
|
);
|
|
429
|
-
if (rows.length === 0)
|
|
430
|
-
return null;
|
|
424
|
+
if (rows.length === 0) return null;
|
|
431
425
|
return this.rowToMemory(rows[0]);
|
|
432
426
|
}
|
|
433
427
|
/**
|
|
@@ -645,8 +639,7 @@ var ConsolidatedStore = class {
|
|
|
645
639
|
WHERE source_events LIKE ?`,
|
|
646
640
|
[`%"${eventId}"%`]
|
|
647
641
|
);
|
|
648
|
-
if ((result[0]?.count || 0) > 0)
|
|
649
|
-
return true;
|
|
642
|
+
if ((result[0]?.count || 0) > 0) return true;
|
|
650
643
|
}
|
|
651
644
|
return false;
|
|
652
645
|
}
|
|
@@ -660,8 +653,7 @@ var ConsolidatedStore = class {
|
|
|
660
653
|
ORDER BY created_at DESC
|
|
661
654
|
LIMIT 1`
|
|
662
655
|
);
|
|
663
|
-
if (result.length === 0)
|
|
664
|
-
return null;
|
|
656
|
+
if (result.length === 0) return null;
|
|
665
657
|
return new Date(result[0].created_at);
|
|
666
658
|
}
|
|
667
659
|
/**
|
|
@@ -691,6 +683,9 @@ var ConsolidationWorker = class {
|
|
|
691
683
|
this.consolidatedStore = consolidatedStore;
|
|
692
684
|
this.config = config;
|
|
693
685
|
}
|
|
686
|
+
workingSetStore;
|
|
687
|
+
consolidatedStore;
|
|
688
|
+
config;
|
|
694
689
|
running = false;
|
|
695
690
|
timeout = null;
|
|
696
691
|
lastActivity = /* @__PURE__ */ new Date();
|
|
@@ -698,8 +693,7 @@ var ConsolidationWorker = class {
|
|
|
698
693
|
* Start the consolidation worker
|
|
699
694
|
*/
|
|
700
695
|
start() {
|
|
701
|
-
if (this.running)
|
|
702
|
-
return;
|
|
696
|
+
if (this.running) return;
|
|
703
697
|
this.running = true;
|
|
704
698
|
this.scheduleNext();
|
|
705
699
|
}
|
|
@@ -742,8 +736,7 @@ var ConsolidationWorker = class {
|
|
|
742
736
|
* Schedule the next consolidation check
|
|
743
737
|
*/
|
|
744
738
|
scheduleNext() {
|
|
745
|
-
if (!this.running)
|
|
746
|
-
return;
|
|
739
|
+
if (!this.running) return;
|
|
747
740
|
this.timeout = setTimeout(
|
|
748
741
|
() => this.run(),
|
|
749
742
|
this.config.consolidation.triggerIntervalMs
|
|
@@ -753,8 +746,7 @@ var ConsolidationWorker = class {
|
|
|
753
746
|
* Run consolidation check
|
|
754
747
|
*/
|
|
755
748
|
async run() {
|
|
756
|
-
if (!this.running)
|
|
757
|
-
return;
|
|
749
|
+
if (!this.running) return;
|
|
758
750
|
try {
|
|
759
751
|
await this.checkAndConsolidate();
|
|
760
752
|
} catch (error) {
|
|
@@ -792,12 +784,10 @@ var ConsolidationWorker = class {
|
|
|
792
784
|
let consolidatedCount = 0;
|
|
793
785
|
const createdMemoryIds = [];
|
|
794
786
|
for (const group of groups) {
|
|
795
|
-
if (group.events.length < 3)
|
|
796
|
-
continue;
|
|
787
|
+
if (group.events.length < 3) continue;
|
|
797
788
|
const eventIds = group.events.map((e) => e.id);
|
|
798
789
|
const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
|
|
799
|
-
if (alreadyConsolidated)
|
|
800
|
-
continue;
|
|
790
|
+
if (alreadyConsolidated) continue;
|
|
801
791
|
const summary = await this.summarize(group);
|
|
802
792
|
const memoryId = await this.consolidatedStore.create({
|
|
803
793
|
summary,
|
|
@@ -813,8 +803,7 @@ var ConsolidationWorker = class {
|
|
|
813
803
|
const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
|
|
814
804
|
const oldEventIds = consolidatedEventIds.filter((id) => {
|
|
815
805
|
const event = workingSet.recentEvents.find((e) => e.id === id);
|
|
816
|
-
if (!event)
|
|
817
|
-
return false;
|
|
806
|
+
if (!event) return false;
|
|
818
807
|
const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
|
|
819
808
|
return ageHours > this.config.workingSet.timeWindowHours / 2;
|
|
820
809
|
});
|
|
@@ -829,18 +818,13 @@ var ConsolidationWorker = class {
|
|
|
829
818
|
let promoted = 0;
|
|
830
819
|
for (const memoryId of memoryIds) {
|
|
831
820
|
const memory = await this.consolidatedStore.get(memoryId);
|
|
832
|
-
if (!memory)
|
|
833
|
-
|
|
834
|
-
if (memory.
|
|
835
|
-
continue;
|
|
836
|
-
if (memory.sourceEvents.length < 4)
|
|
837
|
-
continue;
|
|
821
|
+
if (!memory) continue;
|
|
822
|
+
if (memory.confidence < 0.55) continue;
|
|
823
|
+
if (memory.sourceEvents.length < 4) continue;
|
|
838
824
|
const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
|
|
839
|
-
if (exists)
|
|
840
|
-
continue;
|
|
825
|
+
if (exists) continue;
|
|
841
826
|
const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
|
|
842
|
-
if (!rule)
|
|
843
|
-
continue;
|
|
827
|
+
if (!rule) continue;
|
|
844
828
|
await this.consolidatedStore.createRule({
|
|
845
829
|
rule,
|
|
846
830
|
topics: memory.topics,
|
|
@@ -856,8 +840,7 @@ var ConsolidationWorker = class {
|
|
|
856
840
|
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
|
|
857
841
|
const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
|
|
858
842
|
const seed = bullet || lines[0];
|
|
859
|
-
if (!seed || seed.length < 8)
|
|
860
|
-
return null;
|
|
843
|
+
if (!seed || seed.length < 8) return null;
|
|
861
844
|
const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
|
|
862
845
|
return `${topicPrefix}${seed}`;
|
|
863
846
|
}
|
|
@@ -1018,8 +1001,7 @@ var ConsolidationWorker = class {
|
|
|
1018
1001
|
*/
|
|
1019
1002
|
extractKeyPoint(content) {
|
|
1020
1003
|
const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
|
|
1021
|
-
if (sentences.length === 0)
|
|
1022
|
-
return null;
|
|
1004
|
+
if (sentences.length === 0) return null;
|
|
1023
1005
|
const firstSentence = sentences[0].trim();
|
|
1024
1006
|
if (firstSentence.length > 100) {
|
|
1025
1007
|
return firstSentence.slice(0, 100) + "...";
|
|
@@ -1039,8 +1021,7 @@ var ConsolidationWorker = class {
|
|
|
1039
1021
|
* Calculate time proximity score
|
|
1040
1022
|
*/
|
|
1041
1023
|
calculateTimeProximity(events) {
|
|
1042
|
-
if (events.length < 2)
|
|
1043
|
-
return 1;
|
|
1024
|
+
if (events.length < 2) return 1;
|
|
1044
1025
|
const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
|
|
1045
1026
|
const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
|
|
1046
1027
|
const avgGap = timeSpan / (events.length - 1);
|
|
@@ -1059,6 +1040,8 @@ var ContinuityManager = class {
|
|
|
1059
1040
|
this.eventStore = eventStore;
|
|
1060
1041
|
this.config = config;
|
|
1061
1042
|
}
|
|
1043
|
+
eventStore;
|
|
1044
|
+
config;
|
|
1062
1045
|
lastContext = null;
|
|
1063
1046
|
get db() {
|
|
1064
1047
|
return this.eventStore.getDatabase();
|
|
@@ -1178,8 +1161,7 @@ var ContinuityManager = class {
|
|
|
1178
1161
|
* Calculate overlap between two arrays
|
|
1179
1162
|
*/
|
|
1180
1163
|
calculateOverlap(a, b) {
|
|
1181
|
-
if (a.length === 0 || b.length === 0)
|
|
1182
|
-
return 0;
|
|
1164
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
1183
1165
|
const setA = new Set(a.map((s) => s.toLowerCase()));
|
|
1184
1166
|
const setB = new Set(b.map((s) => s.toLowerCase()));
|
|
1185
1167
|
const intersection = [...setA].filter((x) => setB.has(x));
|
|
@@ -1352,6 +1334,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1352
1334
|
this.options = options;
|
|
1353
1335
|
this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
|
|
1354
1336
|
}
|
|
1337
|
+
options;
|
|
1355
1338
|
factories;
|
|
1356
1339
|
workingSetStore = null;
|
|
1357
1340
|
consolidatedStore = null;
|
|
@@ -1366,8 +1349,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1366
1349
|
}
|
|
1367
1350
|
}
|
|
1368
1351
|
async initializeEndlessMode() {
|
|
1369
|
-
if (this.consolidationWorker)
|
|
1370
|
-
return;
|
|
1352
|
+
if (this.consolidationWorker) return;
|
|
1371
1353
|
const config = await this.getEndlessConfig();
|
|
1372
1354
|
const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
|
|
1373
1355
|
const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
|
|
@@ -1399,8 +1381,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1399
1381
|
}
|
|
1400
1382
|
async setMode(mode) {
|
|
1401
1383
|
await this.options.initialize();
|
|
1402
|
-
if (mode === this.mode)
|
|
1403
|
-
return;
|
|
1384
|
+
if (mode === this.mode) return;
|
|
1404
1385
|
this.mode = mode;
|
|
1405
1386
|
await this.options.configStore.setEndlessConfig("mode", mode);
|
|
1406
1387
|
if (mode === "endless") {
|
|
@@ -1416,33 +1397,27 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1416
1397
|
return this.mode === "endless";
|
|
1417
1398
|
}
|
|
1418
1399
|
async addToWorkingSet(eventId, relevanceScore) {
|
|
1419
|
-
if (!this.workingSetStore)
|
|
1420
|
-
return;
|
|
1400
|
+
if (!this.workingSetStore) return;
|
|
1421
1401
|
await this.workingSetStore.add(eventId, relevanceScore);
|
|
1422
1402
|
}
|
|
1423
1403
|
async getWorkingSet() {
|
|
1424
|
-
if (!this.workingSetStore)
|
|
1425
|
-
return null;
|
|
1404
|
+
if (!this.workingSetStore) return null;
|
|
1426
1405
|
return this.workingSetStore.get();
|
|
1427
1406
|
}
|
|
1428
1407
|
async searchConsolidated(query, options) {
|
|
1429
|
-
if (!this.consolidatedStore)
|
|
1430
|
-
return [];
|
|
1408
|
+
if (!this.consolidatedStore) return [];
|
|
1431
1409
|
return this.consolidatedStore.search(query, options);
|
|
1432
1410
|
}
|
|
1433
1411
|
async getConsolidatedMemories(limit) {
|
|
1434
|
-
if (!this.consolidatedStore)
|
|
1435
|
-
return [];
|
|
1412
|
+
if (!this.consolidatedStore) return [];
|
|
1436
1413
|
return this.consolidatedStore.getAll({ limit });
|
|
1437
1414
|
}
|
|
1438
1415
|
async markMemoryAccessed(memoryId) {
|
|
1439
|
-
if (!this.consolidatedStore)
|
|
1440
|
-
return;
|
|
1416
|
+
if (!this.consolidatedStore) return;
|
|
1441
1417
|
await this.consolidatedStore.markAccessed(memoryId);
|
|
1442
1418
|
}
|
|
1443
1419
|
async calculateContinuity(content, metadata) {
|
|
1444
|
-
if (!this.continuityManager)
|
|
1445
|
-
return null;
|
|
1420
|
+
if (!this.continuityManager) return null;
|
|
1446
1421
|
const snapshot = this.continuityManager.createSnapshot(
|
|
1447
1422
|
this.factories.randomUUID(),
|
|
1448
1423
|
content,
|
|
@@ -1454,8 +1429,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1454
1429
|
this.consolidationWorker?.recordActivity();
|
|
1455
1430
|
}
|
|
1456
1431
|
async forceConsolidation() {
|
|
1457
|
-
if (!this.consolidationWorker)
|
|
1458
|
-
return 0;
|
|
1432
|
+
if (!this.consolidationWorker) return 0;
|
|
1459
1433
|
return this.consolidationWorker.forceRun();
|
|
1460
1434
|
}
|
|
1461
1435
|
async getEndlessModeStatus() {
|
|
@@ -1547,8 +1521,7 @@ var Embedder = class _Embedder {
|
|
|
1547
1521
|
* Initialize the embedding pipeline
|
|
1548
1522
|
*/
|
|
1549
1523
|
async initialize() {
|
|
1550
|
-
if (this.initialized)
|
|
1551
|
-
return;
|
|
1524
|
+
if (this.initialized) return;
|
|
1552
1525
|
const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
|
|
1553
1526
|
try {
|
|
1554
1527
|
return await loadTransformersPipeline();
|
|
@@ -1665,8 +1638,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
|
|
|
1665
1638
|
originalConsoleWarn = console.warn;
|
|
1666
1639
|
console.warn = (...args) => {
|
|
1667
1640
|
const message = args.map(String).join(" ");
|
|
1668
|
-
if (isKnownBenignTransformersWarning(message))
|
|
1669
|
-
return;
|
|
1641
|
+
if (isKnownBenignTransformersWarning(message)) return;
|
|
1670
1642
|
(originalConsoleWarn ?? console.warn)(...args);
|
|
1671
1643
|
};
|
|
1672
1644
|
}
|
|
@@ -1948,8 +1920,7 @@ var GraduationPipeline = class {
|
|
|
1948
1920
|
const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
|
|
1949
1921
|
const preferences = [];
|
|
1950
1922
|
for (const event of events) {
|
|
1951
|
-
if (event.eventType !== "user_prompt")
|
|
1952
|
-
continue;
|
|
1923
|
+
if (event.eventType !== "user_prompt") continue;
|
|
1953
1924
|
const lowerContent = event.content.toLowerCase();
|
|
1954
1925
|
for (const keyword of preferenceKeywords) {
|
|
1955
1926
|
if (lowerContent.includes(keyword)) {
|
|
@@ -2115,11 +2086,9 @@ function sanitizeSegment(input, fallback) {
|
|
|
2115
2086
|
return v || fallback;
|
|
2116
2087
|
}
|
|
2117
2088
|
function getAtPath(obj, dotted) {
|
|
2118
|
-
if (!obj)
|
|
2119
|
-
return void 0;
|
|
2089
|
+
if (!obj) return void 0;
|
|
2120
2090
|
return dotted.split(".").reduce((acc, key) => {
|
|
2121
|
-
if (!acc || typeof acc !== "object")
|
|
2122
|
-
return void 0;
|
|
2091
|
+
if (!acc || typeof acc !== "object") return void 0;
|
|
2123
2092
|
return acc[key];
|
|
2124
2093
|
}, obj);
|
|
2125
2094
|
}
|
|
@@ -2139,6 +2108,7 @@ var MarkdownMirror = class {
|
|
|
2139
2108
|
constructor(rootDir) {
|
|
2140
2109
|
this.rootDir = rootDir;
|
|
2141
2110
|
}
|
|
2111
|
+
rootDir;
|
|
2142
2112
|
async append(event, eventId) {
|
|
2143
2113
|
const out = buildMirrorPath(this.rootDir, event);
|
|
2144
2114
|
fs2.mkdirSync(path2.dirname(out), { recursive: true });
|
|
@@ -2270,10 +2240,8 @@ function sqliteClose(db) {
|
|
|
2270
2240
|
db.close();
|
|
2271
2241
|
}
|
|
2272
2242
|
function toDateFromSQLite(value) {
|
|
2273
|
-
if (value instanceof Date)
|
|
2274
|
-
|
|
2275
|
-
if (typeof value === "number")
|
|
2276
|
-
return new Date(value);
|
|
2243
|
+
if (value instanceof Date) return value;
|
|
2244
|
+
if (typeof value === "number") return new Date(value);
|
|
2277
2245
|
if (typeof value === "string") {
|
|
2278
2246
|
const trimmed = value.trim();
|
|
2279
2247
|
if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
|
|
@@ -2295,8 +2263,7 @@ var DEFAULT_CATEGORY = "uncategorized";
|
|
|
2295
2263
|
function sanitizeSegment2(input, fallback) {
|
|
2296
2264
|
const raw = String(input ?? "").trim().toLowerCase();
|
|
2297
2265
|
const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2298
|
-
if (!safe || safe === "." || safe === "..")
|
|
2299
|
-
return fallback;
|
|
2266
|
+
if (!safe || safe === "." || safe === "..") return fallback;
|
|
2300
2267
|
return safe;
|
|
2301
2268
|
}
|
|
2302
2269
|
function getCategorySegments(metadata, eventType) {
|
|
@@ -2337,6 +2304,7 @@ var MarkdownMirror2 = class {
|
|
|
2337
2304
|
constructor(rootDir) {
|
|
2338
2305
|
this.rootDir = rootDir;
|
|
2339
2306
|
}
|
|
2307
|
+
rootDir;
|
|
2340
2308
|
async append(event) {
|
|
2341
2309
|
const outPath = buildMirrorPath2(this.rootDir, event);
|
|
2342
2310
|
await fs5.mkdir(path4.dirname(outPath), { recursive: true });
|
|
@@ -2359,6 +2327,7 @@ var VectorOutbox = class {
|
|
|
2359
2327
|
this.db = db;
|
|
2360
2328
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
2361
2329
|
}
|
|
2330
|
+
db;
|
|
2362
2331
|
config;
|
|
2363
2332
|
/**
|
|
2364
2333
|
* Enqueue item for vectorization (idempotent).
|
|
@@ -2455,8 +2424,7 @@ var VectorOutbox = class {
|
|
|
2455
2424
|
`SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
|
|
2456
2425
|
[jobId]
|
|
2457
2426
|
);
|
|
2458
|
-
if (rows.length === 0)
|
|
2459
|
-
return;
|
|
2427
|
+
if (rows.length === 0) return;
|
|
2460
2428
|
const retryCount = rows[0].retry_count;
|
|
2461
2429
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
2462
2430
|
await dbRun(
|
|
@@ -2476,8 +2444,7 @@ var VectorOutbox = class {
|
|
|
2476
2444
|
`SELECT * FROM vector_outbox WHERE job_id = ?`,
|
|
2477
2445
|
[jobId]
|
|
2478
2446
|
);
|
|
2479
|
-
if (rows.length === 0)
|
|
2480
|
-
return null;
|
|
2447
|
+
if (rows.length === 0) return null;
|
|
2481
2448
|
return this.rowToJob(rows[0]);
|
|
2482
2449
|
}
|
|
2483
2450
|
/**
|
|
@@ -2611,30 +2578,24 @@ function isRetrievalDebugLaneName(value) {
|
|
|
2611
2578
|
return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
|
|
2612
2579
|
}
|
|
2613
2580
|
function normalizeRetrievalDebugLanes(value, maxItems = 6) {
|
|
2614
|
-
if (!Array.isArray(value) || maxItems <= 0)
|
|
2615
|
-
return [];
|
|
2581
|
+
if (!Array.isArray(value) || maxItems <= 0) return [];
|
|
2616
2582
|
const normalized = [];
|
|
2617
2583
|
const seen = /* @__PURE__ */ new Set();
|
|
2618
2584
|
for (const item of value) {
|
|
2619
2585
|
const lane = normalizeRetrievalDebugLane(item);
|
|
2620
|
-
if (!lane)
|
|
2621
|
-
continue;
|
|
2586
|
+
if (!lane) continue;
|
|
2622
2587
|
const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
|
|
2623
|
-
if (seen.has(key))
|
|
2624
|
-
continue;
|
|
2588
|
+
if (seen.has(key)) continue;
|
|
2625
2589
|
seen.add(key);
|
|
2626
2590
|
normalized.push(lane);
|
|
2627
|
-
if (normalized.length >= maxItems)
|
|
2628
|
-
break;
|
|
2591
|
+
if (normalized.length >= maxItems) break;
|
|
2629
2592
|
}
|
|
2630
2593
|
return normalized;
|
|
2631
2594
|
}
|
|
2632
2595
|
function normalizeRetrievalDebugLane(value) {
|
|
2633
|
-
if (!value || typeof value !== "object")
|
|
2634
|
-
return null;
|
|
2596
|
+
if (!value || typeof value !== "object") return null;
|
|
2635
2597
|
const raw = value;
|
|
2636
|
-
if (!isRetrievalDebugLaneName(raw.lane))
|
|
2637
|
-
return null;
|
|
2598
|
+
if (!isRetrievalDebugLaneName(raw.lane)) return null;
|
|
2638
2599
|
const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
|
|
2639
2600
|
const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
|
|
2640
2601
|
return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
|
|
@@ -2657,27 +2618,21 @@ function normalizeRetrievalTraceDetails(details) {
|
|
|
2657
2618
|
eventId: detail.eventId,
|
|
2658
2619
|
score: detail.score
|
|
2659
2620
|
};
|
|
2660
|
-
if (detail.semanticScore !== void 0)
|
|
2661
|
-
|
|
2662
|
-
if (detail.
|
|
2663
|
-
|
|
2664
|
-
if (detail.recencyScore !== void 0)
|
|
2665
|
-
normalized.recencyScore = detail.recencyScore;
|
|
2666
|
-
if (lanes.length > 0)
|
|
2667
|
-
normalized.lanes = lanes;
|
|
2621
|
+
if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
|
|
2622
|
+
if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
|
|
2623
|
+
if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
|
|
2624
|
+
if (lanes.length > 0) normalized.lanes = lanes;
|
|
2668
2625
|
return normalized;
|
|
2669
2626
|
});
|
|
2670
2627
|
}
|
|
2671
2628
|
function parseRetrievalTraceDetails(value) {
|
|
2672
|
-
if (typeof value !== "string" || value.length === 0)
|
|
2673
|
-
return [];
|
|
2629
|
+
if (typeof value !== "string" || value.length === 0) return [];
|
|
2674
2630
|
const parsed = JSON.parse(value);
|
|
2675
2631
|
return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
|
|
2676
2632
|
}
|
|
2677
2633
|
function normalizeQueryRewriteKind(value) {
|
|
2678
2634
|
const normalized = (value || "").trim().toLowerCase();
|
|
2679
|
-
if (normalized === "follow-up-context" || normalized === "intent-rewrite")
|
|
2680
|
-
return normalized;
|
|
2635
|
+
if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
|
|
2681
2636
|
return "none";
|
|
2682
2637
|
}
|
|
2683
2638
|
var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
|
|
@@ -2695,8 +2650,7 @@ function isRecord(value) {
|
|
|
2695
2650
|
function getNestedRecord(root, path12) {
|
|
2696
2651
|
let cursor = root;
|
|
2697
2652
|
for (const key of path12) {
|
|
2698
|
-
if (!isRecord(cursor))
|
|
2699
|
-
return void 0;
|
|
2653
|
+
if (!isRecord(cursor)) return void 0;
|
|
2700
2654
|
cursor = cursor[key];
|
|
2701
2655
|
}
|
|
2702
2656
|
return isRecord(cursor) ? cursor : void 0;
|
|
@@ -2704,8 +2658,7 @@ function getNestedRecord(root, path12) {
|
|
|
2704
2658
|
function getNestedString(root, path12) {
|
|
2705
2659
|
let cursor = root;
|
|
2706
2660
|
for (const key of path12) {
|
|
2707
|
-
if (!isRecord(cursor))
|
|
2708
|
-
return void 0;
|
|
2661
|
+
if (!isRecord(cursor)) return void 0;
|
|
2709
2662
|
cursor = cursor[key];
|
|
2710
2663
|
}
|
|
2711
2664
|
return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
|
|
@@ -2721,8 +2674,7 @@ function metadataProjectPaths(metadata) {
|
|
|
2721
2674
|
];
|
|
2722
2675
|
const paths = [];
|
|
2723
2676
|
for (const value of candidates) {
|
|
2724
|
-
if (value && !paths.includes(value))
|
|
2725
|
-
paths.push(value);
|
|
2677
|
+
if (value && !paths.includes(value)) paths.push(value);
|
|
2726
2678
|
}
|
|
2727
2679
|
return paths;
|
|
2728
2680
|
}
|
|
@@ -2743,12 +2695,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
|
|
|
2743
2695
|
return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
|
|
2744
2696
|
}
|
|
2745
2697
|
function safeParseMetadataValue(value) {
|
|
2746
|
-
if (!value)
|
|
2747
|
-
|
|
2748
|
-
if (typeof value
|
|
2749
|
-
return isRecord(value) ? value : void 0;
|
|
2750
|
-
if (typeof value !== "string")
|
|
2751
|
-
return void 0;
|
|
2698
|
+
if (!value) return void 0;
|
|
2699
|
+
if (typeof value === "object") return isRecord(value) ? value : void 0;
|
|
2700
|
+
if (typeof value !== "string") return void 0;
|
|
2752
2701
|
try {
|
|
2753
2702
|
const parsed = JSON.parse(value);
|
|
2754
2703
|
return isRecord(parsed) ? parsed : void 0;
|
|
@@ -2757,16 +2706,14 @@ function safeParseMetadataValue(value) {
|
|
|
2757
2706
|
}
|
|
2758
2707
|
}
|
|
2759
2708
|
function isImportedOrLegacyScopedMetadata(metadata) {
|
|
2760
|
-
if (!metadata)
|
|
2761
|
-
return false;
|
|
2709
|
+
if (!metadata) return false;
|
|
2762
2710
|
return Boolean(
|
|
2763
2711
|
metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
|
|
2764
2712
|
);
|
|
2765
2713
|
}
|
|
2766
2714
|
function addMetadataTag(metadata, tag) {
|
|
2767
2715
|
const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
|
|
2768
|
-
if (!current.includes(tag))
|
|
2769
|
-
metadata.tags = [...current, tag];
|
|
2716
|
+
if (!current.includes(tag)) metadata.tags = [...current, tag];
|
|
2770
2717
|
}
|
|
2771
2718
|
function buildRepairResult(projectHash, dryRun) {
|
|
2772
2719
|
return {
|
|
@@ -2784,8 +2731,7 @@ function normalizeRepoName(value) {
|
|
|
2784
2731
|
return value.replace(/\.git$/i, "").trim().toLowerCase();
|
|
2785
2732
|
}
|
|
2786
2733
|
function projectBasename(projectPath) {
|
|
2787
|
-
if (!projectPath)
|
|
2788
|
-
return void 0;
|
|
2734
|
+
if (!projectPath) return void 0;
|
|
2789
2735
|
const trimmed = projectPath.replace(/[\\/]+$/, "");
|
|
2790
2736
|
const basename2 = nodePath2.basename(trimmed);
|
|
2791
2737
|
return basename2 ? normalizeRepoName(basename2) : void 0;
|
|
@@ -2798,23 +2744,19 @@ function isProjectScopeRepairExplanation(content) {
|
|
|
2798
2744
|
}
|
|
2799
2745
|
function hasConflictingContentProjectHint(content, projectPath) {
|
|
2800
2746
|
const currentName = projectBasename(projectPath);
|
|
2801
|
-
if (!currentName)
|
|
2802
|
-
|
|
2803
|
-
if (isProjectScopeRepairExplanation(content))
|
|
2804
|
-
return false;
|
|
2747
|
+
if (!currentName) return false;
|
|
2748
|
+
if (isProjectScopeRepairExplanation(content)) return false;
|
|
2805
2749
|
const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
|
|
2806
2750
|
let githubMatch;
|
|
2807
2751
|
while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
|
|
2808
2752
|
const repo = normalizeRepoName(githubMatch[2] || "");
|
|
2809
|
-
if (repo && repo !== currentName)
|
|
2810
|
-
return true;
|
|
2753
|
+
if (repo && repo !== currentName) return true;
|
|
2811
2754
|
}
|
|
2812
2755
|
const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
|
|
2813
2756
|
let workspaceMatch;
|
|
2814
2757
|
while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
|
|
2815
2758
|
const repo = normalizeRepoName(workspaceMatch[1] || "");
|
|
2816
|
-
if (repo && repo !== currentName)
|
|
2817
|
-
return true;
|
|
2759
|
+
if (repo && repo !== currentName) return true;
|
|
2818
2760
|
}
|
|
2819
2761
|
return false;
|
|
2820
2762
|
}
|
|
@@ -2834,15 +2776,12 @@ var SQLiteEventStore = class {
|
|
|
2834
2776
|
this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
|
|
2835
2777
|
}
|
|
2836
2778
|
createVectorOutbox(option) {
|
|
2837
|
-
if (this.readOnly || option === false)
|
|
2838
|
-
|
|
2839
|
-
if (option instanceof VectorOutbox)
|
|
2840
|
-
return option;
|
|
2779
|
+
if (this.readOnly || option === false) return null;
|
|
2780
|
+
if (option instanceof VectorOutbox) return option;
|
|
2841
2781
|
return new VectorOutbox(this.db, option ?? {});
|
|
2842
2782
|
}
|
|
2843
2783
|
enqueueVectorOutboxEventSync(eventId) {
|
|
2844
|
-
if (!this.vectorOutbox)
|
|
2845
|
-
return;
|
|
2784
|
+
if (!this.vectorOutbox) return;
|
|
2846
2785
|
this.vectorOutbox.enqueueSync("event", eventId);
|
|
2847
2786
|
}
|
|
2848
2787
|
async enqueueVectorOutboxEvent(eventId) {
|
|
@@ -2852,8 +2791,7 @@ var SQLiteEventStore = class {
|
|
|
2852
2791
|
* Initialize database schema
|
|
2853
2792
|
*/
|
|
2854
2793
|
async initialize() {
|
|
2855
|
-
if (this.initialized)
|
|
2856
|
-
return;
|
|
2794
|
+
if (this.initialized) return;
|
|
2857
2795
|
if (this.readOnly) {
|
|
2858
2796
|
this.initialized = true;
|
|
2859
2797
|
return;
|
|
@@ -3411,10 +3349,8 @@ var SQLiteEventStore = class {
|
|
|
3411
3349
|
try {
|
|
3412
3350
|
const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
|
|
3413
3351
|
const hasSourceAwareUnique = edgeIndexes.some((index) => {
|
|
3414
|
-
if (Number(index.unique) !== 1)
|
|
3415
|
-
|
|
3416
|
-
if (!/^[A-Za-z0-9_]+$/.test(index.name))
|
|
3417
|
-
return false;
|
|
3352
|
+
if (Number(index.unique) !== 1) return false;
|
|
3353
|
+
if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
|
|
3418
3354
|
const escapedName = index.name.replace(/"/g, '""');
|
|
3419
3355
|
const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
|
|
3420
3356
|
return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
|
|
@@ -3654,8 +3590,7 @@ var SQLiteEventStore = class {
|
|
|
3654
3590
|
`SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
|
|
3655
3591
|
[id]
|
|
3656
3592
|
);
|
|
3657
|
-
if (!row)
|
|
3658
|
-
return null;
|
|
3593
|
+
if (!row) return null;
|
|
3659
3594
|
return this.rowToEvent(row);
|
|
3660
3595
|
}
|
|
3661
3596
|
/**
|
|
@@ -3693,10 +3628,8 @@ var SQLiteEventStore = class {
|
|
|
3693
3628
|
* NOTE: This bypasses the append() id generation to preserve stable IDs.
|
|
3694
3629
|
*/
|
|
3695
3630
|
async importEvents(events) {
|
|
3696
|
-
if (events.length === 0)
|
|
3697
|
-
|
|
3698
|
-
if (this.readOnly)
|
|
3699
|
-
return { inserted: 0, skipped: events.length };
|
|
3631
|
+
if (events.length === 0) return { inserted: 0, skipped: 0 };
|
|
3632
|
+
if (this.readOnly) return { inserted: 0, skipped: events.length };
|
|
3700
3633
|
await this.initialize();
|
|
3701
3634
|
const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
|
|
3702
3635
|
const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
|
|
@@ -3814,8 +3747,7 @@ var SQLiteEventStore = class {
|
|
|
3814
3747
|
`SELECT * FROM sessions WHERE id = ?`,
|
|
3815
3748
|
[id]
|
|
3816
3749
|
);
|
|
3817
|
-
if (!row)
|
|
3818
|
-
return null;
|
|
3750
|
+
if (!row) return null;
|
|
3819
3751
|
return {
|
|
3820
3752
|
id: row.id,
|
|
3821
3753
|
startedAt: toDateFromSQLite(row.started_at),
|
|
@@ -3870,8 +3802,7 @@ var SQLiteEventStore = class {
|
|
|
3870
3802
|
LIMIT ?`,
|
|
3871
3803
|
[limit]
|
|
3872
3804
|
);
|
|
3873
|
-
if (pending.length === 0)
|
|
3874
|
-
return [];
|
|
3805
|
+
if (pending.length === 0) return [];
|
|
3875
3806
|
const ids = pending.map((r) => r.id);
|
|
3876
3807
|
const placeholders = ids.map(() => "?").join(",");
|
|
3877
3808
|
sqliteRun(
|
|
@@ -3895,8 +3826,7 @@ var SQLiteEventStore = class {
|
|
|
3895
3826
|
* Mark outbox items as done
|
|
3896
3827
|
*/
|
|
3897
3828
|
async completeOutboxItems(ids) {
|
|
3898
|
-
if (ids.length === 0)
|
|
3899
|
-
return;
|
|
3829
|
+
if (ids.length === 0) return;
|
|
3900
3830
|
const placeholders = ids.map(() => "?").join(",");
|
|
3901
3831
|
sqliteRun(
|
|
3902
3832
|
this.db,
|
|
@@ -3935,8 +3865,7 @@ var SQLiteEventStore = class {
|
|
|
3935
3865
|
* Mark outbox items as failed
|
|
3936
3866
|
*/
|
|
3937
3867
|
async failOutboxItems(ids, error) {
|
|
3938
|
-
if (ids.length === 0)
|
|
3939
|
-
return;
|
|
3868
|
+
if (ids.length === 0) return;
|
|
3940
3869
|
const placeholders = ids.map(() => "?").join(",");
|
|
3941
3870
|
sqliteRun(
|
|
3942
3871
|
this.db,
|
|
@@ -4063,8 +3992,7 @@ var SQLiteEventStore = class {
|
|
|
4063
3992
|
[]
|
|
4064
3993
|
);
|
|
4065
3994
|
const sample = (entry) => {
|
|
4066
|
-
if (result.samples.length < 20)
|
|
4067
|
-
result.samples.push(entry);
|
|
3995
|
+
if (result.samples.length < 20) result.samples.push(entry);
|
|
4068
3996
|
};
|
|
4069
3997
|
for (const row of rows) {
|
|
4070
3998
|
result.scanned++;
|
|
@@ -4191,12 +4119,10 @@ var SQLiteEventStore = class {
|
|
|
4191
4119
|
`SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
|
|
4192
4120
|
);
|
|
4193
4121
|
const processingAgeMs = (value) => {
|
|
4194
|
-
if (value === null || value === void 0)
|
|
4195
|
-
return null;
|
|
4122
|
+
if (value === null || value === void 0) return null;
|
|
4196
4123
|
const date = toDateFromSQLite(value);
|
|
4197
4124
|
const time = date.getTime();
|
|
4198
|
-
if (!Number.isFinite(time))
|
|
4199
|
-
return null;
|
|
4125
|
+
if (!Number.isFinite(time)) return null;
|
|
4200
4126
|
return Math.max(0, now.getTime() - time);
|
|
4201
4127
|
};
|
|
4202
4128
|
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
|
|
@@ -4345,8 +4271,7 @@ var SQLiteEventStore = class {
|
|
|
4345
4271
|
`SELECT value FROM endless_config WHERE key = ?`,
|
|
4346
4272
|
[key]
|
|
4347
4273
|
);
|
|
4348
|
-
if (!row)
|
|
4349
|
-
return null;
|
|
4274
|
+
if (!row) return null;
|
|
4350
4275
|
return JSON.parse(row.value);
|
|
4351
4276
|
}
|
|
4352
4277
|
/**
|
|
@@ -4365,8 +4290,7 @@ var SQLiteEventStore = class {
|
|
|
4365
4290
|
* Increment access count for events
|
|
4366
4291
|
*/
|
|
4367
4292
|
async incrementAccessCount(eventIds) {
|
|
4368
|
-
if (eventIds.length === 0 || this.readOnly)
|
|
4369
|
-
return;
|
|
4293
|
+
if (eventIds.length === 0 || this.readOnly) return;
|
|
4370
4294
|
await this.initialize();
|
|
4371
4295
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4372
4296
|
const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -4409,8 +4333,7 @@ var SQLiteEventStore = class {
|
|
|
4409
4333
|
* Record a memory retrieval for helpfulness tracking
|
|
4410
4334
|
*/
|
|
4411
4335
|
async recordRetrieval(eventId, sessionId, score, query) {
|
|
4412
|
-
if (this.readOnly)
|
|
4413
|
-
return;
|
|
4336
|
+
if (this.readOnly) return;
|
|
4414
4337
|
await this.initialize();
|
|
4415
4338
|
const id = randomUUID6();
|
|
4416
4339
|
sqliteRun(
|
|
@@ -4440,16 +4363,14 @@ var SQLiteEventStore = class {
|
|
|
4440
4363
|
* Called at session end - uses behavioral signals to compute score
|
|
4441
4364
|
*/
|
|
4442
4365
|
async evaluateSessionHelpfulness(sessionId) {
|
|
4443
|
-
if (this.readOnly)
|
|
4444
|
-
return;
|
|
4366
|
+
if (this.readOnly) return;
|
|
4445
4367
|
await this.initialize();
|
|
4446
4368
|
const retrievals = sqliteAll(
|
|
4447
4369
|
this.db,
|
|
4448
4370
|
`SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
|
|
4449
4371
|
[sessionId]
|
|
4450
4372
|
);
|
|
4451
|
-
if (retrievals.length === 0)
|
|
4452
|
-
return;
|
|
4373
|
+
if (retrievals.length === 0) return;
|
|
4453
4374
|
const sessionEvents = sqliteAll(
|
|
4454
4375
|
this.db,
|
|
4455
4376
|
`SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
|
|
@@ -4462,8 +4383,7 @@ var SQLiteEventStore = class {
|
|
|
4462
4383
|
for (const t of toolEvents) {
|
|
4463
4384
|
try {
|
|
4464
4385
|
const content = JSON.parse(t.content);
|
|
4465
|
-
if (content.success !== false)
|
|
4466
|
-
toolSuccessCount++;
|
|
4386
|
+
if (content.success !== false) toolSuccessCount++;
|
|
4467
4387
|
} catch {
|
|
4468
4388
|
toolSuccessCount++;
|
|
4469
4389
|
}
|
|
@@ -4481,8 +4401,7 @@ var SQLiteEventStore = class {
|
|
|
4481
4401
|
const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
4482
4402
|
let overlap = 0;
|
|
4483
4403
|
for (const w of queryWords) {
|
|
4484
|
-
if (pWords.has(w))
|
|
4485
|
-
overlap++;
|
|
4404
|
+
if (pWords.has(w)) overlap++;
|
|
4486
4405
|
}
|
|
4487
4406
|
if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
|
|
4488
4407
|
wasReasked = 1;
|
|
@@ -4664,8 +4583,7 @@ var SQLiteEventStore = class {
|
|
|
4664
4583
|
return this.db;
|
|
4665
4584
|
}
|
|
4666
4585
|
hasTableColumn(tableName, columnName2) {
|
|
4667
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
|
|
4668
|
-
return false;
|
|
4586
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
|
|
4669
4587
|
try {
|
|
4670
4588
|
const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
|
|
4671
4589
|
return rows.some((row) => row.name === columnName2);
|
|
@@ -4732,8 +4650,7 @@ var SQLiteEventStore = class {
|
|
|
4732
4650
|
createdAt: toDateFromSQLite(row.created_at)
|
|
4733
4651
|
}));
|
|
4734
4652
|
} catch (err) {
|
|
4735
|
-
if (err?.message?.includes("no such table"))
|
|
4736
|
-
return [];
|
|
4653
|
+
if (err?.message?.includes("no such table")) return [];
|
|
4737
4654
|
throw err;
|
|
4738
4655
|
}
|
|
4739
4656
|
}
|
|
@@ -4906,8 +4823,7 @@ var SQLiteEventStore = class {
|
|
|
4906
4823
|
`SELECT id FROM events WHERE session_id = ?`,
|
|
4907
4824
|
[sessionId]
|
|
4908
4825
|
);
|
|
4909
|
-
if (events.length === 0)
|
|
4910
|
-
return 0;
|
|
4826
|
+
if (events.length === 0) return 0;
|
|
4911
4827
|
const eventIds = events.map((e) => e.id);
|
|
4912
4828
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4913
4829
|
const ftsTriggersDropped = [];
|
|
@@ -5119,8 +5035,7 @@ function sanitizeGovernanceAuditValue(value, key) {
|
|
|
5119
5035
|
return value;
|
|
5120
5036
|
}
|
|
5121
5037
|
function sanitizeAuditJson(value) {
|
|
5122
|
-
if (value === void 0)
|
|
5123
|
-
return void 0;
|
|
5038
|
+
if (value === void 0) return void 0;
|
|
5124
5039
|
return sanitizeGovernanceAuditValue(value);
|
|
5125
5040
|
}
|
|
5126
5041
|
function normalizeSourceEventIds(sourceEventIds) {
|
|
@@ -5169,12 +5084,10 @@ async function writeGovernanceAuditEntry(db, input) {
|
|
|
5169
5084
|
|
|
5170
5085
|
// src/core/operations/facet-repository.ts
|
|
5171
5086
|
function parseStringArray(value) {
|
|
5172
|
-
if (typeof value !== "string")
|
|
5173
|
-
return [];
|
|
5087
|
+
if (typeof value !== "string") return [];
|
|
5174
5088
|
try {
|
|
5175
5089
|
const parsed = JSON.parse(value);
|
|
5176
|
-
if (!Array.isArray(parsed))
|
|
5177
|
-
return [];
|
|
5090
|
+
if (!Array.isArray(parsed)) return [];
|
|
5178
5091
|
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
5179
5092
|
} catch {
|
|
5180
5093
|
return [];
|
|
@@ -5218,6 +5131,7 @@ var FacetRepository = class {
|
|
|
5218
5131
|
constructor(db) {
|
|
5219
5132
|
this.db = db;
|
|
5220
5133
|
}
|
|
5134
|
+
db;
|
|
5221
5135
|
async assign(input) {
|
|
5222
5136
|
const assignment = parseFacetAssignmentInput(input);
|
|
5223
5137
|
const existing = this.findByUniqueKey(assignment);
|
|
@@ -5522,19 +5436,14 @@ var RetentionFacetSchema = z5.object({
|
|
|
5522
5436
|
confidence: z5.number().min(0).max(1).default(1)
|
|
5523
5437
|
});
|
|
5524
5438
|
var DateLikeSchema = z5.preprocess((value) => {
|
|
5525
|
-
if (value instanceof Date)
|
|
5526
|
-
|
|
5527
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5528
|
-
return new Date(value);
|
|
5439
|
+
if (value instanceof Date) return value;
|
|
5440
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5529
5441
|
return value;
|
|
5530
5442
|
}, z5.date());
|
|
5531
5443
|
var NullableDateLikeSchema = z5.preprocess((value) => {
|
|
5532
|
-
if (value === null || value === void 0 || value === "")
|
|
5533
|
-
|
|
5534
|
-
if (value
|
|
5535
|
-
return value;
|
|
5536
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5537
|
-
return new Date(value);
|
|
5444
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
5445
|
+
if (value instanceof Date) return value;
|
|
5446
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5538
5447
|
return value;
|
|
5539
5448
|
}, z5.date().nullable());
|
|
5540
5449
|
var OptionalTrimmedStringSchema2 = z5.preprocess(
|
|
@@ -5563,10 +5472,8 @@ import { z as z6 } from "zod";
|
|
|
5563
5472
|
var RequiredTrimmedStringSchema = z6.string().trim().min(1);
|
|
5564
5473
|
var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
|
|
5565
5474
|
var DateLikeSchema2 = z6.preprocess((value) => {
|
|
5566
|
-
if (value instanceof Date)
|
|
5567
|
-
|
|
5568
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5569
|
-
return new Date(value);
|
|
5475
|
+
if (value instanceof Date) return value;
|
|
5476
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5570
5477
|
return value;
|
|
5571
5478
|
}, z6.date());
|
|
5572
5479
|
var RetentionReasonSchema = z6.object({
|
|
@@ -5755,8 +5662,7 @@ var MemoryOperationsConfigSchema = z7.object({
|
|
|
5755
5662
|
}).default({});
|
|
5756
5663
|
var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5757
5664
|
var MemoryLessonStringArraySchema = z7.preprocess((value) => {
|
|
5758
|
-
if (!Array.isArray(value))
|
|
5759
|
-
return value;
|
|
5665
|
+
if (!Array.isArray(value)) return value;
|
|
5760
5666
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5761
5667
|
}, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
|
|
5762
5668
|
var MemoryLessonSchema = z7.object({
|
|
@@ -5801,14 +5707,12 @@ var ListMemoryLessonsInputSchema = z7.object({
|
|
|
5801
5707
|
});
|
|
5802
5708
|
var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
5803
5709
|
var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
|
|
5804
|
-
if (typeof value !== "string")
|
|
5805
|
-
return value;
|
|
5710
|
+
if (typeof value !== "string") return value;
|
|
5806
5711
|
const normalized = value.trim();
|
|
5807
5712
|
return normalized.length > 0 ? normalized : void 0;
|
|
5808
5713
|
}, PerspectiveMemoryNonEmptyStringSchema.optional());
|
|
5809
5714
|
var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
|
|
5810
|
-
if (!Array.isArray(value))
|
|
5811
|
-
return value;
|
|
5715
|
+
if (!Array.isArray(value)) return value;
|
|
5812
5716
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
5813
5717
|
}, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
|
|
5814
5718
|
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;
|
|
@@ -6466,6 +6370,7 @@ var GraphPathService = class {
|
|
|
6466
6370
|
constructor(db) {
|
|
6467
6371
|
this.db = db;
|
|
6468
6372
|
}
|
|
6373
|
+
db;
|
|
6469
6374
|
expand(input) {
|
|
6470
6375
|
const graph = this.loadGraph(input.direction ?? "both");
|
|
6471
6376
|
const effectiveMaxHops = normalizeMaxHops(input.maxHops);
|
|
@@ -6483,11 +6388,9 @@ var GraphPathService = class {
|
|
|
6483
6388
|
while (queue.length > 0) {
|
|
6484
6389
|
queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
|
|
6485
6390
|
const current = queue.shift();
|
|
6486
|
-
if (current.hops >= effectiveMaxHops)
|
|
6487
|
-
continue;
|
|
6391
|
+
if (current.hops >= effectiveMaxHops) continue;
|
|
6488
6392
|
for (const edge of graph.adjacency.get(current.key) ?? []) {
|
|
6489
|
-
if (current.visited.has(edge.toKey))
|
|
6490
|
-
continue;
|
|
6393
|
+
if (current.visited.has(edge.toKey)) continue;
|
|
6491
6394
|
const nextHops = current.hops + 1;
|
|
6492
6395
|
const nextTotalCost = current.totalCost + edge.step.cost;
|
|
6493
6396
|
const nextSteps = [...current.steps, edge.step];
|
|
@@ -6567,17 +6470,13 @@ function addTraversal(adjacency, fromKey, edge) {
|
|
|
6567
6470
|
adjacency.set(fromKey, edges);
|
|
6568
6471
|
}
|
|
6569
6472
|
function normalizeMaxHops(maxHops) {
|
|
6570
|
-
if (maxHops === void 0)
|
|
6571
|
-
|
|
6572
|
-
if (!Number.isFinite(maxHops))
|
|
6573
|
-
return MAX_HOPS;
|
|
6473
|
+
if (maxHops === void 0) return 1;
|
|
6474
|
+
if (!Number.isFinite(maxHops)) return MAX_HOPS;
|
|
6574
6475
|
return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
|
|
6575
6476
|
}
|
|
6576
6477
|
function normalizeMaxResults(maxResults) {
|
|
6577
|
-
if (maxResults === void 0)
|
|
6578
|
-
|
|
6579
|
-
if (!Number.isFinite(maxResults))
|
|
6580
|
-
return DEFAULT_MAX_RESULTS;
|
|
6478
|
+
if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
|
|
6479
|
+
if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
|
|
6581
6480
|
return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
|
|
6582
6481
|
}
|
|
6583
6482
|
function isBetterPath(totalCost, hops, signature, existing) {
|
|
@@ -6589,18 +6488,15 @@ function pathSignature(steps) {
|
|
|
6589
6488
|
function edgeWeight(metaJson) {
|
|
6590
6489
|
const meta = parseMeta(metaJson);
|
|
6591
6490
|
const raw = meta.weight;
|
|
6592
|
-
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
|
|
6593
|
-
return raw;
|
|
6491
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
|
|
6594
6492
|
if (typeof raw === "string") {
|
|
6595
6493
|
const parsed = Number(raw);
|
|
6596
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
6597
|
-
return parsed;
|
|
6494
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
6598
6495
|
}
|
|
6599
6496
|
return DEFAULT_WEIGHT;
|
|
6600
6497
|
}
|
|
6601
6498
|
function parseMeta(metaJson) {
|
|
6602
|
-
if (!metaJson)
|
|
6603
|
-
return {};
|
|
6499
|
+
if (!metaJson) return {};
|
|
6604
6500
|
try {
|
|
6605
6501
|
const parsed = JSON.parse(metaJson);
|
|
6606
6502
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
@@ -6613,8 +6509,7 @@ function nodeKey(node) {
|
|
|
6613
6509
|
}
|
|
6614
6510
|
function nodeFromKey(key) {
|
|
6615
6511
|
const index = key.indexOf(":");
|
|
6616
|
-
if (index === -1)
|
|
6617
|
-
return { type: "entity", id: key };
|
|
6512
|
+
if (index === -1) return { type: "entity", id: key };
|
|
6618
6513
|
return { type: key.slice(0, index), id: key.slice(index + 1) };
|
|
6619
6514
|
}
|
|
6620
6515
|
|
|
@@ -6670,6 +6565,7 @@ var QueryEntityExtractor = class {
|
|
|
6670
6565
|
constructor(db) {
|
|
6671
6566
|
this.db = db;
|
|
6672
6567
|
}
|
|
6568
|
+
db;
|
|
6673
6569
|
extract(query, options = {}) {
|
|
6674
6570
|
const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
|
|
6675
6571
|
const candidates = [];
|
|
@@ -6691,8 +6587,7 @@ var QueryEntityExtractor = class {
|
|
|
6691
6587
|
let match;
|
|
6692
6588
|
while ((match = regex.exec(query)) !== null) {
|
|
6693
6589
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6694
|
-
if (!isUsefulCandidate(text))
|
|
6695
|
-
continue;
|
|
6590
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6696
6591
|
const start = match.index + 1;
|
|
6697
6592
|
const end = start + text.length;
|
|
6698
6593
|
ranges.push([match.index, match.index + match[0].length]);
|
|
@@ -6706,8 +6601,7 @@ var QueryEntityExtractor = class {
|
|
|
6706
6601
|
return ranges;
|
|
6707
6602
|
}
|
|
6708
6603
|
extractKnownAliases(query, candidates) {
|
|
6709
|
-
if (!this.db)
|
|
6710
|
-
return;
|
|
6604
|
+
if (!this.db) return;
|
|
6711
6605
|
const rows = sqliteAll(
|
|
6712
6606
|
this.db,
|
|
6713
6607
|
`SELECT
|
|
@@ -6731,11 +6625,9 @@ var QueryEntityExtractor = class {
|
|
|
6731
6625
|
]).filter(isUsefulCandidate);
|
|
6732
6626
|
for (const alias of aliasLabels) {
|
|
6733
6627
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6734
|
-
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
|
|
6735
|
-
continue;
|
|
6628
|
+
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
|
|
6736
6629
|
const aliasKey = `${row.entity_id}:${normalizedAlias}`;
|
|
6737
|
-
if (seenAliases.has(aliasKey))
|
|
6738
|
-
continue;
|
|
6630
|
+
if (seenAliases.has(aliasKey)) continue;
|
|
6739
6631
|
seenAliases.add(aliasKey);
|
|
6740
6632
|
const range = findRange(query, alias);
|
|
6741
6633
|
pushCandidate(candidates, {
|
|
@@ -6756,8 +6648,7 @@ var QueryEntityExtractor = class {
|
|
|
6756
6648
|
let match;
|
|
6757
6649
|
while ((match = regex.exec(query)) !== null) {
|
|
6758
6650
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6759
|
-
if (!isUsefulCandidate(text))
|
|
6760
|
-
continue;
|
|
6651
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6761
6652
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6762
6653
|
pushCandidate(candidates, {
|
|
6763
6654
|
text,
|
|
@@ -6772,8 +6663,7 @@ var QueryEntityExtractor = class {
|
|
|
6772
6663
|
let match;
|
|
6773
6664
|
while ((match = regex.exec(query)) !== null) {
|
|
6774
6665
|
const text = cleanCandidateText(match[2] ?? "");
|
|
6775
|
-
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
|
|
6776
|
-
continue;
|
|
6666
|
+
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
|
|
6777
6667
|
const start = match.index + (match[1]?.length ?? 0);
|
|
6778
6668
|
pushCandidate(candidates, {
|
|
6779
6669
|
text,
|
|
@@ -6792,21 +6682,17 @@ var QueryEntityExtractor = class {
|
|
|
6792
6682
|
if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
|
|
6793
6683
|
current.push(token);
|
|
6794
6684
|
} else {
|
|
6795
|
-
if (current.length > 0)
|
|
6796
|
-
groups.push(current);
|
|
6685
|
+
if (current.length > 0) groups.push(current);
|
|
6797
6686
|
current = [token];
|
|
6798
6687
|
}
|
|
6799
6688
|
}
|
|
6800
|
-
if (current.length > 0)
|
|
6801
|
-
groups.push(current);
|
|
6689
|
+
if (current.length > 0) groups.push(current);
|
|
6802
6690
|
for (const group of groups) {
|
|
6803
|
-
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
|
|
6804
|
-
continue;
|
|
6691
|
+
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
|
|
6805
6692
|
const start = group[0].start;
|
|
6806
6693
|
const end = group[group.length - 1].end;
|
|
6807
6694
|
const text = query.slice(start, end);
|
|
6808
|
-
if (!isUsefulCandidate(text))
|
|
6809
|
-
continue;
|
|
6695
|
+
if (!isUsefulCandidate(text)) continue;
|
|
6810
6696
|
pushCandidate(candidates, {
|
|
6811
6697
|
text,
|
|
6812
6698
|
source: "capitalized_term",
|
|
@@ -6827,8 +6713,7 @@ function collectCapitalizedTokens(query) {
|
|
|
6827
6713
|
}
|
|
6828
6714
|
function pushCandidate(candidates, input) {
|
|
6829
6715
|
const text = cleanCandidateText(input.text);
|
|
6830
|
-
if (!isUsefulCandidate(text))
|
|
6831
|
-
return;
|
|
6716
|
+
if (!isUsefulCandidate(text)) return;
|
|
6832
6717
|
const source = input.source;
|
|
6833
6718
|
candidates.push({
|
|
6834
6719
|
...input,
|
|
@@ -6846,15 +6731,13 @@ function dedupeAndSort(candidates) {
|
|
|
6846
6731
|
for (const candidate of sorted) {
|
|
6847
6732
|
if (candidate.source === "entity_alias") {
|
|
6848
6733
|
const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
|
|
6849
|
-
if (seenAliasKeys.has(aliasKey))
|
|
6850
|
-
continue;
|
|
6734
|
+
if (seenAliasKeys.has(aliasKey)) continue;
|
|
6851
6735
|
seenAliasKeys.add(aliasKey);
|
|
6852
6736
|
seenNormalized.add(candidate.normalized);
|
|
6853
6737
|
result.push(candidate);
|
|
6854
6738
|
continue;
|
|
6855
6739
|
}
|
|
6856
|
-
if (seenNormalized.has(candidate.normalized))
|
|
6857
|
-
continue;
|
|
6740
|
+
if (seenNormalized.has(candidate.normalized)) continue;
|
|
6858
6741
|
seenNormalized.add(candidate.normalized);
|
|
6859
6742
|
result.push(candidate);
|
|
6860
6743
|
}
|
|
@@ -6864,8 +6747,7 @@ function compareCandidates(a, b) {
|
|
|
6864
6747
|
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 ?? "");
|
|
6865
6748
|
}
|
|
6866
6749
|
function compareStrings(a, b) {
|
|
6867
|
-
if (a === b)
|
|
6868
|
-
return 0;
|
|
6750
|
+
if (a === b) return 0;
|
|
6869
6751
|
return a < b ? -1 : 1;
|
|
6870
6752
|
}
|
|
6871
6753
|
function stripPriority(candidate) {
|
|
@@ -6873,10 +6755,8 @@ function stripPriority(candidate) {
|
|
|
6873
6755
|
return publicCandidate;
|
|
6874
6756
|
}
|
|
6875
6757
|
function normalizeMaxCandidates(maxCandidates) {
|
|
6876
|
-
if (maxCandidates === void 0)
|
|
6877
|
-
|
|
6878
|
-
if (!Number.isFinite(maxCandidates))
|
|
6879
|
-
return DEFAULT_MAX_CANDIDATES;
|
|
6758
|
+
if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
|
|
6759
|
+
if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
|
|
6880
6760
|
return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
|
|
6881
6761
|
}
|
|
6882
6762
|
function cleanCandidateText(text) {
|
|
@@ -6898,21 +6778,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
|
|
|
6898
6778
|
function findRange(query, alias) {
|
|
6899
6779
|
const normalizedAlias = normalizeForContainment(alias);
|
|
6900
6780
|
const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
|
|
6901
|
-
if (directIndex >= 0)
|
|
6902
|
-
return { start: directIndex, end: directIndex + alias.length };
|
|
6781
|
+
if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
|
|
6903
6782
|
const normalizedQuery = normalizeForContainment(query);
|
|
6904
6783
|
const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
|
|
6905
|
-
if (normalizedIndex < 0)
|
|
6906
|
-
return { start: 0, end: 0 };
|
|
6784
|
+
if (normalizedIndex < 0) return { start: 0, end: 0 };
|
|
6907
6785
|
const queryLower = query.toLowerCase();
|
|
6908
6786
|
const words = normalizedAlias.split(" ").filter(Boolean);
|
|
6909
|
-
if (words.length === 0)
|
|
6910
|
-
return { start: 0, end: 0 };
|
|
6787
|
+
if (words.length === 0) return { start: 0, end: 0 };
|
|
6911
6788
|
const first = queryLower.indexOf(words[0]);
|
|
6912
6789
|
const lastWord = words[words.length - 1];
|
|
6913
6790
|
const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
|
|
6914
|
-
if (first >= 0 && last >= 0)
|
|
6915
|
-
return { start: first, end: last + lastWord.length };
|
|
6791
|
+
if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
|
|
6916
6792
|
return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
|
|
6917
6793
|
}
|
|
6918
6794
|
function isUsefulCandidate(text) {
|
|
@@ -6923,10 +6799,8 @@ function isInsideAnyRange(index, ranges) {
|
|
|
6923
6799
|
return ranges.some(([start, end]) => index >= start && index < end);
|
|
6924
6800
|
}
|
|
6925
6801
|
function isStrongSingleCapitalized(text) {
|
|
6926
|
-
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
|
|
6927
|
-
|
|
6928
|
-
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
|
|
6929
|
-
return true;
|
|
6802
|
+
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
|
|
6803
|
+
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
|
|
6930
6804
|
return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
|
|
6931
6805
|
}
|
|
6932
6806
|
function uniqueStrings(values) {
|
|
@@ -6934,8 +6808,7 @@ function uniqueStrings(values) {
|
|
|
6934
6808
|
const result = [];
|
|
6935
6809
|
for (const value of values) {
|
|
6936
6810
|
const key = normalizeForContainment(value);
|
|
6937
|
-
if (!key || seen.has(key))
|
|
6938
|
-
continue;
|
|
6811
|
+
if (!key || seen.has(key)) continue;
|
|
6939
6812
|
seen.add(key);
|
|
6940
6813
|
result.push(value);
|
|
6941
6814
|
}
|
|
@@ -6957,8 +6830,7 @@ var LessonCandidateInputSchema = z9.object({
|
|
|
6957
6830
|
import { z as z10 } from "zod";
|
|
6958
6831
|
var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
|
|
6959
6832
|
var PromotionStringArraySchema = z10.preprocess((value) => {
|
|
6960
|
-
if (!Array.isArray(value))
|
|
6961
|
-
return value;
|
|
6833
|
+
if (!Array.isArray(value)) return value;
|
|
6962
6834
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
6963
6835
|
}, z10.array(NonEmptyStringSchema5).max(100));
|
|
6964
6836
|
var ReviewedLessonCandidateSchema = z10.object({
|
|
@@ -7006,8 +6878,7 @@ function projectHashFromStorage(projectHash) {
|
|
|
7006
6878
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7007
6879
|
}
|
|
7008
6880
|
function parseJsonRecord(value) {
|
|
7009
|
-
if (!value)
|
|
7010
|
-
return void 0;
|
|
6881
|
+
if (!value) return void 0;
|
|
7011
6882
|
try {
|
|
7012
6883
|
const parsed = JSON.parse(value);
|
|
7013
6884
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7019,8 +6890,7 @@ function sanitizeString(value) {
|
|
|
7019
6890
|
return String(sanitizeGovernanceAuditValue(value)).trim();
|
|
7020
6891
|
}
|
|
7021
6892
|
function sanitizeMetadata(metadata) {
|
|
7022
|
-
if (!metadata)
|
|
7023
|
-
return void 0;
|
|
6893
|
+
if (!metadata) return void 0;
|
|
7024
6894
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7025
6895
|
}
|
|
7026
6896
|
function slugActorPart(value) {
|
|
@@ -7028,8 +6898,7 @@ function slugActorPart(value) {
|
|
|
7028
6898
|
return slug.length > 0 ? slug : "unknown";
|
|
7029
6899
|
}
|
|
7030
6900
|
function stableActorId(input) {
|
|
7031
|
-
if (input.actorId)
|
|
7032
|
-
return sanitizeString(input.actorId);
|
|
6901
|
+
if (input.actorId) return sanitizeString(input.actorId);
|
|
7033
6902
|
const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
|
|
7034
6903
|
return [
|
|
7035
6904
|
"actor",
|
|
@@ -7052,12 +6921,10 @@ function rowToActor(row) {
|
|
|
7052
6921
|
});
|
|
7053
6922
|
}
|
|
7054
6923
|
function metadataString(metadata, keys) {
|
|
7055
|
-
if (!metadata)
|
|
7056
|
-
return void 0;
|
|
6924
|
+
if (!metadata) return void 0;
|
|
7057
6925
|
for (const key of keys) {
|
|
7058
6926
|
const value = metadata[key];
|
|
7059
|
-
if (typeof value === "string" && value.trim().length > 0)
|
|
7060
|
-
return value.trim();
|
|
6927
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
7061
6928
|
}
|
|
7062
6929
|
return void 0;
|
|
7063
6930
|
}
|
|
@@ -7107,6 +6974,7 @@ var ActorRepository = class {
|
|
|
7107
6974
|
constructor(db) {
|
|
7108
6975
|
this.db = db;
|
|
7109
6976
|
}
|
|
6977
|
+
db;
|
|
7110
6978
|
async upsert(input) {
|
|
7111
6979
|
const parsed = UpsertMemoryActorInputSchema.parse(input);
|
|
7112
6980
|
const actorId = stableActorId(parsed);
|
|
@@ -7160,8 +7028,7 @@ var ActorRepository = class {
|
|
|
7160
7028
|
}
|
|
7161
7029
|
require(actorId) {
|
|
7162
7030
|
const actor = this.get(actorId);
|
|
7163
|
-
if (!actor)
|
|
7164
|
-
throw new Error(`Memory actor not found: ${actorId}`);
|
|
7031
|
+
if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
|
|
7165
7032
|
return actor;
|
|
7166
7033
|
}
|
|
7167
7034
|
async list(input = {}) {
|
|
@@ -7197,8 +7064,7 @@ function projectHashFromStorage2(projectHash) {
|
|
|
7197
7064
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7198
7065
|
}
|
|
7199
7066
|
function parseJsonRecord2(value) {
|
|
7200
|
-
if (!value)
|
|
7201
|
-
return void 0;
|
|
7067
|
+
if (!value) return void 0;
|
|
7202
7068
|
try {
|
|
7203
7069
|
const parsed = JSON.parse(value);
|
|
7204
7070
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7207,8 +7073,7 @@ function parseJsonRecord2(value) {
|
|
|
7207
7073
|
}
|
|
7208
7074
|
}
|
|
7209
7075
|
function sanitizeMetadata2(metadata) {
|
|
7210
|
-
if (!metadata)
|
|
7211
|
-
return void 0;
|
|
7076
|
+
if (!metadata) return void 0;
|
|
7212
7077
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7213
7078
|
}
|
|
7214
7079
|
function rowToSessionActor(row) {
|
|
@@ -7228,6 +7093,7 @@ var SessionActorRepository = class {
|
|
|
7228
7093
|
constructor(db) {
|
|
7229
7094
|
this.db = db;
|
|
7230
7095
|
}
|
|
7096
|
+
db;
|
|
7231
7097
|
async upsertMembership(input) {
|
|
7232
7098
|
const parsed = UpsertSessionActorInputSchema.parse(input);
|
|
7233
7099
|
const projectHash = projectHashToStorage3(parsed.projectHash);
|
|
@@ -7274,8 +7140,7 @@ var SessionActorRepository = class {
|
|
|
7274
7140
|
);
|
|
7275
7141
|
}
|
|
7276
7142
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7277
|
-
if (!saved)
|
|
7278
|
-
throw new Error("session actor membership was not saved");
|
|
7143
|
+
if (!saved) throw new Error("session actor membership was not saved");
|
|
7279
7144
|
return saved;
|
|
7280
7145
|
}
|
|
7281
7146
|
async listBySession(input) {
|
|
@@ -7311,8 +7176,7 @@ var SessionActorRepository = class {
|
|
|
7311
7176
|
]
|
|
7312
7177
|
);
|
|
7313
7178
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7314
|
-
if (!saved)
|
|
7315
|
-
throw new Error("session actor membership not found after update");
|
|
7179
|
+
if (!saved) throw new Error("session actor membership not found after update");
|
|
7316
7180
|
return saved;
|
|
7317
7181
|
}
|
|
7318
7182
|
get(projectHash, sessionId, actorId) {
|
|
@@ -7334,8 +7198,7 @@ function projectHashFromStorage3(projectHash) {
|
|
|
7334
7198
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7335
7199
|
}
|
|
7336
7200
|
function parseStringArray2(value) {
|
|
7337
|
-
if (!value)
|
|
7338
|
-
return [];
|
|
7201
|
+
if (!value) return [];
|
|
7339
7202
|
try {
|
|
7340
7203
|
const parsed = JSON.parse(value);
|
|
7341
7204
|
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
@@ -7344,8 +7207,7 @@ function parseStringArray2(value) {
|
|
|
7344
7207
|
}
|
|
7345
7208
|
}
|
|
7346
7209
|
function parseJsonRecord3(value) {
|
|
7347
|
-
if (!value)
|
|
7348
|
-
return void 0;
|
|
7210
|
+
if (!value) return void 0;
|
|
7349
7211
|
try {
|
|
7350
7212
|
const parsed = JSON.parse(value);
|
|
7351
7213
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7361,8 +7223,7 @@ function sanitizeStoredStringArray(values) {
|
|
|
7361
7223
|
return values.map(sanitizeStoredString).filter((value) => value.length > 0);
|
|
7362
7224
|
}
|
|
7363
7225
|
function sanitizeStoredRecord(value) {
|
|
7364
|
-
if (!value)
|
|
7365
|
-
return void 0;
|
|
7226
|
+
if (!value) return void 0;
|
|
7366
7227
|
return sanitizeGovernanceAuditValue(value);
|
|
7367
7228
|
}
|
|
7368
7229
|
function stableHash(value) {
|
|
@@ -7413,8 +7274,7 @@ function sanitizedObservationSnapshot(observation) {
|
|
|
7413
7274
|
});
|
|
7414
7275
|
}
|
|
7415
7276
|
function queryScore(observation, terms) {
|
|
7416
|
-
if (terms.length === 0)
|
|
7417
|
-
return 0;
|
|
7277
|
+
if (terms.length === 0) return 0;
|
|
7418
7278
|
const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
|
|
7419
7279
|
return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
|
|
7420
7280
|
}
|
|
@@ -7460,12 +7320,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7460
7320
|
this.vectorOutbox = options.vectorOutbox;
|
|
7461
7321
|
}
|
|
7462
7322
|
}
|
|
7323
|
+
db;
|
|
7463
7324
|
vectorOutbox = null;
|
|
7464
7325
|
vectorOutboxOption;
|
|
7465
7326
|
getVectorOutbox() {
|
|
7466
7327
|
const option = this.vectorOutboxOption;
|
|
7467
|
-
if (option === false)
|
|
7468
|
-
return null;
|
|
7328
|
+
if (option === false) return null;
|
|
7469
7329
|
if (option instanceof VectorOutbox) {
|
|
7470
7330
|
this.vectorOutbox = option;
|
|
7471
7331
|
return option;
|
|
@@ -7477,8 +7337,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7477
7337
|
}
|
|
7478
7338
|
enqueueObservationSync(observationId) {
|
|
7479
7339
|
const outbox = this.getVectorOutbox();
|
|
7480
|
-
if (!outbox)
|
|
7481
|
-
return;
|
|
7340
|
+
if (!outbox) return;
|
|
7482
7341
|
outbox.enqueueSync("perspective_observation", observationId);
|
|
7483
7342
|
}
|
|
7484
7343
|
async create(input) {
|
|
@@ -7540,14 +7399,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7540
7399
|
contentHash,
|
|
7541
7400
|
sourceHash
|
|
7542
7401
|
);
|
|
7543
|
-
if (!saved)
|
|
7544
|
-
throw new Error("perspective observation was not saved");
|
|
7402
|
+
if (!saved) throw new Error("perspective observation was not saved");
|
|
7545
7403
|
this.enqueueObservationSync(saved.observationId);
|
|
7546
7404
|
});
|
|
7547
7405
|
transaction();
|
|
7548
7406
|
const savedObservation = saved;
|
|
7549
|
-
if (!savedObservation)
|
|
7550
|
-
throw new Error("perspective observation was not saved");
|
|
7407
|
+
if (!savedObservation) throw new Error("perspective observation was not saved");
|
|
7551
7408
|
await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
|
|
7552
7409
|
return savedObservation;
|
|
7553
7410
|
}
|
|
@@ -7557,8 +7414,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7557
7414
|
const ftsQuery = buildObservationFtsQuery(parsed.query);
|
|
7558
7415
|
if (ftsQuery) {
|
|
7559
7416
|
const ftsResult = this.queryWithFts(parsed, ftsQuery);
|
|
7560
|
-
if (ftsResult)
|
|
7561
|
-
return ftsResult;
|
|
7417
|
+
if (ftsResult) return ftsResult;
|
|
7562
7418
|
}
|
|
7563
7419
|
}
|
|
7564
7420
|
return this.queryWithPrefetch(parsed);
|
|
@@ -7579,8 +7435,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7579
7435
|
);
|
|
7580
7436
|
return rows.map(rowToObservation);
|
|
7581
7437
|
} catch (error) {
|
|
7582
|
-
if (isFtsUnavailableError(error))
|
|
7583
|
-
return null;
|
|
7438
|
+
if (isFtsUnavailableError(error)) return null;
|
|
7584
7439
|
throw error;
|
|
7585
7440
|
}
|
|
7586
7441
|
}
|
|
@@ -7621,8 +7476,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7621
7476
|
const parsed = DeletePerspectiveObservationInputSchema.parse(input);
|
|
7622
7477
|
const projectHash = projectHashToStorage4(parsed.projectHash);
|
|
7623
7478
|
const before = this.get(projectHash, parsed.observationId);
|
|
7624
|
-
if (!before)
|
|
7625
|
-
throw new Error("perspective observation not found");
|
|
7479
|
+
if (!before) throw new Error("perspective observation not found");
|
|
7626
7480
|
const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7627
7481
|
sqliteRun(
|
|
7628
7482
|
this.db,
|
|
@@ -7632,8 +7486,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7632
7486
|
[deletedAt, deletedAt, projectHash, parsed.observationId]
|
|
7633
7487
|
);
|
|
7634
7488
|
const after = this.get(projectHash, parsed.observationId);
|
|
7635
|
-
if (!after)
|
|
7636
|
-
throw new Error("perspective observation not found after delete");
|
|
7489
|
+
if (!after) throw new Error("perspective observation not found after delete");
|
|
7637
7490
|
await writeGovernanceAuditEntry(this.db, {
|
|
7638
7491
|
operation: "perspective_observation_delete",
|
|
7639
7492
|
actor: parsed.actor,
|
|
@@ -7689,11 +7542,9 @@ var DEFAULT_CONFIG3 = {
|
|
|
7689
7542
|
var MAX_OBSERVATION_CONTENT_CHARS = 600;
|
|
7690
7543
|
var RuleBasedPerspectiveObservationExtractor = class {
|
|
7691
7544
|
async extract(event) {
|
|
7692
|
-
if (!isSupportedSourceEvent(event))
|
|
7693
|
-
return [];
|
|
7545
|
+
if (!isSupportedSourceEvent(event)) return [];
|
|
7694
7546
|
const content = normalizeObservationContent(event.content);
|
|
7695
|
-
if (!content)
|
|
7696
|
-
return [];
|
|
7547
|
+
if (!content) return [];
|
|
7697
7548
|
return [{
|
|
7698
7549
|
content,
|
|
7699
7550
|
confidence: 0.6,
|
|
@@ -7764,8 +7615,7 @@ var PerspectiveDeriver = class {
|
|
|
7764
7615
|
for (const candidate of candidates) {
|
|
7765
7616
|
const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
|
|
7766
7617
|
const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
|
|
7767
|
-
if (observers.length === 0)
|
|
7768
|
-
continue;
|
|
7618
|
+
if (observers.length === 0) continue;
|
|
7769
7619
|
for (const observerActorId of observers) {
|
|
7770
7620
|
await this.observations.create({
|
|
7771
7621
|
projectHash,
|
|
@@ -7818,28 +7668,22 @@ function normalizeConfig(config) {
|
|
|
7818
7668
|
};
|
|
7819
7669
|
}
|
|
7820
7670
|
function clampInteger(value, fallback, min, max) {
|
|
7821
|
-
if (!Number.isFinite(value))
|
|
7822
|
-
return fallback;
|
|
7671
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7823
7672
|
return Math.max(min, Math.min(max, Math.trunc(Number(value))));
|
|
7824
7673
|
}
|
|
7825
7674
|
function isSupportedSourceEvent(event) {
|
|
7826
7675
|
return event.eventType === "user_prompt" || event.eventType === "agent_response";
|
|
7827
7676
|
}
|
|
7828
7677
|
function roleForEvent(event) {
|
|
7829
|
-
if (event.eventType === "user_prompt")
|
|
7830
|
-
|
|
7831
|
-
if (event.eventType === "
|
|
7832
|
-
|
|
7833
|
-
if (event.eventType === "tool_observation")
|
|
7834
|
-
return "tool";
|
|
7835
|
-
if (event.eventType === "session_summary")
|
|
7836
|
-
return "system";
|
|
7678
|
+
if (event.eventType === "user_prompt") return "speaker";
|
|
7679
|
+
if (event.eventType === "agent_response") return "assistant";
|
|
7680
|
+
if (event.eventType === "tool_observation") return "tool";
|
|
7681
|
+
if (event.eventType === "session_summary") return "system";
|
|
7837
7682
|
return "unknown";
|
|
7838
7683
|
}
|
|
7839
7684
|
function normalizeCandidate2(candidate) {
|
|
7840
7685
|
const content = normalizeObservationContent(candidate.content);
|
|
7841
|
-
if (!content)
|
|
7842
|
-
return null;
|
|
7686
|
+
if (!content) return null;
|
|
7843
7687
|
return {
|
|
7844
7688
|
content,
|
|
7845
7689
|
confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
|
|
@@ -7851,8 +7695,7 @@ function normalizeCandidate2(candidate) {
|
|
|
7851
7695
|
}
|
|
7852
7696
|
function normalizeObservationContent(content) {
|
|
7853
7697
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
7854
|
-
if (!normalized)
|
|
7855
|
-
return null;
|
|
7698
|
+
if (!normalized) return null;
|
|
7856
7699
|
return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
|
|
7857
7700
|
}
|
|
7858
7701
|
function normalizeOptionalString2(value) {
|
|
@@ -7860,13 +7703,11 @@ function normalizeOptionalString2(value) {
|
|
|
7860
7703
|
return normalized.length > 0 ? normalized : void 0;
|
|
7861
7704
|
}
|
|
7862
7705
|
function clampNumber(value, fallback, min, max) {
|
|
7863
|
-
if (!Number.isFinite(value))
|
|
7864
|
-
return fallback;
|
|
7706
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7865
7707
|
return Math.max(min, Math.min(max, Number(value)));
|
|
7866
7708
|
}
|
|
7867
7709
|
function sanitizeCandidateMetadata(metadata) {
|
|
7868
|
-
if (!metadata)
|
|
7869
|
-
return void 0;
|
|
7710
|
+
if (!metadata) return void 0;
|
|
7870
7711
|
const result = {};
|
|
7871
7712
|
for (const [key, value] of Object.entries(metadata)) {
|
|
7872
7713
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -7879,12 +7720,9 @@ function selectObservers(members, observedActorId, maxObservers) {
|
|
|
7879
7720
|
const selected = [];
|
|
7880
7721
|
for (const member of members) {
|
|
7881
7722
|
const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
|
|
7882
|
-
if (!canObserve)
|
|
7883
|
-
|
|
7884
|
-
if (
|
|
7885
|
-
selected.push(member.actorId);
|
|
7886
|
-
if (selected.length >= maxObservers)
|
|
7887
|
-
break;
|
|
7723
|
+
if (!canObserve) continue;
|
|
7724
|
+
if (!selected.includes(member.actorId)) selected.push(member.actorId);
|
|
7725
|
+
if (selected.length >= maxObservers) break;
|
|
7888
7726
|
}
|
|
7889
7727
|
return selected;
|
|
7890
7728
|
}
|
|
@@ -7903,6 +7741,7 @@ var VectorStore = class {
|
|
|
7903
7741
|
constructor(dbPath) {
|
|
7904
7742
|
this.dbPath = dbPath;
|
|
7905
7743
|
}
|
|
7744
|
+
dbPath;
|
|
7906
7745
|
db = null;
|
|
7907
7746
|
tableCache = /* @__PURE__ */ new Map();
|
|
7908
7747
|
defaultTableName = "conversations";
|
|
@@ -7914,8 +7753,7 @@ var VectorStore = class {
|
|
|
7914
7753
|
* conversations table.
|
|
7915
7754
|
*/
|
|
7916
7755
|
async initialize() {
|
|
7917
|
-
if (this.db)
|
|
7918
|
-
return;
|
|
7756
|
+
if (this.db) return;
|
|
7919
7757
|
this.db = await lancedb.connect(this.dbPath);
|
|
7920
7758
|
}
|
|
7921
7759
|
/**
|
|
@@ -7929,8 +7767,7 @@ var VectorStore = class {
|
|
|
7929
7767
|
* Add or update multiple vector records in batch, grouped by inferred table.
|
|
7930
7768
|
*/
|
|
7931
7769
|
async upsertBatch(records) {
|
|
7932
|
-
if (records.length === 0)
|
|
7933
|
-
return;
|
|
7770
|
+
if (records.length === 0) return;
|
|
7934
7771
|
await this.initialize();
|
|
7935
7772
|
if (!this.db) {
|
|
7936
7773
|
throw new Error("Database not initialized");
|
|
@@ -7985,8 +7822,7 @@ var VectorStore = class {
|
|
|
7985
7822
|
async delete(eventId) {
|
|
7986
7823
|
await this.initialize();
|
|
7987
7824
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7988
|
-
if (!table)
|
|
7989
|
-
return;
|
|
7825
|
+
if (!table) return;
|
|
7990
7826
|
await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
|
|
7991
7827
|
}
|
|
7992
7828
|
/**
|
|
@@ -7995,8 +7831,7 @@ var VectorStore = class {
|
|
|
7995
7831
|
async count() {
|
|
7996
7832
|
await this.initialize();
|
|
7997
7833
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
7998
|
-
if (!table)
|
|
7999
|
-
return 0;
|
|
7834
|
+
if (!table) return 0;
|
|
8000
7835
|
const result = await table.countRows();
|
|
8001
7836
|
return result;
|
|
8002
7837
|
}
|
|
@@ -8005,8 +7840,7 @@ var VectorStore = class {
|
|
|
8005
7840
|
*/
|
|
8006
7841
|
async clearAll() {
|
|
8007
7842
|
await this.initialize();
|
|
8008
|
-
if (!this.db)
|
|
8009
|
-
return;
|
|
7843
|
+
if (!this.db) return;
|
|
8010
7844
|
try {
|
|
8011
7845
|
if (typeof this.db.dropTable === "function") {
|
|
8012
7846
|
await this.db.dropTable(this.defaultTableName);
|
|
@@ -8023,8 +7857,7 @@ var VectorStore = class {
|
|
|
8023
7857
|
async exists(eventId) {
|
|
8024
7858
|
await this.initialize();
|
|
8025
7859
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8026
|
-
if (!table)
|
|
8027
|
-
return false;
|
|
7860
|
+
if (!table) return false;
|
|
8028
7861
|
const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
|
|
8029
7862
|
return results.length > 0;
|
|
8030
7863
|
}
|
|
@@ -8059,8 +7892,7 @@ var VectorStore = class {
|
|
|
8059
7892
|
throw new Error("Database not initialized");
|
|
8060
7893
|
}
|
|
8061
7894
|
const cached = this.tableCache.get(tableName);
|
|
8062
|
-
if (cached)
|
|
8063
|
-
return cached;
|
|
7895
|
+
if (cached) return cached;
|
|
8064
7896
|
const tableNames = await this.db.tableNames();
|
|
8065
7897
|
if (!tableNames.includes(tableName)) {
|
|
8066
7898
|
return null;
|
|
@@ -8139,12 +7971,9 @@ var IngestInterceptorRegistry = class {
|
|
|
8139
7971
|
}
|
|
8140
7972
|
};
|
|
8141
7973
|
function mergeHierarchicalMetadata(base, patch) {
|
|
8142
|
-
if (!base && !patch)
|
|
8143
|
-
|
|
8144
|
-
if (!base
|
|
8145
|
-
return patch;
|
|
8146
|
-
if (!patch)
|
|
8147
|
-
return base;
|
|
7974
|
+
if (!base && !patch) return void 0;
|
|
7975
|
+
if (!base) return patch;
|
|
7976
|
+
if (!patch) return base;
|
|
8148
7977
|
const result = { ...base };
|
|
8149
7978
|
for (const [key, value] of Object.entries(patch)) {
|
|
8150
7979
|
const current = result[key];
|
|
@@ -8174,33 +8003,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
|
|
|
8174
8003
|
function parseTag(tag) {
|
|
8175
8004
|
const value = (tag || "").trim();
|
|
8176
8005
|
const idx = value.indexOf(":");
|
|
8177
|
-
if (idx <= 0)
|
|
8178
|
-
return { value };
|
|
8006
|
+
if (idx <= 0) return { value };
|
|
8179
8007
|
const namespace = `${value.slice(0, idx)}:`;
|
|
8180
8008
|
const tagValue = value.slice(idx + 1);
|
|
8181
|
-
if (!tagValue)
|
|
8182
|
-
return { value };
|
|
8009
|
+
if (!tagValue) return { value };
|
|
8183
8010
|
return { namespace, value: tagValue };
|
|
8184
8011
|
}
|
|
8185
8012
|
function validateTag(tag) {
|
|
8186
8013
|
const normalized = (tag || "").trim();
|
|
8187
|
-
if (!normalized)
|
|
8188
|
-
return false;
|
|
8014
|
+
if (!normalized) return false;
|
|
8189
8015
|
const { namespace } = parseTag(normalized);
|
|
8190
|
-
if (!namespace)
|
|
8191
|
-
return true;
|
|
8016
|
+
if (!namespace) return true;
|
|
8192
8017
|
return VALID_TAG_NAMESPACES.has(namespace);
|
|
8193
8018
|
}
|
|
8194
8019
|
function normalizeTags(tags) {
|
|
8195
|
-
if (!Array.isArray(tags))
|
|
8196
|
-
return [];
|
|
8020
|
+
if (!Array.isArray(tags)) return [];
|
|
8197
8021
|
const dedup = /* @__PURE__ */ new Set();
|
|
8198
8022
|
for (const item of tags) {
|
|
8199
|
-
if (typeof item !== "string")
|
|
8200
|
-
continue;
|
|
8023
|
+
if (typeof item !== "string") continue;
|
|
8201
8024
|
const normalized = item.trim();
|
|
8202
|
-
if (!validateTag(normalized))
|
|
8203
|
-
continue;
|
|
8025
|
+
if (!validateTag(normalized)) continue;
|
|
8204
8026
|
dedup.add(normalized);
|
|
8205
8027
|
}
|
|
8206
8028
|
return [...dedup];
|
|
@@ -8217,10 +8039,8 @@ var SummaryDeriver = class {
|
|
|
8217
8039
|
* orchestration, while this class owns summary text and metadata decisions.
|
|
8218
8040
|
*/
|
|
8219
8041
|
deriveSessionSummary(events) {
|
|
8220
|
-
if (events.length < 3)
|
|
8221
|
-
|
|
8222
|
-
if (events.some((event) => event.eventType === "session_summary"))
|
|
8223
|
-
return null;
|
|
8042
|
+
if (events.length < 3) return null;
|
|
8043
|
+
if (events.some((event) => event.eventType === "session_summary")) return null;
|
|
8224
8044
|
const prompts = events.filter((event) => event.eventType === "user_prompt");
|
|
8225
8045
|
const toolObservations = events.filter((event) => event.eventType === "tool_observation");
|
|
8226
8046
|
const toolNames = Array.from(new Set(
|
|
@@ -8368,8 +8188,7 @@ var MemoryIngestService = class {
|
|
|
8368
8188
|
await this.initialize();
|
|
8369
8189
|
const events = await this.eventStore.getSessionEvents(sessionId);
|
|
8370
8190
|
const summary = this.summaryDeriver.deriveSessionSummary(events);
|
|
8371
|
-
if (!summary)
|
|
8372
|
-
return;
|
|
8191
|
+
if (!summary) return;
|
|
8373
8192
|
await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
|
|
8374
8193
|
}
|
|
8375
8194
|
async storeToolObservation(sessionId, payload) {
|
|
@@ -8437,10 +8256,8 @@ var MemoryIngestService = class {
|
|
|
8437
8256
|
}
|
|
8438
8257
|
}
|
|
8439
8258
|
async runPerspectiveDeriver(input, eventId, operation) {
|
|
8440
|
-
if (!this.perspectiveDeriver)
|
|
8441
|
-
|
|
8442
|
-
if (operation !== "user_prompt" && operation !== "agent_response")
|
|
8443
|
-
return;
|
|
8259
|
+
if (!this.perspectiveDeriver) return;
|
|
8260
|
+
if (operation !== "user_prompt" && operation !== "agent_response") return;
|
|
8444
8261
|
const event = {
|
|
8445
8262
|
id: eventId,
|
|
8446
8263
|
eventType: input.eventType,
|
|
@@ -8510,11 +8327,13 @@ var MemoryQueryService = class {
|
|
|
8510
8327
|
this.queryStore = queryStore;
|
|
8511
8328
|
this.deps = deps;
|
|
8512
8329
|
}
|
|
8330
|
+
initialize;
|
|
8331
|
+
queryStore;
|
|
8332
|
+
deps;
|
|
8513
8333
|
async keywordSearch(query, options) {
|
|
8514
8334
|
await this.initialize();
|
|
8515
8335
|
const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
|
|
8516
|
-
if (results.length === 0)
|
|
8517
|
-
return [];
|
|
8336
|
+
if (results.length === 0) return [];
|
|
8518
8337
|
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
8519
8338
|
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
8520
8339
|
const rankRange = maxRank - minRank || 1;
|
|
@@ -8760,55 +8579,42 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
|
|
|
8760
8579
|
]);
|
|
8761
8580
|
function isCommandArtifactQuery(query) {
|
|
8762
8581
|
const trimmed = query.trim();
|
|
8763
|
-
if (!trimmed)
|
|
8764
|
-
return false;
|
|
8582
|
+
if (!trimmed) return false;
|
|
8765
8583
|
const normalized = trimmed.toLowerCase();
|
|
8766
|
-
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
|
|
8767
|
-
|
|
8768
|
-
if (normalized.includes("command-name") || normalized.includes("command-message"))
|
|
8769
|
-
return true;
|
|
8584
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8585
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
8770
8586
|
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8771
8587
|
}
|
|
8772
8588
|
function isGenericContinuationQuery(query) {
|
|
8773
8589
|
const trimmed = query.trim();
|
|
8774
|
-
if (!trimmed)
|
|
8775
|
-
|
|
8776
|
-
if (
|
|
8777
|
-
return false;
|
|
8778
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8779
|
-
return false;
|
|
8590
|
+
if (!trimmed) return false;
|
|
8591
|
+
if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
8592
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8780
8593
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8781
|
-
if (tokens.length > 10)
|
|
8782
|
-
return false;
|
|
8594
|
+
if (tokens.length > 10) return false;
|
|
8783
8595
|
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);
|
|
8784
8596
|
}
|
|
8785
8597
|
function isShortRepairFollowUpQuery(query) {
|
|
8786
8598
|
const trimmed = query.trim();
|
|
8787
|
-
if (!trimmed)
|
|
8788
|
-
|
|
8789
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
8790
|
-
return false;
|
|
8599
|
+
if (!trimmed) return false;
|
|
8600
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
8791
8601
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
8792
|
-
if (tokens.length > 8)
|
|
8793
|
-
return false;
|
|
8602
|
+
if (tokens.length > 8) return false;
|
|
8794
8603
|
return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8795
8604
|
}
|
|
8796
8605
|
function isCurrentStateQuery(query) {
|
|
8797
8606
|
const trimmed = query.trim();
|
|
8798
|
-
if (!trimmed)
|
|
8799
|
-
return false;
|
|
8607
|
+
if (!trimmed) return false;
|
|
8800
8608
|
return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8801
8609
|
}
|
|
8802
8610
|
function isStaleOrSupersededContent(content) {
|
|
8803
8611
|
const trimmed = content.trim();
|
|
8804
|
-
if (!trimmed)
|
|
8805
|
-
return false;
|
|
8612
|
+
if (!trimmed) return false;
|
|
8806
8613
|
return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8807
8614
|
}
|
|
8808
8615
|
function buildRetrievalQualityQuery(query) {
|
|
8809
8616
|
const trimmed = query.trim();
|
|
8810
|
-
if (!trimmed)
|
|
8811
|
-
return query;
|
|
8617
|
+
if (!trimmed) return query;
|
|
8812
8618
|
if (isRetrievalPrivacyDecisionQuery(trimmed)) {
|
|
8813
8619
|
return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
|
|
8814
8620
|
}
|
|
@@ -8822,12 +8628,10 @@ function buildRetrievalQualityQuery(query) {
|
|
|
8822
8628
|
}
|
|
8823
8629
|
function isRetrievalPrivacyDecisionQuery(query) {
|
|
8824
8630
|
const trimmed = query.trim();
|
|
8825
|
-
if (!trimmed)
|
|
8826
|
-
return false;
|
|
8631
|
+
if (!trimmed) return false;
|
|
8827
8632
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8828
8633
|
const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8829
|
-
if (!hasDecisionSignal)
|
|
8830
|
-
return false;
|
|
8634
|
+
if (!hasDecisionSignal) return false;
|
|
8831
8635
|
const hasRawQuerySignal = terms.has("raw") && terms.has("query");
|
|
8832
8636
|
const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
|
|
8833
8637
|
const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
|
|
@@ -8840,16 +8644,14 @@ function extractTechnicalQueryTerms(query) {
|
|
|
8840
8644
|
const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
|
|
8841
8645
|
const terms = matches.filter((term) => {
|
|
8842
8646
|
const lower = term.toLowerCase();
|
|
8843
|
-
if (GENERIC_TECHNICAL_TERMS.has(lower))
|
|
8844
|
-
return false;
|
|
8647
|
+
if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
|
|
8845
8648
|
return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
|
|
8846
8649
|
});
|
|
8847
8650
|
return Array.from(new Set(terms.map((term) => term.toLowerCase())));
|
|
8848
8651
|
}
|
|
8849
8652
|
function hasTechnicalTermOverlap(query, content) {
|
|
8850
8653
|
const terms = extractTechnicalQueryTerms(query);
|
|
8851
|
-
if (terms.length === 0)
|
|
8852
|
-
return true;
|
|
8654
|
+
if (terms.length === 0) return true;
|
|
8853
8655
|
const normalizedContent = content.toLowerCase();
|
|
8854
8656
|
return terms.some((term) => normalizedContent.includes(term));
|
|
8855
8657
|
}
|
|
@@ -8865,15 +8667,12 @@ function hasDiscriminativeTermOverlap(query, content) {
|
|
|
8865
8667
|
return topicTerms.some((term) => contentTerms.has(term));
|
|
8866
8668
|
}
|
|
8867
8669
|
}
|
|
8868
|
-
if (queryTerms.length < 3)
|
|
8869
|
-
return true;
|
|
8670
|
+
if (queryTerms.length < 3) return true;
|
|
8870
8671
|
const requiredHits = queryTerms.length >= 3 ? 2 : 1;
|
|
8871
8672
|
let hits = 0;
|
|
8872
8673
|
for (const term of queryTerms) {
|
|
8873
|
-
if (contentTerms.has(term))
|
|
8874
|
-
|
|
8875
|
-
if (hits >= requiredHits)
|
|
8876
|
-
return true;
|
|
8674
|
+
if (contentTerms.has(term)) hits += 1;
|
|
8675
|
+
if (hits >= requiredHits) return true;
|
|
8877
8676
|
}
|
|
8878
8677
|
return false;
|
|
8879
8678
|
}
|
|
@@ -8883,17 +8682,14 @@ function shouldApplyTechnicalGuard(query) {
|
|
|
8883
8682
|
function hasAnyTerm(terms, expectedTerms) {
|
|
8884
8683
|
let found = false;
|
|
8885
8684
|
expectedTerms.forEach((term) => {
|
|
8886
|
-
if (terms.has(term))
|
|
8887
|
-
found = true;
|
|
8685
|
+
if (terms.has(term)) found = true;
|
|
8888
8686
|
});
|
|
8889
8687
|
return found;
|
|
8890
8688
|
}
|
|
8891
8689
|
function shouldRequireDecisionTopicOverlap(query) {
|
|
8892
|
-
if (isRetrievalPrivacyDecisionQuery(query))
|
|
8893
|
-
return false;
|
|
8690
|
+
if (isRetrievalPrivacyDecisionQuery(query)) return false;
|
|
8894
8691
|
const trimmed = query.trim();
|
|
8895
|
-
if (!trimmed)
|
|
8896
|
-
return false;
|
|
8692
|
+
if (!trimmed) return false;
|
|
8897
8693
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8898
8694
|
return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
8899
8695
|
}
|
|
@@ -8901,12 +8697,9 @@ function extractDiscriminativeQueryTerms(query) {
|
|
|
8901
8697
|
const seen = /* @__PURE__ */ new Set();
|
|
8902
8698
|
const terms = [];
|
|
8903
8699
|
for (const token of tokenizeQualityText(query)) {
|
|
8904
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token))
|
|
8905
|
-
|
|
8906
|
-
if (
|
|
8907
|
-
continue;
|
|
8908
|
-
if (seen.has(token))
|
|
8909
|
-
continue;
|
|
8700
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
|
|
8701
|
+
if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
|
|
8702
|
+
if (seen.has(token)) continue;
|
|
8910
8703
|
seen.add(token);
|
|
8911
8704
|
terms.push(token);
|
|
8912
8705
|
}
|
|
@@ -8921,14 +8714,10 @@ function tokenizeQualityText(text) {
|
|
|
8921
8714
|
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);
|
|
8922
8715
|
}
|
|
8923
8716
|
function normalizeQualityToken(token) {
|
|
8924
|
-
if (token === "apis")
|
|
8925
|
-
|
|
8926
|
-
if (token
|
|
8927
|
-
|
|
8928
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
|
|
8929
|
-
return token;
|
|
8930
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
8931
|
-
return `${token.slice(0, -3)}y`;
|
|
8717
|
+
if (token === "apis") return "api";
|
|
8718
|
+
if (token === "ids") return "id";
|
|
8719
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
|
|
8720
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
8932
8721
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
|
|
8933
8722
|
return token.slice(0, -1);
|
|
8934
8723
|
}
|
|
@@ -9110,8 +8899,7 @@ var Retriever = class {
|
|
|
9110
8899
|
const sharedMemories = [];
|
|
9111
8900
|
for (const result of sharedVectorResults) {
|
|
9112
8901
|
const entry = await this.sharedStore.get(result.entryId);
|
|
9113
|
-
if (!entry)
|
|
9114
|
-
continue;
|
|
8902
|
+
if (!entry) continue;
|
|
9115
8903
|
if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
|
|
9116
8904
|
sharedMemories.push(entry);
|
|
9117
8905
|
await this.sharedStore.recordUsage(entry.entryId);
|
|
@@ -9192,18 +8980,15 @@ var Retriever = class {
|
|
|
9192
8980
|
(result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
|
|
9193
8981
|
);
|
|
9194
8982
|
}
|
|
9195
|
-
if (filtered.length <= 2)
|
|
9196
|
-
return filtered;
|
|
8983
|
+
if (filtered.length <= 2) return filtered;
|
|
9197
8984
|
const topScore = filtered[0].score;
|
|
9198
|
-
if (topScore < 0.8)
|
|
9199
|
-
return filtered;
|
|
8985
|
+
if (topScore < 0.8) return filtered;
|
|
9200
8986
|
const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
|
|
9201
8987
|
return filtered.filter((result) => result.score >= cliffThreshold);
|
|
9202
8988
|
}
|
|
9203
8989
|
mergeResults(primary, secondary, limit) {
|
|
9204
8990
|
const byId = /* @__PURE__ */ new Map();
|
|
9205
|
-
for (const row of primary)
|
|
9206
|
-
byId.set(row.eventId, row);
|
|
8991
|
+
for (const row of primary) byId.set(row.eventId, row);
|
|
9207
8992
|
for (const row of secondary) {
|
|
9208
8993
|
const prev = byId.get(row.eventId);
|
|
9209
8994
|
if (!prev || row.score > prev.score) {
|
|
@@ -9214,23 +8999,19 @@ var Retriever = class {
|
|
|
9214
8999
|
}
|
|
9215
9000
|
async expandGraphHops(seeds, opts) {
|
|
9216
9001
|
const byId = /* @__PURE__ */ new Map();
|
|
9217
|
-
for (const s of seeds)
|
|
9218
|
-
byId.set(s.eventId, s);
|
|
9002
|
+
for (const s of seeds) byId.set(s.eventId, s);
|
|
9219
9003
|
let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
|
|
9220
9004
|
for (let hop = 1; hop <= opts.maxHops; hop += 1) {
|
|
9221
9005
|
const next = [];
|
|
9222
9006
|
for (const f of frontier) {
|
|
9223
9007
|
const ev = await this.eventStore.getEvent(f.row.eventId);
|
|
9224
|
-
if (!ev)
|
|
9225
|
-
continue;
|
|
9008
|
+
if (!ev) continue;
|
|
9226
9009
|
const rel = ev.metadata?.relatedEventIds ?? [];
|
|
9227
9010
|
const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
|
|
9228
9011
|
for (const rid of relatedIds) {
|
|
9229
|
-
if (byId.has(rid))
|
|
9230
|
-
continue;
|
|
9012
|
+
if (byId.has(rid)) continue;
|
|
9231
9013
|
const target = await this.eventStore.getEvent(rid);
|
|
9232
|
-
if (!target)
|
|
9233
|
-
continue;
|
|
9014
|
+
if (!target) continue;
|
|
9234
9015
|
const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
|
|
9235
9016
|
const row = {
|
|
9236
9017
|
id: `hop-${hop}-${rid}`,
|
|
@@ -9244,15 +9025,12 @@ var Retriever = class {
|
|
|
9244
9025
|
};
|
|
9245
9026
|
byId.set(row.eventId, row);
|
|
9246
9027
|
next.push({ row, hop });
|
|
9247
|
-
if (byId.size >= opts.limit)
|
|
9248
|
-
break;
|
|
9028
|
+
if (byId.size >= opts.limit) break;
|
|
9249
9029
|
}
|
|
9250
|
-
if (byId.size >= opts.limit)
|
|
9251
|
-
break;
|
|
9030
|
+
if (byId.size >= opts.limit) break;
|
|
9252
9031
|
}
|
|
9253
9032
|
frontier = next;
|
|
9254
|
-
if (frontier.length === 0 || byId.size >= opts.limit)
|
|
9255
|
-
break;
|
|
9033
|
+
if (frontier.length === 0 || byId.size >= opts.limit) break;
|
|
9256
9034
|
}
|
|
9257
9035
|
if (opts.queryGraphEnabled) {
|
|
9258
9036
|
await this.expandQueryGraphPaths(opts.query, byId, opts);
|
|
@@ -9260,8 +9038,7 @@ var Retriever = class {
|
|
|
9260
9038
|
return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
|
|
9261
9039
|
}
|
|
9262
9040
|
async expandQueryGraphPaths(query, byId, opts) {
|
|
9263
|
-
if (!query.trim() || !this.eventStore.getDatabase)
|
|
9264
|
-
return;
|
|
9041
|
+
if (!query.trim() || !this.eventStore.getDatabase) return;
|
|
9265
9042
|
try {
|
|
9266
9043
|
const db = this.eventStore.getDatabase();
|
|
9267
9044
|
const extraction = new QueryEntityExtractor(db).extract(query, {
|
|
@@ -9270,8 +9047,7 @@ var Retriever = class {
|
|
|
9270
9047
|
});
|
|
9271
9048
|
const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
|
|
9272
9049
|
const startNodes = uniqueEntityStartNodes(startCandidates);
|
|
9273
|
-
if (startNodes.length === 0)
|
|
9274
|
-
return;
|
|
9050
|
+
if (startNodes.length === 0) return;
|
|
9275
9051
|
const expansion = new GraphPathService(db).expand({
|
|
9276
9052
|
startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
|
|
9277
9053
|
maxHops: opts.maxHops,
|
|
@@ -9280,11 +9056,9 @@ var Retriever = class {
|
|
|
9280
9056
|
});
|
|
9281
9057
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
9282
9058
|
for (const path12 of expansion.paths) {
|
|
9283
|
-
if (path12.target.type !== "event")
|
|
9284
|
-
continue;
|
|
9059
|
+
if (path12.target.type !== "event") continue;
|
|
9285
9060
|
const target = await this.eventStore.getEvent(path12.target.id);
|
|
9286
|
-
if (!target)
|
|
9287
|
-
continue;
|
|
9061
|
+
if (!target) continue;
|
|
9288
9062
|
const graphPath = toRetrievalGraphPathDebug(path12, titleByEntityId);
|
|
9289
9063
|
const score = graphPathScore(path12, opts.hopPenalty);
|
|
9290
9064
|
const existing = byId.get(target.id);
|
|
@@ -9310,17 +9084,14 @@ var Retriever = class {
|
|
|
9310
9084
|
lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
|
|
9311
9085
|
};
|
|
9312
9086
|
byId.set(row.eventId, row);
|
|
9313
|
-
if (byId.size >= opts.limit)
|
|
9314
|
-
break;
|
|
9087
|
+
if (byId.size >= opts.limit) break;
|
|
9315
9088
|
}
|
|
9316
9089
|
} catch {
|
|
9317
9090
|
}
|
|
9318
9091
|
}
|
|
9319
9092
|
shouldFallback(matchResult, results) {
|
|
9320
|
-
if (results.length === 0)
|
|
9321
|
-
|
|
9322
|
-
if (matchResult.confidence === "none")
|
|
9323
|
-
return true;
|
|
9093
|
+
if (results.length === 0) return true;
|
|
9094
|
+
if (matchResult.confidence === "none") return true;
|
|
9324
9095
|
return false;
|
|
9325
9096
|
}
|
|
9326
9097
|
async buildSummaryFallback(query, topK) {
|
|
@@ -9425,29 +9196,21 @@ var Retriever = class {
|
|
|
9425
9196
|
(value) => typeof value === "string" && value.length > 0
|
|
9426
9197
|
)
|
|
9427
9198
|
);
|
|
9428
|
-
if (!scope && projectScopeMode === "global" && facetFilters === null)
|
|
9429
|
-
return results;
|
|
9199
|
+
if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
|
|
9430
9200
|
const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
|
|
9431
9201
|
const filtered = [];
|
|
9432
9202
|
for (const result of results) {
|
|
9433
|
-
if (scope?.sessionId && result.sessionId !== scope.sessionId)
|
|
9434
|
-
|
|
9435
|
-
if (scope?.
|
|
9436
|
-
continue;
|
|
9437
|
-
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
|
|
9438
|
-
continue;
|
|
9203
|
+
if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
|
|
9204
|
+
if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
|
|
9205
|
+
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
|
|
9439
9206
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9440
|
-
if (!event)
|
|
9441
|
-
|
|
9442
|
-
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
|
|
9443
|
-
continue;
|
|
9207
|
+
if (!event) continue;
|
|
9208
|
+
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
|
|
9444
9209
|
if (normalizedIncludes.length > 0) {
|
|
9445
9210
|
const lc = event.content.toLowerCase();
|
|
9446
|
-
if (!normalizedIncludes.some((needle) => lc.includes(needle)))
|
|
9447
|
-
continue;
|
|
9211
|
+
if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
|
|
9448
9212
|
}
|
|
9449
|
-
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
|
|
9450
|
-
continue;
|
|
9213
|
+
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
|
|
9451
9214
|
const projectHash = this.extractProjectHash(event.metadata);
|
|
9452
9215
|
filtered.push({ result, projectHash });
|
|
9453
9216
|
}
|
|
@@ -9464,27 +9227,21 @@ var Retriever = class {
|
|
|
9464
9227
|
});
|
|
9465
9228
|
}
|
|
9466
9229
|
normalizeFacetFilters(facets) {
|
|
9467
|
-
if (!facets || facets.length === 0)
|
|
9468
|
-
return null;
|
|
9230
|
+
if (!facets || facets.length === 0) return null;
|
|
9469
9231
|
const normalized = [];
|
|
9470
9232
|
for (const facet of facets) {
|
|
9471
9233
|
const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
|
|
9472
9234
|
const value = typeof facet.value === "string" ? facet.value.trim() : "";
|
|
9473
|
-
if (!parsedDimension.success || !value)
|
|
9474
|
-
return [];
|
|
9235
|
+
if (!parsedDimension.success || !value) return [];
|
|
9475
9236
|
normalized.push({ dimension: parsedDimension.data, value });
|
|
9476
9237
|
}
|
|
9477
9238
|
return normalized;
|
|
9478
9239
|
}
|
|
9479
9240
|
async applyFacetFilters(results, options) {
|
|
9480
|
-
if (options.facets === null)
|
|
9481
|
-
|
|
9482
|
-
if (options.
|
|
9483
|
-
|
|
9484
|
-
if (!options.projectHash)
|
|
9485
|
-
return [];
|
|
9486
|
-
if (!this.eventStore.getDatabase)
|
|
9487
|
-
return [];
|
|
9241
|
+
if (options.facets === null) return results;
|
|
9242
|
+
if (options.facets.length === 0) return [];
|
|
9243
|
+
if (!options.projectHash) return [];
|
|
9244
|
+
if (!this.eventStore.getDatabase) return [];
|
|
9488
9245
|
const repo = new FacetRepository(this.eventStore.getDatabase());
|
|
9489
9246
|
const filtered = [];
|
|
9490
9247
|
for (const result of results) {
|
|
@@ -9541,14 +9298,11 @@ var Retriever = class {
|
|
|
9541
9298
|
return (result.graphPaths || []).length > 0;
|
|
9542
9299
|
}
|
|
9543
9300
|
extractProjectHash(metadata) {
|
|
9544
|
-
if (!metadata || typeof metadata !== "object")
|
|
9545
|
-
return void 0;
|
|
9301
|
+
if (!metadata || typeof metadata !== "object") return void 0;
|
|
9546
9302
|
const scope = metadata.scope;
|
|
9547
|
-
if (!scope || typeof scope !== "object")
|
|
9548
|
-
return void 0;
|
|
9303
|
+
if (!scope || typeof scope !== "object") return void 0;
|
|
9549
9304
|
const project = scope.project;
|
|
9550
|
-
if (!project || typeof project !== "object")
|
|
9551
|
-
return void 0;
|
|
9305
|
+
if (!project || typeof project !== "object") return void 0;
|
|
9552
9306
|
const hash = project.hash;
|
|
9553
9307
|
return typeof hash === "string" && hash.length > 0 ? hash : void 0;
|
|
9554
9308
|
}
|
|
@@ -9562,8 +9316,7 @@ var Retriever = class {
|
|
|
9562
9316
|
const memories = [];
|
|
9563
9317
|
for (const result of results) {
|
|
9564
9318
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9565
|
-
if (!event)
|
|
9566
|
-
continue;
|
|
9319
|
+
if (!event) continue;
|
|
9567
9320
|
if (this.graduation) {
|
|
9568
9321
|
this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
|
|
9569
9322
|
}
|
|
@@ -9578,32 +9331,27 @@ var Retriever = class {
|
|
|
9578
9331
|
async getSessionContext(sessionId, eventId) {
|
|
9579
9332
|
const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
|
|
9580
9333
|
const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
|
|
9581
|
-
if (eventIndex === -1)
|
|
9582
|
-
return void 0;
|
|
9334
|
+
if (eventIndex === -1) return void 0;
|
|
9583
9335
|
const start = Math.max(0, eventIndex - 1);
|
|
9584
9336
|
const end = Math.min(sessionEvents.length, eventIndex + 2);
|
|
9585
9337
|
const contextEvents = sessionEvents.slice(start, end);
|
|
9586
|
-
if (contextEvents.length <= 1)
|
|
9587
|
-
return void 0;
|
|
9338
|
+
if (contextEvents.length <= 1) return void 0;
|
|
9588
9339
|
return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
|
|
9589
9340
|
}
|
|
9590
9341
|
buildUnifiedContext(projectResult, sharedMemories) {
|
|
9591
9342
|
let context = projectResult.context;
|
|
9592
|
-
if (sharedMemories.length === 0)
|
|
9593
|
-
return context;
|
|
9343
|
+
if (sharedMemories.length === 0) return context;
|
|
9594
9344
|
context += "\n\n## Cross-Project Knowledge\n\n";
|
|
9595
9345
|
for (const memory of sharedMemories.slice(0, 3)) {
|
|
9596
9346
|
context += `### ${memory.title}
|
|
9597
9347
|
`;
|
|
9598
|
-
if (memory.symptoms.length > 0)
|
|
9599
|
-
context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9348
|
+
if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9600
9349
|
`;
|
|
9601
9350
|
context += `**Root Cause:** ${memory.rootCause}
|
|
9602
9351
|
`;
|
|
9603
9352
|
context += `**Solution:** ${memory.solution}
|
|
9604
9353
|
`;
|
|
9605
|
-
if (memory.technologies && memory.technologies.length > 0)
|
|
9606
|
-
context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9354
|
+
if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9607
9355
|
`;
|
|
9608
9356
|
context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
|
|
9609
9357
|
|
|
@@ -9617,13 +9365,11 @@ var Retriever = class {
|
|
|
9617
9365
|
for (const memory of memories) {
|
|
9618
9366
|
const memoryText = this.formatMemory(memory);
|
|
9619
9367
|
const memoryTokens = this.estimateTokens(memoryText);
|
|
9620
|
-
if (currentTokens + memoryTokens > maxTokens)
|
|
9621
|
-
break;
|
|
9368
|
+
if (currentTokens + memoryTokens > maxTokens) break;
|
|
9622
9369
|
parts.push(memoryText);
|
|
9623
9370
|
currentTokens += memoryTokens;
|
|
9624
9371
|
}
|
|
9625
|
-
if (parts.length === 0)
|
|
9626
|
-
return "";
|
|
9372
|
+
if (parts.length === 0) return "";
|
|
9627
9373
|
return `## Relevant Memories
|
|
9628
9374
|
|
|
9629
9375
|
${parts.join("\n\n---\n\n")}`;
|
|
@@ -9633,19 +9379,16 @@ ${parts.join("\n\n---\n\n")}`;
|
|
|
9633
9379
|
const date = event.timestamp.toISOString().split("T")[0];
|
|
9634
9380
|
let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
|
|
9635
9381
|
${event.content}`;
|
|
9636
|
-
if (sessionContext)
|
|
9637
|
-
text += `
|
|
9382
|
+
if (sessionContext) text += `
|
|
9638
9383
|
|
|
9639
9384
|
_Context:_ ${sessionContext}`;
|
|
9640
9385
|
return text;
|
|
9641
9386
|
}
|
|
9642
9387
|
matchesMetadataScope(metadata, expected) {
|
|
9643
|
-
if (!metadata)
|
|
9644
|
-
return false;
|
|
9388
|
+
if (!metadata) return false;
|
|
9645
9389
|
return Object.entries(expected).every(([path12, value]) => {
|
|
9646
9390
|
const actual = path12.split(".").reduce((acc, key) => {
|
|
9647
|
-
if (typeof acc !== "object" || acc === null)
|
|
9648
|
-
return void 0;
|
|
9391
|
+
if (typeof acc !== "object" || acc === null) return void 0;
|
|
9649
9392
|
return acc[key];
|
|
9650
9393
|
}, metadata);
|
|
9651
9394
|
return actual === value;
|
|
@@ -9655,27 +9398,20 @@ _Context:_ ${sessionContext}`;
|
|
|
9655
9398
|
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);
|
|
9656
9399
|
}
|
|
9657
9400
|
normalizeToken(token) {
|
|
9658
|
-
if (token === "apis")
|
|
9659
|
-
|
|
9660
|
-
if (token === "
|
|
9661
|
-
|
|
9662
|
-
if (token === "does")
|
|
9663
|
-
return token;
|
|
9664
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
9665
|
-
return `${token.slice(0, -3)}y`;
|
|
9401
|
+
if (token === "apis") return "api";
|
|
9402
|
+
if (token === "ids") return "id";
|
|
9403
|
+
if (token === "does") return token;
|
|
9404
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
9666
9405
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
|
|
9667
9406
|
return token.slice(0, -1);
|
|
9668
9407
|
}
|
|
9669
9408
|
return token;
|
|
9670
9409
|
}
|
|
9671
9410
|
keywordOverlap(a, b) {
|
|
9672
|
-
if (a.length === 0 || b.length === 0)
|
|
9673
|
-
return 0;
|
|
9411
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
9674
9412
|
const bs = new Set(b);
|
|
9675
9413
|
let hit = 0;
|
|
9676
|
-
for (const t of a)
|
|
9677
|
-
if (bs.has(t))
|
|
9678
|
-
hit += 1;
|
|
9414
|
+
for (const t of a) if (bs.has(t)) hit += 1;
|
|
9679
9415
|
return hit / a.length;
|
|
9680
9416
|
}
|
|
9681
9417
|
estimateTokens(text) {
|
|
@@ -9696,8 +9432,7 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
9696
9432
|
const seen = /* @__PURE__ */ new Set();
|
|
9697
9433
|
const nodes = [];
|
|
9698
9434
|
for (const candidate of candidates) {
|
|
9699
|
-
if (!candidate.entityId || seen.has(candidate.entityId))
|
|
9700
|
-
continue;
|
|
9435
|
+
if (!candidate.entityId || seen.has(candidate.entityId)) continue;
|
|
9701
9436
|
seen.add(candidate.entityId);
|
|
9702
9437
|
nodes.push({ entityId: candidate.entityId, title: candidate.text });
|
|
9703
9438
|
}
|
|
@@ -9721,16 +9456,14 @@ function graphPathScore(path12, hopPenalty) {
|
|
|
9721
9456
|
return Math.max(0.05, base - hopPenalty * Math.max(0, path12.hops - 1));
|
|
9722
9457
|
}
|
|
9723
9458
|
function clampGraphHops(maxHops) {
|
|
9724
|
-
if (!Number.isFinite(maxHops))
|
|
9725
|
-
return 2;
|
|
9459
|
+
if (!Number.isFinite(maxHops)) return 2;
|
|
9726
9460
|
return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
|
|
9727
9461
|
}
|
|
9728
9462
|
function mergeGraphPaths(existing, incoming) {
|
|
9729
9463
|
const byKey = /* @__PURE__ */ new Map();
|
|
9730
9464
|
for (const path12 of [...existing, ...incoming]) {
|
|
9731
9465
|
const key = [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("\0");
|
|
9732
|
-
if (!byKey.has(key))
|
|
9733
|
-
byKey.set(key, path12);
|
|
9466
|
+
if (!byKey.has(key)) byKey.set(key, path12);
|
|
9734
9467
|
}
|
|
9735
9468
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
9736
9469
|
}
|
|
@@ -9738,10 +9471,8 @@ function graphPathSignature(path12) {
|
|
|
9738
9471
|
return [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("|");
|
|
9739
9472
|
}
|
|
9740
9473
|
function compareStable(a, b) {
|
|
9741
|
-
if (a < b)
|
|
9742
|
-
|
|
9743
|
-
if (a > b)
|
|
9744
|
-
return 1;
|
|
9474
|
+
if (a < b) return -1;
|
|
9475
|
+
if (a > b) return 1;
|
|
9745
9476
|
return 0;
|
|
9746
9477
|
}
|
|
9747
9478
|
function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
@@ -9753,6 +9484,7 @@ var RetrievalAnalyticsService = class {
|
|
|
9753
9484
|
constructor(deps) {
|
|
9754
9485
|
this.deps = deps;
|
|
9755
9486
|
}
|
|
9487
|
+
deps;
|
|
9756
9488
|
async getRetrievalTraceStats() {
|
|
9757
9489
|
await this.deps.initialize();
|
|
9758
9490
|
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
@@ -9830,6 +9562,7 @@ var RetrievalDisclosureService = class {
|
|
|
9830
9562
|
constructor(deps) {
|
|
9831
9563
|
this.deps = deps;
|
|
9832
9564
|
}
|
|
9565
|
+
deps;
|
|
9833
9566
|
async search(query, options) {
|
|
9834
9567
|
const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
|
|
9835
9568
|
const debugByEventId = this.buildDebugIndex(result);
|
|
@@ -9859,8 +9592,7 @@ var RetrievalDisclosureService = class {
|
|
|
9859
9592
|
return this.expandShared(parsedId.entryId);
|
|
9860
9593
|
}
|
|
9861
9594
|
const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9862
|
-
if (!targetEvent)
|
|
9863
|
-
return null;
|
|
9595
|
+
if (!targetEvent) return null;
|
|
9864
9596
|
const windowSize = Math.max(0, options?.windowSize ?? 3);
|
|
9865
9597
|
const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
9866
9598
|
const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
|
|
@@ -9884,8 +9616,7 @@ var RetrievalDisclosureService = class {
|
|
|
9884
9616
|
return this.sourceShared(parsedId.entryId);
|
|
9885
9617
|
}
|
|
9886
9618
|
const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
9887
|
-
if (!rawEvent)
|
|
9888
|
-
return null;
|
|
9619
|
+
if (!rawEvent) return null;
|
|
9889
9620
|
return {
|
|
9890
9621
|
...this.sourceReferenceForEvent(rawEvent),
|
|
9891
9622
|
rawEvents: [rawEvent],
|
|
@@ -9894,8 +9625,7 @@ var RetrievalDisclosureService = class {
|
|
|
9894
9625
|
}
|
|
9895
9626
|
async expandShared(entryId) {
|
|
9896
9627
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9897
|
-
if (!entry)
|
|
9898
|
-
return null;
|
|
9628
|
+
if (!entry) return null;
|
|
9899
9629
|
return {
|
|
9900
9630
|
target: this.sharedToEnvelope(entry),
|
|
9901
9631
|
surroundingFacts: [],
|
|
@@ -9906,8 +9636,7 @@ var RetrievalDisclosureService = class {
|
|
|
9906
9636
|
}
|
|
9907
9637
|
async sourceShared(entryId) {
|
|
9908
9638
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
9909
|
-
if (!entry)
|
|
9910
|
-
return null;
|
|
9639
|
+
if (!entry) return null;
|
|
9911
9640
|
const sourceReference = this.sourceReferenceForShared(entry);
|
|
9912
9641
|
return {
|
|
9913
9642
|
...sourceReference,
|
|
@@ -9993,38 +9722,25 @@ var RetrievalDisclosureService = class {
|
|
|
9993
9722
|
const reasons = /* @__PURE__ */ new Set();
|
|
9994
9723
|
const usedVector = this.usedVector(result);
|
|
9995
9724
|
const usedKeyword = this.usedKeyword(result);
|
|
9996
|
-
if (usedVector && (debug?.semanticScore ?? 0) > 0)
|
|
9997
|
-
|
|
9998
|
-
if ((debug?.
|
|
9999
|
-
|
|
10000
|
-
if ((debug?.
|
|
10001
|
-
|
|
10002
|
-
if (
|
|
10003
|
-
|
|
10004
|
-
if (
|
|
10005
|
-
reasons.add("entity_overlap");
|
|
10006
|
-
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
|
|
10007
|
-
reasons.add("summary_fallback");
|
|
10008
|
-
if (memory.sessionContext)
|
|
10009
|
-
reasons.add("continuity_link");
|
|
10010
|
-
if (memory.event.eventType === "tool_observation")
|
|
10011
|
-
reasons.add("tool_followup");
|
|
10012
|
-
if (reasons.size === 0)
|
|
10013
|
-
reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
9725
|
+
if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
|
|
9726
|
+
if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
|
|
9727
|
+
if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
|
|
9728
|
+
if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
|
|
9729
|
+
if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
|
|
9730
|
+
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
|
|
9731
|
+
if (memory.sessionContext) reasons.add("continuity_link");
|
|
9732
|
+
if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
|
|
9733
|
+
if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10014
9734
|
return Array.from(reasons);
|
|
10015
9735
|
}
|
|
10016
9736
|
reasonsForContextEvent(event) {
|
|
10017
|
-
if (event.eventType === "tool_observation")
|
|
10018
|
-
|
|
10019
|
-
if (event.eventType === "session_summary")
|
|
10020
|
-
return ["summary_fallback"];
|
|
9737
|
+
if (event.eventType === "tool_observation") return ["tool_followup"];
|
|
9738
|
+
if (event.eventType === "session_summary") return ["summary_fallback"];
|
|
10021
9739
|
return ["continuity_link"];
|
|
10022
9740
|
}
|
|
10023
9741
|
resultTypeForEvent(event) {
|
|
10024
|
-
if (event.eventType === "session_summary")
|
|
10025
|
-
|
|
10026
|
-
if (event.eventType === "tool_observation")
|
|
10027
|
-
return "tool_evidence";
|
|
9742
|
+
if (event.eventType === "session_summary") return "summary";
|
|
9743
|
+
if (event.eventType === "tool_observation") return "tool_evidence";
|
|
10028
9744
|
return "source";
|
|
10029
9745
|
}
|
|
10030
9746
|
sourceReferenceForEvent(event) {
|
|
@@ -10048,21 +9764,15 @@ var RetrievalDisclosureService = class {
|
|
|
10048
9764
|
}
|
|
10049
9765
|
sourceTypeForEvent(event) {
|
|
10050
9766
|
const metadata = event.metadata || {};
|
|
10051
|
-
if (event.eventType === "tool_observation")
|
|
10052
|
-
|
|
10053
|
-
if (typeof metadata.
|
|
10054
|
-
return "transcript";
|
|
10055
|
-
if (typeof metadata.importedFrom === "string")
|
|
10056
|
-
return "imported_history";
|
|
9767
|
+
if (event.eventType === "tool_observation") return "tool_output";
|
|
9768
|
+
if (typeof metadata.transcriptPath === "string") return "transcript";
|
|
9769
|
+
if (typeof metadata.importedFrom === "string") return "imported_history";
|
|
10057
9770
|
return "raw_event";
|
|
10058
9771
|
}
|
|
10059
9772
|
titleForEvent(event) {
|
|
10060
|
-
if (event.eventType === "session_summary")
|
|
10061
|
-
|
|
10062
|
-
if (event.eventType === "
|
|
10063
|
-
return "Tool evidence";
|
|
10064
|
-
if (event.eventType === "agent_response")
|
|
10065
|
-
return "Agent response";
|
|
9773
|
+
if (event.eventType === "session_summary") return "Session summary";
|
|
9774
|
+
if (event.eventType === "tool_observation") return "Tool evidence";
|
|
9775
|
+
if (event.eventType === "agent_response") return "Agent response";
|
|
10066
9776
|
return "User prompt";
|
|
10067
9777
|
}
|
|
10068
9778
|
usedVector(result) {
|
|
@@ -10088,8 +9798,7 @@ var RetrievalDisclosureService = class {
|
|
|
10088
9798
|
}
|
|
10089
9799
|
preview(content, maxLength) {
|
|
10090
9800
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
10091
|
-
if (normalized.length <= maxLength)
|
|
10092
|
-
return normalized;
|
|
9801
|
+
if (normalized.length <= maxLength) return normalized;
|
|
10093
9802
|
return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
10094
9803
|
}
|
|
10095
9804
|
};
|
|
@@ -10118,6 +9827,7 @@ var RetrievalOrchestrator = class {
|
|
|
10118
9827
|
this.deps = deps;
|
|
10119
9828
|
this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
|
|
10120
9829
|
}
|
|
9830
|
+
deps;
|
|
10121
9831
|
/**
|
|
10122
9832
|
* Retrieve relevant memories for a query.
|
|
10123
9833
|
*/
|
|
@@ -10199,8 +9909,7 @@ var RetrievalOrchestrator = class {
|
|
|
10199
9909
|
* the heavier retrieval/vector initialization path for prompt telemetry.
|
|
10200
9910
|
*/
|
|
10201
9911
|
async incrementMemoryAccess(eventIds) {
|
|
10202
|
-
if (eventIds.length === 0)
|
|
10203
|
-
return;
|
|
9912
|
+
if (eventIds.length === 0) return;
|
|
10204
9913
|
await this.deps.accessStore.incrementAccessCount(eventIds);
|
|
10205
9914
|
}
|
|
10206
9915
|
/**
|
|
@@ -10213,10 +9922,8 @@ var RetrievalOrchestrator = class {
|
|
|
10213
9922
|
resolveGraphHopOptions(callerOptions) {
|
|
10214
9923
|
const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
|
|
10215
9924
|
const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
|
|
10216
|
-
if (!callerOptions)
|
|
10217
|
-
|
|
10218
|
-
if (!graphExpansion)
|
|
10219
|
-
return callerOptions;
|
|
9925
|
+
if (!callerOptions) return durableOptions;
|
|
9926
|
+
if (!graphExpansion) return callerOptions;
|
|
10220
9927
|
if (graphExpansion.enabled !== true) {
|
|
10221
9928
|
return {
|
|
10222
9929
|
...callerOptions,
|
|
@@ -10276,12 +9983,10 @@ var RetrievalOrchestrator = class {
|
|
|
10276
9983
|
const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
|
|
10277
9984
|
const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
|
|
10278
9985
|
const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
|
|
10279
|
-
if (!allFinite)
|
|
10280
|
-
return void 0;
|
|
9986
|
+
if (!allFinite) return void 0;
|
|
10281
9987
|
const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
|
|
10282
9988
|
const total = semantic + lexical + recency;
|
|
10283
|
-
if (!nonNegative || total <= 0)
|
|
10284
|
-
return void 0;
|
|
9989
|
+
if (!nonNegative || total <= 0) return void 0;
|
|
10285
9990
|
return {
|
|
10286
9991
|
semantic: semantic / total,
|
|
10287
9992
|
lexical: lexical / total,
|
|
@@ -10290,17 +9995,14 @@ var RetrievalOrchestrator = class {
|
|
|
10290
9995
|
}
|
|
10291
9996
|
async getRerankWeights(adaptive) {
|
|
10292
9997
|
const configured = this.getConfiguredRerankWeights();
|
|
10293
|
-
if (configured)
|
|
10294
|
-
|
|
10295
|
-
if (adaptive)
|
|
10296
|
-
return this.getAdaptiveRerankWeights();
|
|
9998
|
+
if (configured) return configured;
|
|
9999
|
+
if (adaptive) return this.getAdaptiveRerankWeights();
|
|
10297
10000
|
return void 0;
|
|
10298
10001
|
}
|
|
10299
10002
|
async getAdaptiveRerankWeights() {
|
|
10300
10003
|
try {
|
|
10301
10004
|
const stats = await this.deps.traceStore.getHelpfulnessStats();
|
|
10302
|
-
if (stats.totalEvaluated < 20)
|
|
10303
|
-
return void 0;
|
|
10005
|
+
if (stats.totalEvaluated < 20) return void 0;
|
|
10304
10006
|
let semantic = 0.7;
|
|
10305
10007
|
let lexical = 0.2;
|
|
10306
10008
|
let recency = 0.1;
|
|
@@ -10322,11 +10024,9 @@ var RetrievalOrchestrator = class {
|
|
|
10322
10024
|
}
|
|
10323
10025
|
}
|
|
10324
10026
|
async rewriteQueryIntent(query) {
|
|
10325
|
-
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
|
|
10326
|
-
return null;
|
|
10027
|
+
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
|
|
10327
10028
|
const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
|
|
10328
|
-
if (!apiUrl)
|
|
10329
|
-
return null;
|
|
10029
|
+
if (!apiUrl) return null;
|
|
10330
10030
|
const controller = new AbortController();
|
|
10331
10031
|
const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
|
|
10332
10032
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10352,11 +10052,9 @@ var RetrievalOrchestrator = class {
|
|
|
10352
10052
|
signal: controller.signal
|
|
10353
10053
|
});
|
|
10354
10054
|
const text = (await res.text()).trim();
|
|
10355
|
-
if (!text)
|
|
10356
|
-
return null;
|
|
10055
|
+
if (!text) return null;
|
|
10357
10056
|
const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
|
|
10358
|
-
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
|
|
10359
|
-
return null;
|
|
10057
|
+
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
|
|
10360
10058
|
return oneLine;
|
|
10361
10059
|
} catch {
|
|
10362
10060
|
return null;
|
|
@@ -10498,8 +10196,7 @@ function createMemoryEngineServices(options) {
|
|
|
10498
10196
|
};
|
|
10499
10197
|
}
|
|
10500
10198
|
function shouldEnablePerspectiveDeriver(options) {
|
|
10501
|
-
if (options.readOnly)
|
|
10502
|
-
return false;
|
|
10199
|
+
if (options.readOnly) return false;
|
|
10503
10200
|
const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
|
|
10504
10201
|
return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
|
|
10505
10202
|
}
|
|
@@ -10533,6 +10230,9 @@ var GraduationWorker = class {
|
|
|
10533
10230
|
this.graduation = graduation;
|
|
10534
10231
|
this.config = config;
|
|
10535
10232
|
}
|
|
10233
|
+
eventStore;
|
|
10234
|
+
graduation;
|
|
10235
|
+
config;
|
|
10536
10236
|
running = false;
|
|
10537
10237
|
timeout = null;
|
|
10538
10238
|
lastEvaluated = /* @__PURE__ */ new Map();
|
|
@@ -10540,8 +10240,7 @@ var GraduationWorker = class {
|
|
|
10540
10240
|
* Start the graduation worker
|
|
10541
10241
|
*/
|
|
10542
10242
|
start() {
|
|
10543
|
-
if (this.running)
|
|
10544
|
-
return;
|
|
10243
|
+
if (this.running) return;
|
|
10545
10244
|
this.running = true;
|
|
10546
10245
|
this.scheduleNext();
|
|
10547
10246
|
}
|
|
@@ -10571,8 +10270,7 @@ var GraduationWorker = class {
|
|
|
10571
10270
|
* Schedule the next graduation check
|
|
10572
10271
|
*/
|
|
10573
10272
|
scheduleNext() {
|
|
10574
|
-
if (!this.running)
|
|
10575
|
-
return;
|
|
10273
|
+
if (!this.running) return;
|
|
10576
10274
|
this.timeout = setTimeout(
|
|
10577
10275
|
() => this.run(),
|
|
10578
10276
|
this.config.evaluationIntervalMs
|
|
@@ -10582,8 +10280,7 @@ var GraduationWorker = class {
|
|
|
10582
10280
|
* Run graduation evaluation
|
|
10583
10281
|
*/
|
|
10584
10282
|
async run() {
|
|
10585
|
-
if (!this.running)
|
|
10586
|
-
return;
|
|
10283
|
+
if (!this.running) return;
|
|
10587
10284
|
try {
|
|
10588
10285
|
await this.runGraduation();
|
|
10589
10286
|
} catch (error) {
|
|
@@ -10647,10 +10344,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
10647
10344
|
maxRetries: 3
|
|
10648
10345
|
};
|
|
10649
10346
|
function parseJsonArray(value) {
|
|
10650
|
-
if (Array.isArray(value))
|
|
10651
|
-
|
|
10652
|
-
if (typeof value !== "string" || value.trim().length === 0)
|
|
10653
|
-
return [];
|
|
10347
|
+
if (Array.isArray(value)) return value;
|
|
10348
|
+
if (typeof value !== "string" || value.trim().length === 0) return [];
|
|
10654
10349
|
try {
|
|
10655
10350
|
const parsed = JSON.parse(value);
|
|
10656
10351
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -10680,8 +10375,7 @@ var VectorWorker = class {
|
|
|
10680
10375
|
* Start the worker polling loop
|
|
10681
10376
|
*/
|
|
10682
10377
|
start() {
|
|
10683
|
-
if (this.running)
|
|
10684
|
-
return;
|
|
10378
|
+
if (this.running) return;
|
|
10685
10379
|
this.running = true;
|
|
10686
10380
|
this.stopping = false;
|
|
10687
10381
|
this.poll();
|
|
@@ -10757,8 +10451,7 @@ var VectorWorker = class {
|
|
|
10757
10451
|
* Poll for new items
|
|
10758
10452
|
*/
|
|
10759
10453
|
async poll() {
|
|
10760
|
-
if (!this.running || this.stopping)
|
|
10761
|
-
return;
|
|
10454
|
+
if (!this.running || this.stopping) return;
|
|
10762
10455
|
try {
|
|
10763
10456
|
await this.processBatch();
|
|
10764
10457
|
} catch (error) {
|
|
@@ -10803,6 +10496,7 @@ var DefaultContentProvider = class {
|
|
|
10803
10496
|
constructor(db) {
|
|
10804
10497
|
this.db = db;
|
|
10805
10498
|
}
|
|
10499
|
+
db;
|
|
10806
10500
|
async getContent(itemKind, itemId) {
|
|
10807
10501
|
switch (itemKind) {
|
|
10808
10502
|
case "entry":
|
|
@@ -10823,8 +10517,7 @@ var DefaultContentProvider = class {
|
|
|
10823
10517
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
10824
10518
|
[entryId]
|
|
10825
10519
|
);
|
|
10826
|
-
if (rows.length === 0)
|
|
10827
|
-
return null;
|
|
10520
|
+
if (rows.length === 0) return null;
|
|
10828
10521
|
const row = rows[0];
|
|
10829
10522
|
const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
|
|
10830
10523
|
return {
|
|
@@ -10843,8 +10536,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10843
10536
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
10844
10537
|
[taskId]
|
|
10845
10538
|
);
|
|
10846
|
-
if (rows.length === 0)
|
|
10847
|
-
return null;
|
|
10539
|
+
if (rows.length === 0) return null;
|
|
10848
10540
|
const row = rows[0];
|
|
10849
10541
|
return {
|
|
10850
10542
|
content: row.search_text || row.title,
|
|
@@ -10860,8 +10552,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10860
10552
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
10861
10553
|
[eventId]
|
|
10862
10554
|
);
|
|
10863
|
-
if (rows.length === 0)
|
|
10864
|
-
return null;
|
|
10555
|
+
if (rows.length === 0) return null;
|
|
10865
10556
|
const row = rows[0];
|
|
10866
10557
|
return {
|
|
10867
10558
|
content: row.content,
|
|
@@ -10889,8 +10580,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
10889
10580
|
}
|
|
10890
10581
|
throw error;
|
|
10891
10582
|
}
|
|
10892
|
-
if (rows.length === 0)
|
|
10893
|
-
return null;
|
|
10583
|
+
if (rows.length === 0) return null;
|
|
10894
10584
|
const row = rows[0];
|
|
10895
10585
|
const sourceEventIds = parseJsonArray(row.source_event_ids_json);
|
|
10896
10586
|
const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
|
|
@@ -10932,8 +10622,7 @@ var VectorWorkerV2 = class {
|
|
|
10932
10622
|
* Start the worker polling loop
|
|
10933
10623
|
*/
|
|
10934
10624
|
start() {
|
|
10935
|
-
if (this.running)
|
|
10936
|
-
return;
|
|
10625
|
+
if (this.running) return;
|
|
10937
10626
|
this.running = true;
|
|
10938
10627
|
this.stopping = false;
|
|
10939
10628
|
this.poll();
|
|
@@ -11003,8 +10692,7 @@ var VectorWorkerV2 = class {
|
|
|
11003
10692
|
* Poll for new jobs
|
|
11004
10693
|
*/
|
|
11005
10694
|
async poll() {
|
|
11006
|
-
if (!this.running || this.stopping)
|
|
11007
|
-
return;
|
|
10695
|
+
if (!this.running || this.stopping) return;
|
|
11008
10696
|
try {
|
|
11009
10697
|
await this.processBatch();
|
|
11010
10698
|
} catch (error) {
|
|
@@ -11071,8 +10759,7 @@ function createMemoryRuntimeService(deps) {
|
|
|
11071
10759
|
let graduationWorker = null;
|
|
11072
10760
|
return {
|
|
11073
10761
|
async initialize() {
|
|
11074
|
-
if (initialized)
|
|
11075
|
-
return;
|
|
10762
|
+
if (initialized) return;
|
|
11076
10763
|
await deps.sqliteStore.initialize();
|
|
11077
10764
|
if (deps.lightweightMode) {
|
|
11078
10765
|
initialized = true;
|
|
@@ -11166,8 +10853,7 @@ var SharedEventStore = class {
|
|
|
11166
10853
|
this.db = createDatabase(dbPath);
|
|
11167
10854
|
}
|
|
11168
10855
|
async initialize() {
|
|
11169
|
-
if (this.initialized)
|
|
11170
|
-
return;
|
|
10856
|
+
if (this.initialized) return;
|
|
11171
10857
|
await dbRun(this.db, `
|
|
11172
10858
|
CREATE TABLE IF NOT EXISTS shared_troubleshooting (
|
|
11173
10859
|
entry_id VARCHAR PRIMARY KEY,
|
|
@@ -11257,6 +10943,10 @@ var SharedPromoter = class {
|
|
|
11257
10943
|
this.embedder = embedder;
|
|
11258
10944
|
this.config = config;
|
|
11259
10945
|
}
|
|
10946
|
+
sharedStore;
|
|
10947
|
+
sharedVectorStore;
|
|
10948
|
+
embedder;
|
|
10949
|
+
config;
|
|
11260
10950
|
/**
|
|
11261
10951
|
* Check if an entry is eligible for promotion
|
|
11262
10952
|
*/
|
|
@@ -11438,6 +11128,7 @@ var SharedStore = class {
|
|
|
11438
11128
|
constructor(sharedEventStore) {
|
|
11439
11129
|
this.sharedEventStore = sharedEventStore;
|
|
11440
11130
|
}
|
|
11131
|
+
sharedEventStore;
|
|
11441
11132
|
get db() {
|
|
11442
11133
|
return this.sharedEventStore.getDatabase();
|
|
11443
11134
|
}
|
|
@@ -11542,8 +11233,7 @@ var SharedStore = class {
|
|
|
11542
11233
|
`SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
|
|
11543
11234
|
[entryId]
|
|
11544
11235
|
);
|
|
11545
|
-
if (rows.length === 0)
|
|
11546
|
-
return null;
|
|
11236
|
+
if (rows.length === 0) return null;
|
|
11547
11237
|
return this.rowToEntry(rows[0]);
|
|
11548
11238
|
}
|
|
11549
11239
|
/**
|
|
@@ -11556,8 +11246,7 @@ var SharedStore = class {
|
|
|
11556
11246
|
WHERE source_project_hash = ? AND source_entry_id = ?`,
|
|
11557
11247
|
[projectHash, sourceEntryId]
|
|
11558
11248
|
);
|
|
11559
|
-
if (rows.length === 0)
|
|
11560
|
-
return null;
|
|
11249
|
+
if (rows.length === 0) return null;
|
|
11561
11250
|
return this.rowToEntry(rows[0]);
|
|
11562
11251
|
}
|
|
11563
11252
|
/**
|
|
@@ -11667,6 +11356,7 @@ var SharedVectorStore = class {
|
|
|
11667
11356
|
constructor(dbPath) {
|
|
11668
11357
|
this.dbPath = dbPath;
|
|
11669
11358
|
}
|
|
11359
|
+
dbPath;
|
|
11670
11360
|
db = null;
|
|
11671
11361
|
table = null;
|
|
11672
11362
|
tableName = "shared_knowledge";
|
|
@@ -11674,8 +11364,7 @@ var SharedVectorStore = class {
|
|
|
11674
11364
|
* Initialize LanceDB connection
|
|
11675
11365
|
*/
|
|
11676
11366
|
async initialize() {
|
|
11677
|
-
if (this.db)
|
|
11678
|
-
return;
|
|
11367
|
+
if (this.db) return;
|
|
11679
11368
|
this.db = await lancedb2.connect(this.dbPath);
|
|
11680
11369
|
try {
|
|
11681
11370
|
const tables = await this.db.tableNames();
|
|
@@ -11717,8 +11406,7 @@ var SharedVectorStore = class {
|
|
|
11717
11406
|
* Add multiple records in batch
|
|
11718
11407
|
*/
|
|
11719
11408
|
async upsertBatch(records) {
|
|
11720
|
-
if (records.length === 0)
|
|
11721
|
-
return;
|
|
11409
|
+
if (records.length === 0) return;
|
|
11722
11410
|
await this.initialize();
|
|
11723
11411
|
if (!this.db) {
|
|
11724
11412
|
throw new Error("Database not initialized");
|
|
@@ -11779,24 +11467,21 @@ var SharedVectorStore = class {
|
|
|
11779
11467
|
* Delete vector by entry ID
|
|
11780
11468
|
*/
|
|
11781
11469
|
async delete(entryId) {
|
|
11782
|
-
if (!this.table)
|
|
11783
|
-
return;
|
|
11470
|
+
if (!this.table) return;
|
|
11784
11471
|
await this.table.delete(`entryId = '${entryId}'`);
|
|
11785
11472
|
}
|
|
11786
11473
|
/**
|
|
11787
11474
|
* Get total count
|
|
11788
11475
|
*/
|
|
11789
11476
|
async count() {
|
|
11790
|
-
if (!this.table)
|
|
11791
|
-
return 0;
|
|
11477
|
+
if (!this.table) return 0;
|
|
11792
11478
|
return this.table.countRows();
|
|
11793
11479
|
}
|
|
11794
11480
|
/**
|
|
11795
11481
|
* Check if vector exists for entry
|
|
11796
11482
|
*/
|
|
11797
11483
|
async exists(entryId) {
|
|
11798
|
-
if (!this.table)
|
|
11799
|
-
return false;
|
|
11484
|
+
if (!this.table) return false;
|
|
11800
11485
|
try {
|
|
11801
11486
|
const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
|
|
11802
11487
|
return results.length > 0;
|
|
@@ -11814,6 +11499,7 @@ var SharedMemoryServices = class {
|
|
|
11814
11499
|
constructor(options) {
|
|
11815
11500
|
this.options = options;
|
|
11816
11501
|
}
|
|
11502
|
+
options;
|
|
11817
11503
|
sharedEventStore = null;
|
|
11818
11504
|
sharedStore = null;
|
|
11819
11505
|
sharedVectorStore = null;
|
|
@@ -11838,8 +11524,7 @@ var SharedMemoryServices = class {
|
|
|
11838
11524
|
return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
|
|
11839
11525
|
}
|
|
11840
11526
|
async initialize() {
|
|
11841
|
-
if (this.options.config?.enabled === false || this.options.readOnly)
|
|
11842
|
-
return;
|
|
11527
|
+
if (this.options.config?.enabled === false || this.options.readOnly) return;
|
|
11843
11528
|
const sharedPath = this.getSharedStoragePath();
|
|
11844
11529
|
this.ensureDirectory(sharedPath, { allowCreate: true });
|
|
11845
11530
|
const store = await this.openStore(sharedPath);
|
|
@@ -11856,14 +11541,11 @@ var SharedMemoryServices = class {
|
|
|
11856
11541
|
this.options.retriever.setSharedStores(store, this.sharedVectorStore);
|
|
11857
11542
|
}
|
|
11858
11543
|
async ensureStoreForRead() {
|
|
11859
|
-
if (this.options.config?.enabled === false)
|
|
11860
|
-
|
|
11861
|
-
if (this.sharedStore)
|
|
11862
|
-
return this.sharedStore;
|
|
11544
|
+
if (this.options.config?.enabled === false) return null;
|
|
11545
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11863
11546
|
const sharedPath = this.getSharedStoragePath();
|
|
11864
11547
|
const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
|
|
11865
|
-
if (!directoryReady)
|
|
11866
|
-
return null;
|
|
11548
|
+
if (!directoryReady) return null;
|
|
11867
11549
|
return this.openStore(sharedPath);
|
|
11868
11550
|
}
|
|
11869
11551
|
async getEntryForDisclosure(entryId) {
|
|
@@ -11880,13 +11562,11 @@ var SharedMemoryServices = class {
|
|
|
11880
11562
|
return this.sharedPromoter.promoteEntry(entry, projectHash);
|
|
11881
11563
|
}
|
|
11882
11564
|
async getStats() {
|
|
11883
|
-
if (!this.sharedStore)
|
|
11884
|
-
return null;
|
|
11565
|
+
if (!this.sharedStore) return null;
|
|
11885
11566
|
return this.sharedStore.getStats();
|
|
11886
11567
|
}
|
|
11887
11568
|
async search(query, options) {
|
|
11888
|
-
if (!this.sharedStore)
|
|
11889
|
-
return [];
|
|
11569
|
+
if (!this.sharedStore) return [];
|
|
11890
11570
|
return this.sharedStore.search(query, options);
|
|
11891
11571
|
}
|
|
11892
11572
|
async close() {
|
|
@@ -11903,8 +11583,7 @@ var SharedMemoryServices = class {
|
|
|
11903
11583
|
this.openStorePromise = null;
|
|
11904
11584
|
}
|
|
11905
11585
|
async openStore(sharedPath) {
|
|
11906
|
-
if (this.sharedStore)
|
|
11907
|
-
return this.sharedStore;
|
|
11586
|
+
if (this.sharedStore) return this.sharedStore;
|
|
11908
11587
|
if (!this.openStorePromise) {
|
|
11909
11588
|
this.openStorePromise = this.createOpenStorePromise(sharedPath);
|
|
11910
11589
|
}
|
|
@@ -11928,10 +11607,8 @@ var SharedMemoryServices = class {
|
|
|
11928
11607
|
return this.sharedStore;
|
|
11929
11608
|
}
|
|
11930
11609
|
ensureDirectory(sharedPath, options) {
|
|
11931
|
-
if (this.factories.existsSync(sharedPath))
|
|
11932
|
-
|
|
11933
|
-
if (!options.allowCreate)
|
|
11934
|
-
return false;
|
|
11610
|
+
if (this.factories.existsSync(sharedPath)) return true;
|
|
11611
|
+
if (!options.allowCreate) return false;
|
|
11935
11612
|
this.factories.mkdirSync(sharedPath);
|
|
11936
11613
|
return true;
|
|
11937
11614
|
}
|
|
@@ -12807,14 +12484,12 @@ function createServer2() {
|
|
|
12807
12484
|
});
|
|
12808
12485
|
}
|
|
12809
12486
|
async function socketInUse(p) {
|
|
12810
|
-
if (!fs9.existsSync(p))
|
|
12811
|
-
return false;
|
|
12487
|
+
if (!fs9.existsSync(p)) return false;
|
|
12812
12488
|
return new Promise((resolve2) => {
|
|
12813
12489
|
let settled = false;
|
|
12814
12490
|
const client = net.createConnection(p);
|
|
12815
12491
|
const done = (alive) => {
|
|
12816
|
-
if (settled)
|
|
12817
|
-
return;
|
|
12492
|
+
if (settled) return;
|
|
12818
12493
|
settled = true;
|
|
12819
12494
|
client.destroy();
|
|
12820
12495
|
resolve2(alive);
|
|
@@ -12852,8 +12527,7 @@ async function listenServer() {
|
|
|
12852
12527
|
});
|
|
12853
12528
|
}
|
|
12854
12529
|
async function shutdown(code) {
|
|
12855
|
-
if (shuttingDown)
|
|
12856
|
-
return;
|
|
12530
|
+
if (shuttingDown) return;
|
|
12857
12531
|
shuttingDown = true;
|
|
12858
12532
|
if (idleTimer) {
|
|
12859
12533
|
clearTimeout(idleTimer);
|
|
@@ -12880,8 +12554,7 @@ async function shutdown(code) {
|
|
|
12880
12554
|
process.exit(code);
|
|
12881
12555
|
}
|
|
12882
12556
|
function installProcessHandlers() {
|
|
12883
|
-
if (processHandlersInstalled)
|
|
12884
|
-
return;
|
|
12557
|
+
if (processHandlersInstalled) return;
|
|
12885
12558
|
processHandlersInstalled = true;
|
|
12886
12559
|
process.on("SIGINT", () => {
|
|
12887
12560
|
shutdown(0).catch(() => process.exit(0));
|