claude-memory-layer 1.0.44 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +747 -1414
- package/dist/cli/index.js.map +1 -1
- package/dist/core/index.js +1191 -1490
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +411 -749
- package/dist/hooks/post-tool-use.js.map +1 -1
- package/dist/hooks/semantic-daemon.js +400 -727
- package/dist/hooks/semantic-daemon.js.map +1 -1
- package/dist/hooks/session-end.js +396 -719
- package/dist/hooks/session-end.js.map +1 -1
- package/dist/hooks/session-start.js +397 -721
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/hooks/stop.js +404 -735
- package/dist/hooks/stop.js.map +1 -1
- package/dist/hooks/user-prompt-submit.js +440 -807
- package/dist/hooks/user-prompt-submit.js.map +1 -1
- package/dist/index.js +1269 -1604
- package/dist/index.js.map +4 -4
- package/dist/mcp/index.js +1443 -1637
- package/dist/mcp/index.js.map +4 -4
- package/dist/server/api/index.js +430 -785
- package/dist/server/api/index.js.map +1 -1
- package/dist/server/index.js +438 -801
- package/dist/server/index.js.map +1 -1
- package/dist/services/memory-service.js +396 -719
- package/dist/services/memory-service.js.map +1 -1
- package/package.json +15 -3
|
@@ -16,8 +16,7 @@ import * as path7 from "path";
|
|
|
16
16
|
// src/core/metadata-extractor.ts
|
|
17
17
|
function getFileType(filePath) {
|
|
18
18
|
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
19
|
-
if (!ext)
|
|
20
|
-
return void 0;
|
|
19
|
+
if (!ext) return void 0;
|
|
21
20
|
const typeMap = {
|
|
22
21
|
ts: "typescript",
|
|
23
22
|
tsx: "typescript",
|
|
@@ -170,6 +169,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
170
169
|
this.options = options;
|
|
171
170
|
this.fileSystem = options.fileSystem ?? defaultFileSystem;
|
|
172
171
|
}
|
|
172
|
+
options;
|
|
173
173
|
fileSystem;
|
|
174
174
|
getEmbeddingModelName() {
|
|
175
175
|
return this.options.getEmbeddingModelName();
|
|
@@ -204,8 +204,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
204
204
|
}
|
|
205
205
|
const worker = this.options.getVectorWorker();
|
|
206
206
|
const wasRunning = worker?.isRunning() || false;
|
|
207
|
-
if (wasRunning)
|
|
208
|
-
worker?.stop();
|
|
207
|
+
if (wasRunning) worker?.stop();
|
|
209
208
|
await this.options.vectorStore.clearAll();
|
|
210
209
|
await this.options.eventStore.clearEmbeddingOutbox();
|
|
211
210
|
const enqueued = await this.reenqueueAllEvents();
|
|
@@ -222,8 +221,7 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
222
221
|
2
|
|
223
222
|
)
|
|
224
223
|
);
|
|
225
|
-
if (wasRunning)
|
|
226
|
-
worker?.start();
|
|
224
|
+
if (wasRunning) worker?.start();
|
|
227
225
|
return {
|
|
228
226
|
changed: true,
|
|
229
227
|
previousModel,
|
|
@@ -248,15 +246,13 @@ var DefaultEmbeddingMaintenanceService = class {
|
|
|
248
246
|
let enqueued = 0;
|
|
249
247
|
while (true) {
|
|
250
248
|
const page = await this.options.eventStore.getEventsPage(DEFAULT_PAGE_SIZE, offset);
|
|
251
|
-
if (page.length === 0)
|
|
252
|
-
break;
|
|
249
|
+
if (page.length === 0) break;
|
|
253
250
|
for (const event of page) {
|
|
254
251
|
await this.options.eventStore.enqueueForEmbedding(event.id, event.content);
|
|
255
252
|
enqueued += 1;
|
|
256
253
|
}
|
|
257
254
|
offset += page.length;
|
|
258
|
-
if (page.length < DEFAULT_PAGE_SIZE)
|
|
259
|
-
break;
|
|
255
|
+
if (page.length < DEFAULT_PAGE_SIZE) break;
|
|
260
256
|
}
|
|
261
257
|
return enqueued;
|
|
262
258
|
}
|
|
@@ -274,12 +270,9 @@ import { randomUUID } from "crypto";
|
|
|
274
270
|
// src/core/db-wrapper.ts
|
|
275
271
|
import BetterSqlite3 from "better-sqlite3";
|
|
276
272
|
function toDate(value) {
|
|
277
|
-
if (value instanceof Date)
|
|
278
|
-
|
|
279
|
-
if (typeof value === "
|
|
280
|
-
return new Date(value);
|
|
281
|
-
if (typeof value === "number")
|
|
282
|
-
return new Date(value);
|
|
273
|
+
if (value instanceof Date) return value;
|
|
274
|
+
if (typeof value === "string") return new Date(value);
|
|
275
|
+
if (typeof value === "number") return new Date(value);
|
|
283
276
|
return new Date(String(value));
|
|
284
277
|
}
|
|
285
278
|
function createDatabase(dbPath, options) {
|
|
@@ -303,6 +296,8 @@ var WorkingSetStore = class {
|
|
|
303
296
|
this.eventStore = eventStore;
|
|
304
297
|
this.config = config;
|
|
305
298
|
}
|
|
299
|
+
eventStore;
|
|
300
|
+
config;
|
|
306
301
|
get db() {
|
|
307
302
|
return this.eventStore.getDatabase();
|
|
308
303
|
}
|
|
@@ -388,8 +383,7 @@ var WorkingSetStore = class {
|
|
|
388
383
|
* Prune specific events from working set (after consolidation)
|
|
389
384
|
*/
|
|
390
385
|
async prune(eventIds) {
|
|
391
|
-
if (eventIds.length === 0)
|
|
392
|
-
return;
|
|
386
|
+
if (eventIds.length === 0) return;
|
|
393
387
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
394
388
|
await dbRun(
|
|
395
389
|
this.db,
|
|
@@ -459,8 +453,7 @@ var WorkingSetStore = class {
|
|
|
459
453
|
LIMIT ?`,
|
|
460
454
|
[maxEvents]
|
|
461
455
|
);
|
|
462
|
-
if (keepIds.length === 0)
|
|
463
|
-
return;
|
|
456
|
+
if (keepIds.length === 0) return;
|
|
464
457
|
const keepIdList = keepIds.map((r) => r.id);
|
|
465
458
|
const placeholders = keepIdList.map(() => "?").join(",");
|
|
466
459
|
await dbRun(
|
|
@@ -507,6 +500,7 @@ var ConsolidatedStore = class {
|
|
|
507
500
|
constructor(eventStore) {
|
|
508
501
|
this.eventStore = eventStore;
|
|
509
502
|
}
|
|
503
|
+
eventStore;
|
|
510
504
|
get db() {
|
|
511
505
|
return this.eventStore.getDatabase();
|
|
512
506
|
}
|
|
@@ -539,8 +533,7 @@ var ConsolidatedStore = class {
|
|
|
539
533
|
`SELECT * FROM consolidated_memories WHERE memory_id = ?`,
|
|
540
534
|
[memoryId]
|
|
541
535
|
);
|
|
542
|
-
if (rows.length === 0)
|
|
543
|
-
return null;
|
|
536
|
+
if (rows.length === 0) return null;
|
|
544
537
|
return this.rowToMemory(rows[0]);
|
|
545
538
|
}
|
|
546
539
|
/**
|
|
@@ -758,8 +751,7 @@ var ConsolidatedStore = class {
|
|
|
758
751
|
WHERE source_events LIKE ?`,
|
|
759
752
|
[`%"${eventId}"%`]
|
|
760
753
|
);
|
|
761
|
-
if ((result[0]?.count || 0) > 0)
|
|
762
|
-
return true;
|
|
754
|
+
if ((result[0]?.count || 0) > 0) return true;
|
|
763
755
|
}
|
|
764
756
|
return false;
|
|
765
757
|
}
|
|
@@ -773,8 +765,7 @@ var ConsolidatedStore = class {
|
|
|
773
765
|
ORDER BY created_at DESC
|
|
774
766
|
LIMIT 1`
|
|
775
767
|
);
|
|
776
|
-
if (result.length === 0)
|
|
777
|
-
return null;
|
|
768
|
+
if (result.length === 0) return null;
|
|
778
769
|
return new Date(result[0].created_at);
|
|
779
770
|
}
|
|
780
771
|
/**
|
|
@@ -804,6 +795,9 @@ var ConsolidationWorker = class {
|
|
|
804
795
|
this.consolidatedStore = consolidatedStore;
|
|
805
796
|
this.config = config;
|
|
806
797
|
}
|
|
798
|
+
workingSetStore;
|
|
799
|
+
consolidatedStore;
|
|
800
|
+
config;
|
|
807
801
|
running = false;
|
|
808
802
|
timeout = null;
|
|
809
803
|
lastActivity = /* @__PURE__ */ new Date();
|
|
@@ -811,8 +805,7 @@ var ConsolidationWorker = class {
|
|
|
811
805
|
* Start the consolidation worker
|
|
812
806
|
*/
|
|
813
807
|
start() {
|
|
814
|
-
if (this.running)
|
|
815
|
-
return;
|
|
808
|
+
if (this.running) return;
|
|
816
809
|
this.running = true;
|
|
817
810
|
this.scheduleNext();
|
|
818
811
|
}
|
|
@@ -855,8 +848,7 @@ var ConsolidationWorker = class {
|
|
|
855
848
|
* Schedule the next consolidation check
|
|
856
849
|
*/
|
|
857
850
|
scheduleNext() {
|
|
858
|
-
if (!this.running)
|
|
859
|
-
return;
|
|
851
|
+
if (!this.running) return;
|
|
860
852
|
this.timeout = setTimeout(
|
|
861
853
|
() => this.run(),
|
|
862
854
|
this.config.consolidation.triggerIntervalMs
|
|
@@ -866,8 +858,7 @@ var ConsolidationWorker = class {
|
|
|
866
858
|
* Run consolidation check
|
|
867
859
|
*/
|
|
868
860
|
async run() {
|
|
869
|
-
if (!this.running)
|
|
870
|
-
return;
|
|
861
|
+
if (!this.running) return;
|
|
871
862
|
try {
|
|
872
863
|
await this.checkAndConsolidate();
|
|
873
864
|
} catch (error) {
|
|
@@ -905,12 +896,10 @@ var ConsolidationWorker = class {
|
|
|
905
896
|
let consolidatedCount = 0;
|
|
906
897
|
const createdMemoryIds = [];
|
|
907
898
|
for (const group of groups) {
|
|
908
|
-
if (group.events.length < 3)
|
|
909
|
-
continue;
|
|
899
|
+
if (group.events.length < 3) continue;
|
|
910
900
|
const eventIds = group.events.map((e) => e.id);
|
|
911
901
|
const alreadyConsolidated = await this.consolidatedStore.isAlreadyConsolidated(eventIds);
|
|
912
|
-
if (alreadyConsolidated)
|
|
913
|
-
continue;
|
|
902
|
+
if (alreadyConsolidated) continue;
|
|
914
903
|
const summary = await this.summarize(group);
|
|
915
904
|
const memoryId = await this.consolidatedStore.create({
|
|
916
905
|
summary,
|
|
@@ -926,8 +915,7 @@ var ConsolidationWorker = class {
|
|
|
926
915
|
const consolidatedEventIds = groups.filter((g) => g.events.length >= 3).flatMap((g) => g.events.map((e) => e.id));
|
|
927
916
|
const oldEventIds = consolidatedEventIds.filter((id) => {
|
|
928
917
|
const event = workingSet.recentEvents.find((e) => e.id === id);
|
|
929
|
-
if (!event)
|
|
930
|
-
return false;
|
|
918
|
+
if (!event) return false;
|
|
931
919
|
const ageHours = (Date.now() - event.timestamp.getTime()) / (1e3 * 60 * 60);
|
|
932
920
|
return ageHours > this.config.workingSet.timeWindowHours / 2;
|
|
933
921
|
});
|
|
@@ -942,18 +930,13 @@ var ConsolidationWorker = class {
|
|
|
942
930
|
let promoted = 0;
|
|
943
931
|
for (const memoryId of memoryIds) {
|
|
944
932
|
const memory = await this.consolidatedStore.get(memoryId);
|
|
945
|
-
if (!memory)
|
|
946
|
-
|
|
947
|
-
if (memory.
|
|
948
|
-
continue;
|
|
949
|
-
if (memory.sourceEvents.length < 4)
|
|
950
|
-
continue;
|
|
933
|
+
if (!memory) continue;
|
|
934
|
+
if (memory.confidence < 0.55) continue;
|
|
935
|
+
if (memory.sourceEvents.length < 4) continue;
|
|
951
936
|
const exists = await this.consolidatedStore.hasRuleForSourceMemory(memoryId);
|
|
952
|
-
if (exists)
|
|
953
|
-
continue;
|
|
937
|
+
if (exists) continue;
|
|
954
938
|
const rule = this.buildRuleFromSummary(memory.summary, memory.topics);
|
|
955
|
-
if (!rule)
|
|
956
|
-
continue;
|
|
939
|
+
if (!rule) continue;
|
|
957
940
|
await this.consolidatedStore.createRule({
|
|
958
941
|
rule,
|
|
959
942
|
topics: memory.topics,
|
|
@@ -969,8 +952,7 @@ var ConsolidationWorker = class {
|
|
|
969
952
|
const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).filter((l) => !l.toLowerCase().startsWith("topics:"));
|
|
970
953
|
const bullet = lines.find((l) => l.startsWith("- "))?.replace(/^-\s*/, "");
|
|
971
954
|
const seed = bullet || lines[0];
|
|
972
|
-
if (!seed || seed.length < 8)
|
|
973
|
-
return null;
|
|
955
|
+
if (!seed || seed.length < 8) return null;
|
|
974
956
|
const topicPrefix = topics.length > 0 ? `[${topics.slice(0, 2).join(", ")}] ` : "";
|
|
975
957
|
return `${topicPrefix}${seed}`;
|
|
976
958
|
}
|
|
@@ -1131,8 +1113,7 @@ var ConsolidationWorker = class {
|
|
|
1131
1113
|
*/
|
|
1132
1114
|
extractKeyPoint(content) {
|
|
1133
1115
|
const sentences = content.split(/[.!?\n]+/).filter((s) => s.trim().length > 10);
|
|
1134
|
-
if (sentences.length === 0)
|
|
1135
|
-
return null;
|
|
1116
|
+
if (sentences.length === 0) return null;
|
|
1136
1117
|
const firstSentence = sentences[0].trim();
|
|
1137
1118
|
if (firstSentence.length > 100) {
|
|
1138
1119
|
return firstSentence.slice(0, 100) + "...";
|
|
@@ -1152,8 +1133,7 @@ var ConsolidationWorker = class {
|
|
|
1152
1133
|
* Calculate time proximity score
|
|
1153
1134
|
*/
|
|
1154
1135
|
calculateTimeProximity(events) {
|
|
1155
|
-
if (events.length < 2)
|
|
1156
|
-
return 1;
|
|
1136
|
+
if (events.length < 2) return 1;
|
|
1157
1137
|
const timestamps = events.map((e) => e.timestamp.getTime()).sort((a, b) => a - b);
|
|
1158
1138
|
const timeSpan = timestamps[timestamps.length - 1] - timestamps[0];
|
|
1159
1139
|
const avgGap = timeSpan / (events.length - 1);
|
|
@@ -1172,6 +1152,8 @@ var ContinuityManager = class {
|
|
|
1172
1152
|
this.eventStore = eventStore;
|
|
1173
1153
|
this.config = config;
|
|
1174
1154
|
}
|
|
1155
|
+
eventStore;
|
|
1156
|
+
config;
|
|
1175
1157
|
lastContext = null;
|
|
1176
1158
|
get db() {
|
|
1177
1159
|
return this.eventStore.getDatabase();
|
|
@@ -1291,8 +1273,7 @@ var ContinuityManager = class {
|
|
|
1291
1273
|
* Calculate overlap between two arrays
|
|
1292
1274
|
*/
|
|
1293
1275
|
calculateOverlap(a, b) {
|
|
1294
|
-
if (a.length === 0 || b.length === 0)
|
|
1295
|
-
return 0;
|
|
1276
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
1296
1277
|
const setA = new Set(a.map((s) => s.toLowerCase()));
|
|
1297
1278
|
const setB = new Set(b.map((s) => s.toLowerCase()));
|
|
1298
1279
|
const intersection = [...setA].filter((x) => setB.has(x));
|
|
@@ -1465,6 +1446,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1465
1446
|
this.options = options;
|
|
1466
1447
|
this.factories = options.factories ? { ...options.factories, randomUUID: options.factories.randomUUID ?? randomUUID4 } : defaultFactories;
|
|
1467
1448
|
}
|
|
1449
|
+
options;
|
|
1468
1450
|
factories;
|
|
1469
1451
|
workingSetStore = null;
|
|
1470
1452
|
consolidatedStore = null;
|
|
@@ -1479,8 +1461,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1479
1461
|
}
|
|
1480
1462
|
}
|
|
1481
1463
|
async initializeEndlessMode() {
|
|
1482
|
-
if (this.consolidationWorker)
|
|
1483
|
-
return;
|
|
1464
|
+
if (this.consolidationWorker) return;
|
|
1484
1465
|
const config = await this.getEndlessConfig();
|
|
1485
1466
|
const workingSetStore = this.factories.createWorkingSetStore(this.options.eventStore, config);
|
|
1486
1467
|
const consolidatedStore = this.factories.createConsolidatedStore(this.options.eventStore);
|
|
@@ -1512,8 +1493,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1512
1493
|
}
|
|
1513
1494
|
async setMode(mode) {
|
|
1514
1495
|
await this.options.initialize();
|
|
1515
|
-
if (mode === this.mode)
|
|
1516
|
-
return;
|
|
1496
|
+
if (mode === this.mode) return;
|
|
1517
1497
|
this.mode = mode;
|
|
1518
1498
|
await this.options.configStore.setEndlessConfig("mode", mode);
|
|
1519
1499
|
if (mode === "endless") {
|
|
@@ -1529,33 +1509,27 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1529
1509
|
return this.mode === "endless";
|
|
1530
1510
|
}
|
|
1531
1511
|
async addToWorkingSet(eventId, relevanceScore) {
|
|
1532
|
-
if (!this.workingSetStore)
|
|
1533
|
-
return;
|
|
1512
|
+
if (!this.workingSetStore) return;
|
|
1534
1513
|
await this.workingSetStore.add(eventId, relevanceScore);
|
|
1535
1514
|
}
|
|
1536
1515
|
async getWorkingSet() {
|
|
1537
|
-
if (!this.workingSetStore)
|
|
1538
|
-
return null;
|
|
1516
|
+
if (!this.workingSetStore) return null;
|
|
1539
1517
|
return this.workingSetStore.get();
|
|
1540
1518
|
}
|
|
1541
1519
|
async searchConsolidated(query, options) {
|
|
1542
|
-
if (!this.consolidatedStore)
|
|
1543
|
-
return [];
|
|
1520
|
+
if (!this.consolidatedStore) return [];
|
|
1544
1521
|
return this.consolidatedStore.search(query, options);
|
|
1545
1522
|
}
|
|
1546
1523
|
async getConsolidatedMemories(limit) {
|
|
1547
|
-
if (!this.consolidatedStore)
|
|
1548
|
-
return [];
|
|
1524
|
+
if (!this.consolidatedStore) return [];
|
|
1549
1525
|
return this.consolidatedStore.getAll({ limit });
|
|
1550
1526
|
}
|
|
1551
1527
|
async markMemoryAccessed(memoryId) {
|
|
1552
|
-
if (!this.consolidatedStore)
|
|
1553
|
-
return;
|
|
1528
|
+
if (!this.consolidatedStore) return;
|
|
1554
1529
|
await this.consolidatedStore.markAccessed(memoryId);
|
|
1555
1530
|
}
|
|
1556
1531
|
async calculateContinuity(content, metadata) {
|
|
1557
|
-
if (!this.continuityManager)
|
|
1558
|
-
return null;
|
|
1532
|
+
if (!this.continuityManager) return null;
|
|
1559
1533
|
const snapshot = this.continuityManager.createSnapshot(
|
|
1560
1534
|
this.factories.randomUUID(),
|
|
1561
1535
|
content,
|
|
@@ -1567,8 +1541,7 @@ var DefaultEndlessMemoryServices = class {
|
|
|
1567
1541
|
this.consolidationWorker?.recordActivity();
|
|
1568
1542
|
}
|
|
1569
1543
|
async forceConsolidation() {
|
|
1570
|
-
if (!this.consolidationWorker)
|
|
1571
|
-
return 0;
|
|
1544
|
+
if (!this.consolidationWorker) return 0;
|
|
1572
1545
|
return this.consolidationWorker.forceRun();
|
|
1573
1546
|
}
|
|
1574
1547
|
async getEndlessModeStatus() {
|
|
@@ -1660,8 +1633,7 @@ var Embedder = class _Embedder {
|
|
|
1660
1633
|
* Initialize the embedding pipeline
|
|
1661
1634
|
*/
|
|
1662
1635
|
async initialize() {
|
|
1663
|
-
if (this.initialized)
|
|
1664
|
-
return;
|
|
1636
|
+
if (this.initialized) return;
|
|
1665
1637
|
const pipeline = await withSuppressedKnownTransformersWarnings(async () => {
|
|
1666
1638
|
try {
|
|
1667
1639
|
return await loadTransformersPipeline();
|
|
@@ -1778,8 +1750,7 @@ async function withSuppressedKnownTransformersWarnings(fn) {
|
|
|
1778
1750
|
originalConsoleWarn = console.warn;
|
|
1779
1751
|
console.warn = (...args) => {
|
|
1780
1752
|
const message = args.map(String).join(" ");
|
|
1781
|
-
if (isKnownBenignTransformersWarning(message))
|
|
1782
|
-
return;
|
|
1753
|
+
if (isKnownBenignTransformersWarning(message)) return;
|
|
1783
1754
|
(originalConsoleWarn ?? console.warn)(...args);
|
|
1784
1755
|
};
|
|
1785
1756
|
}
|
|
@@ -2061,8 +2032,7 @@ var GraduationPipeline = class {
|
|
|
2061
2032
|
const preferenceKeywords = ["prefer", "like", "want", "always", "never", "favorite"];
|
|
2062
2033
|
const preferences = [];
|
|
2063
2034
|
for (const event of events) {
|
|
2064
|
-
if (event.eventType !== "user_prompt")
|
|
2065
|
-
continue;
|
|
2035
|
+
if (event.eventType !== "user_prompt") continue;
|
|
2066
2036
|
const lowerContent = event.content.toLowerCase();
|
|
2067
2037
|
for (const keyword of preferenceKeywords) {
|
|
2068
2038
|
if (lowerContent.includes(keyword)) {
|
|
@@ -2228,11 +2198,9 @@ function sanitizeSegment(input, fallback) {
|
|
|
2228
2198
|
return v || fallback;
|
|
2229
2199
|
}
|
|
2230
2200
|
function getAtPath(obj, dotted) {
|
|
2231
|
-
if (!obj)
|
|
2232
|
-
return void 0;
|
|
2201
|
+
if (!obj) return void 0;
|
|
2233
2202
|
return dotted.split(".").reduce((acc, key) => {
|
|
2234
|
-
if (!acc || typeof acc !== "object")
|
|
2235
|
-
return void 0;
|
|
2203
|
+
if (!acc || typeof acc !== "object") return void 0;
|
|
2236
2204
|
return acc[key];
|
|
2237
2205
|
}, obj);
|
|
2238
2206
|
}
|
|
@@ -2252,6 +2220,7 @@ var MarkdownMirror = class {
|
|
|
2252
2220
|
constructor(rootDir) {
|
|
2253
2221
|
this.rootDir = rootDir;
|
|
2254
2222
|
}
|
|
2223
|
+
rootDir;
|
|
2255
2224
|
async append(event, eventId) {
|
|
2256
2225
|
const out = buildMirrorPath(this.rootDir, event);
|
|
2257
2226
|
fs2.mkdirSync(path2.dirname(out), { recursive: true });
|
|
@@ -2383,10 +2352,8 @@ function sqliteClose(db) {
|
|
|
2383
2352
|
db.close();
|
|
2384
2353
|
}
|
|
2385
2354
|
function toDateFromSQLite(value) {
|
|
2386
|
-
if (value instanceof Date)
|
|
2387
|
-
|
|
2388
|
-
if (typeof value === "number")
|
|
2389
|
-
return new Date(value);
|
|
2355
|
+
if (value instanceof Date) return value;
|
|
2356
|
+
if (typeof value === "number") return new Date(value);
|
|
2390
2357
|
if (typeof value === "string") {
|
|
2391
2358
|
const trimmed = value.trim();
|
|
2392
2359
|
if (/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(trimmed)) {
|
|
@@ -2408,8 +2375,7 @@ var DEFAULT_CATEGORY = "uncategorized";
|
|
|
2408
2375
|
function sanitizeSegment2(input, fallback) {
|
|
2409
2376
|
const raw = String(input ?? "").trim().toLowerCase();
|
|
2410
2377
|
const safe = raw.normalize("NFKD").replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2411
|
-
if (!safe || safe === "." || safe === "..")
|
|
2412
|
-
return fallback;
|
|
2378
|
+
if (!safe || safe === "." || safe === "..") return fallback;
|
|
2413
2379
|
return safe;
|
|
2414
2380
|
}
|
|
2415
2381
|
function getCategorySegments(metadata, eventType) {
|
|
@@ -2450,6 +2416,7 @@ var MarkdownMirror2 = class {
|
|
|
2450
2416
|
constructor(rootDir) {
|
|
2451
2417
|
this.rootDir = rootDir;
|
|
2452
2418
|
}
|
|
2419
|
+
rootDir;
|
|
2453
2420
|
async append(event) {
|
|
2454
2421
|
const outPath = buildMirrorPath2(this.rootDir, event);
|
|
2455
2422
|
await fs5.mkdir(path4.dirname(outPath), { recursive: true });
|
|
@@ -2472,6 +2439,7 @@ var VectorOutbox = class {
|
|
|
2472
2439
|
this.db = db;
|
|
2473
2440
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
2474
2441
|
}
|
|
2442
|
+
db;
|
|
2475
2443
|
config;
|
|
2476
2444
|
/**
|
|
2477
2445
|
* Enqueue item for vectorization (idempotent).
|
|
@@ -2568,8 +2536,7 @@ var VectorOutbox = class {
|
|
|
2568
2536
|
`SELECT retry_count FROM vector_outbox WHERE job_id = ?`,
|
|
2569
2537
|
[jobId]
|
|
2570
2538
|
);
|
|
2571
|
-
if (rows.length === 0)
|
|
2572
|
-
return;
|
|
2539
|
+
if (rows.length === 0) return;
|
|
2573
2540
|
const retryCount = rows[0].retry_count;
|
|
2574
2541
|
const newStatus = retryCount >= this.config.maxRetries - 1 ? "failed" : "pending";
|
|
2575
2542
|
await dbRun(
|
|
@@ -2589,8 +2556,7 @@ var VectorOutbox = class {
|
|
|
2589
2556
|
`SELECT * FROM vector_outbox WHERE job_id = ?`,
|
|
2590
2557
|
[jobId]
|
|
2591
2558
|
);
|
|
2592
|
-
if (rows.length === 0)
|
|
2593
|
-
return null;
|
|
2559
|
+
if (rows.length === 0) return null;
|
|
2594
2560
|
return this.rowToJob(rows[0]);
|
|
2595
2561
|
}
|
|
2596
2562
|
/**
|
|
@@ -2724,30 +2690,24 @@ function isRetrievalDebugLaneName(value) {
|
|
|
2724
2690
|
return typeof value === "string" && RETRIEVAL_DEBUG_LANE_NAME_SET.has(value);
|
|
2725
2691
|
}
|
|
2726
2692
|
function normalizeRetrievalDebugLanes(value, maxItems = 6) {
|
|
2727
|
-
if (!Array.isArray(value) || maxItems <= 0)
|
|
2728
|
-
return [];
|
|
2693
|
+
if (!Array.isArray(value) || maxItems <= 0) return [];
|
|
2729
2694
|
const normalized = [];
|
|
2730
2695
|
const seen = /* @__PURE__ */ new Set();
|
|
2731
2696
|
for (const item of value) {
|
|
2732
2697
|
const lane = normalizeRetrievalDebugLane(item);
|
|
2733
|
-
if (!lane)
|
|
2734
|
-
continue;
|
|
2698
|
+
if (!lane) continue;
|
|
2735
2699
|
const key = [lane.lane, lane.reason, lane.score ?? ""].join("\0");
|
|
2736
|
-
if (seen.has(key))
|
|
2737
|
-
continue;
|
|
2700
|
+
if (seen.has(key)) continue;
|
|
2738
2701
|
seen.add(key);
|
|
2739
2702
|
normalized.push(lane);
|
|
2740
|
-
if (normalized.length >= maxItems)
|
|
2741
|
-
break;
|
|
2703
|
+
if (normalized.length >= maxItems) break;
|
|
2742
2704
|
}
|
|
2743
2705
|
return normalized;
|
|
2744
2706
|
}
|
|
2745
2707
|
function normalizeRetrievalDebugLane(value) {
|
|
2746
|
-
if (!value || typeof value !== "object")
|
|
2747
|
-
return null;
|
|
2708
|
+
if (!value || typeof value !== "object") return null;
|
|
2748
2709
|
const raw = value;
|
|
2749
|
-
if (!isRetrievalDebugLaneName(raw.lane))
|
|
2750
|
-
return null;
|
|
2710
|
+
if (!isRetrievalDebugLaneName(raw.lane)) return null;
|
|
2751
2711
|
const reason = sanitizeRetrievalLaneReason(typeof raw.reason === "string" ? raw.reason : "") || "unspecified";
|
|
2752
2712
|
const score = typeof raw.score === "number" && Number.isFinite(raw.score) ? Math.max(0, Math.min(1, raw.score)) : void 0;
|
|
2753
2713
|
return score === void 0 ? { lane: raw.lane, reason } : { lane: raw.lane, reason, score };
|
|
@@ -2770,27 +2730,21 @@ function normalizeRetrievalTraceDetails(details) {
|
|
|
2770
2730
|
eventId: detail.eventId,
|
|
2771
2731
|
score: detail.score
|
|
2772
2732
|
};
|
|
2773
|
-
if (detail.semanticScore !== void 0)
|
|
2774
|
-
|
|
2775
|
-
if (detail.
|
|
2776
|
-
|
|
2777
|
-
if (detail.recencyScore !== void 0)
|
|
2778
|
-
normalized.recencyScore = detail.recencyScore;
|
|
2779
|
-
if (lanes.length > 0)
|
|
2780
|
-
normalized.lanes = lanes;
|
|
2733
|
+
if (detail.semanticScore !== void 0) normalized.semanticScore = detail.semanticScore;
|
|
2734
|
+
if (detail.lexicalScore !== void 0) normalized.lexicalScore = detail.lexicalScore;
|
|
2735
|
+
if (detail.recencyScore !== void 0) normalized.recencyScore = detail.recencyScore;
|
|
2736
|
+
if (lanes.length > 0) normalized.lanes = lanes;
|
|
2781
2737
|
return normalized;
|
|
2782
2738
|
});
|
|
2783
2739
|
}
|
|
2784
2740
|
function parseRetrievalTraceDetails(value) {
|
|
2785
|
-
if (typeof value !== "string" || value.length === 0)
|
|
2786
|
-
return [];
|
|
2741
|
+
if (typeof value !== "string" || value.length === 0) return [];
|
|
2787
2742
|
const parsed = JSON.parse(value);
|
|
2788
2743
|
return Array.isArray(parsed) ? normalizeRetrievalTraceDetails(parsed) : [];
|
|
2789
2744
|
}
|
|
2790
2745
|
function normalizeQueryRewriteKind(value) {
|
|
2791
2746
|
const normalized = (value || "").trim().toLowerCase();
|
|
2792
|
-
if (normalized === "follow-up-context" || normalized === "intent-rewrite")
|
|
2793
|
-
return normalized;
|
|
2747
|
+
if (normalized === "follow-up-context" || normalized === "intent-rewrite") return normalized;
|
|
2794
2748
|
return "none";
|
|
2795
2749
|
}
|
|
2796
2750
|
var REWRITTEN_QUERY_REWRITE_KIND_SQL = `LOWER(TRIM(COALESCE(query_rewrite_kind, 'none'))) IN ('follow-up-context', 'intent-rewrite')`;
|
|
@@ -2808,8 +2762,7 @@ function isRecord(value) {
|
|
|
2808
2762
|
function getNestedRecord(root, path12) {
|
|
2809
2763
|
let cursor = root;
|
|
2810
2764
|
for (const key of path12) {
|
|
2811
|
-
if (!isRecord(cursor))
|
|
2812
|
-
return void 0;
|
|
2765
|
+
if (!isRecord(cursor)) return void 0;
|
|
2813
2766
|
cursor = cursor[key];
|
|
2814
2767
|
}
|
|
2815
2768
|
return isRecord(cursor) ? cursor : void 0;
|
|
@@ -2817,8 +2770,7 @@ function getNestedRecord(root, path12) {
|
|
|
2817
2770
|
function getNestedString(root, path12) {
|
|
2818
2771
|
let cursor = root;
|
|
2819
2772
|
for (const key of path12) {
|
|
2820
|
-
if (!isRecord(cursor))
|
|
2821
|
-
return void 0;
|
|
2773
|
+
if (!isRecord(cursor)) return void 0;
|
|
2822
2774
|
cursor = cursor[key];
|
|
2823
2775
|
}
|
|
2824
2776
|
return typeof cursor === "string" && cursor.length > 0 ? cursor : void 0;
|
|
@@ -2834,8 +2786,7 @@ function metadataProjectPaths(metadata) {
|
|
|
2834
2786
|
];
|
|
2835
2787
|
const paths = [];
|
|
2836
2788
|
for (const value of candidates) {
|
|
2837
|
-
if (value && !paths.includes(value))
|
|
2838
|
-
paths.push(value);
|
|
2789
|
+
if (value && !paths.includes(value)) paths.push(value);
|
|
2839
2790
|
}
|
|
2840
2791
|
return paths;
|
|
2841
2792
|
}
|
|
@@ -2856,12 +2807,9 @@ function maybeQuarantinePredicate(options, column = "metadata") {
|
|
|
2856
2807
|
return options?.includeQuarantined ? "1=1" : notActiveQuarantinedSql(column);
|
|
2857
2808
|
}
|
|
2858
2809
|
function safeParseMetadataValue(value) {
|
|
2859
|
-
if (!value)
|
|
2860
|
-
|
|
2861
|
-
if (typeof value
|
|
2862
|
-
return isRecord(value) ? value : void 0;
|
|
2863
|
-
if (typeof value !== "string")
|
|
2864
|
-
return void 0;
|
|
2810
|
+
if (!value) return void 0;
|
|
2811
|
+
if (typeof value === "object") return isRecord(value) ? value : void 0;
|
|
2812
|
+
if (typeof value !== "string") return void 0;
|
|
2865
2813
|
try {
|
|
2866
2814
|
const parsed = JSON.parse(value);
|
|
2867
2815
|
return isRecord(parsed) ? parsed : void 0;
|
|
@@ -2870,16 +2818,14 @@ function safeParseMetadataValue(value) {
|
|
|
2870
2818
|
}
|
|
2871
2819
|
}
|
|
2872
2820
|
function isImportedOrLegacyScopedMetadata(metadata) {
|
|
2873
|
-
if (!metadata)
|
|
2874
|
-
return false;
|
|
2821
|
+
if (!metadata) return false;
|
|
2875
2822
|
return Boolean(
|
|
2876
2823
|
metadata.importedFrom || metadata.sourceSessionId || metadata.sourceSessionHash || metadata.hermesSource || metadata.projectPath || metadata.sourceProjectPath || metadata.source === "hermes" || metadata.source === "claude" || metadata.source === "codex"
|
|
2877
2824
|
);
|
|
2878
2825
|
}
|
|
2879
2826
|
function addMetadataTag(metadata, tag) {
|
|
2880
2827
|
const current = Array.isArray(metadata.tags) ? metadata.tags.filter((value) => typeof value === "string") : [];
|
|
2881
|
-
if (!current.includes(tag))
|
|
2882
|
-
metadata.tags = [...current, tag];
|
|
2828
|
+
if (!current.includes(tag)) metadata.tags = [...current, tag];
|
|
2883
2829
|
}
|
|
2884
2830
|
function buildRepairResult(projectHash, dryRun) {
|
|
2885
2831
|
return {
|
|
@@ -2897,8 +2843,7 @@ function normalizeRepoName(value) {
|
|
|
2897
2843
|
return value.replace(/\.git$/i, "").trim().toLowerCase();
|
|
2898
2844
|
}
|
|
2899
2845
|
function projectBasename(projectPath) {
|
|
2900
|
-
if (!projectPath)
|
|
2901
|
-
return void 0;
|
|
2846
|
+
if (!projectPath) return void 0;
|
|
2902
2847
|
const trimmed = projectPath.replace(/[\\/]+$/, "");
|
|
2903
2848
|
const basename2 = nodePath2.basename(trimmed);
|
|
2904
2849
|
return basename2 ? normalizeRepoName(basename2) : void 0;
|
|
@@ -2911,23 +2856,19 @@ function isProjectScopeRepairExplanation(content) {
|
|
|
2911
2856
|
}
|
|
2912
2857
|
function hasConflictingContentProjectHint(content, projectPath) {
|
|
2913
2858
|
const currentName = projectBasename(projectPath);
|
|
2914
|
-
if (!currentName)
|
|
2915
|
-
|
|
2916
|
-
if (isProjectScopeRepairExplanation(content))
|
|
2917
|
-
return false;
|
|
2859
|
+
if (!currentName) return false;
|
|
2860
|
+
if (isProjectScopeRepairExplanation(content)) return false;
|
|
2918
2861
|
const githubRepoPattern = /github\.com[:/]([^/\s`'"#)]+)\/([^/\s`'"#)]+)(?:\.git)?/gi;
|
|
2919
2862
|
let githubMatch;
|
|
2920
2863
|
while ((githubMatch = githubRepoPattern.exec(content)) !== null) {
|
|
2921
2864
|
const repo = normalizeRepoName(githubMatch[2] || "");
|
|
2922
|
-
if (repo && repo !== currentName)
|
|
2923
|
-
return true;
|
|
2865
|
+
if (repo && repo !== currentName) return true;
|
|
2924
2866
|
}
|
|
2925
2867
|
const workspacePathPattern = /\/workspace\/([^/\s`'"#)]+)/gi;
|
|
2926
2868
|
let workspaceMatch;
|
|
2927
2869
|
while ((workspaceMatch = workspacePathPattern.exec(content)) !== null) {
|
|
2928
2870
|
const repo = normalizeRepoName(workspaceMatch[1] || "");
|
|
2929
|
-
if (repo && repo !== currentName)
|
|
2930
|
-
return true;
|
|
2871
|
+
if (repo && repo !== currentName) return true;
|
|
2931
2872
|
}
|
|
2932
2873
|
return false;
|
|
2933
2874
|
}
|
|
@@ -2947,15 +2888,12 @@ var SQLiteEventStore = class {
|
|
|
2947
2888
|
this.vectorOutbox = this.createVectorOutbox(options?.vectorOutbox);
|
|
2948
2889
|
}
|
|
2949
2890
|
createVectorOutbox(option) {
|
|
2950
|
-
if (this.readOnly || option === false)
|
|
2951
|
-
|
|
2952
|
-
if (option instanceof VectorOutbox)
|
|
2953
|
-
return option;
|
|
2891
|
+
if (this.readOnly || option === false) return null;
|
|
2892
|
+
if (option instanceof VectorOutbox) return option;
|
|
2954
2893
|
return new VectorOutbox(this.db, option ?? {});
|
|
2955
2894
|
}
|
|
2956
2895
|
enqueueVectorOutboxEventSync(eventId) {
|
|
2957
|
-
if (!this.vectorOutbox)
|
|
2958
|
-
return;
|
|
2896
|
+
if (!this.vectorOutbox) return;
|
|
2959
2897
|
this.vectorOutbox.enqueueSync("event", eventId);
|
|
2960
2898
|
}
|
|
2961
2899
|
async enqueueVectorOutboxEvent(eventId) {
|
|
@@ -2965,8 +2903,7 @@ var SQLiteEventStore = class {
|
|
|
2965
2903
|
* Initialize database schema
|
|
2966
2904
|
*/
|
|
2967
2905
|
async initialize() {
|
|
2968
|
-
if (this.initialized)
|
|
2969
|
-
return;
|
|
2906
|
+
if (this.initialized) return;
|
|
2970
2907
|
if (this.readOnly) {
|
|
2971
2908
|
this.initialized = true;
|
|
2972
2909
|
return;
|
|
@@ -3524,10 +3461,8 @@ var SQLiteEventStore = class {
|
|
|
3524
3461
|
try {
|
|
3525
3462
|
const edgeIndexes = sqliteAll(this.db, `PRAGMA index_list(memory_action_edges)`, []);
|
|
3526
3463
|
const hasSourceAwareUnique = edgeIndexes.some((index) => {
|
|
3527
|
-
if (Number(index.unique) !== 1)
|
|
3528
|
-
|
|
3529
|
-
if (!/^[A-Za-z0-9_]+$/.test(index.name))
|
|
3530
|
-
return false;
|
|
3464
|
+
if (Number(index.unique) !== 1) return false;
|
|
3465
|
+
if (!/^[A-Za-z0-9_]+$/.test(index.name)) return false;
|
|
3531
3466
|
const escapedName = index.name.replace(/"/g, '""');
|
|
3532
3467
|
const columns = sqliteAll(this.db, 'PRAGMA index_info("' + escapedName + '")', []).map((column) => column.name);
|
|
3533
3468
|
return columns.length === 5 && columns[0] === "src_action_id" && columns[1] === "rel_type" && columns[2] === "dst_type" && columns[3] === "dst_id" && columns[4] === "source";
|
|
@@ -3767,8 +3702,7 @@ var SQLiteEventStore = class {
|
|
|
3767
3702
|
`SELECT * FROM events WHERE id = ? AND ${maybeQuarantinePredicate(options)}`,
|
|
3768
3703
|
[id]
|
|
3769
3704
|
);
|
|
3770
|
-
if (!row)
|
|
3771
|
-
return null;
|
|
3705
|
+
if (!row) return null;
|
|
3772
3706
|
return this.rowToEvent(row);
|
|
3773
3707
|
}
|
|
3774
3708
|
/**
|
|
@@ -3806,10 +3740,8 @@ var SQLiteEventStore = class {
|
|
|
3806
3740
|
* NOTE: This bypasses the append() id generation to preserve stable IDs.
|
|
3807
3741
|
*/
|
|
3808
3742
|
async importEvents(events) {
|
|
3809
|
-
if (events.length === 0)
|
|
3810
|
-
|
|
3811
|
-
if (this.readOnly)
|
|
3812
|
-
return { inserted: 0, skipped: events.length };
|
|
3743
|
+
if (events.length === 0) return { inserted: 0, skipped: 0 };
|
|
3744
|
+
if (this.readOnly) return { inserted: 0, skipped: events.length };
|
|
3813
3745
|
await this.initialize();
|
|
3814
3746
|
const getById = this.db.prepare(`SELECT id FROM events WHERE id = ?`);
|
|
3815
3747
|
const getByDedupe = this.db.prepare(`SELECT event_id FROM event_dedup WHERE dedupe_key = ?`);
|
|
@@ -3927,8 +3859,7 @@ var SQLiteEventStore = class {
|
|
|
3927
3859
|
`SELECT * FROM sessions WHERE id = ?`,
|
|
3928
3860
|
[id]
|
|
3929
3861
|
);
|
|
3930
|
-
if (!row)
|
|
3931
|
-
return null;
|
|
3862
|
+
if (!row) return null;
|
|
3932
3863
|
return {
|
|
3933
3864
|
id: row.id,
|
|
3934
3865
|
startedAt: toDateFromSQLite(row.started_at),
|
|
@@ -3983,8 +3914,7 @@ var SQLiteEventStore = class {
|
|
|
3983
3914
|
LIMIT ?`,
|
|
3984
3915
|
[limit]
|
|
3985
3916
|
);
|
|
3986
|
-
if (pending.length === 0)
|
|
3987
|
-
return [];
|
|
3917
|
+
if (pending.length === 0) return [];
|
|
3988
3918
|
const ids = pending.map((r) => r.id);
|
|
3989
3919
|
const placeholders = ids.map(() => "?").join(",");
|
|
3990
3920
|
sqliteRun(
|
|
@@ -4008,8 +3938,7 @@ var SQLiteEventStore = class {
|
|
|
4008
3938
|
* Mark outbox items as done
|
|
4009
3939
|
*/
|
|
4010
3940
|
async completeOutboxItems(ids) {
|
|
4011
|
-
if (ids.length === 0)
|
|
4012
|
-
return;
|
|
3941
|
+
if (ids.length === 0) return;
|
|
4013
3942
|
const placeholders = ids.map(() => "?").join(",");
|
|
4014
3943
|
sqliteRun(
|
|
4015
3944
|
this.db,
|
|
@@ -4048,8 +3977,7 @@ var SQLiteEventStore = class {
|
|
|
4048
3977
|
* Mark outbox items as failed
|
|
4049
3978
|
*/
|
|
4050
3979
|
async failOutboxItems(ids, error) {
|
|
4051
|
-
if (ids.length === 0)
|
|
4052
|
-
return;
|
|
3980
|
+
if (ids.length === 0) return;
|
|
4053
3981
|
const placeholders = ids.map(() => "?").join(",");
|
|
4054
3982
|
sqliteRun(
|
|
4055
3983
|
this.db,
|
|
@@ -4176,8 +4104,7 @@ var SQLiteEventStore = class {
|
|
|
4176
4104
|
[]
|
|
4177
4105
|
);
|
|
4178
4106
|
const sample = (entry) => {
|
|
4179
|
-
if (result.samples.length < 20)
|
|
4180
|
-
result.samples.push(entry);
|
|
4107
|
+
if (result.samples.length < 20) result.samples.push(entry);
|
|
4181
4108
|
};
|
|
4182
4109
|
for (const row of rows) {
|
|
4183
4110
|
result.scanned++;
|
|
@@ -4304,12 +4231,10 @@ var SQLiteEventStore = class {
|
|
|
4304
4231
|
`SELECT status, COUNT(*) as count FROM vector_outbox GROUP BY status`
|
|
4305
4232
|
);
|
|
4306
4233
|
const processingAgeMs = (value) => {
|
|
4307
|
-
if (value === null || value === void 0)
|
|
4308
|
-
return null;
|
|
4234
|
+
if (value === null || value === void 0) return null;
|
|
4309
4235
|
const date = toDateFromSQLite(value);
|
|
4310
4236
|
const time = date.getTime();
|
|
4311
|
-
if (!Number.isFinite(time))
|
|
4312
|
-
return null;
|
|
4237
|
+
if (!Number.isFinite(time)) return null;
|
|
4313
4238
|
return Math.max(0, now.getTime() - time);
|
|
4314
4239
|
};
|
|
4315
4240
|
const fromRows = (rows, stuckProcessing, oldestProcessingAgeMs) => {
|
|
@@ -4458,8 +4383,7 @@ var SQLiteEventStore = class {
|
|
|
4458
4383
|
`SELECT value FROM endless_config WHERE key = ?`,
|
|
4459
4384
|
[key]
|
|
4460
4385
|
);
|
|
4461
|
-
if (!row)
|
|
4462
|
-
return null;
|
|
4386
|
+
if (!row) return null;
|
|
4463
4387
|
return JSON.parse(row.value);
|
|
4464
4388
|
}
|
|
4465
4389
|
/**
|
|
@@ -4478,8 +4402,7 @@ var SQLiteEventStore = class {
|
|
|
4478
4402
|
* Increment access count for events
|
|
4479
4403
|
*/
|
|
4480
4404
|
async incrementAccessCount(eventIds) {
|
|
4481
|
-
if (eventIds.length === 0 || this.readOnly)
|
|
4482
|
-
return;
|
|
4405
|
+
if (eventIds.length === 0 || this.readOnly) return;
|
|
4483
4406
|
await this.initialize();
|
|
4484
4407
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
4485
4408
|
const currentTime = toSQLiteTimestamp(/* @__PURE__ */ new Date());
|
|
@@ -4522,8 +4445,7 @@ var SQLiteEventStore = class {
|
|
|
4522
4445
|
* Record a memory retrieval for helpfulness tracking
|
|
4523
4446
|
*/
|
|
4524
4447
|
async recordRetrieval(eventId, sessionId, score, query) {
|
|
4525
|
-
if (this.readOnly)
|
|
4526
|
-
return;
|
|
4448
|
+
if (this.readOnly) return;
|
|
4527
4449
|
await this.initialize();
|
|
4528
4450
|
const id = randomUUID6();
|
|
4529
4451
|
sqliteRun(
|
|
@@ -4553,16 +4475,14 @@ var SQLiteEventStore = class {
|
|
|
4553
4475
|
* Called at session end - uses behavioral signals to compute score
|
|
4554
4476
|
*/
|
|
4555
4477
|
async evaluateSessionHelpfulness(sessionId) {
|
|
4556
|
-
if (this.readOnly)
|
|
4557
|
-
return;
|
|
4478
|
+
if (this.readOnly) return;
|
|
4558
4479
|
await this.initialize();
|
|
4559
4480
|
const retrievals = sqliteAll(
|
|
4560
4481
|
this.db,
|
|
4561
4482
|
`SELECT * FROM memory_helpfulness WHERE session_id = ? AND measured_at IS NULL`,
|
|
4562
4483
|
[sessionId]
|
|
4563
4484
|
);
|
|
4564
|
-
if (retrievals.length === 0)
|
|
4565
|
-
return;
|
|
4485
|
+
if (retrievals.length === 0) return;
|
|
4566
4486
|
const sessionEvents = sqliteAll(
|
|
4567
4487
|
this.db,
|
|
4568
4488
|
`SELECT * FROM events WHERE session_id = ? ORDER BY timestamp ASC`,
|
|
@@ -4575,8 +4495,7 @@ var SQLiteEventStore = class {
|
|
|
4575
4495
|
for (const t of toolEvents) {
|
|
4576
4496
|
try {
|
|
4577
4497
|
const content = JSON.parse(t.content);
|
|
4578
|
-
if (content.success !== false)
|
|
4579
|
-
toolSuccessCount++;
|
|
4498
|
+
if (content.success !== false) toolSuccessCount++;
|
|
4580
4499
|
} catch {
|
|
4581
4500
|
toolSuccessCount++;
|
|
4582
4501
|
}
|
|
@@ -4594,8 +4513,7 @@ var SQLiteEventStore = class {
|
|
|
4594
4513
|
const pWords = new Set(p.content.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
4595
4514
|
let overlap = 0;
|
|
4596
4515
|
for (const w of queryWords) {
|
|
4597
|
-
if (pWords.has(w))
|
|
4598
|
-
overlap++;
|
|
4516
|
+
if (pWords.has(w)) overlap++;
|
|
4599
4517
|
}
|
|
4600
4518
|
if (queryWords.size > 0 && overlap / queryWords.size > 0.5) {
|
|
4601
4519
|
wasReasked = 1;
|
|
@@ -4777,8 +4695,7 @@ var SQLiteEventStore = class {
|
|
|
4777
4695
|
return this.db;
|
|
4778
4696
|
}
|
|
4779
4697
|
hasTableColumn(tableName, columnName2) {
|
|
4780
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName))
|
|
4781
|
-
return false;
|
|
4698
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(tableName)) return false;
|
|
4782
4699
|
try {
|
|
4783
4700
|
const rows = sqliteAll(this.db, `PRAGMA table_info("${tableName}")`, []);
|
|
4784
4701
|
return rows.some((row) => row.name === columnName2);
|
|
@@ -4845,8 +4762,7 @@ var SQLiteEventStore = class {
|
|
|
4845
4762
|
createdAt: toDateFromSQLite(row.created_at)
|
|
4846
4763
|
}));
|
|
4847
4764
|
} catch (err) {
|
|
4848
|
-
if (err?.message?.includes("no such table"))
|
|
4849
|
-
return [];
|
|
4765
|
+
if (err?.message?.includes("no such table")) return [];
|
|
4850
4766
|
throw err;
|
|
4851
4767
|
}
|
|
4852
4768
|
}
|
|
@@ -5019,8 +4935,7 @@ var SQLiteEventStore = class {
|
|
|
5019
4935
|
`SELECT id FROM events WHERE session_id = ?`,
|
|
5020
4936
|
[sessionId]
|
|
5021
4937
|
);
|
|
5022
|
-
if (events.length === 0)
|
|
5023
|
-
return 0;
|
|
4938
|
+
if (events.length === 0) return 0;
|
|
5024
4939
|
const eventIds = events.map((e) => e.id);
|
|
5025
4940
|
const placeholders = eventIds.map(() => "?").join(",");
|
|
5026
4941
|
const ftsTriggersDropped = [];
|
|
@@ -5232,8 +5147,7 @@ function sanitizeGovernanceAuditValue(value, key) {
|
|
|
5232
5147
|
return value;
|
|
5233
5148
|
}
|
|
5234
5149
|
function sanitizeAuditJson(value) {
|
|
5235
|
-
if (value === void 0)
|
|
5236
|
-
return void 0;
|
|
5150
|
+
if (value === void 0) return void 0;
|
|
5237
5151
|
return sanitizeGovernanceAuditValue(value);
|
|
5238
5152
|
}
|
|
5239
5153
|
function normalizeSourceEventIds(sourceEventIds) {
|
|
@@ -5282,12 +5196,10 @@ async function writeGovernanceAuditEntry(db, input) {
|
|
|
5282
5196
|
|
|
5283
5197
|
// src/core/operations/facet-repository.ts
|
|
5284
5198
|
function parseStringArray(value) {
|
|
5285
|
-
if (typeof value !== "string")
|
|
5286
|
-
return [];
|
|
5199
|
+
if (typeof value !== "string") return [];
|
|
5287
5200
|
try {
|
|
5288
5201
|
const parsed = JSON.parse(value);
|
|
5289
|
-
if (!Array.isArray(parsed))
|
|
5290
|
-
return [];
|
|
5202
|
+
if (!Array.isArray(parsed)) return [];
|
|
5291
5203
|
return parsed.filter((item) => typeof item === "string" && item.length > 0);
|
|
5292
5204
|
} catch {
|
|
5293
5205
|
return [];
|
|
@@ -5331,6 +5243,7 @@ var FacetRepository = class {
|
|
|
5331
5243
|
constructor(db) {
|
|
5332
5244
|
this.db = db;
|
|
5333
5245
|
}
|
|
5246
|
+
db;
|
|
5334
5247
|
async assign(input) {
|
|
5335
5248
|
const assignment = parseFacetAssignmentInput(input);
|
|
5336
5249
|
const existing = this.findByUniqueKey(assignment);
|
|
@@ -5635,19 +5548,14 @@ var RetentionFacetSchema = z5.object({
|
|
|
5635
5548
|
confidence: z5.number().min(0).max(1).default(1)
|
|
5636
5549
|
});
|
|
5637
5550
|
var DateLikeSchema = z5.preprocess((value) => {
|
|
5638
|
-
if (value instanceof Date)
|
|
5639
|
-
|
|
5640
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5641
|
-
return new Date(value);
|
|
5551
|
+
if (value instanceof Date) return value;
|
|
5552
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5642
5553
|
return value;
|
|
5643
5554
|
}, z5.date());
|
|
5644
5555
|
var NullableDateLikeSchema = z5.preprocess((value) => {
|
|
5645
|
-
if (value === null || value === void 0 || value === "")
|
|
5646
|
-
|
|
5647
|
-
if (value
|
|
5648
|
-
return value;
|
|
5649
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5650
|
-
return new Date(value);
|
|
5556
|
+
if (value === null || value === void 0 || value === "") return null;
|
|
5557
|
+
if (value instanceof Date) return value;
|
|
5558
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5651
5559
|
return value;
|
|
5652
5560
|
}, z5.date().nullable());
|
|
5653
5561
|
var OptionalTrimmedStringSchema2 = z5.preprocess(
|
|
@@ -5676,10 +5584,8 @@ import { z as z6 } from "zod";
|
|
|
5676
5584
|
var RequiredTrimmedStringSchema = z6.string().trim().min(1);
|
|
5677
5585
|
var OptionalTrimmedStringSchema3 = z6.string().trim().min(1).optional();
|
|
5678
5586
|
var DateLikeSchema2 = z6.preprocess((value) => {
|
|
5679
|
-
if (value instanceof Date)
|
|
5680
|
-
|
|
5681
|
-
if (typeof value === "string" || typeof value === "number")
|
|
5682
|
-
return new Date(value);
|
|
5587
|
+
if (value instanceof Date) return value;
|
|
5588
|
+
if (typeof value === "string" || typeof value === "number") return new Date(value);
|
|
5683
5589
|
return value;
|
|
5684
5590
|
}, z6.date());
|
|
5685
5591
|
var RetentionReasonSchema = z6.object({
|
|
@@ -5756,8 +5662,7 @@ function parsePrivateTags(text, options) {
|
|
|
5756
5662
|
let filtered = text;
|
|
5757
5663
|
for (const format of options.formats) {
|
|
5758
5664
|
const pattern = TAG_PATTERNS[format];
|
|
5759
|
-
if (!pattern)
|
|
5760
|
-
continue;
|
|
5665
|
+
if (!pattern) continue;
|
|
5761
5666
|
pattern.lastIndex = 0;
|
|
5762
5667
|
let match;
|
|
5763
5668
|
while ((match = pattern.exec(text)) !== null) {
|
|
@@ -5771,12 +5676,10 @@ function parsePrivateTags(text, options) {
|
|
|
5771
5676
|
}
|
|
5772
5677
|
for (const format of options.formats) {
|
|
5773
5678
|
const pattern = TAG_PATTERNS[format];
|
|
5774
|
-
if (!pattern)
|
|
5775
|
-
continue;
|
|
5679
|
+
if (!pattern) continue;
|
|
5776
5680
|
const replacePattern = new RegExp(pattern.source, "gi");
|
|
5777
5681
|
filtered = filtered.replace(replacePattern, (_match, content) => {
|
|
5778
|
-
if (!content.trim())
|
|
5779
|
-
return "";
|
|
5682
|
+
if (!content.trim()) return "";
|
|
5780
5683
|
return options.marker;
|
|
5781
5684
|
});
|
|
5782
5685
|
}
|
|
@@ -5854,8 +5757,7 @@ function looksLikePastedSecret(value) {
|
|
|
5854
5757
|
function maskUrlFollowingSecret(value) {
|
|
5855
5758
|
let count = 0;
|
|
5856
5759
|
const content = value.replace(URL_FOLLOWING_SECRET_PATTERN, (_match, prefix, secret) => {
|
|
5857
|
-
if (!looksLikePastedSecret(secret))
|
|
5858
|
-
return `${prefix}${secret}`;
|
|
5760
|
+
if (!looksLikePastedSecret(secret)) return `${prefix}${secret}`;
|
|
5859
5761
|
count++;
|
|
5860
5762
|
return `${prefix}[REDACTED]`;
|
|
5861
5763
|
});
|
|
@@ -6112,8 +6014,7 @@ var MemoryOperationsConfigSchema = z7.object({
|
|
|
6112
6014
|
}).default({});
|
|
6113
6015
|
var MemoryLessonNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
6114
6016
|
var MemoryLessonStringArraySchema = z7.preprocess((value) => {
|
|
6115
|
-
if (!Array.isArray(value))
|
|
6116
|
-
return value;
|
|
6017
|
+
if (!Array.isArray(value)) return value;
|
|
6117
6018
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
6118
6019
|
}, z7.array(MemoryLessonNonEmptyStringSchema)).default([]);
|
|
6119
6020
|
var MemoryLessonSchema = z7.object({
|
|
@@ -6158,14 +6059,12 @@ var ListMemoryLessonsInputSchema = z7.object({
|
|
|
6158
6059
|
});
|
|
6159
6060
|
var PerspectiveMemoryNonEmptyStringSchema = z7.string().transform((value) => value.trim()).pipe(z7.string().min(1));
|
|
6160
6061
|
var PerspectiveMemoryOptionalStringSchema = z7.preprocess((value) => {
|
|
6161
|
-
if (typeof value !== "string")
|
|
6162
|
-
return value;
|
|
6062
|
+
if (typeof value !== "string") return value;
|
|
6163
6063
|
const normalized = value.trim();
|
|
6164
6064
|
return normalized.length > 0 ? normalized : void 0;
|
|
6165
6065
|
}, PerspectiveMemoryNonEmptyStringSchema.optional());
|
|
6166
6066
|
var PerspectiveMemoryStringArraySchema = z7.preprocess((value) => {
|
|
6167
|
-
if (!Array.isArray(value))
|
|
6168
|
-
return value;
|
|
6067
|
+
if (!Array.isArray(value)) return value;
|
|
6169
6068
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
6170
6069
|
}, z7.array(PerspectiveMemoryNonEmptyStringSchema)).default([]);
|
|
6171
6070
|
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;
|
|
@@ -6823,6 +6722,7 @@ var GraphPathService = class {
|
|
|
6823
6722
|
constructor(db) {
|
|
6824
6723
|
this.db = db;
|
|
6825
6724
|
}
|
|
6725
|
+
db;
|
|
6826
6726
|
expand(input) {
|
|
6827
6727
|
const graph = this.loadGraph(input.direction ?? "both");
|
|
6828
6728
|
const effectiveMaxHops = normalizeMaxHops(input.maxHops);
|
|
@@ -6840,11 +6740,9 @@ var GraphPathService = class {
|
|
|
6840
6740
|
while (queue.length > 0) {
|
|
6841
6741
|
queue.sort((a, b) => a.totalCost - b.totalCost || a.hops - b.hops || a.key.localeCompare(b.key));
|
|
6842
6742
|
const current = queue.shift();
|
|
6843
|
-
if (current.hops >= effectiveMaxHops)
|
|
6844
|
-
continue;
|
|
6743
|
+
if (current.hops >= effectiveMaxHops) continue;
|
|
6845
6744
|
for (const edge of graph.adjacency.get(current.key) ?? []) {
|
|
6846
|
-
if (current.visited.has(edge.toKey))
|
|
6847
|
-
continue;
|
|
6745
|
+
if (current.visited.has(edge.toKey)) continue;
|
|
6848
6746
|
const nextHops = current.hops + 1;
|
|
6849
6747
|
const nextTotalCost = current.totalCost + edge.step.cost;
|
|
6850
6748
|
const nextSteps = [...current.steps, edge.step];
|
|
@@ -6924,17 +6822,13 @@ function addTraversal(adjacency, fromKey, edge) {
|
|
|
6924
6822
|
adjacency.set(fromKey, edges);
|
|
6925
6823
|
}
|
|
6926
6824
|
function normalizeMaxHops(maxHops) {
|
|
6927
|
-
if (maxHops === void 0)
|
|
6928
|
-
|
|
6929
|
-
if (!Number.isFinite(maxHops))
|
|
6930
|
-
return MAX_HOPS;
|
|
6825
|
+
if (maxHops === void 0) return 1;
|
|
6826
|
+
if (!Number.isFinite(maxHops)) return MAX_HOPS;
|
|
6931
6827
|
return Math.min(Math.max(0, Math.trunc(maxHops)), MAX_HOPS);
|
|
6932
6828
|
}
|
|
6933
6829
|
function normalizeMaxResults(maxResults) {
|
|
6934
|
-
if (maxResults === void 0)
|
|
6935
|
-
|
|
6936
|
-
if (!Number.isFinite(maxResults))
|
|
6937
|
-
return DEFAULT_MAX_RESULTS;
|
|
6830
|
+
if (maxResults === void 0) return DEFAULT_MAX_RESULTS;
|
|
6831
|
+
if (!Number.isFinite(maxResults)) return DEFAULT_MAX_RESULTS;
|
|
6938
6832
|
return Math.min(Math.max(0, Math.trunc(maxResults)), MAX_RESULTS);
|
|
6939
6833
|
}
|
|
6940
6834
|
function isBetterPath(totalCost, hops, signature, existing) {
|
|
@@ -6946,18 +6840,15 @@ function pathSignature(steps) {
|
|
|
6946
6840
|
function edgeWeight(metaJson) {
|
|
6947
6841
|
const meta = parseMeta(metaJson);
|
|
6948
6842
|
const raw = meta.weight;
|
|
6949
|
-
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0)
|
|
6950
|
-
return raw;
|
|
6843
|
+
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) return raw;
|
|
6951
6844
|
if (typeof raw === "string") {
|
|
6952
6845
|
const parsed = Number(raw);
|
|
6953
|
-
if (Number.isFinite(parsed) && parsed > 0)
|
|
6954
|
-
return parsed;
|
|
6846
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
6955
6847
|
}
|
|
6956
6848
|
return DEFAULT_WEIGHT;
|
|
6957
6849
|
}
|
|
6958
6850
|
function parseMeta(metaJson) {
|
|
6959
|
-
if (!metaJson)
|
|
6960
|
-
return {};
|
|
6851
|
+
if (!metaJson) return {};
|
|
6961
6852
|
try {
|
|
6962
6853
|
const parsed = JSON.parse(metaJson);
|
|
6963
6854
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
@@ -6970,8 +6861,7 @@ function nodeKey(node) {
|
|
|
6970
6861
|
}
|
|
6971
6862
|
function nodeFromKey(key) {
|
|
6972
6863
|
const index = key.indexOf(":");
|
|
6973
|
-
if (index === -1)
|
|
6974
|
-
return { type: "entity", id: key };
|
|
6864
|
+
if (index === -1) return { type: "entity", id: key };
|
|
6975
6865
|
return { type: key.slice(0, index), id: key.slice(index + 1) };
|
|
6976
6866
|
}
|
|
6977
6867
|
|
|
@@ -7027,6 +6917,7 @@ var QueryEntityExtractor = class {
|
|
|
7027
6917
|
constructor(db) {
|
|
7028
6918
|
this.db = db;
|
|
7029
6919
|
}
|
|
6920
|
+
db;
|
|
7030
6921
|
extract(query, options = {}) {
|
|
7031
6922
|
const maxCandidates = normalizeMaxCandidates(options.maxCandidates);
|
|
7032
6923
|
const candidates = [];
|
|
@@ -7048,8 +6939,7 @@ var QueryEntityExtractor = class {
|
|
|
7048
6939
|
let match;
|
|
7049
6940
|
while ((match = regex.exec(query)) !== null) {
|
|
7050
6941
|
const text = cleanCandidateText(match[2] ?? "");
|
|
7051
|
-
if (!isUsefulCandidate(text))
|
|
7052
|
-
continue;
|
|
6942
|
+
if (!isUsefulCandidate(text)) continue;
|
|
7053
6943
|
const start = match.index + 1;
|
|
7054
6944
|
const end = start + text.length;
|
|
7055
6945
|
ranges.push([match.index, match.index + match[0].length]);
|
|
@@ -7063,8 +6953,7 @@ var QueryEntityExtractor = class {
|
|
|
7063
6953
|
return ranges;
|
|
7064
6954
|
}
|
|
7065
6955
|
extractKnownAliases(query, candidates) {
|
|
7066
|
-
if (!this.db)
|
|
7067
|
-
return;
|
|
6956
|
+
if (!this.db) return;
|
|
7068
6957
|
const rows = sqliteAll(
|
|
7069
6958
|
this.db,
|
|
7070
6959
|
`SELECT
|
|
@@ -7088,11 +6977,9 @@ var QueryEntityExtractor = class {
|
|
|
7088
6977
|
]).filter(isUsefulCandidate);
|
|
7089
6978
|
for (const alias of aliasLabels) {
|
|
7090
6979
|
const normalizedAlias = normalizeForContainment(alias);
|
|
7091
|
-
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias))
|
|
7092
|
-
continue;
|
|
6980
|
+
if (!normalizedAlias || !containsPhrase(normalizedQuery, normalizedAlias)) continue;
|
|
7093
6981
|
const aliasKey = `${row.entity_id}:${normalizedAlias}`;
|
|
7094
|
-
if (seenAliases.has(aliasKey))
|
|
7095
|
-
continue;
|
|
6982
|
+
if (seenAliases.has(aliasKey)) continue;
|
|
7096
6983
|
seenAliases.add(aliasKey);
|
|
7097
6984
|
const range = findRange(query, alias);
|
|
7098
6985
|
pushCandidate(candidates, {
|
|
@@ -7113,8 +7000,7 @@ var QueryEntityExtractor = class {
|
|
|
7113
7000
|
let match;
|
|
7114
7001
|
while ((match = regex.exec(query)) !== null) {
|
|
7115
7002
|
const text = cleanCandidateText(match[2] ?? "");
|
|
7116
|
-
if (!isUsefulCandidate(text))
|
|
7117
|
-
continue;
|
|
7003
|
+
if (!isUsefulCandidate(text)) continue;
|
|
7118
7004
|
const start = match.index + (match[1]?.length ?? 0);
|
|
7119
7005
|
pushCandidate(candidates, {
|
|
7120
7006
|
text,
|
|
@@ -7129,8 +7015,7 @@ var QueryEntityExtractor = class {
|
|
|
7129
7015
|
let match;
|
|
7130
7016
|
while ((match = regex.exec(query)) !== null) {
|
|
7131
7017
|
const text = cleanCandidateText(match[2] ?? "");
|
|
7132
|
-
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./"))
|
|
7133
|
-
continue;
|
|
7018
|
+
if (!isUsefulCandidate(text) || text.includes("/.") || text.includes("./")) continue;
|
|
7134
7019
|
const start = match.index + (match[1]?.length ?? 0);
|
|
7135
7020
|
pushCandidate(candidates, {
|
|
7136
7021
|
text,
|
|
@@ -7149,21 +7034,17 @@ var QueryEntityExtractor = class {
|
|
|
7149
7034
|
if (previous && query.slice(previous.end, token.start).match(/^\s+$/)) {
|
|
7150
7035
|
current.push(token);
|
|
7151
7036
|
} else {
|
|
7152
|
-
if (current.length > 0)
|
|
7153
|
-
groups.push(current);
|
|
7037
|
+
if (current.length > 0) groups.push(current);
|
|
7154
7038
|
current = [token];
|
|
7155
7039
|
}
|
|
7156
7040
|
}
|
|
7157
|
-
if (current.length > 0)
|
|
7158
|
-
groups.push(current);
|
|
7041
|
+
if (current.length > 0) groups.push(current);
|
|
7159
7042
|
for (const group of groups) {
|
|
7160
|
-
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text))
|
|
7161
|
-
continue;
|
|
7043
|
+
if (group.length === 1 && !isStrongSingleCapitalized(group[0].text)) continue;
|
|
7162
7044
|
const start = group[0].start;
|
|
7163
7045
|
const end = group[group.length - 1].end;
|
|
7164
7046
|
const text = query.slice(start, end);
|
|
7165
|
-
if (!isUsefulCandidate(text))
|
|
7166
|
-
continue;
|
|
7047
|
+
if (!isUsefulCandidate(text)) continue;
|
|
7167
7048
|
pushCandidate(candidates, {
|
|
7168
7049
|
text,
|
|
7169
7050
|
source: "capitalized_term",
|
|
@@ -7184,8 +7065,7 @@ function collectCapitalizedTokens(query) {
|
|
|
7184
7065
|
}
|
|
7185
7066
|
function pushCandidate(candidates, input) {
|
|
7186
7067
|
const text = cleanCandidateText(input.text);
|
|
7187
|
-
if (!isUsefulCandidate(text))
|
|
7188
|
-
return;
|
|
7068
|
+
if (!isUsefulCandidate(text)) return;
|
|
7189
7069
|
const source = input.source;
|
|
7190
7070
|
candidates.push({
|
|
7191
7071
|
...input,
|
|
@@ -7203,15 +7083,13 @@ function dedupeAndSort(candidates) {
|
|
|
7203
7083
|
for (const candidate of sorted) {
|
|
7204
7084
|
if (candidate.source === "entity_alias") {
|
|
7205
7085
|
const aliasKey = `alias:${candidate.entityId ?? ""}:${normalizeCandidate(candidate.matchedAlias ?? candidate.text)}`;
|
|
7206
|
-
if (seenAliasKeys.has(aliasKey))
|
|
7207
|
-
continue;
|
|
7086
|
+
if (seenAliasKeys.has(aliasKey)) continue;
|
|
7208
7087
|
seenAliasKeys.add(aliasKey);
|
|
7209
7088
|
seenNormalized.add(candidate.normalized);
|
|
7210
7089
|
result.push(candidate);
|
|
7211
7090
|
continue;
|
|
7212
7091
|
}
|
|
7213
|
-
if (seenNormalized.has(candidate.normalized))
|
|
7214
|
-
continue;
|
|
7092
|
+
if (seenNormalized.has(candidate.normalized)) continue;
|
|
7215
7093
|
seenNormalized.add(candidate.normalized);
|
|
7216
7094
|
result.push(candidate);
|
|
7217
7095
|
}
|
|
@@ -7221,8 +7099,7 @@ function compareCandidates(a, b) {
|
|
|
7221
7099
|
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 ?? "");
|
|
7222
7100
|
}
|
|
7223
7101
|
function compareStrings(a, b) {
|
|
7224
|
-
if (a === b)
|
|
7225
|
-
return 0;
|
|
7102
|
+
if (a === b) return 0;
|
|
7226
7103
|
return a < b ? -1 : 1;
|
|
7227
7104
|
}
|
|
7228
7105
|
function stripPriority(candidate) {
|
|
@@ -7230,10 +7107,8 @@ function stripPriority(candidate) {
|
|
|
7230
7107
|
return publicCandidate;
|
|
7231
7108
|
}
|
|
7232
7109
|
function normalizeMaxCandidates(maxCandidates) {
|
|
7233
|
-
if (maxCandidates === void 0)
|
|
7234
|
-
|
|
7235
|
-
if (!Number.isFinite(maxCandidates))
|
|
7236
|
-
return DEFAULT_MAX_CANDIDATES;
|
|
7110
|
+
if (maxCandidates === void 0) return DEFAULT_MAX_CANDIDATES;
|
|
7111
|
+
if (!Number.isFinite(maxCandidates)) return DEFAULT_MAX_CANDIDATES;
|
|
7237
7112
|
return Math.min(Math.max(0, Math.trunc(maxCandidates)), MAX_CANDIDATES);
|
|
7238
7113
|
}
|
|
7239
7114
|
function cleanCandidateText(text) {
|
|
@@ -7255,21 +7130,17 @@ function aliasLabelFromCanonicalKey(canonicalKey) {
|
|
|
7255
7130
|
function findRange(query, alias) {
|
|
7256
7131
|
const normalizedAlias = normalizeForContainment(alias);
|
|
7257
7132
|
const directIndex = query.toLowerCase().indexOf(alias.toLowerCase());
|
|
7258
|
-
if (directIndex >= 0)
|
|
7259
|
-
return { start: directIndex, end: directIndex + alias.length };
|
|
7133
|
+
if (directIndex >= 0) return { start: directIndex, end: directIndex + alias.length };
|
|
7260
7134
|
const normalizedQuery = normalizeForContainment(query);
|
|
7261
7135
|
const normalizedIndex = normalizedQuery.indexOf(normalizedAlias);
|
|
7262
|
-
if (normalizedIndex < 0)
|
|
7263
|
-
return { start: 0, end: 0 };
|
|
7136
|
+
if (normalizedIndex < 0) return { start: 0, end: 0 };
|
|
7264
7137
|
const queryLower = query.toLowerCase();
|
|
7265
7138
|
const words = normalizedAlias.split(" ").filter(Boolean);
|
|
7266
|
-
if (words.length === 0)
|
|
7267
|
-
return { start: 0, end: 0 };
|
|
7139
|
+
if (words.length === 0) return { start: 0, end: 0 };
|
|
7268
7140
|
const first = queryLower.indexOf(words[0]);
|
|
7269
7141
|
const lastWord = words[words.length - 1];
|
|
7270
7142
|
const last = queryLower.indexOf(lastWord, first >= 0 ? first : 0);
|
|
7271
|
-
if (first >= 0 && last >= 0)
|
|
7272
|
-
return { start: first, end: last + lastWord.length };
|
|
7143
|
+
if (first >= 0 && last >= 0) return { start: first, end: last + lastWord.length };
|
|
7273
7144
|
return { start: normalizedIndex, end: normalizedIndex + normalizedAlias.length };
|
|
7274
7145
|
}
|
|
7275
7146
|
function isUsefulCandidate(text) {
|
|
@@ -7280,10 +7151,8 @@ function isInsideAnyRange(index, ranges) {
|
|
|
7280
7151
|
return ranges.some(([start, end]) => index >= start && index < end);
|
|
7281
7152
|
}
|
|
7282
7153
|
function isStrongSingleCapitalized(text) {
|
|
7283
|
-
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text))
|
|
7284
|
-
|
|
7285
|
-
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text))
|
|
7286
|
-
return true;
|
|
7154
|
+
if (/^[A-Z]{2,}[A-Z0-9]*$/.test(text)) return true;
|
|
7155
|
+
if (/^[A-Z][a-z]+[A-Z][A-Za-z0-9]*$/.test(text)) return true;
|
|
7287
7156
|
return text.length >= 4 && !SENTENCE_START_STOPWORDS.has(text);
|
|
7288
7157
|
}
|
|
7289
7158
|
function uniqueStrings(values) {
|
|
@@ -7291,8 +7160,7 @@ function uniqueStrings(values) {
|
|
|
7291
7160
|
const result = [];
|
|
7292
7161
|
for (const value of values) {
|
|
7293
7162
|
const key = normalizeForContainment(value);
|
|
7294
|
-
if (!key || seen.has(key))
|
|
7295
|
-
continue;
|
|
7163
|
+
if (!key || seen.has(key)) continue;
|
|
7296
7164
|
seen.add(key);
|
|
7297
7165
|
result.push(value);
|
|
7298
7166
|
}
|
|
@@ -7314,8 +7182,7 @@ var LessonCandidateInputSchema = z9.object({
|
|
|
7314
7182
|
import { z as z10 } from "zod";
|
|
7315
7183
|
var NonEmptyStringSchema5 = z10.string().transform((value) => value.trim()).pipe(z10.string().min(1));
|
|
7316
7184
|
var PromotionStringArraySchema = z10.preprocess((value) => {
|
|
7317
|
-
if (!Array.isArray(value))
|
|
7318
|
-
return value;
|
|
7185
|
+
if (!Array.isArray(value)) return value;
|
|
7319
7186
|
return value.map((item) => typeof item === "string" ? item.trim() : item).filter((item) => typeof item !== "string" || item.length > 0);
|
|
7320
7187
|
}, z10.array(NonEmptyStringSchema5).max(100));
|
|
7321
7188
|
var ReviewedLessonCandidateSchema = z10.object({
|
|
@@ -7363,8 +7230,7 @@ function projectHashFromStorage(projectHash) {
|
|
|
7363
7230
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7364
7231
|
}
|
|
7365
7232
|
function parseJsonRecord(value) {
|
|
7366
|
-
if (!value)
|
|
7367
|
-
return void 0;
|
|
7233
|
+
if (!value) return void 0;
|
|
7368
7234
|
try {
|
|
7369
7235
|
const parsed = JSON.parse(value);
|
|
7370
7236
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7376,8 +7242,7 @@ function sanitizeString(value) {
|
|
|
7376
7242
|
return String(sanitizeGovernanceAuditValue(value)).trim();
|
|
7377
7243
|
}
|
|
7378
7244
|
function sanitizeMetadata(metadata) {
|
|
7379
|
-
if (!metadata)
|
|
7380
|
-
return void 0;
|
|
7245
|
+
if (!metadata) return void 0;
|
|
7381
7246
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7382
7247
|
}
|
|
7383
7248
|
function slugActorPart(value) {
|
|
@@ -7385,8 +7250,7 @@ function slugActorPart(value) {
|
|
|
7385
7250
|
return slug.length > 0 ? slug : "unknown";
|
|
7386
7251
|
}
|
|
7387
7252
|
function stableActorId(input) {
|
|
7388
|
-
if (input.actorId)
|
|
7389
|
-
return sanitizeString(input.actorId);
|
|
7253
|
+
if (input.actorId) return sanitizeString(input.actorId);
|
|
7390
7254
|
const projectPart = input.projectHash ? `project:${slugActorPart(input.projectHash)}` : "global";
|
|
7391
7255
|
return [
|
|
7392
7256
|
"actor",
|
|
@@ -7409,12 +7273,10 @@ function rowToActor(row) {
|
|
|
7409
7273
|
});
|
|
7410
7274
|
}
|
|
7411
7275
|
function metadataString(metadata, keys) {
|
|
7412
|
-
if (!metadata)
|
|
7413
|
-
return void 0;
|
|
7276
|
+
if (!metadata) return void 0;
|
|
7414
7277
|
for (const key of keys) {
|
|
7415
7278
|
const value = metadata[key];
|
|
7416
|
-
if (typeof value === "string" && value.trim().length > 0)
|
|
7417
|
-
return value.trim();
|
|
7279
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
7418
7280
|
}
|
|
7419
7281
|
return void 0;
|
|
7420
7282
|
}
|
|
@@ -7464,6 +7326,7 @@ var ActorRepository = class {
|
|
|
7464
7326
|
constructor(db) {
|
|
7465
7327
|
this.db = db;
|
|
7466
7328
|
}
|
|
7329
|
+
db;
|
|
7467
7330
|
async upsert(input) {
|
|
7468
7331
|
const parsed = UpsertMemoryActorInputSchema.parse(input);
|
|
7469
7332
|
const actorId = stableActorId(parsed);
|
|
@@ -7517,8 +7380,7 @@ var ActorRepository = class {
|
|
|
7517
7380
|
}
|
|
7518
7381
|
require(actorId) {
|
|
7519
7382
|
const actor = this.get(actorId);
|
|
7520
|
-
if (!actor)
|
|
7521
|
-
throw new Error(`Memory actor not found: ${actorId}`);
|
|
7383
|
+
if (!actor) throw new Error(`Memory actor not found: ${actorId}`);
|
|
7522
7384
|
return actor;
|
|
7523
7385
|
}
|
|
7524
7386
|
async list(input = {}) {
|
|
@@ -7554,8 +7416,7 @@ function projectHashFromStorage2(projectHash) {
|
|
|
7554
7416
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7555
7417
|
}
|
|
7556
7418
|
function parseJsonRecord2(value) {
|
|
7557
|
-
if (!value)
|
|
7558
|
-
return void 0;
|
|
7419
|
+
if (!value) return void 0;
|
|
7559
7420
|
try {
|
|
7560
7421
|
const parsed = JSON.parse(value);
|
|
7561
7422
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7564,8 +7425,7 @@ function parseJsonRecord2(value) {
|
|
|
7564
7425
|
}
|
|
7565
7426
|
}
|
|
7566
7427
|
function sanitizeMetadata2(metadata) {
|
|
7567
|
-
if (!metadata)
|
|
7568
|
-
return void 0;
|
|
7428
|
+
if (!metadata) return void 0;
|
|
7569
7429
|
return sanitizeGovernanceAuditValue(metadata);
|
|
7570
7430
|
}
|
|
7571
7431
|
function rowToSessionActor(row) {
|
|
@@ -7585,6 +7445,7 @@ var SessionActorRepository = class {
|
|
|
7585
7445
|
constructor(db) {
|
|
7586
7446
|
this.db = db;
|
|
7587
7447
|
}
|
|
7448
|
+
db;
|
|
7588
7449
|
async upsertMembership(input) {
|
|
7589
7450
|
const parsed = UpsertSessionActorInputSchema.parse(input);
|
|
7590
7451
|
const projectHash = projectHashToStorage3(parsed.projectHash);
|
|
@@ -7631,8 +7492,7 @@ var SessionActorRepository = class {
|
|
|
7631
7492
|
);
|
|
7632
7493
|
}
|
|
7633
7494
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7634
|
-
if (!saved)
|
|
7635
|
-
throw new Error("session actor membership was not saved");
|
|
7495
|
+
if (!saved) throw new Error("session actor membership was not saved");
|
|
7636
7496
|
return saved;
|
|
7637
7497
|
}
|
|
7638
7498
|
async listBySession(input) {
|
|
@@ -7668,8 +7528,7 @@ var SessionActorRepository = class {
|
|
|
7668
7528
|
]
|
|
7669
7529
|
);
|
|
7670
7530
|
const saved = this.get(projectHash, parsed.sessionId, parsed.actorId);
|
|
7671
|
-
if (!saved)
|
|
7672
|
-
throw new Error("session actor membership not found after update");
|
|
7531
|
+
if (!saved) throw new Error("session actor membership not found after update");
|
|
7673
7532
|
return saved;
|
|
7674
7533
|
}
|
|
7675
7534
|
get(projectHash, sessionId, actorId) {
|
|
@@ -7691,8 +7550,7 @@ function projectHashFromStorage3(projectHash) {
|
|
|
7691
7550
|
return projectHash.length > 0 ? projectHash : void 0;
|
|
7692
7551
|
}
|
|
7693
7552
|
function parseStringArray2(value) {
|
|
7694
|
-
if (!value)
|
|
7695
|
-
return [];
|
|
7553
|
+
if (!value) return [];
|
|
7696
7554
|
try {
|
|
7697
7555
|
const parsed = JSON.parse(value);
|
|
7698
7556
|
return Array.isArray(parsed) ? parsed.filter((entry) => typeof entry === "string") : [];
|
|
@@ -7701,8 +7559,7 @@ function parseStringArray2(value) {
|
|
|
7701
7559
|
}
|
|
7702
7560
|
}
|
|
7703
7561
|
function parseJsonRecord3(value) {
|
|
7704
|
-
if (!value)
|
|
7705
|
-
return void 0;
|
|
7562
|
+
if (!value) return void 0;
|
|
7706
7563
|
try {
|
|
7707
7564
|
const parsed = JSON.parse(value);
|
|
7708
7565
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
@@ -7718,8 +7575,7 @@ function sanitizeStoredStringArray(values) {
|
|
|
7718
7575
|
return values.map(sanitizeStoredString).filter((value) => value.length > 0);
|
|
7719
7576
|
}
|
|
7720
7577
|
function sanitizeStoredRecord(value) {
|
|
7721
|
-
if (!value)
|
|
7722
|
-
return void 0;
|
|
7578
|
+
if (!value) return void 0;
|
|
7723
7579
|
return sanitizeGovernanceAuditValue(value);
|
|
7724
7580
|
}
|
|
7725
7581
|
function stableHash(value) {
|
|
@@ -7770,8 +7626,7 @@ function sanitizedObservationSnapshot(observation) {
|
|
|
7770
7626
|
});
|
|
7771
7627
|
}
|
|
7772
7628
|
function queryScore(observation, terms) {
|
|
7773
|
-
if (terms.length === 0)
|
|
7774
|
-
return 0;
|
|
7629
|
+
if (terms.length === 0) return 0;
|
|
7775
7630
|
const haystack = [observation.content, observation.level, observation.sessionId ?? ""].join(" ").toLowerCase();
|
|
7776
7631
|
return terms.reduce((score, term) => score + (haystack.includes(term) ? 1 : 0), 0);
|
|
7777
7632
|
}
|
|
@@ -7817,12 +7672,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7817
7672
|
this.vectorOutbox = options.vectorOutbox;
|
|
7818
7673
|
}
|
|
7819
7674
|
}
|
|
7675
|
+
db;
|
|
7820
7676
|
vectorOutbox = null;
|
|
7821
7677
|
vectorOutboxOption;
|
|
7822
7678
|
getVectorOutbox() {
|
|
7823
7679
|
const option = this.vectorOutboxOption;
|
|
7824
|
-
if (option === false)
|
|
7825
|
-
return null;
|
|
7680
|
+
if (option === false) return null;
|
|
7826
7681
|
if (option instanceof VectorOutbox) {
|
|
7827
7682
|
this.vectorOutbox = option;
|
|
7828
7683
|
return option;
|
|
@@ -7834,8 +7689,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7834
7689
|
}
|
|
7835
7690
|
enqueueObservationSync(observationId) {
|
|
7836
7691
|
const outbox = this.getVectorOutbox();
|
|
7837
|
-
if (!outbox)
|
|
7838
|
-
return;
|
|
7692
|
+
if (!outbox) return;
|
|
7839
7693
|
outbox.enqueueSync("perspective_observation", observationId);
|
|
7840
7694
|
}
|
|
7841
7695
|
async create(input) {
|
|
@@ -7897,14 +7751,12 @@ var PerspectiveObservationRepository = class {
|
|
|
7897
7751
|
contentHash,
|
|
7898
7752
|
sourceHash
|
|
7899
7753
|
);
|
|
7900
|
-
if (!saved)
|
|
7901
|
-
throw new Error("perspective observation was not saved");
|
|
7754
|
+
if (!saved) throw new Error("perspective observation was not saved");
|
|
7902
7755
|
this.enqueueObservationSync(saved.observationId);
|
|
7903
7756
|
});
|
|
7904
7757
|
transaction();
|
|
7905
7758
|
const savedObservation = saved;
|
|
7906
|
-
if (!savedObservation)
|
|
7907
|
-
throw new Error("perspective observation was not saved");
|
|
7759
|
+
if (!savedObservation) throw new Error("perspective observation was not saved");
|
|
7908
7760
|
await this.writeCreateAudit({ ...parsed, observerActorId, observedActorId, sessionId, content, sourceEventIds, sourceObservationIds, createdBy, actor, metadata }, savedObservation);
|
|
7909
7761
|
return savedObservation;
|
|
7910
7762
|
}
|
|
@@ -7914,8 +7766,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7914
7766
|
const ftsQuery = buildObservationFtsQuery(parsed.query);
|
|
7915
7767
|
if (ftsQuery) {
|
|
7916
7768
|
const ftsResult = this.queryWithFts(parsed, ftsQuery);
|
|
7917
|
-
if (ftsResult)
|
|
7918
|
-
return ftsResult;
|
|
7769
|
+
if (ftsResult) return ftsResult;
|
|
7919
7770
|
}
|
|
7920
7771
|
}
|
|
7921
7772
|
return this.queryWithPrefetch(parsed);
|
|
@@ -7936,8 +7787,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7936
7787
|
);
|
|
7937
7788
|
return rows.map(rowToObservation);
|
|
7938
7789
|
} catch (error) {
|
|
7939
|
-
if (isFtsUnavailableError(error))
|
|
7940
|
-
return null;
|
|
7790
|
+
if (isFtsUnavailableError(error)) return null;
|
|
7941
7791
|
throw error;
|
|
7942
7792
|
}
|
|
7943
7793
|
}
|
|
@@ -7978,8 +7828,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7978
7828
|
const parsed = DeletePerspectiveObservationInputSchema.parse(input);
|
|
7979
7829
|
const projectHash = projectHashToStorage4(parsed.projectHash);
|
|
7980
7830
|
const before = this.get(projectHash, parsed.observationId);
|
|
7981
|
-
if (!before)
|
|
7982
|
-
throw new Error("perspective observation not found");
|
|
7831
|
+
if (!before) throw new Error("perspective observation not found");
|
|
7983
7832
|
const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7984
7833
|
sqliteRun(
|
|
7985
7834
|
this.db,
|
|
@@ -7989,8 +7838,7 @@ var PerspectiveObservationRepository = class {
|
|
|
7989
7838
|
[deletedAt, deletedAt, projectHash, parsed.observationId]
|
|
7990
7839
|
);
|
|
7991
7840
|
const after = this.get(projectHash, parsed.observationId);
|
|
7992
|
-
if (!after)
|
|
7993
|
-
throw new Error("perspective observation not found after delete");
|
|
7841
|
+
if (!after) throw new Error("perspective observation not found after delete");
|
|
7994
7842
|
await writeGovernanceAuditEntry(this.db, {
|
|
7995
7843
|
operation: "perspective_observation_delete",
|
|
7996
7844
|
actor: parsed.actor,
|
|
@@ -8046,11 +7894,9 @@ var DEFAULT_CONFIG3 = {
|
|
|
8046
7894
|
var MAX_OBSERVATION_CONTENT_CHARS = 600;
|
|
8047
7895
|
var RuleBasedPerspectiveObservationExtractor = class {
|
|
8048
7896
|
async extract(event) {
|
|
8049
|
-
if (!isSupportedSourceEvent(event))
|
|
8050
|
-
return [];
|
|
7897
|
+
if (!isSupportedSourceEvent(event)) return [];
|
|
8051
7898
|
const content = normalizeObservationContent(event.content);
|
|
8052
|
-
if (!content)
|
|
8053
|
-
return [];
|
|
7899
|
+
if (!content) return [];
|
|
8054
7900
|
return [{
|
|
8055
7901
|
content,
|
|
8056
7902
|
confidence: 0.6,
|
|
@@ -8121,8 +7967,7 @@ var PerspectiveDeriver = class {
|
|
|
8121
7967
|
for (const candidate of candidates) {
|
|
8122
7968
|
const observedActorId = candidate.observedActorId ?? sourceActor.actorId;
|
|
8123
7969
|
const observers = selectObservers(members, observedActorId, this.config.deriver.maxObserversPerSession);
|
|
8124
|
-
if (observers.length === 0)
|
|
8125
|
-
continue;
|
|
7970
|
+
if (observers.length === 0) continue;
|
|
8126
7971
|
for (const observerActorId of observers) {
|
|
8127
7972
|
await this.observations.create({
|
|
8128
7973
|
projectHash,
|
|
@@ -8175,28 +8020,22 @@ function normalizeConfig(config) {
|
|
|
8175
8020
|
};
|
|
8176
8021
|
}
|
|
8177
8022
|
function clampInteger(value, fallback, min, max) {
|
|
8178
|
-
if (!Number.isFinite(value))
|
|
8179
|
-
return fallback;
|
|
8023
|
+
if (!Number.isFinite(value)) return fallback;
|
|
8180
8024
|
return Math.max(min, Math.min(max, Math.trunc(Number(value))));
|
|
8181
8025
|
}
|
|
8182
8026
|
function isSupportedSourceEvent(event) {
|
|
8183
8027
|
return event.eventType === "user_prompt" || event.eventType === "agent_response";
|
|
8184
8028
|
}
|
|
8185
8029
|
function roleForEvent(event) {
|
|
8186
|
-
if (event.eventType === "user_prompt")
|
|
8187
|
-
|
|
8188
|
-
if (event.eventType === "
|
|
8189
|
-
|
|
8190
|
-
if (event.eventType === "tool_observation")
|
|
8191
|
-
return "tool";
|
|
8192
|
-
if (event.eventType === "session_summary")
|
|
8193
|
-
return "system";
|
|
8030
|
+
if (event.eventType === "user_prompt") return "speaker";
|
|
8031
|
+
if (event.eventType === "agent_response") return "assistant";
|
|
8032
|
+
if (event.eventType === "tool_observation") return "tool";
|
|
8033
|
+
if (event.eventType === "session_summary") return "system";
|
|
8194
8034
|
return "unknown";
|
|
8195
8035
|
}
|
|
8196
8036
|
function normalizeCandidate2(candidate) {
|
|
8197
8037
|
const content = normalizeObservationContent(candidate.content);
|
|
8198
|
-
if (!content)
|
|
8199
|
-
return null;
|
|
8038
|
+
if (!content) return null;
|
|
8200
8039
|
return {
|
|
8201
8040
|
content,
|
|
8202
8041
|
confidence: clampNumber(candidate.confidence, 0.6, 0, 1),
|
|
@@ -8208,8 +8047,7 @@ function normalizeCandidate2(candidate) {
|
|
|
8208
8047
|
}
|
|
8209
8048
|
function normalizeObservationContent(content) {
|
|
8210
8049
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
8211
|
-
if (!normalized)
|
|
8212
|
-
return null;
|
|
8050
|
+
if (!normalized) return null;
|
|
8213
8051
|
return normalized.slice(0, MAX_OBSERVATION_CONTENT_CHARS);
|
|
8214
8052
|
}
|
|
8215
8053
|
function normalizeOptionalString2(value) {
|
|
@@ -8217,13 +8055,11 @@ function normalizeOptionalString2(value) {
|
|
|
8217
8055
|
return normalized.length > 0 ? normalized : void 0;
|
|
8218
8056
|
}
|
|
8219
8057
|
function clampNumber(value, fallback, min, max) {
|
|
8220
|
-
if (!Number.isFinite(value))
|
|
8221
|
-
return fallback;
|
|
8058
|
+
if (!Number.isFinite(value)) return fallback;
|
|
8222
8059
|
return Math.max(min, Math.min(max, Number(value)));
|
|
8223
8060
|
}
|
|
8224
8061
|
function sanitizeCandidateMetadata(metadata) {
|
|
8225
|
-
if (!metadata)
|
|
8226
|
-
return void 0;
|
|
8062
|
+
if (!metadata) return void 0;
|
|
8227
8063
|
const result = {};
|
|
8228
8064
|
for (const [key, value] of Object.entries(metadata)) {
|
|
8229
8065
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -8236,12 +8072,9 @@ function selectObservers(members, observedActorId, maxObservers) {
|
|
|
8236
8072
|
const selected = [];
|
|
8237
8073
|
for (const member of members) {
|
|
8238
8074
|
const canObserve = member.actorId === observedActorId ? member.observeSelf : member.observeOthers;
|
|
8239
|
-
if (!canObserve)
|
|
8240
|
-
|
|
8241
|
-
if (
|
|
8242
|
-
selected.push(member.actorId);
|
|
8243
|
-
if (selected.length >= maxObservers)
|
|
8244
|
-
break;
|
|
8075
|
+
if (!canObserve) continue;
|
|
8076
|
+
if (!selected.includes(member.actorId)) selected.push(member.actorId);
|
|
8077
|
+
if (selected.length >= maxObservers) break;
|
|
8245
8078
|
}
|
|
8246
8079
|
return selected;
|
|
8247
8080
|
}
|
|
@@ -8260,6 +8093,7 @@ var VectorStore = class {
|
|
|
8260
8093
|
constructor(dbPath) {
|
|
8261
8094
|
this.dbPath = dbPath;
|
|
8262
8095
|
}
|
|
8096
|
+
dbPath;
|
|
8263
8097
|
db = null;
|
|
8264
8098
|
tableCache = /* @__PURE__ */ new Map();
|
|
8265
8099
|
defaultTableName = "conversations";
|
|
@@ -8271,8 +8105,7 @@ var VectorStore = class {
|
|
|
8271
8105
|
* conversations table.
|
|
8272
8106
|
*/
|
|
8273
8107
|
async initialize() {
|
|
8274
|
-
if (this.db)
|
|
8275
|
-
return;
|
|
8108
|
+
if (this.db) return;
|
|
8276
8109
|
this.db = await lancedb.connect(this.dbPath);
|
|
8277
8110
|
}
|
|
8278
8111
|
/**
|
|
@@ -8286,8 +8119,7 @@ var VectorStore = class {
|
|
|
8286
8119
|
* Add or update multiple vector records in batch, grouped by inferred table.
|
|
8287
8120
|
*/
|
|
8288
8121
|
async upsertBatch(records) {
|
|
8289
|
-
if (records.length === 0)
|
|
8290
|
-
return;
|
|
8122
|
+
if (records.length === 0) return;
|
|
8291
8123
|
await this.initialize();
|
|
8292
8124
|
if (!this.db) {
|
|
8293
8125
|
throw new Error("Database not initialized");
|
|
@@ -8342,8 +8174,7 @@ var VectorStore = class {
|
|
|
8342
8174
|
async delete(eventId) {
|
|
8343
8175
|
await this.initialize();
|
|
8344
8176
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8345
|
-
if (!table)
|
|
8346
|
-
return;
|
|
8177
|
+
if (!table) return;
|
|
8347
8178
|
await table.delete(`eventId = ${toLanceSqlString(eventId)}`);
|
|
8348
8179
|
}
|
|
8349
8180
|
/**
|
|
@@ -8352,8 +8183,7 @@ var VectorStore = class {
|
|
|
8352
8183
|
async count() {
|
|
8353
8184
|
await this.initialize();
|
|
8354
8185
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8355
|
-
if (!table)
|
|
8356
|
-
return 0;
|
|
8186
|
+
if (!table) return 0;
|
|
8357
8187
|
const result = await table.countRows();
|
|
8358
8188
|
return result;
|
|
8359
8189
|
}
|
|
@@ -8362,8 +8192,7 @@ var VectorStore = class {
|
|
|
8362
8192
|
*/
|
|
8363
8193
|
async clearAll() {
|
|
8364
8194
|
await this.initialize();
|
|
8365
|
-
if (!this.db)
|
|
8366
|
-
return;
|
|
8195
|
+
if (!this.db) return;
|
|
8367
8196
|
try {
|
|
8368
8197
|
if (typeof this.db.dropTable === "function") {
|
|
8369
8198
|
await this.db.dropTable(this.defaultTableName);
|
|
@@ -8380,8 +8209,7 @@ var VectorStore = class {
|
|
|
8380
8209
|
async exists(eventId) {
|
|
8381
8210
|
await this.initialize();
|
|
8382
8211
|
const table = await this.getExistingTable(this.defaultTableName);
|
|
8383
|
-
if (!table)
|
|
8384
|
-
return false;
|
|
8212
|
+
if (!table) return false;
|
|
8385
8213
|
const results = await table.search([]).where(`eventId = ${toLanceSqlString(eventId)}`).limit(1).toArray();
|
|
8386
8214
|
return results.length > 0;
|
|
8387
8215
|
}
|
|
@@ -8416,8 +8244,7 @@ var VectorStore = class {
|
|
|
8416
8244
|
throw new Error("Database not initialized");
|
|
8417
8245
|
}
|
|
8418
8246
|
const cached = this.tableCache.get(tableName);
|
|
8419
|
-
if (cached)
|
|
8420
|
-
return cached;
|
|
8247
|
+
if (cached) return cached;
|
|
8421
8248
|
const tableNames = await this.db.tableNames();
|
|
8422
8249
|
if (!tableNames.includes(tableName)) {
|
|
8423
8250
|
return null;
|
|
@@ -8496,12 +8323,9 @@ var IngestInterceptorRegistry = class {
|
|
|
8496
8323
|
}
|
|
8497
8324
|
};
|
|
8498
8325
|
function mergeHierarchicalMetadata(base, patch) {
|
|
8499
|
-
if (!base && !patch)
|
|
8500
|
-
|
|
8501
|
-
if (!base
|
|
8502
|
-
return patch;
|
|
8503
|
-
if (!patch)
|
|
8504
|
-
return base;
|
|
8326
|
+
if (!base && !patch) return void 0;
|
|
8327
|
+
if (!base) return patch;
|
|
8328
|
+
if (!patch) return base;
|
|
8505
8329
|
const result = { ...base };
|
|
8506
8330
|
for (const [key, value] of Object.entries(patch)) {
|
|
8507
8331
|
const current = result[key];
|
|
@@ -8531,33 +8355,26 @@ var VALID_TAG_NAMESPACES = new Set(Object.values(TAG_NAMESPACES));
|
|
|
8531
8355
|
function parseTag(tag) {
|
|
8532
8356
|
const value = (tag || "").trim();
|
|
8533
8357
|
const idx = value.indexOf(":");
|
|
8534
|
-
if (idx <= 0)
|
|
8535
|
-
return { value };
|
|
8358
|
+
if (idx <= 0) return { value };
|
|
8536
8359
|
const namespace = `${value.slice(0, idx)}:`;
|
|
8537
8360
|
const tagValue = value.slice(idx + 1);
|
|
8538
|
-
if (!tagValue)
|
|
8539
|
-
return { value };
|
|
8361
|
+
if (!tagValue) return { value };
|
|
8540
8362
|
return { namespace, value: tagValue };
|
|
8541
8363
|
}
|
|
8542
8364
|
function validateTag(tag) {
|
|
8543
8365
|
const normalized = (tag || "").trim();
|
|
8544
|
-
if (!normalized)
|
|
8545
|
-
return false;
|
|
8366
|
+
if (!normalized) return false;
|
|
8546
8367
|
const { namespace } = parseTag(normalized);
|
|
8547
|
-
if (!namespace)
|
|
8548
|
-
return true;
|
|
8368
|
+
if (!namespace) return true;
|
|
8549
8369
|
return VALID_TAG_NAMESPACES.has(namespace);
|
|
8550
8370
|
}
|
|
8551
8371
|
function normalizeTags(tags) {
|
|
8552
|
-
if (!Array.isArray(tags))
|
|
8553
|
-
return [];
|
|
8372
|
+
if (!Array.isArray(tags)) return [];
|
|
8554
8373
|
const dedup = /* @__PURE__ */ new Set();
|
|
8555
8374
|
for (const item of tags) {
|
|
8556
|
-
if (typeof item !== "string")
|
|
8557
|
-
continue;
|
|
8375
|
+
if (typeof item !== "string") continue;
|
|
8558
8376
|
const normalized = item.trim();
|
|
8559
|
-
if (!validateTag(normalized))
|
|
8560
|
-
continue;
|
|
8377
|
+
if (!validateTag(normalized)) continue;
|
|
8561
8378
|
dedup.add(normalized);
|
|
8562
8379
|
}
|
|
8563
8380
|
return [...dedup];
|
|
@@ -8574,10 +8391,8 @@ var SummaryDeriver = class {
|
|
|
8574
8391
|
* orchestration, while this class owns summary text and metadata decisions.
|
|
8575
8392
|
*/
|
|
8576
8393
|
deriveSessionSummary(events) {
|
|
8577
|
-
if (events.length < 3)
|
|
8578
|
-
|
|
8579
|
-
if (events.some((event) => event.eventType === "session_summary"))
|
|
8580
|
-
return null;
|
|
8394
|
+
if (events.length < 3) return null;
|
|
8395
|
+
if (events.some((event) => event.eventType === "session_summary")) return null;
|
|
8581
8396
|
const prompts = events.filter((event) => event.eventType === "user_prompt");
|
|
8582
8397
|
const toolObservations = events.filter((event) => event.eventType === "tool_observation");
|
|
8583
8398
|
const toolNames = Array.from(new Set(
|
|
@@ -8725,8 +8540,7 @@ var MemoryIngestService = class {
|
|
|
8725
8540
|
await this.initialize();
|
|
8726
8541
|
const events = await this.eventStore.getSessionEvents(sessionId);
|
|
8727
8542
|
const summary = this.summaryDeriver.deriveSessionSummary(events);
|
|
8728
|
-
if (!summary)
|
|
8729
|
-
return;
|
|
8543
|
+
if (!summary) return;
|
|
8730
8544
|
await this.storeSessionSummary(sessionId, summary.text, summary.metadata);
|
|
8731
8545
|
}
|
|
8732
8546
|
async storeToolObservation(sessionId, payload) {
|
|
@@ -8794,10 +8608,8 @@ var MemoryIngestService = class {
|
|
|
8794
8608
|
}
|
|
8795
8609
|
}
|
|
8796
8610
|
async runPerspectiveDeriver(input, eventId, operation) {
|
|
8797
|
-
if (!this.perspectiveDeriver)
|
|
8798
|
-
|
|
8799
|
-
if (operation !== "user_prompt" && operation !== "agent_response")
|
|
8800
|
-
return;
|
|
8611
|
+
if (!this.perspectiveDeriver) return;
|
|
8612
|
+
if (operation !== "user_prompt" && operation !== "agent_response") return;
|
|
8801
8613
|
const event = {
|
|
8802
8614
|
id: eventId,
|
|
8803
8615
|
eventType: input.eventType,
|
|
@@ -8867,11 +8679,13 @@ var MemoryQueryService = class {
|
|
|
8867
8679
|
this.queryStore = queryStore;
|
|
8868
8680
|
this.deps = deps;
|
|
8869
8681
|
}
|
|
8682
|
+
initialize;
|
|
8683
|
+
queryStore;
|
|
8684
|
+
deps;
|
|
8870
8685
|
async keywordSearch(query, options) {
|
|
8871
8686
|
await this.initialize();
|
|
8872
8687
|
const results = await this.queryStore.keywordSearch(query, options?.topK ?? 10);
|
|
8873
|
-
if (results.length === 0)
|
|
8874
|
-
return [];
|
|
8688
|
+
if (results.length === 0) return [];
|
|
8875
8689
|
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
8876
8690
|
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
8877
8691
|
const rankRange = maxRank - minRank || 1;
|
|
@@ -9117,55 +8931,42 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
|
|
|
9117
8931
|
]);
|
|
9118
8932
|
function isCommandArtifactQuery(query) {
|
|
9119
8933
|
const trimmed = query.trim();
|
|
9120
|
-
if (!trimmed)
|
|
9121
|
-
return false;
|
|
8934
|
+
if (!trimmed) return false;
|
|
9122
8935
|
const normalized = trimmed.toLowerCase();
|
|
9123
|
-
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr"))
|
|
9124
|
-
|
|
9125
|
-
if (normalized.includes("command-name") || normalized.includes("command-message"))
|
|
9126
|
-
return true;
|
|
8936
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8937
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
9127
8938
|
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9128
8939
|
}
|
|
9129
8940
|
function isGenericContinuationQuery(query) {
|
|
9130
8941
|
const trimmed = query.trim();
|
|
9131
|
-
if (!trimmed)
|
|
9132
|
-
|
|
9133
|
-
if (
|
|
9134
|
-
return false;
|
|
9135
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
9136
|
-
return false;
|
|
8942
|
+
if (!trimmed) return false;
|
|
8943
|
+
if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
8944
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
9137
8945
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
9138
|
-
if (tokens.length > 10)
|
|
9139
|
-
return false;
|
|
8946
|
+
if (tokens.length > 10) return false;
|
|
9140
8947
|
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);
|
|
9141
8948
|
}
|
|
9142
8949
|
function isShortRepairFollowUpQuery(query) {
|
|
9143
8950
|
const trimmed = query.trim();
|
|
9144
|
-
if (!trimmed)
|
|
9145
|
-
|
|
9146
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
9147
|
-
return false;
|
|
8951
|
+
if (!trimmed) return false;
|
|
8952
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
9148
8953
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
9149
|
-
if (tokens.length > 8)
|
|
9150
|
-
return false;
|
|
8954
|
+
if (tokens.length > 8) return false;
|
|
9151
8955
|
return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9152
8956
|
}
|
|
9153
8957
|
function isCurrentStateQuery(query) {
|
|
9154
8958
|
const trimmed = query.trim();
|
|
9155
|
-
if (!trimmed)
|
|
9156
|
-
return false;
|
|
8959
|
+
if (!trimmed) return false;
|
|
9157
8960
|
return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9158
8961
|
}
|
|
9159
8962
|
function isStaleOrSupersededContent(content) {
|
|
9160
8963
|
const trimmed = content.trim();
|
|
9161
|
-
if (!trimmed)
|
|
9162
|
-
return false;
|
|
8964
|
+
if (!trimmed) return false;
|
|
9163
8965
|
return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9164
8966
|
}
|
|
9165
8967
|
function buildRetrievalQualityQuery(query) {
|
|
9166
8968
|
const trimmed = query.trim();
|
|
9167
|
-
if (!trimmed)
|
|
9168
|
-
return query;
|
|
8969
|
+
if (!trimmed) return query;
|
|
9169
8970
|
if (isRetrievalPrivacyDecisionQuery(trimmed)) {
|
|
9170
8971
|
return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
|
|
9171
8972
|
}
|
|
@@ -9179,12 +8980,10 @@ function buildRetrievalQualityQuery(query) {
|
|
|
9179
8980
|
}
|
|
9180
8981
|
function isRetrievalPrivacyDecisionQuery(query) {
|
|
9181
8982
|
const trimmed = query.trim();
|
|
9182
|
-
if (!trimmed)
|
|
9183
|
-
return false;
|
|
8983
|
+
if (!trimmed) return false;
|
|
9184
8984
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
9185
8985
|
const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
9186
|
-
if (!hasDecisionSignal)
|
|
9187
|
-
return false;
|
|
8986
|
+
if (!hasDecisionSignal) return false;
|
|
9188
8987
|
const hasRawQuerySignal = terms.has("raw") && terms.has("query");
|
|
9189
8988
|
const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
|
|
9190
8989
|
const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
|
|
@@ -9197,16 +8996,14 @@ function extractTechnicalQueryTerms(query) {
|
|
|
9197
8996
|
const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
|
|
9198
8997
|
const terms = matches.filter((term) => {
|
|
9199
8998
|
const lower = term.toLowerCase();
|
|
9200
|
-
if (GENERIC_TECHNICAL_TERMS.has(lower))
|
|
9201
|
-
return false;
|
|
8999
|
+
if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
|
|
9202
9000
|
return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
|
|
9203
9001
|
});
|
|
9204
9002
|
return Array.from(new Set(terms.map((term) => term.toLowerCase())));
|
|
9205
9003
|
}
|
|
9206
9004
|
function hasTechnicalTermOverlap(query, content) {
|
|
9207
9005
|
const terms = extractTechnicalQueryTerms(query);
|
|
9208
|
-
if (terms.length === 0)
|
|
9209
|
-
return true;
|
|
9006
|
+
if (terms.length === 0) return true;
|
|
9210
9007
|
const normalizedContent = content.toLowerCase();
|
|
9211
9008
|
return terms.some((term) => normalizedContent.includes(term));
|
|
9212
9009
|
}
|
|
@@ -9222,15 +9019,12 @@ function hasDiscriminativeTermOverlap(query, content) {
|
|
|
9222
9019
|
return topicTerms.some((term) => contentTerms.has(term));
|
|
9223
9020
|
}
|
|
9224
9021
|
}
|
|
9225
|
-
if (queryTerms.length < 3)
|
|
9226
|
-
return true;
|
|
9022
|
+
if (queryTerms.length < 3) return true;
|
|
9227
9023
|
const requiredHits = queryTerms.length >= 3 ? 2 : 1;
|
|
9228
9024
|
let hits = 0;
|
|
9229
9025
|
for (const term of queryTerms) {
|
|
9230
|
-
if (contentTerms.has(term))
|
|
9231
|
-
|
|
9232
|
-
if (hits >= requiredHits)
|
|
9233
|
-
return true;
|
|
9026
|
+
if (contentTerms.has(term)) hits += 1;
|
|
9027
|
+
if (hits >= requiredHits) return true;
|
|
9234
9028
|
}
|
|
9235
9029
|
return false;
|
|
9236
9030
|
}
|
|
@@ -9240,17 +9034,14 @@ function shouldApplyTechnicalGuard(query) {
|
|
|
9240
9034
|
function hasAnyTerm(terms, expectedTerms) {
|
|
9241
9035
|
let found = false;
|
|
9242
9036
|
expectedTerms.forEach((term) => {
|
|
9243
|
-
if (terms.has(term))
|
|
9244
|
-
found = true;
|
|
9037
|
+
if (terms.has(term)) found = true;
|
|
9245
9038
|
});
|
|
9246
9039
|
return found;
|
|
9247
9040
|
}
|
|
9248
9041
|
function shouldRequireDecisionTopicOverlap(query) {
|
|
9249
|
-
if (isRetrievalPrivacyDecisionQuery(query))
|
|
9250
|
-
return false;
|
|
9042
|
+
if (isRetrievalPrivacyDecisionQuery(query)) return false;
|
|
9251
9043
|
const trimmed = query.trim();
|
|
9252
|
-
if (!trimmed)
|
|
9253
|
-
return false;
|
|
9044
|
+
if (!trimmed) return false;
|
|
9254
9045
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
9255
9046
|
return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
9256
9047
|
}
|
|
@@ -9258,12 +9049,9 @@ function extractDiscriminativeQueryTerms(query) {
|
|
|
9258
9049
|
const seen = /* @__PURE__ */ new Set();
|
|
9259
9050
|
const terms = [];
|
|
9260
9051
|
for (const token of tokenizeQualityText(query)) {
|
|
9261
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token))
|
|
9262
|
-
|
|
9263
|
-
if (
|
|
9264
|
-
continue;
|
|
9265
|
-
if (seen.has(token))
|
|
9266
|
-
continue;
|
|
9052
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
|
|
9053
|
+
if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
|
|
9054
|
+
if (seen.has(token)) continue;
|
|
9267
9055
|
seen.add(token);
|
|
9268
9056
|
terms.push(token);
|
|
9269
9057
|
}
|
|
@@ -9278,14 +9066,10 @@ function tokenizeQualityText(text) {
|
|
|
9278
9066
|
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);
|
|
9279
9067
|
}
|
|
9280
9068
|
function normalizeQualityToken(token) {
|
|
9281
|
-
if (token === "apis")
|
|
9282
|
-
|
|
9283
|
-
if (token
|
|
9284
|
-
|
|
9285
|
-
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token))
|
|
9286
|
-
return token;
|
|
9287
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
9288
|
-
return `${token.slice(0, -3)}y`;
|
|
9069
|
+
if (token === "apis") return "api";
|
|
9070
|
+
if (token === "ids") return "id";
|
|
9071
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
|
|
9072
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
9289
9073
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
|
|
9290
9074
|
return token.slice(0, -1);
|
|
9291
9075
|
}
|
|
@@ -9467,8 +9251,7 @@ var Retriever = class {
|
|
|
9467
9251
|
const sharedMemories = [];
|
|
9468
9252
|
for (const result of sharedVectorResults) {
|
|
9469
9253
|
const entry = await this.sharedStore.get(result.entryId);
|
|
9470
|
-
if (!entry)
|
|
9471
|
-
continue;
|
|
9254
|
+
if (!entry) continue;
|
|
9472
9255
|
if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
|
|
9473
9256
|
sharedMemories.push(entry);
|
|
9474
9257
|
await this.sharedStore.recordUsage(entry.entryId);
|
|
@@ -9549,18 +9332,15 @@ var Retriever = class {
|
|
|
9549
9332
|
(result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
|
|
9550
9333
|
);
|
|
9551
9334
|
}
|
|
9552
|
-
if (filtered.length <= 2)
|
|
9553
|
-
return filtered;
|
|
9335
|
+
if (filtered.length <= 2) return filtered;
|
|
9554
9336
|
const topScore = filtered[0].score;
|
|
9555
|
-
if (topScore < 0.8)
|
|
9556
|
-
return filtered;
|
|
9337
|
+
if (topScore < 0.8) return filtered;
|
|
9557
9338
|
const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
|
|
9558
9339
|
return filtered.filter((result) => result.score >= cliffThreshold);
|
|
9559
9340
|
}
|
|
9560
9341
|
mergeResults(primary, secondary, limit) {
|
|
9561
9342
|
const byId = /* @__PURE__ */ new Map();
|
|
9562
|
-
for (const row of primary)
|
|
9563
|
-
byId.set(row.eventId, row);
|
|
9343
|
+
for (const row of primary) byId.set(row.eventId, row);
|
|
9564
9344
|
for (const row of secondary) {
|
|
9565
9345
|
const prev = byId.get(row.eventId);
|
|
9566
9346
|
if (!prev || row.score > prev.score) {
|
|
@@ -9571,23 +9351,19 @@ var Retriever = class {
|
|
|
9571
9351
|
}
|
|
9572
9352
|
async expandGraphHops(seeds, opts) {
|
|
9573
9353
|
const byId = /* @__PURE__ */ new Map();
|
|
9574
|
-
for (const s of seeds)
|
|
9575
|
-
byId.set(s.eventId, s);
|
|
9354
|
+
for (const s of seeds) byId.set(s.eventId, s);
|
|
9576
9355
|
let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
|
|
9577
9356
|
for (let hop = 1; hop <= opts.maxHops; hop += 1) {
|
|
9578
9357
|
const next = [];
|
|
9579
9358
|
for (const f of frontier) {
|
|
9580
9359
|
const ev = await this.eventStore.getEvent(f.row.eventId);
|
|
9581
|
-
if (!ev)
|
|
9582
|
-
continue;
|
|
9360
|
+
if (!ev) continue;
|
|
9583
9361
|
const rel = ev.metadata?.relatedEventIds ?? [];
|
|
9584
9362
|
const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
|
|
9585
9363
|
for (const rid of relatedIds) {
|
|
9586
|
-
if (byId.has(rid))
|
|
9587
|
-
continue;
|
|
9364
|
+
if (byId.has(rid)) continue;
|
|
9588
9365
|
const target = await this.eventStore.getEvent(rid);
|
|
9589
|
-
if (!target)
|
|
9590
|
-
continue;
|
|
9366
|
+
if (!target) continue;
|
|
9591
9367
|
const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
|
|
9592
9368
|
const row = {
|
|
9593
9369
|
id: `hop-${hop}-${rid}`,
|
|
@@ -9601,15 +9377,12 @@ var Retriever = class {
|
|
|
9601
9377
|
};
|
|
9602
9378
|
byId.set(row.eventId, row);
|
|
9603
9379
|
next.push({ row, hop });
|
|
9604
|
-
if (byId.size >= opts.limit)
|
|
9605
|
-
break;
|
|
9380
|
+
if (byId.size >= opts.limit) break;
|
|
9606
9381
|
}
|
|
9607
|
-
if (byId.size >= opts.limit)
|
|
9608
|
-
break;
|
|
9382
|
+
if (byId.size >= opts.limit) break;
|
|
9609
9383
|
}
|
|
9610
9384
|
frontier = next;
|
|
9611
|
-
if (frontier.length === 0 || byId.size >= opts.limit)
|
|
9612
|
-
break;
|
|
9385
|
+
if (frontier.length === 0 || byId.size >= opts.limit) break;
|
|
9613
9386
|
}
|
|
9614
9387
|
if (opts.queryGraphEnabled) {
|
|
9615
9388
|
await this.expandQueryGraphPaths(opts.query, byId, opts);
|
|
@@ -9617,8 +9390,7 @@ var Retriever = class {
|
|
|
9617
9390
|
return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
|
|
9618
9391
|
}
|
|
9619
9392
|
async expandQueryGraphPaths(query, byId, opts) {
|
|
9620
|
-
if (!query.trim() || !this.eventStore.getDatabase)
|
|
9621
|
-
return;
|
|
9393
|
+
if (!query.trim() || !this.eventStore.getDatabase) return;
|
|
9622
9394
|
try {
|
|
9623
9395
|
const db = this.eventStore.getDatabase();
|
|
9624
9396
|
const extraction = new QueryEntityExtractor(db).extract(query, {
|
|
@@ -9627,8 +9399,7 @@ var Retriever = class {
|
|
|
9627
9399
|
});
|
|
9628
9400
|
const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
|
|
9629
9401
|
const startNodes = uniqueEntityStartNodes(startCandidates);
|
|
9630
|
-
if (startNodes.length === 0)
|
|
9631
|
-
return;
|
|
9402
|
+
if (startNodes.length === 0) return;
|
|
9632
9403
|
const expansion = new GraphPathService(db).expand({
|
|
9633
9404
|
startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
|
|
9634
9405
|
maxHops: opts.maxHops,
|
|
@@ -9637,11 +9408,9 @@ var Retriever = class {
|
|
|
9637
9408
|
});
|
|
9638
9409
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
9639
9410
|
for (const path12 of expansion.paths) {
|
|
9640
|
-
if (path12.target.type !== "event")
|
|
9641
|
-
continue;
|
|
9411
|
+
if (path12.target.type !== "event") continue;
|
|
9642
9412
|
const target = await this.eventStore.getEvent(path12.target.id);
|
|
9643
|
-
if (!target)
|
|
9644
|
-
continue;
|
|
9413
|
+
if (!target) continue;
|
|
9645
9414
|
const graphPath = toRetrievalGraphPathDebug(path12, titleByEntityId);
|
|
9646
9415
|
const score = graphPathScore(path12, opts.hopPenalty);
|
|
9647
9416
|
const existing = byId.get(target.id);
|
|
@@ -9667,17 +9436,14 @@ var Retriever = class {
|
|
|
9667
9436
|
lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
|
|
9668
9437
|
};
|
|
9669
9438
|
byId.set(row.eventId, row);
|
|
9670
|
-
if (byId.size >= opts.limit)
|
|
9671
|
-
break;
|
|
9439
|
+
if (byId.size >= opts.limit) break;
|
|
9672
9440
|
}
|
|
9673
9441
|
} catch {
|
|
9674
9442
|
}
|
|
9675
9443
|
}
|
|
9676
9444
|
shouldFallback(matchResult, results) {
|
|
9677
|
-
if (results.length === 0)
|
|
9678
|
-
|
|
9679
|
-
if (matchResult.confidence === "none")
|
|
9680
|
-
return true;
|
|
9445
|
+
if (results.length === 0) return true;
|
|
9446
|
+
if (matchResult.confidence === "none") return true;
|
|
9681
9447
|
return false;
|
|
9682
9448
|
}
|
|
9683
9449
|
async buildSummaryFallback(query, topK) {
|
|
@@ -9782,29 +9548,21 @@ var Retriever = class {
|
|
|
9782
9548
|
(value) => typeof value === "string" && value.length > 0
|
|
9783
9549
|
)
|
|
9784
9550
|
);
|
|
9785
|
-
if (!scope && projectScopeMode === "global" && facetFilters === null)
|
|
9786
|
-
return results;
|
|
9551
|
+
if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
|
|
9787
9552
|
const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
|
|
9788
9553
|
const filtered = [];
|
|
9789
9554
|
for (const result of results) {
|
|
9790
|
-
if (scope?.sessionId && result.sessionId !== scope.sessionId)
|
|
9791
|
-
|
|
9792
|
-
if (scope?.
|
|
9793
|
-
continue;
|
|
9794
|
-
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType))
|
|
9795
|
-
continue;
|
|
9555
|
+
if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
|
|
9556
|
+
if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
|
|
9557
|
+
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
|
|
9796
9558
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9797
|
-
if (!event)
|
|
9798
|
-
|
|
9799
|
-
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
|
|
9800
|
-
continue;
|
|
9559
|
+
if (!event) continue;
|
|
9560
|
+
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
|
|
9801
9561
|
if (normalizedIncludes.length > 0) {
|
|
9802
9562
|
const lc = event.content.toLowerCase();
|
|
9803
|
-
if (!normalizedIncludes.some((needle) => lc.includes(needle)))
|
|
9804
|
-
continue;
|
|
9563
|
+
if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
|
|
9805
9564
|
}
|
|
9806
|
-
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
|
|
9807
|
-
continue;
|
|
9565
|
+
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
|
|
9808
9566
|
const projectHash = this.extractProjectHash(event.metadata);
|
|
9809
9567
|
filtered.push({ result, projectHash });
|
|
9810
9568
|
}
|
|
@@ -9821,27 +9579,21 @@ var Retriever = class {
|
|
|
9821
9579
|
});
|
|
9822
9580
|
}
|
|
9823
9581
|
normalizeFacetFilters(facets) {
|
|
9824
|
-
if (!facets || facets.length === 0)
|
|
9825
|
-
return null;
|
|
9582
|
+
if (!facets || facets.length === 0) return null;
|
|
9826
9583
|
const normalized = [];
|
|
9827
9584
|
for (const facet of facets) {
|
|
9828
9585
|
const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
|
|
9829
9586
|
const value = typeof facet.value === "string" ? facet.value.trim() : "";
|
|
9830
|
-
if (!parsedDimension.success || !value)
|
|
9831
|
-
return [];
|
|
9587
|
+
if (!parsedDimension.success || !value) return [];
|
|
9832
9588
|
normalized.push({ dimension: parsedDimension.data, value });
|
|
9833
9589
|
}
|
|
9834
9590
|
return normalized;
|
|
9835
9591
|
}
|
|
9836
9592
|
async applyFacetFilters(results, options) {
|
|
9837
|
-
if (options.facets === null)
|
|
9838
|
-
|
|
9839
|
-
if (options.
|
|
9840
|
-
|
|
9841
|
-
if (!options.projectHash)
|
|
9842
|
-
return [];
|
|
9843
|
-
if (!this.eventStore.getDatabase)
|
|
9844
|
-
return [];
|
|
9593
|
+
if (options.facets === null) return results;
|
|
9594
|
+
if (options.facets.length === 0) return [];
|
|
9595
|
+
if (!options.projectHash) return [];
|
|
9596
|
+
if (!this.eventStore.getDatabase) return [];
|
|
9845
9597
|
const repo = new FacetRepository(this.eventStore.getDatabase());
|
|
9846
9598
|
const filtered = [];
|
|
9847
9599
|
for (const result of results) {
|
|
@@ -9898,14 +9650,11 @@ var Retriever = class {
|
|
|
9898
9650
|
return (result.graphPaths || []).length > 0;
|
|
9899
9651
|
}
|
|
9900
9652
|
extractProjectHash(metadata) {
|
|
9901
|
-
if (!metadata || typeof metadata !== "object")
|
|
9902
|
-
return void 0;
|
|
9653
|
+
if (!metadata || typeof metadata !== "object") return void 0;
|
|
9903
9654
|
const scope = metadata.scope;
|
|
9904
|
-
if (!scope || typeof scope !== "object")
|
|
9905
|
-
return void 0;
|
|
9655
|
+
if (!scope || typeof scope !== "object") return void 0;
|
|
9906
9656
|
const project = scope.project;
|
|
9907
|
-
if (!project || typeof project !== "object")
|
|
9908
|
-
return void 0;
|
|
9657
|
+
if (!project || typeof project !== "object") return void 0;
|
|
9909
9658
|
const hash = project.hash;
|
|
9910
9659
|
return typeof hash === "string" && hash.length > 0 ? hash : void 0;
|
|
9911
9660
|
}
|
|
@@ -9919,8 +9668,7 @@ var Retriever = class {
|
|
|
9919
9668
|
const memories = [];
|
|
9920
9669
|
for (const result of results) {
|
|
9921
9670
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9922
|
-
if (!event)
|
|
9923
|
-
continue;
|
|
9671
|
+
if (!event) continue;
|
|
9924
9672
|
if (this.graduation) {
|
|
9925
9673
|
this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
|
|
9926
9674
|
}
|
|
@@ -9935,32 +9683,27 @@ var Retriever = class {
|
|
|
9935
9683
|
async getSessionContext(sessionId, eventId) {
|
|
9936
9684
|
const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
|
|
9937
9685
|
const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
|
|
9938
|
-
if (eventIndex === -1)
|
|
9939
|
-
return void 0;
|
|
9686
|
+
if (eventIndex === -1) return void 0;
|
|
9940
9687
|
const start = Math.max(0, eventIndex - 1);
|
|
9941
9688
|
const end = Math.min(sessionEvents.length, eventIndex + 2);
|
|
9942
9689
|
const contextEvents = sessionEvents.slice(start, end);
|
|
9943
|
-
if (contextEvents.length <= 1)
|
|
9944
|
-
return void 0;
|
|
9690
|
+
if (contextEvents.length <= 1) return void 0;
|
|
9945
9691
|
return contextEvents.filter((e) => e.id !== eventId).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`).join("\n");
|
|
9946
9692
|
}
|
|
9947
9693
|
buildUnifiedContext(projectResult, sharedMemories) {
|
|
9948
9694
|
let context = projectResult.context;
|
|
9949
|
-
if (sharedMemories.length === 0)
|
|
9950
|
-
return context;
|
|
9695
|
+
if (sharedMemories.length === 0) return context;
|
|
9951
9696
|
context += "\n\n## Cross-Project Knowledge\n\n";
|
|
9952
9697
|
for (const memory of sharedMemories.slice(0, 3)) {
|
|
9953
9698
|
context += `### ${memory.title}
|
|
9954
9699
|
`;
|
|
9955
|
-
if (memory.symptoms.length > 0)
|
|
9956
|
-
context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9700
|
+
if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9957
9701
|
`;
|
|
9958
9702
|
context += `**Root Cause:** ${memory.rootCause}
|
|
9959
9703
|
`;
|
|
9960
9704
|
context += `**Solution:** ${memory.solution}
|
|
9961
9705
|
`;
|
|
9962
|
-
if (memory.technologies && memory.technologies.length > 0)
|
|
9963
|
-
context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9706
|
+
if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9964
9707
|
`;
|
|
9965
9708
|
context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
|
|
9966
9709
|
|
|
@@ -9974,13 +9717,11 @@ var Retriever = class {
|
|
|
9974
9717
|
for (const memory of memories) {
|
|
9975
9718
|
const memoryText = this.formatMemory(memory);
|
|
9976
9719
|
const memoryTokens = this.estimateTokens(memoryText);
|
|
9977
|
-
if (currentTokens + memoryTokens > maxTokens)
|
|
9978
|
-
break;
|
|
9720
|
+
if (currentTokens + memoryTokens > maxTokens) break;
|
|
9979
9721
|
parts.push(memoryText);
|
|
9980
9722
|
currentTokens += memoryTokens;
|
|
9981
9723
|
}
|
|
9982
|
-
if (parts.length === 0)
|
|
9983
|
-
return "";
|
|
9724
|
+
if (parts.length === 0) return "";
|
|
9984
9725
|
return `## Relevant Memories
|
|
9985
9726
|
|
|
9986
9727
|
${parts.join("\n\n---\n\n")}`;
|
|
@@ -9990,19 +9731,16 @@ ${parts.join("\n\n---\n\n")}`;
|
|
|
9990
9731
|
const date = event.timestamp.toISOString().split("T")[0];
|
|
9991
9732
|
let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
|
|
9992
9733
|
${event.content}`;
|
|
9993
|
-
if (sessionContext)
|
|
9994
|
-
text += `
|
|
9734
|
+
if (sessionContext) text += `
|
|
9995
9735
|
|
|
9996
9736
|
_Context:_ ${sessionContext}`;
|
|
9997
9737
|
return text;
|
|
9998
9738
|
}
|
|
9999
9739
|
matchesMetadataScope(metadata, expected) {
|
|
10000
|
-
if (!metadata)
|
|
10001
|
-
return false;
|
|
9740
|
+
if (!metadata) return false;
|
|
10002
9741
|
return Object.entries(expected).every(([path12, value]) => {
|
|
10003
9742
|
const actual = path12.split(".").reduce((acc, key) => {
|
|
10004
|
-
if (typeof acc !== "object" || acc === null)
|
|
10005
|
-
return void 0;
|
|
9743
|
+
if (typeof acc !== "object" || acc === null) return void 0;
|
|
10006
9744
|
return acc[key];
|
|
10007
9745
|
}, metadata);
|
|
10008
9746
|
return actual === value;
|
|
@@ -10012,27 +9750,20 @@ _Context:_ ${sessionContext}`;
|
|
|
10012
9750
|
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);
|
|
10013
9751
|
}
|
|
10014
9752
|
normalizeToken(token) {
|
|
10015
|
-
if (token === "apis")
|
|
10016
|
-
|
|
10017
|
-
if (token === "
|
|
10018
|
-
|
|
10019
|
-
if (token === "does")
|
|
10020
|
-
return token;
|
|
10021
|
-
if (token.length > 4 && token.endsWith("ies"))
|
|
10022
|
-
return `${token.slice(0, -3)}y`;
|
|
9753
|
+
if (token === "apis") return "api";
|
|
9754
|
+
if (token === "ids") return "id";
|
|
9755
|
+
if (token === "does") return token;
|
|
9756
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
10023
9757
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
|
|
10024
9758
|
return token.slice(0, -1);
|
|
10025
9759
|
}
|
|
10026
9760
|
return token;
|
|
10027
9761
|
}
|
|
10028
9762
|
keywordOverlap(a, b) {
|
|
10029
|
-
if (a.length === 0 || b.length === 0)
|
|
10030
|
-
return 0;
|
|
9763
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
10031
9764
|
const bs = new Set(b);
|
|
10032
9765
|
let hit = 0;
|
|
10033
|
-
for (const t of a)
|
|
10034
|
-
if (bs.has(t))
|
|
10035
|
-
hit += 1;
|
|
9766
|
+
for (const t of a) if (bs.has(t)) hit += 1;
|
|
10036
9767
|
return hit / a.length;
|
|
10037
9768
|
}
|
|
10038
9769
|
estimateTokens(text) {
|
|
@@ -10053,8 +9784,7 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
10053
9784
|
const seen = /* @__PURE__ */ new Set();
|
|
10054
9785
|
const nodes = [];
|
|
10055
9786
|
for (const candidate of candidates) {
|
|
10056
|
-
if (!candidate.entityId || seen.has(candidate.entityId))
|
|
10057
|
-
continue;
|
|
9787
|
+
if (!candidate.entityId || seen.has(candidate.entityId)) continue;
|
|
10058
9788
|
seen.add(candidate.entityId);
|
|
10059
9789
|
nodes.push({ entityId: candidate.entityId, title: candidate.text });
|
|
10060
9790
|
}
|
|
@@ -10078,16 +9808,14 @@ function graphPathScore(path12, hopPenalty) {
|
|
|
10078
9808
|
return Math.max(0.05, base - hopPenalty * Math.max(0, path12.hops - 1));
|
|
10079
9809
|
}
|
|
10080
9810
|
function clampGraphHops(maxHops) {
|
|
10081
|
-
if (!Number.isFinite(maxHops))
|
|
10082
|
-
return 2;
|
|
9811
|
+
if (!Number.isFinite(maxHops)) return 2;
|
|
10083
9812
|
return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
|
|
10084
9813
|
}
|
|
10085
9814
|
function mergeGraphPaths(existing, incoming) {
|
|
10086
9815
|
const byKey = /* @__PURE__ */ new Map();
|
|
10087
9816
|
for (const path12 of [...existing, ...incoming]) {
|
|
10088
9817
|
const key = [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("\0");
|
|
10089
|
-
if (!byKey.has(key))
|
|
10090
|
-
byKey.set(key, path12);
|
|
9818
|
+
if (!byKey.has(key)) byKey.set(key, path12);
|
|
10091
9819
|
}
|
|
10092
9820
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
10093
9821
|
}
|
|
@@ -10095,10 +9823,8 @@ function graphPathSignature(path12) {
|
|
|
10095
9823
|
return [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("|");
|
|
10096
9824
|
}
|
|
10097
9825
|
function compareStable(a, b) {
|
|
10098
|
-
if (a < b)
|
|
10099
|
-
|
|
10100
|
-
if (a > b)
|
|
10101
|
-
return 1;
|
|
9826
|
+
if (a < b) return -1;
|
|
9827
|
+
if (a > b) return 1;
|
|
10102
9828
|
return 0;
|
|
10103
9829
|
}
|
|
10104
9830
|
function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
@@ -10110,6 +9836,7 @@ var RetrievalAnalyticsService = class {
|
|
|
10110
9836
|
constructor(deps) {
|
|
10111
9837
|
this.deps = deps;
|
|
10112
9838
|
}
|
|
9839
|
+
deps;
|
|
10113
9840
|
async getRetrievalTraceStats() {
|
|
10114
9841
|
await this.deps.initialize();
|
|
10115
9842
|
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
@@ -10187,6 +9914,7 @@ var RetrievalDisclosureService = class {
|
|
|
10187
9914
|
constructor(deps) {
|
|
10188
9915
|
this.deps = deps;
|
|
10189
9916
|
}
|
|
9917
|
+
deps;
|
|
10190
9918
|
async search(query, options) {
|
|
10191
9919
|
const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
|
|
10192
9920
|
const debugByEventId = this.buildDebugIndex(result);
|
|
@@ -10216,8 +9944,7 @@ var RetrievalDisclosureService = class {
|
|
|
10216
9944
|
return this.expandShared(parsedId.entryId);
|
|
10217
9945
|
}
|
|
10218
9946
|
const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
10219
|
-
if (!targetEvent)
|
|
10220
|
-
return null;
|
|
9947
|
+
if (!targetEvent) return null;
|
|
10221
9948
|
const windowSize = Math.max(0, options?.windowSize ?? 3);
|
|
10222
9949
|
const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
10223
9950
|
const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
|
|
@@ -10241,8 +9968,7 @@ var RetrievalDisclosureService = class {
|
|
|
10241
9968
|
return this.sourceShared(parsedId.entryId);
|
|
10242
9969
|
}
|
|
10243
9970
|
const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
10244
|
-
if (!rawEvent)
|
|
10245
|
-
return null;
|
|
9971
|
+
if (!rawEvent) return null;
|
|
10246
9972
|
return {
|
|
10247
9973
|
...this.sourceReferenceForEvent(rawEvent),
|
|
10248
9974
|
rawEvents: [rawEvent],
|
|
@@ -10251,8 +9977,7 @@ var RetrievalDisclosureService = class {
|
|
|
10251
9977
|
}
|
|
10252
9978
|
async expandShared(entryId) {
|
|
10253
9979
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
10254
|
-
if (!entry)
|
|
10255
|
-
return null;
|
|
9980
|
+
if (!entry) return null;
|
|
10256
9981
|
return {
|
|
10257
9982
|
target: this.sharedToEnvelope(entry),
|
|
10258
9983
|
surroundingFacts: [],
|
|
@@ -10263,8 +9988,7 @@ var RetrievalDisclosureService = class {
|
|
|
10263
9988
|
}
|
|
10264
9989
|
async sourceShared(entryId) {
|
|
10265
9990
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
10266
|
-
if (!entry)
|
|
10267
|
-
return null;
|
|
9991
|
+
if (!entry) return null;
|
|
10268
9992
|
const sourceReference = this.sourceReferenceForShared(entry);
|
|
10269
9993
|
return {
|
|
10270
9994
|
...sourceReference,
|
|
@@ -10350,38 +10074,25 @@ var RetrievalDisclosureService = class {
|
|
|
10350
10074
|
const reasons = /* @__PURE__ */ new Set();
|
|
10351
10075
|
const usedVector = this.usedVector(result);
|
|
10352
10076
|
const usedKeyword = this.usedKeyword(result);
|
|
10353
|
-
if (usedVector && (debug?.semanticScore ?? 0) > 0)
|
|
10354
|
-
|
|
10355
|
-
if ((debug?.
|
|
10356
|
-
|
|
10357
|
-
if ((debug?.
|
|
10358
|
-
|
|
10359
|
-
if (
|
|
10360
|
-
|
|
10361
|
-
if (
|
|
10362
|
-
reasons.add("entity_overlap");
|
|
10363
|
-
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary"))
|
|
10364
|
-
reasons.add("summary_fallback");
|
|
10365
|
-
if (memory.sessionContext)
|
|
10366
|
-
reasons.add("continuity_link");
|
|
10367
|
-
if (memory.event.eventType === "tool_observation")
|
|
10368
|
-
reasons.add("tool_followup");
|
|
10369
|
-
if (reasons.size === 0)
|
|
10370
|
-
reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10077
|
+
if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
|
|
10078
|
+
if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
|
|
10079
|
+
if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
|
|
10080
|
+
if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
|
|
10081
|
+
if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
|
|
10082
|
+
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
|
|
10083
|
+
if (memory.sessionContext) reasons.add("continuity_link");
|
|
10084
|
+
if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
|
|
10085
|
+
if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10371
10086
|
return Array.from(reasons);
|
|
10372
10087
|
}
|
|
10373
10088
|
reasonsForContextEvent(event) {
|
|
10374
|
-
if (event.eventType === "tool_observation")
|
|
10375
|
-
|
|
10376
|
-
if (event.eventType === "session_summary")
|
|
10377
|
-
return ["summary_fallback"];
|
|
10089
|
+
if (event.eventType === "tool_observation") return ["tool_followup"];
|
|
10090
|
+
if (event.eventType === "session_summary") return ["summary_fallback"];
|
|
10378
10091
|
return ["continuity_link"];
|
|
10379
10092
|
}
|
|
10380
10093
|
resultTypeForEvent(event) {
|
|
10381
|
-
if (event.eventType === "session_summary")
|
|
10382
|
-
|
|
10383
|
-
if (event.eventType === "tool_observation")
|
|
10384
|
-
return "tool_evidence";
|
|
10094
|
+
if (event.eventType === "session_summary") return "summary";
|
|
10095
|
+
if (event.eventType === "tool_observation") return "tool_evidence";
|
|
10385
10096
|
return "source";
|
|
10386
10097
|
}
|
|
10387
10098
|
sourceReferenceForEvent(event) {
|
|
@@ -10405,21 +10116,15 @@ var RetrievalDisclosureService = class {
|
|
|
10405
10116
|
}
|
|
10406
10117
|
sourceTypeForEvent(event) {
|
|
10407
10118
|
const metadata = event.metadata || {};
|
|
10408
|
-
if (event.eventType === "tool_observation")
|
|
10409
|
-
|
|
10410
|
-
if (typeof metadata.
|
|
10411
|
-
return "transcript";
|
|
10412
|
-
if (typeof metadata.importedFrom === "string")
|
|
10413
|
-
return "imported_history";
|
|
10119
|
+
if (event.eventType === "tool_observation") return "tool_output";
|
|
10120
|
+
if (typeof metadata.transcriptPath === "string") return "transcript";
|
|
10121
|
+
if (typeof metadata.importedFrom === "string") return "imported_history";
|
|
10414
10122
|
return "raw_event";
|
|
10415
10123
|
}
|
|
10416
10124
|
titleForEvent(event) {
|
|
10417
|
-
if (event.eventType === "session_summary")
|
|
10418
|
-
|
|
10419
|
-
if (event.eventType === "
|
|
10420
|
-
return "Tool evidence";
|
|
10421
|
-
if (event.eventType === "agent_response")
|
|
10422
|
-
return "Agent response";
|
|
10125
|
+
if (event.eventType === "session_summary") return "Session summary";
|
|
10126
|
+
if (event.eventType === "tool_observation") return "Tool evidence";
|
|
10127
|
+
if (event.eventType === "agent_response") return "Agent response";
|
|
10423
10128
|
return "User prompt";
|
|
10424
10129
|
}
|
|
10425
10130
|
usedVector(result) {
|
|
@@ -10445,8 +10150,7 @@ var RetrievalDisclosureService = class {
|
|
|
10445
10150
|
}
|
|
10446
10151
|
preview(content, maxLength) {
|
|
10447
10152
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
10448
|
-
if (normalized.length <= maxLength)
|
|
10449
|
-
return normalized;
|
|
10153
|
+
if (normalized.length <= maxLength) return normalized;
|
|
10450
10154
|
return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
10451
10155
|
}
|
|
10452
10156
|
};
|
|
@@ -10475,6 +10179,7 @@ var RetrievalOrchestrator = class {
|
|
|
10475
10179
|
this.deps = deps;
|
|
10476
10180
|
this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
|
|
10477
10181
|
}
|
|
10182
|
+
deps;
|
|
10478
10183
|
/**
|
|
10479
10184
|
* Retrieve relevant memories for a query.
|
|
10480
10185
|
*/
|
|
@@ -10556,8 +10261,7 @@ var RetrievalOrchestrator = class {
|
|
|
10556
10261
|
* the heavier retrieval/vector initialization path for prompt telemetry.
|
|
10557
10262
|
*/
|
|
10558
10263
|
async incrementMemoryAccess(eventIds) {
|
|
10559
|
-
if (eventIds.length === 0)
|
|
10560
|
-
return;
|
|
10264
|
+
if (eventIds.length === 0) return;
|
|
10561
10265
|
await this.deps.accessStore.incrementAccessCount(eventIds);
|
|
10562
10266
|
}
|
|
10563
10267
|
/**
|
|
@@ -10570,10 +10274,8 @@ var RetrievalOrchestrator = class {
|
|
|
10570
10274
|
resolveGraphHopOptions(callerOptions) {
|
|
10571
10275
|
const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
|
|
10572
10276
|
const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
|
|
10573
|
-
if (!callerOptions)
|
|
10574
|
-
|
|
10575
|
-
if (!graphExpansion)
|
|
10576
|
-
return callerOptions;
|
|
10277
|
+
if (!callerOptions) return durableOptions;
|
|
10278
|
+
if (!graphExpansion) return callerOptions;
|
|
10577
10279
|
if (graphExpansion.enabled !== true) {
|
|
10578
10280
|
return {
|
|
10579
10281
|
...callerOptions,
|
|
@@ -10633,12 +10335,10 @@ var RetrievalOrchestrator = class {
|
|
|
10633
10335
|
const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
|
|
10634
10336
|
const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
|
|
10635
10337
|
const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
|
|
10636
|
-
if (!allFinite)
|
|
10637
|
-
return void 0;
|
|
10338
|
+
if (!allFinite) return void 0;
|
|
10638
10339
|
const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
|
|
10639
10340
|
const total = semantic + lexical + recency;
|
|
10640
|
-
if (!nonNegative || total <= 0)
|
|
10641
|
-
return void 0;
|
|
10341
|
+
if (!nonNegative || total <= 0) return void 0;
|
|
10642
10342
|
return {
|
|
10643
10343
|
semantic: semantic / total,
|
|
10644
10344
|
lexical: lexical / total,
|
|
@@ -10647,17 +10347,14 @@ var RetrievalOrchestrator = class {
|
|
|
10647
10347
|
}
|
|
10648
10348
|
async getRerankWeights(adaptive) {
|
|
10649
10349
|
const configured = this.getConfiguredRerankWeights();
|
|
10650
|
-
if (configured)
|
|
10651
|
-
|
|
10652
|
-
if (adaptive)
|
|
10653
|
-
return this.getAdaptiveRerankWeights();
|
|
10350
|
+
if (configured) return configured;
|
|
10351
|
+
if (adaptive) return this.getAdaptiveRerankWeights();
|
|
10654
10352
|
return void 0;
|
|
10655
10353
|
}
|
|
10656
10354
|
async getAdaptiveRerankWeights() {
|
|
10657
10355
|
try {
|
|
10658
10356
|
const stats = await this.deps.traceStore.getHelpfulnessStats();
|
|
10659
|
-
if (stats.totalEvaluated < 20)
|
|
10660
|
-
return void 0;
|
|
10357
|
+
if (stats.totalEvaluated < 20) return void 0;
|
|
10661
10358
|
let semantic = 0.7;
|
|
10662
10359
|
let lexical = 0.2;
|
|
10663
10360
|
let recency = 0.1;
|
|
@@ -10679,11 +10376,9 @@ var RetrievalOrchestrator = class {
|
|
|
10679
10376
|
}
|
|
10680
10377
|
}
|
|
10681
10378
|
async rewriteQueryIntent(query) {
|
|
10682
|
-
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
|
|
10683
|
-
return null;
|
|
10379
|
+
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
|
|
10684
10380
|
const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
|
|
10685
|
-
if (!apiUrl)
|
|
10686
|
-
return null;
|
|
10381
|
+
if (!apiUrl) return null;
|
|
10687
10382
|
const controller = new AbortController();
|
|
10688
10383
|
const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
|
|
10689
10384
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10709,11 +10404,9 @@ var RetrievalOrchestrator = class {
|
|
|
10709
10404
|
signal: controller.signal
|
|
10710
10405
|
});
|
|
10711
10406
|
const text = (await res.text()).trim();
|
|
10712
|
-
if (!text)
|
|
10713
|
-
return null;
|
|
10407
|
+
if (!text) return null;
|
|
10714
10408
|
const oneLine = text.replace(/^data:\s*/gm, "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).join(" ").slice(0, 240);
|
|
10715
|
-
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase())
|
|
10716
|
-
return null;
|
|
10409
|
+
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
|
|
10717
10410
|
return oneLine;
|
|
10718
10411
|
} catch {
|
|
10719
10412
|
return null;
|
|
@@ -10855,8 +10548,7 @@ function createMemoryEngineServices(options) {
|
|
|
10855
10548
|
};
|
|
10856
10549
|
}
|
|
10857
10550
|
function shouldEnablePerspectiveDeriver(options) {
|
|
10858
|
-
if (options.readOnly)
|
|
10859
|
-
return false;
|
|
10551
|
+
if (options.readOnly) return false;
|
|
10860
10552
|
const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
|
|
10861
10553
|
return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
|
|
10862
10554
|
}
|
|
@@ -10890,6 +10582,9 @@ var GraduationWorker = class {
|
|
|
10890
10582
|
this.graduation = graduation;
|
|
10891
10583
|
this.config = config;
|
|
10892
10584
|
}
|
|
10585
|
+
eventStore;
|
|
10586
|
+
graduation;
|
|
10587
|
+
config;
|
|
10893
10588
|
running = false;
|
|
10894
10589
|
timeout = null;
|
|
10895
10590
|
lastEvaluated = /* @__PURE__ */ new Map();
|
|
@@ -10897,8 +10592,7 @@ var GraduationWorker = class {
|
|
|
10897
10592
|
* Start the graduation worker
|
|
10898
10593
|
*/
|
|
10899
10594
|
start() {
|
|
10900
|
-
if (this.running)
|
|
10901
|
-
return;
|
|
10595
|
+
if (this.running) return;
|
|
10902
10596
|
this.running = true;
|
|
10903
10597
|
this.scheduleNext();
|
|
10904
10598
|
}
|
|
@@ -10928,8 +10622,7 @@ var GraduationWorker = class {
|
|
|
10928
10622
|
* Schedule the next graduation check
|
|
10929
10623
|
*/
|
|
10930
10624
|
scheduleNext() {
|
|
10931
|
-
if (!this.running)
|
|
10932
|
-
return;
|
|
10625
|
+
if (!this.running) return;
|
|
10933
10626
|
this.timeout = setTimeout(
|
|
10934
10627
|
() => this.run(),
|
|
10935
10628
|
this.config.evaluationIntervalMs
|
|
@@ -10939,8 +10632,7 @@ var GraduationWorker = class {
|
|
|
10939
10632
|
* Run graduation evaluation
|
|
10940
10633
|
*/
|
|
10941
10634
|
async run() {
|
|
10942
|
-
if (!this.running)
|
|
10943
|
-
return;
|
|
10635
|
+
if (!this.running) return;
|
|
10944
10636
|
try {
|
|
10945
10637
|
await this.runGraduation();
|
|
10946
10638
|
} catch (error) {
|
|
@@ -11004,10 +10696,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
11004
10696
|
maxRetries: 3
|
|
11005
10697
|
};
|
|
11006
10698
|
function parseJsonArray(value) {
|
|
11007
|
-
if (Array.isArray(value))
|
|
11008
|
-
|
|
11009
|
-
if (typeof value !== "string" || value.trim().length === 0)
|
|
11010
|
-
return [];
|
|
10699
|
+
if (Array.isArray(value)) return value;
|
|
10700
|
+
if (typeof value !== "string" || value.trim().length === 0) return [];
|
|
11011
10701
|
try {
|
|
11012
10702
|
const parsed = JSON.parse(value);
|
|
11013
10703
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -11037,8 +10727,7 @@ var VectorWorker = class {
|
|
|
11037
10727
|
* Start the worker polling loop
|
|
11038
10728
|
*/
|
|
11039
10729
|
start() {
|
|
11040
|
-
if (this.running)
|
|
11041
|
-
return;
|
|
10730
|
+
if (this.running) return;
|
|
11042
10731
|
this.running = true;
|
|
11043
10732
|
this.stopping = false;
|
|
11044
10733
|
this.poll();
|
|
@@ -11114,8 +10803,7 @@ var VectorWorker = class {
|
|
|
11114
10803
|
* Poll for new items
|
|
11115
10804
|
*/
|
|
11116
10805
|
async poll() {
|
|
11117
|
-
if (!this.running || this.stopping)
|
|
11118
|
-
return;
|
|
10806
|
+
if (!this.running || this.stopping) return;
|
|
11119
10807
|
try {
|
|
11120
10808
|
await this.processBatch();
|
|
11121
10809
|
} catch (error) {
|
|
@@ -11160,6 +10848,7 @@ var DefaultContentProvider = class {
|
|
|
11160
10848
|
constructor(db) {
|
|
11161
10849
|
this.db = db;
|
|
11162
10850
|
}
|
|
10851
|
+
db;
|
|
11163
10852
|
async getContent(itemKind, itemId) {
|
|
11164
10853
|
switch (itemKind) {
|
|
11165
10854
|
case "entry":
|
|
@@ -11180,8 +10869,7 @@ var DefaultContentProvider = class {
|
|
|
11180
10869
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
11181
10870
|
[entryId]
|
|
11182
10871
|
);
|
|
11183
|
-
if (rows.length === 0)
|
|
11184
|
-
return null;
|
|
10872
|
+
if (rows.length === 0) return null;
|
|
11185
10873
|
const row = rows[0];
|
|
11186
10874
|
const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
|
|
11187
10875
|
return {
|
|
@@ -11200,8 +10888,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11200
10888
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
11201
10889
|
[taskId]
|
|
11202
10890
|
);
|
|
11203
|
-
if (rows.length === 0)
|
|
11204
|
-
return null;
|
|
10891
|
+
if (rows.length === 0) return null;
|
|
11205
10892
|
const row = rows[0];
|
|
11206
10893
|
return {
|
|
11207
10894
|
content: row.search_text || row.title,
|
|
@@ -11217,8 +10904,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11217
10904
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
11218
10905
|
[eventId]
|
|
11219
10906
|
);
|
|
11220
|
-
if (rows.length === 0)
|
|
11221
|
-
return null;
|
|
10907
|
+
if (rows.length === 0) return null;
|
|
11222
10908
|
const row = rows[0];
|
|
11223
10909
|
return {
|
|
11224
10910
|
content: row.content,
|
|
@@ -11246,8 +10932,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11246
10932
|
}
|
|
11247
10933
|
throw error;
|
|
11248
10934
|
}
|
|
11249
|
-
if (rows.length === 0)
|
|
11250
|
-
return null;
|
|
10935
|
+
if (rows.length === 0) return null;
|
|
11251
10936
|
const row = rows[0];
|
|
11252
10937
|
const sourceEventIds = parseJsonArray(row.source_event_ids_json);
|
|
11253
10938
|
const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
|
|
@@ -11289,8 +10974,7 @@ var VectorWorkerV2 = class {
|
|
|
11289
10974
|
* Start the worker polling loop
|
|
11290
10975
|
*/
|
|
11291
10976
|
start() {
|
|
11292
|
-
if (this.running)
|
|
11293
|
-
return;
|
|
10977
|
+
if (this.running) return;
|
|
11294
10978
|
this.running = true;
|
|
11295
10979
|
this.stopping = false;
|
|
11296
10980
|
this.poll();
|
|
@@ -11360,8 +11044,7 @@ var VectorWorkerV2 = class {
|
|
|
11360
11044
|
* Poll for new jobs
|
|
11361
11045
|
*/
|
|
11362
11046
|
async poll() {
|
|
11363
|
-
if (!this.running || this.stopping)
|
|
11364
|
-
return;
|
|
11047
|
+
if (!this.running || this.stopping) return;
|
|
11365
11048
|
try {
|
|
11366
11049
|
await this.processBatch();
|
|
11367
11050
|
} catch (error) {
|
|
@@ -11428,8 +11111,7 @@ function createMemoryRuntimeService(deps) {
|
|
|
11428
11111
|
let graduationWorker = null;
|
|
11429
11112
|
return {
|
|
11430
11113
|
async initialize() {
|
|
11431
|
-
if (initialized)
|
|
11432
|
-
return;
|
|
11114
|
+
if (initialized) return;
|
|
11433
11115
|
await deps.sqliteStore.initialize();
|
|
11434
11116
|
if (deps.lightweightMode) {
|
|
11435
11117
|
initialized = true;
|
|
@@ -11523,8 +11205,7 @@ var SharedEventStore = class {
|
|
|
11523
11205
|
this.db = createDatabase(dbPath);
|
|
11524
11206
|
}
|
|
11525
11207
|
async initialize() {
|
|
11526
|
-
if (this.initialized)
|
|
11527
|
-
return;
|
|
11208
|
+
if (this.initialized) return;
|
|
11528
11209
|
await dbRun(this.db, `
|
|
11529
11210
|
CREATE TABLE IF NOT EXISTS shared_troubleshooting (
|
|
11530
11211
|
entry_id VARCHAR PRIMARY KEY,
|
|
@@ -11614,6 +11295,10 @@ var SharedPromoter = class {
|
|
|
11614
11295
|
this.embedder = embedder;
|
|
11615
11296
|
this.config = config;
|
|
11616
11297
|
}
|
|
11298
|
+
sharedStore;
|
|
11299
|
+
sharedVectorStore;
|
|
11300
|
+
embedder;
|
|
11301
|
+
config;
|
|
11617
11302
|
/**
|
|
11618
11303
|
* Check if an entry is eligible for promotion
|
|
11619
11304
|
*/
|
|
@@ -11795,6 +11480,7 @@ var SharedStore = class {
|
|
|
11795
11480
|
constructor(sharedEventStore) {
|
|
11796
11481
|
this.sharedEventStore = sharedEventStore;
|
|
11797
11482
|
}
|
|
11483
|
+
sharedEventStore;
|
|
11798
11484
|
get db() {
|
|
11799
11485
|
return this.sharedEventStore.getDatabase();
|
|
11800
11486
|
}
|
|
@@ -11899,8 +11585,7 @@ var SharedStore = class {
|
|
|
11899
11585
|
`SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
|
|
11900
11586
|
[entryId]
|
|
11901
11587
|
);
|
|
11902
|
-
if (rows.length === 0)
|
|
11903
|
-
return null;
|
|
11588
|
+
if (rows.length === 0) return null;
|
|
11904
11589
|
return this.rowToEntry(rows[0]);
|
|
11905
11590
|
}
|
|
11906
11591
|
/**
|
|
@@ -11913,8 +11598,7 @@ var SharedStore = class {
|
|
|
11913
11598
|
WHERE source_project_hash = ? AND source_entry_id = ?`,
|
|
11914
11599
|
[projectHash, sourceEntryId]
|
|
11915
11600
|
);
|
|
11916
|
-
if (rows.length === 0)
|
|
11917
|
-
return null;
|
|
11601
|
+
if (rows.length === 0) return null;
|
|
11918
11602
|
return this.rowToEntry(rows[0]);
|
|
11919
11603
|
}
|
|
11920
11604
|
/**
|
|
@@ -12024,6 +11708,7 @@ var SharedVectorStore = class {
|
|
|
12024
11708
|
constructor(dbPath) {
|
|
12025
11709
|
this.dbPath = dbPath;
|
|
12026
11710
|
}
|
|
11711
|
+
dbPath;
|
|
12027
11712
|
db = null;
|
|
12028
11713
|
table = null;
|
|
12029
11714
|
tableName = "shared_knowledge";
|
|
@@ -12031,8 +11716,7 @@ var SharedVectorStore = class {
|
|
|
12031
11716
|
* Initialize LanceDB connection
|
|
12032
11717
|
*/
|
|
12033
11718
|
async initialize() {
|
|
12034
|
-
if (this.db)
|
|
12035
|
-
return;
|
|
11719
|
+
if (this.db) return;
|
|
12036
11720
|
this.db = await lancedb2.connect(this.dbPath);
|
|
12037
11721
|
try {
|
|
12038
11722
|
const tables = await this.db.tableNames();
|
|
@@ -12074,8 +11758,7 @@ var SharedVectorStore = class {
|
|
|
12074
11758
|
* Add multiple records in batch
|
|
12075
11759
|
*/
|
|
12076
11760
|
async upsertBatch(records) {
|
|
12077
|
-
if (records.length === 0)
|
|
12078
|
-
return;
|
|
11761
|
+
if (records.length === 0) return;
|
|
12079
11762
|
await this.initialize();
|
|
12080
11763
|
if (!this.db) {
|
|
12081
11764
|
throw new Error("Database not initialized");
|
|
@@ -12136,24 +11819,21 @@ var SharedVectorStore = class {
|
|
|
12136
11819
|
* Delete vector by entry ID
|
|
12137
11820
|
*/
|
|
12138
11821
|
async delete(entryId) {
|
|
12139
|
-
if (!this.table)
|
|
12140
|
-
return;
|
|
11822
|
+
if (!this.table) return;
|
|
12141
11823
|
await this.table.delete(`entryId = '${entryId}'`);
|
|
12142
11824
|
}
|
|
12143
11825
|
/**
|
|
12144
11826
|
* Get total count
|
|
12145
11827
|
*/
|
|
12146
11828
|
async count() {
|
|
12147
|
-
if (!this.table)
|
|
12148
|
-
return 0;
|
|
11829
|
+
if (!this.table) return 0;
|
|
12149
11830
|
return this.table.countRows();
|
|
12150
11831
|
}
|
|
12151
11832
|
/**
|
|
12152
11833
|
* Check if vector exists for entry
|
|
12153
11834
|
*/
|
|
12154
11835
|
async exists(entryId) {
|
|
12155
|
-
if (!this.table)
|
|
12156
|
-
return false;
|
|
11836
|
+
if (!this.table) return false;
|
|
12157
11837
|
try {
|
|
12158
11838
|
const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
|
|
12159
11839
|
return results.length > 0;
|
|
@@ -12171,6 +11851,7 @@ var SharedMemoryServices = class {
|
|
|
12171
11851
|
constructor(options) {
|
|
12172
11852
|
this.options = options;
|
|
12173
11853
|
}
|
|
11854
|
+
options;
|
|
12174
11855
|
sharedEventStore = null;
|
|
12175
11856
|
sharedStore = null;
|
|
12176
11857
|
sharedVectorStore = null;
|
|
@@ -12195,8 +11876,7 @@ var SharedMemoryServices = class {
|
|
|
12195
11876
|
return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
|
|
12196
11877
|
}
|
|
12197
11878
|
async initialize() {
|
|
12198
|
-
if (this.options.config?.enabled === false || this.options.readOnly)
|
|
12199
|
-
return;
|
|
11879
|
+
if (this.options.config?.enabled === false || this.options.readOnly) return;
|
|
12200
11880
|
const sharedPath = this.getSharedStoragePath();
|
|
12201
11881
|
this.ensureDirectory(sharedPath, { allowCreate: true });
|
|
12202
11882
|
const store = await this.openStore(sharedPath);
|
|
@@ -12213,14 +11893,11 @@ var SharedMemoryServices = class {
|
|
|
12213
11893
|
this.options.retriever.setSharedStores(store, this.sharedVectorStore);
|
|
12214
11894
|
}
|
|
12215
11895
|
async ensureStoreForRead() {
|
|
12216
|
-
if (this.options.config?.enabled === false)
|
|
12217
|
-
|
|
12218
|
-
if (this.sharedStore)
|
|
12219
|
-
return this.sharedStore;
|
|
11896
|
+
if (this.options.config?.enabled === false) return null;
|
|
11897
|
+
if (this.sharedStore) return this.sharedStore;
|
|
12220
11898
|
const sharedPath = this.getSharedStoragePath();
|
|
12221
11899
|
const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
|
|
12222
|
-
if (!directoryReady)
|
|
12223
|
-
return null;
|
|
11900
|
+
if (!directoryReady) return null;
|
|
12224
11901
|
return this.openStore(sharedPath);
|
|
12225
11902
|
}
|
|
12226
11903
|
async getEntryForDisclosure(entryId) {
|
|
@@ -12237,13 +11914,11 @@ var SharedMemoryServices = class {
|
|
|
12237
11914
|
return this.sharedPromoter.promoteEntry(entry, projectHash);
|
|
12238
11915
|
}
|
|
12239
11916
|
async getStats() {
|
|
12240
|
-
if (!this.sharedStore)
|
|
12241
|
-
return null;
|
|
11917
|
+
if (!this.sharedStore) return null;
|
|
12242
11918
|
return this.sharedStore.getStats();
|
|
12243
11919
|
}
|
|
12244
11920
|
async search(query, options) {
|
|
12245
|
-
if (!this.sharedStore)
|
|
12246
|
-
return [];
|
|
11921
|
+
if (!this.sharedStore) return [];
|
|
12247
11922
|
return this.sharedStore.search(query, options);
|
|
12248
11923
|
}
|
|
12249
11924
|
async close() {
|
|
@@ -12260,8 +11935,7 @@ var SharedMemoryServices = class {
|
|
|
12260
11935
|
this.openStorePromise = null;
|
|
12261
11936
|
}
|
|
12262
11937
|
async openStore(sharedPath) {
|
|
12263
|
-
if (this.sharedStore)
|
|
12264
|
-
return this.sharedStore;
|
|
11938
|
+
if (this.sharedStore) return this.sharedStore;
|
|
12265
11939
|
if (!this.openStorePromise) {
|
|
12266
11940
|
this.openStorePromise = this.createOpenStorePromise(sharedPath);
|
|
12267
11941
|
}
|
|
@@ -12285,10 +11959,8 @@ var SharedMemoryServices = class {
|
|
|
12285
11959
|
return this.sharedStore;
|
|
12286
11960
|
}
|
|
12287
11961
|
ensureDirectory(sharedPath, options) {
|
|
12288
|
-
if (this.factories.existsSync(sharedPath))
|
|
12289
|
-
|
|
12290
|
-
if (!options.allowCreate)
|
|
12291
|
-
return false;
|
|
11962
|
+
if (this.factories.existsSync(sharedPath)) return true;
|
|
11963
|
+
if (!options.allowCreate) return false;
|
|
12292
11964
|
this.factories.mkdirSync(sharedPath);
|
|
12293
11965
|
return true;
|
|
12294
11966
|
}
|
|
@@ -13144,20 +12816,15 @@ var IMPORTANT_BASH_KEYWORDS = [
|
|
|
13144
12816
|
"successfully created"
|
|
13145
12817
|
];
|
|
13146
12818
|
function isBashSignificant(output, response) {
|
|
13147
|
-
if (response?.stderr && response.stderr.trim().length > 20)
|
|
13148
|
-
return true;
|
|
12819
|
+
if (response?.stderr && response.stderr.trim().length > 20) return true;
|
|
13149
12820
|
const lower = output.toLowerCase();
|
|
13150
|
-
if (IMPORTANT_BASH_KEYWORDS.some((kw) => lower.includes(kw)))
|
|
13151
|
-
return true;
|
|
12821
|
+
if (IMPORTANT_BASH_KEYWORDS.some((kw) => lower.includes(kw))) return true;
|
|
13152
12822
|
return output.trim().length > 2e3;
|
|
13153
12823
|
}
|
|
13154
12824
|
function hasSignificantOutput(toolName, output, response, minLen) {
|
|
13155
|
-
if (ALWAYS_STORE_TOOLS.has(toolName))
|
|
13156
|
-
|
|
13157
|
-
if (
|
|
13158
|
-
return isBashSignificant(output, response);
|
|
13159
|
-
if (response?.stderr && response.stderr.trim().length > 0)
|
|
13160
|
-
return true;
|
|
12825
|
+
if (ALWAYS_STORE_TOOLS.has(toolName)) return true;
|
|
12826
|
+
if (toolName === "Bash") return isBashSignificant(output, response);
|
|
12827
|
+
if (response?.stderr && response.stderr.trim().length > 0) return true;
|
|
13161
12828
|
return output.trim().length >= minLen;
|
|
13162
12829
|
}
|
|
13163
12830
|
var DEFAULT_PRIVACY_CONFIG = {
|
|
@@ -13171,14 +12838,11 @@ var DEFAULT_PRIVACY_CONFIG = {
|
|
|
13171
12838
|
}
|
|
13172
12839
|
};
|
|
13173
12840
|
function extractToolOutput(response) {
|
|
13174
|
-
if (!response)
|
|
13175
|
-
return "";
|
|
12841
|
+
if (!response) return "";
|
|
13176
12842
|
if (response.stdout !== void 0) {
|
|
13177
12843
|
const parts = [];
|
|
13178
|
-
if (response.stdout)
|
|
13179
|
-
|
|
13180
|
-
if (response.stderr)
|
|
13181
|
-
parts.push(`[stderr] ${response.stderr}`);
|
|
12844
|
+
if (response.stdout) parts.push(response.stdout);
|
|
12845
|
+
if (response.stderr) parts.push(`[stderr] ${response.stderr}`);
|
|
13182
12846
|
return parts.join("\n") || "";
|
|
13183
12847
|
}
|
|
13184
12848
|
if (response.content !== void 0) {
|
|
@@ -13187,10 +12851,8 @@ function extractToolOutput(response) {
|
|
|
13187
12851
|
return JSON.stringify(response);
|
|
13188
12852
|
}
|
|
13189
12853
|
function isToolSuccess(response) {
|
|
13190
|
-
if (!response)
|
|
13191
|
-
|
|
13192
|
-
if (response.interrupted)
|
|
13193
|
-
return false;
|
|
12854
|
+
if (!response) return false;
|
|
12855
|
+
if (response.interrupted) return false;
|
|
13194
12856
|
return true;
|
|
13195
12857
|
}
|
|
13196
12858
|
async function main() {
|