@remnic/core 1.0.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/abstraction-nodes.d.ts +52 -0
- package/dist/abstraction-nodes.js +15 -0
- package/dist/abstraction-nodes.js.map +1 -0
- package/dist/access-cli.d.ts +5 -0
- package/dist/access-cli.js +308 -0
- package/dist/access-cli.js.map +1 -0
- package/dist/access-http.d.ts +158 -0
- package/dist/access-http.js +32 -0
- package/dist/access-http.js.map +1 -0
- package/dist/access-idempotency.d.ts +31 -0
- package/dist/access-idempotency.js +11 -0
- package/dist/access-idempotency.js.map +1 -0
- package/dist/access-mcp.d.ts +76 -0
- package/dist/access-mcp.js +8 -0
- package/dist/access-mcp.js.map +1 -0
- package/dist/access-schema.d.ts +266 -0
- package/dist/access-schema.js +29 -0
- package/dist/access-schema.js.map +1 -0
- package/dist/access-service.d.ts +614 -0
- package/dist/access-service.js +32 -0
- package/dist/access-service.js.map +1 -0
- package/dist/behavior-learner.d.ts +16 -0
- package/dist/behavior-learner.js +124 -0
- package/dist/behavior-learner.js.map +1 -0
- package/dist/behavior-signals.d.ts +15 -0
- package/dist/behavior-signals.js +11 -0
- package/dist/behavior-signals.js.map +1 -0
- package/dist/bootstrap.d.ts +46 -0
- package/dist/bootstrap.js +9 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/boxes.d.ts +93 -0
- package/dist/boxes.js +14 -0
- package/dist/boxes.js.map +1 -0
- package/dist/buffer.d.ts +22 -0
- package/dist/buffer.js +9 -0
- package/dist/buffer.js.map +1 -0
- package/dist/calibration.d.ts +81 -0
- package/dist/calibration.js +239 -0
- package/dist/calibration.js.map +1 -0
- package/dist/causal-behavior.d.ts +79 -0
- package/dist/causal-behavior.js +190 -0
- package/dist/causal-behavior.js.map +1 -0
- package/dist/causal-chain.d.ts +61 -0
- package/dist/causal-chain.js +24 -0
- package/dist/causal-chain.js.map +1 -0
- package/dist/causal-consolidation.d.ts +71 -0
- package/dist/causal-consolidation.js +211 -0
- package/dist/causal-consolidation.js.map +1 -0
- package/dist/causal-retrieval.d.ts +44 -0
- package/dist/causal-retrieval.js +184 -0
- package/dist/causal-retrieval.js.map +1 -0
- package/dist/causal-trajectory-graph.d.ts +13 -0
- package/dist/causal-trajectory-graph.js +59 -0
- package/dist/causal-trajectory-graph.js.map +1 -0
- package/dist/causal-trajectory.d.ts +68 -0
- package/dist/causal-trajectory.js +18 -0
- package/dist/causal-trajectory.js.map +1 -0
- package/dist/chunk-2CJCWDMR.js +87 -0
- package/dist/chunk-2CJCWDMR.js.map +1 -0
- package/dist/chunk-2NMMFZ5T.js +216 -0
- package/dist/chunk-2NMMFZ5T.js.map +1 -0
- package/dist/chunk-2PO5ZRKV.js +103 -0
- package/dist/chunk-2PO5ZRKV.js.map +1 -0
- package/dist/chunk-3QKK7QOS.js +154 -0
- package/dist/chunk-3QKK7QOS.js.map +1 -0
- package/dist/chunk-3SLRNYNG.js +26 -0
- package/dist/chunk-3SLRNYNG.js.map +1 -0
- package/dist/chunk-4A24LIM2.js +68 -0
- package/dist/chunk-4A24LIM2.js.map +1 -0
- package/dist/chunk-6HZ6AO2P.js +164 -0
- package/dist/chunk-6HZ6AO2P.js.map +1 -0
- package/dist/chunk-763GUIOU.js +302 -0
- package/dist/chunk-763GUIOU.js.map +1 -0
- package/dist/chunk-AAI7JARD.js +173 -0
- package/dist/chunk-AAI7JARD.js.map +1 -0
- package/dist/chunk-B7LOFDVE.js +112 -0
- package/dist/chunk-B7LOFDVE.js.map +1 -0
- package/dist/chunk-BDFZXRSO.js +318 -0
- package/dist/chunk-BDFZXRSO.js.map +1 -0
- package/dist/chunk-BOUYNNYD.js +707 -0
- package/dist/chunk-BOUYNNYD.js.map +1 -0
- package/dist/chunk-BRK4ODMI.js +60 -0
- package/dist/chunk-BRK4ODMI.js.map +1 -0
- package/dist/chunk-C6QPK5GG.js +111 -0
- package/dist/chunk-C6QPK5GG.js.map +1 -0
- package/dist/chunk-C7VW7C3F.js +117 -0
- package/dist/chunk-C7VW7C3F.js.map +1 -0
- package/dist/chunk-CDW777AI.js +621 -0
- package/dist/chunk-CDW777AI.js.map +1 -0
- package/dist/chunk-CULXMQJH.js +185 -0
- package/dist/chunk-CULXMQJH.js.map +1 -0
- package/dist/chunk-CXWFUJR2.js +1203 -0
- package/dist/chunk-CXWFUJR2.js.map +1 -0
- package/dist/chunk-DGXUHMOV.js +61 -0
- package/dist/chunk-DGXUHMOV.js.map +1 -0
- package/dist/chunk-DM2T26WE.js +61 -0
- package/dist/chunk-DM2T26WE.js.map +1 -0
- package/dist/chunk-DORBM6OB.js +81 -0
- package/dist/chunk-DORBM6OB.js.map +1 -0
- package/dist/chunk-DT5TVLJE.js +32 -0
- package/dist/chunk-DT5TVLJE.js.map +1 -0
- package/dist/chunk-EEQLFRUM.js +89 -0
- package/dist/chunk-EEQLFRUM.js.map +1 -0
- package/dist/chunk-EQINRHYR.js +672 -0
- package/dist/chunk-EQINRHYR.js.map +1 -0
- package/dist/chunk-ESSMF2FR.js +146 -0
- package/dist/chunk-ESSMF2FR.js.map +1 -0
- package/dist/chunk-ETOW6ACV.js +158 -0
- package/dist/chunk-ETOW6ACV.js.map +1 -0
- package/dist/chunk-FYIYMQ5N.js +221 -0
- package/dist/chunk-FYIYMQ5N.js.map +1 -0
- package/dist/chunk-G3AG3KZN.js +78 -0
- package/dist/chunk-G3AG3KZN.js.map +1 -0
- package/dist/chunk-GJR6D6KC.js +61 -0
- package/dist/chunk-GJR6D6KC.js.map +1 -0
- package/dist/chunk-GPGBSNKM.js +380 -0
- package/dist/chunk-GPGBSNKM.js.map +1 -0
- package/dist/chunk-H63EDPFJ.js +57 -0
- package/dist/chunk-H63EDPFJ.js.map +1 -0
- package/dist/chunk-HG2NKWR2.js +185 -0
- package/dist/chunk-HG2NKWR2.js.map +1 -0
- package/dist/chunk-HL4DB7TO.js +13 -0
- package/dist/chunk-HL4DB7TO.js.map +1 -0
- package/dist/chunk-HLBYLYRD.js +346 -0
- package/dist/chunk-HLBYLYRD.js.map +1 -0
- package/dist/chunk-HLXVTBF3.js +109 -0
- package/dist/chunk-HLXVTBF3.js.map +1 -0
- package/dist/chunk-IFFFR3MR.js +68 -0
- package/dist/chunk-IFFFR3MR.js.map +1 -0
- package/dist/chunk-ISY75RLM.js +1027 -0
- package/dist/chunk-ISY75RLM.js.map +1 -0
- package/dist/chunk-IZME7KW2.js +1886 -0
- package/dist/chunk-IZME7KW2.js.map +1 -0
- package/dist/chunk-J3BT33K7.js +720 -0
- package/dist/chunk-J3BT33K7.js.map +1 -0
- package/dist/chunk-J47FNDR7.js +113 -0
- package/dist/chunk-J47FNDR7.js.map +1 -0
- package/dist/chunk-JWPLJLDU.js +63 -0
- package/dist/chunk-JWPLJLDU.js.map +1 -0
- package/dist/chunk-K6WK37A6.js +865 -0
- package/dist/chunk-K6WK37A6.js.map +1 -0
- package/dist/chunk-KL4CP4SB.js +130 -0
- package/dist/chunk-KL4CP4SB.js.map +1 -0
- package/dist/chunk-KT4NEUNF.js +315 -0
- package/dist/chunk-KT4NEUNF.js.map +1 -0
- package/dist/chunk-KWBU5S5U.js +42 -0
- package/dist/chunk-KWBU5S5U.js.map +1 -0
- package/dist/chunk-L5RPWGFK.js +59 -0
- package/dist/chunk-L5RPWGFK.js.map +1 -0
- package/dist/chunk-L7WO3MZ4.js +128 -0
- package/dist/chunk-L7WO3MZ4.js.map +1 -0
- package/dist/chunk-LIRZNNUP.js +74 -0
- package/dist/chunk-LIRZNNUP.js.map +1 -0
- package/dist/chunk-LK6SGL53.js +22 -0
- package/dist/chunk-LK6SGL53.js.map +1 -0
- package/dist/chunk-LOBRX7VD.js +200 -0
- package/dist/chunk-LOBRX7VD.js.map +1 -0
- package/dist/chunk-LPSF4OQH.js +47 -0
- package/dist/chunk-LPSF4OQH.js.map +1 -0
- package/dist/chunk-LU3GQNDQ.js +152 -0
- package/dist/chunk-LU3GQNDQ.js.map +1 -0
- package/dist/chunk-M5KEYE5E.js +350 -0
- package/dist/chunk-M5KEYE5E.js.map +1 -0
- package/dist/chunk-M62O4P4T.js +41 -0
- package/dist/chunk-M62O4P4T.js.map +1 -0
- package/dist/chunk-MARWOCVP.js +48 -0
- package/dist/chunk-MARWOCVP.js.map +1 -0
- package/dist/chunk-MDDAA2AO.js +925 -0
- package/dist/chunk-MDDAA2AO.js.map +1 -0
- package/dist/chunk-MWGVGUIS.js +198 -0
- package/dist/chunk-MWGVGUIS.js.map +1 -0
- package/dist/chunk-N5AKDXAI.js +74 -0
- package/dist/chunk-N5AKDXAI.js.map +1 -0
- package/dist/chunk-NGAVDO7E.js +115 -0
- package/dist/chunk-NGAVDO7E.js.map +1 -0
- package/dist/chunk-NTTLPF7F.js +283 -0
- package/dist/chunk-NTTLPF7F.js.map +1 -0
- package/dist/chunk-ONRU4L2N.js +240 -0
- package/dist/chunk-ONRU4L2N.js.map +1 -0
- package/dist/chunk-ORZMT74A.js +209 -0
- package/dist/chunk-ORZMT74A.js.map +1 -0
- package/dist/chunk-OTAVQCSF.js +268 -0
- package/dist/chunk-OTAVQCSF.js.map +1 -0
- package/dist/chunk-PGK3VUHN.js +160 -0
- package/dist/chunk-PGK3VUHN.js.map +1 -0
- package/dist/chunk-Q6FETXJA.js +1362 -0
- package/dist/chunk-Q6FETXJA.js.map +1 -0
- package/dist/chunk-QANCTXQF.js +271 -0
- package/dist/chunk-QANCTXQF.js.map +1 -0
- package/dist/chunk-QCCCQT3O.js +189 -0
- package/dist/chunk-QCCCQT3O.js.map +1 -0
- package/dist/chunk-QDOSNLB4.js +1048 -0
- package/dist/chunk-QDOSNLB4.js.map +1 -0
- package/dist/chunk-QFQVZOGA.js +2168 -0
- package/dist/chunk-QFQVZOGA.js.map +1 -0
- package/dist/chunk-QPKFPHOO.js +178 -0
- package/dist/chunk-QPKFPHOO.js.map +1 -0
- package/dist/chunk-QSVPYQPG.js +268 -0
- package/dist/chunk-QSVPYQPG.js.map +1 -0
- package/dist/chunk-QWUUMMIK.js +3045 -0
- package/dist/chunk-QWUUMMIK.js.map +1 -0
- package/dist/chunk-QY2BHY5O.js +2378 -0
- package/dist/chunk-QY2BHY5O.js.map +1 -0
- package/dist/chunk-SCHEKPYH.js +349 -0
- package/dist/chunk-SCHEKPYH.js.map +1 -0
- package/dist/chunk-SCU65EZI.js +15 -0
- package/dist/chunk-SCU65EZI.js.map +1 -0
- package/dist/chunk-T4WRIV2C.js +170 -0
- package/dist/chunk-T4WRIV2C.js.map +1 -0
- package/dist/chunk-TKO4HZCK.js +1852 -0
- package/dist/chunk-TKO4HZCK.js.map +1 -0
- package/dist/chunk-TP4FZJIZ.js +93 -0
- package/dist/chunk-TP4FZJIZ.js.map +1 -0
- package/dist/chunk-TPB3I2AC.js +403 -0
- package/dist/chunk-TPB3I2AC.js.map +1 -0
- package/dist/chunk-TVVVQQAK.js +1431 -0
- package/dist/chunk-TVVVQQAK.js.map +1 -0
- package/dist/chunk-U4PV25RD.js +14 -0
- package/dist/chunk-U4PV25RD.js.map +1 -0
- package/dist/chunk-UCYSTFZR.js +284 -0
- package/dist/chunk-UCYSTFZR.js.map +1 -0
- package/dist/chunk-UHGBNIOS.js +205 -0
- package/dist/chunk-UHGBNIOS.js.map +1 -0
- package/dist/chunk-UIYZ5T3I.js +108 -0
- package/dist/chunk-UIYZ5T3I.js.map +1 -0
- package/dist/chunk-UV2FO7J4.js +747 -0
- package/dist/chunk-UV2FO7J4.js.map +1 -0
- package/dist/chunk-UZB5KHKX.js +63 -0
- package/dist/chunk-UZB5KHKX.js.map +1 -0
- package/dist/chunk-V3RXWQIE.js +626 -0
- package/dist/chunk-V3RXWQIE.js.map +1 -0
- package/dist/chunk-V4YC4LUK.js +444 -0
- package/dist/chunk-V4YC4LUK.js.map +1 -0
- package/dist/chunk-VEWZZM3H.js +133 -0
- package/dist/chunk-VEWZZM3H.js.map +1 -0
- package/dist/chunk-WWIQTB2Y.js +98 -0
- package/dist/chunk-WWIQTB2Y.js.map +1 -0
- package/dist/chunk-X7XN6YU4.js +24 -0
- package/dist/chunk-X7XN6YU4.js.map +1 -0
- package/dist/chunk-XKECPATV.js +202 -0
- package/dist/chunk-XKECPATV.js.map +1 -0
- package/dist/chunk-XYIK4LF6.js +75 -0
- package/dist/chunk-XYIK4LF6.js.map +1 -0
- package/dist/chunk-Y27UJK6V.js +39 -0
- package/dist/chunk-Y27UJK6V.js.map +1 -0
- package/dist/chunk-Y4Z4I6WK.js +9 -0
- package/dist/chunk-Y4Z4I6WK.js.map +1 -0
- package/dist/chunk-YAPUAHAY.js +10761 -0
- package/dist/chunk-YAPUAHAY.js.map +1 -0
- package/dist/chunk-YAZNBMNF.js +92 -0
- package/dist/chunk-YAZNBMNF.js.map +1 -0
- package/dist/chunk-YCN4BVDK.js +66 -0
- package/dist/chunk-YCN4BVDK.js.map +1 -0
- package/dist/chunk-YNCQ7E4M.js +388 -0
- package/dist/chunk-YNCQ7E4M.js.map +1 -0
- package/dist/chunk-YNI4S5WT.js +143 -0
- package/dist/chunk-YNI4S5WT.js.map +1 -0
- package/dist/chunk-YRMVARQP.js +406 -0
- package/dist/chunk-YRMVARQP.js.map +1 -0
- package/dist/chunk-Z5AAYHUC.js +79 -0
- package/dist/chunk-Z5AAYHUC.js.map +1 -0
- package/dist/chunk-Z5LAYHGJ.js +15 -0
- package/dist/chunk-Z5LAYHGJ.js.map +1 -0
- package/dist/chunk-ZJLY4QSU.js +823 -0
- package/dist/chunk-ZJLY4QSU.js.map +1 -0
- package/dist/chunk-ZKYI7UVO.js +276 -0
- package/dist/chunk-ZKYI7UVO.js.map +1 -0
- package/dist/chunk-ZPKBYX2F.js +297 -0
- package/dist/chunk-ZPKBYX2F.js.map +1 -0
- package/dist/chunking.d.ts +48 -0
- package/dist/chunking.js +11 -0
- package/dist/chunking.js.map +1 -0
- package/dist/cli.d.ts +1162 -0
- package/dist/cli.js +7187 -0
- package/dist/cli.js.map +1 -0
- package/dist/commitment-ledger.d.ts +83 -0
- package/dist/commitment-ledger.js +19 -0
- package/dist/commitment-ledger.js.map +1 -0
- package/dist/compression-optimizer.d.ts +37 -0
- package/dist/compression-optimizer.js +13 -0
- package/dist/compression-optimizer.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -0
- package/dist/cue-anchors.d.ts +50 -0
- package/dist/cue-anchors.js +15 -0
- package/dist/cue-anchors.js.map +1 -0
- package/dist/dashboard-runtime.d.ts +46 -0
- package/dist/dashboard-runtime.js +10 -0
- package/dist/dashboard-runtime.js.map +1 -0
- package/dist/day-summary.d.ts +6 -0
- package/dist/day-summary.js +10 -0
- package/dist/day-summary.js.map +1 -0
- package/dist/delinearize.d.ts +34 -0
- package/dist/delinearize.js +11 -0
- package/dist/delinearize.js.map +1 -0
- package/dist/embedding-fallback.d.ts +22 -0
- package/dist/embedding-fallback.js +8 -0
- package/dist/embedding-fallback.js.map +1 -0
- package/dist/engine-P26JFSVY.js +19 -0
- package/dist/engine-P26JFSVY.js.map +1 -0
- package/dist/entity-retrieval.d.ts +23 -0
- package/dist/entity-retrieval.js +24 -0
- package/dist/entity-retrieval.js.map +1 -0
- package/dist/evals.d.ts +282 -0
- package/dist/evals.js +32 -0
- package/dist/evals.js.map +1 -0
- package/dist/explicit-capture.d.ts +60 -0
- package/dist/explicit-capture.js +23 -0
- package/dist/explicit-capture.js.map +1 -0
- package/dist/extraction.d.ts +141 -0
- package/dist/extraction.js +22 -0
- package/dist/extraction.js.map +1 -0
- package/dist/fallback-llm.d.ts +95 -0
- package/dist/fallback-llm.js +12 -0
- package/dist/fallback-llm.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +12 -0
- package/dist/graph-dashboard-diff.js +8 -0
- package/dist/graph-dashboard-diff.js.map +1 -0
- package/dist/graph-dashboard-key.d.ts +5 -0
- package/dist/graph-dashboard-key.js +7 -0
- package/dist/graph-dashboard-key.js.map +1 -0
- package/dist/graph-dashboard-parser.d.ts +20 -0
- package/dist/graph-dashboard-parser.js +8 -0
- package/dist/graph-dashboard-parser.js.map +1 -0
- package/dist/graph.d.ts +157 -0
- package/dist/graph.js +27 -0
- package/dist/graph.js.map +1 -0
- package/dist/harmonic-retrieval.d.ts +27 -0
- package/dist/harmonic-retrieval.js +12 -0
- package/dist/harmonic-retrieval.js.map +1 -0
- package/dist/himem.d.ts +23 -0
- package/dist/himem.js +7 -0
- package/dist/himem.js.map +1 -0
- package/dist/hygiene.d.ts +24 -0
- package/dist/hygiene.js +9 -0
- package/dist/hygiene.js.map +1 -0
- package/dist/identity-continuity.d.ts +17 -0
- package/dist/identity-continuity.js +19 -0
- package/dist/identity-continuity.js.map +1 -0
- package/dist/importance.d.ts +25 -0
- package/dist/importance.js +11 -0
- package/dist/importance.js.map +1 -0
- package/dist/index.d.ts +923 -0
- package/dist/index.js +2512 -0
- package/dist/index.js.map +1 -0
- package/dist/intent.d.ts +8 -0
- package/dist/intent.js +13 -0
- package/dist/intent.js.map +1 -0
- package/dist/json-extract.d.ts +14 -0
- package/dist/json-extract.js +9 -0
- package/dist/json-extract.js.map +1 -0
- package/dist/json-store.d.ts +5 -0
- package/dist/json-store.js +11 -0
- package/dist/json-store.js.map +1 -0
- package/dist/legacy-hook-compat.d.ts +3 -0
- package/dist/legacy-hook-compat.js +35 -0
- package/dist/legacy-hook-compat.js.map +1 -0
- package/dist/lifecycle.d.ts +52 -0
- package/dist/lifecycle.js +21 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/local-llm.d.ts +154 -0
- package/dist/local-llm.js +10 -0
- package/dist/local-llm.js.map +1 -0
- package/dist/logger.d.ts +15 -0
- package/dist/logger.js +9 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory-action-policy.d.ts +13 -0
- package/dist/memory-action-policy.js +7 -0
- package/dist/memory-action-policy.js.map +1 -0
- package/dist/memory-cache.d.ts +35 -0
- package/dist/memory-cache.js +37 -0
- package/dist/memory-cache.js.map +1 -0
- package/dist/memory-lifecycle-ledger-utils.d.ts +13 -0
- package/dist/memory-lifecycle-ledger-utils.js +23 -0
- package/dist/memory-lifecycle-ledger-utils.js.map +1 -0
- package/dist/memory-projection-format.d.ts +4 -0
- package/dist/memory-projection-format.js +9 -0
- package/dist/memory-projection-format.js.map +1 -0
- package/dist/memory-projection-store-NxMkbocT.d.ts +221 -0
- package/dist/memory-projection-store.d.ts +3 -0
- package/dist/memory-projection-store.js +31 -0
- package/dist/memory-projection-store.js.map +1 -0
- package/dist/model-registry.d.ts +60 -0
- package/dist/model-registry.js +8 -0
- package/dist/model-registry.js.map +1 -0
- package/dist/native-knowledge.d.ts +94 -0
- package/dist/native-knowledge.js +26 -0
- package/dist/native-knowledge.js.map +1 -0
- package/dist/negative.d.ts +26 -0
- package/dist/negative.js +8 -0
- package/dist/negative.js.map +1 -0
- package/dist/objective-state-writers.d.ts +22 -0
- package/dist/objective-state-writers.js +313 -0
- package/dist/objective-state-writers.js.map +1 -0
- package/dist/objective-state.d.ts +75 -0
- package/dist/objective-state.js +17 -0
- package/dist/objective-state.js.map +1 -0
- package/dist/openai-chat-compat.d.ts +13 -0
- package/dist/openai-chat-compat.js +11 -0
- package/dist/openai-chat-compat.js.map +1 -0
- package/dist/operator-toolkit.d.ts +304 -0
- package/dist/operator-toolkit.js +41 -0
- package/dist/operator-toolkit.js.map +1 -0
- package/dist/opik-exporter.d.ts +72 -0
- package/dist/opik-exporter.js +361 -0
- package/dist/opik-exporter.js.map +1 -0
- package/dist/orchestrator-zTa-Qo-1.d.ts +1104 -0
- package/dist/orchestrator.d.ts +21 -0
- package/dist/orchestrator.js +145 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/policy-runtime.d.ts +37 -0
- package/dist/policy-runtime.js +13 -0
- package/dist/policy-runtime.js.map +1 -0
- package/dist/port-C1GZFv8h.d.ts +41 -0
- package/dist/profiling.d.ts +80 -0
- package/dist/profiling.js +10 -0
- package/dist/profiling.js.map +1 -0
- package/dist/qmd-recall-cache.d.ts +29 -0
- package/dist/qmd-recall-cache.js +13 -0
- package/dist/qmd-recall-cache.js.map +1 -0
- package/dist/qmd.d.ts +105 -0
- package/dist/qmd.js +13 -0
- package/dist/qmd.js.map +1 -0
- package/dist/recall-qos.d.ts +33 -0
- package/dist/recall-qos.js +10 -0
- package/dist/recall-qos.js.map +1 -0
- package/dist/recall-query-policy.d.ts +20 -0
- package/dist/recall-query-policy.js +11 -0
- package/dist/recall-query-policy.js.map +1 -0
- package/dist/recall-state.d.ts +113 -0
- package/dist/recall-state.js +12 -0
- package/dist/recall-state.js.map +1 -0
- package/dist/recall-tokenization.d.ts +4 -0
- package/dist/recall-tokenization.js +9 -0
- package/dist/recall-tokenization.js.map +1 -0
- package/dist/reconstruct.d.ts +16 -0
- package/dist/reconstruct.js +7 -0
- package/dist/reconstruct.js.map +1 -0
- package/dist/release-changelog.d.ts +7 -0
- package/dist/release-changelog.js +30 -0
- package/dist/release-changelog.js.map +1 -0
- package/dist/relevance.d.ts +18 -0
- package/dist/relevance.js +8 -0
- package/dist/relevance.js.map +1 -0
- package/dist/rerank.d.ts +57 -0
- package/dist/rerank.js +11 -0
- package/dist/rerank.js.map +1 -0
- package/dist/resolve-provider-secret.d.ts +16 -0
- package/dist/resolve-provider-secret.js +11 -0
- package/dist/resolve-provider-secret.js.map +1 -0
- package/dist/resume-bundles.d.ts +66 -0
- package/dist/resume-bundles.js +27 -0
- package/dist/resume-bundles.js.map +1 -0
- package/dist/retrieval-agents.d.ts +129 -0
- package/dist/retrieval-agents.js +23 -0
- package/dist/retrieval-agents.js.map +1 -0
- package/dist/retrieval.d.ts +19 -0
- package/dist/retrieval.js +10 -0
- package/dist/retrieval.js.map +1 -0
- package/dist/sanitize.d.ts +9 -0
- package/dist/sanitize.js +9 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schemas.d.ts +688 -0
- package/dist/schemas.js +51 -0
- package/dist/schemas.js.map +1 -0
- package/dist/sdk-compat.d.ts +21 -0
- package/dist/sdk-compat.js +28 -0
- package/dist/sdk-compat.js.map +1 -0
- package/dist/semantic-consolidation.d.ts +42 -0
- package/dist/semantic-consolidation.js +12 -0
- package/dist/semantic-consolidation.js.map +1 -0
- package/dist/semantic-rule-promotion.d.ts +28 -0
- package/dist/semantic-rule-promotion.js +17 -0
- package/dist/semantic-rule-promotion.js.map +1 -0
- package/dist/semantic-rule-verifier.d.ts +19 -0
- package/dist/semantic-rule-verifier.js +18 -0
- package/dist/semantic-rule-verifier.js.map +1 -0
- package/dist/session-integrity.d.ts +67 -0
- package/dist/session-integrity.js +11 -0
- package/dist/session-integrity.js.map +1 -0
- package/dist/session-observer-bands.d.ts +6 -0
- package/dist/session-observer-bands.js +9 -0
- package/dist/session-observer-bands.js.map +1 -0
- package/dist/session-observer-state.d.ts +40 -0
- package/dist/session-observer-state.js +11 -0
- package/dist/session-observer-state.js.map +1 -0
- package/dist/signal.d.ts +6 -0
- package/dist/signal.js +9 -0
- package/dist/signal.js.map +1 -0
- package/dist/storage.d.ts +453 -0
- package/dist/storage.js +24 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-contract.d.ts +10 -0
- package/dist/store-contract.js +21 -0
- package/dist/store-contract.js.map +1 -0
- package/dist/summarizer.d.ts +35 -0
- package/dist/summarizer.js +17 -0
- package/dist/summarizer.js.map +1 -0
- package/dist/summary-snapshot.d.ts +8 -0
- package/dist/summary-snapshot.js +13 -0
- package/dist/summary-snapshot.js.map +1 -0
- package/dist/temporal-index.d.ts +139 -0
- package/dist/temporal-index.js +29 -0
- package/dist/temporal-index.js.map +1 -0
- package/dist/threading.d.ts +62 -0
- package/dist/threading.js +8 -0
- package/dist/threading.js.map +1 -0
- package/dist/tier-migration.d.ts +44 -0
- package/dist/tier-migration.js +7 -0
- package/dist/tier-migration.js.map +1 -0
- package/dist/tier-routing.d.ts +21 -0
- package/dist/tier-routing.js +10 -0
- package/dist/tier-routing.js.map +1 -0
- package/dist/tmt.d.ts +79 -0
- package/dist/tmt.js +29 -0
- package/dist/tmt.js.map +1 -0
- package/dist/tokens.d.ts +24 -0
- package/dist/tokens.js +21 -0
- package/dist/tokens.js.map +1 -0
- package/dist/topics.d.ts +29 -0
- package/dist/topics.js +9 -0
- package/dist/topics.js.map +1 -0
- package/dist/transcript.d.ts +171 -0
- package/dist/transcript.js +9 -0
- package/dist/transcript.js.map +1 -0
- package/dist/trust-zones.d.ts +170 -0
- package/dist/trust-zones.js +32 -0
- package/dist/trust-zones.js.map +1 -0
- package/dist/types.d.ts +1243 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/utility-learner.d.ts +59 -0
- package/dist/utility-learner.js +17 -0
- package/dist/utility-learner.js.map +1 -0
- package/dist/utility-runtime.d.ts +21 -0
- package/dist/utility-runtime.js +16 -0
- package/dist/utility-runtime.js.map +1 -0
- package/dist/utility-telemetry.d.ts +68 -0
- package/dist/utility-telemetry.js +17 -0
- package/dist/utility-telemetry.js.map +1 -0
- package/dist/verified-recall.d.ts +17 -0
- package/dist/verified-recall.js +19 -0
- package/dist/verified-recall.js.map +1 -0
- package/dist/version-utils.d.ts +4 -0
- package/dist/version-utils.js +7 -0
- package/dist/version-utils.js.map +1 -0
- package/dist/work-product-ledger.d.ts +65 -0
- package/dist/work-product-ledger.js +18 -0
- package/dist/work-product-ledger.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FallbackLlmClient
|
|
3
|
+
} from "./chunk-KT4NEUNF.js";
|
|
4
|
+
import "./chunk-LU3GQNDQ.js";
|
|
5
|
+
import "./chunk-Y27UJK6V.js";
|
|
6
|
+
import "./chunk-UZB5KHKX.js";
|
|
7
|
+
import "./chunk-MARWOCVP.js";
|
|
8
|
+
import {
|
|
9
|
+
log
|
|
10
|
+
} from "./chunk-KWBU5S5U.js";
|
|
11
|
+
import {
|
|
12
|
+
listJsonFiles
|
|
13
|
+
} from "./chunk-LPSF4OQH.js";
|
|
14
|
+
|
|
15
|
+
// src/calibration.ts
|
|
16
|
+
import { createHash } from "crypto";
|
|
17
|
+
import path from "path";
|
|
18
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
19
|
+
function calibrationDir(memoryDir) {
|
|
20
|
+
return path.join(memoryDir, "state", "calibration");
|
|
21
|
+
}
|
|
22
|
+
function calibrationIndexPath(memoryDir) {
|
|
23
|
+
return path.join(calibrationDir(memoryDir), "calibration-index.json");
|
|
24
|
+
}
|
|
25
|
+
async function readCalibrationIndex(memoryDir) {
|
|
26
|
+
try {
|
|
27
|
+
const raw = JSON.parse(await readFile(calibrationIndexPath(memoryDir), "utf8"));
|
|
28
|
+
return {
|
|
29
|
+
rules: Array.isArray(raw.rules) ? raw.rules : [],
|
|
30
|
+
updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
31
|
+
totalCorrectionsAnalyzed: typeof raw.totalCorrectionsAnalyzed === "number" ? raw.totalCorrectionsAnalyzed : 0
|
|
32
|
+
};
|
|
33
|
+
} catch {
|
|
34
|
+
return { rules: [], updatedAt: (/* @__PURE__ */ new Date()).toISOString(), totalCorrectionsAnalyzed: 0 };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function writeCalibrationIndex(memoryDir, index) {
|
|
38
|
+
const dir = calibrationDir(memoryDir);
|
|
39
|
+
await mkdir(dir, { recursive: true });
|
|
40
|
+
index.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
41
|
+
await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), "utf8");
|
|
42
|
+
}
|
|
43
|
+
async function readCorrections(memoryDir) {
|
|
44
|
+
const correctionsDir = path.join(memoryDir, "corrections");
|
|
45
|
+
const files = await listJsonFiles(correctionsDir).catch(() => {
|
|
46
|
+
return [];
|
|
47
|
+
});
|
|
48
|
+
const factsDir = path.join(memoryDir, "facts");
|
|
49
|
+
try {
|
|
50
|
+
const { readdir } = await import("fs/promises");
|
|
51
|
+
const dayDirs = (await readdir(factsDir)).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d));
|
|
52
|
+
for (const day of dayDirs) {
|
|
53
|
+
const dayPath = path.join(factsDir, day);
|
|
54
|
+
const dayFiles = (await readdir(dayPath)).filter((f) => f.startsWith("correction-") && f.endsWith(".md")).map((f) => path.join(dayPath, f));
|
|
55
|
+
files.push(...dayFiles);
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const { readdir } = await import("fs/promises");
|
|
61
|
+
const corrFiles = (await readdir(correctionsDir)).filter((f) => f.endsWith(".md")).map((f) => path.join(correctionsDir, f));
|
|
62
|
+
files.push(...corrFiles);
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
const corrections = [];
|
|
66
|
+
const seen = /* @__PURE__ */ new Set();
|
|
67
|
+
for (const filePath of files) {
|
|
68
|
+
try {
|
|
69
|
+
const raw = await readFile(filePath, "utf8");
|
|
70
|
+
const fmMatch = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
71
|
+
if (!fmMatch) continue;
|
|
72
|
+
const content = fmMatch[2].trim();
|
|
73
|
+
if (!content || content.length < 10) continue;
|
|
74
|
+
const idMatch = fmMatch[1].match(/^id:\s*(.+)$/m);
|
|
75
|
+
const id = idMatch?.[1]?.trim() ?? path.basename(filePath, ".md");
|
|
76
|
+
if (seen.has(id)) continue;
|
|
77
|
+
seen.add(id);
|
|
78
|
+
const confMatch = fmMatch[1].match(/^confidence:\s*(.+)$/m);
|
|
79
|
+
const confidence = confMatch ? parseFloat(confMatch[1]) : 0.9;
|
|
80
|
+
const entityMatch = fmMatch[1].match(/^entityRef:\s*(.+)$/m);
|
|
81
|
+
const entityRefs = entityMatch ? [entityMatch[1].trim()] : [];
|
|
82
|
+
corrections.push({ id, content, created: "", confidence, entityRefs, tags: [] });
|
|
83
|
+
} catch {
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return corrections;
|
|
87
|
+
}
|
|
88
|
+
var CLUSTER_PROMPT = `You are analyzing user corrections to an AI assistant. Each correction represents a moment where the assistant's prediction of what the user wanted was WRONG.
|
|
89
|
+
|
|
90
|
+
Your job: Group these corrections into clusters where the SAME TYPE of misunderstanding is happening. Then for each cluster, synthesize a CalibrationRule.
|
|
91
|
+
|
|
92
|
+
A CalibrationRule describes:
|
|
93
|
+
- condition: When does this type of mistake happen?
|
|
94
|
+
- modelTendency: What does the model tend to assume or do wrong?
|
|
95
|
+
- userExpectation: What does the user actually want instead?
|
|
96
|
+
- calibration: How should the model adjust its behavior?
|
|
97
|
+
- ruleType: One of "model_tendency", "user_expectation", "scope_boundary", "verification_required"
|
|
98
|
+
|
|
99
|
+
Focus on PATTERNS, not individual corrections. A cluster needs at least 2 corrections to be worth a rule.
|
|
100
|
+
|
|
101
|
+
Output valid JSON only:
|
|
102
|
+
{
|
|
103
|
+
"rules": [
|
|
104
|
+
{
|
|
105
|
+
"ruleType": "model_tendency",
|
|
106
|
+
"condition": "When discussing project scope or task boundaries",
|
|
107
|
+
"modelTendency": "The model tends to assume broader scope than the user intends",
|
|
108
|
+
"userExpectation": "The user prefers narrow, specific task definitions and wants to be asked before scope expansion",
|
|
109
|
+
"calibration": "When uncertain about scope, ask for clarification rather than assuming. Default to the narrower interpretation.",
|
|
110
|
+
"confidence": 0.85,
|
|
111
|
+
"evidenceIds": ["correction-id-1", "correction-id-2"]
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}`;
|
|
115
|
+
async function synthesizeCalibrationRules(corrections, llm, existingRules, agentId) {
|
|
116
|
+
if (corrections.length < 2) return [];
|
|
117
|
+
const correctionText = corrections.slice(0, 50).map((c, i) => `[${c.id}] ${c.content}`).join("\n\n");
|
|
118
|
+
const existingRulesText = existingRules.length > 0 ? `
|
|
119
|
+
|
|
120
|
+
Existing calibration rules (avoid duplicating these):
|
|
121
|
+
${existingRules.map((r) => `- ${r.condition}: ${r.calibration}`).join("\n")}` : "";
|
|
122
|
+
const response = await llm.chatCompletion(
|
|
123
|
+
[
|
|
124
|
+
{ role: "system", content: CLUSTER_PROMPT },
|
|
125
|
+
{ role: "user", content: `Here are ${corrections.length} corrections from this user:
|
|
126
|
+
|
|
127
|
+
${correctionText}${existingRulesText}` }
|
|
128
|
+
],
|
|
129
|
+
{ temperature: 0.3, maxTokens: 3e3, agentId }
|
|
130
|
+
);
|
|
131
|
+
if (!response?.content) return [];
|
|
132
|
+
try {
|
|
133
|
+
let jsonStr = response.content.trim();
|
|
134
|
+
const fenceMatch = jsonStr.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);
|
|
135
|
+
if (fenceMatch) jsonStr = fenceMatch[1];
|
|
136
|
+
const parsed = JSON.parse(jsonStr);
|
|
137
|
+
if (!Array.isArray(parsed.rules)) return [];
|
|
138
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
139
|
+
return parsed.rules.filter((r) => r.condition && r.calibration && r.modelTendency).map((r) => ({
|
|
140
|
+
id: `cal-${createHash("sha256").update(r.condition + r.calibration).digest("hex").slice(0, 12)}`,
|
|
141
|
+
ruleType: r.ruleType ?? "model_tendency",
|
|
142
|
+
condition: String(r.condition),
|
|
143
|
+
modelTendency: String(r.modelTendency),
|
|
144
|
+
userExpectation: String(r.userExpectation ?? ""),
|
|
145
|
+
calibration: String(r.calibration),
|
|
146
|
+
confidence: typeof r.confidence === "number" ? r.confidence : 0.7,
|
|
147
|
+
evidenceCount: Array.isArray(r.evidenceIds) ? r.evidenceIds.length : 1,
|
|
148
|
+
evidenceCorrectionIds: Array.isArray(r.evidenceIds) ? r.evidenceIds : [],
|
|
149
|
+
createdAt: now,
|
|
150
|
+
lastReinforcedAt: now
|
|
151
|
+
}));
|
|
152
|
+
} catch {
|
|
153
|
+
log.warn("[calibration] failed to parse LLM response");
|
|
154
|
+
return [];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function buildCalibrationRecallSection(rules, query, maxChars = 1200) {
|
|
158
|
+
if (rules.length === 0) return null;
|
|
159
|
+
const lines = [
|
|
160
|
+
"## Model Calibration (learned from past corrections)",
|
|
161
|
+
"",
|
|
162
|
+
"Adjustments for this specific user, learned from patterns in their corrections:",
|
|
163
|
+
""
|
|
164
|
+
];
|
|
165
|
+
let totalChars = lines.join("\n").length;
|
|
166
|
+
for (const rule of rules) {
|
|
167
|
+
const line = `- **${rule.condition}**: ${rule.modelTendency} \u2192 Instead: ${rule.calibration}`;
|
|
168
|
+
if (totalChars + line.length + 1 > maxChars) break;
|
|
169
|
+
lines.push(line);
|
|
170
|
+
totalChars += line.length + 1;
|
|
171
|
+
}
|
|
172
|
+
if (lines.length <= 4) return null;
|
|
173
|
+
lines.push("");
|
|
174
|
+
return lines.join("\n");
|
|
175
|
+
}
|
|
176
|
+
async function runCalibrationConsolidation(options) {
|
|
177
|
+
try {
|
|
178
|
+
const llm = new FallbackLlmClient(options.gatewayConfig);
|
|
179
|
+
if (!llm.isAvailable(options.gatewayAgentId)) {
|
|
180
|
+
log.debug("[calibration] no LLM available \u2014 skipping consolidation");
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
const corrections = await readCorrections(options.memoryDir);
|
|
184
|
+
if (corrections.length < 3) {
|
|
185
|
+
log.debug(`[calibration] only ${corrections.length} corrections \u2014 need at least 3`);
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
const existingIndex = await readCalibrationIndex(options.memoryDir);
|
|
189
|
+
const newRules = await synthesizeCalibrationRules(corrections, llm, existingIndex.rules, options.gatewayAgentId);
|
|
190
|
+
if (newRules.length === 0) {
|
|
191
|
+
log.debug("[calibration] no new calibration rules synthesized");
|
|
192
|
+
return existingIndex.rules;
|
|
193
|
+
}
|
|
194
|
+
const ruleMap = new Map(existingIndex.rules.map((r) => [r.id, r]));
|
|
195
|
+
for (const rule of newRules) {
|
|
196
|
+
if (ruleMap.has(rule.id)) {
|
|
197
|
+
const existing = ruleMap.get(rule.id);
|
|
198
|
+
existing.lastReinforcedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
199
|
+
existing.evidenceCount += rule.evidenceCount;
|
|
200
|
+
existing.confidence = Math.min(1, existing.confidence + 0.05);
|
|
201
|
+
} else {
|
|
202
|
+
ruleMap.set(rule.id, rule);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const allRules = [...ruleMap.values()];
|
|
206
|
+
await writeCalibrationIndex(options.memoryDir, {
|
|
207
|
+
rules: allRules,
|
|
208
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
209
|
+
totalCorrectionsAnalyzed: corrections.length
|
|
210
|
+
});
|
|
211
|
+
log.debug(`[calibration] synthesized ${newRules.length} new rule(s), ${allRules.length} total`);
|
|
212
|
+
return allRules;
|
|
213
|
+
} catch (error) {
|
|
214
|
+
log.warn(`[calibration] consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function runCalibrationIfEnabled(options) {
|
|
219
|
+
if (!options.calibrationEnabled) {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
return runCalibrationConsolidation({
|
|
223
|
+
memoryDir: options.memoryDir,
|
|
224
|
+
gatewayConfig: options.gatewayConfig
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async function getCalibrationRulesForRecall(memoryDir) {
|
|
228
|
+
const index = await readCalibrationIndex(memoryDir);
|
|
229
|
+
return index.rules;
|
|
230
|
+
}
|
|
231
|
+
export {
|
|
232
|
+
buildCalibrationRecallSection,
|
|
233
|
+
getCalibrationRulesForRecall,
|
|
234
|
+
readCalibrationIndex,
|
|
235
|
+
runCalibrationConsolidation,
|
|
236
|
+
runCalibrationIfEnabled,
|
|
237
|
+
synthesizeCalibrationRules
|
|
238
|
+
};
|
|
239
|
+
//# sourceMappingURL=calibration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/calibration.ts"],"sourcesContent":["/**\n * calibration.ts — Prediction-Error-Driven Model-User Calibration\n *\n * Analyzes patterns in user corrections to identify systematic miscalibration\n * between the model's predictions and the user's actual expectations.\n * During consolidation, replays chains of similar corrections through an LLM\n * to synthesize CalibrationRules that adjust model behavior for this specific user.\n *\n * Inspired by:\n * - Cerebellar motor calibration (prediction errors drive lasting adjustments)\n * - Temporal difference learning (dopamine signals prediction error)\n * - Tesla FSD shadow mode (divergence between prediction and reality = training signal)\n */\n\nimport { createHash } from \"node:crypto\";\nimport path from \"node:path\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { FallbackLlmClient } from \"./fallback-llm.js\";\nimport type { GatewayConfig, MemoryFile } from \"./types.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport { log } from \"./logger.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface CalibrationRule {\n id: string;\n ruleType: \"model_tendency\" | \"user_expectation\" | \"scope_boundary\" | \"verification_required\";\n condition: string;\n modelTendency: string;\n userExpectation: string;\n calibration: string;\n confidence: number;\n evidenceCount: number;\n evidenceCorrectionIds: string[];\n createdAt: string;\n lastReinforcedAt: string;\n}\n\nexport interface CalibrationIndex {\n rules: CalibrationRule[];\n updatedAt: string;\n totalCorrectionsAnalyzed: number;\n}\n\n// ─── Storage ─────────────────────────────────────────────────────────────────\n\nfunction calibrationDir(memoryDir: string): string {\n return path.join(memoryDir, \"state\", \"calibration\");\n}\n\nfunction calibrationIndexPath(memoryDir: string): string {\n return path.join(calibrationDir(memoryDir), \"calibration-index.json\");\n}\n\nexport async function readCalibrationIndex(memoryDir: string): Promise<CalibrationIndex> {\n try {\n const raw = JSON.parse(await readFile(calibrationIndexPath(memoryDir), \"utf8\"));\n return {\n rules: Array.isArray(raw.rules) ? raw.rules : [],\n updatedAt: typeof raw.updatedAt === \"string\" ? raw.updatedAt : new Date().toISOString(),\n totalCorrectionsAnalyzed: typeof raw.totalCorrectionsAnalyzed === \"number\" ? raw.totalCorrectionsAnalyzed : 0,\n };\n } catch {\n return { rules: [], updatedAt: new Date().toISOString(), totalCorrectionsAnalyzed: 0 };\n }\n}\n\nasync function writeCalibrationIndex(memoryDir: string, index: CalibrationIndex): Promise<void> {\n const dir = calibrationDir(memoryDir);\n await mkdir(dir, { recursive: true });\n index.updatedAt = new Date().toISOString();\n await writeFile(calibrationIndexPath(memoryDir), JSON.stringify(index, null, 2), \"utf8\");\n}\n\n// ─── Correction Reading ──────────────────────────────────────────────────────\n\ninterface CorrectionMemory {\n id: string;\n content: string;\n created: string;\n confidence: number;\n entityRefs: string[];\n tags: string[];\n}\n\nasync function readCorrections(memoryDir: string): Promise<CorrectionMemory[]> {\n const correctionsDir = path.join(memoryDir, \"corrections\");\n const files = await listJsonFiles(correctionsDir).catch(() => {\n // Corrections might be in facts/ directories too\n return [] as string[];\n });\n\n // Also scan facts directories for correction-category files\n const factsDir = path.join(memoryDir, \"facts\");\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const dayDirs = (await readdir(factsDir)).filter((d: string) => /^\\d{4}-\\d{2}-\\d{2}$/.test(d));\n for (const day of dayDirs) {\n const dayPath = path.join(factsDir, day);\n const dayFiles = (await readdir(dayPath))\n .filter((f: string) => f.startsWith(\"correction-\") && f.endsWith(\".md\"))\n .map((f: string) => path.join(dayPath, f));\n files.push(...dayFiles);\n }\n } catch {\n // facts dir might not exist\n }\n\n // Also check the dedicated corrections directory\n try {\n const { readdir } = await import(\"node:fs/promises\");\n const corrFiles = (await readdir(correctionsDir))\n .filter((f: string) => f.endsWith(\".md\"))\n .map((f: string) => path.join(correctionsDir, f));\n files.push(...corrFiles);\n } catch {\n // corrections dir might not exist\n }\n\n const corrections: CorrectionMemory[] = [];\n const seen = new Set<string>();\n\n for (const filePath of files) {\n try {\n const raw = await readFile(filePath, \"utf8\");\n\n // Parse frontmatter\n const fmMatch = raw.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!fmMatch) continue;\n\n const content = fmMatch[2].trim();\n if (!content || content.length < 10) continue;\n\n // Extract id from frontmatter\n const idMatch = fmMatch[1].match(/^id:\\s*(.+)$/m);\n const id = idMatch?.[1]?.trim() ?? path.basename(filePath, \".md\");\n\n if (seen.has(id)) continue;\n seen.add(id);\n\n const confMatch = fmMatch[1].match(/^confidence:\\s*(.+)$/m);\n const confidence = confMatch ? parseFloat(confMatch[1]) : 0.9;\n\n const entityMatch = fmMatch[1].match(/^entityRef:\\s*(.+)$/m);\n const entityRefs = entityMatch ? [entityMatch[1].trim()] : [];\n\n corrections.push({ id, content, created: \"\", confidence, entityRefs, tags: [] });\n } catch {\n // skip unparseable files\n }\n }\n\n return corrections;\n}\n\n// ─── LLM-Assisted Clustering and Replay ──────────────────────────────────────\n\nconst CLUSTER_PROMPT = `You are analyzing user corrections to an AI assistant. Each correction represents a moment where the assistant's prediction of what the user wanted was WRONG.\n\nYour job: Group these corrections into clusters where the SAME TYPE of misunderstanding is happening. Then for each cluster, synthesize a CalibrationRule.\n\nA CalibrationRule describes:\n- condition: When does this type of mistake happen?\n- modelTendency: What does the model tend to assume or do wrong?\n- userExpectation: What does the user actually want instead?\n- calibration: How should the model adjust its behavior?\n- ruleType: One of \"model_tendency\", \"user_expectation\", \"scope_boundary\", \"verification_required\"\n\nFocus on PATTERNS, not individual corrections. A cluster needs at least 2 corrections to be worth a rule.\n\nOutput valid JSON only:\n{\n \"rules\": [\n {\n \"ruleType\": \"model_tendency\",\n \"condition\": \"When discussing project scope or task boundaries\",\n \"modelTendency\": \"The model tends to assume broader scope than the user intends\",\n \"userExpectation\": \"The user prefers narrow, specific task definitions and wants to be asked before scope expansion\",\n \"calibration\": \"When uncertain about scope, ask for clarification rather than assuming. Default to the narrower interpretation.\",\n \"confidence\": 0.85,\n \"evidenceIds\": [\"correction-id-1\", \"correction-id-2\"]\n }\n ]\n}`;\n\nexport async function synthesizeCalibrationRules(\n corrections: CorrectionMemory[],\n llm: FallbackLlmClient,\n existingRules: CalibrationRule[],\n agentId?: string,\n): Promise<CalibrationRule[]> {\n if (corrections.length < 2) return [];\n\n // Format corrections for the LLM\n const correctionText = corrections\n .slice(0, 50) // limit to avoid huge prompts\n .map((c, i) => `[${c.id}] ${c.content}`)\n .join(\"\\n\\n\");\n\n const existingRulesText = existingRules.length > 0\n ? `\\n\\nExisting calibration rules (avoid duplicating these):\\n${existingRules.map((r) => `- ${r.condition}: ${r.calibration}`).join(\"\\n\")}`\n : \"\";\n\n const response = await llm.chatCompletion(\n [\n { role: \"system\", content: CLUSTER_PROMPT },\n { role: \"user\", content: `Here are ${corrections.length} corrections from this user:\\n\\n${correctionText}${existingRulesText}` },\n ],\n { temperature: 0.3, maxTokens: 3000, agentId },\n );\n\n if (!response?.content) return [];\n\n try {\n let jsonStr = response.content.trim();\n const fenceMatch = jsonStr.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/);\n if (fenceMatch) jsonStr = fenceMatch[1];\n\n const parsed = JSON.parse(jsonStr);\n if (!Array.isArray(parsed.rules)) return [];\n\n const now = new Date().toISOString();\n return parsed.rules\n .filter((r: any) => r.condition && r.calibration && r.modelTendency)\n .map((r: any) => ({\n id: `cal-${createHash(\"sha256\").update(r.condition + r.calibration).digest(\"hex\").slice(0, 12)}`,\n ruleType: r.ruleType ?? \"model_tendency\",\n condition: String(r.condition),\n modelTendency: String(r.modelTendency),\n userExpectation: String(r.userExpectation ?? \"\"),\n calibration: String(r.calibration),\n confidence: typeof r.confidence === \"number\" ? r.confidence : 0.7,\n evidenceCount: Array.isArray(r.evidenceIds) ? r.evidenceIds.length : 1,\n evidenceCorrectionIds: Array.isArray(r.evidenceIds) ? r.evidenceIds : [],\n createdAt: now,\n lastReinforcedAt: now,\n }));\n } catch {\n log.warn(\"[calibration] failed to parse LLM response\");\n return [];\n }\n}\n\n// ─── Recall Section ──────────────────────────────────────────────────────────\n\n/**\n * Build a recall section from calibration rules relevant to the current query.\n * Uses the LLM to select which rules apply to the current context.\n */\nexport function buildCalibrationRecallSection(\n rules: CalibrationRule[],\n query: string,\n maxChars: number = 1200,\n): string | null {\n if (rules.length === 0) return null;\n\n // Simple relevance: include all rules (they're already filtered to this user)\n // In production, could use embedding similarity to filter\n const lines: string[] = [\n \"## Model Calibration (learned from past corrections)\",\n \"\",\n \"Adjustments for this specific user, learned from patterns in their corrections:\",\n \"\",\n ];\n\n let totalChars = lines.join(\"\\n\").length;\n\n for (const rule of rules) {\n const line = `- **${rule.condition}**: ${rule.modelTendency} → Instead: ${rule.calibration}`;\n if (totalChars + line.length + 1 > maxChars) break;\n lines.push(line);\n totalChars += line.length + 1;\n }\n\n if (lines.length <= 4) return null;\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Run the full calibration pipeline:\n * 1. Read all corrections\n * 2. Send to LLM for clustering and rule synthesis\n * 3. Merge with existing rules\n * 4. Write updated index\n */\nexport async function runCalibrationConsolidation(options: {\n memoryDir: string;\n gatewayConfig?: GatewayConfig;\n gatewayAgentId?: string;\n}): Promise<CalibrationRule[]> {\n try {\n const llm = new FallbackLlmClient(options.gatewayConfig);\n if (!llm.isAvailable(options.gatewayAgentId)) {\n log.debug(\"[calibration] no LLM available — skipping consolidation\");\n return [];\n }\n\n const corrections = await readCorrections(options.memoryDir);\n if (corrections.length < 3) {\n log.debug(`[calibration] only ${corrections.length} corrections — need at least 3`);\n return [];\n }\n\n const existingIndex = await readCalibrationIndex(options.memoryDir);\n\n const newRules = await synthesizeCalibrationRules(corrections, llm, existingIndex.rules, options.gatewayAgentId);\n if (newRules.length === 0) {\n log.debug(\"[calibration] no new calibration rules synthesized\");\n return existingIndex.rules;\n }\n\n // Merge: keep existing rules, add new ones (deduplicate by id)\n const ruleMap = new Map(existingIndex.rules.map((r) => [r.id, r]));\n for (const rule of newRules) {\n if (ruleMap.has(rule.id)) {\n // Reinforce existing rule\n const existing = ruleMap.get(rule.id)!;\n existing.lastReinforcedAt = new Date().toISOString();\n existing.evidenceCount += rule.evidenceCount;\n existing.confidence = Math.min(1, existing.confidence + 0.05);\n } else {\n ruleMap.set(rule.id, rule);\n }\n }\n\n const allRules = [...ruleMap.values()];\n await writeCalibrationIndex(options.memoryDir, {\n rules: allRules,\n updatedAt: new Date().toISOString(),\n totalCorrectionsAnalyzed: corrections.length,\n });\n\n log.debug(`[calibration] synthesized ${newRules.length} new rule(s), ${allRules.length} total`);\n return allRules;\n } catch (error) {\n log.warn(`[calibration] consolidation failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n\n/**\n * Standalone entry point for calibration consolidation that can be called\n * independently of weekly compounding. The compounding engine's\n * `synthesizeWeekly()` is one trigger, but orchestrators or periodic\n * maintenance jobs should call this directly so calibration is not gated\n * on weekly compounding being enabled.\n */\nexport async function runCalibrationIfEnabled(options: {\n memoryDir: string;\n calibrationEnabled: boolean;\n gatewayConfig?: GatewayConfig;\n}): Promise<CalibrationRule[]> {\n if (!options.calibrationEnabled) {\n return [];\n }\n return runCalibrationConsolidation({\n memoryDir: options.memoryDir,\n gatewayConfig: options.gatewayConfig,\n });\n}\n\n/**\n * Get calibration rules for recall injection.\n * Reads the pre-computed calibration index.\n */\nexport async function getCalibrationRulesForRecall(\n memoryDir: string,\n): Promise<CalibrationRule[]> {\n const index = await readCalibrationIndex(memoryDir);\n return index.rules;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { CausalChainIndex } from './causal-chain.js';
|
|
2
|
+
import { MemoryCategory } from './types.js';
|
|
3
|
+
import './causal-trajectory.js';
|
|
4
|
+
import './objective-state.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* preference-consolidator.ts — IRC Preference Consolidation for Engram
|
|
8
|
+
*
|
|
9
|
+
* Post-extraction pass that synthesizes preference and correction memories
|
|
10
|
+
* into explicit preference statements. These statements are formatted to
|
|
11
|
+
* match the expected answer patterns in memory benchmarks (e.g., LongMemEval)
|
|
12
|
+
* and provide clear behavioral context during recall.
|
|
13
|
+
*
|
|
14
|
+
* The key insight: Engram extracts preferences as factual statements like
|
|
15
|
+
* "The user uses Adobe Premiere Pro for video editing." But benchmarks
|
|
16
|
+
* expect preference statements like "The user would prefer resources
|
|
17
|
+
* specifically tailored to Adobe Premiere Pro." This module bridges that gap.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface ConsolidatedPreference {
|
|
21
|
+
/** Synthesized preference statement */
|
|
22
|
+
statement: string;
|
|
23
|
+
/** Source memory IDs */
|
|
24
|
+
sourceIds: string[];
|
|
25
|
+
/** Category of the source memories */
|
|
26
|
+
category: MemoryCategory;
|
|
27
|
+
/** Confidence (max of sources) */
|
|
28
|
+
confidence: number;
|
|
29
|
+
/** Keywords for matching during recall */
|
|
30
|
+
keywords: string[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* causal-behavior.ts — CMC Phase 4: Implicit Behavioral Preference Learning
|
|
35
|
+
*
|
|
36
|
+
* Extracts behavioral signals from causal chain analysis. Unlike explicit
|
|
37
|
+
* preference extraction (which reads text), this derives preferences from
|
|
38
|
+
* patterns of action: what goals recur, what actions succeed repeatedly,
|
|
39
|
+
* what outcomes are consistently pursued.
|
|
40
|
+
*
|
|
41
|
+
* Key insight: "Preferences are recurring causal pathways."
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
type CausalBehaviorSignalType = "topic_revisitation" | "action_pattern" | "outcome_preference" | "phrasing_style";
|
|
45
|
+
interface CausalBehaviorSignal {
|
|
46
|
+
signalType: CausalBehaviorSignalType;
|
|
47
|
+
pattern: string;
|
|
48
|
+
frequency: number;
|
|
49
|
+
sessionCount: number;
|
|
50
|
+
confidence: number;
|
|
51
|
+
trajectoryIds: string[];
|
|
52
|
+
}
|
|
53
|
+
interface BehaviorConfig {
|
|
54
|
+
minFrequency: number;
|
|
55
|
+
minSessions: number;
|
|
56
|
+
confidenceThreshold: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Convert behavioral signals into ConsolidatedPreference entries
|
|
60
|
+
* that can be merged with existing IRC preference output.
|
|
61
|
+
*/
|
|
62
|
+
declare function synthesizeCausalPreferences(signals: CausalBehaviorSignal[], confidenceThreshold: number): ConsolidatedPreference[];
|
|
63
|
+
/**
|
|
64
|
+
* Compute the causal impact score for a memory based on its
|
|
65
|
+
* presence in causal chains. Used in lifecycle heat/decay.
|
|
66
|
+
*
|
|
67
|
+
* Formula: 0.1 * incomingEdges + 0.15 * outgoingEdges, clamped to [0, 0.3]
|
|
68
|
+
*/
|
|
69
|
+
declare function computeCausalImpactScore(memoryId: string, chainIndex: CausalChainIndex): number;
|
|
70
|
+
/**
|
|
71
|
+
* Extract all behavioral signals from causal trajectories and chain analysis.
|
|
72
|
+
*/
|
|
73
|
+
declare function extractCausalBehaviorSignals(options: {
|
|
74
|
+
memoryDir: string;
|
|
75
|
+
causalTrajectoryStoreDir?: string;
|
|
76
|
+
config: BehaviorConfig;
|
|
77
|
+
}): Promise<CausalBehaviorSignal[]>;
|
|
78
|
+
|
|
79
|
+
export { type BehaviorConfig, type CausalBehaviorSignal, type CausalBehaviorSignalType, computeCausalImpactScore, extractCausalBehaviorSignals, synthesizeCausalPreferences };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readChainIndex,
|
|
3
|
+
resolveChainsDir
|
|
4
|
+
} from "./chunk-NTTLPF7F.js";
|
|
5
|
+
import "./chunk-M5KEYE5E.js";
|
|
6
|
+
import {
|
|
7
|
+
normalizeRecallTokens
|
|
8
|
+
} from "./chunk-DT5TVLJE.js";
|
|
9
|
+
import {
|
|
10
|
+
log
|
|
11
|
+
} from "./chunk-KWBU5S5U.js";
|
|
12
|
+
import {
|
|
13
|
+
isRecord
|
|
14
|
+
} from "./chunk-DGXUHMOV.js";
|
|
15
|
+
import {
|
|
16
|
+
listJsonFiles,
|
|
17
|
+
readJsonFile
|
|
18
|
+
} from "./chunk-LPSF4OQH.js";
|
|
19
|
+
|
|
20
|
+
// src/causal-behavior.ts
|
|
21
|
+
import path from "path";
|
|
22
|
+
function detectTopicRevisitation(trajectories, config) {
|
|
23
|
+
const goalGroups = /* @__PURE__ */ new Map();
|
|
24
|
+
for (const t of trajectories) {
|
|
25
|
+
const tokens = normalizeRecallTokens(t.goal, []).sort().join(" ");
|
|
26
|
+
if (!tokens) continue;
|
|
27
|
+
const group = goalGroups.get(tokens) ?? { sessions: /* @__PURE__ */ new Set(), trajectoryIds: [], goal: t.goal };
|
|
28
|
+
group.sessions.add(t.sessionKey);
|
|
29
|
+
group.trajectoryIds.push(t.trajectoryId);
|
|
30
|
+
goalGroups.set(tokens, group);
|
|
31
|
+
}
|
|
32
|
+
const signals = [];
|
|
33
|
+
for (const [_key, group] of goalGroups) {
|
|
34
|
+
if (group.trajectoryIds.length < config.minFrequency) continue;
|
|
35
|
+
if (group.sessions.size < config.minSessions) continue;
|
|
36
|
+
signals.push({
|
|
37
|
+
signalType: "topic_revisitation",
|
|
38
|
+
pattern: group.goal,
|
|
39
|
+
frequency: group.trajectoryIds.length,
|
|
40
|
+
sessionCount: group.sessions.size,
|
|
41
|
+
confidence: Math.min(1, 0.5 + group.sessions.size / 10),
|
|
42
|
+
trajectoryIds: group.trajectoryIds.slice(0, 10)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return signals;
|
|
46
|
+
}
|
|
47
|
+
function detectActionPatterns(trajectories, config) {
|
|
48
|
+
const actionGroups = /* @__PURE__ */ new Map();
|
|
49
|
+
for (const t of trajectories) {
|
|
50
|
+
const tokens = normalizeRecallTokens(t.actionSummary, []).sort().join(" ");
|
|
51
|
+
if (!tokens) continue;
|
|
52
|
+
const group = actionGroups.get(tokens) ?? {
|
|
53
|
+
sessions: /* @__PURE__ */ new Set(),
|
|
54
|
+
trajectoryIds: [],
|
|
55
|
+
action: t.actionSummary,
|
|
56
|
+
successCount: 0,
|
|
57
|
+
totalCount: 0
|
|
58
|
+
};
|
|
59
|
+
group.sessions.add(t.sessionKey);
|
|
60
|
+
group.trajectoryIds.push(t.trajectoryId);
|
|
61
|
+
group.totalCount++;
|
|
62
|
+
if (t.outcomeKind === "success") group.successCount++;
|
|
63
|
+
actionGroups.set(tokens, group);
|
|
64
|
+
}
|
|
65
|
+
const signals = [];
|
|
66
|
+
for (const [_key, group] of actionGroups) {
|
|
67
|
+
if (group.totalCount < Math.max(config.minFrequency, 4)) continue;
|
|
68
|
+
if (group.sessions.size < config.minSessions) continue;
|
|
69
|
+
const successRate = group.successCount / group.totalCount;
|
|
70
|
+
if (successRate < 0.8) continue;
|
|
71
|
+
signals.push({
|
|
72
|
+
signalType: "action_pattern",
|
|
73
|
+
pattern: group.action,
|
|
74
|
+
frequency: group.totalCount,
|
|
75
|
+
sessionCount: group.sessions.size,
|
|
76
|
+
confidence: Math.min(1, 0.6 + successRate * 0.3),
|
|
77
|
+
trajectoryIds: group.trajectoryIds.slice(0, 10)
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return signals;
|
|
81
|
+
}
|
|
82
|
+
function detectOutcomePreferences(trajectories, chainIndex, config) {
|
|
83
|
+
const retrySuccesses = /* @__PURE__ */ new Map();
|
|
84
|
+
const trajectoryMap = new Map(trajectories.map((t) => [t.trajectoryId, t]));
|
|
85
|
+
for (const [edgeId, edge] of Object.entries(chainIndex.edges)) {
|
|
86
|
+
if (edge.edgeType !== "retry") continue;
|
|
87
|
+
const from = trajectoryMap.get(edge.fromTrajectoryId);
|
|
88
|
+
const to = trajectoryMap.get(edge.toTrajectoryId);
|
|
89
|
+
if (!from || !to) continue;
|
|
90
|
+
if (from.outcomeKind !== "failure" || to.outcomeKind !== "success") continue;
|
|
91
|
+
const goalTokens = normalizeRecallTokens(from.goal, []).sort().join(" ");
|
|
92
|
+
const group = retrySuccesses.get(goalTokens) ?? {
|
|
93
|
+
sessions: /* @__PURE__ */ new Set(),
|
|
94
|
+
trajectoryIds: [],
|
|
95
|
+
goal: from.goal,
|
|
96
|
+
count: 0
|
|
97
|
+
};
|
|
98
|
+
group.sessions.add(from.sessionKey);
|
|
99
|
+
group.sessions.add(to.sessionKey);
|
|
100
|
+
group.trajectoryIds.push(from.trajectoryId, to.trajectoryId);
|
|
101
|
+
group.count++;
|
|
102
|
+
retrySuccesses.set(goalTokens, group);
|
|
103
|
+
}
|
|
104
|
+
const signals = [];
|
|
105
|
+
for (const [_key, group] of retrySuccesses) {
|
|
106
|
+
if (group.count < config.minFrequency) continue;
|
|
107
|
+
if (group.sessions.size < config.minSessions) continue;
|
|
108
|
+
signals.push({
|
|
109
|
+
signalType: "outcome_preference",
|
|
110
|
+
pattern: group.goal,
|
|
111
|
+
frequency: group.count,
|
|
112
|
+
sessionCount: group.sessions.size,
|
|
113
|
+
confidence: Math.min(1, 0.7 + group.count / 20),
|
|
114
|
+
trajectoryIds: [...new Set(group.trajectoryIds)].slice(0, 10)
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return signals;
|
|
118
|
+
}
|
|
119
|
+
function synthesizeCausalPreferences(signals, confidenceThreshold) {
|
|
120
|
+
const preferences = [];
|
|
121
|
+
for (const signal of signals) {
|
|
122
|
+
if (signal.confidence < confidenceThreshold) continue;
|
|
123
|
+
let statement;
|
|
124
|
+
switch (signal.signalType) {
|
|
125
|
+
case "topic_revisitation":
|
|
126
|
+
statement = `The user frequently works on: ${signal.pattern}. This topic has been revisited across ${signal.sessionCount} sessions.`;
|
|
127
|
+
break;
|
|
128
|
+
case "action_pattern":
|
|
129
|
+
statement = `The user prefers this approach: ${signal.pattern}. This action pattern has been successful ${signal.frequency} times.`;
|
|
130
|
+
break;
|
|
131
|
+
case "outcome_preference":
|
|
132
|
+
statement = `The user persistently pursues: ${signal.pattern}. They retry until successful, indicating strong preference.`;
|
|
133
|
+
break;
|
|
134
|
+
case "phrasing_style":
|
|
135
|
+
statement = `The user's phrasing pattern: ${signal.pattern}`;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
preferences.push({
|
|
139
|
+
statement,
|
|
140
|
+
sourceIds: signal.trajectoryIds.slice(0, 5),
|
|
141
|
+
category: "preference",
|
|
142
|
+
confidence: signal.confidence,
|
|
143
|
+
keywords: normalizeRecallTokens(signal.pattern, []).slice(0, 10)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return preferences;
|
|
147
|
+
}
|
|
148
|
+
function computeCausalImpactScore(memoryId, chainIndex) {
|
|
149
|
+
const incoming = chainIndex.incoming[memoryId]?.length ?? 0;
|
|
150
|
+
const outgoing = chainIndex.outgoing[memoryId]?.length ?? 0;
|
|
151
|
+
const raw = 0.1 * incoming + 0.15 * outgoing;
|
|
152
|
+
return Math.min(0.3, Math.max(0, raw));
|
|
153
|
+
}
|
|
154
|
+
async function extractCausalBehaviorSignals(options) {
|
|
155
|
+
try {
|
|
156
|
+
const { memoryDir, causalTrajectoryStoreDir, config: behaviorConfig } = options;
|
|
157
|
+
const root = causalTrajectoryStoreDir ? path.join(memoryDir, causalTrajectoryStoreDir) : path.join(memoryDir, "state", "causal-trajectories");
|
|
158
|
+
const trajectoriesDir = path.join(root, "trajectories");
|
|
159
|
+
const files = await listJsonFiles(trajectoriesDir).catch(() => []);
|
|
160
|
+
const trajectories = [];
|
|
161
|
+
for (const filePath of files) {
|
|
162
|
+
try {
|
|
163
|
+
const raw = await readJsonFile(filePath);
|
|
164
|
+
if (isRecord(raw) && typeof raw.trajectoryId === "string") {
|
|
165
|
+
trajectories.push(raw);
|
|
166
|
+
}
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (trajectories.length === 0) return [];
|
|
171
|
+
const chainsDir = resolveChainsDir(memoryDir, causalTrajectoryStoreDir);
|
|
172
|
+
const chainIndex = await readChainIndex(chainsDir);
|
|
173
|
+
const signals = [
|
|
174
|
+
...detectTopicRevisitation(trajectories, behaviorConfig),
|
|
175
|
+
...detectActionPatterns(trajectories, behaviorConfig),
|
|
176
|
+
...detectOutcomePreferences(trajectories, chainIndex, behaviorConfig)
|
|
177
|
+
];
|
|
178
|
+
log.debug(`[cmc] extracted ${signals.length} behavioral signal(s) from ${trajectories.length} trajectories`);
|
|
179
|
+
return signals;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
log.warn(`[cmc] behavioral signal extraction failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export {
|
|
186
|
+
computeCausalImpactScore,
|
|
187
|
+
extractCausalBehaviorSignals,
|
|
188
|
+
synthesizeCausalPreferences
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=causal-behavior.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/causal-behavior.ts"],"sourcesContent":["/**\n * causal-behavior.ts — CMC Phase 4: Implicit Behavioral Preference Learning\n *\n * Extracts behavioral signals from causal chain analysis. Unlike explicit\n * preference extraction (which reads text), this derives preferences from\n * patterns of action: what goals recur, what actions succeed repeatedly,\n * what outcomes are consistently pursued.\n *\n * Key insight: \"Preferences are recurring causal pathways.\"\n */\n\nimport type { CausalTrajectoryRecord } from \"./causal-trajectory.js\";\nimport type { CausalChainIndex } from \"./causal-chain.js\";\nimport { readChainIndex, resolveChainsDir } from \"./causal-chain.js\";\nimport { normalizeRecallTokens } from \"./recall-tokenization.js\";\nimport { topicOverlapScore } from \"./boxes.js\";\nimport { listJsonFiles, readJsonFile } from \"./json-store.js\";\nimport { isRecord } from \"./store-contract.js\";\nimport type { ConsolidatedPreference } from \"./compounding/preference-consolidator.js\";\nimport path from \"node:path\";\nimport { log } from \"./logger.js\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type CausalBehaviorSignalType =\n | \"topic_revisitation\"\n | \"action_pattern\"\n | \"outcome_preference\"\n | \"phrasing_style\";\n\nexport interface CausalBehaviorSignal {\n signalType: CausalBehaviorSignalType;\n pattern: string;\n frequency: number;\n sessionCount: number;\n confidence: number;\n trajectoryIds: string[];\n}\n\nexport interface BehaviorConfig {\n minFrequency: number;\n minSessions: number;\n confidenceThreshold: number;\n}\n\n// ─── Signal Extraction ───────────────────────────────────────────────────────\n\n/**\n * Detect topic revisitation: same goal fingerprint appearing in 3+ sessions.\n */\nfunction detectTopicRevisitation(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const goalGroups = new Map<string, { sessions: Set<string>; trajectoryIds: string[]; goal: string }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.goal, []).sort().join(\" \");\n if (!tokens) continue;\n const group = goalGroups.get(tokens) ?? { sessions: new Set(), trajectoryIds: [], goal: t.goal };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n goalGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of goalGroups) {\n if (group.trajectoryIds.length < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"topic_revisitation\",\n pattern: group.goal,\n frequency: group.trajectoryIds.length,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.5 + (group.sessions.size / 10)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect action patterns: same action with >= 80% success rate, 4+ occurrences.\n */\nfunction detectActionPatterns(\n trajectories: CausalTrajectoryRecord[],\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const actionGroups = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n action: string;\n successCount: number;\n totalCount: number;\n }>();\n\n for (const t of trajectories) {\n const tokens = normalizeRecallTokens(t.actionSummary, []).sort().join(\" \");\n if (!tokens) continue;\n const group = actionGroups.get(tokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n action: t.actionSummary,\n successCount: 0,\n totalCount: 0,\n };\n group.sessions.add(t.sessionKey);\n group.trajectoryIds.push(t.trajectoryId);\n group.totalCount++;\n if (t.outcomeKind === \"success\") group.successCount++;\n actionGroups.set(tokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of actionGroups) {\n if (group.totalCount < Math.max(config.minFrequency, 4)) continue;\n if (group.sessions.size < config.minSessions) continue;\n const successRate = group.successCount / group.totalCount;\n if (successRate < 0.8) continue;\n\n signals.push({\n signalType: \"action_pattern\",\n pattern: group.action,\n frequency: group.totalCount,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.6 + (successRate * 0.3)),\n trajectoryIds: group.trajectoryIds.slice(0, 10),\n });\n }\n\n return signals;\n}\n\n/**\n * Detect outcome preferences: consistent retry patterns leading to success.\n * When a trajectory fails and is retried (via chain edges) successfully,\n * it indicates a strong preference for that outcome.\n */\nfunction detectOutcomePreferences(\n trajectories: CausalTrajectoryRecord[],\n chainIndex: CausalChainIndex,\n config: BehaviorConfig,\n): CausalBehaviorSignal[] {\n const retrySuccesses = new Map<string, {\n sessions: Set<string>;\n trajectoryIds: string[];\n goal: string;\n count: number;\n }>();\n\n const trajectoryMap = new Map(trajectories.map((t) => [t.trajectoryId, t]));\n\n for (const [edgeId, edge] of Object.entries(chainIndex.edges)) {\n if (edge.edgeType !== \"retry\") continue;\n\n const from = trajectoryMap.get(edge.fromTrajectoryId);\n const to = trajectoryMap.get(edge.toTrajectoryId);\n if (!from || !to) continue;\n if (from.outcomeKind !== \"failure\" || to.outcomeKind !== \"success\") continue;\n\n const goalTokens = normalizeRecallTokens(from.goal, []).sort().join(\" \");\n const group = retrySuccesses.get(goalTokens) ?? {\n sessions: new Set(),\n trajectoryIds: [],\n goal: from.goal,\n count: 0,\n };\n group.sessions.add(from.sessionKey);\n group.sessions.add(to.sessionKey);\n group.trajectoryIds.push(from.trajectoryId, to.trajectoryId);\n group.count++;\n retrySuccesses.set(goalTokens, group);\n }\n\n const signals: CausalBehaviorSignal[] = [];\n for (const [_key, group] of retrySuccesses) {\n if (group.count < config.minFrequency) continue;\n if (group.sessions.size < config.minSessions) continue;\n\n signals.push({\n signalType: \"outcome_preference\",\n pattern: group.goal,\n frequency: group.count,\n sessionCount: group.sessions.size,\n confidence: Math.min(1, 0.7 + (group.count / 20)),\n trajectoryIds: [...new Set(group.trajectoryIds)].slice(0, 10),\n });\n }\n\n return signals;\n}\n\n// ─── Preference Synthesis ────────────────────────────────────────────────────\n\n/**\n * Convert behavioral signals into ConsolidatedPreference entries\n * that can be merged with existing IRC preference output.\n */\nexport function synthesizeCausalPreferences(\n signals: CausalBehaviorSignal[],\n confidenceThreshold: number,\n): ConsolidatedPreference[] {\n const preferences: ConsolidatedPreference[] = [];\n\n for (const signal of signals) {\n if (signal.confidence < confidenceThreshold) continue;\n\n let statement: string;\n switch (signal.signalType) {\n case \"topic_revisitation\":\n statement = `The user frequently works on: ${signal.pattern}. This topic has been revisited across ${signal.sessionCount} sessions.`;\n break;\n case \"action_pattern\":\n statement = `The user prefers this approach: ${signal.pattern}. This action pattern has been successful ${signal.frequency} times.`;\n break;\n case \"outcome_preference\":\n statement = `The user persistently pursues: ${signal.pattern}. They retry until successful, indicating strong preference.`;\n break;\n case \"phrasing_style\":\n statement = `The user's phrasing pattern: ${signal.pattern}`;\n break;\n }\n\n preferences.push({\n statement,\n sourceIds: signal.trajectoryIds.slice(0, 5),\n category: \"preference\",\n confidence: signal.confidence,\n keywords: normalizeRecallTokens(signal.pattern, []).slice(0, 10),\n });\n }\n\n return preferences;\n}\n\n// ─── Causal Impact Score ─────────────────────────────────────────────────────\n\n/**\n * Compute the causal impact score for a memory based on its\n * presence in causal chains. Used in lifecycle heat/decay.\n *\n * Formula: 0.1 * incomingEdges + 0.15 * outgoingEdges, clamped to [0, 0.3]\n */\nexport function computeCausalImpactScore(\n memoryId: string,\n chainIndex: CausalChainIndex,\n): number {\n // Memory IDs don't directly map to trajectory IDs, but trajectory-based\n // memories may reference their source trajectory ID. For now, check\n // if the memoryId appears as a trajectory ID in the chain index.\n const incoming = chainIndex.incoming[memoryId]?.length ?? 0;\n const outgoing = chainIndex.outgoing[memoryId]?.length ?? 0;\n const raw = 0.1 * incoming + 0.15 * outgoing;\n return Math.min(0.3, Math.max(0, raw));\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Extract all behavioral signals from causal trajectories and chain analysis.\n */\nexport async function extractCausalBehaviorSignals(options: {\n memoryDir: string;\n causalTrajectoryStoreDir?: string;\n config: BehaviorConfig;\n}): Promise<CausalBehaviorSignal[]> {\n try {\n const { memoryDir, causalTrajectoryStoreDir, config: behaviorConfig } = options;\n\n // Read all trajectories\n const root = causalTrajectoryStoreDir\n ? path.join(memoryDir, causalTrajectoryStoreDir)\n : path.join(memoryDir, \"state\", \"causal-trajectories\");\n const trajectoriesDir = path.join(root, \"trajectories\");\n const files = await listJsonFiles(trajectoriesDir).catch(() => [] as string[]);\n\n const trajectories: CausalTrajectoryRecord[] = [];\n for (const filePath of files) {\n try {\n const raw = await readJsonFile(filePath);\n if (isRecord(raw) && typeof raw.trajectoryId === \"string\") {\n trajectories.push(raw as unknown as CausalTrajectoryRecord);\n }\n } catch {\n // skip\n }\n }\n\n if (trajectories.length === 0) return [];\n\n // Read chain index\n const chainsDir = resolveChainsDir(memoryDir, causalTrajectoryStoreDir);\n const chainIndex = await readChainIndex(chainsDir);\n\n // Extract all signal types\n const signals: CausalBehaviorSignal[] = [\n ...detectTopicRevisitation(trajectories, behaviorConfig),\n ...detectActionPatterns(trajectories, behaviorConfig),\n ...detectOutcomePreferences(trajectories, chainIndex, behaviorConfig),\n ];\n\n log.debug(`[cmc] extracted ${signals.length} behavioral signal(s) from ${trajectories.length} trajectories`);\n return signals;\n } catch (error) {\n log.warn(`[cmc] behavioral signal extraction failed (non-fatal): ${error instanceof Error ? error.message : String(error)}`);\n return [];\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { CausalTrajectoryRecord } from './causal-trajectory.js';
|
|
2
|
+
import './objective-state.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* causal-chain.ts — Cross-session causal chain persistence for CMC.
|
|
6
|
+
*
|
|
7
|
+
* Stitches causal trajectories across session boundaries by detecting
|
|
8
|
+
* when a trajectory in one session follows up on a trajectory from
|
|
9
|
+
* another session. Persists edges in a graph index for later retrieval.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
interface CausalEdge {
|
|
13
|
+
schemaVersion: 1;
|
|
14
|
+
edgeId: string;
|
|
15
|
+
fromTrajectoryId: string;
|
|
16
|
+
toTrajectoryId: string;
|
|
17
|
+
edgeType: "follow_up_to_goal" | "retry" | "continuation" | "correction";
|
|
18
|
+
confidence: number;
|
|
19
|
+
stitchMethod: "lexical" | "entity" | "temporal" | "explicit";
|
|
20
|
+
createdAt: string;
|
|
21
|
+
metadata?: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
interface CausalChainIndex {
|
|
24
|
+
outgoing: Record<string, string[]>;
|
|
25
|
+
incoming: Record<string, string[]>;
|
|
26
|
+
edges: Record<string, CausalEdge>;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
}
|
|
29
|
+
interface StitchConfig {
|
|
30
|
+
lookbackDays: number;
|
|
31
|
+
minScore: number;
|
|
32
|
+
maxEdgesPerTrajectory: number;
|
|
33
|
+
}
|
|
34
|
+
interface StitchCandidate {
|
|
35
|
+
trajectory: CausalTrajectoryRecord;
|
|
36
|
+
score: number;
|
|
37
|
+
edgeType: CausalEdge["edgeType"];
|
|
38
|
+
stitchMethod: CausalEdge["stitchMethod"];
|
|
39
|
+
}
|
|
40
|
+
declare function validateCausalEdge(raw: unknown): CausalEdge;
|
|
41
|
+
declare function makeEdgeId(fromId: string, toId: string): string;
|
|
42
|
+
declare function resolveChainsDir(memoryDir: string, causalTrajectoryStoreDir?: string): string;
|
|
43
|
+
declare function readChainIndex(chainsDir: string): Promise<CausalChainIndex>;
|
|
44
|
+
declare function writeChainIndex(chainsDir: string, index: CausalChainIndex): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Score how strongly a candidate trajectory from another session
|
|
47
|
+
* relates to the new trajectory being recorded.
|
|
48
|
+
*/
|
|
49
|
+
declare function scoreStitchCandidate(newTrajectory: CausalTrajectoryRecord, candidate: CausalTrajectoryRecord): StitchCandidate;
|
|
50
|
+
/**
|
|
51
|
+
* After a new trajectory is recorded, attempt to stitch it to
|
|
52
|
+
* existing trajectories from other sessions.
|
|
53
|
+
*/
|
|
54
|
+
declare function stitchCausalChain(options: {
|
|
55
|
+
memoryDir: string;
|
|
56
|
+
causalTrajectoryStoreDir?: string;
|
|
57
|
+
newTrajectory: CausalTrajectoryRecord;
|
|
58
|
+
config: StitchConfig;
|
|
59
|
+
}): Promise<CausalEdge[]>;
|
|
60
|
+
|
|
61
|
+
export { type CausalChainIndex, type CausalEdge, type StitchCandidate, type StitchConfig, makeEdgeId, readChainIndex, resolveChainsDir, scoreStitchCandidate, stitchCausalChain, validateCausalEdge, writeChainIndex };
|