claude-memory-layer 1.0.44 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli/index.js +801 -1421
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +1319 -1501
- package/dist/core/index.js.map +4 -4
- package/dist/hooks/post-tool-use.js +465 -756
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/semantic-daemon.js +454 -734
- package/dist/hooks/semantic-daemon.js.map +2 -2
- package/dist/hooks/session-end.js +450 -726
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +451 -728
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +458 -742
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +494 -814
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/index.js +1397 -1615
- package/dist/index.js.map +4 -4
- package/dist/mcp/index.js +1587 -1655
- package/dist/mcp/index.js.map +4 -4
- package/dist/server/api/index.js +484 -792
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +492 -808
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +450 -726
- package/dist/services/memory-service.js.map +2 -2
- package/package.json +15 -3
|
@@ -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;
|
|
@@ -8966,6 +8780,18 @@ var COMMAND_ARTIFACT_PATTERNS = [
|
|
|
8966
8780
|
/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/i,
|
|
8967
8781
|
/<local-command-stderr>[\s\S]*?<\/local-command-stderr>/i
|
|
8968
8782
|
];
|
|
8783
|
+
var LOW_SIGNAL_CONTEXT_PATTERNS = [
|
|
8784
|
+
/<environment_context\b[\s\S]*<\/environment_context>/i,
|
|
8785
|
+
/<turn_aborted>/i,
|
|
8786
|
+
/^#\s*AGENTS\.md\s+instructions\b[\s\S]*<INSTRUCTIONS>/i,
|
|
8787
|
+
/^\s*(?:understood[,\s.]*)?(?:stopping|stopped|pausing|paused)\s+here\b[\s\S]{0,180}\blet\s+me\s+know\s+when\s+you(?:'d|\s+would)?\s+like\s+to\s+continue\b/i,
|
|
8788
|
+
/^\s*\[?CONTEXT\s+COMPACTION\s*[—-]\s*REFERENCE\s+ONLY\]?\b[\s\S]{0,600}\b(?:earlier\s+turns\s+were\s+compacted|handoff\s+from\s+a\s+previous\s+context\s+window|active\s+task)\b/i,
|
|
8789
|
+
/^\s*Summary\s+generation\s+was\s+unavailable\.\s*\d+\s+message\(s\)\s+were\s+removed\s+to\s+free\s+context\s+space\b/i,
|
|
8790
|
+
/^\s*---\s*END\s+OF\s+CONTEXT\s+SUMMARY\b/i,
|
|
8791
|
+
/^\s*\[Your\s+active\s+task\s+list\s+was\s+preserved\s+across\s+context\s+compression\]/i,
|
|
8792
|
+
/^➜\s+\S+\s+git:\([^)]*\)\s+/i,
|
|
8793
|
+
/^\$\s+\S+/i
|
|
8794
|
+
];
|
|
8969
8795
|
var CONTINUATION_QUERY_PATTERNS = [
|
|
8970
8796
|
/^\s*(?:continue|resume|next|what(?:'s| is)? next|next\s+(?:step|task|action)|recommended\s+(?:next\s+)?(?:step|task|action)|what should (?:we|i) do next)\??\s*$/i,
|
|
8971
8797
|
/^\s*(?:응\s*)?(?:이어서(?:\s*진행(?:해줘)?)?|계속(?:\s*해줘)?|다음\s*(?:단계|작업|추천\s*작업|추천|할\s*일)?(?:은|는)?(?:\s*(?:뭐야|진행(?:해줘)?))?\??|남은\s*(?:추가(?:로)?\s*)?(?:(?:할\s*만한\s*)?(?:작업|일)|할\s*일)?(?:은|는)?\s*(?:있어|있나|있나요|뭐야)\??|추천\s*작업(?:은|는)?(?:\s*뭐야)?\??|진행해줘)\s*$/i
|
|
@@ -8977,7 +8803,7 @@ var SHORT_REPAIR_FOLLOW_UP_PATTERNS = [
|
|
|
8977
8803
|
var CURRENT_STATE_QUERY_PATTERNS = [
|
|
8978
8804
|
/\bcurrent\b.*\b(?:state|status|deployment|blocker|pr|pull request)\b/i,
|
|
8979
8805
|
/\b(?:still|as current|current)\b.*\b(?:unresolved|open|pending|not completed)\b/i,
|
|
8980
|
-
/\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|
|
|
8806
|
+
/\b(?:old|obsolete|stale|resolved|already resolved)\b.*\b(?:current|still|unresolved|open|status)\b/i,
|
|
8981
8807
|
/(?:현재|아직|이전|오래된|해결된).*(?:상태|미해결|열린|블로커|PR|풀리퀘스트)/i
|
|
8982
8808
|
];
|
|
8983
8809
|
var STALE_CONTENT_PATTERNS = [
|
|
@@ -9117,55 +8943,67 @@ var LOW_INFORMATION_QUERY_TERMS = /* @__PURE__ */ new Set([
|
|
|
9117
8943
|
]);
|
|
9118
8944
|
function isCommandArtifactQuery(query) {
|
|
9119
8945
|
const trimmed = query.trim();
|
|
9120
|
-
if (!trimmed)
|
|
9121
|
-
return false;
|
|
8946
|
+
if (!trimmed) return false;
|
|
9122
8947
|
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;
|
|
8948
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8949
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
9127
8950
|
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9128
8951
|
}
|
|
8952
|
+
function isCommandArtifactContent(content) {
|
|
8953
|
+
const trimmed = content.trim();
|
|
8954
|
+
if (!trimmed) return false;
|
|
8955
|
+
const normalized = trimmed.toLowerCase();
|
|
8956
|
+
if (normalized.includes("local-command-stdout") || normalized.includes("local-command-stderr")) return true;
|
|
8957
|
+
if (normalized.includes("command-name") || normalized.includes("command-message")) return true;
|
|
8958
|
+
return COMMAND_ARTIFACT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
8959
|
+
}
|
|
8960
|
+
function isLowSignalContextContent(content) {
|
|
8961
|
+
const trimmed = content.trim();
|
|
8962
|
+
if (!trimmed) return true;
|
|
8963
|
+
if (isCommandArtifactContent(trimmed)) return true;
|
|
8964
|
+
if (LOW_SIGNAL_CONTEXT_PATTERNS.some((pattern) => pattern.test(trimmed))) return true;
|
|
8965
|
+
return false;
|
|
8966
|
+
}
|
|
9129
8967
|
function isGenericContinuationQuery(query) {
|
|
9130
8968
|
const trimmed = query.trim();
|
|
9131
|
-
if (!trimmed)
|
|
9132
|
-
|
|
9133
|
-
if (
|
|
9134
|
-
return false;
|
|
9135
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
9136
|
-
return false;
|
|
8969
|
+
if (!trimmed) return false;
|
|
8970
|
+
if (!CONTINUATION_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed))) return false;
|
|
8971
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
9137
8972
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
9138
|
-
if (tokens.length > 10)
|
|
9139
|
-
return false;
|
|
8973
|
+
if (tokens.length > 10) return false;
|
|
9140
8974
|
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
8975
|
}
|
|
9142
8976
|
function isShortRepairFollowUpQuery(query) {
|
|
9143
8977
|
const trimmed = query.trim();
|
|
9144
|
-
if (!trimmed)
|
|
9145
|
-
|
|
9146
|
-
if (extractTechnicalQueryTerms(trimmed).length > 0)
|
|
9147
|
-
return false;
|
|
8978
|
+
if (!trimmed) return false;
|
|
8979
|
+
if (extractTechnicalQueryTerms(trimmed).length > 0) return false;
|
|
9148
8980
|
const tokens = trimmed.match(/[A-Za-z0-9가-힣#._/-]+/g) ?? [];
|
|
9149
|
-
if (tokens.length > 8)
|
|
9150
|
-
return false;
|
|
8981
|
+
if (tokens.length > 8) return false;
|
|
9151
8982
|
return SHORT_REPAIR_FOLLOW_UP_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9152
8983
|
}
|
|
8984
|
+
function isLowConfidenceContextFallbackQuery(query) {
|
|
8985
|
+
const trimmed = query.trim();
|
|
8986
|
+
if (!trimmed) return false;
|
|
8987
|
+
if (isGenericContinuationQuery(trimmed) || isShortRepairFollowUpQuery(trimmed)) return true;
|
|
8988
|
+
const terms = new Set(tokenizeQualityText(trimmed));
|
|
8989
|
+
if ((terms.has("compacted") || terms.has("compaction")) && terms.has("handoff")) return false;
|
|
8990
|
+
const hasContinuationRecall = /^(?:continue|resume)\b/i.test(trimmed) && (terms.has("work") || terms.has("step") || terms.has("task") || terms.has("last") || terms.has("completed"));
|
|
8991
|
+
const hasValidationGateRecall = terms.has("validation") && (terms.has("gate") || terms.has("check")) && (terms.has("run") || terms.has("before") || terms.has("commit") || terms.has("committing") || terms.has("change"));
|
|
8992
|
+
return hasContinuationRecall || hasValidationGateRecall;
|
|
8993
|
+
}
|
|
9153
8994
|
function isCurrentStateQuery(query) {
|
|
9154
8995
|
const trimmed = query.trim();
|
|
9155
|
-
if (!trimmed)
|
|
9156
|
-
return false;
|
|
8996
|
+
if (!trimmed) return false;
|
|
9157
8997
|
return CURRENT_STATE_QUERY_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9158
8998
|
}
|
|
9159
8999
|
function isStaleOrSupersededContent(content) {
|
|
9160
9000
|
const trimmed = content.trim();
|
|
9161
|
-
if (!trimmed)
|
|
9162
|
-
return false;
|
|
9001
|
+
if (!trimmed) return false;
|
|
9163
9002
|
return STALE_CONTENT_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
9164
9003
|
}
|
|
9165
9004
|
function buildRetrievalQualityQuery(query) {
|
|
9166
9005
|
const trimmed = query.trim();
|
|
9167
|
-
if (!trimmed)
|
|
9168
|
-
return query;
|
|
9006
|
+
if (!trimmed) return query;
|
|
9169
9007
|
if (isRetrievalPrivacyDecisionQuery(trimmed)) {
|
|
9170
9008
|
return `${trimmed} ${RETRIEVAL_PRIVACY_DECISION_EXPANSION}`;
|
|
9171
9009
|
}
|
|
@@ -9179,12 +9017,10 @@ function buildRetrievalQualityQuery(query) {
|
|
|
9179
9017
|
}
|
|
9180
9018
|
function isRetrievalPrivacyDecisionQuery(query) {
|
|
9181
9019
|
const trimmed = query.trim();
|
|
9182
|
-
if (!trimmed)
|
|
9183
|
-
return false;
|
|
9020
|
+
if (!trimmed) return false;
|
|
9184
9021
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
9185
9022
|
const hasDecisionSignal = hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
9186
|
-
if (!hasDecisionSignal)
|
|
9187
|
-
return false;
|
|
9023
|
+
if (!hasDecisionSignal) return false;
|
|
9188
9024
|
const hasRawQuerySignal = terms.has("raw") && terms.has("query");
|
|
9189
9025
|
const hasPrivacySignal = terms.has("privacy") || terms.has("expose") || terms.has("redacted");
|
|
9190
9026
|
const hasRetrievalSurface = hasAnyTerm(terms, RETRIEVAL_PRIVACY_SURFACE_TERMS) || terms.has("api") && terms.has("query");
|
|
@@ -9197,16 +9033,14 @@ function extractTechnicalQueryTerms(query) {
|
|
|
9197
9033
|
const matches = query.match(/[A-Za-z][A-Za-z0-9_.:-]{2,}/g) ?? [];
|
|
9198
9034
|
const terms = matches.filter((term) => {
|
|
9199
9035
|
const lower = term.toLowerCase();
|
|
9200
|
-
if (GENERIC_TECHNICAL_TERMS.has(lower))
|
|
9201
|
-
return false;
|
|
9036
|
+
if (GENERIC_TECHNICAL_TERMS.has(lower)) return false;
|
|
9202
9037
|
return /[._:-]/.test(term) || /[a-z][A-Z]/.test(term) || /[A-Z]{2,}/.test(term) || /\d/.test(term);
|
|
9203
9038
|
});
|
|
9204
9039
|
return Array.from(new Set(terms.map((term) => term.toLowerCase())));
|
|
9205
9040
|
}
|
|
9206
9041
|
function hasTechnicalTermOverlap(query, content) {
|
|
9207
9042
|
const terms = extractTechnicalQueryTerms(query);
|
|
9208
|
-
if (terms.length === 0)
|
|
9209
|
-
return true;
|
|
9043
|
+
if (terms.length === 0) return true;
|
|
9210
9044
|
const normalizedContent = content.toLowerCase();
|
|
9211
9045
|
return terms.some((term) => normalizedContent.includes(term));
|
|
9212
9046
|
}
|
|
@@ -9222,15 +9056,12 @@ function hasDiscriminativeTermOverlap(query, content) {
|
|
|
9222
9056
|
return topicTerms.some((term) => contentTerms.has(term));
|
|
9223
9057
|
}
|
|
9224
9058
|
}
|
|
9225
|
-
if (queryTerms.length < 3)
|
|
9226
|
-
return true;
|
|
9059
|
+
if (queryTerms.length < 3) return true;
|
|
9227
9060
|
const requiredHits = queryTerms.length >= 3 ? 2 : 1;
|
|
9228
9061
|
let hits = 0;
|
|
9229
9062
|
for (const term of queryTerms) {
|
|
9230
|
-
if (contentTerms.has(term))
|
|
9231
|
-
|
|
9232
|
-
if (hits >= requiredHits)
|
|
9233
|
-
return true;
|
|
9063
|
+
if (contentTerms.has(term)) hits += 1;
|
|
9064
|
+
if (hits >= requiredHits) return true;
|
|
9234
9065
|
}
|
|
9235
9066
|
return false;
|
|
9236
9067
|
}
|
|
@@ -9240,17 +9071,14 @@ function shouldApplyTechnicalGuard(query) {
|
|
|
9240
9071
|
function hasAnyTerm(terms, expectedTerms) {
|
|
9241
9072
|
let found = false;
|
|
9242
9073
|
expectedTerms.forEach((term) => {
|
|
9243
|
-
if (terms.has(term))
|
|
9244
|
-
found = true;
|
|
9074
|
+
if (terms.has(term)) found = true;
|
|
9245
9075
|
});
|
|
9246
9076
|
return found;
|
|
9247
9077
|
}
|
|
9248
9078
|
function shouldRequireDecisionTopicOverlap(query) {
|
|
9249
|
-
if (isRetrievalPrivacyDecisionQuery(query))
|
|
9250
|
-
return false;
|
|
9079
|
+
if (isRetrievalPrivacyDecisionQuery(query)) return false;
|
|
9251
9080
|
const trimmed = query.trim();
|
|
9252
|
-
if (!trimmed)
|
|
9253
|
-
return false;
|
|
9081
|
+
if (!trimmed) return false;
|
|
9254
9082
|
const terms = new Set(tokenizeQualityText(trimmed));
|
|
9255
9083
|
return hasAnyTerm(terms, DECISION_RECALL_TERMS) || /(?:결정|정책|원칙)/i.test(trimmed);
|
|
9256
9084
|
}
|
|
@@ -9258,12 +9086,9 @@ function extractDiscriminativeQueryTerms(query) {
|
|
|
9258
9086
|
const seen = /* @__PURE__ */ new Set();
|
|
9259
9087
|
const terms = [];
|
|
9260
9088
|
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;
|
|
9089
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token)) continue;
|
|
9090
|
+
if (GENERIC_TECHNICAL_TERMS.has(token)) continue;
|
|
9091
|
+
if (seen.has(token)) continue;
|
|
9267
9092
|
seen.add(token);
|
|
9268
9093
|
terms.push(token);
|
|
9269
9094
|
}
|
|
@@ -9278,14 +9103,10 @@ function tokenizeQualityText(text) {
|
|
|
9278
9103
|
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
9104
|
}
|
|
9280
9105
|
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`;
|
|
9106
|
+
if (token === "apis") return "api";
|
|
9107
|
+
if (token === "ids") return "id";
|
|
9108
|
+
if (LOW_INFORMATION_QUERY_TERMS.has(token) || GENERIC_TECHNICAL_TERMS.has(token)) return token;
|
|
9109
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
9289
9110
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is")) {
|
|
9290
9111
|
return token.slice(0, -1);
|
|
9291
9112
|
}
|
|
@@ -9437,7 +9258,14 @@ var Retriever = class {
|
|
|
9437
9258
|
};
|
|
9438
9259
|
fallbackTrace.push("fallback:summary");
|
|
9439
9260
|
}
|
|
9440
|
-
const
|
|
9261
|
+
const selectedResults = current.results.slice(0, opts.topK).filter((result) => {
|
|
9262
|
+
if (current.matchResult.confidence !== "none") return true;
|
|
9263
|
+
if (isLowConfidenceContextFallbackQuery(query)) {
|
|
9264
|
+
return (result.semanticScore ?? result.score) >= 0.5 || result.score >= 0.5;
|
|
9265
|
+
}
|
|
9266
|
+
return (result.semanticScore ?? result.score) >= 0.62 || result.score >= 0.62;
|
|
9267
|
+
});
|
|
9268
|
+
const memories = await this.enrichResults(selectedResults, opts, query);
|
|
9441
9269
|
const context = this.buildContext(memories, opts.maxTokens);
|
|
9442
9270
|
return {
|
|
9443
9271
|
memories,
|
|
@@ -9445,7 +9273,7 @@ var Retriever = class {
|
|
|
9445
9273
|
totalTokens: this.estimateTokens(context),
|
|
9446
9274
|
context,
|
|
9447
9275
|
fallbackTrace,
|
|
9448
|
-
selectedDebug:
|
|
9276
|
+
selectedDebug: selectedResults.map((r) => this.debugDetailForResult(r)),
|
|
9449
9277
|
candidateDebug: (current.candidateResults || []).slice(0, Math.max(opts.topK * 3, 20)).map((r) => this.debugDetailForResult(r)),
|
|
9450
9278
|
rawQueryText: current.queryRewriteKind ? query : void 0,
|
|
9451
9279
|
effectiveQueryText: current.effectiveQueryText,
|
|
@@ -9467,8 +9295,7 @@ var Retriever = class {
|
|
|
9467
9295
|
const sharedMemories = [];
|
|
9468
9296
|
for (const result of sharedVectorResults) {
|
|
9469
9297
|
const entry = await this.sharedStore.get(result.entryId);
|
|
9470
|
-
if (!entry)
|
|
9471
|
-
continue;
|
|
9298
|
+
if (!entry) continue;
|
|
9472
9299
|
if (!options.projectHash || entry.sourceProjectHash !== options.projectHash) {
|
|
9473
9300
|
sharedMemories.push(entry);
|
|
9474
9301
|
await this.sharedStore.recordUsage(entry.entryId);
|
|
@@ -9541,6 +9368,7 @@ var Retriever = class {
|
|
|
9541
9368
|
if (isCurrentStateQuery(options.query)) {
|
|
9542
9369
|
filtered = filtered.filter((result) => !isStaleOrSupersededContent(result.content));
|
|
9543
9370
|
}
|
|
9371
|
+
filtered = filtered.filter((result) => !isLowSignalContextContent(result.content));
|
|
9544
9372
|
filtered = filtered.filter(
|
|
9545
9373
|
(result) => this.isGraphPathResult(result) || hasDiscriminativeTermOverlap(options.query, result.content)
|
|
9546
9374
|
);
|
|
@@ -9549,18 +9377,15 @@ var Retriever = class {
|
|
|
9549
9377
|
(result) => this.isGraphPathResult(result) || hasTechnicalTermOverlap(options.query, result.content)
|
|
9550
9378
|
);
|
|
9551
9379
|
}
|
|
9552
|
-
if (filtered.length <= 2)
|
|
9553
|
-
return filtered;
|
|
9380
|
+
if (filtered.length <= 2) return filtered;
|
|
9554
9381
|
const topScore = filtered[0].score;
|
|
9555
|
-
if (topScore < 0.8)
|
|
9556
|
-
return filtered;
|
|
9382
|
+
if (topScore < 0.8) return filtered;
|
|
9557
9383
|
const cliffThreshold = Math.max(options.minScore, topScore - 0.25);
|
|
9558
9384
|
return filtered.filter((result) => result.score >= cliffThreshold);
|
|
9559
9385
|
}
|
|
9560
9386
|
mergeResults(primary, secondary, limit) {
|
|
9561
9387
|
const byId = /* @__PURE__ */ new Map();
|
|
9562
|
-
for (const row of primary)
|
|
9563
|
-
byId.set(row.eventId, row);
|
|
9388
|
+
for (const row of primary) byId.set(row.eventId, row);
|
|
9564
9389
|
for (const row of secondary) {
|
|
9565
9390
|
const prev = byId.get(row.eventId);
|
|
9566
9391
|
if (!prev || row.score > prev.score) {
|
|
@@ -9571,23 +9396,19 @@ var Retriever = class {
|
|
|
9571
9396
|
}
|
|
9572
9397
|
async expandGraphHops(seeds, opts) {
|
|
9573
9398
|
const byId = /* @__PURE__ */ new Map();
|
|
9574
|
-
for (const s of seeds)
|
|
9575
|
-
byId.set(s.eventId, s);
|
|
9399
|
+
for (const s of seeds) byId.set(s.eventId, s);
|
|
9576
9400
|
let frontier = seeds.map((s) => ({ row: s, hop: 0 }));
|
|
9577
9401
|
for (let hop = 1; hop <= opts.maxHops; hop += 1) {
|
|
9578
9402
|
const next = [];
|
|
9579
9403
|
for (const f of frontier) {
|
|
9580
9404
|
const ev = await this.eventStore.getEvent(f.row.eventId);
|
|
9581
|
-
if (!ev)
|
|
9582
|
-
continue;
|
|
9405
|
+
if (!ev) continue;
|
|
9583
9406
|
const rel = ev.metadata?.relatedEventIds ?? [];
|
|
9584
9407
|
const relatedIds = Array.isArray(rel) ? rel.filter((x) => typeof x === "string") : [];
|
|
9585
9408
|
for (const rid of relatedIds) {
|
|
9586
|
-
if (byId.has(rid))
|
|
9587
|
-
continue;
|
|
9409
|
+
if (byId.has(rid)) continue;
|
|
9588
9410
|
const target = await this.eventStore.getEvent(rid);
|
|
9589
|
-
if (!target)
|
|
9590
|
-
continue;
|
|
9411
|
+
if (!target) continue;
|
|
9591
9412
|
const score = Math.max(0, f.row.score - opts.hopPenalty * hop);
|
|
9592
9413
|
const row = {
|
|
9593
9414
|
id: `hop-${hop}-${rid}`,
|
|
@@ -9601,15 +9422,12 @@ var Retriever = class {
|
|
|
9601
9422
|
};
|
|
9602
9423
|
byId.set(row.eventId, row);
|
|
9603
9424
|
next.push({ row, hop });
|
|
9604
|
-
if (byId.size >= opts.limit)
|
|
9605
|
-
break;
|
|
9425
|
+
if (byId.size >= opts.limit) break;
|
|
9606
9426
|
}
|
|
9607
|
-
if (byId.size >= opts.limit)
|
|
9608
|
-
break;
|
|
9427
|
+
if (byId.size >= opts.limit) break;
|
|
9609
9428
|
}
|
|
9610
9429
|
frontier = next;
|
|
9611
|
-
if (frontier.length === 0 || byId.size >= opts.limit)
|
|
9612
|
-
break;
|
|
9430
|
+
if (frontier.length === 0 || byId.size >= opts.limit) break;
|
|
9613
9431
|
}
|
|
9614
9432
|
if (opts.queryGraphEnabled) {
|
|
9615
9433
|
await this.expandQueryGraphPaths(opts.query, byId, opts);
|
|
@@ -9617,8 +9435,7 @@ var Retriever = class {
|
|
|
9617
9435
|
return [...byId.values()].sort((a, b) => b.score - a.score || compareStable(a.eventId, b.eventId)).slice(0, opts.limit);
|
|
9618
9436
|
}
|
|
9619
9437
|
async expandQueryGraphPaths(query, byId, opts) {
|
|
9620
|
-
if (!query.trim() || !this.eventStore.getDatabase)
|
|
9621
|
-
return;
|
|
9438
|
+
if (!query.trim() || !this.eventStore.getDatabase) return;
|
|
9622
9439
|
try {
|
|
9623
9440
|
const db = this.eventStore.getDatabase();
|
|
9624
9441
|
const extraction = new QueryEntityExtractor(db).extract(query, {
|
|
@@ -9627,8 +9444,7 @@ var Retriever = class {
|
|
|
9627
9444
|
});
|
|
9628
9445
|
const startCandidates = extraction.candidates.filter((candidate) => candidate.entityId).slice(0, 8);
|
|
9629
9446
|
const startNodes = uniqueEntityStartNodes(startCandidates);
|
|
9630
|
-
if (startNodes.length === 0)
|
|
9631
|
-
return;
|
|
9447
|
+
if (startNodes.length === 0) return;
|
|
9632
9448
|
const expansion = new GraphPathService(db).expand({
|
|
9633
9449
|
startNodes: startNodes.map((node) => ({ type: "entity", id: node.entityId })),
|
|
9634
9450
|
maxHops: opts.maxHops,
|
|
@@ -9637,11 +9453,9 @@ var Retriever = class {
|
|
|
9637
9453
|
});
|
|
9638
9454
|
const titleByEntityId = new Map(startNodes.map((node) => [node.entityId, node.title]));
|
|
9639
9455
|
for (const path12 of expansion.paths) {
|
|
9640
|
-
if (path12.target.type !== "event")
|
|
9641
|
-
continue;
|
|
9456
|
+
if (path12.target.type !== "event") continue;
|
|
9642
9457
|
const target = await this.eventStore.getEvent(path12.target.id);
|
|
9643
|
-
if (!target)
|
|
9644
|
-
continue;
|
|
9458
|
+
if (!target) continue;
|
|
9645
9459
|
const graphPath = toRetrievalGraphPathDebug(path12, titleByEntityId);
|
|
9646
9460
|
const score = graphPathScore(path12, opts.hopPenalty);
|
|
9647
9461
|
const existing = byId.get(target.id);
|
|
@@ -9667,17 +9481,14 @@ var Retriever = class {
|
|
|
9667
9481
|
lanes: mergeRetrievalLanes(existing?.lanes ?? [], [graphLane])
|
|
9668
9482
|
};
|
|
9669
9483
|
byId.set(row.eventId, row);
|
|
9670
|
-
if (byId.size >= opts.limit)
|
|
9671
|
-
break;
|
|
9484
|
+
if (byId.size >= opts.limit) break;
|
|
9672
9485
|
}
|
|
9673
9486
|
} catch {
|
|
9674
9487
|
}
|
|
9675
9488
|
}
|
|
9676
9489
|
shouldFallback(matchResult, results) {
|
|
9677
|
-
if (results.length === 0)
|
|
9678
|
-
|
|
9679
|
-
if (matchResult.confidence === "none")
|
|
9680
|
-
return true;
|
|
9490
|
+
if (results.length === 0) return true;
|
|
9491
|
+
if (matchResult.confidence === "none") return true;
|
|
9681
9492
|
return false;
|
|
9682
9493
|
}
|
|
9683
9494
|
async buildSummaryFallback(query, topK) {
|
|
@@ -9782,29 +9593,21 @@ var Retriever = class {
|
|
|
9782
9593
|
(value) => typeof value === "string" && value.length > 0
|
|
9783
9594
|
)
|
|
9784
9595
|
);
|
|
9785
|
-
if (!scope && projectScopeMode === "global" && facetFilters === null)
|
|
9786
|
-
return results;
|
|
9596
|
+
if (!scope && projectScopeMode === "global" && facetFilters === null) return results;
|
|
9787
9597
|
const normalizedIncludes = (scope?.contentIncludes || []).map((s) => s.toLowerCase());
|
|
9788
9598
|
const filtered = [];
|
|
9789
9599
|
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;
|
|
9600
|
+
if (scope?.sessionId && result.sessionId !== scope.sessionId) continue;
|
|
9601
|
+
if (scope?.sessionIdPrefix && !result.sessionId.startsWith(scope.sessionIdPrefix)) continue;
|
|
9602
|
+
if (scope?.eventTypes && scope.eventTypes.length > 0 && !scope.eventTypes.includes(result.eventType)) continue;
|
|
9796
9603
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9797
|
-
if (!event)
|
|
9798
|
-
|
|
9799
|
-
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix))
|
|
9800
|
-
continue;
|
|
9604
|
+
if (!event) continue;
|
|
9605
|
+
if (scope?.canonicalKeyPrefix && !event.canonicalKey.startsWith(scope.canonicalKeyPrefix)) continue;
|
|
9801
9606
|
if (normalizedIncludes.length > 0) {
|
|
9802
9607
|
const lc = event.content.toLowerCase();
|
|
9803
|
-
if (!normalizedIncludes.some((needle) => lc.includes(needle)))
|
|
9804
|
-
continue;
|
|
9608
|
+
if (!normalizedIncludes.some((needle) => lc.includes(needle))) continue;
|
|
9805
9609
|
}
|
|
9806
|
-
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata))
|
|
9807
|
-
continue;
|
|
9610
|
+
if (scope?.metadata && !this.matchesMetadataScope(event.metadata, scope.metadata)) continue;
|
|
9808
9611
|
const projectHash = this.extractProjectHash(event.metadata);
|
|
9809
9612
|
filtered.push({ result, projectHash });
|
|
9810
9613
|
}
|
|
@@ -9821,27 +9624,21 @@ var Retriever = class {
|
|
|
9821
9624
|
});
|
|
9822
9625
|
}
|
|
9823
9626
|
normalizeFacetFilters(facets) {
|
|
9824
|
-
if (!facets || facets.length === 0)
|
|
9825
|
-
return null;
|
|
9627
|
+
if (!facets || facets.length === 0) return null;
|
|
9826
9628
|
const normalized = [];
|
|
9827
9629
|
for (const facet of facets) {
|
|
9828
9630
|
const parsedDimension = FacetDimensionSchema.safeParse(facet.dimension);
|
|
9829
9631
|
const value = typeof facet.value === "string" ? facet.value.trim() : "";
|
|
9830
|
-
if (!parsedDimension.success || !value)
|
|
9831
|
-
return [];
|
|
9632
|
+
if (!parsedDimension.success || !value) return [];
|
|
9832
9633
|
normalized.push({ dimension: parsedDimension.data, value });
|
|
9833
9634
|
}
|
|
9834
9635
|
return normalized;
|
|
9835
9636
|
}
|
|
9836
9637
|
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 [];
|
|
9638
|
+
if (options.facets === null) return results;
|
|
9639
|
+
if (options.facets.length === 0) return [];
|
|
9640
|
+
if (!options.projectHash) return [];
|
|
9641
|
+
if (!this.eventStore.getDatabase) return [];
|
|
9845
9642
|
const repo = new FacetRepository(this.eventStore.getDatabase());
|
|
9846
9643
|
const filtered = [];
|
|
9847
9644
|
for (const result of results) {
|
|
@@ -9898,14 +9695,11 @@ var Retriever = class {
|
|
|
9898
9695
|
return (result.graphPaths || []).length > 0;
|
|
9899
9696
|
}
|
|
9900
9697
|
extractProjectHash(metadata) {
|
|
9901
|
-
if (!metadata || typeof metadata !== "object")
|
|
9902
|
-
return void 0;
|
|
9698
|
+
if (!metadata || typeof metadata !== "object") return void 0;
|
|
9903
9699
|
const scope = metadata.scope;
|
|
9904
|
-
if (!scope || typeof scope !== "object")
|
|
9905
|
-
return void 0;
|
|
9700
|
+
if (!scope || typeof scope !== "object") return void 0;
|
|
9906
9701
|
const project = scope.project;
|
|
9907
|
-
if (!project || typeof project !== "object")
|
|
9908
|
-
return void 0;
|
|
9702
|
+
if (!project || typeof project !== "object") return void 0;
|
|
9909
9703
|
const hash = project.hash;
|
|
9910
9704
|
return typeof hash === "string" && hash.length > 0 ? hash : void 0;
|
|
9911
9705
|
}
|
|
@@ -9915,52 +9709,48 @@ var Retriever = class {
|
|
|
9915
9709
|
async retrieveRecent(limit = 100) {
|
|
9916
9710
|
return this.eventStore.getRecentEvents(limit);
|
|
9917
9711
|
}
|
|
9918
|
-
async enrichResults(results, options) {
|
|
9712
|
+
async enrichResults(results, options, query) {
|
|
9919
9713
|
const memories = [];
|
|
9920
9714
|
for (const result of results) {
|
|
9921
9715
|
const event = await this.eventStore.getEvent(result.eventId);
|
|
9922
|
-
if (!event)
|
|
9923
|
-
continue;
|
|
9716
|
+
if (!event) continue;
|
|
9924
9717
|
if (this.graduation) {
|
|
9925
9718
|
this.graduation.recordAccess(event.id, options.sessionId || "unknown", result.score);
|
|
9926
9719
|
}
|
|
9927
9720
|
let sessionContext;
|
|
9928
9721
|
if (options.includeSessionContext) {
|
|
9929
|
-
sessionContext = await this.getSessionContext(event.sessionId, event.id);
|
|
9722
|
+
sessionContext = await this.getSessionContext(event.sessionId, event.id, query);
|
|
9930
9723
|
}
|
|
9931
9724
|
memories.push({ event, score: result.score, sessionContext });
|
|
9932
9725
|
}
|
|
9933
9726
|
return memories;
|
|
9934
9727
|
}
|
|
9935
|
-
async getSessionContext(sessionId, eventId) {
|
|
9728
|
+
async getSessionContext(sessionId, eventId, query) {
|
|
9936
9729
|
const sessionEvents = await this.eventStore.getSessionEvents(sessionId);
|
|
9937
9730
|
const eventIndex = sessionEvents.findIndex((e) => e.id === eventId);
|
|
9938
|
-
if (eventIndex === -1)
|
|
9939
|
-
return void 0;
|
|
9731
|
+
if (eventIndex === -1) return void 0;
|
|
9940
9732
|
const start = Math.max(0, eventIndex - 1);
|
|
9941
9733
|
const end = Math.min(sessionEvents.length, eventIndex + 2);
|
|
9942
9734
|
const contextEvents = sessionEvents.slice(start, end);
|
|
9943
|
-
if (contextEvents.length <= 1)
|
|
9944
|
-
|
|
9945
|
-
|
|
9735
|
+
if (contextEvents.length <= 1) return void 0;
|
|
9736
|
+
const suppressStaleState = isCurrentStateQuery(query);
|
|
9737
|
+
const contextLines = contextEvents.filter((e) => e.id !== eventId).filter((e) => !isLowSignalContextContent(e.content)).filter((e) => !(suppressStaleState && isStaleOrSupersededContent(e.content))).map((e) => `[${e.eventType}]: ${e.content.slice(0, 200)}...`);
|
|
9738
|
+
return contextLines.length > 0 ? contextLines.join("\n") : void 0;
|
|
9946
9739
|
}
|
|
9947
9740
|
buildUnifiedContext(projectResult, sharedMemories) {
|
|
9948
9741
|
let context = projectResult.context;
|
|
9949
|
-
if (sharedMemories.length === 0)
|
|
9950
|
-
return context;
|
|
9742
|
+
if (sharedMemories.length === 0) return context;
|
|
9951
9743
|
context += "\n\n## Cross-Project Knowledge\n\n";
|
|
9952
9744
|
for (const memory of sharedMemories.slice(0, 3)) {
|
|
9953
9745
|
context += `### ${memory.title}
|
|
9954
9746
|
`;
|
|
9955
|
-
if (memory.symptoms.length > 0)
|
|
9956
|
-
context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9747
|
+
if (memory.symptoms.length > 0) context += `**Symptoms:** ${memory.symptoms.join(", ")}
|
|
9957
9748
|
`;
|
|
9958
9749
|
context += `**Root Cause:** ${memory.rootCause}
|
|
9959
9750
|
`;
|
|
9960
9751
|
context += `**Solution:** ${memory.solution}
|
|
9961
9752
|
`;
|
|
9962
|
-
if (memory.technologies && memory.technologies.length > 0)
|
|
9963
|
-
context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9753
|
+
if (memory.technologies && memory.technologies.length > 0) context += `**Technologies:** ${memory.technologies.join(", ")}
|
|
9964
9754
|
`;
|
|
9965
9755
|
context += `_Confidence: ${(memory.confidence * 100).toFixed(0)}%_
|
|
9966
9756
|
|
|
@@ -9974,13 +9764,11 @@ var Retriever = class {
|
|
|
9974
9764
|
for (const memory of memories) {
|
|
9975
9765
|
const memoryText = this.formatMemory(memory);
|
|
9976
9766
|
const memoryTokens = this.estimateTokens(memoryText);
|
|
9977
|
-
if (currentTokens + memoryTokens > maxTokens)
|
|
9978
|
-
break;
|
|
9767
|
+
if (currentTokens + memoryTokens > maxTokens) break;
|
|
9979
9768
|
parts.push(memoryText);
|
|
9980
9769
|
currentTokens += memoryTokens;
|
|
9981
9770
|
}
|
|
9982
|
-
if (parts.length === 0)
|
|
9983
|
-
return "";
|
|
9771
|
+
if (parts.length === 0) return "";
|
|
9984
9772
|
return `## Relevant Memories
|
|
9985
9773
|
|
|
9986
9774
|
${parts.join("\n\n---\n\n")}`;
|
|
@@ -9990,19 +9778,16 @@ ${parts.join("\n\n---\n\n")}`;
|
|
|
9990
9778
|
const date = event.timestamp.toISOString().split("T")[0];
|
|
9991
9779
|
let text = `**${event.eventType}** (${date}, score: ${score.toFixed(2)})
|
|
9992
9780
|
${event.content}`;
|
|
9993
|
-
if (sessionContext)
|
|
9994
|
-
text += `
|
|
9781
|
+
if (sessionContext) text += `
|
|
9995
9782
|
|
|
9996
9783
|
_Context:_ ${sessionContext}`;
|
|
9997
9784
|
return text;
|
|
9998
9785
|
}
|
|
9999
9786
|
matchesMetadataScope(metadata, expected) {
|
|
10000
|
-
if (!metadata)
|
|
10001
|
-
return false;
|
|
9787
|
+
if (!metadata) return false;
|
|
10002
9788
|
return Object.entries(expected).every(([path12, value]) => {
|
|
10003
9789
|
const actual = path12.split(".").reduce((acc, key) => {
|
|
10004
|
-
if (typeof acc !== "object" || acc === null)
|
|
10005
|
-
return void 0;
|
|
9790
|
+
if (typeof acc !== "object" || acc === null) return void 0;
|
|
10006
9791
|
return acc[key];
|
|
10007
9792
|
}, metadata);
|
|
10008
9793
|
return actual === value;
|
|
@@ -10012,27 +9797,20 @@ _Context:_ ${sessionContext}`;
|
|
|
10012
9797
|
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
9798
|
}
|
|
10014
9799
|
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`;
|
|
9800
|
+
if (token === "apis") return "api";
|
|
9801
|
+
if (token === "ids") return "id";
|
|
9802
|
+
if (token === "does") return token;
|
|
9803
|
+
if (token.length > 4 && token.endsWith("ies")) return `${token.slice(0, -3)}y`;
|
|
10023
9804
|
if (token.length > 3 && token.endsWith("s") && !token.endsWith("ss") && !token.endsWith("us") && !token.endsWith("is") && !token.endsWith("ps")) {
|
|
10024
9805
|
return token.slice(0, -1);
|
|
10025
9806
|
}
|
|
10026
9807
|
return token;
|
|
10027
9808
|
}
|
|
10028
9809
|
keywordOverlap(a, b) {
|
|
10029
|
-
if (a.length === 0 || b.length === 0)
|
|
10030
|
-
return 0;
|
|
9810
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
10031
9811
|
const bs = new Set(b);
|
|
10032
9812
|
let hit = 0;
|
|
10033
|
-
for (const t of a)
|
|
10034
|
-
if (bs.has(t))
|
|
10035
|
-
hit += 1;
|
|
9813
|
+
for (const t of a) if (bs.has(t)) hit += 1;
|
|
10036
9814
|
return hit / a.length;
|
|
10037
9815
|
}
|
|
10038
9816
|
estimateTokens(text) {
|
|
@@ -10053,8 +9831,7 @@ function uniqueEntityStartNodes(candidates) {
|
|
|
10053
9831
|
const seen = /* @__PURE__ */ new Set();
|
|
10054
9832
|
const nodes = [];
|
|
10055
9833
|
for (const candidate of candidates) {
|
|
10056
|
-
if (!candidate.entityId || seen.has(candidate.entityId))
|
|
10057
|
-
continue;
|
|
9834
|
+
if (!candidate.entityId || seen.has(candidate.entityId)) continue;
|
|
10058
9835
|
seen.add(candidate.entityId);
|
|
10059
9836
|
nodes.push({ entityId: candidate.entityId, title: candidate.text });
|
|
10060
9837
|
}
|
|
@@ -10078,16 +9855,14 @@ function graphPathScore(path12, hopPenalty) {
|
|
|
10078
9855
|
return Math.max(0.05, base - hopPenalty * Math.max(0, path12.hops - 1));
|
|
10079
9856
|
}
|
|
10080
9857
|
function clampGraphHops(maxHops) {
|
|
10081
|
-
if (!Number.isFinite(maxHops))
|
|
10082
|
-
return 2;
|
|
9858
|
+
if (!Number.isFinite(maxHops)) return 2;
|
|
10083
9859
|
return Math.min(Math.max(0, Math.trunc(maxHops)), 2);
|
|
10084
9860
|
}
|
|
10085
9861
|
function mergeGraphPaths(existing, incoming) {
|
|
10086
9862
|
const byKey = /* @__PURE__ */ new Map();
|
|
10087
9863
|
for (const path12 of [...existing, ...incoming]) {
|
|
10088
9864
|
const key = [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("\0");
|
|
10089
|
-
if (!byKey.has(key))
|
|
10090
|
-
byKey.set(key, path12);
|
|
9865
|
+
if (!byKey.has(key)) byKey.set(key, path12);
|
|
10091
9866
|
}
|
|
10092
9867
|
return [...byKey.values()].sort((a, b) => a.hops - b.hops || compareStable(graphPathSignature(a), graphPathSignature(b))).slice(0, 3);
|
|
10093
9868
|
}
|
|
@@ -10095,10 +9870,8 @@ function graphPathSignature(path12) {
|
|
|
10095
9870
|
return [path12.startEntityId, path12.targetType, path12.targetId, path12.hops, ...path12.relationPath].join("|");
|
|
10096
9871
|
}
|
|
10097
9872
|
function compareStable(a, b) {
|
|
10098
|
-
if (a < b)
|
|
10099
|
-
|
|
10100
|
-
if (a > b)
|
|
10101
|
-
return 1;
|
|
9873
|
+
if (a < b) return -1;
|
|
9874
|
+
if (a > b) return 1;
|
|
10102
9875
|
return 0;
|
|
10103
9876
|
}
|
|
10104
9877
|
function createRetriever(eventStore, vectorStore, embedder, matcher, sharedOptions) {
|
|
@@ -10110,6 +9883,7 @@ var RetrievalAnalyticsService = class {
|
|
|
10110
9883
|
constructor(deps) {
|
|
10111
9884
|
this.deps = deps;
|
|
10112
9885
|
}
|
|
9886
|
+
deps;
|
|
10113
9887
|
async getRetrievalTraceStats() {
|
|
10114
9888
|
await this.deps.initialize();
|
|
10115
9889
|
return this.deps.retrievalStore.getRetrievalTraceStats();
|
|
@@ -10187,6 +9961,7 @@ var RetrievalDisclosureService = class {
|
|
|
10187
9961
|
constructor(deps) {
|
|
10188
9962
|
this.deps = deps;
|
|
10189
9963
|
}
|
|
9964
|
+
deps;
|
|
10190
9965
|
async search(query, options) {
|
|
10191
9966
|
const result = await this.deps.retrievalOrchestrator.retrieveMemories(query, options);
|
|
10192
9967
|
const debugByEventId = this.buildDebugIndex(result);
|
|
@@ -10216,8 +9991,7 @@ var RetrievalDisclosureService = class {
|
|
|
10216
9991
|
return this.expandShared(parsedId.entryId);
|
|
10217
9992
|
}
|
|
10218
9993
|
const targetEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
10219
|
-
if (!targetEvent)
|
|
10220
|
-
return null;
|
|
9994
|
+
if (!targetEvent) return null;
|
|
10221
9995
|
const windowSize = Math.max(0, options?.windowSize ?? 3);
|
|
10222
9996
|
const sessionEvents = (await this.deps.eventStore.getSessionEvents(targetEvent.sessionId)).slice().sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
10223
9997
|
const targetIndex = sessionEvents.findIndex((event) => event.id === targetEvent.id);
|
|
@@ -10241,8 +10015,7 @@ var RetrievalDisclosureService = class {
|
|
|
10241
10015
|
return this.sourceShared(parsedId.entryId);
|
|
10242
10016
|
}
|
|
10243
10017
|
const rawEvent = await this.deps.eventStore.getEvent(parsedId.eventId);
|
|
10244
|
-
if (!rawEvent)
|
|
10245
|
-
return null;
|
|
10018
|
+
if (!rawEvent) return null;
|
|
10246
10019
|
return {
|
|
10247
10020
|
...this.sourceReferenceForEvent(rawEvent),
|
|
10248
10021
|
rawEvents: [rawEvent],
|
|
@@ -10251,8 +10024,7 @@ var RetrievalDisclosureService = class {
|
|
|
10251
10024
|
}
|
|
10252
10025
|
async expandShared(entryId) {
|
|
10253
10026
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
10254
|
-
if (!entry)
|
|
10255
|
-
return null;
|
|
10027
|
+
if (!entry) return null;
|
|
10256
10028
|
return {
|
|
10257
10029
|
target: this.sharedToEnvelope(entry),
|
|
10258
10030
|
surroundingFacts: [],
|
|
@@ -10263,8 +10035,7 @@ var RetrievalDisclosureService = class {
|
|
|
10263
10035
|
}
|
|
10264
10036
|
async sourceShared(entryId) {
|
|
10265
10037
|
const entry = await this.deps.sharedStore?.get(entryId);
|
|
10266
|
-
if (!entry)
|
|
10267
|
-
return null;
|
|
10038
|
+
if (!entry) return null;
|
|
10268
10039
|
const sourceReference = this.sourceReferenceForShared(entry);
|
|
10269
10040
|
return {
|
|
10270
10041
|
...sourceReference,
|
|
@@ -10350,38 +10121,25 @@ var RetrievalDisclosureService = class {
|
|
|
10350
10121
|
const reasons = /* @__PURE__ */ new Set();
|
|
10351
10122
|
const usedVector = this.usedVector(result);
|
|
10352
10123
|
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");
|
|
10124
|
+
if (usedVector && (debug?.semanticScore ?? 0) > 0) reasons.add("semantic_match");
|
|
10125
|
+
if ((debug?.lexicalScore ?? 0) > 0 || usedKeyword) reasons.add("keyword_match");
|
|
10126
|
+
if ((debug?.recencyScore ?? 0) > 0) reasons.add("recent_relevance");
|
|
10127
|
+
if ((debug?.facetMatches || []).length > 0) reasons.add("facet_match");
|
|
10128
|
+
if ((debug?.graphPaths || []).length > 0) reasons.add("entity_overlap");
|
|
10129
|
+
if ((result.fallbackTrace || []).some((step) => step === "fallback:summary")) reasons.add("summary_fallback");
|
|
10130
|
+
if (memory.sessionContext) reasons.add("continuity_link");
|
|
10131
|
+
if (memory.event.eventType === "tool_observation") reasons.add("tool_followup");
|
|
10132
|
+
if (reasons.size === 0) reasons.add(usedVector ? "semantic_match" : "keyword_match");
|
|
10371
10133
|
return Array.from(reasons);
|
|
10372
10134
|
}
|
|
10373
10135
|
reasonsForContextEvent(event) {
|
|
10374
|
-
if (event.eventType === "tool_observation")
|
|
10375
|
-
|
|
10376
|
-
if (event.eventType === "session_summary")
|
|
10377
|
-
return ["summary_fallback"];
|
|
10136
|
+
if (event.eventType === "tool_observation") return ["tool_followup"];
|
|
10137
|
+
if (event.eventType === "session_summary") return ["summary_fallback"];
|
|
10378
10138
|
return ["continuity_link"];
|
|
10379
10139
|
}
|
|
10380
10140
|
resultTypeForEvent(event) {
|
|
10381
|
-
if (event.eventType === "session_summary")
|
|
10382
|
-
|
|
10383
|
-
if (event.eventType === "tool_observation")
|
|
10384
|
-
return "tool_evidence";
|
|
10141
|
+
if (event.eventType === "session_summary") return "summary";
|
|
10142
|
+
if (event.eventType === "tool_observation") return "tool_evidence";
|
|
10385
10143
|
return "source";
|
|
10386
10144
|
}
|
|
10387
10145
|
sourceReferenceForEvent(event) {
|
|
@@ -10405,21 +10163,15 @@ var RetrievalDisclosureService = class {
|
|
|
10405
10163
|
}
|
|
10406
10164
|
sourceTypeForEvent(event) {
|
|
10407
10165
|
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";
|
|
10166
|
+
if (event.eventType === "tool_observation") return "tool_output";
|
|
10167
|
+
if (typeof metadata.transcriptPath === "string") return "transcript";
|
|
10168
|
+
if (typeof metadata.importedFrom === "string") return "imported_history";
|
|
10414
10169
|
return "raw_event";
|
|
10415
10170
|
}
|
|
10416
10171
|
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";
|
|
10172
|
+
if (event.eventType === "session_summary") return "Session summary";
|
|
10173
|
+
if (event.eventType === "tool_observation") return "Tool evidence";
|
|
10174
|
+
if (event.eventType === "agent_response") return "Agent response";
|
|
10423
10175
|
return "User prompt";
|
|
10424
10176
|
}
|
|
10425
10177
|
usedVector(result) {
|
|
@@ -10445,8 +10197,7 @@ var RetrievalDisclosureService = class {
|
|
|
10445
10197
|
}
|
|
10446
10198
|
preview(content, maxLength) {
|
|
10447
10199
|
const normalized = content.replace(/\s+/g, " ").trim();
|
|
10448
|
-
if (normalized.length <= maxLength)
|
|
10449
|
-
return normalized;
|
|
10200
|
+
if (normalized.length <= maxLength) return normalized;
|
|
10450
10201
|
return `${normalized.slice(0, Math.max(0, maxLength - 3))}...`;
|
|
10451
10202
|
}
|
|
10452
10203
|
};
|
|
@@ -10475,6 +10226,7 @@ var RetrievalOrchestrator = class {
|
|
|
10475
10226
|
this.deps = deps;
|
|
10476
10227
|
this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
|
|
10477
10228
|
}
|
|
10229
|
+
deps;
|
|
10478
10230
|
/**
|
|
10479
10231
|
* Retrieve relevant memories for a query.
|
|
10480
10232
|
*/
|
|
@@ -10556,8 +10308,7 @@ var RetrievalOrchestrator = class {
|
|
|
10556
10308
|
* the heavier retrieval/vector initialization path for prompt telemetry.
|
|
10557
10309
|
*/
|
|
10558
10310
|
async incrementMemoryAccess(eventIds) {
|
|
10559
|
-
if (eventIds.length === 0)
|
|
10560
|
-
return;
|
|
10311
|
+
if (eventIds.length === 0) return;
|
|
10561
10312
|
await this.deps.accessStore.incrementAccessCount(eventIds);
|
|
10562
10313
|
}
|
|
10563
10314
|
/**
|
|
@@ -10570,10 +10321,8 @@ var RetrievalOrchestrator = class {
|
|
|
10570
10321
|
resolveGraphHopOptions(callerOptions) {
|
|
10571
10322
|
const graphExpansion = this.deps.memoryOperationsConfig?.graphExpansion;
|
|
10572
10323
|
const durableOptions = graphExpansion?.enabled === true ? { enabled: true, maxHops: graphExpansion.maxHops } : void 0;
|
|
10573
|
-
if (!callerOptions)
|
|
10574
|
-
|
|
10575
|
-
if (!graphExpansion)
|
|
10576
|
-
return callerOptions;
|
|
10324
|
+
if (!callerOptions) return durableOptions;
|
|
10325
|
+
if (!graphExpansion) return callerOptions;
|
|
10577
10326
|
if (graphExpansion.enabled !== true) {
|
|
10578
10327
|
return {
|
|
10579
10328
|
...callerOptions,
|
|
@@ -10633,12 +10382,10 @@ var RetrievalOrchestrator = class {
|
|
|
10633
10382
|
const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? "");
|
|
10634
10383
|
const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? "");
|
|
10635
10384
|
const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
|
|
10636
|
-
if (!allFinite)
|
|
10637
|
-
return void 0;
|
|
10385
|
+
if (!allFinite) return void 0;
|
|
10638
10386
|
const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
|
|
10639
10387
|
const total = semantic + lexical + recency;
|
|
10640
|
-
if (!nonNegative || total <= 0)
|
|
10641
|
-
return void 0;
|
|
10388
|
+
if (!nonNegative || total <= 0) return void 0;
|
|
10642
10389
|
return {
|
|
10643
10390
|
semantic: semantic / total,
|
|
10644
10391
|
lexical: lexical / total,
|
|
@@ -10647,17 +10394,14 @@ var RetrievalOrchestrator = class {
|
|
|
10647
10394
|
}
|
|
10648
10395
|
async getRerankWeights(adaptive) {
|
|
10649
10396
|
const configured = this.getConfiguredRerankWeights();
|
|
10650
|
-
if (configured)
|
|
10651
|
-
|
|
10652
|
-
if (adaptive)
|
|
10653
|
-
return this.getAdaptiveRerankWeights();
|
|
10397
|
+
if (configured) return configured;
|
|
10398
|
+
if (adaptive) return this.getAdaptiveRerankWeights();
|
|
10654
10399
|
return void 0;
|
|
10655
10400
|
}
|
|
10656
10401
|
async getAdaptiveRerankWeights() {
|
|
10657
10402
|
try {
|
|
10658
10403
|
const stats = await this.deps.traceStore.getHelpfulnessStats();
|
|
10659
|
-
if (stats.totalEvaluated < 20)
|
|
10660
|
-
return void 0;
|
|
10404
|
+
if (stats.totalEvaluated < 20) return void 0;
|
|
10661
10405
|
let semantic = 0.7;
|
|
10662
10406
|
let lexical = 0.2;
|
|
10663
10407
|
let recency = 0.1;
|
|
@@ -10679,11 +10423,9 @@ var RetrievalOrchestrator = class {
|
|
|
10679
10423
|
}
|
|
10680
10424
|
}
|
|
10681
10425
|
async rewriteQueryIntent(query) {
|
|
10682
|
-
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1")
|
|
10683
|
-
return null;
|
|
10426
|
+
if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== "1") return null;
|
|
10684
10427
|
const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
|
|
10685
|
-
if (!apiUrl)
|
|
10686
|
-
return null;
|
|
10428
|
+
if (!apiUrl) return null;
|
|
10687
10429
|
const controller = new AbortController();
|
|
10688
10430
|
const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5e3);
|
|
10689
10431
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -10709,11 +10451,9 @@ var RetrievalOrchestrator = class {
|
|
|
10709
10451
|
signal: controller.signal
|
|
10710
10452
|
});
|
|
10711
10453
|
const text = (await res.text()).trim();
|
|
10712
|
-
if (!text)
|
|
10713
|
-
return null;
|
|
10454
|
+
if (!text) return null;
|
|
10714
10455
|
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;
|
|
10456
|
+
if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
|
|
10717
10457
|
return oneLine;
|
|
10718
10458
|
} catch {
|
|
10719
10459
|
return null;
|
|
@@ -10855,8 +10595,7 @@ function createMemoryEngineServices(options) {
|
|
|
10855
10595
|
};
|
|
10856
10596
|
}
|
|
10857
10597
|
function shouldEnablePerspectiveDeriver(options) {
|
|
10858
|
-
if (options.readOnly)
|
|
10859
|
-
return false;
|
|
10598
|
+
if (options.readOnly) return false;
|
|
10860
10599
|
const perspectiveMemory = options.memoryOperationsConfig?.perspectiveMemory;
|
|
10861
10600
|
return perspectiveMemory?.enabled === true && perspectiveMemory.deriver?.enabled === true;
|
|
10862
10601
|
}
|
|
@@ -10890,6 +10629,9 @@ var GraduationWorker = class {
|
|
|
10890
10629
|
this.graduation = graduation;
|
|
10891
10630
|
this.config = config;
|
|
10892
10631
|
}
|
|
10632
|
+
eventStore;
|
|
10633
|
+
graduation;
|
|
10634
|
+
config;
|
|
10893
10635
|
running = false;
|
|
10894
10636
|
timeout = null;
|
|
10895
10637
|
lastEvaluated = /* @__PURE__ */ new Map();
|
|
@@ -10897,8 +10639,7 @@ var GraduationWorker = class {
|
|
|
10897
10639
|
* Start the graduation worker
|
|
10898
10640
|
*/
|
|
10899
10641
|
start() {
|
|
10900
|
-
if (this.running)
|
|
10901
|
-
return;
|
|
10642
|
+
if (this.running) return;
|
|
10902
10643
|
this.running = true;
|
|
10903
10644
|
this.scheduleNext();
|
|
10904
10645
|
}
|
|
@@ -10928,8 +10669,7 @@ var GraduationWorker = class {
|
|
|
10928
10669
|
* Schedule the next graduation check
|
|
10929
10670
|
*/
|
|
10930
10671
|
scheduleNext() {
|
|
10931
|
-
if (!this.running)
|
|
10932
|
-
return;
|
|
10672
|
+
if (!this.running) return;
|
|
10933
10673
|
this.timeout = setTimeout(
|
|
10934
10674
|
() => this.run(),
|
|
10935
10675
|
this.config.evaluationIntervalMs
|
|
@@ -10939,8 +10679,7 @@ var GraduationWorker = class {
|
|
|
10939
10679
|
* Run graduation evaluation
|
|
10940
10680
|
*/
|
|
10941
10681
|
async run() {
|
|
10942
|
-
if (!this.running)
|
|
10943
|
-
return;
|
|
10682
|
+
if (!this.running) return;
|
|
10944
10683
|
try {
|
|
10945
10684
|
await this.runGraduation();
|
|
10946
10685
|
} catch (error) {
|
|
@@ -11004,10 +10743,8 @@ var DEFAULT_CONFIG5 = {
|
|
|
11004
10743
|
maxRetries: 3
|
|
11005
10744
|
};
|
|
11006
10745
|
function parseJsonArray(value) {
|
|
11007
|
-
if (Array.isArray(value))
|
|
11008
|
-
|
|
11009
|
-
if (typeof value !== "string" || value.trim().length === 0)
|
|
11010
|
-
return [];
|
|
10746
|
+
if (Array.isArray(value)) return value;
|
|
10747
|
+
if (typeof value !== "string" || value.trim().length === 0) return [];
|
|
11011
10748
|
try {
|
|
11012
10749
|
const parsed = JSON.parse(value);
|
|
11013
10750
|
return Array.isArray(parsed) ? parsed : [];
|
|
@@ -11037,8 +10774,7 @@ var VectorWorker = class {
|
|
|
11037
10774
|
* Start the worker polling loop
|
|
11038
10775
|
*/
|
|
11039
10776
|
start() {
|
|
11040
|
-
if (this.running)
|
|
11041
|
-
return;
|
|
10777
|
+
if (this.running) return;
|
|
11042
10778
|
this.running = true;
|
|
11043
10779
|
this.stopping = false;
|
|
11044
10780
|
this.poll();
|
|
@@ -11114,8 +10850,7 @@ var VectorWorker = class {
|
|
|
11114
10850
|
* Poll for new items
|
|
11115
10851
|
*/
|
|
11116
10852
|
async poll() {
|
|
11117
|
-
if (!this.running || this.stopping)
|
|
11118
|
-
return;
|
|
10853
|
+
if (!this.running || this.stopping) return;
|
|
11119
10854
|
try {
|
|
11120
10855
|
await this.processBatch();
|
|
11121
10856
|
} catch (error) {
|
|
@@ -11160,6 +10895,7 @@ var DefaultContentProvider = class {
|
|
|
11160
10895
|
constructor(db) {
|
|
11161
10896
|
this.db = db;
|
|
11162
10897
|
}
|
|
10898
|
+
db;
|
|
11163
10899
|
async getContent(itemKind, itemId) {
|
|
11164
10900
|
switch (itemKind) {
|
|
11165
10901
|
case "entry":
|
|
@@ -11180,8 +10916,7 @@ var DefaultContentProvider = class {
|
|
|
11180
10916
|
`SELECT title, content_json, entry_type FROM entries WHERE entry_id = ?`,
|
|
11181
10917
|
[entryId]
|
|
11182
10918
|
);
|
|
11183
|
-
if (rows.length === 0)
|
|
11184
|
-
return null;
|
|
10919
|
+
if (rows.length === 0) return null;
|
|
11185
10920
|
const row = rows[0];
|
|
11186
10921
|
const contentJson = typeof row.content_json === "string" ? JSON.parse(row.content_json) : row.content_json;
|
|
11187
10922
|
return {
|
|
@@ -11200,8 +10935,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11200
10935
|
WHERE entity_id = ? AND entity_type = 'task'`,
|
|
11201
10936
|
[taskId]
|
|
11202
10937
|
);
|
|
11203
|
-
if (rows.length === 0)
|
|
11204
|
-
return null;
|
|
10938
|
+
if (rows.length === 0) return null;
|
|
11205
10939
|
const row = rows[0];
|
|
11206
10940
|
return {
|
|
11207
10941
|
content: row.search_text || row.title,
|
|
@@ -11217,8 +10951,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11217
10951
|
`SELECT content, event_type, session_id FROM events WHERE id = ?`,
|
|
11218
10952
|
[eventId]
|
|
11219
10953
|
);
|
|
11220
|
-
if (rows.length === 0)
|
|
11221
|
-
return null;
|
|
10954
|
+
if (rows.length === 0) return null;
|
|
11222
10955
|
const row = rows[0];
|
|
11223
10956
|
return {
|
|
11224
10957
|
content: row.content,
|
|
@@ -11246,8 +10979,7 @@ ${JSON.stringify(contentJson)}`,
|
|
|
11246
10979
|
}
|
|
11247
10980
|
throw error;
|
|
11248
10981
|
}
|
|
11249
|
-
if (rows.length === 0)
|
|
11250
|
-
return null;
|
|
10982
|
+
if (rows.length === 0) return null;
|
|
11251
10983
|
const row = rows[0];
|
|
11252
10984
|
const sourceEventIds = parseJsonArray(row.source_event_ids_json);
|
|
11253
10985
|
const sourceObservationIds = parseJsonArray(row.source_observation_ids_json);
|
|
@@ -11289,8 +11021,7 @@ var VectorWorkerV2 = class {
|
|
|
11289
11021
|
* Start the worker polling loop
|
|
11290
11022
|
*/
|
|
11291
11023
|
start() {
|
|
11292
|
-
if (this.running)
|
|
11293
|
-
return;
|
|
11024
|
+
if (this.running) return;
|
|
11294
11025
|
this.running = true;
|
|
11295
11026
|
this.stopping = false;
|
|
11296
11027
|
this.poll();
|
|
@@ -11360,8 +11091,7 @@ var VectorWorkerV2 = class {
|
|
|
11360
11091
|
* Poll for new jobs
|
|
11361
11092
|
*/
|
|
11362
11093
|
async poll() {
|
|
11363
|
-
if (!this.running || this.stopping)
|
|
11364
|
-
return;
|
|
11094
|
+
if (!this.running || this.stopping) return;
|
|
11365
11095
|
try {
|
|
11366
11096
|
await this.processBatch();
|
|
11367
11097
|
} catch (error) {
|
|
@@ -11428,8 +11158,7 @@ function createMemoryRuntimeService(deps) {
|
|
|
11428
11158
|
let graduationWorker = null;
|
|
11429
11159
|
return {
|
|
11430
11160
|
async initialize() {
|
|
11431
|
-
if (initialized)
|
|
11432
|
-
return;
|
|
11161
|
+
if (initialized) return;
|
|
11433
11162
|
await deps.sqliteStore.initialize();
|
|
11434
11163
|
if (deps.lightweightMode) {
|
|
11435
11164
|
initialized = true;
|
|
@@ -11523,8 +11252,7 @@ var SharedEventStore = class {
|
|
|
11523
11252
|
this.db = createDatabase(dbPath);
|
|
11524
11253
|
}
|
|
11525
11254
|
async initialize() {
|
|
11526
|
-
if (this.initialized)
|
|
11527
|
-
return;
|
|
11255
|
+
if (this.initialized) return;
|
|
11528
11256
|
await dbRun(this.db, `
|
|
11529
11257
|
CREATE TABLE IF NOT EXISTS shared_troubleshooting (
|
|
11530
11258
|
entry_id VARCHAR PRIMARY KEY,
|
|
@@ -11614,6 +11342,10 @@ var SharedPromoter = class {
|
|
|
11614
11342
|
this.embedder = embedder;
|
|
11615
11343
|
this.config = config;
|
|
11616
11344
|
}
|
|
11345
|
+
sharedStore;
|
|
11346
|
+
sharedVectorStore;
|
|
11347
|
+
embedder;
|
|
11348
|
+
config;
|
|
11617
11349
|
/**
|
|
11618
11350
|
* Check if an entry is eligible for promotion
|
|
11619
11351
|
*/
|
|
@@ -11795,6 +11527,7 @@ var SharedStore = class {
|
|
|
11795
11527
|
constructor(sharedEventStore) {
|
|
11796
11528
|
this.sharedEventStore = sharedEventStore;
|
|
11797
11529
|
}
|
|
11530
|
+
sharedEventStore;
|
|
11798
11531
|
get db() {
|
|
11799
11532
|
return this.sharedEventStore.getDatabase();
|
|
11800
11533
|
}
|
|
@@ -11899,8 +11632,7 @@ var SharedStore = class {
|
|
|
11899
11632
|
`SELECT * FROM shared_troubleshooting WHERE entry_id = ?`,
|
|
11900
11633
|
[entryId]
|
|
11901
11634
|
);
|
|
11902
|
-
if (rows.length === 0)
|
|
11903
|
-
return null;
|
|
11635
|
+
if (rows.length === 0) return null;
|
|
11904
11636
|
return this.rowToEntry(rows[0]);
|
|
11905
11637
|
}
|
|
11906
11638
|
/**
|
|
@@ -11913,8 +11645,7 @@ var SharedStore = class {
|
|
|
11913
11645
|
WHERE source_project_hash = ? AND source_entry_id = ?`,
|
|
11914
11646
|
[projectHash, sourceEntryId]
|
|
11915
11647
|
);
|
|
11916
|
-
if (rows.length === 0)
|
|
11917
|
-
return null;
|
|
11648
|
+
if (rows.length === 0) return null;
|
|
11918
11649
|
return this.rowToEntry(rows[0]);
|
|
11919
11650
|
}
|
|
11920
11651
|
/**
|
|
@@ -12024,6 +11755,7 @@ var SharedVectorStore = class {
|
|
|
12024
11755
|
constructor(dbPath) {
|
|
12025
11756
|
this.dbPath = dbPath;
|
|
12026
11757
|
}
|
|
11758
|
+
dbPath;
|
|
12027
11759
|
db = null;
|
|
12028
11760
|
table = null;
|
|
12029
11761
|
tableName = "shared_knowledge";
|
|
@@ -12031,8 +11763,7 @@ var SharedVectorStore = class {
|
|
|
12031
11763
|
* Initialize LanceDB connection
|
|
12032
11764
|
*/
|
|
12033
11765
|
async initialize() {
|
|
12034
|
-
if (this.db)
|
|
12035
|
-
return;
|
|
11766
|
+
if (this.db) return;
|
|
12036
11767
|
this.db = await lancedb2.connect(this.dbPath);
|
|
12037
11768
|
try {
|
|
12038
11769
|
const tables = await this.db.tableNames();
|
|
@@ -12074,8 +11805,7 @@ var SharedVectorStore = class {
|
|
|
12074
11805
|
* Add multiple records in batch
|
|
12075
11806
|
*/
|
|
12076
11807
|
async upsertBatch(records) {
|
|
12077
|
-
if (records.length === 0)
|
|
12078
|
-
return;
|
|
11808
|
+
if (records.length === 0) return;
|
|
12079
11809
|
await this.initialize();
|
|
12080
11810
|
if (!this.db) {
|
|
12081
11811
|
throw new Error("Database not initialized");
|
|
@@ -12136,24 +11866,21 @@ var SharedVectorStore = class {
|
|
|
12136
11866
|
* Delete vector by entry ID
|
|
12137
11867
|
*/
|
|
12138
11868
|
async delete(entryId) {
|
|
12139
|
-
if (!this.table)
|
|
12140
|
-
return;
|
|
11869
|
+
if (!this.table) return;
|
|
12141
11870
|
await this.table.delete(`entryId = '${entryId}'`);
|
|
12142
11871
|
}
|
|
12143
11872
|
/**
|
|
12144
11873
|
* Get total count
|
|
12145
11874
|
*/
|
|
12146
11875
|
async count() {
|
|
12147
|
-
if (!this.table)
|
|
12148
|
-
return 0;
|
|
11876
|
+
if (!this.table) return 0;
|
|
12149
11877
|
return this.table.countRows();
|
|
12150
11878
|
}
|
|
12151
11879
|
/**
|
|
12152
11880
|
* Check if vector exists for entry
|
|
12153
11881
|
*/
|
|
12154
11882
|
async exists(entryId) {
|
|
12155
|
-
if (!this.table)
|
|
12156
|
-
return false;
|
|
11883
|
+
if (!this.table) return false;
|
|
12157
11884
|
try {
|
|
12158
11885
|
const results = await this.table.search([]).where(`entryId = '${entryId}'`).limit(1).toArray();
|
|
12159
11886
|
return results.length > 0;
|
|
@@ -12171,6 +11898,7 @@ var SharedMemoryServices = class {
|
|
|
12171
11898
|
constructor(options) {
|
|
12172
11899
|
this.options = options;
|
|
12173
11900
|
}
|
|
11901
|
+
options;
|
|
12174
11902
|
sharedEventStore = null;
|
|
12175
11903
|
sharedStore = null;
|
|
12176
11904
|
sharedVectorStore = null;
|
|
@@ -12195,8 +11923,7 @@ var SharedMemoryServices = class {
|
|
|
12195
11923
|
return this.options.config?.sharedStoragePath ? this.options.expandPath(this.options.config.sharedStoragePath) : this.options.defaultSharedStoragePath;
|
|
12196
11924
|
}
|
|
12197
11925
|
async initialize() {
|
|
12198
|
-
if (this.options.config?.enabled === false || this.options.readOnly)
|
|
12199
|
-
return;
|
|
11926
|
+
if (this.options.config?.enabled === false || this.options.readOnly) return;
|
|
12200
11927
|
const sharedPath = this.getSharedStoragePath();
|
|
12201
11928
|
this.ensureDirectory(sharedPath, { allowCreate: true });
|
|
12202
11929
|
const store = await this.openStore(sharedPath);
|
|
@@ -12213,14 +11940,11 @@ var SharedMemoryServices = class {
|
|
|
12213
11940
|
this.options.retriever.setSharedStores(store, this.sharedVectorStore);
|
|
12214
11941
|
}
|
|
12215
11942
|
async ensureStoreForRead() {
|
|
12216
|
-
if (this.options.config?.enabled === false)
|
|
12217
|
-
|
|
12218
|
-
if (this.sharedStore)
|
|
12219
|
-
return this.sharedStore;
|
|
11943
|
+
if (this.options.config?.enabled === false) return null;
|
|
11944
|
+
if (this.sharedStore) return this.sharedStore;
|
|
12220
11945
|
const sharedPath = this.getSharedStoragePath();
|
|
12221
11946
|
const directoryReady = this.ensureDirectory(sharedPath, { allowCreate: !this.options.readOnly });
|
|
12222
|
-
if (!directoryReady)
|
|
12223
|
-
return null;
|
|
11947
|
+
if (!directoryReady) return null;
|
|
12224
11948
|
return this.openStore(sharedPath);
|
|
12225
11949
|
}
|
|
12226
11950
|
async getEntryForDisclosure(entryId) {
|
|
@@ -12237,13 +11961,11 @@ var SharedMemoryServices = class {
|
|
|
12237
11961
|
return this.sharedPromoter.promoteEntry(entry, projectHash);
|
|
12238
11962
|
}
|
|
12239
11963
|
async getStats() {
|
|
12240
|
-
if (!this.sharedStore)
|
|
12241
|
-
return null;
|
|
11964
|
+
if (!this.sharedStore) return null;
|
|
12242
11965
|
return this.sharedStore.getStats();
|
|
12243
11966
|
}
|
|
12244
11967
|
async search(query, options) {
|
|
12245
|
-
if (!this.sharedStore)
|
|
12246
|
-
return [];
|
|
11968
|
+
if (!this.sharedStore) return [];
|
|
12247
11969
|
return this.sharedStore.search(query, options);
|
|
12248
11970
|
}
|
|
12249
11971
|
async close() {
|
|
@@ -12260,8 +11982,7 @@ var SharedMemoryServices = class {
|
|
|
12260
11982
|
this.openStorePromise = null;
|
|
12261
11983
|
}
|
|
12262
11984
|
async openStore(sharedPath) {
|
|
12263
|
-
if (this.sharedStore)
|
|
12264
|
-
return this.sharedStore;
|
|
11985
|
+
if (this.sharedStore) return this.sharedStore;
|
|
12265
11986
|
if (!this.openStorePromise) {
|
|
12266
11987
|
this.openStorePromise = this.createOpenStorePromise(sharedPath);
|
|
12267
11988
|
}
|
|
@@ -12285,10 +12006,8 @@ var SharedMemoryServices = class {
|
|
|
12285
12006
|
return this.sharedStore;
|
|
12286
12007
|
}
|
|
12287
12008
|
ensureDirectory(sharedPath, options) {
|
|
12288
|
-
if (this.factories.existsSync(sharedPath))
|
|
12289
|
-
|
|
12290
|
-
if (!options.allowCreate)
|
|
12291
|
-
return false;
|
|
12009
|
+
if (this.factories.existsSync(sharedPath)) return true;
|
|
12010
|
+
if (!options.allowCreate) return false;
|
|
12292
12011
|
this.factories.mkdirSync(sharedPath);
|
|
12293
12012
|
return true;
|
|
12294
12013
|
}
|
|
@@ -13144,20 +12863,15 @@ var IMPORTANT_BASH_KEYWORDS = [
|
|
|
13144
12863
|
"successfully created"
|
|
13145
12864
|
];
|
|
13146
12865
|
function isBashSignificant(output, response) {
|
|
13147
|
-
if (response?.stderr && response.stderr.trim().length > 20)
|
|
13148
|
-
return true;
|
|
12866
|
+
if (response?.stderr && response.stderr.trim().length > 20) return true;
|
|
13149
12867
|
const lower = output.toLowerCase();
|
|
13150
|
-
if (IMPORTANT_BASH_KEYWORDS.some((kw) => lower.includes(kw)))
|
|
13151
|
-
return true;
|
|
12868
|
+
if (IMPORTANT_BASH_KEYWORDS.some((kw) => lower.includes(kw))) return true;
|
|
13152
12869
|
return output.trim().length > 2e3;
|
|
13153
12870
|
}
|
|
13154
12871
|
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;
|
|
12872
|
+
if (ALWAYS_STORE_TOOLS.has(toolName)) return true;
|
|
12873
|
+
if (toolName === "Bash") return isBashSignificant(output, response);
|
|
12874
|
+
if (response?.stderr && response.stderr.trim().length > 0) return true;
|
|
13161
12875
|
return output.trim().length >= minLen;
|
|
13162
12876
|
}
|
|
13163
12877
|
var DEFAULT_PRIVACY_CONFIG = {
|
|
@@ -13171,14 +12885,11 @@ var DEFAULT_PRIVACY_CONFIG = {
|
|
|
13171
12885
|
}
|
|
13172
12886
|
};
|
|
13173
12887
|
function extractToolOutput(response) {
|
|
13174
|
-
if (!response)
|
|
13175
|
-
return "";
|
|
12888
|
+
if (!response) return "";
|
|
13176
12889
|
if (response.stdout !== void 0) {
|
|
13177
12890
|
const parts = [];
|
|
13178
|
-
if (response.stdout)
|
|
13179
|
-
|
|
13180
|
-
if (response.stderr)
|
|
13181
|
-
parts.push(`[stderr] ${response.stderr}`);
|
|
12891
|
+
if (response.stdout) parts.push(response.stdout);
|
|
12892
|
+
if (response.stderr) parts.push(`[stderr] ${response.stderr}`);
|
|
13182
12893
|
return parts.join("\n") || "";
|
|
13183
12894
|
}
|
|
13184
12895
|
if (response.content !== void 0) {
|
|
@@ -13187,10 +12898,8 @@ function extractToolOutput(response) {
|
|
|
13187
12898
|
return JSON.stringify(response);
|
|
13188
12899
|
}
|
|
13189
12900
|
function isToolSuccess(response) {
|
|
13190
|
-
if (!response)
|
|
13191
|
-
|
|
13192
|
-
if (response.interrupted)
|
|
13193
|
-
return false;
|
|
12901
|
+
if (!response) return false;
|
|
12902
|
+
if (response.interrupted) return false;
|
|
13194
12903
|
return true;
|
|
13195
12904
|
}
|
|
13196
12905
|
async function main() {
|