@remnic/core 9.3.733 → 9.3.734
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 +10 -10
- package/dist/access-boundary.js +9 -9
- package/dist/access-cli.js +25 -23
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +10 -10
- package/dist/access-http.js +14 -14
- package/dist/access-mcp.d.ts +10 -10
- package/dist/access-mcp.js +13 -13
- package/dist/access-operations-batch.js +11 -11
- package/dist/access-operations.d.ts +10 -10
- package/dist/access-operations.js +12 -12
- package/dist/{access-service-Byoe3HsT.d.ts → access-service-rjFfmfKB.d.ts} +4 -4
- package/dist/access-service.d.ts +10 -10
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +10 -10
- 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 +9 -9
- 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 +97 -2
- package/dist/capabilities.js +11 -3
- package/dist/{catalog-DM1nk7cM.d.ts → catalog-DHYXzM4-.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-24D66MMN.js → chunk-2L5RTVMO.js} +7 -4
- package/dist/chunk-2L5RTVMO.js.map +1 -0
- package/dist/{chunk-KQYGNGON.js → chunk-3QETM5NG.js} +6 -3
- package/dist/chunk-3QETM5NG.js.map +1 -0
- package/dist/{chunk-ZQUAVZNG.js → chunk-54RCE5Z3.js} +7 -4
- package/dist/chunk-54RCE5Z3.js.map +1 -0
- package/dist/{chunk-NOU77OHX.js → chunk-5DIKZKOD.js} +2 -2
- package/dist/{chunk-CGPHMNL4.js → chunk-5OYHJIJN.js} +10 -6
- package/dist/chunk-5OYHJIJN.js.map +1 -0
- package/dist/{chunk-LUCARK4W.js → chunk-6U7TES2M.js} +29 -28
- package/dist/chunk-6U7TES2M.js.map +1 -0
- package/dist/{chunk-FFUCCKPN.js → chunk-7FPJFCXL.js} +10 -7
- package/dist/chunk-7FPJFCXL.js.map +1 -0
- package/dist/{chunk-PMAQRUN4.js → chunk-CILX2XW7.js} +5 -2
- package/dist/chunk-CILX2XW7.js.map +1 -0
- package/dist/{chunk-ZVHRSR2R.js → chunk-ET5HXSQL.js} +6 -3
- package/dist/chunk-ET5HXSQL.js.map +1 -0
- package/dist/{chunk-KSJCXXOU.js → chunk-FAGERSH2.js} +6 -3
- package/dist/chunk-FAGERSH2.js.map +1 -0
- package/dist/{chunk-FYWUNVFZ.js → chunk-IDIXGGDN.js} +6 -6
- package/dist/{chunk-CX77GNMB.js → chunk-IWMGBNXY.js} +6 -3
- package/dist/chunk-IWMGBNXY.js.map +1 -0
- package/dist/{chunk-GGL34GCW.js → chunk-IZLTOS5L.js} +7 -4
- package/dist/chunk-IZLTOS5L.js.map +1 -0
- package/dist/{chunk-HHNSLPX7.js → chunk-K7PAILHO.js} +10 -9
- package/dist/chunk-K7PAILHO.js.map +1 -0
- package/dist/{chunk-UZYLX7M6.js → chunk-LV32K4OP.js} +9 -6
- package/dist/chunk-LV32K4OP.js.map +1 -0
- package/dist/{chunk-HJWQJUKQ.js → chunk-NDYQIN6C.js} +3 -3
- package/dist/{chunk-DKT3X5C3.js → chunk-PEF2XOIV.js} +7 -4
- package/dist/chunk-PEF2XOIV.js.map +1 -0
- package/dist/{chunk-646B5ERJ.js → chunk-PKO5NJ65.js} +51 -48
- package/dist/chunk-PKO5NJ65.js.map +1 -0
- package/dist/{chunk-QZHF4BWN.js → chunk-Q5LGXWNG.js} +6 -6
- package/dist/{chunk-ESF7TRYJ.js → chunk-SHJGBAIW.js} +37 -2
- package/dist/{chunk-ESF7TRYJ.js.map → chunk-SHJGBAIW.js.map} +1 -1
- package/dist/{chunk-O4ZIBPIW.js → chunk-T7CGPTFU.js} +3 -3
- package/dist/{chunk-PLBIPT6I.js → chunk-TJSQHO4Q.js} +7 -4
- package/dist/chunk-TJSQHO4Q.js.map +1 -0
- package/dist/{chunk-6TUWSUUD.js → chunk-UF3N7IRP.js} +26 -24
- package/dist/chunk-UF3N7IRP.js.map +1 -0
- package/dist/{chunk-P3VJCTVE.js → chunk-UH3NYOHN.js} +4 -3
- package/dist/chunk-UH3NYOHN.js.map +1 -0
- package/dist/{chunk-J6BH2OBA.js → chunk-UK6U5C3N.js} +8 -5
- package/dist/chunk-UK6U5C3N.js.map +1 -0
- package/dist/{chunk-OTQE66IX.js → chunk-V5OVSGB6.js} +6 -3
- package/dist/chunk-V5OVSGB6.js.map +1 -0
- package/dist/{chunk-H3MB3F62.js → chunk-WHQ2JB35.js} +4 -3
- package/dist/chunk-WHQ2JB35.js.map +1 -0
- package/dist/{chunk-NIZQH6AU.js → chunk-WTTVFSCO.js} +8 -7
- package/dist/chunk-WTTVFSCO.js.map +1 -0
- package/dist/{chunk-OUITHS6V.js → chunk-Z7J3OAPR.js} +357 -325
- package/dist/chunk-Z7J3OAPR.js.map +1 -0
- package/dist/{cli-Dt-tuiYH.d.ts → cli-XVpmSoQs.d.ts} +3 -3
- package/dist/cli.d.ts +11 -11
- 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-OUHMCUBT.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 +9 -9
- 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-W4U6XDKI.js} +7 -6
- package/dist/first-start-migration-W4U6XDKI.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 +43 -43
- 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 +10 -10
- 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/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -5
- package/dist/{orchestrator-B4KjaOtY.d.ts → orchestrator-BXi-gadS.d.ts} +66 -5
- package/dist/orchestrator.d.ts +5 -5
- package/dist/orchestrator.js +20 -18
- 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 +22 -22
- 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-DeL5grLx.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -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-LSM35HZY.js} +5 -2
- package/dist/tier-stats-LSM35HZY.js.map +1 -0
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/types.d.ts +12 -12
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-VkxElCHR.d.ts → types-CpFz51Pv.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 +42 -37
- package/src/active-memory-bridge.ts +2 -1
- package/src/admin/admin-surfaces.ts +2 -1
- package/src/capabilities.test.ts +178 -0
- package/src/capabilities.ts +197 -0
- package/src/cli.ts +13 -9
- 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 +6 -3
- package/src/maintenance/namespace-maintenance-fanout.ts +2 -1
- package/src/maintenance/namespace-planner.ts +4 -3
- package/src/maintenance/tier-stats.ts +2 -1
- 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 +19 -18
- 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 +78 -417
- 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-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-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-NOU77OHX.js.map → chunk-5DIKZKOD.js.map} +0 -0
- /package/dist/{chunk-FYWUNVFZ.js.map → chunk-IDIXGGDN.js.map} +0 -0
- /package/dist/{chunk-HJWQJUKQ.js.map → chunk-NDYQIN6C.js.map} +0 -0
- /package/dist/{chunk-QZHF4BWN.js.map → chunk-Q5LGXWNG.js.map} +0 -0
- /package/dist/{chunk-O4ZIBPIW.js.map → chunk-T7CGPTFU.js.map} +0 -0
- /package/dist/{contradiction-scan-HWGEOUDS.js.map → contradiction-scan-OUHMCUBT.js.map} +0 -0
package/src/orchestrator.ts
CHANGED
|
@@ -101,6 +101,7 @@ import { MaintenanceScheduler } from "./orchestration/maintenance.js";
|
|
|
101
101
|
import { TierMigrationCoordinator } from "./orchestration/tier-migration-coordinator.js";
|
|
102
102
|
import { ExtractionQueueCoordinator } from "./orchestration/extraction-queue-coordinator.js";
|
|
103
103
|
import { CompressionGuidelineCoordinator } from "./orchestration/compression-guideline-coordinator.js";
|
|
104
|
+
import { SemanticConsolidationCoordinator } from "./orchestration/semantic-consolidation-coordinator.js";
|
|
104
105
|
import {
|
|
105
106
|
runLiveConnectorsOnce,
|
|
106
107
|
type LiveConnectorsRunSummary,
|
|
@@ -266,6 +267,7 @@ import {
|
|
|
266
267
|
} from "./trust-zones.js";
|
|
267
268
|
import { tryDirectAnswer, type DirectAnswerSources } from "./direct-answer-wiring.js";
|
|
268
269
|
import {
|
|
270
|
+
resolveNamespaceCapabilities,
|
|
269
271
|
resolveCapabilities,
|
|
270
272
|
resolveGraphConstructionCapabilities,
|
|
271
273
|
resolveMemoryLifecycleCapabilities,
|
|
@@ -276,6 +278,9 @@ import {
|
|
|
276
278
|
type MemoryLifecycleCapabilitySet,
|
|
277
279
|
type IndexingCapabilitySet,
|
|
278
280
|
type CreationMemoryCapabilitySet,
|
|
281
|
+
resolveQmdCapabilities,
|
|
282
|
+
resolveIdentityContinuityCapabilities,
|
|
283
|
+
resolveLocalLlmCapabilities,
|
|
279
284
|
} from "./capabilities.js";
|
|
280
285
|
import { DEFAULT_TAXONOMY } from "./taxonomy/index.js";
|
|
281
286
|
import {
|
|
@@ -1896,6 +1901,7 @@ export class Orchestrator {
|
|
|
1896
1901
|
readonly tierMigrationStatus: TierMigrationStatusStore;
|
|
1897
1902
|
readonly tierMigrationCoordinator: TierMigrationCoordinator;
|
|
1898
1903
|
readonly compressionGuidelineCoordinator: CompressionGuidelineCoordinator;
|
|
1904
|
+
readonly semanticConsolidationCoordinator: SemanticConsolidationCoordinator;
|
|
1899
1905
|
/**
|
|
1900
1906
|
* In-memory X-ray snapshot from the most recent `recall()` call that
|
|
1901
1907
|
* was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
|
|
@@ -2251,7 +2257,7 @@ export class Orchestrator {
|
|
|
2251
2257
|
* @internal
|
|
2252
2258
|
*/
|
|
2253
2259
|
applyCodingNamespaceOverlay(sessionKey: string | undefined, baseNamespace: string): string {
|
|
2254
|
-
if (!this.config.
|
|
2260
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return baseNamespace;
|
|
2255
2261
|
const codingContext = this.getCodingContextForSession(sessionKey);
|
|
2256
2262
|
const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);
|
|
2257
2263
|
if (!overlay) return baseNamespace;
|
|
@@ -2331,7 +2337,7 @@ export class Orchestrator {
|
|
|
2331
2337
|
* @internal
|
|
2332
2338
|
*/
|
|
2333
2339
|
applyCodingRecallOverlay(sessionKey: string | undefined): { namespace: string; readFallbacks: string[] } | null {
|
|
2334
|
-
if (!this.config.
|
|
2340
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return null;
|
|
2335
2341
|
const codingContext = this.getCodingContextForSession(sessionKey);
|
|
2336
2342
|
const overlay = resolveCodingNamespaceOverlay(codingContext, this.config.codingMode, this.config.defaultNamespace);
|
|
2337
2343
|
if (!overlay) return null;
|
|
@@ -2354,7 +2360,7 @@ export class Orchestrator {
|
|
|
2354
2360
|
}
|
|
2355
2361
|
|
|
2356
2362
|
private rememberNamespaceStorageDirHint(namespace: string, storageDir?: string): void {
|
|
2357
|
-
if (!this.config.
|
|
2363
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces || !storageDir) return;
|
|
2358
2364
|
const ns = normalizeNamespaceIdentity(namespace);
|
|
2359
2365
|
if (!ns) return;
|
|
2360
2366
|
const defaultNs = normalizeNamespaceIdentity(this.config.defaultNamespace);
|
|
@@ -2558,10 +2564,10 @@ export class Orchestrator {
|
|
|
2558
2564
|
private buildConfiguredQmdSearchOptions(
|
|
2559
2565
|
queryText: string,
|
|
2560
2566
|
): SearchQueryOptions | undefined {
|
|
2561
|
-
const intentHint = this.config.
|
|
2567
|
+
const intentHint = resolveQmdCapabilities(this.config).qmdIntentHints
|
|
2562
2568
|
? buildQmdIntentHint(inferIntentFromText(queryText))
|
|
2563
2569
|
: undefined;
|
|
2564
|
-
const explain = this.config.
|
|
2570
|
+
const explain = resolveQmdCapabilities(this.config).qmdExplain === true;
|
|
2565
2571
|
const searchOptions: SearchQueryOptions = {};
|
|
2566
2572
|
if (intentHint) {
|
|
2567
2573
|
searchOptions.intent = intentHint;
|
|
@@ -2581,13 +2587,13 @@ export class Orchestrator {
|
|
|
2581
2587
|
execution?: SearchExecutionOptions;
|
|
2582
2588
|
}): Promise<QmdSearchResult[]> {
|
|
2583
2589
|
if (
|
|
2584
|
-
this.config.
|
|
2590
|
+
resolveNamespaceCapabilities(this.config).namespaces &&
|
|
2585
2591
|
options.namespaces !== undefined &&
|
|
2586
2592
|
options.namespaces.length === 0
|
|
2587
2593
|
) {
|
|
2588
2594
|
return [];
|
|
2589
2595
|
}
|
|
2590
|
-
const namespaces = this.config.
|
|
2596
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
2591
2597
|
? Array.from(
|
|
2592
2598
|
new Set(
|
|
2593
2599
|
(options.namespaces?.length
|
|
@@ -2600,7 +2606,7 @@ export class Orchestrator {
|
|
|
2600
2606
|
)
|
|
2601
2607
|
: [this.config.defaultNamespace];
|
|
2602
2608
|
|
|
2603
|
-
if (!this.config.
|
|
2609
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
2604
2610
|
switch (options.mode) {
|
|
2605
2611
|
case "hybrid":
|
|
2606
2612
|
return await this.qmd.hybridSearch(
|
|
@@ -2652,7 +2658,7 @@ export class Orchestrator {
|
|
|
2652
2658
|
}
|
|
2653
2659
|
|
|
2654
2660
|
private isSearchAvailableForNamespaceRouting(): boolean {
|
|
2655
|
-
if (this.config.
|
|
2661
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) return true;
|
|
2656
2662
|
return this.qmd.isAvailable();
|
|
2657
2663
|
}
|
|
2658
2664
|
|
|
@@ -3019,6 +3025,7 @@ export class Orchestrator {
|
|
|
3019
3025
|
fastChatCompletion: (messages, options) =>
|
|
3020
3026
|
this.fastChatCompletion(messages, options),
|
|
3021
3027
|
});
|
|
3028
|
+
|
|
3022
3029
|
this.sessionObserver = new SessionObserverState({
|
|
3023
3030
|
memoryDir: config.memoryDir,
|
|
3024
3031
|
debounceMs: config.sessionObserverDebounceMs ?? 120_000,
|
|
@@ -3061,6 +3068,15 @@ export class Orchestrator {
|
|
|
3061
3068
|
return client;
|
|
3062
3069
|
})()
|
|
3063
3070
|
: this.localLlm;
|
|
3071
|
+
this.semanticConsolidationCoordinator = new SemanticConsolidationCoordinator({
|
|
3072
|
+
config,
|
|
3073
|
+
getStorage: () => this.storage,
|
|
3074
|
+
getFastLlm: () => this.fastLlm,
|
|
3075
|
+
embeddingFallback: this.embeddingFallback,
|
|
3076
|
+
removeContentHashForMemory: (targetStorage, memory, context) =>
|
|
3077
|
+
this.removeContentHashForMemory(targetStorage, memory, context),
|
|
3078
|
+
saveContentHashIndexes: () => this.saveContentHashIndexes(),
|
|
3079
|
+
});
|
|
3064
3080
|
// Initialize gateway fast LLM for fast-tier ops when modelSource is "gateway"
|
|
3065
3081
|
this._fastGatewayLlm = config.modelSource === "gateway"
|
|
3066
3082
|
? new FallbackLlmClient(
|
|
@@ -3224,7 +3240,7 @@ export class Orchestrator {
|
|
|
3224
3240
|
}
|
|
3225
3241
|
|
|
3226
3242
|
private routeEngineOptions(): RoutingEngineOptions {
|
|
3227
|
-
const allowedNamespaces = this.config.
|
|
3243
|
+
const allowedNamespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
3228
3244
|
? Array.from(
|
|
3229
3245
|
new Set([
|
|
3230
3246
|
this.config.defaultNamespace,
|
|
@@ -3418,7 +3434,7 @@ export class Orchestrator {
|
|
|
3418
3434
|
? this._fastGatewayLlm?.isAvailable(
|
|
3419
3435
|
this.config.fastGatewayAgentId || this.config.gatewayAgentId || undefined,
|
|
3420
3436
|
) === true
|
|
3421
|
-
: this.config.
|
|
3437
|
+
: resolveLocalLlmCapabilities(this.config).localLlm;
|
|
3422
3438
|
if (!chainAvailable) return undefined;
|
|
3423
3439
|
return buildChainFollowupGenerator(this.fastLlmForRerank);
|
|
3424
3440
|
}
|
|
@@ -3440,7 +3456,7 @@ export class Orchestrator {
|
|
|
3440
3456
|
});
|
|
3441
3457
|
await this.storage.ensureDirectories();
|
|
3442
3458
|
await this.storage.loadAliases();
|
|
3443
|
-
if (this.config.
|
|
3459
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
3444
3460
|
const namespaces = new Set<string>([
|
|
3445
3461
|
this.config.defaultNamespace,
|
|
3446
3462
|
this.config.sharedNamespace,
|
|
@@ -3560,14 +3576,14 @@ export class Orchestrator {
|
|
|
3560
3576
|
// after a restart. `registerConfiguredNamespaces()` already seeded the
|
|
3561
3577
|
// catalog above, so `maintenanceNamespaces()` is readable here; it falls
|
|
3562
3578
|
// back to the configured set on any catalog read failure.
|
|
3563
|
-
const namespaces = this.config.
|
|
3579
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
3564
3580
|
? await this.maintenanceNamespaces()
|
|
3565
3581
|
: [this.config.defaultNamespace];
|
|
3566
3582
|
const states = await Promise.all(
|
|
3567
3583
|
namespaces.map(async (namespace) => {
|
|
3568
3584
|
const collectionCheckAbort = new AbortController();
|
|
3569
3585
|
const state = await qmdStartupCollectionCheckWithTimeout(
|
|
3570
|
-
this.config.
|
|
3586
|
+
resolveNamespaceCapabilities(this.config).namespaces
|
|
3571
3587
|
? this.namespaceSearchRouter.ensureNamespaceCollection(
|
|
3572
3588
|
namespace,
|
|
3573
3589
|
{ signal: collectionCheckAbort.signal },
|
|
@@ -3681,10 +3697,10 @@ export class Orchestrator {
|
|
|
3681
3697
|
// triggered update — which can be days ago if the daemon restarted without
|
|
3682
3698
|
// new extractions. This is the root cause of "0 memories" recall results
|
|
3683
3699
|
// despite thousands of facts on disk.
|
|
3684
|
-
if (this.qmd.isAvailable() && this.config.
|
|
3700
|
+
if (this.qmd.isAvailable() && resolveQmdCapabilities(this.config).qmdMaintenance) {
|
|
3685
3701
|
try {
|
|
3686
3702
|
log.info("QMD startup sync: updating index to match current disk state");
|
|
3687
|
-
if (this.config.
|
|
3703
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
3688
3704
|
// Cover cataloged dynamic namespaces at startup too (NHZEV, codex P2):
|
|
3689
3705
|
// a dynamic namespace written before a daemon restart must be synced on
|
|
3690
3706
|
// boot, not only by the debounced runQmdMaintenance() path. Same union +
|
|
@@ -3788,7 +3804,7 @@ export class Orchestrator {
|
|
|
3788
3804
|
|
|
3789
3805
|
if (signal.aborted) return;
|
|
3790
3806
|
|
|
3791
|
-
if (this.config.
|
|
3807
|
+
if (resolveLocalLlmCapabilities(this.config).localLlm) {
|
|
3792
3808
|
try {
|
|
3793
3809
|
await this.validateLocalLlmModel();
|
|
3794
3810
|
} catch (err) {
|
|
@@ -3813,7 +3829,7 @@ export class Orchestrator {
|
|
|
3813
3829
|
// sweep (capped at 50 demotions) so the hot tier isn't flooded on the
|
|
3814
3830
|
// first real cron pass. Non-fatal — a failure here must not break init.
|
|
3815
3831
|
if (signal.aborted) return;
|
|
3816
|
-
if (lifecycleCaps.lifecyclePolicy && this.config.
|
|
3832
|
+
if (lifecycleCaps.lifecyclePolicy && resolveQmdCapabilities(this.config).qmdTierMigration) {
|
|
3817
3833
|
try {
|
|
3818
3834
|
const { runFirstStartMigration } = await import(
|
|
3819
3835
|
"./maintenance/first-start-migration.js"
|
|
@@ -3918,7 +3934,7 @@ export class Orchestrator {
|
|
|
3918
3934
|
log.info(`startupSearchSync: backend now available ${this.qmd.debugStatus()}`);
|
|
3919
3935
|
|
|
3920
3936
|
// Clear namespace router cache so re-probe picks up newly available backends
|
|
3921
|
-
if (this.config.
|
|
3937
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
3922
3938
|
this.namespaceSearchRouter.clearCache();
|
|
3923
3939
|
}
|
|
3924
3940
|
|
|
@@ -3930,14 +3946,14 @@ export class Orchestrator {
|
|
|
3930
3946
|
// re-synced here too, otherwise after a backend-was-unavailable-at-boot
|
|
3931
3947
|
// recovery its collection stays stale. Falls back to the configured set on any
|
|
3932
3948
|
// catalog read failure.
|
|
3933
|
-
const namespaces = this.config.
|
|
3949
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
3934
3950
|
? await this.maintenanceNamespaces()
|
|
3935
3951
|
: [this.config.defaultNamespace];
|
|
3936
3952
|
|
|
3937
3953
|
const states = await Promise.all(
|
|
3938
3954
|
namespaces.map(async (namespace) => ({
|
|
3939
3955
|
namespace,
|
|
3940
|
-
state: this.config.
|
|
3956
|
+
state: resolveNamespaceCapabilities(this.config).namespaces
|
|
3941
3957
|
? await this.namespaceSearchRouter.ensureNamespaceCollection(namespace, { signal })
|
|
3942
3958
|
: await this.qmd.ensureCollection(this.config.memoryDir, this.config.qmdCollection, { signal }),
|
|
3943
3959
|
})),
|
|
@@ -3972,7 +3988,7 @@ export class Orchestrator {
|
|
|
3972
3988
|
// and didn't fail silently.
|
|
3973
3989
|
// The abort signal is forwarded into the QMD subprocess call so the
|
|
3974
3990
|
// long-running `qmd update` process is killed promptly on shutdown.
|
|
3975
|
-
if (this.config.
|
|
3991
|
+
if (resolveQmdCapabilities(this.config).qmdMaintenance) {
|
|
3976
3992
|
try {
|
|
3977
3993
|
const failTsBefore = "lastUpdateFailedAtMs" in this.qmd
|
|
3978
3994
|
? (this.qmd as any).lastUpdateFailedAtMs as number | null
|
|
@@ -3983,7 +3999,7 @@ export class Orchestrator {
|
|
|
3983
3999
|
}
|
|
3984
4000
|
log.info("startupSearchSync: updating index to match current disk state");
|
|
3985
4001
|
let namespacesUpdated = 0;
|
|
3986
|
-
if (this.config.
|
|
4002
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
3987
4003
|
namespacesUpdated = await this.namespaceSearchRouter.updateNamespaces(
|
|
3988
4004
|
namespaces,
|
|
3989
4005
|
{ signal },
|
|
@@ -4005,7 +4021,7 @@ export class Orchestrator {
|
|
|
4005
4021
|
log.warn("startupSearchSync: update silently failed (detected via fail timestamp)");
|
|
4006
4022
|
return false;
|
|
4007
4023
|
}
|
|
4008
|
-
if (this.config.
|
|
4024
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
4009
4025
|
if (namespacesUpdated === 0) {
|
|
4010
4026
|
log.warn("startupSearchSync: no namespace backends were eligible for update (all unavailable or collections missing)");
|
|
4011
4027
|
return false;
|
|
@@ -4374,372 +4390,17 @@ export class Orchestrator {
|
|
|
4374
4390
|
return summarizeGovernanceResultForDreams(govResult, options?.dryRun === true);
|
|
4375
4391
|
}
|
|
4376
4392
|
|
|
4393
|
+
// Issue #1526 (seam 5): semantic consolidation moved to
|
|
4394
|
+
// SemanticConsolidationCoordinator. Thin delegation keeps all
|
|
4395
|
+
// call sites (runConsolidation, runSemanticConsolidationNow,
|
|
4396
|
+
// runSemanticConsolidationFanout) stable.
|
|
4377
4397
|
private async runSemanticConsolidation(options?: {
|
|
4378
4398
|
dryRun?: boolean;
|
|
4379
4399
|
thresholdOverride?: number;
|
|
4380
4400
|
force?: boolean;
|
|
4381
4401
|
storage?: StorageManager;
|
|
4382
4402
|
}): Promise<SemanticConsolidationResult> {
|
|
4383
|
-
|
|
4384
|
-
const result: SemanticConsolidationResult = {
|
|
4385
|
-
clustersFound: 0,
|
|
4386
|
-
memoriesConsolidated: 0,
|
|
4387
|
-
memoriesArchived: 0,
|
|
4388
|
-
errors: 0,
|
|
4389
|
-
clusters: [],
|
|
4390
|
-
};
|
|
4391
|
-
|
|
4392
|
-
if (!this.config.semanticConsolidationEnabled && !options?.force) {
|
|
4393
|
-
log.debug("[semantic-consolidation] disabled in config");
|
|
4394
|
-
return result;
|
|
4395
|
-
}
|
|
4396
|
-
|
|
4397
|
-
log.info("[semantic-consolidation] starting run");
|
|
4398
|
-
|
|
4399
|
-
const allMemories = await targetStorage.readAllMemories();
|
|
4400
|
-
if (allMemories.length < 10) {
|
|
4401
|
-
log.debug("[semantic-consolidation] too few memories, skipping");
|
|
4402
|
-
return result;
|
|
4403
|
-
}
|
|
4404
|
-
|
|
4405
|
-
const threshold =
|
|
4406
|
-
options?.thresholdOverride ?? this.config.semanticConsolidationThreshold;
|
|
4407
|
-
const clusters = findSimilarClusters(allMemories, {
|
|
4408
|
-
threshold,
|
|
4409
|
-
minClusterSize: this.config.semanticConsolidationMinClusterSize,
|
|
4410
|
-
excludeCategories: this.config.semanticConsolidationExcludeCategories,
|
|
4411
|
-
maxPerRun: this.config.semanticConsolidationMaxPerRun,
|
|
4412
|
-
});
|
|
4413
|
-
|
|
4414
|
-
result.clustersFound = clusters.length;
|
|
4415
|
-
result.clusters = clusters;
|
|
4416
|
-
|
|
4417
|
-
if (clusters.length === 0) {
|
|
4418
|
-
log.info("[semantic-consolidation] no clusters found");
|
|
4419
|
-
return result;
|
|
4420
|
-
}
|
|
4421
|
-
|
|
4422
|
-
log.info(`[semantic-consolidation] found ${clusters.length} cluster(s)`);
|
|
4423
|
-
|
|
4424
|
-
if (options?.dryRun) {
|
|
4425
|
-
log.info(
|
|
4426
|
-
"[semantic-consolidation] dry run — skipping LLM synthesis and archival",
|
|
4427
|
-
);
|
|
4428
|
-
return result;
|
|
4429
|
-
}
|
|
4430
|
-
|
|
4431
|
-
// Use FallbackLlmClient for LLM calls (same pattern as causal-consolidation.ts)
|
|
4432
|
-
// Honor semanticConsolidationModel: "auto" = primary, "fast" = local fast, or specific model
|
|
4433
|
-
const { FallbackLlmClient, gatewayTaskChainOptions } = await import("./fallback-llm.js");
|
|
4434
|
-
const useGateway = this.config.modelSource === "gateway";
|
|
4435
|
-
const modelSetting = this.config.semanticConsolidationModel;
|
|
4436
|
-
if (modelSetting === "fast" && this.fastLlm && !useGateway) {
|
|
4437
|
-
log.info("[semantic-consolidation] using fast local LLM for synthesis");
|
|
4438
|
-
}
|
|
4439
|
-
// Gateway routing: an explicit "fast" setting keeps the fast persona chain
|
|
4440
|
-
// (the operator's deliberate fast-tier choice). Otherwise route through the
|
|
4441
|
-
// shared task-chain resolution so taskModelChain applies to semantic
|
|
4442
|
-
// consolidation like every other background task (gotcha #22). Issue #1365.
|
|
4443
|
-
const gatewayChainOptions: { modelChain?: AgentPersonaModelConfig; agentId?: string } =
|
|
4444
|
-
!useGateway
|
|
4445
|
-
? {}
|
|
4446
|
-
: modelSetting === "fast"
|
|
4447
|
-
? (this.config.fastGatewayAgentId
|
|
4448
|
-
? { agentId: this.config.fastGatewayAgentId }
|
|
4449
|
-
: this.config.gatewayAgentId
|
|
4450
|
-
? { agentId: this.config.gatewayAgentId }
|
|
4451
|
-
: {})
|
|
4452
|
-
: gatewayTaskChainOptions(this.config);
|
|
4453
|
-
const llm = new FallbackLlmClient(
|
|
4454
|
-
this.config.gatewayConfig,
|
|
4455
|
-
fallbackLlmRuntimeContextFromConfig(this.config),
|
|
4456
|
-
);
|
|
4457
|
-
if (!llm.isAvailable(gatewayChainOptions) && !(modelSetting === "fast" && this.fastLlm && !useGateway)) {
|
|
4458
|
-
log.warn(
|
|
4459
|
-
"[semantic-consolidation] no LLM available — skipping synthesis",
|
|
4460
|
-
);
|
|
4461
|
-
return result;
|
|
4462
|
-
}
|
|
4463
|
-
|
|
4464
|
-
// Discover memory extensions once for all clusters (#382)
|
|
4465
|
-
let extensionsBlock = "";
|
|
4466
|
-
try {
|
|
4467
|
-
extensionsBlock = await buildExtensionsBlockForConsolidation(this.config);
|
|
4468
|
-
} catch (err) {
|
|
4469
|
-
log.warn(`[semantic-consolidation] extension discovery failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
|
|
4470
|
-
}
|
|
4471
|
-
|
|
4472
|
-
for (const cluster of clusters) {
|
|
4473
|
-
let canonicalWriteCompleted = false;
|
|
4474
|
-
try {
|
|
4475
|
-
// Operator-aware prompt (issue #561 PR 3): ask the LLM to pick the
|
|
4476
|
-
// SPLIT/MERGE/UPDATE operator alongside the canonical output. Falls
|
|
4477
|
-
// back to the legacy plain-blob prompt when operator-aware
|
|
4478
|
-
// consolidation is explicitly disabled via config, so rollbacks stay
|
|
4479
|
-
// clean.
|
|
4480
|
-
// Use the `=== true` idiom for default-false flags (PR #632
|
|
4481
|
-
// review, cursor Low): sibling disabled-by-default flags like
|
|
4482
|
-
// `semanticConsolidationEnabled` follow the same convention,
|
|
4483
|
-
// while `!== false` is reserved for default-on flags.
|
|
4484
|
-
const operatorAwareEnabled =
|
|
4485
|
-
this.config.operatorAwareConsolidationEnabled === true;
|
|
4486
|
-
let prompt = operatorAwareEnabled
|
|
4487
|
-
? buildOperatorAwareConsolidationPrompt(cluster)
|
|
4488
|
-
: buildConsolidationPrompt(cluster);
|
|
4489
|
-
if (extensionsBlock.length > 0) {
|
|
4490
|
-
prompt += "\n\n" + extensionsBlock;
|
|
4491
|
-
}
|
|
4492
|
-
const messages = [
|
|
4493
|
-
{
|
|
4494
|
-
role: "system" as const,
|
|
4495
|
-
content: operatorAwareEnabled
|
|
4496
|
-
? '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" — never a pipe-separated placeholder, never prose. The "output" value is the canonical memory text.'
|
|
4497
|
-
: "You are a memory consolidation system. Output only the consolidated memory text.",
|
|
4498
|
-
},
|
|
4499
|
-
{ role: "user" as const, content: prompt },
|
|
4500
|
-
];
|
|
4501
|
-
const llmOpts = { temperature: 0.2, maxTokens: 2000 };
|
|
4502
|
-
|
|
4503
|
-
// Route to the configured model
|
|
4504
|
-
let response: { content: string } | null = null;
|
|
4505
|
-
if (useGateway) {
|
|
4506
|
-
// Gateway model source — use the appropriate agent chain
|
|
4507
|
-
response = await llm.chatCompletion(messages, { ...llmOpts, ...gatewayChainOptions });
|
|
4508
|
-
} else if (modelSetting === "fast" && this.fastLlm) {
|
|
4509
|
-
const fastResult = await this.fastLlm.chatCompletion(messages, {
|
|
4510
|
-
operation: "semantic-consolidation",
|
|
4511
|
-
maxTokens: llmOpts.maxTokens,
|
|
4512
|
-
temperature: llmOpts.temperature,
|
|
4513
|
-
priority: "background",
|
|
4514
|
-
forceDisableThinking: true,
|
|
4515
|
-
});
|
|
4516
|
-
response = fastResult ? { content: fastResult.content } : null;
|
|
4517
|
-
} else {
|
|
4518
|
-
response = await llm.chatCompletion(messages, llmOpts);
|
|
4519
|
-
}
|
|
4520
|
-
|
|
4521
|
-
if (!response?.content) {
|
|
4522
|
-
log.warn(
|
|
4523
|
-
`[semantic-consolidation] empty LLM response for cluster in "${cluster.category}"`,
|
|
4524
|
-
);
|
|
4525
|
-
result.errors++;
|
|
4526
|
-
continue;
|
|
4527
|
-
}
|
|
4528
|
-
|
|
4529
|
-
// Operator-aware parse (issue #561 PR 3). In legacy mode we fall
|
|
4530
|
-
// back to the plain-text parser and derive the operator from the
|
|
4531
|
-
// cluster-shape heuristic so `derived_via` still lands.
|
|
4532
|
-
// Restricted to `SemanticConsolidationLlmOperator`
|
|
4533
|
-
// (split/merge/update) — `pattern-reinforcement` joined the
|
|
4534
|
-
// wider `ConsolidationOperator` type in #687 PR 2/4 but is
|
|
4535
|
-
// reserved for the maintenance job and must never be assignable
|
|
4536
|
-
// here (Cursor Bugbot review, PR #730).
|
|
4537
|
-
let canonicalContent: string;
|
|
4538
|
-
let operator: SemanticConsolidationLlmOperator;
|
|
4539
|
-
if (operatorAwareEnabled) {
|
|
4540
|
-
const parsed = parseOperatorAwareConsolidationResponse(
|
|
4541
|
-
response.content,
|
|
4542
|
-
cluster,
|
|
4543
|
-
);
|
|
4544
|
-
canonicalContent = parsed.output;
|
|
4545
|
-
operator = parsed.operator;
|
|
4546
|
-
} else {
|
|
4547
|
-
canonicalContent = parseConsolidationResponse(response.content);
|
|
4548
|
-
operator = chooseConsolidationOperator(cluster);
|
|
4549
|
-
}
|
|
4550
|
-
cluster.canonicalContent = canonicalContent;
|
|
4551
|
-
|
|
4552
|
-
// Pick the most recent memory's metadata as the basis for lineage
|
|
4553
|
-
const sorted = [...cluster.memories].sort(
|
|
4554
|
-
(a, b) =>
|
|
4555
|
-
new Date(b.frontmatter.created).getTime() -
|
|
4556
|
-
new Date(a.frontmatter.created).getTime(),
|
|
4557
|
-
);
|
|
4558
|
-
const newest = sorted[0];
|
|
4559
|
-
const lineageIds = cluster.memories.map((m) => m.frontmatter.id);
|
|
4560
|
-
|
|
4561
|
-
// Consolidation provenance (issue #561 PR 2+3): snapshot each
|
|
4562
|
-
// source memory BEFORE archiving it, collecting
|
|
4563
|
-
// "<relpath>:<versionId>" pointers for the new canonical memory's
|
|
4564
|
-
// `derived_from` frontmatter field. Snapshots are best-effort — if
|
|
4565
|
-
// page-versioning is disabled (default in `config.ts`) or a single
|
|
4566
|
-
// source fails to snapshot we simply omit that entry rather than
|
|
4567
|
-
// abort the consolidation. The `derived_via` operator is chosen
|
|
4568
|
-
// above (PR 3) from the LLM response or the cluster-shape
|
|
4569
|
-
// heuristic fallback and emitted unconditionally so consolidation
|
|
4570
|
-
// outputs stay identifiable even when no snapshots are captured
|
|
4571
|
-
// (PR #624 review feedback).
|
|
4572
|
-
const derivedFromEntries: string[] = [];
|
|
4573
|
-
for (const m of cluster.memories) {
|
|
4574
|
-
if (!m.path) continue;
|
|
4575
|
-
const entry = await targetStorage.snapshotForProvenance(m.path);
|
|
4576
|
-
if (entry) derivedFromEntries.push(entry);
|
|
4577
|
-
}
|
|
4578
|
-
|
|
4579
|
-
// Write the canonical memory
|
|
4580
|
-
const { id: canonicalId, tombstoneBlocked: canonicalBlocked } = await targetStorage.writeMemory(
|
|
4581
|
-
newest.frontmatter.category,
|
|
4582
|
-
canonicalContent,
|
|
4583
|
-
{
|
|
4584
|
-
actor: "semantic-consolidation",
|
|
4585
|
-
confidence: newest.frontmatter.confidence,
|
|
4586
|
-
tags: [
|
|
4587
|
-
...new Set(
|
|
4588
|
-
cluster.memories.flatMap((m) => m.frontmatter.tags ?? []),
|
|
4589
|
-
),
|
|
4590
|
-
],
|
|
4591
|
-
source: "semantic-consolidation",
|
|
4592
|
-
lineage: lineageIds,
|
|
4593
|
-
derivedFrom: derivedFromEntries.length > 0 ? derivedFromEntries : undefined,
|
|
4594
|
-
derivedVia: operator,
|
|
4595
|
-
},
|
|
4596
|
-
);
|
|
4597
|
-
if (canonicalBlocked) {
|
|
4598
|
-
// #1645: canonical matched a tombstone (pending_review). Don't archive
|
|
4599
|
-
// the sources — consolidation must never delete the only active copy.
|
|
4600
|
-
log.info(`[semantic-consolidation] cluster in "${cluster.category}" tombstone-blocked — keeping ${cluster.memories.length} source(s) active (pending_review ${canonicalId})`);
|
|
4601
|
-
continue;
|
|
4602
|
-
}
|
|
4603
|
-
canonicalWriteCompleted = true;
|
|
4604
|
-
|
|
4605
|
-
result.memoriesConsolidated++;
|
|
4606
|
-
|
|
4607
|
-
// Archive originals
|
|
4608
|
-
for (const m of cluster.memories) {
|
|
4609
|
-
const archiveResult = await targetStorage.archiveMemory(m, {
|
|
4610
|
-
actor: "semantic-consolidation",
|
|
4611
|
-
reasonCode: "semantic-consolidation",
|
|
4612
|
-
relatedMemoryIds: [canonicalId],
|
|
4613
|
-
});
|
|
4614
|
-
if (archiveResult) {
|
|
4615
|
-
// Remove from the same storage-scoped content-hash index that
|
|
4616
|
-
// originally deduped this memory.
|
|
4617
|
-
await this.removeContentHashForMemory(
|
|
4618
|
-
targetStorage,
|
|
4619
|
-
m,
|
|
4620
|
-
"semantic-consolidation",
|
|
4621
|
-
);
|
|
4622
|
-
// Best-effort index cleanup: a failure here (e.g. on-disk index save
|
|
4623
|
-
// under disk-full) must NOT abort the archival loop and thereby skip
|
|
4624
|
-
// the catalog write touch below for an already-durable canonical write
|
|
4625
|
-
// (kilo NV0mh).
|
|
4626
|
-
try {
|
|
4627
|
-
await this.embeddingFallback.removeFromIndex(m.frontmatter.id);
|
|
4628
|
-
if (
|
|
4629
|
-
resolveIndexingCapabilities(this.config).queryAwareIndexing &&
|
|
4630
|
-
m.path &&
|
|
4631
|
-
m.frontmatter?.created
|
|
4632
|
-
) {
|
|
4633
|
-
deindexMemory(
|
|
4634
|
-
targetStorage.dir,
|
|
4635
|
-
m.path,
|
|
4636
|
-
m.frontmatter.created,
|
|
4637
|
-
m.frontmatter.tags ?? [],
|
|
4638
|
-
);
|
|
4639
|
-
}
|
|
4640
|
-
} catch (cleanupErr) {
|
|
4641
|
-
log.warn(
|
|
4642
|
-
`[semantic-consolidation] index cleanup failed (non-fatal): ${cleanupErr}`,
|
|
4643
|
-
);
|
|
4644
|
-
}
|
|
4645
|
-
result.memoriesArchived++;
|
|
4646
|
-
}
|
|
4647
|
-
}
|
|
4648
|
-
|
|
4649
|
-
log.info(
|
|
4650
|
-
`[semantic-consolidation] consolidated ${cluster.memories.length} memories → ${canonicalId}`,
|
|
4651
|
-
);
|
|
4652
|
-
} catch (err) {
|
|
4653
|
-
log.warn(
|
|
4654
|
-
`[semantic-consolidation] cluster processing failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
4655
|
-
);
|
|
4656
|
-
result.errors++;
|
|
4657
|
-
} finally {
|
|
4658
|
-
if (canonicalWriteCompleted) {
|
|
4659
|
-
// Catalog write touch (issue #1499 sweep): record after the canonical
|
|
4660
|
-
// write and, on the happy path, after archival of superseded cluster
|
|
4661
|
-
// memories, so `lastWriteAt` reflects every durable mutation in this
|
|
4662
|
-
// consolidation (cursor NUtCK). The `finally` also covers partial
|
|
4663
|
-
// failures where the canonical memory was written but a later archive
|
|
4664
|
-
// step throws and the cluster catch continues (codex NY-dK).
|
|
4665
|
-
// Best-effort; namespace decoded from the storage dir since this path
|
|
4666
|
-
// #1522: catalog touch handled at the storage chokepoint.
|
|
4667
|
-
}
|
|
4668
|
-
}
|
|
4669
|
-
}
|
|
4670
|
-
|
|
4671
|
-
// Save hash indexes if we modified them.
|
|
4672
|
-
if (result.memoriesArchived > 0) {
|
|
4673
|
-
await this.saveContentHashIndexes().catch((err) =>
|
|
4674
|
-
log.warn(
|
|
4675
|
-
`[semantic-consolidation] content-hash index save failed: ${err}`,
|
|
4676
|
-
),
|
|
4677
|
-
);
|
|
4678
|
-
}
|
|
4679
|
-
|
|
4680
|
-
log.info(
|
|
4681
|
-
`[semantic-consolidation] complete: clusters=${result.clustersFound}, consolidated=${result.memoriesConsolidated}, archived=${result.memoriesArchived}, errors=${result.errors}`,
|
|
4682
|
-
);
|
|
4683
|
-
|
|
4684
|
-
// #378: fire the Codex materialize post-hook so `codexMaterializeOnConsolidation`
|
|
4685
|
-
// actually has a runtime effect. The helper silently no-ops when the
|
|
4686
|
-
// feature flag or the per-trigger toggle is off, when the sentinel is
|
|
4687
|
-
// missing, or when nothing has changed since the previous run, so it's
|
|
4688
|
-
// safe to always call here. Wrapped in a try/catch because a failed
|
|
4689
|
-
// materialize must never abort the consolidation result — consolidation
|
|
4690
|
-
// is the load-bearing operation; materialization is an optional mirror.
|
|
4691
|
-
try {
|
|
4692
|
-
await materializeAfterSemanticConsolidation({
|
|
4693
|
-
config: this.config,
|
|
4694
|
-
memoryDir: targetStorage.dir,
|
|
4695
|
-
});
|
|
4696
|
-
} catch (err) {
|
|
4697
|
-
log.warn(
|
|
4698
|
-
`[semantic-consolidation] Codex materialize post-hook failed (non-fatal): ${
|
|
4699
|
-
err instanceof Error ? err.message : String(err)
|
|
4700
|
-
}`,
|
|
4701
|
-
);
|
|
4702
|
-
}
|
|
4703
|
-
|
|
4704
|
-
// Issue #679 PR 2/5 — async peer profile reasoner runs as part of
|
|
4705
|
-
// the REM phase, immediately after semantic consolidation. Gated
|
|
4706
|
-
// on `peerProfileReasonerEnabled` (default false, opt-in). Wrapped
|
|
4707
|
-
// in a try/catch because reasoner I/O (LLM call, peer-profile
|
|
4708
|
-
// writes) must never abort the consolidation result. The reasoner
|
|
4709
|
-
// itself also defends against partial failure — see profile-reasoner.ts.
|
|
4710
|
-
if (this.config.peerProfileReasonerEnabled) {
|
|
4711
|
-
try {
|
|
4712
|
-
const { runPeerProfileReasoner } = await import("./peers/index.js");
|
|
4713
|
-
const llm = new FallbackLlmClient(
|
|
4714
|
-
this.config.gatewayConfig,
|
|
4715
|
-
fallbackLlmRuntimeContextFromConfig(this.config),
|
|
4716
|
-
);
|
|
4717
|
-
const peerResult = await runPeerProfileReasoner({
|
|
4718
|
-
memoryDir: targetStorage.dir,
|
|
4719
|
-
enabled: true,
|
|
4720
|
-
llm,
|
|
4721
|
-
model: this.config.peerProfileReasonerModel,
|
|
4722
|
-
minInteractions: this.config.peerProfileReasonerMinInteractions,
|
|
4723
|
-
maxFieldsPerRun: this.config.peerProfileReasonerMaxFieldsPerRun,
|
|
4724
|
-
log: {
|
|
4725
|
-
debug: (msg) => log.debug(msg),
|
|
4726
|
-
info: (msg) => log.info(msg),
|
|
4727
|
-
warn: (msg) => log.warn(msg),
|
|
4728
|
-
},
|
|
4729
|
-
});
|
|
4730
|
-
log.info(
|
|
4731
|
-
`[peer-profile-reasoner] complete: peers=${peerResult.peersConsidered}, processed=${peerResult.peersProcessed}, fields=${peerResult.fieldsApplied}`,
|
|
4732
|
-
);
|
|
4733
|
-
} catch (err) {
|
|
4734
|
-
log.warn(
|
|
4735
|
-
`[peer-profile-reasoner] post-consolidation hook failed (non-fatal): ${
|
|
4736
|
-
err instanceof Error ? err.message : String(err)
|
|
4737
|
-
}`,
|
|
4738
|
-
);
|
|
4739
|
-
}
|
|
4740
|
-
}
|
|
4741
|
-
|
|
4742
|
-
return result;
|
|
4403
|
+
return this.semanticConsolidationCoordinator.runSemanticConsolidation(options);
|
|
4743
4404
|
}
|
|
4744
4405
|
|
|
4745
4406
|
async waitForExtractionIdle(timeoutMs: number = 60_000): Promise<boolean> {
|
|
@@ -5950,7 +5611,7 @@ export class Orchestrator {
|
|
|
5950
5611
|
options.principalOverride.length > 0
|
|
5951
5612
|
? options.principalOverride
|
|
5952
5613
|
: resolvePrincipal(sessionKey, this.config);
|
|
5953
|
-
const namespacesEnabled = this.config.
|
|
5614
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
5954
5615
|
if (namespacesEnabled && !principal) {
|
|
5955
5616
|
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
5956
5617
|
}
|
|
@@ -6419,7 +6080,7 @@ export class Orchestrator {
|
|
|
6419
6080
|
for (const memoryPath of paths) {
|
|
6420
6081
|
if (!memoryPath || isArtifactMemoryPath(memoryPath)) continue;
|
|
6421
6082
|
if (
|
|
6422
|
-
this.config.
|
|
6083
|
+
resolveNamespaceCapabilities(this.config).namespaces &&
|
|
6423
6084
|
!recallNamespaces.includes(this.namespaceFromPath(memoryPath))
|
|
6424
6085
|
) {
|
|
6425
6086
|
continue;
|
|
@@ -6536,7 +6197,7 @@ export class Orchestrator {
|
|
|
6536
6197
|
const memories = (
|
|
6537
6198
|
await Promise.all(
|
|
6538
6199
|
Array.from(candidatePaths).map(async (memoryPath) => {
|
|
6539
|
-
const namespace = this.config.
|
|
6200
|
+
const namespace = resolveNamespaceCapabilities(this.config).namespaces
|
|
6540
6201
|
? this.namespaceFromPath(memoryPath)
|
|
6541
6202
|
: this.config.defaultNamespace;
|
|
6542
6203
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
@@ -7160,7 +6821,7 @@ export class Orchestrator {
|
|
|
7160
6821
|
private async resolveStateDirForNamespace(
|
|
7161
6822
|
namespace: string,
|
|
7162
6823
|
): Promise<string> {
|
|
7163
|
-
if (!this.config.
|
|
6824
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) {
|
|
7164
6825
|
return path.join(this.config.memoryDir, "state");
|
|
7165
6826
|
}
|
|
7166
6827
|
if (namespace !== this.config.defaultNamespace) {
|
|
@@ -7480,7 +7141,7 @@ export class Orchestrator {
|
|
|
7480
7141
|
}
|
|
7481
7142
|
const timings: Record<string, string> = {};
|
|
7482
7143
|
const profileTraceId = this.profiler.startTrace("recall", sessionKey, {
|
|
7483
|
-
qmdEnabled: this.config.
|
|
7144
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
7484
7145
|
rerankEnabled: caps.rerank,
|
|
7485
7146
|
parallelRetrieval: caps.parallelRetrieval,
|
|
7486
7147
|
});
|
|
@@ -7753,7 +7414,7 @@ export class Orchestrator {
|
|
|
7753
7414
|
&& options.principalOverride.length > 0
|
|
7754
7415
|
? options.principalOverride
|
|
7755
7416
|
: resolvePrincipal(sessionKey, this.config);
|
|
7756
|
-
const namespacesEnabled = this.config.
|
|
7417
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
7757
7418
|
if (namespacesEnabled && !principal) {
|
|
7758
7419
|
throw new Error("authentication required: namespaces are enabled and no principal was supplied");
|
|
7759
7420
|
}
|
|
@@ -7998,7 +7659,7 @@ export class Orchestrator {
|
|
|
7998
7659
|
retrievalQueryLength: retrievalQuery.length,
|
|
7999
7660
|
recallMode,
|
|
8000
7661
|
recallResultLimit,
|
|
8001
|
-
qmdEnabled: this.config.
|
|
7662
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
8002
7663
|
qmdAvailable: this.qmd.isAvailable(),
|
|
8003
7664
|
recallNamespaces: [],
|
|
8004
7665
|
source: recallSource,
|
|
@@ -8404,7 +8065,7 @@ export class Orchestrator {
|
|
|
8404
8065
|
if (
|
|
8405
8066
|
!this.isRecallSectionEnabled(
|
|
8406
8067
|
"identity-continuity",
|
|
8407
|
-
this.config.
|
|
8068
|
+
resolveIdentityContinuityCapabilities(this.config).identityContinuity === true,
|
|
8408
8069
|
)
|
|
8409
8070
|
)
|
|
8410
8071
|
return null;
|
|
@@ -8679,17 +8340,17 @@ export class Orchestrator {
|
|
|
8679
8340
|
|
|
8680
8341
|
const objectiveStateSearches = await Promise.all(
|
|
8681
8342
|
recallNamespaces.map(async (namespace) => {
|
|
8682
|
-
const storage = this.config.
|
|
8343
|
+
const storage = resolveNamespaceCapabilities(this.config).namespaces
|
|
8683
8344
|
? await this.getStorage(namespace)
|
|
8684
8345
|
: null;
|
|
8685
8346
|
return searchObjectiveStateSnapshots({
|
|
8686
|
-
memoryDir: this.config.
|
|
8347
|
+
memoryDir: resolveNamespaceCapabilities(this.config).namespaces
|
|
8687
8348
|
? storage!.dir
|
|
8688
8349
|
: this.config.memoryDir,
|
|
8689
8350
|
objectiveStateStoreDir: objectiveStateStoreOverrideForNamespace({
|
|
8690
8351
|
memoryDir: this.config.memoryDir,
|
|
8691
8352
|
configuredStoreDir: this.config.objectiveStateStoreDir,
|
|
8692
|
-
namespacesEnabled: this.config.
|
|
8353
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
8693
8354
|
namespace,
|
|
8694
8355
|
}),
|
|
8695
8356
|
query: retrievalQuery,
|
|
@@ -9593,7 +9254,7 @@ export class Orchestrator {
|
|
|
9593
9254
|
qmdFetchLimit,
|
|
9594
9255
|
qmdHybridFetchLimit,
|
|
9595
9256
|
{
|
|
9596
|
-
namespacesEnabled: this.config.
|
|
9257
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
9597
9258
|
recallNamespaces,
|
|
9598
9259
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
9599
9260
|
queryAwarePrefilter,
|
|
@@ -10011,7 +9672,7 @@ export class Orchestrator {
|
|
|
10011
9672
|
workspaceDir: this.config.workspaceDir,
|
|
10012
9673
|
memoryDir: this.config.memoryDir,
|
|
10013
9674
|
config: this.config.nativeKnowledge,
|
|
10014
|
-
recallNamespaces: this.config.
|
|
9675
|
+
recallNamespaces: resolveNamespaceCapabilities(this.config).namespaces
|
|
10015
9676
|
? recallNamespaces
|
|
10016
9677
|
: undefined,
|
|
10017
9678
|
defaultNamespace: this.config.defaultNamespace,
|
|
@@ -11085,7 +10746,7 @@ export class Orchestrator {
|
|
|
11085
10746
|
let memoryResults = memoryResultsRaw;
|
|
11086
10747
|
|
|
11087
10748
|
// Enforce namespace read policies by filtering paths.
|
|
11088
|
-
if (this.config.
|
|
10749
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
11089
10750
|
memoryResults = memoryResults.filter((r) =>
|
|
11090
10751
|
recallNamespaces.includes(this.namespaceFromPath(r.path)),
|
|
11091
10752
|
);
|
|
@@ -11459,7 +11120,7 @@ export class Orchestrator {
|
|
|
11459
11120
|
const scopedCandidates = filterRecallCandidates(
|
|
11460
11121
|
prefilteredEmbeddingResults,
|
|
11461
11122
|
{
|
|
11462
|
-
namespacesEnabled: this.config.
|
|
11123
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
11463
11124
|
recallNamespaces,
|
|
11464
11125
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
11465
11126
|
limit: embeddingFetchLimit,
|
|
@@ -11638,7 +11299,7 @@ export class Orchestrator {
|
|
|
11638
11299
|
const scopedCandidates = filterRecallCandidates(
|
|
11639
11300
|
prefilteredEmbeddingResults,
|
|
11640
11301
|
{
|
|
11641
|
-
namespacesEnabled: this.config.
|
|
11302
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
11642
11303
|
recallNamespaces,
|
|
11643
11304
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
11644
11305
|
limit: embeddingFetchLimit,
|
|
@@ -12476,7 +12137,7 @@ export class Orchestrator {
|
|
|
12476
12137
|
retrievalQueryLength: retrievalQuery.length,
|
|
12477
12138
|
recallMode,
|
|
12478
12139
|
recallResultLimit,
|
|
12479
|
-
qmdEnabled: this.config.
|
|
12140
|
+
qmdEnabled: resolveQmdCapabilities(this.config).qmd,
|
|
12480
12141
|
qmdAvailable: this.qmd.isAvailable(),
|
|
12481
12142
|
recallNamespaces,
|
|
12482
12143
|
source: recallSource,
|
|
@@ -14193,7 +13854,7 @@ export class Orchestrator {
|
|
|
14193
13854
|
// #1713: hoist namespaces-enabled once for the scope-routing mirrors
|
|
14194
13855
|
// (pre-judge + write-loop) so no new scattered config.*Enabled read is
|
|
14195
13856
|
// introduced (ratchet scatteredConfigFlagReads; see #1523).
|
|
14196
|
-
const namespacesEnabled = this.config.
|
|
13857
|
+
const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces;
|
|
14197
13858
|
const profileAutoPromotionAllows = (
|
|
14198
13859
|
category: string,
|
|
14199
13860
|
confidence: number,
|
|
@@ -14235,7 +13896,7 @@ export class Orchestrator {
|
|
|
14235
13896
|
confidence: number,
|
|
14236
13897
|
): boolean => {
|
|
14237
13898
|
if (
|
|
14238
|
-
!this.config.
|
|
13899
|
+
!resolveNamespaceCapabilities(this.config).namespaces ||
|
|
14239
13900
|
!profileAllowsSharedWrites ||
|
|
14240
13901
|
!sharedAutoPromotionAllows(category, confidence)
|
|
14241
13902
|
)
|
|
@@ -16769,7 +16430,7 @@ export class Orchestrator {
|
|
|
16769
16430
|
// On full rebuild with namespaces enabled, span all configured namespaces so
|
|
16770
16431
|
// memories written to other namespaces before the index existed are also captured.
|
|
16771
16432
|
const allMemories =
|
|
16772
|
-
needsFullRebuild && this.config.
|
|
16433
|
+
needsFullRebuild && resolveNamespaceCapabilities(this.config).namespaces
|
|
16773
16434
|
? await this.readAllMemoriesForNamespaces(
|
|
16774
16435
|
Array.from(
|
|
16775
16436
|
new Set<string>([
|
|
@@ -17782,14 +17443,14 @@ export class Orchestrator {
|
|
|
17782
17443
|
// namespace that accumulated IDENTITY.md reflections must also be eligible for
|
|
17783
17444
|
// auto-consolidation, otherwise its identity file grows unbounded and is never
|
|
17784
17445
|
// consolidated. Falls back to the configured set on any catalog read failure.
|
|
17785
|
-
const namespaces = this.config.
|
|
17446
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
17786
17447
|
? await this.maintenanceNamespaces()
|
|
17787
17448
|
: [this.config.defaultNamespace];
|
|
17788
17449
|
|
|
17789
17450
|
for (const namespace of namespaces) {
|
|
17790
17451
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
17791
17452
|
const identityNamespace =
|
|
17792
|
-
this.config.
|
|
17453
|
+
resolveNamespaceCapabilities(this.config).namespaces &&
|
|
17793
17454
|
namespace !== this.config.defaultNamespace
|
|
17794
17455
|
? namespace
|
|
17795
17456
|
: undefined;
|
|
@@ -18138,7 +17799,7 @@ export class Orchestrator {
|
|
|
18138
17799
|
injectedChars: number;
|
|
18139
17800
|
truncated: boolean;
|
|
18140
17801
|
} | null> {
|
|
18141
|
-
if (!this.config.
|
|
17802
|
+
if (!resolveIdentityContinuityCapabilities(this.config).identityContinuity) return null;
|
|
18142
17803
|
if (this.config.identityMaxInjectChars <= 0) return null;
|
|
18143
17804
|
|
|
18144
17805
|
const resolved = resolveEffectiveIdentityInjectionMode({
|
|
@@ -18344,7 +18005,7 @@ export class Orchestrator {
|
|
|
18344
18005
|
: this.config.defaultNamespace;
|
|
18345
18006
|
if (
|
|
18346
18007
|
recallNamespaces.length === 0 ||
|
|
18347
|
-
!this.config.
|
|
18008
|
+
!resolveNamespaceCapabilities(this.config).namespaces ||
|
|
18348
18009
|
recallNamespaces.includes(fallbackNamespace)
|
|
18349
18010
|
) {
|
|
18350
18011
|
addStorage(fallbackStorage);
|
|
@@ -18471,7 +18132,7 @@ export class Orchestrator {
|
|
|
18471
18132
|
recallNamespaces,
|
|
18472
18133
|
);
|
|
18473
18134
|
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
18474
|
-
if (!ownerNamespace && this.config.
|
|
18135
|
+
if (!ownerNamespace && resolveNamespaceCapabilities(this.config).namespaces) return null;
|
|
18475
18136
|
}
|
|
18476
18137
|
ownerNamespace ??= this.namespaceFromPath(memory.path);
|
|
18477
18138
|
if (
|
|
@@ -19030,7 +18691,7 @@ export class Orchestrator {
|
|
|
19030
18691
|
pathPrefix?: string;
|
|
19031
18692
|
pathExcludePrefixes?: readonly string[];
|
|
19032
18693
|
} {
|
|
19033
|
-
if (!this.config.
|
|
18694
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return {};
|
|
19034
18695
|
const memoryDir = path.resolve(this.config.memoryDir);
|
|
19035
18696
|
const storageDir = path.resolve(targetStorage.dir);
|
|
19036
18697
|
if (storageDir === memoryDir) {
|
|
@@ -19267,7 +18928,7 @@ export class Orchestrator {
|
|
|
19267
18928
|
}
|
|
19268
18929
|
};
|
|
19269
18930
|
|
|
19270
|
-
const coldQmdEnabled = this.config.
|
|
18931
|
+
const coldQmdEnabled = resolveQmdCapabilities(this.config).qmdColdTier === true;
|
|
19271
18932
|
const coldCollection =
|
|
19272
18933
|
this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
19273
18934
|
const coldMaxResults =
|
|
@@ -19312,7 +18973,7 @@ export class Orchestrator {
|
|
|
19312
18973
|
coldFetchLimit,
|
|
19313
18974
|
coldHybridLimit,
|
|
19314
18975
|
{
|
|
19315
|
-
namespacesEnabled: this.config.
|
|
18976
|
+
namespacesEnabled: resolveNamespaceCapabilities(this.config).namespaces,
|
|
19316
18977
|
recallNamespaces: options.recallNamespaces,
|
|
19317
18978
|
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
19318
18979
|
collection: coldCollection,
|
|
@@ -19359,7 +19020,7 @@ export class Orchestrator {
|
|
|
19359
19020
|
if (longTerm.length === 0) return [];
|
|
19360
19021
|
|
|
19361
19022
|
let results = longTerm;
|
|
19362
|
-
if (this.config.
|
|
19023
|
+
if (resolveNamespaceCapabilities(this.config).namespaces) {
|
|
19363
19024
|
const recallRoots: string[] = [];
|
|
19364
19025
|
const seenRecallRoots = new Set<string>();
|
|
19365
19026
|
for (const namespace of options.recallNamespaces) {
|
|
@@ -19417,13 +19078,13 @@ export class Orchestrator {
|
|
|
19417
19078
|
if (results.length === 0) return [];
|
|
19418
19079
|
|
|
19419
19080
|
const isFullModeGraphAssist =
|
|
19420
|
-
this.config.
|
|
19081
|
+
resolveQmdCapabilities(this.config).qmdTierParityGraph &&
|
|
19421
19082
|
graphCaps.multiGraphMemory &&
|
|
19422
19083
|
caps.graphAssistInFullMode &&
|
|
19423
19084
|
options.recallMode === "full" &&
|
|
19424
19085
|
results.length >= Math.max(1, this.config.graphAssistMinSeedResults ?? 3);
|
|
19425
19086
|
const shouldRunGraphExpansion =
|
|
19426
|
-
this.config.
|
|
19087
|
+
resolveQmdCapabilities(this.config).qmdTierParityGraph &&
|
|
19427
19088
|
(options.recallMode === "graph_mode" || isFullModeGraphAssist);
|
|
19428
19089
|
|
|
19429
19090
|
if (shouldRunGraphExpansion) {
|
|
@@ -19620,7 +19281,7 @@ export class Orchestrator {
|
|
|
19620
19281
|
|
|
19621
19282
|
// Build entries from buffer, merging with existing counts
|
|
19622
19283
|
const entries: AccessTrackingEntry[] = [];
|
|
19623
|
-
const namespaces = this.config.
|
|
19284
|
+
const namespaces = resolveNamespaceCapabilities(this.config).namespaces
|
|
19624
19285
|
? Array.from(
|
|
19625
19286
|
new Set<string>([
|
|
19626
19287
|
this.config.defaultNamespace,
|
|
@@ -20580,7 +20241,7 @@ export class Orchestrator {
|
|
|
20580
20241
|
}
|
|
20581
20242
|
|
|
20582
20243
|
private namespaceFromPath(p: string): string {
|
|
20583
|
-
if (!this.config.
|
|
20244
|
+
if (!resolveNamespaceCapabilities(this.config).namespaces) return this.config.defaultNamespace;
|
|
20584
20245
|
const parts = qmdCollectionPathParts(p);
|
|
20585
20246
|
const collectionNamespace = parts
|
|
20586
20247
|
? this.qmdCollectionNamespaceFromPrefix(parts.collection)
|