@remnic/core 9.3.734 → 9.3.736
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 +8 -6
- package/dist/access-boundary.js +9 -9
- package/dist/access-cli.js +24 -24
- package/dist/access-http.d.ts +8 -6
- package/dist/access-http.js +14 -14
- package/dist/access-mcp.d.ts +8 -6
- package/dist/access-mcp.js +13 -13
- package/dist/access-operations-batch.js +11 -11
- package/dist/access-operations.d.ts +8 -6
- package/dist/access-operations.js +12 -12
- package/dist/{access-service-rjFfmfKB.d.ts → access-service-CdC0q4pr.d.ts} +3 -3
- package/dist/access-service.d.ts +8 -6
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +8 -6
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +7 -5
- package/dist/briefing.d.ts +1 -1
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +101 -2
- package/dist/capabilities.js +13 -3
- package/dist/{catalog-DHYXzM4-.d.ts → catalog-D2NLDg4S.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-IWMGBNXY.js → chunk-2T2N7ISV.js} +3 -3
- package/dist/{chunk-K7PAILHO.js → chunk-5BOQNB2K.js} +3 -3
- package/dist/{chunk-Q5LGXWNG.js → chunk-AAIHDIMD.js} +6 -6
- package/dist/{chunk-WHQ2JB35.js → chunk-AB2E5DCN.js} +2 -2
- package/dist/{chunk-Z7J3OAPR.js → chunk-AE2HPUP7.js} +726 -645
- package/dist/chunk-AE2HPUP7.js.map +1 -0
- package/dist/{chunk-FAGERSH2.js → chunk-AE7NTZ75.js} +3 -3
- package/dist/{chunk-V5OVSGB6.js → chunk-AESC5OQJ.js} +2 -2
- package/dist/{chunk-7FPJFCXL.js → chunk-BXPG5AVX.js} +4 -4
- package/dist/{chunk-UH3NYOHN.js → chunk-CHJIWG2H.js} +2 -2
- package/dist/{chunk-IDIXGGDN.js → chunk-E4LYJ7PY.js} +6 -6
- package/dist/{chunk-WTTVFSCO.js → chunk-FF36YNKY.js} +3 -3
- package/dist/{chunk-TJSQHO4Q.js → chunk-FLPKEMSO.js} +2 -2
- package/dist/{chunk-UF3N7IRP.js → chunk-G54IDCD3.js} +45 -41
- package/dist/chunk-G54IDCD3.js.map +1 -0
- package/dist/{chunk-UK6U5C3N.js → chunk-GB2FZOWB.js} +3 -3
- package/dist/{chunk-5OYHJIJN.js → chunk-GYICIICQ.js} +3 -3
- package/dist/{chunk-PEF2XOIV.js → chunk-HFXZIF3V.js} +3 -3
- package/dist/{chunk-PKO5NJ65.js → chunk-HLPYL6LC.js} +27 -24
- package/dist/chunk-HLPYL6LC.js.map +1 -0
- package/dist/{chunk-ET5HXSQL.js → chunk-IPI45Q4S.js} +2 -2
- package/dist/{chunk-2L5RTVMO.js → chunk-IX4L7E5G.js} +2 -2
- package/dist/{chunk-SYX73XD7.js → chunk-IXGXALRV.js} +10 -7
- package/dist/chunk-IXGXALRV.js.map +1 -0
- package/dist/{chunk-SHJGBAIW.js → chunk-JWDE7OVJ.js} +44 -2
- package/dist/{chunk-SHJGBAIW.js.map → chunk-JWDE7OVJ.js.map} +1 -1
- package/dist/{chunk-IZLTOS5L.js → chunk-K3Y2SJTN.js} +4 -4
- package/dist/{chunk-CILX2XW7.js → chunk-NDKW67ER.js} +2 -2
- package/dist/{chunk-54RCE5Z3.js → chunk-NNJKEAP2.js} +2 -2
- package/dist/{chunk-LV32K4OP.js → chunk-OYHYBHHI.js} +2 -2
- package/dist/{chunk-5DIKZKOD.js → chunk-P6VLG7KE.js} +2 -2
- package/dist/{chunk-T7CGPTFU.js → chunk-QNTLWH3T.js} +3 -3
- package/dist/{chunk-6U7TES2M.js → chunk-UO6MPN77.js} +13 -12
- package/dist/chunk-UO6MPN77.js.map +1 -0
- package/dist/{chunk-NDYQIN6C.js → chunk-VOEVVIP3.js} +3 -3
- package/dist/{chunk-3QETM5NG.js → chunk-ZBZ4XULO.js} +3 -3
- package/dist/{cli-XVpmSoQs.d.ts → cli-BHy6Bo6u.d.ts} +3 -3
- package/dist/cli.d.ts +9 -7
- package/dist/cli.js +20 -20
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +2 -2
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-OUHMCUBT.js → contradiction-scan-2B4AE4TI.js} +3 -3
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +2 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +7 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-W4U6XDKI.js → first-start-migration-2RQYDIZ7.js} +6 -5
- package/dist/first-start-migration-2RQYDIZ7.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +30 -30
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +8 -6
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +2 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -6
- package/dist/{orchestrator-BXi-gadS.d.ts → orchestrator-C-xp_rtZ.d.ts} +141 -18
- package/dist/orchestrator.d.ts +7 -5
- package/dist/orchestrator.js +19 -21
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-DeL5grLx.d.ts → semantic-consolidation-COdwU-me.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-LSM35HZY.js → tier-stats-KPDIISG7.js} +6 -5
- package/dist/tier-stats-KPDIISG7.js.map +1 -0
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CpFz51Pv.d.ts → types-w3Y232yi.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-service.ts +20 -20
- package/src/capabilities.test.ts +197 -0
- package/src/capabilities.ts +206 -0
- package/src/cli/creation-ledger-commands.ts +2 -2
- package/src/cli/research-status-commands.ts +13 -13
- package/src/cli.ts +17 -17
- package/src/maintenance/first-start-migration.ts +3 -3
- package/src/maintenance/tier-stats.ts +3 -3
- package/src/operator-toolkit.ts +8 -8
- package/src/orchestration/compression-guideline-coordinator.ts +7 -6
- package/src/orchestration/entity-synthesis-coordinator.ts +319 -0
- package/src/orchestration/lifecycle-policy-coordinator.ts +504 -0
- package/src/orchestrator.ts +40 -618
- package/dist/chunk-6U7TES2M.js.map +0 -1
- package/dist/chunk-PKO5NJ65.js.map +0 -1
- package/dist/chunk-SYX73XD7.js.map +0 -1
- package/dist/chunk-UF3N7IRP.js.map +0 -1
- package/dist/chunk-Z7J3OAPR.js.map +0 -1
- package/dist/first-start-migration-W4U6XDKI.js.map +0 -1
- package/dist/tier-stats-LSM35HZY.js.map +0 -1
- /package/dist/{chunk-IWMGBNXY.js.map → chunk-2T2N7ISV.js.map} +0 -0
- /package/dist/{chunk-K7PAILHO.js.map → chunk-5BOQNB2K.js.map} +0 -0
- /package/dist/{chunk-Q5LGXWNG.js.map → chunk-AAIHDIMD.js.map} +0 -0
- /package/dist/{chunk-WHQ2JB35.js.map → chunk-AB2E5DCN.js.map} +0 -0
- /package/dist/{chunk-FAGERSH2.js.map → chunk-AE7NTZ75.js.map} +0 -0
- /package/dist/{chunk-V5OVSGB6.js.map → chunk-AESC5OQJ.js.map} +0 -0
- /package/dist/{chunk-7FPJFCXL.js.map → chunk-BXPG5AVX.js.map} +0 -0
- /package/dist/{chunk-UH3NYOHN.js.map → chunk-CHJIWG2H.js.map} +0 -0
- /package/dist/{chunk-IDIXGGDN.js.map → chunk-E4LYJ7PY.js.map} +0 -0
- /package/dist/{chunk-WTTVFSCO.js.map → chunk-FF36YNKY.js.map} +0 -0
- /package/dist/{chunk-TJSQHO4Q.js.map → chunk-FLPKEMSO.js.map} +0 -0
- /package/dist/{chunk-UK6U5C3N.js.map → chunk-GB2FZOWB.js.map} +0 -0
- /package/dist/{chunk-5OYHJIJN.js.map → chunk-GYICIICQ.js.map} +0 -0
- /package/dist/{chunk-PEF2XOIV.js.map → chunk-HFXZIF3V.js.map} +0 -0
- /package/dist/{chunk-ET5HXSQL.js.map → chunk-IPI45Q4S.js.map} +0 -0
- /package/dist/{chunk-2L5RTVMO.js.map → chunk-IX4L7E5G.js.map} +0 -0
- /package/dist/{chunk-IZLTOS5L.js.map → chunk-K3Y2SJTN.js.map} +0 -0
- /package/dist/{chunk-CILX2XW7.js.map → chunk-NDKW67ER.js.map} +0 -0
- /package/dist/{chunk-54RCE5Z3.js.map → chunk-NNJKEAP2.js.map} +0 -0
- /package/dist/{chunk-LV32K4OP.js.map → chunk-OYHYBHHI.js.map} +0 -0
- /package/dist/{chunk-5DIKZKOD.js.map → chunk-P6VLG7KE.js.map} +0 -0
- /package/dist/{chunk-T7CGPTFU.js.map → chunk-QNTLWH3T.js.map} +0 -0
- /package/dist/{chunk-NDYQIN6C.js.map → chunk-VOEVVIP3.js.map} +0 -0
- /package/dist/{chunk-3QETM5NG.js.map → chunk-ZBZ4XULO.js.map} +0 -0
- /package/dist/{contradiction-scan-OUHMCUBT.js.map → contradiction-scan-2B4AE4TI.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-IXGXALRV.js";
|
|
11
11
|
import {
|
|
12
12
|
MaintenanceScheduler
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-GYICIICQ.js";
|
|
14
14
|
import {
|
|
15
15
|
runPeerProfileReasoner
|
|
16
16
|
} from "./chunk-I74SUMNI.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
CompoundingEngine,
|
|
31
31
|
defaultTierMigrationCycleBudget
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-IPI45Q4S.js";
|
|
33
33
|
import {
|
|
34
34
|
SharedContextManager
|
|
35
35
|
} from "./chunk-UFS7OXGL.js";
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
} from "./chunk-UHGBNIOS.js";
|
|
64
64
|
import {
|
|
65
65
|
HourlySummarizer
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-HFXZIF3V.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-FF36YNKY.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-IX4L7E5G.js";
|
|
173
173
|
import {
|
|
174
174
|
buildFocusedListRecallSection,
|
|
175
175
|
shouldRecallFocusedListEvidence
|
|
@@ -193,12 +193,12 @@ import {
|
|
|
193
193
|
} from "./chunk-Q6IP2ARR.js";
|
|
194
194
|
import {
|
|
195
195
|
EmbeddingFallback
|
|
196
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-CHJIWG2H.js";
|
|
197
197
|
import {
|
|
198
198
|
buildEntityRecallSection,
|
|
199
199
|
entityRecentTranscriptLookbackHours,
|
|
200
200
|
readRecentEntityTranscriptEntries
|
|
201
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-AESC5OQJ.js";
|
|
202
202
|
import {
|
|
203
203
|
RoutingRulesStore
|
|
204
204
|
} from "./chunk-WIWPSQYU.js";
|
|
@@ -228,14 +228,14 @@ import {
|
|
|
228
228
|
import {
|
|
229
229
|
runNamespaceMaintenanceFanout,
|
|
230
230
|
summarizeNamespaceMaintenanceHealth
|
|
231
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-AE7NTZ75.js";
|
|
232
232
|
import {
|
|
233
233
|
NamespaceCatalog,
|
|
234
234
|
planNamespaceMaintenance
|
|
235
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-BXPG5AVX.js";
|
|
236
236
|
import {
|
|
237
237
|
NamespaceStorageRouter
|
|
238
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-NNJKEAP2.js";
|
|
239
239
|
import {
|
|
240
240
|
searchHarmonicRetrieval
|
|
241
241
|
} from "./chunk-AV5ZEH4M.js";
|
|
@@ -333,14 +333,14 @@ import {
|
|
|
333
333
|
resolveNamespaceFromStorageDir,
|
|
334
334
|
resolveScopePlan,
|
|
335
335
|
resolveScopeProfilePlan
|
|
336
|
-
} from "./chunk-
|
|
336
|
+
} from "./chunk-GB2FZOWB.js";
|
|
337
337
|
import {
|
|
338
338
|
NamespaceSearchRouter
|
|
339
|
-
} from "./chunk-
|
|
339
|
+
} from "./chunk-ZBZ4XULO.js";
|
|
340
340
|
import {
|
|
341
341
|
createConversationIndexRuntime,
|
|
342
342
|
createSearchBackend
|
|
343
|
-
} from "./chunk-
|
|
343
|
+
} from "./chunk-5BOQNB2K.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-NDKW67ER.js";
|
|
367
367
|
import {
|
|
368
368
|
searchCausalTrajectories
|
|
369
369
|
} from "./chunk-SQNED75R.js";
|
|
@@ -465,18 +465,23 @@ import {
|
|
|
465
465
|
defaultNamespaceForPrincipal,
|
|
466
466
|
recallNamespacesForPrincipal,
|
|
467
467
|
resolvePrincipal
|
|
468
|
-
} from "./chunk-
|
|
468
|
+
} from "./chunk-OYHYBHHI.js";
|
|
469
469
|
import {
|
|
470
470
|
resolveCapabilities,
|
|
471
|
+
resolveCompressionCapabilities,
|
|
471
472
|
resolveCreationMemoryCapabilities,
|
|
473
|
+
resolveEvalCapabilities,
|
|
472
474
|
resolveGraphConstructionCapabilities,
|
|
473
475
|
resolveIdentityContinuityCapabilities,
|
|
474
476
|
resolveIndexingCapabilities,
|
|
475
477
|
resolveLocalLlmCapabilities,
|
|
476
478
|
resolveMemoryLifecycleCapabilities,
|
|
477
479
|
resolveNamespaceCapabilities,
|
|
478
|
-
|
|
479
|
-
|
|
480
|
+
resolveObjectiveStateCapabilities,
|
|
481
|
+
resolveQmdCapabilities,
|
|
482
|
+
resolveSecurityCapabilities,
|
|
483
|
+
resolveUtilityLearningCapabilities
|
|
484
|
+
} from "./chunk-JWDE7OVJ.js";
|
|
480
485
|
import {
|
|
481
486
|
isSafeRouteNamespace,
|
|
482
487
|
selectRouteRule
|
|
@@ -501,19 +506,19 @@ import {
|
|
|
501
506
|
} from "./chunk-PVGDJXVK.js";
|
|
502
507
|
|
|
503
508
|
// src/orchestrator.ts
|
|
504
|
-
import
|
|
509
|
+
import path4 from "path";
|
|
505
510
|
import os2 from "os";
|
|
506
|
-
import { createHash, randomBytes } from "crypto";
|
|
511
|
+
import { createHash as createHash2, randomBytes } from "crypto";
|
|
507
512
|
import { existsSync, readFileSync } from "fs";
|
|
508
513
|
import {
|
|
509
514
|
lstat,
|
|
510
|
-
mkdir as
|
|
515
|
+
mkdir as mkdir3,
|
|
511
516
|
readdir,
|
|
512
517
|
readFile as readFile2,
|
|
513
518
|
realpath,
|
|
514
519
|
stat,
|
|
515
520
|
unlink,
|
|
516
|
-
writeFile as
|
|
521
|
+
writeFile as writeFile3
|
|
517
522
|
} from "fs/promises";
|
|
518
523
|
|
|
519
524
|
// src/procedural/procedure-recall.ts
|
|
@@ -1065,68 +1070,559 @@ var SemanticConsolidationCoordinator = class {
|
|
|
1065
1070
|
result.memoriesArchived++;
|
|
1066
1071
|
}
|
|
1067
1072
|
}
|
|
1068
|
-
log.info(
|
|
1069
|
-
`[semantic-consolidation] consolidated ${cluster.memories.length} memories \u2192 ${canonicalId}`
|
|
1070
|
-
);
|
|
1071
|
-
} catch (err) {
|
|
1072
|
-
log.warn(
|
|
1073
|
-
`[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1074
|
-
);
|
|
1075
|
-
result.errors++;
|
|
1076
|
-
} finally {
|
|
1077
|
-
if (canonicalWriteCompleted) {
|
|
1073
|
+
log.info(
|
|
1074
|
+
`[semantic-consolidation] consolidated ${cluster.memories.length} memories \u2192 ${canonicalId}`
|
|
1075
|
+
);
|
|
1076
|
+
} catch (err) {
|
|
1077
|
+
log.warn(
|
|
1078
|
+
`[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`
|
|
1079
|
+
);
|
|
1080
|
+
result.errors++;
|
|
1081
|
+
} finally {
|
|
1082
|
+
if (canonicalWriteCompleted) {
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
if (result.memoriesArchived > 0) {
|
|
1087
|
+
await this.deps.saveContentHashIndexes().catch(
|
|
1088
|
+
(err) => log.warn(
|
|
1089
|
+
`[semantic-consolidation] content-hash index save failed: ${err}`
|
|
1090
|
+
)
|
|
1091
|
+
);
|
|
1092
|
+
}
|
|
1093
|
+
log.info(
|
|
1094
|
+
`[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`
|
|
1095
|
+
);
|
|
1096
|
+
try {
|
|
1097
|
+
await materializeAfterSemanticConsolidation({
|
|
1098
|
+
config: this.config,
|
|
1099
|
+
memoryDir: targetStorage.dir
|
|
1100
|
+
});
|
|
1101
|
+
} catch (err) {
|
|
1102
|
+
log.warn(
|
|
1103
|
+
`[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
if (this.config.peerProfileReasonerEnabled) {
|
|
1107
|
+
try {
|
|
1108
|
+
const peerLlm = new FallbackLlmClient(
|
|
1109
|
+
this.config.gatewayConfig,
|
|
1110
|
+
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
1111
|
+
);
|
|
1112
|
+
const peerResult = await runPeerProfileReasoner({
|
|
1113
|
+
memoryDir: targetStorage.dir,
|
|
1114
|
+
enabled: true,
|
|
1115
|
+
llm: peerLlm,
|
|
1116
|
+
model: this.config.peerProfileReasonerModel,
|
|
1117
|
+
minInteractions: this.config.peerProfileReasonerMinInteractions,
|
|
1118
|
+
maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
|
|
1119
|
+
log: {
|
|
1120
|
+
debug: (msg) => log.debug(msg),
|
|
1121
|
+
info: (msg) => log.info(msg),
|
|
1122
|
+
warn: (msg) => log.warn(msg)
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
log.info(
|
|
1126
|
+
`[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`
|
|
1127
|
+
);
|
|
1128
|
+
} catch (err) {
|
|
1129
|
+
log.warn(
|
|
1130
|
+
`[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
1131
|
+
);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return result;
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// src/orchestration/lifecycle-policy-coordinator.ts
|
|
1139
|
+
import path2 from "path";
|
|
1140
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
1141
|
+
var LifecyclePolicyCoordinator = class {
|
|
1142
|
+
constructor(deps) {
|
|
1143
|
+
this.deps = deps;
|
|
1144
|
+
}
|
|
1145
|
+
deps;
|
|
1146
|
+
get config() {
|
|
1147
|
+
return this.deps.config;
|
|
1148
|
+
}
|
|
1149
|
+
// -------------------------------------------------------------------------
|
|
1150
|
+
// Action-outcome priors (feeds lifecycle transition decisions)
|
|
1151
|
+
// -------------------------------------------------------------------------
|
|
1152
|
+
actionOutcomePriorDelta(event) {
|
|
1153
|
+
if (event.outcome === "failed") return -0.3;
|
|
1154
|
+
if (event.policyDecision === "deny") return -0.22;
|
|
1155
|
+
if (event.policyDecision === "defer") return -0.14;
|
|
1156
|
+
if (event.outcome === "skipped") return -0.1;
|
|
1157
|
+
if (event.outcome !== "applied") return 0;
|
|
1158
|
+
switch (event.action) {
|
|
1159
|
+
case "store_episode":
|
|
1160
|
+
case "store_note":
|
|
1161
|
+
case "update_note":
|
|
1162
|
+
return 0.08;
|
|
1163
|
+
case "create_artifact":
|
|
1164
|
+
case "summarize_node":
|
|
1165
|
+
case "link_graph":
|
|
1166
|
+
return 0.04;
|
|
1167
|
+
case "discard":
|
|
1168
|
+
return -0.03;
|
|
1169
|
+
default:
|
|
1170
|
+
return 0;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
async buildLifecycleActionPriors(storage = this.deps.getStorage()) {
|
|
1174
|
+
const events = await storage.readMemoryActionEvents(1200);
|
|
1175
|
+
if (events.length === 0) return /* @__PURE__ */ new Map();
|
|
1176
|
+
const nowMs = Date.now();
|
|
1177
|
+
const windowMs = 14 * 24 * 60 * 60 * 1e3;
|
|
1178
|
+
const byMemory = /* @__PURE__ */ new Map();
|
|
1179
|
+
for (const event of events) {
|
|
1180
|
+
if (typeof event.memoryId !== "string" || event.memoryId.trim().length === 0)
|
|
1181
|
+
continue;
|
|
1182
|
+
const ts = Date.parse(event.timestamp);
|
|
1183
|
+
if (!Number.isFinite(ts)) continue;
|
|
1184
|
+
const ageMs = nowMs - ts;
|
|
1185
|
+
if (ageMs < 0 || ageMs > windowMs) continue;
|
|
1186
|
+
const delta = this.actionOutcomePriorDelta(event);
|
|
1187
|
+
if (delta === 0) continue;
|
|
1188
|
+
const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
|
|
1189
|
+
const list = byMemory.get(event.memoryId) ?? [];
|
|
1190
|
+
if (list.length >= 8) list.shift();
|
|
1191
|
+
list.push({
|
|
1192
|
+
weightedDelta: delta * recencyWeight,
|
|
1193
|
+
weight: recencyWeight
|
|
1194
|
+
});
|
|
1195
|
+
byMemory.set(event.memoryId, list);
|
|
1196
|
+
}
|
|
1197
|
+
const out = /* @__PURE__ */ new Map();
|
|
1198
|
+
for (const [memoryId, deltas] of byMemory.entries()) {
|
|
1199
|
+
if (deltas.length === 0) continue;
|
|
1200
|
+
const weightedSum = deltas.reduce(
|
|
1201
|
+
(sum, item) => sum + item.weightedDelta,
|
|
1202
|
+
0
|
|
1203
|
+
);
|
|
1204
|
+
const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
|
|
1205
|
+
if (weightTotal <= 0) continue;
|
|
1206
|
+
const score = weightedSum / weightTotal;
|
|
1207
|
+
out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
|
|
1208
|
+
}
|
|
1209
|
+
return out;
|
|
1210
|
+
}
|
|
1211
|
+
// -------------------------------------------------------------------------
|
|
1212
|
+
// Lifecycle policy pass (heat/decay scoring + transition)
|
|
1213
|
+
// -------------------------------------------------------------------------
|
|
1214
|
+
async runLifecyclePolicyPass(allMemories, storage = this.deps.getStorage()) {
|
|
1215
|
+
const now = /* @__PURE__ */ new Date();
|
|
1216
|
+
const nowIso = now.toISOString();
|
|
1217
|
+
const countsByState = {
|
|
1218
|
+
candidate: 0,
|
|
1219
|
+
validated: 0,
|
|
1220
|
+
active: 0,
|
|
1221
|
+
stale: 0,
|
|
1222
|
+
archived: 0
|
|
1223
|
+
};
|
|
1224
|
+
const transitionCounts = {};
|
|
1225
|
+
let updatedCount = 0;
|
|
1226
|
+
let disputedCount = 0;
|
|
1227
|
+
let evaluatedCount = 0;
|
|
1228
|
+
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
1229
|
+
const thresholds = this.deps.getEffectiveLifecycleThresholds();
|
|
1230
|
+
const policy = {
|
|
1231
|
+
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
1232
|
+
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
1233
|
+
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
1234
|
+
protectedCategories: this.config.lifecycleProtectedCategories
|
|
1235
|
+
};
|
|
1236
|
+
const actionPriors = await this.buildLifecycleActionPriors(storage);
|
|
1237
|
+
for (const memory of allMemories) {
|
|
1238
|
+
if (memory.frontmatter.status === "superseded" || memory.frontmatter.status === "forgotten") {
|
|
1239
|
+
continue;
|
|
1240
|
+
}
|
|
1241
|
+
evaluatedCount += 1;
|
|
1242
|
+
const currentState = resolveLifecycleState(memory.frontmatter);
|
|
1243
|
+
const actionPriorScore = actionPriors.get(memory.frontmatter.id);
|
|
1244
|
+
const signals = typeof actionPriorScore === "number" && Number.isFinite(actionPriorScore) ? { actionPriorScore } : void 0;
|
|
1245
|
+
const decision = decideLifecycleTransition(memory, policy, now, signals);
|
|
1246
|
+
const nextState = memory.frontmatter.status === "archived" ? "archived" : decision.nextState;
|
|
1247
|
+
countsByState[nextState] += 1;
|
|
1248
|
+
if (memory.frontmatter.verificationState === "disputed") {
|
|
1249
|
+
disputedCount += 1;
|
|
1250
|
+
}
|
|
1251
|
+
if (nextState !== currentState) {
|
|
1252
|
+
const key = `${currentState}->${nextState}`;
|
|
1253
|
+
transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
|
|
1254
|
+
}
|
|
1255
|
+
const prevHeat = memory.frontmatter.heatScore;
|
|
1256
|
+
const prevDecay = memory.frontmatter.decayScore;
|
|
1257
|
+
const scoreDelta = Math.abs((prevHeat ?? -1) - decision.heatScore) + Math.abs((prevDecay ?? -1) - decision.decayScore);
|
|
1258
|
+
const shouldPersist = memory.frontmatter.lifecycleState !== nextState || memory.frontmatter.heatScore === void 0 || memory.frontmatter.decayScore === void 0 || memory.frontmatter.lastValidatedAt === void 0 || scoreDelta >= 0.01;
|
|
1259
|
+
if (!shouldPersist) continue;
|
|
1260
|
+
const wrote = await storage.writeMemoryFrontmatter(memory, {
|
|
1261
|
+
lifecycleState: nextState,
|
|
1262
|
+
heatScore: decision.heatScore,
|
|
1263
|
+
decayScore: decision.decayScore,
|
|
1264
|
+
lastValidatedAt: nowIso
|
|
1265
|
+
});
|
|
1266
|
+
if (wrote) updatedCount += 1;
|
|
1267
|
+
}
|
|
1268
|
+
if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
|
|
1269
|
+
const total = evaluatedCount;
|
|
1270
|
+
const metrics = {
|
|
1271
|
+
generatedAt: nowIso,
|
|
1272
|
+
memoriesEvaluated: total,
|
|
1273
|
+
memoriesUpdated: updatedCount,
|
|
1274
|
+
countsByLifecycleState: countsByState,
|
|
1275
|
+
transitionCounts,
|
|
1276
|
+
staleRatio: total > 0 ? countsByState.stale / total : 0,
|
|
1277
|
+
disputedRatio: total > 0 ? disputedCount / total : 0,
|
|
1278
|
+
policy: {
|
|
1279
|
+
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
1280
|
+
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
1281
|
+
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
1282
|
+
protectedCategories: this.config.lifecycleProtectedCategories
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
const metricsPath = path2.join(
|
|
1286
|
+
storage.dir,
|
|
1287
|
+
"state",
|
|
1288
|
+
"lifecycle-metrics.json"
|
|
1289
|
+
);
|
|
1290
|
+
await mkdir(path2.dirname(metricsPath), { recursive: true });
|
|
1291
|
+
await writeFile(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
|
|
1292
|
+
return updatedCount;
|
|
1293
|
+
}
|
|
1294
|
+
// -------------------------------------------------------------------------
|
|
1295
|
+
// Fact archival
|
|
1296
|
+
// -------------------------------------------------------------------------
|
|
1297
|
+
/**
|
|
1298
|
+
* Archive old, low-importance, rarely-accessed facts (v6.0).
|
|
1299
|
+
* Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
|
|
1300
|
+
* Returns the number of archived facts.
|
|
1301
|
+
*/
|
|
1302
|
+
async runFactArchival(allMemories) {
|
|
1303
|
+
const storage = this.deps.getStorage();
|
|
1304
|
+
const now = Date.now();
|
|
1305
|
+
const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1e3;
|
|
1306
|
+
const protectedCategories = new Set(
|
|
1307
|
+
this.config.factArchivalProtectedCategories
|
|
1308
|
+
);
|
|
1309
|
+
let archivedCount = 0;
|
|
1310
|
+
for (const memory of allMemories) {
|
|
1311
|
+
const fm = memory.frontmatter;
|
|
1312
|
+
if (fm.status && fm.status !== "active") continue;
|
|
1313
|
+
if (protectedCategories.has(fm.category)) continue;
|
|
1314
|
+
if (fm.category === "correction") continue;
|
|
1315
|
+
const createdMs = new Date(fm.created).getTime();
|
|
1316
|
+
if (now - createdMs < ageCutoffMs) continue;
|
|
1317
|
+
const importanceScore = fm.importance?.score ?? 0.5;
|
|
1318
|
+
if (importanceScore >= this.config.factArchivalMaxImportance) continue;
|
|
1319
|
+
const accessCount = fm.accessCount ?? 0;
|
|
1320
|
+
if (accessCount > this.config.factArchivalMaxAccessCount) continue;
|
|
1321
|
+
const result = await storage.archiveMemory(memory);
|
|
1322
|
+
if (result) {
|
|
1323
|
+
await this.deps.removeContentHashForMemory(
|
|
1324
|
+
storage,
|
|
1325
|
+
memory,
|
|
1326
|
+
"fact-archival"
|
|
1327
|
+
);
|
|
1328
|
+
await this.deps.embeddingFallback.removeFromIndex(memory.frontmatter.id);
|
|
1329
|
+
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && memory.path && memory.frontmatter?.created) {
|
|
1330
|
+
deindexMemory(
|
|
1331
|
+
this.config.memoryDir,
|
|
1332
|
+
memory.path,
|
|
1333
|
+
memory.frontmatter.created,
|
|
1334
|
+
memory.frontmatter.tags ?? []
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
archivedCount++;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
if (archivedCount > 0) {
|
|
1341
|
+
await this.deps.saveContentHashIndexes().catch(
|
|
1342
|
+
(err) => log.warn(`content-hash index save failed during archival: ${err}`)
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
return archivedCount;
|
|
1346
|
+
}
|
|
1347
|
+
// -------------------------------------------------------------------------
|
|
1348
|
+
// Summarization (Phase 4A)
|
|
1349
|
+
// -------------------------------------------------------------------------
|
|
1350
|
+
/**
|
|
1351
|
+
* Run memory summarization if memory count exceeds threshold (Phase 4A).
|
|
1352
|
+
*/
|
|
1353
|
+
async runSummarization(allMemories) {
|
|
1354
|
+
const storage = this.deps.getStorage();
|
|
1355
|
+
const activeMemories = allMemories.filter(
|
|
1356
|
+
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
1357
|
+
);
|
|
1358
|
+
if (activeMemories.length < this.config.summarizationTriggerCount) {
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
log.info(
|
|
1362
|
+
`memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) \u2014 running summarization`
|
|
1363
|
+
);
|
|
1364
|
+
const sorted = activeMemories.sort(
|
|
1365
|
+
(a, b) => new Date(a.frontmatter.created).getTime() - new Date(b.frontmatter.created).getTime()
|
|
1366
|
+
);
|
|
1367
|
+
const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
|
|
1368
|
+
const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
|
|
1369
|
+
const candidates = toSummarize.filter((m) => {
|
|
1370
|
+
if (m.frontmatter.entityRef) return false;
|
|
1371
|
+
const protectedTags = this.config.summarizationProtectedTags;
|
|
1372
|
+
if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
|
|
1373
|
+
return false;
|
|
1374
|
+
const importance = m.frontmatter.importance?.score ?? 0.5;
|
|
1375
|
+
if (importance >= this.config.summarizationImportanceThreshold)
|
|
1376
|
+
return false;
|
|
1377
|
+
return true;
|
|
1378
|
+
});
|
|
1379
|
+
if (candidates.length < 50) {
|
|
1380
|
+
log.debug(
|
|
1381
|
+
`only ${candidates.length} candidates for summarization \u2014 skipping`
|
|
1382
|
+
);
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
const batchSize = 50;
|
|
1386
|
+
for (let i = 0; i < candidates.length; i += batchSize) {
|
|
1387
|
+
const batch = candidates.slice(i, i + batchSize);
|
|
1388
|
+
const batchData = batch.map((m) => ({
|
|
1389
|
+
id: m.frontmatter.id,
|
|
1390
|
+
content: m.content,
|
|
1391
|
+
category: m.frontmatter.category,
|
|
1392
|
+
created: m.frontmatter.created
|
|
1393
|
+
}));
|
|
1394
|
+
const result = await this.deps.extraction.summarizeMemories(batchData);
|
|
1395
|
+
if (!result) continue;
|
|
1396
|
+
const summary = {
|
|
1397
|
+
id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
1398
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1399
|
+
timeRangeStart: batch[0].frontmatter.created,
|
|
1400
|
+
timeRangeEnd: batch[batch.length - 1].frontmatter.created,
|
|
1401
|
+
summaryText: result.summaryText,
|
|
1402
|
+
keyFacts: result.keyFacts,
|
|
1403
|
+
keyEntities: result.keyEntities,
|
|
1404
|
+
sourceEpisodeIds: batch.map((m) => m.frontmatter.id)
|
|
1405
|
+
};
|
|
1406
|
+
await storage.writeSummary(summary);
|
|
1407
|
+
const archived = await storage.archiveMemories(
|
|
1408
|
+
batch.map((m) => m.frontmatter.id),
|
|
1409
|
+
summary.id
|
|
1410
|
+
);
|
|
1411
|
+
log.info(
|
|
1412
|
+
`created summary ${summary.id} from ${batch.length} memories, archived ${archived}`
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
// -------------------------------------------------------------------------
|
|
1417
|
+
// Topic extraction (Phase 4B)
|
|
1418
|
+
// -------------------------------------------------------------------------
|
|
1419
|
+
/**
|
|
1420
|
+
* Run topic extraction on all memories (Phase 4B).
|
|
1421
|
+
*/
|
|
1422
|
+
async runTopicExtraction(allMemories) {
|
|
1423
|
+
const storage = this.deps.getStorage();
|
|
1424
|
+
const activeMemories = allMemories.filter(
|
|
1425
|
+
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
1426
|
+
);
|
|
1427
|
+
if (activeMemories.length === 0) return;
|
|
1428
|
+
const topics = extractTopics(
|
|
1429
|
+
activeMemories,
|
|
1430
|
+
this.config.topicExtractionTopN
|
|
1431
|
+
);
|
|
1432
|
+
await storage.saveTopics(topics);
|
|
1433
|
+
log.debug(
|
|
1434
|
+
`extracted ${topics.length} topics from ${activeMemories.length} memories`
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
// src/orchestration/entity-synthesis-coordinator.ts
|
|
1440
|
+
import { createHash } from "crypto";
|
|
1441
|
+
function dedupeEntitySynthesisEvidenceEntries(entries) {
|
|
1442
|
+
const dedupedEvidenceEntries = [];
|
|
1443
|
+
const evidenceByFact = /* @__PURE__ */ new Map();
|
|
1444
|
+
for (const entry of entries) {
|
|
1445
|
+
const normalizedFact = entry.text.trim();
|
|
1446
|
+
if (!normalizedFact) continue;
|
|
1447
|
+
const existing = evidenceByFact.get(normalizedFact);
|
|
1448
|
+
if (!existing) {
|
|
1449
|
+
evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
|
|
1450
|
+
continue;
|
|
1451
|
+
}
|
|
1452
|
+
if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
|
|
1453
|
+
existing.newest = entry;
|
|
1454
|
+
}
|
|
1455
|
+
if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
|
|
1456
|
+
existing.oldest = entry;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
for (const { newest, oldest } of evidenceByFact.values()) {
|
|
1460
|
+
dedupedEvidenceEntries.push(newest);
|
|
1461
|
+
const newestKey = [
|
|
1462
|
+
newest.timestamp,
|
|
1463
|
+
newest.source ?? "",
|
|
1464
|
+
newest.sessionKey ?? "",
|
|
1465
|
+
newest.principal ?? "",
|
|
1466
|
+
newest.text
|
|
1467
|
+
].join("\0");
|
|
1468
|
+
const oldestKey = [
|
|
1469
|
+
oldest.timestamp,
|
|
1470
|
+
oldest.source ?? "",
|
|
1471
|
+
oldest.sessionKey ?? "",
|
|
1472
|
+
oldest.principal ?? "",
|
|
1473
|
+
oldest.text
|
|
1474
|
+
].join("\0");
|
|
1475
|
+
if (oldestKey !== newestKey) {
|
|
1476
|
+
dedupedEvidenceEntries.push(oldest);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return dedupedEvidenceEntries;
|
|
1480
|
+
}
|
|
1481
|
+
function flattenStructuredSectionEvidence(sections) {
|
|
1482
|
+
return (sections ?? []).flatMap(
|
|
1483
|
+
(section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
|
|
1484
|
+
timestamp: "",
|
|
1485
|
+
text: fact,
|
|
1486
|
+
source: `section:${section.title}`
|
|
1487
|
+
}))
|
|
1488
|
+
);
|
|
1489
|
+
}
|
|
1490
|
+
function fingerprintEntitySynthesisEvidence(entity) {
|
|
1491
|
+
const fingerprint = createHash("sha256");
|
|
1492
|
+
const timelineEntries = entity.timeline.map((entry) => [
|
|
1493
|
+
entry.timestamp,
|
|
1494
|
+
entry.source ?? "",
|
|
1495
|
+
entry.sessionKey ?? "",
|
|
1496
|
+
entry.principal ?? "",
|
|
1497
|
+
entry.text
|
|
1498
|
+
].join("\0")).sort();
|
|
1499
|
+
const timelineEntrySeparator = String.fromCharCode(1);
|
|
1500
|
+
const structuredFactsSeparator = String.fromCharCode(2);
|
|
1501
|
+
fingerprint.update(timelineEntries.join(timelineEntrySeparator));
|
|
1502
|
+
fingerprint.update(structuredFactsSeparator);
|
|
1503
|
+
fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
|
|
1504
|
+
return fingerprint.digest("hex");
|
|
1505
|
+
}
|
|
1506
|
+
var EntitySynthesisCoordinator = class {
|
|
1507
|
+
constructor(deps) {
|
|
1508
|
+
this.deps = deps;
|
|
1509
|
+
}
|
|
1510
|
+
deps;
|
|
1511
|
+
/**
|
|
1512
|
+
* Process up to `maxEntities` entities from the synthesis queue for the
|
|
1513
|
+
* given namespace. Returns the number of entities whose synthesis was
|
|
1514
|
+
* successfully refreshed.
|
|
1515
|
+
*/
|
|
1516
|
+
async processQueue(namespace, maxEntities = 5) {
|
|
1517
|
+
const { config } = this.deps;
|
|
1518
|
+
if (!config.entitySummaryEnabled || maxEntities <= 0 || config.entitySynthesisMaxTokens <= 0) return 0;
|
|
1519
|
+
const storage = await this.deps.getStorage(namespace);
|
|
1520
|
+
const queued = await storage.refreshEntitySynthesisQueue();
|
|
1521
|
+
let processed = 0;
|
|
1522
|
+
let attempted = 0;
|
|
1523
|
+
for (const entityName of queued) {
|
|
1524
|
+
if (attempted >= maxEntities) break;
|
|
1525
|
+
attempted += 1;
|
|
1526
|
+
try {
|
|
1527
|
+
const raw = await storage.readEntity(entityName);
|
|
1528
|
+
if (!raw) continue;
|
|
1529
|
+
const entity = parseEntityFile(raw, config.entitySchemas);
|
|
1530
|
+
const previousSynthesis = entity.synthesis || entity.summary || "";
|
|
1531
|
+
const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
1532
|
+
const newerTimelineEntries = sortedTimelineEntries.filter(
|
|
1533
|
+
(entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
|
|
1534
|
+
);
|
|
1535
|
+
const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
|
|
1536
|
+
const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
|
|
1537
|
+
const structuredEvidenceCount = structuredEvidenceEntries.length;
|
|
1538
|
+
const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
|
|
1539
|
+
const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
|
|
1540
|
+
const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
|
|
1541
|
+
const candidateEvidenceEntries = [
|
|
1542
|
+
...newerTimelineEntries,
|
|
1543
|
+
...appendedTimelineEntries,
|
|
1544
|
+
...appendedStructuredEvidenceEntries
|
|
1545
|
+
].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
1546
|
+
const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
|
|
1547
|
+
candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
|
|
1548
|
+
);
|
|
1549
|
+
const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
|
|
1550
|
+
if (chronologicalEvidenceEntries.length === 0) continue;
|
|
1551
|
+
const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
|
|
1552
|
+
const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
|
|
1553
|
+
const nextSynthesisUpdatedAt = compareEntityTimestamps(
|
|
1554
|
+
latestEvidenceTimestamp,
|
|
1555
|
+
previousSynthesisUpdatedAt
|
|
1556
|
+
) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
|
|
1557
|
+
const evidenceBatches = [];
|
|
1558
|
+
for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
|
|
1559
|
+
evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
|
|
1560
|
+
}
|
|
1561
|
+
let nextSynthesis = previousSynthesis;
|
|
1562
|
+
let batchFailed = false;
|
|
1563
|
+
for (const evidenceEntries of evidenceBatches) {
|
|
1564
|
+
const evidenceText = evidenceEntries.map((entry) => {
|
|
1565
|
+
const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
|
|
1566
|
+
const metadata = [
|
|
1567
|
+
`timestamp=${entry.timestamp}`,
|
|
1568
|
+
sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
|
|
1569
|
+
entry.sessionKey ? `session=${entry.sessionKey}` : "",
|
|
1570
|
+
entry.principal ? `principal=${entry.principal}` : ""
|
|
1571
|
+
].filter(Boolean).join(", ");
|
|
1572
|
+
return `- ${metadata}: ${entry.text}`;
|
|
1573
|
+
}).join("\n");
|
|
1574
|
+
const response = await this.deps.fastChatCompletion(
|
|
1575
|
+
[
|
|
1576
|
+
{
|
|
1577
|
+
role: "system",
|
|
1578
|
+
content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
|
|
1579
|
+
},
|
|
1580
|
+
{
|
|
1581
|
+
role: "user",
|
|
1582
|
+
content: [
|
|
1583
|
+
`Entity: ${entity.name} (${entity.type})`,
|
|
1584
|
+
nextSynthesis ? `Previous synthesis:
|
|
1585
|
+
${nextSynthesis}` : "Previous synthesis: none",
|
|
1586
|
+
`New evidence:
|
|
1587
|
+
${evidenceText}`
|
|
1588
|
+
].join("\n\n")
|
|
1589
|
+
}
|
|
1590
|
+
],
|
|
1591
|
+
{
|
|
1592
|
+
temperature: 0.2,
|
|
1593
|
+
maxTokens: config.entitySynthesisMaxTokens,
|
|
1594
|
+
operation: "entity_summary",
|
|
1595
|
+
priority: "background"
|
|
1596
|
+
}
|
|
1597
|
+
);
|
|
1598
|
+
const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
|
|
1599
|
+
const maxSynthesisChars = Math.max(2e3, config.entitySynthesisMaxTokens * 8);
|
|
1600
|
+
if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
|
|
1601
|
+
batchFailed = true;
|
|
1602
|
+
break;
|
|
1603
|
+
}
|
|
1604
|
+
nextSynthesis = synthesis;
|
|
1605
|
+
}
|
|
1606
|
+
if (batchFailed || nextSynthesis.length === 0) continue;
|
|
1607
|
+
const latestRaw = await storage.readEntity(entityName);
|
|
1608
|
+
if (!latestRaw) continue;
|
|
1609
|
+
const latestEntity = parseEntityFile(latestRaw, config.entitySchemas);
|
|
1610
|
+
if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
|
|
1611
|
+
continue;
|
|
1078
1612
|
}
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
)
|
|
1086
|
-
);
|
|
1087
|
-
}
|
|
1088
|
-
log.info(
|
|
1089
|
-
`[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`
|
|
1090
|
-
);
|
|
1091
|
-
try {
|
|
1092
|
-
await materializeAfterSemanticConsolidation({
|
|
1093
|
-
config: this.config,
|
|
1094
|
-
memoryDir: targetStorage.dir
|
|
1095
|
-
});
|
|
1096
|
-
} catch (err) {
|
|
1097
|
-
log.warn(
|
|
1098
|
-
`[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
1099
|
-
);
|
|
1100
|
-
}
|
|
1101
|
-
if (this.config.peerProfileReasonerEnabled) {
|
|
1102
|
-
try {
|
|
1103
|
-
const peerLlm = new FallbackLlmClient(
|
|
1104
|
-
this.config.gatewayConfig,
|
|
1105
|
-
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
1106
|
-
);
|
|
1107
|
-
const peerResult = await runPeerProfileReasoner({
|
|
1108
|
-
memoryDir: targetStorage.dir,
|
|
1109
|
-
enabled: true,
|
|
1110
|
-
llm: peerLlm,
|
|
1111
|
-
model: this.config.peerProfileReasonerModel,
|
|
1112
|
-
minInteractions: this.config.peerProfileReasonerMinInteractions,
|
|
1113
|
-
maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
|
|
1114
|
-
log: {
|
|
1115
|
-
debug: (msg) => log.debug(msg),
|
|
1116
|
-
info: (msg) => log.info(msg),
|
|
1117
|
-
warn: (msg) => log.warn(msg)
|
|
1118
|
-
}
|
|
1613
|
+
await storage.updateEntitySynthesis(entityName, nextSynthesis, {
|
|
1614
|
+
entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1615
|
+
synthesisStructuredFactDigest: structuredEvidenceDigest,
|
|
1616
|
+
synthesisStructuredFactCount: structuredEvidenceCount,
|
|
1617
|
+
synthesisTimelineCount: entity.timeline.length,
|
|
1618
|
+
updatedAt: nextSynthesisUpdatedAt
|
|
1119
1619
|
});
|
|
1120
|
-
|
|
1121
|
-
`[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`
|
|
1122
|
-
);
|
|
1620
|
+
processed += 1;
|
|
1123
1621
|
} catch (err) {
|
|
1124
|
-
log.
|
|
1125
|
-
`[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
1126
|
-
);
|
|
1622
|
+
log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
|
|
1127
1623
|
}
|
|
1128
1624
|
}
|
|
1129
|
-
return
|
|
1625
|
+
return processed;
|
|
1130
1626
|
}
|
|
1131
1627
|
};
|
|
1132
1628
|
|
|
@@ -1462,8 +1958,8 @@ function generateResolverDocument(taxonomy) {
|
|
|
1462
1958
|
}
|
|
1463
1959
|
|
|
1464
1960
|
// src/taxonomy/taxonomy-loader.ts
|
|
1465
|
-
import { readFile, mkdir, writeFile } from "fs/promises";
|
|
1466
|
-
import
|
|
1961
|
+
import { readFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
1962
|
+
import path3 from "path";
|
|
1467
1963
|
var TAXONOMY_DIR = ".taxonomy";
|
|
1468
1964
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
1469
1965
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -1561,7 +2057,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
1561
2057
|
}
|
|
1562
2058
|
}
|
|
1563
2059
|
async function loadTaxonomy(memoryDir) {
|
|
1564
|
-
const taxonomyPath =
|
|
2060
|
+
const taxonomyPath = path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
1565
2061
|
let raw;
|
|
1566
2062
|
try {
|
|
1567
2063
|
raw = await readFile(taxonomyPath, "utf-8");
|
|
@@ -1611,16 +2107,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
1611
2107
|
}
|
|
1612
2108
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
1613
2109
|
validateTaxonomy(taxonomy);
|
|
1614
|
-
const dir =
|
|
1615
|
-
await
|
|
1616
|
-
const filePath =
|
|
1617
|
-
await
|
|
2110
|
+
const dir = path3.join(memoryDir, TAXONOMY_DIR);
|
|
2111
|
+
await mkdir2(dir, { recursive: true });
|
|
2112
|
+
const filePath = path3.join(dir, TAXONOMY_FILE);
|
|
2113
|
+
await writeFile2(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
1618
2114
|
}
|
|
1619
2115
|
function getTaxonomyDir(memoryDir) {
|
|
1620
|
-
return
|
|
2116
|
+
return path3.join(memoryDir, TAXONOMY_DIR);
|
|
1621
2117
|
}
|
|
1622
2118
|
function getTaxonomyFilePath(memoryDir) {
|
|
1623
|
-
return
|
|
2119
|
+
return path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
1624
2120
|
}
|
|
1625
2121
|
|
|
1626
2122
|
// src/wearables/registry.ts
|
|
@@ -2486,71 +2982,6 @@ var BulkImportBatchPartialFailureError = class extends Error {
|
|
|
2486
2982
|
this.originalError = originalError;
|
|
2487
2983
|
}
|
|
2488
2984
|
};
|
|
2489
|
-
function dedupeEntitySynthesisEvidenceEntries(entries) {
|
|
2490
|
-
const dedupedEvidenceEntries = [];
|
|
2491
|
-
const evidenceByFact = /* @__PURE__ */ new Map();
|
|
2492
|
-
for (const entry of entries) {
|
|
2493
|
-
const normalizedFact = entry.text.trim();
|
|
2494
|
-
if (!normalizedFact) continue;
|
|
2495
|
-
const existing = evidenceByFact.get(normalizedFact);
|
|
2496
|
-
if (!existing) {
|
|
2497
|
-
evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
|
|
2498
|
-
continue;
|
|
2499
|
-
}
|
|
2500
|
-
if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
|
|
2501
|
-
existing.newest = entry;
|
|
2502
|
-
}
|
|
2503
|
-
if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
|
|
2504
|
-
existing.oldest = entry;
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
for (const { newest, oldest } of evidenceByFact.values()) {
|
|
2508
|
-
dedupedEvidenceEntries.push(newest);
|
|
2509
|
-
const newestKey = [
|
|
2510
|
-
newest.timestamp,
|
|
2511
|
-
newest.source ?? "",
|
|
2512
|
-
newest.sessionKey ?? "",
|
|
2513
|
-
newest.principal ?? "",
|
|
2514
|
-
newest.text
|
|
2515
|
-
].join("\0");
|
|
2516
|
-
const oldestKey = [
|
|
2517
|
-
oldest.timestamp,
|
|
2518
|
-
oldest.source ?? "",
|
|
2519
|
-
oldest.sessionKey ?? "",
|
|
2520
|
-
oldest.principal ?? "",
|
|
2521
|
-
oldest.text
|
|
2522
|
-
].join("\0");
|
|
2523
|
-
if (oldestKey !== newestKey) {
|
|
2524
|
-
dedupedEvidenceEntries.push(oldest);
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
return dedupedEvidenceEntries;
|
|
2528
|
-
}
|
|
2529
|
-
function flattenStructuredSectionEvidence(sections) {
|
|
2530
|
-
return (sections ?? []).flatMap(
|
|
2531
|
-
(section) => section.facts.map((fact) => fact.trim()).filter((fact) => fact.length > 0).map((fact) => ({
|
|
2532
|
-
timestamp: "",
|
|
2533
|
-
text: fact,
|
|
2534
|
-
source: `section:${section.title}`
|
|
2535
|
-
}))
|
|
2536
|
-
);
|
|
2537
|
-
}
|
|
2538
|
-
function fingerprintEntitySynthesisEvidence(entity) {
|
|
2539
|
-
const fingerprint = createHash("sha256");
|
|
2540
|
-
const timelineEntries = entity.timeline.map((entry) => [
|
|
2541
|
-
entry.timestamp,
|
|
2542
|
-
entry.source ?? "",
|
|
2543
|
-
entry.sessionKey ?? "",
|
|
2544
|
-
entry.principal ?? "",
|
|
2545
|
-
entry.text
|
|
2546
|
-
].join("\0")).sort();
|
|
2547
|
-
const timelineEntrySeparator = String.fromCharCode(1);
|
|
2548
|
-
const structuredFactsSeparator = String.fromCharCode(2);
|
|
2549
|
-
fingerprint.update(timelineEntries.join(timelineEntrySeparator));
|
|
2550
|
-
fingerprint.update(structuredFactsSeparator);
|
|
2551
|
-
fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
|
|
2552
|
-
return fingerprint.digest("hex");
|
|
2553
|
-
}
|
|
2554
2985
|
function mapRecallSourceToXrayServedBy(source) {
|
|
2555
2986
|
switch (source) {
|
|
2556
2987
|
case "recent_scan":
|
|
@@ -2586,7 +3017,7 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
|
|
|
2586
3017
|
}
|
|
2587
3018
|
}
|
|
2588
3019
|
function qmdCollectionPathParts(resultPath) {
|
|
2589
|
-
if (!resultPath ||
|
|
3020
|
+
if (!resultPath || path4.isAbsolute(resultPath)) return null;
|
|
2590
3021
|
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2591
3022
|
const slashIndex = normalized.indexOf("/");
|
|
2592
3023
|
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
@@ -2599,9 +3030,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
2599
3030
|
}
|
|
2600
3031
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
2601
3032
|
const candidates = /* @__PURE__ */ new Set();
|
|
2602
|
-
const storageRoot =
|
|
3033
|
+
const storageRoot = path4.resolve(storageDir);
|
|
2603
3034
|
const addCandidate = (candidate) => {
|
|
2604
|
-
const resolved =
|
|
3035
|
+
const resolved = path4.resolve(candidate);
|
|
2605
3036
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
2606
3037
|
candidates.add(resolved);
|
|
2607
3038
|
}
|
|
@@ -2609,12 +3040,12 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
2609
3040
|
const addRelativeCandidates = (relativePath) => {
|
|
2610
3041
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2611
3042
|
if (!normalized) return;
|
|
2612
|
-
addCandidate(
|
|
3043
|
+
addCandidate(path4.join(storageRoot, normalized));
|
|
2613
3044
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
2614
|
-
addCandidate(
|
|
3045
|
+
addCandidate(path4.join(storageRoot, "facts", normalized));
|
|
2615
3046
|
}
|
|
2616
3047
|
};
|
|
2617
|
-
if (
|
|
3048
|
+
if (path4.isAbsolute(resultPath)) {
|
|
2618
3049
|
addCandidate(resultPath);
|
|
2619
3050
|
} else {
|
|
2620
3051
|
addRelativeCandidates(resultPath);
|
|
@@ -2731,11 +3162,11 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
|
|
|
2731
3162
|
return await Promise.race([checkedPromise, timeoutPromise]);
|
|
2732
3163
|
}
|
|
2733
3164
|
function defaultWorkspaceDir() {
|
|
2734
|
-
return
|
|
3165
|
+
return path4.join(os2.homedir(), ".openclaw", "workspace");
|
|
2735
3166
|
}
|
|
2736
3167
|
function sanitizeSessionKeyForFilename(sessionKey) {
|
|
2737
3168
|
const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
2738
|
-
const hash =
|
|
3169
|
+
const hash = createHash2("sha256").update(sessionKey).digest("hex").slice(0, 12);
|
|
2739
3170
|
return `${readable}-${hash}`;
|
|
2740
3171
|
}
|
|
2741
3172
|
function latestSourceValidAtFromTurns(turns) {
|
|
@@ -3024,11 +3455,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
3024
3455
|
return Array.from(mergedByPath.values());
|
|
3025
3456
|
}
|
|
3026
3457
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
3027
|
-
const absolutePath =
|
|
3028
|
-
const rel =
|
|
3458
|
+
const absolutePath = path4.isAbsolute(candidatePath) ? candidatePath : path4.resolve(storageDir, candidatePath);
|
|
3459
|
+
const rel = path4.relative(storageDir, absolutePath);
|
|
3029
3460
|
if (!rel || rel === ".") return null;
|
|
3030
3461
|
if (rel.startsWith("..")) return null;
|
|
3031
|
-
return rel.split(
|
|
3462
|
+
return rel.split(path4.sep).join("/");
|
|
3032
3463
|
}
|
|
3033
3464
|
function normalizeGraphActivationScore(score) {
|
|
3034
3465
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -3173,7 +3604,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
|
|
|
3173
3604
|
for (const mem of allMemsForGraph ?? []) {
|
|
3174
3605
|
const id = mem.frontmatter.id;
|
|
3175
3606
|
if (!id) continue;
|
|
3176
|
-
pathById.set(id,
|
|
3607
|
+
pathById.set(id, path4.relative(storageDir, mem.path));
|
|
3177
3608
|
}
|
|
3178
3609
|
return pathById;
|
|
3179
3610
|
}
|
|
@@ -3181,7 +3612,7 @@ function appendMemoryToGraphContext(options) {
|
|
|
3181
3612
|
if (!Array.isArray(options.allMemsForGraph)) return;
|
|
3182
3613
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
3183
3614
|
options.allMemsForGraph.push({
|
|
3184
|
-
path:
|
|
3615
|
+
path: path4.join(options.storageDir, options.memoryRelPath),
|
|
3185
3616
|
content: options.content,
|
|
3186
3617
|
frontmatter: {
|
|
3187
3618
|
id: options.memoryId,
|
|
@@ -3201,16 +3632,16 @@ function resolvePersistedMemoryRelativePath(options) {
|
|
|
3201
3632
|
const persisted = options.pathById.get(options.memoryId);
|
|
3202
3633
|
if (persisted) return persisted;
|
|
3203
3634
|
if (options.category === "correction") {
|
|
3204
|
-
return
|
|
3635
|
+
return path4.join("corrections", `${options.memoryId}.md`);
|
|
3205
3636
|
}
|
|
3206
3637
|
const subtree = categoryDirName(options.category);
|
|
3207
3638
|
const idParts = options.memoryId.split("-");
|
|
3208
3639
|
const maybeTimestamp = Number(idParts[1]);
|
|
3209
3640
|
if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
|
|
3210
3641
|
const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
|
|
3211
|
-
return
|
|
3642
|
+
return path4.join(subtree, day, `${options.memoryId}.md`);
|
|
3212
3643
|
}
|
|
3213
|
-
return
|
|
3644
|
+
return path4.join(subtree, `${options.memoryId}.md`);
|
|
3214
3645
|
}
|
|
3215
3646
|
var Orchestrator = class _Orchestrator {
|
|
3216
3647
|
storage;
|
|
@@ -3290,6 +3721,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
3290
3721
|
tierMigrationCoordinator;
|
|
3291
3722
|
compressionGuidelineCoordinator;
|
|
3292
3723
|
semanticConsolidationCoordinator;
|
|
3724
|
+
lifecyclePolicyCoordinator;
|
|
3725
|
+
entitySynthesisCoordinator;
|
|
3293
3726
|
/**
|
|
3294
3727
|
* In-memory X-ray snapshot from the most recent `recall()` call that
|
|
3295
3728
|
* was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
|
|
@@ -3671,7 +4104,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3671
4104
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
3672
4105
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
3673
4106
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
3674
|
-
const resolvedStorageDir =
|
|
4107
|
+
const resolvedStorageDir = path4.resolve(storageDir);
|
|
3675
4108
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
3676
4109
|
if (!hints) {
|
|
3677
4110
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -3682,21 +4115,21 @@ var Orchestrator = class _Orchestrator {
|
|
|
3682
4115
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
3683
4116
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
3684
4117
|
if (!ns) return false;
|
|
3685
|
-
const resolvedStorageDir =
|
|
3686
|
-
const resolvedMemoryDir =
|
|
4118
|
+
const resolvedStorageDir = path4.resolve(storageDir);
|
|
4119
|
+
const resolvedMemoryDir = path4.resolve(this.config.memoryDir);
|
|
3687
4120
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
3688
4121
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
3689
|
-
const resolvedNamespacesDir =
|
|
4122
|
+
const resolvedNamespacesDir = path4.join(resolvedMemoryDir, "namespaces");
|
|
3690
4123
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
3691
|
-
const rawRoot =
|
|
3692
|
-
const tokenRoot =
|
|
4124
|
+
const rawRoot = path4.resolve(resolvedNamespacesDir, ns);
|
|
4125
|
+
const tokenRoot = path4.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
3693
4126
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
3694
4127
|
}
|
|
3695
4128
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
3696
|
-
if (resolvedStorageDir ===
|
|
4129
|
+
if (resolvedStorageDir === path4.resolve(this.config.memoryDir)) {
|
|
3697
4130
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
3698
4131
|
}
|
|
3699
|
-
const leaf =
|
|
4132
|
+
const leaf = path4.basename(resolvedStorageDir);
|
|
3700
4133
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
3701
4134
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
3702
4135
|
if (record.namespace === leaf) return 1;
|
|
@@ -3724,7 +4157,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3724
4157
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
3725
4158
|
if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;
|
|
3726
4159
|
this.namespaceStorageDirHintsLoaded = true;
|
|
3727
|
-
const catalogPath =
|
|
4160
|
+
const catalogPath = path4.join(this.config.memoryDir, "state", "namespaces.jsonl");
|
|
3728
4161
|
if (!existsSync(catalogPath)) return;
|
|
3729
4162
|
let body;
|
|
3730
4163
|
try {
|
|
@@ -3761,7 +4194,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3761
4194
|
if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
3762
4195
|
continue;
|
|
3763
4196
|
}
|
|
3764
|
-
const resolvedStorageDir =
|
|
4197
|
+
const resolvedStorageDir = path4.resolve(record.storageDir);
|
|
3765
4198
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
3766
4199
|
preferredByStorageDir.set(
|
|
3767
4200
|
resolvedStorageDir,
|
|
@@ -4025,7 +4458,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4025
4458
|
this.config = config;
|
|
4026
4459
|
this.profiler = new ProfilingCollector({
|
|
4027
4460
|
enabled: config.profilingEnabled,
|
|
4028
|
-
storageDir: config.profilingStorageDir ||
|
|
4461
|
+
storageDir: config.profilingStorageDir || path4.join(config.memoryDir, "profiling"),
|
|
4029
4462
|
maxTraces: config.profilingMaxTraces
|
|
4030
4463
|
});
|
|
4031
4464
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -4094,7 +4527,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4094
4527
|
this.compounding = config.compoundingEnabled ? new CompoundingEngine(config, this.storage) : void 0;
|
|
4095
4528
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
4096
4529
|
this.transcript = new TranscriptManager(config);
|
|
4097
|
-
this.conversationIndexDir =
|
|
4530
|
+
this.conversationIndexDir = path4.join(
|
|
4098
4531
|
config.memoryDir,
|
|
4099
4532
|
"conversation-index",
|
|
4100
4533
|
"chunks"
|
|
@@ -4120,6 +4553,11 @@ var Orchestrator = class _Orchestrator {
|
|
|
4120
4553
|
getStorage: () => this.storage,
|
|
4121
4554
|
fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
|
|
4122
4555
|
});
|
|
4556
|
+
this.entitySynthesisCoordinator = new EntitySynthesisCoordinator({
|
|
4557
|
+
config,
|
|
4558
|
+
getStorage: (namespace) => this.getStorage(namespace),
|
|
4559
|
+
fastChatCompletion: (messages, options) => this.fastChatCompletion(messages, options)
|
|
4560
|
+
});
|
|
4123
4561
|
this.sessionObserver = new SessionObserverState({
|
|
4124
4562
|
memoryDir: config.memoryDir,
|
|
4125
4563
|
debounceMs: config.sessionObserverDebounceMs ?? 12e4,
|
|
@@ -4174,8 +4612,17 @@ var Orchestrator = class _Orchestrator {
|
|
|
4174
4612
|
config.gatewayConfig,
|
|
4175
4613
|
this.modelRegistry
|
|
4176
4614
|
);
|
|
4615
|
+
this.lifecyclePolicyCoordinator = new LifecyclePolicyCoordinator({
|
|
4616
|
+
config,
|
|
4617
|
+
getStorage: () => this.storage,
|
|
4618
|
+
extraction: this.extraction,
|
|
4619
|
+
embeddingFallback: this.embeddingFallback,
|
|
4620
|
+
getEffectiveLifecycleThresholds: () => this.effectiveLifecycleThresholds(),
|
|
4621
|
+
removeContentHashForMemory: (targetStorage, memory, context) => this.removeContentHashForMemory(targetStorage, memory, context),
|
|
4622
|
+
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
4623
|
+
});
|
|
4177
4624
|
this.threading = new ThreadingManager(
|
|
4178
|
-
|
|
4625
|
+
path4.join(config.memoryDir, "threads"),
|
|
4179
4626
|
config.threadingGapMinutes
|
|
4180
4627
|
);
|
|
4181
4628
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -4255,7 +4702,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4255
4702
|
utilityPromoteThresholdDelta: this.utilityRuntimeValues?.promoteThresholdDelta ?? 0,
|
|
4256
4703
|
utilityDemoteThresholdDelta: this.utilityRuntimeValues?.demoteThresholdDelta ?? 0
|
|
4257
4704
|
};
|
|
4258
|
-
return
|
|
4705
|
+
return createHash2("sha256").update(JSON.stringify(payload)).digest("hex").slice(0, 12);
|
|
4259
4706
|
}
|
|
4260
4707
|
effectiveLifecycleThresholds() {
|
|
4261
4708
|
const archiveDecayThreshold = this.config.lifecycleArchiveDecayThreshold;
|
|
@@ -4466,8 +4913,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
4466
4913
|
this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();
|
|
4467
4914
|
this.utilityRuntimeValues = await loadUtilityRuntimeValues({
|
|
4468
4915
|
memoryDir: this.config.memoryDir,
|
|
4469
|
-
memoryUtilityLearningEnabled: this.config.
|
|
4470
|
-
promotionByOutcomeEnabled: this.config.
|
|
4916
|
+
memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(this.config).memoryUtilityLearning,
|
|
4917
|
+
promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(this.config).promotionByOutcome
|
|
4471
4918
|
});
|
|
4472
4919
|
if (this.config.factDeduplicationEnabled) {
|
|
4473
4920
|
this.contentHashIndex = this.storage.createContentHashIndex();
|
|
@@ -4498,7 +4945,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4498
4945
|
const files = await readdir(wsDir).catch(() => []);
|
|
4499
4946
|
for (const f of files) {
|
|
4500
4947
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
4501
|
-
const fp =
|
|
4948
|
+
const fp = path4.join(wsDir, f);
|
|
4502
4949
|
const s = await stat(fp).catch(() => null);
|
|
4503
4950
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
4504
4951
|
await unlink(fp).catch(() => {
|
|
@@ -4693,7 +5140,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4693
5140
|
if (signal.aborted) return;
|
|
4694
5141
|
if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.config).qmdTierMigration) {
|
|
4695
5142
|
try {
|
|
4696
|
-
const { runFirstStartMigration } = await import("./first-start-migration-
|
|
5143
|
+
const { runFirstStartMigration } = await import("./first-start-migration-2RQYDIZ7.js");
|
|
4697
5144
|
const result = await runFirstStartMigration({
|
|
4698
5145
|
storage: this.storage,
|
|
4699
5146
|
config: this.config,
|
|
@@ -5007,15 +5454,15 @@ ${doc.content}` : doc.content,
|
|
|
5007
5454
|
this.lastFileHygieneRunAtMs = now;
|
|
5008
5455
|
if (hygiene.rotateEnabled) {
|
|
5009
5456
|
for (const rel of hygiene.rotatePaths) {
|
|
5010
|
-
const abs =
|
|
5457
|
+
const abs = path4.isAbsolute(rel) ? rel : path4.join(this.config.workspaceDir, rel);
|
|
5011
5458
|
try {
|
|
5012
5459
|
const raw = await readFile2(abs, "utf-8");
|
|
5013
5460
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
5014
|
-
const archiveDir =
|
|
5461
|
+
const archiveDir = path4.join(
|
|
5015
5462
|
this.config.workspaceDir,
|
|
5016
5463
|
hygiene.archiveDir
|
|
5017
5464
|
);
|
|
5018
|
-
const base =
|
|
5465
|
+
const base = path4.basename(abs);
|
|
5019
5466
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
5020
5467
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
5021
5468
|
filePath: abs,
|
|
@@ -5023,7 +5470,7 @@ ${doc.content}` : doc.content,
|
|
|
5023
5470
|
archivePrefix: prefix,
|
|
5024
5471
|
keepTailChars: hygiene.rotateKeepTailChars
|
|
5025
5472
|
});
|
|
5026
|
-
await
|
|
5473
|
+
await writeFile3(abs, newContent, "utf-8");
|
|
5027
5474
|
}
|
|
5028
5475
|
} catch {
|
|
5029
5476
|
}
|
|
@@ -5040,8 +5487,8 @@ ${doc.content}` : doc.content,
|
|
|
5040
5487
|
log.warn(w.message);
|
|
5041
5488
|
}
|
|
5042
5489
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
5043
|
-
const fp =
|
|
5044
|
-
await
|
|
5490
|
+
const fp = path4.join(this.config.memoryDir, hygiene.warningsLogPath);
|
|
5491
|
+
await mkdir3(path4.dirname(fp), { recursive: true });
|
|
5045
5492
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
5046
5493
|
const block = `
|
|
5047
5494
|
|
|
@@ -5054,7 +5501,7 @@ ${doc.content}` : doc.content,
|
|
|
5054
5501
|
} catch {
|
|
5055
5502
|
existing = "# Engram File Hygiene Warnings\n";
|
|
5056
5503
|
}
|
|
5057
|
-
await
|
|
5504
|
+
await writeFile3(fp, existing + block, "utf-8");
|
|
5058
5505
|
}
|
|
5059
5506
|
}
|
|
5060
5507
|
}
|
|
@@ -5119,120 +5566,13 @@ ${doc.content}` : doc.content,
|
|
|
5119
5566
|
}
|
|
5120
5567
|
return true;
|
|
5121
5568
|
}
|
|
5122
|
-
async getStorage(namespace) {
|
|
5123
|
-
const ns = namespace && namespace.length > 0 ? namespace : this.config.defaultNamespace;
|
|
5124
|
-
return this.storageRouter.storageFor(ns);
|
|
5125
|
-
}
|
|
5126
|
-
async processEntitySynthesisQueue(namespace, maxEntities = 5) {
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
const queued = await storage.refreshEntitySynthesisQueue();
|
|
5130
|
-
let processed = 0;
|
|
5131
|
-
let attempted = 0;
|
|
5132
|
-
for (const entityName of queued) {
|
|
5133
|
-
if (attempted >= maxEntities) break;
|
|
5134
|
-
attempted += 1;
|
|
5135
|
-
try {
|
|
5136
|
-
const raw = await storage.readEntity(entityName);
|
|
5137
|
-
if (!raw) continue;
|
|
5138
|
-
const entity = parseEntityFile(raw, this.config.entitySchemas);
|
|
5139
|
-
const previousSynthesis = entity.synthesis || entity.summary || "";
|
|
5140
|
-
const sortedTimelineEntries = entity.timeline.slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
5141
|
-
const newerTimelineEntries = sortedTimelineEntries.filter(
|
|
5142
|
-
(entry) => !entity.synthesisUpdatedAt || compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0
|
|
5143
|
-
);
|
|
5144
|
-
const appendedTimelineEntries = entity.synthesisTimelineCount === void 0 ? [] : entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
|
|
5145
|
-
const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
|
|
5146
|
-
const structuredEvidenceCount = structuredEvidenceEntries.length;
|
|
5147
|
-
const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
|
|
5148
|
-
const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || void 0);
|
|
5149
|
-
const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === void 0 || structuredEvidenceDrifted ? structuredEvidenceEntries : structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
|
|
5150
|
-
const candidateEvidenceEntries = [
|
|
5151
|
-
...newerTimelineEntries,
|
|
5152
|
-
...appendedTimelineEntries,
|
|
5153
|
-
...appendedStructuredEvidenceEntries
|
|
5154
|
-
].slice().sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
5155
|
-
const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
|
|
5156
|
-
candidateEvidenceEntries.length > 0 ? candidateEvidenceEntries : [...sortedTimelineEntries, ...structuredEvidenceEntries]
|
|
5157
|
-
);
|
|
5158
|
-
const chronologicalEvidenceEntries = dedupedEvidenceEntries.slice().sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
|
|
5159
|
-
if (chronologicalEvidenceEntries.length === 0) continue;
|
|
5160
|
-
const latestEvidenceTimestamp = chronologicalEvidenceEntries.slice().reverse().map((entry) => entry.timestamp?.trim() || void 0).find((timestamp) => Boolean(timestamp));
|
|
5161
|
-
const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || void 0;
|
|
5162
|
-
const nextSynthesisUpdatedAt = compareEntityTimestamps(
|
|
5163
|
-
latestEvidenceTimestamp,
|
|
5164
|
-
previousSynthesisUpdatedAt
|
|
5165
|
-
) >= 0 ? latestEvidenceTimestamp : previousSynthesisUpdatedAt;
|
|
5166
|
-
const evidenceBatches = [];
|
|
5167
|
-
for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
|
|
5168
|
-
evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
|
|
5169
|
-
}
|
|
5170
|
-
let nextSynthesis = previousSynthesis;
|
|
5171
|
-
let batchFailed = false;
|
|
5172
|
-
for (const evidenceEntries of evidenceBatches) {
|
|
5173
|
-
const evidenceText = evidenceEntries.map((entry) => {
|
|
5174
|
-
const sectionTitle = entry.source?.startsWith("section:") ? entry.source.slice("section:".length) : "";
|
|
5175
|
-
const metadata = [
|
|
5176
|
-
`timestamp=${entry.timestamp}`,
|
|
5177
|
-
sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
|
|
5178
|
-
entry.sessionKey ? `session=${entry.sessionKey}` : "",
|
|
5179
|
-
entry.principal ? `principal=${entry.principal}` : ""
|
|
5180
|
-
].filter(Boolean).join(", ");
|
|
5181
|
-
return `- ${metadata}: ${entry.text}`;
|
|
5182
|
-
}).join("\n");
|
|
5183
|
-
const response = await this.fastChatCompletion(
|
|
5184
|
-
[
|
|
5185
|
-
{
|
|
5186
|
-
role: "system",
|
|
5187
|
-
content: "Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only."
|
|
5188
|
-
},
|
|
5189
|
-
{
|
|
5190
|
-
role: "user",
|
|
5191
|
-
content: [
|
|
5192
|
-
`Entity: ${entity.name} (${entity.type})`,
|
|
5193
|
-
nextSynthesis ? `Previous synthesis:
|
|
5194
|
-
${nextSynthesis}` : "Previous synthesis: none",
|
|
5195
|
-
`New evidence:
|
|
5196
|
-
${evidenceText}`
|
|
5197
|
-
].join("\n\n")
|
|
5198
|
-
}
|
|
5199
|
-
],
|
|
5200
|
-
{
|
|
5201
|
-
temperature: 0.2,
|
|
5202
|
-
maxTokens: this.config.entitySynthesisMaxTokens,
|
|
5203
|
-
operation: "entity_summary",
|
|
5204
|
-
priority: "background"
|
|
5205
|
-
}
|
|
5206
|
-
);
|
|
5207
|
-
const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
|
|
5208
|
-
const maxSynthesisChars = Math.max(2e3, this.config.entitySynthesisMaxTokens * 8);
|
|
5209
|
-
if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
|
|
5210
|
-
batchFailed = true;
|
|
5211
|
-
break;
|
|
5212
|
-
}
|
|
5213
|
-
nextSynthesis = synthesis;
|
|
5214
|
-
}
|
|
5215
|
-
if (batchFailed || nextSynthesis.length === 0) continue;
|
|
5216
|
-
const latestRaw = await storage.readEntity(entityName);
|
|
5217
|
-
if (!latestRaw) continue;
|
|
5218
|
-
const latestEntity = parseEntityFile(latestRaw, this.config.entitySchemas);
|
|
5219
|
-
if (fingerprintEntitySynthesisEvidence(latestEntity) !== fingerprintEntitySynthesisEvidence(entity)) {
|
|
5220
|
-
continue;
|
|
5221
|
-
}
|
|
5222
|
-
await storage.updateEntitySynthesis(entityName, nextSynthesis, {
|
|
5223
|
-
entityUpdatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5224
|
-
synthesisStructuredFactDigest: structuredEvidenceDigest,
|
|
5225
|
-
synthesisStructuredFactCount: structuredEvidenceCount,
|
|
5226
|
-
synthesisTimelineCount: entity.timeline.length,
|
|
5227
|
-
updatedAt: nextSynthesisUpdatedAt
|
|
5228
|
-
});
|
|
5229
|
-
processed += 1;
|
|
5230
|
-
} catch (err) {
|
|
5231
|
-
log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
|
|
5232
|
-
}
|
|
5233
|
-
}
|
|
5234
|
-
return processed;
|
|
5235
|
-
}
|
|
5569
|
+
async getStorage(namespace) {
|
|
5570
|
+
const ns = namespace && namespace.length > 0 ? namespace : this.config.defaultNamespace;
|
|
5571
|
+
return this.storageRouter.storageFor(ns);
|
|
5572
|
+
}
|
|
5573
|
+
async processEntitySynthesisQueue(namespace, maxEntities = 5) {
|
|
5574
|
+
return this.entitySynthesisCoordinator.processQueue(namespace, maxEntities);
|
|
5575
|
+
}
|
|
5236
5576
|
async generateDaySummary(memories) {
|
|
5237
5577
|
if (this.initPromise) {
|
|
5238
5578
|
let initGateTimeoutHandle;
|
|
@@ -5287,7 +5627,7 @@ ${evidenceText}`
|
|
|
5287
5627
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
5288
5628
|
if (memoryRootReal === null) break;
|
|
5289
5629
|
for (const date of datesToScan) {
|
|
5290
|
-
const dateDir =
|
|
5630
|
+
const dateDir = path4.join(storage.dir, categoryDir, date);
|
|
5291
5631
|
try {
|
|
5292
5632
|
const dirStat = await lstat(dateDir);
|
|
5293
5633
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -5296,7 +5636,7 @@ ${evidenceText}`
|
|
|
5296
5636
|
for (const entry of entries) {
|
|
5297
5637
|
if (entry.isSymbolicLink()) continue;
|
|
5298
5638
|
if (!entry.name.endsWith(".md")) continue;
|
|
5299
|
-
const fullPath =
|
|
5639
|
+
const fullPath = path4.join(dateDir, entry.name);
|
|
5300
5640
|
try {
|
|
5301
5641
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
5302
5642
|
const raw = await readFile2(fullPath, "utf-8");
|
|
@@ -5318,7 +5658,7 @@ ${evidenceText}`
|
|
|
5318
5658
|
facts.push({
|
|
5319
5659
|
path: fullPath,
|
|
5320
5660
|
frontmatter: {
|
|
5321
|
-
id: fm.id ||
|
|
5661
|
+
id: fm.id || path4.basename(entry.name, ".md"),
|
|
5322
5662
|
category: fm.category || "fact",
|
|
5323
5663
|
created,
|
|
5324
5664
|
updated: fm.updated || created,
|
|
@@ -5341,13 +5681,13 @@ ${evidenceText}`
|
|
|
5341
5681
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
5342
5682
|
});
|
|
5343
5683
|
const hourlySummaries = [];
|
|
5344
|
-
const hourlyBaseDir =
|
|
5684
|
+
const hourlyBaseDir = path4.join(storage.dir, "summaries", "hourly");
|
|
5345
5685
|
try {
|
|
5346
5686
|
const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });
|
|
5347
5687
|
for (const sk of sessionKeys) {
|
|
5348
5688
|
if (!sk.isDirectory()) continue;
|
|
5349
5689
|
for (const date of datesToScan) {
|
|
5350
|
-
const summaryFile =
|
|
5690
|
+
const summaryFile = path4.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
5351
5691
|
try {
|
|
5352
5692
|
const raw = await readFile2(summaryFile, "utf-8");
|
|
5353
5693
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -5395,7 +5735,7 @@ ${evidenceText}`
|
|
|
5395
5735
|
action: event.action,
|
|
5396
5736
|
eligibility,
|
|
5397
5737
|
options: {
|
|
5398
|
-
actionsEnabled: this.config.
|
|
5738
|
+
actionsEnabled: resolveCompressionCapabilities(this.config).contextCompressionActions,
|
|
5399
5739
|
maxCompressionTokensPerHour: this.config.maxCompressionTokensPerHour
|
|
5400
5740
|
}
|
|
5401
5741
|
});
|
|
@@ -5451,7 +5791,7 @@ ${evidenceText}`
|
|
|
5451
5791
|
}
|
|
5452
5792
|
async getLastGraphRecallSnapshot(namespace) {
|
|
5453
5793
|
const storage = await this.getStorage(namespace);
|
|
5454
|
-
const snapshotPath =
|
|
5794
|
+
const snapshotPath = path4.join(
|
|
5455
5795
|
storage.dir,
|
|
5456
5796
|
"state",
|
|
5457
5797
|
"last_graph_recall.json"
|
|
@@ -5490,7 +5830,7 @@ ${evidenceText}`
|
|
|
5490
5830
|
}
|
|
5491
5831
|
async getLastIntentSnapshot(namespace) {
|
|
5492
5832
|
const storage = await this.getStorage(namespace);
|
|
5493
|
-
const snapshotPath =
|
|
5833
|
+
const snapshotPath = path4.join(storage.dir, "state", "last_intent.json");
|
|
5494
5834
|
try {
|
|
5495
5835
|
const raw = await readFile2(snapshotPath, "utf-8");
|
|
5496
5836
|
const parsed = JSON.parse(raw);
|
|
@@ -5523,7 +5863,7 @@ ${evidenceText}`
|
|
|
5523
5863
|
}
|
|
5524
5864
|
async getLastQmdRecallSnapshot(namespace) {
|
|
5525
5865
|
const storage = await this.getStorage(namespace);
|
|
5526
|
-
const snapshotPath =
|
|
5866
|
+
const snapshotPath = path4.join(
|
|
5527
5867
|
storage.dir,
|
|
5528
5868
|
"state",
|
|
5529
5869
|
"last_qmd_recall.json"
|
|
@@ -5676,7 +6016,7 @@ ${r.snippet.trim()}
|
|
|
5676
6016
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
5677
6017
|
let total = 0;
|
|
5678
6018
|
for (const entry of entries) {
|
|
5679
|
-
const fullPath =
|
|
6019
|
+
const fullPath = path4.join(dir, entry.name);
|
|
5680
6020
|
if (entry.isDirectory()) {
|
|
5681
6021
|
total += await this.countConversationChunkDocs(fullPath);
|
|
5682
6022
|
continue;
|
|
@@ -6400,7 +6740,7 @@ ${r.snippet.trim()}
|
|
|
6400
6740
|
if (!options.onDebugSnapshot) return;
|
|
6401
6741
|
await options.onDebugSnapshot({
|
|
6402
6742
|
recordedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6403
|
-
queryHash:
|
|
6743
|
+
queryHash: createHash2("sha256").update(prompt).digest("hex"),
|
|
6404
6744
|
queryLength: prompt.length,
|
|
6405
6745
|
collection: options.collection,
|
|
6406
6746
|
namespaces: options.recallNamespaces,
|
|
@@ -6582,7 +6922,7 @@ ${r.snippet.trim()}
|
|
|
6582
6922
|
resolvedPath = resolvedCold.result.path;
|
|
6583
6923
|
resolvedResult = resolvedCold.result;
|
|
6584
6924
|
}
|
|
6585
|
-
if (!
|
|
6925
|
+
if (!path4.isAbsolute(resolvedPath)) {
|
|
6586
6926
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6587
6927
|
return null;
|
|
6588
6928
|
}
|
|
@@ -6607,7 +6947,7 @@ ${r.snippet.trim()}
|
|
|
6607
6947
|
}
|
|
6608
6948
|
continue;
|
|
6609
6949
|
}
|
|
6610
|
-
if (
|
|
6950
|
+
if (path4.isAbsolute(result.path)) {
|
|
6611
6951
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
6612
6952
|
if (resolved) {
|
|
6613
6953
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -6650,7 +6990,7 @@ ${r.snippet.trim()}
|
|
|
6650
6990
|
0
|
|
6651
6991
|
);
|
|
6652
6992
|
seedPaths.push(
|
|
6653
|
-
...seedRelativePaths.map((rel) =>
|
|
6993
|
+
...seedRelativePaths.map((rel) => path4.join(storage.dir, rel))
|
|
6654
6994
|
);
|
|
6655
6995
|
const seedSet = new Set(seedRelativePaths);
|
|
6656
6996
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
@@ -6666,7 +7006,7 @@ ${r.snippet.trim()}
|
|
|
6666
7006
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
6667
7007
|
if (deadlineExpired()) break;
|
|
6668
7008
|
if (seedSet.has(candidate.path)) continue;
|
|
6669
|
-
const memoryPath =
|
|
7009
|
+
const memoryPath = path4.resolve(storage.dir, candidate.path);
|
|
6670
7010
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
6671
7011
|
if (deadlineExpired()) break;
|
|
6672
7012
|
if (!memory) continue;
|
|
@@ -6691,7 +7031,7 @@ ${r.snippet.trim()}
|
|
|
6691
7031
|
path: memory.path,
|
|
6692
7032
|
score,
|
|
6693
7033
|
namespace,
|
|
6694
|
-
seed:
|
|
7034
|
+
seed: path4.resolve(storage.dir, candidate.seed),
|
|
6695
7035
|
hopDepth: candidate.hopDepth,
|
|
6696
7036
|
decayedWeight: candidate.decayedWeight,
|
|
6697
7037
|
graphType: candidate.graphType,
|
|
@@ -6712,12 +7052,12 @@ ${r.snippet.trim()}
|
|
|
6712
7052
|
}
|
|
6713
7053
|
async recordLastGraphRecallSnapshot(options) {
|
|
6714
7054
|
try {
|
|
6715
|
-
const snapshotPath =
|
|
7055
|
+
const snapshotPath = path4.join(
|
|
6716
7056
|
options.storage.dir,
|
|
6717
7057
|
"state",
|
|
6718
7058
|
"last_graph_recall.json"
|
|
6719
7059
|
);
|
|
6720
|
-
await
|
|
7060
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
6721
7061
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6722
7062
|
const totalSeedCount = options.seedPaths.length;
|
|
6723
7063
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -6729,7 +7069,7 @@ ${r.snippet.trim()}
|
|
|
6729
7069
|
const payload = {
|
|
6730
7070
|
recordedAt: now,
|
|
6731
7071
|
mode: options.recallMode,
|
|
6732
|
-
queryHash:
|
|
7072
|
+
queryHash: createHash2("sha256").update(options.prompt).digest("hex"),
|
|
6733
7073
|
queryLength: options.prompt.length,
|
|
6734
7074
|
namespaces: options.recallNamespaces,
|
|
6735
7075
|
seedCount: totalSeedCount,
|
|
@@ -6744,20 +7084,20 @@ ${r.snippet.trim()}
|
|
|
6744
7084
|
finalResults: (options.finalResults ?? []).slice(0, 64),
|
|
6745
7085
|
shadowComparison: options.shadowComparison
|
|
6746
7086
|
};
|
|
6747
|
-
await
|
|
7087
|
+
await writeFile3(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
6748
7088
|
} catch (err) {
|
|
6749
7089
|
log.debug(`last graph recall write failed: ${err}`);
|
|
6750
7090
|
}
|
|
6751
7091
|
}
|
|
6752
7092
|
async recordLastIntentSnapshot(options) {
|
|
6753
7093
|
try {
|
|
6754
|
-
const snapshotPath =
|
|
7094
|
+
const snapshotPath = path4.join(
|
|
6755
7095
|
options.storage.dir,
|
|
6756
7096
|
"state",
|
|
6757
7097
|
"last_intent.json"
|
|
6758
7098
|
);
|
|
6759
|
-
await
|
|
6760
|
-
await
|
|
7099
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7100
|
+
await writeFile3(
|
|
6761
7101
|
snapshotPath,
|
|
6762
7102
|
JSON.stringify(options.snapshot, null, 2),
|
|
6763
7103
|
"utf-8"
|
|
@@ -6768,13 +7108,13 @@ ${r.snippet.trim()}
|
|
|
6768
7108
|
}
|
|
6769
7109
|
async recordLastQmdRecallSnapshot(options) {
|
|
6770
7110
|
try {
|
|
6771
|
-
const snapshotPath =
|
|
7111
|
+
const snapshotPath = path4.join(
|
|
6772
7112
|
options.storage.dir,
|
|
6773
7113
|
"state",
|
|
6774
7114
|
"last_qmd_recall.json"
|
|
6775
7115
|
);
|
|
6776
|
-
await
|
|
6777
|
-
await
|
|
7116
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7117
|
+
await writeFile3(
|
|
6778
7118
|
snapshotPath,
|
|
6779
7119
|
JSON.stringify(options.snapshot, null, 2),
|
|
6780
7120
|
"utf-8"
|
|
@@ -6788,9 +7128,9 @@ ${r.snippet.trim()}
|
|
|
6788
7128
|
const stateDir = await this.resolveStateDirForNamespace(
|
|
6789
7129
|
options.namespace
|
|
6790
7130
|
);
|
|
6791
|
-
const snapshotPath =
|
|
6792
|
-
await
|
|
6793
|
-
await
|
|
7131
|
+
const snapshotPath = path4.join(stateDir, "last_intent.json");
|
|
7132
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7133
|
+
await writeFile3(
|
|
6794
7134
|
snapshotPath,
|
|
6795
7135
|
JSON.stringify(options.snapshot, null, 2),
|
|
6796
7136
|
"utf-8"
|
|
@@ -6801,12 +7141,12 @@ ${r.snippet.trim()}
|
|
|
6801
7141
|
}
|
|
6802
7142
|
async resolveStateDirForNamespace(namespace) {
|
|
6803
7143
|
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
6804
|
-
return
|
|
7144
|
+
return path4.join(this.config.memoryDir, "state");
|
|
6805
7145
|
}
|
|
6806
7146
|
if (namespace !== this.config.defaultNamespace) {
|
|
6807
|
-
return
|
|
7147
|
+
return path4.join(this.config.memoryDir, "namespaces", namespace, "state");
|
|
6808
7148
|
}
|
|
6809
|
-
const candidate =
|
|
7149
|
+
const candidate = path4.join(
|
|
6810
7150
|
this.config.memoryDir,
|
|
6811
7151
|
"namespaces",
|
|
6812
7152
|
this.config.defaultNamespace
|
|
@@ -6814,11 +7154,11 @@ ${r.snippet.trim()}
|
|
|
6814
7154
|
try {
|
|
6815
7155
|
const candidateStat = await stat(candidate);
|
|
6816
7156
|
if (candidateStat.isDirectory()) {
|
|
6817
|
-
return
|
|
7157
|
+
return path4.join(candidate, "state");
|
|
6818
7158
|
}
|
|
6819
7159
|
} catch {
|
|
6820
7160
|
}
|
|
6821
|
-
return
|
|
7161
|
+
return path4.join(this.config.memoryDir, "state");
|
|
6822
7162
|
}
|
|
6823
7163
|
buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
|
|
6824
7164
|
return results.slice(0, limit).map((result) => ({
|
|
@@ -7071,8 +7411,8 @@ ${r.snippet.trim()}
|
|
|
7071
7411
|
timings,
|
|
7072
7412
|
logger: log
|
|
7073
7413
|
});
|
|
7074
|
-
const promptHash =
|
|
7075
|
-
const traceId =
|
|
7414
|
+
const promptHash = createHash2("sha256").update(prompt).digest("hex");
|
|
7415
|
+
const traceId = createHash2("sha256").update(`${sessionKey ?? "default"}:${recallStart}:${promptHash}`).digest("hex").slice(0, 16);
|
|
7076
7416
|
const sectionBuckets = /* @__PURE__ */ new Map();
|
|
7077
7417
|
const queryPolicy = buildRecallQueryPolicy(prompt, sessionKey, {
|
|
7078
7418
|
cronRecallPolicyEnabled: this.config.cronRecallPolicyEnabled,
|
|
@@ -7081,7 +7421,7 @@ ${r.snippet.trim()}
|
|
|
7081
7421
|
cronConversationRecallMode: this.config.cronConversationRecallMode
|
|
7082
7422
|
});
|
|
7083
7423
|
const retrievalQuery = queryPolicy.retrievalQuery || prompt;
|
|
7084
|
-
const retrievalQueryHash =
|
|
7424
|
+
const retrievalQueryHash = createHash2("sha256").update(retrievalQuery).digest("hex");
|
|
7085
7425
|
const policyVersion = this.currentPolicyVersion();
|
|
7086
7426
|
let impressionRecorded = false;
|
|
7087
7427
|
let recallSource = "none";
|
|
@@ -7220,7 +7560,7 @@ ${r.snippet.trim()}
|
|
|
7220
7560
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
7221
7561
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
7222
7562
|
const labels = [];
|
|
7223
|
-
const normalizedPath = resultPath.split(
|
|
7563
|
+
const normalizedPath = resultPath.split(path4.sep).join("/");
|
|
7224
7564
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
7225
7565
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
7226
7566
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -7370,7 +7710,7 @@ ${r.snippet.trim()}
|
|
|
7370
7710
|
profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace))
|
|
7371
7711
|
);
|
|
7372
7712
|
const emptyProfileStorage = new Proxy(
|
|
7373
|
-
{ dir:
|
|
7713
|
+
{ dir: path4.join(this.config.memoryDir, ".empty-scope-profile") },
|
|
7374
7714
|
{
|
|
7375
7715
|
get(target, prop) {
|
|
7376
7716
|
if (prop in target) return target[prop];
|
|
@@ -7852,9 +8192,9 @@ ${rows.join("\n")}
|
|
|
7852
8192
|
})();
|
|
7853
8193
|
const objectiveStatePromise = (async () => {
|
|
7854
8194
|
const t0 = Date.now();
|
|
7855
|
-
if (!this.config.
|
|
8195
|
+
if (!resolveObjectiveStateCapabilities(this.config).objectiveStateMemory || !resolveObjectiveStateCapabilities(this.config).objectiveStateRecall || !this.isRecallSectionEnabled(
|
|
7856
8196
|
"objective-state",
|
|
7857
|
-
this.config.
|
|
8197
|
+
resolveObjectiveStateCapabilities(this.config).objectiveStateRecall === true
|
|
7858
8198
|
)) {
|
|
7859
8199
|
recordRecallSectionMetric({
|
|
7860
8200
|
section: "objectiveState",
|
|
@@ -8073,9 +8413,9 @@ ${rows.join("\n")}
|
|
|
8073
8413
|
})();
|
|
8074
8414
|
const trustZonePromise = (async () => {
|
|
8075
8415
|
const t0 = Date.now();
|
|
8076
|
-
if (!this.config.
|
|
8416
|
+
if (!resolveSecurityCapabilities(this.config).trustZones || !resolveSecurityCapabilities(this.config).trustZoneRecall || !this.isRecallSectionEnabled(
|
|
8077
8417
|
"trust-zones",
|
|
8078
|
-
this.config.
|
|
8418
|
+
resolveSecurityCapabilities(this.config).trustZoneRecall === true
|
|
8079
8419
|
)) {
|
|
8080
8420
|
recordRecallSectionMetric({
|
|
8081
8421
|
section: "trustZones",
|
|
@@ -8846,11 +9186,11 @@ ${formatted}`;
|
|
|
8846
9186
|
if (!this.config.compactionResetEnabled) return null;
|
|
8847
9187
|
const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
|
|
8848
9188
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
8849
|
-
const signalPath =
|
|
9189
|
+
const signalPath = path4.join(
|
|
8850
9190
|
workspaceDir,
|
|
8851
9191
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
8852
9192
|
);
|
|
8853
|
-
const bootPath =
|
|
9193
|
+
const bootPath = path4.join(workspaceDir, "BOOT.md");
|
|
8854
9194
|
try {
|
|
8855
9195
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
8856
9196
|
if (!signalStat) return null;
|
|
@@ -10535,7 +10875,7 @@ ${tmtNode.summary}`
|
|
|
10535
10875
|
});
|
|
10536
10876
|
if (this.isRecallSectionEnabled(
|
|
10537
10877
|
"compression-guidelines",
|
|
10538
|
-
this.config.
|
|
10878
|
+
resolveCompressionCapabilities(this.config).compressionGuidelineLearning === true
|
|
10539
10879
|
)) {
|
|
10540
10880
|
const compressionGuidelineSection = await this.buildCompressionGuidelineRecallSection();
|
|
10541
10881
|
if (compressionGuidelineSection) {
|
|
@@ -11121,7 +11461,7 @@ _Context: ${topQuestion.context}_`
|
|
|
11121
11461
|
const shouldUseStableBatchKey = turns.some(
|
|
11122
11462
|
(turn) => turn.persistProcessedFingerprint === true || typeof turn.turnFingerprint === "string" && turn.turnFingerprint.length > 0
|
|
11123
11463
|
);
|
|
11124
|
-
const stableBatchFingerprint = shouldUseStableBatchKey ?
|
|
11464
|
+
const stableBatchFingerprint = shouldUseStableBatchKey ? createHash2("sha256").update(
|
|
11125
11465
|
turns.map(
|
|
11126
11466
|
(turn) => [
|
|
11127
11467
|
turn.role,
|
|
@@ -11371,7 +11711,7 @@ _Context: ${topQuestion.context}_`
|
|
|
11371
11711
|
buildExtractionFingerprint(turns, bufferKey) {
|
|
11372
11712
|
const normalized = this.normalizeExtractionFingerprintTurns(turns).join("\n");
|
|
11373
11713
|
if (!normalized) return null;
|
|
11374
|
-
return
|
|
11714
|
+
return createHash2("sha256").update(`${bufferKey}
|
|
11375
11715
|
${normalized}`).digest("hex");
|
|
11376
11716
|
}
|
|
11377
11717
|
shouldQueueExtraction(turns, options = {}) {
|
|
@@ -13452,7 +13792,7 @@ ${normalized}`).digest("hex");
|
|
|
13452
13792
|
const allMems = allMemsForGraph ?? [];
|
|
13453
13793
|
for (const m of allMems) {
|
|
13454
13794
|
if (m.frontmatter.entityRef === entityRef) {
|
|
13455
|
-
const rel =
|
|
13795
|
+
const rel = path4.relative(storage.dir, m.path);
|
|
13456
13796
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
13457
13797
|
}
|
|
13458
13798
|
}
|
|
@@ -13776,7 +14116,7 @@ ${normalized}`).digest("hex");
|
|
|
13776
14116
|
}
|
|
13777
14117
|
if (this.config.semanticConsolidationEnabled) {
|
|
13778
14118
|
try {
|
|
13779
|
-
const stateFilePath =
|
|
14119
|
+
const stateFilePath = path4.join(
|
|
13780
14120
|
this.config.memoryDir,
|
|
13781
14121
|
"state",
|
|
13782
14122
|
"semantic-consolidation-last-run.json"
|
|
@@ -13824,9 +14164,9 @@ ${normalized}`).digest("hex");
|
|
|
13824
14164
|
);
|
|
13825
14165
|
}
|
|
13826
14166
|
if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
|
|
13827
|
-
const stateDir =
|
|
13828
|
-
await
|
|
13829
|
-
await
|
|
14167
|
+
const stateDir = path4.join(this.config.memoryDir, "state");
|
|
14168
|
+
await mkdir3(stateDir, { recursive: true });
|
|
14169
|
+
await writeFile3(
|
|
13830
14170
|
stateFilePath,
|
|
13831
14171
|
JSON.stringify({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString() }),
|
|
13832
14172
|
"utf-8"
|
|
@@ -13951,65 +14291,6 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
13951
14291
|
async buildCompressionGuidelineRecallSection() {
|
|
13952
14292
|
return this.compressionGuidelineCoordinator.buildCompressionGuidelineRecallSection();
|
|
13953
14293
|
}
|
|
13954
|
-
actionOutcomePriorDelta(event) {
|
|
13955
|
-
if (event.outcome === "failed") return -0.3;
|
|
13956
|
-
if (event.policyDecision === "deny") return -0.22;
|
|
13957
|
-
if (event.policyDecision === "defer") return -0.14;
|
|
13958
|
-
if (event.outcome === "skipped") return -0.1;
|
|
13959
|
-
if (event.outcome !== "applied") return 0;
|
|
13960
|
-
switch (event.action) {
|
|
13961
|
-
case "store_episode":
|
|
13962
|
-
case "store_note":
|
|
13963
|
-
case "update_note":
|
|
13964
|
-
return 0.08;
|
|
13965
|
-
case "create_artifact":
|
|
13966
|
-
case "summarize_node":
|
|
13967
|
-
case "link_graph":
|
|
13968
|
-
return 0.04;
|
|
13969
|
-
case "discard":
|
|
13970
|
-
return -0.03;
|
|
13971
|
-
default:
|
|
13972
|
-
return 0;
|
|
13973
|
-
}
|
|
13974
|
-
}
|
|
13975
|
-
async buildLifecycleActionPriors(storage = this.storage) {
|
|
13976
|
-
const events = await storage.readMemoryActionEvents(1200);
|
|
13977
|
-
if (events.length === 0) return /* @__PURE__ */ new Map();
|
|
13978
|
-
const nowMs = Date.now();
|
|
13979
|
-
const windowMs = 14 * 24 * 60 * 60 * 1e3;
|
|
13980
|
-
const byMemory = /* @__PURE__ */ new Map();
|
|
13981
|
-
for (const event of events) {
|
|
13982
|
-
if (typeof event.memoryId !== "string" || event.memoryId.trim().length === 0)
|
|
13983
|
-
continue;
|
|
13984
|
-
const ts = Date.parse(event.timestamp);
|
|
13985
|
-
if (!Number.isFinite(ts)) continue;
|
|
13986
|
-
const ageMs = nowMs - ts;
|
|
13987
|
-
if (ageMs < 0 || ageMs > windowMs) continue;
|
|
13988
|
-
const delta = this.actionOutcomePriorDelta(event);
|
|
13989
|
-
if (delta === 0) continue;
|
|
13990
|
-
const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
|
|
13991
|
-
const list = byMemory.get(event.memoryId) ?? [];
|
|
13992
|
-
if (list.length >= 8) list.shift();
|
|
13993
|
-
list.push({
|
|
13994
|
-
weightedDelta: delta * recencyWeight,
|
|
13995
|
-
weight: recencyWeight
|
|
13996
|
-
});
|
|
13997
|
-
byMemory.set(event.memoryId, list);
|
|
13998
|
-
}
|
|
13999
|
-
const out = /* @__PURE__ */ new Map();
|
|
14000
|
-
for (const [memoryId, deltas] of byMemory.entries()) {
|
|
14001
|
-
if (deltas.length === 0) continue;
|
|
14002
|
-
const weightedSum = deltas.reduce(
|
|
14003
|
-
(sum, item) => sum + item.weightedDelta,
|
|
14004
|
-
0
|
|
14005
|
-
);
|
|
14006
|
-
const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
|
|
14007
|
-
if (weightTotal <= 0) continue;
|
|
14008
|
-
const score = weightedSum / weightTotal;
|
|
14009
|
-
out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
|
|
14010
|
-
}
|
|
14011
|
-
return out;
|
|
14012
|
-
}
|
|
14013
14294
|
async recordScheduledDreamsPhaseRun(phase, itemsProcessed, notes, timing = {}) {
|
|
14014
14295
|
try {
|
|
14015
14296
|
const { recordDreamsPhaseRun } = await import("./dreams-ledger-6UODQOX6.js");
|
|
@@ -14033,215 +14314,16 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
14033
14314
|
return { memoriesAssessed: lifecycleCorpus.length };
|
|
14034
14315
|
}
|
|
14035
14316
|
async runLifecyclePolicyPass(allMemories, storage = this.storage) {
|
|
14036
|
-
|
|
14037
|
-
const nowIso = now.toISOString();
|
|
14038
|
-
const countsByState = {
|
|
14039
|
-
candidate: 0,
|
|
14040
|
-
validated: 0,
|
|
14041
|
-
active: 0,
|
|
14042
|
-
stale: 0,
|
|
14043
|
-
archived: 0
|
|
14044
|
-
};
|
|
14045
|
-
const transitionCounts = {};
|
|
14046
|
-
let updatedCount = 0;
|
|
14047
|
-
let disputedCount = 0;
|
|
14048
|
-
let evaluatedCount = 0;
|
|
14049
|
-
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
14050
|
-
const thresholds = this.effectiveLifecycleThresholds();
|
|
14051
|
-
const policy = {
|
|
14052
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
14053
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
14054
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
14055
|
-
protectedCategories: this.config.lifecycleProtectedCategories
|
|
14056
|
-
};
|
|
14057
|
-
const actionPriors = await this.buildLifecycleActionPriors(storage);
|
|
14058
|
-
for (const memory of allMemories) {
|
|
14059
|
-
if (memory.frontmatter.status === "superseded" || memory.frontmatter.status === "forgotten") {
|
|
14060
|
-
continue;
|
|
14061
|
-
}
|
|
14062
|
-
evaluatedCount += 1;
|
|
14063
|
-
const currentState = resolveLifecycleState(memory.frontmatter);
|
|
14064
|
-
const actionPriorScore = actionPriors.get(memory.frontmatter.id);
|
|
14065
|
-
const signals = typeof actionPriorScore === "number" && Number.isFinite(actionPriorScore) ? { actionPriorScore } : void 0;
|
|
14066
|
-
const decision = decideLifecycleTransition(memory, policy, now, signals);
|
|
14067
|
-
const nextState = memory.frontmatter.status === "archived" ? "archived" : decision.nextState;
|
|
14068
|
-
countsByState[nextState] += 1;
|
|
14069
|
-
if (memory.frontmatter.verificationState === "disputed") {
|
|
14070
|
-
disputedCount += 1;
|
|
14071
|
-
}
|
|
14072
|
-
if (nextState !== currentState) {
|
|
14073
|
-
const key = `${currentState}->${nextState}`;
|
|
14074
|
-
transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
|
|
14075
|
-
}
|
|
14076
|
-
const prevHeat = memory.frontmatter.heatScore;
|
|
14077
|
-
const prevDecay = memory.frontmatter.decayScore;
|
|
14078
|
-
const scoreDelta = Math.abs((prevHeat ?? -1) - decision.heatScore) + Math.abs((prevDecay ?? -1) - decision.decayScore);
|
|
14079
|
-
const shouldPersist = memory.frontmatter.lifecycleState !== nextState || memory.frontmatter.heatScore === void 0 || memory.frontmatter.decayScore === void 0 || memory.frontmatter.lastValidatedAt === void 0 || scoreDelta >= 0.01;
|
|
14080
|
-
if (!shouldPersist) continue;
|
|
14081
|
-
const wrote = await storage.writeMemoryFrontmatter(memory, {
|
|
14082
|
-
lifecycleState: nextState,
|
|
14083
|
-
heatScore: decision.heatScore,
|
|
14084
|
-
decayScore: decision.decayScore,
|
|
14085
|
-
lastValidatedAt: nowIso
|
|
14086
|
-
});
|
|
14087
|
-
if (wrote) updatedCount += 1;
|
|
14088
|
-
}
|
|
14089
|
-
if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
|
|
14090
|
-
const total = evaluatedCount;
|
|
14091
|
-
const metrics = {
|
|
14092
|
-
generatedAt: nowIso,
|
|
14093
|
-
memoriesEvaluated: total,
|
|
14094
|
-
memoriesUpdated: updatedCount,
|
|
14095
|
-
countsByLifecycleState: countsByState,
|
|
14096
|
-
transitionCounts,
|
|
14097
|
-
staleRatio: total > 0 ? countsByState.stale / total : 0,
|
|
14098
|
-
disputedRatio: total > 0 ? disputedCount / total : 0,
|
|
14099
|
-
policy: {
|
|
14100
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
14101
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
14102
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
14103
|
-
protectedCategories: this.config.lifecycleProtectedCategories
|
|
14104
|
-
}
|
|
14105
|
-
};
|
|
14106
|
-
const metricsPath = path3.join(
|
|
14107
|
-
storage.dir,
|
|
14108
|
-
"state",
|
|
14109
|
-
"lifecycle-metrics.json"
|
|
14110
|
-
);
|
|
14111
|
-
await mkdir2(path3.dirname(metricsPath), { recursive: true });
|
|
14112
|
-
await writeFile2(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
|
|
14113
|
-
return updatedCount;
|
|
14317
|
+
return this.lifecyclePolicyCoordinator.runLifecyclePolicyPass(allMemories, storage);
|
|
14114
14318
|
}
|
|
14115
|
-
/**
|
|
14116
|
-
* Archive old, low-importance, rarely-accessed facts (v6.0).
|
|
14117
|
-
* Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
|
|
14118
|
-
* Returns the number of archived facts.
|
|
14119
|
-
*/
|
|
14120
14319
|
async runFactArchival(allMemories) {
|
|
14121
|
-
|
|
14122
|
-
const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1e3;
|
|
14123
|
-
const protectedCategories = new Set(
|
|
14124
|
-
this.config.factArchivalProtectedCategories
|
|
14125
|
-
);
|
|
14126
|
-
let archivedCount = 0;
|
|
14127
|
-
for (const memory of allMemories) {
|
|
14128
|
-
const fm = memory.frontmatter;
|
|
14129
|
-
if (fm.status && fm.status !== "active") continue;
|
|
14130
|
-
if (protectedCategories.has(fm.category)) continue;
|
|
14131
|
-
if (fm.category === "correction") continue;
|
|
14132
|
-
const createdMs = new Date(fm.created).getTime();
|
|
14133
|
-
if (now - createdMs < ageCutoffMs) continue;
|
|
14134
|
-
const importanceScore = fm.importance?.score ?? 0.5;
|
|
14135
|
-
if (importanceScore >= this.config.factArchivalMaxImportance) continue;
|
|
14136
|
-
const accessCount = fm.accessCount ?? 0;
|
|
14137
|
-
if (accessCount > this.config.factArchivalMaxAccessCount) continue;
|
|
14138
|
-
const result = await this.storage.archiveMemory(memory);
|
|
14139
|
-
if (result) {
|
|
14140
|
-
await this.removeContentHashForMemory(
|
|
14141
|
-
this.storage,
|
|
14142
|
-
memory,
|
|
14143
|
-
"fact-archival"
|
|
14144
|
-
);
|
|
14145
|
-
await this.embeddingFallback.removeFromIndex(memory.frontmatter.id);
|
|
14146
|
-
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && memory.path && memory.frontmatter?.created) {
|
|
14147
|
-
deindexMemory(
|
|
14148
|
-
this.config.memoryDir,
|
|
14149
|
-
memory.path,
|
|
14150
|
-
memory.frontmatter.created,
|
|
14151
|
-
memory.frontmatter.tags ?? []
|
|
14152
|
-
);
|
|
14153
|
-
}
|
|
14154
|
-
archivedCount++;
|
|
14155
|
-
}
|
|
14156
|
-
}
|
|
14157
|
-
if (archivedCount > 0) {
|
|
14158
|
-
await this.saveContentHashIndexes().catch(
|
|
14159
|
-
(err) => log.warn(`content-hash index save failed during archival: ${err}`)
|
|
14160
|
-
);
|
|
14161
|
-
}
|
|
14162
|
-
return archivedCount;
|
|
14320
|
+
return this.lifecyclePolicyCoordinator.runFactArchival(allMemories);
|
|
14163
14321
|
}
|
|
14164
|
-
/**
|
|
14165
|
-
* Run memory summarization if memory count exceeds threshold (Phase 4A).
|
|
14166
|
-
*/
|
|
14167
14322
|
async runSummarization(allMemories) {
|
|
14168
|
-
|
|
14169
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
14170
|
-
);
|
|
14171
|
-
if (activeMemories.length < this.config.summarizationTriggerCount) {
|
|
14172
|
-
return;
|
|
14173
|
-
}
|
|
14174
|
-
log.info(
|
|
14175
|
-
`memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) \u2014 running summarization`
|
|
14176
|
-
);
|
|
14177
|
-
const sorted = activeMemories.sort(
|
|
14178
|
-
(a, b) => new Date(a.frontmatter.created).getTime() - new Date(b.frontmatter.created).getTime()
|
|
14179
|
-
);
|
|
14180
|
-
const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
|
|
14181
|
-
const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
|
|
14182
|
-
const candidates = toSummarize.filter((m) => {
|
|
14183
|
-
if (m.frontmatter.entityRef) return false;
|
|
14184
|
-
const protectedTags = this.config.summarizationProtectedTags;
|
|
14185
|
-
if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
|
|
14186
|
-
return false;
|
|
14187
|
-
const importance = m.frontmatter.importance?.score ?? 0.5;
|
|
14188
|
-
if (importance >= this.config.summarizationImportanceThreshold)
|
|
14189
|
-
return false;
|
|
14190
|
-
return true;
|
|
14191
|
-
});
|
|
14192
|
-
if (candidates.length < 50) {
|
|
14193
|
-
log.debug(
|
|
14194
|
-
`only ${candidates.length} candidates for summarization \u2014 skipping`
|
|
14195
|
-
);
|
|
14196
|
-
return;
|
|
14197
|
-
}
|
|
14198
|
-
const batchSize = 50;
|
|
14199
|
-
for (let i = 0; i < candidates.length; i += batchSize) {
|
|
14200
|
-
const batch = candidates.slice(i, i + batchSize);
|
|
14201
|
-
const batchData = batch.map((m) => ({
|
|
14202
|
-
id: m.frontmatter.id,
|
|
14203
|
-
content: m.content,
|
|
14204
|
-
category: m.frontmatter.category,
|
|
14205
|
-
created: m.frontmatter.created
|
|
14206
|
-
}));
|
|
14207
|
-
const result = await this.extraction.summarizeMemories(batchData);
|
|
14208
|
-
if (!result) continue;
|
|
14209
|
-
const summary = {
|
|
14210
|
-
id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
14211
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14212
|
-
timeRangeStart: batch[0].frontmatter.created,
|
|
14213
|
-
timeRangeEnd: batch[batch.length - 1].frontmatter.created,
|
|
14214
|
-
summaryText: result.summaryText,
|
|
14215
|
-
keyFacts: result.keyFacts,
|
|
14216
|
-
keyEntities: result.keyEntities,
|
|
14217
|
-
sourceEpisodeIds: batch.map((m) => m.frontmatter.id)
|
|
14218
|
-
};
|
|
14219
|
-
await this.storage.writeSummary(summary);
|
|
14220
|
-
const archived = await this.storage.archiveMemories(
|
|
14221
|
-
batch.map((m) => m.frontmatter.id),
|
|
14222
|
-
summary.id
|
|
14223
|
-
);
|
|
14224
|
-
log.info(
|
|
14225
|
-
`created summary ${summary.id} from ${batch.length} memories, archived ${archived}`
|
|
14226
|
-
);
|
|
14227
|
-
}
|
|
14323
|
+
return this.lifecyclePolicyCoordinator.runSummarization(allMemories);
|
|
14228
14324
|
}
|
|
14229
|
-
/**
|
|
14230
|
-
* Run topic extraction on all memories (Phase 4B).
|
|
14231
|
-
*/
|
|
14232
14325
|
async runTopicExtraction(allMemories) {
|
|
14233
|
-
|
|
14234
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
14235
|
-
);
|
|
14236
|
-
if (activeMemories.length === 0) return;
|
|
14237
|
-
const topics = extractTopics(
|
|
14238
|
-
activeMemories,
|
|
14239
|
-
this.config.topicExtractionTopN
|
|
14240
|
-
);
|
|
14241
|
-
await this.storage.saveTopics(topics);
|
|
14242
|
-
log.debug(
|
|
14243
|
-
`extracted ${topics.length} topics from ${activeMemories.length} memories`
|
|
14244
|
-
);
|
|
14326
|
+
return this.lifecyclePolicyCoordinator.runTopicExtraction(allMemories);
|
|
14245
14327
|
}
|
|
14246
14328
|
/** Threshold (bytes) at which IDENTITY.md reflections get auto-consolidated */
|
|
14247
14329
|
static IDENTITY_CONSOLIDATE_THRESHOLD = 8e3;
|
|
@@ -14589,7 +14671,7 @@ ${lines.join("\n\n")}`;
|
|
|
14589
14671
|
}
|
|
14590
14672
|
}
|
|
14591
14673
|
queueEvalShadowRecall(record) {
|
|
14592
|
-
if (!this.config.
|
|
14674
|
+
if (!resolveEvalCapabilities(this.config).evalHarness || !resolveEvalCapabilities(this.config).evalShadowMode)
|
|
14593
14675
|
return;
|
|
14594
14676
|
this.evalShadowWriteChain = this.evalShadowWriteChain.catch(() => void 0).then(async () => {
|
|
14595
14677
|
try {
|
|
@@ -14651,7 +14733,7 @@ ${lines.join("\n\n")}`;
|
|
|
14651
14733
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
14652
14734
|
const addStorage = (storage) => {
|
|
14653
14735
|
const storageDir = storageDirFor(storage);
|
|
14654
|
-
const storageKey = storageDir ?
|
|
14736
|
+
const storageKey = storageDir ? path4.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
14655
14737
|
if (seenStorageDirs.has(storageKey)) return;
|
|
14656
14738
|
seenStorageDirs.add(storageKey);
|
|
14657
14739
|
storages.push(storage);
|
|
@@ -14681,7 +14763,7 @@ ${lines.join("\n\n")}`;
|
|
|
14681
14763
|
continue;
|
|
14682
14764
|
}
|
|
14683
14765
|
try {
|
|
14684
|
-
const coldRoot =
|
|
14766
|
+
const coldRoot = path4.join(storageDir, "cold");
|
|
14685
14767
|
for (const candidate of qmdResultPathCandidates(
|
|
14686
14768
|
coldRoot,
|
|
14687
14769
|
parts.relativePath
|
|
@@ -14722,7 +14804,7 @@ ${lines.join("\n\n")}`;
|
|
|
14722
14804
|
return null;
|
|
14723
14805
|
}
|
|
14724
14806
|
}
|
|
14725
|
-
if (
|
|
14807
|
+
if (path4.isAbsolute(resultPath)) {
|
|
14726
14808
|
if (!fallbackStorageDir) {
|
|
14727
14809
|
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
14728
14810
|
}
|
|
@@ -14761,7 +14843,7 @@ ${lines.join("\n\n")}`;
|
|
|
14761
14843
|
);
|
|
14762
14844
|
if (!memory) return null;
|
|
14763
14845
|
let ownerNamespace = null;
|
|
14764
|
-
if (
|
|
14846
|
+
if (path4.isAbsolute(memory.path)) {
|
|
14765
14847
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
14766
14848
|
memory.path,
|
|
14767
14849
|
fallbackStorage,
|
|
@@ -14785,16 +14867,16 @@ ${lines.join("\n\n")}`;
|
|
|
14785
14867
|
};
|
|
14786
14868
|
}
|
|
14787
14869
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
14788
|
-
const resolvedPath =
|
|
14789
|
-
const memoryRoot =
|
|
14790
|
-
const namespacesRoot =
|
|
14870
|
+
const resolvedPath = path4.resolve(resultPath);
|
|
14871
|
+
const memoryRoot = path4.resolve(this.config.memoryDir);
|
|
14872
|
+
const namespacesRoot = path4.join(memoryRoot, "namespaces");
|
|
14791
14873
|
const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
|
|
14792
14874
|
const matches = [];
|
|
14793
14875
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
14794
14876
|
const maybeAddStorage = (storage, namespace) => {
|
|
14795
14877
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
14796
14878
|
if (!storageDir) return;
|
|
14797
|
-
const candidateRoot =
|
|
14879
|
+
const candidateRoot = path4.resolve(storageDir);
|
|
14798
14880
|
if (seenDirs.has(candidateRoot)) return;
|
|
14799
14881
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
14800
14882
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -14812,7 +14894,7 @@ ${lines.join("\n\n")}`;
|
|
|
14812
14894
|
candidateNamespaces.add(ns);
|
|
14813
14895
|
}
|
|
14814
14896
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
14815
|
-
const relativeToNamespaces =
|
|
14897
|
+
const relativeToNamespaces = path4.relative(namespacesRoot, resolvedPath);
|
|
14816
14898
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
14817
14899
|
if (namespaceSegment) {
|
|
14818
14900
|
candidateNamespaces.add(
|
|
@@ -14857,7 +14939,7 @@ ${lines.join("\n\n")}`;
|
|
|
14857
14939
|
nsMap = buildMemoryWorthCounterMap(memories);
|
|
14858
14940
|
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
14859
14941
|
}
|
|
14860
|
-
for (const [
|
|
14942
|
+
for (const [path5, c] of nsMap) counters.set(path5, c);
|
|
14861
14943
|
} catch (err) {
|
|
14862
14944
|
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
14863
14945
|
namespace: ns,
|
|
@@ -14940,7 +15022,7 @@ ${lines.join("\n\n")}`;
|
|
|
14940
15022
|
namespaces,
|
|
14941
15023
|
{
|
|
14942
15024
|
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
14943
|
-
readMemoryFrontmatter: async (
|
|
15025
|
+
readMemoryFrontmatter: async (path5) => {
|
|
14944
15026
|
if (!fallbackReader) {
|
|
14945
15027
|
for (const ns of namespaces) {
|
|
14946
15028
|
try {
|
|
@@ -14951,7 +15033,7 @@ ${lines.join("\n\n")}`;
|
|
|
14951
15033
|
}
|
|
14952
15034
|
}
|
|
14953
15035
|
if (!fallbackReader) return null;
|
|
14954
|
-
const memory = await this.readQmdResultMemory(
|
|
15036
|
+
const memory = await this.readQmdResultMemory(path5, fallbackReader, namespaces);
|
|
14955
15037
|
return memory ? memory.frontmatter : null;
|
|
14956
15038
|
}
|
|
14957
15039
|
},
|
|
@@ -15121,12 +15203,12 @@ ${lines.join("\n\n")}`;
|
|
|
15121
15203
|
*/
|
|
15122
15204
|
semanticDedupScopeFor(targetStorage) {
|
|
15123
15205
|
if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
|
|
15124
|
-
const memoryDir =
|
|
15125
|
-
const storageDir =
|
|
15206
|
+
const memoryDir = path4.resolve(this.config.memoryDir);
|
|
15207
|
+
const storageDir = path4.resolve(targetStorage.dir);
|
|
15126
15208
|
if (storageDir === memoryDir) {
|
|
15127
15209
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
15128
15210
|
}
|
|
15129
|
-
let rel =
|
|
15211
|
+
let rel = path4.relative(memoryDir, storageDir);
|
|
15130
15212
|
if (!rel || rel.startsWith("..")) {
|
|
15131
15213
|
log.debug(
|
|
15132
15214
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -15145,7 +15227,7 @@ ${lines.join("\n\n")}`;
|
|
|
15145
15227
|
if (hits.length === 0) return [];
|
|
15146
15228
|
const results = [];
|
|
15147
15229
|
for (const hit of hits) {
|
|
15148
|
-
const fullPath =
|
|
15230
|
+
const fullPath = path4.isAbsolute(hit.path) ? hit.path : path4.join(this.config.memoryDir, hit.path);
|
|
15149
15231
|
const memory = await this.storage.readMemoryByPath(fullPath);
|
|
15150
15232
|
if (!memory) continue;
|
|
15151
15233
|
results.push({
|
|
@@ -15342,7 +15424,7 @@ ${lines.join("\n\n")}`;
|
|
|
15342
15424
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
15343
15425
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
15344
15426
|
if (!storageDir) continue;
|
|
15345
|
-
const recallRoot =
|
|
15427
|
+
const recallRoot = path4.resolve(storageDir);
|
|
15346
15428
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
15347
15429
|
seenRecallRoots.add(recallRoot);
|
|
15348
15430
|
recallRoots.push(recallRoot);
|
|
@@ -15366,8 +15448,8 @@ ${lines.join("\n\n")}`;
|
|
|
15366
15448
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
15367
15449
|
continue;
|
|
15368
15450
|
}
|
|
15369
|
-
if (
|
|
15370
|
-
const resolvedPath =
|
|
15451
|
+
if (path4.isAbsolute(result.path)) {
|
|
15452
|
+
const resolvedPath = path4.resolve(result.path);
|
|
15371
15453
|
if (recallRoots.some(
|
|
15372
15454
|
(recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
|
|
15373
15455
|
)) {
|
|
@@ -16274,7 +16356,6 @@ export {
|
|
|
16274
16356
|
WearablesService,
|
|
16275
16357
|
locateTranscriptPath,
|
|
16276
16358
|
BulkImportBatchPartialFailureError,
|
|
16277
|
-
dedupeEntitySynthesisEvidenceEntries,
|
|
16278
16359
|
defaultWorkspaceDir,
|
|
16279
16360
|
sanitizeSessionKeyForFilename,
|
|
16280
16361
|
isArtifactMemoryPath,
|
|
@@ -16302,4 +16383,4 @@ export {
|
|
|
16302
16383
|
resolvePersistedMemoryRelativePath,
|
|
16303
16384
|
Orchestrator
|
|
16304
16385
|
};
|
|
16305
|
-
//# sourceMappingURL=chunk-
|
|
16386
|
+
//# sourceMappingURL=chunk-AE2HPUP7.js.map
|