@remnic/core 10.0.17 → 10.0.19
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.js +15 -15
- package/dist/access-authorization-probe.js +16 -16
- package/dist/access-boundary.js +15 -15
- package/dist/access-cli.js +56 -56
- package/dist/access-extraction-force-flush.js +15 -15
- package/dist/access-http-briefing.js +16 -16
- package/dist/access-http-query.js +17 -17
- package/dist/access-http.js +32 -32
- package/dist/access-identity-continuity-surface.js +15 -15
- package/dist/access-lcm-surface.js +15 -15
- package/dist/access-mcp.js +25 -25
- package/dist/access-namespace-preflight.js +15 -15
- package/dist/access-observe-write-surface.js +15 -15
- package/dist/access-operations-batch.js +16 -16
- package/dist/access-operations.js +23 -23
- package/dist/access-recall-concurrency.js +15 -15
- package/dist/access-recall-diagnostics.js +2 -2
- package/dist/access-recall-response.js +15 -15
- package/dist/access-recall-surface.js +15 -15
- package/dist/access-service.js +15 -15
- package/dist/access-surface-catalog.js +17 -17
- package/dist/active-recall.js +2 -2
- package/dist/briefing.js +3 -3
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-2PYHLSXK.js → chunk-2C5YAVHA.js} +2 -2
- package/dist/{chunk-GWVNGDJW.js → chunk-2I3OREMR.js} +2 -2
- package/dist/{chunk-GCVDFX66.js → chunk-2JGBX5XY.js} +2 -2
- package/dist/{chunk-PEF5LHQU.js → chunk-32FVH5OQ.js} +5 -5
- package/dist/{chunk-XYGQSDTH.js → chunk-3K6J5GO5.js} +3 -3
- package/dist/{chunk-3MO4LWYU.js → chunk-466EGMFQ.js} +1 -1
- package/dist/{chunk-3MO4LWYU.js.map → chunk-466EGMFQ.js.map} +1 -1
- package/dist/{chunk-HQSK2INQ.js → chunk-4OEBL5T3.js} +2 -2
- package/dist/{chunk-IJMDBYCO.js → chunk-5JXNXKKV.js} +2 -2
- package/dist/{chunk-CQOIWJ5E.js → chunk-5NO42IYF.js} +3 -3
- package/dist/{chunk-NHUX6GXA.js → chunk-62CRBI5B.js} +2 -2
- package/dist/{chunk-5ATSXCAG.js → chunk-6VWCL2IZ.js} +3 -3
- package/dist/{chunk-CXOYUANR.js → chunk-7UHCV5B3.js} +2 -2
- package/dist/{chunk-BK2BVLZW.js → chunk-A2IJEV5L.js} +2 -2
- package/dist/{chunk-EH4BQ7LT.js → chunk-AAQ77A44.js} +2 -2
- package/dist/{chunk-R2H4ZFBJ.js → chunk-BI3CIDIH.js} +3 -3
- package/dist/{chunk-GFWRXPF6.js → chunk-CA2R2AD4.js} +12 -12
- package/dist/{chunk-4SCZZ3U7.js → chunk-D42L5SQF.js} +2 -2
- package/dist/{chunk-C6JMGAMO.js → chunk-DJMGVSST.js} +2 -2
- package/dist/{chunk-H5IUN433.js → chunk-EML6HJE6.js} +2 -2
- package/dist/{chunk-ZZTOURJI.js → chunk-EVWDNKQA.js} +13 -4
- package/dist/chunk-EVWDNKQA.js.map +1 -0
- package/dist/{chunk-MJIOGYKX.js → chunk-FBNL4BYD.js} +2 -2
- package/dist/{chunk-5KGYTX5O.js → chunk-GXVLEXIX.js} +2 -2
- package/dist/{chunk-6YEPGWUP.js → chunk-HVIXRLXJ.js} +2 -2
- package/dist/{chunk-AZDTDWS2.js → chunk-IBGRIAE5.js} +2 -2
- package/dist/{chunk-YDBIWGNI.js → chunk-IIK2PD3F.js} +8 -2
- package/dist/{chunk-YDBIWGNI.js.map → chunk-IIK2PD3F.js.map} +1 -1
- package/dist/{chunk-YR4COAEC.js → chunk-INBB7D3V.js} +2 -2
- package/dist/{chunk-VW6VIJOS.js → chunk-IVUCF3QO.js} +2 -2
- package/dist/{chunk-UGYUBENJ.js → chunk-LDZD3OQG.js} +2 -2
- package/dist/{chunk-VNZMZPAC.js → chunk-LT4SMGE4.js} +2 -2
- package/dist/{chunk-7VQ6AI7H.js → chunk-N36PBG4A.js} +2 -2
- package/dist/{chunk-G3UUAQOD.js → chunk-NFB5QTOH.js} +2 -2
- package/dist/{chunk-F2772ATT.js → chunk-NIS3FOMD.js} +2 -2
- package/dist/{chunk-4PDTVVSW.js → chunk-O6ADSFGY.js} +2 -2
- package/dist/{chunk-MAVYEZKM.js → chunk-OFQOOLQQ.js} +2 -2
- package/dist/{chunk-O2YPCFJT.js → chunk-OPNSIFFU.js} +7 -7
- package/dist/{chunk-W3FVQBGF.js → chunk-PDFAX4PK.js} +2 -2
- package/dist/{chunk-NAGMQXWV.js → chunk-QC5TJUSP.js} +2 -2
- package/dist/{chunk-2PTH4PRL.js → chunk-QZ7WOCME.js} +2 -2
- package/dist/{chunk-5MLGY6IY.js → chunk-RQMSD4CN.js} +56 -35
- package/dist/chunk-RQMSD4CN.js.map +1 -0
- package/dist/{chunk-TN4EA4X4.js → chunk-RTV3DB4I.js} +2 -2
- package/dist/{chunk-NZCKG25S.js → chunk-SSUTJLCF.js} +2 -2
- package/dist/{chunk-GUY6L6LL.js → chunk-TXE55Z3X.js} +2 -2
- package/dist/{chunk-XKRXN63M.js → chunk-UHBZK3CK.js} +2 -2
- package/dist/{chunk-PRU7OF3Y.js → chunk-UXXLP2PD.js} +3 -3
- package/dist/{chunk-V3TXIXXY.js → chunk-VOEBHBWG.js} +2 -2
- package/dist/{chunk-RI2KCQHP.js → chunk-VUBVNY3W.js} +2 -2
- package/dist/{chunk-QSEUUQUF.js → chunk-VVSPHTSU.js} +2 -2
- package/dist/{chunk-OXNTOHL6.js → chunk-VYVQZRXF.js} +2 -2
- package/dist/{chunk-L6AZOEXV.js → chunk-W3GFSWKE.js} +4 -4
- package/dist/{chunk-MXV2MY6C.js → chunk-W7NVMERN.js} +2 -2
- package/dist/{chunk-Q7DWEXG2.js → chunk-XKPLERHV.js} +19 -19
- package/dist/{chunk-KLJVTZ3R.js → chunk-YRKKW4KT.js} +3 -3
- package/dist/{chunk-DQR2LD3V.js → chunk-YW4ZYASS.js} +2 -2
- package/dist/{chunk-QS3OLP5I.js → chunk-ZDDDWTC7.js} +2 -2
- package/dist/{chunk-JZTEOBOR.js → chunk-ZDUMF4H6.js} +12 -12
- package/dist/{chunk-H6FREOYX.js → chunk-ZUCNOTNF.js} +7 -7
- package/dist/cli.js +43 -43
- package/dist/coding/export-okf-codegraph.js +2 -2
- package/dist/compounding/engine.js +4 -4
- package/dist/config.js +2 -2
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/convergence-refresh.js +5 -5
- package/dist/corpus-watermark.js +5 -5
- package/dist/entity-retrieval.js +3 -3
- package/dist/external-wiki-access.js +16 -16
- package/dist/extraction.js +3 -3
- package/dist/harmonic-retrieval.js +3 -3
- package/dist/index.js +56 -56
- package/dist/location/index.js +5 -5
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection-runner.js +5 -5
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/memory-browse-operations.js +16 -16
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-doctor-corpus.js +6 -6
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/maintenance.js +13 -13
- package/dist/orchestration/recall-rerank-coordinator.d.ts.map +1 -1
- package/dist/orchestrator.js +56 -56
- package/dist/preferences/drift-recall.d.ts.map +1 -1
- package/dist/reasoning-trace-recall.d.ts +2 -0
- package/dist/reasoning-trace-recall.d.ts.map +1 -1
- package/dist/reasoning-trace-recall.js +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-mmr.d.ts +5 -0
- package/dist/recall-mmr.d.ts.map +1 -1
- package/dist/recall-mmr.js +1 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.js +2 -2
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-navigation-operations.js +16 -16
- package/dist/recall-navigation.js +15 -15
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/resume-bundles.js +2 -2
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/source-agent-qualifier.js +3 -3
- package/dist/standup/build.js +3 -3
- package/dist/storage.js +2 -2
- package/dist/support-passport/index.js +18 -18
- package/dist/transfer/export-okf.js +3 -3
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +3 -3
- package/dist/who-knows-cli.js +4 -4
- package/dist/who-knows.js +3 -3
- package/package.json +2 -2
- package/src/orchestration/recall-rerank-coordinator.ts +46 -14
- package/src/preferences/drift-recall.ts +14 -8
- package/src/preferences/preference-drift.test.ts +15 -0
- package/src/reasoning-trace-recall.ts +33 -8
- package/src/recall-mmr.ts +17 -1
- package/src/recall-rerank-coordinator.test.ts +275 -0
- package/src/types.ts +5 -0
- package/dist/chunk-5MLGY6IY.js.map +0 -1
- package/dist/chunk-ZZTOURJI.js.map +0 -1
- /package/dist/{chunk-2PYHLSXK.js.map → chunk-2C5YAVHA.js.map} +0 -0
- /package/dist/{chunk-GWVNGDJW.js.map → chunk-2I3OREMR.js.map} +0 -0
- /package/dist/{chunk-GCVDFX66.js.map → chunk-2JGBX5XY.js.map} +0 -0
- /package/dist/{chunk-PEF5LHQU.js.map → chunk-32FVH5OQ.js.map} +0 -0
- /package/dist/{chunk-XYGQSDTH.js.map → chunk-3K6J5GO5.js.map} +0 -0
- /package/dist/{chunk-HQSK2INQ.js.map → chunk-4OEBL5T3.js.map} +0 -0
- /package/dist/{chunk-IJMDBYCO.js.map → chunk-5JXNXKKV.js.map} +0 -0
- /package/dist/{chunk-CQOIWJ5E.js.map → chunk-5NO42IYF.js.map} +0 -0
- /package/dist/{chunk-NHUX6GXA.js.map → chunk-62CRBI5B.js.map} +0 -0
- /package/dist/{chunk-5ATSXCAG.js.map → chunk-6VWCL2IZ.js.map} +0 -0
- /package/dist/{chunk-CXOYUANR.js.map → chunk-7UHCV5B3.js.map} +0 -0
- /package/dist/{chunk-BK2BVLZW.js.map → chunk-A2IJEV5L.js.map} +0 -0
- /package/dist/{chunk-EH4BQ7LT.js.map → chunk-AAQ77A44.js.map} +0 -0
- /package/dist/{chunk-R2H4ZFBJ.js.map → chunk-BI3CIDIH.js.map} +0 -0
- /package/dist/{chunk-GFWRXPF6.js.map → chunk-CA2R2AD4.js.map} +0 -0
- /package/dist/{chunk-4SCZZ3U7.js.map → chunk-D42L5SQF.js.map} +0 -0
- /package/dist/{chunk-C6JMGAMO.js.map → chunk-DJMGVSST.js.map} +0 -0
- /package/dist/{chunk-H5IUN433.js.map → chunk-EML6HJE6.js.map} +0 -0
- /package/dist/{chunk-MJIOGYKX.js.map → chunk-FBNL4BYD.js.map} +0 -0
- /package/dist/{chunk-5KGYTX5O.js.map → chunk-GXVLEXIX.js.map} +0 -0
- /package/dist/{chunk-6YEPGWUP.js.map → chunk-HVIXRLXJ.js.map} +0 -0
- /package/dist/{chunk-AZDTDWS2.js.map → chunk-IBGRIAE5.js.map} +0 -0
- /package/dist/{chunk-YR4COAEC.js.map → chunk-INBB7D3V.js.map} +0 -0
- /package/dist/{chunk-VW6VIJOS.js.map → chunk-IVUCF3QO.js.map} +0 -0
- /package/dist/{chunk-UGYUBENJ.js.map → chunk-LDZD3OQG.js.map} +0 -0
- /package/dist/{chunk-VNZMZPAC.js.map → chunk-LT4SMGE4.js.map} +0 -0
- /package/dist/{chunk-7VQ6AI7H.js.map → chunk-N36PBG4A.js.map} +0 -0
- /package/dist/{chunk-G3UUAQOD.js.map → chunk-NFB5QTOH.js.map} +0 -0
- /package/dist/{chunk-F2772ATT.js.map → chunk-NIS3FOMD.js.map} +0 -0
- /package/dist/{chunk-4PDTVVSW.js.map → chunk-O6ADSFGY.js.map} +0 -0
- /package/dist/{chunk-MAVYEZKM.js.map → chunk-OFQOOLQQ.js.map} +0 -0
- /package/dist/{chunk-O2YPCFJT.js.map → chunk-OPNSIFFU.js.map} +0 -0
- /package/dist/{chunk-W3FVQBGF.js.map → chunk-PDFAX4PK.js.map} +0 -0
- /package/dist/{chunk-NAGMQXWV.js.map → chunk-QC5TJUSP.js.map} +0 -0
- /package/dist/{chunk-2PTH4PRL.js.map → chunk-QZ7WOCME.js.map} +0 -0
- /package/dist/{chunk-TN4EA4X4.js.map → chunk-RTV3DB4I.js.map} +0 -0
- /package/dist/{chunk-NZCKG25S.js.map → chunk-SSUTJLCF.js.map} +0 -0
- /package/dist/{chunk-GUY6L6LL.js.map → chunk-TXE55Z3X.js.map} +0 -0
- /package/dist/{chunk-XKRXN63M.js.map → chunk-UHBZK3CK.js.map} +0 -0
- /package/dist/{chunk-PRU7OF3Y.js.map → chunk-UXXLP2PD.js.map} +0 -0
- /package/dist/{chunk-V3TXIXXY.js.map → chunk-VOEBHBWG.js.map} +0 -0
- /package/dist/{chunk-RI2KCQHP.js.map → chunk-VUBVNY3W.js.map} +0 -0
- /package/dist/{chunk-QSEUUQUF.js.map → chunk-VVSPHTSU.js.map} +0 -0
- /package/dist/{chunk-OXNTOHL6.js.map → chunk-VYVQZRXF.js.map} +0 -0
- /package/dist/{chunk-L6AZOEXV.js.map → chunk-W3GFSWKE.js.map} +0 -0
- /package/dist/{chunk-MXV2MY6C.js.map → chunk-W7NVMERN.js.map} +0 -0
- /package/dist/{chunk-Q7DWEXG2.js.map → chunk-XKPLERHV.js.map} +0 -0
- /package/dist/{chunk-KLJVTZ3R.js.map → chunk-YRKKW4KT.js.map} +0 -0
- /package/dist/{chunk-DQR2LD3V.js.map → chunk-YW4ZYASS.js.map} +0 -0
- /package/dist/{chunk-QS3OLP5I.js.map → chunk-ZDDDWTC7.js.map} +0 -0
- /package/dist/{chunk-JZTEOBOR.js.map → chunk-ZDUMF4H6.js.map} +0 -0
- /package/dist/{chunk-H6FREOYX.js.map → chunk-ZUCNOTNF.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RECALL_DISCLOSURE_LEVELS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-466EGMFQ.js";
|
|
4
4
|
|
|
5
5
|
// src/recall-navigate.ts
|
|
6
6
|
var RECALL_NAV_LINK_TYPES = [
|
|
@@ -48,4 +48,4 @@ export {
|
|
|
48
48
|
expandRecallNode,
|
|
49
49
|
traverseRecallLink
|
|
50
50
|
};
|
|
51
|
-
//# sourceMappingURL=chunk-
|
|
51
|
+
//# sourceMappingURL=chunk-4OEBL5T3.js.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
computeCorpusWatermarks,
|
|
6
6
|
resolveCorpusNamespaceRoots
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VVSPHTSU.js";
|
|
8
8
|
|
|
9
9
|
// src/operator-doctor-corpus.ts
|
|
10
10
|
var DIGEST_PREFIX_LENGTH = 12;
|
|
@@ -78,4 +78,4 @@ export {
|
|
|
78
78
|
corpusWatermarksFromCheck,
|
|
79
79
|
summarizeCorpusAndReplica
|
|
80
80
|
};
|
|
81
|
-
//# sourceMappingURL=chunk-
|
|
81
|
+
//# sourceMappingURL=chunk-5JXNXKKV.js.map
|
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
defineOperation,
|
|
22
22
|
parseNamespacePreflightWriteOp,
|
|
23
23
|
resolveAuthorizedNamespaceWritablePreflight
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-CA2R2AD4.js";
|
|
25
25
|
import {
|
|
26
26
|
parseSharedWriteOutputControls
|
|
27
27
|
} from "./chunk-IFBSZGW3.js";
|
|
28
28
|
import {
|
|
29
29
|
validateBriefingFormat
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-LT4SMGE4.js";
|
|
31
31
|
import {
|
|
32
32
|
parseDeepRecallMaxSteps
|
|
33
33
|
} from "./chunk-A7AISUJI.js";
|
|
@@ -603,4 +603,4 @@ defineOperation({ name: "graph_events", description: "SSE graph events.", schema
|
|
|
603
603
|
defineOperation({ name: "chat_message", description: "Chat message.", schema: strictSchema({ message: S.str, chatSessionId: S.str }), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
|
|
604
604
|
defineOperation({ name: "chat_events", description: "SSE chat events.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { stream: "sse" } }) });
|
|
605
605
|
defineOperation({ name: "adapters_status", description: "Adapter registry metadata (issue #1850 round 5). Marker op: the HTTP transport builds the response from its own adapterRegistry, but the op still must be registered so it appears in listRegisteredOperations and enforceTokenOp can gate it for scoped tokens.", schema: strictSchema({}), handler: async (_i, _ctx) => ({ result: { ok: true } }) });
|
|
606
|
-
//# sourceMappingURL=chunk-
|
|
606
|
+
//# sourceMappingURL=chunk-5NO42IYF.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "./chunk-LXATZLSC.js";
|
|
12
12
|
import {
|
|
13
13
|
StorageManager
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-D42L5SQF.js";
|
|
15
15
|
import {
|
|
16
16
|
isValidityExpiredNow
|
|
17
17
|
} from "./chunk-6CIAGZ6X.js";
|
|
@@ -416,4 +416,4 @@ export {
|
|
|
416
416
|
readProjectedHarmonicGraph,
|
|
417
417
|
searchHarmonicRetrieval
|
|
418
418
|
};
|
|
419
|
-
//# sourceMappingURL=chunk-
|
|
419
|
+
//# sourceMappingURL=chunk-62CRBI5B.js.map
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
listMemoryGovernanceRuns,
|
|
9
9
|
readMemoryGovernanceRunArtifact
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-DJMGVSST.js";
|
|
11
11
|
import {
|
|
12
12
|
StorageManager
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-D42L5SQF.js";
|
|
14
14
|
import {
|
|
15
15
|
normalizeProjectionPreview,
|
|
16
16
|
normalizeProjectionTags
|
|
@@ -1156,4 +1156,4 @@ export {
|
|
|
1156
1156
|
verifyMemoryProjection,
|
|
1157
1157
|
repairMemoryProjection
|
|
1158
1158
|
};
|
|
1159
|
-
//# sourceMappingURL=chunk-
|
|
1159
|
+
//# sourceMappingURL=chunk-6VWCL2IZ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineOperation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CA2R2AD4.js";
|
|
4
4
|
import {
|
|
5
5
|
EngramAccessInputError
|
|
6
6
|
} from "./chunk-3MUKQQ7A.js";
|
|
@@ -92,4 +92,4 @@ defineOperation({
|
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
});
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-7UHCV5B3.js.map
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
} from "./chunk-3UXOZBHV.js";
|
|
15
15
|
import {
|
|
16
16
|
StorageManager
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-D42L5SQF.js";
|
|
18
18
|
import {
|
|
19
19
|
OKF_PROFILE_TYPE,
|
|
20
20
|
okfTypeForMemory
|
|
@@ -272,4 +272,4 @@ export {
|
|
|
272
272
|
exportOkfBundle,
|
|
273
273
|
firstHeading
|
|
274
274
|
};
|
|
275
|
-
//# sourceMappingURL=chunk-
|
|
275
|
+
//# sourceMappingURL=chunk-A2IJEV5L.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-4Q26RNSR.js";
|
|
4
4
|
import {
|
|
5
5
|
isRecallDisclosure
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-466EGMFQ.js";
|
|
7
7
|
import {
|
|
8
8
|
EngramAccessInputError
|
|
9
9
|
} from "./chunk-3MUKQQ7A.js";
|
|
@@ -165,4 +165,4 @@ export {
|
|
|
165
165
|
handleRecallWhyHttpQuery,
|
|
166
166
|
handleRecallXrayHttpQuery
|
|
167
167
|
};
|
|
168
|
-
//# sourceMappingURL=chunk-
|
|
168
|
+
//# sourceMappingURL=chunk-AAQ77A44.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseXrayFormat
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-VYVQZRXF.js";
|
|
4
4
|
import {
|
|
5
5
|
RECALL_DISCLOSURE_LEVELS,
|
|
6
6
|
isRecallDisclosure
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-466EGMFQ.js";
|
|
8
8
|
|
|
9
9
|
// src/recall-xray-cli.ts
|
|
10
10
|
function parseXrayDisclosureFlag(value) {
|
|
@@ -50,4 +50,4 @@ export {
|
|
|
50
50
|
parseXrayBudgetFlag,
|
|
51
51
|
parseXrayCliOptions
|
|
52
52
|
};
|
|
53
|
-
//# sourceMappingURL=chunk-
|
|
53
|
+
//# sourceMappingURL=chunk-BI3CIDIH.js.map
|
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
computeWhoKnows,
|
|
42
42
|
loadWhoKnowsEntities,
|
|
43
43
|
validateWhoKnowsInput
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-O6ADSFGY.js";
|
|
45
45
|
import {
|
|
46
46
|
getTrustZoneStoreStatus,
|
|
47
47
|
isTrustZoneName,
|
|
@@ -77,7 +77,7 @@ import {
|
|
|
77
77
|
} from "./chunk-KIW3OOZE.js";
|
|
78
78
|
import {
|
|
79
79
|
planDisclosureStep
|
|
80
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-ZDDDWTC7.js";
|
|
81
81
|
import {
|
|
82
82
|
DEFAULT_TRAVERSE_LIMIT,
|
|
83
83
|
selectTraverseNeighbors
|
|
@@ -87,11 +87,11 @@ import {
|
|
|
87
87
|
} from "./chunk-7O5EW7KX.js";
|
|
88
88
|
import {
|
|
89
89
|
toRecallExplainJson
|
|
90
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-VYVQZRXF.js";
|
|
91
91
|
import {
|
|
92
92
|
estimateRecallTokens,
|
|
93
93
|
summarizeDisclosureTokens
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-IVUCF3QO.js";
|
|
95
95
|
import {
|
|
96
96
|
takeNavigateBudget
|
|
97
97
|
} from "./chunk-VYDGHJIN.js";
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
} from "./chunk-H7XKCNR6.js";
|
|
101
101
|
import {
|
|
102
102
|
readAggregateExtractionWatermark
|
|
103
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-YW4ZYASS.js";
|
|
104
104
|
import {
|
|
105
105
|
ReplicaDivergenceMonitor
|
|
106
106
|
} from "./chunk-E6UNM67F.js";
|
|
@@ -130,7 +130,7 @@ import {
|
|
|
130
130
|
} from "./chunk-DMDWFQMR.js";
|
|
131
131
|
import {
|
|
132
132
|
readProjectedHarmonicGraph
|
|
133
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-62CRBI5B.js";
|
|
134
134
|
import {
|
|
135
135
|
wrapWorkLayerContext
|
|
136
136
|
} from "./chunk-EI6V5UXY.js";
|
|
@@ -175,7 +175,7 @@ import {
|
|
|
175
175
|
import {
|
|
176
176
|
CorpusWatermarkCache,
|
|
177
177
|
computeServiceCorpusCensus
|
|
178
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-VVSPHTSU.js";
|
|
179
179
|
import {
|
|
180
180
|
CrossNamespaceBudget,
|
|
181
181
|
toBudgetWarning
|
|
@@ -187,7 +187,7 @@ import {
|
|
|
187
187
|
listMemoryGovernanceRuns,
|
|
188
188
|
readMemoryGovernanceRunArtifact,
|
|
189
189
|
runMemoryGovernance
|
|
190
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-DJMGVSST.js";
|
|
191
191
|
import {
|
|
192
192
|
defaultCapsulesDir
|
|
193
193
|
} from "./chunk-ZY2MNJR6.js";
|
|
@@ -197,7 +197,7 @@ import {
|
|
|
197
197
|
enqueuePassiveCorrectionNotification,
|
|
198
198
|
parseBriefingFocus,
|
|
199
199
|
parseBriefingWindow
|
|
200
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-LT4SMGE4.js";
|
|
201
201
|
import {
|
|
202
202
|
ExtractionDeadlineError
|
|
203
203
|
} from "./chunk-LO76EF3Y.js";
|
|
@@ -256,7 +256,7 @@ import {
|
|
|
256
256
|
qmdCollectionPathParts,
|
|
257
257
|
qmdResultPathCandidates,
|
|
258
258
|
selfDeps
|
|
259
|
-
} from "./chunk-
|
|
259
|
+
} from "./chunk-D42L5SQF.js";
|
|
260
260
|
import {
|
|
261
261
|
namespaceCollectionName
|
|
262
262
|
} from "./chunk-MWWAQXZ6.js";
|
|
@@ -291,7 +291,7 @@ import {
|
|
|
291
291
|
import {
|
|
292
292
|
DEFAULT_RECALL_DISCLOSURE,
|
|
293
293
|
isRecallDisclosure
|
|
294
|
-
} from "./chunk-
|
|
294
|
+
} from "./chunk-466EGMFQ.js";
|
|
295
295
|
import {
|
|
296
296
|
extractJsonCandidates
|
|
297
297
|
} from "./chunk-YBA52OKG.js";
|
|
@@ -18737,4 +18737,4 @@ export {
|
|
|
18737
18737
|
EngramAccessService,
|
|
18738
18738
|
AccessAdminOpsSurface
|
|
18739
18739
|
};
|
|
18740
|
-
//# sourceMappingURL=chunk-
|
|
18740
|
+
//# sourceMappingURL=chunk-CA2R2AD4.js.map
|
|
@@ -162,7 +162,7 @@ import {
|
|
|
162
162
|
import {
|
|
163
163
|
SPECULATIVE_TTL_DAYS,
|
|
164
164
|
confidenceTier
|
|
165
|
-
} from "./chunk-
|
|
165
|
+
} from "./chunk-466EGMFQ.js";
|
|
166
166
|
import {
|
|
167
167
|
composeMemoryEnvelope,
|
|
168
168
|
isSealedMemoryEnvelope,
|
|
@@ -11579,4 +11579,4 @@ export {
|
|
|
11579
11579
|
isValidBufferSurpriseEvent,
|
|
11580
11580
|
StorageManager3 as StorageManager
|
|
11581
11581
|
};
|
|
11582
|
-
//# sourceMappingURL=chunk-
|
|
11582
|
+
//# sourceMappingURL=chunk-D42L5SQF.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-TBBDFYXW.js";
|
|
4
4
|
import {
|
|
5
5
|
StorageManager
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D42L5SQF.js";
|
|
7
7
|
import {
|
|
8
8
|
bumpMemoryCorpusVersionForDir
|
|
9
9
|
} from "./chunk-M5GVCJSJ.js";
|
|
@@ -769,4 +769,4 @@ export {
|
|
|
769
769
|
listMemoryGovernanceRuns,
|
|
770
770
|
readMemoryGovernanceRunArtifact
|
|
771
771
|
};
|
|
772
|
-
//# sourceMappingURL=chunk-
|
|
772
|
+
//# sourceMappingURL=chunk-DJMGVSST.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-B7RWBZXW.js";
|
|
4
4
|
import {
|
|
5
5
|
StorageManager
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-D42L5SQF.js";
|
|
7
7
|
import {
|
|
8
8
|
getCachedEpisodeMap,
|
|
9
9
|
setCachedEpisodeMap
|
|
@@ -109,4 +109,4 @@ export {
|
|
|
109
109
|
compareVerifiedEpisodeResults,
|
|
110
110
|
searchVerifiedEpisodes
|
|
111
111
|
};
|
|
112
|
-
//# sourceMappingURL=chunk-
|
|
112
|
+
//# sourceMappingURL=chunk-EML6HJE6.js.map
|
|
@@ -46,6 +46,12 @@ function isReasoningTracePath(candidatePath) {
|
|
|
46
46
|
return /(^|[\\/])reasoning-traces([\\/]|$)/.test(candidatePath);
|
|
47
47
|
}
|
|
48
48
|
var DEFAULT_REASONING_TRACE_BOOST = 0.15;
|
|
49
|
+
function comparisonRelevance(row) {
|
|
50
|
+
if (typeof row.effectiveScore === "number" && Number.isFinite(row.effectiveScore)) {
|
|
51
|
+
return row.effectiveScore;
|
|
52
|
+
}
|
|
53
|
+
return typeof row.score === "number" && Number.isFinite(row.score) ? row.score : 0;
|
|
54
|
+
}
|
|
49
55
|
function applyReasoningTraceBoost(results, options) {
|
|
50
56
|
if (!options.enabled) return [...results];
|
|
51
57
|
if (!Array.isArray(results) || results.length === 0) return [...results];
|
|
@@ -57,7 +63,10 @@ function applyReasoningTraceBoost(results, options) {
|
|
|
57
63
|
if (isReasoningTracePath(r.path)) {
|
|
58
64
|
changed = true;
|
|
59
65
|
const baseScore = typeof r.score === "number" && Number.isFinite(r.score) ? r.score : 0;
|
|
60
|
-
|
|
66
|
+
const effective = typeof r.effectiveScore === "number" && Number.isFinite(r.effectiveScore) ? r.effectiveScore + boostAmount : void 0;
|
|
67
|
+
boosted.push(
|
|
68
|
+
effective === void 0 ? { ...r, score: baseScore + boostAmount } : { ...r, score: baseScore + boostAmount, effectiveScore: effective }
|
|
69
|
+
);
|
|
61
70
|
} else {
|
|
62
71
|
boosted.push(r);
|
|
63
72
|
}
|
|
@@ -67,12 +76,12 @@ function applyReasoningTraceBoost(results, options) {
|
|
|
67
76
|
for (let i = 0; i < out.length; i++) {
|
|
68
77
|
if (!isReasoningTracePath(out[i].path)) continue;
|
|
69
78
|
const trace = out[i];
|
|
70
|
-
const traceScore =
|
|
79
|
+
const traceScore = comparisonRelevance(trace);
|
|
71
80
|
let j = i;
|
|
72
81
|
while (j > 0) {
|
|
73
82
|
const prev = out[j - 1];
|
|
74
83
|
if (isReasoningTracePath(prev.path)) break;
|
|
75
|
-
const prevScore =
|
|
84
|
+
const prevScore = comparisonRelevance(prev);
|
|
76
85
|
if (prevScore >= traceScore) break;
|
|
77
86
|
out[j] = prev;
|
|
78
87
|
j -= 1;
|
|
@@ -88,4 +97,4 @@ export {
|
|
|
88
97
|
DEFAULT_REASONING_TRACE_BOOST,
|
|
89
98
|
applyReasoningTraceBoost
|
|
90
99
|
};
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
100
|
+
//# sourceMappingURL=chunk-EVWDNKQA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/reasoning-trace-recall.ts"],"sourcesContent":["/**\n * Reasoning-trace recall boost (issue #564 PR 3).\n *\n * Pure helpers for:\n * - detecting whether a user query looks like a problem-solving ask\n * (\"how do I…\", \"step by step\", etc.)\n * - boosting stored reasoning_trace memories within a result list when that\n * condition matches.\n *\n * Callers gate these helpers behind the `recallReasoningTraceBoostEnabled`\n * config flag (default false); the helpers themselves are also no-ops when\n * `enabled` is false so they can be safely chained into the recall pipeline.\n */\n\n/**\n * Heuristic: does the incoming query read like the user wants a stored\n * solution chain (reasoning trace)?\n *\n * Positive signals:\n * - starts with \"how do I\", \"how can I\", \"how would I\", \"how to\"\n * - contains \"step by step\", \"walk me through\", \"work through\"\n * - contains \"reasoning\", \"think through\", \"figure out\", \"debug\"\n * - explicitly mentions \"trace\" or \"chain of thought\"\n *\n * This is intentionally conservative — the boost is OFF by default, so false\n * negatives are cheap, but false positives would shift retrieval for ordinary\n * queries on an opt-in install.\n */\nexport function looksLikeProblemSolvingQuery(query: string): boolean {\n if (typeof query !== \"string\") return false;\n const q = query.trim().toLowerCase();\n if (q.length === 0) return false;\n\n // Starts-with patterns.\n const startsWithPatterns = [\n /^how\\s+do\\s+i\\b/,\n /^how\\s+can\\s+i\\b/,\n /^how\\s+would\\s+i\\b/,\n /^how\\s+should\\s+i\\b/,\n /^how\\s+to\\b/,\n /^what'?s?\\s+the\\s+best\\s+way\\s+to\\b/,\n /^can\\s+you\\s+walk\\s+me\\s+through\\b/,\n /^walk\\s+me\\s+through\\b/,\n /^help\\s+me\\s+debug\\b/,\n /^help\\s+me\\s+figure\\s+out\\b/,\n /^why\\s+(does|is|did)\\b/,\n ];\n for (const re of startsWithPatterns) {\n if (re.test(q)) return true;\n }\n\n // Anywhere-in-string phrases. These mirror the doc-comment's stated\n // positive signals: broader variants (\"work through\", \"figure out\",\n // \"debug this\") are included so \"how do I debug this\" doesn't have to\n // lean on the `help me debug` starts-with entry alone, and so queries\n // like \"work through the problem\" or \"figure out why it broke\" trigger\n // the heuristic as the docstring claims.\n const phrases = [\n \"step by step\",\n \"step-by-step\",\n \"work through\",\n \"walk through\",\n \"walk me through\",\n \"reason through\",\n \"think through\",\n \"figure out\",\n \"chain of thought\",\n \"reasoning trace\",\n \"solution chain\",\n \"troubleshoot\",\n \"debug this\",\n \"debug the\",\n \" debug \",\n ];\n for (const phrase of phrases) {\n if (q.includes(phrase)) return true;\n }\n\n return false;\n}\n\n/**\n * Minimal shape the boost helper needs to read from a recall result. Matches\n * QmdSearchResult as of issue #564 but kept structural so tests and future\n * callers don't have to import orchestrator-level types.\n */\nexport interface BoostableResult {\n path: string;\n score: number;\n docid?: string;\n /** Effective relevance carried forward by an upstream rerank stage. */\n effectiveScore?: number;\n}\n\n/**\n * Path-based marker for memories that live in the dedicated\n * reasoning-traces/ subtree. Using a path segment keeps this cheap: no\n * frontmatter parsing or extra I/O is needed.\n */\nexport function isReasoningTracePath(candidatePath: string): boolean {\n if (typeof candidatePath !== \"string\") return false;\n // Match \"/reasoning-traces/\" as a full path segment to avoid false\n // positives like \"my-reasoning-traces-notes/\".\n return /(^|[\\\\/])reasoning-traces([\\\\/]|$)/.test(candidatePath);\n}\n\n/**\n * Default additive boost applied to a reasoning_trace candidate when the\n * current query looks like a problem-solving ask.\n *\n * Chosen to be roughly the same magnitude as the existing CATEGORY_BOOSTS\n * entry for reasoning_trace (0.09 in importance scoring), keeping the signal\n * visible but not overwhelming stronger lexical/vector matches.\n */\nexport const DEFAULT_REASONING_TRACE_BOOST = 0.15;\n\nexport interface ApplyReasoningTraceBoostOptions {\n enabled: boolean;\n query: string;\n boost?: number;\n}\n\n/**\n * The relevance a row is compared on: its effective relevance when a rerank\n * stage left one (MMR ranks on the same basis), else the raw retrieval score.\n */\nfunction comparisonRelevance(row: BoostableResult): number {\n if (typeof row.effectiveScore === \"number\" && Number.isFinite(row.effectiveScore)) {\n return row.effectiveScore;\n }\n return typeof row.score === \"number\" && Number.isFinite(row.score) ? row.score : 0;\n}\n\n/**\n * Apply a score boost to results whose path sits under reasoning-traces/\n * when the query looks like a problem-solving ask. Returns a new array;\n * the input array is not mutated.\n *\n * Ordering policy: the helper walks the results in order, boosts every\n * matching reasoning trace in place, then promotes each boosted trace\n * upward PAST any non-boosted neighbor whose score is strictly lower\n * than the trace's boosted score. Non-matching results keep their\n * incoming relative order — so reranker-driven path ordering and any\n * other upstream nudges on non-trace items are preserved. We do NOT\n * re-sort the full list, which would wipe out rerank priority on\n * non-trace items (whose numeric scores may have been left stale by the\n * rerank pass). This matters because MMR runs immediately after and\n * truncates to a topN window — globally re-sorting would silently drop\n * reranker-promoted items below the cutoff.\n *\n * No-ops (returns a copy of the input unchanged) when:\n * - `enabled` is false,\n * - `query` is empty / not a problem-solving ask,\n * - the result list contains no reasoning-trace paths.\n *\n * Note on legacy paths: this helper intentionally only matches paths\n * under the dedicated `reasoning-traces/` subtree introduced by PR 3.\n * Historical reasoning_trace memories (if any) written before that\n * subtree existed were routed to `facts/<date>/` and are NOT\n * boost-eligible. Operators upgrading across that boundary should run\n * the migration CLI or rewrite old paths before enabling the boost.\n */\nexport function applyReasoningTraceBoost<R extends BoostableResult>(\n results: readonly R[],\n options: ApplyReasoningTraceBoostOptions,\n): R[] {\n if (!options.enabled) return [...results];\n if (!Array.isArray(results) || results.length === 0) return [...results];\n if (!looksLikeProblemSolvingQuery(options.query)) return [...results];\n\n const boostAmount =\n typeof options.boost === \"number\" && Number.isFinite(options.boost) && options.boost >= 0\n ? options.boost\n : DEFAULT_REASONING_TRACE_BOOST;\n\n // Step 1: boost the scores of matching traces, preserving positions.\n const boosted: R[] = [];\n let changed = false;\n for (const r of results) {\n if (isReasoningTracePath(r.path)) {\n changed = true;\n const baseScore = typeof r.score === \"number\" && Number.isFinite(r.score) ? r.score : 0;\n // Compose the boost into the effective relevance too: a downstream MMR\n // pass prefers it over the raw score, so a stale value would drop the\n // boost.\n const effective =\n typeof r.effectiveScore === \"number\" && Number.isFinite(r.effectiveScore)\n ? r.effectiveScore + boostAmount\n : undefined;\n boosted.push(\n effective === undefined\n ? ({ ...r, score: baseScore + boostAmount } as R)\n : ({ ...r, score: baseScore + boostAmount, effectiveScore: effective } as R),\n );\n } else {\n boosted.push(r);\n }\n }\n if (!changed) return boosted;\n\n // Step 2: promote each boosted trace upward past any non-trace neighbor\n // whose relevance is strictly lower than the boosted trace's. The\n // comparison uses the SAME basis MMR ranks on — the effective relevance a\n // rerank stage left behind, else the raw score — so the boost cannot\n // promote a trace the pipeline deliberately demoted. Non-trace items never\n // move past each other, so reranker-driven ordering on non-trace items is\n // preserved.\n const out = boosted.slice();\n for (let i = 0; i < out.length; i++) {\n if (!isReasoningTracePath(out[i].path)) continue;\n const trace = out[i];\n const traceScore = comparisonRelevance(trace);\n let j = i;\n while (j > 0) {\n const prev = out[j - 1];\n if (isReasoningTracePath(prev.path)) break; // don't reorder traces vs each other\n const prevScore = comparisonRelevance(prev);\n if (prevScore >= traceScore) break;\n out[j] = prev;\n j -= 1;\n }\n if (j !== i) out[j] = trace;\n }\n\n return out;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isNamespaceKind
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2I3OREMR.js";
|
|
4
4
|
import {
|
|
5
5
|
EngramAccessInputError
|
|
6
6
|
} from "./chunk-3MUKQQ7A.js";
|
|
@@ -40,4 +40,4 @@ export {
|
|
|
40
40
|
positiveIntQueryParam,
|
|
41
41
|
optionalNamespaceKindQueryParam
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-FBNL4BYD.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseFrontmatter
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-D42L5SQF.js";
|
|
4
4
|
import {
|
|
5
5
|
activityDigestPath,
|
|
6
6
|
isValidActivityDate
|
|
@@ -199,4 +199,4 @@ export {
|
|
|
199
199
|
buildStandup,
|
|
200
200
|
standupHelp
|
|
201
201
|
};
|
|
202
|
-
//# sourceMappingURL=chunk-
|
|
202
|
+
//# sourceMappingURL=chunk-GXVLEXIX.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-7T4TOGMS.js";
|
|
4
4
|
import {
|
|
5
5
|
defineOperation
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CA2R2AD4.js";
|
|
7
7
|
|
|
8
8
|
// src/external-wiki-access.ts
|
|
9
9
|
import { z } from "zod";
|
|
@@ -26,4 +26,4 @@ var externalWikiSearchOperation = defineOperation({
|
|
|
26
26
|
export {
|
|
27
27
|
externalWikiSearchOperation
|
|
28
28
|
};
|
|
29
|
-
//# sourceMappingURL=chunk-
|
|
29
|
+
//# sourceMappingURL=chunk-HVIXRLXJ.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineOperation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CA2R2AD4.js";
|
|
4
4
|
import {
|
|
5
5
|
EngramAccessInputError
|
|
6
6
|
} from "./chunk-3MUKQQ7A.js";
|
|
@@ -71,4 +71,4 @@ defineOperation({
|
|
|
71
71
|
})
|
|
72
72
|
})
|
|
73
73
|
});
|
|
74
|
-
//# sourceMappingURL=chunk-
|
|
74
|
+
//# sourceMappingURL=chunk-IBGRIAE5.js.map
|
|
@@ -242,7 +242,7 @@ function reorderRecallResultsWithMmr(results, options = {}) {
|
|
|
242
242
|
const candidates = results.map((r, index) => ({
|
|
243
243
|
id: makeRecallKey(r, index),
|
|
244
244
|
content: r.snippet ?? "",
|
|
245
|
-
score:
|
|
245
|
+
score: effectiveRelevance(r),
|
|
246
246
|
embedding: null
|
|
247
247
|
}));
|
|
248
248
|
const indexById = /* @__PURE__ */ new Map();
|
|
@@ -282,6 +282,12 @@ function reorderRecallResultsWithMmr(results, options = {}) {
|
|
|
282
282
|
);
|
|
283
283
|
return { reordered, diversity, lambda };
|
|
284
284
|
}
|
|
285
|
+
function effectiveRelevance(r) {
|
|
286
|
+
if (typeof r.effectiveScore === "number" && Number.isFinite(r.effectiveScore)) {
|
|
287
|
+
return r.effectiveScore;
|
|
288
|
+
}
|
|
289
|
+
return typeof r.score === "number" ? r.score : 0;
|
|
290
|
+
}
|
|
285
291
|
function makeRecallKey(r, index) {
|
|
286
292
|
const baseKey = r.path || r.docid || "";
|
|
287
293
|
return `${baseKey}::${index}`;
|
|
@@ -295,4 +301,4 @@ export {
|
|
|
295
301
|
normalizeTokens,
|
|
296
302
|
reorderRecallResultsWithMmr
|
|
297
303
|
};
|
|
298
|
-
//# sourceMappingURL=chunk-
|
|
304
|
+
//# sourceMappingURL=chunk-IIK2PD3F.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/recall-mmr.ts"],"sourcesContent":["/**\n * Maximal Marginal Relevance (MMR) re-selection for recall candidates.\n *\n * After the reranker produces its ordered candidate list, we run an MMR pass\n * over the top N candidates (per-section) so that a cluster of near-duplicate\n * high-scoring facts cannot dominate the injected context.\n *\n * MMR(d) = λ * sim(d, query) − (1 − λ) * max_{d' ∈ selected} sim(d, d')\n *\n * - λ defaults to 0.7 (tilted toward relevance, with meaningful diversity).\n * - Similarity uses cosine over pre-computed embeddings when available, and\n * falls back to Jaccard over normalized tokens (lowercased alphanumerics)\n * when embeddings are missing.\n * - Per-section application is the caller's responsibility: pass each\n * section's ordered candidate slice independently so one cluster in one\n * section cannot starve another section.\n *\n * Pure, deterministic, no IO. Input arrays are never mutated.\n */\n\n/** Minimal candidate shape used by MMR. Callers may wrap their own records. */\nexport interface MmrCandidate {\n /** Stable identifier for the candidate. Only used for tie-breaking. */\n id: string;\n /** Text content used for the Jaccard similarity fallback. */\n content: string;\n /**\n * Relevance score from the upstream ranker (e.g. rerank score or RRF).\n * Used as the `sim(d, query)` term when no query embedding is available.\n */\n score: number;\n /** Optional pre-computed embedding vector for cosine similarity. */\n embedding?: readonly number[] | null;\n}\n\nexport interface ApplyMmrOptions<C extends MmrCandidate> {\n /** Ordered candidate list (most relevant first). */\n candidates: readonly C[];\n /** Optional query embedding. If provided and candidates carry embeddings,\n * relevance is measured by cosine similarity to the query. Otherwise\n * candidate `score` is normalized and used. */\n queryEmbedding?: readonly number[] | null;\n /** λ ∈ [0, 1]. 1 = pure relevance, 0 = pure diversity. Default 0.7. */\n lambda?: number;\n /** Apply MMR only over the top N candidates. Default 40. */\n topN?: number;\n /** Maximum number of candidates to select. Default = candidates length. */\n budget?: number;\n}\n\nexport interface MmrDiversityReport {\n /**\n * Total number of candidates MMR considered (the full input pool, pre-MMR).\n * Previously this mirrored `kept` and was therefore uninformative; it now\n * reflects the true pool size so `kept/considered` logs carry signal even\n * though MMR is reorder-only.\n */\n considered: number;\n /**\n * Number of candidates present in the MMR output. With the current\n * orchestrator pipeline MMR is reorder-only (no drops), so this is the\n * same as `considered`. It's still reported separately so a future\n * drop-mode MMR can distinguish them without another schema change.\n */\n kept: number;\n /**\n * Head-of-list positions whose candidate identity changed between the\n * pre-MMR and post-MMR slices. This is the *actionable* diversity signal:\n * it tells the caller how many of the top `sampleSize` results MMR\n * promoted or demoted. Zero means MMR had no head-of-list effect; a value\n * greater than zero means at least one diverse candidate was swapped in.\n */\n headReorderCount: number;\n /** Average pairwise similarity of the head-of-list input slice (pre-MMR). */\n avgPairwiseSimBefore: number;\n /** Average pairwise similarity of the head-of-list MMR output slice. */\n avgPairwiseSimAfter: number;\n}\n\nexport const DEFAULT_LAMBDA = 0.7;\nexport const DEFAULT_TOP_N = 40;\n/**\n * Default number of head-of-list candidates compared by\n * {@link summarizeMmrDiversity}. Small on purpose: we want to measure whether\n * MMR actually *changed* the head of the list. Comparing the full top-N slice\n * is meaningless when `budget >= candidates.length` because both slices\n * contain the same set (just reordered), making pairwise-similarity\n * order-independent and identical before vs after.\n */\nconst DEFAULT_DIVERSITY_SAMPLE_SIZE = 10;\n\n/**\n * Pure MMR re-selection over an ordered candidate list.\n *\n * Returns a new array — the input is never mutated. When `candidates.length`\n * is `<= 1` or `budget <= 0`, a defensive copy is returned as a no-op.\n */\nexport function applyMmrToCandidates<C extends MmrCandidate>(\n opts: ApplyMmrOptions<C>,\n): C[] {\n const candidates = Array.isArray(opts.candidates) ? opts.candidates : [];\n if (candidates.length === 0) return [];\n\n const lambda = clampLambda(opts.lambda);\n const topN = clampPositiveInt(opts.topN, DEFAULT_TOP_N);\n const budget = clampPositiveInt(opts.budget, candidates.length);\n\n if (budget <= 0) return [];\n if (candidates.length === 1) return [candidates[0]!];\n\n // Only reorder the top-N slice; anything past it keeps its original position\n // appended at the end (but will not be selected unless budget > topN).\n const pool = candidates.slice(0, topN);\n const tail = candidates.slice(topN);\n\n // Relevance scores as `sim(d, query)`. Prefer cosine to the query embedding\n // when we can compute it; otherwise fall back to the candidate's own score\n // normalized into [0, 1] across the pool.\n const relevance = computeRelevanceScores(pool, opts.queryEmbedding);\n\n // Pre-compute pairwise candidate-candidate similarity lazily as needed.\n const pairSim = new Map<string, number>();\n const pairKey = (i: number, j: number): string =>\n i < j ? `${i}:${j}` : `${j}:${i}`;\n const sim = (i: number, j: number): number => {\n if (i === j) return 1;\n const key = pairKey(i, j);\n const cached = pairSim.get(key);\n if (cached !== undefined) return cached;\n const a = pool[i]!;\n const b = pool[j]!;\n const s = similarity(a, b);\n pairSim.set(key, s);\n return s;\n };\n\n const selectedIdx: number[] = [];\n const remaining = new Set<number>();\n for (let i = 0; i < pool.length; i += 1) remaining.add(i);\n\n while (selectedIdx.length < budget && remaining.size > 0) {\n let bestIdx = -1;\n let bestMmr = Number.NEGATIVE_INFINITY;\n for (const idx of remaining) {\n const rel = relevance[idx] ?? 0;\n let maxSimToSelected = 0;\n if (selectedIdx.length > 0) {\n for (const s of selectedIdx) {\n const pairwise = sim(idx, s);\n if (pairwise > maxSimToSelected) maxSimToSelected = pairwise;\n }\n }\n const mmr = lambda * rel - (1 - lambda) * maxSimToSelected;\n if (\n mmr > bestMmr ||\n // Stable tie-breaker: prefer the earlier original position.\n (mmr === bestMmr && (bestIdx < 0 || idx < bestIdx))\n ) {\n bestMmr = mmr;\n bestIdx = idx;\n }\n }\n if (bestIdx < 0) break;\n selectedIdx.push(bestIdx);\n remaining.delete(bestIdx);\n }\n\n const selected: C[] = selectedIdx.map((i) => pool[i]!);\n\n // If the caller set a budget larger than topN, append tail candidates in\n // their original order until budget is filled. This keeps MMR scoped to the\n // top-N slice while still respecting the caller's requested size.\n if (selected.length < budget && tail.length > 0) {\n for (const c of tail) {\n if (selected.length >= budget) break;\n selected.push(c);\n }\n }\n\n return selected;\n}\n\n/**\n * Summarize how much MMR reshuffled the head of the candidate list, for\n * logging. Optional — callers can skip this if they don't care about metrics.\n *\n * IMPORTANT: `before` should be the score-ordered input (the same ordering the\n * upstream reranker emitted, *not* the MMR output), and `after` should be the\n * MMR-reordered list. Both are truncated to `sampleSize` before their pairwise\n * similarity is averaged.\n *\n * The sample size intentionally defaults to a small number\n * ({@link DEFAULT_DIVERSITY_SAMPLE_SIZE}) so that when the caller uses\n * `budget >= candidates.length` (i.e. MMR only reorders without dropping), the\n * head-of-list comparison still reflects whether MMR promoted diverse\n * candidates. Passing a sample size `>= candidates.length` in that situation\n * makes `avgPairwiseSimBefore` and `avgPairwiseSimAfter` trivially equal\n * because pairwise similarity is order-independent.\n */\nexport function summarizeMmrDiversity<C extends MmrCandidate>(\n before: readonly C[],\n after: readonly C[],\n sampleSize: number = DEFAULT_DIVERSITY_SAMPLE_SIZE,\n): MmrDiversityReport {\n const n = clampPositiveInt(sampleSize, DEFAULT_DIVERSITY_SAMPLE_SIZE);\n const beforeSlice = before.slice(0, n);\n const afterSlice = after.slice(0, n);\n // Count how many head-of-list positions MMR actually changed. A zero value\n // means MMR left the head untouched; a positive value is the actionable\n // \"MMR promoted N diverse candidates\" signal the previous metric lacked.\n let headReorderCount = 0;\n const compareLength = Math.min(beforeSlice.length, afterSlice.length);\n for (let i = 0; i < compareLength; i += 1) {\n if (beforeSlice[i]!.id !== afterSlice[i]!.id) headReorderCount += 1;\n }\n return {\n considered: before.length,\n kept: after.length,\n headReorderCount,\n avgPairwiseSimBefore: averagePairwiseSimilarity(beforeSlice),\n avgPairwiseSimAfter: averagePairwiseSimilarity(afterSlice),\n };\n}\n\n// -----------------------------------------------------------------------------\n// Internals\n// -----------------------------------------------------------------------------\n\nfunction clampLambda(value: number | undefined): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return DEFAULT_LAMBDA;\n if (value < 0) return 0;\n if (value > 1) return 1;\n return value;\n}\n\nfunction clampPositiveInt(\n value: number | undefined,\n fallback: number,\n): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n if (value <= 0) return 0;\n return Math.floor(value);\n}\n\nfunction computeRelevanceScores<C extends MmrCandidate>(\n pool: readonly C[],\n queryEmbedding: readonly number[] | null | undefined,\n): number[] {\n // If we have a query embedding, use cosine against each candidate embedding\n // where possible. Candidates without embeddings fall back to normalized score.\n const canUseQueryEmbedding =\n Array.isArray(queryEmbedding) && queryEmbedding.length > 0;\n\n if (canUseQueryEmbedding) {\n const scores: number[] = [];\n for (const c of pool) {\n if (Array.isArray(c.embedding) && c.embedding.length > 0) {\n scores.push(cosineSimilarity(queryEmbedding!, c.embedding));\n } else {\n // Fall back to the upstream relevance score for this one candidate.\n scores.push(normalizeFinite(c.score));\n }\n }\n return normalizeVector(scores);\n }\n\n // No query embedding — use normalized candidate scores.\n const raw = pool.map((c) => normalizeFinite(c.score));\n return normalizeVector(raw);\n}\n\nfunction similarity<C extends MmrCandidate>(a: C, b: C): number {\n if (\n Array.isArray(a.embedding) &&\n a.embedding.length > 0 &&\n Array.isArray(b.embedding) &&\n b.embedding.length > 0 &&\n a.embedding.length === b.embedding.length\n ) {\n return cosineSimilarity(a.embedding, b.embedding);\n }\n return jaccardSimilarity(a.content ?? \"\", b.content ?? \"\");\n}\n\nfunction cosineSimilarity(\n a: readonly number[],\n b: readonly number[],\n): number {\n if (a.length === 0 || b.length === 0) return 0;\n const len = Math.min(a.length, b.length);\n let dot = 0;\n let na = 0;\n let nb = 0;\n for (let i = 0; i < len; i += 1) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n dot += av * bv;\n na += av * av;\n nb += bv * bv;\n }\n if (na === 0 || nb === 0) return 0;\n const cos = dot / (Math.sqrt(na) * Math.sqrt(nb));\n // Clamp to [0, 1]. Negative cosines (opposite directions) are treated as 0\n // for MMR purposes — two embeddings pointing opposite ways should be\n // \"maximally diverse\", not discouraged further.\n if (cos < 0) return 0;\n if (cos > 1) return 1;\n return cos;\n}\n\nexport function normalizeTokens(text: string): Set<string> {\n if (!text) return new Set();\n // Unicode-aware normalization. We lowercase and replace any character that\n // is NOT a Unicode letter or number with a space, then split on whitespace.\n // This preserves non-Latin scripts (Cyrillic, Greek, Hebrew, Arabic, etc.)\n // so the Jaccard fallback still detects near-duplicates in multilingual\n // snippets. Without this fix, `[^a-z0-9]+` strips all non-ASCII and two\n // identical Chinese/Japanese/Cyrillic snippets both collapse to the empty\n // set, returning similarity 0 and letting duplicates dominate recall.\n const cleaned = text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, \" \")\n .trim();\n if (cleaned.length === 0) {\n // CJK fallback: scripts like Chinese/Japanese/Korean do not use word\n // breaks, so after the Unicode strip the above split-on-whitespace yields\n // one big token. The Latin-style split is a bad match for these scripts;\n // use per-codepoint character tokens instead, which approximates a\n // unigram shingle and is accurate enough for near-duplicate detection.\n const chars = new Set<string>();\n for (const ch of text.toLowerCase()) {\n if (/\\s/.test(ch)) continue;\n chars.add(ch);\n }\n return chars;\n }\n const tokens = new Set<string>();\n for (const token of cleaned.split(/\\s+/)) {\n if (!token) continue;\n // A single \"token\" that is actually a run of CJK codepoints (no spaces in\n // the source) should still be split into per-character tokens so the\n // Jaccard overlap works. Latin/Cyrillic/etc. keep their word-level tokens.\n if (token.length >= 2 && hasUnsegmentableScript(token)) {\n for (const ch of token) tokens.add(ch);\n } else {\n tokens.add(token);\n }\n }\n return tokens;\n}\n\n/**\n * Returns true when `token` contains at least one codepoint in a script that\n * does not use whitespace for word segmentation (CJK Unified Ideographs,\n * Hiragana, Katakana, Hangul). These are tokenized per-character so Jaccard\n * similarity can still detect near-duplicate snippets.\n */\nfunction hasUnsegmentableScript(token: string): boolean {\n return /[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}]/u.test(\n token,\n );\n}\n\nfunction jaccardSimilarity(a: string, b: string): number {\n const ta = normalizeTokens(a);\n const tb = normalizeTokens(b);\n if (ta.size === 0 && tb.size === 0) return 0;\n let intersection = 0;\n for (const t of ta) if (tb.has(t)) intersection += 1;\n const union = ta.size + tb.size - intersection;\n if (union === 0) return 0;\n return intersection / union;\n}\n\nfunction normalizeFinite(value: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return 0;\n return value;\n}\n\nfunction normalizeVector(values: number[]): number[] {\n if (values.length === 0) return values;\n // Intentionally *not* min-max normalized. Min-max maps the lowest score to\n // 0 and the highest to 1, which amplifies tiny relevance gaps (e.g. a tight\n // reranker cluster like [0.93, 0.94, 0.95]) into the full [0, 1] range.\n // That lets a near-duplicate at the top permanently beat a diverse\n // candidate at the bottom because `lambda * 0 - (1 - lambda) * 0 = 0` is\n // always worse than `lambda * 1 - (1 - lambda) * maxSim` for any\n // maxSim < lambda / (1 - lambda). MMR is supposed to escape exactly that\n // scenario; min-max defeats it.\n //\n // Instead we preserve the relative score gaps by scaling only if the\n // scores leave the MMR-friendly `[0, 1]` range. Negative or out-of-range\n // scores are clamped to `[0, 1]` by dividing by the max absolute value; if\n // everything is already inside `[0, 1]`, we pass through untouched so\n // tight clusters stay tight and MMR can promote a diverse candidate from\n // the bottom of the cluster.\n let max = 0;\n let min = Number.POSITIVE_INFINITY;\n for (const v of values) {\n if (!Number.isFinite(v)) continue;\n const a = Math.abs(v);\n if (a > max) max = a;\n if (v < min) min = v;\n }\n if (!Number.isFinite(min)) {\n return values.map(() => 0);\n }\n if (max === 0) {\n // All scores are zero — give everyone 1 so diversity fully drives\n // selection (otherwise every candidate has `lambda * 0 = 0` and the\n // first-found wins trivially, hiding any diversity benefit).\n return values.map(() => 1);\n }\n // If scores already live in [0, 1], pass them through so tight clusters\n // (e.g. [0.93, 0.94, 0.95]) stay tight and the (1 - lambda) * maxSim term\n // can actually outweigh a 0.01 relevance gap, which is the whole point of\n // MMR. Otherwise divide by `max` to bring the top score to 1 while\n // preserving *relative* gaps (e.g. [100, 200, 300] -> [0.33, 0.67, 1.0]).\n if (min >= 0 && max <= 1) {\n return values.map((v) =>\n Number.isFinite(v) ? (v < 0 ? 0 : v > 1 ? 1 : v) : 0,\n );\n }\n return values.map((v) => {\n if (!Number.isFinite(v)) return 0;\n const scaled = v / max;\n if (scaled < 0) return 0;\n if (scaled > 1) return 1;\n return scaled;\n });\n}\n\nfunction averagePairwiseSimilarity<C extends MmrCandidate>(\n candidates: readonly C[],\n): number {\n if (candidates.length < 2) return 0;\n let sum = 0;\n let count = 0;\n for (let i = 0; i < candidates.length; i += 1) {\n for (let j = i + 1; j < candidates.length; j += 1) {\n sum += similarity(candidates[i]!, candidates[j]!);\n count += 1;\n }\n }\n if (count === 0) return 0;\n return sum / count;\n}\n\n// -----------------------------------------------------------------------------\n// Orchestration helper: MMR for recall results keyed by path-first\n// -----------------------------------------------------------------------------\n\n/**\n * Minimum shape the recall-MMR orchestration helper expects from a result.\n * Any richer result type (e.g. {@link QmdSearchResult}) satisfies this.\n */\nexport interface MmrRecallResult {\n readonly docid?: string;\n readonly path?: string;\n readonly snippet?: string;\n readonly score?: number;\n}\n\nexport interface ReorderRecallResultsOptions {\n readonly lambda?: number;\n readonly topN?: number;\n /**\n * Head-of-list sample size used by the diversity metric. Defaults to\n * {@link DEFAULT_DIVERSITY_SAMPLE_SIZE}. Intentionally small so the metric\n * reflects head-of-list changes even when `budget >= results.length`.\n */\n readonly diversitySampleSize?: number;\n}\n\nexport interface ReorderRecallResultsOutcome<R extends MmrRecallResult> {\n readonly reordered: R[];\n readonly diversity: MmrDiversityReport;\n readonly lambda: number;\n}\n\n/**\n * Apply MMR to an ordered list of recall results and return the reordered\n * list plus a head-of-list diversity report.\n *\n * This helper is the single source of truth for the orchestrator's\n * per-section MMR pass. It is pure and deterministic so it can be unit\n * tested without constructing an Orchestrator.\n *\n * Key invariants:\n * 1. **No silent drops.** Candidates are keyed by a stable unique key derived\n * from `path` first, falling back to `docid`, and always suffixed with the\n * candidate's original index. Two results that share a basename-style\n * docid but differ in path are treated as distinct candidates and both\n * survive the reorder.\n * 2. **No mutation.** The input array is never mutated; a new array is\n * returned.\n * 3. **Diversity metric is meaningful.** The report compares the *head of\n * list* before and after MMR using a small sample size, so it reflects\n * whether MMR promoted diverse candidates even when\n * `budget >= results.length`.\n */\nexport function reorderRecallResultsWithMmr<R extends MmrRecallResult>(\n results: readonly R[],\n options: ReorderRecallResultsOptions = {},\n): ReorderRecallResultsOutcome<R> {\n const emptyReport: MmrDiversityReport = {\n considered: 0,\n kept: 0,\n headReorderCount: 0,\n avgPairwiseSimBefore: 0,\n avgPairwiseSimAfter: 0,\n };\n const lambda = clampLambda(options.lambda);\n\n if (!Array.isArray(results) || results.length === 0) {\n return { reordered: [], diversity: emptyReport, lambda };\n }\n if (results.length < 2) {\n // Single-element input: MMR is a trivial no-op but the diversity report\n // must still reflect the real pool size so external callers see\n // `considered=1 kept=1` rather than the `0/0` sentinel used for the\n // empty case. This is also the exact path the orchestrator short-circuits\n // past, but the helper is a public export and external callers cannot\n // rely on that invariant.\n return {\n reordered: [results[0]!],\n diversity: {\n considered: 1,\n kept: 1,\n headReorderCount: 0,\n avgPairwiseSimBefore: 0,\n avgPairwiseSimAfter: 0,\n },\n lambda,\n };\n }\n\n const topN = clampPositiveInt(options.topN, DEFAULT_TOP_N);\n\n // Build a per-result *unique* key so distinct results with colliding\n // docids or paths are never silently collapsed by id-based lookups.\n // Keys are always suffixed with the original input index so two results\n // that share the same `path` (or share the same `docid` when `path` is\n // empty) still get distinct identities.\n const candidates: MmrCandidate[] = results.map((r, index) => ({\n id: makeRecallKey(r, index),\n content: r.snippet ?? \"\",\n score: typeof r.score === \"number\" ? r.score : 0,\n embedding: null,\n }));\n // Index lookup by id so we can map MMR-selected candidates back to their\n // *original* position (and therefore their original `candidates[i]` object,\n // which preserves its `id` across the reorder). Reusing those original\n // candidate objects in the diversity comparison means\n // `headReorderCount` works correctly even when two results in the input\n // share the same base key: a swap at the same head position shows up\n // because their original-index-suffixed ids still differ.\n const indexById = new Map<string, number>();\n for (let i = 0; i < candidates.length; i += 1) {\n indexById.set(candidates[i]!.id, i);\n }\n\n const selectedMmr = applyMmrToCandidates({\n candidates,\n lambda,\n topN,\n budget: results.length,\n });\n\n const reordered: R[] = [];\n // Parallel array of the *original* candidate objects in the new (post-MMR)\n // order. Used for a faithful diversity comparison that preserves each\n // candidate's original identity.\n const reorderedCandidates: MmrCandidate[] = [];\n const seen = new Set<string>();\n for (const c of selectedMmr) {\n if (seen.has(c.id)) continue;\n const origIndex = indexById.get(c.id);\n if (origIndex === undefined) continue;\n seen.add(c.id);\n reordered.push(results[origIndex]!);\n reorderedCandidates.push(candidates[origIndex]!);\n }\n // Safety: append any candidates MMR did not select so nothing is dropped.\n if (reordered.length < results.length) {\n for (let i = 0; i < results.length; i += 1) {\n const origCandidate = candidates[i]!;\n if (seen.has(origCandidate.id)) continue;\n seen.add(origCandidate.id);\n reordered.push(results[i]!);\n reorderedCandidates.push(origCandidate);\n }\n }\n\n const diversity = summarizeMmrDiversity(\n candidates,\n reorderedCandidates,\n options.diversitySampleSize,\n );\n\n return { reordered, diversity, lambda };\n}\n\nfunction makeRecallKey(r: MmrRecallResult, index: number): string {\n const baseKey = r.path || r.docid || \"\";\n return `${baseKey}::${index}`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/recall-mmr.ts"],"sourcesContent":["/**\n * Maximal Marginal Relevance (MMR) re-selection for recall candidates.\n *\n * After the reranker produces its ordered candidate list, we run an MMR pass\n * over the top N candidates (per-section) so that a cluster of near-duplicate\n * high-scoring facts cannot dominate the injected context.\n *\n * MMR(d) = λ * sim(d, query) − (1 − λ) * max_{d' ∈ selected} sim(d, d')\n *\n * - λ defaults to 0.7 (tilted toward relevance, with meaningful diversity).\n * - Similarity uses cosine over pre-computed embeddings when available, and\n * falls back to Jaccard over normalized tokens (lowercased alphanumerics)\n * when embeddings are missing.\n * - Per-section application is the caller's responsibility: pass each\n * section's ordered candidate slice independently so one cluster in one\n * section cannot starve another section.\n *\n * Pure, deterministic, no IO. Input arrays are never mutated.\n */\n\n/** Minimal candidate shape used by MMR. Callers may wrap their own records. */\nexport interface MmrCandidate {\n /** Stable identifier for the candidate. Only used for tie-breaking. */\n id: string;\n /** Text content used for the Jaccard similarity fallback. */\n content: string;\n /**\n * Relevance score from the upstream ranker (e.g. rerank score or RRF).\n * Used as the `sim(d, query)` term when no query embedding is available.\n */\n score: number;\n /** Optional pre-computed embedding vector for cosine similarity. */\n embedding?: readonly number[] | null;\n}\n\nexport interface ApplyMmrOptions<C extends MmrCandidate> {\n /** Ordered candidate list (most relevant first). */\n candidates: readonly C[];\n /** Optional query embedding. If provided and candidates carry embeddings,\n * relevance is measured by cosine similarity to the query. Otherwise\n * candidate `score` is normalized and used. */\n queryEmbedding?: readonly number[] | null;\n /** λ ∈ [0, 1]. 1 = pure relevance, 0 = pure diversity. Default 0.7. */\n lambda?: number;\n /** Apply MMR only over the top N candidates. Default 40. */\n topN?: number;\n /** Maximum number of candidates to select. Default = candidates length. */\n budget?: number;\n}\n\nexport interface MmrDiversityReport {\n /**\n * Total number of candidates MMR considered (the full input pool, pre-MMR).\n * Previously this mirrored `kept` and was therefore uninformative; it now\n * reflects the true pool size so `kept/considered` logs carry signal even\n * though MMR is reorder-only.\n */\n considered: number;\n /**\n * Number of candidates present in the MMR output. With the current\n * orchestrator pipeline MMR is reorder-only (no drops), so this is the\n * same as `considered`. It's still reported separately so a future\n * drop-mode MMR can distinguish them without another schema change.\n */\n kept: number;\n /**\n * Head-of-list positions whose candidate identity changed between the\n * pre-MMR and post-MMR slices. This is the *actionable* diversity signal:\n * it tells the caller how many of the top `sampleSize` results MMR\n * promoted or demoted. Zero means MMR had no head-of-list effect; a value\n * greater than zero means at least one diverse candidate was swapped in.\n */\n headReorderCount: number;\n /** Average pairwise similarity of the head-of-list input slice (pre-MMR). */\n avgPairwiseSimBefore: number;\n /** Average pairwise similarity of the head-of-list MMR output slice. */\n avgPairwiseSimAfter: number;\n}\n\nexport const DEFAULT_LAMBDA = 0.7;\nexport const DEFAULT_TOP_N = 40;\n/**\n * Default number of head-of-list candidates compared by\n * {@link summarizeMmrDiversity}. Small on purpose: we want to measure whether\n * MMR actually *changed* the head of the list. Comparing the full top-N slice\n * is meaningless when `budget >= candidates.length` because both slices\n * contain the same set (just reordered), making pairwise-similarity\n * order-independent and identical before vs after.\n */\nconst DEFAULT_DIVERSITY_SAMPLE_SIZE = 10;\n\n/**\n * Pure MMR re-selection over an ordered candidate list.\n *\n * Returns a new array — the input is never mutated. When `candidates.length`\n * is `<= 1` or `budget <= 0`, a defensive copy is returned as a no-op.\n */\nexport function applyMmrToCandidates<C extends MmrCandidate>(\n opts: ApplyMmrOptions<C>,\n): C[] {\n const candidates = Array.isArray(opts.candidates) ? opts.candidates : [];\n if (candidates.length === 0) return [];\n\n const lambda = clampLambda(opts.lambda);\n const topN = clampPositiveInt(opts.topN, DEFAULT_TOP_N);\n const budget = clampPositiveInt(opts.budget, candidates.length);\n\n if (budget <= 0) return [];\n if (candidates.length === 1) return [candidates[0]!];\n\n // Only reorder the top-N slice; anything past it keeps its original position\n // appended at the end (but will not be selected unless budget > topN).\n const pool = candidates.slice(0, topN);\n const tail = candidates.slice(topN);\n\n // Relevance scores as `sim(d, query)`. Prefer cosine to the query embedding\n // when we can compute it; otherwise fall back to the candidate's own score\n // normalized into [0, 1] across the pool.\n const relevance = computeRelevanceScores(pool, opts.queryEmbedding);\n\n // Pre-compute pairwise candidate-candidate similarity lazily as needed.\n const pairSim = new Map<string, number>();\n const pairKey = (i: number, j: number): string =>\n i < j ? `${i}:${j}` : `${j}:${i}`;\n const sim = (i: number, j: number): number => {\n if (i === j) return 1;\n const key = pairKey(i, j);\n const cached = pairSim.get(key);\n if (cached !== undefined) return cached;\n const a = pool[i]!;\n const b = pool[j]!;\n const s = similarity(a, b);\n pairSim.set(key, s);\n return s;\n };\n\n const selectedIdx: number[] = [];\n const remaining = new Set<number>();\n for (let i = 0; i < pool.length; i += 1) remaining.add(i);\n\n while (selectedIdx.length < budget && remaining.size > 0) {\n let bestIdx = -1;\n let bestMmr = Number.NEGATIVE_INFINITY;\n for (const idx of remaining) {\n const rel = relevance[idx] ?? 0;\n let maxSimToSelected = 0;\n if (selectedIdx.length > 0) {\n for (const s of selectedIdx) {\n const pairwise = sim(idx, s);\n if (pairwise > maxSimToSelected) maxSimToSelected = pairwise;\n }\n }\n const mmr = lambda * rel - (1 - lambda) * maxSimToSelected;\n if (\n mmr > bestMmr ||\n // Stable tie-breaker: prefer the earlier original position.\n (mmr === bestMmr && (bestIdx < 0 || idx < bestIdx))\n ) {\n bestMmr = mmr;\n bestIdx = idx;\n }\n }\n if (bestIdx < 0) break;\n selectedIdx.push(bestIdx);\n remaining.delete(bestIdx);\n }\n\n const selected: C[] = selectedIdx.map((i) => pool[i]!);\n\n // If the caller set a budget larger than topN, append tail candidates in\n // their original order until budget is filled. This keeps MMR scoped to the\n // top-N slice while still respecting the caller's requested size.\n if (selected.length < budget && tail.length > 0) {\n for (const c of tail) {\n if (selected.length >= budget) break;\n selected.push(c);\n }\n }\n\n return selected;\n}\n\n/**\n * Summarize how much MMR reshuffled the head of the candidate list, for\n * logging. Optional — callers can skip this if they don't care about metrics.\n *\n * IMPORTANT: `before` should be the score-ordered input (the same ordering the\n * upstream reranker emitted, *not* the MMR output), and `after` should be the\n * MMR-reordered list. Both are truncated to `sampleSize` before their pairwise\n * similarity is averaged.\n *\n * The sample size intentionally defaults to a small number\n * ({@link DEFAULT_DIVERSITY_SAMPLE_SIZE}) so that when the caller uses\n * `budget >= candidates.length` (i.e. MMR only reorders without dropping), the\n * head-of-list comparison still reflects whether MMR promoted diverse\n * candidates. Passing a sample size `>= candidates.length` in that situation\n * makes `avgPairwiseSimBefore` and `avgPairwiseSimAfter` trivially equal\n * because pairwise similarity is order-independent.\n */\nexport function summarizeMmrDiversity<C extends MmrCandidate>(\n before: readonly C[],\n after: readonly C[],\n sampleSize: number = DEFAULT_DIVERSITY_SAMPLE_SIZE,\n): MmrDiversityReport {\n const n = clampPositiveInt(sampleSize, DEFAULT_DIVERSITY_SAMPLE_SIZE);\n const beforeSlice = before.slice(0, n);\n const afterSlice = after.slice(0, n);\n // Count how many head-of-list positions MMR actually changed. A zero value\n // means MMR left the head untouched; a positive value is the actionable\n // \"MMR promoted N diverse candidates\" signal the previous metric lacked.\n let headReorderCount = 0;\n const compareLength = Math.min(beforeSlice.length, afterSlice.length);\n for (let i = 0; i < compareLength; i += 1) {\n if (beforeSlice[i]!.id !== afterSlice[i]!.id) headReorderCount += 1;\n }\n return {\n considered: before.length,\n kept: after.length,\n headReorderCount,\n avgPairwiseSimBefore: averagePairwiseSimilarity(beforeSlice),\n avgPairwiseSimAfter: averagePairwiseSimilarity(afterSlice),\n };\n}\n\n// -----------------------------------------------------------------------------\n// Internals\n// -----------------------------------------------------------------------------\n\nfunction clampLambda(value: number | undefined): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return DEFAULT_LAMBDA;\n if (value < 0) return 0;\n if (value > 1) return 1;\n return value;\n}\n\nfunction clampPositiveInt(\n value: number | undefined,\n fallback: number,\n): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n if (value <= 0) return 0;\n return Math.floor(value);\n}\n\nfunction computeRelevanceScores<C extends MmrCandidate>(\n pool: readonly C[],\n queryEmbedding: readonly number[] | null | undefined,\n): number[] {\n // If we have a query embedding, use cosine against each candidate embedding\n // where possible. Candidates without embeddings fall back to normalized score.\n const canUseQueryEmbedding =\n Array.isArray(queryEmbedding) && queryEmbedding.length > 0;\n\n if (canUseQueryEmbedding) {\n const scores: number[] = [];\n for (const c of pool) {\n if (Array.isArray(c.embedding) && c.embedding.length > 0) {\n scores.push(cosineSimilarity(queryEmbedding!, c.embedding));\n } else {\n // Fall back to the upstream relevance score for this one candidate.\n scores.push(normalizeFinite(c.score));\n }\n }\n return normalizeVector(scores);\n }\n\n // No query embedding — use normalized candidate scores.\n const raw = pool.map((c) => normalizeFinite(c.score));\n return normalizeVector(raw);\n}\n\nfunction similarity<C extends MmrCandidate>(a: C, b: C): number {\n if (\n Array.isArray(a.embedding) &&\n a.embedding.length > 0 &&\n Array.isArray(b.embedding) &&\n b.embedding.length > 0 &&\n a.embedding.length === b.embedding.length\n ) {\n return cosineSimilarity(a.embedding, b.embedding);\n }\n return jaccardSimilarity(a.content ?? \"\", b.content ?? \"\");\n}\n\nfunction cosineSimilarity(\n a: readonly number[],\n b: readonly number[],\n): number {\n if (a.length === 0 || b.length === 0) return 0;\n const len = Math.min(a.length, b.length);\n let dot = 0;\n let na = 0;\n let nb = 0;\n for (let i = 0; i < len; i += 1) {\n const av = a[i] ?? 0;\n const bv = b[i] ?? 0;\n dot += av * bv;\n na += av * av;\n nb += bv * bv;\n }\n if (na === 0 || nb === 0) return 0;\n const cos = dot / (Math.sqrt(na) * Math.sqrt(nb));\n // Clamp to [0, 1]. Negative cosines (opposite directions) are treated as 0\n // for MMR purposes — two embeddings pointing opposite ways should be\n // \"maximally diverse\", not discouraged further.\n if (cos < 0) return 0;\n if (cos > 1) return 1;\n return cos;\n}\n\nexport function normalizeTokens(text: string): Set<string> {\n if (!text) return new Set();\n // Unicode-aware normalization. We lowercase and replace any character that\n // is NOT a Unicode letter or number with a space, then split on whitespace.\n // This preserves non-Latin scripts (Cyrillic, Greek, Hebrew, Arabic, etc.)\n // so the Jaccard fallback still detects near-duplicates in multilingual\n // snippets. Without this fix, `[^a-z0-9]+` strips all non-ASCII and two\n // identical Chinese/Japanese/Cyrillic snippets both collapse to the empty\n // set, returning similarity 0 and letting duplicates dominate recall.\n const cleaned = text\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, \" \")\n .trim();\n if (cleaned.length === 0) {\n // CJK fallback: scripts like Chinese/Japanese/Korean do not use word\n // breaks, so after the Unicode strip the above split-on-whitespace yields\n // one big token. The Latin-style split is a bad match for these scripts;\n // use per-codepoint character tokens instead, which approximates a\n // unigram shingle and is accurate enough for near-duplicate detection.\n const chars = new Set<string>();\n for (const ch of text.toLowerCase()) {\n if (/\\s/.test(ch)) continue;\n chars.add(ch);\n }\n return chars;\n }\n const tokens = new Set<string>();\n for (const token of cleaned.split(/\\s+/)) {\n if (!token) continue;\n // A single \"token\" that is actually a run of CJK codepoints (no spaces in\n // the source) should still be split into per-character tokens so the\n // Jaccard overlap works. Latin/Cyrillic/etc. keep their word-level tokens.\n if (token.length >= 2 && hasUnsegmentableScript(token)) {\n for (const ch of token) tokens.add(ch);\n } else {\n tokens.add(token);\n }\n }\n return tokens;\n}\n\n/**\n * Returns true when `token` contains at least one codepoint in a script that\n * does not use whitespace for word segmentation (CJK Unified Ideographs,\n * Hiragana, Katakana, Hangul). These are tokenized per-character so Jaccard\n * similarity can still detect near-duplicate snippets.\n */\nfunction hasUnsegmentableScript(token: string): boolean {\n return /[\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\p{Script=Hangul}]/u.test(\n token,\n );\n}\n\nfunction jaccardSimilarity(a: string, b: string): number {\n const ta = normalizeTokens(a);\n const tb = normalizeTokens(b);\n if (ta.size === 0 && tb.size === 0) return 0;\n let intersection = 0;\n for (const t of ta) if (tb.has(t)) intersection += 1;\n const union = ta.size + tb.size - intersection;\n if (union === 0) return 0;\n return intersection / union;\n}\n\nfunction normalizeFinite(value: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return 0;\n return value;\n}\n\nfunction normalizeVector(values: number[]): number[] {\n if (values.length === 0) return values;\n // Intentionally *not* min-max normalized. Min-max maps the lowest score to\n // 0 and the highest to 1, which amplifies tiny relevance gaps (e.g. a tight\n // reranker cluster like [0.93, 0.94, 0.95]) into the full [0, 1] range.\n // That lets a near-duplicate at the top permanently beat a diverse\n // candidate at the bottom because `lambda * 0 - (1 - lambda) * 0 = 0` is\n // always worse than `lambda * 1 - (1 - lambda) * maxSim` for any\n // maxSim < lambda / (1 - lambda). MMR is supposed to escape exactly that\n // scenario; min-max defeats it.\n //\n // Instead we preserve the relative score gaps by scaling only if the\n // scores leave the MMR-friendly `[0, 1]` range. Negative or out-of-range\n // scores are clamped to `[0, 1]` by dividing by the max absolute value; if\n // everything is already inside `[0, 1]`, we pass through untouched so\n // tight clusters stay tight and MMR can promote a diverse candidate from\n // the bottom of the cluster.\n let max = 0;\n let min = Number.POSITIVE_INFINITY;\n for (const v of values) {\n if (!Number.isFinite(v)) continue;\n const a = Math.abs(v);\n if (a > max) max = a;\n if (v < min) min = v;\n }\n if (!Number.isFinite(min)) {\n return values.map(() => 0);\n }\n if (max === 0) {\n // All scores are zero — give everyone 1 so diversity fully drives\n // selection (otherwise every candidate has `lambda * 0 = 0` and the\n // first-found wins trivially, hiding any diversity benefit).\n return values.map(() => 1);\n }\n // If scores already live in [0, 1], pass them through so tight clusters\n // (e.g. [0.93, 0.94, 0.95]) stay tight and the (1 - lambda) * maxSim term\n // can actually outweigh a 0.01 relevance gap, which is the whole point of\n // MMR. Otherwise divide by `max` to bring the top score to 1 while\n // preserving *relative* gaps (e.g. [100, 200, 300] -> [0.33, 0.67, 1.0]).\n if (min >= 0 && max <= 1) {\n return values.map((v) =>\n Number.isFinite(v) ? (v < 0 ? 0 : v > 1 ? 1 : v) : 0,\n );\n }\n return values.map((v) => {\n if (!Number.isFinite(v)) return 0;\n const scaled = v / max;\n if (scaled < 0) return 0;\n if (scaled > 1) return 1;\n return scaled;\n });\n}\n\nfunction averagePairwiseSimilarity<C extends MmrCandidate>(\n candidates: readonly C[],\n): number {\n if (candidates.length < 2) return 0;\n let sum = 0;\n let count = 0;\n for (let i = 0; i < candidates.length; i += 1) {\n for (let j = i + 1; j < candidates.length; j += 1) {\n sum += similarity(candidates[i]!, candidates[j]!);\n count += 1;\n }\n }\n if (count === 0) return 0;\n return sum / count;\n}\n\n// -----------------------------------------------------------------------------\n// Orchestration helper: MMR for recall results keyed by path-first\n// -----------------------------------------------------------------------------\n\n/**\n * Minimum shape the recall-MMR orchestration helper expects from a result.\n * Any richer result type (e.g. {@link QmdSearchResult}) satisfies this.\n */\nexport interface MmrRecallResult {\n readonly docid?: string;\n readonly path?: string;\n readonly snippet?: string;\n readonly score?: number;\n /**\n * Effective relevance carried forward by the rerank stage that last\n * adjusted the result. Preferred over `score` for MMR's relevance term.\n */\n readonly effectiveScore?: number;\n}\n\nexport interface ReorderRecallResultsOptions {\n readonly lambda?: number;\n readonly topN?: number;\n /**\n * Head-of-list sample size used by the diversity metric. Defaults to\n * {@link DEFAULT_DIVERSITY_SAMPLE_SIZE}. Intentionally small so the metric\n * reflects head-of-list changes even when `budget >= results.length`.\n */\n readonly diversitySampleSize?: number;\n}\n\nexport interface ReorderRecallResultsOutcome<R extends MmrRecallResult> {\n readonly reordered: R[];\n readonly diversity: MmrDiversityReport;\n readonly lambda: number;\n}\n\n/**\n * Apply MMR to an ordered list of recall results and return the reordered\n * list plus a head-of-list diversity report.\n *\n * This helper is the single source of truth for the orchestrator's\n * per-section MMR pass. It is pure and deterministic so it can be unit\n * tested without constructing an Orchestrator.\n *\n * Key invariants:\n * 1. **No silent drops.** Candidates are keyed by a stable unique key derived\n * from `path` first, falling back to `docid`, and always suffixed with the\n * candidate's original index. Two results that share a basename-style\n * docid but differ in path are treated as distinct candidates and both\n * survive the reorder.\n * 2. **No mutation.** The input array is never mutated; a new array is\n * returned.\n * 3. **Diversity metric is meaningful.** The report compares the *head of\n * list* before and after MMR using a small sample size, so it reflects\n * whether MMR promoted diverse candidates even when\n * `budget >= results.length`.\n */\nexport function reorderRecallResultsWithMmr<R extends MmrRecallResult>(\n results: readonly R[],\n options: ReorderRecallResultsOptions = {},\n): ReorderRecallResultsOutcome<R> {\n const emptyReport: MmrDiversityReport = {\n considered: 0,\n kept: 0,\n headReorderCount: 0,\n avgPairwiseSimBefore: 0,\n avgPairwiseSimAfter: 0,\n };\n const lambda = clampLambda(options.lambda);\n\n if (!Array.isArray(results) || results.length === 0) {\n return { reordered: [], diversity: emptyReport, lambda };\n }\n if (results.length < 2) {\n // Single-element input: MMR is a trivial no-op but the diversity report\n // must still reflect the real pool size so external callers see\n // `considered=1 kept=1` rather than the `0/0` sentinel used for the\n // empty case. This is also the exact path the orchestrator short-circuits\n // past, but the helper is a public export and external callers cannot\n // rely on that invariant.\n return {\n reordered: [results[0]!],\n diversity: {\n considered: 1,\n kept: 1,\n headReorderCount: 0,\n avgPairwiseSimBefore: 0,\n avgPairwiseSimAfter: 0,\n },\n lambda,\n };\n }\n\n const topN = clampPositiveInt(options.topN, DEFAULT_TOP_N);\n\n // Build a per-result *unique* key so distinct results with colliding\n // docids or paths are never silently collapsed by id-based lookups.\n // Keys are always suffixed with the original input index so two results\n // that share the same `path` (or share the same `docid` when `path` is\n // empty) still get distinct identities.\n const candidates: MmrCandidate[] = results.map((r, index) => ({\n id: makeRecallKey(r, index),\n content: r.snippet ?? \"\",\n score: effectiveRelevance(r),\n embedding: null,\n }));\n // Index lookup by id so we can map MMR-selected candidates back to their\n // *original* position (and therefore their original `candidates[i]` object,\n // which preserves its `id` across the reorder). Reusing those original\n // candidate objects in the diversity comparison means\n // `headReorderCount` works correctly even when two results in the input\n // share the same base key: a swap at the same head position shows up\n // because their original-index-suffixed ids still differ.\n const indexById = new Map<string, number>();\n for (let i = 0; i < candidates.length; i += 1) {\n indexById.set(candidates[i]!.id, i);\n }\n\n const selectedMmr = applyMmrToCandidates({\n candidates,\n lambda,\n topN,\n budget: results.length,\n });\n\n const reordered: R[] = [];\n // Parallel array of the *original* candidate objects in the new (post-MMR)\n // order. Used for a faithful diversity comparison that preserves each\n // candidate's original identity.\n const reorderedCandidates: MmrCandidate[] = [];\n const seen = new Set<string>();\n for (const c of selectedMmr) {\n if (seen.has(c.id)) continue;\n const origIndex = indexById.get(c.id);\n if (origIndex === undefined) continue;\n seen.add(c.id);\n reordered.push(results[origIndex]!);\n reorderedCandidates.push(candidates[origIndex]!);\n }\n // Safety: append any candidates MMR did not select so nothing is dropped.\n if (reordered.length < results.length) {\n for (let i = 0; i < results.length; i += 1) {\n const origCandidate = candidates[i]!;\n if (seen.has(origCandidate.id)) continue;\n seen.add(origCandidate.id);\n reordered.push(results[i]!);\n reorderedCandidates.push(origCandidate);\n }\n }\n\n const diversity = summarizeMmrDiversity(\n candidates,\n reorderedCandidates,\n options.diversitySampleSize,\n );\n\n return { reordered, diversity, lambda };\n}\n\n/**\n * Relevance for MMR's `sim(d, query)` term: the effective relevance an\n * upstream rerank stage carried forward, else the raw retrieval score.\n */\nfunction effectiveRelevance(r: MmrRecallResult): number {\n if (typeof r.effectiveScore === \"number\" && Number.isFinite(r.effectiveScore)) {\n return r.effectiveScore;\n }\n return typeof r.score === \"number\" ? r.score : 0;\n}\n\nfunction makeRecallKey(r: MmrRecallResult, index: number): string {\n const baseKey = r.path || r.docid || \"\";\n return `${baseKey}::${index}`;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
getOperation,
|
|
4
4
|
operationRequiresAuthorizedNamespace,
|
|
5
5
|
operationUsesPrincipalNamespace
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-CA2R2AD4.js";
|
|
7
7
|
import {
|
|
8
8
|
assertOperationAuthorizationAllowed
|
|
9
9
|
} from "./chunk-IG747LRN.js";
|
|
@@ -60,4 +60,4 @@ export {
|
|
|
60
60
|
authorizationProbeNamespaces,
|
|
61
61
|
authorizationProbeRequiresPrincipalNamespace
|
|
62
62
|
};
|
|
63
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-INBB7D3V.js.map
|