@remnic/core 9.3.637 → 9.3.639
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-cli.js +29 -29
- package/dist/access-http.d.ts +56 -5
- package/dist/access-http.js +15 -13
- package/dist/access-mcp.d.ts +4 -4
- package/dist/access-mcp.js +14 -12
- package/dist/access-schema.d.ts +3 -0
- package/dist/access-schema.js +1 -1
- package/dist/{access-service-GVOE5U3C.d.ts → access-service-jyYute38.d.ts} +4 -2
- package/dist/access-service.d.ts +4 -4
- package/dist/access-service.js +12 -10
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/{auto-sync-RFADEHIQ.js → auto-sync-54QQHOG5.js} +4 -4
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +3 -3
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +3 -3
- 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/calibration.js +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-behavior.js +2 -2
- package/dist/causal-chain.js +2 -2
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +7 -7
- package/dist/causal-retrieval.js +2 -2
- package/dist/causal-trajectory-graph.js +1 -1
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-TFICNXXU.js → chunk-2BHNQRE5.js} +1153 -294
- package/dist/chunk-2BHNQRE5.js.map +1 -0
- package/dist/{chunk-3RDYU3JS.js → chunk-3AZDLWDW.js} +3 -3
- package/dist/{chunk-FPNQF475.js → chunk-3F7RMHC4.js} +1 -1
- package/dist/chunk-3F7RMHC4.js.map +1 -0
- package/dist/{chunk-3EJ5OOZ3.js → chunk-3SF7QNKF.js} +3 -3
- package/dist/{chunk-NFNQ7TWF.js → chunk-4VTVCWVB.js} +20 -12
- package/dist/chunk-4VTVCWVB.js.map +1 -0
- package/dist/{chunk-XM6M6DHG.js → chunk-52XI77OQ.js} +204 -13
- package/dist/chunk-52XI77OQ.js.map +1 -0
- package/dist/{chunk-6BDVBBBY.js → chunk-666A3MOW.js} +88 -30
- package/dist/chunk-666A3MOW.js.map +1 -0
- package/dist/{chunk-242XFZ36.js → chunk-7OH7KPF5.js} +2 -2
- package/dist/{chunk-HZVIYZYN.js → chunk-7R37SOT4.js} +6 -6
- package/dist/{chunk-7A2QKUUA.js → chunk-7XRSLMUD.js} +2 -2
- package/dist/{chunk-723OMPUI.js → chunk-A3BS64GV.js} +7 -1
- package/dist/chunk-A3BS64GV.js.map +1 -0
- package/dist/{chunk-JCLECECB.js → chunk-A3UPMOJZ.js} +2 -2
- package/dist/{chunk-YCX45GOQ.js → chunk-AFH2JXSF.js} +2 -2
- package/dist/{chunk-BK35NOJL.js → chunk-BB6FNMMB.js} +52 -6
- package/dist/chunk-BB6FNMMB.js.map +1 -0
- package/dist/{chunk-3XNMN242.js → chunk-BTY5XQG3.js} +7 -7
- package/dist/{chunk-QHXW3LZV.js → chunk-C3EJ3UIS.js} +3 -3
- package/dist/{chunk-A3HKTPPV.js → chunk-C63WC454.js} +12 -1
- package/dist/chunk-C63WC454.js.map +1 -0
- package/dist/{chunk-4S3N6HFG.js → chunk-C6XO6ONP.js} +2 -2
- package/dist/{chunk-WD2W4234.js → chunk-CDHRUNBX.js} +11 -2
- package/dist/chunk-CDHRUNBX.js.map +1 -0
- package/dist/{chunk-YQNADJCT.js → chunk-CMZLMIZI.js} +2 -2
- package/dist/{chunk-KVDUDYEN.js → chunk-DDRNDPX4.js} +2 -2
- package/dist/{chunk-PW6GURU3.js → chunk-EKIQBGAY.js} +2 -2
- package/dist/{chunk-QJGTSCJN.js → chunk-FGRV3X3Y.js} +19 -19
- package/dist/{chunk-2IT7WFYE.js → chunk-FWIROLS6.js} +2 -1
- package/dist/chunk-FWIROLS6.js.map +1 -0
- package/dist/{chunk-X7EJF46S.js → chunk-H4RWKZE2.js} +2 -2
- package/dist/{chunk-A6D7A2FW.js → chunk-IHG27THY.js} +4 -4
- package/dist/{chunk-PUEAEQSN.js → chunk-ISMZIMD3.js} +2 -2
- package/dist/{chunk-LEG7XWS2.js → chunk-IXSTQGYV.js} +2 -2
- package/dist/{chunk-CMN5AWAZ.js → chunk-J2KFC47S.js} +2 -2
- package/dist/{chunk-K47C6M2C.js → chunk-M75TBFKQ.js} +2 -2
- package/dist/{chunk-7V2SGZ3H.js → chunk-NE566K4E.js} +2 -2
- package/dist/{chunk-YROCXMCK.js → chunk-RJGPH2Q3.js} +2 -2
- package/dist/{chunk-UXFOGILU.js → chunk-SBHQBC37.js} +2 -2
- package/dist/{chunk-QYGIQ5NM.js → chunk-SHHT4JTC.js} +2 -2
- package/dist/{chunk-TQOU3VAT.js → chunk-SSOMTUCA.js} +1 -1
- package/dist/{chunk-NRST7W5Q.js → chunk-UI2UP7XX.js} +2 -2
- package/dist/{chunk-C4KKM62E.js → chunk-UU5LHD6J.js} +2 -2
- package/dist/{chunk-EWC6W6AB.js → chunk-UXA5L2DZ.js} +2 -2
- package/dist/{chunk-XL7FK7PJ.js → chunk-Y56J7CXW.js} +33 -16
- package/dist/{chunk-XL7FK7PJ.js.map → chunk-Y56J7CXW.js.map} +1 -1
- package/dist/{cli-B-fHk59D.d.ts → cli-A4AIhv9e.d.ts} +3 -3
- package/dist/cli.d.ts +5 -5
- package/dist/cli.js +28 -27
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -3
- 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/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -3
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/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/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +3 -3
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +3 -3
- 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-judge.js +2 -2
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +2 -2
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/fallback-llm.js +1 -1
- package/dist/{graph-edge-decay-5ZOK7ZNO.js → graph-edge-decay-PUFNHOBS.js} +2 -2
- package/dist/graph-snapshot.js +2 -2
- package/dist/graph.d.ts +3 -0
- package/dist/graph.js +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +40 -40
- 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/maintenance/memory-governance-cron.d.ts +8 -0
- package/dist/maintenance/memory-governance-cron.js +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +4 -4
- 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 +1 -1
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +3 -3
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +8 -8
- package/dist/{orchestrator-CoqytbK_.d.ts → orchestrator-BEDTiuEO.d.ts} +20 -5
- package/dist/orchestrator.d.ts +3 -3
- package/dist/orchestrator.js +24 -24
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.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-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +1 -1
- package/dist/recall-state.d.ts +3 -1
- package/dist/recall-state.js +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +4 -4
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-BPs6BURk.d.ts → semantic-consolidation-Byut1ufK.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +3 -3
- 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/storage.js +2 -2
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transcript.js +2 -2
- package/dist/{types-CpMPD8xl.d.ts → types-BzA1FKbg.d.ts} +4 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +3 -3
- package/package.json +1 -1
- package/src/access-http.test.ts +110 -2
- package/src/access-http.ts +117 -1
- package/src/access-mcp.ts +15 -6
- package/src/access-schema.ts +14 -0
- package/src/access-service-namespace.test.ts +740 -0
- package/src/access-service.ts +226 -4
- package/src/config.ts +14 -0
- package/src/fallback-llm.ts +16 -0
- package/src/graph.ts +39 -17
- package/src/index.ts +9 -1
- package/src/maintenance/memory-governance-cron.ts +113 -30
- package/src/orchestrator.ts +1456 -336
- package/src/recall-state.ts +3 -0
- package/src/types.ts +4 -0
- package/dist/chunk-2IT7WFYE.js.map +0 -1
- package/dist/chunk-6BDVBBBY.js.map +0 -1
- package/dist/chunk-723OMPUI.js.map +0 -1
- package/dist/chunk-A3HKTPPV.js.map +0 -1
- package/dist/chunk-BK35NOJL.js.map +0 -1
- package/dist/chunk-FPNQF475.js.map +0 -1
- package/dist/chunk-NFNQ7TWF.js.map +0 -1
- package/dist/chunk-TFICNXXU.js.map +0 -1
- package/dist/chunk-WD2W4234.js.map +0 -1
- package/dist/chunk-XM6M6DHG.js.map +0 -1
- /package/dist/{auto-sync-RFADEHIQ.js.map → auto-sync-54QQHOG5.js.map} +0 -0
- /package/dist/{chunk-3RDYU3JS.js.map → chunk-3AZDLWDW.js.map} +0 -0
- /package/dist/{chunk-3EJ5OOZ3.js.map → chunk-3SF7QNKF.js.map} +0 -0
- /package/dist/{chunk-242XFZ36.js.map → chunk-7OH7KPF5.js.map} +0 -0
- /package/dist/{chunk-HZVIYZYN.js.map → chunk-7R37SOT4.js.map} +0 -0
- /package/dist/{chunk-7A2QKUUA.js.map → chunk-7XRSLMUD.js.map} +0 -0
- /package/dist/{chunk-JCLECECB.js.map → chunk-A3UPMOJZ.js.map} +0 -0
- /package/dist/{chunk-YCX45GOQ.js.map → chunk-AFH2JXSF.js.map} +0 -0
- /package/dist/{chunk-3XNMN242.js.map → chunk-BTY5XQG3.js.map} +0 -0
- /package/dist/{chunk-QHXW3LZV.js.map → chunk-C3EJ3UIS.js.map} +0 -0
- /package/dist/{chunk-4S3N6HFG.js.map → chunk-C6XO6ONP.js.map} +0 -0
- /package/dist/{chunk-YQNADJCT.js.map → chunk-CMZLMIZI.js.map} +0 -0
- /package/dist/{chunk-KVDUDYEN.js.map → chunk-DDRNDPX4.js.map} +0 -0
- /package/dist/{chunk-PW6GURU3.js.map → chunk-EKIQBGAY.js.map} +0 -0
- /package/dist/{chunk-QJGTSCJN.js.map → chunk-FGRV3X3Y.js.map} +0 -0
- /package/dist/{chunk-X7EJF46S.js.map → chunk-H4RWKZE2.js.map} +0 -0
- /package/dist/{chunk-A6D7A2FW.js.map → chunk-IHG27THY.js.map} +0 -0
- /package/dist/{chunk-PUEAEQSN.js.map → chunk-ISMZIMD3.js.map} +0 -0
- /package/dist/{chunk-LEG7XWS2.js.map → chunk-IXSTQGYV.js.map} +0 -0
- /package/dist/{chunk-CMN5AWAZ.js.map → chunk-J2KFC47S.js.map} +0 -0
- /package/dist/{chunk-K47C6M2C.js.map → chunk-M75TBFKQ.js.map} +0 -0
- /package/dist/{chunk-7V2SGZ3H.js.map → chunk-NE566K4E.js.map} +0 -0
- /package/dist/{chunk-YROCXMCK.js.map → chunk-RJGPH2Q3.js.map} +0 -0
- /package/dist/{chunk-UXFOGILU.js.map → chunk-SBHQBC37.js.map} +0 -0
- /package/dist/{chunk-QYGIQ5NM.js.map → chunk-SHHT4JTC.js.map} +0 -0
- /package/dist/{chunk-TQOU3VAT.js.map → chunk-SSOMTUCA.js.map} +0 -0
- /package/dist/{chunk-NRST7W5Q.js.map → chunk-UI2UP7XX.js.map} +0 -0
- /package/dist/{chunk-C4KKM62E.js.map → chunk-UU5LHD6J.js.map} +0 -0
- /package/dist/{chunk-EWC6W6AB.js.map → chunk-UXA5L2DZ.js.map} +0 -0
- /package/dist/{graph-edge-decay-5ZOK7ZNO.js.map → graph-edge-decay-PUFNHOBS.js.map} +0 -0
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
loadSyncState,
|
|
5
5
|
syncWearableSource,
|
|
6
6
|
wearableSourceLabel
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-DDRNDPX4.js";
|
|
8
8
|
import {
|
|
9
9
|
migrateFromEngram
|
|
10
10
|
} from "./chunk-4HFJQCJZ.js";
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
ensurePatternReinforcementCron,
|
|
17
17
|
ensureProceduralMiningCron,
|
|
18
18
|
graphEdgeDecayCadenceToCronExpr
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-666A3MOW.js";
|
|
20
20
|
import {
|
|
21
21
|
LcmEngine
|
|
22
22
|
} from "./chunk-D2B22JDF.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import {
|
|
30
30
|
CompoundingEngine,
|
|
31
31
|
defaultTierMigrationCycleBudget
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-SBHQBC37.js";
|
|
33
33
|
import {
|
|
34
34
|
SharedContextManager
|
|
35
35
|
} from "./chunk-DRD2Q7HQ.js";
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
} from "./chunk-VOUOLGIP.js";
|
|
65
65
|
import {
|
|
66
66
|
HourlySummarizer
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-7R37SOT4.js";
|
|
68
68
|
import {
|
|
69
69
|
SessionObserverState
|
|
70
70
|
} from "./chunk-MHQC2WU2.js";
|
|
@@ -113,7 +113,7 @@ import {
|
|
|
113
113
|
LastRecallStore,
|
|
114
114
|
TierMigrationStatusStore,
|
|
115
115
|
clampGraphRecallExpandedEntries
|
|
116
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-FWIROLS6.js";
|
|
117
117
|
import {
|
|
118
118
|
buildQmdRecallCacheKey,
|
|
119
119
|
getCachedQmdRecall,
|
|
@@ -154,10 +154,10 @@ import {
|
|
|
154
154
|
getVerdictKind,
|
|
155
155
|
judgeFactDurability,
|
|
156
156
|
validateProcedureExtraction
|
|
157
|
-
} from "./chunk-
|
|
157
|
+
} from "./chunk-M75TBFKQ.js";
|
|
158
158
|
import {
|
|
159
159
|
ExtractionEngine
|
|
160
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-UI2UP7XX.js";
|
|
161
161
|
import {
|
|
162
162
|
parseMemoryActionEligibilityContext
|
|
163
163
|
} from "./chunk-ROZJACKP.js";
|
|
@@ -175,7 +175,7 @@ import {
|
|
|
175
175
|
buildEntityRecallSection,
|
|
176
176
|
entityRecentTranscriptLookbackHours,
|
|
177
177
|
readRecentEntityTranscriptEntries
|
|
178
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-A3UPMOJZ.js";
|
|
179
179
|
import {
|
|
180
180
|
buildEventOrderRecallSection,
|
|
181
181
|
shouldRecallEventOrderEvidence
|
|
@@ -210,7 +210,7 @@ import {
|
|
|
210
210
|
materializeAfterSemanticConsolidation,
|
|
211
211
|
parseConsolidationResponse,
|
|
212
212
|
parseOperatorAwareConsolidationResponse
|
|
213
|
-
} from "./chunk-
|
|
213
|
+
} from "./chunk-H4RWKZE2.js";
|
|
214
214
|
import {
|
|
215
215
|
normalizeReplaySessionKey
|
|
216
216
|
} from "./chunk-2PRQG7PV.js";
|
|
@@ -219,22 +219,22 @@ import {
|
|
|
219
219
|
} from "./chunk-X6IRLNOO.js";
|
|
220
220
|
import {
|
|
221
221
|
searchVerifiedEpisodes
|
|
222
|
-
} from "./chunk-
|
|
222
|
+
} from "./chunk-RJGPH2Q3.js";
|
|
223
223
|
import {
|
|
224
224
|
ThreadingManager
|
|
225
225
|
} from "./chunk-W4RVMTHR.js";
|
|
226
226
|
import {
|
|
227
227
|
searchVerifiedSemanticRules
|
|
228
|
-
} from "./chunk-
|
|
228
|
+
} from "./chunk-C6XO6ONP.js";
|
|
229
229
|
import {
|
|
230
230
|
searchWorkProductLedgerEntries
|
|
231
231
|
} from "./chunk-ZRWB5D4H.js";
|
|
232
232
|
import {
|
|
233
233
|
TranscriptManager
|
|
234
|
-
} from "./chunk-
|
|
234
|
+
} from "./chunk-IHG27THY.js";
|
|
235
235
|
import {
|
|
236
236
|
NamespaceStorageRouter
|
|
237
|
-
} from "./chunk-
|
|
237
|
+
} from "./chunk-IXSTQGYV.js";
|
|
238
238
|
import {
|
|
239
239
|
PolicyRuntimeManager
|
|
240
240
|
} from "./chunk-33JBK2XP.js";
|
|
@@ -271,8 +271,9 @@ import {
|
|
|
271
271
|
} from "./chunk-IBTZEBUD.js";
|
|
272
272
|
import {
|
|
273
273
|
FallbackLlmClient,
|
|
274
|
-
fallbackLlmRuntimeContextFromConfig
|
|
275
|
-
|
|
274
|
+
fallbackLlmRuntimeContextFromConfig,
|
|
275
|
+
gatewayTaskChainOptions
|
|
276
|
+
} from "./chunk-A3BS64GV.js";
|
|
276
277
|
import {
|
|
277
278
|
compileCorrectionRule,
|
|
278
279
|
correctionsFilePath,
|
|
@@ -308,9 +309,12 @@ import {
|
|
|
308
309
|
listTrustZoneRecords,
|
|
309
310
|
searchTrustZoneRecords
|
|
310
311
|
} from "./chunk-JGSKJHF7.js";
|
|
312
|
+
import {
|
|
313
|
+
isPathInsideStorageRoot
|
|
314
|
+
} from "./chunk-FF4KLI5W.js";
|
|
311
315
|
import {
|
|
312
316
|
buildXraySnapshot
|
|
313
|
-
} from "./chunk-
|
|
317
|
+
} from "./chunk-CMZLMIZI.js";
|
|
314
318
|
import {
|
|
315
319
|
NamespaceSearchRouter
|
|
316
320
|
} from "./chunk-LASA46TQ.js";
|
|
@@ -345,10 +349,10 @@ import {
|
|
|
345
349
|
} from "./chunk-H3PHZLMF.js";
|
|
346
350
|
import {
|
|
347
351
|
GraphIndex
|
|
348
|
-
} from "./chunk-
|
|
352
|
+
} from "./chunk-Y56J7CXW.js";
|
|
349
353
|
import {
|
|
350
354
|
buildChainFollowupGenerator
|
|
351
|
-
} from "./chunk-
|
|
355
|
+
} from "./chunk-J2KFC47S.js";
|
|
352
356
|
import {
|
|
353
357
|
ContentHashIndex,
|
|
354
358
|
StorageManager,
|
|
@@ -358,7 +362,7 @@ import {
|
|
|
358
362
|
normalizeEntityName,
|
|
359
363
|
parseEntityFile,
|
|
360
364
|
stripAttributesSuffix
|
|
361
|
-
} from "./chunk-
|
|
365
|
+
} from "./chunk-SHHT4JTC.js";
|
|
362
366
|
import {
|
|
363
367
|
isValidTranscriptDate,
|
|
364
368
|
loadSpeakerRegistry,
|
|
@@ -373,7 +377,7 @@ import {
|
|
|
373
377
|
} from "./chunk-J6A3CX5N.js";
|
|
374
378
|
import {
|
|
375
379
|
confidenceTier
|
|
376
|
-
} from "./chunk-
|
|
380
|
+
} from "./chunk-3F7RMHC4.js";
|
|
377
381
|
import {
|
|
378
382
|
inferMemoryStatus,
|
|
379
383
|
isActiveMemoryStatus
|
|
@@ -387,7 +391,7 @@ import {
|
|
|
387
391
|
} from "./chunk-FVQJYWH7.js";
|
|
388
392
|
import {
|
|
389
393
|
searchCausalTrajectories
|
|
390
|
-
} from "./chunk-
|
|
394
|
+
} from "./chunk-SSOMTUCA.js";
|
|
391
395
|
import {
|
|
392
396
|
canReadNamespace,
|
|
393
397
|
defaultNamespaceForPrincipal,
|
|
@@ -416,6 +420,9 @@ import {
|
|
|
416
420
|
keyring_exports,
|
|
417
421
|
secureStoreDir
|
|
418
422
|
} from "./chunk-BJMBJZ2Y.js";
|
|
423
|
+
import {
|
|
424
|
+
SecureStoreLockedError
|
|
425
|
+
} from "./chunk-ILXTATKK.js";
|
|
419
426
|
import {
|
|
420
427
|
parseFlexibleIsoTimestamp
|
|
421
428
|
} from "./chunk-P7FMDTKL.js";
|
|
@@ -1633,8 +1640,119 @@ async function raceRecallAbort(promise, signal, message = "recall aborted") {
|
|
|
1633
1640
|
}
|
|
1634
1641
|
}
|
|
1635
1642
|
}
|
|
1643
|
+
function qmdCollectionPathParts(resultPath) {
|
|
1644
|
+
if (!resultPath || path2.isAbsolute(resultPath)) return null;
|
|
1645
|
+
const normalized = resultPath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
1646
|
+
const slashIndex = normalized.indexOf("/");
|
|
1647
|
+
if (slashIndex <= 0 || slashIndex >= normalized.length - 1) return null;
|
|
1648
|
+
const collection = normalized.slice(0, slashIndex);
|
|
1649
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(collection)) return null;
|
|
1650
|
+
return {
|
|
1651
|
+
collection,
|
|
1652
|
+
relativePath: normalized.slice(slashIndex + 1)
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
function qmdResultPathCandidates(storageDir, resultPath) {
|
|
1656
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
1657
|
+
const storageRoot = path2.resolve(storageDir);
|
|
1658
|
+
const addCandidate = (candidate) => {
|
|
1659
|
+
const resolved = path2.resolve(candidate);
|
|
1660
|
+
if (isPathInsideStorageRoot(storageRoot, resolved)) {
|
|
1661
|
+
candidates.add(resolved);
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
const addRelativeCandidates = (relativePath) => {
|
|
1665
|
+
const normalized = relativePath.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
1666
|
+
if (!normalized) return;
|
|
1667
|
+
addCandidate(path2.join(storageRoot, normalized));
|
|
1668
|
+
if (/^\d{4}-\d{2}-\d{2}\//.test(normalized)) {
|
|
1669
|
+
addCandidate(path2.join(storageRoot, "facts", normalized));
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
if (path2.isAbsolute(resultPath)) {
|
|
1673
|
+
addCandidate(resultPath);
|
|
1674
|
+
} else {
|
|
1675
|
+
addRelativeCandidates(resultPath);
|
|
1676
|
+
}
|
|
1677
|
+
return [...candidates];
|
|
1678
|
+
}
|
|
1636
1679
|
var COMPACTION_SIGNAL_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
1637
1680
|
var DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS = 1e4;
|
|
1681
|
+
function normalizeIanaTimeZone(value) {
|
|
1682
|
+
if (typeof value !== "string") return void 0;
|
|
1683
|
+
const trimmed = value.trim();
|
|
1684
|
+
if (!trimmed) return void 0;
|
|
1685
|
+
try {
|
|
1686
|
+
Intl.DateTimeFormat(void 0, { timeZone: trimmed });
|
|
1687
|
+
return trimmed;
|
|
1688
|
+
} catch {
|
|
1689
|
+
return void 0;
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
function formatDateInTimeZone(date, timeZone) {
|
|
1693
|
+
const parts = new Intl.DateTimeFormat("en-US", {
|
|
1694
|
+
timeZone,
|
|
1695
|
+
year: "numeric",
|
|
1696
|
+
month: "2-digit",
|
|
1697
|
+
day: "2-digit"
|
|
1698
|
+
}).formatToParts(date);
|
|
1699
|
+
const get = (type) => parts.find((part) => part.type === type)?.value ?? "";
|
|
1700
|
+
return `${get("year")}-${get("month")}-${get("day")}`;
|
|
1701
|
+
}
|
|
1702
|
+
function utcDateKey(date) {
|
|
1703
|
+
return date.toISOString().slice(0, 10);
|
|
1704
|
+
}
|
|
1705
|
+
function utcDateKeysAround(date) {
|
|
1706
|
+
const dayMs = 864e5;
|
|
1707
|
+
const keys = [
|
|
1708
|
+
utcDateKey(new Date(date.getTime() - dayMs)),
|
|
1709
|
+
utcDateKey(date),
|
|
1710
|
+
utcDateKey(new Date(date.getTime() + dayMs))
|
|
1711
|
+
];
|
|
1712
|
+
return keys.filter((value, index, array) => array.indexOf(value) === index);
|
|
1713
|
+
}
|
|
1714
|
+
function utcDateKeysForLocalDay(date, timeZone) {
|
|
1715
|
+
const targetLocalDate = formatDateInTimeZone(date, timeZone);
|
|
1716
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1717
|
+
const hourMs = 36e5;
|
|
1718
|
+
const scanStart = date.getTime() - 48 * hourMs;
|
|
1719
|
+
const scanEnd = date.getTime() + 48 * hourMs;
|
|
1720
|
+
for (let ms = scanStart; ms <= scanEnd; ms += hourMs) {
|
|
1721
|
+
const candidate = new Date(ms);
|
|
1722
|
+
if (formatDateInTimeZone(candidate, timeZone) === targetLocalDate) {
|
|
1723
|
+
keys.add(utcDateKey(candidate));
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
return keys.size > 0 ? [...keys].sort() : utcDateKeysAround(date);
|
|
1727
|
+
}
|
|
1728
|
+
function parseFiniteDate(value) {
|
|
1729
|
+
if (typeof value !== "string" || value.trim().length === 0) return null;
|
|
1730
|
+
const parsed = new Date(value);
|
|
1731
|
+
return Number.isFinite(parsed.getTime()) ? parsed : null;
|
|
1732
|
+
}
|
|
1733
|
+
function filterHourlySummaryMarkdownForLocalDay(raw, utcDate, timeZone, targetLocalDate) {
|
|
1734
|
+
const hourHeaderPattern = /^## ([01]\d|2[0-3]):00[ \t]*$/gm;
|
|
1735
|
+
const matches = Array.from(raw.matchAll(hourHeaderPattern));
|
|
1736
|
+
if (matches.length === 0) return null;
|
|
1737
|
+
const firstSectionStart = matches[0]?.index ?? 0;
|
|
1738
|
+
const preamble = raw.slice(0, firstSectionStart).trim();
|
|
1739
|
+
const sections = [];
|
|
1740
|
+
for (let index = 0; index < matches.length; index += 1) {
|
|
1741
|
+
const match = matches[index];
|
|
1742
|
+
const hour = match[1];
|
|
1743
|
+
if (!hour) continue;
|
|
1744
|
+
const sectionTimestamp = parseFiniteDate(`${utcDate}T${hour}:00:00.000Z`);
|
|
1745
|
+
if (!sectionTimestamp || formatDateInTimeZone(sectionTimestamp, timeZone) !== targetLocalDate) {
|
|
1746
|
+
continue;
|
|
1747
|
+
}
|
|
1748
|
+
const sectionStart = match.index ?? 0;
|
|
1749
|
+
const sectionEnd = matches[index + 1]?.index ?? raw.length;
|
|
1750
|
+
const section = raw.slice(sectionStart, sectionEnd).trim();
|
|
1751
|
+
if (section.length > 0) sections.push(section);
|
|
1752
|
+
}
|
|
1753
|
+
if (sections.length === 0) return null;
|
|
1754
|
+
return [preamble, ...sections].filter((section) => section.length > 0).join("\n\n");
|
|
1755
|
+
}
|
|
1638
1756
|
function qmdStartupCollectionCheckTimeoutMs() {
|
|
1639
1757
|
const raw = process.env.REMNIC_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS ?? process.env.ENGRAM_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;
|
|
1640
1758
|
if (raw === void 0) return DEFAULT_QMD_STARTUP_COLLECTION_CHECK_TIMEOUT_MS;
|
|
@@ -2714,7 +2832,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
2714
2832
|
const result = this.config.modelSource === "gateway" && this._fastGatewayLlm ? await this._fastGatewayLlm.chatCompletion(messages, {
|
|
2715
2833
|
maxTokens: targetTokens * 2,
|
|
2716
2834
|
timeoutMs: this.config.localLlmFastTimeoutMs,
|
|
2717
|
-
|
|
2835
|
+
// LCM is latency-sensitive. A configured fast persona is the
|
|
2836
|
+
// explicit fast-tier route; otherwise use taskModelChain so LCM
|
|
2837
|
+
// avoids falling to an expensive gateway default. Issue #1473.
|
|
2838
|
+
...this.config.fastGatewayAgentId ? { agentId: this.config.fastGatewayAgentId } : gatewayTaskChainOptions(this.config)
|
|
2718
2839
|
}) : await this.localLlm.chatCompletion(messages, {
|
|
2719
2840
|
maxTokens: targetTokens * 2,
|
|
2720
2841
|
operation: "lcm-summarize",
|
|
@@ -3251,7 +3372,7 @@ var Orchestrator = class _Orchestrator {
|
|
|
3251
3372
|
if (signal.aborted) return;
|
|
3252
3373
|
if (!this.wearablesAutoSyncHandle && this.config.wearables.enabled && this.config.wearables.autoSyncEnabled && Object.values(this.config.wearables.sources).some((source) => source.enabled)) {
|
|
3253
3374
|
try {
|
|
3254
|
-
const { startWearablesAutoSync } = await import("./auto-sync-
|
|
3375
|
+
const { startWearablesAutoSync } = await import("./auto-sync-54QQHOG5.js");
|
|
3255
3376
|
if (signal.aborted) return;
|
|
3256
3377
|
this.wearablesAutoSyncHandle = startWearablesAutoSync(
|
|
3257
3378
|
{
|
|
@@ -3380,8 +3501,10 @@ var Orchestrator = class _Orchestrator {
|
|
|
3380
3501
|
return true;
|
|
3381
3502
|
}
|
|
3382
3503
|
/**
|
|
3383
|
-
* Auto-register the engram-day-summary cron job in OpenClaw
|
|
3504
|
+
* Auto-register the engram-day-summary cron job in OpenClaw.
|
|
3505
|
+
* Reconciles model and timezone on every startup so config changes propagate.
|
|
3384
3506
|
* Fire-and-forget — never blocks init or crashes on failure.
|
|
3507
|
+
* Issues #1474, #1475.
|
|
3385
3508
|
*/
|
|
3386
3509
|
async autoRegisterDaySummaryCron() {
|
|
3387
3510
|
const home = resolveHomeDir();
|
|
@@ -3393,15 +3516,44 @@ var Orchestrator = class _Orchestrator {
|
|
|
3393
3516
|
);
|
|
3394
3517
|
return;
|
|
3395
3518
|
}
|
|
3396
|
-
const
|
|
3397
|
-
|
|
3519
|
+
const rawSummaryModel = this.config.summaryModel;
|
|
3520
|
+
const taskPrimary = this.config.taskModelChain?.primary;
|
|
3521
|
+
const isGateway = this.config.modelSource === "gateway";
|
|
3522
|
+
const model = isGateway ? rawSummaryModel || taskPrimary || void 0 : void 0;
|
|
3523
|
+
const fallbacks = [];
|
|
3524
|
+
if (model && taskPrimary && model === taskPrimary) {
|
|
3525
|
+
const seen = new Set(model ? [model] : []);
|
|
3526
|
+
const addUnique = (value) => {
|
|
3527
|
+
if (typeof value !== "string") return;
|
|
3528
|
+
const trimmed = value.trim();
|
|
3529
|
+
if (trimmed.length > 0 && !seen.has(trimmed)) {
|
|
3530
|
+
seen.add(trimmed);
|
|
3531
|
+
fallbacks.push(trimmed);
|
|
3532
|
+
}
|
|
3533
|
+
};
|
|
3534
|
+
for (const fb of this.config.taskModelChain?.fallbacks ?? []) addUnique(fb);
|
|
3535
|
+
const gwDefaults = this.config.gatewayConfig?.agents?.defaults?.model;
|
|
3536
|
+
addUnique(gwDefaults?.primary);
|
|
3537
|
+
if (Array.isArray(gwDefaults?.fallbacks)) {
|
|
3538
|
+
for (const fb of gwDefaults.fallbacks) addUnique(fb);
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
const timezone = this.config.daySummaryTimezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
3542
|
+
const result = await ensureDaySummaryCron(jobsPath, {
|
|
3543
|
+
timezone,
|
|
3544
|
+
...model ? { model } : {},
|
|
3545
|
+
...fallbacks.length > 0 ? { fallbacks } : {}
|
|
3398
3546
|
});
|
|
3399
|
-
if (
|
|
3547
|
+
if (result.created) {
|
|
3548
|
+
log.info(
|
|
3549
|
+
`day-summary cron auto-registered (${result.jobId}, 23:47 ${timezone}${model ? `, model: ${model}` : ""})`
|
|
3550
|
+
);
|
|
3551
|
+
} else if (result.updated) {
|
|
3400
3552
|
log.info(
|
|
3401
|
-
`day-summary cron
|
|
3553
|
+
`day-summary cron reconciled (${result.jobId}, timezone: ${timezone}${model ? `, model: ${model}` : ""})`
|
|
3402
3554
|
);
|
|
3403
3555
|
} else {
|
|
3404
|
-
log.debug("day-summary cron already
|
|
3556
|
+
log.debug("day-summary cron already up to date");
|
|
3405
3557
|
}
|
|
3406
3558
|
} catch (err) {
|
|
3407
3559
|
log.debug(`day-summary cron auto-register error: ${err}`);
|
|
@@ -3720,13 +3872,13 @@ ${doc.content}` : doc.content,
|
|
|
3720
3872
|
);
|
|
3721
3873
|
return result;
|
|
3722
3874
|
}
|
|
3723
|
-
const { FallbackLlmClient: FallbackLlmClient2, gatewayTaskChainOptions } = await import("./fallback-llm.js");
|
|
3875
|
+
const { FallbackLlmClient: FallbackLlmClient2, gatewayTaskChainOptions: gatewayTaskChainOptions2 } = await import("./fallback-llm.js");
|
|
3724
3876
|
const useGateway = this.config.modelSource === "gateway";
|
|
3725
3877
|
const modelSetting = this.config.semanticConsolidationModel;
|
|
3726
3878
|
if (modelSetting === "fast" && this.fastLlm && !useGateway) {
|
|
3727
3879
|
log.info("[semantic-consolidation] using fast local LLM for synthesis");
|
|
3728
3880
|
}
|
|
3729
|
-
const gatewayChainOptions = !useGateway ? {} : modelSetting === "fast" ? this.config.fastGatewayAgentId ? { agentId: this.config.fastGatewayAgentId } : this.config.gatewayAgentId ? { agentId: this.config.gatewayAgentId } : {} :
|
|
3881
|
+
const gatewayChainOptions = !useGateway ? {} : modelSetting === "fast" ? this.config.fastGatewayAgentId ? { agentId: this.config.fastGatewayAgentId } : this.config.gatewayAgentId ? { agentId: this.config.gatewayAgentId } : {} : gatewayTaskChainOptions2(this.config);
|
|
3730
3882
|
const llm = new FallbackLlmClient2(
|
|
3731
3883
|
this.config.gatewayConfig,
|
|
3732
3884
|
fallbackLlmRuntimeContextFromConfig(this.config)
|
|
@@ -4072,8 +4224,8 @@ ${evidenceText}`
|
|
|
4072
4224
|
* Auto-gather today's facts and hourly summaries from storage, then generate a day summary.
|
|
4073
4225
|
* Returns null if no facts are found for today.
|
|
4074
4226
|
*/
|
|
4075
|
-
async generateDaySummaryAuto(namespace) {
|
|
4076
|
-
const gathered = await this.gatherTodayFacts(namespace);
|
|
4227
|
+
async generateDaySummaryAuto(namespace, options = {}) {
|
|
4228
|
+
const gathered = await this.gatherTodayFacts(namespace, options);
|
|
4077
4229
|
if (!gathered || !gathered.trim()) {
|
|
4078
4230
|
log.warn("generateDaySummaryAuto: no facts found for today, skipping");
|
|
4079
4231
|
return null;
|
|
@@ -4084,15 +4236,14 @@ ${evidenceText}`
|
|
|
4084
4236
|
* Read today's facts and hourly summaries from storage, returning them
|
|
4085
4237
|
* as a formatted string suitable for generateDaySummary().
|
|
4086
4238
|
*/
|
|
4087
|
-
async gatherTodayFacts(namespace) {
|
|
4239
|
+
async gatherTodayFacts(namespace, options = {}) {
|
|
4088
4240
|
const ns = namespace && namespace.length > 0 ? namespace : this.config.defaultNamespace;
|
|
4089
4241
|
const storage = await this.storageRouter.storageFor(ns);
|
|
4090
|
-
const
|
|
4091
|
-
const
|
|
4092
|
-
const
|
|
4093
|
-
const
|
|
4094
|
-
|
|
4095
|
-
);
|
|
4242
|
+
const configuredTimeZone = normalizeIanaTimeZone(options.timeZone) ?? normalizeIanaTimeZone(this.config.daySummaryTimezone);
|
|
4243
|
+
const timeZone = configuredTimeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
4244
|
+
const now = options.now instanceof Date && Number.isFinite(options.now.getTime()) ? options.now : /* @__PURE__ */ new Date();
|
|
4245
|
+
const targetLocalDate = formatDateInTimeZone(now, timeZone);
|
|
4246
|
+
const datesToScan = utcDateKeysForLocalDay(now, timeZone);
|
|
4096
4247
|
const factsBaseDir = path2.join(storage.dir, "facts");
|
|
4097
4248
|
const MAX_CHARS = 1e5;
|
|
4098
4249
|
const facts = [];
|
|
@@ -4115,13 +4266,18 @@ ${evidenceText}`
|
|
|
4115
4266
|
if (colonIdx === -1) continue;
|
|
4116
4267
|
fm[line.slice(0, colonIdx).trim()] = line.slice(colonIdx + 1).trim();
|
|
4117
4268
|
}
|
|
4269
|
+
const created = fm.created || "unknown";
|
|
4270
|
+
const createdAt = parseFiniteDate(created);
|
|
4271
|
+
if (createdAt && formatDateInTimeZone(createdAt, timeZone) !== targetLocalDate) {
|
|
4272
|
+
continue;
|
|
4273
|
+
}
|
|
4118
4274
|
facts.push({
|
|
4119
4275
|
path: fullPath,
|
|
4120
4276
|
frontmatter: {
|
|
4121
4277
|
id: fm.id || path2.basename(entry.name, ".md"),
|
|
4122
4278
|
category: fm.category || "fact",
|
|
4123
|
-
created
|
|
4124
|
-
updated: fm.updated ||
|
|
4279
|
+
created,
|
|
4280
|
+
updated: fm.updated || created,
|
|
4125
4281
|
source: fm.source || "unknown",
|
|
4126
4282
|
confidence: parseFloat(fm.confidence || "0.8"),
|
|
4127
4283
|
confidenceTier: fm.confidenceTier || "implied",
|
|
@@ -4135,9 +4291,10 @@ ${evidenceText}`
|
|
|
4135
4291
|
} catch {
|
|
4136
4292
|
}
|
|
4137
4293
|
}
|
|
4138
|
-
facts.sort(
|
|
4139
|
-
(a
|
|
4140
|
-
|
|
4294
|
+
facts.sort((a, b) => {
|
|
4295
|
+
if (a.frontmatter.created === b.frontmatter.created) return 0;
|
|
4296
|
+
return a.frontmatter.created < b.frontmatter.created ? -1 : 1;
|
|
4297
|
+
});
|
|
4141
4298
|
const hourlySummaries = [];
|
|
4142
4299
|
const hourlyBaseDir = path2.join(storage.dir, "summaries", "hourly");
|
|
4143
4300
|
try {
|
|
@@ -4148,8 +4305,14 @@ ${evidenceText}`
|
|
|
4148
4305
|
const summaryFile = path2.join(hourlyBaseDir, sk.name, `${date}.md`);
|
|
4149
4306
|
try {
|
|
4150
4307
|
const raw = await readFile2(summaryFile, "utf-8");
|
|
4151
|
-
|
|
4152
|
-
|
|
4308
|
+
const filtered = filterHourlySummaryMarkdownForLocalDay(
|
|
4309
|
+
raw,
|
|
4310
|
+
date,
|
|
4311
|
+
timeZone,
|
|
4312
|
+
targetLocalDate
|
|
4313
|
+
);
|
|
4314
|
+
if (filtered) {
|
|
4315
|
+
hourlySummaries.push(filtered);
|
|
4153
4316
|
}
|
|
4154
4317
|
} catch {
|
|
4155
4318
|
}
|
|
@@ -4174,7 +4337,7 @@ ${evidenceText}`
|
|
|
4174
4337
|
}
|
|
4175
4338
|
}
|
|
4176
4339
|
log.info(
|
|
4177
|
-
`gatherTodayFacts: collected ${facts.length} facts, ${hourlySummaries.length} hourly summaries (${formatted.length} chars)`
|
|
4340
|
+
`gatherTodayFacts: collected ${facts.length} facts, ${hourlySummaries.length} hourly summaries for ${targetLocalDate} (${timeZone}, ${formatted.length} chars)`
|
|
4178
4341
|
);
|
|
4179
4342
|
return formatted;
|
|
4180
4343
|
}
|
|
@@ -5334,16 +5497,74 @@ ${r.snippet.trim()}
|
|
|
5334
5497
|
return capped;
|
|
5335
5498
|
}
|
|
5336
5499
|
async expandResultsViaGraph(options) {
|
|
5500
|
+
const deadlineExpired = () => typeof options.deadlineAtMs === "number" && Date.now() >= options.deadlineAtMs;
|
|
5337
5501
|
const byNamespace = /* @__PURE__ */ new Map();
|
|
5338
|
-
|
|
5339
|
-
const
|
|
5340
|
-
if (!options.recallNamespaces.includes(ns)) continue;
|
|
5341
|
-
const existing = byNamespace.get(ns);
|
|
5502
|
+
const addResultForNamespace = (namespace, result) => {
|
|
5503
|
+
const existing = byNamespace.get(namespace);
|
|
5342
5504
|
if (existing) {
|
|
5343
5505
|
existing.push(result);
|
|
5344
5506
|
} else {
|
|
5345
|
-
byNamespace.set(
|
|
5507
|
+
byNamespace.set(namespace, [result]);
|
|
5508
|
+
}
|
|
5509
|
+
};
|
|
5510
|
+
const resolvedAmbiguousSeeds = /* @__PURE__ */ new Map();
|
|
5511
|
+
const resolveAmbiguousSeedOwner = async (result, parts) => {
|
|
5512
|
+
const cached = resolvedAmbiguousSeeds.get(result.path);
|
|
5513
|
+
if (cached !== void 0) return cached;
|
|
5514
|
+
if (deadlineExpired()) {
|
|
5515
|
+
resolvedAmbiguousSeeds.set(result.path, null);
|
|
5516
|
+
return null;
|
|
5517
|
+
}
|
|
5518
|
+
let resolvedPath = result.path;
|
|
5519
|
+
let resolvedResult = result;
|
|
5520
|
+
if (parts) {
|
|
5521
|
+
const resolvedCold = await this.resolveColdQmdResultForRecall(
|
|
5522
|
+
result,
|
|
5523
|
+
this.storage,
|
|
5524
|
+
options.recallNamespaces
|
|
5525
|
+
);
|
|
5526
|
+
if (!resolvedCold || deadlineExpired()) {
|
|
5527
|
+
resolvedAmbiguousSeeds.set(result.path, null);
|
|
5528
|
+
return null;
|
|
5529
|
+
}
|
|
5530
|
+
resolvedPath = resolvedCold.result.path;
|
|
5531
|
+
resolvedResult = resolvedCold.result;
|
|
5532
|
+
}
|
|
5533
|
+
if (!path2.isAbsolute(resolvedPath)) {
|
|
5534
|
+
resolvedAmbiguousSeeds.set(result.path, null);
|
|
5535
|
+
return null;
|
|
5536
|
+
}
|
|
5537
|
+
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
5538
|
+
resolvedPath,
|
|
5539
|
+
this.storage,
|
|
5540
|
+
options.recallNamespaces
|
|
5541
|
+
);
|
|
5542
|
+
const ownerNamespace = ownerStorage?.namespace ?? null;
|
|
5543
|
+
const resolved = ownerNamespace && options.recallNamespaces.includes(ownerNamespace) ? { namespace: ownerNamespace, result: resolvedResult } : null;
|
|
5544
|
+
resolvedAmbiguousSeeds.set(result.path, resolved);
|
|
5545
|
+
return resolved;
|
|
5546
|
+
};
|
|
5547
|
+
const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
5548
|
+
for (const result of options.memoryResults) {
|
|
5549
|
+
if (deadlineExpired()) break;
|
|
5550
|
+
const parts = qmdCollectionPathParts(result.path);
|
|
5551
|
+
if (parts?.collection === coldCollection) {
|
|
5552
|
+
const resolved = await resolveAmbiguousSeedOwner(result, parts);
|
|
5553
|
+
if (resolved) {
|
|
5554
|
+
addResultForNamespace(resolved.namespace, resolved.result);
|
|
5555
|
+
}
|
|
5556
|
+
continue;
|
|
5557
|
+
}
|
|
5558
|
+
if (path2.isAbsolute(result.path)) {
|
|
5559
|
+
const resolved = await resolveAmbiguousSeedOwner(result, null);
|
|
5560
|
+
if (resolved) {
|
|
5561
|
+
addResultForNamespace(resolved.namespace, resolved.result);
|
|
5562
|
+
}
|
|
5563
|
+
continue;
|
|
5346
5564
|
}
|
|
5565
|
+
const ns = this.namespaceFromPath(result.path);
|
|
5566
|
+
if (!options.recallNamespaces.includes(ns)) continue;
|
|
5567
|
+
addResultForNamespace(ns, result);
|
|
5347
5568
|
}
|
|
5348
5569
|
const perNamespaceSeedCap = Math.max(3, options.recallResultLimit);
|
|
5349
5570
|
const perNamespaceExpandedCap = Math.max(8, options.recallResultLimit * 2);
|
|
@@ -5352,12 +5573,25 @@ ${r.snippet.trim()}
|
|
|
5352
5573
|
const expandedPaths = [];
|
|
5353
5574
|
const expandedResults = [];
|
|
5354
5575
|
for (const [namespace, nsResults] of byNamespace.entries()) {
|
|
5576
|
+
if (deadlineExpired()) break;
|
|
5355
5577
|
const storage = await this.storageRouter.storageFor(namespace);
|
|
5356
5578
|
const seedCandidates = nsResults.slice(0, perNamespaceSeedCap);
|
|
5357
5579
|
seedResults.push(...seedCandidates);
|
|
5358
|
-
const seedRelativePaths =
|
|
5580
|
+
const seedRelativePaths = typeof options.deadlineAtMs === "number" ? await this.graphSeedPathsWithinDeadline(
|
|
5581
|
+
storage,
|
|
5582
|
+
seedCandidates,
|
|
5583
|
+
options.deadlineAtMs,
|
|
5584
|
+
[namespace]
|
|
5585
|
+
) : (await Promise.all(
|
|
5586
|
+
seedCandidates.map(
|
|
5587
|
+
(result) => this.graphSeedPathRelativeToStorage(storage, result, [
|
|
5588
|
+
namespace
|
|
5589
|
+
])
|
|
5590
|
+
)
|
|
5591
|
+
)).filter(
|
|
5359
5592
|
(value) => typeof value === "string" && value.length > 0
|
|
5360
5593
|
);
|
|
5594
|
+
if (deadlineExpired()) break;
|
|
5361
5595
|
if (seedRelativePaths.length === 0) continue;
|
|
5362
5596
|
const seedRecallScore = seedCandidates.reduce(
|
|
5363
5597
|
(max, item) => Math.max(max, item.score),
|
|
@@ -5370,13 +5604,19 @@ ${r.snippet.trim()}
|
|
|
5370
5604
|
const expanded = await this.graphIndexFor(storage).spreadingActivation(
|
|
5371
5605
|
seedRelativePaths,
|
|
5372
5606
|
this.config.maxGraphTraversalSteps,
|
|
5373
|
-
|
|
5607
|
+
{
|
|
5608
|
+
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {},
|
|
5609
|
+
...typeof options.deadlineAtMs === "number" ? { deadlineAtMs: options.deadlineAtMs } : {}
|
|
5610
|
+
}
|
|
5374
5611
|
);
|
|
5375
5612
|
if (expanded.length === 0) continue;
|
|
5613
|
+
if (deadlineExpired()) break;
|
|
5376
5614
|
for (const candidate of expanded.slice(0, perNamespaceExpandedCap)) {
|
|
5615
|
+
if (deadlineExpired()) break;
|
|
5377
5616
|
if (seedSet.has(candidate.path)) continue;
|
|
5378
5617
|
const memoryPath = path2.resolve(storage.dir, candidate.path);
|
|
5379
5618
|
const memory = await storage.readMemoryByPath(memoryPath);
|
|
5619
|
+
if (deadlineExpired()) break;
|
|
5380
5620
|
if (!memory) continue;
|
|
5381
5621
|
if (isArtifactMemoryPath(memory.path)) continue;
|
|
5382
5622
|
if (memory.frontmatter.status && memory.frontmatter.status !== "active")
|
|
@@ -7505,10 +7745,12 @@ ${formatted}`;
|
|
|
7505
7745
|
return section;
|
|
7506
7746
|
})()
|
|
7507
7747
|
);
|
|
7508
|
-
const recentBoxesPromise =
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
7748
|
+
const recentBoxesPromise = observeEnrichmentPromise(
|
|
7749
|
+
this.isRecallSectionEnabled(
|
|
7750
|
+
"memory-boxes",
|
|
7751
|
+
this.config.memoryBoxesEnabled === true
|
|
7752
|
+
) && this.config.memoryBoxesEnabled && this.config.boxRecallDays > 0 ? this.boxBuilderFor(profileStorage).readRecentBoxes(this.config.boxRecallDays).catch(() => []) : Promise.resolve([])
|
|
7753
|
+
);
|
|
7512
7754
|
this.profiler.startSpan("phase-1-parallel", profileTraceId);
|
|
7513
7755
|
const phase1Start = Date.now();
|
|
7514
7756
|
log.info(
|
|
@@ -7637,6 +7879,48 @@ ${formatted}`;
|
|
|
7637
7879
|
}
|
|
7638
7880
|
return finalizeEnrichmentOutcome(outcome);
|
|
7639
7881
|
};
|
|
7882
|
+
const remainingEnrichmentAssemblyMs = () => enrichmentAssemblyDeadlineAtMs === null ? null : Math.max(0, enrichmentAssemblyDeadlineAtMs - Date.now());
|
|
7883
|
+
const awaitAssemblyStep = async (name, task, fallback) => {
|
|
7884
|
+
if (options.abortSignal?.aborted) {
|
|
7885
|
+
log.debug(
|
|
7886
|
+
`recall phase-1 assembly [${name}]: skipped after abort at +${Date.now() - phase1Start}ms`
|
|
7887
|
+
);
|
|
7888
|
+
return fallback;
|
|
7889
|
+
}
|
|
7890
|
+
const timeoutMs = remainingEnrichmentAssemblyMs();
|
|
7891
|
+
if (timeoutMs === 0) {
|
|
7892
|
+
log.debug(
|
|
7893
|
+
`recall phase-1 assembly [${name}]: skipped after shared ${enrichmentSectionDeadlineMs}ms budget expired at +${Date.now() - phase1Start}ms`
|
|
7894
|
+
);
|
|
7895
|
+
return fallback;
|
|
7896
|
+
}
|
|
7897
|
+
let timeoutHandle;
|
|
7898
|
+
try {
|
|
7899
|
+
const result = await (timeoutMs !== null ? Promise.race([
|
|
7900
|
+
task(),
|
|
7901
|
+
new Promise((resolve) => {
|
|
7902
|
+
timeoutHandle = setTimeout(
|
|
7903
|
+
() => resolve({ status: "timed_out" }),
|
|
7904
|
+
timeoutMs
|
|
7905
|
+
);
|
|
7906
|
+
})
|
|
7907
|
+
]) : task());
|
|
7908
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
7909
|
+
if (typeof result === "object" && result !== null && "status" in result && result.status === "timed_out") {
|
|
7910
|
+
log.debug(
|
|
7911
|
+
`recall phase-1 assembly [${name}]: timed out within shared ${enrichmentSectionDeadlineMs}ms budget at +${Date.now() - phase1Start}ms`
|
|
7912
|
+
);
|
|
7913
|
+
return fallback;
|
|
7914
|
+
}
|
|
7915
|
+
return result;
|
|
7916
|
+
} catch (err) {
|
|
7917
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
7918
|
+
log.warn(
|
|
7919
|
+
`recall phase-1 assembly [${name}] failed open: ${err instanceof Error ? err.message : String(err)}`
|
|
7920
|
+
);
|
|
7921
|
+
return fallback;
|
|
7922
|
+
}
|
|
7923
|
+
};
|
|
7640
7924
|
this.profiler.startSpan("assembly", profileTraceId);
|
|
7641
7925
|
if (sharedCtx)
|
|
7642
7926
|
this.appendRecallSection(sectionBuckets, "shared-context", sharedCtx);
|
|
@@ -7855,8 +8139,11 @@ ${lines.join("\n")}`
|
|
|
7855
8139
|
);
|
|
7856
8140
|
}
|
|
7857
8141
|
{
|
|
7858
|
-
const recentBoxes = await
|
|
7859
|
-
|
|
8142
|
+
const recentBoxes = await awaitEnrichmentSection(
|
|
8143
|
+
"memory-boxes",
|
|
8144
|
+
recentBoxesPromise
|
|
8145
|
+
);
|
|
8146
|
+
if (recentBoxes && recentBoxes.length > 0) {
|
|
7860
8147
|
const boxLines = recentBoxes.slice(0, 5).map((b) => {
|
|
7861
8148
|
const sealedDate = b.sealedAt ? b.sealedAt.slice(0, 16).replace("T", " ") : "?";
|
|
7862
8149
|
const traceNote = b.traceId ? ` [trace: ${b.traceId.slice(0, 12)}]` : "";
|
|
@@ -7986,6 +8273,7 @@ ${tmtNode.summary}`
|
|
|
7986
8273
|
workProductsSection
|
|
7987
8274
|
);
|
|
7988
8275
|
}
|
|
8276
|
+
const qmdWasSettledBeforeAssemblyWait = qmdPromise.getSettledOutcome() !== void 0;
|
|
7989
8277
|
const qmdResult = await awaitEnrichmentSection("qmd", qmdPromise);
|
|
7990
8278
|
if (qmdResult) {
|
|
7991
8279
|
const t0 = Date.now();
|
|
@@ -8032,48 +8320,69 @@ ${tmtNode.summary}`
|
|
|
8032
8320
|
graphExpandedResultPaths.clear();
|
|
8033
8321
|
} else {
|
|
8034
8322
|
try {
|
|
8035
|
-
const
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
});
|
|
8046
|
-
graphSnapshotStatus = "completed";
|
|
8047
|
-
graphDecisionStatus = "completed";
|
|
8048
|
-
graphDecisionReason = graphShadowEvalEnabled ? "graph shadow evaluation completed without altering injected context" : "graph expansion merged into recall ranking";
|
|
8049
|
-
graphSnapshotReason = graphDecisionReason;
|
|
8050
|
-
graphSnapshotSeedPaths = seedPaths;
|
|
8051
|
-
graphSnapshotExpandedPaths = expandedPaths;
|
|
8052
|
-
graphSnapshotSeedResults = this.buildGraphRecallRankedResults(
|
|
8053
|
-
seedResults,
|
|
8054
|
-
() => ["baseline"]
|
|
8055
|
-
);
|
|
8056
|
-
graphExpandedResultPaths.clear();
|
|
8057
|
-
expandedPaths.forEach(
|
|
8058
|
-
(entry) => graphExpandedResultPaths.add(entry.path)
|
|
8323
|
+
const graphExpansion = await awaitAssemblyStep(
|
|
8324
|
+
"graph-expansion",
|
|
8325
|
+
() => this.expandResultsViaGraph({
|
|
8326
|
+
memoryResults,
|
|
8327
|
+
recallNamespaces,
|
|
8328
|
+
recallResultLimit,
|
|
8329
|
+
deadlineAtMs: enrichmentAssemblyDeadlineAtMs,
|
|
8330
|
+
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
8331
|
+
}),
|
|
8332
|
+
null
|
|
8059
8333
|
);
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8334
|
+
if (!graphExpansion) {
|
|
8335
|
+
graphSnapshotStatus = "aborted";
|
|
8336
|
+
graphDecisionStatus = "aborted";
|
|
8337
|
+
graphDecisionReason = options.abortSignal?.aborted ? "graph expansion skipped because recall assembly was aborted" : "graph expansion skipped because shared post-retrieval assembly budget expired";
|
|
8338
|
+
graphSnapshotReason = graphDecisionReason;
|
|
8339
|
+
graphSnapshotSeedPaths = baselineMemoryResults.slice(0, Math.max(1, recallResultLimit)).map((result) => result.path);
|
|
8340
|
+
graphSnapshotSeedResults = this.buildGraphRecallRankedResults(
|
|
8063
8341
|
baselineMemoryResults,
|
|
8342
|
+
() => ["baseline"]
|
|
8343
|
+
);
|
|
8344
|
+
graphSnapshotExpandedPaths = [];
|
|
8345
|
+
graphExpandedResultPaths.clear();
|
|
8346
|
+
memoryResults = baselineMemoryResults;
|
|
8347
|
+
} else {
|
|
8348
|
+
const {
|
|
8064
8349
|
merged,
|
|
8065
|
-
|
|
8350
|
+
seedPaths,
|
|
8351
|
+
expandedPaths,
|
|
8352
|
+
seedResults = baselineMemoryResults
|
|
8353
|
+
} = graphExpansion;
|
|
8354
|
+
graphSnapshotStatus = "completed";
|
|
8355
|
+
graphDecisionStatus = "completed";
|
|
8356
|
+
graphDecisionReason = graphShadowEvalEnabled ? "graph shadow evaluation completed without altering injected context" : "graph expansion merged into recall ranking";
|
|
8357
|
+
graphSnapshotReason = graphDecisionReason;
|
|
8358
|
+
graphSnapshotSeedPaths = seedPaths;
|
|
8359
|
+
graphSnapshotExpandedPaths = expandedPaths;
|
|
8360
|
+
graphSnapshotSeedResults = this.buildGraphRecallRankedResults(
|
|
8361
|
+
seedResults,
|
|
8362
|
+
() => ["baseline"]
|
|
8066
8363
|
);
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8364
|
+
graphExpandedResultPaths.clear();
|
|
8365
|
+
expandedPaths.forEach(
|
|
8366
|
+
(entry) => graphExpandedResultPaths.add(entry.path)
|
|
8367
|
+
);
|
|
8368
|
+
memoryResults = graphShadowEvalEnabled ? baselineMemoryResults : merged;
|
|
8369
|
+
if (graphShadowEvalEnabled) {
|
|
8370
|
+
const comparison = summarizeGraphShadowComparison(
|
|
8371
|
+
baselineMemoryResults,
|
|
8372
|
+
merged,
|
|
8373
|
+
recallResultLimit
|
|
8374
|
+
);
|
|
8375
|
+
graphSnapshotShadowComparison = comparison;
|
|
8376
|
+
recordRecallSectionMetric({
|
|
8377
|
+
section: "graphShadow",
|
|
8378
|
+
priority: "enrichment",
|
|
8379
|
+
durationMs: Date.now() - t0,
|
|
8380
|
+
deadlineMs: enrichmentSectionDeadlineMs,
|
|
8381
|
+
source: "fresh",
|
|
8382
|
+
success: true,
|
|
8383
|
+
timing: `on b=${comparison.baselineCount} g=${comparison.graphCount} ov=${comparison.overlapCount} (${comparison.overlapRatio.toFixed(2)}) avgDelta=${comparison.averageOverlapDelta.toFixed(3)}`
|
|
8384
|
+
});
|
|
8385
|
+
}
|
|
8077
8386
|
}
|
|
8078
8387
|
} catch (err) {
|
|
8079
8388
|
graphSnapshotStatus = "aborted";
|
|
@@ -8092,12 +8401,31 @@ ${tmtNode.summary}`
|
|
|
8092
8401
|
}
|
|
8093
8402
|
}
|
|
8094
8403
|
}
|
|
8095
|
-
|
|
8404
|
+
const qmdBoostInput = await this.filterSearchResultsForRecall(
|
|
8096
8405
|
memoryResults,
|
|
8097
|
-
recallNamespaces,
|
|
8098
|
-
retrievalQuery,
|
|
8099
8406
|
void 0,
|
|
8100
|
-
{
|
|
8407
|
+
{
|
|
8408
|
+
asOfMs,
|
|
8409
|
+
// If QMD had already settled before the ordered assembly reached it,
|
|
8410
|
+
// do not let unrelated slow enrichment turn those known results into
|
|
8411
|
+
// unchecked misses. QMD that only settles during its own wait remains
|
|
8412
|
+
// bounded by the shared post-retrieval assembly deadline.
|
|
8413
|
+
deadlineAtMs: qmdWasSettledBeforeAssemblyWait ? null : enrichmentAssemblyDeadlineAtMs,
|
|
8414
|
+
abortSignal: options.abortSignal,
|
|
8415
|
+
dropUnresolved: true,
|
|
8416
|
+
recallNamespaces
|
|
8417
|
+
}
|
|
8418
|
+
);
|
|
8419
|
+
memoryResults = await awaitAssemblyStep(
|
|
8420
|
+
"qmd-boost",
|
|
8421
|
+
() => this.boostSearchResults(
|
|
8422
|
+
qmdBoostInput.results,
|
|
8423
|
+
recallNamespaces,
|
|
8424
|
+
retrievalQuery,
|
|
8425
|
+
qmdBoostInput.memoryByPath,
|
|
8426
|
+
{ asOfMs }
|
|
8427
|
+
),
|
|
8428
|
+
qmdBoostInput.results
|
|
8101
8429
|
);
|
|
8102
8430
|
if (this.config.rerankEnabled && this.config.rerankProvider === "local") {
|
|
8103
8431
|
const ranked = await rerankLocalOrNoop({
|
|
@@ -8224,39 +8552,45 @@ ${tmtNode.summary}`
|
|
|
8224
8552
|
} else if (!confidenceGateRejected) {
|
|
8225
8553
|
const queryAwarePrefilter = await queryAwarePrefilterPromise;
|
|
8226
8554
|
if (queryAwarePrefilter.candidatePaths?.size !== 0) {
|
|
8227
|
-
const
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8555
|
+
const scoped = await awaitAssemblyStep(
|
|
8556
|
+
"embedding-fallback",
|
|
8557
|
+
async () => {
|
|
8558
|
+
const embeddingResults = await this.searchEmbeddingFallback(
|
|
8559
|
+
retrievalQuery,
|
|
8560
|
+
embeddingFetchLimit
|
|
8561
|
+
);
|
|
8562
|
+
const prefilteredEmbeddingResults = applyQueryAwareCandidateFilter(
|
|
8563
|
+
embeddingResults,
|
|
8564
|
+
queryAwarePrefilter.candidatePaths
|
|
8565
|
+
);
|
|
8566
|
+
const scopedCandidates = filterRecallCandidates(
|
|
8567
|
+
prefilteredEmbeddingResults,
|
|
8568
|
+
{
|
|
8569
|
+
namespacesEnabled: this.config.namespacesEnabled,
|
|
8570
|
+
recallNamespaces,
|
|
8571
|
+
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
8572
|
+
limit: embeddingFetchLimit
|
|
8573
|
+
}
|
|
8574
|
+
);
|
|
8575
|
+
const boostedScoped = await this.boostSearchResults(
|
|
8576
|
+
scopedCandidates,
|
|
8577
|
+
recallNamespaces,
|
|
8578
|
+
retrievalQuery,
|
|
8579
|
+
void 0,
|
|
8580
|
+
{ asOfMs }
|
|
8581
|
+
);
|
|
8582
|
+
xrayBranchPoolSize.hot_embedding = Math.max(
|
|
8583
|
+
xrayBranchPoolSize.hot_embedding,
|
|
8584
|
+
boostedScoped.length
|
|
8585
|
+
);
|
|
8586
|
+
return this.diversifyAndLimitRecallResults(
|
|
8587
|
+
"memories",
|
|
8588
|
+
boostedScoped,
|
|
8589
|
+
recallResultLimit,
|
|
8590
|
+
retrievalQuery
|
|
8591
|
+
);
|
|
8592
|
+
},
|
|
8593
|
+
[]
|
|
8260
8594
|
);
|
|
8261
8595
|
if (scoped.length > 0) {
|
|
8262
8596
|
if (shouldPersistGraphSnapshot) {
|
|
@@ -8292,6 +8626,7 @@ ${tmtNode.summary}`
|
|
|
8292
8626
|
queryAwarePrefilter,
|
|
8293
8627
|
abortSignal: options.abortSignal,
|
|
8294
8628
|
xrayPoolSizeSink: xrayColdPoolSink,
|
|
8629
|
+
deadlineAtMs: enrichmentAssemblyDeadlineAtMs,
|
|
8295
8630
|
asOfMs,
|
|
8296
8631
|
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
8297
8632
|
});
|
|
@@ -8358,39 +8693,45 @@ ${tmtNode.summary}`
|
|
|
8358
8693
|
} else if (recallResultLimit > 0 && !this.qmd.isAvailable()) {
|
|
8359
8694
|
const queryAwarePrefilter = await queryAwarePrefilterPromise;
|
|
8360
8695
|
if (queryAwarePrefilter.candidatePaths?.size !== 0) {
|
|
8361
|
-
const
|
|
8362
|
-
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8696
|
+
const scoped = await awaitAssemblyStep(
|
|
8697
|
+
"embedding-fallback",
|
|
8698
|
+
async () => {
|
|
8699
|
+
const embeddingResults = await this.searchEmbeddingFallback(
|
|
8700
|
+
retrievalQuery,
|
|
8701
|
+
embeddingFetchLimit
|
|
8702
|
+
);
|
|
8703
|
+
const prefilteredEmbeddingResults = applyQueryAwareCandidateFilter(
|
|
8704
|
+
embeddingResults,
|
|
8705
|
+
queryAwarePrefilter.candidatePaths
|
|
8706
|
+
);
|
|
8707
|
+
const scopedCandidates = filterRecallCandidates(
|
|
8708
|
+
prefilteredEmbeddingResults,
|
|
8709
|
+
{
|
|
8710
|
+
namespacesEnabled: this.config.namespacesEnabled,
|
|
8711
|
+
recallNamespaces,
|
|
8712
|
+
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
8713
|
+
limit: embeddingFetchLimit
|
|
8714
|
+
}
|
|
8715
|
+
);
|
|
8716
|
+
const boostedScoped = await this.boostSearchResults(
|
|
8717
|
+
scopedCandidates,
|
|
8718
|
+
recallNamespaces,
|
|
8719
|
+
retrievalQuery,
|
|
8720
|
+
void 0,
|
|
8721
|
+
{ asOfMs }
|
|
8722
|
+
);
|
|
8723
|
+
xrayBranchPoolSize.hot_embedding = Math.max(
|
|
8724
|
+
xrayBranchPoolSize.hot_embedding,
|
|
8725
|
+
boostedScoped.length
|
|
8726
|
+
);
|
|
8727
|
+
return this.diversifyAndLimitRecallResults(
|
|
8728
|
+
"memories",
|
|
8729
|
+
boostedScoped,
|
|
8730
|
+
recallResultLimit,
|
|
8731
|
+
retrievalQuery
|
|
8732
|
+
);
|
|
8733
|
+
},
|
|
8734
|
+
[]
|
|
8394
8735
|
);
|
|
8395
8736
|
if (scoped.length > 0) {
|
|
8396
8737
|
if (shouldPersistGraphSnapshot) {
|
|
@@ -8418,7 +8759,11 @@ ${tmtNode.summary}`
|
|
|
8418
8759
|
xrayRecalledResults = scoped;
|
|
8419
8760
|
impressionRecorded = true;
|
|
8420
8761
|
} else {
|
|
8421
|
-
const memories = await
|
|
8762
|
+
const memories = await awaitAssemblyStep(
|
|
8763
|
+
"recent-memory-read",
|
|
8764
|
+
() => this.readAllMemoriesForNamespaces(recallNamespaces),
|
|
8765
|
+
[]
|
|
8766
|
+
);
|
|
8422
8767
|
if (memories.length > 0) {
|
|
8423
8768
|
const supersessionOptions = {
|
|
8424
8769
|
enabled: this.config.temporalSupersessionEnabled,
|
|
@@ -8449,6 +8794,7 @@ ${tmtNode.summary}`
|
|
|
8449
8794
|
queryAwarePrefilter,
|
|
8450
8795
|
abortSignal: options.abortSignal,
|
|
8451
8796
|
xrayPoolSizeSink: xrayColdPoolSink,
|
|
8797
|
+
deadlineAtMs: enrichmentAssemblyDeadlineAtMs,
|
|
8452
8798
|
asOfMs,
|
|
8453
8799
|
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
8454
8800
|
});
|
|
@@ -8473,36 +8819,42 @@ ${tmtNode.summary}`
|
|
|
8473
8819
|
impressionRecorded = true;
|
|
8474
8820
|
}
|
|
8475
8821
|
} else {
|
|
8476
|
-
const
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8502
|
-
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8822
|
+
const recent = await awaitAssemblyStep(
|
|
8823
|
+
"recent-memory-scan",
|
|
8824
|
+
async () => {
|
|
8825
|
+
const recentSorted = queryAwareScopedMemories.sort(
|
|
8826
|
+
(a, b) => new Date(b.frontmatter.updated).getTime() - new Date(a.frontmatter.updated).getTime()
|
|
8827
|
+
);
|
|
8828
|
+
const preloadedMap = new Map(
|
|
8829
|
+
queryAwareScopedMemories.filter((m) => m.path).map((m) => [m.path, m])
|
|
8830
|
+
);
|
|
8831
|
+
const recentAsResults = recentSorted.map(
|
|
8832
|
+
(m, i) => ({
|
|
8833
|
+
docid: m.frontmatter.id,
|
|
8834
|
+
path: m.path,
|
|
8835
|
+
snippet: m.content,
|
|
8836
|
+
score: 1 - i / Math.max(recentSorted.length, 1)
|
|
8837
|
+
})
|
|
8838
|
+
);
|
|
8839
|
+
const boostedRecent = (await this.boostSearchResults(
|
|
8840
|
+
recentAsResults,
|
|
8841
|
+
recallNamespaces,
|
|
8842
|
+
retrievalQuery,
|
|
8843
|
+
preloadedMap,
|
|
8844
|
+
{ asOfMs }
|
|
8845
|
+
)).sort((a, b) => b.score - a.score);
|
|
8846
|
+
xrayBranchPoolSize.recent_scan = Math.max(
|
|
8847
|
+
xrayBranchPoolSize.recent_scan,
|
|
8848
|
+
boostedRecent.length
|
|
8849
|
+
);
|
|
8850
|
+
return this.diversifyAndLimitRecallResults(
|
|
8851
|
+
"memories",
|
|
8852
|
+
boostedRecent,
|
|
8853
|
+
recallResultLimit,
|
|
8854
|
+
retrievalQuery
|
|
8855
|
+
);
|
|
8856
|
+
},
|
|
8857
|
+
[]
|
|
8506
8858
|
);
|
|
8507
8859
|
if (recent.length > 0) {
|
|
8508
8860
|
if (shouldPersistGraphSnapshot) {
|
|
@@ -8538,6 +8890,7 @@ ${tmtNode.summary}`
|
|
|
8538
8890
|
queryAwarePrefilter,
|
|
8539
8891
|
abortSignal: options.abortSignal,
|
|
8540
8892
|
xrayPoolSizeSink: xrayColdPoolSink,
|
|
8893
|
+
deadlineAtMs: enrichmentAssemblyDeadlineAtMs,
|
|
8541
8894
|
asOfMs,
|
|
8542
8895
|
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
8543
8896
|
});
|
|
@@ -8578,6 +8931,7 @@ ${tmtNode.summary}`
|
|
|
8578
8931
|
queryAwarePrefilter,
|
|
8579
8932
|
abortSignal: options.abortSignal,
|
|
8580
8933
|
xrayPoolSizeSink: xrayColdPoolSink,
|
|
8934
|
+
deadlineAtMs: enrichmentAssemblyDeadlineAtMs,
|
|
8581
8935
|
asOfMs,
|
|
8582
8936
|
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
8583
8937
|
});
|
|
@@ -8872,6 +9226,7 @@ _Context: ${topQuestion.context}_`
|
|
|
8872
9226
|
query: retrievalQuery,
|
|
8873
9227
|
memoryIds: recalledMemoryIds,
|
|
8874
9228
|
namespace: selfNamespace,
|
|
9229
|
+
recallNamespaces,
|
|
8875
9230
|
traceId,
|
|
8876
9231
|
plannerMode: recallMode,
|
|
8877
9232
|
requestedMode,
|
|
@@ -12268,6 +12623,212 @@ ${lines.join("\n\n")}`;
|
|
|
12268
12623
|
*
|
|
12269
12624
|
* Callers must pass the full candidate pool (post-rerank, pre-slice).
|
|
12270
12625
|
*/
|
|
12626
|
+
qmdCollectionNamespaceFromPrefix(collectionPrefix) {
|
|
12627
|
+
const baseCollection = this.config.qmdCollection;
|
|
12628
|
+
if (collectionPrefix === baseCollection) return this.config.defaultNamespace;
|
|
12629
|
+
const namespaceSuffix = collectionPrefix.startsWith(`${baseCollection}--`) ? collectionPrefix.slice(baseCollection.length + 2) : "";
|
|
12630
|
+
if (!namespaceSuffix) return null;
|
|
12631
|
+
const decoded = namespaceIdentityFromToken(namespaceSuffix);
|
|
12632
|
+
if (decoded !== null) return decoded || this.config.defaultNamespace;
|
|
12633
|
+
if (namespaceSuffix.startsWith("ns--")) {
|
|
12634
|
+
const legacyNamespace = namespaceSuffix.slice("ns--".length).trim();
|
|
12635
|
+
return legacyNamespace || null;
|
|
12636
|
+
}
|
|
12637
|
+
return null;
|
|
12638
|
+
}
|
|
12639
|
+
async readQmdResultMemory(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
12640
|
+
const parts = qmdCollectionPathParts(resultPath);
|
|
12641
|
+
const storageDirFor = (storage) => typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
12642
|
+
const fallbackStorageDir = storageDirFor(fallbackStorage);
|
|
12643
|
+
const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
12644
|
+
if (parts && parts.collection === coldCollection) {
|
|
12645
|
+
const storages = [];
|
|
12646
|
+
const seenStorageDirs = /* @__PURE__ */ new Set();
|
|
12647
|
+
const addStorage = (storage) => {
|
|
12648
|
+
const storageDir = storageDirFor(storage);
|
|
12649
|
+
const storageKey = storageDir ? path2.resolve(storageDir) : `storage-without-dir-${storages.length}`;
|
|
12650
|
+
if (seenStorageDirs.has(storageKey)) return;
|
|
12651
|
+
seenStorageDirs.add(storageKey);
|
|
12652
|
+
storages.push(storage);
|
|
12653
|
+
};
|
|
12654
|
+
const fallbackNamespace = fallbackStorageDir !== null ? this.namespaceFromStorageDir(fallbackStorageDir) : this.config.defaultNamespace;
|
|
12655
|
+
if (recallNamespaces.length === 0 || !this.config.namespacesEnabled || recallNamespaces.includes(fallbackNamespace)) {
|
|
12656
|
+
addStorage(fallbackStorage);
|
|
12657
|
+
}
|
|
12658
|
+
if (recallNamespaces.length > 0) {
|
|
12659
|
+
for (const namespace of recallNamespaces) {
|
|
12660
|
+
try {
|
|
12661
|
+
addStorage(await this.storageRouter.storageFor(namespace));
|
|
12662
|
+
} catch (err) {
|
|
12663
|
+
log.debug("qmd cold result namespace storage lookup skipped", {
|
|
12664
|
+
path: resultPath,
|
|
12665
|
+
namespace,
|
|
12666
|
+
error: err.message
|
|
12667
|
+
});
|
|
12668
|
+
}
|
|
12669
|
+
}
|
|
12670
|
+
}
|
|
12671
|
+
for (const storage of storages) {
|
|
12672
|
+
const storageDir = storageDirFor(storage);
|
|
12673
|
+
if (!storageDir) {
|
|
12674
|
+
const memory = await storage.readMemoryByPath(resultPath);
|
|
12675
|
+
if (memory) return memory;
|
|
12676
|
+
continue;
|
|
12677
|
+
}
|
|
12678
|
+
try {
|
|
12679
|
+
const coldRoot = path2.join(storageDir, "cold");
|
|
12680
|
+
for (const candidate of qmdResultPathCandidates(
|
|
12681
|
+
coldRoot,
|
|
12682
|
+
parts.relativePath
|
|
12683
|
+
)) {
|
|
12684
|
+
const memory = await storage.readMemoryByPath(candidate);
|
|
12685
|
+
if (memory) return memory;
|
|
12686
|
+
}
|
|
12687
|
+
} catch (err) {
|
|
12688
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
12689
|
+
log.debug("qmd cold result path lookup failed open", {
|
|
12690
|
+
path: resultPath,
|
|
12691
|
+
collection: coldCollection,
|
|
12692
|
+
error: err.message
|
|
12693
|
+
});
|
|
12694
|
+
}
|
|
12695
|
+
}
|
|
12696
|
+
return null;
|
|
12697
|
+
}
|
|
12698
|
+
const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
|
|
12699
|
+
if (parts && collectionNamespace) {
|
|
12700
|
+
try {
|
|
12701
|
+
const collectionStorage = await this.storageRouter.storageFor(collectionNamespace);
|
|
12702
|
+
for (const candidate of qmdResultPathCandidates(
|
|
12703
|
+
collectionStorage.dir,
|
|
12704
|
+
parts.relativePath
|
|
12705
|
+
)) {
|
|
12706
|
+
const memory = await collectionStorage.readMemoryByPath(candidate);
|
|
12707
|
+
if (memory) return memory;
|
|
12708
|
+
}
|
|
12709
|
+
return null;
|
|
12710
|
+
} catch (err) {
|
|
12711
|
+
if (err instanceof SecureStoreLockedError) throw err;
|
|
12712
|
+
log.debug("qmd result namespace path lookup failed open", {
|
|
12713
|
+
path: resultPath,
|
|
12714
|
+
namespace: collectionNamespace,
|
|
12715
|
+
error: err.message
|
|
12716
|
+
});
|
|
12717
|
+
return null;
|
|
12718
|
+
}
|
|
12719
|
+
}
|
|
12720
|
+
if (path2.isAbsolute(resultPath)) {
|
|
12721
|
+
if (!fallbackStorageDir) {
|
|
12722
|
+
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
12723
|
+
}
|
|
12724
|
+
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
12725
|
+
resultPath,
|
|
12726
|
+
fallbackStorage,
|
|
12727
|
+
recallNamespaces
|
|
12728
|
+
);
|
|
12729
|
+
if (!ownerStorage) return null;
|
|
12730
|
+
for (const candidate of qmdResultPathCandidates(
|
|
12731
|
+
ownerStorage.dir,
|
|
12732
|
+
resultPath
|
|
12733
|
+
)) {
|
|
12734
|
+
const memory = await ownerStorage.storage.readMemoryByPath(candidate);
|
|
12735
|
+
if (memory) return memory;
|
|
12736
|
+
}
|
|
12737
|
+
return null;
|
|
12738
|
+
}
|
|
12739
|
+
if (!fallbackStorageDir) {
|
|
12740
|
+
return await fallbackStorage.readMemoryByPath(resultPath);
|
|
12741
|
+
}
|
|
12742
|
+
for (const candidate of qmdResultPathCandidates(
|
|
12743
|
+
fallbackStorageDir,
|
|
12744
|
+
resultPath
|
|
12745
|
+
)) {
|
|
12746
|
+
const memory = await fallbackStorage.readMemoryByPath(candidate);
|
|
12747
|
+
if (memory) return memory;
|
|
12748
|
+
}
|
|
12749
|
+
return null;
|
|
12750
|
+
}
|
|
12751
|
+
async resolveColdQmdResultForRecall(result, fallbackStorage, recallNamespaces = []) {
|
|
12752
|
+
const memory = await this.readQmdResultMemory(
|
|
12753
|
+
result.path,
|
|
12754
|
+
fallbackStorage,
|
|
12755
|
+
recallNamespaces
|
|
12756
|
+
);
|
|
12757
|
+
if (!memory) return null;
|
|
12758
|
+
let ownerNamespace = null;
|
|
12759
|
+
if (path2.isAbsolute(memory.path)) {
|
|
12760
|
+
const ownerStorage = await this.storageForAbsoluteQmdResultPath(
|
|
12761
|
+
memory.path,
|
|
12762
|
+
fallbackStorage,
|
|
12763
|
+
recallNamespaces
|
|
12764
|
+
);
|
|
12765
|
+
ownerNamespace = ownerStorage?.namespace ?? null;
|
|
12766
|
+
if (!ownerNamespace && this.config.namespacesEnabled) return null;
|
|
12767
|
+
}
|
|
12768
|
+
ownerNamespace ??= this.namespaceFromPath(memory.path);
|
|
12769
|
+
if (recallNamespaces.length > 0 && !recallNamespaces.includes(ownerNamespace)) {
|
|
12770
|
+
return null;
|
|
12771
|
+
}
|
|
12772
|
+
return {
|
|
12773
|
+
namespace: ownerNamespace,
|
|
12774
|
+
result: {
|
|
12775
|
+
...result,
|
|
12776
|
+
docid: result.docid || memory.frontmatter.id,
|
|
12777
|
+
path: memory.path,
|
|
12778
|
+
snippet: result.snippet || memory.content.slice(0, 400)
|
|
12779
|
+
}
|
|
12780
|
+
};
|
|
12781
|
+
}
|
|
12782
|
+
async storageForAbsoluteQmdResultPath(resultPath, fallbackStorage, recallNamespaces = []) {
|
|
12783
|
+
const resolvedPath = path2.resolve(resultPath);
|
|
12784
|
+
const memoryRoot = path2.resolve(this.config.memoryDir);
|
|
12785
|
+
const namespacesRoot = path2.join(memoryRoot, "namespaces");
|
|
12786
|
+
const fallbackStorageDir = typeof fallbackStorage.dir === "string" && fallbackStorage.dir ? fallbackStorage.dir : null;
|
|
12787
|
+
const matches = [];
|
|
12788
|
+
const seenDirs = /* @__PURE__ */ new Set();
|
|
12789
|
+
const maybeAddStorage = (storage, namespace) => {
|
|
12790
|
+
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
12791
|
+
if (!storageDir) return;
|
|
12792
|
+
const candidateRoot = path2.resolve(storageDir);
|
|
12793
|
+
if (seenDirs.has(candidateRoot)) return;
|
|
12794
|
+
if (!isPathInsideStorageRoot(candidateRoot, resolvedPath)) return;
|
|
12795
|
+
if (candidateRoot === memoryRoot && isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
12796
|
+
return;
|
|
12797
|
+
}
|
|
12798
|
+
seenDirs.add(candidateRoot);
|
|
12799
|
+
matches.push({ storage, dir: candidateRoot, namespace });
|
|
12800
|
+
};
|
|
12801
|
+
const fallbackNamespace = fallbackStorageDir !== null ? this.namespaceFromStorageDir(fallbackStorageDir) : this.config.defaultNamespace;
|
|
12802
|
+
maybeAddStorage(fallbackStorage, fallbackNamespace);
|
|
12803
|
+
const candidateNamespaces = /* @__PURE__ */ new Set();
|
|
12804
|
+
candidateNamespaces.add(this.config.defaultNamespace);
|
|
12805
|
+
candidateNamespaces.add(this.config.sharedNamespace);
|
|
12806
|
+
for (const ns of recallNamespaces) {
|
|
12807
|
+
candidateNamespaces.add(ns);
|
|
12808
|
+
}
|
|
12809
|
+
if (isPathInsideStorageRoot(namespacesRoot, resolvedPath)) {
|
|
12810
|
+
const relativeToNamespaces = path2.relative(namespacesRoot, resolvedPath);
|
|
12811
|
+
const [namespaceSegment] = relativeToNamespaces.split(/[\\/]/);
|
|
12812
|
+
if (namespaceSegment) {
|
|
12813
|
+
candidateNamespaces.add(
|
|
12814
|
+
namespaceIdentityFromToken(namespaceSegment) ?? namespaceSegment
|
|
12815
|
+
);
|
|
12816
|
+
}
|
|
12817
|
+
}
|
|
12818
|
+
for (const policy of this.config.namespacePolicies ?? []) {
|
|
12819
|
+
candidateNamespaces.add(policy.name);
|
|
12820
|
+
}
|
|
12821
|
+
for (const ns of candidateNamespaces) {
|
|
12822
|
+
if (!ns) continue;
|
|
12823
|
+
try {
|
|
12824
|
+
maybeAddStorage(await this.storageRouter.storageFor(ns), ns);
|
|
12825
|
+
} catch {
|
|
12826
|
+
continue;
|
|
12827
|
+
}
|
|
12828
|
+
}
|
|
12829
|
+
matches.sort((a, b) => b.dir.length - a.dir.length);
|
|
12830
|
+
return matches[0] ?? null;
|
|
12831
|
+
}
|
|
12271
12832
|
async applyMemoryWorthRerank(results, namespaces) {
|
|
12272
12833
|
const counters = /* @__PURE__ */ new Map();
|
|
12273
12834
|
const seenNamespaces = /* @__PURE__ */ new Set();
|
|
@@ -12312,7 +12873,7 @@ ${lines.join("\n\n")}`;
|
|
|
12312
12873
|
if (reader) {
|
|
12313
12874
|
for (const r of missing) {
|
|
12314
12875
|
try {
|
|
12315
|
-
const memory = await
|
|
12876
|
+
const memory = await this.readQmdResultMemory(r.path, reader, namespaces);
|
|
12316
12877
|
if (!memory) continue;
|
|
12317
12878
|
const fm = memory.frontmatter;
|
|
12318
12879
|
if (fm.mw_success === void 0 && fm.mw_fail === void 0) continue;
|
|
@@ -12560,6 +13121,41 @@ ${lines.join("\n\n")}`;
|
|
|
12560
13121
|
if (options.xrayPoolSizeSink) options.xrayPoolSizeSink.size = 0;
|
|
12561
13122
|
return [];
|
|
12562
13123
|
}
|
|
13124
|
+
const deadlineRemainingMs = () => typeof options.deadlineAtMs === "number" ? Math.max(0, options.deadlineAtMs - Date.now()) : null;
|
|
13125
|
+
const runColdStepWithinDeadline = async (label, fallback, task) => {
|
|
13126
|
+
throwIfRecallAborted(options.abortSignal);
|
|
13127
|
+
const remainingMs = deadlineRemainingMs();
|
|
13128
|
+
if (remainingMs === 0) {
|
|
13129
|
+
log.debug(`cold-tier recall ${label} skipped: shared assembly deadline expired`);
|
|
13130
|
+
return fallback;
|
|
13131
|
+
}
|
|
13132
|
+
if (remainingMs === null) return task();
|
|
13133
|
+
let timeoutHandle;
|
|
13134
|
+
let timedOut = false;
|
|
13135
|
+
const taskPromise = task().catch((err) => {
|
|
13136
|
+
if (timedOut) {
|
|
13137
|
+
log.debug(`cold-tier recall ${label} failed after deadline: ${err}`);
|
|
13138
|
+
return fallback;
|
|
13139
|
+
}
|
|
13140
|
+
throw err;
|
|
13141
|
+
});
|
|
13142
|
+
try {
|
|
13143
|
+
return await Promise.race([
|
|
13144
|
+
taskPromise,
|
|
13145
|
+
new Promise((resolve) => {
|
|
13146
|
+
timeoutHandle = setTimeout(() => {
|
|
13147
|
+
timedOut = true;
|
|
13148
|
+
log.debug(
|
|
13149
|
+
`cold-tier recall ${label} skipped: shared assembly deadline expired`
|
|
13150
|
+
);
|
|
13151
|
+
resolve(fallback);
|
|
13152
|
+
}, remainingMs);
|
|
13153
|
+
})
|
|
13154
|
+
]);
|
|
13155
|
+
} finally {
|
|
13156
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
13157
|
+
}
|
|
13158
|
+
};
|
|
12563
13159
|
const coldQmdEnabled = this.config.qmdColdTierEnabled === true;
|
|
12564
13160
|
const coldCollection = this.config.qmdColdCollection ?? "openclaw-engram-cold";
|
|
12565
13161
|
const coldMaxResults = this.config.qmdColdMaxResults ?? this.config.qmdMaxResults;
|
|
@@ -12575,19 +13171,23 @@ ${lines.join("\n\n")}`;
|
|
|
12575
13171
|
false,
|
|
12576
13172
|
0
|
|
12577
13173
|
);
|
|
12578
|
-
longTerm = await
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
13174
|
+
longTerm = await runColdStepWithinDeadline(
|
|
13175
|
+
"qmd lookup",
|
|
13176
|
+
[],
|
|
13177
|
+
() => this.fetchQmdMemoryResultsWithArtifactTopUp(
|
|
13178
|
+
options.prompt,
|
|
13179
|
+
coldFetchLimit,
|
|
13180
|
+
coldHybridLimit,
|
|
13181
|
+
{
|
|
13182
|
+
namespacesEnabled: this.config.namespacesEnabled,
|
|
13183
|
+
recallNamespaces: options.recallNamespaces,
|
|
13184
|
+
resolveNamespace: (p) => this.namespaceFromPath(p),
|
|
13185
|
+
collection: coldCollection,
|
|
13186
|
+
queryAwarePrefilter: options.queryAwarePrefilter,
|
|
13187
|
+
searchOptions: this.buildConfiguredQmdSearchOptions(options.prompt),
|
|
13188
|
+
abortSignal: options.abortSignal
|
|
13189
|
+
}
|
|
13190
|
+
)
|
|
12591
13191
|
);
|
|
12592
13192
|
if (longTerm.length > 0) {
|
|
12593
13193
|
log.debug(
|
|
@@ -12597,12 +13197,16 @@ ${lines.join("\n\n")}`;
|
|
|
12597
13197
|
}
|
|
12598
13198
|
}
|
|
12599
13199
|
if (longTerm.length === 0) {
|
|
12600
|
-
longTerm = await
|
|
12601
|
-
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
13200
|
+
longTerm = await runColdStepWithinDeadline(
|
|
13201
|
+
"archive scan",
|
|
13202
|
+
[],
|
|
13203
|
+
() => this.searchLongTermArchiveFallback(
|
|
13204
|
+
options.prompt,
|
|
13205
|
+
options.recallNamespaces,
|
|
13206
|
+
options.recallResultLimit,
|
|
13207
|
+
options.queryAwarePrefilter,
|
|
13208
|
+
options.abortSignal
|
|
13209
|
+
)
|
|
12606
13210
|
);
|
|
12607
13211
|
if (longTerm.length > 0) {
|
|
12608
13212
|
log.debug("cold-tier recall source=archive-scan");
|
|
@@ -12611,9 +13215,51 @@ ${lines.join("\n\n")}`;
|
|
|
12611
13215
|
if (longTerm.length === 0) return [];
|
|
12612
13216
|
let results = longTerm;
|
|
12613
13217
|
if (this.config.namespacesEnabled) {
|
|
12614
|
-
|
|
12615
|
-
|
|
12616
|
-
)
|
|
13218
|
+
const recallRoots = [];
|
|
13219
|
+
const seenRecallRoots = /* @__PURE__ */ new Set();
|
|
13220
|
+
for (const namespace of options.recallNamespaces) {
|
|
13221
|
+
try {
|
|
13222
|
+
const storage = await this.storageRouter.storageFor(namespace);
|
|
13223
|
+
const storageDir = typeof storage.dir === "string" && storage.dir ? storage.dir : null;
|
|
13224
|
+
if (!storageDir) continue;
|
|
13225
|
+
const recallRoot = path2.resolve(storageDir);
|
|
13226
|
+
if (seenRecallRoots.has(recallRoot)) continue;
|
|
13227
|
+
seenRecallRoots.add(recallRoot);
|
|
13228
|
+
recallRoots.push(recallRoot);
|
|
13229
|
+
} catch (err) {
|
|
13230
|
+
log.debug("cold-tier recall namespace root lookup skipped", {
|
|
13231
|
+
namespace,
|
|
13232
|
+
error: err.message
|
|
13233
|
+
});
|
|
13234
|
+
}
|
|
13235
|
+
}
|
|
13236
|
+
const scopedResults = [];
|
|
13237
|
+
for (const result of results) {
|
|
13238
|
+
if (options.abortSignal?.aborted || deadlineRemainingMs() === 0) break;
|
|
13239
|
+
const parts = qmdCollectionPathParts(result.path);
|
|
13240
|
+
if (parts?.collection === coldCollection) {
|
|
13241
|
+
const resolvedCold = await this.resolveColdQmdResultForRecall(
|
|
13242
|
+
result,
|
|
13243
|
+
this.storage,
|
|
13244
|
+
options.recallNamespaces
|
|
13245
|
+
);
|
|
13246
|
+
if (resolvedCold) scopedResults.push(resolvedCold.result);
|
|
13247
|
+
continue;
|
|
13248
|
+
}
|
|
13249
|
+
if (path2.isAbsolute(result.path)) {
|
|
13250
|
+
const resolvedPath = path2.resolve(result.path);
|
|
13251
|
+
if (recallRoots.some(
|
|
13252
|
+
(recallRoot) => isPathInsideStorageRoot(recallRoot, resolvedPath)
|
|
13253
|
+
)) {
|
|
13254
|
+
scopedResults.push(result);
|
|
13255
|
+
}
|
|
13256
|
+
continue;
|
|
13257
|
+
}
|
|
13258
|
+
if (options.recallNamespaces.includes(this.namespaceFromPath(result.path))) {
|
|
13259
|
+
scopedResults.push(result);
|
|
13260
|
+
}
|
|
13261
|
+
}
|
|
13262
|
+
results = scopedResults;
|
|
12617
13263
|
}
|
|
12618
13264
|
results = results.filter((r) => !isArtifactMemoryPath(r.path));
|
|
12619
13265
|
if (results.length === 0) return [];
|
|
@@ -12624,17 +13270,64 @@ ${lines.join("\n\n")}`;
|
|
|
12624
13270
|
memoryResults: results,
|
|
12625
13271
|
recallNamespaces: options.recallNamespaces,
|
|
12626
13272
|
recallResultLimit: options.recallResultLimit,
|
|
13273
|
+
deadlineAtMs: options.deadlineAtMs,
|
|
12627
13274
|
...options.includeLowConfidence === true ? { includeLowConfidence: true } : {}
|
|
12628
13275
|
});
|
|
12629
13276
|
results = merged;
|
|
12630
13277
|
}
|
|
12631
|
-
|
|
13278
|
+
const boostInput = await this.filterSearchResultsForRecall(
|
|
12632
13279
|
results,
|
|
12633
|
-
options.recallNamespaces,
|
|
12634
|
-
options.prompt,
|
|
12635
13280
|
void 0,
|
|
12636
|
-
{
|
|
13281
|
+
{
|
|
13282
|
+
allowLifecycleFiltered: true,
|
|
13283
|
+
asOfMs: options.asOfMs,
|
|
13284
|
+
deadlineAtMs: options.deadlineAtMs,
|
|
13285
|
+
abortSignal: options.abortSignal,
|
|
13286
|
+
dropUnresolved: true,
|
|
13287
|
+
recallNamespaces: options.recallNamespaces
|
|
13288
|
+
}
|
|
12637
13289
|
);
|
|
13290
|
+
results = boostInput.results;
|
|
13291
|
+
const boostTimeoutMs = typeof options.deadlineAtMs === "number" ? Math.max(0, options.deadlineAtMs - Date.now()) : null;
|
|
13292
|
+
if (boostTimeoutMs !== 0) {
|
|
13293
|
+
let timeoutHandle;
|
|
13294
|
+
try {
|
|
13295
|
+
const boosted = await (boostTimeoutMs !== null ? Promise.race([
|
|
13296
|
+
this.boostSearchResults(
|
|
13297
|
+
boostInput.results,
|
|
13298
|
+
options.recallNamespaces,
|
|
13299
|
+
options.prompt,
|
|
13300
|
+
boostInput.memoryByPath,
|
|
13301
|
+
{ allowLifecycleFiltered: true, asOfMs: options.asOfMs }
|
|
13302
|
+
),
|
|
13303
|
+
new Promise((resolve) => {
|
|
13304
|
+
timeoutHandle = setTimeout(
|
|
13305
|
+
() => resolve({ status: "timed_out" }),
|
|
13306
|
+
boostTimeoutMs
|
|
13307
|
+
);
|
|
13308
|
+
})
|
|
13309
|
+
]) : this.boostSearchResults(
|
|
13310
|
+
boostInput.results,
|
|
13311
|
+
options.recallNamespaces,
|
|
13312
|
+
options.prompt,
|
|
13313
|
+
boostInput.memoryByPath,
|
|
13314
|
+
{ allowLifecycleFiltered: true, asOfMs: options.asOfMs }
|
|
13315
|
+
));
|
|
13316
|
+
if (typeof boosted === "object" && boosted !== null && "status" in boosted && boosted.status === "timed_out") {
|
|
13317
|
+
log.debug("cold-tier recall boost skipped: shared assembly deadline expired");
|
|
13318
|
+
} else if (Array.isArray(boosted)) {
|
|
13319
|
+
results = boosted;
|
|
13320
|
+
} else {
|
|
13321
|
+
results = boostInput.results;
|
|
13322
|
+
}
|
|
13323
|
+
} catch (err) {
|
|
13324
|
+
log.debug(`cold-tier recall boost failed open: ${err}`);
|
|
13325
|
+
} finally {
|
|
13326
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
13327
|
+
}
|
|
13328
|
+
} else {
|
|
13329
|
+
log.debug("cold-tier recall boost skipped: shared assembly deadline already expired");
|
|
13330
|
+
}
|
|
12638
13331
|
if (this.config.rerankEnabled && this.config.rerankProvider === "local") {
|
|
12639
13332
|
const ranked = await rerankLocalOrNoop({
|
|
12640
13333
|
query: options.prompt,
|
|
@@ -12755,64 +13448,101 @@ ${lines.join("\n\n")}`;
|
|
|
12755
13448
|
this.accessTrackingBuffer.clear();
|
|
12756
13449
|
log.debug(`flushed ${entries.length} access tracking entries`);
|
|
12757
13450
|
}
|
|
12758
|
-
|
|
12759
|
-
* Apply recency, access count, and importance boosting to QMD search results.
|
|
12760
|
-
* Returns re-ranked results.
|
|
12761
|
-
*/
|
|
12762
|
-
async boostSearchResults(results, _recallNamespaces, prompt, preloadedMemoryMap, options) {
|
|
12763
|
-
if (results.length === 0) return results;
|
|
12764
|
-
const now = Date.now();
|
|
13451
|
+
async loadSearchResultMemoryMap(results, preloadedMemoryMap, options) {
|
|
12765
13452
|
const memoryByPath = preloadedMemoryMap ? new Map(preloadedMemoryMap) : /* @__PURE__ */ new Map();
|
|
12766
|
-
const
|
|
12767
|
-
|
|
12768
|
-
)
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
if (
|
|
12773
|
-
|
|
13453
|
+
const checkedPaths = /* @__PURE__ */ new Set();
|
|
13454
|
+
const unreadablePaths = /* @__PURE__ */ new Set();
|
|
13455
|
+
const markChecked = (result) => {
|
|
13456
|
+
if (result.path) checkedPaths.add(result.path);
|
|
13457
|
+
};
|
|
13458
|
+
const markUnreadable = (result, err) => {
|
|
13459
|
+
if (!result.path) return;
|
|
13460
|
+
checkedPaths.add(result.path);
|
|
13461
|
+
unreadablePaths.add(result.path);
|
|
13462
|
+
log.warn("recall safety filter dropped unreadable secure-store candidate", {
|
|
13463
|
+
path: result.path,
|
|
13464
|
+
error: err.message
|
|
13465
|
+
});
|
|
13466
|
+
};
|
|
13467
|
+
const deadlineExpired = () => typeof options?.deadlineAtMs === "number" && Date.now() >= options.deadlineAtMs;
|
|
13468
|
+
if (options?.deadlineAtMs == null) {
|
|
13469
|
+
const batchSize = options?.abortSignal ? 16 : results.length;
|
|
13470
|
+
for (let offset = 0; offset < results.length; offset += batchSize) {
|
|
13471
|
+
if (options?.abortSignal?.aborted) {
|
|
13472
|
+
return {
|
|
13473
|
+
memoryByPath,
|
|
13474
|
+
checkedPaths,
|
|
13475
|
+
unreadablePaths,
|
|
13476
|
+
completed: false
|
|
13477
|
+
};
|
|
13478
|
+
}
|
|
13479
|
+
await Promise.all(
|
|
13480
|
+
results.slice(offset, offset + batchSize).map(async (r) => {
|
|
13481
|
+
if (!r.path) return;
|
|
13482
|
+
if (memoryByPath.has(r.path)) {
|
|
13483
|
+
markChecked(r);
|
|
13484
|
+
return;
|
|
13485
|
+
}
|
|
13486
|
+
try {
|
|
13487
|
+
const mem = await this.readQmdResultMemory(
|
|
13488
|
+
r.path,
|
|
13489
|
+
this.storage,
|
|
13490
|
+
options?.recallNamespaces
|
|
13491
|
+
);
|
|
13492
|
+
markChecked(r);
|
|
13493
|
+
if (mem) memoryByPath.set(r.path, mem);
|
|
13494
|
+
} catch (err) {
|
|
13495
|
+
if (err instanceof SecureStoreLockedError) {
|
|
13496
|
+
markUnreadable(r, err);
|
|
13497
|
+
return;
|
|
13498
|
+
}
|
|
13499
|
+
throw err;
|
|
13500
|
+
}
|
|
13501
|
+
})
|
|
13502
|
+
);
|
|
12774
13503
|
}
|
|
12775
|
-
|
|
13504
|
+
return { memoryByPath, checkedPaths, unreadablePaths, completed: true };
|
|
12776
13505
|
}
|
|
12777
|
-
const
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
if (mem) memoryByPath.set(r.path, mem);
|
|
12783
|
-
})
|
|
12784
|
-
),
|
|
12785
|
-
temporalFromDate !== null ? queryByDateRangeAsync(this.config.memoryDir, temporalFromDate) : Promise.resolve(null),
|
|
12786
|
-
promptTags.length > 0 ? queryByTagsAsync(this.config.memoryDir, promptTags) : Promise.resolve(null)
|
|
12787
|
-
]);
|
|
12788
|
-
const queryIntent = this.config.intentRoutingEnabled && prompt ? inferIntentFromText(prompt) : null;
|
|
12789
|
-
let temporalCandidates = null;
|
|
12790
|
-
let tagCandidates = null;
|
|
12791
|
-
if (this.config.queryAwareIndexingEnabled && prompt) {
|
|
12792
|
-
const maxCandidates = this.config.queryAwareIndexingMaxCandidates;
|
|
12793
|
-
const capSet = (s) => {
|
|
12794
|
-
if (!s) return null;
|
|
12795
|
-
const scoped = new Set(Array.from(s).filter((p) => resultPaths.has(p)));
|
|
12796
|
-
if (maxCandidates === 0 || scoped.size <= maxCandidates)
|
|
12797
|
-
return scoped;
|
|
12798
|
-
return new Set(Array.from(scoped).slice(0, maxCandidates));
|
|
12799
|
-
};
|
|
12800
|
-
if (temporalFromDate !== null) {
|
|
12801
|
-
temporalCandidates = capSet(rawTemporal);
|
|
13506
|
+
for (const result of results) {
|
|
13507
|
+
if (!result.path) continue;
|
|
13508
|
+
if (memoryByPath.has(result.path)) {
|
|
13509
|
+
markChecked(result);
|
|
13510
|
+
continue;
|
|
12802
13511
|
}
|
|
12803
|
-
if (
|
|
12804
|
-
|
|
13512
|
+
if (options?.abortSignal?.aborted || deadlineExpired()) {
|
|
13513
|
+
return { memoryByPath, checkedPaths, unreadablePaths, completed: false };
|
|
13514
|
+
}
|
|
13515
|
+
try {
|
|
13516
|
+
const mem = await this.readQmdResultMemory(
|
|
13517
|
+
result.path,
|
|
13518
|
+
this.storage,
|
|
13519
|
+
options?.recallNamespaces
|
|
13520
|
+
);
|
|
13521
|
+
markChecked(result);
|
|
13522
|
+
if (mem) memoryByPath.set(result.path, mem);
|
|
13523
|
+
} catch (err) {
|
|
13524
|
+
if (err instanceof SecureStoreLockedError) {
|
|
13525
|
+
markUnreadable(result, err);
|
|
13526
|
+
continue;
|
|
13527
|
+
}
|
|
13528
|
+
throw err;
|
|
12805
13529
|
}
|
|
12806
13530
|
}
|
|
13531
|
+
return { memoryByPath, checkedPaths, unreadablePaths, completed: true };
|
|
13532
|
+
}
|
|
13533
|
+
filterSearchResultsByRecallSafety(results, memoryByPath, options) {
|
|
12807
13534
|
let lifecycleFilteredCount = 0;
|
|
12808
13535
|
let temporalSupersededFilteredCount = 0;
|
|
12809
13536
|
let dedicatedSurfaceFilteredCount = 0;
|
|
12810
13537
|
let forgottenFilteredCount = 0;
|
|
12811
|
-
|
|
12812
|
-
const
|
|
13538
|
+
let blockedPathFilteredCount = 0;
|
|
13539
|
+
const filtered = [];
|
|
12813
13540
|
for (const r of results) {
|
|
13541
|
+
if (r.path && options?.blockedPaths?.has(r.path)) {
|
|
13542
|
+
blockedPathFilteredCount += 1;
|
|
13543
|
+
continue;
|
|
13544
|
+
}
|
|
12814
13545
|
const memory = memoryByPath.get(r.path);
|
|
12815
|
-
let score = r.score;
|
|
12816
13546
|
if (memory) {
|
|
12817
13547
|
if (memory.frontmatter.status === "forgotten") {
|
|
12818
13548
|
forgottenFilteredCount += 1;
|
|
@@ -12854,6 +13584,126 @@ ${lines.join("\n\n")}`;
|
|
|
12854
13584
|
dedicatedSurfaceFilteredCount += 1;
|
|
12855
13585
|
continue;
|
|
12856
13586
|
}
|
|
13587
|
+
}
|
|
13588
|
+
filtered.push(r);
|
|
13589
|
+
}
|
|
13590
|
+
if (lifecycleFilteredCount > 0) {
|
|
13591
|
+
log.debug(
|
|
13592
|
+
`lifecycle retrieval filter removed ${lifecycleFilteredCount} stale/archived candidates`
|
|
13593
|
+
);
|
|
13594
|
+
}
|
|
13595
|
+
if (temporalSupersededFilteredCount > 0) {
|
|
13596
|
+
log.debug(
|
|
13597
|
+
`temporal supersession filter removed ${temporalSupersededFilteredCount} superseded candidates`
|
|
13598
|
+
);
|
|
13599
|
+
}
|
|
13600
|
+
if (dedicatedSurfaceFilteredCount > 0) {
|
|
13601
|
+
log.debug(
|
|
13602
|
+
`dedicated surface filter removed ${dedicatedSurfaceFilteredCount} dream/procedural candidates from generic recall`
|
|
13603
|
+
);
|
|
13604
|
+
}
|
|
13605
|
+
if (forgottenFilteredCount > 0) {
|
|
13606
|
+
log.debug(
|
|
13607
|
+
`forgotten status filter removed ${forgottenFilteredCount} candidates from recall`
|
|
13608
|
+
);
|
|
13609
|
+
}
|
|
13610
|
+
if (blockedPathFilteredCount > 0) {
|
|
13611
|
+
log.debug(
|
|
13612
|
+
`unreadable-path filter removed ${blockedPathFilteredCount} candidates from recall`
|
|
13613
|
+
);
|
|
13614
|
+
}
|
|
13615
|
+
return filtered;
|
|
13616
|
+
}
|
|
13617
|
+
async filterSearchResultsForRecall(results, preloadedMemoryMap, options) {
|
|
13618
|
+
if (results.length === 0) {
|
|
13619
|
+
return {
|
|
13620
|
+
results,
|
|
13621
|
+
memoryByPath: preloadedMemoryMap ? new Map(preloadedMemoryMap) : /* @__PURE__ */ new Map()
|
|
13622
|
+
};
|
|
13623
|
+
}
|
|
13624
|
+
const loaded = await this.loadSearchResultMemoryMap(
|
|
13625
|
+
results,
|
|
13626
|
+
preloadedMemoryMap,
|
|
13627
|
+
options
|
|
13628
|
+
);
|
|
13629
|
+
const candidateResults = loaded.completed ? results : results.filter((result) => !result.path || loaded.checkedPaths.has(result.path));
|
|
13630
|
+
if (!loaded.completed) {
|
|
13631
|
+
log.debug(
|
|
13632
|
+
`recall safety filter stopped before validating all candidates (${candidateResults.length}/${results.length} eligible)`
|
|
13633
|
+
);
|
|
13634
|
+
}
|
|
13635
|
+
const blockedPaths = new Set(loaded.unreadablePaths);
|
|
13636
|
+
if (options?.dropUnresolved === true) {
|
|
13637
|
+
for (const resultPath of loaded.checkedPaths) {
|
|
13638
|
+
if (!loaded.memoryByPath.has(resultPath)) {
|
|
13639
|
+
blockedPaths.add(resultPath);
|
|
13640
|
+
}
|
|
13641
|
+
}
|
|
13642
|
+
}
|
|
13643
|
+
return {
|
|
13644
|
+
results: this.filterSearchResultsByRecallSafety(
|
|
13645
|
+
candidateResults,
|
|
13646
|
+
loaded.memoryByPath,
|
|
13647
|
+
{ ...options, blockedPaths }
|
|
13648
|
+
),
|
|
13649
|
+
memoryByPath: loaded.memoryByPath
|
|
13650
|
+
};
|
|
13651
|
+
}
|
|
13652
|
+
/**
|
|
13653
|
+
* Apply recency, access count, and importance boosting to QMD search results.
|
|
13654
|
+
* Returns re-ranked results.
|
|
13655
|
+
*/
|
|
13656
|
+
async boostSearchResults(results, _recallNamespaces, prompt, preloadedMemoryMap, options) {
|
|
13657
|
+
if (results.length === 0) return results;
|
|
13658
|
+
const safety = await this.filterSearchResultsForRecall(
|
|
13659
|
+
results,
|
|
13660
|
+
preloadedMemoryMap,
|
|
13661
|
+
{ ...options, recallNamespaces: _recallNamespaces }
|
|
13662
|
+
);
|
|
13663
|
+
const safeResults = safety.results;
|
|
13664
|
+
const memoryByPath = safety.memoryByPath;
|
|
13665
|
+
if (safeResults.length === 0) return safeResults;
|
|
13666
|
+
const now = Date.now();
|
|
13667
|
+
const resultPaths = new Set(
|
|
13668
|
+
safeResults.map((r) => r.path).filter(Boolean)
|
|
13669
|
+
);
|
|
13670
|
+
let temporalFromDate = null;
|
|
13671
|
+
let promptTags = [];
|
|
13672
|
+
if (this.config.queryAwareIndexingEnabled && prompt) {
|
|
13673
|
+
if (isTemporalQuery(prompt)) {
|
|
13674
|
+
temporalFromDate = recencyWindowFromPrompt(prompt, now);
|
|
13675
|
+
}
|
|
13676
|
+
promptTags = extractTagsFromPrompt(prompt);
|
|
13677
|
+
}
|
|
13678
|
+
const [rawTemporal, rawTags] = await Promise.all([
|
|
13679
|
+
temporalFromDate !== null ? queryByDateRangeAsync(this.config.memoryDir, temporalFromDate) : Promise.resolve(null),
|
|
13680
|
+
promptTags.length > 0 ? queryByTagsAsync(this.config.memoryDir, promptTags) : Promise.resolve(null)
|
|
13681
|
+
]);
|
|
13682
|
+
const queryIntent = this.config.intentRoutingEnabled && prompt ? inferIntentFromText(prompt) : null;
|
|
13683
|
+
let temporalCandidates = null;
|
|
13684
|
+
let tagCandidates = null;
|
|
13685
|
+
if (this.config.queryAwareIndexingEnabled && prompt) {
|
|
13686
|
+
const maxCandidates = this.config.queryAwareIndexingMaxCandidates;
|
|
13687
|
+
const capSet = (s) => {
|
|
13688
|
+
if (!s) return null;
|
|
13689
|
+
const scoped = new Set(Array.from(s).filter((p) => resultPaths.has(p)));
|
|
13690
|
+
if (maxCandidates === 0 || scoped.size <= maxCandidates)
|
|
13691
|
+
return scoped;
|
|
13692
|
+
return new Set(Array.from(scoped).slice(0, maxCandidates));
|
|
13693
|
+
};
|
|
13694
|
+
if (temporalFromDate !== null) {
|
|
13695
|
+
temporalCandidates = capSet(rawTemporal);
|
|
13696
|
+
}
|
|
13697
|
+
if (promptTags.length > 0) {
|
|
13698
|
+
tagCandidates = capSet(rawTags);
|
|
13699
|
+
}
|
|
13700
|
+
}
|
|
13701
|
+
const boosted = [];
|
|
13702
|
+
const recencyWeight = this.effectiveRecencyWeight();
|
|
13703
|
+
for (const r of safeResults) {
|
|
13704
|
+
const memory = memoryByPath.get(r.path);
|
|
13705
|
+
let score = r.score;
|
|
13706
|
+
if (memory) {
|
|
12857
13707
|
if (recencyWeight > 0) {
|
|
12858
13708
|
const createdAt = new Date(memory.frontmatter.created).getTime();
|
|
12859
13709
|
const ageMs = now - createdAt;
|
|
@@ -12964,26 +13814,6 @@ ${lines.join("\n\n")}`;
|
|
|
12964
13814
|
}
|
|
12965
13815
|
boosted.push({ ...r, score });
|
|
12966
13816
|
}
|
|
12967
|
-
if (lifecycleFilteredCount > 0) {
|
|
12968
|
-
log.debug(
|
|
12969
|
-
`lifecycle retrieval filter removed ${lifecycleFilteredCount} stale/archived candidates`
|
|
12970
|
-
);
|
|
12971
|
-
}
|
|
12972
|
-
if (temporalSupersededFilteredCount > 0) {
|
|
12973
|
-
log.debug(
|
|
12974
|
-
`temporal supersession filter removed ${temporalSupersededFilteredCount} superseded candidates`
|
|
12975
|
-
);
|
|
12976
|
-
}
|
|
12977
|
-
if (dedicatedSurfaceFilteredCount > 0) {
|
|
12978
|
-
log.debug(
|
|
12979
|
-
`dedicated surface filter removed ${dedicatedSurfaceFilteredCount} dream/procedural candidates from generic recall`
|
|
12980
|
-
);
|
|
12981
|
-
}
|
|
12982
|
-
if (forgottenFilteredCount > 0) {
|
|
12983
|
-
log.debug(
|
|
12984
|
-
`forgotten status filter removed ${forgottenFilteredCount} candidates from recall`
|
|
12985
|
-
);
|
|
12986
|
-
}
|
|
12987
13817
|
return boosted.sort((a, b) => b.score - a.score);
|
|
12988
13818
|
}
|
|
12989
13819
|
/**
|
|
@@ -13121,8 +13951,37 @@ ${lines.join("\n\n")}`;
|
|
|
13121
13951
|
reason: link.reason || void 0
|
|
13122
13952
|
}));
|
|
13123
13953
|
}
|
|
13954
|
+
async graphSeedPathRelativeToStorage(storage, result, recallNamespaces = []) {
|
|
13955
|
+
const parts = qmdCollectionPathParts(result.path);
|
|
13956
|
+
if (parts) {
|
|
13957
|
+
const memory = await this.readQmdResultMemory(
|
|
13958
|
+
result.path,
|
|
13959
|
+
storage,
|
|
13960
|
+
recallNamespaces
|
|
13961
|
+
);
|
|
13962
|
+
return memory ? graphPathRelativeToStorage(storage.dir, memory.path) : null;
|
|
13963
|
+
}
|
|
13964
|
+
return graphPathRelativeToStorage(storage.dir, result.path);
|
|
13965
|
+
}
|
|
13966
|
+
async graphSeedPathsWithinDeadline(storage, results, deadlineAtMs, recallNamespaces = []) {
|
|
13967
|
+
const resolved = [];
|
|
13968
|
+
for (const result of results) {
|
|
13969
|
+
if (Date.now() >= deadlineAtMs) break;
|
|
13970
|
+
const seedPath = await this.graphSeedPathRelativeToStorage(
|
|
13971
|
+
storage,
|
|
13972
|
+
result,
|
|
13973
|
+
recallNamespaces
|
|
13974
|
+
);
|
|
13975
|
+
if (Date.now() >= deadlineAtMs) break;
|
|
13976
|
+
if (seedPath) resolved.push(seedPath);
|
|
13977
|
+
}
|
|
13978
|
+
return resolved;
|
|
13979
|
+
}
|
|
13124
13980
|
namespaceFromPath(p) {
|
|
13125
13981
|
if (!this.config.namespacesEnabled) return this.config.defaultNamespace;
|
|
13982
|
+
const parts = qmdCollectionPathParts(p);
|
|
13983
|
+
const collectionNamespace = parts ? this.qmdCollectionNamespaceFromPrefix(parts.collection) : null;
|
|
13984
|
+
if (collectionNamespace) return collectionNamespace;
|
|
13126
13985
|
const m = p.match(/[\\/]+namespaces[\\/]+([^\\/]+)(?:[\\/]|$)/);
|
|
13127
13986
|
if (!m?.[1]) return this.config.defaultNamespace;
|
|
13128
13987
|
return namespaceIdentityFromToken(m[1]) ?? m[1];
|
|
@@ -13206,4 +14065,4 @@ export {
|
|
|
13206
14065
|
resolvePersistedMemoryRelativePath,
|
|
13207
14066
|
Orchestrator
|
|
13208
14067
|
};
|
|
13209
|
-
//# sourceMappingURL=chunk-
|
|
14068
|
+
//# sourceMappingURL=chunk-2BHNQRE5.js.map
|