@remnic/core 9.3.733 → 9.3.735
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 +13 -11
- package/dist/access-boundary.js +9 -9
- package/dist/access-cli.js +26 -24
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +13 -11
- package/dist/access-http.js +14 -14
- package/dist/access-mcp.d.ts +13 -11
- package/dist/access-mcp.js +13 -13
- package/dist/access-operations-batch.js +11 -11
- package/dist/access-operations.d.ts +13 -11
- package/dist/access-operations.js +12 -12
- package/dist/access-schema.d.ts +4 -4
- package/dist/{access-service-Byoe3HsT.d.ts → access-service-CVx7mmvK.d.ts} +4 -4
- package/dist/access-service.d.ts +13 -11
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +13 -11
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -2
- 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 +12 -10
- 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 +196 -2
- package/dist/capabilities.js +21 -3
- package/dist/{catalog-DM1nk7cM.d.ts → catalog-BVhDEUhT.d.ts} +2 -2
- 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-CX77GNMB.js → chunk-2T2N7ISV.js} +6 -3
- package/dist/chunk-2T2N7ISV.js.map +1 -0
- package/dist/{chunk-HHNSLPX7.js → chunk-5BOQNB2K.js} +10 -9
- package/dist/chunk-5BOQNB2K.js.map +1 -0
- package/dist/{chunk-QZHF4BWN.js → chunk-AAIHDIMD.js} +6 -6
- package/dist/{chunk-H3MB3F62.js → chunk-AB2E5DCN.js} +4 -3
- package/dist/chunk-AB2E5DCN.js.map +1 -0
- package/dist/{chunk-KSJCXXOU.js → chunk-AE7NTZ75.js} +6 -3
- package/dist/chunk-AE7NTZ75.js.map +1 -0
- package/dist/{chunk-OTQE66IX.js → chunk-AESC5OQJ.js} +6 -3
- package/dist/chunk-AESC5OQJ.js.map +1 -0
- package/dist/{chunk-FFUCCKPN.js → chunk-BXPG5AVX.js} +10 -7
- package/dist/chunk-BXPG5AVX.js.map +1 -0
- package/dist/{chunk-P3VJCTVE.js → chunk-CHJIWG2H.js} +4 -3
- package/dist/chunk-CHJIWG2H.js.map +1 -0
- package/dist/{chunk-FYWUNVFZ.js → chunk-E4LYJ7PY.js} +6 -6
- package/dist/{chunk-NIZQH6AU.js → chunk-FF36YNKY.js} +8 -7
- package/dist/chunk-FF36YNKY.js.map +1 -0
- package/dist/{chunk-OUITHS6V.js → chunk-FLCYY5JX.js} +801 -711
- package/dist/chunk-FLCYY5JX.js.map +1 -0
- package/dist/{chunk-PLBIPT6I.js → chunk-FLPKEMSO.js} +7 -4
- package/dist/chunk-FLPKEMSO.js.map +1 -0
- package/dist/{chunk-6TUWSUUD.js → chunk-G54IDCD3.js} +59 -53
- package/dist/chunk-G54IDCD3.js.map +1 -0
- package/dist/{chunk-J6BH2OBA.js → chunk-GB2FZOWB.js} +8 -5
- package/dist/chunk-GB2FZOWB.js.map +1 -0
- package/dist/{chunk-CGPHMNL4.js → chunk-GYICIICQ.js} +10 -6
- package/dist/chunk-GYICIICQ.js.map +1 -0
- package/dist/{chunk-DKT3X5C3.js → chunk-HFXZIF3V.js} +7 -4
- package/dist/chunk-HFXZIF3V.js.map +1 -0
- package/dist/{chunk-646B5ERJ.js → chunk-HLPYL6LC.js} +71 -65
- package/dist/chunk-HLPYL6LC.js.map +1 -0
- package/dist/{chunk-ZVHRSR2R.js → chunk-IPI45Q4S.js} +6 -3
- package/dist/chunk-IPI45Q4S.js.map +1 -0
- package/dist/{chunk-24D66MMN.js → chunk-IX4L7E5G.js} +7 -4
- package/dist/chunk-IX4L7E5G.js.map +1 -0
- package/dist/{chunk-SYX73XD7.js → chunk-IXGXALRV.js} +10 -7
- package/dist/chunk-IXGXALRV.js.map +1 -0
- package/dist/{chunk-ESF7TRYJ.js → chunk-JWDE7OVJ.js} +79 -2
- package/dist/chunk-JWDE7OVJ.js.map +1 -0
- package/dist/{chunk-GGL34GCW.js → chunk-K3Y2SJTN.js} +7 -4
- package/dist/chunk-K3Y2SJTN.js.map +1 -0
- package/dist/{chunk-PMAQRUN4.js → chunk-NDKW67ER.js} +5 -2
- package/dist/chunk-NDKW67ER.js.map +1 -0
- package/dist/{chunk-ZQUAVZNG.js → chunk-NNJKEAP2.js} +7 -4
- package/dist/chunk-NNJKEAP2.js.map +1 -0
- package/dist/{chunk-UZYLX7M6.js → chunk-OYHYBHHI.js} +9 -6
- package/dist/chunk-OYHYBHHI.js.map +1 -0
- package/dist/{chunk-NOU77OHX.js → chunk-P6VLG7KE.js} +2 -2
- package/dist/{chunk-O4ZIBPIW.js → chunk-QNTLWH3T.js} +3 -3
- package/dist/{chunk-LUCARK4W.js → chunk-UO6MPN77.js} +37 -35
- package/dist/chunk-UO6MPN77.js.map +1 -0
- package/dist/{chunk-HJWQJUKQ.js → chunk-VOEVVIP3.js} +3 -3
- package/dist/{chunk-KQYGNGON.js → chunk-ZBZ4XULO.js} +6 -3
- package/dist/chunk-ZBZ4XULO.js.map +1 -0
- package/dist/{cli-Dt-tuiYH.d.ts → cli-Cx5Mxwk7.d.ts} +3 -3
- package/dist/cli.d.ts +14 -12
- package/dist/cli.js +20 -20
- package/dist/compounding/engine.d.ts +3 -2
- package/dist/compounding/engine.js +2 -1
- 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 +2 -2
- package/dist/contradiction/index.js +2 -1
- package/dist/{contradiction-scan-HWGEOUDS.js → contradiction-scan-2B4AE4TI.js} +3 -2
- 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 -1
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +12 -10
- package/dist/explicit-capture.js +2 -1
- 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-OOR57AYR.js → first-start-migration-2RQYDIZ7.js} +10 -8
- 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 +12 -12
- package/dist/index.js +44 -44
- 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 -1
- 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 +13 -11
- 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 -1
- 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 -1
- 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 -5
- package/dist/{orchestrator-B4KjaOtY.d.ts → orchestrator-oF0cceBX.d.ts} +143 -18
- package/dist/orchestrator.d.ts +8 -6
- package/dist/orchestrator.js +21 -19
- 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/schemas.d.ts +2 -2
- 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-SLAa_prH.d.ts → semantic-DJR8_DMQ.d.ts} +1 -1
- package/dist/{semantic-consolidation-CstTvHPo.d.ts → semantic-consolidation-DKGbufYO.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 +3 -3
- 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 -2
- 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-3LYQ3VV5.js → tier-stats-KPDIISG7.js} +8 -4
- 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/transfer/types.d.ts +30 -30
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-VkxElCHR.d.ts → types-C7UCxpuO.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 +61 -56
- package/src/active-memory-bridge.ts +2 -1
- package/src/admin/admin-surfaces.ts +2 -1
- package/src/capabilities.test.ts +375 -0
- package/src/capabilities.ts +403 -0
- package/src/cli/creation-ledger-commands.ts +2 -2
- package/src/cli/research-status-commands.ts +13 -13
- package/src/cli.ts +29 -25
- package/src/compounding/engine.ts +4 -3
- package/src/contradiction/contradiction-scan.ts +4 -3
- package/src/embedding-fallback.ts +5 -2
- package/src/entity-retrieval.ts +3 -2
- package/src/explicit-capture.ts +2 -1
- package/src/extraction.ts +6 -3
- package/src/local-llm.ts +4 -3
- package/src/maintenance/first-start-migration.ts +8 -5
- package/src/maintenance/namespace-maintenance-fanout.ts +2 -1
- package/src/maintenance/namespace-planner.ts +4 -3
- package/src/maintenance/tier-stats.ts +4 -3
- package/src/namespaces/catalog.ts +2 -1
- package/src/namespaces/migrate.ts +2 -1
- package/src/namespaces/principal.ts +6 -5
- package/src/namespaces/scope-profiles.ts +2 -1
- package/src/namespaces/search.ts +2 -1
- package/src/namespaces/storage.ts +4 -3
- package/src/operator-toolkit.ts +27 -26
- package/src/orchestration/compression-guideline-coordinator.ts +7 -6
- package/src/orchestration/lifecycle-policy-coordinator.ts +504 -0
- package/src/orchestration/maintenance.ts +8 -4
- package/src/orchestration/semantic-consolidation-coordinator.ts +454 -0
- package/src/orchestration/tier-migration-coordinator.ts +5 -4
- package/src/orchestrator.ts +106 -800
- package/src/scopes/scope-plan.ts +3 -2
- package/src/search/embed-helper.ts +5 -2
- package/src/search/factory.ts +9 -6
- package/src/summarizer.ts +3 -2
- package/dist/chunk-24D66MMN.js.map +0 -1
- package/dist/chunk-646B5ERJ.js.map +0 -1
- package/dist/chunk-6TUWSUUD.js.map +0 -1
- package/dist/chunk-CGPHMNL4.js.map +0 -1
- package/dist/chunk-CX77GNMB.js.map +0 -1
- package/dist/chunk-DKT3X5C3.js.map +0 -1
- package/dist/chunk-ESF7TRYJ.js.map +0 -1
- package/dist/chunk-FFUCCKPN.js.map +0 -1
- package/dist/chunk-GGL34GCW.js.map +0 -1
- package/dist/chunk-H3MB3F62.js.map +0 -1
- package/dist/chunk-HHNSLPX7.js.map +0 -1
- package/dist/chunk-J6BH2OBA.js.map +0 -1
- package/dist/chunk-KQYGNGON.js.map +0 -1
- package/dist/chunk-KSJCXXOU.js.map +0 -1
- package/dist/chunk-LUCARK4W.js.map +0 -1
- package/dist/chunk-NIZQH6AU.js.map +0 -1
- package/dist/chunk-OTQE66IX.js.map +0 -1
- package/dist/chunk-OUITHS6V.js.map +0 -1
- package/dist/chunk-P3VJCTVE.js.map +0 -1
- package/dist/chunk-PLBIPT6I.js.map +0 -1
- package/dist/chunk-PMAQRUN4.js.map +0 -1
- package/dist/chunk-SYX73XD7.js.map +0 -1
- package/dist/chunk-UZYLX7M6.js.map +0 -1
- package/dist/chunk-ZQUAVZNG.js.map +0 -1
- package/dist/chunk-ZVHRSR2R.js.map +0 -1
- package/dist/first-start-migration-OOR57AYR.js.map +0 -1
- package/dist/tier-stats-3LYQ3VV5.js.map +0 -1
- /package/dist/{chunk-QZHF4BWN.js.map → chunk-AAIHDIMD.js.map} +0 -0
- /package/dist/{chunk-FYWUNVFZ.js.map → chunk-E4LYJ7PY.js.map} +0 -0
- /package/dist/{chunk-NOU77OHX.js.map → chunk-P6VLG7KE.js.map} +0 -0
- /package/dist/{chunk-O4ZIBPIW.js.map → chunk-QNTLWH3T.js.map} +0 -0
- /package/dist/{chunk-HJWQJUKQ.js.map → chunk-VOEVVIP3.js.map} +0 -0
- /package/dist/{contradiction-scan-HWGEOUDS.js.map → contradiction-scan-2B4AE4TI.js.map} +0 -0
|
@@ -7,10 +7,13 @@ 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
|
+
import {
|
|
15
|
+
runPeerProfileReasoner
|
|
16
|
+
} from "./chunk-I74SUMNI.js";
|
|
14
17
|
import {
|
|
15
18
|
migrateFromEngram
|
|
16
19
|
} from "./chunk-7HYPN2GC.js";
|
|
@@ -26,7 +29,7 @@ import {
|
|
|
26
29
|
import {
|
|
27
30
|
CompoundingEngine,
|
|
28
31
|
defaultTierMigrationCycleBudget
|
|
29
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-IPI45Q4S.js";
|
|
30
33
|
import {
|
|
31
34
|
SharedContextManager
|
|
32
35
|
} from "./chunk-UFS7OXGL.js";
|
|
@@ -60,7 +63,7 @@ import {
|
|
|
60
63
|
} from "./chunk-UHGBNIOS.js";
|
|
61
64
|
import {
|
|
62
65
|
HourlySummarizer
|
|
63
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-HFXZIF3V.js";
|
|
64
67
|
import {
|
|
65
68
|
buildTargetedFactRecallSection,
|
|
66
69
|
shouldRecallTargetedFactEvidence
|
|
@@ -157,7 +160,7 @@ import {
|
|
|
157
160
|
} from "./chunk-LTHVM4XN.js";
|
|
158
161
|
import {
|
|
159
162
|
ExtractionEngine
|
|
160
|
-
} from "./chunk-
|
|
163
|
+
} from "./chunk-FF36YNKY.js";
|
|
161
164
|
import {
|
|
162
165
|
parseMemoryActionEligibilityContext
|
|
163
166
|
} from "./chunk-5GSUBCZM.js";
|
|
@@ -166,7 +169,7 @@ import {
|
|
|
166
169
|
} from "./chunk-PWFWCGOO.js";
|
|
167
170
|
import {
|
|
168
171
|
LocalLlmClient
|
|
169
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-IX4L7E5G.js";
|
|
170
173
|
import {
|
|
171
174
|
buildFocusedListRecallSection,
|
|
172
175
|
shouldRecallFocusedListEvidence
|
|
@@ -190,12 +193,12 @@ import {
|
|
|
190
193
|
} from "./chunk-Q6IP2ARR.js";
|
|
191
194
|
import {
|
|
192
195
|
EmbeddingFallback
|
|
193
|
-
} from "./chunk-
|
|
196
|
+
} from "./chunk-CHJIWG2H.js";
|
|
194
197
|
import {
|
|
195
198
|
buildEntityRecallSection,
|
|
196
199
|
entityRecentTranscriptLookbackHours,
|
|
197
200
|
readRecentEntityTranscriptEntries
|
|
198
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-AESC5OQJ.js";
|
|
199
202
|
import {
|
|
200
203
|
RoutingRulesStore
|
|
201
204
|
} from "./chunk-WIWPSQYU.js";
|
|
@@ -225,14 +228,14 @@ import {
|
|
|
225
228
|
import {
|
|
226
229
|
runNamespaceMaintenanceFanout,
|
|
227
230
|
summarizeNamespaceMaintenanceHealth
|
|
228
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-AE7NTZ75.js";
|
|
229
232
|
import {
|
|
230
233
|
NamespaceCatalog,
|
|
231
234
|
planNamespaceMaintenance
|
|
232
|
-
} from "./chunk-
|
|
235
|
+
} from "./chunk-BXPG5AVX.js";
|
|
233
236
|
import {
|
|
234
237
|
NamespaceStorageRouter
|
|
235
|
-
} from "./chunk-
|
|
238
|
+
} from "./chunk-NNJKEAP2.js";
|
|
236
239
|
import {
|
|
237
240
|
searchHarmonicRetrieval
|
|
238
241
|
} from "./chunk-AV5ZEH4M.js";
|
|
@@ -330,14 +333,14 @@ import {
|
|
|
330
333
|
resolveNamespaceFromStorageDir,
|
|
331
334
|
resolveScopePlan,
|
|
332
335
|
resolveScopeProfilePlan
|
|
333
|
-
} from "./chunk-
|
|
336
|
+
} from "./chunk-GB2FZOWB.js";
|
|
334
337
|
import {
|
|
335
338
|
NamespaceSearchRouter
|
|
336
|
-
} from "./chunk-
|
|
339
|
+
} from "./chunk-ZBZ4XULO.js";
|
|
337
340
|
import {
|
|
338
341
|
createConversationIndexRuntime,
|
|
339
342
|
createSearchBackend
|
|
340
|
-
} from "./chunk-
|
|
343
|
+
} from "./chunk-5BOQNB2K.js";
|
|
341
344
|
import {
|
|
342
345
|
NoopSearchBackend
|
|
343
346
|
} from "./chunk-CYEPCZN5.js";
|
|
@@ -360,14 +363,7 @@ import {
|
|
|
360
363
|
} from "./chunk-QDW3E4RD.js";
|
|
361
364
|
import {
|
|
362
365
|
shouldSkipImplicitExtraction
|
|
363
|
-
} from "./chunk-
|
|
364
|
-
import {
|
|
365
|
-
resolveCapabilities,
|
|
366
|
-
resolveCreationMemoryCapabilities,
|
|
367
|
-
resolveGraphConstructionCapabilities,
|
|
368
|
-
resolveIndexingCapabilities,
|
|
369
|
-
resolveMemoryLifecycleCapabilities
|
|
370
|
-
} from "./chunk-ESF7TRYJ.js";
|
|
366
|
+
} from "./chunk-NDKW67ER.js";
|
|
371
367
|
import {
|
|
372
368
|
searchCausalTrajectories
|
|
373
369
|
} from "./chunk-SQNED75R.js";
|
|
@@ -469,7 +465,23 @@ import {
|
|
|
469
465
|
defaultNamespaceForPrincipal,
|
|
470
466
|
recallNamespacesForPrincipal,
|
|
471
467
|
resolvePrincipal
|
|
472
|
-
} from "./chunk-
|
|
468
|
+
} from "./chunk-OYHYBHHI.js";
|
|
469
|
+
import {
|
|
470
|
+
resolveCapabilities,
|
|
471
|
+
resolveCompressionCapabilities,
|
|
472
|
+
resolveCreationMemoryCapabilities,
|
|
473
|
+
resolveEvalCapabilities,
|
|
474
|
+
resolveGraphConstructionCapabilities,
|
|
475
|
+
resolveIdentityContinuityCapabilities,
|
|
476
|
+
resolveIndexingCapabilities,
|
|
477
|
+
resolveLocalLlmCapabilities,
|
|
478
|
+
resolveMemoryLifecycleCapabilities,
|
|
479
|
+
resolveNamespaceCapabilities,
|
|
480
|
+
resolveObjectiveStateCapabilities,
|
|
481
|
+
resolveQmdCapabilities,
|
|
482
|
+
resolveSecurityCapabilities,
|
|
483
|
+
resolveUtilityLearningCapabilities
|
|
484
|
+
} from "./chunk-JWDE7OVJ.js";
|
|
473
485
|
import {
|
|
474
486
|
isSafeRouteNamespace,
|
|
475
487
|
selectRouteRule
|
|
@@ -494,19 +506,19 @@ import {
|
|
|
494
506
|
} from "./chunk-PVGDJXVK.js";
|
|
495
507
|
|
|
496
508
|
// src/orchestrator.ts
|
|
497
|
-
import
|
|
509
|
+
import path4 from "path";
|
|
498
510
|
import os2 from "os";
|
|
499
511
|
import { createHash, randomBytes } from "crypto";
|
|
500
512
|
import { existsSync, readFileSync } from "fs";
|
|
501
513
|
import {
|
|
502
514
|
lstat,
|
|
503
|
-
mkdir as
|
|
515
|
+
mkdir as mkdir3,
|
|
504
516
|
readdir,
|
|
505
517
|
readFile as readFile2,
|
|
506
518
|
realpath,
|
|
507
519
|
stat,
|
|
508
520
|
unlink,
|
|
509
|
-
writeFile as
|
|
521
|
+
writeFile as writeFile3
|
|
510
522
|
} from "fs/promises";
|
|
511
523
|
|
|
512
524
|
// src/procedural/procedure-recall.ts
|
|
@@ -587,7 +599,7 @@ var TierMigrationCoordinator = class {
|
|
|
587
599
|
const { config, tierMigrationStatus } = this.deps;
|
|
588
600
|
const dryRun = options?.dryRun === true;
|
|
589
601
|
const persistSkipped = options?.force === true || trigger === "manual";
|
|
590
|
-
if (!config.
|
|
602
|
+
if (!resolveQmdCapabilities(config).qmdTierMigration && options?.force !== true) {
|
|
591
603
|
const skipped = {
|
|
592
604
|
trigger,
|
|
593
605
|
scanned: 0,
|
|
@@ -601,7 +613,7 @@ var TierMigrationCoordinator = class {
|
|
|
601
613
|
if (persistSkipped) await tierMigrationStatus.recordCycle(skipped);
|
|
602
614
|
return skipped;
|
|
603
615
|
}
|
|
604
|
-
if (trigger === "maintenance" && !config.
|
|
616
|
+
if (trigger === "maintenance" && !resolveQmdCapabilities(config).qmdTierAutoBackfill && options?.force !== true) {
|
|
605
617
|
const skipped = {
|
|
606
618
|
trigger,
|
|
607
619
|
scanned: 0,
|
|
@@ -649,7 +661,7 @@ var TierMigrationCoordinator = class {
|
|
|
649
661
|
}
|
|
650
662
|
const policy = applyUtilityPromotionRuntimePolicy(
|
|
651
663
|
{
|
|
652
|
-
enabled: config.
|
|
664
|
+
enabled: resolveQmdCapabilities(config).qmdTierMigration,
|
|
653
665
|
demotionMinAgeDays: config.qmdTierDemotionMinAgeDays,
|
|
654
666
|
demotionValueThreshold: config.qmdTierDemotionValueThreshold,
|
|
655
667
|
promotionValueThreshold: config.qmdTierPromotionValueThreshold
|
|
@@ -684,7 +696,7 @@ var TierMigrationCoordinator = class {
|
|
|
684
696
|
qmd: this.deps.getQmd(),
|
|
685
697
|
hotCollection: config.qmdCollection,
|
|
686
698
|
coldCollection: config.qmdColdCollection ?? `${config.qmdCollection}-cold`,
|
|
687
|
-
autoEmbed: config.
|
|
699
|
+
autoEmbed: resolveQmdCapabilities(config).qmdAutoEmbed
|
|
688
700
|
});
|
|
689
701
|
let migrated = 0;
|
|
690
702
|
let promoted = 0;
|
|
@@ -867,8 +879,560 @@ var ExtractionQueueCoordinator = class {
|
|
|
867
879
|
* drain — used by the flush deadline test to simulate a busy queue and
|
|
868
880
|
* assert a queued task's deadline expires while it waits.
|
|
869
881
|
*/
|
|
870
|
-
setProcessingForTest(value) {
|
|
871
|
-
this.processing = value;
|
|
882
|
+
setProcessingForTest(value) {
|
|
883
|
+
this.processing = value;
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
// src/orchestration/semantic-consolidation-coordinator.ts
|
|
888
|
+
var SemanticConsolidationCoordinator = class {
|
|
889
|
+
constructor(deps) {
|
|
890
|
+
this.deps = deps;
|
|
891
|
+
}
|
|
892
|
+
deps;
|
|
893
|
+
get config() {
|
|
894
|
+
return this.deps.config;
|
|
895
|
+
}
|
|
896
|
+
async runSemanticConsolidation(options) {
|
|
897
|
+
const targetStorage = options?.storage ?? this.deps.getStorage();
|
|
898
|
+
const result = {
|
|
899
|
+
clustersFound: 0,
|
|
900
|
+
memoriesConsolidated: 0,
|
|
901
|
+
memoriesArchived: 0,
|
|
902
|
+
errors: 0,
|
|
903
|
+
clusters: []
|
|
904
|
+
};
|
|
905
|
+
if (!this.config.semanticConsolidationEnabled && !options?.force) {
|
|
906
|
+
log.debug("[semantic-consolidation] disabled in config");
|
|
907
|
+
return result;
|
|
908
|
+
}
|
|
909
|
+
log.info("[semantic-consolidation] starting run");
|
|
910
|
+
const allMemories = await targetStorage.readAllMemories();
|
|
911
|
+
if (allMemories.length < 10) {
|
|
912
|
+
log.debug("[semantic-consolidation] too few memories, skipping");
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
const threshold = options?.thresholdOverride ?? this.config.semanticConsolidationThreshold;
|
|
916
|
+
const clusters = findSimilarClusters(allMemories, {
|
|
917
|
+
threshold,
|
|
918
|
+
minClusterSize: this.config.semanticConsolidationMinClusterSize,
|
|
919
|
+
excludeCategories: this.config.semanticConsolidationExcludeCategories,
|
|
920
|
+
maxPerRun: this.config.semanticConsolidationMaxPerRun
|
|
921
|
+
});
|
|
922
|
+
result.clustersFound = clusters.length;
|
|
923
|
+
result.clusters = clusters;
|
|
924
|
+
if (clusters.length === 0) {
|
|
925
|
+
log.info("[semantic-consolidation] no clusters found");
|
|
926
|
+
return result;
|
|
927
|
+
}
|
|
928
|
+
log.info(`[semantic-consolidation] found ${clusters.length} cluster(s)`);
|
|
929
|
+
if (options?.dryRun) {
|
|
930
|
+
log.info(
|
|
931
|
+
"[semantic-consolidation] dry run \u2014 skipping LLM synthesis and archival"
|
|
932
|
+
);
|
|
933
|
+
return result;
|
|
934
|
+
}
|
|
935
|
+
const useGateway = this.config.modelSource === "gateway";
|
|
936
|
+
const modelSetting = this.config.semanticConsolidationModel;
|
|
937
|
+
if (modelSetting === "fast" && this.deps.getFastLlm() && !useGateway) {
|
|
938
|
+
log.info("[semantic-consolidation] using fast local LLM for synthesis");
|
|
939
|
+
}
|
|
940
|
+
const gatewayChainOptions = !useGateway ? {} : modelSetting === "fast" ? this.config.fastGatewayAgentId ? { agentId: this.config.fastGatewayAgentId } : this.config.gatewayAgentId ? { agentId: this.config.gatewayAgentId } : {} : gatewayTaskChainOptions(this.config);
|
|
941
|
+
const llm = new FallbackLlmClient(
|
|
942
|
+
this.config.gatewayConfig,
|
|
943
|
+
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
944
|
+
);
|
|
945
|
+
if (!llm.isAvailable(gatewayChainOptions) && !(modelSetting === "fast" && this.deps.getFastLlm() && !useGateway)) {
|
|
946
|
+
log.warn(
|
|
947
|
+
"[semantic-consolidation] no LLM available \u2014 skipping synthesis"
|
|
948
|
+
);
|
|
949
|
+
return result;
|
|
950
|
+
}
|
|
951
|
+
let extensionsBlock = "";
|
|
952
|
+
try {
|
|
953
|
+
extensionsBlock = await buildExtensionsBlockForConsolidation(this.config);
|
|
954
|
+
} catch (err) {
|
|
955
|
+
log.warn(`[semantic-consolidation] extension discovery failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
956
|
+
}
|
|
957
|
+
for (const cluster of clusters) {
|
|
958
|
+
let canonicalWriteCompleted = false;
|
|
959
|
+
try {
|
|
960
|
+
const operatorAwareEnabled = this.config.operatorAwareConsolidationEnabled === true;
|
|
961
|
+
let prompt = operatorAwareEnabled ? buildOperatorAwareConsolidationPrompt(cluster) : buildConsolidationPrompt(cluster);
|
|
962
|
+
if (extensionsBlock.length > 0) {
|
|
963
|
+
prompt += "\n\n" + extensionsBlock;
|
|
964
|
+
}
|
|
965
|
+
const messages = [
|
|
966
|
+
{
|
|
967
|
+
role: "system",
|
|
968
|
+
content: operatorAwareEnabled ? 'You are a memory consolidation system. Return ONLY a JSON object with two keys, "operator" and "output". The "operator" value MUST be one of the exact strings "merge", "update", or "split" \u2014 never a pipe-separated placeholder, never prose. The "output" value is the canonical memory text.' : "You are a memory consolidation system. Output only the consolidated memory text."
|
|
969
|
+
},
|
|
970
|
+
{ role: "user", content: prompt }
|
|
971
|
+
];
|
|
972
|
+
const llmOpts = { temperature: 0.2, maxTokens: 2e3 };
|
|
973
|
+
let response = null;
|
|
974
|
+
if (useGateway) {
|
|
975
|
+
response = await llm.chatCompletion(messages, { ...llmOpts, ...gatewayChainOptions });
|
|
976
|
+
} else if (modelSetting === "fast" && this.deps.getFastLlm()) {
|
|
977
|
+
const fastResult = await this.deps.getFastLlm().chatCompletion(messages, {
|
|
978
|
+
operation: "semantic-consolidation",
|
|
979
|
+
maxTokens: llmOpts.maxTokens,
|
|
980
|
+
temperature: llmOpts.temperature,
|
|
981
|
+
priority: "background",
|
|
982
|
+
forceDisableThinking: true
|
|
983
|
+
});
|
|
984
|
+
response = fastResult ? { content: fastResult.content } : null;
|
|
985
|
+
} else {
|
|
986
|
+
response = await llm.chatCompletion(messages, llmOpts);
|
|
987
|
+
}
|
|
988
|
+
if (!response?.content) {
|
|
989
|
+
log.warn(
|
|
990
|
+
`[semantic-consolidation] empty LLM response for cluster in "${cluster.category}"`
|
|
991
|
+
);
|
|
992
|
+
result.errors++;
|
|
993
|
+
continue;
|
|
994
|
+
}
|
|
995
|
+
let canonicalContent;
|
|
996
|
+
let operator;
|
|
997
|
+
if (operatorAwareEnabled) {
|
|
998
|
+
const parsed = parseOperatorAwareConsolidationResponse(
|
|
999
|
+
response.content,
|
|
1000
|
+
cluster
|
|
1001
|
+
);
|
|
1002
|
+
canonicalContent = parsed.output;
|
|
1003
|
+
operator = parsed.operator;
|
|
1004
|
+
} else {
|
|
1005
|
+
canonicalContent = parseConsolidationResponse(response.content);
|
|
1006
|
+
operator = chooseConsolidationOperator(cluster);
|
|
1007
|
+
}
|
|
1008
|
+
cluster.canonicalContent = canonicalContent;
|
|
1009
|
+
const sorted = [...cluster.memories].sort(
|
|
1010
|
+
(a, b) => new Date(b.frontmatter.created).getTime() - new Date(a.frontmatter.created).getTime()
|
|
1011
|
+
);
|
|
1012
|
+
const newest = sorted[0];
|
|
1013
|
+
const lineageIds = cluster.memories.map((m) => m.frontmatter.id);
|
|
1014
|
+
const derivedFromEntries = [];
|
|
1015
|
+
for (const m of cluster.memories) {
|
|
1016
|
+
if (!m.path) continue;
|
|
1017
|
+
const entry = await targetStorage.snapshotForProvenance(m.path);
|
|
1018
|
+
if (entry) derivedFromEntries.push(entry);
|
|
1019
|
+
}
|
|
1020
|
+
const { id: canonicalId, tombstoneBlocked: canonicalBlocked } = await targetStorage.writeMemory(
|
|
1021
|
+
newest.frontmatter.category,
|
|
1022
|
+
canonicalContent,
|
|
1023
|
+
{
|
|
1024
|
+
actor: "semantic-consolidation",
|
|
1025
|
+
confidence: newest.frontmatter.confidence,
|
|
1026
|
+
tags: [
|
|
1027
|
+
...new Set(
|
|
1028
|
+
cluster.memories.flatMap((m) => m.frontmatter.tags ?? [])
|
|
1029
|
+
)
|
|
1030
|
+
],
|
|
1031
|
+
source: "semantic-consolidation",
|
|
1032
|
+
lineage: lineageIds,
|
|
1033
|
+
derivedFrom: derivedFromEntries.length > 0 ? derivedFromEntries : void 0,
|
|
1034
|
+
derivedVia: operator
|
|
1035
|
+
}
|
|
1036
|
+
);
|
|
1037
|
+
if (canonicalBlocked) {
|
|
1038
|
+
log.info(`[semantic-consolidation] cluster in "${cluster.category}" tombstone-blocked \u2014 keeping ${cluster.memories.length} source(s) active (pending_review ${canonicalId})`);
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
1041
|
+
canonicalWriteCompleted = true;
|
|
1042
|
+
result.memoriesConsolidated++;
|
|
1043
|
+
for (const m of cluster.memories) {
|
|
1044
|
+
const archiveResult = await targetStorage.archiveMemory(m, {
|
|
1045
|
+
actor: "semantic-consolidation",
|
|
1046
|
+
reasonCode: "semantic-consolidation",
|
|
1047
|
+
relatedMemoryIds: [canonicalId]
|
|
1048
|
+
});
|
|
1049
|
+
if (archiveResult) {
|
|
1050
|
+
await this.deps.removeContentHashForMemory(
|
|
1051
|
+
targetStorage,
|
|
1052
|
+
m,
|
|
1053
|
+
"semantic-consolidation"
|
|
1054
|
+
);
|
|
1055
|
+
try {
|
|
1056
|
+
await this.deps.embeddingFallback.removeFromIndex(m.frontmatter.id);
|
|
1057
|
+
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && m.path && m.frontmatter?.created) {
|
|
1058
|
+
deindexMemory(
|
|
1059
|
+
targetStorage.dir,
|
|
1060
|
+
m.path,
|
|
1061
|
+
m.frontmatter.created,
|
|
1062
|
+
m.frontmatter.tags ?? []
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
} catch (cleanupErr) {
|
|
1066
|
+
log.warn(
|
|
1067
|
+
`[semantic-consolidation] index cleanup failed (non-fatal): ${cleanupErr}`
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
result.memoriesArchived++;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
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
|
+
);
|
|
872
1436
|
}
|
|
873
1437
|
};
|
|
874
1438
|
|
|
@@ -1204,8 +1768,8 @@ function generateResolverDocument(taxonomy) {
|
|
|
1204
1768
|
}
|
|
1205
1769
|
|
|
1206
1770
|
// src/taxonomy/taxonomy-loader.ts
|
|
1207
|
-
import { readFile, mkdir, writeFile } from "fs/promises";
|
|
1208
|
-
import
|
|
1771
|
+
import { readFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
1772
|
+
import path3 from "path";
|
|
1209
1773
|
var TAXONOMY_DIR = ".taxonomy";
|
|
1210
1774
|
var TAXONOMY_FILE = "taxonomy.json";
|
|
1211
1775
|
var MAX_SLUG_LENGTH = 32;
|
|
@@ -1303,7 +1867,7 @@ function validateTaxonomy(taxonomy) {
|
|
|
1303
1867
|
}
|
|
1304
1868
|
}
|
|
1305
1869
|
async function loadTaxonomy(memoryDir) {
|
|
1306
|
-
const taxonomyPath =
|
|
1870
|
+
const taxonomyPath = path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
1307
1871
|
let raw;
|
|
1308
1872
|
try {
|
|
1309
1873
|
raw = await readFile(taxonomyPath, "utf-8");
|
|
@@ -1353,16 +1917,16 @@ async function loadTaxonomy(memoryDir) {
|
|
|
1353
1917
|
}
|
|
1354
1918
|
async function saveTaxonomy(memoryDir, taxonomy) {
|
|
1355
1919
|
validateTaxonomy(taxonomy);
|
|
1356
|
-
const dir =
|
|
1357
|
-
await
|
|
1358
|
-
const filePath =
|
|
1359
|
-
await
|
|
1920
|
+
const dir = path3.join(memoryDir, TAXONOMY_DIR);
|
|
1921
|
+
await mkdir2(dir, { recursive: true });
|
|
1922
|
+
const filePath = path3.join(dir, TAXONOMY_FILE);
|
|
1923
|
+
await writeFile2(filePath, JSON.stringify(taxonomy, null, 2) + "\n", "utf-8");
|
|
1360
1924
|
}
|
|
1361
1925
|
function getTaxonomyDir(memoryDir) {
|
|
1362
|
-
return
|
|
1926
|
+
return path3.join(memoryDir, TAXONOMY_DIR);
|
|
1363
1927
|
}
|
|
1364
1928
|
function getTaxonomyFilePath(memoryDir) {
|
|
1365
|
-
return
|
|
1929
|
+
return path3.join(memoryDir, TAXONOMY_DIR, TAXONOMY_FILE);
|
|
1366
1930
|
}
|
|
1367
1931
|
|
|
1368
1932
|
// src/wearables/registry.ts
|
|
@@ -2328,7 +2892,7 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
|
|
|
2328
2892
|
}
|
|
2329
2893
|
}
|
|
2330
2894
|
function qmdCollectionPathParts(resultPath) {
|
|
2331
|
-
if (!resultPath ||
|
|
2895
|
+
if (!resultPath || path4.isAbsolute(resultPath)) return null;
|
|
2332
2896
|
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2333
2897
|
const slashIndex = normalized.indexOf("/");
|
|
2334
2898
|
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
@@ -2341,9 +2905,9 @@ function qmdCollectionPathParts(resultPath) {
|
|
|
2341
2905
|
}
|
|
2342
2906
|
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
2343
2907
|
const candidates = /* @__PURE__ */ new Set();
|
|
2344
|
-
const storageRoot =
|
|
2908
|
+
const storageRoot = path4.resolve(storageDir);
|
|
2345
2909
|
const addCandidate = (candidate) => {
|
|
2346
|
-
const resolved =
|
|
2910
|
+
const resolved = path4.resolve(candidate);
|
|
2347
2911
|
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
2348
2912
|
candidates.add(resolved);
|
|
2349
2913
|
}
|
|
@@ -2351,12 +2915,12 @@ function qmdResultPathCandidates(storageDir, resultPath) {
|
|
|
2351
2915
|
const addRelativeCandidates = (relativePath) => {
|
|
2352
2916
|
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2353
2917
|
if (!normalized) return;
|
|
2354
|
-
addCandidate(
|
|
2918
|
+
addCandidate(path4.join(storageRoot, normalized));
|
|
2355
2919
|
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
2356
|
-
addCandidate(
|
|
2920
|
+
addCandidate(path4.join(storageRoot, "facts", normalized));
|
|
2357
2921
|
}
|
|
2358
2922
|
};
|
|
2359
|
-
if (
|
|
2923
|
+
if (path4.isAbsolute(resultPath)) {
|
|
2360
2924
|
addCandidate(resultPath);
|
|
2361
2925
|
} else {
|
|
2362
2926
|
addRelativeCandidates(resultPath);
|
|
@@ -2473,7 +3037,7 @@ async function qmdStartupCollectionCheckWithTimeout(promise, controller, label)
|
|
|
2473
3037
|
return await Promise.race([checkedPromise, timeoutPromise]);
|
|
2474
3038
|
}
|
|
2475
3039
|
function defaultWorkspaceDir() {
|
|
2476
|
-
return
|
|
3040
|
+
return path4.join(os2.homedir(), ".openclaw", "workspace");
|
|
2477
3041
|
}
|
|
2478
3042
|
function sanitizeSessionKeyForFilename(sessionKey) {
|
|
2479
3043
|
const readable = sessionKey.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
@@ -2766,11 +3330,11 @@ function mergeGraphExpandedResults(primary, expanded) {
|
|
|
2766
3330
|
return Array.from(mergedByPath.values());
|
|
2767
3331
|
}
|
|
2768
3332
|
function graphPathRelativeToStorage(storageDir, candidatePath) {
|
|
2769
|
-
const absolutePath =
|
|
2770
|
-
const rel =
|
|
3333
|
+
const absolutePath = path4.isAbsolute(candidatePath) ? candidatePath : path4.resolve(storageDir, candidatePath);
|
|
3334
|
+
const rel = path4.relative(storageDir, absolutePath);
|
|
2771
3335
|
if (!rel || rel === ".") return null;
|
|
2772
3336
|
if (rel.startsWith("..")) return null;
|
|
2773
|
-
return rel.split(
|
|
3337
|
+
return rel.split(path4.sep).join("/");
|
|
2774
3338
|
}
|
|
2775
3339
|
function normalizeGraphActivationScore(score) {
|
|
2776
3340
|
const bounded = Number.isFinite(score) && score > 0 ? score : 0;
|
|
@@ -2915,7 +3479,7 @@ function buildMemoryPathById(allMemsForGraph, storageDir) {
|
|
|
2915
3479
|
for (const mem of allMemsForGraph ?? []) {
|
|
2916
3480
|
const id = mem.frontmatter.id;
|
|
2917
3481
|
if (!id) continue;
|
|
2918
|
-
pathById.set(id,
|
|
3482
|
+
pathById.set(id, path4.relative(storageDir, mem.path));
|
|
2919
3483
|
}
|
|
2920
3484
|
return pathById;
|
|
2921
3485
|
}
|
|
@@ -2923,7 +3487,7 @@ function appendMemoryToGraphContext(options) {
|
|
|
2923
3487
|
if (!Array.isArray(options.allMemsForGraph)) return;
|
|
2924
3488
|
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
2925
3489
|
options.allMemsForGraph.push({
|
|
2926
|
-
path:
|
|
3490
|
+
path: path4.join(options.storageDir, options.memoryRelPath),
|
|
2927
3491
|
content: options.content,
|
|
2928
3492
|
frontmatter: {
|
|
2929
3493
|
id: options.memoryId,
|
|
@@ -2943,16 +3507,16 @@ function resolvePersistedMemoryRelativePath(options) {
|
|
|
2943
3507
|
const persisted = options.pathById.get(options.memoryId);
|
|
2944
3508
|
if (persisted) return persisted;
|
|
2945
3509
|
if (options.category === "correction") {
|
|
2946
|
-
return
|
|
3510
|
+
return path4.join("corrections", `${options.memoryId}.md`);
|
|
2947
3511
|
}
|
|
2948
3512
|
const subtree = categoryDirName(options.category);
|
|
2949
3513
|
const idParts = options.memoryId.split("-");
|
|
2950
3514
|
const maybeTimestamp = Number(idParts[1]);
|
|
2951
3515
|
if (Number.isFinite(maybeTimestamp) && maybeTimestamp > 0) {
|
|
2952
3516
|
const day = new Date(maybeTimestamp).toISOString().slice(0, 10);
|
|
2953
|
-
return
|
|
3517
|
+
return path4.join(subtree, day, `${options.memoryId}.md`);
|
|
2954
3518
|
}
|
|
2955
|
-
return
|
|
3519
|
+
return path4.join(subtree, `${options.memoryId}.md`);
|
|
2956
3520
|
}
|
|
2957
3521
|
var Orchestrator = class _Orchestrator {
|
|
2958
3522
|
storage;
|
|
@@ -3031,6 +3595,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
3031
3595
|
tierMigrationStatus;
|
|
3032
3596
|
tierMigrationCoordinator;
|
|
3033
3597
|
compressionGuidelineCoordinator;
|
|
3598
|
+
semanticConsolidationCoordinator;
|
|
3599
|
+
lifecyclePolicyCoordinator;
|
|
3034
3600
|
/**
|
|
3035
3601
|
* In-memory X-ray snapshot from the most recent `recall()` call that
|
|
3036
3602
|
* was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
|
|
@@ -3324,7 +3890,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3324
3890
|
* @internal
|
|
3325
3891
|
*/
|
|
3326
3892
|
applyCodingNamespaceOverlay(sessionKey, baseNamespace) {
|
|
3327
|
-
if (!this.config.
|
|
3893
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return baseNamespace;
|
|
3328
3894
|
const codingContext = this.getCodingContextForSession(sessionKey);
|
|
3329
3895
|
const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);
|
|
3330
3896
|
if (!overlay) return baseNamespace;
|
|
@@ -3392,7 +3958,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3392
3958
|
* @internal
|
|
3393
3959
|
*/
|
|
3394
3960
|
applyCodingRecallOverlay(sessionKey) {
|
|
3395
|
-
if (!this.config.
|
|
3961
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return null;
|
|
3396
3962
|
const codingContext = this.getCodingContextForSession(sessionKey);
|
|
3397
3963
|
const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);
|
|
3398
3964
|
if (!overlay) return null;
|
|
@@ -3406,13 +3972,13 @@ var Orchestrator = class _Orchestrator {
|
|
|
3406
3972
|
return getConfiguredNamespaces(this.config);
|
|
3407
3973
|
}
|
|
3408
3974
|
rememberNamespaceStorageDirHint(namespace, storageDir) {
|
|
3409
|
-
if (!this.config.
|
|
3975
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces || !storageDir) return;
|
|
3410
3976
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
3411
3977
|
if (!ns) return;
|
|
3412
3978
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
3413
3979
|
if (ns !== defaultNs && !isSafeRouteNamespace(ns)) return;
|
|
3414
3980
|
if (!this.storageDirMatchesNamespaceHint(ns, storageDir)) return;
|
|
3415
|
-
const resolvedStorageDir =
|
|
3981
|
+
const resolvedStorageDir = path4.resolve(storageDir);
|
|
3416
3982
|
let hints = this.namespaceStorageDirHints.get(resolvedStorageDir);
|
|
3417
3983
|
if (!hints) {
|
|
3418
3984
|
hints = /* @__PURE__ */ new Set();
|
|
@@ -3423,21 +3989,21 @@ var Orchestrator = class _Orchestrator {
|
|
|
3423
3989
|
storageDirMatchesNamespaceHint(namespace, storageDir) {
|
|
3424
3990
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
3425
3991
|
if (!ns) return false;
|
|
3426
|
-
const resolvedStorageDir =
|
|
3427
|
-
const resolvedMemoryDir =
|
|
3992
|
+
const resolvedStorageDir = path4.resolve(storageDir);
|
|
3993
|
+
const resolvedMemoryDir = path4.resolve(this.config.memoryDir);
|
|
3428
3994
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
3429
3995
|
if (resolvedStorageDir === resolvedMemoryDir) return ns === defaultNs;
|
|
3430
|
-
const resolvedNamespacesDir =
|
|
3996
|
+
const resolvedNamespacesDir = path4.join(resolvedMemoryDir, "namespaces");
|
|
3431
3997
|
if (!isPathInsideStorageRoot(resolvedNamespacesDir, resolvedStorageDir)) return false;
|
|
3432
|
-
const rawRoot =
|
|
3433
|
-
const tokenRoot =
|
|
3998
|
+
const rawRoot = path4.resolve(resolvedNamespacesDir, ns);
|
|
3999
|
+
const tokenRoot = path4.resolve(resolvedNamespacesDir, namespaceIdentityToken(ns));
|
|
3434
4000
|
return resolvedStorageDir === rawRoot || resolvedStorageDir === tokenRoot;
|
|
3435
4001
|
}
|
|
3436
4002
|
namespaceStorageDirHintOwnershipRank(record, resolvedStorageDir, configured) {
|
|
3437
|
-
if (resolvedStorageDir ===
|
|
4003
|
+
if (resolvedStorageDir === path4.resolve(this.config.memoryDir)) {
|
|
3438
4004
|
return record.namespace === normalizeNamespaceIdentity(this.config.defaultNamespace) ? 0 : 3;
|
|
3439
4005
|
}
|
|
3440
|
-
const leaf =
|
|
4006
|
+
const leaf = path4.basename(resolvedStorageDir);
|
|
3441
4007
|
const tokenOwnsRoot = namespaceIdentityToken(record.namespace) === leaf;
|
|
3442
4008
|
if (tokenOwnsRoot && configured.has(record.namespace)) return 0;
|
|
3443
4009
|
if (record.namespace === leaf) return 1;
|
|
@@ -3465,7 +4031,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3465
4031
|
loadNamespaceStorageDirHintsFromCatalog() {
|
|
3466
4032
|
if (this.namespaceStorageDirHintsLoaded || !this.namespaceCatalog.enabled) return;
|
|
3467
4033
|
this.namespaceStorageDirHintsLoaded = true;
|
|
3468
|
-
const catalogPath =
|
|
4034
|
+
const catalogPath = path4.join(this.config.memoryDir, "state", "namespaces.jsonl");
|
|
3469
4035
|
if (!existsSync(catalogPath)) return;
|
|
3470
4036
|
let body;
|
|
3471
4037
|
try {
|
|
@@ -3502,7 +4068,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3502
4068
|
if (!this.storageDirMatchesNamespaceHint(record.namespace, record.storageDir)) {
|
|
3503
4069
|
continue;
|
|
3504
4070
|
}
|
|
3505
|
-
const resolvedStorageDir =
|
|
4071
|
+
const resolvedStorageDir = path4.resolve(record.storageDir);
|
|
3506
4072
|
const current = preferredByStorageDir.get(resolvedStorageDir);
|
|
3507
4073
|
preferredByStorageDir.set(
|
|
3508
4074
|
resolvedStorageDir,
|
|
@@ -3557,8 +4123,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
3557
4123
|
return summarizeNamespaceMaintenanceHealth(this.config);
|
|
3558
4124
|
}
|
|
3559
4125
|
buildConfiguredQmdSearchOptions(queryText) {
|
|
3560
|
-
const intentHint = this.config.
|
|
3561
|
-
const explain = this.config.
|
|
4126
|
+
const intentHint = resolveQmdCapabilities(this.config).qmdIntentHints ? buildQmdIntentHint(inferIntentFromText(queryText)) : void 0;
|
|
4127
|
+
const explain = resolveQmdCapabilities(this.config).qmdExplain === true;
|
|
3562
4128
|
const searchOptions = {};
|
|
3563
4129
|
if (intentHint) {
|
|
3564
4130
|
searchOptions.intent = intentHint;
|
|
@@ -3569,15 +4135,15 @@ var Orchestrator = class _Orchestrator {
|
|
|
3569
4135
|
return Object.keys(searchOptions).length > 0 ? searchOptions : void 0;
|
|
3570
4136
|
}
|
|
3571
4137
|
async searchAcrossNamespaces(options) {
|
|
3572
|
-
if (this.config.
|
|
4138
|
+
if (resolveNamespaceCapabilities(this.config).namespaces && options.namespaces !== void 0 && options.namespaces.length === 0) {
|
|
3573
4139
|
return [];
|
|
3574
4140
|
}
|
|
3575
|
-
const namespaces = this.config.
|
|
4141
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces ? Array.from(
|
|
3576
4142
|
new Set(
|
|
3577
4143
|
(options.namespaces?.length ? options.namespaces : this.configuredNamespaceList()).map((value) => value.trim()).filter(Boolean)
|
|
3578
4144
|
)
|
|
3579
4145
|
) : [this.config.defaultNamespace];
|
|
3580
|
-
if (!this.config.
|
|
4146
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
3581
4147
|
switch (options.mode) {
|
|
3582
4148
|
case "hybrid":
|
|
3583
4149
|
return await this.qmd.hybridSearch(
|
|
@@ -3623,7 +4189,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3623
4189
|
return await this.namespaceSearchRouter.healthForNamespace(namespace, execution);
|
|
3624
4190
|
}
|
|
3625
4191
|
isSearchAvailableForNamespaceRouting() {
|
|
3626
|
-
if (this.config.
|
|
4192
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) return true;
|
|
3627
4193
|
return this.qmd.isAvailable();
|
|
3628
4194
|
}
|
|
3629
4195
|
invalidateLiveContentHashIndex() {
|
|
@@ -3766,7 +4332,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3766
4332
|
this.config = config;
|
|
3767
4333
|
this.profiler = new ProfilingCollector({
|
|
3768
4334
|
enabled: config.profilingEnabled,
|
|
3769
|
-
storageDir: config.profilingStorageDir ||
|
|
4335
|
+
storageDir: config.profilingStorageDir || path4.join(config.memoryDir, "profiling"),
|
|
3770
4336
|
maxTraces: config.profilingMaxTraces
|
|
3771
4337
|
});
|
|
3772
4338
|
this.namespaceCatalog = new NamespaceCatalog(config);
|
|
@@ -3835,7 +4401,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3835
4401
|
this.compounding = config.compoundingEnabled ? new CompoundingEngine(config, this.storage) : void 0;
|
|
3836
4402
|
this.buffer = new SmartBuffer(config, this.storage);
|
|
3837
4403
|
this.transcript = new TranscriptManager(config);
|
|
3838
|
-
this.conversationIndexDir =
|
|
4404
|
+
this.conversationIndexDir = path4.join(
|
|
3839
4405
|
config.memoryDir,
|
|
3840
4406
|
"conversation-index",
|
|
3841
4407
|
"chunks"
|
|
@@ -3891,6 +4457,14 @@ var Orchestrator = class _Orchestrator {
|
|
|
3891
4457
|
client.disableThinking = true;
|
|
3892
4458
|
return client;
|
|
3893
4459
|
})() : this.localLlm;
|
|
4460
|
+
this.semanticConsolidationCoordinator = new SemanticConsolidationCoordinator({
|
|
4461
|
+
config,
|
|
4462
|
+
getStorage: () => this.storage,
|
|
4463
|
+
getFastLlm: () => this.fastLlm,
|
|
4464
|
+
embeddingFallback: this.embeddingFallback,
|
|
4465
|
+
removeContentHashForMemory: (targetStorage, memory, context) => this.removeContentHashForMemory(targetStorage, memory, context),
|
|
4466
|
+
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
4467
|
+
});
|
|
3894
4468
|
this._fastGatewayLlm = config.modelSource === "gateway" ? new FallbackLlmClient(
|
|
3895
4469
|
config.gatewayConfig,
|
|
3896
4470
|
fallbackLlmRuntimeContextFromConfig(config)
|
|
@@ -3907,8 +4481,17 @@ var Orchestrator = class _Orchestrator {
|
|
|
3907
4481
|
config.gatewayConfig,
|
|
3908
4482
|
this.modelRegistry
|
|
3909
4483
|
);
|
|
4484
|
+
this.lifecyclePolicyCoordinator = new LifecyclePolicyCoordinator({
|
|
4485
|
+
config,
|
|
4486
|
+
getStorage: () => this.storage,
|
|
4487
|
+
extraction: this.extraction,
|
|
4488
|
+
embeddingFallback: this.embeddingFallback,
|
|
4489
|
+
getEffectiveLifecycleThresholds: () => this.effectiveLifecycleThresholds(),
|
|
4490
|
+
removeContentHashForMemory: (targetStorage, memory, context) => this.removeContentHashForMemory(targetStorage, memory, context),
|
|
4491
|
+
saveContentHashIndexes: () => this.saveContentHashIndexes()
|
|
4492
|
+
});
|
|
3910
4493
|
this.threading = new ThreadingManager(
|
|
3911
|
-
|
|
4494
|
+
path4.join(config.memoryDir, "threads"),
|
|
3912
4495
|
config.threadingGapMinutes
|
|
3913
4496
|
);
|
|
3914
4497
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(config);
|
|
@@ -4003,7 +4586,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4003
4586
|
};
|
|
4004
4587
|
}
|
|
4005
4588
|
routeEngineOptions() {
|
|
4006
|
-
const allowedNamespaces = this.config.
|
|
4589
|
+
const allowedNamespaces = resolveNamespaceCapabilities(this.config).namespaces ? Array.from(
|
|
4007
4590
|
/* @__PURE__ */ new Set([
|
|
4008
4591
|
this.config.defaultNamespace,
|
|
4009
4592
|
this.config.sharedNamespace,
|
|
@@ -4143,7 +4726,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4143
4726
|
get briefingChainFollowupGenerator() {
|
|
4144
4727
|
const chainAvailable = this.config.modelSource === "gateway" ? this._fastGatewayLlm?.isAvailable(
|
|
4145
4728
|
this.config.fastGatewayAgentId || this.config.gatewayAgentId || void 0
|
|
4146
|
-
) === true : this.config.
|
|
4729
|
+
) === true : resolveLocalLlmCapabilities(this.config).localLlm;
|
|
4147
4730
|
if (!chainAvailable) return void 0;
|
|
4148
4731
|
return buildChainFollowupGenerator(this.fastLlmForRerank);
|
|
4149
4732
|
}
|
|
@@ -4158,7 +4741,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4158
4741
|
});
|
|
4159
4742
|
await this.storage.ensureDirectories();
|
|
4160
4743
|
await this.storage.loadAliases();
|
|
4161
|
-
if (this.config.
|
|
4744
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4162
4745
|
const namespaces = /* @__PURE__ */ new Set([
|
|
4163
4746
|
this.config.defaultNamespace,
|
|
4164
4747
|
this.config.sharedNamespace,
|
|
@@ -4199,8 +4782,8 @@ var Orchestrator = class _Orchestrator {
|
|
|
4199
4782
|
this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();
|
|
4200
4783
|
this.utilityRuntimeValues = await loadUtilityRuntimeValues({
|
|
4201
4784
|
memoryDir: this.config.memoryDir,
|
|
4202
|
-
memoryUtilityLearningEnabled: this.config.
|
|
4203
|
-
promotionByOutcomeEnabled: this.config.
|
|
4785
|
+
memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(this.config).memoryUtilityLearning,
|
|
4786
|
+
promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(this.config).promotionByOutcome
|
|
4204
4787
|
});
|
|
4205
4788
|
if (this.config.factDeduplicationEnabled) {
|
|
4206
4789
|
this.contentHashIndex = this.storage.createContentHashIndex();
|
|
@@ -4231,7 +4814,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4231
4814
|
const files = await readdir(wsDir).catch(() => []);
|
|
4232
4815
|
for (const f of files) {
|
|
4233
4816
|
if (!f.startsWith(".compaction-reset-signal-")) continue;
|
|
4234
|
-
const fp =
|
|
4817
|
+
const fp = path4.join(wsDir, f);
|
|
4235
4818
|
const s = await stat(fp).catch(() => null);
|
|
4236
4819
|
if (s && Date.now() - s.mtimeMs >= COMPACTION_SIGNAL_MAX_AGE_MS) {
|
|
4237
4820
|
await unlink(fp).catch(() => {
|
|
@@ -4247,12 +4830,12 @@ var Orchestrator = class _Orchestrator {
|
|
|
4247
4830
|
const available = await this.qmd.probe();
|
|
4248
4831
|
if (available) {
|
|
4249
4832
|
log.info(`Search backend: available ${this.qmd.debugStatus()}`);
|
|
4250
|
-
const namespaces = this.config.
|
|
4833
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces ? await this.maintenanceNamespaces() : [this.config.defaultNamespace];
|
|
4251
4834
|
const states = await Promise.all(
|
|
4252
4835
|
namespaces.map(async (namespace) => {
|
|
4253
4836
|
const collectionCheckAbort = new AbortController();
|
|
4254
4837
|
const state = await qmdStartupCollectionCheckWithTimeout(
|
|
4255
|
-
this.config.
|
|
4838
|
+
resolveNamespaceCapabilities(this.config).namespaces ? this.namespaceSearchRouter.ensureNamespaceCollection(
|
|
4256
4839
|
namespace,
|
|
4257
4840
|
{ signal: collectionCheckAbort.signal }
|
|
4258
4841
|
) : this.qmd.ensureCollection(
|
|
@@ -4327,10 +4910,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
4327
4910
|
}
|
|
4328
4911
|
async deferredInitialize(signal) {
|
|
4329
4912
|
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
4330
|
-
if (this.qmd.isAvailable() && this.config.
|
|
4913
|
+
if (this.qmd.isAvailable() && resolveQmdCapabilities(this.config).qmdMaintenance) {
|
|
4331
4914
|
try {
|
|
4332
4915
|
log.info("QMD startup sync: updating index to match current disk state");
|
|
4333
|
-
if (this.config.
|
|
4916
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4334
4917
|
await this.namespaceSearchRouter.updateNamespaces(
|
|
4335
4918
|
await this.maintenanceNamespaces(),
|
|
4336
4919
|
{ signal }
|
|
@@ -4414,7 +4997,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4414
4997
|
}
|
|
4415
4998
|
}
|
|
4416
4999
|
if (signal.aborted) return;
|
|
4417
|
-
if (this.config.
|
|
5000
|
+
if (resolveLocalLlmCapabilities(this.config).localLlm) {
|
|
4418
5001
|
try {
|
|
4419
5002
|
await this.validateLocalLlmModel();
|
|
4420
5003
|
} catch (err) {
|
|
@@ -4424,9 +5007,9 @@ var Orchestrator = class _Orchestrator {
|
|
|
4424
5007
|
if (signal.aborted) return;
|
|
4425
5008
|
await this.maintenanceScheduler.autoRegisterCrons(signal);
|
|
4426
5009
|
if (signal.aborted) return;
|
|
4427
|
-
if (lifecycleCaps.lifecyclePolicy && this.config.
|
|
5010
|
+
if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.config).qmdTierMigration) {
|
|
4428
5011
|
try {
|
|
4429
|
-
const { runFirstStartMigration } = await import("./first-start-migration-
|
|
5012
|
+
const { runFirstStartMigration } = await import("./first-start-migration-2RQYDIZ7.js");
|
|
4430
5013
|
const result = await runFirstStartMigration({
|
|
4431
5014
|
storage: this.storage,
|
|
4432
5015
|
config: this.config,
|
|
@@ -4500,14 +5083,14 @@ var Orchestrator = class _Orchestrator {
|
|
|
4500
5083
|
return false;
|
|
4501
5084
|
}
|
|
4502
5085
|
log.info(`startupSearchSync: backend now available ${this.qmd.debugStatus()}`);
|
|
4503
|
-
if (this.config.
|
|
5086
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4504
5087
|
this.namespaceSearchRouter.clearCache();
|
|
4505
5088
|
}
|
|
4506
|
-
const namespaces = this.config.
|
|
5089
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces ? await this.maintenanceNamespaces() : [this.config.defaultNamespace];
|
|
4507
5090
|
const states = await Promise.all(
|
|
4508
5091
|
namespaces.map(async (namespace) => ({
|
|
4509
5092
|
namespace,
|
|
4510
|
-
state: this.config.
|
|
5093
|
+
state: resolveNamespaceCapabilities(this.config).namespaces ? await this.namespaceSearchRouter.ensureNamespaceCollection(namespace, { signal }) : await this.qmd.ensureCollection(this.config.memoryDir, this.config.qmdCollection, { signal })
|
|
4511
5094
|
}))
|
|
4512
5095
|
);
|
|
4513
5096
|
if (signal?.aborted) {
|
|
@@ -4524,7 +5107,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4524
5107
|
log.warn("startupSearchSync: search collection missing; disabling search (fallback retrieval remains enabled)");
|
|
4525
5108
|
return false;
|
|
4526
5109
|
}
|
|
4527
|
-
if (this.config.
|
|
5110
|
+
if (resolveQmdCapabilities(this.config).qmdMaintenance) {
|
|
4528
5111
|
try {
|
|
4529
5112
|
const failTsBefore = "lastUpdateFailedAtMs" in this.qmd ? this.qmd.lastUpdateFailedAtMs : null;
|
|
4530
5113
|
const hasRunTs = "lastUpdateRanAtMs" in this.qmd;
|
|
@@ -4533,7 +5116,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4533
5116
|
}
|
|
4534
5117
|
log.info("startupSearchSync: updating index to match current disk state");
|
|
4535
5118
|
let namespacesUpdated = 0;
|
|
4536
|
-
if (this.config.
|
|
5119
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4537
5120
|
namespacesUpdated = await this.namespaceSearchRouter.updateNamespaces(
|
|
4538
5121
|
namespaces,
|
|
4539
5122
|
{ signal }
|
|
@@ -4551,7 +5134,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
4551
5134
|
log.warn("startupSearchSync: update silently failed (detected via fail timestamp)");
|
|
4552
5135
|
return false;
|
|
4553
5136
|
}
|
|
4554
|
-
if (this.config.
|
|
5137
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4555
5138
|
if (namespacesUpdated === 0) {
|
|
4556
5139
|
log.warn("startupSearchSync: no namespace backends were eligible for update (all unavailable or collections missing)");
|
|
4557
5140
|
return false;
|
|
@@ -4740,15 +5323,15 @@ ${doc.content}` : doc.content,
|
|
|
4740
5323
|
this.lastFileHygieneRunAtMs = now;
|
|
4741
5324
|
if (hygiene.rotateEnabled) {
|
|
4742
5325
|
for (const rel of hygiene.rotatePaths) {
|
|
4743
|
-
const abs =
|
|
5326
|
+
const abs = path4.isAbsolute(rel) ? rel : path4.join(this.config.workspaceDir, rel);
|
|
4744
5327
|
try {
|
|
4745
5328
|
const raw = await readFile2(abs, "utf-8");
|
|
4746
5329
|
if (raw.length > hygiene.rotateMaxBytes) {
|
|
4747
|
-
const archiveDir =
|
|
5330
|
+
const archiveDir = path4.join(
|
|
4748
5331
|
this.config.workspaceDir,
|
|
4749
5332
|
hygiene.archiveDir
|
|
4750
5333
|
);
|
|
4751
|
-
const base =
|
|
5334
|
+
const base = path4.basename(abs);
|
|
4752
5335
|
const prefix = base.toUpperCase().replace(/\.MD$/i, "").replace(/[^A-Z0-9]+/g, "-") || "FILE";
|
|
4753
5336
|
const { newContent } = await rotateMarkdownFileToArchive({
|
|
4754
5337
|
filePath: abs,
|
|
@@ -4756,7 +5339,7 @@ ${doc.content}` : doc.content,
|
|
|
4756
5339
|
archivePrefix: prefix,
|
|
4757
5340
|
keepTailChars: hygiene.rotateKeepTailChars
|
|
4758
5341
|
});
|
|
4759
|
-
await
|
|
5342
|
+
await writeFile3(abs, newContent, "utf-8");
|
|
4760
5343
|
}
|
|
4761
5344
|
} catch {
|
|
4762
5345
|
}
|
|
@@ -4773,8 +5356,8 @@ ${doc.content}` : doc.content,
|
|
|
4773
5356
|
log.warn(w.message);
|
|
4774
5357
|
}
|
|
4775
5358
|
if (hygiene.warningsLogEnabled && warnings.length > 0) {
|
|
4776
|
-
const fp =
|
|
4777
|
-
await
|
|
5359
|
+
const fp = path4.join(this.config.memoryDir, hygiene.warningsLogPath);
|
|
5360
|
+
await mkdir3(path4.dirname(fp), { recursive: true });
|
|
4778
5361
|
const stamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
4779
5362
|
const block = `
|
|
4780
5363
|
|
|
@@ -4787,7 +5370,7 @@ ${doc.content}` : doc.content,
|
|
|
4787
5370
|
} catch {
|
|
4788
5371
|
existing = "# Engram File Hygiene Warnings\n";
|
|
4789
5372
|
}
|
|
4790
|
-
await
|
|
5373
|
+
await writeFile3(fp, existing + block, "utf-8");
|
|
4791
5374
|
}
|
|
4792
5375
|
}
|
|
4793
5376
|
}
|
|
@@ -4825,253 +5408,18 @@ ${doc.content}` : doc.content,
|
|
|
4825
5408
|
this.storageDirNamespace(targetStorage.dir),
|
|
4826
5409
|
5
|
|
4827
5410
|
);
|
|
4828
|
-
} catch (error) {
|
|
4829
|
-
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
4830
|
-
}
|
|
4831
|
-
}
|
|
4832
|
-
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
4833
|
-
}
|
|
4834
|
-
async runSemanticConsolidation(options) {
|
|
4835
|
-
const targetStorage = options?.storage ?? this.storage;
|
|
4836
|
-
const result = {
|
|
4837
|
-
clustersFound: 0,
|
|
4838
|
-
memoriesConsolidated: 0,
|
|
4839
|
-
memoriesArchived: 0,
|
|
4840
|
-
errors: 0,
|
|
4841
|
-
clusters: []
|
|
4842
|
-
};
|
|
4843
|
-
if (!this.config.semanticConsolidationEnabled && !options?.force) {
|
|
4844
|
-
log.debug("[semantic-consolidation] disabled in config");
|
|
4845
|
-
return result;
|
|
4846
|
-
}
|
|
4847
|
-
log.info("[semantic-consolidation] starting run");
|
|
4848
|
-
const allMemories = await targetStorage.readAllMemories();
|
|
4849
|
-
if (allMemories.length < 10) {
|
|
4850
|
-
log.debug("[semantic-consolidation] too few memories, skipping");
|
|
4851
|
-
return result;
|
|
4852
|
-
}
|
|
4853
|
-
const threshold = options?.thresholdOverride ?? this.config.semanticConsolidationThreshold;
|
|
4854
|
-
const clusters = findSimilarClusters(allMemories, {
|
|
4855
|
-
threshold,
|
|
4856
|
-
minClusterSize: this.config.semanticConsolidationMinClusterSize,
|
|
4857
|
-
excludeCategories: this.config.semanticConsolidationExcludeCategories,
|
|
4858
|
-
maxPerRun: this.config.semanticConsolidationMaxPerRun
|
|
4859
|
-
});
|
|
4860
|
-
result.clustersFound = clusters.length;
|
|
4861
|
-
result.clusters = clusters;
|
|
4862
|
-
if (clusters.length === 0) {
|
|
4863
|
-
log.info("[semantic-consolidation] no clusters found");
|
|
4864
|
-
return result;
|
|
4865
|
-
}
|
|
4866
|
-
log.info(`[semantic-consolidation] found ${clusters.length} cluster(s)`);
|
|
4867
|
-
if (options?.dryRun) {
|
|
4868
|
-
log.info(
|
|
4869
|
-
"[semantic-consolidation] dry run \u2014 skipping LLM synthesis and archival"
|
|
4870
|
-
);
|
|
4871
|
-
return result;
|
|
4872
|
-
}
|
|
4873
|
-
const { FallbackLlmClient: FallbackLlmClient2, gatewayTaskChainOptions: gatewayTaskChainOptions2 } = await import("./fallback-llm.js");
|
|
4874
|
-
const useGateway = this.config.modelSource === "gateway";
|
|
4875
|
-
const modelSetting = this.config.semanticConsolidationModel;
|
|
4876
|
-
if (modelSetting === "fast" && this.fastLlm && !useGateway) {
|
|
4877
|
-
log.info("[semantic-consolidation] using fast local LLM for synthesis");
|
|
4878
|
-
}
|
|
4879
|
-
const gatewayChainOptions = !useGateway ? {} : modelSetting === "fast" ? this.config.fastGatewayAgentId ? { agentId: this.config.fastGatewayAgentId } : this.config.gatewayAgentId ? { agentId: this.config.gatewayAgentId } : {} : gatewayTaskChainOptions2(this.config);
|
|
4880
|
-
const llm = new FallbackLlmClient2(
|
|
4881
|
-
this.config.gatewayConfig,
|
|
4882
|
-
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
4883
|
-
);
|
|
4884
|
-
if (!llm.isAvailable(gatewayChainOptions) && !(modelSetting === "fast" && this.fastLlm && !useGateway)) {
|
|
4885
|
-
log.warn(
|
|
4886
|
-
"[semantic-consolidation] no LLM available \u2014 skipping synthesis"
|
|
4887
|
-
);
|
|
4888
|
-
return result;
|
|
4889
|
-
}
|
|
4890
|
-
let extensionsBlock = "";
|
|
4891
|
-
try {
|
|
4892
|
-
extensionsBlock = await buildExtensionsBlockForConsolidation(this.config);
|
|
4893
|
-
} catch (err) {
|
|
4894
|
-
log.warn(`[semantic-consolidation] extension discovery failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
4895
|
-
}
|
|
4896
|
-
for (const cluster of clusters) {
|
|
4897
|
-
let canonicalWriteCompleted = false;
|
|
4898
|
-
try {
|
|
4899
|
-
const operatorAwareEnabled = this.config.operatorAwareConsolidationEnabled === true;
|
|
4900
|
-
let prompt = operatorAwareEnabled ? buildOperatorAwareConsolidationPrompt(cluster) : buildConsolidationPrompt(cluster);
|
|
4901
|
-
if (extensionsBlock.length > 0) {
|
|
4902
|
-
prompt += "\n\n" + extensionsBlock;
|
|
4903
|
-
}
|
|
4904
|
-
const messages = [
|
|
4905
|
-
{
|
|
4906
|
-
role: "system",
|
|
4907
|
-
content: operatorAwareEnabled ? 'You are a memory consolidation system. Return ONLY a JSON object with two keys, "operator" and "output". The "operator" value MUST be one of the exact strings "merge", "update", or "split" \u2014 never a pipe-separated placeholder, never prose. The "output" value is the canonical memory text.' : "You are a memory consolidation system. Output only the consolidated memory text."
|
|
4908
|
-
},
|
|
4909
|
-
{ role: "user", content: prompt }
|
|
4910
|
-
];
|
|
4911
|
-
const llmOpts = { temperature: 0.2, maxTokens: 2e3 };
|
|
4912
|
-
let response = null;
|
|
4913
|
-
if (useGateway) {
|
|
4914
|
-
response = await llm.chatCompletion(messages, { ...llmOpts, ...gatewayChainOptions });
|
|
4915
|
-
} else if (modelSetting === "fast" && this.fastLlm) {
|
|
4916
|
-
const fastResult = await this.fastLlm.chatCompletion(messages, {
|
|
4917
|
-
operation: "semantic-consolidation",
|
|
4918
|
-
maxTokens: llmOpts.maxTokens,
|
|
4919
|
-
temperature: llmOpts.temperature,
|
|
4920
|
-
priority: "background",
|
|
4921
|
-
forceDisableThinking: true
|
|
4922
|
-
});
|
|
4923
|
-
response = fastResult ? { content: fastResult.content } : null;
|
|
4924
|
-
} else {
|
|
4925
|
-
response = await llm.chatCompletion(messages, llmOpts);
|
|
4926
|
-
}
|
|
4927
|
-
if (!response?.content) {
|
|
4928
|
-
log.warn(
|
|
4929
|
-
`[semantic-consolidation] empty LLM response for cluster in "${cluster.category}"`
|
|
4930
|
-
);
|
|
4931
|
-
result.errors++;
|
|
4932
|
-
continue;
|
|
4933
|
-
}
|
|
4934
|
-
let canonicalContent;
|
|
4935
|
-
let operator;
|
|
4936
|
-
if (operatorAwareEnabled) {
|
|
4937
|
-
const parsed = parseOperatorAwareConsolidationResponse(
|
|
4938
|
-
response.content,
|
|
4939
|
-
cluster
|
|
4940
|
-
);
|
|
4941
|
-
canonicalContent = parsed.output;
|
|
4942
|
-
operator = parsed.operator;
|
|
4943
|
-
} else {
|
|
4944
|
-
canonicalContent = parseConsolidationResponse(response.content);
|
|
4945
|
-
operator = chooseConsolidationOperator(cluster);
|
|
4946
|
-
}
|
|
4947
|
-
cluster.canonicalContent = canonicalContent;
|
|
4948
|
-
const sorted = [...cluster.memories].sort(
|
|
4949
|
-
(a, b) => new Date(b.frontmatter.created).getTime() - new Date(a.frontmatter.created).getTime()
|
|
4950
|
-
);
|
|
4951
|
-
const newest = sorted[0];
|
|
4952
|
-
const lineageIds = cluster.memories.map((m) => m.frontmatter.id);
|
|
4953
|
-
const derivedFromEntries = [];
|
|
4954
|
-
for (const m of cluster.memories) {
|
|
4955
|
-
if (!m.path) continue;
|
|
4956
|
-
const entry = await targetStorage.snapshotForProvenance(m.path);
|
|
4957
|
-
if (entry) derivedFromEntries.push(entry);
|
|
4958
|
-
}
|
|
4959
|
-
const { id: canonicalId, tombstoneBlocked: canonicalBlocked } = await targetStorage.writeMemory(
|
|
4960
|
-
newest.frontmatter.category,
|
|
4961
|
-
canonicalContent,
|
|
4962
|
-
{
|
|
4963
|
-
actor: "semantic-consolidation",
|
|
4964
|
-
confidence: newest.frontmatter.confidence,
|
|
4965
|
-
tags: [
|
|
4966
|
-
...new Set(
|
|
4967
|
-
cluster.memories.flatMap((m) => m.frontmatter.tags ?? [])
|
|
4968
|
-
)
|
|
4969
|
-
],
|
|
4970
|
-
source: "semantic-consolidation",
|
|
4971
|
-
lineage: lineageIds,
|
|
4972
|
-
derivedFrom: derivedFromEntries.length > 0 ? derivedFromEntries : void 0,
|
|
4973
|
-
derivedVia: operator
|
|
4974
|
-
}
|
|
4975
|
-
);
|
|
4976
|
-
if (canonicalBlocked) {
|
|
4977
|
-
log.info(`[semantic-consolidation] cluster in "${cluster.category}" tombstone-blocked \u2014 keeping ${cluster.memories.length} source(s) active (pending_review ${canonicalId})`);
|
|
4978
|
-
continue;
|
|
4979
|
-
}
|
|
4980
|
-
canonicalWriteCompleted = true;
|
|
4981
|
-
result.memoriesConsolidated++;
|
|
4982
|
-
for (const m of cluster.memories) {
|
|
4983
|
-
const archiveResult = await targetStorage.archiveMemory(m, {
|
|
4984
|
-
actor: "semantic-consolidation",
|
|
4985
|
-
reasonCode: "semantic-consolidation",
|
|
4986
|
-
relatedMemoryIds: [canonicalId]
|
|
4987
|
-
});
|
|
4988
|
-
if (archiveResult) {
|
|
4989
|
-
await this.removeContentHashForMemory(
|
|
4990
|
-
targetStorage,
|
|
4991
|
-
m,
|
|
4992
|
-
"semantic-consolidation"
|
|
4993
|
-
);
|
|
4994
|
-
try {
|
|
4995
|
-
await this.embeddingFallback.removeFromIndex(m.frontmatter.id);
|
|
4996
|
-
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && m.path && m.frontmatter?.created) {
|
|
4997
|
-
deindexMemory(
|
|
4998
|
-
targetStorage.dir,
|
|
4999
|
-
m.path,
|
|
5000
|
-
m.frontmatter.created,
|
|
5001
|
-
m.frontmatter.tags ?? []
|
|
5002
|
-
);
|
|
5003
|
-
}
|
|
5004
|
-
} catch (cleanupErr) {
|
|
5005
|
-
log.warn(
|
|
5006
|
-
`[semantic-consolidation] index cleanup failed (non-fatal): ${cleanupErr}`
|
|
5007
|
-
);
|
|
5008
|
-
}
|
|
5009
|
-
result.memoriesArchived++;
|
|
5010
|
-
}
|
|
5011
|
-
}
|
|
5012
|
-
log.info(
|
|
5013
|
-
`[semantic-consolidation] consolidated ${cluster.memories.length} memories \u2192 ${canonicalId}`
|
|
5014
|
-
);
|
|
5015
|
-
} catch (err) {
|
|
5016
|
-
log.warn(
|
|
5017
|
-
`[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`
|
|
5018
|
-
);
|
|
5019
|
-
result.errors++;
|
|
5020
|
-
} finally {
|
|
5021
|
-
if (canonicalWriteCompleted) {
|
|
5022
|
-
}
|
|
5023
|
-
}
|
|
5024
|
-
}
|
|
5025
|
-
if (result.memoriesArchived > 0) {
|
|
5026
|
-
await this.saveContentHashIndexes().catch(
|
|
5027
|
-
(err) => log.warn(
|
|
5028
|
-
`[semantic-consolidation] content-hash index save failed: ${err}`
|
|
5029
|
-
)
|
|
5030
|
-
);
|
|
5031
|
-
}
|
|
5032
|
-
log.info(
|
|
5033
|
-
`[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`
|
|
5034
|
-
);
|
|
5035
|
-
try {
|
|
5036
|
-
await materializeAfterSemanticConsolidation({
|
|
5037
|
-
config: this.config,
|
|
5038
|
-
memoryDir: targetStorage.dir
|
|
5039
|
-
});
|
|
5040
|
-
} catch (err) {
|
|
5041
|
-
log.warn(
|
|
5042
|
-
`[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
5043
|
-
);
|
|
5044
|
-
}
|
|
5045
|
-
if (this.config.peerProfileReasonerEnabled) {
|
|
5046
|
-
try {
|
|
5047
|
-
const { runPeerProfileReasoner } = await import("./peers/index.js");
|
|
5048
|
-
const llm2 = new FallbackLlmClient2(
|
|
5049
|
-
this.config.gatewayConfig,
|
|
5050
|
-
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
5051
|
-
);
|
|
5052
|
-
const peerResult = await runPeerProfileReasoner({
|
|
5053
|
-
memoryDir: targetStorage.dir,
|
|
5054
|
-
enabled: true,
|
|
5055
|
-
llm: llm2,
|
|
5056
|
-
model: this.config.peerProfileReasonerModel,
|
|
5057
|
-
minInteractions: this.config.peerProfileReasonerMinInteractions,
|
|
5058
|
-
maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
|
|
5059
|
-
log: {
|
|
5060
|
-
debug: (msg) => log.debug(msg),
|
|
5061
|
-
info: (msg) => log.info(msg),
|
|
5062
|
-
warn: (msg) => log.warn(msg)
|
|
5063
|
-
}
|
|
5064
|
-
});
|
|
5065
|
-
log.info(
|
|
5066
|
-
`[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`
|
|
5067
|
-
);
|
|
5068
|
-
} catch (err) {
|
|
5069
|
-
log.warn(
|
|
5070
|
-
`[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`
|
|
5071
|
-
);
|
|
5411
|
+
} catch (error) {
|
|
5412
|
+
log.debug(`deep-sleep governance: entity synthesis refresh failed after apply: ${error}`);
|
|
5072
5413
|
}
|
|
5073
5414
|
}
|
|
5074
|
-
return
|
|
5415
|
+
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
5416
|
+
}
|
|
5417
|
+
// Issue #1526 (seam 5): semantic consolidation moved to
|
|
5418
|
+
// SemanticConsolidationCoordinator. Thin delegation keeps all
|
|
5419
|
+
// call sites (runConsolidation, runSemanticConsolidationNow,
|
|
5420
|
+
// runSemanticConsolidationFanout) stable.
|
|
5421
|
+
async runSemanticConsolidation(options) {
|
|
5422
|
+
return this.semanticConsolidationCoordinator.runSemanticConsolidation(options);
|
|
5075
5423
|
}
|
|
5076
5424
|
async waitForExtractionIdle(timeoutMs = 6e4) {
|
|
5077
5425
|
return this.extractionQueueCoordinator.waitForIdle(timeoutMs);
|
|
@@ -5255,7 +5603,7 @@ ${evidenceText}`
|
|
|
5255
5603
|
for (const categoryDir of RECALL_FALLBACK_DIRS) {
|
|
5256
5604
|
if (memoryRootReal === null) break;
|
|
5257
5605
|
for (const date of datesToScan) {
|
|
5258
|
-
const dateDir =
|
|
5606
|
+
const dateDir = path4.join(storage.dir, categoryDir, date);
|
|
5259
5607
|
try {
|
|
5260
5608
|
const dirStat = await lstat(dateDir);
|
|
5261
5609
|
if (dirStat.isSymbolicLink() || !dirStat.isDirectory()) continue;
|
|
@@ -5264,7 +5612,7 @@ ${evidenceText}`
|
|
|
5264
5612
|
for (const entry of entries) {
|
|
5265
5613
|
if (entry.isSymbolicLink()) continue;
|
|
5266
5614
|
if (!entry.name.endsWith(".md")) continue;
|
|
5267
|
-
const fullPath =
|
|
5615
|
+
const fullPath = path4.join(dateDir, entry.name);
|
|
5268
5616
|
try {
|
|
5269
5617
|
assertPathInsideRoot(memoryRootReal, await realpath(fullPath), fullPath);
|
|
5270
5618
|
const raw = await readFile2(fullPath, "utf-8");
|
|
@@ -5286,7 +5634,7 @@ ${evidenceText}`
|
|
|
5286
5634
|
facts.push({
|
|
5287
5635
|
path: fullPath,
|
|
5288
5636
|
frontmatter: {
|
|
5289
|
-
id: fm.id ||
|
|
5637
|
+
id: fm.id || path4.basename(entry.name, ".md"),
|
|
5290
5638
|
category: fm.category || "fact",
|
|
5291
5639
|
created,
|
|
5292
5640
|
updated: fm.updated || created,
|
|
@@ -5309,13 +5657,13 @@ ${evidenceText}`
|
|
|
5309
5657
|
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
5310
5658
|
});
|
|
5311
5659
|
const hourlySummaries = [];
|
|
5312
|
-
const hourlyBaseDir =
|
|
5660
|
+
const hourlyBaseDir = path4.join(storage.dir, "summaries", "hourly");
|
|
5313
5661
|
try {
|
|
5314
5662
|
const sessionKeys = await readdir(hourlyBaseDir, { withFileTypes: true });
|
|
5315
5663
|
for (const sk of sessionKeys) {
|
|
5316
5664
|
if (!sk.isDirectory()) continue;
|
|
5317
5665
|
for (const date of datesToScan) {
|
|
5318
|
-
const summaryFile =
|
|
5666
|
+
const summaryFile = path4.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
5319
5667
|
try {
|
|
5320
5668
|
const raw = await readFile2(summaryFile, "utf-8");
|
|
5321
5669
|
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
@@ -5363,7 +5711,7 @@ ${evidenceText}`
|
|
|
5363
5711
|
action: event.action,
|
|
5364
5712
|
eligibility,
|
|
5365
5713
|
options: {
|
|
5366
|
-
actionsEnabled: this.config.
|
|
5714
|
+
actionsEnabled: resolveCompressionCapabilities(this.config).contextCompressionActions,
|
|
5367
5715
|
maxCompressionTokensPerHour: this.config.maxCompressionTokensPerHour
|
|
5368
5716
|
}
|
|
5369
5717
|
});
|
|
@@ -5419,7 +5767,7 @@ ${evidenceText}`
|
|
|
5419
5767
|
}
|
|
5420
5768
|
async getLastGraphRecallSnapshot(namespace) {
|
|
5421
5769
|
const storage = await this.getStorage(namespace);
|
|
5422
|
-
const snapshotPath =
|
|
5770
|
+
const snapshotPath = path4.join(
|
|
5423
5771
|
storage.dir,
|
|
5424
5772
|
"state",
|
|
5425
5773
|
"last_graph_recall.json"
|
|
@@ -5458,7 +5806,7 @@ ${evidenceText}`
|
|
|
5458
5806
|
}
|
|
5459
5807
|
async getLastIntentSnapshot(namespace) {
|
|
5460
5808
|
const storage = await this.getStorage(namespace);
|
|
5461
|
-
const snapshotPath =
|
|
5809
|
+
const snapshotPath = path4.join(storage.dir, "state", "last_intent.json");
|
|
5462
5810
|
try {
|
|
5463
5811
|
const raw = await readFile2(snapshotPath, "utf-8");
|
|
5464
5812
|
const parsed = JSON.parse(raw);
|
|
@@ -5491,7 +5839,7 @@ ${evidenceText}`
|
|
|
5491
5839
|
}
|
|
5492
5840
|
async getLastQmdRecallSnapshot(namespace) {
|
|
5493
5841
|
const storage = await this.getStorage(namespace);
|
|
5494
|
-
const snapshotPath =
|
|
5842
|
+
const snapshotPath = path4.join(
|
|
5495
5843
|
storage.dir,
|
|
5496
5844
|
"state",
|
|
5497
5845
|
"last_qmd_recall.json"
|
|
@@ -5644,7 +5992,7 @@ ${r.snippet.trim()}
|
|
|
5644
5992
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
5645
5993
|
let total = 0;
|
|
5646
5994
|
for (const entry of entries) {
|
|
5647
|
-
const fullPath =
|
|
5995
|
+
const fullPath = path4.join(dir, entry.name);
|
|
5648
5996
|
if (entry.isDirectory()) {
|
|
5649
5997
|
total += await this.countConversationChunkDocs(fullPath);
|
|
5650
5998
|
continue;
|
|
@@ -5872,7 +6220,7 @@ ${r.snippet.trim()}
|
|
|
5872
6220
|
options.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
5873
6221
|
}
|
|
5874
6222
|
const principal = typeof options.principalOverride === "string" && options.principalOverride.length > 0 ? options.principalOverride : resolvePrincipal(sessionKey, this.config);
|
|
5875
|
-
const namespacesEnabled = this.config.
|
|
6223
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
5876
6224
|
if (namespacesEnabled && !principal) {
|
|
5877
6225
|
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
5878
6226
|
}
|
|
@@ -6213,7 +6561,7 @@ ${r.snippet.trim()}
|
|
|
6213
6561
|
const scoped = /* @__PURE__ */ new Set();
|
|
6214
6562
|
for (const memoryPath of paths) {
|
|
6215
6563
|
if (!memoryPath || isArtifactMemoryPath(memoryPath)) continue;
|
|
6216
|
-
if (this.config.
|
|
6564
|
+
if (resolveNamespaceCapabilities(this.config).namespaces && !recallNamespaces.includes(this.namespaceFromPath(memoryPath))) {
|
|
6217
6565
|
continue;
|
|
6218
6566
|
}
|
|
6219
6567
|
scoped.add(memoryPath);
|
|
@@ -6296,7 +6644,7 @@ ${r.snippet.trim()}
|
|
|
6296
6644
|
const tokens = Array.from(new Set(tokenizeRecallQuery(query)));
|
|
6297
6645
|
const memories = (await Promise.all(
|
|
6298
6646
|
Array.from(candidatePaths).map(async (memoryPath) => {
|
|
6299
|
-
const namespace = this.config.
|
|
6647
|
+
const namespace = resolveNamespaceCapabilities(this.config).namespaces ? this.namespaceFromPath(memoryPath) : this.config.defaultNamespace;
|
|
6300
6648
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
6301
6649
|
return await storage.readMemoryByPath(memoryPath);
|
|
6302
6650
|
})
|
|
@@ -6550,7 +6898,7 @@ ${r.snippet.trim()}
|
|
|
6550
6898
|
resolvedPath = resolvedCold.result.path;
|
|
6551
6899
|
resolvedResult = resolvedCold.result;
|
|
6552
6900
|
}
|
|
6553
|
-
if (!
|
|
6901
|
+
if (!path4.isAbsolute(resolvedPath)) {
|
|
6554
6902
|
resolvedAmbiguousSeeds.set(result.path, null);
|
|
6555
6903
|
return null;
|
|
6556
6904
|
}
|
|
@@ -6575,7 +6923,7 @@ ${r.snippet.trim()}
|
|
|
6575
6923
|
}
|
|
6576
6924
|
continue;
|
|
6577
6925
|
}
|
|
6578
|
-
if (
|
|
6926
|
+
if (path4.isAbsolute(result.path)) {
|
|
6579
6927
|
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
6580
6928
|
if (resolved) {
|
|
6581
6929
|
addResultForNamespace(resolved.namespace, resolved.result);
|
|
@@ -6618,7 +6966,7 @@ ${r.snippet.trim()}
|
|
|
6618
6966
|
0
|
|
6619
6967
|
);
|
|
6620
6968
|
seedPaths.push(
|
|
6621
|
-
...seedRelativePaths.map((rel) =>
|
|
6969
|
+
...seedRelativePaths.map((rel) => path4.join(storage.dir, rel))
|
|
6622
6970
|
);
|
|
6623
6971
|
const seedSet = new Set(seedRelativePaths);
|
|
6624
6972
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
@@ -6634,7 +6982,7 @@ ${r.snippet.trim()}
|
|
|
6634
6982
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
6635
6983
|
if (deadlineExpired()) break;
|
|
6636
6984
|
if (seedSet.has(candidate.path)) continue;
|
|
6637
|
-
const memoryPath =
|
|
6985
|
+
const memoryPath = path4.resolve(storage.dir, candidate.path);
|
|
6638
6986
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
6639
6987
|
if (deadlineExpired()) break;
|
|
6640
6988
|
if (!memory) continue;
|
|
@@ -6659,7 +7007,7 @@ ${r.snippet.trim()}
|
|
|
6659
7007
|
path: memory.path,
|
|
6660
7008
|
score,
|
|
6661
7009
|
namespace,
|
|
6662
|
-
seed:
|
|
7010
|
+
seed: path4.resolve(storage.dir, candidate.seed),
|
|
6663
7011
|
hopDepth: candidate.hopDepth,
|
|
6664
7012
|
decayedWeight: candidate.decayedWeight,
|
|
6665
7013
|
graphType: candidate.graphType,
|
|
@@ -6680,12 +7028,12 @@ ${r.snippet.trim()}
|
|
|
6680
7028
|
}
|
|
6681
7029
|
async recordLastGraphRecallSnapshot(options) {
|
|
6682
7030
|
try {
|
|
6683
|
-
const snapshotPath =
|
|
7031
|
+
const snapshotPath = path4.join(
|
|
6684
7032
|
options.storage.dir,
|
|
6685
7033
|
"state",
|
|
6686
7034
|
"last_graph_recall.json"
|
|
6687
7035
|
);
|
|
6688
|
-
await
|
|
7036
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
6689
7037
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
6690
7038
|
const totalSeedCount = options.seedPaths.length;
|
|
6691
7039
|
const totalExpandedCount = options.expandedPaths.length;
|
|
@@ -6712,20 +7060,20 @@ ${r.snippet.trim()}
|
|
|
6712
7060
|
finalResults: (options.finalResults ?? []).slice(0, 64),
|
|
6713
7061
|
shadowComparison: options.shadowComparison
|
|
6714
7062
|
};
|
|
6715
|
-
await
|
|
7063
|
+
await writeFile3(snapshotPath, JSON.stringify(payload, null, 2), "utf-8");
|
|
6716
7064
|
} catch (err) {
|
|
6717
7065
|
log.debug(`last graph recall write failed: ${err}`);
|
|
6718
7066
|
}
|
|
6719
7067
|
}
|
|
6720
7068
|
async recordLastIntentSnapshot(options) {
|
|
6721
7069
|
try {
|
|
6722
|
-
const snapshotPath =
|
|
7070
|
+
const snapshotPath = path4.join(
|
|
6723
7071
|
options.storage.dir,
|
|
6724
7072
|
"state",
|
|
6725
7073
|
"last_intent.json"
|
|
6726
7074
|
);
|
|
6727
|
-
await
|
|
6728
|
-
await
|
|
7075
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7076
|
+
await writeFile3(
|
|
6729
7077
|
snapshotPath,
|
|
6730
7078
|
JSON.stringify(options.snapshot, null, 2),
|
|
6731
7079
|
"utf-8"
|
|
@@ -6736,13 +7084,13 @@ ${r.snippet.trim()}
|
|
|
6736
7084
|
}
|
|
6737
7085
|
async recordLastQmdRecallSnapshot(options) {
|
|
6738
7086
|
try {
|
|
6739
|
-
const snapshotPath =
|
|
7087
|
+
const snapshotPath = path4.join(
|
|
6740
7088
|
options.storage.dir,
|
|
6741
7089
|
"state",
|
|
6742
7090
|
"last_qmd_recall.json"
|
|
6743
7091
|
);
|
|
6744
|
-
await
|
|
6745
|
-
await
|
|
7092
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7093
|
+
await writeFile3(
|
|
6746
7094
|
snapshotPath,
|
|
6747
7095
|
JSON.stringify(options.snapshot, null, 2),
|
|
6748
7096
|
"utf-8"
|
|
@@ -6756,9 +7104,9 @@ ${r.snippet.trim()}
|
|
|
6756
7104
|
const stateDir = await this.resolveStateDirForNamespace(
|
|
6757
7105
|
options.namespace
|
|
6758
7106
|
);
|
|
6759
|
-
const snapshotPath =
|
|
6760
|
-
await
|
|
6761
|
-
await
|
|
7107
|
+
const snapshotPath = path4.join(stateDir, "last_intent.json");
|
|
7108
|
+
await mkdir3(path4.dirname(snapshotPath), { recursive: true });
|
|
7109
|
+
await writeFile3(
|
|
6762
7110
|
snapshotPath,
|
|
6763
7111
|
JSON.stringify(options.snapshot, null, 2),
|
|
6764
7112
|
"utf-8"
|
|
@@ -6768,13 +7116,13 @@ ${r.snippet.trim()}
|
|
|
6768
7116
|
}
|
|
6769
7117
|
}
|
|
6770
7118
|
async resolveStateDirForNamespace(namespace) {
|
|
6771
|
-
if (!this.config.
|
|
6772
|
-
return
|
|
7119
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
7120
|
+
return path4.join(this.config.memoryDir, "state");
|
|
6773
7121
|
}
|
|
6774
7122
|
if (namespace !== this.config.defaultNamespace) {
|
|
6775
|
-
return
|
|
7123
|
+
return path4.join(this.config.memoryDir, "namespaces", namespace, "state");
|
|
6776
7124
|
}
|
|
6777
|
-
const candidate =
|
|
7125
|
+
const candidate = path4.join(
|
|
6778
7126
|
this.config.memoryDir,
|
|
6779
7127
|
"namespaces",
|
|
6780
7128
|
this.config.defaultNamespace
|
|
@@ -6782,11 +7130,11 @@ ${r.snippet.trim()}
|
|
|
6782
7130
|
try {
|
|
6783
7131
|
const candidateStat = await stat(candidate);
|
|
6784
7132
|
if (candidateStat.isDirectory()) {
|
|
6785
|
-
return
|
|
7133
|
+
return path4.join(candidate, "state");
|
|
6786
7134
|
}
|
|
6787
7135
|
} catch {
|
|
6788
7136
|
}
|
|
6789
|
-
return
|
|
7137
|
+
return path4.join(this.config.memoryDir, "state");
|
|
6790
7138
|
}
|
|
6791
7139
|
buildGraphRecallRankedResults(results, sourceLabelResolver, limit = 64) {
|
|
6792
7140
|
return results.slice(0, limit).map((result) => ({
|
|
@@ -6984,7 +7332,7 @@ ${r.snippet.trim()}
|
|
|
6984
7332
|
}
|
|
6985
7333
|
const timings = {};
|
|
6986
7334
|
const profileTraceId = this.profiler.startTrace("recall", sessionKey, {
|
|
6987
|
-
qmdEnabled: this.config.
|
|
7335
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
6988
7336
|
rerankEnabled: caps.rerank,
|
|
6989
7337
|
parallelRetrieval: caps.parallelRetrieval
|
|
6990
7338
|
});
|
|
@@ -7141,7 +7489,7 @@ ${r.snippet.trim()}
|
|
|
7141
7489
|
);
|
|
7142
7490
|
const embeddingFetchLimit = computedFetchLimit;
|
|
7143
7491
|
const principal = typeof options.principalOverride === "string" && options.principalOverride.length > 0 ? options.principalOverride : resolvePrincipal(sessionKey, this.config);
|
|
7144
|
-
const namespacesEnabled = this.config.
|
|
7492
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
7145
7493
|
if (namespacesEnabled && !principal) {
|
|
7146
7494
|
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
7147
7495
|
}
|
|
@@ -7188,7 +7536,7 @@ ${r.snippet.trim()}
|
|
|
7188
7536
|
const graphExpandedResultPaths = /* @__PURE__ */ new Set();
|
|
7189
7537
|
const graphSourceLabelsForPath = (resultPath) => {
|
|
7190
7538
|
const labels = [];
|
|
7191
|
-
const normalizedPath = resultPath.split(
|
|
7539
|
+
const normalizedPath = resultPath.split(path4.sep).join("/");
|
|
7192
7540
|
const isEntityPath = normalizedPath.startsWith("entities/") || normalizedPath.includes("/entities/");
|
|
7193
7541
|
if (graphBaselinePaths.has(resultPath)) labels.push("baseline");
|
|
7194
7542
|
if (graphExpandedResultPaths.has(resultPath))
|
|
@@ -7317,7 +7665,7 @@ ${r.snippet.trim()}
|
|
|
7317
7665
|
retrievalQueryLength: retrievalQuery.length,
|
|
7318
7666
|
recallMode,
|
|
7319
7667
|
recallResultLimit,
|
|
7320
|
-
qmdEnabled: this.config.
|
|
7668
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
7321
7669
|
qmdAvailable: this.qmd.isAvailable(),
|
|
7322
7670
|
recallNamespaces: [],
|
|
7323
7671
|
source: recallSource,
|
|
@@ -7338,7 +7686,7 @@ ${r.snippet.trim()}
|
|
|
7338
7686
|
profileStorageNamespaces.map((namespace) => this.storageRouter.storageFor(namespace))
|
|
7339
7687
|
);
|
|
7340
7688
|
const emptyProfileStorage = new Proxy(
|
|
7341
|
-
{ dir:
|
|
7689
|
+
{ dir: path4.join(this.config.memoryDir, ".empty-scope-profile") },
|
|
7342
7690
|
{
|
|
7343
7691
|
get(target, prop) {
|
|
7344
7692
|
if (prop in target) return target[prop];
|
|
@@ -7622,7 +7970,7 @@ ${lines.join("\n\n")}`;
|
|
|
7622
7970
|
const identityContinuityPromise = (async () => {
|
|
7623
7971
|
if (!this.isRecallSectionEnabled(
|
|
7624
7972
|
"identity-continuity",
|
|
7625
|
-
this.config.
|
|
7973
|
+
resolveIdentityContinuityCapabilities(this.config).identityContinuity === true
|
|
7626
7974
|
))
|
|
7627
7975
|
return null;
|
|
7628
7976
|
const t0 = Date.now();
|
|
@@ -7820,9 +8168,9 @@ ${rows.join("\n")}
|
|
|
7820
8168
|
})();
|
|
7821
8169
|
const objectiveStatePromise = (async () => {
|
|
7822
8170
|
const t0 = Date.now();
|
|
7823
|
-
if (!this.config.
|
|
8171
|
+
if (!resolveObjectiveStateCapabilities(this.config).objectiveStateMemory || !resolveObjectiveStateCapabilities(this.config).objectiveStateRecall || !this.isRecallSectionEnabled(
|
|
7824
8172
|
"objective-state",
|
|
7825
|
-
this.config.
|
|
8173
|
+
resolveObjectiveStateCapabilities(this.config).objectiveStateRecall === true
|
|
7826
8174
|
)) {
|
|
7827
8175
|
recordRecallSectionMetric({
|
|
7828
8176
|
section: "objectiveState",
|
|
@@ -7850,13 +8198,13 @@ ${rows.join("\n")}
|
|
|
7850
8198
|
}
|
|
7851
8199
|
const objectiveStateSearches = await Promise.all(
|
|
7852
8200
|
recallNamespaces.map(async (namespace) => {
|
|
7853
|
-
const storage = this.config.
|
|
8201
|
+
const storage = resolveNamespaceCapabilities(this.config).namespaces ? await this.getStorage(namespace) : null;
|
|
7854
8202
|
return searchObjectiveStateSnapshots({
|
|
7855
|
-
memoryDir: this.config.
|
|
8203
|
+
memoryDir: resolveNamespaceCapabilities(this.config).namespaces ? storage.dir : this.config.memoryDir,
|
|
7856
8204
|
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
7857
8205
|
memoryDir: this.config.memoryDir,
|
|
7858
8206
|
configuredStoreDir: this.config.objectiveStateStoreDir,
|
|
7859
|
-
namespacesEnabled: this.config.
|
|
8207
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
7860
8208
|
namespace
|
|
7861
8209
|
}),
|
|
7862
8210
|
query: retrievalQuery,
|
|
@@ -8041,9 +8389,9 @@ ${rows.join("\n")}
|
|
|
8041
8389
|
})();
|
|
8042
8390
|
const trustZonePromise = (async () => {
|
|
8043
8391
|
const t0 = Date.now();
|
|
8044
|
-
if (!this.config.
|
|
8392
|
+
if (!resolveSecurityCapabilities(this.config).trustZones || !resolveSecurityCapabilities(this.config).trustZoneRecall || !this.isRecallSectionEnabled(
|
|
8045
8393
|
"trust-zones",
|
|
8046
|
-
this.config.
|
|
8394
|
+
resolveSecurityCapabilities(this.config).trustZoneRecall === true
|
|
8047
8395
|
)) {
|
|
8048
8396
|
recordRecallSectionMetric({
|
|
8049
8397
|
section: "trustZones",
|
|
@@ -8612,7 +8960,7 @@ ${rows.join("\n")}
|
|
|
8612
8960
|
qmdFetchLimit,
|
|
8613
8961
|
qmdHybridFetchLimit,
|
|
8614
8962
|
{
|
|
8615
|
-
namespacesEnabled: this.config.
|
|
8963
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
8616
8964
|
recallNamespaces,
|
|
8617
8965
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
8618
8966
|
queryAwarePrefilter,
|
|
@@ -8814,11 +9162,11 @@ ${formatted}`;
|
|
|
8814
9162
|
if (!this.config.compactionResetEnabled) return null;
|
|
8815
9163
|
const workspaceDir = compactionWorkspaceDir || this.config.workspaceDir || defaultWorkspaceDir();
|
|
8816
9164
|
const safeSessionKey = sanitizeSessionKeyForFilename(effectiveSessionKey);
|
|
8817
|
-
const signalPath =
|
|
9165
|
+
const signalPath = path4.join(
|
|
8818
9166
|
workspaceDir,
|
|
8819
9167
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
8820
9168
|
);
|
|
8821
|
-
const bootPath =
|
|
9169
|
+
const bootPath = path4.join(workspaceDir, "BOOT.md");
|
|
8822
9170
|
try {
|
|
8823
9171
|
const signalStat = await stat(signalPath).catch(() => null);
|
|
8824
9172
|
if (!signalStat) return null;
|
|
@@ -8945,7 +9293,7 @@ ${formatted}`;
|
|
|
8945
9293
|
workspaceDir: this.config.workspaceDir,
|
|
8946
9294
|
memoryDir: this.config.memoryDir,
|
|
8947
9295
|
config: this.config.nativeKnowledge,
|
|
8948
|
-
recallNamespaces: this.config.
|
|
9296
|
+
recallNamespaces: resolveNamespaceCapabilities(this.config).namespaces ? recallNamespaces : void 0,
|
|
8949
9297
|
defaultNamespace: this.config.defaultNamespace,
|
|
8950
9298
|
abortSignal: nativeKnowledgeAbort.signal
|
|
8951
9299
|
}).catch(() => []);
|
|
@@ -9700,7 +10048,7 @@ ${tmtNode.summary}`
|
|
|
9700
10048
|
[]
|
|
9701
10049
|
);
|
|
9702
10050
|
let memoryResults = memoryResultsRaw;
|
|
9703
|
-
if (this.config.
|
|
10051
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
9704
10052
|
memoryResults = memoryResults.filter(
|
|
9705
10053
|
(r) => recallNamespaces.includes(this.namespaceFromPath(r.path))
|
|
9706
10054
|
);
|
|
@@ -9983,7 +10331,7 @@ ${tmtNode.summary}`
|
|
|
9983
10331
|
const scopedCandidates = filterRecallCandidates(
|
|
9984
10332
|
prefilteredEmbeddingResults,
|
|
9985
10333
|
{
|
|
9986
|
-
namespacesEnabled: this.config.
|
|
10334
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
9987
10335
|
recallNamespaces,
|
|
9988
10336
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
9989
10337
|
limit: embeddingFetchLimit
|
|
@@ -10144,7 +10492,7 @@ ${tmtNode.summary}`
|
|
|
10144
10492
|
const scopedCandidates = filterRecallCandidates(
|
|
10145
10493
|
prefilteredEmbeddingResults,
|
|
10146
10494
|
{
|
|
10147
|
-
namespacesEnabled: this.config.
|
|
10495
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
10148
10496
|
recallNamespaces,
|
|
10149
10497
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
10150
10498
|
limit: embeddingFetchLimit
|
|
@@ -10503,7 +10851,7 @@ ${tmtNode.summary}`
|
|
|
10503
10851
|
});
|
|
10504
10852
|
if (this.isRecallSectionEnabled(
|
|
10505
10853
|
"compression-guidelines",
|
|
10506
|
-
this.config.
|
|
10854
|
+
resolveCompressionCapabilities(this.config).compressionGuidelineLearning === true
|
|
10507
10855
|
)) {
|
|
10508
10856
|
const compressionGuidelineSection = await this.buildCompressionGuidelineRecallSection();
|
|
10509
10857
|
if (compressionGuidelineSection) {
|
|
@@ -10809,7 +11157,7 @@ _Context: ${topQuestion.context}_`
|
|
|
10809
11157
|
retrievalQueryLength: retrievalQuery.length,
|
|
10810
11158
|
recallMode,
|
|
10811
11159
|
recallResultLimit,
|
|
10812
|
-
qmdEnabled: this.config.
|
|
11160
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
10813
11161
|
qmdAvailable: this.qmd.isAvailable(),
|
|
10814
11162
|
recallNamespaces,
|
|
10815
11163
|
source: recallSource,
|
|
@@ -11982,7 +12330,7 @@ ${normalized}`).digest("hex");
|
|
|
11982
12330
|
const profileAllowsSharedWrites = !scopeProfileWritePlan || Boolean(
|
|
11983
12331
|
scopeProfileWritePlan.profile.readOrder.includes("serverShared") && scopeProfileWritePlan.readNamespaces.includes(this.config.sharedNamespace) && sharedProfileLayer?.readable && sharedProfileLayer.writable && sharedPromotionTarget?.authorized
|
|
11984
12332
|
);
|
|
11985
|
-
const namespacesEnabled = this.config.
|
|
12333
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
11986
12334
|
const profileAutoPromotionAllows = (category, confidence) => {
|
|
11987
12335
|
if (!scopeProfileWritePlan) return false;
|
|
11988
12336
|
const actualTier = confidenceTier(confidence);
|
|
@@ -12010,7 +12358,7 @@ ${normalized}`).digest("hex");
|
|
|
12010
12358
|
return scopeProfileWritePlan.profile.autoPromote.targets.includes("serverShared") && profileAutoPromotionAllows(category, confidence);
|
|
12011
12359
|
};
|
|
12012
12360
|
const shouldPromoteToShared = (targetStorage, category, confidence) => {
|
|
12013
|
-
if (!this.config.
|
|
12361
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces || !profileAllowsSharedWrites || !sharedAutoPromotionAllows(category, confidence))
|
|
12014
12362
|
return false;
|
|
12015
12363
|
if (this.storageDirNamespace(targetStorage.dir) === this.config.sharedNamespace)
|
|
12016
12364
|
return false;
|
|
@@ -13420,7 +13768,7 @@ ${normalized}`).digest("hex");
|
|
|
13420
13768
|
const allMems = allMemsForGraph ?? [];
|
|
13421
13769
|
for (const m of allMems) {
|
|
13422
13770
|
if (m.frontmatter.entityRef === entityRef) {
|
|
13423
|
-
const rel =
|
|
13771
|
+
const rel = path4.relative(storage.dir, m.path);
|
|
13424
13772
|
if (rel !== memoryRelPath) entitySiblings.push(rel);
|
|
13425
13773
|
}
|
|
13426
13774
|
}
|
|
@@ -13485,7 +13833,7 @@ ${normalized}`).digest("hex");
|
|
|
13485
13833
|
const needsFullRebuild = !indexesExist(this.config.memoryDir);
|
|
13486
13834
|
if (!needsFullRebuild && persistedIds.length === 0) return;
|
|
13487
13835
|
try {
|
|
13488
|
-
const allMemories = needsFullRebuild && this.config.
|
|
13836
|
+
const allMemories = needsFullRebuild && resolveNamespaceCapabilities(this.config).namespaces ? await this.readAllMemoriesForNamespaces(
|
|
13489
13837
|
Array.from(
|
|
13490
13838
|
/* @__PURE__ */ new Set([
|
|
13491
13839
|
this.config.defaultNamespace,
|
|
@@ -13744,7 +14092,7 @@ ${normalized}`).digest("hex");
|
|
|
13744
14092
|
}
|
|
13745
14093
|
if (this.config.semanticConsolidationEnabled) {
|
|
13746
14094
|
try {
|
|
13747
|
-
const stateFilePath =
|
|
14095
|
+
const stateFilePath = path4.join(
|
|
13748
14096
|
this.config.memoryDir,
|
|
13749
14097
|
"state",
|
|
13750
14098
|
"semantic-consolidation-last-run.json"
|
|
@@ -13792,9 +14140,9 @@ ${normalized}`).digest("hex");
|
|
|
13792
14140
|
);
|
|
13793
14141
|
}
|
|
13794
14142
|
if (semResult.errors === 0 || semResult.memoriesArchived > 0) {
|
|
13795
|
-
const stateDir =
|
|
13796
|
-
await
|
|
13797
|
-
await
|
|
14143
|
+
const stateDir = path4.join(this.config.memoryDir, "state");
|
|
14144
|
+
await mkdir3(stateDir, { recursive: true });
|
|
14145
|
+
await writeFile3(
|
|
13798
14146
|
stateFilePath,
|
|
13799
14147
|
JSON.stringify({ lastRunAt: (/* @__PURE__ */ new Date()).toISOString() }),
|
|
13800
14148
|
"utf-8"
|
|
@@ -13919,65 +14267,6 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
13919
14267
|
async buildCompressionGuidelineRecallSection() {
|
|
13920
14268
|
return this.compressionGuidelineCoordinator.buildCompressionGuidelineRecallSection();
|
|
13921
14269
|
}
|
|
13922
|
-
actionOutcomePriorDelta(event) {
|
|
13923
|
-
if (event.outcome === "failed") return -0.3;
|
|
13924
|
-
if (event.policyDecision === "deny") return -0.22;
|
|
13925
|
-
if (event.policyDecision === "defer") return -0.14;
|
|
13926
|
-
if (event.outcome === "skipped") return -0.1;
|
|
13927
|
-
if (event.outcome !== "applied") return 0;
|
|
13928
|
-
switch (event.action) {
|
|
13929
|
-
case "store_episode":
|
|
13930
|
-
case "store_note":
|
|
13931
|
-
case "update_note":
|
|
13932
|
-
return 0.08;
|
|
13933
|
-
case "create_artifact":
|
|
13934
|
-
case "summarize_node":
|
|
13935
|
-
case "link_graph":
|
|
13936
|
-
return 0.04;
|
|
13937
|
-
case "discard":
|
|
13938
|
-
return -0.03;
|
|
13939
|
-
default:
|
|
13940
|
-
return 0;
|
|
13941
|
-
}
|
|
13942
|
-
}
|
|
13943
|
-
async buildLifecycleActionPriors(storage = this.storage) {
|
|
13944
|
-
const events = await storage.readMemoryActionEvents(1200);
|
|
13945
|
-
if (events.length === 0) return /* @__PURE__ */ new Map();
|
|
13946
|
-
const nowMs = Date.now();
|
|
13947
|
-
const windowMs = 14 * 24 * 60 * 60 * 1e3;
|
|
13948
|
-
const byMemory = /* @__PURE__ */ new Map();
|
|
13949
|
-
for (const event of events) {
|
|
13950
|
-
if (typeof event.memoryId !== "string" || event.memoryId.trim().length === 0)
|
|
13951
|
-
continue;
|
|
13952
|
-
const ts = Date.parse(event.timestamp);
|
|
13953
|
-
if (!Number.isFinite(ts)) continue;
|
|
13954
|
-
const ageMs = nowMs - ts;
|
|
13955
|
-
if (ageMs < 0 || ageMs > windowMs) continue;
|
|
13956
|
-
const delta = this.actionOutcomePriorDelta(event);
|
|
13957
|
-
if (delta === 0) continue;
|
|
13958
|
-
const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
|
|
13959
|
-
const list = byMemory.get(event.memoryId) ?? [];
|
|
13960
|
-
if (list.length >= 8) list.shift();
|
|
13961
|
-
list.push({
|
|
13962
|
-
weightedDelta: delta * recencyWeight,
|
|
13963
|
-
weight: recencyWeight
|
|
13964
|
-
});
|
|
13965
|
-
byMemory.set(event.memoryId, list);
|
|
13966
|
-
}
|
|
13967
|
-
const out = /* @__PURE__ */ new Map();
|
|
13968
|
-
for (const [memoryId, deltas] of byMemory.entries()) {
|
|
13969
|
-
if (deltas.length === 0) continue;
|
|
13970
|
-
const weightedSum = deltas.reduce(
|
|
13971
|
-
(sum, item) => sum + item.weightedDelta,
|
|
13972
|
-
0
|
|
13973
|
-
);
|
|
13974
|
-
const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
|
|
13975
|
-
if (weightTotal <= 0) continue;
|
|
13976
|
-
const score = weightedSum / weightTotal;
|
|
13977
|
-
out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
|
|
13978
|
-
}
|
|
13979
|
-
return out;
|
|
13980
|
-
}
|
|
13981
14270
|
async recordScheduledDreamsPhaseRun(phase, itemsProcessed, notes, timing = {}) {
|
|
13982
14271
|
try {
|
|
13983
14272
|
const { recordDreamsPhaseRun } = await import("./dreams-ledger-6UODQOX6.js");
|
|
@@ -14001,223 +14290,24 @@ ${texts.map((t, i) => `[${i + 1}] ${t}`).join("\n\n")}`;
|
|
|
14001
14290
|
return { memoriesAssessed: lifecycleCorpus.length };
|
|
14002
14291
|
}
|
|
14003
14292
|
async runLifecyclePolicyPass(allMemories, storage = this.storage) {
|
|
14004
|
-
|
|
14005
|
-
const nowIso = now.toISOString();
|
|
14006
|
-
const countsByState = {
|
|
14007
|
-
candidate: 0,
|
|
14008
|
-
validated: 0,
|
|
14009
|
-
active: 0,
|
|
14010
|
-
stale: 0,
|
|
14011
|
-
archived: 0
|
|
14012
|
-
};
|
|
14013
|
-
const transitionCounts = {};
|
|
14014
|
-
let updatedCount = 0;
|
|
14015
|
-
let disputedCount = 0;
|
|
14016
|
-
let evaluatedCount = 0;
|
|
14017
|
-
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
14018
|
-
const thresholds = this.effectiveLifecycleThresholds();
|
|
14019
|
-
const policy = {
|
|
14020
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
14021
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
14022
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
14023
|
-
protectedCategories: this.config.lifecycleProtectedCategories
|
|
14024
|
-
};
|
|
14025
|
-
const actionPriors = await this.buildLifecycleActionPriors(storage);
|
|
14026
|
-
for (const memory of allMemories) {
|
|
14027
|
-
if (memory.frontmatter.status === "superseded" || memory.frontmatter.status === "forgotten") {
|
|
14028
|
-
continue;
|
|
14029
|
-
}
|
|
14030
|
-
evaluatedCount += 1;
|
|
14031
|
-
const currentState = resolveLifecycleState(memory.frontmatter);
|
|
14032
|
-
const actionPriorScore = actionPriors.get(memory.frontmatter.id);
|
|
14033
|
-
const signals = typeof actionPriorScore === "number" && Number.isFinite(actionPriorScore) ? { actionPriorScore } : void 0;
|
|
14034
|
-
const decision = decideLifecycleTransition(memory, policy, now, signals);
|
|
14035
|
-
const nextState = memory.frontmatter.status === "archived" ? "archived" : decision.nextState;
|
|
14036
|
-
countsByState[nextState] += 1;
|
|
14037
|
-
if (memory.frontmatter.verificationState === "disputed") {
|
|
14038
|
-
disputedCount += 1;
|
|
14039
|
-
}
|
|
14040
|
-
if (nextState !== currentState) {
|
|
14041
|
-
const key = `${currentState}->${nextState}`;
|
|
14042
|
-
transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
|
|
14043
|
-
}
|
|
14044
|
-
const prevHeat = memory.frontmatter.heatScore;
|
|
14045
|
-
const prevDecay = memory.frontmatter.decayScore;
|
|
14046
|
-
const scoreDelta = Math.abs((prevHeat ?? -1) - decision.heatScore) + Math.abs((prevDecay ?? -1) - decision.decayScore);
|
|
14047
|
-
const shouldPersist = memory.frontmatter.lifecycleState !== nextState || memory.frontmatter.heatScore === void 0 || memory.frontmatter.decayScore === void 0 || memory.frontmatter.lastValidatedAt === void 0 || scoreDelta >= 0.01;
|
|
14048
|
-
if (!shouldPersist) continue;
|
|
14049
|
-
const wrote = await storage.writeMemoryFrontmatter(memory, {
|
|
14050
|
-
lifecycleState: nextState,
|
|
14051
|
-
heatScore: decision.heatScore,
|
|
14052
|
-
decayScore: decision.decayScore,
|
|
14053
|
-
lastValidatedAt: nowIso
|
|
14054
|
-
});
|
|
14055
|
-
if (wrote) updatedCount += 1;
|
|
14056
|
-
}
|
|
14057
|
-
if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
|
|
14058
|
-
const total = evaluatedCount;
|
|
14059
|
-
const metrics = {
|
|
14060
|
-
generatedAt: nowIso,
|
|
14061
|
-
memoriesEvaluated: total,
|
|
14062
|
-
memoriesUpdated: updatedCount,
|
|
14063
|
-
countsByLifecycleState: countsByState,
|
|
14064
|
-
transitionCounts,
|
|
14065
|
-
staleRatio: total > 0 ? countsByState.stale / total : 0,
|
|
14066
|
-
disputedRatio: total > 0 ? disputedCount / total : 0,
|
|
14067
|
-
policy: {
|
|
14068
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
14069
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
14070
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
14071
|
-
protectedCategories: this.config.lifecycleProtectedCategories
|
|
14072
|
-
}
|
|
14073
|
-
};
|
|
14074
|
-
const metricsPath = path3.join(
|
|
14075
|
-
storage.dir,
|
|
14076
|
-
"state",
|
|
14077
|
-
"lifecycle-metrics.json"
|
|
14078
|
-
);
|
|
14079
|
-
await mkdir2(path3.dirname(metricsPath), { recursive: true });
|
|
14080
|
-
await writeFile2(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
|
|
14081
|
-
return updatedCount;
|
|
14293
|
+
return this.lifecyclePolicyCoordinator.runLifecyclePolicyPass(allMemories, storage);
|
|
14082
14294
|
}
|
|
14083
|
-
/**
|
|
14084
|
-
* Archive old, low-importance, rarely-accessed facts (v6.0).
|
|
14085
|
-
* Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
|
|
14086
|
-
* Returns the number of archived facts.
|
|
14087
|
-
*/
|
|
14088
14295
|
async runFactArchival(allMemories) {
|
|
14089
|
-
|
|
14090
|
-
const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1e3;
|
|
14091
|
-
const protectedCategories = new Set(
|
|
14092
|
-
this.config.factArchivalProtectedCategories
|
|
14093
|
-
);
|
|
14094
|
-
let archivedCount = 0;
|
|
14095
|
-
for (const memory of allMemories) {
|
|
14096
|
-
const fm = memory.frontmatter;
|
|
14097
|
-
if (fm.status && fm.status !== "active") continue;
|
|
14098
|
-
if (protectedCategories.has(fm.category)) continue;
|
|
14099
|
-
if (fm.category === "correction") continue;
|
|
14100
|
-
const createdMs = new Date(fm.created).getTime();
|
|
14101
|
-
if (now - createdMs < ageCutoffMs) continue;
|
|
14102
|
-
const importanceScore = fm.importance?.score ?? 0.5;
|
|
14103
|
-
if (importanceScore >= this.config.factArchivalMaxImportance) continue;
|
|
14104
|
-
const accessCount = fm.accessCount ?? 0;
|
|
14105
|
-
if (accessCount > this.config.factArchivalMaxAccessCount) continue;
|
|
14106
|
-
const result = await this.storage.archiveMemory(memory);
|
|
14107
|
-
if (result) {
|
|
14108
|
-
await this.removeContentHashForMemory(
|
|
14109
|
-
this.storage,
|
|
14110
|
-
memory,
|
|
14111
|
-
"fact-archival"
|
|
14112
|
-
);
|
|
14113
|
-
await this.embeddingFallback.removeFromIndex(memory.frontmatter.id);
|
|
14114
|
-
if (resolveIndexingCapabilities(this.config).queryAwareIndexing && memory.path && memory.frontmatter?.created) {
|
|
14115
|
-
deindexMemory(
|
|
14116
|
-
this.config.memoryDir,
|
|
14117
|
-
memory.path,
|
|
14118
|
-
memory.frontmatter.created,
|
|
14119
|
-
memory.frontmatter.tags ?? []
|
|
14120
|
-
);
|
|
14121
|
-
}
|
|
14122
|
-
archivedCount++;
|
|
14123
|
-
}
|
|
14124
|
-
}
|
|
14125
|
-
if (archivedCount > 0) {
|
|
14126
|
-
await this.saveContentHashIndexes().catch(
|
|
14127
|
-
(err) => log.warn(`content-hash index save failed during archival: ${err}`)
|
|
14128
|
-
);
|
|
14129
|
-
}
|
|
14130
|
-
return archivedCount;
|
|
14296
|
+
return this.lifecyclePolicyCoordinator.runFactArchival(allMemories);
|
|
14131
14297
|
}
|
|
14132
|
-
/**
|
|
14133
|
-
* Run memory summarization if memory count exceeds threshold (Phase 4A).
|
|
14134
|
-
*/
|
|
14135
14298
|
async runSummarization(allMemories) {
|
|
14136
|
-
|
|
14137
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
14138
|
-
);
|
|
14139
|
-
if (activeMemories.length < this.config.summarizationTriggerCount) {
|
|
14140
|
-
return;
|
|
14141
|
-
}
|
|
14142
|
-
log.info(
|
|
14143
|
-
`memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) \u2014 running summarization`
|
|
14144
|
-
);
|
|
14145
|
-
const sorted = activeMemories.sort(
|
|
14146
|
-
(a, b) => new Date(a.frontmatter.created).getTime() - new Date(b.frontmatter.created).getTime()
|
|
14147
|
-
);
|
|
14148
|
-
const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
|
|
14149
|
-
const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
|
|
14150
|
-
const candidates = toSummarize.filter((m) => {
|
|
14151
|
-
if (m.frontmatter.entityRef) return false;
|
|
14152
|
-
const protectedTags = this.config.summarizationProtectedTags;
|
|
14153
|
-
if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
|
|
14154
|
-
return false;
|
|
14155
|
-
const importance = m.frontmatter.importance?.score ?? 0.5;
|
|
14156
|
-
if (importance >= this.config.summarizationImportanceThreshold)
|
|
14157
|
-
return false;
|
|
14158
|
-
return true;
|
|
14159
|
-
});
|
|
14160
|
-
if (candidates.length < 50) {
|
|
14161
|
-
log.debug(
|
|
14162
|
-
`only ${candidates.length} candidates for summarization \u2014 skipping`
|
|
14163
|
-
);
|
|
14164
|
-
return;
|
|
14165
|
-
}
|
|
14166
|
-
const batchSize = 50;
|
|
14167
|
-
for (let i = 0; i < candidates.length; i += batchSize) {
|
|
14168
|
-
const batch = candidates.slice(i, i + batchSize);
|
|
14169
|
-
const batchData = batch.map((m) => ({
|
|
14170
|
-
id: m.frontmatter.id,
|
|
14171
|
-
content: m.content,
|
|
14172
|
-
category: m.frontmatter.category,
|
|
14173
|
-
created: m.frontmatter.created
|
|
14174
|
-
}));
|
|
14175
|
-
const result = await this.extraction.summarizeMemories(batchData);
|
|
14176
|
-
if (!result) continue;
|
|
14177
|
-
const summary = {
|
|
14178
|
-
id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
14179
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
14180
|
-
timeRangeStart: batch[0].frontmatter.created,
|
|
14181
|
-
timeRangeEnd: batch[batch.length - 1].frontmatter.created,
|
|
14182
|
-
summaryText: result.summaryText,
|
|
14183
|
-
keyFacts: result.keyFacts,
|
|
14184
|
-
keyEntities: result.keyEntities,
|
|
14185
|
-
sourceEpisodeIds: batch.map((m) => m.frontmatter.id)
|
|
14186
|
-
};
|
|
14187
|
-
await this.storage.writeSummary(summary);
|
|
14188
|
-
const archived = await this.storage.archiveMemories(
|
|
14189
|
-
batch.map((m) => m.frontmatter.id),
|
|
14190
|
-
summary.id
|
|
14191
|
-
);
|
|
14192
|
-
log.info(
|
|
14193
|
-
`created summary ${summary.id} from ${batch.length} memories, archived ${archived}`
|
|
14194
|
-
);
|
|
14195
|
-
}
|
|
14299
|
+
return this.lifecyclePolicyCoordinator.runSummarization(allMemories);
|
|
14196
14300
|
}
|
|
14197
|
-
/**
|
|
14198
|
-
* Run topic extraction on all memories (Phase 4B).
|
|
14199
|
-
*/
|
|
14200
14301
|
async runTopicExtraction(allMemories) {
|
|
14201
|
-
|
|
14202
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status)
|
|
14203
|
-
);
|
|
14204
|
-
if (activeMemories.length === 0) return;
|
|
14205
|
-
const topics = extractTopics(
|
|
14206
|
-
activeMemories,
|
|
14207
|
-
this.config.topicExtractionTopN
|
|
14208
|
-
);
|
|
14209
|
-
await this.storage.saveTopics(topics);
|
|
14210
|
-
log.debug(
|
|
14211
|
-
`extracted ${topics.length} topics from ${activeMemories.length} memories`
|
|
14212
|
-
);
|
|
14302
|
+
return this.lifecyclePolicyCoordinator.runTopicExtraction(allMemories);
|
|
14213
14303
|
}
|
|
14214
14304
|
/** Threshold (bytes) at which IDENTITY.md reflections get auto-consolidated */
|
|
14215
14305
|
static IDENTITY_CONSOLIDATE_THRESHOLD = 8e3;
|
|
14216
14306
|
async autoConsolidateIdentity() {
|
|
14217
|
-
const namespaces = this.config.
|
|
14307
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces ? await this.maintenanceNamespaces() : [this.config.defaultNamespace];
|
|
14218
14308
|
for (const namespace of namespaces) {
|
|
14219
14309
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
14220
|
-
const identityNamespace = this.config.
|
|
14310
|
+
const identityNamespace = resolveNamespaceCapabilities(this.config).namespaces && namespace !== this.config.defaultNamespace ? namespace : void 0;
|
|
14221
14311
|
const reflectionsContent = await storage.readIdentityReflections() ?? "";
|
|
14222
14312
|
const existingIdentity = await storage.readIdentity(
|
|
14223
14313
|
this.config.workspaceDir,
|
|
@@ -14486,7 +14576,7 @@ ${lines.join("\n\n")}`;
|
|
|
14486
14576
|
return { text: `${content.slice(0, headroom)}${suffix}`, truncated: true };
|
|
14487
14577
|
}
|
|
14488
14578
|
async buildIdentityContinuitySection(options) {
|
|
14489
|
-
if (!this.config.
|
|
14579
|
+
if (!resolveIdentityContinuityCapabilities(this.config).identityContinuity) return null;
|
|
14490
14580
|
if (this.config.identityMaxInjectChars <= 0) return null;
|
|
14491
14581
|
const resolved = resolveEffectiveIdentityInjectionMode({
|
|
14492
14582
|
configuredMode: this.config.identityInjectionMode,
|
|
@@ -14557,7 +14647,7 @@ ${lines.join("\n\n")}`;
|
|
|
14557
14647
|
}
|
|
14558
14648
|
}
|
|
14559
14649
|
queueEvalShadowRecall(record) {
|
|
14560
|
-
if (!this.config.
|
|
14650
|
+
if (!resolveEvalCapabilities(this.config).evalHarness || !resolveEvalCapabilities(this.config).evalShadowMode)
|
|
14561
14651
|
return;
|
|
14562
14652
|
this.evalShadowWriteChain = this.evalShadowWriteChain.catch(() => void 0).then(async () => {
|
|
14563
14653
|
try {
|
|
@@ -14619,13 +14709,13 @@ ${lines.join("\n\n")}`;
|
|
|
14619
14709
|
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
14620
14710
|
const addStorage = (storage) => {
|
|
14621
14711
|
const storageDir = storageDirFor(storage);
|
|
14622
|
-
const storageKey = storageDir ?
|
|
14712
|
+
const storageKey = storageDir ? path4.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
14623
14713
|
if (seenStorageDirs.has(storageKey)) return;
|
|
14624
14714
|
seenStorageDirs.add(storageKey);
|
|
14625
14715
|
storages.push(storage);
|
|
14626
14716
|
};
|
|
14627
14717
|
const fallbackNamespace = fallbackStorageDir !== null ? this.storageDirNamespace(fallbackStorageDir) : this.config.defaultNamespace;
|
|
14628
|
-
if (recallNamespaces.length === 0 || !this.config.
|
|
14718
|
+
if (recallNamespaces.length === 0 || !resolveNamespaceCapabilities(this.config).namespaces || recallNamespaces.includes(fallbackNamespace)) {
|
|
14629
14719
|
addStorage(fallbackStorage);
|
|
14630
14720
|
}
|
|
14631
14721
|
if (recallNamespaces.length > 0) {
|
|
@@ -14649,7 +14739,7 @@ ${lines.join("\n\n")}`;
|
|
|
14649
14739
|
continue;
|
|
14650
14740
|
}
|
|
14651
14741
|
try {
|
|
14652
|
-
const coldRoot =
|
|
14742
|
+
const coldRoot = path4.join(storageDir, "cold");
|
|
14653
14743
|
for (const candidate of qmdResultPathCandidates(
|
|
14654
14744
|
coldRoot,
|
|
14655
14745
|
parts.relativePath
|
|
@@ -14690,7 +14780,7 @@ ${lines.join("\n\n")}`;
|
|
|
14690
14780
|
return null;
|
|
14691
14781
|
}
|
|
14692
14782
|
}
|
|
14693
|
-
if (
|
|
14783
|
+
if (path4.isAbsolute(resultPath)) {
|
|
14694
14784
|
if (!fallbackStorageDir) {
|
|
14695
14785
|
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
14696
14786
|
}
|
|
@@ -14729,14 +14819,14 @@ ${lines.join("\n\n")}`;
|
|
|
14729
14819
|
);
|
|
14730
14820
|
if (!memory) return null;
|
|
14731
14821
|
let ownerNamespace = null;
|
|
14732
|
-
if (
|
|
14822
|
+
if (path4.isAbsolute(memory.path)) {
|
|
14733
14823
|
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
14734
14824
|
memory.path,
|
|
14735
14825
|
fallbackStorage,
|
|
14736
14826
|
recallNamespaces
|
|
14737
14827
|
);
|
|
14738
14828
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
14739
|
-
if (!ownerNamespace && this.config.
|
|
14829
|
+
if (!ownerNamespace && resolveNamespaceCapabilities(this.config).namespaces) return null;
|
|
14740
14830
|
}
|
|
14741
14831
|
ownerNamespace ??= this.namespaceFromPath(memory.path);
|
|
14742
14832
|
if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {
|
|
@@ -14753,16 +14843,16 @@ ${lines.join("\n\n")}`;
|
|
|
14753
14843
|
};
|
|
14754
14844
|
}
|
|
14755
14845
|
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
14756
|
-
const resolvedPath =
|
|
14757
|
-
const memoryRoot =
|
|
14758
|
-
const namespacesRoot =
|
|
14846
|
+
const resolvedPath = path4.resolve(resultPath);
|
|
14847
|
+
const memoryRoot = path4.resolve(this.config.memoryDir);
|
|
14848
|
+
const namespacesRoot = path4.join(memoryRoot, "namespaces");
|
|
14759
14849
|
const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
|
|
14760
14850
|
const matches = [];
|
|
14761
14851
|
const seenDirs = /* @__PURE__ */ new Set();
|
|
14762
14852
|
const maybeAddStorage = (storage, namespace) => {
|
|
14763
14853
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
14764
14854
|
if (!storageDir) return;
|
|
14765
|
-
const candidateRoot =
|
|
14855
|
+
const candidateRoot = path4.resolve(storageDir);
|
|
14766
14856
|
if (seenDirs.has(candidateRoot)) return;
|
|
14767
14857
|
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
14768
14858
|
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
@@ -14780,7 +14870,7 @@ ${lines.join("\n\n")}`;
|
|
|
14780
14870
|
candidateNamespaces.add(ns);
|
|
14781
14871
|
}
|
|
14782
14872
|
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
14783
|
-
const relativeToNamespaces =
|
|
14873
|
+
const relativeToNamespaces = path4.relative(namespacesRoot, resolvedPath);
|
|
14784
14874
|
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
14785
14875
|
if (namespaceSegment) {
|
|
14786
14876
|
candidateNamespaces.add(
|
|
@@ -14825,7 +14915,7 @@ ${lines.join("\n\n")}`;
|
|
|
14825
14915
|
nsMap = buildMemoryWorthCounterMap(memories);
|
|
14826
14916
|
this.memoryWorthCounterCache.set(ns, { at: nowMs, counters: nsMap });
|
|
14827
14917
|
}
|
|
14828
|
-
for (const [
|
|
14918
|
+
for (const [path5, c] of nsMap) counters.set(path5, c);
|
|
14829
14919
|
} catch (err) {
|
|
14830
14920
|
log.debug("memory-worth: failed to read namespace, skipping", {
|
|
14831
14921
|
namespace: ns,
|
|
@@ -14908,7 +14998,7 @@ ${lines.join("\n\n")}`;
|
|
|
14908
14998
|
namespaces,
|
|
14909
14999
|
{
|
|
14910
15000
|
readNamespaceMemories: async (ns) => (await this.getStorage(ns)).readAllMemories(),
|
|
14911
|
-
readMemoryFrontmatter: async (
|
|
15001
|
+
readMemoryFrontmatter: async (path5) => {
|
|
14912
15002
|
if (!fallbackReader) {
|
|
14913
15003
|
for (const ns of namespaces) {
|
|
14914
15004
|
try {
|
|
@@ -14919,7 +15009,7 @@ ${lines.join("\n\n")}`;
|
|
|
14919
15009
|
}
|
|
14920
15010
|
}
|
|
14921
15011
|
if (!fallbackReader) return null;
|
|
14922
|
-
const memory = await this.readQmdResultMemory(
|
|
15012
|
+
const memory = await this.readQmdResultMemory(path5, fallbackReader, namespaces);
|
|
14923
15013
|
return memory ? memory.frontmatter : null;
|
|
14924
15014
|
}
|
|
14925
15015
|
},
|
|
@@ -15088,13 +15178,13 @@ ${lines.join("\n\n")}`;
|
|
|
15088
15178
|
* so facts from non-default namespaces can't cross-match.
|
|
15089
15179
|
*/
|
|
15090
15180
|
semanticDedupScopeFor(targetStorage) {
|
|
15091
|
-
if (!this.config.
|
|
15092
|
-
const memoryDir =
|
|
15093
|
-
const storageDir =
|
|
15181
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
|
|
15182
|
+
const memoryDir = path4.resolve(this.config.memoryDir);
|
|
15183
|
+
const storageDir = path4.resolve(targetStorage.dir);
|
|
15094
15184
|
if (storageDir === memoryDir) {
|
|
15095
15185
|
return { pathExcludePrefixes: ["namespaces/"] };
|
|
15096
15186
|
}
|
|
15097
|
-
let rel =
|
|
15187
|
+
let rel = path4.relative(memoryDir, storageDir);
|
|
15098
15188
|
if (!rel || rel.startsWith("..")) {
|
|
15099
15189
|
log.debug(
|
|
15100
15190
|
`semantic dedup: target storage dir ${storageDir} is outside memoryDir ${memoryDir}; scoping lookup to absolute path prefix`
|
|
@@ -15113,7 +15203,7 @@ ${lines.join("\n\n")}`;
|
|
|
15113
15203
|
if (hits.length === 0) return [];
|
|
15114
15204
|
const results = [];
|
|
15115
15205
|
for (const hit of hits) {
|
|
15116
|
-
const fullPath =
|
|
15206
|
+
const fullPath = path4.isAbsolute(hit.path) ? hit.path : path4.join(this.config.memoryDir, hit.path);
|
|
15117
15207
|
const memory = await this.storage.readMemoryByPath(fullPath);
|
|
15118
15208
|
if (!memory) continue;
|
|
15119
15209
|
results.push({
|
|
@@ -15221,7 +15311,7 @@ ${lines.join("\n\n")}`;
|
|
|
15221
15311
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
15222
15312
|
}
|
|
15223
15313
|
};
|
|
15224
|
-
const coldQmdEnabled = this.config.
|
|
15314
|
+
const coldQmdEnabled = resolveQmdCapabilities(this.config).qmdColdTier === true;
|
|
15225
15315
|
const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
15226
15316
|
const coldMaxResults = this.config.qmdColdMaxResults ?? this.config.qmdMaxResults;
|
|
15227
15317
|
let longTerm = [];
|
|
@@ -15256,7 +15346,7 @@ ${lines.join("\n\n")}`;
|
|
|
15256
15346
|
coldFetchLimit,
|
|
15257
15347
|
coldHybridLimit,
|
|
15258
15348
|
{
|
|
15259
|
-
namespacesEnabled: this.config.
|
|
15349
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
15260
15350
|
recallNamespaces: options.recallNamespaces,
|
|
15261
15351
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
15262
15352
|
collection: coldCollection,
|
|
@@ -15302,7 +15392,7 @@ ${lines.join("\n\n")}`;
|
|
|
15302
15392
|
}
|
|
15303
15393
|
if (longTerm.length === 0) return [];
|
|
15304
15394
|
let results = longTerm;
|
|
15305
|
-
if (this.config.
|
|
15395
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
15306
15396
|
const recallRoots = [];
|
|
15307
15397
|
const seenRecallRoots = /* @__PURE__ */ new Set();
|
|
15308
15398
|
for (const namespace of options.recallNamespaces) {
|
|
@@ -15310,7 +15400,7 @@ ${lines.join("\n\n")}`;
|
|
|
15310
15400
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
15311
15401
|
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
15312
15402
|
if (!storageDir) continue;
|
|
15313
|
-
const recallRoot =
|
|
15403
|
+
const recallRoot = path4.resolve(storageDir);
|
|
15314
15404
|
if (seenRecallRoots.has(recallRoot)) continue;
|
|
15315
15405
|
seenRecallRoots.add(recallRoot);
|
|
15316
15406
|
recallRoots.push(recallRoot);
|
|
@@ -15334,8 +15424,8 @@ ${lines.join("\n\n")}`;
|
|
|
15334
15424
|
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
15335
15425
|
continue;
|
|
15336
15426
|
}
|
|
15337
|
-
if (
|
|
15338
|
-
const resolvedPath =
|
|
15427
|
+
if (path4.isAbsolute(result.path)) {
|
|
15428
|
+
const resolvedPath = path4.resolve(result.path);
|
|
15339
15429
|
if (recallRoots.some(
|
|
15340
15430
|
(recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
|
|
15341
15431
|
)) {
|
|
@@ -15351,8 +15441,8 @@ ${lines.join("\n\n")}`;
|
|
|
15351
15441
|
}
|
|
15352
15442
|
results = results.filter((r) => !isArtifactMemoryPath(r.path));
|
|
15353
15443
|
if (results.length === 0) return [];
|
|
15354
|
-
const isFullModeGraphAssist = this.config.
|
|
15355
|
-
const shouldRunGraphExpansion = this.config.
|
|
15444
|
+
const isFullModeGraphAssist = resolveQmdCapabilities(this.config).qmdTierParityGraph && graphCaps.multiGraphMemory && caps.graphAssistInFullMode && options.recallMode === "full" && results.length >= Math.max(1, this.config.graphAssistMinSeedResults ?? 3);
|
|
15445
|
+
const shouldRunGraphExpansion = resolveQmdCapabilities(this.config).qmdTierParityGraph && (options.recallMode === "graph_mode" || isFullModeGraphAssist);
|
|
15356
15446
|
if (shouldRunGraphExpansion) {
|
|
15357
15447
|
const { merged } = await this.expandResultsViaGraph({
|
|
15358
15448
|
memoryResults: results,
|
|
@@ -15513,7 +15603,7 @@ ${lines.join("\n\n")}`;
|
|
|
15513
15603
|
async flushAccessTracking() {
|
|
15514
15604
|
if (this.accessTrackingBuffer.size === 0) return;
|
|
15515
15605
|
const entries = [];
|
|
15516
|
-
const namespaces = this.config.
|
|
15606
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces ? Array.from(
|
|
15517
15607
|
/* @__PURE__ */ new Set([
|
|
15518
15608
|
this.config.defaultNamespace,
|
|
15519
15609
|
this.config.sharedNamespace,
|
|
@@ -16169,7 +16259,7 @@ ${lines.join("\n\n")}`;
|
|
|
16169
16259
|
return resolved;
|
|
16170
16260
|
}
|
|
16171
16261
|
namespaceFromPath(p) {
|
|
16172
|
-
if (!this.config.
|
|
16262
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return this.config.defaultNamespace;
|
|
16173
16263
|
const parts = qmdCollectionPathParts(p);
|
|
16174
16264
|
const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
|
|
16175
16265
|
if (collectionNamespace) return collectionNamespace;
|
|
@@ -16270,4 +16360,4 @@ export {
|
|
|
16270
16360
|
resolvePersistedMemoryRelativePath,
|
|
16271
16361
|
Orchestrator
|
|
16272
16362
|
};
|
|
16273
|
-
//# sourceMappingURL=chunk-
|
|
16363
|
+
//# sourceMappingURL=chunk-FLCYY5JX.js.map
|