@graphrefly/ts 0.0.0 → 0.0.2
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/README.md +135 -0
- package/dist/actions-types-CSC3NMDl.d.ts +657 -0
- package/dist/actions-types-wl9Mgkmr.d.cts +657 -0
- package/dist/adapters/index.cjs +5219 -2974
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +204 -192
- package/dist/adapters/index.d.ts +204 -192
- package/dist/adapters/index.js +3685 -1833
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/nestjs/microservices.cjs +841 -0
- package/dist/adapters/nestjs/microservices.cjs.map +1 -0
- package/dist/adapters/nestjs/microservices.d.cts +45 -0
- package/dist/adapters/nestjs/microservices.d.ts +45 -0
- package/dist/adapters/nestjs/microservices.js +206 -0
- package/dist/adapters/nestjs/microservices.js.map +1 -0
- package/dist/adapters/nestjs/native.cjs +1391 -0
- package/dist/adapters/nestjs/native.cjs.map +1 -0
- package/dist/adapters/nestjs/native.d.cts +111 -0
- package/dist/adapters/nestjs/native.d.ts +111 -0
- package/dist/adapters/nestjs/native.js +577 -0
- package/dist/adapters/nestjs/native.js.map +1 -0
- package/dist/adapters/nestjs/websockets.cjs +924 -0
- package/dist/adapters/nestjs/websockets.cjs.map +1 -0
- package/dist/adapters/nestjs/websockets.d.cts +47 -0
- package/dist/adapters/nestjs/websockets.d.ts +47 -0
- package/dist/adapters/nestjs/websockets.js +286 -0
- package/dist/adapters/nestjs/websockets.js.map +1 -0
- package/dist/adapters/nestjs.cjs +1085 -0
- package/dist/adapters/nestjs.cjs.map +1 -0
- package/dist/adapters/nestjs.d.cts +385 -0
- package/dist/adapters/nestjs.d.ts +385 -0
- package/dist/adapters/nestjs.js +112 -0
- package/dist/adapters/nestjs.js.map +1 -0
- package/dist/adapters/observe-storage.d.cts +4 -4
- package/dist/adapters/observe-storage.d.ts +4 -4
- package/dist/adapters/observe-storage.js +5 -4
- package/dist/adapters/observe-storage.js.map +1 -1
- package/dist/adapters/react.cjs +166 -0
- package/dist/adapters/react.cjs.map +1 -0
- package/dist/adapters/react.d.cts +31 -0
- package/dist/adapters/react.d.ts +31 -0
- package/dist/adapters/react.js +51 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/solid.cjs +157 -0
- package/dist/adapters/solid.cjs.map +1 -0
- package/dist/adapters/solid.d.cts +26 -0
- package/dist/adapters/solid.d.ts +26 -0
- package/dist/adapters/solid.js +48 -0
- package/dist/adapters/solid.js.map +1 -0
- package/dist/adapters/svelte.cjs +148 -0
- package/dist/adapters/svelte.cjs.map +1 -0
- package/dist/adapters/svelte.d.cts +31 -0
- package/dist/adapters/svelte.d.ts +31 -0
- package/dist/adapters/svelte.js +46 -0
- package/dist/adapters/svelte.js.map +1 -0
- package/dist/adapters/vue.cjs +155 -0
- package/dist/adapters/vue.cjs.map +1 -0
- package/dist/adapters/vue.d.cts +26 -0
- package/dist/adapters/vue.d.ts +26 -0
- package/dist/adapters/vue.js +46 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/agent-runtime-types-core-CaXfKNtY.d.cts +406 -0
- package/dist/agent-runtime-types-core-hU299uIC.d.ts +406 -0
- package/dist/agent-runtime-types-tool-BEpSINol.d.ts +695 -0
- package/dist/agent-runtime-types-tool-DninPEzk.d.cts +695 -0
- package/dist/agentic-memory-retention-BmGX368S.d.ts +14 -0
- package/dist/agentic-memory-retention-Ih1qhX9Z.d.cts +14 -0
- package/dist/agentic-memory-types-CVSUS6XR.d.ts +473 -0
- package/dist/agentic-memory-types-FnnYlVUs.d.cts +473 -0
- package/dist/capability-admission-BW2CziT6.d.ts +102 -0
- package/dist/capability-admission-lwSecxXs.d.cts +102 -0
- package/dist/chunk-2KUAG2GZ.js +9693 -0
- package/dist/chunk-2KUAG2GZ.js.map +1 -0
- package/dist/chunk-2NJP6GO4.js +1320 -0
- package/dist/chunk-2NJP6GO4.js.map +1 -0
- package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
- package/dist/{chunk-COHO25CZ.js → chunk-4NWSNI4K.js} +2232 -1672
- package/dist/chunk-4NWSNI4K.js.map +1 -0
- package/dist/{chunk-Z2ANQ6JW.js → chunk-4Q77MMJY.js} +2 -2
- package/dist/chunk-6E76H4OU.js +132 -0
- package/dist/chunk-6E76H4OU.js.map +1 -0
- package/dist/chunk-7GOTIIQ7.js +819 -0
- package/dist/chunk-7GOTIIQ7.js.map +1 -0
- package/dist/{chunk-D6BG7U6A.js → chunk-7HZRJMN6.js} +3 -3
- package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
- package/dist/{chunk-PKVBHGBM.js → chunk-CJIFGJQG.js} +7 -7
- package/dist/{chunk-G4M3NHRJ.js → chunk-CX6B6PO2.js} +93 -10
- package/dist/chunk-CX6B6PO2.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-JIMUDQN3.js → chunk-E4QCH32M.js} +449 -447
- package/dist/chunk-E4QCH32M.js.map +1 -0
- package/dist/{chunk-RIIOUTGM.js → chunk-ECURQ3HD.js} +19 -129
- package/dist/chunk-ECURQ3HD.js.map +1 -0
- package/dist/{chunk-2ILL7HQI.js → chunk-EOKT4QFF.js} +134 -128
- package/dist/chunk-EOKT4QFF.js.map +1 -0
- package/dist/{chunk-K3FXTC3I.js → chunk-HJACH5PU.js} +3 -3
- package/dist/{chunk-GTPCOEOZ.js → chunk-IDMLXLLG.js} +3 -3
- package/dist/{chunk-DKP56CSW.js → chunk-JKAYLDQV.js} +2 -2
- package/dist/{chunk-4VLAQHZI.js → chunk-K7FB3JTD.js} +17 -1
- package/dist/chunk-K7FB3JTD.js.map +1 -0
- package/dist/chunk-L6LDXRWE.js +219 -0
- package/dist/chunk-L6LDXRWE.js.map +1 -0
- package/dist/chunk-M7J6Z4IJ.js +1930 -0
- package/dist/chunk-M7J6Z4IJ.js.map +1 -0
- package/dist/chunk-MQEQMS7B.js +1009 -0
- package/dist/chunk-MQEQMS7B.js.map +1 -0
- package/dist/chunk-MTELVIYR.js +1421 -0
- package/dist/chunk-MTELVIYR.js.map +1 -0
- package/dist/chunk-PVC7WDKI.js +885 -0
- package/dist/chunk-PVC7WDKI.js.map +1 -0
- package/dist/chunk-RAHNUYA5.js +368 -0
- package/dist/chunk-RAHNUYA5.js.map +1 -0
- package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
- package/dist/chunk-S6HXABGL.js.map +1 -0
- package/dist/{chunk-I3IHOHCJ.js → chunk-SHZDP2MQ.js} +1181 -1001
- package/dist/chunk-SHZDP2MQ.js.map +1 -0
- package/dist/{chunk-Y3ZLRGHC.js → chunk-SIDJO2T4.js} +16 -16
- package/dist/chunk-STXRMPW4.js +4131 -0
- package/dist/chunk-STXRMPW4.js.map +1 -0
- package/dist/{chunk-JR4IKCR2.js → chunk-TPND5MJS.js} +5 -5
- package/dist/chunk-TQPCAIQI.js +612 -0
- package/dist/chunk-TQPCAIQI.js.map +1 -0
- package/dist/chunk-UT3MHJCW.js +49 -0
- package/dist/chunk-UT3MHJCW.js.map +1 -0
- package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
- package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
- package/dist/chunk-WQIA3GFB.js.map +1 -0
- package/dist/{chunk-DJC4CHLQ.js → chunk-YDWBXXQZ.js} +5 -5
- package/dist/{chunk-6PHB5CJS.js → chunk-ZLFRB6FI.js} +2 -2
- package/dist/composition/index.cjs +1256 -1059
- package/dist/composition/index.cjs.map +1 -1
- package/dist/composition/index.d.cts +4 -4
- package/dist/composition/index.d.ts +4 -4
- package/dist/composition/index.js +7 -6
- package/dist/core/index.cjs +1218 -1021
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +5 -4
- package/dist/cqrs/index.cjs.map +1 -1
- package/dist/cqrs/index.d.cts +4 -4
- package/dist/cqrs/index.d.ts +4 -4
- package/dist/cqrs/index.js +3 -2
- package/dist/cqrs/index.js.map +1 -1
- package/dist/cqrs/messaging.cjs +312 -0
- package/dist/cqrs/messaging.cjs.map +1 -0
- package/dist/cqrs/messaging.d.cts +57 -0
- package/dist/cqrs/messaging.d.ts +57 -0
- package/dist/cqrs/messaging.js +274 -0
- package/dist/cqrs/messaging.js.map +1 -0
- package/dist/cqrs/work-queue.cjs +329 -0
- package/dist/cqrs/work-queue.cjs.map +1 -0
- package/dist/cqrs/work-queue.d.cts +90 -0
- package/dist/cqrs/work-queue.d.ts +90 -0
- package/dist/cqrs/work-queue.js +292 -0
- package/dist/cqrs/work-queue.js.map +1 -0
- package/dist/data/index.cjs +19 -0
- package/dist/data/index.cjs.map +1 -0
- package/dist/data/index.d.cts +36 -0
- package/dist/data/index.d.ts +36 -0
- package/dist/data/index.js +1 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data-structures/index.cjs +1252 -1052
- package/dist/data-structures/index.cjs.map +1 -1
- package/dist/data-structures/index.d.cts +9 -8
- package/dist/data-structures/index.d.ts +9 -8
- package/dist/data-structures/index.js +9 -7
- package/dist/{describe-BZb7AS2y.d.ts → describe-B_A5fbXH.d.ts} +1 -1
- package/dist/{describe-Ciu8SUnN.d.cts → describe-CQRrkv-Q.d.cts} +1 -1
- package/dist/executors/tool-provider-adapters.cjs +3091 -0
- package/dist/executors/tool-provider-adapters.cjs.map +1 -0
- package/dist/executors/tool-provider-adapters.d.cts +174 -0
- package/dist/executors/tool-provider-adapters.d.ts +174 -0
- package/dist/executors/tool-provider-adapters.js +1336 -0
- package/dist/executors/tool-provider-adapters.js.map +1 -0
- package/dist/executors/tool-provider-runtime.cjs +5178 -0
- package/dist/executors/tool-provider-runtime.cjs.map +1 -0
- package/dist/executors/tool-provider-runtime.d.cts +17 -0
- package/dist/executors/tool-provider-runtime.d.ts +17 -0
- package/dist/executors/tool-provider-runtime.js +15 -0
- package/dist/executors/tool-provider-runtime.js.map +1 -0
- package/dist/executors/tool-provider.cjs +6392 -0
- package/dist/executors/tool-provider.cjs.map +1 -0
- package/dist/executors/tool-provider.d.cts +60 -0
- package/dist/executors/tool-provider.d.ts +60 -0
- package/dist/executors/tool-provider.js +89 -0
- package/dist/executors/tool-provider.js.map +1 -0
- package/dist/executors/work-queue.cjs +342 -0
- package/dist/executors/work-queue.cjs.map +1 -0
- package/dist/executors/work-queue.d.cts +90 -0
- package/dist/executors/work-queue.d.ts +90 -0
- package/dist/executors/work-queue.js +306 -0
- package/dist/executors/work-queue.js.map +1 -0
- package/dist/graph/index.cjs +1536 -1324
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +10 -9
- package/dist/graph/index.d.ts +10 -9
- package/dist/graph/index.js +22 -20
- package/dist/{graph-s23RbbFO.d.cts → graph-CWK3HLPB.d.cts} +134 -132
- package/dist/{graph-DfdF9zy4.d.ts → graph-ho5sotHP.d.ts} +134 -132
- package/dist/{index-SnzZu3x7.d.ts → index-CQWcE0Dw.d.ts} +18 -4
- package/dist/{index-CAEmLCYF.d.cts → index-DHA1i67c.d.cts} +18 -4
- package/dist/index.cjs +3331 -3020
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -10
- package/dist/index.d.ts +14 -10
- package/dist/index.js +114 -108
- package/dist/inspection/boundary.cjs +98 -0
- package/dist/inspection/boundary.cjs.map +1 -0
- package/dist/inspection/boundary.d.cts +61 -0
- package/dist/inspection/boundary.d.ts +61 -0
- package/dist/inspection/boundary.js +75 -0
- package/dist/inspection/boundary.js.map +1 -0
- package/dist/measurements-C0mAvWU1.d.cts +164 -0
- package/dist/measurements-OMpCeBwh.d.ts +164 -0
- package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
- package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
- package/dist/messaging/index.cjs +756 -619
- package/dist/messaging/index.cjs.map +1 -1
- package/dist/messaging/index.d.cts +17 -226
- package/dist/messaging/index.d.ts +17 -226
- package/dist/messaging/index.js +19 -749
- package/dist/messaging/index.js.map +1 -1
- package/dist/operators/index.cjs +1256 -1059
- package/dist/operators/index.cjs.map +1 -1
- package/dist/operators/index.d.cts +6 -6
- package/dist/operators/index.d.ts +6 -6
- package/dist/operators/index.js +9 -8
- package/dist/orchestration/index.cjs +8664 -2617
- package/dist/orchestration/index.cjs.map +1 -1
- package/dist/orchestration/index.d.cts +171 -221
- package/dist/orchestration/index.d.ts +171 -221
- package/dist/orchestration/index.js +74 -982
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/messaging.cjs +314 -0
- package/dist/orchestration/messaging.cjs.map +1 -0
- package/dist/orchestration/messaging.d.cts +56 -0
- package/dist/orchestration/messaging.d.ts +56 -0
- package/dist/orchestration/messaging.js +276 -0
- package/dist/orchestration/messaging.js.map +1 -0
- package/dist/orchestration/work-queue.cjs +1500 -0
- package/dist/orchestration/work-queue.cjs.map +1 -0
- package/dist/orchestration/work-queue.d.cts +196 -0
- package/dist/orchestration/work-queue.d.ts +196 -0
- package/dist/orchestration/work-queue.js +1289 -0
- package/dist/orchestration/work-queue.js.map +1 -0
- package/dist/patterns/event-flow.cjs +433 -0
- package/dist/patterns/event-flow.cjs.map +1 -0
- package/dist/patterns/event-flow.d.cts +115 -0
- package/dist/patterns/event-flow.d.ts +115 -0
- package/dist/patterns/event-flow.js +14 -0
- package/dist/patterns/event-flow.js.map +1 -0
- package/dist/patterns/index.cjs +748 -355
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +9 -5
- package/dist/patterns/index.d.ts +9 -5
- package/dist/patterns/index.js +13 -4
- package/dist/process-types-C9uMYz3i.d.ts +200 -0
- package/dist/process-types-h3uRlzDc.d.cts +200 -0
- package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-B9R0Bl1P.d.cts} +11 -41
- package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BXFrH0U2.d.ts} +11 -41
- package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BLGv8Xp8.d.cts} +5 -5
- package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-a4zD3665.d.ts} +5 -5
- package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-C_8sOfdS.d.cts} +7 -6
- package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-jle5dnok.d.ts} +7 -6
- package/dist/render/index.d.cts +3 -3
- package/dist/render/index.d.ts +3 -3
- package/dist/render/index.js +1 -0
- package/dist/scheduled-readiness-5rwQlyjV.d.ts +91 -0
- package/dist/scheduled-readiness-DpRY8jI0.d.cts +91 -0
- package/dist/semantic-memory-graph-C2ZUwIlq.d.ts +30 -0
- package/dist/semantic-memory-graph-DlZBD_Eu.d.cts +30 -0
- package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-types-BvzdqmkY.d.cts} +2 -28
- package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-types-Ci-OtahO.d.ts} +2 -28
- package/dist/solutions/index.cjs +6788 -2128
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +15 -519
- package/dist/solutions/index.d.ts +15 -519
- package/dist/solutions/index.js +91 -7
- package/dist/solutions/reactive-layout/browser/index.cjs +457 -0
- package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
- package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
- package/dist/solutions/reactive-layout/browser/index.js +69 -0
- package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
- package/dist/solutions/reactive-layout/index.cjs +4494 -0
- package/dist/solutions/reactive-layout/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/index.d.cts +37 -0
- package/dist/solutions/reactive-layout/index.d.ts +37 -0
- package/dist/solutions/reactive-layout/index.js +146 -0
- package/dist/solutions/reactive-layout/index.js.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs +555 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs +504 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.js +77 -0
- package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.cjs +557 -0
- package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
- package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
- package/dist/solutions/reactive-layout/skia/index.js +70 -0
- package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
- package/dist/solutions/work-item/actions.cjs +2345 -0
- package/dist/solutions/work-item/actions.cjs.map +1 -0
- package/dist/solutions/work-item/actions.d.cts +40 -0
- package/dist/solutions/work-item/actions.d.ts +40 -0
- package/dist/solutions/work-item/actions.js +2078 -0
- package/dist/solutions/work-item/actions.js.map +1 -0
- package/dist/solutions/work-item/scheduling.cjs +9797 -0
- package/dist/solutions/work-item/scheduling.cjs.map +1 -0
- package/dist/solutions/work-item/scheduling.d.cts +1868 -0
- package/dist/solutions/work-item/scheduling.d.ts +1868 -0
- package/dist/solutions/work-item/scheduling.js +146 -0
- package/dist/solutions/work-item/scheduling.js.map +1 -0
- package/dist/solutions/work-item/work-queue.cjs +306 -0
- package/dist/solutions/work-item/work-queue.cjs.map +1 -0
- package/dist/solutions/work-item/work-queue.d.cts +71 -0
- package/dist/solutions/work-item/work-queue.d.ts +71 -0
- package/dist/solutions/work-item/work-queue.js +270 -0
- package/dist/solutions/work-item/work-queue.js.map +1 -0
- package/dist/sources/browser.cjs +1399 -1052
- package/dist/sources/browser.cjs.map +1 -1
- package/dist/sources/browser.d.cts +33 -6
- package/dist/sources/browser.d.ts +33 -6
- package/dist/sources/browser.js +73 -6
- package/dist/sources/browser.js.map +1 -1
- package/dist/sources/index.cjs +1345 -1065
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.d.cts +5 -5
- package/dist/sources/index.d.ts +5 -5
- package/dist/sources/index.js +7 -6
- package/dist/sources/node.cjs.map +1 -1
- package/dist/sources/node.d.cts +4 -4
- package/dist/sources/node.d.ts +4 -4
- package/dist/sources/node.js +2 -1
- package/dist/sources/node.js.map +1 -1
- package/dist/storage/browser.cjs +16 -0
- package/dist/storage/browser.cjs.map +1 -1
- package/dist/storage/browser.js +4 -3
- package/dist/storage/browser.js.map +1 -1
- package/dist/storage/index.cjs +16 -0
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.d.cts +6 -5
- package/dist/storage/index.d.ts +6 -5
- package/dist/storage/index.js +10 -9
- package/dist/storage/node.cjs +16 -0
- package/dist/storage/node.cjs.map +1 -1
- package/dist/storage/node.js +4 -3
- package/dist/storage/node.js.map +1 -1
- package/dist/store-BmtEs9mG.d.ts +123 -0
- package/dist/store-PAAsYvML.d.cts +123 -0
- package/dist/testing/index.cjs +1 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +3 -2
- package/dist/types-BRNKoFHj.d.ts +357 -0
- package/dist/{types-h12mNYbq.d.ts → types-BS6CyR-x.d.cts} +49 -130
- package/dist/types-BWK2ay3e.d.cts +457 -0
- package/dist/types-BXKSAoE1.d.cts +357 -0
- package/dist/types-BaPpZItj.d.ts +457 -0
- package/dist/types-BhveCMg5.d.cts +274 -0
- package/dist/{types-bNMSWKqF.d.cts → types-C9NOgNJw.d.ts} +49 -130
- package/dist/types-CTsQ8Ww4.d.ts +274 -0
- package/dist/types-DL_05n2M.d.ts +34 -0
- package/dist/types-XDoqxYO9.d.cts +34 -0
- package/dist/work-item-runtime-types-BqtWnSCS.d.ts +138 -0
- package/dist/work-item-runtime-types-CHO03AKh.d.cts +138 -0
- package/dist/work-queue/index.cjs +1136 -0
- package/dist/work-queue/index.cjs.map +1 -0
- package/dist/work-queue/index.d.cts +21 -0
- package/dist/work-queue/index.d.ts +21 -0
- package/dist/work-queue/index.js +1082 -0
- package/dist/work-queue/index.js.map +1 -0
- package/package.json +603 -249
- package/dist/chunk-2ILL7HQI.js.map +0 -1
- package/dist/chunk-4VLAQHZI.js.map +0 -1
- package/dist/chunk-COHO25CZ.js.map +0 -1
- package/dist/chunk-DK554R7P.js.map +0 -1
- package/dist/chunk-G4M3NHRJ.js.map +0 -1
- package/dist/chunk-I3IHOHCJ.js.map +0 -1
- package/dist/chunk-JIMUDQN3.js.map +0 -1
- package/dist/chunk-RIIOUTGM.js.map +0 -1
- package/dist/chunk-SWTLEQL6.js.map +0 -1
- /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
- /package/dist/{chunk-Z2ANQ6JW.js.map → chunk-4Q77MMJY.js.map} +0 -0
- /package/dist/{chunk-D6BG7U6A.js.map → chunk-7HZRJMN6.js.map} +0 -0
- /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
- /package/dist/{chunk-PKVBHGBM.js.map → chunk-CJIFGJQG.js.map} +0 -0
- /package/dist/{chunk-K3FXTC3I.js.map → chunk-HJACH5PU.js.map} +0 -0
- /package/dist/{chunk-GTPCOEOZ.js.map → chunk-IDMLXLLG.js.map} +0 -0
- /package/dist/{chunk-DKP56CSW.js.map → chunk-JKAYLDQV.js.map} +0 -0
- /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-SIDJO2T4.js.map} +0 -0
- /package/dist/{chunk-JR4IKCR2.js.map → chunk-TPND5MJS.js.map} +0 -0
- /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
- /package/dist/{chunk-DJC4CHLQ.js.map → chunk-YDWBXXQZ.js.map} +0 -0
- /package/dist/{chunk-6PHB5CJS.js.map → chunk-ZLFRB6FI.js.map} +0 -0
|
@@ -1,520 +1,530 @@
|
|
|
1
1
|
import {
|
|
2
2
|
memoryRetrievalBundle,
|
|
3
3
|
validateMemoryFragment
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
strictJsonCodec
|
|
7
|
-
} from "./chunk-4VLAQHZI.js";
|
|
4
|
+
} from "./chunk-E4QCH32M.js";
|
|
8
5
|
import {
|
|
9
6
|
depBatch,
|
|
10
7
|
depLatest
|
|
11
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-WQIA3GFB.js";
|
|
9
|
+
import {
|
|
10
|
+
strictJsonCodec
|
|
11
|
+
} from "./chunk-K7FB3JTD.js";
|
|
12
12
|
|
|
13
|
-
// src/solutions/agentic-memory.ts
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
query: opts.query
|
|
51
|
-
});
|
|
52
|
-
const sources = agenticMemoryProjection(
|
|
53
|
-
graph,
|
|
54
|
-
projection,
|
|
55
|
-
`${name}/sources`,
|
|
56
|
-
"agenticMemorySources",
|
|
57
|
-
(fact) => Object.freeze(
|
|
58
|
-
fact.fragments.map(
|
|
59
|
-
(fragment) => Object.freeze({
|
|
60
|
-
fragmentId: fragment.id,
|
|
61
|
-
...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
|
|
62
|
-
sources: Object.freeze([...fragment.sources]),
|
|
63
|
-
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
64
|
-
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
65
|
-
})
|
|
66
|
-
)
|
|
67
|
-
)
|
|
68
|
-
);
|
|
69
|
-
const context = agenticMemoryContextProjection(
|
|
70
|
-
graph,
|
|
71
|
-
projection,
|
|
72
|
-
retrieval.snapshot,
|
|
73
|
-
`${name}/context`
|
|
74
|
-
);
|
|
75
|
-
return {
|
|
76
|
-
input: { records: opts.records, query: opts.query },
|
|
77
|
-
projection,
|
|
78
|
-
retrieval,
|
|
79
|
-
retrievalSnapshot: retrieval.snapshot,
|
|
80
|
-
records: projectedRecords,
|
|
81
|
-
fragments: projectedFragments,
|
|
82
|
-
sources,
|
|
83
|
-
indexed: retrieval.indexed,
|
|
84
|
-
ranked: retrieval.ranked,
|
|
85
|
-
context,
|
|
86
|
-
status,
|
|
87
|
-
errors,
|
|
88
|
-
retrievalStatus: retrieval.status,
|
|
89
|
-
retrievalErrors: retrieval.errors,
|
|
90
|
-
cursor: retrieval.cursor
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
function agenticMemoryKgProjectionBundle(graph, opts) {
|
|
94
|
-
const name = opts.name ?? "agenticMemoryKgProjection";
|
|
95
|
-
const projection = graph.node(
|
|
96
|
-
[opts.records, opts.drafts],
|
|
97
|
-
(ctx) => {
|
|
98
|
-
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
99
|
-
state.evaluation += 1;
|
|
100
|
-
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
101
|
-
const draftProjection = validateAndProjectKgDrafts(
|
|
102
|
-
depLatest(ctx, 1),
|
|
103
|
-
recordProjection.records
|
|
104
|
-
);
|
|
105
|
-
const cursor = Object.freeze({
|
|
106
|
-
evaluation: state.evaluation,
|
|
107
|
-
validRecords: recordProjection.records.length,
|
|
108
|
-
validDrafts: draftProjection.assertions.length,
|
|
109
|
-
invalidDrafts: draftProjection.invalidDrafts,
|
|
110
|
-
projectedAssertions: draftProjection.assertions.length
|
|
13
|
+
// src/solutions/agentic-memory-shared.ts
|
|
14
|
+
function validateAndProjectRecords(value) {
|
|
15
|
+
const records = [];
|
|
16
|
+
const fragments = [];
|
|
17
|
+
const metadataByFragmentId = /* @__PURE__ */ Object.create(null);
|
|
18
|
+
const errors = [];
|
|
19
|
+
const invalidRecordIndexes = /* @__PURE__ */ new Set();
|
|
20
|
+
const seenRecordIds = /* @__PURE__ */ new Set();
|
|
21
|
+
const seenFragmentIds = /* @__PURE__ */ new Set();
|
|
22
|
+
if (!Array.isArray(value)) {
|
|
23
|
+
errors.push({
|
|
24
|
+
code: "invalid-records-input",
|
|
25
|
+
message: "agenticMemoryBundle: records input must be an array",
|
|
26
|
+
record: value
|
|
27
|
+
});
|
|
28
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
29
|
+
}
|
|
30
|
+
const length = safeArrayLength(value);
|
|
31
|
+
if (length === void 0) {
|
|
32
|
+
errors.push({
|
|
33
|
+
code: "invalid-records-input",
|
|
34
|
+
message: "agenticMemoryBundle: records input length could not be read",
|
|
35
|
+
record: value
|
|
36
|
+
});
|
|
37
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
38
|
+
}
|
|
39
|
+
for (let i = 0; i < length; i += 1) {
|
|
40
|
+
let raw;
|
|
41
|
+
try {
|
|
42
|
+
raw = value[i];
|
|
43
|
+
} catch (error) {
|
|
44
|
+
invalidRecordIndexes.add(i);
|
|
45
|
+
errors.push({
|
|
46
|
+
code: "invalid-record",
|
|
47
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
|
|
48
|
+
index: i,
|
|
49
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
111
50
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const result = validateAndSnapshotRecord(raw, i);
|
|
54
|
+
if (result.errors.length > 0) {
|
|
55
|
+
invalidRecordIndexes.add(i);
|
|
56
|
+
errors.push(...result.errors);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (result.record === void 0) continue;
|
|
60
|
+
if (seenRecordIds.has(result.record.id)) {
|
|
61
|
+
invalidRecordIndexes.add(i);
|
|
62
|
+
errors.push({
|
|
63
|
+
code: "duplicate-record-id",
|
|
64
|
+
message: "agenticMemoryBundle: duplicate record id",
|
|
65
|
+
index: i,
|
|
66
|
+
recordId: result.record.id,
|
|
67
|
+
record: raw,
|
|
68
|
+
validationErrors: [`duplicate record id '${result.record.id}'`]
|
|
120
69
|
});
|
|
121
|
-
|
|
122
|
-
ctx.down([
|
|
123
|
-
[
|
|
124
|
-
"DATA",
|
|
125
|
-
Object.freeze({
|
|
126
|
-
assertions: Object.freeze(draftProjection.assertions),
|
|
127
|
-
status,
|
|
128
|
-
errors,
|
|
129
|
-
cursor
|
|
130
|
-
})
|
|
131
|
-
]
|
|
132
|
-
]);
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: `${name}/projection`,
|
|
136
|
-
factory: "agenticMemoryKgProjection",
|
|
137
|
-
completeWhenDepsComplete: false,
|
|
138
|
-
errorWhenDepsError: false
|
|
70
|
+
continue;
|
|
139
71
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
158
|
-
errors: solutionProjection(
|
|
159
|
-
graph,
|
|
160
|
-
projection,
|
|
161
|
-
`${name}/errors`,
|
|
162
|
-
"agenticMemoryKgErrors",
|
|
163
|
-
(fact) => fact.errors
|
|
164
|
-
),
|
|
165
|
-
cursor: solutionProjection(
|
|
166
|
-
graph,
|
|
167
|
-
projection,
|
|
168
|
-
`${name}/cursor`,
|
|
169
|
-
"agenticMemoryKgCursor",
|
|
170
|
-
(fact) => fact.cursor
|
|
171
|
-
)
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function agenticMemoryRecordFrame(record) {
|
|
175
|
-
const result = validateAndSnapshotRecord(record, 0);
|
|
176
|
-
if (result.errors.length > 0 || result.record === void 0) {
|
|
177
|
-
throw new TypeError(
|
|
178
|
-
`agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
179
|
-
);
|
|
72
|
+
if (seenFragmentIds.has(result.record.fragment.id)) {
|
|
73
|
+
invalidRecordIndexes.add(i);
|
|
74
|
+
errors.push({
|
|
75
|
+
code: "duplicate-fragment-id",
|
|
76
|
+
message: "agenticMemoryBundle: duplicate fragment id",
|
|
77
|
+
index: i,
|
|
78
|
+
recordId: result.record.id,
|
|
79
|
+
fragmentId: result.record.fragment.id,
|
|
80
|
+
record: raw,
|
|
81
|
+
validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
|
|
82
|
+
});
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
seenRecordIds.add(result.record.id);
|
|
86
|
+
seenFragmentIds.add(result.record.fragment.id);
|
|
87
|
+
records.push(result.record);
|
|
88
|
+
fragments.push(result.record.fragment);
|
|
89
|
+
metadataByFragmentId[result.record.fragment.id] = recordMetadata(result.record);
|
|
180
90
|
}
|
|
181
|
-
|
|
182
|
-
assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
|
|
183
|
-
return Object.freeze({
|
|
184
|
-
format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
185
|
-
version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
186
|
-
record: Object.freeze({
|
|
187
|
-
id: result.record.id,
|
|
188
|
-
kind: result.record.kind,
|
|
189
|
-
persistenceLevel: result.record.persistenceLevel,
|
|
190
|
-
artifactKind: result.record.artifactKind,
|
|
191
|
-
...result.record.scope === void 0 ? {} : { scope: result.record.scope },
|
|
192
|
-
fragment: fragmentFrame(result.record.fragment)
|
|
193
|
-
})
|
|
194
|
-
});
|
|
91
|
+
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
195
92
|
}
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
93
|
+
function validateAndSnapshotRecord(value, index) {
|
|
94
|
+
try {
|
|
95
|
+
return validateAndSnapshotRecordInner(value, index);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
errors: [
|
|
99
|
+
{
|
|
100
|
+
code: "invalid-record",
|
|
101
|
+
message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
|
|
102
|
+
index,
|
|
103
|
+
record: value,
|
|
104
|
+
validationErrors: Object.freeze(["record access failed"])
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
};
|
|
203
108
|
}
|
|
204
|
-
|
|
205
|
-
|
|
109
|
+
}
|
|
110
|
+
function validateAndSnapshotRecordInner(value, index) {
|
|
111
|
+
const errors = [];
|
|
112
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
113
|
+
return {
|
|
114
|
+
errors: [
|
|
115
|
+
{
|
|
116
|
+
code: "invalid-record",
|
|
117
|
+
message: "agenticMemoryBundle: record must be an object",
|
|
118
|
+
index,
|
|
119
|
+
record: value
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
};
|
|
206
123
|
}
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
124
|
+
const record = value;
|
|
125
|
+
const recordId = typeof record.id === "string" ? record.id : void 0;
|
|
126
|
+
if (recordId === void 0 || recordId.length === 0) {
|
|
127
|
+
errors.push({
|
|
128
|
+
code: "invalid-record",
|
|
129
|
+
message: "agenticMemoryBundle: record.id must be a non-empty string",
|
|
130
|
+
index,
|
|
131
|
+
record: value,
|
|
132
|
+
validationErrors: ["record.id must be a non-empty string"]
|
|
133
|
+
});
|
|
210
134
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
135
|
+
if (!isAgenticMemoryKind(record.kind)) {
|
|
136
|
+
errors.push({
|
|
137
|
+
code: "invalid-record-kind",
|
|
138
|
+
message: "agenticMemoryBundle: record.kind is invalid",
|
|
139
|
+
index,
|
|
140
|
+
recordId,
|
|
141
|
+
record: value,
|
|
142
|
+
validationErrors: ["kind must be one of working, episodic, semantic, procedural, profile"]
|
|
143
|
+
});
|
|
219
144
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
"
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
145
|
+
if (!isAgenticMemoryPersistenceLevel(record.persistenceLevel)) {
|
|
146
|
+
errors.push({
|
|
147
|
+
code: "invalid-persistence-level",
|
|
148
|
+
message: "agenticMemoryBundle: record.persistenceLevel is invalid",
|
|
149
|
+
index,
|
|
150
|
+
recordId,
|
|
151
|
+
record: value,
|
|
152
|
+
validationErrors: [
|
|
153
|
+
"persistenceLevel must be one of turn, session, project, longTerm, permanent, archived"
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (!isAgenticMemoryArtifactKind(record.artifactKind)) {
|
|
158
|
+
errors.push({
|
|
159
|
+
code: "invalid-artifact-kind",
|
|
160
|
+
message: "agenticMemoryBundle: record.artifactKind is invalid",
|
|
161
|
+
index,
|
|
162
|
+
recordId,
|
|
163
|
+
record: value,
|
|
164
|
+
validationErrors: ["artifactKind must be one of raw, insight, profile, procedure"]
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
const scopeValidation = validateScope(record.scope);
|
|
168
|
+
if (!scopeValidation.ok) {
|
|
169
|
+
errors.push({
|
|
170
|
+
code: "invalid-scope",
|
|
171
|
+
message: "agenticMemoryBundle: record.scope is invalid",
|
|
172
|
+
index,
|
|
173
|
+
recordId,
|
|
174
|
+
record: value,
|
|
175
|
+
validationErrors: Object.freeze(scopeValidation.errors)
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const fragmentValidation = validateMemoryFragment(record.fragment);
|
|
179
|
+
if (!fragmentValidation.ok) {
|
|
180
|
+
errors.push({
|
|
181
|
+
code: "invalid-fragment",
|
|
182
|
+
message: "agenticMemoryBundle: record.fragment is invalid",
|
|
183
|
+
index,
|
|
184
|
+
recordId,
|
|
185
|
+
fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
|
|
186
|
+
record: value,
|
|
187
|
+
validationErrors: Object.freeze([...fragmentValidation.errors])
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const forbiddenFields = [
|
|
191
|
+
"storageTier",
|
|
192
|
+
"storageKey",
|
|
193
|
+
"adapter",
|
|
194
|
+
"collection",
|
|
195
|
+
"collections",
|
|
196
|
+
"ttl",
|
|
197
|
+
"ttlMs",
|
|
198
|
+
"ttlNs",
|
|
199
|
+
"expiresAt",
|
|
200
|
+
"timer",
|
|
201
|
+
"scheduler",
|
|
202
|
+
"schedule",
|
|
203
|
+
"retentionTimer",
|
|
204
|
+
"consolidationSchedule",
|
|
205
|
+
"reflectionSchedule",
|
|
206
|
+
"llm",
|
|
207
|
+
"llmHandle",
|
|
208
|
+
"tool",
|
|
209
|
+
"toolHandle",
|
|
210
|
+
"runner",
|
|
211
|
+
"runnerHandle",
|
|
212
|
+
"restore",
|
|
213
|
+
"hydrate",
|
|
214
|
+
"hydration",
|
|
215
|
+
"graphMutation",
|
|
216
|
+
"protocol"
|
|
217
|
+
];
|
|
218
|
+
const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
|
|
219
|
+
if (presentForbidden.length > 0) {
|
|
220
|
+
errors.push({
|
|
221
|
+
code: "invalid-record",
|
|
222
|
+
message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
|
|
223
|
+
index,
|
|
224
|
+
recordId,
|
|
225
|
+
record: value,
|
|
226
|
+
validationErrors: Object.freeze(
|
|
227
|
+
presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
|
|
228
|
+
)
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (errors.length > 0) return { errors };
|
|
232
|
+
const scope = scopeValidation.scope;
|
|
233
|
+
const fragment = snapshotFragment(record.fragment);
|
|
244
234
|
return {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
235
|
+
record: Object.freeze({
|
|
236
|
+
id: recordId,
|
|
237
|
+
kind: record.kind,
|
|
238
|
+
persistenceLevel: record.persistenceLevel,
|
|
239
|
+
artifactKind: record.artifactKind,
|
|
240
|
+
...scope === void 0 ? {} : { scope },
|
|
241
|
+
fragment
|
|
242
|
+
}),
|
|
243
|
+
errors
|
|
251
244
|
};
|
|
252
245
|
}
|
|
253
|
-
function
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
246
|
+
function snapshotFragment(fragment) {
|
|
247
|
+
return Object.freeze({
|
|
248
|
+
id: fragment.id,
|
|
249
|
+
payload: fragment.payload,
|
|
250
|
+
tNs: fragment.tNs,
|
|
251
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
|
|
252
|
+
...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
|
|
253
|
+
confidence: fragment.confidence,
|
|
254
|
+
tags: Object.freeze([...fragment.tags]),
|
|
255
|
+
sources: Object.freeze([...fragment.sources]),
|
|
256
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
257
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
258
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
259
|
+
});
|
|
263
260
|
}
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
});
|
|
282
|
-
const errors = Object.freeze(
|
|
283
|
-
[...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
|
|
284
|
-
(error) => freezeError({ ...error, cursor })
|
|
285
|
-
)
|
|
286
|
-
);
|
|
287
|
-
const status = Object.freeze({
|
|
288
|
-
state: agenticStatusState(errors.length, recordProjection.records.length),
|
|
289
|
-
cursor
|
|
290
|
-
});
|
|
291
|
-
ctx.state.set(state);
|
|
292
|
-
ctx.down([
|
|
293
|
-
[
|
|
294
|
-
"DATA",
|
|
295
|
-
Object.freeze({
|
|
296
|
-
activeRecords: Object.freeze(retention.activeRecords),
|
|
297
|
-
archivedRecords: Object.freeze(retention.archivedRecords),
|
|
298
|
-
consolidationRequests: Object.freeze(retention.consolidationRequests),
|
|
299
|
-
status,
|
|
300
|
-
errors,
|
|
301
|
-
cursor
|
|
302
|
-
})
|
|
303
|
-
]
|
|
304
|
-
]);
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
name: `${name}/projection`,
|
|
308
|
-
factory: "agenticMemoryRetention",
|
|
309
|
-
completeWhenDepsComplete: false,
|
|
310
|
-
errorWhenDepsError: false
|
|
261
|
+
function recordMetadata(record) {
|
|
262
|
+
return Object.freeze({
|
|
263
|
+
recordId: record.id,
|
|
264
|
+
kind: record.kind,
|
|
265
|
+
persistenceLevel: record.persistenceLevel,
|
|
266
|
+
artifactKind: record.artifactKind,
|
|
267
|
+
...record.scope === void 0 ? {} : { scope: record.scope }
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function validateRecordMetadata(value) {
|
|
271
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
272
|
+
if (!isPlainRecord(value)) {
|
|
273
|
+
return { ok: false, errors: ["record metadata must be an object when present"] };
|
|
274
|
+
}
|
|
275
|
+
const errors = [];
|
|
276
|
+
for (const key of Object.keys(value)) {
|
|
277
|
+
if (key !== "recordId" && key !== "kind" && key !== "persistenceLevel" && key !== "artifactKind" && key !== "scope") {
|
|
278
|
+
errors.push(`record.${key} is not part of AgenticMemoryRecordMetadata`);
|
|
311
279
|
}
|
|
312
|
-
|
|
280
|
+
}
|
|
281
|
+
if (!isNonEmptyString(value.recordId)) {
|
|
282
|
+
errors.push("record.recordId must be a non-empty string");
|
|
283
|
+
}
|
|
284
|
+
if (!isAgenticMemoryKind(value.kind)) {
|
|
285
|
+
errors.push("record.kind is invalid");
|
|
286
|
+
}
|
|
287
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
288
|
+
errors.push("record.persistenceLevel is invalid");
|
|
289
|
+
}
|
|
290
|
+
if (!isAgenticMemoryArtifactKind(value.artifactKind)) {
|
|
291
|
+
errors.push("record.artifactKind is invalid");
|
|
292
|
+
}
|
|
293
|
+
const scopeValidation = validateScope(value.scope);
|
|
294
|
+
if (!scopeValidation.ok) {
|
|
295
|
+
errors.push(...scopeValidation.errors.map((error) => `record.${error}`));
|
|
296
|
+
}
|
|
297
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
313
298
|
return {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
)
|
|
323
|
-
archivedRecords: solutionProjection(
|
|
324
|
-
graph,
|
|
325
|
-
projection,
|
|
326
|
-
`${name}/archivedRecords`,
|
|
327
|
-
"agenticMemoryRetentionArchivedRecords",
|
|
328
|
-
(fact) => fact.archivedRecords
|
|
329
|
-
),
|
|
330
|
-
consolidationRequests: solutionProjection(
|
|
331
|
-
graph,
|
|
332
|
-
projection,
|
|
333
|
-
`${name}/consolidationRequests`,
|
|
334
|
-
"agenticMemoryRetentionConsolidationRequests",
|
|
335
|
-
(fact) => fact.consolidationRequests
|
|
336
|
-
),
|
|
337
|
-
status: solutionProjection(
|
|
338
|
-
graph,
|
|
339
|
-
projection,
|
|
340
|
-
`${name}/status`,
|
|
341
|
-
"agenticMemoryRetentionStatus",
|
|
342
|
-
(fact) => fact.status
|
|
343
|
-
),
|
|
344
|
-
errors: solutionProjection(
|
|
345
|
-
graph,
|
|
346
|
-
projection,
|
|
347
|
-
`${name}/errors`,
|
|
348
|
-
"agenticMemoryRetentionErrors",
|
|
349
|
-
(fact) => fact.errors
|
|
350
|
-
),
|
|
351
|
-
cursor: solutionProjection(
|
|
352
|
-
graph,
|
|
353
|
-
projection,
|
|
354
|
-
`${name}/cursor`,
|
|
355
|
-
"agenticMemoryRetentionCursor",
|
|
356
|
-
(fact) => fact.cursor
|
|
357
|
-
)
|
|
299
|
+
ok: true,
|
|
300
|
+
errors,
|
|
301
|
+
metadata: Object.freeze({
|
|
302
|
+
recordId: value.recordId,
|
|
303
|
+
kind: value.kind,
|
|
304
|
+
persistenceLevel: value.persistenceLevel,
|
|
305
|
+
artifactKind: value.artifactKind,
|
|
306
|
+
...scopeValidation.scope === void 0 ? {} : { scope: scopeValidation.scope }
|
|
307
|
+
})
|
|
358
308
|
};
|
|
359
309
|
}
|
|
360
|
-
function
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
});
|
|
393
|
-
ctx.state.set(state);
|
|
394
|
-
ctx.down([
|
|
395
|
-
[
|
|
396
|
-
"DATA",
|
|
397
|
-
Object.freeze({
|
|
398
|
-
results: Object.freeze(outcomes.results),
|
|
399
|
-
proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
|
|
400
|
-
commands: Object.freeze(outcomes.commands),
|
|
401
|
-
status,
|
|
402
|
-
errors,
|
|
403
|
-
cursor
|
|
404
|
-
})
|
|
405
|
-
]
|
|
406
|
-
]);
|
|
407
|
-
},
|
|
408
|
-
{
|
|
409
|
-
name: `${name}/projection`,
|
|
410
|
-
factory: "agenticMemoryConsolidation",
|
|
411
|
-
completeWhenDepsComplete: false,
|
|
412
|
-
errorWhenDepsError: false
|
|
310
|
+
function contextState(projection, retrieval) {
|
|
311
|
+
if (projection === "error" || retrieval === "error") return "error";
|
|
312
|
+
if (projection === "partial" || retrieval === "partial") return "partial";
|
|
313
|
+
return retrieval;
|
|
314
|
+
}
|
|
315
|
+
function agenticStatusState(errorCount, validRecords) {
|
|
316
|
+
if (errorCount > 0 && validRecords === 0) return "error";
|
|
317
|
+
if (errorCount > 0) return "partial";
|
|
318
|
+
return validRecords > 0 ? "ready" : "empty";
|
|
319
|
+
}
|
|
320
|
+
function isAgenticMemoryKind(value) {
|
|
321
|
+
return value === "working" || value === "episodic" || value === "semantic" || value === "procedural" || value === "profile";
|
|
322
|
+
}
|
|
323
|
+
function isAgenticMemoryPersistenceLevel(value) {
|
|
324
|
+
return value === "turn" || value === "session" || value === "project" || value === "longTerm" || value === "permanent" || value === "archived";
|
|
325
|
+
}
|
|
326
|
+
function isAgenticMemoryArtifactKind(value) {
|
|
327
|
+
return value === "raw" || value === "insight" || value === "profile" || value === "procedure";
|
|
328
|
+
}
|
|
329
|
+
function validateScope(value) {
|
|
330
|
+
if (value === void 0) return { ok: true, errors: [] };
|
|
331
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
332
|
+
return { ok: false, errors: ["scope must be an object when present"] };
|
|
333
|
+
}
|
|
334
|
+
const scope = value;
|
|
335
|
+
const errors = [];
|
|
336
|
+
const allowed = /* @__PURE__ */ new Set(["sessionId", "projectId", "userId", "tenantId"]);
|
|
337
|
+
for (const key of Object.keys(scope)) {
|
|
338
|
+
if (!allowed.has(key)) errors.push(`scope.${key} is not part of AgenticMemoryScope`);
|
|
339
|
+
}
|
|
340
|
+
for (const key of allowed) {
|
|
341
|
+
if (scope[key] !== void 0 && (typeof scope[key] !== "string" || scope[key].length === 0)) {
|
|
342
|
+
errors.push(`scope.${key} must be a non-empty string when present`);
|
|
413
343
|
}
|
|
414
|
-
|
|
344
|
+
}
|
|
345
|
+
if (errors.length > 0) return { ok: false, errors };
|
|
415
346
|
return {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
),
|
|
425
|
-
proposedRecordDrafts: solutionProjection(
|
|
426
|
-
graph,
|
|
427
|
-
projection,
|
|
428
|
-
`${name}/proposedRecordDrafts`,
|
|
429
|
-
"agenticMemoryConsolidationRecordDrafts",
|
|
430
|
-
(fact) => fact.proposedRecordDrafts
|
|
431
|
-
),
|
|
432
|
-
commands: solutionProjection(
|
|
433
|
-
graph,
|
|
434
|
-
projection,
|
|
435
|
-
`${name}/commands`,
|
|
436
|
-
"agenticMemoryConsolidationCommands",
|
|
437
|
-
(fact) => fact.commands
|
|
438
|
-
),
|
|
439
|
-
status: solutionProjection(
|
|
440
|
-
graph,
|
|
441
|
-
projection,
|
|
442
|
-
`${name}/status`,
|
|
443
|
-
"agenticMemoryConsolidationStatus",
|
|
444
|
-
(fact) => fact.status
|
|
445
|
-
),
|
|
446
|
-
errors: solutionProjection(
|
|
447
|
-
graph,
|
|
448
|
-
projection,
|
|
449
|
-
`${name}/errors`,
|
|
450
|
-
"agenticMemoryConsolidationErrors",
|
|
451
|
-
(fact) => fact.errors
|
|
452
|
-
),
|
|
453
|
-
cursor: solutionProjection(
|
|
454
|
-
graph,
|
|
455
|
-
projection,
|
|
456
|
-
`${name}/cursor`,
|
|
457
|
-
"agenticMemoryConsolidationCursor",
|
|
458
|
-
(fact) => fact.cursor
|
|
459
|
-
)
|
|
347
|
+
ok: true,
|
|
348
|
+
errors,
|
|
349
|
+
scope: Object.freeze({
|
|
350
|
+
...scope.sessionId === void 0 ? {} : { sessionId: scope.sessionId },
|
|
351
|
+
...scope.projectId === void 0 ? {} : { projectId: scope.projectId },
|
|
352
|
+
...scope.userId === void 0 ? {} : { userId: scope.userId },
|
|
353
|
+
...scope.tenantId === void 0 ? {} : { tenantId: scope.tenantId }
|
|
354
|
+
})
|
|
460
355
|
};
|
|
461
356
|
}
|
|
462
|
-
function
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
357
|
+
function isPlainRecord(value) {
|
|
358
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
359
|
+
}
|
|
360
|
+
function ownKeys(value) {
|
|
361
|
+
return Object.keys(value).sort();
|
|
362
|
+
}
|
|
363
|
+
function assertExactKeys(value, expected, label) {
|
|
364
|
+
const actual = ownKeys(value);
|
|
365
|
+
const want = [...expected].sort();
|
|
366
|
+
if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
|
|
367
|
+
throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function assertAgenticMemoryRecordCodecShape(value) {
|
|
371
|
+
if (!isPlainRecord(value)) {
|
|
372
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
373
|
+
}
|
|
374
|
+
assertNoSymbolKeys(value, "agenticMemoryRecordFrame.record");
|
|
375
|
+
assertExactKeys(
|
|
376
|
+
value,
|
|
377
|
+
value.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
378
|
+
"agenticMemoryRecordFrame.record"
|
|
484
379
|
);
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
"
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
380
|
+
const fragment = value.fragment;
|
|
381
|
+
if (!isPlainRecord(fragment)) {
|
|
382
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
383
|
+
}
|
|
384
|
+
assertNoSymbolKeys(fragment, "agenticMemoryRecordFrame.record.fragment");
|
|
385
|
+
assertExactKeys(
|
|
386
|
+
fragment,
|
|
387
|
+
[
|
|
388
|
+
"id",
|
|
389
|
+
"payload",
|
|
390
|
+
"tNs",
|
|
391
|
+
...fragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
392
|
+
...fragment.validTo === void 0 ? [] : ["validTo"],
|
|
393
|
+
"confidence",
|
|
394
|
+
"tags",
|
|
395
|
+
"sources",
|
|
396
|
+
...fragment.embedding === void 0 ? [] : ["embedding"],
|
|
397
|
+
...fragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
398
|
+
...fragment.provenance === void 0 ? [] : ["provenance"]
|
|
399
|
+
],
|
|
400
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
401
|
+
);
|
|
402
|
+
assertStrictJsonValue(fragment.tags, "record.fragment.tags");
|
|
403
|
+
assertStrictJsonValue(fragment.sources, "record.fragment.sources");
|
|
404
|
+
if (fragment.embedding !== void 0) {
|
|
405
|
+
assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
|
|
406
|
+
}
|
|
407
|
+
if (value.scope !== void 0) assertScopeFrame(value.scope);
|
|
408
|
+
}
|
|
409
|
+
function assertNoSymbolKeys(value, label) {
|
|
410
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
411
|
+
throw new TypeError(`${label}: unexpected symbol fields`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function decimalBigIntString(value, label) {
|
|
415
|
+
const out = value.toString(10);
|
|
416
|
+
if (!/^-?(0|[1-9]\d*)$/.test(out)) {
|
|
417
|
+
throw new TypeError(`${label} must encode as a canonical decimal bigint string`);
|
|
418
|
+
}
|
|
419
|
+
return out;
|
|
420
|
+
}
|
|
421
|
+
function parseDecimalBigInt(value, label) {
|
|
422
|
+
if (typeof value !== "string" || !/^(0|-?[1-9]\d*)$/.test(value)) {
|
|
423
|
+
throw new TypeError(`${label} must be a canonical decimal bigint string`);
|
|
424
|
+
}
|
|
425
|
+
return BigInt(value);
|
|
426
|
+
}
|
|
427
|
+
function assertStrictJsonValue(value, label) {
|
|
428
|
+
try {
|
|
429
|
+
strictJsonCodec.encode(value);
|
|
430
|
+
return value;
|
|
431
|
+
} catch (error) {
|
|
432
|
+
throw new TypeError(`${label} must be strict JSON: ${errorMessage(error)}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
function assertScopeFrame(value) {
|
|
436
|
+
if (!isPlainRecord(value)) {
|
|
437
|
+
throw new TypeError("agenticMemoryRecordFrame: scope must be an object when present");
|
|
438
|
+
}
|
|
439
|
+
assertStrictJsonValue(value, "record.scope");
|
|
440
|
+
const validation = validateScope(value);
|
|
441
|
+
if (!validation.ok || validation.scope === void 0) {
|
|
442
|
+
throw new TypeError(`agenticMemoryRecordFrame: invalid scope: ${validation.errors.join("; ")}`);
|
|
443
|
+
}
|
|
444
|
+
assertExactKeys(
|
|
445
|
+
value,
|
|
446
|
+
[
|
|
447
|
+
...value.sessionId === void 0 ? [] : ["sessionId"],
|
|
448
|
+
...value.projectId === void 0 ? [] : ["projectId"],
|
|
449
|
+
...value.userId === void 0 ? [] : ["userId"],
|
|
450
|
+
...value.tenantId === void 0 ? [] : ["tenantId"]
|
|
451
|
+
],
|
|
452
|
+
"agenticMemoryRecordFrame.record.scope"
|
|
453
|
+
);
|
|
454
|
+
return validation.scope;
|
|
455
|
+
}
|
|
456
|
+
function assertKindValue(value) {
|
|
457
|
+
if (!isAgenticMemoryKind(value)) {
|
|
458
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid memory kind");
|
|
459
|
+
}
|
|
460
|
+
return value;
|
|
461
|
+
}
|
|
462
|
+
function assertPersistenceLevelValue(value) {
|
|
463
|
+
if (!isAgenticMemoryPersistenceLevel(value)) {
|
|
464
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid persistence level");
|
|
465
|
+
}
|
|
466
|
+
return value;
|
|
467
|
+
}
|
|
468
|
+
function assertArtifactKindValue(value) {
|
|
469
|
+
if (!isAgenticMemoryArtifactKind(value)) {
|
|
470
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid artifact kind");
|
|
471
|
+
}
|
|
472
|
+
return value;
|
|
473
|
+
}
|
|
474
|
+
function assertNonEmptyString(value, label) {
|
|
475
|
+
if (!isNonEmptyString(value)) throw new TypeError(`${label} must be a non-empty string`);
|
|
476
|
+
return value;
|
|
477
|
+
}
|
|
478
|
+
function assertString(value, label) {
|
|
479
|
+
if (typeof value !== "string") throw new TypeError(`${label} must be a string`);
|
|
480
|
+
return value;
|
|
481
|
+
}
|
|
482
|
+
function assertConfidence(value, label) {
|
|
483
|
+
if (!Number.isFinite(value) || value < 0 || value > 1) {
|
|
484
|
+
throw new TypeError(`${label} must be a finite number in [0, 1]`);
|
|
485
|
+
}
|
|
486
|
+
return value;
|
|
487
|
+
}
|
|
488
|
+
function assertStringArray(value, label) {
|
|
489
|
+
if (!isDenseArrayOf(value, (item) => typeof item === "string")) {
|
|
490
|
+
throw new TypeError(`${label} must be a readonly string array`);
|
|
491
|
+
}
|
|
492
|
+
return Object.freeze([...value]);
|
|
493
|
+
}
|
|
494
|
+
function assertFiniteNumberArray(value, label) {
|
|
495
|
+
if (!isDenseArrayOf(value, (item) => Number.isFinite(item))) {
|
|
496
|
+
throw new TypeError(`${label} must be a finite number array`);
|
|
497
|
+
}
|
|
498
|
+
return Object.freeze([...value]);
|
|
499
|
+
}
|
|
500
|
+
function isNonEmptyString(value) {
|
|
501
|
+
return typeof value === "string" && value.length > 0;
|
|
502
|
+
}
|
|
503
|
+
function isDenseArrayOf(value, predicate) {
|
|
504
|
+
if (!Array.isArray(value)) return false;
|
|
505
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
506
|
+
if (!Object.hasOwn(value, i) || !predicate(value[i])) return false;
|
|
507
|
+
}
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
function freezeError(error) {
|
|
511
|
+
return Object.freeze({
|
|
512
|
+
...error,
|
|
513
|
+
...error.validationErrors === void 0 ? {} : { validationErrors: Object.freeze([...error.validationErrors]) }
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
function safeArrayLength(value) {
|
|
517
|
+
try {
|
|
518
|
+
return value.length;
|
|
519
|
+
} catch {
|
|
520
|
+
return void 0;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function errorMessage(error) {
|
|
524
|
+
return error instanceof Error ? error.message : String(error);
|
|
517
525
|
}
|
|
526
|
+
|
|
527
|
+
// src/solutions/agentic-memory-projection.ts
|
|
518
528
|
function solutionProjection(graph, snapshot, name, factory, select) {
|
|
519
529
|
return graph.node(
|
|
520
530
|
[snapshot],
|
|
@@ -642,569 +652,187 @@ function agenticMemoryRecordProjection(graph, records, name) {
|
|
|
642
652
|
}
|
|
643
653
|
);
|
|
644
654
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
raw = value[i];
|
|
683
|
-
const result = validateKgDraft(raw, i);
|
|
684
|
-
if (result.errors.length > 0 || result.draft === void 0) {
|
|
685
|
-
invalidDrafts += 1;
|
|
686
|
-
errors.push(...result.errors);
|
|
687
|
-
continue;
|
|
688
|
-
}
|
|
689
|
-
const draft = result.draft;
|
|
690
|
-
if (seenAssertions.has(draft.id)) {
|
|
691
|
-
invalidDrafts += 1;
|
|
692
|
-
errors.push({
|
|
693
|
-
code: "duplicate-assertion-id",
|
|
694
|
-
message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
|
|
695
|
-
index: i,
|
|
696
|
-
assertionId: draft.id,
|
|
697
|
-
recordId: draft.recordId,
|
|
698
|
-
fragmentId: draft.fragmentId,
|
|
699
|
-
draft: raw,
|
|
700
|
-
validationErrors: [`duplicate assertion id '${draft.id}'`]
|
|
701
|
-
});
|
|
702
|
-
continue;
|
|
703
|
-
}
|
|
704
|
-
const record = recordById.get(draft.recordId);
|
|
705
|
-
if (record === void 0) {
|
|
706
|
-
invalidDrafts += 1;
|
|
707
|
-
errors.push({
|
|
708
|
-
code: "missing-record-ref",
|
|
709
|
-
message: "agenticMemoryKgProjectionBundle: draft references a missing record",
|
|
710
|
-
index: i,
|
|
711
|
-
assertionId: draft.id,
|
|
712
|
-
recordId: draft.recordId,
|
|
713
|
-
fragmentId: draft.fragmentId,
|
|
714
|
-
draft: raw,
|
|
715
|
-
validationErrors: [`record '${draft.recordId}' is not projected`]
|
|
716
|
-
});
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
const owner = fragmentToRecord.get(draft.fragmentId);
|
|
720
|
-
if (owner === void 0) {
|
|
721
|
-
invalidDrafts += 1;
|
|
722
|
-
errors.push({
|
|
723
|
-
code: "missing-fragment-ref",
|
|
724
|
-
message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
|
|
725
|
-
index: i,
|
|
726
|
-
assertionId: draft.id,
|
|
727
|
-
recordId: draft.recordId,
|
|
728
|
-
fragmentId: draft.fragmentId,
|
|
729
|
-
draft: raw,
|
|
730
|
-
validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
|
|
731
|
-
});
|
|
732
|
-
continue;
|
|
733
|
-
}
|
|
734
|
-
if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
|
|
735
|
-
invalidDrafts += 1;
|
|
736
|
-
errors.push({
|
|
737
|
-
code: "fragment-record-mismatch",
|
|
738
|
-
message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
|
|
739
|
-
index: i,
|
|
740
|
-
assertionId: draft.id,
|
|
741
|
-
recordId: draft.recordId,
|
|
742
|
-
fragmentId: draft.fragmentId,
|
|
743
|
-
draft: raw,
|
|
744
|
-
validationErrors: [
|
|
745
|
-
`fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
|
|
746
|
-
]
|
|
747
|
-
});
|
|
748
|
-
continue;
|
|
749
|
-
}
|
|
750
|
-
seenAssertions.add(draft.id);
|
|
751
|
-
assertions.push(
|
|
752
|
-
Object.freeze({
|
|
753
|
-
id: draft.id,
|
|
754
|
-
recordId: draft.recordId,
|
|
755
|
-
fragmentId: draft.fragmentId,
|
|
756
|
-
subject: draft.subject,
|
|
757
|
-
predicate: draft.predicate,
|
|
758
|
-
object: draft.object,
|
|
759
|
-
...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
|
|
760
|
-
sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
|
|
761
|
-
...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
|
|
762
|
-
})
|
|
763
|
-
);
|
|
764
|
-
} catch (error) {
|
|
765
|
-
invalidDrafts += 1;
|
|
766
|
-
errors.push({
|
|
767
|
-
code: "invalid-draft",
|
|
768
|
-
message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage(error)}`,
|
|
769
|
-
index: i,
|
|
770
|
-
draft: raw,
|
|
771
|
-
validationErrors: ["draft access failed"]
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
return { assertions, errors, invalidDrafts };
|
|
776
|
-
}
|
|
777
|
-
function validateKgDraft(value, index) {
|
|
778
|
-
const errors = [];
|
|
779
|
-
if (!isPlainRecord(value)) {
|
|
780
|
-
return {
|
|
781
|
-
errors: [
|
|
782
|
-
{
|
|
783
|
-
code: "invalid-draft",
|
|
784
|
-
message: "agenticMemoryKgProjectionBundle: draft must be an object",
|
|
785
|
-
index,
|
|
786
|
-
draft: value
|
|
787
|
-
}
|
|
788
|
-
]
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
const raw = value;
|
|
792
|
-
const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
|
|
793
|
-
const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
|
|
794
|
-
const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
|
|
795
|
-
const subject = validateAssertionSubject(raw.subject);
|
|
796
|
-
const object = validateAssertionObject(raw.object);
|
|
797
|
-
const shapeErrors = [];
|
|
798
|
-
if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
|
|
799
|
-
if (recordId === void 0) {
|
|
800
|
-
shapeErrors.push("draft.recordId must be a non-empty string");
|
|
801
|
-
}
|
|
802
|
-
if (fragmentId === void 0) {
|
|
803
|
-
shapeErrors.push("draft.fragmentId must be a non-empty string");
|
|
804
|
-
}
|
|
805
|
-
shapeErrors.push(...subject.errors);
|
|
806
|
-
if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
|
|
807
|
-
shapeErrors.push("draft.predicate must be a non-empty string");
|
|
808
|
-
}
|
|
809
|
-
shapeErrors.push(...object.errors);
|
|
810
|
-
if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
|
|
811
|
-
shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
|
|
812
|
-
}
|
|
813
|
-
if (raw.sources !== void 0 && !isDenseArrayOf(raw.sources, isNonEmptyString)) {
|
|
814
|
-
shapeErrors.push("draft.sources must be a readonly string array");
|
|
815
|
-
}
|
|
816
|
-
if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
|
|
817
|
-
shapeErrors.push("draft.provenance must be a string when present");
|
|
818
|
-
}
|
|
819
|
-
if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
|
|
820
|
-
if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
|
|
821
|
-
return { errors };
|
|
822
|
-
}
|
|
823
|
-
return {
|
|
824
|
-
draft: Object.freeze({
|
|
825
|
-
id,
|
|
826
|
-
recordId,
|
|
827
|
-
fragmentId,
|
|
828
|
-
subject: subject.subject,
|
|
829
|
-
predicate: raw.predicate,
|
|
830
|
-
object: object.object,
|
|
831
|
-
...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
|
|
832
|
-
...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
|
|
833
|
-
...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
|
|
834
|
-
}),
|
|
835
|
-
errors
|
|
836
|
-
};
|
|
837
|
-
}
|
|
838
|
-
function validateAssertionSubject(value) {
|
|
839
|
-
if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
|
|
840
|
-
const id = value.id;
|
|
841
|
-
const type = value.type;
|
|
842
|
-
const errors = [];
|
|
843
|
-
if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
|
|
844
|
-
if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
|
|
845
|
-
errors.push("subject.type must be a non-empty string when present");
|
|
846
|
-
}
|
|
847
|
-
if (errors.length > 0) return { errors };
|
|
848
|
-
return {
|
|
849
|
-
subject: Object.freeze({
|
|
850
|
-
id,
|
|
851
|
-
...type === void 0 ? {} : { type }
|
|
852
|
-
}),
|
|
853
|
-
errors
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
function validateAssertionObject(value) {
|
|
857
|
-
if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
|
|
858
|
-
const kind = value.kind;
|
|
859
|
-
const errors = [];
|
|
860
|
-
if (kind === "entity") {
|
|
861
|
-
if (typeof value.id !== "string" || value.id.length === 0) {
|
|
862
|
-
errors.push("object.id must be non-empty for entity objects");
|
|
863
|
-
}
|
|
864
|
-
if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
|
|
865
|
-
errors.push("object.type must be a non-empty string when present");
|
|
866
|
-
}
|
|
867
|
-
if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
|
|
868
|
-
if (errors.length > 0) return { errors };
|
|
869
|
-
return {
|
|
870
|
-
object: Object.freeze({
|
|
871
|
-
kind: "entity",
|
|
872
|
-
id: value.id,
|
|
873
|
-
...value.type === void 0 ? {} : { type: value.type }
|
|
874
|
-
}),
|
|
875
|
-
errors
|
|
876
|
-
};
|
|
877
|
-
}
|
|
878
|
-
if (kind === "value") {
|
|
879
|
-
if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
|
|
880
|
-
else {
|
|
881
|
-
try {
|
|
882
|
-
assertStrictJsonValue(value.value, "object.value");
|
|
883
|
-
} catch (error) {
|
|
884
|
-
errors.push(errorMessage(error));
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
|
|
888
|
-
errors.push("object.valueType must be a non-empty string when present");
|
|
889
|
-
}
|
|
890
|
-
if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
|
|
891
|
-
if (errors.length > 0) return { errors };
|
|
892
|
-
return {
|
|
893
|
-
object: Object.freeze({
|
|
894
|
-
kind: "value",
|
|
895
|
-
value: value.value,
|
|
896
|
-
...value.valueType === void 0 ? {} : { valueType: value.valueType }
|
|
897
|
-
}),
|
|
898
|
-
errors
|
|
899
|
-
};
|
|
900
|
-
}
|
|
901
|
-
return { errors: ["object.kind must be entity or value"] };
|
|
902
|
-
}
|
|
903
|
-
function kgShapeError(index, draft, ...validationErrors) {
|
|
904
|
-
return {
|
|
905
|
-
code: "invalid-assertion-shape",
|
|
906
|
-
message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
|
|
907
|
-
index,
|
|
908
|
-
draft,
|
|
909
|
-
validationErrors: Object.freeze([...validationErrors])
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
function kgErrorFromRecordError(error) {
|
|
913
|
-
return {
|
|
914
|
-
...error,
|
|
915
|
-
code: error.code
|
|
916
|
-
};
|
|
917
|
-
}
|
|
918
|
-
function fragmentFrame(fragment) {
|
|
919
|
-
return Object.freeze({
|
|
920
|
-
id: fragment.id,
|
|
921
|
-
payload: fragment.payload,
|
|
922
|
-
tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
|
|
923
|
-
...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
|
|
924
|
-
...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
|
|
925
|
-
confidence: fragment.confidence,
|
|
926
|
-
tags: Object.freeze([...fragment.tags]),
|
|
927
|
-
sources: Object.freeze([...fragment.sources]),
|
|
928
|
-
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
929
|
-
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
930
|
-
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
655
|
+
|
|
656
|
+
// src/solutions/agentic-memory-bundle.ts
|
|
657
|
+
function agenticMemoryBundle(graph, opts) {
|
|
658
|
+
const name = opts.name ?? "agenticMemory";
|
|
659
|
+
const projection = agenticMemoryRecordProjection(graph, opts.records, `${name}/projection`);
|
|
660
|
+
const projectedRecords = agenticMemoryProjection(
|
|
661
|
+
graph,
|
|
662
|
+
projection,
|
|
663
|
+
`${name}/records`,
|
|
664
|
+
"agenticMemoryRecords",
|
|
665
|
+
(fact) => fact.records
|
|
666
|
+
);
|
|
667
|
+
const projectedFragments = agenticMemoryProjection(
|
|
668
|
+
graph,
|
|
669
|
+
projection,
|
|
670
|
+
`${name}/fragments`,
|
|
671
|
+
"agenticMemoryFragments",
|
|
672
|
+
(fact) => fact.fragments
|
|
673
|
+
);
|
|
674
|
+
const status = agenticMemoryProjection(
|
|
675
|
+
graph,
|
|
676
|
+
projection,
|
|
677
|
+
`${name}/status`,
|
|
678
|
+
"agenticMemoryStatus",
|
|
679
|
+
(fact) => fact.status
|
|
680
|
+
);
|
|
681
|
+
const errors = agenticMemoryProjection(
|
|
682
|
+
graph,
|
|
683
|
+
projection,
|
|
684
|
+
`${name}/errors`,
|
|
685
|
+
"agenticMemoryErrors",
|
|
686
|
+
(fact) => fact.errors
|
|
687
|
+
);
|
|
688
|
+
const retrieval = memoryRetrievalBundle(graph, {
|
|
689
|
+
name: `${name}/retrieval`,
|
|
690
|
+
fragments: projectedFragments,
|
|
691
|
+
query: opts.query
|
|
931
692
|
});
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
}
|
|
956
|
-
};
|
|
957
|
-
const result = validateAndSnapshotRecord(record, 0);
|
|
958
|
-
if (result.errors.length > 0 || result.record === void 0) {
|
|
959
|
-
throw new TypeError(
|
|
960
|
-
`agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
961
|
-
);
|
|
962
|
-
}
|
|
963
|
-
return result.record;
|
|
964
|
-
}
|
|
965
|
-
function projectRetention(value, records) {
|
|
966
|
-
const byId = new Map(records.map((record) => [record.id, record]));
|
|
967
|
-
const view = new Map(records.map((record) => [record.id, record]));
|
|
968
|
-
const requests = [];
|
|
969
|
-
const errors = [];
|
|
970
|
-
let validCommands = 0;
|
|
971
|
-
let invalidCommands = 0;
|
|
972
|
-
if (!Array.isArray(value)) {
|
|
973
|
-
return {
|
|
974
|
-
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
975
|
-
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
976
|
-
consolidationRequests: requests,
|
|
977
|
-
validCommands,
|
|
978
|
-
invalidCommands: 1,
|
|
979
|
-
errors: [
|
|
980
|
-
{
|
|
981
|
-
code: "invalid-commands-input",
|
|
982
|
-
message: "agenticMemoryRetentionBundle: commands input must be an array",
|
|
983
|
-
command: value
|
|
984
|
-
}
|
|
985
|
-
]
|
|
986
|
-
};
|
|
987
|
-
}
|
|
988
|
-
const length = safeArrayLength(value);
|
|
989
|
-
if (length === void 0) {
|
|
990
|
-
return {
|
|
991
|
-
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
992
|
-
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
993
|
-
consolidationRequests: requests,
|
|
994
|
-
validCommands,
|
|
995
|
-
invalidCommands: 1,
|
|
996
|
-
errors: [
|
|
997
|
-
{
|
|
998
|
-
code: "invalid-commands-input",
|
|
999
|
-
message: "agenticMemoryRetentionBundle: commands input length could not be read",
|
|
1000
|
-
command: value
|
|
1001
|
-
}
|
|
1002
|
-
]
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
const seenCommands = /* @__PURE__ */ new Set();
|
|
1006
|
-
for (let i = 0; i < length; i += 1) {
|
|
1007
|
-
let raw;
|
|
1008
|
-
try {
|
|
1009
|
-
raw = value[i];
|
|
1010
|
-
const result = validateRetentionCommand(raw, i);
|
|
1011
|
-
if (result.errors.length > 0 || result.command === void 0) {
|
|
1012
|
-
invalidCommands += 1;
|
|
1013
|
-
errors.push(...result.errors);
|
|
1014
|
-
continue;
|
|
1015
|
-
}
|
|
1016
|
-
const command = result.command;
|
|
1017
|
-
if (seenCommands.has(command.id)) {
|
|
1018
|
-
invalidCommands += 1;
|
|
1019
|
-
errors.push({
|
|
1020
|
-
code: "duplicate-command-id",
|
|
1021
|
-
message: "agenticMemoryRetentionBundle: duplicate command id",
|
|
1022
|
-
index: i,
|
|
1023
|
-
commandId: command.id,
|
|
1024
|
-
command: raw,
|
|
1025
|
-
validationErrors: [`duplicate command id '${command.id}'`]
|
|
1026
|
-
});
|
|
1027
|
-
continue;
|
|
1028
|
-
}
|
|
1029
|
-
const missing = retentionMissingRecords(command, byId);
|
|
1030
|
-
if (missing.length > 0) {
|
|
1031
|
-
invalidCommands += 1;
|
|
1032
|
-
errors.push({
|
|
1033
|
-
code: "missing-record-ref",
|
|
1034
|
-
message: "agenticMemoryRetentionBundle: command references missing records",
|
|
1035
|
-
index: i,
|
|
1036
|
-
commandId: command.id,
|
|
1037
|
-
recordId: "recordId" in command ? command.recordId : void 0,
|
|
1038
|
-
recordIds: Object.freeze(missing),
|
|
1039
|
-
command: raw,
|
|
1040
|
-
validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
|
|
1041
|
-
});
|
|
1042
|
-
continue;
|
|
1043
|
-
}
|
|
1044
|
-
seenCommands.add(command.id);
|
|
1045
|
-
validCommands += 1;
|
|
1046
|
-
applyRetentionCommand(command, byId, view, requests);
|
|
1047
|
-
} catch (error) {
|
|
1048
|
-
invalidCommands += 1;
|
|
1049
|
-
errors.push({
|
|
1050
|
-
code: "invalid-command",
|
|
1051
|
-
message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage(error)}`,
|
|
1052
|
-
index: i,
|
|
1053
|
-
command: raw,
|
|
1054
|
-
validationErrors: ["command access failed"]
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
const projected = records.map((record) => view.get(record.id) ?? record);
|
|
693
|
+
const sources = agenticMemoryProjection(
|
|
694
|
+
graph,
|
|
695
|
+
projection,
|
|
696
|
+
`${name}/sources`,
|
|
697
|
+
"agenticMemorySources",
|
|
698
|
+
(fact) => Object.freeze(
|
|
699
|
+
fact.fragments.map(
|
|
700
|
+
(fragment) => Object.freeze({
|
|
701
|
+
fragmentId: fragment.id,
|
|
702
|
+
...fact.metadataByFragmentId[fragment.id] === void 0 ? {} : { record: fact.metadataByFragmentId[fragment.id] },
|
|
703
|
+
sources: Object.freeze([...fragment.sources]),
|
|
704
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
705
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
706
|
+
})
|
|
707
|
+
)
|
|
708
|
+
)
|
|
709
|
+
);
|
|
710
|
+
const context = agenticMemoryContextProjection(
|
|
711
|
+
graph,
|
|
712
|
+
projection,
|
|
713
|
+
retrieval.snapshot,
|
|
714
|
+
`${name}/context`
|
|
715
|
+
);
|
|
1059
716
|
return {
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
717
|
+
input: { records: opts.records, query: opts.query },
|
|
718
|
+
projection,
|
|
719
|
+
retrieval,
|
|
720
|
+
retrievalSnapshot: retrieval.snapshot,
|
|
721
|
+
records: projectedRecords,
|
|
722
|
+
fragments: projectedFragments,
|
|
723
|
+
sources,
|
|
724
|
+
indexed: retrieval.indexed,
|
|
725
|
+
ranked: retrieval.ranked,
|
|
726
|
+
context,
|
|
727
|
+
status,
|
|
1063
728
|
errors,
|
|
1064
|
-
|
|
1065
|
-
|
|
729
|
+
retrievalStatus: retrieval.status,
|
|
730
|
+
retrievalErrors: retrieval.errors,
|
|
731
|
+
cursor: retrieval.cursor
|
|
1066
732
|
};
|
|
1067
733
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
734
|
+
|
|
735
|
+
// src/solutions/agentic-memory-consolidation.ts
|
|
736
|
+
function agenticMemoryConsolidationBundle(graph, opts) {
|
|
737
|
+
const name = opts.name ?? "agenticMemoryConsolidation";
|
|
738
|
+
const projection = graph.node(
|
|
739
|
+
[opts.records, opts.requests, opts.outcomes],
|
|
740
|
+
(ctx) => {
|
|
741
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
742
|
+
state.evaluation += 1;
|
|
743
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
744
|
+
const requests = validateConsolidationRequests(depLatest(ctx, 1), recordProjection.records);
|
|
745
|
+
const outcomes = projectConsolidationOutcomes(
|
|
746
|
+
depLatest(ctx, 2),
|
|
747
|
+
requests.requests,
|
|
748
|
+
state.evaluation
|
|
749
|
+
);
|
|
750
|
+
const cursor = Object.freeze({
|
|
751
|
+
evaluation: state.evaluation,
|
|
752
|
+
validRequests: requests.requests.length,
|
|
753
|
+
validOutcomes: outcomes.validOutcomes,
|
|
754
|
+
invalidOutcomes: outcomes.invalidOutcomes,
|
|
755
|
+
results: outcomes.results.length,
|
|
756
|
+
proposedRecordDrafts: outcomes.proposedRecordDrafts.length
|
|
757
|
+
});
|
|
758
|
+
const errors = Object.freeze(
|
|
759
|
+
[
|
|
760
|
+
...recordProjection.errors.map(consolidationErrorFromRecordError),
|
|
761
|
+
...requests.errors.map(consolidationErrorFromRetentionError),
|
|
762
|
+
...outcomes.errors
|
|
763
|
+
].map((error) => freezeError({ ...error, cursor }))
|
|
764
|
+
);
|
|
765
|
+
const status = Object.freeze({
|
|
766
|
+
state: agenticStatusState(errors.length, outcomes.results.length),
|
|
767
|
+
cursor
|
|
768
|
+
});
|
|
769
|
+
ctx.state.set(state);
|
|
770
|
+
ctx.down([
|
|
771
|
+
[
|
|
772
|
+
"DATA",
|
|
773
|
+
Object.freeze({
|
|
774
|
+
results: Object.freeze(outcomes.results),
|
|
775
|
+
proposedRecordDrafts: Object.freeze(outcomes.proposedRecordDrafts),
|
|
776
|
+
commands: Object.freeze(outcomes.commands),
|
|
777
|
+
status,
|
|
778
|
+
errors,
|
|
779
|
+
cursor
|
|
780
|
+
})
|
|
781
|
+
]
|
|
782
|
+
]);
|
|
783
|
+
},
|
|
784
|
+
{
|
|
785
|
+
name: `${name}/projection`,
|
|
786
|
+
factory: "agenticMemoryConsolidation",
|
|
787
|
+
completeWhenDepsComplete: false,
|
|
788
|
+
errorWhenDepsError: false
|
|
1109
789
|
}
|
|
1110
|
-
|
|
1111
|
-
if (errors.length > 0 || id === void 0) {
|
|
1112
|
-
return {
|
|
1113
|
-
errors: [
|
|
1114
|
-
{
|
|
1115
|
-
code: "invalid-command",
|
|
1116
|
-
message: "agenticMemoryRetentionBundle: command is invalid",
|
|
1117
|
-
index,
|
|
1118
|
-
commandId: id,
|
|
1119
|
-
command: value,
|
|
1120
|
-
validationErrors: Object.freeze(errors)
|
|
1121
|
-
}
|
|
1122
|
-
]
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
const base = { id, reason: value.reason };
|
|
1126
|
-
if (kind === "archive") {
|
|
1127
|
-
return {
|
|
1128
|
-
command: Object.freeze({
|
|
1129
|
-
...base,
|
|
1130
|
-
kind,
|
|
1131
|
-
recordId: value.recordId,
|
|
1132
|
-
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1133
|
-
}),
|
|
1134
|
-
errors: []
|
|
1135
|
-
};
|
|
1136
|
-
}
|
|
1137
|
-
if (kind === "restore") {
|
|
1138
|
-
return {
|
|
1139
|
-
command: Object.freeze({
|
|
1140
|
-
...base,
|
|
1141
|
-
kind,
|
|
1142
|
-
recordId: value.recordId,
|
|
1143
|
-
...value.persistenceLevel === void 0 ? {} : {
|
|
1144
|
-
persistenceLevel: value.persistenceLevel
|
|
1145
|
-
},
|
|
1146
|
-
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1147
|
-
}),
|
|
1148
|
-
errors: []
|
|
1149
|
-
};
|
|
1150
|
-
}
|
|
1151
|
-
if (kind === "setPersistenceLevel") {
|
|
1152
|
-
return {
|
|
1153
|
-
command: Object.freeze({
|
|
1154
|
-
...base,
|
|
1155
|
-
kind,
|
|
1156
|
-
recordId: value.recordId,
|
|
1157
|
-
persistenceLevel: value.persistenceLevel,
|
|
1158
|
-
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1159
|
-
}),
|
|
1160
|
-
errors: []
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
return {
|
|
1164
|
-
command: Object.freeze({
|
|
1165
|
-
...base,
|
|
1166
|
-
kind: "requestConsolidation",
|
|
1167
|
-
recordIds: Object.freeze([...value.recordIds]),
|
|
1168
|
-
...value.requestId === void 0 ? {} : { requestId: value.requestId },
|
|
1169
|
-
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
1170
|
-
}),
|
|
1171
|
-
errors: []
|
|
1172
|
-
};
|
|
1173
|
-
}
|
|
1174
|
-
function retentionMissingRecords(command, records) {
|
|
1175
|
-
if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
|
|
1176
|
-
return command.recordIds.filter((recordId) => !records.has(recordId));
|
|
1177
|
-
}
|
|
1178
|
-
function applyRetentionCommand(command, source, view, requests) {
|
|
1179
|
-
if (command.kind === "requestConsolidation") {
|
|
1180
|
-
requests.push(
|
|
1181
|
-
Object.freeze({
|
|
1182
|
-
id: command.requestId ?? command.id,
|
|
1183
|
-
commandId: command.id,
|
|
1184
|
-
recordIds: Object.freeze([...command.recordIds]),
|
|
1185
|
-
...command.reason === void 0 ? {} : { reason: command.reason }
|
|
1186
|
-
})
|
|
1187
|
-
);
|
|
1188
|
-
return;
|
|
1189
|
-
}
|
|
1190
|
-
const record = view.get(command.recordId) ?? source.get(command.recordId);
|
|
1191
|
-
if (record === void 0) return;
|
|
1192
|
-
const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
|
|
1193
|
-
view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
|
|
1194
|
-
}
|
|
1195
|
-
function nonArchivedLevel(record) {
|
|
1196
|
-
return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
|
|
1197
|
-
}
|
|
1198
|
-
function withPersistenceLevel(record, persistenceLevel) {
|
|
1199
|
-
return Object.freeze({
|
|
1200
|
-
...record,
|
|
1201
|
-
persistenceLevel
|
|
1202
|
-
});
|
|
1203
|
-
}
|
|
1204
|
-
function retentionErrorFromRecordError(error) {
|
|
790
|
+
);
|
|
1205
791
|
return {
|
|
1206
|
-
|
|
1207
|
-
|
|
792
|
+
input: { records: opts.records, requests: opts.requests, outcomes: opts.outcomes },
|
|
793
|
+
projection,
|
|
794
|
+
results: solutionProjection(
|
|
795
|
+
graph,
|
|
796
|
+
projection,
|
|
797
|
+
`${name}/results`,
|
|
798
|
+
"agenticMemoryConsolidationResults",
|
|
799
|
+
(fact) => fact.results
|
|
800
|
+
),
|
|
801
|
+
proposedRecordDrafts: solutionProjection(
|
|
802
|
+
graph,
|
|
803
|
+
projection,
|
|
804
|
+
`${name}/proposedRecordDrafts`,
|
|
805
|
+
"agenticMemoryConsolidationRecordDrafts",
|
|
806
|
+
(fact) => fact.proposedRecordDrafts
|
|
807
|
+
),
|
|
808
|
+
commands: solutionProjection(
|
|
809
|
+
graph,
|
|
810
|
+
projection,
|
|
811
|
+
`${name}/commands`,
|
|
812
|
+
"agenticMemoryConsolidationCommands",
|
|
813
|
+
(fact) => fact.commands
|
|
814
|
+
),
|
|
815
|
+
status: solutionProjection(
|
|
816
|
+
graph,
|
|
817
|
+
projection,
|
|
818
|
+
`${name}/status`,
|
|
819
|
+
"agenticMemoryConsolidationStatus",
|
|
820
|
+
(fact) => fact.status
|
|
821
|
+
),
|
|
822
|
+
errors: solutionProjection(
|
|
823
|
+
graph,
|
|
824
|
+
projection,
|
|
825
|
+
`${name}/errors`,
|
|
826
|
+
"agenticMemoryConsolidationErrors",
|
|
827
|
+
(fact) => fact.errors
|
|
828
|
+
),
|
|
829
|
+
cursor: solutionProjection(
|
|
830
|
+
graph,
|
|
831
|
+
projection,
|
|
832
|
+
`${name}/cursor`,
|
|
833
|
+
"agenticMemoryConsolidationCursor",
|
|
834
|
+
(fact) => fact.cursor
|
|
835
|
+
)
|
|
1208
836
|
};
|
|
1209
837
|
}
|
|
1210
838
|
function validateConsolidationRequests(value, records) {
|
|
@@ -1590,6 +1218,64 @@ function consolidationErrorFromRetentionError(error) {
|
|
|
1590
1218
|
code: error.code
|
|
1591
1219
|
};
|
|
1592
1220
|
}
|
|
1221
|
+
|
|
1222
|
+
// src/solutions/agentic-memory-context-packing.ts
|
|
1223
|
+
function agenticMemoryContextPackingBundle(graph, opts) {
|
|
1224
|
+
const name = opts.name ?? "agenticMemoryContextPacking";
|
|
1225
|
+
const projection = graph.node(
|
|
1226
|
+
[opts.context, opts.texts, opts.policy],
|
|
1227
|
+
(ctx) => {
|
|
1228
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1229
|
+
state.evaluation += 1;
|
|
1230
|
+
const packed = packContext(
|
|
1231
|
+
depLatest(ctx, 0),
|
|
1232
|
+
depLatest(ctx, 1),
|
|
1233
|
+
depLatest(ctx, 2),
|
|
1234
|
+
state.evaluation
|
|
1235
|
+
);
|
|
1236
|
+
ctx.state.set(state);
|
|
1237
|
+
ctx.down([["DATA", packed]]);
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
name: `${name}/projection`,
|
|
1241
|
+
factory: "agenticMemoryContextPacking",
|
|
1242
|
+
completeWhenDepsComplete: false,
|
|
1243
|
+
errorWhenDepsError: false
|
|
1244
|
+
}
|
|
1245
|
+
);
|
|
1246
|
+
return {
|
|
1247
|
+
input: { context: opts.context, texts: opts.texts, policy: opts.policy },
|
|
1248
|
+
projection,
|
|
1249
|
+
packedContext: solutionProjection(
|
|
1250
|
+
graph,
|
|
1251
|
+
projection,
|
|
1252
|
+
`${name}/packedContext`,
|
|
1253
|
+
"agenticMemoryPackedContext",
|
|
1254
|
+
(fact) => fact.packedContext
|
|
1255
|
+
),
|
|
1256
|
+
status: solutionProjection(
|
|
1257
|
+
graph,
|
|
1258
|
+
projection,
|
|
1259
|
+
`${name}/status`,
|
|
1260
|
+
"agenticMemoryContextPackingStatus",
|
|
1261
|
+
(fact) => fact.status
|
|
1262
|
+
),
|
|
1263
|
+
errors: solutionProjection(
|
|
1264
|
+
graph,
|
|
1265
|
+
projection,
|
|
1266
|
+
`${name}/errors`,
|
|
1267
|
+
"agenticMemoryContextPackingErrors",
|
|
1268
|
+
(fact) => fact.errors
|
|
1269
|
+
),
|
|
1270
|
+
cursor: solutionProjection(
|
|
1271
|
+
graph,
|
|
1272
|
+
projection,
|
|
1273
|
+
`${name}/cursor`,
|
|
1274
|
+
"agenticMemoryContextPackingCursor",
|
|
1275
|
+
(fact) => fact.cursor
|
|
1276
|
+
)
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1593
1279
|
function packContext(contextValue, textsValue, policyValue, evaluation) {
|
|
1594
1280
|
const errors = [];
|
|
1595
1281
|
const context = validatePackingContext(contextValue, errors);
|
|
@@ -1669,781 +1355,1655 @@ function packContext(contextValue, textsValue, policyValue, evaluation) {
|
|
|
1669
1355
|
cursor
|
|
1670
1356
|
});
|
|
1671
1357
|
}
|
|
1672
|
-
function validatePackingContext(value, errors) {
|
|
1358
|
+
function validatePackingContext(value, errors) {
|
|
1359
|
+
if (!isPlainRecord(value)) {
|
|
1360
|
+
errors.push({
|
|
1361
|
+
code: "invalid-context",
|
|
1362
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
1363
|
+
value
|
|
1364
|
+
});
|
|
1365
|
+
return void 0;
|
|
1366
|
+
}
|
|
1367
|
+
let entriesValue;
|
|
1368
|
+
try {
|
|
1369
|
+
entriesValue = value.entries;
|
|
1370
|
+
} catch (error) {
|
|
1371
|
+
errors.push({
|
|
1372
|
+
code: "invalid-context",
|
|
1373
|
+
message: `agenticMemoryContextPackingBundle: context entries access failed: ${errorMessage(error)}`,
|
|
1374
|
+
value,
|
|
1375
|
+
validationErrors: ["context entries access failed"]
|
|
1376
|
+
});
|
|
1377
|
+
return void 0;
|
|
1378
|
+
}
|
|
1379
|
+
if (!Array.isArray(entriesValue)) {
|
|
1380
|
+
errors.push({
|
|
1381
|
+
code: "invalid-context",
|
|
1382
|
+
message: "agenticMemoryContextPackingBundle: context must be an AgenticMemoryContext fact",
|
|
1383
|
+
value,
|
|
1384
|
+
validationErrors: ["context.entries must be an array"]
|
|
1385
|
+
});
|
|
1386
|
+
return void 0;
|
|
1387
|
+
}
|
|
1388
|
+
const length = safeArrayLength(entriesValue);
|
|
1389
|
+
if (length === void 0) {
|
|
1390
|
+
errors.push({
|
|
1391
|
+
code: "invalid-context",
|
|
1392
|
+
message: "agenticMemoryContextPackingBundle: context entries length could not be read",
|
|
1393
|
+
value,
|
|
1394
|
+
validationErrors: ["context.entries length could not be read"]
|
|
1395
|
+
});
|
|
1396
|
+
return void 0;
|
|
1397
|
+
}
|
|
1398
|
+
const entries = [];
|
|
1399
|
+
for (let i = 0; i < length; i += 1) {
|
|
1400
|
+
let raw;
|
|
1401
|
+
try {
|
|
1402
|
+
raw = entriesValue[i];
|
|
1403
|
+
if (!isPlainRecord(raw) || !isNonEmptyString(raw.fragmentId)) {
|
|
1404
|
+
errors.push({
|
|
1405
|
+
code: "invalid-context",
|
|
1406
|
+
message: "agenticMemoryContextPackingBundle: context entry is invalid",
|
|
1407
|
+
index: i,
|
|
1408
|
+
value: raw,
|
|
1409
|
+
validationErrors: ["context entry fragmentId must be a non-empty string"]
|
|
1410
|
+
});
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
const record = validateRecordMetadata(raw.record);
|
|
1414
|
+
if (!record.ok) {
|
|
1415
|
+
errors.push({
|
|
1416
|
+
code: "invalid-context",
|
|
1417
|
+
message: "agenticMemoryContextPackingBundle: context entry record metadata is invalid",
|
|
1418
|
+
index: i,
|
|
1419
|
+
fragmentId: raw.fragmentId,
|
|
1420
|
+
value: raw,
|
|
1421
|
+
validationErrors: Object.freeze(record.errors)
|
|
1422
|
+
});
|
|
1423
|
+
continue;
|
|
1424
|
+
}
|
|
1425
|
+
entries.push(
|
|
1426
|
+
Object.freeze({
|
|
1427
|
+
fragmentId: raw.fragmentId,
|
|
1428
|
+
...record.metadata === void 0 ? {} : { record: record.metadata }
|
|
1429
|
+
})
|
|
1430
|
+
);
|
|
1431
|
+
} catch (error) {
|
|
1432
|
+
errors.push({
|
|
1433
|
+
code: "invalid-context",
|
|
1434
|
+
message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage(error)}`,
|
|
1435
|
+
index: i,
|
|
1436
|
+
value: raw,
|
|
1437
|
+
validationErrors: ["context entry access failed"]
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
return Object.freeze({
|
|
1442
|
+
entries: Object.freeze(entries)
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
function validateContextTexts(value, errors) {
|
|
1446
|
+
const out = /* @__PURE__ */ new Map();
|
|
1447
|
+
if (!Array.isArray(value)) {
|
|
1448
|
+
errors.push({
|
|
1449
|
+
code: "invalid-texts-input",
|
|
1450
|
+
message: "agenticMemoryContextPackingBundle: texts input must be an array",
|
|
1451
|
+
value
|
|
1452
|
+
});
|
|
1453
|
+
return out;
|
|
1454
|
+
}
|
|
1455
|
+
const length = safeArrayLength(value);
|
|
1456
|
+
if (length === void 0) {
|
|
1457
|
+
errors.push({
|
|
1458
|
+
code: "invalid-texts-input",
|
|
1459
|
+
message: "agenticMemoryContextPackingBundle: texts input length could not be read",
|
|
1460
|
+
value
|
|
1461
|
+
});
|
|
1462
|
+
return out;
|
|
1463
|
+
}
|
|
1464
|
+
for (let i = 0; i < length; i += 1) {
|
|
1465
|
+
try {
|
|
1466
|
+
const raw = value[i];
|
|
1467
|
+
const result = validateContextText(raw, i);
|
|
1468
|
+
if (result.error !== void 0) {
|
|
1469
|
+
errors.push(result.error);
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
if (result.text === void 0) {
|
|
1473
|
+
errors.push({
|
|
1474
|
+
code: "invalid-text",
|
|
1475
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
1476
|
+
index: i,
|
|
1477
|
+
value: raw,
|
|
1478
|
+
validationErrors: ["text validation returned no fact"]
|
|
1479
|
+
});
|
|
1480
|
+
continue;
|
|
1481
|
+
}
|
|
1482
|
+
if (out.has(result.text.fragmentId)) {
|
|
1483
|
+
errors.push({
|
|
1484
|
+
code: "duplicate-text-fragment-id",
|
|
1485
|
+
message: "agenticMemoryContextPackingBundle: duplicate text fragment id",
|
|
1486
|
+
index: i,
|
|
1487
|
+
fragmentId: result.text.fragmentId,
|
|
1488
|
+
value: raw,
|
|
1489
|
+
validationErrors: [`duplicate text fragment id '${result.text.fragmentId}'`]
|
|
1490
|
+
});
|
|
1491
|
+
continue;
|
|
1492
|
+
}
|
|
1493
|
+
out.set(result.text.fragmentId, result.text);
|
|
1494
|
+
} catch (error) {
|
|
1495
|
+
errors.push({
|
|
1496
|
+
code: "invalid-text",
|
|
1497
|
+
message: `agenticMemoryContextPackingBundle: text access failed: ${errorMessage(error)}`,
|
|
1498
|
+
index: i,
|
|
1499
|
+
validationErrors: ["text access failed"]
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
return out;
|
|
1504
|
+
}
|
|
1505
|
+
function validateContextText(value, index) {
|
|
1506
|
+
if (!isPlainRecord(value)) {
|
|
1507
|
+
return {
|
|
1508
|
+
error: {
|
|
1509
|
+
code: "invalid-text",
|
|
1510
|
+
message: "agenticMemoryContextPackingBundle: text fact must be an object",
|
|
1511
|
+
index,
|
|
1512
|
+
value
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
const errors = [];
|
|
1517
|
+
if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
|
|
1518
|
+
if (typeof value.text !== "string") errors.push("text must be a string");
|
|
1519
|
+
if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
|
|
1520
|
+
errors.push("cost must be a finite number >= 0");
|
|
1521
|
+
}
|
|
1522
|
+
if (value.metadata !== void 0) {
|
|
1523
|
+
try {
|
|
1524
|
+
if (!isPlainRecord(value.metadata)) {
|
|
1525
|
+
throw new TypeError("metadata must be a plain object when present");
|
|
1526
|
+
}
|
|
1527
|
+
assertStrictJsonValue(value.metadata, "metadata");
|
|
1528
|
+
} catch (error) {
|
|
1529
|
+
errors.push(errorMessage(error));
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
if (errors.length > 0) {
|
|
1533
|
+
return {
|
|
1534
|
+
error: {
|
|
1535
|
+
code: "invalid-text",
|
|
1536
|
+
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
1537
|
+
index,
|
|
1538
|
+
fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
|
|
1539
|
+
value,
|
|
1540
|
+
validationErrors: Object.freeze(errors)
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
return {
|
|
1545
|
+
text: Object.freeze({
|
|
1546
|
+
fragmentId: value.fragmentId,
|
|
1547
|
+
text: value.text,
|
|
1548
|
+
...value.cost === void 0 ? {} : { cost: value.cost },
|
|
1549
|
+
...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
|
|
1550
|
+
})
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
function validatePackingPolicy(value, errors) {
|
|
1673
1554
|
if (!isPlainRecord(value)) {
|
|
1674
1555
|
errors.push({
|
|
1675
|
-
code: "invalid-
|
|
1676
|
-
message: "agenticMemoryContextPackingBundle:
|
|
1556
|
+
code: "invalid-policy",
|
|
1557
|
+
message: "agenticMemoryContextPackingBundle: policy must be an object",
|
|
1677
1558
|
value
|
|
1678
1559
|
});
|
|
1679
1560
|
return void 0;
|
|
1680
1561
|
}
|
|
1681
|
-
|
|
1562
|
+
const validation = [];
|
|
1563
|
+
let maxEntries;
|
|
1564
|
+
let maxChars;
|
|
1565
|
+
let maxCost;
|
|
1566
|
+
let includeMetadata;
|
|
1682
1567
|
try {
|
|
1683
|
-
|
|
1568
|
+
maxEntries = value.maxEntries;
|
|
1569
|
+
maxChars = value.maxChars;
|
|
1570
|
+
maxCost = value.maxCost;
|
|
1571
|
+
includeMetadata = value.includeMetadata;
|
|
1684
1572
|
} catch (error) {
|
|
1685
1573
|
errors.push({
|
|
1686
|
-
code: "invalid-
|
|
1687
|
-
message: `agenticMemoryContextPackingBundle:
|
|
1574
|
+
code: "invalid-policy",
|
|
1575
|
+
message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage(error)}`,
|
|
1688
1576
|
value,
|
|
1689
|
-
validationErrors: ["
|
|
1577
|
+
validationErrors: ["policy access failed"]
|
|
1690
1578
|
});
|
|
1691
1579
|
return void 0;
|
|
1692
1580
|
}
|
|
1693
|
-
if (!
|
|
1581
|
+
if (maxEntries !== void 0 && (typeof maxEntries !== "number" || !Number.isSafeInteger(maxEntries) || maxEntries < 0)) {
|
|
1582
|
+
validation.push("maxEntries must be a safe integer >= 0");
|
|
1583
|
+
}
|
|
1584
|
+
if (maxChars !== void 0 && (typeof maxChars !== "number" || !Number.isSafeInteger(maxChars) || maxChars < 0)) {
|
|
1585
|
+
validation.push("maxChars must be a safe integer >= 0");
|
|
1586
|
+
}
|
|
1587
|
+
if (maxCost !== void 0 && (typeof maxCost !== "number" || !Number.isFinite(maxCost) || maxCost < 0)) {
|
|
1588
|
+
validation.push("maxCost must be a finite number >= 0");
|
|
1589
|
+
}
|
|
1590
|
+
if (includeMetadata !== void 0 && typeof includeMetadata !== "boolean") {
|
|
1591
|
+
validation.push("includeMetadata must be a boolean when present");
|
|
1592
|
+
}
|
|
1593
|
+
if (validation.length > 0) {
|
|
1694
1594
|
errors.push({
|
|
1695
|
-
code: "invalid-
|
|
1696
|
-
message: "agenticMemoryContextPackingBundle:
|
|
1595
|
+
code: "invalid-policy",
|
|
1596
|
+
message: "agenticMemoryContextPackingBundle: policy is invalid",
|
|
1697
1597
|
value,
|
|
1698
|
-
validationErrors:
|
|
1598
|
+
validationErrors: Object.freeze(validation)
|
|
1699
1599
|
});
|
|
1700
1600
|
return void 0;
|
|
1701
1601
|
}
|
|
1702
|
-
|
|
1602
|
+
return Object.freeze({
|
|
1603
|
+
...maxEntries === void 0 ? {} : { maxEntries },
|
|
1604
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
1605
|
+
...maxCost === void 0 ? {} : { maxCost },
|
|
1606
|
+
...includeMetadata === void 0 ? {} : { includeMetadata }
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/solutions/agentic-memory-frame.ts
|
|
1611
|
+
var AGENTIC_MEMORY_RECORD_FRAME_FORMAT = "graphrefly.agenticMemoryRecord";
|
|
1612
|
+
var AGENTIC_MEMORY_RECORD_FRAME_VERSION = 1;
|
|
1613
|
+
function agenticMemoryRecordFrame(record) {
|
|
1614
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
1615
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
1616
|
+
throw new TypeError(
|
|
1617
|
+
`agenticMemoryRecordFrame: invalid record: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
assertAgenticMemoryRecordCodecShape(record);
|
|
1621
|
+
assertStrictJsonValue(result.record.fragment.payload, "record.fragment.payload");
|
|
1622
|
+
return Object.freeze({
|
|
1623
|
+
format: AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
1624
|
+
version: AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
1625
|
+
record: Object.freeze({
|
|
1626
|
+
id: result.record.id,
|
|
1627
|
+
kind: result.record.kind,
|
|
1628
|
+
persistenceLevel: result.record.persistenceLevel,
|
|
1629
|
+
artifactKind: result.record.artifactKind,
|
|
1630
|
+
...result.record.scope === void 0 ? {} : { scope: result.record.scope },
|
|
1631
|
+
fragment: fragmentFrame(result.record.fragment)
|
|
1632
|
+
})
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
function assertAgenticMemoryRecordFrame(value) {
|
|
1636
|
+
if (!isPlainRecord(value))
|
|
1637
|
+
throw new TypeError("agenticMemoryRecordFrame: frame must be an object");
|
|
1638
|
+
assertStrictJsonValue(value, "agenticMemoryRecordFrame");
|
|
1639
|
+
assertExactKeys(value, ["format", "record", "version"], "agenticMemoryRecordFrame");
|
|
1640
|
+
if (value.format !== AGENTIC_MEMORY_RECORD_FRAME_FORMAT) {
|
|
1641
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid format");
|
|
1642
|
+
}
|
|
1643
|
+
if (value.version !== AGENTIC_MEMORY_RECORD_FRAME_VERSION) {
|
|
1644
|
+
throw new TypeError("agenticMemoryRecordFrame: invalid version");
|
|
1645
|
+
}
|
|
1646
|
+
const rawRecord = value.record;
|
|
1647
|
+
if (!isPlainRecord(rawRecord)) {
|
|
1648
|
+
throw new TypeError("agenticMemoryRecordFrame: record must be an object");
|
|
1649
|
+
}
|
|
1650
|
+
assertExactKeys(
|
|
1651
|
+
rawRecord,
|
|
1652
|
+
rawRecord.scope === void 0 ? ["artifactKind", "fragment", "id", "kind", "persistenceLevel"] : ["artifactKind", "fragment", "id", "kind", "persistenceLevel", "scope"],
|
|
1653
|
+
"agenticMemoryRecordFrame.record"
|
|
1654
|
+
);
|
|
1655
|
+
const rawFragment = rawRecord.fragment;
|
|
1656
|
+
if (!isPlainRecord(rawFragment)) {
|
|
1657
|
+
throw new TypeError("agenticMemoryRecordFrame: fragment must be an object");
|
|
1658
|
+
}
|
|
1659
|
+
assertExactKeys(
|
|
1660
|
+
rawFragment,
|
|
1661
|
+
[
|
|
1662
|
+
"id",
|
|
1663
|
+
"payload",
|
|
1664
|
+
"tNs",
|
|
1665
|
+
...rawFragment.validFrom === void 0 ? [] : ["validFrom"],
|
|
1666
|
+
...rawFragment.validTo === void 0 ? [] : ["validTo"],
|
|
1667
|
+
"confidence",
|
|
1668
|
+
"tags",
|
|
1669
|
+
"sources",
|
|
1670
|
+
...rawFragment.embedding === void 0 ? [] : ["embedding"],
|
|
1671
|
+
...rawFragment.parentFragmentId === void 0 ? [] : ["parentFragmentId"],
|
|
1672
|
+
...rawFragment.provenance === void 0 ? [] : ["provenance"]
|
|
1673
|
+
],
|
|
1674
|
+
"agenticMemoryRecordFrame.record.fragment"
|
|
1675
|
+
);
|
|
1676
|
+
if (rawRecord.scope !== void 0) assertScopeFrame(rawRecord.scope);
|
|
1677
|
+
const frame = value;
|
|
1678
|
+
const decoded = recordFromFrame(frame);
|
|
1679
|
+
const roundtrip = agenticMemoryRecordFrame(decoded);
|
|
1680
|
+
return roundtrip;
|
|
1681
|
+
}
|
|
1682
|
+
function agenticMemoryRecordFrameCodec() {
|
|
1683
|
+
return {
|
|
1684
|
+
encode(value) {
|
|
1685
|
+
return strictJsonCodec.encode(assertAgenticMemoryRecordFrame(value));
|
|
1686
|
+
},
|
|
1687
|
+
decode(bytes) {
|
|
1688
|
+
return assertAgenticMemoryRecordFrame(strictJsonCodec.decode(bytes));
|
|
1689
|
+
}
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1692
|
+
function agenticMemoryRecordCodec() {
|
|
1693
|
+
const frameCodec = agenticMemoryRecordFrameCodec();
|
|
1694
|
+
return {
|
|
1695
|
+
encode(value) {
|
|
1696
|
+
return frameCodec.encode(agenticMemoryRecordFrame(value));
|
|
1697
|
+
},
|
|
1698
|
+
decode(bytes) {
|
|
1699
|
+
return recordFromFrame(frameCodec.decode(bytes));
|
|
1700
|
+
}
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
function fragmentFrame(fragment) {
|
|
1704
|
+
return Object.freeze({
|
|
1705
|
+
id: fragment.id,
|
|
1706
|
+
payload: fragment.payload,
|
|
1707
|
+
tNs: decimalBigIntString(fragment.tNs, "fragment.tNs"),
|
|
1708
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: decimalBigIntString(fragment.validFrom, "fragment.validFrom") },
|
|
1709
|
+
...fragment.validTo === void 0 ? {} : { validTo: decimalBigIntString(fragment.validTo, "fragment.validTo") },
|
|
1710
|
+
confidence: fragment.confidence,
|
|
1711
|
+
tags: Object.freeze([...fragment.tags]),
|
|
1712
|
+
sources: Object.freeze([...fragment.sources]),
|
|
1713
|
+
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
1714
|
+
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
1715
|
+
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
function recordFromFrame(frame) {
|
|
1719
|
+
const fragment = frame.record.fragment;
|
|
1720
|
+
const record = {
|
|
1721
|
+
id: assertNonEmptyString(frame.record.id, "record.id"),
|
|
1722
|
+
kind: assertKindValue(frame.record.kind),
|
|
1723
|
+
persistenceLevel: assertPersistenceLevelValue(frame.record.persistenceLevel),
|
|
1724
|
+
artifactKind: assertArtifactKindValue(frame.record.artifactKind),
|
|
1725
|
+
...frame.record.scope === void 0 ? {} : { scope: assertScopeFrame(frame.record.scope) },
|
|
1726
|
+
fragment: {
|
|
1727
|
+
id: assertNonEmptyString(fragment.id, "fragment.id"),
|
|
1728
|
+
payload: assertStrictJsonValue(fragment.payload, "fragment.payload"),
|
|
1729
|
+
tNs: parseDecimalBigInt(fragment.tNs, "fragment.tNs"),
|
|
1730
|
+
...fragment.validFrom === void 0 ? {} : { validFrom: parseDecimalBigInt(fragment.validFrom, "fragment.validFrom") },
|
|
1731
|
+
...fragment.validTo === void 0 ? {} : { validTo: parseDecimalBigInt(fragment.validTo, "fragment.validTo") },
|
|
1732
|
+
confidence: assertConfidence(fragment.confidence, "fragment.confidence"),
|
|
1733
|
+
tags: assertStringArray(fragment.tags, "fragment.tags"),
|
|
1734
|
+
sources: assertStringArray(fragment.sources, "fragment.sources"),
|
|
1735
|
+
...fragment.embedding === void 0 ? {} : { embedding: assertFiniteNumberArray(fragment.embedding, "fragment.embedding") },
|
|
1736
|
+
...fragment.parentFragmentId === void 0 ? {} : {
|
|
1737
|
+
parentFragmentId: assertNonEmptyString(fragment.parentFragmentId, "parentFragmentId")
|
|
1738
|
+
},
|
|
1739
|
+
...fragment.provenance === void 0 ? {} : { provenance: assertString(fragment.provenance, "provenance") }
|
|
1740
|
+
}
|
|
1741
|
+
};
|
|
1742
|
+
const result = validateAndSnapshotRecord(record, 0);
|
|
1743
|
+
if (result.errors.length > 0 || result.record === void 0) {
|
|
1744
|
+
throw new TypeError(
|
|
1745
|
+
`agenticMemoryRecordFrame: decoded record is invalid: ${result.errors.flatMap((error) => error.validationErrors ?? [error.message]).join("; ")}`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return result.record;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// src/solutions/agentic-memory-kg.ts
|
|
1752
|
+
function agenticMemoryKgProjectionBundle(graph, opts) {
|
|
1753
|
+
const name = opts.name ?? "agenticMemoryKgProjection";
|
|
1754
|
+
const projection = graph.node(
|
|
1755
|
+
[opts.records, opts.drafts],
|
|
1756
|
+
(ctx) => {
|
|
1757
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
1758
|
+
state.evaluation += 1;
|
|
1759
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
1760
|
+
const draftProjection = validateAndProjectKgDrafts(
|
|
1761
|
+
depLatest(ctx, 1),
|
|
1762
|
+
recordProjection.records
|
|
1763
|
+
);
|
|
1764
|
+
const cursor = Object.freeze({
|
|
1765
|
+
evaluation: state.evaluation,
|
|
1766
|
+
validRecords: recordProjection.records.length,
|
|
1767
|
+
validDrafts: draftProjection.assertions.length,
|
|
1768
|
+
invalidDrafts: draftProjection.invalidDrafts,
|
|
1769
|
+
projectedAssertions: draftProjection.assertions.length
|
|
1770
|
+
});
|
|
1771
|
+
const errors = Object.freeze(
|
|
1772
|
+
[...recordProjection.errors.map(kgErrorFromRecordError), ...draftProjection.errors].map(
|
|
1773
|
+
(error) => freezeError({ ...error, cursor })
|
|
1774
|
+
)
|
|
1775
|
+
);
|
|
1776
|
+
const status = Object.freeze({
|
|
1777
|
+
state: agenticStatusState(errors.length, draftProjection.assertions.length),
|
|
1778
|
+
cursor
|
|
1779
|
+
});
|
|
1780
|
+
ctx.state.set(state);
|
|
1781
|
+
ctx.down([
|
|
1782
|
+
[
|
|
1783
|
+
"DATA",
|
|
1784
|
+
Object.freeze({
|
|
1785
|
+
assertions: Object.freeze(draftProjection.assertions),
|
|
1786
|
+
status,
|
|
1787
|
+
errors,
|
|
1788
|
+
cursor
|
|
1789
|
+
})
|
|
1790
|
+
]
|
|
1791
|
+
]);
|
|
1792
|
+
},
|
|
1793
|
+
{
|
|
1794
|
+
name: `${name}/projection`,
|
|
1795
|
+
factory: "agenticMemoryKgProjection",
|
|
1796
|
+
completeWhenDepsComplete: false,
|
|
1797
|
+
errorWhenDepsError: false
|
|
1798
|
+
}
|
|
1799
|
+
);
|
|
1800
|
+
return {
|
|
1801
|
+
input: { records: opts.records, drafts: opts.drafts },
|
|
1802
|
+
projection,
|
|
1803
|
+
assertions: solutionProjection(
|
|
1804
|
+
graph,
|
|
1805
|
+
projection,
|
|
1806
|
+
`${name}/assertions`,
|
|
1807
|
+
"agenticMemoryKgAssertions",
|
|
1808
|
+
(fact) => fact.assertions
|
|
1809
|
+
),
|
|
1810
|
+
status: solutionProjection(
|
|
1811
|
+
graph,
|
|
1812
|
+
projection,
|
|
1813
|
+
`${name}/status`,
|
|
1814
|
+
"agenticMemoryKgStatus",
|
|
1815
|
+
(fact) => fact.status
|
|
1816
|
+
),
|
|
1817
|
+
errors: solutionProjection(
|
|
1818
|
+
graph,
|
|
1819
|
+
projection,
|
|
1820
|
+
`${name}/errors`,
|
|
1821
|
+
"agenticMemoryKgErrors",
|
|
1822
|
+
(fact) => fact.errors
|
|
1823
|
+
),
|
|
1824
|
+
cursor: solutionProjection(
|
|
1825
|
+
graph,
|
|
1826
|
+
projection,
|
|
1827
|
+
`${name}/cursor`,
|
|
1828
|
+
"agenticMemoryKgCursor",
|
|
1829
|
+
(fact) => fact.cursor
|
|
1830
|
+
)
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
function validateAndProjectKgDrafts(value, records) {
|
|
1834
|
+
const assertions = [];
|
|
1835
|
+
const errors = [];
|
|
1836
|
+
let invalidDrafts = 0;
|
|
1837
|
+
if (!Array.isArray(value)) {
|
|
1838
|
+
return {
|
|
1839
|
+
assertions,
|
|
1840
|
+
invalidDrafts: 1,
|
|
1841
|
+
errors: [
|
|
1842
|
+
{
|
|
1843
|
+
code: "invalid-drafts-input",
|
|
1844
|
+
message: "agenticMemoryKgProjectionBundle: drafts input must be an array",
|
|
1845
|
+
draft: value
|
|
1846
|
+
}
|
|
1847
|
+
]
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
const length = safeArrayLength(value);
|
|
1703
1851
|
if (length === void 0) {
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1852
|
+
return {
|
|
1853
|
+
assertions,
|
|
1854
|
+
invalidDrafts: 1,
|
|
1855
|
+
errors: [
|
|
1856
|
+
{
|
|
1857
|
+
code: "invalid-drafts-input",
|
|
1858
|
+
message: "agenticMemoryKgProjectionBundle: drafts input length could not be read",
|
|
1859
|
+
draft: value
|
|
1860
|
+
}
|
|
1861
|
+
]
|
|
1862
|
+
};
|
|
1711
1863
|
}
|
|
1712
|
-
const
|
|
1864
|
+
const recordById = new Map(records.map((record) => [record.id, record]));
|
|
1865
|
+
const fragmentToRecord = new Map(records.map((record) => [record.fragment.id, record.id]));
|
|
1866
|
+
const seenAssertions = /* @__PURE__ */ new Set();
|
|
1713
1867
|
for (let i = 0; i < length; i += 1) {
|
|
1714
1868
|
let raw;
|
|
1715
1869
|
try {
|
|
1716
|
-
raw =
|
|
1717
|
-
|
|
1870
|
+
raw = value[i];
|
|
1871
|
+
const result = validateKgDraft(raw, i);
|
|
1872
|
+
if (result.errors.length > 0 || result.draft === void 0) {
|
|
1873
|
+
invalidDrafts += 1;
|
|
1874
|
+
errors.push(...result.errors);
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
const draft = result.draft;
|
|
1878
|
+
if (seenAssertions.has(draft.id)) {
|
|
1879
|
+
invalidDrafts += 1;
|
|
1718
1880
|
errors.push({
|
|
1719
|
-
code: "
|
|
1720
|
-
message: "
|
|
1881
|
+
code: "duplicate-assertion-id",
|
|
1882
|
+
message: "agenticMemoryKgProjectionBundle: duplicate assertion id",
|
|
1721
1883
|
index: i,
|
|
1722
|
-
|
|
1723
|
-
|
|
1884
|
+
assertionId: draft.id,
|
|
1885
|
+
recordId: draft.recordId,
|
|
1886
|
+
fragmentId: draft.fragmentId,
|
|
1887
|
+
draft: raw,
|
|
1888
|
+
validationErrors: [`duplicate assertion id '${draft.id}'`]
|
|
1724
1889
|
});
|
|
1725
1890
|
continue;
|
|
1726
1891
|
}
|
|
1727
|
-
const record =
|
|
1728
|
-
if (
|
|
1892
|
+
const record = recordById.get(draft.recordId);
|
|
1893
|
+
if (record === void 0) {
|
|
1894
|
+
invalidDrafts += 1;
|
|
1729
1895
|
errors.push({
|
|
1730
|
-
code: "
|
|
1731
|
-
message: "
|
|
1896
|
+
code: "missing-record-ref",
|
|
1897
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing record",
|
|
1732
1898
|
index: i,
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1899
|
+
assertionId: draft.id,
|
|
1900
|
+
recordId: draft.recordId,
|
|
1901
|
+
fragmentId: draft.fragmentId,
|
|
1902
|
+
draft: raw,
|
|
1903
|
+
validationErrors: [`record '${draft.recordId}' is not projected`]
|
|
1736
1904
|
});
|
|
1737
1905
|
continue;
|
|
1738
1906
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
...record.metadata === void 0 ? {} : { record: record.metadata }
|
|
1743
|
-
})
|
|
1744
|
-
);
|
|
1745
|
-
} catch (error) {
|
|
1746
|
-
errors.push({
|
|
1747
|
-
code: "invalid-context",
|
|
1748
|
-
message: `agenticMemoryContextPackingBundle: context entry access failed: ${errorMessage(error)}`,
|
|
1749
|
-
index: i,
|
|
1750
|
-
value: raw,
|
|
1751
|
-
validationErrors: ["context entry access failed"]
|
|
1752
|
-
});
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
return Object.freeze({
|
|
1756
|
-
entries: Object.freeze(entries)
|
|
1757
|
-
});
|
|
1758
|
-
}
|
|
1759
|
-
function validateContextTexts(value, errors) {
|
|
1760
|
-
const out = /* @__PURE__ */ new Map();
|
|
1761
|
-
if (!Array.isArray(value)) {
|
|
1762
|
-
errors.push({
|
|
1763
|
-
code: "invalid-texts-input",
|
|
1764
|
-
message: "agenticMemoryContextPackingBundle: texts input must be an array",
|
|
1765
|
-
value
|
|
1766
|
-
});
|
|
1767
|
-
return out;
|
|
1768
|
-
}
|
|
1769
|
-
const length = safeArrayLength(value);
|
|
1770
|
-
if (length === void 0) {
|
|
1771
|
-
errors.push({
|
|
1772
|
-
code: "invalid-texts-input",
|
|
1773
|
-
message: "agenticMemoryContextPackingBundle: texts input length could not be read",
|
|
1774
|
-
value
|
|
1775
|
-
});
|
|
1776
|
-
return out;
|
|
1777
|
-
}
|
|
1778
|
-
for (let i = 0; i < length; i += 1) {
|
|
1779
|
-
try {
|
|
1780
|
-
const raw = value[i];
|
|
1781
|
-
const result = validateContextText(raw, i);
|
|
1782
|
-
if (result.error !== void 0) {
|
|
1783
|
-
errors.push(result.error);
|
|
1784
|
-
continue;
|
|
1785
|
-
}
|
|
1786
|
-
if (result.text === void 0) {
|
|
1907
|
+
const owner = fragmentToRecord.get(draft.fragmentId);
|
|
1908
|
+
if (owner === void 0) {
|
|
1909
|
+
invalidDrafts += 1;
|
|
1787
1910
|
errors.push({
|
|
1788
|
-
code: "
|
|
1789
|
-
message: "
|
|
1911
|
+
code: "missing-fragment-ref",
|
|
1912
|
+
message: "agenticMemoryKgProjectionBundle: draft references a missing fragment",
|
|
1790
1913
|
index: i,
|
|
1791
|
-
|
|
1792
|
-
|
|
1914
|
+
assertionId: draft.id,
|
|
1915
|
+
recordId: draft.recordId,
|
|
1916
|
+
fragmentId: draft.fragmentId,
|
|
1917
|
+
draft: raw,
|
|
1918
|
+
validationErrors: [`fragment '${draft.fragmentId}' is not projected`]
|
|
1793
1919
|
});
|
|
1794
1920
|
continue;
|
|
1795
1921
|
}
|
|
1796
|
-
if (
|
|
1922
|
+
if (owner !== draft.recordId || record.fragment.id !== draft.fragmentId) {
|
|
1923
|
+
invalidDrafts += 1;
|
|
1797
1924
|
errors.push({
|
|
1798
|
-
code: "
|
|
1799
|
-
message: "
|
|
1925
|
+
code: "fragment-record-mismatch",
|
|
1926
|
+
message: "agenticMemoryKgProjectionBundle: draft record and fragment refs disagree",
|
|
1800
1927
|
index: i,
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1928
|
+
assertionId: draft.id,
|
|
1929
|
+
recordId: draft.recordId,
|
|
1930
|
+
fragmentId: draft.fragmentId,
|
|
1931
|
+
draft: raw,
|
|
1932
|
+
validationErrors: [
|
|
1933
|
+
`fragment '${draft.fragmentId}' belongs to record '${owner}', not '${draft.recordId}'`
|
|
1934
|
+
]
|
|
1804
1935
|
});
|
|
1805
1936
|
continue;
|
|
1806
1937
|
}
|
|
1807
|
-
|
|
1938
|
+
seenAssertions.add(draft.id);
|
|
1939
|
+
assertions.push(
|
|
1940
|
+
Object.freeze({
|
|
1941
|
+
id: draft.id,
|
|
1942
|
+
recordId: draft.recordId,
|
|
1943
|
+
fragmentId: draft.fragmentId,
|
|
1944
|
+
subject: draft.subject,
|
|
1945
|
+
predicate: draft.predicate,
|
|
1946
|
+
object: draft.object,
|
|
1947
|
+
...draft.confidence === void 0 ? {} : { confidence: draft.confidence },
|
|
1948
|
+
sources: Object.freeze(draft.sources ?? [draft.fragmentId]),
|
|
1949
|
+
...draft.provenance === void 0 ? {} : { provenance: draft.provenance }
|
|
1950
|
+
})
|
|
1951
|
+
);
|
|
1808
1952
|
} catch (error) {
|
|
1953
|
+
invalidDrafts += 1;
|
|
1809
1954
|
errors.push({
|
|
1810
|
-
code: "invalid-
|
|
1811
|
-
message: `
|
|
1955
|
+
code: "invalid-draft",
|
|
1956
|
+
message: `agenticMemoryKgProjectionBundle: draft access failed: ${errorMessage(error)}`,
|
|
1812
1957
|
index: i,
|
|
1813
|
-
|
|
1958
|
+
draft: raw,
|
|
1959
|
+
validationErrors: ["draft access failed"]
|
|
1814
1960
|
});
|
|
1815
1961
|
}
|
|
1816
1962
|
}
|
|
1817
|
-
return
|
|
1818
|
-
}
|
|
1819
|
-
function validateContextText(value, index) {
|
|
1820
|
-
if (!isPlainRecord(value)) {
|
|
1821
|
-
return {
|
|
1822
|
-
error: {
|
|
1823
|
-
code: "invalid-text",
|
|
1824
|
-
message: "agenticMemoryContextPackingBundle: text fact must be an object",
|
|
1825
|
-
index,
|
|
1826
|
-
value
|
|
1827
|
-
}
|
|
1828
|
-
};
|
|
1829
|
-
}
|
|
1830
|
-
const errors = [];
|
|
1831
|
-
if (!isNonEmptyString(value.fragmentId)) errors.push("fragmentId must be a non-empty string");
|
|
1832
|
-
if (typeof value.text !== "string") errors.push("text must be a string");
|
|
1833
|
-
if (value.cost !== void 0 && (typeof value.cost !== "number" || !Number.isFinite(value.cost) || value.cost < 0)) {
|
|
1834
|
-
errors.push("cost must be a finite number >= 0");
|
|
1835
|
-
}
|
|
1836
|
-
if (value.metadata !== void 0) {
|
|
1837
|
-
try {
|
|
1838
|
-
if (!isPlainRecord(value.metadata)) {
|
|
1839
|
-
throw new TypeError("metadata must be a plain object when present");
|
|
1840
|
-
}
|
|
1841
|
-
assertStrictJsonValue(value.metadata, "metadata");
|
|
1842
|
-
} catch (error) {
|
|
1843
|
-
errors.push(errorMessage(error));
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
if (errors.length > 0) {
|
|
1847
|
-
return {
|
|
1848
|
-
error: {
|
|
1849
|
-
code: "invalid-text",
|
|
1850
|
-
message: "agenticMemoryContextPackingBundle: text fact is invalid",
|
|
1851
|
-
index,
|
|
1852
|
-
fragmentId: typeof value.fragmentId === "string" ? value.fragmentId : void 0,
|
|
1853
|
-
value,
|
|
1854
|
-
validationErrors: Object.freeze(errors)
|
|
1855
|
-
}
|
|
1856
|
-
};
|
|
1857
|
-
}
|
|
1858
|
-
return {
|
|
1859
|
-
text: Object.freeze({
|
|
1860
|
-
fragmentId: value.fragmentId,
|
|
1861
|
-
text: value.text,
|
|
1862
|
-
...value.cost === void 0 ? {} : { cost: value.cost },
|
|
1863
|
-
...value.metadata === void 0 ? {} : { metadata: Object.freeze({ ...value.metadata }) }
|
|
1864
|
-
})
|
|
1865
|
-
};
|
|
1963
|
+
return { assertions, errors, invalidDrafts };
|
|
1866
1964
|
}
|
|
1867
|
-
function
|
|
1965
|
+
function validateKgDraft(value, index) {
|
|
1966
|
+
const errors = [];
|
|
1868
1967
|
if (!isPlainRecord(value)) {
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1968
|
+
return {
|
|
1969
|
+
errors: [
|
|
1970
|
+
{
|
|
1971
|
+
code: "invalid-draft",
|
|
1972
|
+
message: "agenticMemoryKgProjectionBundle: draft must be an object",
|
|
1973
|
+
index,
|
|
1974
|
+
draft: value
|
|
1975
|
+
}
|
|
1976
|
+
]
|
|
1977
|
+
};
|
|
1875
1978
|
}
|
|
1876
|
-
const
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
} catch (error) {
|
|
1887
|
-
errors.push({
|
|
1888
|
-
code: "invalid-policy",
|
|
1889
|
-
message: `agenticMemoryContextPackingBundle: policy access failed: ${errorMessage(error)}`,
|
|
1890
|
-
value,
|
|
1891
|
-
validationErrors: ["policy access failed"]
|
|
1892
|
-
});
|
|
1893
|
-
return void 0;
|
|
1979
|
+
const raw = value;
|
|
1980
|
+
const id = typeof raw.id === "string" && raw.id.length > 0 ? raw.id : void 0;
|
|
1981
|
+
const recordId = typeof raw.recordId === "string" && raw.recordId.length > 0 ? raw.recordId : void 0;
|
|
1982
|
+
const fragmentId = typeof raw.fragmentId === "string" && raw.fragmentId.length > 0 ? raw.fragmentId : void 0;
|
|
1983
|
+
const subject = validateAssertionSubject(raw.subject);
|
|
1984
|
+
const object = validateAssertionObject(raw.object);
|
|
1985
|
+
const shapeErrors = [];
|
|
1986
|
+
if (id === void 0) shapeErrors.push("draft.id must be a non-empty string");
|
|
1987
|
+
if (recordId === void 0) {
|
|
1988
|
+
shapeErrors.push("draft.recordId must be a non-empty string");
|
|
1894
1989
|
}
|
|
1895
|
-
if (
|
|
1896
|
-
|
|
1990
|
+
if (fragmentId === void 0) {
|
|
1991
|
+
shapeErrors.push("draft.fragmentId must be a non-empty string");
|
|
1897
1992
|
}
|
|
1898
|
-
|
|
1899
|
-
|
|
1993
|
+
shapeErrors.push(...subject.errors);
|
|
1994
|
+
if (typeof raw.predicate !== "string" || raw.predicate.length === 0) {
|
|
1995
|
+
shapeErrors.push("draft.predicate must be a non-empty string");
|
|
1900
1996
|
}
|
|
1901
|
-
|
|
1902
|
-
|
|
1997
|
+
shapeErrors.push(...object.errors);
|
|
1998
|
+
if (raw.confidence !== void 0 && (!Number.isFinite(raw.confidence) || raw.confidence < 0 || raw.confidence > 1)) {
|
|
1999
|
+
shapeErrors.push("draft.confidence must be a finite number in [0, 1]");
|
|
1903
2000
|
}
|
|
1904
|
-
if (
|
|
1905
|
-
|
|
2001
|
+
if (raw.sources !== void 0 && !isDenseArrayOf(raw.sources, isNonEmptyString)) {
|
|
2002
|
+
shapeErrors.push("draft.sources must be a readonly string array");
|
|
1906
2003
|
}
|
|
1907
|
-
if (
|
|
1908
|
-
|
|
1909
|
-
code: "invalid-policy",
|
|
1910
|
-
message: "agenticMemoryContextPackingBundle: policy is invalid",
|
|
1911
|
-
value,
|
|
1912
|
-
validationErrors: Object.freeze(validation)
|
|
1913
|
-
});
|
|
1914
|
-
return void 0;
|
|
2004
|
+
if (raw.provenance !== void 0 && typeof raw.provenance !== "string") {
|
|
2005
|
+
shapeErrors.push("draft.provenance must be a string when present");
|
|
1915
2006
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2007
|
+
if (shapeErrors.length > 0) errors.push(kgShapeError(index, value, ...shapeErrors));
|
|
2008
|
+
if (errors.length > 0 || id === void 0 || recordId === void 0 || fragmentId === void 0) {
|
|
2009
|
+
return { errors };
|
|
2010
|
+
}
|
|
2011
|
+
return {
|
|
2012
|
+
draft: Object.freeze({
|
|
2013
|
+
id,
|
|
2014
|
+
recordId,
|
|
2015
|
+
fragmentId,
|
|
2016
|
+
subject: subject.subject,
|
|
2017
|
+
predicate: raw.predicate,
|
|
2018
|
+
object: object.object,
|
|
2019
|
+
...raw.confidence === void 0 ? {} : { confidence: raw.confidence },
|
|
2020
|
+
...raw.sources === void 0 ? {} : { sources: Object.freeze([...raw.sources]) },
|
|
2021
|
+
...raw.provenance === void 0 ? {} : { provenance: raw.provenance }
|
|
2022
|
+
}),
|
|
2023
|
+
errors
|
|
2024
|
+
};
|
|
1922
2025
|
}
|
|
1923
|
-
function
|
|
1924
|
-
|
|
1925
|
-
const
|
|
1926
|
-
const
|
|
2026
|
+
function validateAssertionSubject(value) {
|
|
2027
|
+
if (!isPlainRecord(value)) return { errors: ["subject must be an object"] };
|
|
2028
|
+
const id = value.id;
|
|
2029
|
+
const type = value.type;
|
|
1927
2030
|
const errors = [];
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
if (!Array.isArray(value)) {
|
|
1932
|
-
errors.push({
|
|
1933
|
-
code: "invalid-records-input",
|
|
1934
|
-
message: "agenticMemoryBundle: records input must be an array",
|
|
1935
|
-
record: value
|
|
1936
|
-
});
|
|
1937
|
-
return { records, fragments, metadataByFragmentId, errors, invalidRecordIndexes };
|
|
2031
|
+
if (typeof id !== "string" || id.length === 0) errors.push("subject.id must be non-empty");
|
|
2032
|
+
if (type !== void 0 && (typeof type !== "string" || type.length === 0)) {
|
|
2033
|
+
errors.push("subject.type must be a non-empty string when present");
|
|
1938
2034
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
2035
|
+
if (errors.length > 0) return { errors };
|
|
2036
|
+
return {
|
|
2037
|
+
subject: Object.freeze({
|
|
2038
|
+
id,
|
|
2039
|
+
...type === void 0 ? {} : { type }
|
|
2040
|
+
}),
|
|
2041
|
+
errors
|
|
2042
|
+
};
|
|
2043
|
+
}
|
|
2044
|
+
function validateAssertionObject(value) {
|
|
2045
|
+
if (!isPlainRecord(value)) return { errors: ["object must be an object"] };
|
|
2046
|
+
const kind = value.kind;
|
|
2047
|
+
const errors = [];
|
|
2048
|
+
if (kind === "entity") {
|
|
2049
|
+
if (typeof value.id !== "string" || value.id.length === 0) {
|
|
2050
|
+
errors.push("object.id must be non-empty for entity objects");
|
|
2051
|
+
}
|
|
2052
|
+
if (value.type !== void 0 && (typeof value.type !== "string" || value.type.length === 0)) {
|
|
2053
|
+
errors.push("object.type must be a non-empty string when present");
|
|
2054
|
+
}
|
|
2055
|
+
if (Object.hasOwn(value, "value")) errors.push("entity object must not include value");
|
|
2056
|
+
if (errors.length > 0) return { errors };
|
|
2057
|
+
return {
|
|
2058
|
+
object: Object.freeze({
|
|
2059
|
+
kind: "entity",
|
|
2060
|
+
id: value.id,
|
|
2061
|
+
...value.type === void 0 ? {} : { type: value.type }
|
|
2062
|
+
}),
|
|
2063
|
+
errors
|
|
2064
|
+
};
|
|
1947
2065
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
message: `agenticMemoryBundle: record access failed: ${errorMessage(error)}`,
|
|
1957
|
-
index: i,
|
|
1958
|
-
validationErrors: Object.freeze(["record access failed"])
|
|
1959
|
-
});
|
|
1960
|
-
continue;
|
|
2066
|
+
if (kind === "value") {
|
|
2067
|
+
if (!Object.hasOwn(value, "value")) errors.push("value object must include value");
|
|
2068
|
+
else {
|
|
2069
|
+
try {
|
|
2070
|
+
assertStrictJsonValue(value.value, "object.value");
|
|
2071
|
+
} catch (error) {
|
|
2072
|
+
errors.push(errorMessage(error));
|
|
2073
|
+
}
|
|
1961
2074
|
}
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
invalidRecordIndexes.add(i);
|
|
1965
|
-
errors.push(...result.errors);
|
|
1966
|
-
continue;
|
|
2075
|
+
if (value.valueType !== void 0 && (typeof value.valueType !== "string" || value.valueType.length === 0)) {
|
|
2076
|
+
errors.push("object.valueType must be a non-empty string when present");
|
|
1967
2077
|
}
|
|
1968
|
-
if (
|
|
1969
|
-
if (
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2078
|
+
if (Object.hasOwn(value, "id")) errors.push("value object must not include id");
|
|
2079
|
+
if (errors.length > 0) return { errors };
|
|
2080
|
+
return {
|
|
2081
|
+
object: Object.freeze({
|
|
2082
|
+
kind: "value",
|
|
2083
|
+
value: value.value,
|
|
2084
|
+
...value.valueType === void 0 ? {} : { valueType: value.valueType }
|
|
2085
|
+
}),
|
|
2086
|
+
errors
|
|
2087
|
+
};
|
|
2088
|
+
}
|
|
2089
|
+
return { errors: ["object.kind must be entity or value"] };
|
|
2090
|
+
}
|
|
2091
|
+
function kgShapeError(index, draft, ...validationErrors) {
|
|
2092
|
+
return {
|
|
2093
|
+
code: "invalid-assertion-shape",
|
|
2094
|
+
message: "agenticMemoryKgProjectionBundle: draft assertion shape is invalid",
|
|
2095
|
+
index,
|
|
2096
|
+
draft,
|
|
2097
|
+
validationErrors: Object.freeze([...validationErrors])
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
function kgErrorFromRecordError(error) {
|
|
2101
|
+
return {
|
|
2102
|
+
...error,
|
|
2103
|
+
code: error.code
|
|
2104
|
+
};
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
// src/solutions/agentic-memory-retention.ts
|
|
2108
|
+
function agenticMemoryRetentionBundle(graph, opts) {
|
|
2109
|
+
const name = opts.name ?? "agenticMemoryRetention";
|
|
2110
|
+
const projection = graph.node(
|
|
2111
|
+
[opts.records, opts.commands],
|
|
2112
|
+
(ctx) => {
|
|
2113
|
+
const state = ctx.state.get() ?? { evaluation: 0 };
|
|
2114
|
+
state.evaluation += 1;
|
|
2115
|
+
const recordProjection = validateAndProjectRecords(depLatest(ctx, 0));
|
|
2116
|
+
const retention = projectRetention(depLatest(ctx, 1), recordProjection.records);
|
|
2117
|
+
const cursor = Object.freeze({
|
|
2118
|
+
evaluation: state.evaluation,
|
|
2119
|
+
validRecords: recordProjection.records.length,
|
|
2120
|
+
validCommands: retention.validCommands,
|
|
2121
|
+
invalidCommands: retention.invalidCommands,
|
|
2122
|
+
activeRecords: retention.activeRecords.length,
|
|
2123
|
+
archivedRecords: retention.archivedRecords.length,
|
|
2124
|
+
consolidationRequests: retention.consolidationRequests.length
|
|
1978
2125
|
});
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
recordId: result.record.id,
|
|
1988
|
-
fragmentId: result.record.fragment.id,
|
|
1989
|
-
record: raw,
|
|
1990
|
-
validationErrors: [`duplicate fragment id '${result.record.fragment.id}'`]
|
|
2126
|
+
const errors = Object.freeze(
|
|
2127
|
+
[...recordProjection.errors.map(retentionErrorFromRecordError), ...retention.errors].map(
|
|
2128
|
+
(error) => freezeError({ ...error, cursor })
|
|
2129
|
+
)
|
|
2130
|
+
);
|
|
2131
|
+
const status = Object.freeze({
|
|
2132
|
+
state: agenticStatusState(errors.length, recordProjection.records.length),
|
|
2133
|
+
cursor
|
|
1991
2134
|
});
|
|
1992
|
-
|
|
2135
|
+
ctx.state.set(state);
|
|
2136
|
+
ctx.down([
|
|
2137
|
+
[
|
|
2138
|
+
"DATA",
|
|
2139
|
+
Object.freeze({
|
|
2140
|
+
activeRecords: Object.freeze(retention.activeRecords),
|
|
2141
|
+
archivedRecords: Object.freeze(retention.archivedRecords),
|
|
2142
|
+
consolidationRequests: Object.freeze(retention.consolidationRequests),
|
|
2143
|
+
status,
|
|
2144
|
+
errors,
|
|
2145
|
+
cursor
|
|
2146
|
+
})
|
|
2147
|
+
]
|
|
2148
|
+
]);
|
|
2149
|
+
},
|
|
2150
|
+
{
|
|
2151
|
+
name: `${name}/projection`,
|
|
2152
|
+
factory: "agenticMemoryRetention",
|
|
2153
|
+
completeWhenDepsComplete: false,
|
|
2154
|
+
errorWhenDepsError: false
|
|
1993
2155
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
records.
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2156
|
+
);
|
|
2157
|
+
return {
|
|
2158
|
+
input: { records: opts.records, commands: opts.commands },
|
|
2159
|
+
projection,
|
|
2160
|
+
activeRecords: solutionProjection(
|
|
2161
|
+
graph,
|
|
2162
|
+
projection,
|
|
2163
|
+
`${name}/activeRecords`,
|
|
2164
|
+
"agenticMemoryRetentionActiveRecords",
|
|
2165
|
+
(fact) => fact.activeRecords
|
|
2166
|
+
),
|
|
2167
|
+
archivedRecords: solutionProjection(
|
|
2168
|
+
graph,
|
|
2169
|
+
projection,
|
|
2170
|
+
`${name}/archivedRecords`,
|
|
2171
|
+
"agenticMemoryRetentionArchivedRecords",
|
|
2172
|
+
(fact) => fact.archivedRecords
|
|
2173
|
+
),
|
|
2174
|
+
consolidationRequests: solutionProjection(
|
|
2175
|
+
graph,
|
|
2176
|
+
projection,
|
|
2177
|
+
`${name}/consolidationRequests`,
|
|
2178
|
+
"agenticMemoryRetentionConsolidationRequests",
|
|
2179
|
+
(fact) => fact.consolidationRequests
|
|
2180
|
+
),
|
|
2181
|
+
status: solutionProjection(
|
|
2182
|
+
graph,
|
|
2183
|
+
projection,
|
|
2184
|
+
`${name}/status`,
|
|
2185
|
+
"agenticMemoryRetentionStatus",
|
|
2186
|
+
(fact) => fact.status
|
|
2187
|
+
),
|
|
2188
|
+
errors: solutionProjection(
|
|
2189
|
+
graph,
|
|
2190
|
+
projection,
|
|
2191
|
+
`${name}/errors`,
|
|
2192
|
+
"agenticMemoryRetentionErrors",
|
|
2193
|
+
(fact) => fact.errors
|
|
2194
|
+
),
|
|
2195
|
+
cursor: solutionProjection(
|
|
2196
|
+
graph,
|
|
2197
|
+
projection,
|
|
2198
|
+
`${name}/cursor`,
|
|
2199
|
+
"agenticMemoryRetentionCursor",
|
|
2200
|
+
(fact) => fact.cursor
|
|
2201
|
+
)
|
|
2202
|
+
};
|
|
2001
2203
|
}
|
|
2002
|
-
function
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2204
|
+
function projectRetention(value, records) {
|
|
2205
|
+
const byId = new Map(records.map((record) => [record.id, record]));
|
|
2206
|
+
const view = new Map(records.map((record) => [record.id, record]));
|
|
2207
|
+
const requests = [];
|
|
2208
|
+
const errors = [];
|
|
2209
|
+
let validCommands = 0;
|
|
2210
|
+
let invalidCommands = 0;
|
|
2211
|
+
if (!Array.isArray(value)) {
|
|
2006
2212
|
return {
|
|
2213
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
2214
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
2215
|
+
consolidationRequests: requests,
|
|
2216
|
+
validCommands,
|
|
2217
|
+
invalidCommands: 1,
|
|
2007
2218
|
errors: [
|
|
2008
2219
|
{
|
|
2009
|
-
code: "invalid-
|
|
2010
|
-
message:
|
|
2011
|
-
|
|
2012
|
-
record: value,
|
|
2013
|
-
validationErrors: Object.freeze(["record access failed"])
|
|
2220
|
+
code: "invalid-commands-input",
|
|
2221
|
+
message: "agenticMemoryRetentionBundle: commands input must be an array",
|
|
2222
|
+
command: value
|
|
2014
2223
|
}
|
|
2015
2224
|
]
|
|
2016
2225
|
};
|
|
2017
2226
|
}
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
const errors = [];
|
|
2021
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2227
|
+
const length = safeArrayLength(value);
|
|
2228
|
+
if (length === void 0) {
|
|
2022
2229
|
return {
|
|
2230
|
+
activeRecords: records.filter((record) => record.persistenceLevel !== "archived"),
|
|
2231
|
+
archivedRecords: records.filter((record) => record.persistenceLevel === "archived"),
|
|
2232
|
+
consolidationRequests: requests,
|
|
2233
|
+
validCommands,
|
|
2234
|
+
invalidCommands: 1,
|
|
2023
2235
|
errors: [
|
|
2024
2236
|
{
|
|
2025
|
-
code: "invalid-
|
|
2026
|
-
message: "
|
|
2027
|
-
|
|
2028
|
-
record: value
|
|
2237
|
+
code: "invalid-commands-input",
|
|
2238
|
+
message: "agenticMemoryRetentionBundle: commands input length could not be read",
|
|
2239
|
+
command: value
|
|
2029
2240
|
}
|
|
2030
2241
|
]
|
|
2031
2242
|
};
|
|
2032
2243
|
}
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
});
|
|
2086
|
-
}
|
|
2087
|
-
const fragmentValidation = validateMemoryFragment(record.fragment);
|
|
2088
|
-
if (!fragmentValidation.ok) {
|
|
2089
|
-
errors.push({
|
|
2090
|
-
code: "invalid-fragment",
|
|
2091
|
-
message: "agenticMemoryBundle: record.fragment is invalid",
|
|
2092
|
-
index,
|
|
2093
|
-
recordId,
|
|
2094
|
-
fragmentId: typeof record.fragment === "object" && record.fragment !== null && typeof record.fragment.id === "string" ? record.fragment.id : void 0,
|
|
2095
|
-
record: value,
|
|
2096
|
-
validationErrors: Object.freeze([...fragmentValidation.errors])
|
|
2097
|
-
});
|
|
2098
|
-
}
|
|
2099
|
-
const forbiddenFields = [
|
|
2100
|
-
"storageTier",
|
|
2101
|
-
"storageKey",
|
|
2102
|
-
"adapter",
|
|
2103
|
-
"collection",
|
|
2104
|
-
"collections",
|
|
2105
|
-
"ttl",
|
|
2106
|
-
"ttlMs",
|
|
2107
|
-
"ttlNs",
|
|
2108
|
-
"expiresAt",
|
|
2109
|
-
"timer",
|
|
2110
|
-
"scheduler",
|
|
2111
|
-
"schedule",
|
|
2112
|
-
"retentionTimer",
|
|
2113
|
-
"consolidationSchedule",
|
|
2114
|
-
"reflectionSchedule",
|
|
2115
|
-
"llm",
|
|
2116
|
-
"llmHandle",
|
|
2117
|
-
"tool",
|
|
2118
|
-
"toolHandle",
|
|
2119
|
-
"runner",
|
|
2120
|
-
"runnerHandle",
|
|
2121
|
-
"restore",
|
|
2122
|
-
"hydrate",
|
|
2123
|
-
"hydration",
|
|
2124
|
-
"graphMutation",
|
|
2125
|
-
"protocol"
|
|
2126
|
-
];
|
|
2127
|
-
const presentForbidden = forbiddenFields.filter((field) => Object.hasOwn(record, field));
|
|
2128
|
-
if (presentForbidden.length > 0) {
|
|
2129
|
-
errors.push({
|
|
2130
|
-
code: "invalid-record",
|
|
2131
|
-
message: "agenticMemoryBundle: record contains forbidden runtime/persistence fields",
|
|
2132
|
-
index,
|
|
2133
|
-
recordId,
|
|
2134
|
-
record: value,
|
|
2135
|
-
validationErrors: Object.freeze(
|
|
2136
|
-
presentForbidden.map((field) => `${field} is not part of AgenticMemoryRecord`)
|
|
2137
|
-
)
|
|
2138
|
-
});
|
|
2244
|
+
const seenCommands = /* @__PURE__ */ new Set();
|
|
2245
|
+
for (let i = 0; i < length; i += 1) {
|
|
2246
|
+
let raw;
|
|
2247
|
+
try {
|
|
2248
|
+
raw = value[i];
|
|
2249
|
+
const result = validateRetentionCommand(raw, i);
|
|
2250
|
+
if (result.errors.length > 0 || result.command === void 0) {
|
|
2251
|
+
invalidCommands += 1;
|
|
2252
|
+
errors.push(...result.errors);
|
|
2253
|
+
continue;
|
|
2254
|
+
}
|
|
2255
|
+
const command = result.command;
|
|
2256
|
+
if (seenCommands.has(command.id)) {
|
|
2257
|
+
invalidCommands += 1;
|
|
2258
|
+
errors.push({
|
|
2259
|
+
code: "duplicate-command-id",
|
|
2260
|
+
message: "agenticMemoryRetentionBundle: duplicate command id",
|
|
2261
|
+
index: i,
|
|
2262
|
+
commandId: command.id,
|
|
2263
|
+
command: raw,
|
|
2264
|
+
validationErrors: [`duplicate command id '${command.id}'`]
|
|
2265
|
+
});
|
|
2266
|
+
continue;
|
|
2267
|
+
}
|
|
2268
|
+
const missing = retentionMissingRecords(command, byId);
|
|
2269
|
+
if (missing.length > 0) {
|
|
2270
|
+
invalidCommands += 1;
|
|
2271
|
+
errors.push({
|
|
2272
|
+
code: "missing-record-ref",
|
|
2273
|
+
message: "agenticMemoryRetentionBundle: command references missing records",
|
|
2274
|
+
index: i,
|
|
2275
|
+
commandId: command.id,
|
|
2276
|
+
recordId: "recordId" in command ? command.recordId : void 0,
|
|
2277
|
+
recordIds: Object.freeze(missing),
|
|
2278
|
+
command: raw,
|
|
2279
|
+
validationErrors: Object.freeze(missing.map((id) => `record '${id}' is not projected`))
|
|
2280
|
+
});
|
|
2281
|
+
continue;
|
|
2282
|
+
}
|
|
2283
|
+
seenCommands.add(command.id);
|
|
2284
|
+
validCommands += 1;
|
|
2285
|
+
applyRetentionCommand(command, byId, view, requests);
|
|
2286
|
+
} catch (error) {
|
|
2287
|
+
invalidCommands += 1;
|
|
2288
|
+
errors.push({
|
|
2289
|
+
code: "invalid-command",
|
|
2290
|
+
message: `agenticMemoryRetentionBundle: command access failed: ${errorMessage(error)}`,
|
|
2291
|
+
index: i,
|
|
2292
|
+
command: raw,
|
|
2293
|
+
validationErrors: ["command access failed"]
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2139
2296
|
}
|
|
2140
|
-
|
|
2141
|
-
const scope = scopeValidation.scope;
|
|
2142
|
-
const fragment = snapshotFragment(record.fragment);
|
|
2297
|
+
const projected = records.map((record) => view.get(record.id) ?? record);
|
|
2143
2298
|
return {
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
fragment
|
|
2151
|
-
}),
|
|
2152
|
-
errors
|
|
2299
|
+
activeRecords: projected.filter((record) => record.persistenceLevel !== "archived"),
|
|
2300
|
+
archivedRecords: projected.filter((record) => record.persistenceLevel === "archived"),
|
|
2301
|
+
consolidationRequests: requests,
|
|
2302
|
+
errors,
|
|
2303
|
+
validCommands,
|
|
2304
|
+
invalidCommands
|
|
2153
2305
|
};
|
|
2154
2306
|
}
|
|
2155
|
-
function
|
|
2156
|
-
return Object.freeze({
|
|
2157
|
-
id: fragment.id,
|
|
2158
|
-
payload: fragment.payload,
|
|
2159
|
-
tNs: fragment.tNs,
|
|
2160
|
-
...fragment.validFrom === void 0 ? {} : { validFrom: fragment.validFrom },
|
|
2161
|
-
...fragment.validTo === void 0 ? {} : { validTo: fragment.validTo },
|
|
2162
|
-
confidence: fragment.confidence,
|
|
2163
|
-
tags: Object.freeze([...fragment.tags]),
|
|
2164
|
-
sources: Object.freeze([...fragment.sources]),
|
|
2165
|
-
...fragment.embedding === void 0 ? {} : { embedding: Object.freeze([...fragment.embedding]) },
|
|
2166
|
-
...fragment.parentFragmentId === void 0 ? {} : { parentFragmentId: fragment.parentFragmentId },
|
|
2167
|
-
...fragment.provenance === void 0 ? {} : { provenance: fragment.provenance }
|
|
2168
|
-
});
|
|
2169
|
-
}
|
|
2170
|
-
function recordMetadata(record) {
|
|
2171
|
-
return Object.freeze({
|
|
2172
|
-
recordId: record.id,
|
|
2173
|
-
kind: record.kind,
|
|
2174
|
-
persistenceLevel: record.persistenceLevel,
|
|
2175
|
-
artifactKind: record.artifactKind,
|
|
2176
|
-
...record.scope === void 0 ? {} : { scope: record.scope }
|
|
2177
|
-
});
|
|
2178
|
-
}
|
|
2179
|
-
function validateRecordMetadata(value) {
|
|
2180
|
-
if (value === void 0) return { ok: true, errors: [] };
|
|
2307
|
+
function validateRetentionCommand(value, index) {
|
|
2181
2308
|
if (!isPlainRecord(value)) {
|
|
2182
|
-
return {
|
|
2309
|
+
return {
|
|
2310
|
+
errors: [
|
|
2311
|
+
{
|
|
2312
|
+
code: "invalid-command",
|
|
2313
|
+
message: "agenticMemoryRetentionBundle: command must be an object",
|
|
2314
|
+
index,
|
|
2315
|
+
command: value
|
|
2316
|
+
}
|
|
2317
|
+
]
|
|
2318
|
+
};
|
|
2183
2319
|
}
|
|
2320
|
+
const id = typeof value.id === "string" && value.id.length > 0 ? value.id : void 0;
|
|
2321
|
+
const kind = value.kind;
|
|
2184
2322
|
const errors = [];
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
}
|
|
2323
|
+
if (id === void 0) errors.push("command.id must be a non-empty string");
|
|
2324
|
+
if (kind !== "archive" && kind !== "restore" && kind !== "setPersistenceLevel" && kind !== "requestConsolidation") {
|
|
2325
|
+
errors.push("command.kind is invalid");
|
|
2189
2326
|
}
|
|
2190
|
-
if (
|
|
2191
|
-
errors.push("
|
|
2327
|
+
if (value.reason !== void 0 && typeof value.reason !== "string") {
|
|
2328
|
+
errors.push("command.reason must be a string when present");
|
|
2192
2329
|
}
|
|
2193
|
-
if (
|
|
2194
|
-
errors.push("
|
|
2330
|
+
if (kind === "archive") {
|
|
2331
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
2332
|
+
} else if (kind === "restore") {
|
|
2333
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
2334
|
+
if (value.persistenceLevel !== void 0 && (!isAgenticMemoryPersistenceLevel(value.persistenceLevel) || value.persistenceLevel === "archived")) {
|
|
2335
|
+
errors.push("restore.persistenceLevel must be a non-archived persistence level when present");
|
|
2336
|
+
}
|
|
2337
|
+
} else if (kind === "setPersistenceLevel") {
|
|
2338
|
+
if (!isNonEmptyString(value.recordId)) errors.push("command.recordId must be non-empty");
|
|
2339
|
+
if (!isAgenticMemoryPersistenceLevel(value.persistenceLevel)) {
|
|
2340
|
+
errors.push("setPersistenceLevel.persistenceLevel is invalid");
|
|
2341
|
+
}
|
|
2342
|
+
} else if (kind === "requestConsolidation") {
|
|
2343
|
+
if (!isDenseArrayOf(value.recordIds, isNonEmptyString) || value.recordIds.length === 0) {
|
|
2344
|
+
errors.push("requestConsolidation.recordIds must be a non-empty string array");
|
|
2345
|
+
}
|
|
2346
|
+
if (value.requestId !== void 0 && (typeof value.requestId !== "string" || value.requestId.length === 0)) {
|
|
2347
|
+
errors.push("requestConsolidation.requestId must be non-empty when present");
|
|
2348
|
+
}
|
|
2195
2349
|
}
|
|
2196
|
-
if (
|
|
2197
|
-
|
|
2350
|
+
if (errors.length > 0 || id === void 0) {
|
|
2351
|
+
return {
|
|
2352
|
+
errors: [
|
|
2353
|
+
{
|
|
2354
|
+
code: "invalid-command",
|
|
2355
|
+
message: "agenticMemoryRetentionBundle: command is invalid",
|
|
2356
|
+
index,
|
|
2357
|
+
commandId: id,
|
|
2358
|
+
command: value,
|
|
2359
|
+
validationErrors: Object.freeze(errors)
|
|
2360
|
+
}
|
|
2361
|
+
]
|
|
2362
|
+
};
|
|
2198
2363
|
}
|
|
2199
|
-
|
|
2200
|
-
|
|
2364
|
+
const base = { id, reason: value.reason };
|
|
2365
|
+
if (kind === "archive") {
|
|
2366
|
+
return {
|
|
2367
|
+
command: Object.freeze({
|
|
2368
|
+
...base,
|
|
2369
|
+
kind,
|
|
2370
|
+
recordId: value.recordId,
|
|
2371
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
2372
|
+
}),
|
|
2373
|
+
errors: []
|
|
2374
|
+
};
|
|
2201
2375
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2376
|
+
if (kind === "restore") {
|
|
2377
|
+
return {
|
|
2378
|
+
command: Object.freeze({
|
|
2379
|
+
...base,
|
|
2380
|
+
kind,
|
|
2381
|
+
recordId: value.recordId,
|
|
2382
|
+
...value.persistenceLevel === void 0 ? {} : {
|
|
2383
|
+
persistenceLevel: value.persistenceLevel
|
|
2384
|
+
},
|
|
2385
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
2386
|
+
}),
|
|
2387
|
+
errors: []
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
if (kind === "setPersistenceLevel") {
|
|
2391
|
+
return {
|
|
2392
|
+
command: Object.freeze({
|
|
2393
|
+
...base,
|
|
2394
|
+
kind,
|
|
2395
|
+
recordId: value.recordId,
|
|
2396
|
+
persistenceLevel: value.persistenceLevel,
|
|
2397
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
2398
|
+
}),
|
|
2399
|
+
errors: []
|
|
2400
|
+
};
|
|
2205
2401
|
}
|
|
2206
|
-
if (errors.length > 0) return { ok: false, errors };
|
|
2207
2402
|
return {
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
})
|
|
2403
|
+
command: Object.freeze({
|
|
2404
|
+
...base,
|
|
2405
|
+
kind: "requestConsolidation",
|
|
2406
|
+
recordIds: Object.freeze([...value.recordIds]),
|
|
2407
|
+
...value.requestId === void 0 ? {} : { requestId: value.requestId },
|
|
2408
|
+
...base.reason === void 0 ? {} : { reason: base.reason }
|
|
2409
|
+
}),
|
|
2410
|
+
errors: []
|
|
2217
2411
|
};
|
|
2218
2412
|
}
|
|
2219
|
-
function
|
|
2220
|
-
if (
|
|
2221
|
-
|
|
2222
|
-
return retrieval;
|
|
2413
|
+
function retentionMissingRecords(command, records) {
|
|
2414
|
+
if ("recordId" in command) return records.has(command.recordId) ? [] : [command.recordId];
|
|
2415
|
+
return command.recordIds.filter((recordId) => !records.has(recordId));
|
|
2223
2416
|
}
|
|
2224
|
-
function
|
|
2225
|
-
if (
|
|
2226
|
-
|
|
2227
|
-
|
|
2417
|
+
function applyRetentionCommand(command, source, view, requests) {
|
|
2418
|
+
if (command.kind === "requestConsolidation") {
|
|
2419
|
+
requests.push(
|
|
2420
|
+
Object.freeze({
|
|
2421
|
+
id: command.requestId ?? command.id,
|
|
2422
|
+
commandId: command.id,
|
|
2423
|
+
recordIds: Object.freeze([...command.recordIds]),
|
|
2424
|
+
...command.reason === void 0 ? {} : { reason: command.reason }
|
|
2425
|
+
})
|
|
2426
|
+
);
|
|
2427
|
+
return;
|
|
2428
|
+
}
|
|
2429
|
+
const record = view.get(command.recordId) ?? source.get(command.recordId);
|
|
2430
|
+
if (record === void 0) return;
|
|
2431
|
+
const persistenceLevel = command.kind === "archive" ? "archived" : command.kind === "restore" ? command.persistenceLevel ?? nonArchivedLevel(source.get(command.recordId) ?? record) : command.persistenceLevel;
|
|
2432
|
+
view.set(command.recordId, withPersistenceLevel(record, persistenceLevel));
|
|
2228
2433
|
}
|
|
2229
|
-
function
|
|
2230
|
-
return
|
|
2434
|
+
function nonArchivedLevel(record) {
|
|
2435
|
+
return record.persistenceLevel === "archived" ? "session" : record.persistenceLevel;
|
|
2231
2436
|
}
|
|
2232
|
-
function
|
|
2233
|
-
return
|
|
2437
|
+
function withPersistenceLevel(record, persistenceLevel) {
|
|
2438
|
+
return Object.freeze({
|
|
2439
|
+
...record,
|
|
2440
|
+
persistenceLevel
|
|
2441
|
+
});
|
|
2234
2442
|
}
|
|
2235
|
-
function
|
|
2236
|
-
return
|
|
2443
|
+
function retentionErrorFromRecordError(error) {
|
|
2444
|
+
return {
|
|
2445
|
+
...error,
|
|
2446
|
+
code: error.code
|
|
2447
|
+
};
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
// src/solutions/capability-admission.ts
|
|
2451
|
+
function capabilityAdmissionProposal(opts) {
|
|
2452
|
+
return { kind: "capability-admission-proposal", ...opts };
|
|
2453
|
+
}
|
|
2454
|
+
function capabilityAdmissionProjector(graph, opts) {
|
|
2455
|
+
const name = opts.name ?? "capabilityAdmissions";
|
|
2456
|
+
const policyDeps = opts.admissionPolicies ?? [];
|
|
2457
|
+
const now = opts.now ?? Date.now;
|
|
2458
|
+
const runtime = graph.node(
|
|
2459
|
+
[opts.proposals, opts.decisions, ...policyDeps],
|
|
2460
|
+
(ctx) => {
|
|
2461
|
+
const state = ctx.state.get() ?? emptyCapabilityAdmissionState();
|
|
2462
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2463
|
+
const proposal = raw;
|
|
2464
|
+
const issue = capabilityAdmissionProposalIssue(proposal);
|
|
2465
|
+
if (issue !== void 0) {
|
|
2466
|
+
emitIssue(
|
|
2467
|
+
ctx,
|
|
2468
|
+
state,
|
|
2469
|
+
nextMalformedIssueKey(state, "proposal", proposalKeyFallback(proposal)),
|
|
2470
|
+
issue
|
|
2471
|
+
);
|
|
2472
|
+
continue;
|
|
2473
|
+
}
|
|
2474
|
+
if (state.proposals.has(proposal.proposalId)) {
|
|
2475
|
+
emitIssue(
|
|
2476
|
+
ctx,
|
|
2477
|
+
state,
|
|
2478
|
+
`duplicate-proposal:${proposal.proposalId}`,
|
|
2479
|
+
dataIssue(
|
|
2480
|
+
"duplicate-capability-admission-proposal",
|
|
2481
|
+
`CapabilityAdmissionProposal '${proposal.proposalId}' was already seen`,
|
|
2482
|
+
{ subjectId: proposal.subjectId, refs: capabilityProposalRefs(proposal) }
|
|
2483
|
+
)
|
|
2484
|
+
);
|
|
2485
|
+
continue;
|
|
2486
|
+
}
|
|
2487
|
+
state.proposals.set(proposal.proposalId, proposal);
|
|
2488
|
+
}
|
|
2489
|
+
forEachPolicyDepBatch(ctx, 2, policyDeps.length, (raw) => {
|
|
2490
|
+
const policy = raw;
|
|
2491
|
+
const issue = capabilityAdmissionPolicyIssue(policy);
|
|
2492
|
+
if (issue !== void 0) {
|
|
2493
|
+
emitIssue(
|
|
2494
|
+
ctx,
|
|
2495
|
+
state,
|
|
2496
|
+
nextMalformedIssueKey(state, "policy", policyKeyFallback(policy)),
|
|
2497
|
+
issue
|
|
2498
|
+
);
|
|
2499
|
+
return;
|
|
2500
|
+
}
|
|
2501
|
+
if (state.policies.has(policy.policyId)) {
|
|
2502
|
+
emitIssue(
|
|
2503
|
+
ctx,
|
|
2504
|
+
state,
|
|
2505
|
+
`duplicate-policy:${policy.policyId}`,
|
|
2506
|
+
dataIssue(
|
|
2507
|
+
"duplicate-capability-admission-policy",
|
|
2508
|
+
`CapabilityAdmissionPolicy '${policy.policyId}' was already seen`,
|
|
2509
|
+
{ refs: [ref("capability-admission-policy", policy.policyId)] }
|
|
2510
|
+
)
|
|
2511
|
+
);
|
|
2512
|
+
return;
|
|
2513
|
+
}
|
|
2514
|
+
state.policies.set(policy.policyId, policy);
|
|
2515
|
+
});
|
|
2516
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
2517
|
+
const decision = raw;
|
|
2518
|
+
const issue = capabilityAdmissionDecisionIssue(decision);
|
|
2519
|
+
if (issue !== void 0) {
|
|
2520
|
+
emitIssue(
|
|
2521
|
+
ctx,
|
|
2522
|
+
state,
|
|
2523
|
+
nextMalformedIssueKey(state, "decision", decisionKeyFallback(decision)),
|
|
2524
|
+
issue
|
|
2525
|
+
);
|
|
2526
|
+
continue;
|
|
2527
|
+
}
|
|
2528
|
+
if (state.decisions.has(decision.decisionId)) {
|
|
2529
|
+
emitIssue(
|
|
2530
|
+
ctx,
|
|
2531
|
+
state,
|
|
2532
|
+
`duplicate-decision:${decision.decisionId}`,
|
|
2533
|
+
dataIssue(
|
|
2534
|
+
"duplicate-capability-admission-decision",
|
|
2535
|
+
`CapabilityAdmissionDecision '${decision.decisionId}' was already seen`,
|
|
2536
|
+
{ refs: capabilityDecisionRefs(decision) }
|
|
2537
|
+
)
|
|
2538
|
+
);
|
|
2539
|
+
continue;
|
|
2540
|
+
}
|
|
2541
|
+
state.decisions.set(decision.decisionId, decision);
|
|
2542
|
+
}
|
|
2543
|
+
evaluateCapabilityAdmissions(ctx, state, now());
|
|
2544
|
+
ctx.state.set(state);
|
|
2545
|
+
},
|
|
2546
|
+
{ name: `${name}/runtime`, factory: "capabilityAdmissionProjector", partial: true }
|
|
2547
|
+
);
|
|
2548
|
+
return {
|
|
2549
|
+
admissions: projectRuntimeFact(
|
|
2550
|
+
graph,
|
|
2551
|
+
runtime,
|
|
2552
|
+
`${name}/admissions`,
|
|
2553
|
+
"capabilityAdmissions",
|
|
2554
|
+
(fact) => fact.kind === "admission" ? fact.admission : void 0
|
|
2555
|
+
),
|
|
2556
|
+
status: projectRuntimeFact(
|
|
2557
|
+
graph,
|
|
2558
|
+
runtime,
|
|
2559
|
+
`${name}/status`,
|
|
2560
|
+
"capabilityAdmissionStatus",
|
|
2561
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
2562
|
+
),
|
|
2563
|
+
issues: projectRuntimeFact(
|
|
2564
|
+
graph,
|
|
2565
|
+
runtime,
|
|
2566
|
+
`${name}/issues`,
|
|
2567
|
+
"capabilityAdmissionIssues",
|
|
2568
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
2569
|
+
),
|
|
2570
|
+
audit: projectRuntimeFact(
|
|
2571
|
+
graph,
|
|
2572
|
+
runtime,
|
|
2573
|
+
`${name}/audit`,
|
|
2574
|
+
"capabilityAdmissionAudit",
|
|
2575
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
2576
|
+
),
|
|
2577
|
+
views: capabilityAdmissionViews(graph, runtime, `${name}/views`)
|
|
2578
|
+
};
|
|
2237
2579
|
}
|
|
2238
|
-
function
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2580
|
+
function evaluateCapabilityAdmissions(ctx, state, admittedAtMs) {
|
|
2581
|
+
for (const decision of state.decisions.values()) {
|
|
2582
|
+
if (state.terminalDecisionIds.has(decision.decisionId)) continue;
|
|
2583
|
+
evaluateCapabilityAdmission(ctx, state, decision, admittedAtMs);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
function evaluateCapabilityAdmission(ctx, state, decision, admittedAtMs) {
|
|
2587
|
+
const proposal = state.proposals.get(decision.proposalId);
|
|
2588
|
+
if (proposal === void 0) {
|
|
2589
|
+
emitIssue(
|
|
2590
|
+
ctx,
|
|
2591
|
+
state,
|
|
2592
|
+
`missing-proposal:${decision.decisionId}:${decision.proposalId}`,
|
|
2593
|
+
dataIssue(
|
|
2594
|
+
"missing-capability-admission-proposal",
|
|
2595
|
+
`CapabilityAdmissionDecision '${decision.decisionId}' references missing proposal '${decision.proposalId}'`,
|
|
2596
|
+
{ subjectId: decision.proposalId, refs: capabilityDecisionRefs(decision) }
|
|
2597
|
+
)
|
|
2598
|
+
);
|
|
2599
|
+
return;
|
|
2242
2600
|
}
|
|
2243
|
-
const
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2601
|
+
const policy = capabilityPolicyForDecision(state, decision);
|
|
2602
|
+
if (typeof policy === "string") {
|
|
2603
|
+
emitIssue(
|
|
2604
|
+
ctx,
|
|
2605
|
+
state,
|
|
2606
|
+
`${policy}:${decision.decisionId}:${decision.policyId ?? "missing"}`,
|
|
2607
|
+
dataIssue(policy, capabilityPolicyIssueMessage(policy, decision), {
|
|
2608
|
+
subjectId: proposal.subjectId,
|
|
2609
|
+
refs: capabilityDecisionRefs(decision, proposal)
|
|
2610
|
+
})
|
|
2611
|
+
);
|
|
2612
|
+
if (policy === "stale-capability-admission-policy-ref")
|
|
2613
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
2614
|
+
return;
|
|
2248
2615
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2616
|
+
if (policy !== void 0) {
|
|
2617
|
+
const policyIssue = validateCapabilityAdmissionPolicy(policy, decision, proposal);
|
|
2618
|
+
if (policyIssue !== void 0) {
|
|
2619
|
+
emitIssue(
|
|
2620
|
+
ctx,
|
|
2621
|
+
state,
|
|
2622
|
+
`${policyIssue.code}:${decision.decisionId}:${policy.policyId}`,
|
|
2623
|
+
dataIssue(policyIssue.code, policyIssue.message, {
|
|
2624
|
+
subjectId: proposal.subjectId,
|
|
2625
|
+
refs: capabilityDecisionRefs(decision, proposal, policy)
|
|
2626
|
+
})
|
|
2627
|
+
);
|
|
2628
|
+
return;
|
|
2252
2629
|
}
|
|
2253
2630
|
}
|
|
2254
|
-
if (
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2268
|
-
}
|
|
2269
|
-
function ownKeys(value) {
|
|
2270
|
-
return Object.keys(value).sort();
|
|
2271
|
-
}
|
|
2272
|
-
function assertExactKeys(value, expected, label) {
|
|
2273
|
-
const actual = ownKeys(value);
|
|
2274
|
-
const want = [...expected].sort();
|
|
2275
|
-
if (actual.length !== want.length || actual.some((key, i) => key !== want[i])) {
|
|
2276
|
-
throw new TypeError(`${label}: unexpected fields ${actual.join(",")}`);
|
|
2631
|
+
if (state.admissionsById.has(decision.admissionId)) {
|
|
2632
|
+
emitIssue(
|
|
2633
|
+
ctx,
|
|
2634
|
+
state,
|
|
2635
|
+
`duplicate-admission-id:${decision.admissionId}`,
|
|
2636
|
+
dataIssue(
|
|
2637
|
+
"duplicate-capability-admission",
|
|
2638
|
+
`CapabilityAdmission '${decision.admissionId}' was already emitted`,
|
|
2639
|
+
{ subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
|
|
2640
|
+
)
|
|
2641
|
+
);
|
|
2642
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
2643
|
+
return;
|
|
2277
2644
|
}
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2645
|
+
if (state.admissionsByProposal.has(decision.proposalId)) {
|
|
2646
|
+
emitIssue(
|
|
2647
|
+
ctx,
|
|
2648
|
+
state,
|
|
2649
|
+
`duplicate-admission-proposal:${decision.proposalId}:${decision.decisionId}`,
|
|
2650
|
+
dataIssue(
|
|
2651
|
+
"duplicate-capability-admission-proposal",
|
|
2652
|
+
`CapabilityAdmissionProposal '${decision.proposalId}' already has an admission decision`,
|
|
2653
|
+
{ subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
|
|
2654
|
+
)
|
|
2655
|
+
);
|
|
2656
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
2657
|
+
return;
|
|
2282
2658
|
}
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2659
|
+
const admissionState = admissionStateForOutcome(decision.outcome);
|
|
2660
|
+
if (admissionState === void 0) {
|
|
2661
|
+
emitIssue(
|
|
2662
|
+
ctx,
|
|
2663
|
+
state,
|
|
2664
|
+
`unsupported-outcome:${decision.decisionId}:${String(decision.outcome)}`,
|
|
2665
|
+
dataIssue(
|
|
2666
|
+
"unsupported-capability-admission-outcome",
|
|
2667
|
+
`CapabilityAdmissionDecision '${decision.decisionId}' uses unsupported outcome '${String(decision.outcome)}'`,
|
|
2668
|
+
{ subjectId: proposal.subjectId, refs: capabilityDecisionRefs(decision, proposal, policy) }
|
|
2669
|
+
)
|
|
2670
|
+
);
|
|
2671
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
2672
|
+
return;
|
|
2292
2673
|
}
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2674
|
+
const admission = {
|
|
2675
|
+
kind: "capability-admission",
|
|
2676
|
+
admissionId: decision.admissionId,
|
|
2677
|
+
proposalId: proposal.proposalId,
|
|
2678
|
+
subjectId: proposal.subjectId,
|
|
2679
|
+
capability: cloneCapabilityRef(proposal.capability),
|
|
2680
|
+
state: admissionState,
|
|
2681
|
+
decisionId: decision.decisionId,
|
|
2682
|
+
boundaryName: proposal.boundaryName,
|
|
2683
|
+
role: proposal.role,
|
|
2684
|
+
policyId: decision.policyId,
|
|
2685
|
+
reason: decision.reason ?? proposal.reason,
|
|
2686
|
+
sourceRefs: capabilityDecisionRefs(decision, proposal, policy),
|
|
2687
|
+
admittedAtMs: decision.decidedAtMs ?? admittedAtMs,
|
|
2688
|
+
metadata: {
|
|
2689
|
+
...proposal.metadata ?? {},
|
|
2690
|
+
...policy?.metadata ?? {},
|
|
2691
|
+
...decision.metadata ?? {}
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2694
|
+
state.admissionsById.set(admission.admissionId, admission);
|
|
2695
|
+
state.admissionsByProposal.set(admission.proposalId, admission);
|
|
2696
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
2697
|
+
emitAdmission(ctx, state, admission);
|
|
2698
|
+
}
|
|
2699
|
+
function capabilityAdmissionViews(graph, runtime, name) {
|
|
2700
|
+
return graph.node(
|
|
2701
|
+
[runtime],
|
|
2702
|
+
(ctx) => {
|
|
2703
|
+
const state = ctx.state.get() ?? {
|
|
2704
|
+
admissionsByProposal: /* @__PURE__ */ new Map(),
|
|
2705
|
+
admissionsBySubject: /* @__PURE__ */ new Map(),
|
|
2706
|
+
issues: [],
|
|
2707
|
+
audit: []
|
|
2708
|
+
};
|
|
2709
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2710
|
+
const fact = raw;
|
|
2711
|
+
if (fact.kind === "admission") {
|
|
2712
|
+
const admission = fact.admission;
|
|
2713
|
+
state.admissionsByProposal.set(admission.proposalId, admission);
|
|
2714
|
+
const bySubject = state.admissionsBySubject.get(admission.subjectId) ?? [];
|
|
2715
|
+
bySubject.push(admission);
|
|
2716
|
+
state.admissionsBySubject.set(admission.subjectId, bySubject);
|
|
2717
|
+
}
|
|
2718
|
+
if (fact.kind === "issue") state.issues.push(fact.issue);
|
|
2719
|
+
if (fact.kind === "audit") state.audit.push(fact.audit);
|
|
2720
|
+
}
|
|
2721
|
+
ctx.state.set(state);
|
|
2722
|
+
ctx.down([["DATA", freezeCapabilityAdmissionViews(state)]]);
|
|
2723
|
+
},
|
|
2724
|
+
{ name, factory: "capabilityAdmissionViews" }
|
|
2310
2725
|
);
|
|
2311
|
-
assertStrictJsonValue(fragment.tags, "record.fragment.tags");
|
|
2312
|
-
assertStrictJsonValue(fragment.sources, "record.fragment.sources");
|
|
2313
|
-
if (fragment.embedding !== void 0) {
|
|
2314
|
-
assertStrictJsonValue(fragment.embedding, "record.fragment.embedding");
|
|
2315
|
-
}
|
|
2316
|
-
if (value.scope !== void 0) assertScopeFrame(value.scope);
|
|
2317
2726
|
}
|
|
2318
|
-
function
|
|
2319
|
-
|
|
2320
|
-
|
|
2727
|
+
function emitAdmission(ctx, state, admission) {
|
|
2728
|
+
state.statusSeq += 1;
|
|
2729
|
+
state.auditSeq += 1;
|
|
2730
|
+
const statusState = capabilityAdmissionStatusState(admission.state);
|
|
2731
|
+
const status = {
|
|
2732
|
+
kind: "capability-admission-status",
|
|
2733
|
+
statusId: `${admission.subjectId}:${statusState}:${state.statusSeq}`,
|
|
2734
|
+
state: statusState,
|
|
2735
|
+
proposalId: admission.proposalId,
|
|
2736
|
+
admissionId: admission.admissionId,
|
|
2737
|
+
subjectId: admission.subjectId,
|
|
2738
|
+
capabilityId: admission.capability.id,
|
|
2739
|
+
capabilityKind: admission.capability.kind,
|
|
2740
|
+
policyId: admission.policyId,
|
|
2741
|
+
sourceRefs: admission.sourceRefs
|
|
2742
|
+
};
|
|
2743
|
+
const audit = {
|
|
2744
|
+
id: `${admission.subjectId}:${statusState}:${state.auditSeq}`,
|
|
2745
|
+
kind: `capability-admission-${admission.state}`,
|
|
2746
|
+
subjectId: admission.subjectId,
|
|
2747
|
+
sourceRefs: admission.sourceRefs,
|
|
2748
|
+
metadata: {
|
|
2749
|
+
admissionId: admission.admissionId,
|
|
2750
|
+
capabilityId: admission.capability.id,
|
|
2751
|
+
capabilityKind: admission.capability.kind,
|
|
2752
|
+
policyId: admission.policyId,
|
|
2753
|
+
proposalId: admission.proposalId
|
|
2754
|
+
}
|
|
2755
|
+
};
|
|
2756
|
+
ctx.down([
|
|
2757
|
+
["DATA", { kind: "admission", admission }],
|
|
2758
|
+
["DATA", { kind: "status", status }],
|
|
2759
|
+
["DATA", { kind: "audit", audit }]
|
|
2760
|
+
]);
|
|
2761
|
+
}
|
|
2762
|
+
function emitIssue(ctx, state, key, issue) {
|
|
2763
|
+
if (state.issueKeys.has(key)) return;
|
|
2764
|
+
state.issueKeys.add(key);
|
|
2765
|
+
state.statusSeq += 1;
|
|
2766
|
+
state.auditSeq += 1;
|
|
2767
|
+
const status = {
|
|
2768
|
+
kind: "capability-admission-status",
|
|
2769
|
+
statusId: `capability-admission-issue:${state.statusSeq}`,
|
|
2770
|
+
state: "capability-admission-issue",
|
|
2771
|
+
subjectId: issue.subjectId,
|
|
2772
|
+
issues: [issue]
|
|
2773
|
+
};
|
|
2774
|
+
const audit = {
|
|
2775
|
+
id: `capability-admission-issue:${state.auditSeq}`,
|
|
2776
|
+
kind: "capability-admission-issue",
|
|
2777
|
+
subjectId: issue.subjectId,
|
|
2778
|
+
message: issue.message,
|
|
2779
|
+
issueCode: issue.code
|
|
2780
|
+
};
|
|
2781
|
+
ctx.down([
|
|
2782
|
+
["DATA", { kind: "issue", issue }],
|
|
2783
|
+
["DATA", { kind: "status", status }],
|
|
2784
|
+
["DATA", { kind: "audit", audit }]
|
|
2785
|
+
]);
|
|
2786
|
+
}
|
|
2787
|
+
function capabilityAdmissionProposalIssue(proposal) {
|
|
2788
|
+
if (proposal.kind !== "capability-admission-proposal" || typeof proposal.proposalId !== "string" || proposal.proposalId.length === 0 || typeof proposal.subjectId !== "string" || proposal.subjectId.length === 0 || !isBoundaryCapabilityRef(proposal.capability)) {
|
|
2789
|
+
return dataIssue(
|
|
2790
|
+
"malformed-capability-admission-proposal",
|
|
2791
|
+
"CapabilityAdmissionProposal requires proposalId, subjectId, and a D348 BoundaryCapabilityRef",
|
|
2792
|
+
{ subjectId: typeof proposal.subjectId === "string" ? proposal.subjectId : void 0 }
|
|
2793
|
+
);
|
|
2321
2794
|
}
|
|
2795
|
+
return void 0;
|
|
2322
2796
|
}
|
|
2323
|
-
function
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2797
|
+
function capabilityAdmissionPolicyIssue(policy) {
|
|
2798
|
+
if (policy.kind !== "capability-admission-policy" || typeof policy.policyId !== "string" || policy.policyId.length === 0 || policy.capabilityIds !== void 0 && (!Array.isArray(policy.capabilityIds) || !policy.capabilityIds.every((id) => typeof id === "string" && id.length > 0)) || policy.capabilityKinds !== void 0 && (!Array.isArray(policy.capabilityKinds) || !policy.capabilityKinds.every(isBoundaryCapabilityKind)) || policy.requiredOnly !== void 0 && typeof policy.requiredOnly !== "boolean" || policy.allowedOutcomes !== void 0 && (!Array.isArray(policy.allowedOutcomes) || !policy.allowedOutcomes.every(isCapabilityAdmissionOutcome))) {
|
|
2799
|
+
return dataIssue(
|
|
2800
|
+
"malformed-capability-admission-policy",
|
|
2801
|
+
"CapabilityAdmissionPolicy requires a policyId and D348 capability/outcome filters",
|
|
2802
|
+
{ subjectId: typeof policy.policyId === "string" ? policy.policyId : void 0 }
|
|
2803
|
+
);
|
|
2327
2804
|
}
|
|
2328
|
-
return
|
|
2805
|
+
return void 0;
|
|
2329
2806
|
}
|
|
2330
|
-
function
|
|
2331
|
-
if (typeof
|
|
2332
|
-
|
|
2807
|
+
function capabilityAdmissionDecisionIssue(decision) {
|
|
2808
|
+
if (decision.kind !== "capability-admission-decision" || typeof decision.decisionId !== "string" || decision.decisionId.length === 0 || typeof decision.admissionId !== "string" || decision.admissionId.length === 0 || typeof decision.proposalId !== "string" || decision.proposalId.length === 0 || !isCapabilityAdmissionOutcome(decision.outcome) || decision.policyId !== void 0 && (typeof decision.policyId !== "string" || decision.policyId.length === 0)) {
|
|
2809
|
+
return dataIssue(
|
|
2810
|
+
"malformed-capability-admission-decision",
|
|
2811
|
+
"CapabilityAdmissionDecision requires decisionId, admissionId, proposalId, and allow/block/defer outcome",
|
|
2812
|
+
{ subjectId: typeof decision.proposalId === "string" ? decision.proposalId : void 0 }
|
|
2813
|
+
);
|
|
2333
2814
|
}
|
|
2334
|
-
return
|
|
2815
|
+
return void 0;
|
|
2335
2816
|
}
|
|
2336
|
-
function
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2817
|
+
function validateCapabilityAdmissionPolicy(policy, decision, proposal) {
|
|
2818
|
+
if (policy.capabilityIds !== void 0 && !policy.capabilityIds.includes(proposal.capability.id)) {
|
|
2819
|
+
return {
|
|
2820
|
+
code: "capability-admission-policy-mismatch",
|
|
2821
|
+
message: `CapabilityAdmissionPolicy '${policy.policyId}' does not apply to capability '${proposal.capability.id}'`
|
|
2822
|
+
};
|
|
2342
2823
|
}
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2824
|
+
if (policy.capabilityKinds !== void 0 && !policy.capabilityKinds.includes(proposal.capability.kind)) {
|
|
2825
|
+
return {
|
|
2826
|
+
code: "capability-admission-policy-mismatch",
|
|
2827
|
+
message: `CapabilityAdmissionPolicy '${policy.policyId}' does not apply to capability kind '${proposal.capability.kind}'`
|
|
2828
|
+
};
|
|
2347
2829
|
}
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2830
|
+
if (policy.requiredOnly === true && !proposal.capability.required) {
|
|
2831
|
+
return {
|
|
2832
|
+
code: "capability-admission-policy-mismatch",
|
|
2833
|
+
message: `CapabilityAdmissionPolicy '${policy.policyId}' applies only to required capabilities`
|
|
2834
|
+
};
|
|
2352
2835
|
}
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2836
|
+
if (policy.allowedOutcomes !== void 0 && !policy.allowedOutcomes.includes(decision.outcome)) {
|
|
2837
|
+
return {
|
|
2838
|
+
code: "unsupported-capability-admission-outcome",
|
|
2839
|
+
message: `CapabilityAdmissionPolicy '${policy.policyId}' does not allow outcome '${decision.outcome}'`
|
|
2840
|
+
};
|
|
2841
|
+
}
|
|
2842
|
+
return void 0;
|
|
2843
|
+
}
|
|
2844
|
+
function capabilityPolicyForDecision(state, decision) {
|
|
2845
|
+
if (decision.policyId === void 0) return void 0;
|
|
2846
|
+
const stalePolicyRef = (decision.sourceRefs ?? []).find(
|
|
2847
|
+
(sourceRef) => sourceRef.kind === "capability-admission-policy" && sourceRef.id !== decision.policyId
|
|
2362
2848
|
);
|
|
2363
|
-
return
|
|
2849
|
+
if (stalePolicyRef !== void 0) return "stale-capability-admission-policy-ref";
|
|
2850
|
+
return state.policies.get(decision.policyId) ?? "missing-capability-admission-policy";
|
|
2364
2851
|
}
|
|
2365
|
-
function
|
|
2366
|
-
if (
|
|
2367
|
-
|
|
2852
|
+
function capabilityPolicyIssueMessage(code, decision) {
|
|
2853
|
+
if (code === "missing-capability-admission-policy") {
|
|
2854
|
+
return `CapabilityAdmissionPolicy '${decision.policyId}' was referenced but not present`;
|
|
2368
2855
|
}
|
|
2369
|
-
return
|
|
2856
|
+
return `CapabilityAdmissionDecision '${decision.decisionId}' carries a stale admission policy source ref`;
|
|
2370
2857
|
}
|
|
2371
|
-
function
|
|
2372
|
-
if (
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
return
|
|
2858
|
+
function admissionStateForOutcome(outcome) {
|
|
2859
|
+
if (outcome === "allow") return "allowed";
|
|
2860
|
+
if (outcome === "block") return "blocked";
|
|
2861
|
+
if (outcome === "defer") return "deferred";
|
|
2862
|
+
return void 0;
|
|
2376
2863
|
}
|
|
2377
|
-
function
|
|
2378
|
-
if (
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
return value;
|
|
2864
|
+
function capabilityAdmissionStatusState(state) {
|
|
2865
|
+
if (state === "allowed") return "capability-admission-allowed";
|
|
2866
|
+
if (state === "blocked") return "capability-admission-blocked";
|
|
2867
|
+
return "capability-admission-deferred";
|
|
2382
2868
|
}
|
|
2383
|
-
function
|
|
2384
|
-
|
|
2385
|
-
|
|
2869
|
+
function cloneCapabilityRef(ref2) {
|
|
2870
|
+
return {
|
|
2871
|
+
id: ref2.id,
|
|
2872
|
+
kind: ref2.kind,
|
|
2873
|
+
required: ref2.required,
|
|
2874
|
+
...ref2.sourceRefs === void 0 ? {} : { sourceRefs: [...ref2.sourceRefs] }
|
|
2875
|
+
};
|
|
2386
2876
|
}
|
|
2387
|
-
function
|
|
2388
|
-
if (typeof value !== "
|
|
2389
|
-
|
|
2877
|
+
function isBoundaryCapabilityRef(value) {
|
|
2878
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
2879
|
+
const record = value;
|
|
2880
|
+
return typeof record.id === "string" && record.id.length > 0 && isBoundaryCapabilityKind(record.kind) && typeof record.required === "boolean" && (record.sourceRefs === void 0 || Array.isArray(record.sourceRefs) && record.sourceRefs.every((sourceRef) => typeof sourceRef === "string"));
|
|
2390
2881
|
}
|
|
2391
|
-
function
|
|
2392
|
-
|
|
2393
|
-
throw new TypeError(`${label} must be a finite number in [0, 1]`);
|
|
2394
|
-
}
|
|
2395
|
-
return value;
|
|
2882
|
+
function isBoundaryCapabilityKind(value) {
|
|
2883
|
+
return value === "auth" || value === "permission" || value === "config" || value === "resource";
|
|
2396
2884
|
}
|
|
2397
|
-
function
|
|
2398
|
-
|
|
2399
|
-
throw new TypeError(`${label} must be a readonly string array`);
|
|
2400
|
-
}
|
|
2401
|
-
return Object.freeze([...value]);
|
|
2885
|
+
function isCapabilityAdmissionOutcome(value) {
|
|
2886
|
+
return value === "allow" || value === "block" || value === "defer";
|
|
2402
2887
|
}
|
|
2403
|
-
function
|
|
2404
|
-
|
|
2405
|
-
throw new TypeError(`${label} must be a finite number array`);
|
|
2406
|
-
}
|
|
2407
|
-
return Object.freeze([...value]);
|
|
2888
|
+
function proposalKeyFallback(proposal) {
|
|
2889
|
+
return typeof proposal.proposalId === "string" && proposal.proposalId.length > 0 ? proposal.proposalId : `${stringValue(proposal.subjectId) ?? "unknown"}:${capabilityKeyFallback(proposal.capability)}`;
|
|
2408
2890
|
}
|
|
2409
|
-
function
|
|
2410
|
-
return typeof
|
|
2891
|
+
function policyKeyFallback(policy) {
|
|
2892
|
+
return typeof policy.policyId === "string" && policy.policyId.length > 0 ? policy.policyId : "unknown";
|
|
2411
2893
|
}
|
|
2412
|
-
function
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2894
|
+
function decisionKeyFallback(decision) {
|
|
2895
|
+
return typeof decision.decisionId === "string" && decision.decisionId.length > 0 ? decision.decisionId : `${stringValue(decision.proposalId) ?? "unknown"}:${stringValue(decision.admissionId) ?? "unknown"}`;
|
|
2896
|
+
}
|
|
2897
|
+
function capabilityKeyFallback(value) {
|
|
2898
|
+
if (!isBoundaryCapabilityRef(value)) return "unknown-capability";
|
|
2899
|
+
return `${value.kind}:${value.id}`;
|
|
2900
|
+
}
|
|
2901
|
+
function nextMalformedIssueKey(state, kind, fallback) {
|
|
2902
|
+
state.issueSeq += 1;
|
|
2903
|
+
return `malformed-${kind}:${state.issueSeq}:${fallback}`;
|
|
2904
|
+
}
|
|
2905
|
+
function stringValue(value) {
|
|
2906
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2907
|
+
}
|
|
2908
|
+
function capabilityProposalRefs(proposal) {
|
|
2909
|
+
return uniqueSourceRefs([
|
|
2910
|
+
ref("capability-admission-proposal", proposal.proposalId),
|
|
2911
|
+
ref("boundary-capability", `${proposal.capability.kind}:${proposal.capability.id}`),
|
|
2912
|
+
...proposal.sourceRefs ?? []
|
|
2913
|
+
]);
|
|
2914
|
+
}
|
|
2915
|
+
function capabilityDecisionRefs(decision, proposal, policy) {
|
|
2916
|
+
return uniqueSourceRefs([
|
|
2917
|
+
ref("capability-admission-decision", decision.decisionId),
|
|
2918
|
+
ref("capability-admission", decision.admissionId),
|
|
2919
|
+
ref("capability-admission-proposal", decision.proposalId),
|
|
2920
|
+
...proposal === void 0 ? [] : capabilityProposalRefs(proposal),
|
|
2921
|
+
...decision.policyId === void 0 ? [] : [ref("capability-admission-policy", decision.policyId)],
|
|
2922
|
+
...policy === void 0 ? [] : [ref("capability-admission-policy", policy.policyId)],
|
|
2923
|
+
...decision.sourceRefs ?? []
|
|
2924
|
+
]);
|
|
2925
|
+
}
|
|
2926
|
+
function forEachPolicyDepBatch(ctx, start, count, fn) {
|
|
2927
|
+
for (let i = 0; i < count; i += 1) {
|
|
2928
|
+
for (const value of depBatch(ctx, start + i) ?? []) fn(value);
|
|
2416
2929
|
}
|
|
2417
|
-
return true;
|
|
2418
2930
|
}
|
|
2419
|
-
function
|
|
2420
|
-
return
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2931
|
+
function projectRuntimeFact(graph, runtime, name, factory, pick) {
|
|
2932
|
+
return graph.node(
|
|
2933
|
+
[runtime],
|
|
2934
|
+
(ctx) => {
|
|
2935
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
2936
|
+
const typed = fact;
|
|
2937
|
+
const value = pick(typed);
|
|
2938
|
+
if (value !== void 0) ctx.down([["DATA", value]]);
|
|
2939
|
+
}
|
|
2940
|
+
},
|
|
2941
|
+
{ name, factory }
|
|
2942
|
+
);
|
|
2424
2943
|
}
|
|
2425
|
-
function
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2944
|
+
function freezeCapabilityAdmissionViews(state) {
|
|
2945
|
+
return {
|
|
2946
|
+
admissionsByProposal: new Map(state.admissionsByProposal),
|
|
2947
|
+
admissionsBySubject: new Map(
|
|
2948
|
+
Array.from(state.admissionsBySubject, ([key, value]) => [key, Object.freeze([...value])])
|
|
2949
|
+
),
|
|
2950
|
+
issues: Object.freeze([...state.issues]),
|
|
2951
|
+
audit: Object.freeze([...state.audit])
|
|
2952
|
+
};
|
|
2953
|
+
}
|
|
2954
|
+
function emptyCapabilityAdmissionState() {
|
|
2955
|
+
return {
|
|
2956
|
+
proposals: /* @__PURE__ */ new Map(),
|
|
2957
|
+
policies: /* @__PURE__ */ new Map(),
|
|
2958
|
+
decisions: /* @__PURE__ */ new Map(),
|
|
2959
|
+
admissionsById: /* @__PURE__ */ new Map(),
|
|
2960
|
+
admissionsByProposal: /* @__PURE__ */ new Map(),
|
|
2961
|
+
terminalDecisionIds: /* @__PURE__ */ new Set(),
|
|
2962
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
2963
|
+
issueSeq: 0,
|
|
2964
|
+
statusSeq: 0,
|
|
2965
|
+
auditSeq: 0
|
|
2966
|
+
};
|
|
2967
|
+
}
|
|
2968
|
+
function dataIssue(code, message, opts = {}) {
|
|
2969
|
+
return {
|
|
2970
|
+
kind: "issue",
|
|
2971
|
+
code,
|
|
2972
|
+
message,
|
|
2973
|
+
severity: "error",
|
|
2974
|
+
subjectId: opts.subjectId,
|
|
2975
|
+
refs: opts.refs?.map((sourceRef) => `${sourceRef.kind}:${sourceRef.id}`),
|
|
2976
|
+
details: opts.details
|
|
2977
|
+
};
|
|
2978
|
+
}
|
|
2979
|
+
function uniqueSourceRefs(sourceRefs) {
|
|
2980
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2981
|
+
const out = [];
|
|
2982
|
+
for (const sourceRef of sourceRefs) {
|
|
2983
|
+
const key = `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
|
|
2984
|
+
if (seen.has(key)) continue;
|
|
2985
|
+
seen.add(key);
|
|
2986
|
+
out.push(sourceRef);
|
|
2430
2987
|
}
|
|
2988
|
+
return out;
|
|
2431
2989
|
}
|
|
2432
|
-
function
|
|
2433
|
-
return
|
|
2990
|
+
function ref(kind, id) {
|
|
2991
|
+
return { kind, id };
|
|
2434
2992
|
}
|
|
2435
2993
|
|
|
2436
2994
|
export {
|
|
2995
|
+
agenticMemoryBundle,
|
|
2996
|
+
agenticMemoryConsolidationBundle,
|
|
2997
|
+
agenticMemoryContextPackingBundle,
|
|
2437
2998
|
AGENTIC_MEMORY_RECORD_FRAME_FORMAT,
|
|
2438
2999
|
AGENTIC_MEMORY_RECORD_FRAME_VERSION,
|
|
2439
|
-
agenticMemoryBundle,
|
|
2440
|
-
agenticMemoryKgProjectionBundle,
|
|
2441
3000
|
agenticMemoryRecordFrame,
|
|
2442
3001
|
assertAgenticMemoryRecordFrame,
|
|
2443
3002
|
agenticMemoryRecordFrameCodec,
|
|
2444
3003
|
agenticMemoryRecordCodec,
|
|
3004
|
+
agenticMemoryKgProjectionBundle,
|
|
2445
3005
|
agenticMemoryRetentionBundle,
|
|
2446
|
-
|
|
2447
|
-
|
|
3006
|
+
capabilityAdmissionProposal,
|
|
3007
|
+
capabilityAdmissionProjector
|
|
2448
3008
|
};
|
|
2449
|
-
//# sourceMappingURL=chunk-
|
|
3009
|
+
//# sourceMappingURL=chunk-4NWSNI4K.js.map
|