@remnic/core 9.19.0 → 9.20.0
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-admin-ops-surface.d.ts +8 -8
- package/dist/access-admin-ops-surface.js +8 -8
- package/dist/access-boundary.d.ts +8 -8
- package/dist/access-boundary.js +8 -8
- package/dist/access-cli.js +32 -32
- package/dist/access-http.d.ts +8 -8
- package/dist/access-http.js +12 -12
- package/dist/access-identity-continuity-surface.d.ts +6 -6
- package/dist/access-identity-continuity-surface.js +8 -8
- package/dist/access-lcm-surface.d.ts +8 -8
- package/dist/access-lcm-surface.js +8 -8
- package/dist/access-mcp.d.ts +8 -8
- package/dist/access-mcp.js +11 -11
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-BsawJa-L.d.ts → access-namespace-preflight-tmwQgCT6.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +8 -8
- package/dist/access-observe-write-surface.d.ts +8 -8
- package/dist/access-observe-write-surface.js +8 -8
- package/dist/access-operations-batch.js +9 -9
- package/dist/access-operations.d.ts +8 -8
- package/dist/access-operations.js +10 -10
- package/dist/access-recall-concurrency.d.ts +8 -8
- package/dist/access-recall-concurrency.js +8 -8
- package/dist/access-recall-response.d.ts +8 -8
- package/dist/access-recall-response.js +8 -8
- package/dist/access-recall-surface.d.ts +8 -8
- package/dist/access-recall-surface.js +8 -8
- package/dist/{access-service-DLuVnV6a.d.ts → access-service-BqUii7LY.d.ts} +6 -6
- package/dist/access-service.d.ts +8 -8
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +8 -8
- 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-IH3G25MT.js → auto-sync-UPTUVE4X.js} +3 -3
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +6 -6
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +4 -4
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-O6P8694A.d.ts → catalog-iWvWz61I.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +5 -5
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-YUWFASAK.js → chunk-275ENJDK.js} +2 -2
- package/dist/{chunk-EZFVVEQG.js → chunk-3ZUY2VQF.js} +2 -2
- package/dist/{chunk-HRREDJSL.js → chunk-4F6AANKS.js} +3 -3
- package/dist/{chunk-U7D5HWNG.js → chunk-4PYLBXX6.js} +2 -2
- package/dist/{chunk-3LZSS77C.js → chunk-53WDAG7X.js} +2 -2
- package/dist/{chunk-QEEMLGCO.js → chunk-5IXPWEQB.js} +5 -5
- package/dist/{chunk-VSVX777Y.js → chunk-5JQLAQUZ.js} +2 -2
- package/dist/{chunk-DR65EEXG.js → chunk-62QM5MKY.js} +7 -7
- package/dist/{chunk-WYL5ODHJ.js → chunk-6NZ7U4R4.js} +1 -1
- package/dist/chunk-6NZ7U4R4.js.map +1 -0
- package/dist/{chunk-OFQUY5NZ.js → chunk-7M6APKJL.js} +331 -5
- package/dist/chunk-7M6APKJL.js.map +1 -0
- package/dist/{chunk-OOJQ6ID5.js → chunk-AT3TDN6O.js} +1017 -296
- package/dist/chunk-AT3TDN6O.js.map +1 -0
- package/dist/{chunk-DQCUBRTZ.js → chunk-B7C3TF5H.js} +2 -2
- package/dist/{chunk-RPOOJPMB.js → chunk-EILX7SQR.js} +3 -3
- package/dist/{chunk-D5H3B36B.js → chunk-EXU5IQ3S.js} +2 -2
- package/dist/{chunk-KUF7OIFK.js → chunk-EZKKHVFY.js} +2 -2
- package/dist/{chunk-S5HCKQ7Q.js → chunk-GEUDRENF.js} +2 -2
- package/dist/{chunk-X7GOH7Y6.js → chunk-HJEEAO4O.js} +2 -2
- package/dist/{chunk-FL7MNSH3.js → chunk-HPOY2PHQ.js} +3 -3
- package/dist/{chunk-Q55XM4SU.js → chunk-JFDEYXF7.js} +2 -2
- package/dist/{chunk-UVSDFM7R.js → chunk-JN3IUA2Q.js} +2 -2
- package/dist/{chunk-PLRDZ2OO.js → chunk-JWMYVQAM.js} +2 -2
- package/dist/{chunk-KOFVOVJG.js → chunk-KHRKEELC.js} +17 -17
- package/dist/{chunk-Y4JHE2ML.js → chunk-LI4ZOFHW.js} +2 -2
- package/dist/{chunk-MLW3J7IC.js → chunk-LMHDFOVV.js} +3 -3
- package/dist/{chunk-X6E5WAGX.js → chunk-N7EVMKP6.js} +6 -6
- package/dist/{chunk-HCNG42P3.js → chunk-Q3FWRDCP.js} +2 -2
- package/dist/{chunk-5MFHOX5T.js → chunk-QO2KODU6.js} +2 -2
- package/dist/{chunk-W3DJOT22.js → chunk-TCZWBJBO.js} +2 -2
- package/dist/{chunk-B3ABVQ36.js → chunk-UHVXE24Y.js} +2 -1
- package/dist/{chunk-UX3ZXN34.js → chunk-UV72DEZD.js} +2 -2
- package/dist/{chunk-OZSL2QZC.js → chunk-V5TSUGRB.js} +5 -5
- package/dist/{chunk-CH3BRJ3P.js → chunk-X5QS5C2O.js} +2 -2
- package/dist/{cli-0dQHR6e6.d.ts → cli-DPEhq0Cp.d.ts} +5 -5
- package/dist/cli.d.ts +10 -10
- package/dist/cli.js +25 -25
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +4 -4
- 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 +4 -4
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +4 -4
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +4 -4
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +6 -6
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/index.d.ts +468 -88
- package/dist/index.js +66 -36
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +4 -4
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +5 -5
- package/dist/mcp-memory-inspector-app.d.ts +8 -8
- 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 +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +5 -5
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +4 -4
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +2 -2
- package/dist/operator-toolkit.js +9 -9
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +3 -3
- package/dist/orchestration/maintenance.js +9 -9
- package/dist/{orchestrator-B8ickLkd.d.ts → orchestrator-DB93S48I.d.ts} +5 -5
- package/dist/orchestrator.d.ts +6 -6
- package/dist/orchestrator.js +32 -32
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-B669unGm.d.ts → pipeline-DmGc-H66.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/{qmd-D0PVXmea.d.ts → qmd-cJT0crkF.d.ts} +1 -1
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/recall-concurrency-config.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-memory-map.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.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/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- package/dist/retrieval-agents.d.ts +2 -2
- 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/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-BOp3gSzp.d.ts → scope-profiles-KG2nODX7.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-C7SZNzUJ.d.ts → semantic-consolidation-BaZlg0D8.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +5 -5
- package/dist/semantic-rule-promotion.js +4 -4
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +4 -4
- 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-CJ_Fia4H.d.ts → storage-BKhHHnRo.d.ts} +2 -221
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +3 -3
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.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 +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-GeWGXq9E.d.ts → types-GBQZuT7l.d.ts} +395 -1
- 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 +4 -4
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/config.ts +3 -3
- package/src/meetings/build.test.ts +646 -0
- package/src/meetings/build.ts +365 -0
- package/src/meetings/cli.test.ts +276 -0
- package/src/meetings/cli.ts +242 -0
- package/src/meetings/config.test.ts +72 -0
- package/src/meetings/config.ts +183 -0
- package/src/meetings/errors.ts +13 -0
- package/src/meetings/fuse.test.ts +208 -0
- package/src/meetings/fuse.ts +297 -0
- package/src/meetings/index.ts +11 -1
- package/src/meetings/memory-generator.ts +116 -0
- package/src/meetings/recall-exclusion.test.ts +88 -0
- package/src/meetings/store.test.ts +232 -0
- package/src/meetings/store.ts +465 -0
- package/src/meetings/types.ts +111 -0
- package/src/orchestration/orchestrator-helpers.ts +23 -3
- package/src/orchestration/recall-search-pipeline.test.ts +182 -0
- package/src/orchestration/recall-search-pipeline.ts +36 -15
- package/src/types.ts +6 -0
- package/dist/chunk-OFQUY5NZ.js.map +0 -1
- package/dist/chunk-OOJQ6ID5.js.map +0 -1
- package/dist/chunk-WYL5ODHJ.js.map +0 -1
- /package/dist/{auto-sync-IH3G25MT.js.map → auto-sync-UPTUVE4X.js.map} +0 -0
- /package/dist/{chunk-YUWFASAK.js.map → chunk-275ENJDK.js.map} +0 -0
- /package/dist/{chunk-EZFVVEQG.js.map → chunk-3ZUY2VQF.js.map} +0 -0
- /package/dist/{chunk-HRREDJSL.js.map → chunk-4F6AANKS.js.map} +0 -0
- /package/dist/{chunk-U7D5HWNG.js.map → chunk-4PYLBXX6.js.map} +0 -0
- /package/dist/{chunk-3LZSS77C.js.map → chunk-53WDAG7X.js.map} +0 -0
- /package/dist/{chunk-QEEMLGCO.js.map → chunk-5IXPWEQB.js.map} +0 -0
- /package/dist/{chunk-VSVX777Y.js.map → chunk-5JQLAQUZ.js.map} +0 -0
- /package/dist/{chunk-DR65EEXG.js.map → chunk-62QM5MKY.js.map} +0 -0
- /package/dist/{chunk-DQCUBRTZ.js.map → chunk-B7C3TF5H.js.map} +0 -0
- /package/dist/{chunk-RPOOJPMB.js.map → chunk-EILX7SQR.js.map} +0 -0
- /package/dist/{chunk-D5H3B36B.js.map → chunk-EXU5IQ3S.js.map} +0 -0
- /package/dist/{chunk-KUF7OIFK.js.map → chunk-EZKKHVFY.js.map} +0 -0
- /package/dist/{chunk-S5HCKQ7Q.js.map → chunk-GEUDRENF.js.map} +0 -0
- /package/dist/{chunk-X7GOH7Y6.js.map → chunk-HJEEAO4O.js.map} +0 -0
- /package/dist/{chunk-FL7MNSH3.js.map → chunk-HPOY2PHQ.js.map} +0 -0
- /package/dist/{chunk-Q55XM4SU.js.map → chunk-JFDEYXF7.js.map} +0 -0
- /package/dist/{chunk-UVSDFM7R.js.map → chunk-JN3IUA2Q.js.map} +0 -0
- /package/dist/{chunk-PLRDZ2OO.js.map → chunk-JWMYVQAM.js.map} +0 -0
- /package/dist/{chunk-KOFVOVJG.js.map → chunk-KHRKEELC.js.map} +0 -0
- /package/dist/{chunk-Y4JHE2ML.js.map → chunk-LI4ZOFHW.js.map} +0 -0
- /package/dist/{chunk-MLW3J7IC.js.map → chunk-LMHDFOVV.js.map} +0 -0
- /package/dist/{chunk-X6E5WAGX.js.map → chunk-N7EVMKP6.js.map} +0 -0
- /package/dist/{chunk-HCNG42P3.js.map → chunk-Q3FWRDCP.js.map} +0 -0
- /package/dist/{chunk-5MFHOX5T.js.map → chunk-QO2KODU6.js.map} +0 -0
- /package/dist/{chunk-W3DJOT22.js.map → chunk-TCZWBJBO.js.map} +0 -0
- /package/dist/{chunk-B3ABVQ36.js.map → chunk-UHVXE24Y.js.map} +0 -0
- /package/dist/{chunk-UX3ZXN34.js.map → chunk-UV72DEZD.js.map} +0 -0
- /package/dist/{chunk-OZSL2QZC.js.map → chunk-V5TSUGRB.js.map} +0 -0
- /package/dist/{chunk-CH3BRJ3P.js.map → chunk-X5QS5C2O.js.map} +0 -0
|
@@ -9,6 +9,7 @@ import { RecallSearchPipelineCoordinator } from "./recall-search-pipeline.js";
|
|
|
9
9
|
import type { RecallSearchPipelineDeps } from "./recall-search-pipeline.js";
|
|
10
10
|
import type { MemoryFile, QmdSearchResult } from "../types.js";
|
|
11
11
|
import type { StorageManager } from "../index.js";
|
|
12
|
+
import type { QueryAwarePrefilter } from "../orchestrator.js";
|
|
12
13
|
|
|
13
14
|
function result(namespace: string, path: string): QmdSearchResult {
|
|
14
15
|
return { docid: `${namespace}:${path}`, namespace, path, score: 1, snippet: path };
|
|
@@ -68,3 +69,184 @@ test("recall safety keeps same relative path distinct across namespaces", async
|
|
|
68
69
|
await rm(memoryDir, { recursive: true, force: true });
|
|
69
70
|
}
|
|
70
71
|
});
|
|
72
|
+
|
|
73
|
+
function scopedCandidatesStub(
|
|
74
|
+
seed: QmdSearchResult[],
|
|
75
|
+
): RecallSearchPipelineDeps["searchScopedMemoryCandidates"] {
|
|
76
|
+
// Faithful to production: return only the requested candidates, capped to limit.
|
|
77
|
+
return async (candidatePaths, _query, limit) =>
|
|
78
|
+
seed.filter((r) => candidatePaths.has(r.path)).slice(0, Math.max(0, limit));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function fallbackCoordinator(seed: QmdSearchResult[], archived: MemoryFile[]): RecallSearchPipelineCoordinator {
|
|
82
|
+
const readArchivedMemoriesForNamespaces: RecallSearchPipelineDeps["readArchivedMemoriesForNamespaces"] =
|
|
83
|
+
async () => archived;
|
|
84
|
+
const namespaceFromPath: RecallSearchPipelineDeps["namespaceFromPath"] = () => "default";
|
|
85
|
+
const deps = {
|
|
86
|
+
searchScopedMemoryCandidates: scopedCandidatesStub(seed),
|
|
87
|
+
readArchivedMemoriesForNamespaces,
|
|
88
|
+
namespaceFromPath,
|
|
89
|
+
config: { memoryDir: "/mem" },
|
|
90
|
+
} as unknown as RecallSearchPipelineDeps;
|
|
91
|
+
return new RecallSearchPipelineCoordinator(deps);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function prefilter(paths: string[]): QueryAwarePrefilter {
|
|
95
|
+
return {
|
|
96
|
+
candidatePaths: new Set(paths),
|
|
97
|
+
temporalFromDate: null,
|
|
98
|
+
matchedTags: [],
|
|
99
|
+
expandedTags: [],
|
|
100
|
+
combination: "none",
|
|
101
|
+
filteredToFullSearch: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const MEETING_RECORD = "meetings/2026-03-10/mtg-2026-03-10-abcdef01.md";
|
|
106
|
+
const SEED_PATHS = [MEETING_RECORD, "facts/a.md", "artifacts/y.md"];
|
|
107
|
+
const SEED_WITH_NON_RECALLABLE = SEED_PATHS.map((p) => result("default", p));
|
|
108
|
+
const PREFILTER = prefilter(SEED_PATHS);
|
|
109
|
+
|
|
110
|
+
test("archive fallback excludes non-recallable seeds on the archived-empty early return", async () => {
|
|
111
|
+
const coordinator = fallbackCoordinator(SEED_WITH_NON_RECALLABLE, []);
|
|
112
|
+
// limit 10 > filtered seed count, tokens non-empty, archived empty → the
|
|
113
|
+
// `return scopedSeedResults` early path at the archived-empty guard.
|
|
114
|
+
const out = await coordinator.searchLongTermArchiveFallback("quarterly report", ["default"], 10, PREFILTER);
|
|
115
|
+
assert.deepEqual(
|
|
116
|
+
out.map((r) => r.path),
|
|
117
|
+
["facts/a.md"],
|
|
118
|
+
"meeting record + artifact must not leak through the direct-caller early return",
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("archive fallback excludes non-recallable seeds on the empty-tokens early return", async () => {
|
|
123
|
+
const coordinator = fallbackCoordinator(SEED_WITH_NON_RECALLABLE, [memory("facts/z.md", "archived")]);
|
|
124
|
+
// Empty prompt → zero tokens → the `return scopedSeedResults` early path
|
|
125
|
+
// before archive scoring is even attempted.
|
|
126
|
+
const out = await coordinator.searchLongTermArchiveFallback("", ["default"], 10, PREFILTER);
|
|
127
|
+
assert.deepEqual(out.map((r) => r.path), ["facts/a.md"]);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("archive fallback applies the cap to FILTERED seeds, not raw non-recallable hits", async () => {
|
|
131
|
+
// The scoped search returns a single non-recallable hit that would fill a cap
|
|
132
|
+
// of 1 if counted raw; the method must count only recallable seeds, so it does
|
|
133
|
+
// not early-return that hit and (archive empty) yields nothing.
|
|
134
|
+
const coordinator = fallbackCoordinator([result("default", MEETING_RECORD)], []);
|
|
135
|
+
const out = await coordinator.searchLongTermArchiveFallback("quarterly", ["default"], 1, prefilter([MEETING_RECORD]));
|
|
136
|
+
assert.deepEqual(out.map((r) => r.path), []);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("finding 1 — overfetches scoped seeds before exclusion so a capped fetch still yields recallable hits", async () => {
|
|
140
|
+
// The scoped candidate order puts the NON-recallable meeting record FIRST;
|
|
141
|
+
// capping the scoped fetch to the caller's limit (1) BEFORE the generic-recall
|
|
142
|
+
// exclusion would return only the meeting record, which is then filtered out —
|
|
143
|
+
// dropping facts/a.md with no refill. Overfetching the full candidate set first
|
|
144
|
+
// and excluding afterward must still surface the recallable hit at the cap.
|
|
145
|
+
const coordinator = fallbackCoordinator(
|
|
146
|
+
[result("default", MEETING_RECORD), result("default", "facts/a.md")],
|
|
147
|
+
[],
|
|
148
|
+
);
|
|
149
|
+
const out = await coordinator.searchLongTermArchiveFallback(
|
|
150
|
+
"quarterly",
|
|
151
|
+
["default"],
|
|
152
|
+
1,
|
|
153
|
+
prefilter([MEETING_RECORD, "facts/a.md"]),
|
|
154
|
+
);
|
|
155
|
+
assert.deepEqual(
|
|
156
|
+
out.map((r) => r.path),
|
|
157
|
+
["facts/a.md"],
|
|
158
|
+
"an excluded-first seed must not starve the result of a recallable hit at the cap",
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
function hotSeedCoordinator(seed: QmdSearchResult[]): RecallSearchPipelineCoordinator {
|
|
163
|
+
const deps = {
|
|
164
|
+
config: { memoryDir: "/mem", qmdSearchStrategy: "lex", searchBackend: "qmd" },
|
|
165
|
+
qmd: {},
|
|
166
|
+
searchScopedMemoryCandidates: scopedCandidatesStub(seed),
|
|
167
|
+
searchAcrossNamespaces: async () => [],
|
|
168
|
+
namespaceFromPath: () => "default",
|
|
169
|
+
} as unknown as RecallSearchPipelineDeps;
|
|
170
|
+
return new RecallSearchPipelineCoordinator(deps);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
test("finding 1 (round-4) — hot QMD seed path overfetches scoped seeds before exclusion", async () => {
|
|
174
|
+
// The query-aware candidate order puts the NON-recallable meeting record FIRST.
|
|
175
|
+
// The hot seed fetch previously capped the scoped fetch to qmdFetchLimit (1)
|
|
176
|
+
// BEFORE the generic-recall exclusion, so the sole fetched seed was the meeting
|
|
177
|
+
// record — filtered out, dropping facts/a.md with no refill. Overfetching the
|
|
178
|
+
// full candidate set and excluding afterward must still surface the recallable
|
|
179
|
+
// hit at the cap.
|
|
180
|
+
const coordinator = hotSeedCoordinator([
|
|
181
|
+
result("default", MEETING_RECORD),
|
|
182
|
+
result("default", "facts/a.md"),
|
|
183
|
+
]);
|
|
184
|
+
const out = await coordinator.fetchQmdMemoryResultsWithArtifactTopUp("quarterly", 1, 1, {
|
|
185
|
+
namespacesEnabled: false,
|
|
186
|
+
recallNamespaces: ["default"],
|
|
187
|
+
resolveNamespace: () => "default",
|
|
188
|
+
queryAwarePrefilter: prefilter([MEETING_RECORD, "facts/a.md"]),
|
|
189
|
+
});
|
|
190
|
+
assert.deepEqual(
|
|
191
|
+
out.map((r) => r.path),
|
|
192
|
+
["facts/a.md"],
|
|
193
|
+
"an excluded-first candidate must not starve the hot seed of a recallable hit at the cap",
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
function resultScored(namespace: string, path: string, score: number): QmdSearchResult {
|
|
198
|
+
return { docid: `${namespace}:${path}`, namespace, path, score, snippet: path };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function meetingRecordPath(hash: string): string {
|
|
202
|
+
return `meetings/2026-03-10/mtg-2026-03-10-${hash}.md`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function starvedPrimaryCoordinator(
|
|
206
|
+
seed: QmdSearchResult[],
|
|
207
|
+
primary: QmdSearchResult[],
|
|
208
|
+
): RecallSearchPipelineCoordinator {
|
|
209
|
+
const deps = {
|
|
210
|
+
config: { memoryDir: "/mem", qmdSearchStrategy: "lex", searchBackend: "qmd" },
|
|
211
|
+
qmd: {},
|
|
212
|
+
searchScopedMemoryCandidates: scopedCandidatesStub(seed),
|
|
213
|
+
// Faithful to the QMD backend: cap the primary hits to the requested budget.
|
|
214
|
+
searchAcrossNamespaces: async ({ maxResults }: { maxResults: number }) =>
|
|
215
|
+
[...primary].sort((a, b) => b.score - a.score).slice(0, Math.max(0, maxResults)),
|
|
216
|
+
namespaceFromPath: () => "default",
|
|
217
|
+
} as unknown as RecallSearchPipelineDeps;
|
|
218
|
+
return new RecallSearchPipelineCoordinator(deps);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
test("finding 1 (round-5) — excluded seeds must not fill the merge cap and starve a primary hit", async () => {
|
|
222
|
+
// Excluded meeting records dominate the query-aware SEED set (higher score),
|
|
223
|
+
// while the sole recallable memory arrives from the PRIMARY QMD search — so the
|
|
224
|
+
// scoped-seed overfetch fix and the seed-derived `bestFiltered` fallback cannot
|
|
225
|
+
// rescue it. The seed MERGE `[...seeds, ...primary]` capped to fetchLimit BEFORE
|
|
226
|
+
// filterRecallCandidates ran, so every cap slot (even after the two-attempt
|
|
227
|
+
// fetchLimit growth) went to meeting records later filtered out — dropping
|
|
228
|
+
// facts/a.md with no refill. Excluding non-recallable paths BEFORE the cap must
|
|
229
|
+
// let the primary hit survive at qmdFetchLimit=1.
|
|
230
|
+
const meetings = [
|
|
231
|
+
"aaaaaaaa",
|
|
232
|
+
"bbbbbbbb",
|
|
233
|
+
"cccccccc",
|
|
234
|
+
"dddddddd",
|
|
235
|
+
"eeeeeeee",
|
|
236
|
+
"ffffffff",
|
|
237
|
+
].map((h) => resultScored("default", meetingRecordPath(h), 2));
|
|
238
|
+
const coordinator = starvedPrimaryCoordinator(meetings, [
|
|
239
|
+
resultScored("default", "facts/a.md", 1),
|
|
240
|
+
]);
|
|
241
|
+
const out = await coordinator.fetchQmdMemoryResultsWithArtifactTopUp("quarterly", 1, 1, {
|
|
242
|
+
namespacesEnabled: false,
|
|
243
|
+
recallNamespaces: ["default"],
|
|
244
|
+
resolveNamespace: () => "default",
|
|
245
|
+
queryAwarePrefilter: prefilter(meetings.map((m) => m.path)),
|
|
246
|
+
});
|
|
247
|
+
assert.deepEqual(
|
|
248
|
+
out.map((r) => r.path),
|
|
249
|
+
["facts/a.md"],
|
|
250
|
+
"excluded seeds ranked ahead must not fill the fetchLimit cap and starve the recallable primary hit",
|
|
251
|
+
);
|
|
252
|
+
});
|
|
@@ -422,10 +422,19 @@ export class RecallSearchPipelineCoordinator {
|
|
|
422
422
|
? await this.deps.searchScopedMemoryCandidates(
|
|
423
423
|
queryAwarePrefilter.candidatePaths,
|
|
424
424
|
prompt,
|
|
425
|
-
|
|
425
|
+
// Overfetch the FULL scoped candidate set BEFORE the generic-recall
|
|
426
|
+
// exclusion `filterRecallCandidates` applies below (L464). Capping to
|
|
427
|
+
// `qmdFetchLimit` here lets excluded paths (artifacts, activity digests,
|
|
428
|
+
// meeting records) consume the caller's budget and drop legitimate hits
|
|
429
|
+
// with no refill — the hot-path mirror of the archive-fallback fix. The
|
|
430
|
+
// candidate set is an already-bounded prefilter, so its size is the
|
|
431
|
+
// natural ceiling; the post-exclusion cap is applied by filterRecallCandidates.
|
|
432
|
+
queryAwarePrefilter.candidatePaths.size,
|
|
426
433
|
{ allowArchived: options.collection !== undefined },
|
|
427
434
|
)
|
|
428
435
|
: [];
|
|
436
|
+
// Drop generic-recall-excluded records before the fetchLimit cap so they can't starve valid memories (#1995).
|
|
437
|
+
const recallable = (r: QmdSearchResult) => !isGenericRecallExcludedPath(r.path, this.deps.config.memoryDir);
|
|
429
438
|
|
|
430
439
|
let fetchLimit = Math.max(qmdFetchLimit, qmdHybridFetchLimit);
|
|
431
440
|
const maxFetchLimit = Math.min(
|
|
@@ -586,13 +595,12 @@ export class RecallSearchPipelineCoordinator {
|
|
|
586
595
|
lastHybridResultCount = hybridResults.length;
|
|
587
596
|
lastHybridTopUpUsed = hybridResults.length > 0;
|
|
588
597
|
if (hybridResults.length > 0) {
|
|
589
|
-
// Dedup by composite (namespace, path) so a
|
|
590
|
-
// seed/hybrid hit for the same memory never inject twice (#2020).
|
|
598
|
+
// Dedup by composite (namespace, path) so a hit never injects twice (#2020).
|
|
591
599
|
mergedResults = dedupeResultsByNamespace(
|
|
592
600
|
[...primaryResults, ...hybridResults],
|
|
593
601
|
this.deps.namespaceFromPath,
|
|
594
602
|
fetchLimit,
|
|
595
|
-
{ transportFallback: "hybrid" },
|
|
603
|
+
{ transportFallback: "hybrid", filter: recallable },
|
|
596
604
|
);
|
|
597
605
|
}
|
|
598
606
|
}
|
|
@@ -603,6 +611,7 @@ export class RecallSearchPipelineCoordinator {
|
|
|
603
611
|
[...scopedSeedResults, ...mergedResults],
|
|
604
612
|
this.deps.namespaceFromPath,
|
|
605
613
|
fetchLimit,
|
|
614
|
+
{ filter: recallable },
|
|
606
615
|
);
|
|
607
616
|
}
|
|
608
617
|
|
|
@@ -685,18 +694,30 @@ export class RecallSearchPipelineCoordinator {
|
|
|
685
694
|
if (cappedLimit === 0) return [];
|
|
686
695
|
if (queryAwarePrefilter?.candidatePaths?.size === 0) return [];
|
|
687
696
|
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
697
|
+
const candidatePaths = queryAwarePrefilter?.candidatePaths;
|
|
698
|
+
const scopedSeedResults = (
|
|
699
|
+
candidatePaths?.size
|
|
700
|
+
? await this.deps.searchScopedMemoryCandidates(
|
|
701
|
+
candidatePaths,
|
|
702
|
+
prompt,
|
|
703
|
+
// Overfetch the FULL scoped candidate set BEFORE the generic-recall
|
|
704
|
+
// exclusion below. Capping to `cappedLimit` first lets excluded paths
|
|
705
|
+
// (artifacts, activity digests, meeting records) consume the caller's
|
|
706
|
+
// budget and drop legitimate hits with no refill — e.g. a prefilter of
|
|
707
|
+
// [meetingRecord, facts/a.md] at limit 1 would return nothing. The
|
|
708
|
+
// candidate set is an already-bounded prefilter, so its size is the
|
|
709
|
+
// natural ceiling; the post-exclusion cap is applied below.
|
|
710
|
+
candidatePaths.size,
|
|
711
|
+
{ allowArchived: true },
|
|
712
|
+
)
|
|
713
|
+
: []
|
|
714
|
+
).filter((result) => !isGenericRecallExcludedPath(result.path, this.deps.config.memoryDir));
|
|
715
|
+
// Non-recallable seed paths (artifacts, activity digests, meeting records) are
|
|
716
|
+
// excluded above AFTER an unconstrained candidate fetch, so the cap here counts
|
|
717
|
+
// only recallable seeds — and EVERY early-return / direct-caller path below
|
|
718
|
+
// returns already-filtered, budget-honoring seeds.
|
|
696
719
|
if (scopedSeedResults.length >= cappedLimit) {
|
|
697
|
-
return scopedSeedResults
|
|
698
|
-
.filter((result) => !isGenericRecallExcludedPath(result.path, this.deps.config.memoryDir))
|
|
699
|
-
.slice(0, cappedLimit);
|
|
720
|
+
return scopedSeedResults.slice(0, cappedLimit);
|
|
700
721
|
}
|
|
701
722
|
|
|
702
723
|
const tokens = Array.from(new Set(tokenizeRecallQuery(prompt)));
|
package/src/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BoundedJsonlStateConfig } from "./bounded-jsonl-state.js";
|
|
2
|
+
import type { MeetingsConfig } from "./meetings/types.js";
|
|
2
3
|
import type { ActivityConfig } from "./activity/types.js";
|
|
3
4
|
import type { WearablesConfig } from "./wearables/types.js";
|
|
4
5
|
|
|
@@ -1217,6 +1218,11 @@ export interface PluginConfig extends BoundedJsonlStateConfig {
|
|
|
1217
1218
|
*/
|
|
1218
1219
|
wearables: WearablesConfig;
|
|
1219
1220
|
activity: ActivityConfig;
|
|
1221
|
+
/**
|
|
1222
|
+
* Retrospective meeting intelligence (issue #1900): detect + fuse meetings
|
|
1223
|
+
* from already-ingested audio + screen activity. Disabled by default.
|
|
1224
|
+
*/
|
|
1225
|
+
meetings: MeetingsConfig;
|
|
1220
1226
|
/**
|
|
1221
1227
|
* At-rest encryption configuration (issue #690 PR 3/4).
|
|
1222
1228
|
*
|