@remnic/core 9.3.738 → 9.3.740
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.d.ts +6 -6
- package/dist/access-boundary.js +13 -13
- package/dist/access-cli.js +35 -35
- package/dist/access-http.d.ts +6 -6
- package/dist/access-http.js +18 -18
- package/dist/access-mcp.d.ts +6 -6
- package/dist/access-mcp.js +17 -17
- package/dist/access-operations-batch.js +15 -15
- package/dist/access-operations.d.ts +6 -6
- package/dist/access-operations.js +16 -16
- package/dist/{access-service-DwQ6BIQw.d.ts → access-service-Cbk-Kv_A.d.ts} +1 -1
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +12 -12
- package/dist/access-surface-catalog.d.ts +6 -6
- package/dist/active-memory-bridge.js +3 -3
- package/dist/bootstrap.d.ts +5 -5
- package/dist/briefing.js +2 -2
- package/dist/buffer.js +2 -2
- package/dist/capabilities.d.ts +97 -1
- package/dist/capabilities.js +7 -1
- package/dist/causal-consolidation.js +4 -3
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-IFCM6OLK.js → chunk-3TUDKDTQ.js} +7 -7
- package/dist/{chunk-A7INTIC5.js → chunk-4J53ZVPQ.js} +3 -3
- package/dist/{chunk-XYUFGHUW.js → chunk-56F6EAQ6.js} +2 -2
- package/dist/{chunk-F6OEXJQQ.js → chunk-6XG3NQRC.js} +2 -2
- package/dist/{chunk-24ZLC5QN.js → chunk-7N7S2RKF.js} +2 -2
- package/dist/{chunk-Y5OOHER4.js → chunk-7Y5KKMIP.js} +12 -11
- package/dist/chunk-7Y5KKMIP.js.map +1 -0
- package/dist/{chunk-VRBBZH4U.js → chunk-AX4TRSRE.js} +3 -3
- package/dist/{chunk-66RZ4EIT.js → chunk-BE6NEQLF.js} +3 -3
- package/dist/{chunk-YF2MMBKA.js → chunk-BJPL5WAL.js} +3 -3
- package/dist/{chunk-EO5QWINU.js → chunk-C3Z5YJSM.js} +5 -2
- package/dist/chunk-C3Z5YJSM.js.map +1 -0
- package/dist/{chunk-GEXI357K.js → chunk-C7C5WIIF.js} +2 -2
- package/dist/{chunk-L3TYGUTH.js → chunk-CMPXLMC3.js} +3 -3
- package/dist/{chunk-W2FBVBQ4.js → chunk-DBVBV2RF.js} +4 -4
- package/dist/{chunk-JQSP7YBJ.js → chunk-ELL5VYXC.js} +5 -4
- package/dist/chunk-ELL5VYXC.js.map +1 -0
- package/dist/{chunk-IQOEW5YV.js → chunk-FCQ7ZYCQ.js} +2 -2
- package/dist/{chunk-IIBFCZA7.js → chunk-FWXLKH2H.js} +3 -3
- package/dist/{chunk-RJBW4EOU.js → chunk-G7Q4D2G3.js} +74 -2
- package/dist/{chunk-RJBW4EOU.js.map → chunk-G7Q4D2G3.js.map} +1 -1
- package/dist/{chunk-WVAEIKUY.js → chunk-GPX5E36D.js} +5 -4
- package/dist/chunk-GPX5E36D.js.map +1 -0
- package/dist/{chunk-23PLOBWT.js → chunk-H3WSZWHK.js} +22 -20
- package/dist/chunk-H3WSZWHK.js.map +1 -0
- package/dist/{chunk-Q6BAA57B.js → chunk-JFCS6PQU.js} +2 -2
- package/dist/chunk-JFCS6PQU.js.map +1 -0
- package/dist/{chunk-CKHPUOAP.js → chunk-K2N6WIZM.js} +3 -3
- package/dist/{chunk-BHJAMSVC.js → chunk-LD6A7XG5.js} +7 -7
- package/dist/{chunk-AKKFHN3I.js → chunk-M4WI23X3.js} +2 -2
- package/dist/{chunk-N2O23WYA.js → chunk-M5KLYHHI.js} +2 -2
- package/dist/{chunk-TNLXCSXV.js → chunk-O4IWVWSW.js} +5 -4
- package/dist/chunk-O4IWVWSW.js.map +1 -0
- package/dist/{chunk-OQQRWPFZ.js → chunk-OS5RKJOH.js} +2 -2
- package/dist/{chunk-MAU7DFCJ.js → chunk-OT5K26NG.js} +5 -4
- package/dist/chunk-OT5K26NG.js.map +1 -0
- package/dist/{chunk-DS3FZ7GS.js → chunk-OUSOMUFV.js} +2 -2
- package/dist/{chunk-7B7IPPN5.js → chunk-OVYBENIJ.js} +3 -3
- package/dist/{chunk-5RZOFIDL.js → chunk-PI4JHLDD.js} +6 -3
- package/dist/chunk-PI4JHLDD.js.map +1 -0
- package/dist/{chunk-EU543UDC.js → chunk-QCO2QFLZ.js} +7 -7
- package/dist/chunk-QCO2QFLZ.js.map +1 -0
- package/dist/{chunk-YXOXAQ5Y.js → chunk-TQQN64J2.js} +5 -4
- package/dist/chunk-TQQN64J2.js.map +1 -0
- package/dist/{chunk-WDJCZQB4.js → chunk-UGFPGWJB.js} +2 -2
- package/dist/{chunk-75PDC7VT.js → chunk-UOVDO6TC.js} +6 -5
- package/dist/chunk-UOVDO6TC.js.map +1 -0
- package/dist/{chunk-BVG2IZOB.js → chunk-USHVHI6J.js} +7 -6
- package/dist/chunk-USHVHI6J.js.map +1 -0
- package/dist/{chunk-56LP72AD.js → chunk-UYYSOMS2.js} +4 -4
- package/dist/{chunk-EKQ3LWBM.js → chunk-VC7QELR6.js} +659 -584
- package/dist/chunk-VC7QELR6.js.map +1 -0
- package/dist/{chunk-XIQAOGAA.js → chunk-WGDE2TJP.js} +7 -6
- package/dist/chunk-WGDE2TJP.js.map +1 -0
- package/dist/{chunk-UFS7OXGL.js → chunk-WHEF76BQ.js} +5 -2
- package/dist/chunk-WHEF76BQ.js.map +1 -0
- package/dist/{chunk-QTJOORGN.js → chunk-WIMKOTNY.js} +2 -2
- package/dist/{chunk-GXTYEG7Q.js → chunk-WO22UEM3.js} +2 -2
- package/dist/{chunk-BHQQVUEQ.js → chunk-X5PMDVY4.js} +6 -5
- package/dist/{chunk-BHQQVUEQ.js.map → chunk-X5PMDVY4.js.map} +1 -1
- package/dist/{chunk-C53JDEH3.js → chunk-Y62QPRKV.js} +2 -2
- package/dist/{chunk-WFNH4UDF.js → chunk-Y6PNYJVO.js} +3 -3
- package/dist/{chunk-6YKIYQU7.js → chunk-YNHRWFAP.js} +5 -2
- package/dist/{chunk-6YKIYQU7.js.map → chunk-YNHRWFAP.js.map} +1 -1
- package/dist/{cli-BlEIWDQw.d.ts → cli-BQW2xKdb.d.ts} +2 -2
- package/dist/cli.d.ts +7 -7
- package/dist/cli.js +29 -29
- package/dist/compounding/engine.js +4 -4
- package/dist/connectors/codex-materialize-runner.js +2 -2
- package/dist/connectors/index.js +4 -3
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-CWO3LIWV.js → contradiction-scan-UERKJESC.js} +3 -3
- package/dist/day-summary.js +2 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/entity-retrieval.js +3 -3
- package/dist/explicit-capture.d.ts +5 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction.js +4 -4
- package/dist/{first-start-migration-5DXD3TF2.js → first-start-migration-GQ3UQNIL.js} +2 -2
- package/dist/index.d.ts +8 -8
- package/dist/index.js +45 -45
- package/dist/local-llm.js +2 -2
- package/dist/maintenance/memory-governance.js +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +3 -3
- package/dist/mcp-memory-inspector-app.d.ts +6 -6
- package/dist/namespaces/migrate.js +7 -7
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-toolkit.js +13 -13
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.js +7 -7
- package/dist/{orchestrator-CJZ21ZiB.d.ts → orchestrator-BOAFN_Yr.d.ts} +186 -56
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +29 -29
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.js +3 -3
- package/dist/search/index.js +3 -3
- package/dist/semantic-consolidation.js +4 -3
- package/dist/semantic-rule-promotion.js +2 -2
- package/dist/semantic-rule-verifier.js +2 -2
- package/dist/shared-context/manager.js +2 -1
- package/dist/storage.d.ts +1 -1
- package/dist/storage.js +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/{tier-stats-QID73BBB.js → tier-stats-CSKL7BDG.js} +2 -2
- package/dist/verified-recall.js +2 -2
- package/package.json +2 -2
- package/src/access-service.ts +2 -1
- package/src/capabilities.test.ts +166 -0
- package/src/capabilities.ts +267 -0
- package/src/cli/research-status-commands.ts +2 -1
- package/src/cli.ts +3 -2
- package/src/compounding/engine.ts +2 -1
- package/src/connectors/codex-marketplace.ts +2 -1
- package/src/day-summary.ts +2 -1
- package/src/embedding-fallback.ts +2 -1
- package/src/extraction.ts +3 -2
- package/src/local-llm.ts +2 -1
- package/src/maintenance/namespace-maintenance-fanout.ts +2 -1
- package/src/maintenance/namespace-planner.ts +2 -1
- package/src/operator-toolkit.ts +1 -0
- package/src/orchestration/conversation-index-coordinator.ts +344 -0
- package/src/orchestration/recall-rerank-coordinator.ts +425 -0
- package/src/orchestration/semantic-consolidation-coordinator.ts +3 -2
- package/src/orchestrator.ts +89 -598
- package/src/search/embed-helper.ts +2 -1
- package/src/search/factory.ts +2 -1
- package/src/semantic-consolidation.ts +2 -1
- package/src/shared-context/manager.ts +3 -2
- package/src/storage.ts +1 -1
- package/src/summarizer.ts +3 -2
- package/dist/chunk-23PLOBWT.js.map +0 -1
- package/dist/chunk-5RZOFIDL.js.map +0 -1
- package/dist/chunk-75PDC7VT.js.map +0 -1
- package/dist/chunk-BVG2IZOB.js.map +0 -1
- package/dist/chunk-EKQ3LWBM.js.map +0 -1
- package/dist/chunk-EO5QWINU.js.map +0 -1
- package/dist/chunk-EU543UDC.js.map +0 -1
- package/dist/chunk-JQSP7YBJ.js.map +0 -1
- package/dist/chunk-MAU7DFCJ.js.map +0 -1
- package/dist/chunk-Q6BAA57B.js.map +0 -1
- package/dist/chunk-TNLXCSXV.js.map +0 -1
- package/dist/chunk-UFS7OXGL.js.map +0 -1
- package/dist/chunk-WVAEIKUY.js.map +0 -1
- package/dist/chunk-XIQAOGAA.js.map +0 -1
- package/dist/chunk-Y5OOHER4.js.map +0 -1
- package/dist/chunk-YXOXAQ5Y.js.map +0 -1
- /package/dist/{chunk-IFCM6OLK.js.map → chunk-3TUDKDTQ.js.map} +0 -0
- /package/dist/{chunk-A7INTIC5.js.map → chunk-4J53ZVPQ.js.map} +0 -0
- /package/dist/{chunk-XYUFGHUW.js.map → chunk-56F6EAQ6.js.map} +0 -0
- /package/dist/{chunk-F6OEXJQQ.js.map → chunk-6XG3NQRC.js.map} +0 -0
- /package/dist/{chunk-24ZLC5QN.js.map → chunk-7N7S2RKF.js.map} +0 -0
- /package/dist/{chunk-VRBBZH4U.js.map → chunk-AX4TRSRE.js.map} +0 -0
- /package/dist/{chunk-66RZ4EIT.js.map → chunk-BE6NEQLF.js.map} +0 -0
- /package/dist/{chunk-YF2MMBKA.js.map → chunk-BJPL5WAL.js.map} +0 -0
- /package/dist/{chunk-GEXI357K.js.map → chunk-C7C5WIIF.js.map} +0 -0
- /package/dist/{chunk-L3TYGUTH.js.map → chunk-CMPXLMC3.js.map} +0 -0
- /package/dist/{chunk-W2FBVBQ4.js.map → chunk-DBVBV2RF.js.map} +0 -0
- /package/dist/{chunk-IQOEW5YV.js.map → chunk-FCQ7ZYCQ.js.map} +0 -0
- /package/dist/{chunk-IIBFCZA7.js.map → chunk-FWXLKH2H.js.map} +0 -0
- /package/dist/{chunk-CKHPUOAP.js.map → chunk-K2N6WIZM.js.map} +0 -0
- /package/dist/{chunk-BHJAMSVC.js.map → chunk-LD6A7XG5.js.map} +0 -0
- /package/dist/{chunk-AKKFHN3I.js.map → chunk-M4WI23X3.js.map} +0 -0
- /package/dist/{chunk-N2O23WYA.js.map → chunk-M5KLYHHI.js.map} +0 -0
- /package/dist/{chunk-OQQRWPFZ.js.map → chunk-OS5RKJOH.js.map} +0 -0
- /package/dist/{chunk-DS3FZ7GS.js.map → chunk-OUSOMUFV.js.map} +0 -0
- /package/dist/{chunk-7B7IPPN5.js.map → chunk-OVYBENIJ.js.map} +0 -0
- /package/dist/{chunk-WDJCZQB4.js.map → chunk-UGFPGWJB.js.map} +0 -0
- /package/dist/{chunk-56LP72AD.js.map → chunk-UYYSOMS2.js.map} +0 -0
- /package/dist/{chunk-QTJOORGN.js.map → chunk-WIMKOTNY.js.map} +0 -0
- /package/dist/{chunk-GXTYEG7Q.js.map → chunk-WO22UEM3.js.map} +0 -0
- /package/dist/{chunk-C53JDEH3.js.map → chunk-Y62QPRKV.js.map} +0 -0
- /package/dist/{chunk-WFNH4UDF.js.map → chunk-Y6PNYJVO.js.map} +0 -0
- /package/dist/{contradiction-scan-CWO3LIWV.js.map → contradiction-scan-UERKJESC.js.map} +0 -0
- /package/dist/{first-start-migration-5DXD3TF2.js.map → first-start-migration-GQ3UQNIL.js.map} +0 -0
- /package/dist/{tier-stats-QID73BBB.js.map → tier-stats-CSKL7BDG.js.map} +0 -0
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
} from "./chunk-OZECYVGI.js";
|
|
8
8
|
import {
|
|
9
9
|
CompressionGuidelineCoordinator
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WIMKOTNY.js";
|
|
11
11
|
import {
|
|
12
12
|
MaintenanceScheduler
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BJPL5WAL.js";
|
|
14
14
|
import {
|
|
15
15
|
runPeerProfileReasoner
|
|
16
16
|
} from "./chunk-I74SUMNI.js";
|
|
@@ -29,10 +29,10 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
CompoundingEngine,
|
|
31
31
|
defaultTierMigrationCycleBudget
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-UOVDO6TC.js";
|
|
33
33
|
import {
|
|
34
34
|
SharedContextManager
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-WHEF76BQ.js";
|
|
36
36
|
import {
|
|
37
37
|
applyTrustScoreStage,
|
|
38
38
|
buildTrustSignalsForRerank,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
} from "./chunk-UHGBNIOS.js";
|
|
64
64
|
import {
|
|
65
65
|
HourlySummarizer
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-USHVHI6J.js";
|
|
67
67
|
import {
|
|
68
68
|
buildTargetedFactRecallSection,
|
|
69
69
|
shouldRecallTargetedFactEvidence
|
|
@@ -160,7 +160,7 @@ import {
|
|
|
160
160
|
} from "./chunk-LTHVM4XN.js";
|
|
161
161
|
import {
|
|
162
162
|
ExtractionEngine
|
|
163
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-WGDE2TJP.js";
|
|
164
164
|
import {
|
|
165
165
|
parseMemoryActionEligibilityContext
|
|
166
166
|
} from "./chunk-5GSUBCZM.js";
|
|
@@ -169,7 +169,7 @@ import {
|
|
|
169
169
|
} from "./chunk-PWFWCGOO.js";
|
|
170
170
|
import {
|
|
171
171
|
LocalLlmClient
|
|
172
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-TQQN64J2.js";
|
|
173
173
|
import {
|
|
174
174
|
buildFocusedListRecallSection,
|
|
175
175
|
shouldRecallFocusedListEvidence
|
|
@@ -187,18 +187,18 @@ import {
|
|
|
187
187
|
} from "./chunk-4463LUIE.js";
|
|
188
188
|
import {
|
|
189
189
|
formatDaySummaryMemories
|
|
190
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-C3Z5YJSM.js";
|
|
191
191
|
import {
|
|
192
192
|
tryDirectAnswer
|
|
193
193
|
} from "./chunk-Q6IP2ARR.js";
|
|
194
194
|
import {
|
|
195
195
|
EmbeddingFallback
|
|
196
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-GPX5E36D.js";
|
|
197
197
|
import {
|
|
198
198
|
buildEntityRecallSection,
|
|
199
199
|
entityRecentTranscriptLookbackHours,
|
|
200
200
|
readRecentEntityTranscriptEntries
|
|
201
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-K2N6WIZM.js";
|
|
202
202
|
import {
|
|
203
203
|
RoutingRulesStore
|
|
204
204
|
} from "./chunk-WIWPSQYU.js";
|
|
@@ -208,14 +208,14 @@ import {
|
|
|
208
208
|
import {
|
|
209
209
|
compareVerifiedEpisodeResults,
|
|
210
210
|
searchVerifiedEpisodes
|
|
211
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-UGFPGWJB.js";
|
|
212
212
|
import {
|
|
213
213
|
ThreadingManager
|
|
214
214
|
} from "./chunk-QRDOSYOR.js";
|
|
215
215
|
import {
|
|
216
216
|
compareVerifiedSemanticRuleResults,
|
|
217
217
|
searchVerifiedSemanticRules
|
|
218
|
-
} from "./chunk-
|
|
218
|
+
} from "./chunk-FCQ7ZYCQ.js";
|
|
219
219
|
import {
|
|
220
220
|
searchWorkProductLedgerEntries
|
|
221
221
|
} from "./chunk-ZRWB5D4H.js";
|
|
@@ -228,14 +228,14 @@ import {
|
|
|
228
228
|
import {
|
|
229
229
|
runNamespaceMaintenanceFanout,
|
|
230
230
|
summarizeNamespaceMaintenanceHealth
|
|
231
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-O4IWVWSW.js";
|
|
232
232
|
import {
|
|
233
233
|
NamespaceCatalog,
|
|
234
234
|
planNamespaceMaintenance
|
|
235
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-X5PMDVY4.js";
|
|
236
236
|
import {
|
|
237
237
|
NamespaceStorageRouter
|
|
238
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-AX4TRSRE.js";
|
|
239
239
|
import {
|
|
240
240
|
searchHarmonicRetrieval
|
|
241
241
|
} from "./chunk-AV5ZEH4M.js";
|
|
@@ -270,7 +270,7 @@ import {
|
|
|
270
270
|
materializeAfterSemanticConsolidation,
|
|
271
271
|
parseConsolidationResponse,
|
|
272
272
|
parseOperatorAwareConsolidationResponse
|
|
273
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-PI4JHLDD.js";
|
|
274
274
|
import {
|
|
275
275
|
buildRecallQueryPolicy
|
|
276
276
|
} from "./chunk-LBJBNWS2.js";
|
|
@@ -292,7 +292,7 @@ import {
|
|
|
292
292
|
} from "./chunk-UQ7RN5HK.js";
|
|
293
293
|
import {
|
|
294
294
|
SmartBuffer
|
|
295
|
-
} from "./chunk-
|
|
295
|
+
} from "./chunk-OS5RKJOH.js";
|
|
296
296
|
import {
|
|
297
297
|
isDisagreementPrompt
|
|
298
298
|
} from "./chunk-H3FZVNRN.js";
|
|
@@ -311,7 +311,7 @@ import {
|
|
|
311
311
|
clusterByKey,
|
|
312
312
|
createCorrectionService,
|
|
313
313
|
detectPassiveCorrections
|
|
314
|
-
} from "./chunk-
|
|
314
|
+
} from "./chunk-Y6PNYJVO.js";
|
|
315
315
|
import {
|
|
316
316
|
listTrustZoneRecords,
|
|
317
317
|
searchTrustZoneRecords
|
|
@@ -333,14 +333,14 @@ import {
|
|
|
333
333
|
resolveNamespaceFromStorageDir,
|
|
334
334
|
resolveScopePlan,
|
|
335
335
|
resolveScopeProfilePlan
|
|
336
|
-
} from "./chunk-
|
|
336
|
+
} from "./chunk-OVYBENIJ.js";
|
|
337
337
|
import {
|
|
338
338
|
NamespaceSearchRouter
|
|
339
|
-
} from "./chunk-
|
|
339
|
+
} from "./chunk-BE6NEQLF.js";
|
|
340
340
|
import {
|
|
341
341
|
createConversationIndexRuntime,
|
|
342
342
|
createSearchBackend
|
|
343
|
-
} from "./chunk-
|
|
343
|
+
} from "./chunk-ELL5VYXC.js";
|
|
344
344
|
import {
|
|
345
345
|
NoopSearchBackend
|
|
346
346
|
} from "./chunk-CYEPCZN5.js";
|
|
@@ -363,7 +363,7 @@ import {
|
|
|
363
363
|
} from "./chunk-QDW3E4RD.js";
|
|
364
364
|
import {
|
|
365
365
|
shouldSkipImplicitExtraction
|
|
366
|
-
} from "./chunk-
|
|
366
|
+
} from "./chunk-Y62QPRKV.js";
|
|
367
367
|
import {
|
|
368
368
|
searchCausalTrajectories
|
|
369
369
|
} from "./chunk-SQNED75R.js";
|
|
@@ -376,7 +376,7 @@ import {
|
|
|
376
376
|
} from "./chunk-TBBDFYXW.js";
|
|
377
377
|
import {
|
|
378
378
|
buildChainFollowupGenerator
|
|
379
|
-
} from "./chunk-
|
|
379
|
+
} from "./chunk-6XG3NQRC.js";
|
|
380
380
|
import {
|
|
381
381
|
ContentHashIndex,
|
|
382
382
|
StorageManager,
|
|
@@ -384,7 +384,7 @@ import {
|
|
|
384
384
|
fingerprintEntityStructuredFacts,
|
|
385
385
|
normalizeAttributePairs,
|
|
386
386
|
parseEntityFile
|
|
387
|
-
} from "./chunk-
|
|
387
|
+
} from "./chunk-JFCS6PQU.js";
|
|
388
388
|
import {
|
|
389
389
|
buildRetiredFactTombstoneInputs
|
|
390
390
|
} from "./chunk-L2B3EE7B.js";
|
|
@@ -465,7 +465,7 @@ import {
|
|
|
465
465
|
defaultNamespaceForPrincipal,
|
|
466
466
|
recallNamespacesForPrincipal,
|
|
467
467
|
resolvePrincipal
|
|
468
|
-
} from "./chunk-
|
|
468
|
+
} from "./chunk-OUSOMUFV.js";
|
|
469
469
|
import {
|
|
470
470
|
isSafeRouteNamespace,
|
|
471
471
|
selectRouteRule
|
|
@@ -474,6 +474,7 @@ import {
|
|
|
474
474
|
resolveCapabilities,
|
|
475
475
|
resolveCompressionCapabilities,
|
|
476
476
|
resolveConsolidationCapabilities,
|
|
477
|
+
resolveConversationContextCapabilities,
|
|
477
478
|
resolveCreationMemoryCapabilities,
|
|
478
479
|
resolveEvalCapabilities,
|
|
479
480
|
resolveGraphConstructionCapabilities,
|
|
@@ -483,12 +484,14 @@ import {
|
|
|
483
484
|
resolveMemoryLifecycleCapabilities,
|
|
484
485
|
resolveNamespaceCapabilities,
|
|
485
486
|
resolveObjectiveStateCapabilities,
|
|
487
|
+
resolvePipelineProcessingCapabilities,
|
|
486
488
|
resolvePresentationCapabilities,
|
|
487
489
|
resolveQmdCapabilities,
|
|
488
490
|
resolveRecallAuxiliaryCapabilities,
|
|
491
|
+
resolveRecallEnhancementCapabilities,
|
|
489
492
|
resolveSecurityCapabilities,
|
|
490
493
|
resolveUtilityLearningCapabilities
|
|
491
|
-
} from "./chunk-
|
|
494
|
+
} from "./chunk-G7Q4D2G3.js";
|
|
492
495
|
import {
|
|
493
496
|
sanitizeMemoryContent
|
|
494
497
|
} from "./chunk-5GKPFL3S.js";
|
|
@@ -509,14 +512,14 @@ import {
|
|
|
509
512
|
} from "./chunk-PVGDJXVK.js";
|
|
510
513
|
|
|
511
514
|
// src/orchestrator.ts
|
|
512
|
-
import
|
|
515
|
+
import path5 from "path";
|
|
513
516
|
import os2 from "os";
|
|
514
517
|
import { createHash as createHash2, randomBytes } from "crypto";
|
|
515
518
|
import { existsSync, readFileSync } from "fs";
|
|
516
519
|
import {
|
|
517
520
|
lstat,
|
|
518
521
|
mkdir as mkdir3,
|
|
519
|
-
readdir,
|
|
522
|
+
readdir as readdir2,
|
|
520
523
|
readFile as readFile2,
|
|
521
524
|
realpath,
|
|
522
525
|
stat,
|
|
@@ -960,7 +963,7 @@ var SemanticConsolidationCoordinator = class {
|
|
|
960
963
|
for (const cluster of clusters) {
|
|
961
964
|
let canonicalWriteCompleted = false;
|
|
962
965
|
try {
|
|
963
|
-
const operatorAwareEnabled = this.config.
|
|
966
|
+
const operatorAwareEnabled = resolveConversationContextCapabilities(this.config).operatorAwareConsolidation === true;
|
|
964
967
|
let prompt = operatorAwareEnabled ? buildOperatorAwareConsolidationPrompt(cluster) : buildConsolidationPrompt(cluster);
|
|
965
968
|
if (extensionsBlock.length > 0) {
|
|
966
969
|
prompt += "\n\n" + extensionsBlock;
|
|
@@ -1106,7 +1109,7 @@ var SemanticConsolidationCoordinator = class {
|
|
|
1106
1109
|
`[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
1107
1110
|
);
|
|
1108
1111
|
}
|
|
1109
|
-
if (this.config.
|
|
1112
|
+
if (resolveConversationContextCapabilities(this.config).peerProfileReasoner) {
|
|
1110
1113
|
try {
|
|
1111
1114
|
const peerLlm = new FallbackLlmClient(
|
|
1112
1115
|
this.config.gatewayConfig,
|
|
@@ -1942,6 +1945,452 @@ ${lines.join("\n\n")}`;
|
|
|
1942
1945
|
}
|
|
1943
1946
|
};
|
|
1944
1947
|
|
|
1948
|
+
// src/orchestration/conversation-index-coordinator.ts
|
|
1949
|
+
import { readdir } from "fs/promises";
|
|
1950
|
+
import path3 from "path";
|
|
1951
|
+
var ConversationIndexCoordinator = class {
|
|
1952
|
+
config;
|
|
1953
|
+
getTranscript;
|
|
1954
|
+
getBackend;
|
|
1955
|
+
indexDir;
|
|
1956
|
+
lastUpdateAtMs = /* @__PURE__ */ new Map();
|
|
1957
|
+
constructor(options) {
|
|
1958
|
+
this.config = options.config;
|
|
1959
|
+
this.getTranscript = options.getTranscript;
|
|
1960
|
+
this.getBackend = options.getBackend;
|
|
1961
|
+
this.indexDir = options.indexDir;
|
|
1962
|
+
}
|
|
1963
|
+
/** Semantic recall over past-conversation chunks (fail-open: empty on miss). */
|
|
1964
|
+
async search(retrievalQuery, topK) {
|
|
1965
|
+
const backend = this.getBackend();
|
|
1966
|
+
if (backend) {
|
|
1967
|
+
return backend.search(retrievalQuery, topK);
|
|
1968
|
+
}
|
|
1969
|
+
return [];
|
|
1970
|
+
}
|
|
1971
|
+
/** Render conversation-recall search hits as a budgeted markdown section. */
|
|
1972
|
+
formatRecallSection(results, maxChars) {
|
|
1973
|
+
if (!Array.isArray(results) || results.length === 0) return null;
|
|
1974
|
+
const lines = ["## Semantic Recall (Past Conversations)", ""];
|
|
1975
|
+
let used = 0;
|
|
1976
|
+
for (const r of results) {
|
|
1977
|
+
if (!r?.snippet) continue;
|
|
1978
|
+
const chunk = `### ${r.path}
|
|
1979
|
+
Score: ${r.score.toFixed(3)}
|
|
1980
|
+
|
|
1981
|
+
${r.snippet.trim()}
|
|
1982
|
+
`;
|
|
1983
|
+
if (used + chunk.length > maxChars) break;
|
|
1984
|
+
lines.push(chunk);
|
|
1985
|
+
used += chunk.length;
|
|
1986
|
+
}
|
|
1987
|
+
return used > 0 ? lines.join("\n") : null;
|
|
1988
|
+
}
|
|
1989
|
+
/** Recursively count `.md` chunk documents under a directory. */
|
|
1990
|
+
async countChunkDocs(dir) {
|
|
1991
|
+
try {
|
|
1992
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
1993
|
+
let total = 0;
|
|
1994
|
+
for (const entry of entries) {
|
|
1995
|
+
const fullPath = path3.join(dir, entry.name);
|
|
1996
|
+
if (entry.isDirectory()) {
|
|
1997
|
+
total += await this.countChunkDocs(fullPath);
|
|
1998
|
+
continue;
|
|
1999
|
+
}
|
|
2000
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
2001
|
+
total += 1;
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
return total;
|
|
2005
|
+
} catch {
|
|
2006
|
+
return 0;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
/** Read recent transcript entries and chunk them for indexing. */
|
|
2010
|
+
async buildChunks(sessionKey, hours = 24) {
|
|
2011
|
+
const entries = await this.getTranscript().readRecent(hours, sessionKey);
|
|
2012
|
+
const effectiveSessionKey = sessionKey ?? "all-sessions";
|
|
2013
|
+
return chunkTranscriptEntries(effectiveSessionKey, entries, {
|
|
2014
|
+
maxChars: this.config.conversationRecallMaxChars * 2,
|
|
2015
|
+
maxTurns: Math.max(10, this.config.hourlySummariesMaxTurnsPerRun)
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
2018
|
+
async getHealth() {
|
|
2019
|
+
const chunkDocCount = await this.countChunkDocs(this.indexDir);
|
|
2020
|
+
const lastUpdateAtMs = Math.max(0, ...this.lastUpdateAtMs.values());
|
|
2021
|
+
const lastUpdateAt = lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;
|
|
2022
|
+
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
2023
|
+
return {
|
|
2024
|
+
enabled: false,
|
|
2025
|
+
backend: this.config.conversationIndexBackend,
|
|
2026
|
+
status: "disabled",
|
|
2027
|
+
chunkDocCount,
|
|
2028
|
+
lastUpdateAt
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
const backend = this.getBackend();
|
|
2032
|
+
const backendHealth = backend ? await backend.health() : {
|
|
2033
|
+
backend: this.config.conversationIndexBackend,
|
|
2034
|
+
status: "degraded"
|
|
2035
|
+
};
|
|
2036
|
+
return {
|
|
2037
|
+
enabled: true,
|
|
2038
|
+
chunkDocCount,
|
|
2039
|
+
lastUpdateAt,
|
|
2040
|
+
...backendHealth
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
async inspect() {
|
|
2044
|
+
const chunkDocCount = await this.countChunkDocs(this.indexDir);
|
|
2045
|
+
const lastUpdateAtMs = Math.max(0, ...this.lastUpdateAtMs.values());
|
|
2046
|
+
const lastUpdateAt = lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;
|
|
2047
|
+
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
2048
|
+
return {
|
|
2049
|
+
enabled: false,
|
|
2050
|
+
backend: this.config.conversationIndexBackend,
|
|
2051
|
+
status: "disabled",
|
|
2052
|
+
available: false,
|
|
2053
|
+
indexPath: this.indexDir,
|
|
2054
|
+
supportsIncrementalUpdate: true,
|
|
2055
|
+
message: "Conversation index disabled by config",
|
|
2056
|
+
metadata: {
|
|
2057
|
+
chunkCount: chunkDocCount
|
|
2058
|
+
},
|
|
2059
|
+
chunkDocCount,
|
|
2060
|
+
lastUpdateAt
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
const backend = this.getBackend();
|
|
2064
|
+
const inspection = backend ? await backend.inspect() : {
|
|
2065
|
+
backend: this.config.conversationIndexBackend,
|
|
2066
|
+
status: "degraded",
|
|
2067
|
+
available: false,
|
|
2068
|
+
indexPath: this.indexDir,
|
|
2069
|
+
supportsIncrementalUpdate: true,
|
|
2070
|
+
message: "Conversation index backend unavailable",
|
|
2071
|
+
metadata: {
|
|
2072
|
+
chunkCount: chunkDocCount
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
return {
|
|
2076
|
+
enabled: true,
|
|
2077
|
+
chunkDocCount,
|
|
2078
|
+
lastUpdateAt,
|
|
2079
|
+
...inspection
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
async update(sessionKey, hours = 24, opts) {
|
|
2083
|
+
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
2084
|
+
return { chunks: 0, skipped: true, reason: "disabled", embedded: false };
|
|
2085
|
+
}
|
|
2086
|
+
const enforceMinInterval = opts?.enforceMinInterval !== false;
|
|
2087
|
+
if (enforceMinInterval) {
|
|
2088
|
+
const minIntervalMs = Math.max(
|
|
2089
|
+
0,
|
|
2090
|
+
this.config.conversationIndexMinUpdateIntervalMs
|
|
2091
|
+
);
|
|
2092
|
+
const now = Date.now();
|
|
2093
|
+
const last = this.lastUpdateAtMs.get(sessionKey) ?? 0;
|
|
2094
|
+
const elapsed = now - last;
|
|
2095
|
+
if (minIntervalMs > 0 && elapsed < minIntervalMs) {
|
|
2096
|
+
return {
|
|
2097
|
+
chunks: 0,
|
|
2098
|
+
skipped: true,
|
|
2099
|
+
reason: "min_interval",
|
|
2100
|
+
retryAfterMs: minIntervalMs - elapsed,
|
|
2101
|
+
embedded: false
|
|
2102
|
+
};
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
const chunks = await this.buildChunks(sessionKey, hours);
|
|
2106
|
+
await writeConversationChunks(this.indexDir, chunks);
|
|
2107
|
+
const retentionCutoffMs = Number.isFinite(this.config.conversationIndexRetentionDays) && this.config.conversationIndexRetentionDays > 0 ? Date.now() - this.config.conversationIndexRetentionDays * 24 * 60 * 60 * 1e3 : void 0;
|
|
2108
|
+
await cleanupConversationChunks(
|
|
2109
|
+
this.indexDir,
|
|
2110
|
+
this.config.conversationIndexRetentionDays
|
|
2111
|
+
);
|
|
2112
|
+
const shouldEmbed = opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;
|
|
2113
|
+
let embedded = false;
|
|
2114
|
+
const backend = this.getBackend();
|
|
2115
|
+
if (backend) {
|
|
2116
|
+
const result = await backend.update(chunks, {
|
|
2117
|
+
embed: shouldEmbed,
|
|
2118
|
+
...retentionCutoffMs !== void 0 ? { retentionCutoffMs } : {}
|
|
2119
|
+
});
|
|
2120
|
+
embedded = result.embedded;
|
|
2121
|
+
}
|
|
2122
|
+
this.lastUpdateAtMs.set(sessionKey, Date.now());
|
|
2123
|
+
return { chunks: chunks.length, skipped: false, embedded };
|
|
2124
|
+
}
|
|
2125
|
+
async rebuild(sessionKey, hours = 24, opts) {
|
|
2126
|
+
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
2127
|
+
return {
|
|
2128
|
+
chunks: 0,
|
|
2129
|
+
skipped: true,
|
|
2130
|
+
reason: "disabled",
|
|
2131
|
+
embedded: false,
|
|
2132
|
+
rebuilt: false
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
const chunks = await this.buildChunks(sessionKey, hours);
|
|
2136
|
+
await writeConversationChunks(this.indexDir, chunks);
|
|
2137
|
+
await cleanupConversationChunks(
|
|
2138
|
+
this.indexDir,
|
|
2139
|
+
this.config.conversationIndexRetentionDays
|
|
2140
|
+
);
|
|
2141
|
+
const shouldEmbed = opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;
|
|
2142
|
+
let embedded = false;
|
|
2143
|
+
let rebuilt = false;
|
|
2144
|
+
const backend = this.getBackend();
|
|
2145
|
+
if (backend) {
|
|
2146
|
+
const result = await backend.rebuild(chunks, {
|
|
2147
|
+
embed: shouldEmbed
|
|
2148
|
+
});
|
|
2149
|
+
embedded = result.embedded;
|
|
2150
|
+
rebuilt = result.rebuilt;
|
|
2151
|
+
}
|
|
2152
|
+
const stamp = Date.now();
|
|
2153
|
+
if (sessionKey) {
|
|
2154
|
+
this.lastUpdateAtMs.set(sessionKey, stamp);
|
|
2155
|
+
} else {
|
|
2156
|
+
this.lastUpdateAtMs.set("__rebuild__", stamp);
|
|
2157
|
+
}
|
|
2158
|
+
return { chunks: chunks.length, skipped: false, embedded, rebuilt };
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
|
|
2162
|
+
// src/orchestration/recall-rerank-coordinator.ts
|
|
2163
|
+
var RecallRerankCoordinator = class _RecallRerankCoordinator {
|
|
2164
|
+
getConfig;
|
|
2165
|
+
getStorage;
|
|
2166
|
+
readQmdResultMemory;
|
|
2167
|
+
memoryWorthCounterCache = /* @__PURE__ */ new Map();
|
|
2168
|
+
static MEMORY_WORTH_CACHE_TTL_MS = 3e4;
|
|
2169
|
+
trustSignalCache = /* @__PURE__ */ new Map();
|
|
2170
|
+
static TRUST_SIGNAL_CACHE_TTL_MS = 3e4;
|
|
2171
|
+
constructor(options) {
|
|
2172
|
+
this.getConfig = options.getConfig;
|
|
2173
|
+
this.getStorage = options.getStorage;
|
|
2174
|
+
this.readQmdResultMemory = options.readQmdResultMemory;
|
|
2175
|
+
}
|
|
2176
|
+
async applyMemoryWorthRerank(results, namespaces) {
|
|
2177
|
+
const counters = /* @__PURE__ */ new Map();
|
|
2178
|
+
const seenNamespaces = /* @__PURE__ */ new Set();
|
|
2179
|
+
const nowMs = Date.now();
|
|
2180
|
+
for (const [key, entry] of this.memoryWorthCounterCache) {
|
|
2181
|
+
if (nowMs - entry.at >= _RecallRerankCoordinator.MEMORY_WORTH_CACHE_TTL_MS) {
|
|
2182
|
+
this.memoryWorthCounterCache.delete(key);
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
for (const ns of namespaces) {
|
|
2186
|
+
if (seenNamespaces.has(ns)) continue;
|
|
2187
|
+
seenNamespaces.add(ns);
|
|
2188
|
+
try {
|
|
2189
|
+
const cached = this.memoryWorthCounterCache.get(ns);
|
|
2190
|
+
let nsMap;
|
|
2191
|
+
if (cached && nowMs - cached.at < _RecallRerankCoordinator.MEMORY_WORTH_CACHE_TTL_MS) {
|
|
2192
|
+
nsMap = cached.counters;
|
|
2193
|
+
} else {
|
|
2194
|
+
const storage = await this.getStorage(ns);
|
|
2195
|
+
const memories = await storage.readAllMemories();
|
|
2196
|
+
nsMap = buildMemoryWorthCounterMap(memories);
|
|
2197
|
+
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
2198
|
+
}
|
|
2199
|
+
for (const [path6, c] of nsMap) counters.set(path6, c);
|
|
2200
|
+
} catch (err) {
|
|
2201
|
+
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
2202
|
+
namespace: ns,
|
|
2203
|
+
error: err.message
|
|
2204
|
+
});
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
const missing = results.filter((r) => !counters.has(r.path));
|
|
2208
|
+
if (missing.length > 0) {
|
|
2209
|
+
let reader = null;
|
|
2210
|
+
for (const ns of namespaces) {
|
|
2211
|
+
try {
|
|
2212
|
+
reader = await this.getStorage(ns);
|
|
2213
|
+
break;
|
|
2214
|
+
} catch {
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
if (reader) {
|
|
2218
|
+
for (const r of missing) {
|
|
2219
|
+
try {
|
|
2220
|
+
const memory = await this.readQmdResultMemory(r.path, reader, namespaces);
|
|
2221
|
+
if (!memory) continue;
|
|
2222
|
+
const fm = memory.frontmatter;
|
|
2223
|
+
if (fm.mw_success === void 0 && fm.mw_fail === void 0) continue;
|
|
2224
|
+
counters.set(r.path, {
|
|
2225
|
+
mw_success: fm.mw_success,
|
|
2226
|
+
mw_fail: fm.mw_fail,
|
|
2227
|
+
lastAccessed: fm.lastAccessed
|
|
2228
|
+
});
|
|
2229
|
+
} catch (err) {
|
|
2230
|
+
log.debug("memory-worth: direct path lookup failed", {
|
|
2231
|
+
path: r.path,
|
|
2232
|
+
error: err.message
|
|
2233
|
+
});
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
if (counters.size === 0) return results;
|
|
2239
|
+
const rankedInputs = results.map((r, i) => ({
|
|
2240
|
+
path: r.path,
|
|
2241
|
+
// Large positive rank score so multiplier math stays well-scaled and
|
|
2242
|
+
// we never hit zero; descending so earlier items rank higher.
|
|
2243
|
+
score: results.length - i
|
|
2244
|
+
}));
|
|
2245
|
+
const config = this.getConfig();
|
|
2246
|
+
const filtered = applyMemoryWorthFilter(rankedInputs, {
|
|
2247
|
+
counters,
|
|
2248
|
+
now: /* @__PURE__ */ new Date(),
|
|
2249
|
+
halfLifeMs: config.recallMemoryWorthHalfLifeMs > 0 ? config.recallMemoryWorthHalfLifeMs : void 0
|
|
2250
|
+
});
|
|
2251
|
+
const byPath = new Map(results.map((r) => [r.path, r]));
|
|
2252
|
+
const reordered = [];
|
|
2253
|
+
for (const item of filtered) {
|
|
2254
|
+
const original = byPath.get(item.path);
|
|
2255
|
+
if (original) reordered.push(original);
|
|
2256
|
+
}
|
|
2257
|
+
return reordered;
|
|
2258
|
+
}
|
|
2259
|
+
/**
|
|
2260
|
+
* Issue #1577 — unified TrustScore recall stage. Thin wiring over the pure
|
|
2261
|
+
* {@link applyTrustScoreStage} scorer + the {@link buildTrustSignalsForRerank}
|
|
2262
|
+
* signal builder. The stage subsumes the Memory Worth multiplier — the
|
|
2263
|
+
* orchestrator runs exactly one of the two (mutual exclusion, rule 39; the
|
|
2264
|
+
* double-multiplier test in trust-score-stage.test.ts pins it structurally).
|
|
2265
|
+
*
|
|
2266
|
+
* Returns the admitted results AND the per-path trust map (including
|
|
2267
|
+
* quarantined items) so the caller can: (a) render epistemic hedges, (b)
|
|
2268
|
+
* surface quarantined items in X-ray with a reason (rule 34), and (c) filter
|
|
2269
|
+
* quarantined paths from fallback recall branches. The trust map is a
|
|
2270
|
+
* per-recall local — never instance state — so concurrent recalls cannot
|
|
2271
|
+
* race on it (review: shared-trust-map concurrency).
|
|
2272
|
+
*/
|
|
2273
|
+
async applyTrustScoreRerank(results, namespaces) {
|
|
2274
|
+
if (results.length === 0) return { results, trustByPath: null };
|
|
2275
|
+
const config = this.getConfig();
|
|
2276
|
+
const now = /* @__PURE__ */ new Date();
|
|
2277
|
+
const halfLifeDays = config.recallMemoryWorthHalfLifeMs > 0 ? config.recallMemoryWorthHalfLifeMs / (24 * 60 * 60 * 1e3) : void 0;
|
|
2278
|
+
let fallbackReader = null;
|
|
2279
|
+
const signals = await buildTrustSignalsForRerank(
|
|
2280
|
+
results.map((r) => r.path),
|
|
2281
|
+
namespaces,
|
|
2282
|
+
{
|
|
2283
|
+
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
2284
|
+
readMemoryFrontmatter: async (path6) => {
|
|
2285
|
+
if (!fallbackReader) {
|
|
2286
|
+
for (const ns of namespaces) {
|
|
2287
|
+
try {
|
|
2288
|
+
fallbackReader = await this.getStorage(ns);
|
|
2289
|
+
break;
|
|
2290
|
+
} catch {
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (!fallbackReader) return null;
|
|
2295
|
+
const memory = await this.readQmdResultMemory(path6, fallbackReader, namespaces);
|
|
2296
|
+
return memory ? memory.frontmatter : null;
|
|
2297
|
+
}
|
|
2298
|
+
},
|
|
2299
|
+
{ cache: this.trustSignalCache, ttlMs: _RecallRerankCoordinator.TRUST_SIGNAL_CACHE_TTL_MS },
|
|
2300
|
+
now,
|
|
2301
|
+
{
|
|
2302
|
+
recencyHalfLifeDays: halfLifeDays,
|
|
2303
|
+
logDebug: (message, context) => log.debug(message, context)
|
|
2304
|
+
}
|
|
2305
|
+
);
|
|
2306
|
+
if (signals.size === 0) {
|
|
2307
|
+
return { results, trustByPath: null };
|
|
2308
|
+
}
|
|
2309
|
+
const rankedInputs = results.map((r, i) => ({ path: r.path, score: results.length - i }));
|
|
2310
|
+
const stage = applyTrustScoreStage(rankedInputs, {
|
|
2311
|
+
signals,
|
|
2312
|
+
weights: config.trustScoreWeights,
|
|
2313
|
+
minMultiplier: config.trustScoreMinMultiplier,
|
|
2314
|
+
maxMultiplier: config.trustScoreMaxMultiplier,
|
|
2315
|
+
quarantine: config.trustScoreQuarantine
|
|
2316
|
+
});
|
|
2317
|
+
const trustByPath = new Map(stage.all.map((item) => [item.path, item]));
|
|
2318
|
+
const byPath = new Map(results.map((r) => [r.path, r]));
|
|
2319
|
+
const admitted = stage.admitted.map((item) => byPath.get(item.path)).filter((r) => r !== void 0);
|
|
2320
|
+
return { results: admitted, trustByPath };
|
|
2321
|
+
}
|
|
2322
|
+
/**
|
|
2323
|
+
* Issue #1577 — apply the TrustScore stage (or, when trust is off, the Memory
|
|
2324
|
+
* Worth multiplier fallback) to ONE recall branch's results, returning the
|
|
2325
|
+
* scored results + the per-path trust map. Thin wiring over
|
|
2326
|
+
* {@link applyTrustScoreRerank} so every recall path — hot QMD, embedding
|
|
2327
|
+
* fallback, recent scan — applies the SAME multiplier gate (rule 41: a
|
|
2328
|
+
* feature gate must apply across ALL parallel recall paths). TrustScore
|
|
2329
|
+
* subsumes Memory Worth; exactly one runs (rule 39). Fail-open on lookup
|
|
2330
|
+
* errors so a storage hiccup never breaks a fallback path.
|
|
2331
|
+
*/
|
|
2332
|
+
async applyTrustScoreToBranch(results, namespaces, caps, label) {
|
|
2333
|
+
if (caps.recallTrustScore && results.length > 0) {
|
|
2334
|
+
try {
|
|
2335
|
+
return await this.applyTrustScoreRerank(results, namespaces);
|
|
2336
|
+
} catch (err) {
|
|
2337
|
+
log.debug(`trust-score stage (${label}) failed open`, {
|
|
2338
|
+
error: err.message
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2341
|
+
} else if (caps.recallMemoryWorthFilter && results.length > 0) {
|
|
2342
|
+
try {
|
|
2343
|
+
const filtered = await this.applyMemoryWorthRerank(results, namespaces);
|
|
2344
|
+
return { results: filtered, trustByPath: null };
|
|
2345
|
+
} catch (err) {
|
|
2346
|
+
log.debug(`memory-worth filter (${label}) failed open`, {
|
|
2347
|
+
error: err.message
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
return { results, trustByPath: null };
|
|
2352
|
+
}
|
|
2353
|
+
diversifyAndLimitRecallResults(sectionId, results, limit, retrievalQuery, caps = resolveCapabilities(this.getConfig())) {
|
|
2354
|
+
const safeLimit = typeof limit === "number" && Number.isFinite(limit) ? Math.max(0, Math.floor(limit)) : 0;
|
|
2355
|
+
if (!Array.isArray(results) || results.length === 0) return [];
|
|
2356
|
+
if (safeLimit === 0) return [];
|
|
2357
|
+
const boosted = caps.recallReasoningTraceBoost && typeof retrievalQuery === "string" ? applyReasoningTraceBoost(results, {
|
|
2358
|
+
enabled: true,
|
|
2359
|
+
query: retrievalQuery
|
|
2360
|
+
}) : results;
|
|
2361
|
+
const diversified = this.applyMmrToQmdResults(sectionId, boosted, caps);
|
|
2362
|
+
return diversified.slice(0, safeLimit);
|
|
2363
|
+
}
|
|
2364
|
+
/**
|
|
2365
|
+
* Apply Maximal Marginal Relevance to a section's ordered candidate list.
|
|
2366
|
+
*
|
|
2367
|
+
* Operates per-section so one redundant cluster cannot dominate a section,
|
|
2368
|
+
* and so one section's MMR pass cannot starve other sections. Returns the
|
|
2369
|
+
* input unchanged when disabled, when there are fewer than 2 candidates, or
|
|
2370
|
+
* when no budget information is available.
|
|
2371
|
+
*/
|
|
2372
|
+
applyMmrToQmdResults(sectionId, results, caps = resolveCapabilities(this.getConfig())) {
|
|
2373
|
+
if (!caps.recallMmr) return results;
|
|
2374
|
+
if (!Array.isArray(results) || results.length < 2) return results;
|
|
2375
|
+
const config = this.getConfig();
|
|
2376
|
+
const configuredTopN = config.recallMmrTopN;
|
|
2377
|
+
const topN = typeof configuredTopN === "number" && Number.isFinite(configuredTopN) ? Math.max(0, Math.floor(configuredTopN)) : 40;
|
|
2378
|
+
if (topN === 0) return results;
|
|
2379
|
+
const lambda = config.recallMmrLambda ?? 0.7;
|
|
2380
|
+
const { reordered, diversity } = reorderRecallResultsWithMmr(results, {
|
|
2381
|
+
lambda,
|
|
2382
|
+
topN
|
|
2383
|
+
});
|
|
2384
|
+
try {
|
|
2385
|
+
log.info(
|
|
2386
|
+
`recall_mmr: section=${sectionId} kept=${diversity.kept}/${diversity.considered} headReorderCount=${diversity.headReorderCount} avgSimBefore=${diversity.avgPairwiseSimBefore.toFixed(3)} avgSimAfter=${diversity.avgPairwiseSimAfter.toFixed(3)} lambda=${lambda.toFixed(2)}`
|
|
2387
|
+
);
|
|
2388
|
+
} catch {
|
|
2389
|
+
}
|
|
2390
|
+
return reordered;
|
|
2391
|
+
}
|
|
2392
|
+
};
|
|
2393
|
+
|
|
1945
2394
|
// src/maintenance/pattern-reinforcement.ts
|
|
1946
2395
|
function patternReinforcementKey(content) {
|
|
1947
2396
|
return content.trim().toLowerCase().replace(/\s+/g, " ").slice(0, 200);
|
|
@@ -2275,7 +2724,7 @@ function generateResolverDocument(taxonomy) {
|
|
|
2275
2724
|
|
|
2276
2725
|
// src/taxonomy/taxonomy-loader.ts
|
|
2277
2726
|
import { readFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
2278
|
-
import
|
|
2727
|
+
import path4 from "path";
|
|
2279
2728
|
var TAXONOMY_DIR = ".taxonomy";
|
|
2280
2729
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
2281
2730
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -2373,7 +2822,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
2373
2822
|
}
|
|
2374
2823
|
}
|
|
2375
2824
|
async function loadTaxonomy(memoryDir) {
|
|
2376
|
-
const taxonomyPath =
|
|
2825
|
+
const taxonomyPath = path4.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
2377
2826
|
let raw;
|
|
2378
2827
|
try {
|
|
2379
2828
|
raw = await readFile(taxonomyPath, "utf-8");
|
|
@@ -2423,16 +2872,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
2423
2872
|
}
|
|
2424
2873
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
2425
2874
|
validateTaxonomy(taxonomy);
|
|
2426
|
-
const dir =
|
|
2875
|
+
const dir = path4.join(memoryDir, TAXONOMY_DIR);
|
|
2427
2876
|
await mkdir2(dir, { recursive: true });
|
|
2428
|
-
const filePath =
|
|
2877
|
+
const filePath = path4.join(dir, TAXONOMY_FILE);
|
|
2429
2878
|
await writeFile2(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
2430
2879
|
}
|
|
2431
2880
|
function getTaxonomyDir(memoryDir) {
|
|
2432
|
-
return
|
|
2881
|
+
return path4.join(memoryDir, TAXONOMY_DIR);
|
|
2433
2882
|
}
|
|
2434
2883
|
function getTaxonomyFilePath(memoryDir) {
|
|
2435
|
-
return
|
|
2884
|
+
return path4.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
2436
2885
|
}
|
|
2437
2886
|
|
|
2438
2887
|
// src/wearables/registry.ts
|
|
@@ -3333,7 +3782,7 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
|
|
|
3333
3782
|
}
|
|
3334
3783
|
}
|
|
3335
3784
|
function qmdCollectionPathParts(resultPath) {
|
|
3336
|
-
if (!resultPath ||
|
|
3785
|
+
if (!resultPath || path5.isAbsolute(resultPath)) return null;
|
|
3337
3786
|
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3338
3787
|
const slashIndex = normalized.indexOf("/");
|
|
3339
3788
|
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
@@ -3346,9 +3795,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
3346
3795
|
}
|
|
3347
3796
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
3348
3797
|
const candidates = /* @__PURE__ */ new Set();
|
|
3349
|
-
const storageRoot =
|
|
3798
|
+
const storageRoot = path5.resolve(storageDir);
|
|
3350
3799
|
const addCandidate = (candidate) => {
|
|
3351
|
-
const resolved =
|
|
3800
|
+
const resolved = path5.resolve(candidate);
|
|
3352
3801
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
3353
3802
|
candidates.add(resolved);
|
|
3354
3803
|
}
|
|
@@ -3356,12 +3805,12 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
3356
3805
|
const addRelativeCandidates = (relativePath) => {
|
|
3357
3806
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3358
3807
|
if (!normalized) return;
|
|
3359
|
-
addCandidate(
|
|
3808
|
+
addCandidate(path5.join(storageRoot, normalized));
|
|
3360
3809
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
3361
|
-
addCandidate(
|
|
3810
|
+
addCandidate(path5.join(storageRoot, "facts", normalized));
|
|
3362
3811
|
}
|
|
3363
3812
|
};
|
|
3364
|
-
if (
|
|
3813
|
+
if (path5.isAbsolute(resultPath)) {
|
|
3365
3814
|
addCandidate(resultPath);
|
|
3366
3815
|
} else {
|
|
3367
3816
|
addRelativeCandidates(resultPath);
|
|
@@ -3478,7 +3927,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
|
|
|
3478
3927
|
return await Promise.race([checkedPromise, timeoutPromise]);
|
|
3479
3928
|
}
|
|
3480
3929
|
function defaultWorkspaceDir() {
|
|
3481
|
-
return
|
|
3930
|
+
return path5.join(os2.homedir(), ".openclaw", "workspace");
|
|
3482
3931
|
}
|
|
3483
3932
|
function sanitizeSessionKeyForFilename(sessionKey) {
|
|
3484
3933
|
const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -3755,11 +4204,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
3755
4204
|
return Array.from(mergedByPath.values());
|
|
3756
4205
|
}
|
|
3757
4206
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
3758
|
-
const absolutePath =
|
|
3759
|
-
const rel =
|
|
4207
|
+
const absolutePath = path5.isAbsolute(candidatePath) ? candidatePath : path5.resolve(storageDir, candidatePath);
|
|
4208
|
+
const rel = path5.relative(storageDir, absolutePath);
|
|
3760
4209
|
if (!rel || rel === ".") return null;
|
|
3761
4210
|
if (rel.startsWith("..")) return null;
|
|
3762
|
-
return rel.split(
|
|
4211
|
+
return rel.split(path5.sep).join("/");
|
|
3763
4212
|
}
|
|
3764
4213
|
function normalizeGraphActivationScore(score) {
|
|
3765
4214
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -3904,7 +4353,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
|
|
|
3904
4353
|
for (const mem of allMemsForGraph ?? []) {
|
|
3905
4354
|
const id = mem.frontmatter.id;
|
|
3906
4355
|
if (!id) continue;
|
|
3907
|
-
pathById.set(id,
|
|
4356
|
+
pathById.set(id, path5.relative(storageDir, mem.path));
|
|
3908
4357
|
}
|
|
3909
4358
|
return pathById;
|
|
3910
4359
|
}
|
|
@@ -3912,7 +4361,7 @@ function appendMemoryToGraphContext(options) {
|
|
|
3912
4361
|
if (!Array.isArray(options.allMemsForGraph)) return;
|
|
3913
4362
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
3914
4363
|
options.allMemsForGraph.push({
|
|
3915
|
-
path:
|
|
4364
|
+
path: path5.join(options.storageDir, options.memoryRelPath),
|
|
3916
4365
|
content: options.content,
|
|
3917
4366
|
frontmatter: {
|
|
3918
4367
|
id: options.memoryId,
|
|
@@ -3932,16 +4381,16 @@ function resolvePersistedMemoryRelativePath(options) {
|
|
|
3932
4381
|
const persisted = options.pathById.get(options.memoryId);
|
|
3933
4382
|
if (persisted) return persisted;
|
|
3934
4383
|
if (options.category === "correction") {
|
|
3935
|
-
return
|
|
4384
|
+
return path5.join("corrections", `${options.memoryId}.md`);
|
|
3936
4385
|
}
|
|
3937
4386
|
const subtree = categoryDirName(options.category);
|
|
3938
4387
|
const idParts = options.memoryId.split("-");
|
|
3939
4388
|
const maybeTimestamp = Number(idParts[1]);
|
|
3940
4389
|
if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
|
|
3941
4390
|
const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
|
|
3942
|
-
return
|
|
4391
|
+
return path5.join(subtree, day, `${options.memoryId}.md`);
|
|
3943
4392
|
}
|
|
3944
|
-
return
|
|
4393
|
+
return path5.join(subtree, `${options.memoryId}.md`);
|
|
3945
4394
|
}
|
|
3946
4395
|
var Orchestrator = class _Orchestrator {
|
|
3947
4396
|
storage;
|
|
@@ -4048,25 +4497,6 @@ var Orchestrator = class _Orchestrator {
|
|
|
4048
4497
|
/** Lossless Context Management engine — proactive session archive + DAG summarization. */
|
|
4049
4498
|
lcmEngine = null;
|
|
4050
4499
|
rerankCache = new RerankCache();
|
|
4051
|
-
/**
|
|
4052
|
-
* Short-TTL cache for Memory Worth counter lookups so interactive recall
|
|
4053
|
-
* doesn't trigger a full `readAllMemories` scan per query. Keyed by
|
|
4054
|
-
* namespace; the filter unions across namespaces at query time. The TTL
|
|
4055
|
-
* is intentionally short (seconds, not minutes) because counters are
|
|
4056
|
-
* mutated by `recordMemoryOutcome` asynchronously and we'd rather serve
|
|
4057
|
-
* a 30-second-stale worth score than a stable-but-wrong one.
|
|
4058
|
-
*/
|
|
4059
|
-
memoryWorthCounterCache = /* @__PURE__ */ new Map();
|
|
4060
|
-
static MEMORY_WORTH_CACHE_TTL_MS = 3e4;
|
|
4061
|
-
/**
|
|
4062
|
-
* Issue #1577 — per-namespace TrustScore signal map cache. Same TTL/shape
|
|
4063
|
-
* discipline as {@link memoryWorthCounterCache}: seconds-scale, evicted on
|
|
4064
|
-
* every call, keyed by namespace. Holds the frontmatter-derived signals
|
|
4065
|
-
* (worth, provenance, faithfulness, corroboration, recency) so the trust
|
|
4066
|
-
* stage doesn't trigger a fresh `readAllMemories` scan per query.
|
|
4067
|
-
*/
|
|
4068
|
-
trustSignalCache = /* @__PURE__ */ new Map();
|
|
4069
|
-
static TRUST_SIGNAL_CACHE_TTL_MS = 3e4;
|
|
4070
4500
|
/**
|
|
4071
4501
|
* Per-session workspace selections keyed by sessionKey.
|
|
4072
4502
|
* Set by the before_agent_start hook so recall() uses the correct
|
|
@@ -4116,13 +4546,18 @@ var Orchestrator = class _Orchestrator {
|
|
|
4116
4546
|
* to RecallResultFormatter.
|
|
4117
4547
|
*/
|
|
4118
4548
|
recallResultFormatter;
|
|
4549
|
+
/**
|
|
4550
|
+
* Issue #1526: conversation-index subsystem moved to
|
|
4551
|
+
* ConversationIndexCoordinator.
|
|
4552
|
+
*/
|
|
4553
|
+
conversationIndexCoordinator;
|
|
4554
|
+
recallRerankCoordinator;
|
|
4119
4555
|
heartbeatObserverChains = /* @__PURE__ */ new Map();
|
|
4120
4556
|
recentExtractionFingerprints = /* @__PURE__ */ new Map();
|
|
4121
4557
|
consolidationObservers = /* @__PURE__ */ new Set();
|
|
4122
4558
|
wearablesServiceInstance = null;
|
|
4123
4559
|
wearablesAutoSyncHandle = null;
|
|
4124
4560
|
lastQmdReprobeAtMs = 0;
|
|
4125
|
-
conversationIndexLastUpdateAtMs = /* @__PURE__ */ new Map();
|
|
4126
4561
|
lastFileHygieneRunAtMs = 0;
|
|
4127
4562
|
// Pattern-reinforcement cadence gate (issue #687 PR 2/4). Tracks the
|
|
4128
4563
|
// last successful run so `runPatternReinforcement` can short-circuit
|
|
@@ -4409,7 +4844,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4409
4844
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
4410
4845
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
4411
4846
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
4412
|
-
const resolvedStorageDir =
|
|
4847
|
+
const resolvedStorageDir = path5.resolve(storageDir);
|
|
4413
4848
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
4414
4849
|
if (!hints) {
|
|
4415
4850
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -4420,21 +4855,21 @@ var Orchestrator = class _Orchestrator {
|
|
|
4420
4855
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
4421
4856
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
4422
4857
|
if (!ns) return false;
|
|
4423
|
-
const resolvedStorageDir =
|
|
4424
|
-
const resolvedMemoryDir =
|
|
4858
|
+
const resolvedStorageDir = path5.resolve(storageDir);
|
|
4859
|
+
const resolvedMemoryDir = path5.resolve(this.config.memoryDir);
|
|
4425
4860
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
4426
4861
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
4427
|
-
const resolvedNamespacesDir =
|
|
4862
|
+
const resolvedNamespacesDir = path5.join(resolvedMemoryDir, "namespaces");
|
|
4428
4863
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
4429
|
-
const rawRoot =
|
|
4430
|
-
const tokenRoot =
|
|
4864
|
+
const rawRoot = path5.resolve(resolvedNamespacesDir, ns);
|
|
4865
|
+
const tokenRoot = path5.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
4431
4866
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
4432
4867
|
}
|
|
4433
4868
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
4434
|
-
if (resolvedStorageDir ===
|
|
4869
|
+
if (resolvedStorageDir === path5.resolve(this.config.memoryDir)) {
|
|
4435
4870
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
4436
4871
|
}
|
|
4437
|
-
const leaf =
|
|
4872
|
+
const leaf = path5.basename(resolvedStorageDir);
|
|
4438
4873
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
4439
4874
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
4440
4875
|
if (record.namespace === leaf) return 1;
|
|
@@ -4462,7 +4897,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4462
4897
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
4463
4898
|
if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;
|
|
4464
4899
|
this.namespaceStorageDirHintsLoaded = true;
|
|
4465
|
-
const catalogPath =
|
|
4900
|
+
const catalogPath = path5.join(this.config.memoryDir, "state", "namespaces.jsonl");
|
|
4466
4901
|
if (!existsSync(catalogPath)) return;
|
|
4467
4902
|
let body;
|
|
4468
4903
|
try {
|
|
@@ -4499,7 +4934,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4499
4934
|
if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
4500
4935
|
continue;
|
|
4501
4936
|
}
|
|
4502
|
-
const resolvedStorageDir =
|
|
4937
|
+
const resolvedStorageDir = path5.resolve(record.storageDir);
|
|
4503
4938
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
4504
4939
|
preferredByStorageDir.set(
|
|
4505
4940
|
resolvedStorageDir,
|
|
@@ -4762,8 +5197,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
4762
5197
|
constructor(config) {
|
|
4763
5198
|
this.config = config;
|
|
4764
5199
|
this.profiler = new ProfilingCollector({
|
|
4765
|
-
enabled: config.
|
|
4766
|
-
storageDir: config.profilingStorageDir ||
|
|
5200
|
+
enabled: resolvePipelineProcessingCapabilities(this.config).profiling,
|
|
5201
|
+
storageDir: config.profilingStorageDir || path5.join(config.memoryDir, "profiling"),
|
|
4767
5202
|
maxTraces: config.profilingMaxTraces
|
|
4768
5203
|
});
|
|
4769
5204
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -4829,15 +5264,26 @@ var Orchestrator = class _Orchestrator {
|
|
|
4829
5264
|
this.conversationQmd = conversationIndexRuntime.qmd;
|
|
4830
5265
|
this.conversationFaiss = conversationIndexRuntime.faiss;
|
|
4831
5266
|
this.conversationIndexBackend = conversationIndexRuntime.backend;
|
|
4832
|
-
this.sharedContext = config.
|
|
5267
|
+
this.sharedContext = resolveConversationContextCapabilities(this.config).sharedContext ? new SharedContextManager(config) : void 0;
|
|
4833
5268
|
this.compounding = resolveConsolidationCapabilities(config).compounding ? new CompoundingEngine(config, this.storage) : void 0;
|
|
4834
5269
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
4835
5270
|
this.transcript = new TranscriptManager(config);
|
|
4836
|
-
this.conversationIndexDir =
|
|
5271
|
+
this.conversationIndexDir = path5.join(
|
|
4837
5272
|
config.memoryDir,
|
|
4838
5273
|
"conversation-index",
|
|
4839
5274
|
"chunks"
|
|
4840
5275
|
);
|
|
5276
|
+
this.conversationIndexCoordinator = new ConversationIndexCoordinator({
|
|
5277
|
+
config,
|
|
5278
|
+
getTranscript: () => this.transcript,
|
|
5279
|
+
getBackend: () => this.conversationIndexBackend,
|
|
5280
|
+
indexDir: this.conversationIndexDir
|
|
5281
|
+
});
|
|
5282
|
+
this.recallRerankCoordinator = new RecallRerankCoordinator({
|
|
5283
|
+
getConfig: () => this.config,
|
|
5284
|
+
getStorage: (namespace) => this.getStorage(namespace),
|
|
5285
|
+
readQmdResultMemory: (resultPath, fallbackStorage, recallNamespaces) => this.readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces)
|
|
5286
|
+
});
|
|
4841
5287
|
this.modelRegistry = new ModelRegistry(config.memoryDir);
|
|
4842
5288
|
this.relevance = new RelevanceStore(config.memoryDir);
|
|
4843
5289
|
this.negatives = new NegativeExampleStore(config.memoryDir);
|
|
@@ -4881,7 +5327,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4881
5327
|
this.judgeDeferCounts = createDeferCountMap();
|
|
4882
5328
|
this.localLlm = new LocalLlmClient(config, this.modelRegistry);
|
|
4883
5329
|
this.localLlm.disableThinking = config.localLlmDisableThinking;
|
|
4884
|
-
this.fastLlm = config.
|
|
5330
|
+
this.fastLlm = resolvePipelineProcessingCapabilities(this.config).localLlmFast ? (() => {
|
|
4885
5331
|
const client = new LocalLlmClient(
|
|
4886
5332
|
{
|
|
4887
5333
|
...config,
|
|
@@ -4928,7 +5374,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4928
5374
|
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
4929
5375
|
});
|
|
4930
5376
|
this.threading = new ThreadingManager(
|
|
4931
|
-
|
|
5377
|
+
path5.join(config.memoryDir, "threads"),
|
|
4932
5378
|
config.threadingGapMinutes
|
|
4933
5379
|
);
|
|
4934
5380
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -4937,7 +5383,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4937
5383
|
tmtHourlyMinMemories: config.tmtHourlyMinMemories,
|
|
4938
5384
|
tmtSummaryMaxTokens: config.tmtSummaryMaxTokens
|
|
4939
5385
|
});
|
|
4940
|
-
if (config.
|
|
5386
|
+
if (resolvePipelineProcessingCapabilities(this.config).lcm) {
|
|
4941
5387
|
const summarizeFn = async (text, targetTokens, aggressive) => {
|
|
4942
5388
|
const instructionText = aggressive ? `Compress the following into bullet points. One bullet per distinct fact or decision. Maximum ${targetTokens} tokens total. No prose.` : `Compress the following conversation segment into a dense summary. Preserve: decisions made, code artifacts mentioned, errors encountered, open questions, and any commitments or next-steps. Omit: pleasantries, restatements, and anything the agent would not need to recall later. Output a single paragraph, maximum ${targetTokens} tokens.`;
|
|
4943
5389
|
try {
|
|
@@ -4976,7 +5422,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4976
5422
|
dir,
|
|
4977
5423
|
new BoxBuilder(dir, {
|
|
4978
5424
|
memoryBoxesEnabled: resolvePresentationCapabilities(this.config).memoryBoxes,
|
|
4979
|
-
traceWeaverEnabled: this.config.
|
|
5425
|
+
traceWeaverEnabled: resolvePipelineProcessingCapabilities(this.config).traceWeaver,
|
|
4980
5426
|
boxTopicShiftThreshold: this.config.boxTopicShiftThreshold,
|
|
4981
5427
|
boxTimeGapMs: this.config.boxTimeGapMs,
|
|
4982
5428
|
boxMaxMemories: this.config.boxMaxMemories,
|
|
@@ -5042,7 +5488,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
5042
5488
|
return this.routingRulesStore;
|
|
5043
5489
|
}
|
|
5044
5490
|
async loadRoutingRules() {
|
|
5045
|
-
if (!this.config.
|
|
5491
|
+
if (!resolvePipelineProcessingCapabilities(this.config).routingRules) return [];
|
|
5046
5492
|
try {
|
|
5047
5493
|
return await this.getRoutingRulesStore().read(this.routeEngineOptions());
|
|
5048
5494
|
} catch (err) {
|
|
@@ -5248,10 +5694,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
5248
5694
|
if (resolveRecallAuxiliaryCapabilities(this.config).compactionReset) {
|
|
5249
5695
|
try {
|
|
5250
5696
|
const wsDir = this.config.workspaceDir || defaultWorkspaceDir();
|
|
5251
|
-
const files = await
|
|
5697
|
+
const files = await readdir2(wsDir).catch(() => []);
|
|
5252
5698
|
for (const f of files) {
|
|
5253
5699
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
5254
|
-
const fp =
|
|
5700
|
+
const fp = path5.join(wsDir, f);
|
|
5255
5701
|
const s = await stat(fp).catch(() => null);
|
|
5256
5702
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
5257
5703
|
await unlink(fp).catch(() => {
|
|
@@ -5446,7 +5892,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
5446
5892
|
if (signal.aborted) return;
|
|
5447
5893
|
if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.config).qmdTierMigration) {
|
|
5448
5894
|
try {
|
|
5449
|
-
const { runFirstStartMigration } = await import("./first-start-migration-
|
|
5895
|
+
const { runFirstStartMigration } = await import("./first-start-migration-GQ3UQNIL.js");
|
|
5450
5896
|
const result = await runFirstStartMigration({
|
|
5451
5897
|
storage: this.storage,
|
|
5452
5898
|
config: this.config,
|
|
@@ -5760,15 +6206,15 @@ ${doc.content}` : doc.content,
|
|
|
5760
6206
|
this.lastFileHygieneRunAtMs = now;
|
|
5761
6207
|
if (hygiene.rotateEnabled) {
|
|
5762
6208
|
for (const rel of hygiene.rotatePaths) {
|
|
5763
|
-
const abs =
|
|
6209
|
+
const abs = path5.isAbsolute(rel) ? rel : path5.join(this.config.workspaceDir, rel);
|
|
5764
6210
|
try {
|
|
5765
6211
|
const raw = await readFile2(abs, "utf-8");
|
|
5766
6212
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
5767
|
-
const archiveDir =
|
|
6213
|
+
const archiveDir = path5.join(
|
|
5768
6214
|
this.config.workspaceDir,
|
|
5769
6215
|
hygiene.archiveDir
|
|
5770
6216
|
);
|
|
5771
|
-
const base =
|
|
6217
|
+
const base = path5.basename(abs);
|
|
5772
6218
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
5773
6219
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
5774
6220
|
filePath: abs,
|
|
@@ -5793,8 +6239,8 @@ ${doc.content}` : doc.content,
|
|
|
5793
6239
|
log.warn(w.message);
|
|
5794
6240
|
}
|
|
5795
6241
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
5796
|
-
const fp =
|
|
5797
|
-
await mkdir3(
|
|
6242
|
+
const fp = path5.join(this.config.memoryDir, hygiene.warningsLogPath);
|
|
6243
|
+
await mkdir3(path5.dirname(fp), { recursive: true });
|
|
5798
6244
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
5799
6245
|
const block = `
|
|
5800
6246
|
|
|
@@ -5933,16 +6379,16 @@ ${doc.content}` : doc.content,
|
|
|
5933
6379
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
5934
6380
|
if (memoryRootReal === null) break;
|
|
5935
6381
|
for (const date of datesToScan) {
|
|
5936
|
-
const dateDir =
|
|
6382
|
+
const dateDir = path5.join(storage.dir, categoryDir, date);
|
|
5937
6383
|
try {
|
|
5938
6384
|
const dirStat = await lstat(dateDir);
|
|
5939
6385
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
5940
6386
|
assertPathInsideRoot(memoryRootReal, await realpath(dateDir), dateDir);
|
|
5941
|
-
const entries = await
|
|
6387
|
+
const entries = await readdir2(dateDir, { withFileTypes: true });
|
|
5942
6388
|
for (const entry of entries) {
|
|
5943
6389
|
if (entry.isSymbolicLink()) continue;
|
|
5944
6390
|
if (!entry.name.endsWith(".md")) continue;
|
|
5945
|
-
const fullPath =
|
|
6391
|
+
const fullPath = path5.join(dateDir, entry.name);
|
|
5946
6392
|
try {
|
|
5947
6393
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
5948
6394
|
const raw = await readFile2(fullPath, "utf-8");
|
|
@@ -5964,7 +6410,7 @@ ${doc.content}` : doc.content,
|
|
|
5964
6410
|
facts.push({
|
|
5965
6411
|
path: fullPath,
|
|
5966
6412
|
frontmatter: {
|
|
5967
|
-
id: fm.id ||
|
|
6413
|
+
id: fm.id || path5.basename(entry.name, ".md"),
|
|
5968
6414
|
category: fm.category || "fact",
|
|
5969
6415
|
created,
|
|
5970
6416
|
updated: fm.updated || created,
|
|
@@ -5987,13 +6433,13 @@ ${doc.content}` : doc.content,
|
|
|
5987
6433
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
5988
6434
|
});
|
|
5989
6435
|
const hourlySummaries = [];
|
|
5990
|
-
const hourlyBaseDir =
|
|
6436
|
+
const hourlyBaseDir = path5.join(storage.dir, "summaries", "hourly");
|
|
5991
6437
|
try {
|
|
5992
|
-
const sessionKeys = await
|
|
6438
|
+
const sessionKeys = await readdir2(hourlyBaseDir, { withFileTypes: true });
|
|
5993
6439
|
for (const sk of sessionKeys) {
|
|
5994
6440
|
if (!sk.isDirectory()) continue;
|
|
5995
6441
|
for (const date of datesToScan) {
|
|
5996
|
-
const summaryFile =
|
|
6442
|
+
const summaryFile = path5.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
5997
6443
|
try {
|
|
5998
6444
|
const raw = await readFile2(summaryFile, "utf-8");
|
|
5999
6445
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -6097,7 +6543,7 @@ ${doc.content}` : doc.content,
|
|
|
6097
6543
|
}
|
|
6098
6544
|
async getLastGraphRecallSnapshot(namespace) {
|
|
6099
6545
|
const storage = await this.getStorage(namespace);
|
|
6100
|
-
const snapshotPath =
|
|
6546
|
+
const snapshotPath = path5.join(
|
|
6101
6547
|
storage.dir,
|
|
6102
6548
|
"state",
|
|
6103
6549
|
"last_graph_recall.json"
|
|
@@ -6136,7 +6582,7 @@ ${doc.content}` : doc.content,
|
|
|
6136
6582
|
}
|
|
6137
6583
|
async getLastIntentSnapshot(namespace) {
|
|
6138
6584
|
const storage = await this.getStorage(namespace);
|
|
6139
|
-
const snapshotPath =
|
|
6585
|
+
const snapshotPath = path5.join(storage.dir, "state", "last_intent.json");
|
|
6140
6586
|
try {
|
|
6141
6587
|
const raw = await readFile2(snapshotPath, "utf-8");
|
|
6142
6588
|
const parsed = JSON.parse(raw);
|
|
@@ -6169,7 +6615,7 @@ ${doc.content}` : doc.content,
|
|
|
6169
6615
|
}
|
|
6170
6616
|
async getLastQmdRecallSnapshot(namespace) {
|
|
6171
6617
|
const storage = await this.getStorage(namespace);
|
|
6172
|
-
const snapshotPath =
|
|
6618
|
+
const snapshotPath = path5.join(
|
|
6173
6619
|
storage.dir,
|
|
6174
6620
|
"state",
|
|
6175
6621
|
"last_qmd_recall.json"
|
|
@@ -6294,206 +6740,31 @@ ${doc.content}` : doc.content,
|
|
|
6294
6740
|
})
|
|
6295
6741
|
].join("\n");
|
|
6296
6742
|
}
|
|
6297
|
-
async searchConversationRecallResults(retrievalQuery, topK) {
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
return
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
`;
|
|
6314
|
-
if (used + chunk.length > maxChars) break;
|
|
6315
|
-
lines.push(chunk);
|
|
6316
|
-
used += chunk.length;
|
|
6317
|
-
}
|
|
6318
|
-
return used > 0 ? lines.join("\n") : null;
|
|
6319
|
-
}
|
|
6320
|
-
async countConversationChunkDocs(dir) {
|
|
6321
|
-
try {
|
|
6322
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
6323
|
-
let total = 0;
|
|
6324
|
-
for (const entry of entries) {
|
|
6325
|
-
const fullPath = path4.join(dir, entry.name);
|
|
6326
|
-
if (entry.isDirectory()) {
|
|
6327
|
-
total += await this.countConversationChunkDocs(fullPath);
|
|
6328
|
-
continue;
|
|
6329
|
-
}
|
|
6330
|
-
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
6331
|
-
total += 1;
|
|
6332
|
-
}
|
|
6333
|
-
}
|
|
6334
|
-
return total;
|
|
6335
|
-
} catch {
|
|
6336
|
-
return 0;
|
|
6337
|
-
}
|
|
6338
|
-
}
|
|
6339
|
-
async buildConversationIndexChunks(sessionKey, hours = 24) {
|
|
6340
|
-
const entries = await this.transcript.readRecent(hours, sessionKey);
|
|
6341
|
-
const effectiveSessionKey = sessionKey ?? "all-sessions";
|
|
6342
|
-
return chunkTranscriptEntries(effectiveSessionKey, entries, {
|
|
6343
|
-
maxChars: this.config.conversationRecallMaxChars * 2,
|
|
6344
|
-
maxTurns: Math.max(10, this.config.hourlySummariesMaxTurnsPerRun)
|
|
6345
|
-
});
|
|
6346
|
-
}
|
|
6347
|
-
async getConversationIndexHealth() {
|
|
6348
|
-
const chunkDocCount = await this.countConversationChunkDocs(
|
|
6349
|
-
this.conversationIndexDir
|
|
6350
|
-
);
|
|
6351
|
-
const lastUpdateAtMs = Math.max(
|
|
6352
|
-
0,
|
|
6353
|
-
...this.conversationIndexLastUpdateAtMs.values()
|
|
6354
|
-
);
|
|
6355
|
-
const lastUpdateAt = lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;
|
|
6356
|
-
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
6357
|
-
return {
|
|
6358
|
-
enabled: false,
|
|
6359
|
-
backend: this.config.conversationIndexBackend,
|
|
6360
|
-
status: "disabled",
|
|
6361
|
-
chunkDocCount,
|
|
6362
|
-
lastUpdateAt
|
|
6363
|
-
};
|
|
6364
|
-
}
|
|
6365
|
-
const backendHealth = this.conversationIndexBackend ? await this.conversationIndexBackend.health() : {
|
|
6366
|
-
backend: this.config.conversationIndexBackend,
|
|
6367
|
-
status: "degraded"
|
|
6368
|
-
};
|
|
6369
|
-
return {
|
|
6370
|
-
enabled: true,
|
|
6371
|
-
chunkDocCount,
|
|
6372
|
-
lastUpdateAt,
|
|
6373
|
-
...backendHealth
|
|
6374
|
-
};
|
|
6375
|
-
}
|
|
6376
|
-
async inspectConversationIndex() {
|
|
6377
|
-
const chunkDocCount = await this.countConversationChunkDocs(
|
|
6378
|
-
this.conversationIndexDir
|
|
6379
|
-
);
|
|
6380
|
-
const lastUpdateAtMs = Math.max(
|
|
6381
|
-
0,
|
|
6382
|
-
...this.conversationIndexLastUpdateAtMs.values()
|
|
6383
|
-
);
|
|
6384
|
-
const lastUpdateAt = lastUpdateAtMs > 0 ? new Date(lastUpdateAtMs).toISOString() : null;
|
|
6385
|
-
if (!resolveIndexingCapabilities(this.config).conversationIndex) {
|
|
6386
|
-
return {
|
|
6387
|
-
enabled: false,
|
|
6388
|
-
backend: this.config.conversationIndexBackend,
|
|
6389
|
-
status: "disabled",
|
|
6390
|
-
available: false,
|
|
6391
|
-
indexPath: this.conversationIndexDir,
|
|
6392
|
-
supportsIncrementalUpdate: true,
|
|
6393
|
-
message: "Conversation index disabled by config",
|
|
6394
|
-
metadata: {
|
|
6395
|
-
chunkCount: chunkDocCount
|
|
6396
|
-
},
|
|
6397
|
-
chunkDocCount,
|
|
6398
|
-
lastUpdateAt
|
|
6399
|
-
};
|
|
6400
|
-
}
|
|
6401
|
-
const inspection = this.conversationIndexBackend ? await this.conversationIndexBackend.inspect() : {
|
|
6402
|
-
backend: this.config.conversationIndexBackend,
|
|
6403
|
-
status: "degraded",
|
|
6404
|
-
available: false,
|
|
6405
|
-
indexPath: this.conversationIndexDir,
|
|
6406
|
-
supportsIncrementalUpdate: true,
|
|
6407
|
-
message: "Conversation index backend unavailable",
|
|
6408
|
-
metadata: {
|
|
6409
|
-
chunkCount: chunkDocCount
|
|
6410
|
-
}
|
|
6411
|
-
};
|
|
6412
|
-
return {
|
|
6413
|
-
enabled: true,
|
|
6414
|
-
chunkDocCount,
|
|
6415
|
-
lastUpdateAt,
|
|
6416
|
-
...inspection
|
|
6417
|
-
};
|
|
6743
|
+
async searchConversationRecallResults(retrievalQuery, topK) {
|
|
6744
|
+
return this.conversationIndexCoordinator.search(retrievalQuery, topK);
|
|
6745
|
+
}
|
|
6746
|
+
formatConversationRecallSection(results, maxChars) {
|
|
6747
|
+
return this.conversationIndexCoordinator.formatRecallSection(
|
|
6748
|
+
results,
|
|
6749
|
+
maxChars
|
|
6750
|
+
);
|
|
6751
|
+
}
|
|
6752
|
+
// Issue #1526: countConversationChunkDocs / buildConversationIndexChunks moved
|
|
6753
|
+
// to ConversationIndexCoordinator (internal helpers, no orchestrator callers).
|
|
6754
|
+
async getConversationIndexHealth() {
|
|
6755
|
+
return this.conversationIndexCoordinator.getHealth();
|
|
6756
|
+
}
|
|
6757
|
+
async inspectConversationIndex() {
|
|
6758
|
+
return this.conversationIndexCoordinator.inspect();
|
|
6418
6759
|
}
|
|
6419
6760
|
async getRecoverySummary(sessionKey) {
|
|
6420
6761
|
return this.transcript.getRecoverySummary(sessionKey);
|
|
6421
6762
|
}
|
|
6422
6763
|
async updateConversationIndex(sessionKey, hours = 24, opts) {
|
|
6423
|
-
|
|
6424
|
-
return { chunks: 0, skipped: true, reason: "disabled", embedded: false };
|
|
6425
|
-
}
|
|
6426
|
-
const enforceMinInterval = opts?.enforceMinInterval !== false;
|
|
6427
|
-
if (enforceMinInterval) {
|
|
6428
|
-
const minIntervalMs = Math.max(
|
|
6429
|
-
0,
|
|
6430
|
-
this.config.conversationIndexMinUpdateIntervalMs
|
|
6431
|
-
);
|
|
6432
|
-
const now = Date.now();
|
|
6433
|
-
const last = this.conversationIndexLastUpdateAtMs.get(sessionKey) ?? 0;
|
|
6434
|
-
const elapsed = now - last;
|
|
6435
|
-
if (minIntervalMs > 0 && elapsed < minIntervalMs) {
|
|
6436
|
-
return {
|
|
6437
|
-
chunks: 0,
|
|
6438
|
-
skipped: true,
|
|
6439
|
-
reason: "min_interval",
|
|
6440
|
-
retryAfterMs: minIntervalMs - elapsed,
|
|
6441
|
-
embedded: false
|
|
6442
|
-
};
|
|
6443
|
-
}
|
|
6444
|
-
}
|
|
6445
|
-
const chunks = await this.buildConversationIndexChunks(sessionKey, hours);
|
|
6446
|
-
await writeConversationChunks(this.conversationIndexDir, chunks);
|
|
6447
|
-
const retentionCutoffMs = Number.isFinite(this.config.conversationIndexRetentionDays) && this.config.conversationIndexRetentionDays > 0 ? Date.now() - this.config.conversationIndexRetentionDays * 24 * 60 * 60 * 1e3 : void 0;
|
|
6448
|
-
await cleanupConversationChunks(
|
|
6449
|
-
this.conversationIndexDir,
|
|
6450
|
-
this.config.conversationIndexRetentionDays
|
|
6451
|
-
);
|
|
6452
|
-
const shouldEmbed = opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;
|
|
6453
|
-
let embedded = false;
|
|
6454
|
-
if (this.conversationIndexBackend) {
|
|
6455
|
-
const result = await this.conversationIndexBackend.update(chunks, {
|
|
6456
|
-
embed: shouldEmbed,
|
|
6457
|
-
...retentionCutoffMs !== void 0 ? { retentionCutoffMs } : {}
|
|
6458
|
-
});
|
|
6459
|
-
embedded = result.embedded;
|
|
6460
|
-
}
|
|
6461
|
-
this.conversationIndexLastUpdateAtMs.set(sessionKey, Date.now());
|
|
6462
|
-
return { chunks: chunks.length, skipped: false, embedded };
|
|
6764
|
+
return this.conversationIndexCoordinator.update(sessionKey, hours, opts);
|
|
6463
6765
|
}
|
|
6464
6766
|
async rebuildConversationIndex(sessionKey, hours = 24, opts) {
|
|
6465
|
-
|
|
6466
|
-
return {
|
|
6467
|
-
chunks: 0,
|
|
6468
|
-
skipped: true,
|
|
6469
|
-
reason: "disabled",
|
|
6470
|
-
embedded: false,
|
|
6471
|
-
rebuilt: false
|
|
6472
|
-
};
|
|
6473
|
-
}
|
|
6474
|
-
const chunks = await this.buildConversationIndexChunks(sessionKey, hours);
|
|
6475
|
-
await writeConversationChunks(this.conversationIndexDir, chunks);
|
|
6476
|
-
await cleanupConversationChunks(
|
|
6477
|
-
this.conversationIndexDir,
|
|
6478
|
-
this.config.conversationIndexRetentionDays
|
|
6479
|
-
);
|
|
6480
|
-
const shouldEmbed = opts?.embed ?? this.config.conversationIndexEmbedOnUpdate;
|
|
6481
|
-
let embedded = false;
|
|
6482
|
-
let rebuilt = false;
|
|
6483
|
-
if (this.conversationIndexBackend) {
|
|
6484
|
-
const result = await this.conversationIndexBackend.rebuild(chunks, {
|
|
6485
|
-
embed: shouldEmbed
|
|
6486
|
-
});
|
|
6487
|
-
embedded = result.embedded;
|
|
6488
|
-
rebuilt = result.rebuilt;
|
|
6489
|
-
}
|
|
6490
|
-
const stamp = Date.now();
|
|
6491
|
-
if (sessionKey) {
|
|
6492
|
-
this.conversationIndexLastUpdateAtMs.set(sessionKey, stamp);
|
|
6493
|
-
} else {
|
|
6494
|
-
this.conversationIndexLastUpdateAtMs.set("__rebuild__", stamp);
|
|
6495
|
-
}
|
|
6496
|
-
return { chunks: chunks.length, skipped: false, embedded, rebuilt };
|
|
6767
|
+
return this.conversationIndexCoordinator.rebuild(sessionKey, hours, opts);
|
|
6497
6768
|
}
|
|
6498
6769
|
/**
|
|
6499
6770
|
* Validate local LLM model availability and context window compatibility.
|
|
@@ -7228,7 +7499,7 @@ ${r.snippet.trim()}
|
|
|
7228
7499
|
resolvedPath = resolvedCold.result.path;
|
|
7229
7500
|
resolvedResult = resolvedCold.result;
|
|
7230
7501
|
}
|
|
7231
|
-
if (!
|
|
7502
|
+
if (!path5.isAbsolute(resolvedPath)) {
|
|
7232
7503
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
7233
7504
|
return null;
|
|
7234
7505
|
}
|
|
@@ -7253,7 +7524,7 @@ ${r.snippet.trim()}
|
|
|
7253
7524
|
}
|
|
7254
7525
|
continue;
|
|
7255
7526
|
}
|
|
7256
|
-
if (
|
|
7527
|
+
if (path5.isAbsolute(result.path)) {
|
|
7257
7528
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
7258
7529
|
if (resolved) {
|
|
7259
7530
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -7296,7 +7567,7 @@ ${r.snippet.trim()}
|
|
|
7296
7567
|
0
|
|
7297
7568
|
);
|
|
7298
7569
|
seedPaths.push(
|
|
7299
|
-
...seedRelativePaths.map((rel) =>
|
|
7570
|
+
...seedRelativePaths.map((rel) => path5.join(storage.dir, rel))
|
|
7300
7571
|
);
|
|
7301
7572
|
const seedSet = new Set(seedRelativePaths);
|
|
7302
7573
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
@@ -7312,7 +7583,7 @@ ${r.snippet.trim()}
|
|
|
7312
7583
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
7313
7584
|
if (deadlineExpired()) break;
|
|
7314
7585
|
if (seedSet.has(candidate.path)) continue;
|
|
7315
|
-
const memoryPath =
|
|
7586
|
+
const memoryPath = path5.resolve(storage.dir, candidate.path);
|
|
7316
7587
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
7317
7588
|
if (deadlineExpired()) break;
|
|
7318
7589
|
if (!memory) continue;
|
|
@@ -7337,7 +7608,7 @@ ${r.snippet.trim()}
|
|
|
7337
7608
|
path: memory.path,
|
|
7338
7609
|
score,
|
|
7339
7610
|
namespace,
|
|
7340
|
-
seed:
|
|
7611
|
+
seed: path5.resolve(storage.dir, candidate.seed),
|
|
7341
7612
|
hopDepth: candidate.hopDepth,
|
|
7342
7613
|
decayedWeight: candidate.decayedWeight,
|
|
7343
7614
|
graphType: candidate.graphType,
|
|
@@ -7358,12 +7629,12 @@ ${r.snippet.trim()}
|
|
|
7358
7629
|
}
|
|
7359
7630
|
async recordLastGraphRecallSnapshot(options) {
|
|
7360
7631
|
try {
|
|
7361
|
-
const snapshotPath =
|
|
7632
|
+
const snapshotPath = path5.join(
|
|
7362
7633
|
options.storage.dir,
|
|
7363
7634
|
"state",
|
|
7364
7635
|
"last_graph_recall.json"
|
|
7365
7636
|
);
|
|
7366
|
-
await mkdir3(
|
|
7637
|
+
await mkdir3(path5.dirname(snapshotPath), { recursive: true });
|
|
7367
7638
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
7368
7639
|
const totalSeedCount = options.seedPaths.length;
|
|
7369
7640
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -7397,12 +7668,12 @@ ${r.snippet.trim()}
|
|
|
7397
7668
|
}
|
|
7398
7669
|
async recordLastIntentSnapshot(options) {
|
|
7399
7670
|
try {
|
|
7400
|
-
const snapshotPath =
|
|
7671
|
+
const snapshotPath = path5.join(
|
|
7401
7672
|
options.storage.dir,
|
|
7402
7673
|
"state",
|
|
7403
7674
|
"last_intent.json"
|
|
7404
7675
|
);
|
|
7405
|
-
await mkdir3(
|
|
7676
|
+
await mkdir3(path5.dirname(snapshotPath), { recursive: true });
|
|
7406
7677
|
await writeFile3(
|
|
7407
7678
|
snapshotPath,
|
|
7408
7679
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -7414,12 +7685,12 @@ ${r.snippet.trim()}
|
|
|
7414
7685
|
}
|
|
7415
7686
|
async recordLastQmdRecallSnapshot(options) {
|
|
7416
7687
|
try {
|
|
7417
|
-
const snapshotPath =
|
|
7688
|
+
const snapshotPath = path5.join(
|
|
7418
7689
|
options.storage.dir,
|
|
7419
7690
|
"state",
|
|
7420
7691
|
"last_qmd_recall.json"
|
|
7421
7692
|
);
|
|
7422
|
-
await mkdir3(
|
|
7693
|
+
await mkdir3(path5.dirname(snapshotPath), { recursive: true });
|
|
7423
7694
|
await writeFile3(
|
|
7424
7695
|
snapshotPath,
|
|
7425
7696
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -7434,8 +7705,8 @@ ${r.snippet.trim()}
|
|
|
7434
7705
|
const stateDir = await this.resolveStateDirForNamespace(
|
|
7435
7706
|
options.namespace
|
|
7436
7707
|
);
|
|
7437
|
-
const snapshotPath =
|
|
7438
|
-
await mkdir3(
|
|
7708
|
+
const snapshotPath = path5.join(stateDir, "last_intent.json");
|
|
7709
|
+
await mkdir3(path5.dirname(snapshotPath), { recursive: true });
|
|
7439
7710
|
await writeFile3(
|
|
7440
7711
|
snapshotPath,
|
|
7441
7712
|
JSON.stringify(options.snapshot, null, 2),
|
|
@@ -7447,12 +7718,12 @@ ${r.snippet.trim()}
|
|
|
7447
7718
|
}
|
|
7448
7719
|
async resolveStateDirForNamespace(namespace) {
|
|
7449
7720
|
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
7450
|
-
return
|
|
7721
|
+
return path5.join(this.config.memoryDir, "state");
|
|
7451
7722
|
}
|
|
7452
7723
|
if (namespace !== this.config.defaultNamespace) {
|
|
7453
|
-
return
|
|
7724
|
+
return path5.join(this.config.memoryDir, "namespaces", namespace, "state");
|
|
7454
7725
|
}
|
|
7455
|
-
const candidate =
|
|
7726
|
+
const candidate = path5.join(
|
|
7456
7727
|
this.config.memoryDir,
|
|
7457
7728
|
"namespaces",
|
|
7458
7729
|
this.config.defaultNamespace
|
|
@@ -7460,11 +7731,11 @@ ${r.snippet.trim()}
|
|
|
7460
7731
|
try {
|
|
7461
7732
|
const candidateStat = await stat(candidate);
|
|
7462
7733
|
if (candidateStat.isDirectory()) {
|
|
7463
|
-
return
|
|
7734
|
+
return path5.join(candidate, "state");
|
|
7464
7735
|
}
|
|
7465
7736
|
} catch {
|
|
7466
7737
|
}
|
|
7467
|
-
return
|
|
7738
|
+
return path5.join(this.config.memoryDir, "state");
|
|
7468
7739
|
}
|
|
7469
7740
|
buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
|
|
7470
7741
|
return results.slice(0, limit).map((result) => ({
|
|
@@ -7765,7 +8036,7 @@ ${r.snippet.trim()}
|
|
|
7765
8036
|
caps,
|
|
7766
8037
|
signal: options.abortSignal
|
|
7767
8038
|
});
|
|
7768
|
-
if (this.config.
|
|
8039
|
+
if (resolveRecallEnhancementCapabilities(this.config).recallPlannerTelemetry && recallDecision.plannerSource && recallDecision.plannerSource !== "heuristic") {
|
|
7769
8040
|
log.debug(
|
|
7770
8041
|
`[recall-planner] mode=${recallDecision.shadowLlmMode ?? recallDecision.effectiveMode} source=${recallDecision.plannerSource} planned=${recallDecision.plannedMode} heuristic=${recallDecision.plannerHeuristicMode ?? recallDecision.plannedMode} model=${recallDecision.plannerModelUsed ?? "n/a"} latencyMs=${recallDecision.plannerLatencyMs ?? 0} fallback=${recallDecision.plannerFallbackUsed ?? false}` + (recallDecision.shadowLlmMode ? " (shadow)" : "")
|
|
7771
8042
|
);
|
|
@@ -7866,7 +8137,7 @@ ${r.snippet.trim()}
|
|
|
7866
8137
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
7867
8138
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
7868
8139
|
const labels = [];
|
|
7869
|
-
const normalizedPath = resultPath.split(
|
|
8140
|
+
const normalizedPath = resultPath.split(path5.sep).join("/");
|
|
7870
8141
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
7871
8142
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
7872
8143
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -8016,7 +8287,7 @@ ${r.snippet.trim()}
|
|
|
8016
8287
|
profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace))
|
|
8017
8288
|
);
|
|
8018
8289
|
const emptyProfileStorage = new Proxy(
|
|
8019
|
-
{ dir:
|
|
8290
|
+
{ dir: path5.join(this.config.memoryDir, ".empty-scope-profile") },
|
|
8020
8291
|
{
|
|
8021
8292
|
get(target, prop) {
|
|
8022
8293
|
if (prop in target) return target[prop];
|
|
@@ -8156,7 +8427,7 @@ ${r.snippet.trim()}
|
|
|
8156
8427
|
const sharedContextPromise = (async () => {
|
|
8157
8428
|
if (!this.isRecallSectionEnabled(
|
|
8158
8429
|
"shared-context",
|
|
8159
|
-
this.config.
|
|
8430
|
+
resolveConversationContextCapabilities(this.config).sharedContext === true
|
|
8160
8431
|
))
|
|
8161
8432
|
return null;
|
|
8162
8433
|
if (!this.sharedContext) return null;
|
|
@@ -8234,7 +8505,7 @@ ${trimmedBody}`;
|
|
|
8234
8505
|
})();
|
|
8235
8506
|
let peerProfileXrayAnnotation = void 0;
|
|
8236
8507
|
const peerProfileRecallPromise = (async () => {
|
|
8237
|
-
if (!this.config.
|
|
8508
|
+
if (!resolveRecallEnhancementCapabilities(this.config).peerProfileRecall) return null;
|
|
8238
8509
|
if (this.config.peerProfileRecallMaxFields <= 0) return null;
|
|
8239
8510
|
const peerId = this.getPeerIdForSession(sessionKey);
|
|
8240
8511
|
if (!peerId) return null;
|
|
@@ -8559,9 +8830,9 @@ ${rows.join("\n")}
|
|
|
8559
8830
|
})();
|
|
8560
8831
|
const causalTrajectoryPromise = (async () => {
|
|
8561
8832
|
const t0 = Date.now();
|
|
8562
|
-
if (!this.config.
|
|
8833
|
+
if (!resolveRecallEnhancementCapabilities(this.config).causalTrajectoryMemory || !resolveRecallEnhancementCapabilities(this.config).causalTrajectoryRecall || !this.isRecallSectionEnabled(
|
|
8563
8834
|
"causal-trajectories",
|
|
8564
|
-
this.config.
|
|
8835
|
+
resolveRecallEnhancementCapabilities(this.config).causalTrajectoryRecall === true
|
|
8565
8836
|
)) {
|
|
8566
8837
|
recordRecallSectionMetric({
|
|
8567
8838
|
section: "causalTrajectories",
|
|
@@ -8606,9 +8877,9 @@ ${rows.join("\n")}
|
|
|
8606
8877
|
})();
|
|
8607
8878
|
const cmcRetrievalPromise = (async () => {
|
|
8608
8879
|
const t0 = Date.now();
|
|
8609
|
-
if (!this.config.
|
|
8880
|
+
if (!resolveRecallEnhancementCapabilities(this.config).cmcRetrieval || !this.isRecallSectionEnabled(
|
|
8610
8881
|
"cmc-causal-chains",
|
|
8611
|
-
this.config.
|
|
8882
|
+
resolveRecallEnhancementCapabilities(this.config).cmcRetrieval === true
|
|
8612
8883
|
)) {
|
|
8613
8884
|
recordRecallSectionMetric({
|
|
8614
8885
|
section: "cmcCausalChains",
|
|
@@ -9436,7 +9707,7 @@ ${rows.join("\n")}
|
|
|
9436
9707
|
}
|
|
9437
9708
|
let section = null;
|
|
9438
9709
|
let checkpointInjected = false;
|
|
9439
|
-
if (this.config.
|
|
9710
|
+
if (resolvePipelineProcessingCapabilities(this.config).checkpoint) {
|
|
9440
9711
|
const checkpoint = await this.transcript.loadCheckpoint(sessionKey);
|
|
9441
9712
|
log.debug(
|
|
9442
9713
|
`recall: checkpoint loaded, turns=${checkpoint?.turns?.length ?? 0}`
|
|
@@ -9492,11 +9763,11 @@ ${formatted}`;
|
|
|
9492
9763
|
if (!resolveRecallAuxiliaryCapabilities(this.config).compactionReset) return null;
|
|
9493
9764
|
const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
|
|
9494
9765
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
9495
|
-
const signalPath =
|
|
9766
|
+
const signalPath = path5.join(
|
|
9496
9767
|
workspaceDir,
|
|
9497
9768
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
9498
9769
|
);
|
|
9499
|
-
const bootPath =
|
|
9770
|
+
const bootPath = path5.join(workspaceDir, "BOOT.md");
|
|
9500
9771
|
try {
|
|
9501
9772
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
9502
9773
|
if (!signalStat) return null;
|
|
@@ -9544,7 +9815,7 @@ ${formatted}`;
|
|
|
9544
9815
|
})();
|
|
9545
9816
|
const summariesPromise = (async () => {
|
|
9546
9817
|
const t0 = Date.now();
|
|
9547
|
-
if (!this.config.
|
|
9818
|
+
if (!resolvePipelineProcessingCapabilities(this.config).hourlySummaries || !sessionKey || !this.isRecallSectionEnabled("summaries", true)) {
|
|
9548
9819
|
recordRecallSectionMetric({
|
|
9549
9820
|
section: "summaries",
|
|
9550
9821
|
priority: "core",
|
|
@@ -9729,7 +10000,7 @@ ${formatted}`;
|
|
|
9729
10000
|
const compoundingPromise = observeEnrichmentPromise(
|
|
9730
10001
|
(async () => {
|
|
9731
10002
|
const t0 = Date.now();
|
|
9732
|
-
if (!this.compounding || !this.config.
|
|
10003
|
+
if (!this.compounding || !resolveRecallEnhancementCapabilities(this.config).compoundingInject || !this.isRecallSectionEnabled("compounding", true)) {
|
|
9733
10004
|
recordRecallSectionMetric({
|
|
9734
10005
|
section: "compounding",
|
|
9735
10006
|
priority: "enrichment",
|
|
@@ -9970,7 +10241,7 @@ ${formatted}`;
|
|
|
9970
10241
|
if (sharedCtx)
|
|
9971
10242
|
this.appendRecallSection(sectionBuckets, "shared-context", sharedCtx);
|
|
9972
10243
|
const explicitCueMaxChars = this.getRecallSectionMaxChars("explicit-cue") ?? this.config.explicitCueRecallMaxChars;
|
|
9973
|
-
if (this.config.
|
|
10244
|
+
if (resolveRecallEnhancementCapabilities(this.config).explicitCueRecall && this.isRecallSectionEnabled("explicit-cue") && explicitCueMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall") {
|
|
9974
10245
|
try {
|
|
9975
10246
|
const explicitCueSection = await buildExplicitCueRecallSection({
|
|
9976
10247
|
engine: this.lcmEngine,
|
|
@@ -9999,7 +10270,7 @@ ${formatted}`;
|
|
|
9999
10270
|
const targetedFactMaxChars = this.getRecallSectionMaxChars("targeted-facts") ?? this.config.targetedFactRecallMaxChars;
|
|
10000
10271
|
if (this.isSpecializedRecallSectionEnabled(
|
|
10001
10272
|
"targeted-facts",
|
|
10002
|
-
this.config.
|
|
10273
|
+
resolveRecallEnhancementCapabilities(this.config).targetedFactRecall
|
|
10003
10274
|
) && targetedFactMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall" && shouldRecallTargetedFactEvidence(retrievalQuery)) {
|
|
10004
10275
|
try {
|
|
10005
10276
|
const targetedFactSection = await buildTargetedFactRecallSection({
|
|
@@ -10029,7 +10300,7 @@ ${formatted}`;
|
|
|
10029
10300
|
const focusedListMaxChars = this.getRecallSectionMaxChars("focused-list") ?? this.config.focusedListRecallMaxChars;
|
|
10030
10301
|
if (this.isSpecializedRecallSectionEnabled(
|
|
10031
10302
|
"focused-list",
|
|
10032
|
-
this.config.
|
|
10303
|
+
resolveRecallEnhancementCapabilities(this.config).focusedListRecall
|
|
10033
10304
|
) && focusedListMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall" && shouldRecallFocusedListEvidence(retrievalQuery)) {
|
|
10034
10305
|
try {
|
|
10035
10306
|
const focusedListSection = await buildFocusedListRecallSection({
|
|
@@ -10063,7 +10334,7 @@ ${formatted}`;
|
|
|
10063
10334
|
const responseGuidanceForcedByPipeline = responseGuidanceEntry?.forceGeneric === true && !responseGuidanceMatchesQuery;
|
|
10064
10335
|
if (this.isSpecializedRecallSectionEnabled(
|
|
10065
10336
|
"response-guidance",
|
|
10066
|
-
this.config.
|
|
10337
|
+
resolveRecallEnhancementCapabilities(this.config).responseGuidanceRecall
|
|
10067
10338
|
) && responseGuidanceMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall" && (responseGuidanceMatchesQuery || responseGuidanceForcedByPipeline)) {
|
|
10068
10339
|
try {
|
|
10069
10340
|
const responseGuidanceSection = await buildResponseGuidanceRecallSection({
|
|
@@ -10095,7 +10366,7 @@ ${formatted}`;
|
|
|
10095
10366
|
const eventOrderMaxChars = this.getRecallSectionMaxChars("event-order") ?? this.config.eventOrderRecallMaxChars;
|
|
10096
10367
|
if (this.isSpecializedRecallSectionEnabled(
|
|
10097
10368
|
"event-order",
|
|
10098
|
-
this.config.
|
|
10369
|
+
resolveRecallEnhancementCapabilities(this.config).eventOrderRecall
|
|
10099
10370
|
) && eventOrderMaxChars !== 0 && this.lcmEngine?.enabled && recallMode !== "no_recall" && shouldRecallEventOrderEvidence(retrievalQuery)) {
|
|
10100
10371
|
try {
|
|
10101
10372
|
const eventOrderSection = await firstNonEmptyLcmRead(
|
|
@@ -10388,7 +10659,7 @@ ${tmtNode.summary}`
|
|
|
10388
10659
|
);
|
|
10389
10660
|
const isFullModeGraphAssist = graphCaps.multiGraphMemory && caps.graphAssistInFullMode && recallMode === "full" && memoryResults.length >= Math.max(1, this.config.graphAssistMinSeedResults ?? 3);
|
|
10390
10661
|
const shouldRunGraphExpansion = recallMode === "graph_mode" || isFullModeGraphAssist;
|
|
10391
|
-
const graphShadowEvalEnabled = isFullModeGraphAssist && this.config.
|
|
10662
|
+
const graphShadowEvalEnabled = isFullModeGraphAssist && resolveRecallEnhancementCapabilities(this.config).graphAssistShadowEval === true;
|
|
10392
10663
|
if (shouldRunGraphExpansion) {
|
|
10393
10664
|
shouldPersistGraphSnapshot = true;
|
|
10394
10665
|
graphDecisionShadowMode = graphShadowEvalEnabled;
|
|
@@ -10583,7 +10854,7 @@ ${tmtNode.summary}`
|
|
|
10583
10854
|
retrievalQuery,
|
|
10584
10855
|
caps
|
|
10585
10856
|
);
|
|
10586
|
-
if (this.config.
|
|
10857
|
+
if (resolveRecallEnhancementCapabilities(this.config).memoryReconstruction && memoryResults.length > 0) {
|
|
10587
10858
|
try {
|
|
10588
10859
|
const snippets = memoryResults.map((r) => r.snippet);
|
|
10589
10860
|
const coveredRefs = memoryResults.map((r) => r.path).filter((p) => p.startsWith("entities/")).map((p) => p.replace(/^entities\//, "").replace(/\.md$/, ""));
|
|
@@ -11888,7 +12159,7 @@ _Context: ${topQuestion.context}_`
|
|
|
11888
12159
|
return ingestResult;
|
|
11889
12160
|
}
|
|
11890
12161
|
async observeSessionHeartbeat(sessionKey, options = {}) {
|
|
11891
|
-
if (this.config.
|
|
12162
|
+
if (resolvePipelineProcessingCapabilities(this.config).sessionObserver !== true) return;
|
|
11892
12163
|
if (!sessionKey || sessionKey.length === 0) return;
|
|
11893
12164
|
const bufferKey = typeof options.bufferKey === "string" && options.bufferKey.length > 0 ? options.bufferKey : sessionKey;
|
|
11894
12165
|
const previous = this.heartbeatObserverChains.get(sessionKey) ?? Promise.resolve();
|
|
@@ -12580,7 +12851,7 @@ ${normalized}`).digest("hex");
|
|
|
12580
12851
|
this.maintenanceScheduler.requestQmdMaintenanceForTool(reason);
|
|
12581
12852
|
}
|
|
12582
12853
|
async persistExtraction(result, storage, threadIdForExtraction, sourceContext, baseNamespace, scopeProfileWritePlan, sourceText, graphCaps = resolveGraphConstructionCapabilities(this.config), lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config)) {
|
|
12583
|
-
const citationEnabled = this.config.
|
|
12854
|
+
const citationEnabled = resolvePipelineProcessingCapabilities(this.config).inlineSourceAttribution === true;
|
|
12584
12855
|
const citationTemplate = this.config.inlineSourceAttributionFormat;
|
|
12585
12856
|
const citationContextBase = citationEnabled ? {
|
|
12586
12857
|
agent: sourceContext?.principal,
|
|
@@ -12677,7 +12948,7 @@ ${normalized}`).digest("hex");
|
|
|
12677
12948
|
const actualTier = confidenceTier(confidence);
|
|
12678
12949
|
const actualRank = confidenceTierOrder.indexOf(actualTier);
|
|
12679
12950
|
if (actualRank === -1) return false;
|
|
12680
|
-
if (!this.config.
|
|
12951
|
+
if (!resolveRecallEnhancementCapabilities(this.config).autoPromoteToShared) return false;
|
|
12681
12952
|
if (!this.config.autoPromoteToSharedCategories.includes(category))
|
|
12682
12953
|
return false;
|
|
12683
12954
|
const minimumRank = confidenceTierOrder.indexOf(
|
|
@@ -13428,7 +13699,7 @@ ${normalized}`).digest("hex");
|
|
|
13428
13699
|
const requireSpansPendingStatus = this.config.provenance?.requireSpans === true && fact.requireSpansPending === true ? "pending_review" : void 0;
|
|
13429
13700
|
const faithfulnessEnforceStatus = faithfulnessGateStatus ?? requireSpansPendingStatus;
|
|
13430
13701
|
let pendingSemanticSkip = null;
|
|
13431
|
-
if (this.config.
|
|
13702
|
+
if (resolvePipelineProcessingCapabilities(this.config).semanticDedup) {
|
|
13432
13703
|
let semanticDecision;
|
|
13433
13704
|
if (batchBackendUnavailable) {
|
|
13434
13705
|
semanticDecision = { action: "keep", reason: "backend_unavailable" };
|
|
@@ -13461,7 +13732,7 @@ ${normalized}`).digest("hex");
|
|
|
13461
13732
|
pendingSemanticSkip = semanticDecision;
|
|
13462
13733
|
}
|
|
13463
13734
|
}
|
|
13464
|
-
const inferredIntent = this.config.
|
|
13735
|
+
const inferredIntent = resolveConversationContextCapabilities(this.config).intentRouting ? inferIntentFromText(
|
|
13465
13736
|
`${writeCategory} ${fact.tags.join(" ")} ${fact.content}`
|
|
13466
13737
|
) : null;
|
|
13467
13738
|
const extractionWriteSource = fact.source === "proactive" ? "extraction-proactive" : "extraction";
|
|
@@ -13469,7 +13740,7 @@ ${normalized}`).digest("hex");
|
|
|
13469
13740
|
let links = [];
|
|
13470
13741
|
let contradictionDetected = false;
|
|
13471
13742
|
let contradiction;
|
|
13472
|
-
if (this.config.
|
|
13743
|
+
if (resolveRecallEnhancementCapabilities(this.config).contradictionDetection && this.qmd.isAvailable() && faithfulnessEnforceStatus !== "pending_review") {
|
|
13473
13744
|
const targetNamespace = this.storageDirNamespace(targetStorage.dir);
|
|
13474
13745
|
contradiction = await this.checkForContradiction(
|
|
13475
13746
|
fact.content,
|
|
@@ -13499,9 +13770,9 @@ ${normalized}`).digest("hex");
|
|
|
13499
13770
|
dedupedCount++;
|
|
13500
13771
|
continue;
|
|
13501
13772
|
}
|
|
13502
|
-
if (this.config.
|
|
13773
|
+
if (resolvePipelineProcessingCapabilities(this.config).chunking && writeCategory !== "procedure") {
|
|
13503
13774
|
let chunkResult;
|
|
13504
|
-
if (this.config.
|
|
13775
|
+
if (resolvePipelineProcessingCapabilities(this.config).semanticChunking) {
|
|
13505
13776
|
try {
|
|
13506
13777
|
const embedFn = this.embeddingFallback.embedTexts.bind(this.embeddingFallback);
|
|
13507
13778
|
const semanticResult = await semanticChunkContent(
|
|
@@ -13752,7 +14023,7 @@ ${normalized}`).digest("hex");
|
|
|
13752
14023
|
continue;
|
|
13753
14024
|
}
|
|
13754
14025
|
}
|
|
13755
|
-
if (this.config.
|
|
14026
|
+
if (resolveRecallEnhancementCapabilities(this.config).memoryLinking && this.qmd.isAvailable()) {
|
|
13756
14027
|
const targetNamespace = this.storageDirNamespace(targetStorage.dir);
|
|
13757
14028
|
const suggestedLinks = await this.suggestLinksForMemory(
|
|
13758
14029
|
fact.content,
|
|
@@ -13964,7 +14235,7 @@ ${normalized}`).digest("hex");
|
|
|
13964
14235
|
log.warn(`persistExtraction: entity write failed: ${err}`);
|
|
13965
14236
|
}
|
|
13966
14237
|
}
|
|
13967
|
-
if (this.config.
|
|
14238
|
+
if (resolveRecallEnhancementCapabilities(this.config).entityRelationships && Array.isArray(result.relationships)) {
|
|
13968
14239
|
for (const rel of result.relationships.slice(0, 5)) {
|
|
13969
14240
|
if (!rel.source || !rel.target || !rel.label) continue;
|
|
13970
14241
|
try {
|
|
@@ -13983,7 +14254,7 @@ ${normalized}`).digest("hex");
|
|
|
13983
14254
|
}
|
|
13984
14255
|
}
|
|
13985
14256
|
}
|
|
13986
|
-
if (this.config.
|
|
14257
|
+
if (resolveRecallEnhancementCapabilities(this.config).entityActivityLog) {
|
|
13987
14258
|
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
13988
14259
|
for (const entity of entities) {
|
|
13989
14260
|
const name = entity?.name;
|
|
@@ -14012,7 +14283,7 @@ ${normalized}`).digest("hex");
|
|
|
14012
14283
|
recordDurableNonFactWrite();
|
|
14013
14284
|
}
|
|
14014
14285
|
}
|
|
14015
|
-
if (this.config.
|
|
14286
|
+
if (resolveRecallEnhancementCapabilities(this.config).identity && result.identityReflection) {
|
|
14016
14287
|
try {
|
|
14017
14288
|
await storage.appendIdentityReflection(result.identityReflection);
|
|
14018
14289
|
recordDurableNonFactWrite();
|
|
@@ -14098,7 +14369,7 @@ ${normalized}`).digest("hex");
|
|
|
14098
14369
|
const allMems = allMemsForGraph ?? [];
|
|
14099
14370
|
for (const m of allMems) {
|
|
14100
14371
|
if (m.frontmatter.entityRef === entityRef) {
|
|
14101
|
-
const rel =
|
|
14372
|
+
const rel = path5.relative(storage.dir, m.path);
|
|
14102
14373
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
14103
14374
|
}
|
|
14104
14375
|
}
|
|
@@ -14395,7 +14666,7 @@ ${normalized}`).digest("hex");
|
|
|
14395
14666
|
const tierMigration = await this.runTierMigrationCycle(this.storage, "maintenance");
|
|
14396
14667
|
if (tierMigration.migrated > 0) memoryItemMutated = true;
|
|
14397
14668
|
allMemories = await this.storage.readAllMemories();
|
|
14398
|
-
if (this.config.
|
|
14669
|
+
if (resolveRecallEnhancementCapabilities(this.config).factArchival) {
|
|
14399
14670
|
const archived = await this.runFactArchival(allMemories);
|
|
14400
14671
|
if (archived > 0) {
|
|
14401
14672
|
memoryItemMutated = true;
|
|
@@ -14422,7 +14693,7 @@ ${normalized}`).digest("hex");
|
|
|
14422
14693
|
}
|
|
14423
14694
|
if (resolveConsolidationCapabilities(this.config).semanticConsolidation) {
|
|
14424
14695
|
try {
|
|
14425
|
-
const stateFilePath =
|
|
14696
|
+
const stateFilePath = path5.join(
|
|
14426
14697
|
this.config.memoryDir,
|
|
14427
14698
|
"state",
|
|
14428
14699
|
"semantic-consolidation-last-run.json"
|
|
@@ -14470,7 +14741,7 @@ ${normalized}`).digest("hex");
|
|
|
14470
14741
|
);
|
|
14471
14742
|
}
|
|
14472
14743
|
if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
|
|
14473
|
-
const stateDir =
|
|
14744
|
+
const stateDir = path5.join(this.config.memoryDir, "state");
|
|
14474
14745
|
await mkdir3(stateDir, { recursive: true });
|
|
14475
14746
|
await writeFile3(
|
|
14476
14747
|
stateFilePath,
|
|
@@ -14485,7 +14756,7 @@ ${normalized}`).digest("hex");
|
|
|
14485
14756
|
);
|
|
14486
14757
|
}
|
|
14487
14758
|
}
|
|
14488
|
-
if (this.config.
|
|
14759
|
+
if (resolveRecallEnhancementCapabilities(this.config).identity) {
|
|
14489
14760
|
await this.autoConsolidateIdentity();
|
|
14490
14761
|
}
|
|
14491
14762
|
const profileSection = this.getRecallSectionEntry("profile");
|
|
@@ -14510,10 +14781,10 @@ ${normalized}`).digest("hex");
|
|
|
14510
14781
|
}
|
|
14511
14782
|
}
|
|
14512
14783
|
}
|
|
14513
|
-
if (this.config.
|
|
14784
|
+
if (resolvePipelineProcessingCapabilities(this.config).summarization) {
|
|
14514
14785
|
await this.runSummarization(allMemories);
|
|
14515
14786
|
}
|
|
14516
|
-
if (this.config.
|
|
14787
|
+
if (resolvePipelineProcessingCapabilities(this.config).topicExtraction) {
|
|
14517
14788
|
await this.runTopicExtraction(allMemories);
|
|
14518
14789
|
}
|
|
14519
14790
|
const meta = await this.storage.loadMeta();
|
|
@@ -14791,7 +15062,7 @@ ${reflectionsContent.trim()}
|
|
|
14791
15062
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
14792
15063
|
const addStorage = (storage) => {
|
|
14793
15064
|
const storageDir = storageDirFor(storage);
|
|
14794
|
-
const storageKey = storageDir ?
|
|
15065
|
+
const storageKey = storageDir ? path5.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
14795
15066
|
if (seenStorageDirs.has(storageKey)) return;
|
|
14796
15067
|
seenStorageDirs.add(storageKey);
|
|
14797
15068
|
storages.push(storage);
|
|
@@ -14821,7 +15092,7 @@ ${reflectionsContent.trim()}
|
|
|
14821
15092
|
continue;
|
|
14822
15093
|
}
|
|
14823
15094
|
try {
|
|
14824
|
-
const coldRoot =
|
|
15095
|
+
const coldRoot = path5.join(storageDir, "cold");
|
|
14825
15096
|
for (const candidate of qmdResultPathCandidates(
|
|
14826
15097
|
coldRoot,
|
|
14827
15098
|
parts.relativePath
|
|
@@ -14862,7 +15133,7 @@ ${reflectionsContent.trim()}
|
|
|
14862
15133
|
return null;
|
|
14863
15134
|
}
|
|
14864
15135
|
}
|
|
14865
|
-
if (
|
|
15136
|
+
if (path5.isAbsolute(resultPath)) {
|
|
14866
15137
|
if (!fallbackStorageDir) {
|
|
14867
15138
|
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
14868
15139
|
}
|
|
@@ -14901,7 +15172,7 @@ ${reflectionsContent.trim()}
|
|
|
14901
15172
|
);
|
|
14902
15173
|
if (!memory) return null;
|
|
14903
15174
|
let ownerNamespace = null;
|
|
14904
|
-
if (
|
|
15175
|
+
if (path5.isAbsolute(memory.path)) {
|
|
14905
15176
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
14906
15177
|
memory.path,
|
|
14907
15178
|
fallbackStorage,
|
|
@@ -14925,16 +15196,16 @@ ${reflectionsContent.trim()}
|
|
|
14925
15196
|
};
|
|
14926
15197
|
}
|
|
14927
15198
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
14928
|
-
const resolvedPath =
|
|
14929
|
-
const memoryRoot =
|
|
14930
|
-
const namespacesRoot =
|
|
15199
|
+
const resolvedPath = path5.resolve(resultPath);
|
|
15200
|
+
const memoryRoot = path5.resolve(this.config.memoryDir);
|
|
15201
|
+
const namespacesRoot = path5.join(memoryRoot, "namespaces");
|
|
14931
15202
|
const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
|
|
14932
15203
|
const matches = [];
|
|
14933
15204
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
14934
15205
|
const maybeAddStorage = (storage, namespace) => {
|
|
14935
15206
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
14936
15207
|
if (!storageDir) return;
|
|
14937
|
-
const candidateRoot =
|
|
15208
|
+
const candidateRoot = path5.resolve(storageDir);
|
|
14938
15209
|
if (seenDirs.has(candidateRoot)) return;
|
|
14939
15210
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
14940
15211
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -14952,7 +15223,7 @@ ${reflectionsContent.trim()}
|
|
|
14952
15223
|
candidateNamespaces.add(ns);
|
|
14953
15224
|
}
|
|
14954
15225
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
14955
|
-
const relativeToNamespaces =
|
|
15226
|
+
const relativeToNamespaces = path5.relative(namespacesRoot, resolvedPath);
|
|
14956
15227
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
14957
15228
|
if (namespaceSegment) {
|
|
14958
15229
|
candidateNamespaces.add(
|
|
@@ -14974,218 +15245,22 @@ ${reflectionsContent.trim()}
|
|
|
14974
15245
|
matches.sort((a, b) => b.dir.length - a.dir.length);
|
|
14975
15246
|
return matches[0] ?? null;
|
|
14976
15247
|
}
|
|
15248
|
+
// Issue #1526: recall-rerank methods moved to RecallRerankCoordinator.
|
|
15249
|
+
// Thin delegation keeps the private API stable for callers + tests.
|
|
14977
15250
|
async applyMemoryWorthRerank(results, namespaces) {
|
|
14978
|
-
|
|
14979
|
-
const seenNamespaces = /* @__PURE__ */ new Set();
|
|
14980
|
-
const nowMs = Date.now();
|
|
14981
|
-
for (const [key, entry] of this.memoryWorthCounterCache) {
|
|
14982
|
-
if (nowMs - entry.at >= _Orchestrator.MEMORY_WORTH_CACHE_TTL_MS) {
|
|
14983
|
-
this.memoryWorthCounterCache.delete(key);
|
|
14984
|
-
}
|
|
14985
|
-
}
|
|
14986
|
-
for (const ns of namespaces) {
|
|
14987
|
-
if (seenNamespaces.has(ns)) continue;
|
|
14988
|
-
seenNamespaces.add(ns);
|
|
14989
|
-
try {
|
|
14990
|
-
const cached = this.memoryWorthCounterCache.get(ns);
|
|
14991
|
-
let nsMap;
|
|
14992
|
-
if (cached && nowMs - cached.at < _Orchestrator.MEMORY_WORTH_CACHE_TTL_MS) {
|
|
14993
|
-
nsMap = cached.counters;
|
|
14994
|
-
} else {
|
|
14995
|
-
const storage = await this.getStorage(ns);
|
|
14996
|
-
const memories = await storage.readAllMemories();
|
|
14997
|
-
nsMap = buildMemoryWorthCounterMap(memories);
|
|
14998
|
-
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
14999
|
-
}
|
|
15000
|
-
for (const [path5, c] of nsMap) counters.set(path5, c);
|
|
15001
|
-
} catch (err) {
|
|
15002
|
-
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
15003
|
-
namespace: ns,
|
|
15004
|
-
error: err.message
|
|
15005
|
-
});
|
|
15006
|
-
}
|
|
15007
|
-
}
|
|
15008
|
-
const missing = results.filter((r) => !counters.has(r.path));
|
|
15009
|
-
if (missing.length > 0) {
|
|
15010
|
-
let reader = null;
|
|
15011
|
-
for (const ns of namespaces) {
|
|
15012
|
-
try {
|
|
15013
|
-
reader = await this.getStorage(ns);
|
|
15014
|
-
break;
|
|
15015
|
-
} catch {
|
|
15016
|
-
}
|
|
15017
|
-
}
|
|
15018
|
-
if (reader) {
|
|
15019
|
-
for (const r of missing) {
|
|
15020
|
-
try {
|
|
15021
|
-
const memory = await this.readQmdResultMemory(r.path, reader, namespaces);
|
|
15022
|
-
if (!memory) continue;
|
|
15023
|
-
const fm = memory.frontmatter;
|
|
15024
|
-
if (fm.mw_success === void 0 && fm.mw_fail === void 0) continue;
|
|
15025
|
-
counters.set(r.path, {
|
|
15026
|
-
mw_success: fm.mw_success,
|
|
15027
|
-
mw_fail: fm.mw_fail,
|
|
15028
|
-
lastAccessed: fm.lastAccessed
|
|
15029
|
-
});
|
|
15030
|
-
} catch (err) {
|
|
15031
|
-
log.debug("memory-worth: direct path lookup failed", {
|
|
15032
|
-
path: r.path,
|
|
15033
|
-
error: err.message
|
|
15034
|
-
});
|
|
15035
|
-
}
|
|
15036
|
-
}
|
|
15037
|
-
}
|
|
15038
|
-
}
|
|
15039
|
-
if (counters.size === 0) return results;
|
|
15040
|
-
const rankedInputs = results.map((r, i) => ({
|
|
15041
|
-
path: r.path,
|
|
15042
|
-
// Large positive rank score so multiplier math stays well-scaled and
|
|
15043
|
-
// we never hit zero; descending so earlier items rank higher.
|
|
15044
|
-
score: results.length - i
|
|
15045
|
-
}));
|
|
15046
|
-
const filtered = applyMemoryWorthFilter(rankedInputs, {
|
|
15047
|
-
counters,
|
|
15048
|
-
now: /* @__PURE__ */ new Date(),
|
|
15049
|
-
halfLifeMs: this.config.recallMemoryWorthHalfLifeMs > 0 ? this.config.recallMemoryWorthHalfLifeMs : void 0
|
|
15050
|
-
});
|
|
15051
|
-
const byPath = new Map(results.map((r) => [r.path, r]));
|
|
15052
|
-
const reordered = [];
|
|
15053
|
-
for (const item of filtered) {
|
|
15054
|
-
const original = byPath.get(item.path);
|
|
15055
|
-
if (original) reordered.push(original);
|
|
15056
|
-
}
|
|
15057
|
-
return reordered;
|
|
15251
|
+
return this.recallRerankCoordinator.applyMemoryWorthRerank(results, namespaces);
|
|
15058
15252
|
}
|
|
15059
|
-
/**
|
|
15060
|
-
* Issue #1577 — unified TrustScore recall stage. Thin wiring over the pure
|
|
15061
|
-
* {@link applyTrustScoreStage} scorer + the {@link buildTrustSignalsForRerank}
|
|
15062
|
-
* signal builder. The stage subsumes the Memory Worth multiplier — the
|
|
15063
|
-
* orchestrator runs exactly one of the two (mutual exclusion, rule 39; the
|
|
15064
|
-
* double-multiplier test in trust-score-stage.test.ts pins it structurally).
|
|
15065
|
-
*
|
|
15066
|
-
* Returns the admitted results AND the per-path trust map (including
|
|
15067
|
-
* quarantined items) so the caller can: (a) render epistemic hedges, (b)
|
|
15068
|
-
* surface quarantined items in X-ray with a reason (rule 34), and (c) filter
|
|
15069
|
-
* quarantined paths from fallback recall branches. The trust map is a
|
|
15070
|
-
* per-recall local — never instance state — so concurrent recalls cannot
|
|
15071
|
-
* race on it (review: shared-trust-map concurrency).
|
|
15072
|
-
*/
|
|
15073
15253
|
async applyTrustScoreRerank(results, namespaces) {
|
|
15074
|
-
|
|
15075
|
-
const now = /* @__PURE__ */ new Date();
|
|
15076
|
-
const halfLifeDays = this.config.recallMemoryWorthHalfLifeMs > 0 ? this.config.recallMemoryWorthHalfLifeMs / (24 * 60 * 60 * 1e3) : void 0;
|
|
15077
|
-
let fallbackReader = null;
|
|
15078
|
-
const signals = await buildTrustSignalsForRerank(
|
|
15079
|
-
results.map((r) => r.path),
|
|
15080
|
-
namespaces,
|
|
15081
|
-
{
|
|
15082
|
-
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
15083
|
-
readMemoryFrontmatter: async (path5) => {
|
|
15084
|
-
if (!fallbackReader) {
|
|
15085
|
-
for (const ns of namespaces) {
|
|
15086
|
-
try {
|
|
15087
|
-
fallbackReader = await this.getStorage(ns);
|
|
15088
|
-
break;
|
|
15089
|
-
} catch {
|
|
15090
|
-
}
|
|
15091
|
-
}
|
|
15092
|
-
}
|
|
15093
|
-
if (!fallbackReader) return null;
|
|
15094
|
-
const memory = await this.readQmdResultMemory(path5, fallbackReader, namespaces);
|
|
15095
|
-
return memory ? memory.frontmatter : null;
|
|
15096
|
-
}
|
|
15097
|
-
},
|
|
15098
|
-
{ cache: this.trustSignalCache, ttlMs: _Orchestrator.TRUST_SIGNAL_CACHE_TTL_MS },
|
|
15099
|
-
now,
|
|
15100
|
-
{
|
|
15101
|
-
recencyHalfLifeDays: halfLifeDays,
|
|
15102
|
-
logDebug: (message, context) => log.debug(message, context)
|
|
15103
|
-
}
|
|
15104
|
-
);
|
|
15105
|
-
if (signals.size === 0) {
|
|
15106
|
-
return { results, trustByPath: null };
|
|
15107
|
-
}
|
|
15108
|
-
const rankedInputs = results.map((r, i) => ({ path: r.path, score: results.length - i }));
|
|
15109
|
-
const stage = applyTrustScoreStage(rankedInputs, {
|
|
15110
|
-
signals,
|
|
15111
|
-
weights: this.config.trustScoreWeights,
|
|
15112
|
-
minMultiplier: this.config.trustScoreMinMultiplier,
|
|
15113
|
-
maxMultiplier: this.config.trustScoreMaxMultiplier,
|
|
15114
|
-
quarantine: this.config.trustScoreQuarantine
|
|
15115
|
-
});
|
|
15116
|
-
const trustByPath = new Map(stage.all.map((item) => [item.path, item]));
|
|
15117
|
-
const byPath = new Map(results.map((r) => [r.path, r]));
|
|
15118
|
-
const admitted = stage.admitted.map((item) => byPath.get(item.path)).filter((r) => r !== void 0);
|
|
15119
|
-
return { results: admitted, trustByPath };
|
|
15254
|
+
return this.recallRerankCoordinator.applyTrustScoreRerank(results, namespaces);
|
|
15120
15255
|
}
|
|
15121
|
-
/**
|
|
15122
|
-
* Issue #1577 — apply the TrustScore stage (or, when trust is off, the Memory
|
|
15123
|
-
* Worth multiplier fallback) to ONE recall branch's results, returning the
|
|
15124
|
-
* scored results + the per-path trust map. Thin wiring over
|
|
15125
|
-
* {@link applyTrustScoreRerank} so every recall path — hot QMD, embedding
|
|
15126
|
-
* fallback, recent scan — applies the SAME multiplier gate (rule 41: a
|
|
15127
|
-
* feature gate must apply across ALL parallel recall paths). TrustScore
|
|
15128
|
-
* subsumes Memory Worth; exactly one runs (rule 39). Fail-open on lookup
|
|
15129
|
-
* errors so a storage hiccup never breaks a fallback path.
|
|
15130
|
-
*/
|
|
15131
15256
|
async applyTrustScoreToBranch(results, namespaces, caps, label) {
|
|
15132
|
-
|
|
15133
|
-
try {
|
|
15134
|
-
return await this.applyTrustScoreRerank(results, namespaces);
|
|
15135
|
-
} catch (err) {
|
|
15136
|
-
log.debug(`trust-score stage (${label}) failed open`, {
|
|
15137
|
-
error: err.message
|
|
15138
|
-
});
|
|
15139
|
-
}
|
|
15140
|
-
} else if (caps.recallMemoryWorthFilter && results.length > 0) {
|
|
15141
|
-
try {
|
|
15142
|
-
const filtered = await this.applyMemoryWorthRerank(results, namespaces);
|
|
15143
|
-
return { results: filtered, trustByPath: null };
|
|
15144
|
-
} catch (err) {
|
|
15145
|
-
log.debug(`memory-worth filter (${label}) failed open`, {
|
|
15146
|
-
error: err.message
|
|
15147
|
-
});
|
|
15148
|
-
}
|
|
15149
|
-
}
|
|
15150
|
-
return { results, trustByPath: null };
|
|
15257
|
+
return this.recallRerankCoordinator.applyTrustScoreToBranch(results, namespaces, caps, label);
|
|
15151
15258
|
}
|
|
15152
15259
|
diversifyAndLimitRecallResults(sectionId, results, limit, retrievalQuery, caps = resolveCapabilities(this.config)) {
|
|
15153
|
-
|
|
15154
|
-
if (!Array.isArray(results) || results.length === 0) return [];
|
|
15155
|
-
if (safeLimit === 0) return [];
|
|
15156
|
-
const boosted = caps.recallReasoningTraceBoost && typeof retrievalQuery === "string" ? applyReasoningTraceBoost(results, {
|
|
15157
|
-
enabled: true,
|
|
15158
|
-
query: retrievalQuery
|
|
15159
|
-
}) : results;
|
|
15160
|
-
const diversified = this.applyMmrToQmdResults(sectionId, boosted, caps);
|
|
15161
|
-
return diversified.slice(0, safeLimit);
|
|
15260
|
+
return this.recallRerankCoordinator.diversifyAndLimitRecallResults(sectionId, results, limit, retrievalQuery, caps);
|
|
15162
15261
|
}
|
|
15163
|
-
/**
|
|
15164
|
-
* Apply Maximal Marginal Relevance to a section's ordered candidate list.
|
|
15165
|
-
*
|
|
15166
|
-
* Operates per-section so one redundant cluster cannot dominate a section,
|
|
15167
|
-
* and so one section's MMR pass cannot starve other sections. Returns the
|
|
15168
|
-
* input unchanged when disabled, when there are fewer than 2 candidates, or
|
|
15169
|
-
* when no budget information is available.
|
|
15170
|
-
*/
|
|
15171
15262
|
applyMmrToQmdResults(sectionId, results, caps = resolveCapabilities(this.config)) {
|
|
15172
|
-
|
|
15173
|
-
if (!Array.isArray(results) || results.length < 2) return results;
|
|
15174
|
-
const configuredTopN = this.config.recallMmrTopN;
|
|
15175
|
-
const topN = typeof configuredTopN === "number" && Number.isFinite(configuredTopN) ? Math.max(0, Math.floor(configuredTopN)) : 40;
|
|
15176
|
-
if (topN === 0) return results;
|
|
15177
|
-
const lambda = this.config.recallMmrLambda ?? 0.7;
|
|
15178
|
-
const { reordered, diversity } = reorderRecallResultsWithMmr(results, {
|
|
15179
|
-
lambda,
|
|
15180
|
-
topN
|
|
15181
|
-
});
|
|
15182
|
-
try {
|
|
15183
|
-
log.info(
|
|
15184
|
-
`recall_mmr: section=${sectionId} kept=${diversity.kept}/${diversity.considered} headReorderCount=${diversity.headReorderCount} avgSimBefore=${diversity.avgPairwiseSimBefore.toFixed(3)} avgSimAfter=${diversity.avgPairwiseSimAfter.toFixed(3)} lambda=${lambda.toFixed(2)}`
|
|
15185
|
-
);
|
|
15186
|
-
} catch {
|
|
15187
|
-
}
|
|
15188
|
-
return reordered;
|
|
15263
|
+
return this.recallRerankCoordinator.applyMmrToQmdResults(sectionId, results, caps);
|
|
15189
15264
|
}
|
|
15190
15265
|
buildLastRecallBudgetSummary(options) {
|
|
15191
15266
|
return {
|
|
@@ -15261,12 +15336,12 @@ ${reflectionsContent.trim()}
|
|
|
15261
15336
|
*/
|
|
15262
15337
|
semanticDedupScopeFor(targetStorage) {
|
|
15263
15338
|
if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
|
|
15264
|
-
const memoryDir =
|
|
15265
|
-
const storageDir =
|
|
15339
|
+
const memoryDir = path5.resolve(this.config.memoryDir);
|
|
15340
|
+
const storageDir = path5.resolve(targetStorage.dir);
|
|
15266
15341
|
if (storageDir === memoryDir) {
|
|
15267
15342
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
15268
15343
|
}
|
|
15269
|
-
let rel =
|
|
15344
|
+
let rel = path5.relative(memoryDir, storageDir);
|
|
15270
15345
|
if (!rel || rel.startsWith("..")) {
|
|
15271
15346
|
log.debug(
|
|
15272
15347
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -15285,7 +15360,7 @@ ${reflectionsContent.trim()}
|
|
|
15285
15360
|
if (hits.length === 0) return [];
|
|
15286
15361
|
const results = [];
|
|
15287
15362
|
for (const hit of hits) {
|
|
15288
|
-
const fullPath =
|
|
15363
|
+
const fullPath = path5.isAbsolute(hit.path) ? hit.path : path5.join(this.config.memoryDir, hit.path);
|
|
15289
15364
|
const memory = await this.storage.readMemoryByPath(fullPath);
|
|
15290
15365
|
if (!memory) continue;
|
|
15291
15366
|
results.push({
|
|
@@ -15482,7 +15557,7 @@ ${reflectionsContent.trim()}
|
|
|
15482
15557
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
15483
15558
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
15484
15559
|
if (!storageDir) continue;
|
|
15485
|
-
const recallRoot =
|
|
15560
|
+
const recallRoot = path5.resolve(storageDir);
|
|
15486
15561
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
15487
15562
|
seenRecallRoots.add(recallRoot);
|
|
15488
15563
|
recallRoots.push(recallRoot);
|
|
@@ -15506,8 +15581,8 @@ ${reflectionsContent.trim()}
|
|
|
15506
15581
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
15507
15582
|
continue;
|
|
15508
15583
|
}
|
|
15509
|
-
if (
|
|
15510
|
-
const resolvedPath =
|
|
15584
|
+
if (path5.isAbsolute(result.path)) {
|
|
15585
|
+
const resolvedPath = path5.resolve(result.path);
|
|
15511
15586
|
if (recallRoots.some(
|
|
15512
15587
|
(recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
|
|
15513
15588
|
)) {
|
|
@@ -15663,7 +15738,7 @@ ${reflectionsContent.trim()}
|
|
|
15663
15738
|
* Updates are batched in memory and flushed during consolidation.
|
|
15664
15739
|
*/
|
|
15665
15740
|
trackMemoryAccess(memoryIds) {
|
|
15666
|
-
if (!this.config.
|
|
15741
|
+
if (!resolveRecallEnhancementCapabilities(this.config).accessTracking) return;
|
|
15667
15742
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
15668
15743
|
for (const id of memoryIds) {
|
|
15669
15744
|
const existing = this.accessTrackingBuffer.get(id);
|
|
@@ -15963,7 +16038,7 @@ ${reflectionsContent.trim()}
|
|
|
15963
16038
|
temporalFromDate !== null ? queryByDateRangeAsync(this.config.memoryDir, temporalFromDate) : Promise.resolve(null),
|
|
15964
16039
|
promptTags.length > 0 ? queryByTagsAsync(this.config.memoryDir, promptTags) : Promise.resolve(null)
|
|
15965
16040
|
]);
|
|
15966
|
-
const queryIntent = this.config.
|
|
16041
|
+
const queryIntent = resolveConversationContextCapabilities(this.config).intentRouting && prompt ? inferIntentFromText(prompt) : null;
|
|
15967
16042
|
let temporalCandidates = null;
|
|
15968
16043
|
let tagCandidates = null;
|
|
15969
16044
|
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && prompt) {
|
|
@@ -16013,7 +16088,7 @@ ${reflectionsContent.trim()}
|
|
|
16013
16088
|
importanceBoost >= 0 ? "boost" : "suppress"
|
|
16014
16089
|
);
|
|
16015
16090
|
}
|
|
16016
|
-
if (this.config.
|
|
16091
|
+
if (resolveRecallEnhancementCapabilities(this.config).feedback) {
|
|
16017
16092
|
const match = memory.path.match(/([^/]+)\.md$/);
|
|
16018
16093
|
const memoryId = match ? match[1] : null;
|
|
16019
16094
|
if (memoryId) {
|
|
@@ -16025,7 +16100,7 @@ ${reflectionsContent.trim()}
|
|
|
16025
16100
|
);
|
|
16026
16101
|
}
|
|
16027
16102
|
}
|
|
16028
|
-
if (this.config.
|
|
16103
|
+
if (resolvePipelineProcessingCapabilities(this.config).negativeExamples) {
|
|
16029
16104
|
const match = memory.path.match(/([^/]+)\.md$/);
|
|
16030
16105
|
const memoryId = match ? match[1] : null;
|
|
16031
16106
|
if (memoryId) {
|
|
@@ -16080,7 +16155,7 @@ ${reflectionsContent.trim()}
|
|
|
16080
16155
|
lifecycleDelta >= 0 ? "boost" : "suppress"
|
|
16081
16156
|
);
|
|
16082
16157
|
let reinforcementBoost = 0;
|
|
16083
|
-
if (this.config.
|
|
16158
|
+
if (resolveRecallEnhancementCapabilities(this.config).reinforcementRecallBoost && typeof memory.frontmatter.reinforcement_count === "number" && memory.frontmatter.reinforcement_count > 0) {
|
|
16084
16159
|
reinforcementBoost = Math.min(
|
|
16085
16160
|
memory.frontmatter.reinforcement_count * this.config.reinforcementRecallBoostWeight,
|
|
16086
16161
|
this.config.reinforcementRecallBoostMax
|
|
@@ -16441,4 +16516,4 @@ export {
|
|
|
16441
16516
|
resolvePersistedMemoryRelativePath,
|
|
16442
16517
|
Orchestrator
|
|
16443
16518
|
};
|
|
16444
|
-
//# sourceMappingURL=chunk-
|
|
16519
|
+
//# sourceMappingURL=chunk-VC7QELR6.js.map
|