@graphrefly/ts 0.0.0 → 0.0.1
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/adapters/index.cjs +105 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +11 -136
- package/dist/adapters/index.d.ts +11 -136
- package/dist/adapters/index.js +27 -225
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/observe-storage.d.cts +4 -4
- package/dist/adapters/observe-storage.d.ts +4 -4
- package/dist/adapters/observe-storage.js +1 -0
- 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-BesGDZcB.d.ts +555 -0
- package/dist/agent-runtime-DZTJ3C-p.d.cts +555 -0
- package/dist/agentic-memory-BmRCvh0d.d.ts +517 -0
- package/dist/agentic-memory-DfuVZ-lY.d.cts +517 -0
- package/dist/capability-admission-B0BzqAm5.d.cts +102 -0
- package/dist/capability-admission-g0mn9hpq.d.ts +102 -0
- package/dist/{chunk-JR4IKCR2.js → chunk-2747WN4Y.js} +5 -5
- package/dist/{chunk-2ILL7HQI.js → chunk-3JR3EDB2.js} +17 -17
- package/dist/{chunk-2ILL7HQI.js.map → chunk-3JR3EDB2.js.map} +1 -1
- package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
- package/dist/{chunk-DJC4CHLQ.js → chunk-43BKLFZU.js} +9 -9
- package/dist/chunk-6XAIOL3X.js +2407 -0
- package/dist/chunk-6XAIOL3X.js.map +1 -0
- package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
- package/dist/{chunk-Y3ZLRGHC.js → chunk-CZNV3VXM.js} +16 -16
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-JIMUDQN3.js → chunk-FBUU43PM.js} +2 -2
- package/dist/chunk-H75VXTGT.js +219 -0
- package/dist/chunk-H75VXTGT.js.map +1 -0
- package/dist/{chunk-RIIOUTGM.js → chunk-HKK2JD7Z.js} +12 -9
- package/dist/chunk-HKK2JD7Z.js.map +1 -0
- package/dist/{chunk-D6BG7U6A.js → chunk-IXZBUWSP.js} +3 -3
- package/dist/chunk-PC3BTTBE.js +3217 -0
- package/dist/chunk-PC3BTTBE.js.map +1 -0
- package/dist/chunk-QFY4AFY4.js +879 -0
- package/dist/chunk-QFY4AFY4.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-PKVBHGBM.js → chunk-SS2A464I.js} +7 -7
- package/dist/chunk-UT3MHJCW.js +49 -0
- package/dist/chunk-UT3MHJCW.js.map +1 -0
- package/dist/{chunk-G4M3NHRJ.js → chunk-V7CIJE4B.js} +3 -3
- package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
- package/dist/chunk-VTHLCFN4.js +368 -0
- package/dist/chunk-VTHLCFN4.js.map +1 -0
- package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
- package/dist/chunk-WQIA3GFB.js.map +1 -0
- package/dist/{chunk-I3IHOHCJ.js → chunk-XKXWK2KP.js} +108 -64
- package/dist/chunk-XKXWK2KP.js.map +1 -0
- package/dist/{chunk-COHO25CZ.js → chunk-YDSIVHRR.js} +553 -7
- package/dist/chunk-YDSIVHRR.js.map +1 -0
- package/dist/chunk-YXMZ2N6J.js +1884 -0
- package/dist/chunk-YXMZ2N6J.js.map +1 -0
- package/dist/composition/index.cjs +102 -57
- 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 +6 -5
- package/dist/core/index.cjs +102 -57
- 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 +105 -57
- package/dist/data-structures/index.cjs.map +1 -1
- package/dist/data-structures/index.d.cts +8 -8
- package/dist/data-structures/index.d.ts +8 -8
- package/dist/data-structures/index.js +7 -6
- package/dist/{describe-BZb7AS2y.d.ts → describe-BpyJuWkw.d.ts} +1 -1
- package/dist/{describe-Ciu8SUnN.d.cts → describe-DYMw_l1C.d.cts} +1 -1
- 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 +112 -58
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +9 -9
- package/dist/graph/index.d.ts +9 -9
- package/dist/graph/index.js +18 -17
- package/dist/{graph-DfdF9zy4.d.ts → graph-D-1-SQeC.d.ts} +3 -3
- package/dist/{graph-s23RbbFO.d.cts → graph-DCEWh4T2.d.cts} +3 -3
- package/dist/{index-CAEmLCYF.d.cts → index-72VZC0-E.d.cts} +2 -2
- package/dist/{index-SnzZu3x7.d.ts → index-Bmxeu0nK.d.ts} +2 -2
- package/dist/index.cjs +112 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +118 -113
- 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/{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 +744 -613
- package/dist/messaging/index.cjs.map +1 -1
- package/dist/messaging/index.d.cts +216 -160
- package/dist/messaging/index.d.ts +216 -160
- package/dist/messaging/index.js +19 -749
- package/dist/messaging/index.js.map +1 -1
- package/dist/operators/index.cjs +102 -57
- 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 +8 -7
- package/dist/orchestration/index.cjs +3333 -59
- package/dist/orchestration/index.cjs.map +1 -1
- package/dist/orchestration/index.d.cts +7 -4
- package/dist/orchestration/index.d.ts +7 -4
- package/dist/orchestration/index.js +49 -8
- 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 +59 -0
- package/dist/orchestration/messaging.d.ts +59 -0
- package/dist/orchestration/messaging.js +276 -0
- package/dist/orchestration/messaging.js.map +1 -0
- package/dist/orchestration/work-queue.cjs +262 -0
- package/dist/orchestration/work-queue.cjs.map +1 -0
- package/dist/orchestration/work-queue.d.cts +85 -0
- package/dist/orchestration/work-queue.d.ts +85 -0
- package/dist/orchestration/work-queue.js +226 -0
- package/dist/orchestration/work-queue.js.map +1 -0
- package/dist/patterns/event-flow.cjs +447 -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 +423 -18
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +8 -5
- package/dist/patterns/index.d.ts +8 -5
- package/dist/patterns/index.js +13 -4
- package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BAmfrGjd.d.ts} +9 -9
- package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-DNV0-gFi.d.cts} +9 -9
- package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BNEldDyi.d.cts} +5 -5
- package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-YZsAQsWK.d.ts} +5 -5
- package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-DRD1LJ2H.d.cts} +6 -6
- package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-EsDiCmJk.d.ts} +6 -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/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-DKuNzuWw.d.cts} +2 -2
- package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-uwbwJdhe.d.ts} +2 -2
- package/dist/solutions/index.cjs +4478 -2
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +13 -519
- package/dist/solutions/index.d.ts +13 -519
- package/dist/solutions/index.js +90 -6
- package/dist/solutions/reactive-layout/browser/index.cjs +449 -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 +4266 -0
- package/dist/solutions/reactive-layout/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/index.d.cts +581 -0
- package/dist/solutions/reactive-layout/index.d.ts +581 -0
- package/dist/solutions/reactive-layout/index.js +86 -0
- package/dist/solutions/reactive-layout/index.js.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs +545 -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 +494 -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 +547 -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 +2164 -0
- package/dist/solutions/work-item/actions.cjs.map +1 -0
- package/dist/solutions/work-item/actions.d.cts +201 -0
- package/dist/solutions/work-item/actions.d.ts +201 -0
- package/dist/solutions/work-item/actions.js +1454 -0
- package/dist/solutions/work-item/actions.js.map +1 -0
- package/dist/solutions/work-item/scheduling.cjs +2454 -0
- package/dist/solutions/work-item/scheduling.cjs.map +1 -0
- package/dist/solutions/work-item/scheduling.d.cts +433 -0
- package/dist/solutions/work-item/scheduling.d.ts +433 -0
- package/dist/solutions/work-item/scheduling.js +32 -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 +169 -57
- 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 +102 -57
- 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 +6 -5
- 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.js +1 -0
- package/dist/storage/browser.js.map +1 -1
- package/dist/storage/index.d.cts +5 -5
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +5 -4
- package/dist/storage/node.js +1 -0
- package/dist/storage/node.js.map +1 -1
- package/dist/store-C-joM4gh.d.ts +123 -0
- package/dist/store-CNJwmT-h.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-h12mNYbq.d.ts → types-BsJvElYZ.d.ts} +31 -31
- package/dist/{types-bNMSWKqF.d.cts → types-CcPIn7sy.d.cts} +31 -31
- package/dist/work-item-runtime-C3M79vE9.d.ts +228 -0
- package/dist/work-item-runtime-qaVgsL0T.d.cts +228 -0
- package/dist/work-queue/index.cjs +1132 -0
- package/dist/work-queue/index.cjs.map +1 -0
- package/dist/work-queue/index.d.cts +369 -0
- package/dist/work-queue/index.d.ts +369 -0
- package/dist/work-queue/index.js +1078 -0
- package/dist/work-queue/index.js.map +1 -0
- package/package.json +266 -2
- package/dist/chunk-COHO25CZ.js.map +0 -1
- package/dist/chunk-DK554R7P.js.map +0 -1
- package/dist/chunk-I3IHOHCJ.js.map +0 -1
- package/dist/chunk-RIIOUTGM.js.map +0 -1
- package/dist/chunk-SWTLEQL6.js.map +0 -1
- /package/dist/{chunk-JR4IKCR2.js.map → chunk-2747WN4Y.js.map} +0 -0
- /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
- /package/dist/{chunk-DJC4CHLQ.js.map → chunk-43BKLFZU.js.map} +0 -0
- /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
- /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-CZNV3VXM.js.map} +0 -0
- /package/dist/{chunk-JIMUDQN3.js.map → chunk-FBUU43PM.js.map} +0 -0
- /package/dist/{chunk-D6BG7U6A.js.map → chunk-IXZBUWSP.js.map} +0 -0
- /package/dist/{chunk-PKVBHGBM.js.map → chunk-SS2A464I.js.map} +0 -0
- /package/dist/{chunk-G4M3NHRJ.js.map → chunk-V7CIJE4B.js.map} +0 -0
- /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
|
@@ -20,18 +20,37 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/orchestration/index.ts
|
|
21
21
|
var orchestration_exports = {};
|
|
22
22
|
__export(orchestration_exports, {
|
|
23
|
+
admitAgentRequestProposal: () => admitAgentRequestProposal,
|
|
24
|
+
agentRequestLedgerViews: () => agentRequestLedgerViews,
|
|
25
|
+
agentRequestProposalFromDecision: () => agentRequestProposalFromDecision,
|
|
23
26
|
backoffDelayMs: () => backoffDelayMs,
|
|
24
27
|
breakerBundle: () => breakerBundle,
|
|
25
28
|
constantBackoff: () => constantBackoff,
|
|
29
|
+
effectRun: () => effectRun,
|
|
30
|
+
effectRunCompletionProjector: () => effectRunCompletionProjector,
|
|
31
|
+
executorOutcomeViewProjector: () => executorOutcomeViewProjector,
|
|
32
|
+
fakeExecutorBlocked: () => fakeExecutorBlocked,
|
|
33
|
+
fakeExecutorCanceled: () => fakeExecutorCanceled,
|
|
34
|
+
fakeExecutorFailure: () => fakeExecutorFailure,
|
|
35
|
+
fakeExecutorResult: () => fakeExecutorResult,
|
|
36
|
+
fakeExecutorTimeout: () => fakeExecutorTimeout,
|
|
37
|
+
issueAgentRequest: () => issueAgentRequest,
|
|
38
|
+
localBuiltinToolProviderCatalog: () => localBuiltinToolProviderCatalog,
|
|
26
39
|
nextRetryDelayMs: () => nextRetryDelayMs,
|
|
27
40
|
noBackoff: () => noBackoff,
|
|
28
41
|
processBundle: () => processBundle,
|
|
29
42
|
processEffectRunner: () => processEffectRunner,
|
|
30
43
|
rateLimitBundle: () => rateLimitBundle,
|
|
44
|
+
requestSatisfactionProjector: () => requestSatisfactionProjector,
|
|
31
45
|
retryPolicy: () => retryPolicy,
|
|
32
46
|
retryStatusBundle: () => retryStatusBundle,
|
|
33
47
|
shouldRetry: () => shouldRetry,
|
|
34
|
-
|
|
48
|
+
structuredAgentDecisionInterpreter: () => structuredAgentDecisionInterpreter,
|
|
49
|
+
timeoutBundle: () => timeoutBundle,
|
|
50
|
+
workItemDomainActionAdmissionProjector: () => workItemDomainActionAdmissionProjector,
|
|
51
|
+
workItemDomainActionProposalProjector: () => workItemDomainActionProposalProjector,
|
|
52
|
+
workItemEffectResultMapper: () => workItemEffectResultMapper,
|
|
53
|
+
workItemEffectRunProjector: () => workItemEffectRunProjector
|
|
35
54
|
});
|
|
36
55
|
module.exports = __toCommonJS(orchestration_exports);
|
|
37
56
|
|
|
@@ -54,6 +73,7 @@ var TIER = {
|
|
|
54
73
|
START: TIER_START,
|
|
55
74
|
PAUSE: TIER_CONTROL,
|
|
56
75
|
RESUME: TIER_CONTROL,
|
|
76
|
+
PULL: TIER_CONTROL,
|
|
57
77
|
DIRTY: TIER_NOTIFICATION,
|
|
58
78
|
DATA: TIER_VALUE,
|
|
59
79
|
RESOLVED: TIER_VALUE,
|
|
@@ -967,6 +987,17 @@ function notifyTopologyDepsChanged(node, prevDeps, deps) {
|
|
|
967
987
|
function terminalView(t) {
|
|
968
988
|
return t === void 0 ? false : t;
|
|
969
989
|
}
|
|
990
|
+
function normalizePullDemand(demand) {
|
|
991
|
+
if (typeof demand !== "object" || demand === null || Array.isArray(demand)) {
|
|
992
|
+
throw new Error("ctx.up: PULL requires { pullId, params? } demand payload (D269)");
|
|
993
|
+
}
|
|
994
|
+
const pullId = demand.pullId;
|
|
995
|
+
if (typeof pullId !== "string" && typeof pullId !== "symbol") {
|
|
996
|
+
throw new Error("ctx.up: PULL demand requires a string or symbol pullId (D269)");
|
|
997
|
+
}
|
|
998
|
+
const params = demand.params;
|
|
999
|
+
return params === void 0 ? { pullId } : { pullId, params };
|
|
1000
|
+
}
|
|
970
1001
|
function validateDownPayloads(msgs) {
|
|
971
1002
|
for (const m of msgs) {
|
|
972
1003
|
if (m[0] === "DATA" && m[1] === void 0) {
|
|
@@ -1010,7 +1041,7 @@ var Node = class {
|
|
|
1010
1041
|
const pull = opts.pullId !== void 0;
|
|
1011
1042
|
if (pull && pausable === false)
|
|
1012
1043
|
throw new Error(
|
|
1013
|
-
"node: pullId is incompatible with pausable:false \u2014 a pull node
|
|
1044
|
+
"node: pullId is incompatible with pausable:false \u2014 a pull node uses the pausable delivery-content axis (R-pull / R-pause-modes / D55,D269)"
|
|
1014
1045
|
);
|
|
1015
1046
|
let handle;
|
|
1016
1047
|
if (handleOrFn === null) handle = null;
|
|
@@ -1033,7 +1064,6 @@ var Node = class {
|
|
|
1033
1064
|
value.status = "settled";
|
|
1034
1065
|
}
|
|
1035
1066
|
const pauseLockset = /* @__PURE__ */ new Set();
|
|
1036
|
-
if (pull) pauseLockset.add(pullLock);
|
|
1037
1067
|
this._core = core ?? new NodeCore();
|
|
1038
1068
|
const created = this._core.createSlot(
|
|
1039
1069
|
{
|
|
@@ -1074,7 +1104,9 @@ var Node = class {
|
|
|
1074
1104
|
pauseLockset,
|
|
1075
1105
|
pausedDepWaveOccurred: false,
|
|
1076
1106
|
pauseBuffer: [],
|
|
1077
|
-
demandOwed:
|
|
1107
|
+
demandOwed: void 0,
|
|
1108
|
+
activePull: void 0,
|
|
1109
|
+
pullDirtyOwed: false,
|
|
1078
1110
|
inDeliverDemand: false
|
|
1079
1111
|
},
|
|
1080
1112
|
privateState: { value: SENTINEL, persist: false },
|
|
@@ -1131,10 +1163,11 @@ var Node = class {
|
|
|
1131
1163
|
this._wave.batchDirtyOwed = false;
|
|
1132
1164
|
this._control.pauseBuffer = [];
|
|
1133
1165
|
this._control.pausedDepWaveOccurred = false;
|
|
1134
|
-
this._control.demandOwed =
|
|
1166
|
+
this._control.demandOwed = void 0;
|
|
1167
|
+
this._control.activePull = void 0;
|
|
1168
|
+
this._control.pullDirtyOwed = false;
|
|
1135
1169
|
this._control.inDeliverDemand = false;
|
|
1136
1170
|
this._control.pauseLockset.clear();
|
|
1137
|
-
if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
|
|
1138
1171
|
this._privateState.value = state.ctxState.value;
|
|
1139
1172
|
this._privateState.persist = state.ctxState.persist;
|
|
1140
1173
|
if (state.version === false) {
|
|
@@ -1173,17 +1206,16 @@ var Node = class {
|
|
|
1173
1206
|
subscriberCountReaders.set(this, () => this._subscriberCount());
|
|
1174
1207
|
activationReaders.set(this, () => this._lifecycle.activated);
|
|
1175
1208
|
}
|
|
1176
|
-
/** R-pull (D55): true while a pull node is
|
|
1209
|
+
/** R-pull (D55/D272): true while a pull node is not serving a PULL demand pulse. */
|
|
1177
1210
|
_isPullQuiet() {
|
|
1178
|
-
return this._slot.pull && this._control.
|
|
1211
|
+
return this._slot.pull && this._control.activePull === void 0;
|
|
1179
1212
|
}
|
|
1180
1213
|
/**
|
|
1181
|
-
* R-pull (
|
|
1182
|
-
* triggers computation). A consumer demands one delivery by cone-routing
|
|
1183
|
-
* reference): `ctx.up([["
|
|
1184
|
-
* `ctx.upNext([["
|
|
1185
|
-
*
|
|
1186
|
-
* for inspection/describe; routing matches by the pullId value carried in the RESUME, by identity.
|
|
1214
|
+
* R-pull (D269/D272): this pull node's pullId (pure data, like {@link cache}/{@link handle} —
|
|
1215
|
+
* never triggers computation). A consumer demands one delivery by cone-routing PULL of it (no
|
|
1216
|
+
* node reference): `ctx.up([["PULL", { pullId }]])` (immediate; loops back → D37 for a self-read
|
|
1217
|
+
* dep) or `ctx.upNext([["PULL", { pullId }]])` (boundary-deferred self-demand). Undefined for a
|
|
1218
|
+
* non-pull node. The author writes the pullId verbatim; routing matches by identity.
|
|
1187
1219
|
*/
|
|
1188
1220
|
get pullId() {
|
|
1189
1221
|
return this._slot.pullLock;
|
|
@@ -1290,10 +1322,10 @@ var Node = class {
|
|
|
1290
1322
|
});
|
|
1291
1323
|
}
|
|
1292
1324
|
/**
|
|
1293
|
-
* Enqueue a deferred up-going control wave (R-up-routing / R-pull /
|
|
1325
|
+
* Enqueue a deferred up-going control/demand wave (R-up-routing / R-pull / D269): at the committed wave
|
|
1294
1326
|
* boundary, route `msgs` up from THIS node (broadcast, or up the single `towardDep` edge). The
|
|
1295
|
-
* deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[
|
|
1296
|
-
* pullId]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
|
|
1327
|
+
* deferred form of `ctx.up` — the SELF-demand path: a consumer issues `ctx.upNext([[PULL,
|
|
1328
|
+
* { pullId }]])` to demand a dep it ALSO reads; the demand applies at the boundary (not mid-fn), so
|
|
1297
1329
|
* the pull node's delivery loops back as a FRESH wave rather than re-entering the consumer (D37 /
|
|
1298
1330
|
* R-reentrancy). Rides the same R-rewire-deferred (D47) drain as ctx.rewireNext.
|
|
1299
1331
|
*/
|
|
@@ -1508,7 +1540,6 @@ var Node = class {
|
|
|
1508
1540
|
this._lifecycle.activated = true;
|
|
1509
1541
|
const seedRestoredDeps = this._restoredActivationPending;
|
|
1510
1542
|
this._restoredActivationPending = false;
|
|
1511
|
-
if (this._slot.pull) this._control.pauseLockset.add(this._slot.pullLock);
|
|
1512
1543
|
this._dep.unsubs = new Array(this._slot.deps.length);
|
|
1513
1544
|
this._dep.idxBoxes = new Array(this._slot.deps.length);
|
|
1514
1545
|
for (const dep of this._slot.deps)
|
|
@@ -1580,7 +1611,9 @@ var Node = class {
|
|
|
1580
1611
|
this._control.pauseLockset.clear();
|
|
1581
1612
|
this._control.pauseBuffer = [];
|
|
1582
1613
|
this._control.pausedDepWaveOccurred = false;
|
|
1583
|
-
this._control.demandOwed =
|
|
1614
|
+
this._control.demandOwed = void 0;
|
|
1615
|
+
this._control.activePull = void 0;
|
|
1616
|
+
this._control.pullDirtyOwed = false;
|
|
1584
1617
|
this._value.replayRing = [];
|
|
1585
1618
|
if (!this._privateState.persist) this._privateState.value = SENTINEL;
|
|
1586
1619
|
}
|
|
@@ -1592,8 +1625,7 @@ var Node = class {
|
|
|
1592
1625
|
return this._lifecycle.subscribers.size;
|
|
1593
1626
|
}
|
|
1594
1627
|
_isRuntimeQuiescentForRelease() {
|
|
1595
|
-
|
|
1596
|
-
return !this._released && this._value.status !== "dirty" && this._value.status !== "pending" && this._wave.pending === 0 && !this._wave.insideRunWave && !this._wave.inDepMutation && !this._wave.rewireRunPending && !this._wave.batchDirtyOwed && this._dep.dirty.every((dirty) => !dirty) && this._control.pauseBuffer.length === 0 && !this._control.pausedDepWaveOccurred && !this._control.demandOwed && !this._control.inDeliverDemand && (this._control.pauseLockset.size === 0 || allowedPullQuietLock);
|
|
1628
|
+
return !this._released && this._value.status !== "dirty" && this._value.status !== "pending" && this._wave.pending === 0 && !this._wave.insideRunWave && !this._wave.inDepMutation && !this._wave.rewireRunPending && !this._wave.batchDirtyOwed && this._dep.dirty.every((dirty) => !dirty) && this._control.pauseBuffer.length === 0 && !this._control.pausedDepWaveOccurred && this._control.demandOwed === void 0 && this._control.activePull === void 0 && !this._control.inDeliverDemand && this._control.pauseLockset.size === 0;
|
|
1597
1629
|
}
|
|
1598
1630
|
_releaseRuntime() {
|
|
1599
1631
|
if (this._released) return;
|
|
@@ -1649,7 +1681,9 @@ var Node = class {
|
|
|
1649
1681
|
this._control.pauseLockset.clear();
|
|
1650
1682
|
this._control.pauseBuffer = [];
|
|
1651
1683
|
this._control.pausedDepWaveOccurred = false;
|
|
1652
|
-
this._control.demandOwed =
|
|
1684
|
+
this._control.demandOwed = void 0;
|
|
1685
|
+
this._control.activePull = void 0;
|
|
1686
|
+
this._control.pullDirtyOwed = false;
|
|
1653
1687
|
this._restoredActivationPending = false;
|
|
1654
1688
|
checkpointReaders.delete(this);
|
|
1655
1689
|
restoreWriters.delete(this);
|
|
@@ -1831,7 +1865,7 @@ var Node = class {
|
|
|
1831
1865
|
this._wave.rewireRunPending = true;
|
|
1832
1866
|
return;
|
|
1833
1867
|
}
|
|
1834
|
-
if (this._slot.pausable === true && this._isPaused()) {
|
|
1868
|
+
if (this._slot.pausable === true && (this._isPaused() || this._isPullQuiet())) {
|
|
1835
1869
|
this._control.pausedDepWaveOccurred = true;
|
|
1836
1870
|
return;
|
|
1837
1871
|
}
|
|
@@ -1971,10 +2005,11 @@ var Node = class {
|
|
|
1971
2005
|
unsubscribeDep: (dep, fn) => this._requestRewireNext({ kind: "remove", dep, fn }),
|
|
1972
2006
|
replaceDeps: (deps, fn) => this._requestRewireNext({ kind: "set", deps, fn })
|
|
1973
2007
|
},
|
|
1974
|
-
// R-up-routing / R-pull (
|
|
1975
|
-
//
|
|
2008
|
+
// R-up-routing / R-pull (D269): deferred up — route a control/demand wave (e.g. PULL)
|
|
2009
|
+
// up the declared cone at the committed boundary. The SELF-demand path: an
|
|
1976
2010
|
// immediate ctx.up whose delivery loops back re-enters this fn (D37 / R-reentrancy).
|
|
1977
2011
|
upNext: (msgs, towardDep) => this._requestUpNext(msgs, towardDep),
|
|
2012
|
+
...this._control.activePull === void 0 ? {} : { pull: this._control.activePull },
|
|
1978
2013
|
[CTX_DEP_CACHE]: { latest: snapshot?.latest ?? this._dep.prev },
|
|
1979
2014
|
[CTX_NODE_BINDING]: {
|
|
1980
2015
|
dispatcher: this._slot.dispatcher,
|
|
@@ -1989,6 +2024,11 @@ var Node = class {
|
|
|
1989
2024
|
_refreshCtx(ctx) {
|
|
1990
2025
|
ctx.waveData = this._dep.waveData;
|
|
1991
2026
|
ctx.terminal = this._dep.terminalInput.map(terminalView);
|
|
2027
|
+
if (this._control.activePull === void 0) {
|
|
2028
|
+
delete ctx.pull;
|
|
2029
|
+
} else {
|
|
2030
|
+
ctx.pull = this._control.activePull;
|
|
2031
|
+
}
|
|
1992
2032
|
ctx[CTX_DEP_CACHE] = { latest: this._dep.prev };
|
|
1993
2033
|
}
|
|
1994
2034
|
_makeState() {
|
|
@@ -2081,7 +2121,7 @@ var Node = class {
|
|
|
2081
2121
|
plannedVersions[i] = plannedVersion;
|
|
2082
2122
|
}
|
|
2083
2123
|
}
|
|
2084
|
-
if (hasTier3 && !this._wave.insideRunWave && !this._wave.emittedDirtyThisWave) {
|
|
2124
|
+
if (hasTier3 && (!this._wave.insideRunWave || this._control.pullDirtyOwed) && !this._wave.emittedDirtyThisWave) {
|
|
2085
2125
|
this._wave.emittedDirtyThisWave = true;
|
|
2086
2126
|
this._value.status = "dirty";
|
|
2087
2127
|
this._emitToSubs(["DIRTY"], { wave: deliveryWave, last: false });
|
|
@@ -2161,13 +2201,18 @@ var Node = class {
|
|
|
2161
2201
|
if (m[0] === "PAUSE") {
|
|
2162
2202
|
this._pauseAcquire(m[1]);
|
|
2163
2203
|
} else if (m[0] === "RESUME") {
|
|
2164
|
-
if (this.
|
|
2165
|
-
if (!this._markDemandRouted(m[1], routeState)) this._onDemand();
|
|
2166
|
-
} else if (this._control.pauseLockset.has(m[1])) {
|
|
2204
|
+
if (this._control.pauseLockset.has(m[1])) {
|
|
2167
2205
|
this._pauseRelease(m[1]);
|
|
2168
2206
|
} else {
|
|
2169
2207
|
this._forwardUp(m, towardDep, routeState);
|
|
2170
2208
|
}
|
|
2209
|
+
} else if (m[0] === "PULL") {
|
|
2210
|
+
const demand = normalizePullDemand(m[1]);
|
|
2211
|
+
if (this._slot.pull && demand.pullId === this._slot.pullLock) {
|
|
2212
|
+
if (!this._markDemandRouted(demand.pullId, routeState)) this._onDemand(demand);
|
|
2213
|
+
} else {
|
|
2214
|
+
this._forwardUp(["PULL", demand], towardDep, routeState);
|
|
2215
|
+
}
|
|
2171
2216
|
} else if (this._slot.deps.length === 0) {
|
|
2172
2217
|
if (m[0] === "INVALIDATE") this._down([["INVALIDATE"]]);
|
|
2173
2218
|
} else {
|
|
@@ -2189,7 +2234,7 @@ var Node = class {
|
|
|
2189
2234
|
* Forward one up-going control message toward deps (R-up-routing): up the single declared edge
|
|
2190
2235
|
* `towardDep` (directed — prunes other branches; only meaningful on the issuer's FIRST hop) or
|
|
2191
2236
|
* broadcast up ALL deps. A depless source has no deps → the message DROPS here (the terminus —
|
|
2192
|
-
* e.g. a cone-routed
|
|
2237
|
+
* e.g. a cone-routed PULL whose pullId no node up this cone holds, R-up-at-source). Recursive
|
|
2193
2238
|
* forwarding carries the same per-wave route state and no `towardDep` → broadcast beyond the
|
|
2194
2239
|
* first hop.
|
|
2195
2240
|
*/
|
|
@@ -2208,9 +2253,7 @@ var Node = class {
|
|
|
2208
2253
|
}
|
|
2209
2254
|
_hasBoundaryPauseLock() {
|
|
2210
2255
|
if (this._slot.pausable === false) return false;
|
|
2211
|
-
|
|
2212
|
-
if (this._slot.pull && this._control.pauseLockset.has(this._slot.pullLock)) locks--;
|
|
2213
|
-
return locks > 0;
|
|
2256
|
+
return this._control.pauseLockset.size > 0;
|
|
2214
2257
|
}
|
|
2215
2258
|
_isAsyncPool() {
|
|
2216
2259
|
return this._slot.handle !== null && this._slot.dispatcher.poolKind(this._slot.handle.poolId) === "async";
|
|
@@ -2221,17 +2264,19 @@ var Node = class {
|
|
|
2221
2264
|
_pauseRelease(lockId) {
|
|
2222
2265
|
if (!this._control.pauseLockset.has(lockId)) return;
|
|
2223
2266
|
this._control.pauseLockset.delete(lockId);
|
|
2224
|
-
if (this._slot.pull && this._control.demandOwed) this._fireOwedDemandIfReady();
|
|
2267
|
+
if (this._slot.pull && this._control.demandOwed !== void 0) this._fireOwedDemandIfReady();
|
|
2225
2268
|
if (this._hasBoundaryPauseLock()) return;
|
|
2226
2269
|
scheduleBoundaryDrain(this._core);
|
|
2227
|
-
if (this.
|
|
2270
|
+
if (this._slot.pull) return;
|
|
2228
2271
|
this._onResume();
|
|
2229
2272
|
}
|
|
2230
2273
|
_onResume() {
|
|
2231
2274
|
if (this._value.terminal !== void 0) {
|
|
2232
2275
|
this._control.pauseBuffer = [];
|
|
2233
2276
|
this._control.pausedDepWaveOccurred = false;
|
|
2234
|
-
this._control.demandOwed =
|
|
2277
|
+
this._control.demandOwed = void 0;
|
|
2278
|
+
this._control.activePull = void 0;
|
|
2279
|
+
this._control.pullDirtyOwed = false;
|
|
2235
2280
|
return;
|
|
2236
2281
|
}
|
|
2237
2282
|
if (this._control.pauseBuffer.length > 0) {
|
|
@@ -2245,41 +2290,38 @@ var Node = class {
|
|
|
2245
2290
|
}
|
|
2246
2291
|
}
|
|
2247
2292
|
/**
|
|
2248
|
-
* R-pull (
|
|
2293
|
+
* R-pull (D269): can this pull node fire a demand NOW? — not terminal, settle-ready (_pending===0),
|
|
2249
2294
|
* and no OTHER (non-pullId) lock holds it paused. The gate that decides fire-now vs OWE.
|
|
2250
2295
|
*/
|
|
2251
2296
|
_canFireDemand() {
|
|
2252
2297
|
if (this._value.terminal !== void 0 || this._wave.pending > 0) return false;
|
|
2253
|
-
|
|
2254
|
-
return this._control.pauseLockset.size <= own;
|
|
2298
|
+
return this._control.pauseLockset.size === 0;
|
|
2255
2299
|
}
|
|
2256
2300
|
/**
|
|
2257
|
-
* R-pull (
|
|
2258
|
-
*
|
|
2259
|
-
* `finally` so a throwing pull fn (graph-less node, no D30 catch) cannot leave the node
|
|
2260
|
-
* permanently non-quiet (the wedge-fix silently disabled) — QA-found robustness fix.
|
|
2301
|
+
* R-pull (D269/D272): deliver ONE demand pulse — install activePull so the demand wave may
|
|
2302
|
+
* emit, fire it, then clear activePull so the node is quiet again (1:1).
|
|
2261
2303
|
*/
|
|
2262
|
-
_deliverPullDemand() {
|
|
2263
|
-
this._control.demandOwed =
|
|
2304
|
+
_deliverPullDemand(demand) {
|
|
2305
|
+
this._control.demandOwed = void 0;
|
|
2306
|
+
this._control.activePull = demand;
|
|
2264
2307
|
this._control.inDeliverDemand = true;
|
|
2265
|
-
this._control.pauseLockset.delete(this._slot.pullLock);
|
|
2266
2308
|
try {
|
|
2267
2309
|
this._firePullDemand();
|
|
2268
2310
|
} finally {
|
|
2269
|
-
this._control.
|
|
2311
|
+
this._control.activePull = void 0;
|
|
2270
2312
|
this._control.inDeliverDemand = false;
|
|
2271
2313
|
}
|
|
2272
2314
|
}
|
|
2273
2315
|
/**
|
|
2274
|
-
* R-pull (
|
|
2316
|
+
* R-pull (D269): a cone-routed PULL of THIS node's pullId arrived (R-up-routing) = a DEMAND.
|
|
2275
2317
|
* Fire immediately if able; else OWE it — pin-5 (a dep DIRTY in flight, _pending>0) or F4/F5 (an
|
|
2276
2318
|
* external PAUSE lock co-holds the node) — and fire when the node next becomes able. A demand
|
|
2277
2319
|
* arriving WHILE a delivery is in flight (synchronous re-entry) is DROPPED (1:1, QA guard).
|
|
2278
2320
|
*/
|
|
2279
|
-
_onDemand() {
|
|
2321
|
+
_onDemand(demand) {
|
|
2280
2322
|
if (this._control.inDeliverDemand) return;
|
|
2281
|
-
if (this._canFireDemand()) this._deliverPullDemand();
|
|
2282
|
-
else this._control.demandOwed =
|
|
2323
|
+
if (this._canFireDemand()) this._deliverPullDemand(demand);
|
|
2324
|
+
else this._control.demandOwed = demand;
|
|
2283
2325
|
}
|
|
2284
2326
|
/**
|
|
2285
2327
|
* R-pull (D55): service ONE demand. Delivery content = the orthogonal pausable mode:
|
|
@@ -2292,33 +2334,53 @@ var Node = class {
|
|
|
2292
2334
|
* `_markDirty` relays the leading DIRTY (not absorbed).
|
|
2293
2335
|
*/
|
|
2294
2336
|
_firePullDemand() {
|
|
2337
|
+
let drainedBuffer = false;
|
|
2295
2338
|
if (this._control.pauseBuffer.length > 0) {
|
|
2296
2339
|
const buf = this._control.pauseBuffer;
|
|
2297
2340
|
this._control.pauseBuffer = [];
|
|
2298
2341
|
for (const wave of buf) this._down(wave);
|
|
2342
|
+
drainedBuffer = true;
|
|
2299
2343
|
}
|
|
2344
|
+
if (drainedBuffer) return;
|
|
2300
2345
|
if (this._control.pausedDepWaveOccurred) {
|
|
2301
2346
|
const gated = this._slot.handle !== null && !this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled());
|
|
2302
2347
|
if (this._wave.pending > 0 || gated) return;
|
|
2303
2348
|
this._control.pausedDepWaveOccurred = false;
|
|
2304
|
-
this.
|
|
2305
|
-
this.
|
|
2349
|
+
this._wave.emittedDirtyThisWave = false;
|
|
2350
|
+
this._control.pullDirtyOwed = true;
|
|
2351
|
+
try {
|
|
2352
|
+
this._tryRun();
|
|
2353
|
+
} finally {
|
|
2354
|
+
this._control.pullDirtyOwed = false;
|
|
2355
|
+
}
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
if (this._slot.handle !== null) {
|
|
2359
|
+
if (!this._wave.hasCalledFnOnce && !(this._slot.partial || this._allDepsSettled())) return;
|
|
2360
|
+
this._wave.emittedDirtyThisWave = false;
|
|
2361
|
+
this._control.pullDirtyOwed = true;
|
|
2362
|
+
try {
|
|
2363
|
+
this._runWave();
|
|
2364
|
+
} finally {
|
|
2365
|
+
this._control.pullDirtyOwed = false;
|
|
2366
|
+
}
|
|
2306
2367
|
}
|
|
2307
2368
|
}
|
|
2308
2369
|
/**
|
|
2309
|
-
* R-pull (
|
|
2370
|
+
* R-pull (D269): fire a demand that was OWED (deferred at demand time) once the node becomes
|
|
2310
2371
|
* able — called from the dep-settle arms (DATA/RESOLVED/INVALIDATE/terminal drain _pending, pin-5
|
|
2311
2372
|
* + B1/F6) and from `_pauseRelease` (an external PAUSE lock releases, F4/F5).
|
|
2312
2373
|
*/
|
|
2313
2374
|
_fireOwedDemandIfReady() {
|
|
2314
2375
|
if (this._control.inDeliverDemand) return;
|
|
2315
|
-
if (this._slot.pull && this._control.demandOwed && this._canFireDemand())
|
|
2316
|
-
this._deliverPullDemand();
|
|
2376
|
+
if (this._slot.pull && this._control.demandOwed !== void 0 && this._canFireDemand()) {
|
|
2377
|
+
this._deliverPullDemand(this._control.demandOwed);
|
|
2378
|
+
}
|
|
2317
2379
|
}
|
|
2318
2380
|
/** Should an outgoing settle slice be deferred into the pause buffer? */
|
|
2319
2381
|
_shouldBufferOnPause() {
|
|
2320
2382
|
if (this._slot.pausable === false) return false;
|
|
2321
|
-
if (!this._isPaused()) return false;
|
|
2383
|
+
if (!this._isPaused() && !this._isPullQuiet()) return false;
|
|
2322
2384
|
if (this._slot.pausable === "resumeAll") return true;
|
|
2323
2385
|
if (!this._wave.insideRunWave && this._isAsyncPool() && this._slot.deps.length > 0) return true;
|
|
2324
2386
|
return false;
|
|
@@ -2358,7 +2420,9 @@ var Node = class {
|
|
|
2358
2420
|
this._control.pauseLockset.clear();
|
|
2359
2421
|
this._control.pauseBuffer = [];
|
|
2360
2422
|
this._control.pausedDepWaveOccurred = false;
|
|
2361
|
-
this._control.demandOwed =
|
|
2423
|
+
this._control.demandOwed = void 0;
|
|
2424
|
+
this._control.activePull = void 0;
|
|
2425
|
+
this._control.pullDirtyOwed = false;
|
|
2362
2426
|
this._value.replayRing = [];
|
|
2363
2427
|
const isCompute = this._slot.handle !== null || this._slot.deps.length > 0;
|
|
2364
2428
|
if (isCompute) {
|
|
@@ -2553,6 +2617,3197 @@ function timeout(source2, ms) {
|
|
|
2553
2617
|
);
|
|
2554
2618
|
}
|
|
2555
2619
|
|
|
2620
|
+
// src/orchestration/agent-runtime.ts
|
|
2621
|
+
function effectRun(opts) {
|
|
2622
|
+
return {
|
|
2623
|
+
kind: "effect-run",
|
|
2624
|
+
effectRunId: opts.effectRunId,
|
|
2625
|
+
agentRunId: opts.agentRunId,
|
|
2626
|
+
subjectRefs: opts.subjectRefs,
|
|
2627
|
+
goal: opts.goal,
|
|
2628
|
+
sourceRefs: opts.sourceRefs,
|
|
2629
|
+
policyRefs: opts.policyRefs,
|
|
2630
|
+
limits: opts.limits,
|
|
2631
|
+
createdBy: opts.createdBy,
|
|
2632
|
+
createdAtMs: opts.createdAtMs,
|
|
2633
|
+
metadata: opts.metadata
|
|
2634
|
+
};
|
|
2635
|
+
}
|
|
2636
|
+
function agentRequestProposalFromDecision(decision, proposal) {
|
|
2637
|
+
return {
|
|
2638
|
+
kind: "proposal",
|
|
2639
|
+
...proposal,
|
|
2640
|
+
effectRunId: decision.effectRunId,
|
|
2641
|
+
agentRunId: decision.agentRunId,
|
|
2642
|
+
sourceDecisionId: decision.decisionId,
|
|
2643
|
+
evidenceRefs: proposal.evidenceRefs ?? decision.evidenceRefs
|
|
2644
|
+
};
|
|
2645
|
+
}
|
|
2646
|
+
function admitAgentRequestProposal(proposal, opts) {
|
|
2647
|
+
return {
|
|
2648
|
+
kind: "admitted",
|
|
2649
|
+
proposalId: proposal.proposalId,
|
|
2650
|
+
requestId: opts.requestId,
|
|
2651
|
+
operationId: opts.operationId,
|
|
2652
|
+
effectRunId: proposal.effectRunId,
|
|
2653
|
+
agentRunId: proposal.agentRunId,
|
|
2654
|
+
admittedAtMs: opts.admittedAtMs,
|
|
2655
|
+
reason: opts.reason,
|
|
2656
|
+
sourceRefs: opts.sourceRefs,
|
|
2657
|
+
metadata: opts.metadata
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
function issueAgentRequest(proposal, admission, opts = {}) {
|
|
2661
|
+
return {
|
|
2662
|
+
kind: "issued",
|
|
2663
|
+
requestId: admission.requestId,
|
|
2664
|
+
operationId: admission.operationId,
|
|
2665
|
+
effectRunId: admission.effectRunId,
|
|
2666
|
+
agentRunId: admission.agentRunId,
|
|
2667
|
+
proposalId: proposal.proposalId,
|
|
2668
|
+
parentRequestId: proposal.parentRequestId,
|
|
2669
|
+
requestKind: proposal.requestKind,
|
|
2670
|
+
required: proposal.required ?? true,
|
|
2671
|
+
input: proposal.input,
|
|
2672
|
+
payload: proposal.payload,
|
|
2673
|
+
issuedAtMs: opts.issuedAtMs,
|
|
2674
|
+
sourceRefs: opts.sourceRefs ?? admission.sourceRefs,
|
|
2675
|
+
metadata: proposal.metadata
|
|
2676
|
+
};
|
|
2677
|
+
}
|
|
2678
|
+
function agentRequestLedgerViews(graph, facts, opts = {}) {
|
|
2679
|
+
const name = opts.name ?? "agentRequests";
|
|
2680
|
+
const views = graph.node(
|
|
2681
|
+
[facts],
|
|
2682
|
+
(ctx) => {
|
|
2683
|
+
const prev = ctx.state.get() ?? emptyAgentRequestViewsState();
|
|
2684
|
+
const next = cloneAgentRequestViewsState(prev);
|
|
2685
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2686
|
+
const fact = raw;
|
|
2687
|
+
reduceAgentRequestViews(next, fact);
|
|
2688
|
+
}
|
|
2689
|
+
ctx.state.set(next);
|
|
2690
|
+
ctx.down([["DATA", freezeAgentRequestViews(next)]]);
|
|
2691
|
+
},
|
|
2692
|
+
{ name: `${name}/views`, factory: "agentRequestLedgerViews" }
|
|
2693
|
+
);
|
|
2694
|
+
const issues = graph.node(
|
|
2695
|
+
[facts],
|
|
2696
|
+
(ctx) => {
|
|
2697
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2698
|
+
const fact = raw;
|
|
2699
|
+
if (fact.kind === "rejected") ctx.down([["DATA", fact.issue]]);
|
|
2700
|
+
if (fact.kind === "status") {
|
|
2701
|
+
for (const issue of fact.issues ?? []) ctx.down([["DATA", issue]]);
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
},
|
|
2705
|
+
{ name: `${name}/issues`, factory: "agentRequestLedgerIssues" }
|
|
2706
|
+
);
|
|
2707
|
+
const audit = graph.node(
|
|
2708
|
+
[facts],
|
|
2709
|
+
(ctx) => {
|
|
2710
|
+
let seq = ctx.state.get() ?? 0;
|
|
2711
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2712
|
+
seq += 1;
|
|
2713
|
+
const fact = raw;
|
|
2714
|
+
ctx.down([
|
|
2715
|
+
[
|
|
2716
|
+
"DATA",
|
|
2717
|
+
{
|
|
2718
|
+
id: `${name}:ledger:${seq}`,
|
|
2719
|
+
kind: `agent-request-${fact.kind}`,
|
|
2720
|
+
subjectId: "requestId" in fact ? fact.requestId : fact.proposalId
|
|
2721
|
+
}
|
|
2722
|
+
]
|
|
2723
|
+
]);
|
|
2724
|
+
}
|
|
2725
|
+
ctx.state.set(seq);
|
|
2726
|
+
},
|
|
2727
|
+
{ name: `${name}/audit`, factory: "agentRequestLedgerAudit" }
|
|
2728
|
+
);
|
|
2729
|
+
return { views, issues, audit };
|
|
2730
|
+
}
|
|
2731
|
+
function requestSatisfactionProjector(graph, opts) {
|
|
2732
|
+
const name = opts.name ?? "requestSatisfaction";
|
|
2733
|
+
const profileDeps = opts.executorProfiles ?? [];
|
|
2734
|
+
const routeDeps = opts.executorRoutes ?? [];
|
|
2735
|
+
const outcomeDeps = opts.executorOutcomes ?? [];
|
|
2736
|
+
const contextDeps = opts.contextContributions ?? [];
|
|
2737
|
+
const promptDeps = opts.promptBundles ?? [];
|
|
2738
|
+
const deps = [
|
|
2739
|
+
opts.requestFacts,
|
|
2740
|
+
...profileDeps,
|
|
2741
|
+
...routeDeps,
|
|
2742
|
+
...outcomeDeps,
|
|
2743
|
+
...contextDeps,
|
|
2744
|
+
...promptDeps
|
|
2745
|
+
];
|
|
2746
|
+
const profileStart = 1;
|
|
2747
|
+
const routeStart = profileStart + profileDeps.length;
|
|
2748
|
+
const outcomeStart = routeStart + routeDeps.length;
|
|
2749
|
+
const contextStart = outcomeStart + outcomeDeps.length;
|
|
2750
|
+
const promptStart = contextStart + contextDeps.length;
|
|
2751
|
+
const runtime = graph.node(
|
|
2752
|
+
deps,
|
|
2753
|
+
(ctx) => {
|
|
2754
|
+
const state = ctx.state.get() ?? {
|
|
2755
|
+
requests: /* @__PURE__ */ new Map(),
|
|
2756
|
+
profiles: /* @__PURE__ */ new Map(),
|
|
2757
|
+
routes: /* @__PURE__ */ new Map(),
|
|
2758
|
+
outcomes: /* @__PURE__ */ new Map(),
|
|
2759
|
+
contexts: /* @__PURE__ */ new Map(),
|
|
2760
|
+
prompts: /* @__PURE__ */ new Map(),
|
|
2761
|
+
compatibleRoutesByRouteId: /* @__PURE__ */ new Map(),
|
|
2762
|
+
terminalRequests: /* @__PURE__ */ new Set(),
|
|
2763
|
+
acceptedTerminalFactIds: /* @__PURE__ */ new Set(),
|
|
2764
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
2765
|
+
statusKeys: /* @__PURE__ */ new Set(),
|
|
2766
|
+
issueSeq: 0,
|
|
2767
|
+
auditSeq: 0
|
|
2768
|
+
};
|
|
2769
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
2770
|
+
if (fact.kind === "issued") {
|
|
2771
|
+
const request = fact;
|
|
2772
|
+
state.requests.set(request.requestId, request);
|
|
2773
|
+
emitStatus(ctx, state, request, initialRequestStatus(request), [
|
|
2774
|
+
ref("agent-request", request.requestId)
|
|
2775
|
+
]);
|
|
2776
|
+
}
|
|
2777
|
+
}
|
|
2778
|
+
forEachDepBatch(ctx, profileStart, profileDeps.length, (raw) => {
|
|
2779
|
+
const profile = raw;
|
|
2780
|
+
state.profiles.set(profile.profileId, profile);
|
|
2781
|
+
});
|
|
2782
|
+
forEachDepBatch(ctx, routeStart, routeDeps.length, (raw) => {
|
|
2783
|
+
const route = raw;
|
|
2784
|
+
state.routes.set(route.routeId, route);
|
|
2785
|
+
});
|
|
2786
|
+
forEachDepBatch(ctx, outcomeStart, outcomeDeps.length, (raw) => {
|
|
2787
|
+
const outcome = raw;
|
|
2788
|
+
state.outcomes.set(outcome.outcomeId, outcome);
|
|
2789
|
+
});
|
|
2790
|
+
forEachDepBatch(ctx, contextStart, contextDeps.length, (raw) => {
|
|
2791
|
+
const contribution = raw;
|
|
2792
|
+
state.contexts.set(contribution.contributionId, contribution);
|
|
2793
|
+
});
|
|
2794
|
+
forEachDepBatch(ctx, promptStart, promptDeps.length, (raw) => {
|
|
2795
|
+
const prompt = raw;
|
|
2796
|
+
state.prompts.set(prompt.promptId, prompt);
|
|
2797
|
+
});
|
|
2798
|
+
evaluateRequestSatisfaction(ctx, state);
|
|
2799
|
+
ctx.state.set(state);
|
|
2800
|
+
},
|
|
2801
|
+
{ name: `${name}/runtime`, factory: "requestSatisfactionProjector" }
|
|
2802
|
+
);
|
|
2803
|
+
const status = graph.node(
|
|
2804
|
+
[runtime],
|
|
2805
|
+
(ctx) => {
|
|
2806
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
2807
|
+
const typed = fact;
|
|
2808
|
+
if (typed.kind === "status") ctx.down([["DATA", typed.status]]);
|
|
2809
|
+
}
|
|
2810
|
+
},
|
|
2811
|
+
{ name: `${name}/status`, factory: "requestSatisfactionStatus" }
|
|
2812
|
+
);
|
|
2813
|
+
const issues = graph.node(
|
|
2814
|
+
[runtime],
|
|
2815
|
+
(ctx) => {
|
|
2816
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
2817
|
+
const typed = fact;
|
|
2818
|
+
if (typed.kind === "issue") ctx.down([["DATA", typed.issue]]);
|
|
2819
|
+
}
|
|
2820
|
+
},
|
|
2821
|
+
{ name: `${name}/issues`, factory: "requestSatisfactionIssues" }
|
|
2822
|
+
);
|
|
2823
|
+
const audit = graph.node(
|
|
2824
|
+
[runtime],
|
|
2825
|
+
(ctx) => {
|
|
2826
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
2827
|
+
const typed = fact;
|
|
2828
|
+
if (typed.kind === "audit") ctx.down([["DATA", typed.audit]]);
|
|
2829
|
+
}
|
|
2830
|
+
},
|
|
2831
|
+
{ name: `${name}/audit`, factory: "requestSatisfactionAudit" }
|
|
2832
|
+
);
|
|
2833
|
+
return { status, issues, audit };
|
|
2834
|
+
}
|
|
2835
|
+
function localBuiltinToolProviderCatalog(opts = {}) {
|
|
2836
|
+
const providerId = opts.providerId ?? "local-builtin";
|
|
2837
|
+
const executorId = opts.executorId ?? `${providerId}:tool-executor`;
|
|
2838
|
+
const profileId = opts.profileId ?? `${providerId}:tool-profile`;
|
|
2839
|
+
const tools = opts.tools ?? [
|
|
2840
|
+
{ toolName: "document/read-doc", operation: "read" },
|
|
2841
|
+
{ toolName: "file.read", operation: "read" },
|
|
2842
|
+
{ toolName: "file.edit/apply-patch", operation: "edit" },
|
|
2843
|
+
{ toolName: "bash.run", operation: "run" },
|
|
2844
|
+
{ toolName: "url.fetch", operation: "fetch" },
|
|
2845
|
+
{ toolName: "date.now", operation: "read" },
|
|
2846
|
+
{ toolName: "weather.fetch", operation: "fetch" },
|
|
2847
|
+
{ toolName: "calculator/eval", operation: "eval" }
|
|
2848
|
+
];
|
|
2849
|
+
const toolEntries = tools.map(
|
|
2850
|
+
(tool) => Object.freeze({
|
|
2851
|
+
kind: "tool-catalog-entry",
|
|
2852
|
+
providerId,
|
|
2853
|
+
inputKind: "tool-call",
|
|
2854
|
+
profileId,
|
|
2855
|
+
executorId,
|
|
2856
|
+
...tool
|
|
2857
|
+
})
|
|
2858
|
+
);
|
|
2859
|
+
return Object.freeze({
|
|
2860
|
+
kind: "tool-provider-catalog",
|
|
2861
|
+
providerId,
|
|
2862
|
+
providerKind: "local-builtin",
|
|
2863
|
+
status: "ready",
|
|
2864
|
+
profiles: Object.freeze([
|
|
2865
|
+
Object.freeze({
|
|
2866
|
+
profileId,
|
|
2867
|
+
executorId,
|
|
2868
|
+
kind: "tool",
|
|
2869
|
+
acceptedInputKinds: Object.freeze(["tool-call"]),
|
|
2870
|
+
acceptedResultKinds: Object.freeze(
|
|
2871
|
+
Array.from(new Set(toolEntries.flatMap((tool) => tool.resultKinds ?? [])))
|
|
2872
|
+
),
|
|
2873
|
+
capabilities: Object.freeze({
|
|
2874
|
+
toolNames: Object.freeze(toolEntries.map((tool) => tool.toolName)),
|
|
2875
|
+
...opts.capabilities ?? {}
|
|
2876
|
+
}),
|
|
2877
|
+
limits: opts.limits,
|
|
2878
|
+
metadata: opts.metadata
|
|
2879
|
+
})
|
|
2880
|
+
]),
|
|
2881
|
+
tools: Object.freeze(toolEntries),
|
|
2882
|
+
metadata: opts.metadata
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
function executorOutcomeViewProjector(graph, opts) {
|
|
2886
|
+
const name = opts.name ?? "executorOutcomeViews";
|
|
2887
|
+
const policy = {
|
|
2888
|
+
audience: opts.policy?.audience ?? "agent-observation",
|
|
2889
|
+
maxSummaryChars: opts.policy?.maxSummaryChars ?? 512,
|
|
2890
|
+
includeIssues: opts.policy?.includeIssues ?? true,
|
|
2891
|
+
includeUsage: opts.policy?.includeUsage ?? false,
|
|
2892
|
+
includeMetadata: opts.policy?.includeMetadata ?? false
|
|
2893
|
+
};
|
|
2894
|
+
const runtime = graph.node(
|
|
2895
|
+
[opts.outcomes],
|
|
2896
|
+
(ctx) => {
|
|
2897
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2898
|
+
const outcome = raw;
|
|
2899
|
+
const projection = executorOutcomeViewProjectionFromOutcome(outcome, policy);
|
|
2900
|
+
ctx.down([
|
|
2901
|
+
["DATA", { kind: "view", view: projection.view }],
|
|
2902
|
+
[
|
|
2903
|
+
"DATA",
|
|
2904
|
+
{
|
|
2905
|
+
kind: "audit",
|
|
2906
|
+
audit: {
|
|
2907
|
+
id: `${outcome.outcomeId}:outcome-view:${policy.audience}`,
|
|
2908
|
+
kind: "executor-outcome-view-projected",
|
|
2909
|
+
subjectId: outcome.requestId,
|
|
2910
|
+
sourceRefs: [ref("executor-outcome", outcome.outcomeId)],
|
|
2911
|
+
metadata: { audience: policy.audience, status: outcome.kind }
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
]
|
|
2915
|
+
]);
|
|
2916
|
+
for (const issue of projection.issues) {
|
|
2917
|
+
ctx.down([["DATA", { kind: "issue", issue }]]);
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
},
|
|
2921
|
+
{ name: `${name}/runtime`, factory: "executorOutcomeViewProjector" }
|
|
2922
|
+
);
|
|
2923
|
+
return {
|
|
2924
|
+
views: projectRuntimeFact(
|
|
2925
|
+
graph,
|
|
2926
|
+
runtime,
|
|
2927
|
+
`${name}/views`,
|
|
2928
|
+
"executorOutcomeViews",
|
|
2929
|
+
(fact) => fact.kind === "view" ? fact.view : void 0
|
|
2930
|
+
),
|
|
2931
|
+
issues: projectRuntimeFact(
|
|
2932
|
+
graph,
|
|
2933
|
+
runtime,
|
|
2934
|
+
`${name}/issues`,
|
|
2935
|
+
"executorOutcomeViewIssues",
|
|
2936
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
2937
|
+
),
|
|
2938
|
+
audit: projectRuntimeFact(
|
|
2939
|
+
graph,
|
|
2940
|
+
runtime,
|
|
2941
|
+
`${name}/audit`,
|
|
2942
|
+
"executorOutcomeViewAudit",
|
|
2943
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
2944
|
+
)
|
|
2945
|
+
};
|
|
2946
|
+
}
|
|
2947
|
+
function structuredAgentDecisionInterpreter(graph, outcomes, opts = {}) {
|
|
2948
|
+
const name = opts.name ?? "structuredAgentDecisionInterpreter";
|
|
2949
|
+
const requestFacts = opts.requestFacts ?? [];
|
|
2950
|
+
const runtime = graph.node(
|
|
2951
|
+
[outcomes, ...requestFacts],
|
|
2952
|
+
(ctx) => {
|
|
2953
|
+
const state = ctx.state.get() ?? {
|
|
2954
|
+
requests: /* @__PURE__ */ new Map(),
|
|
2955
|
+
issueSeq: 0
|
|
2956
|
+
};
|
|
2957
|
+
forEachDepBatch(ctx, 1, requestFacts.length, (raw) => {
|
|
2958
|
+
const fact = raw;
|
|
2959
|
+
if (fact.kind === "issued") state.requests.set(fact.requestId, fact);
|
|
2960
|
+
});
|
|
2961
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
2962
|
+
const outcome = raw;
|
|
2963
|
+
if (outcome.kind !== "result") {
|
|
2964
|
+
state.issueSeq += 1;
|
|
2965
|
+
emitInterpreterIssue(
|
|
2966
|
+
ctx,
|
|
2967
|
+
state.issueSeq,
|
|
2968
|
+
outcome,
|
|
2969
|
+
"non-result-outcome",
|
|
2970
|
+
"Only result outcomes can carry AgentDecision envelopes"
|
|
2971
|
+
);
|
|
2972
|
+
continue;
|
|
2973
|
+
}
|
|
2974
|
+
const value = outcome.result.value;
|
|
2975
|
+
if (!isRecord(value)) {
|
|
2976
|
+
state.issueSeq += 1;
|
|
2977
|
+
emitInterpreterIssue(
|
|
2978
|
+
ctx,
|
|
2979
|
+
state.issueSeq,
|
|
2980
|
+
outcome,
|
|
2981
|
+
"malformed-agent-decision",
|
|
2982
|
+
"ExecutorOutcome result must carry a structured agent-decision envelope"
|
|
2983
|
+
);
|
|
2984
|
+
continue;
|
|
2985
|
+
}
|
|
2986
|
+
const envelope = value;
|
|
2987
|
+
if (envelope.kind !== "agent-decision" || !isRecord(envelope.decision)) {
|
|
2988
|
+
state.issueSeq += 1;
|
|
2989
|
+
emitInterpreterIssue(
|
|
2990
|
+
ctx,
|
|
2991
|
+
state.issueSeq,
|
|
2992
|
+
outcome,
|
|
2993
|
+
"malformed-agent-decision",
|
|
2994
|
+
"Structured agent-decision envelope is missing kind or decision"
|
|
2995
|
+
);
|
|
2996
|
+
continue;
|
|
2997
|
+
}
|
|
2998
|
+
if (typeof envelope.schemaRef !== "string" || envelope.schemaRef.length === 0) {
|
|
2999
|
+
state.issueSeq += 1;
|
|
3000
|
+
emitInterpreterIssue(
|
|
3001
|
+
ctx,
|
|
3002
|
+
state.issueSeq,
|
|
3003
|
+
outcome,
|
|
3004
|
+
"missing-agent-decision-schema",
|
|
3005
|
+
"Structured agent-decision envelope must carry schemaRef evidence"
|
|
3006
|
+
);
|
|
3007
|
+
continue;
|
|
3008
|
+
}
|
|
3009
|
+
if (opts.schemaRef !== void 0 && envelope.schemaRef !== opts.schemaRef) {
|
|
3010
|
+
state.issueSeq += 1;
|
|
3011
|
+
emitInterpreterIssue(
|
|
3012
|
+
ctx,
|
|
3013
|
+
state.issueSeq,
|
|
3014
|
+
outcome,
|
|
3015
|
+
"agent-decision-schema-mismatch",
|
|
3016
|
+
"Structured agent-decision envelope schemaRef did not match"
|
|
3017
|
+
);
|
|
3018
|
+
continue;
|
|
3019
|
+
}
|
|
3020
|
+
const decision = validateAgentDecision(envelope.decision, outcome);
|
|
3021
|
+
if (typeof decision === "string") {
|
|
3022
|
+
state.issueSeq += 1;
|
|
3023
|
+
emitInterpreterIssue(ctx, state.issueSeq, outcome, "malformed-agent-decision", decision);
|
|
3024
|
+
continue;
|
|
3025
|
+
}
|
|
3026
|
+
const request = state.requests.get(decision.source.requestId);
|
|
3027
|
+
if (request === void 0) {
|
|
3028
|
+
state.issueSeq += 1;
|
|
3029
|
+
emitInterpreterIssue(
|
|
3030
|
+
ctx,
|
|
3031
|
+
state.issueSeq,
|
|
3032
|
+
outcome,
|
|
3033
|
+
"missing-agent-decision-request",
|
|
3034
|
+
"AgentDecision source request must be present in the request ledger"
|
|
3035
|
+
);
|
|
3036
|
+
continue;
|
|
3037
|
+
}
|
|
3038
|
+
if (request.effectRunId !== decision.effectRunId || request.operationId !== decision.source.operationId) {
|
|
3039
|
+
state.issueSeq += 1;
|
|
3040
|
+
emitInterpreterIssue(
|
|
3041
|
+
ctx,
|
|
3042
|
+
state.issueSeq,
|
|
3043
|
+
outcome,
|
|
3044
|
+
"stale-agent-decision-source",
|
|
3045
|
+
"AgentDecision source request/effectRun/operation identity did not match the request ledger"
|
|
3046
|
+
);
|
|
3047
|
+
continue;
|
|
3048
|
+
}
|
|
3049
|
+
ctx.down([
|
|
3050
|
+
["DATA", { kind: "decision", decision }],
|
|
3051
|
+
[
|
|
3052
|
+
"DATA",
|
|
3053
|
+
{
|
|
3054
|
+
kind: "audit",
|
|
3055
|
+
audit: {
|
|
3056
|
+
id: `${outcome.outcomeId}:agent-decision-interpreted`,
|
|
3057
|
+
kind: "agent-decision-interpreted",
|
|
3058
|
+
subjectId: decision.effectRunId,
|
|
3059
|
+
sourceRefs: [ref("executor-outcome", outcome.outcomeId)]
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
]
|
|
3063
|
+
]);
|
|
3064
|
+
}
|
|
3065
|
+
ctx.state.set(state);
|
|
3066
|
+
},
|
|
3067
|
+
{ name: `${name}/runtime`, factory: "structuredAgentDecisionInterpreter" }
|
|
3068
|
+
);
|
|
3069
|
+
return {
|
|
3070
|
+
decisions: projectRuntimeFact(
|
|
3071
|
+
graph,
|
|
3072
|
+
runtime,
|
|
3073
|
+
`${name}/decisions`,
|
|
3074
|
+
"structuredAgentDecisions",
|
|
3075
|
+
(fact) => fact.kind === "decision" ? fact.decision : void 0
|
|
3076
|
+
),
|
|
3077
|
+
issues: projectRuntimeFact(
|
|
3078
|
+
graph,
|
|
3079
|
+
runtime,
|
|
3080
|
+
`${name}/issues`,
|
|
3081
|
+
"structuredAgentDecisionIssues",
|
|
3082
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
3083
|
+
),
|
|
3084
|
+
audit: projectRuntimeFact(
|
|
3085
|
+
graph,
|
|
3086
|
+
runtime,
|
|
3087
|
+
`${name}/audit`,
|
|
3088
|
+
"structuredAgentDecisionAudit",
|
|
3089
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
3090
|
+
)
|
|
3091
|
+
};
|
|
3092
|
+
}
|
|
3093
|
+
function effectRunCompletionProjector(graph, opts) {
|
|
3094
|
+
const name = opts.name ?? "effectRunCompletion";
|
|
3095
|
+
const decisions = opts.decisions ?? [];
|
|
3096
|
+
const requestStatuses = opts.requestStatuses ?? [];
|
|
3097
|
+
const requestFacts = opts.requestFacts ?? [];
|
|
3098
|
+
const resultCandidates = opts.resultCandidates ?? [];
|
|
3099
|
+
const deps = [
|
|
3100
|
+
opts.effectRuns,
|
|
3101
|
+
...decisions,
|
|
3102
|
+
...requestStatuses,
|
|
3103
|
+
...requestFacts,
|
|
3104
|
+
...resultCandidates
|
|
3105
|
+
];
|
|
3106
|
+
const decisionStart = 1;
|
|
3107
|
+
const requestStatusStart = decisionStart + decisions.length;
|
|
3108
|
+
const requestFactStart = requestStatusStart + requestStatuses.length;
|
|
3109
|
+
const resultCandidateStart = requestFactStart + requestFacts.length;
|
|
3110
|
+
const now = opts.now ?? Date.now;
|
|
3111
|
+
const runtime = graph.node(
|
|
3112
|
+
deps,
|
|
3113
|
+
(ctx) => {
|
|
3114
|
+
const state = ctx.state.get() ?? emptyEffectRunCompletionState();
|
|
3115
|
+
const touchedEffectRunIds = /* @__PURE__ */ new Set();
|
|
3116
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
3117
|
+
const run = raw;
|
|
3118
|
+
state.runs.set(run.effectRunId, run);
|
|
3119
|
+
touchedEffectRunIds.add(run.effectRunId);
|
|
3120
|
+
}
|
|
3121
|
+
forEachDepBatch(ctx, requestFactStart, requestFacts.length, (raw) => {
|
|
3122
|
+
const fact = raw;
|
|
3123
|
+
if (fact.kind === "issued") {
|
|
3124
|
+
state.requests.set(fact.requestId, fact);
|
|
3125
|
+
touchedEffectRunIds.add(fact.effectRunId);
|
|
3126
|
+
const existingStatus = state.statusByRequest.get(fact.requestId);
|
|
3127
|
+
if (existingStatus !== void 0 && !statusMatchesRequest(existingStatus, fact)) {
|
|
3128
|
+
emitEffectRunIssue(
|
|
3129
|
+
ctx,
|
|
3130
|
+
state,
|
|
3131
|
+
"stale-request-status",
|
|
3132
|
+
`AgentRequest status for '${fact.requestId}' did not match its issued effectRun/operation identity`,
|
|
3133
|
+
fact.effectRunId,
|
|
3134
|
+
[ref("agent-request", fact.requestId)]
|
|
3135
|
+
);
|
|
3136
|
+
}
|
|
3137
|
+
const result = state.resultsByEffectRun.get(fact.effectRunId);
|
|
3138
|
+
if (result !== void 0 && fact.required) {
|
|
3139
|
+
state.issueSeq += 1;
|
|
3140
|
+
const issue = dataIssue(
|
|
3141
|
+
"late-required-request-after-effect-run-result",
|
|
3142
|
+
`Required request '${fact.requestId}' arrived after EffectRun '${fact.effectRunId}' already had a terminal result`,
|
|
3143
|
+
{
|
|
3144
|
+
subjectId: fact.effectRunId,
|
|
3145
|
+
refs: [
|
|
3146
|
+
ref("agent-request", fact.requestId),
|
|
3147
|
+
ref("effect-run-result", result.resultId)
|
|
3148
|
+
]
|
|
3149
|
+
}
|
|
3150
|
+
);
|
|
3151
|
+
ctx.down([
|
|
3152
|
+
["DATA", { kind: "issue", issue }],
|
|
3153
|
+
[
|
|
3154
|
+
"DATA",
|
|
3155
|
+
{
|
|
3156
|
+
kind: "audit",
|
|
3157
|
+
audit: {
|
|
3158
|
+
id: `${fact.effectRunId}:late-required-request:${state.issueSeq}`,
|
|
3159
|
+
kind: "late-required-request-after-effect-run-result",
|
|
3160
|
+
subjectId: fact.effectRunId,
|
|
3161
|
+
issueCode: issue.code,
|
|
3162
|
+
sourceRefs: [
|
|
3163
|
+
ref("agent-request", fact.requestId),
|
|
3164
|
+
ref("effect-run-result", result.resultId)
|
|
3165
|
+
]
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
]
|
|
3169
|
+
]);
|
|
3170
|
+
}
|
|
3171
|
+
} else if (fact.kind === "status") {
|
|
3172
|
+
acceptRequestStatus(ctx, state, fact);
|
|
3173
|
+
touchedEffectRunIds.add(fact.effectRunId);
|
|
3174
|
+
}
|
|
3175
|
+
});
|
|
3176
|
+
forEachDepBatch(ctx, requestStatusStart, requestStatuses.length, (raw) => {
|
|
3177
|
+
const status = raw;
|
|
3178
|
+
acceptRequestStatus(ctx, state, status);
|
|
3179
|
+
touchedEffectRunIds.add(status.effectRunId);
|
|
3180
|
+
});
|
|
3181
|
+
forEachDepBatch(ctx, resultCandidateStart, resultCandidates.length, (raw) => {
|
|
3182
|
+
acceptEffectRunResultCandidate(ctx, state, raw);
|
|
3183
|
+
});
|
|
3184
|
+
forEachDepBatch(ctx, decisionStart, decisions.length, (raw) => {
|
|
3185
|
+
const decision = raw;
|
|
3186
|
+
state.decisions.set(decision.decisionId, decision);
|
|
3187
|
+
touchedEffectRunIds.add(decision.effectRunId);
|
|
3188
|
+
});
|
|
3189
|
+
for (const decision of state.decisions.values()) {
|
|
3190
|
+
if (state.resultsByEffectRun.has(decision.effectRunId)) continue;
|
|
3191
|
+
const candidate = candidateFromDecision(decision, state, now());
|
|
3192
|
+
if (candidate === void 0) continue;
|
|
3193
|
+
acceptEffectRunResultCandidate(ctx, state, candidate);
|
|
3194
|
+
}
|
|
3195
|
+
for (const effectRunId of touchedEffectRunIds) {
|
|
3196
|
+
if (!state.resultsByEffectRun.has(effectRunId)) {
|
|
3197
|
+
emitEffectRunStatus(
|
|
3198
|
+
ctx,
|
|
3199
|
+
effectRunId,
|
|
3200
|
+
"pending",
|
|
3201
|
+
requiredPendingRequests(effectRunId, state),
|
|
3202
|
+
requiredTerminalRequests(effectRunId, state)
|
|
3203
|
+
);
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
ctx.state.set(state);
|
|
3207
|
+
},
|
|
3208
|
+
{ name: `${name}/runtime`, factory: "effectRunCompletionProjector" }
|
|
3209
|
+
);
|
|
3210
|
+
return {
|
|
3211
|
+
results: projectRuntimeFact(
|
|
3212
|
+
graph,
|
|
3213
|
+
runtime,
|
|
3214
|
+
`${name}/results`,
|
|
3215
|
+
"effectRunCompletionResults",
|
|
3216
|
+
(fact) => fact.kind === "result" ? fact.result : void 0
|
|
3217
|
+
),
|
|
3218
|
+
status: projectRuntimeFact(
|
|
3219
|
+
graph,
|
|
3220
|
+
runtime,
|
|
3221
|
+
`${name}/status`,
|
|
3222
|
+
"effectRunCompletionStatus",
|
|
3223
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
3224
|
+
),
|
|
3225
|
+
issues: projectRuntimeFact(
|
|
3226
|
+
graph,
|
|
3227
|
+
runtime,
|
|
3228
|
+
`${name}/issues`,
|
|
3229
|
+
"effectRunCompletionIssues",
|
|
3230
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
3231
|
+
),
|
|
3232
|
+
audit: projectRuntimeFact(
|
|
3233
|
+
graph,
|
|
3234
|
+
runtime,
|
|
3235
|
+
`${name}/audit`,
|
|
3236
|
+
"effectRunCompletionAudit",
|
|
3237
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
3238
|
+
)
|
|
3239
|
+
};
|
|
3240
|
+
}
|
|
3241
|
+
function fakeExecutorResult(opts) {
|
|
3242
|
+
return { kind: "result", ...opts };
|
|
3243
|
+
}
|
|
3244
|
+
function fakeExecutorFailure(opts) {
|
|
3245
|
+
return { kind: "failure", ...opts };
|
|
3246
|
+
}
|
|
3247
|
+
function fakeExecutorBlocked(opts) {
|
|
3248
|
+
return { kind: "blocked", ...opts };
|
|
3249
|
+
}
|
|
3250
|
+
function fakeExecutorTimeout(opts) {
|
|
3251
|
+
return { kind: "timeout", ...opts };
|
|
3252
|
+
}
|
|
3253
|
+
function fakeExecutorCanceled(opts) {
|
|
3254
|
+
return { kind: "canceled", ...opts };
|
|
3255
|
+
}
|
|
3256
|
+
function initialRequestStatus(request) {
|
|
3257
|
+
if (request.requestKind === "context") return "awaiting-context";
|
|
3258
|
+
if (request.requestKind === "prompt") return "awaiting-prompt";
|
|
3259
|
+
return "awaiting-route";
|
|
3260
|
+
}
|
|
3261
|
+
function evaluateRequestSatisfaction(ctx, state) {
|
|
3262
|
+
for (const route of state.routes.values()) handleRoute(ctx, state, route);
|
|
3263
|
+
for (const contribution of state.contexts.values())
|
|
3264
|
+
handleContextContribution(ctx, state, contribution);
|
|
3265
|
+
for (const prompt of state.prompts.values()) handlePromptBundle(ctx, state, prompt);
|
|
3266
|
+
for (const outcome of state.outcomes.values()) handleExecutorOutcome(ctx, state, outcome);
|
|
3267
|
+
}
|
|
3268
|
+
function handleRoute(ctx, state, route) {
|
|
3269
|
+
const request = state.requests.get(route.requestId);
|
|
3270
|
+
if (request === void 0) {
|
|
3271
|
+
return;
|
|
3272
|
+
}
|
|
3273
|
+
if (state.terminalRequests.has(request.requestId)) {
|
|
3274
|
+
if (state.compatibleRoutesByRouteId.get(route.routeId)?.requestId !== request.requestId) {
|
|
3275
|
+
emitIssueOnce(
|
|
3276
|
+
ctx,
|
|
3277
|
+
state,
|
|
3278
|
+
`late-route:${route.routeId}`,
|
|
3279
|
+
"late-route-after-terminal",
|
|
3280
|
+
`ExecutorRoute '${route.routeId}' arrived after request '${request.requestId}' was already terminal`,
|
|
3281
|
+
request.requestId,
|
|
3282
|
+
[ref("executor-route", route.routeId), ref("agent-request", request.requestId)]
|
|
3283
|
+
);
|
|
3284
|
+
}
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
if (request.operationId !== route.operationId) {
|
|
3288
|
+
emitIssueOnce(
|
|
3289
|
+
ctx,
|
|
3290
|
+
state,
|
|
3291
|
+
`stale-route:${route.routeId}`,
|
|
3292
|
+
"stale-route-operation",
|
|
3293
|
+
`ExecutorRoute '${route.routeId}' operationId does not match request '${request.requestId}'`,
|
|
3294
|
+
request.requestId,
|
|
3295
|
+
[ref("executor-route", route.routeId), ref("agent-request", request.requestId)]
|
|
3296
|
+
);
|
|
3297
|
+
return;
|
|
3298
|
+
}
|
|
3299
|
+
const profile = state.profiles.get(route.profileId);
|
|
3300
|
+
if (profile === void 0) {
|
|
3301
|
+
return;
|
|
3302
|
+
}
|
|
3303
|
+
const compatibilityIssue = routeCompatibilityIssue(request, route, profile);
|
|
3304
|
+
if (compatibilityIssue !== void 0) {
|
|
3305
|
+
emitIssueOnce(
|
|
3306
|
+
ctx,
|
|
3307
|
+
state,
|
|
3308
|
+
`route-incompatible:${route.routeId}:${compatibilityIssue}`,
|
|
3309
|
+
compatibilityIssue,
|
|
3310
|
+
`ExecutorRoute '${route.routeId}' is incompatible with request '${request.requestId}'`,
|
|
3311
|
+
request.requestId,
|
|
3312
|
+
[
|
|
3313
|
+
ref("executor-route", route.routeId),
|
|
3314
|
+
ref("executor-profile", profile.profileId),
|
|
3315
|
+
ref("agent-request", request.requestId)
|
|
3316
|
+
]
|
|
3317
|
+
);
|
|
3318
|
+
return;
|
|
3319
|
+
}
|
|
3320
|
+
state.compatibleRoutesByRouteId.set(route.routeId, route);
|
|
3321
|
+
emitStatusOnce(
|
|
3322
|
+
ctx,
|
|
3323
|
+
state,
|
|
3324
|
+
`route:${route.routeId}:awaiting-provider`,
|
|
3325
|
+
request,
|
|
3326
|
+
"awaiting-provider",
|
|
3327
|
+
[
|
|
3328
|
+
ref("executor-route", route.routeId),
|
|
3329
|
+
ref("executor-profile", profile.profileId),
|
|
3330
|
+
ref("agent-request", request.requestId)
|
|
3331
|
+
]
|
|
3332
|
+
);
|
|
3333
|
+
}
|
|
3334
|
+
function handleExecutorOutcome(ctx, state, outcome) {
|
|
3335
|
+
const request = state.requests.get(outcome.requestId);
|
|
3336
|
+
if (request === void 0) {
|
|
3337
|
+
return;
|
|
3338
|
+
}
|
|
3339
|
+
if (request.operationId !== outcome.operationId) {
|
|
3340
|
+
emitIssueOnce(
|
|
3341
|
+
ctx,
|
|
3342
|
+
state,
|
|
3343
|
+
`stale-outcome:${outcome.outcomeId}`,
|
|
3344
|
+
"stale-outcome-operation",
|
|
3345
|
+
`ExecutorOutcome '${outcome.outcomeId}' operationId does not match request '${request.requestId}'`,
|
|
3346
|
+
request.requestId,
|
|
3347
|
+
[ref("executor-outcome", outcome.outcomeId), ref("agent-request", request.requestId)]
|
|
3348
|
+
);
|
|
3349
|
+
return;
|
|
3350
|
+
}
|
|
3351
|
+
const route = state.compatibleRoutesByRouteId.get(outcome.routeId);
|
|
3352
|
+
if (route === void 0 || route.requestId !== request.requestId) {
|
|
3353
|
+
emitIssueOnce(
|
|
3354
|
+
ctx,
|
|
3355
|
+
state,
|
|
3356
|
+
`missing-route:${outcome.outcomeId}`,
|
|
3357
|
+
"missing-compatible-route",
|
|
3358
|
+
`ExecutorOutcome '${outcome.outcomeId}' has no compatible route for request '${request.requestId}'`,
|
|
3359
|
+
request.requestId,
|
|
3360
|
+
[ref("executor-outcome", outcome.outcomeId), ref("agent-request", request.requestId)]
|
|
3361
|
+
);
|
|
3362
|
+
return;
|
|
3363
|
+
}
|
|
3364
|
+
const outcomeIssue = outcomeCompatibilityIssue(request, route, outcome);
|
|
3365
|
+
if (outcomeIssue !== void 0) {
|
|
3366
|
+
emitIssueOnce(
|
|
3367
|
+
ctx,
|
|
3368
|
+
state,
|
|
3369
|
+
`outcome-incompatible:${outcome.outcomeId}:${outcomeIssue}`,
|
|
3370
|
+
outcomeIssue,
|
|
3371
|
+
`ExecutorOutcome '${outcome.outcomeId}' is incompatible with route '${route.routeId}' for request '${request.requestId}'`,
|
|
3372
|
+
request.requestId,
|
|
3373
|
+
[
|
|
3374
|
+
ref("executor-outcome", outcome.outcomeId),
|
|
3375
|
+
ref("executor-route", route.routeId),
|
|
3376
|
+
ref("agent-request", request.requestId)
|
|
3377
|
+
]
|
|
3378
|
+
);
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
if (state.terminalRequests.has(request.requestId)) {
|
|
3382
|
+
if (state.acceptedTerminalFactIds.has(`outcome:${outcome.outcomeId}`)) return;
|
|
3383
|
+
emitIssueOnce(
|
|
3384
|
+
ctx,
|
|
3385
|
+
state,
|
|
3386
|
+
`duplicate-outcome:${outcome.outcomeId}`,
|
|
3387
|
+
"duplicate-terminal-outcome",
|
|
3388
|
+
`ExecutorOutcome '${outcome.outcomeId}' arrived after request '${request.requestId}' was already terminal`,
|
|
3389
|
+
request.requestId,
|
|
3390
|
+
[ref("executor-outcome", outcome.outcomeId), ref("agent-request", request.requestId)]
|
|
3391
|
+
);
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
state.terminalRequests.add(request.requestId);
|
|
3395
|
+
state.acceptedTerminalFactIds.add(`outcome:${outcome.outcomeId}`);
|
|
3396
|
+
const status = outcomeStatus(outcome);
|
|
3397
|
+
emitStatus(ctx, state, request, status, [
|
|
3398
|
+
ref("executor-outcome", outcome.outcomeId),
|
|
3399
|
+
ref("executor-route", route.routeId),
|
|
3400
|
+
ref("agent-request", request.requestId)
|
|
3401
|
+
]);
|
|
3402
|
+
}
|
|
3403
|
+
function handleContextContribution(ctx, state, contribution) {
|
|
3404
|
+
const request = state.requests.get(contribution.requestId);
|
|
3405
|
+
if (request === void 0) return;
|
|
3406
|
+
if (request.operationId !== contribution.operationId) {
|
|
3407
|
+
emitIssueOnce(
|
|
3408
|
+
ctx,
|
|
3409
|
+
state,
|
|
3410
|
+
`stale-context:${contribution.contributionId}`,
|
|
3411
|
+
"stale-context-operation",
|
|
3412
|
+
`ContextContribution '${contribution.contributionId}' operationId does not match request '${request.requestId}'`,
|
|
3413
|
+
request.requestId,
|
|
3414
|
+
[ref("context-contribution", contribution.contributionId)]
|
|
3415
|
+
);
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
if (request.requestKind !== "context") {
|
|
3419
|
+
emitIssueOnce(
|
|
3420
|
+
ctx,
|
|
3421
|
+
state,
|
|
3422
|
+
`wrong-context-kind:${contribution.contributionId}`,
|
|
3423
|
+
"wrong-kind-context-satisfaction",
|
|
3424
|
+
`ContextContribution '${contribution.contributionId}' cannot satisfy ${request.requestKind} request '${request.requestId}'`,
|
|
3425
|
+
request.requestId,
|
|
3426
|
+
[ref("context-contribution", contribution.contributionId)]
|
|
3427
|
+
);
|
|
3428
|
+
return;
|
|
3429
|
+
}
|
|
3430
|
+
if (state.terminalRequests.has(request.requestId)) {
|
|
3431
|
+
if (state.acceptedTerminalFactIds.has(`context:${contribution.contributionId}`) || state.statusKeys.has(`context:${contribution.contributionId}:awaiting-context`)) {
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3434
|
+
emitIssueOnce(
|
|
3435
|
+
ctx,
|
|
3436
|
+
state,
|
|
3437
|
+
`duplicate-context:${contribution.contributionId}`,
|
|
3438
|
+
"duplicate-terminal-context",
|
|
3439
|
+
`ContextContribution '${contribution.contributionId}' arrived after request '${request.requestId}' was already terminal`,
|
|
3440
|
+
request.requestId,
|
|
3441
|
+
[
|
|
3442
|
+
ref("context-contribution", contribution.contributionId),
|
|
3443
|
+
ref("agent-request", request.requestId)
|
|
3444
|
+
]
|
|
3445
|
+
);
|
|
3446
|
+
return;
|
|
3447
|
+
}
|
|
3448
|
+
if (contribution.status === "pending")
|
|
3449
|
+
emitStatusOnce(
|
|
3450
|
+
ctx,
|
|
3451
|
+
state,
|
|
3452
|
+
`context:${contribution.contributionId}:awaiting-context`,
|
|
3453
|
+
request,
|
|
3454
|
+
"awaiting-context",
|
|
3455
|
+
[ref("context-contribution", contribution.contributionId)]
|
|
3456
|
+
);
|
|
3457
|
+
else {
|
|
3458
|
+
state.terminalRequests.add(request.requestId);
|
|
3459
|
+
state.acceptedTerminalFactIds.add(`context:${contribution.contributionId}`);
|
|
3460
|
+
emitStatus(
|
|
3461
|
+
ctx,
|
|
3462
|
+
state,
|
|
3463
|
+
request,
|
|
3464
|
+
contribution.status === "ready" ? "completed" : "failed",
|
|
3465
|
+
[ref("context-contribution", contribution.contributionId)],
|
|
3466
|
+
contribution.issues
|
|
3467
|
+
);
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
function handlePromptBundle(ctx, state, prompt) {
|
|
3471
|
+
const request = state.requests.get(prompt.requestId);
|
|
3472
|
+
if (request === void 0) return;
|
|
3473
|
+
if (request.operationId !== prompt.operationId) {
|
|
3474
|
+
emitIssueOnce(
|
|
3475
|
+
ctx,
|
|
3476
|
+
state,
|
|
3477
|
+
`stale-prompt:${prompt.promptId}`,
|
|
3478
|
+
"stale-prompt-operation",
|
|
3479
|
+
`PromptBundle '${prompt.promptId}' operationId does not match request '${request.requestId}'`,
|
|
3480
|
+
request.requestId,
|
|
3481
|
+
[ref("prompt-bundle", prompt.promptId)]
|
|
3482
|
+
);
|
|
3483
|
+
return;
|
|
3484
|
+
}
|
|
3485
|
+
if (request.requestKind !== "prompt") {
|
|
3486
|
+
emitIssueOnce(
|
|
3487
|
+
ctx,
|
|
3488
|
+
state,
|
|
3489
|
+
`wrong-prompt-kind:${prompt.promptId}`,
|
|
3490
|
+
"wrong-kind-prompt-satisfaction",
|
|
3491
|
+
`PromptBundle '${prompt.promptId}' cannot satisfy ${request.requestKind} request '${request.requestId}'`,
|
|
3492
|
+
request.requestId,
|
|
3493
|
+
[ref("prompt-bundle", prompt.promptId)]
|
|
3494
|
+
);
|
|
3495
|
+
return;
|
|
3496
|
+
}
|
|
3497
|
+
if (state.terminalRequests.has(request.requestId)) {
|
|
3498
|
+
if (state.acceptedTerminalFactIds.has(`prompt:${prompt.promptId}`) || state.statusKeys.has(`prompt:${prompt.promptId}:awaiting-prompt`)) {
|
|
3499
|
+
return;
|
|
3500
|
+
}
|
|
3501
|
+
emitIssueOnce(
|
|
3502
|
+
ctx,
|
|
3503
|
+
state,
|
|
3504
|
+
`duplicate-prompt:${prompt.promptId}`,
|
|
3505
|
+
"duplicate-terminal-prompt",
|
|
3506
|
+
`PromptBundle '${prompt.promptId}' arrived after request '${request.requestId}' was already terminal`,
|
|
3507
|
+
request.requestId,
|
|
3508
|
+
[ref("prompt-bundle", prompt.promptId), ref("agent-request", request.requestId)]
|
|
3509
|
+
);
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3512
|
+
if (prompt.status === "ready") {
|
|
3513
|
+
state.terminalRequests.add(request.requestId);
|
|
3514
|
+
state.acceptedTerminalFactIds.add(`prompt:${prompt.promptId}`);
|
|
3515
|
+
emitStatus(ctx, state, request, "completed", [ref("prompt-bundle", prompt.promptId)]);
|
|
3516
|
+
} else if (prompt.status === "issue") {
|
|
3517
|
+
state.terminalRequests.add(request.requestId);
|
|
3518
|
+
state.acceptedTerminalFactIds.add(`prompt:${prompt.promptId}`);
|
|
3519
|
+
emitStatus(
|
|
3520
|
+
ctx,
|
|
3521
|
+
state,
|
|
3522
|
+
request,
|
|
3523
|
+
"failed",
|
|
3524
|
+
[ref("prompt-bundle", prompt.promptId)],
|
|
3525
|
+
prompt.issues
|
|
3526
|
+
);
|
|
3527
|
+
} else {
|
|
3528
|
+
emitStatusOnce(
|
|
3529
|
+
ctx,
|
|
3530
|
+
state,
|
|
3531
|
+
`prompt:${prompt.promptId}:awaiting-prompt`,
|
|
3532
|
+
request,
|
|
3533
|
+
"awaiting-prompt",
|
|
3534
|
+
[ref("prompt-bundle", prompt.promptId)],
|
|
3535
|
+
prompt.issues
|
|
3536
|
+
);
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
function routeCompatibilityIssue(request, route, profile) {
|
|
3540
|
+
if (request.requestKind !== "executor") return "route-for-non-executor-request";
|
|
3541
|
+
if (route.executorId !== profile.executorId) return "route-profile-executor-mismatch";
|
|
3542
|
+
if (request.input?.inputId !== void 0 && route.inputId !== void 0 && request.input.inputId !== route.inputId) {
|
|
3543
|
+
return "route-input-mismatch";
|
|
3544
|
+
}
|
|
3545
|
+
if (request.input?.inputKind !== void 0 && route.inputKind !== void 0 && request.input.inputKind !== route.inputKind) {
|
|
3546
|
+
return "route-input-kind-mismatch";
|
|
3547
|
+
}
|
|
3548
|
+
const inputKind = request.input?.inputKind ?? route.inputKind;
|
|
3549
|
+
if (inputKind !== void 0 && !profileKindAcceptsInput(profile.kind, inputKind))
|
|
3550
|
+
return "profile-kind-input-incompatible";
|
|
3551
|
+
if (inputKind !== void 0 && profile.acceptedInputKinds !== void 0 && !profile.acceptedInputKinds.includes(inputKind)) {
|
|
3552
|
+
return "profile-rejects-input-kind";
|
|
3553
|
+
}
|
|
3554
|
+
if (request.input?.schemaRef !== void 0 && profile.acceptedSchemaRefs !== void 0 && !profile.acceptedSchemaRefs.includes(request.input.schemaRef)) {
|
|
3555
|
+
return "profile-rejects-schema";
|
|
3556
|
+
}
|
|
3557
|
+
return void 0;
|
|
3558
|
+
}
|
|
3559
|
+
function outcomeCompatibilityIssue(request, route, outcome) {
|
|
3560
|
+
if (outcome.executorId !== route.executorId) return "outcome-route-executor-mismatch";
|
|
3561
|
+
if (outcome.profileId !== route.profileId) return "outcome-route-profile-mismatch";
|
|
3562
|
+
if (route.inputId !== void 0 && (outcome.inputId === void 0 || outcome.inputId !== route.inputId)) {
|
|
3563
|
+
return "outcome-route-input-mismatch";
|
|
3564
|
+
}
|
|
3565
|
+
if (request.input?.inputId !== void 0 && outcome.inputId !== void 0 && outcome.inputId !== request.input.inputId) {
|
|
3566
|
+
return "outcome-request-input-mismatch";
|
|
3567
|
+
}
|
|
3568
|
+
if (route.inputKind !== void 0 && (outcome.inputKind === void 0 || outcome.inputKind !== route.inputKind)) {
|
|
3569
|
+
return "outcome-route-input-kind-mismatch";
|
|
3570
|
+
}
|
|
3571
|
+
if (request.input?.inputKind !== void 0 && outcome.inputKind !== void 0 && outcome.inputKind !== request.input.inputKind) {
|
|
3572
|
+
return "outcome-request-input-kind-mismatch";
|
|
3573
|
+
}
|
|
3574
|
+
return void 0;
|
|
3575
|
+
}
|
|
3576
|
+
function profileKindAcceptsInput(kind, inputKind) {
|
|
3577
|
+
if (kind === "llm") return inputKind === "llm-call";
|
|
3578
|
+
if (kind === "tool") return inputKind === "tool-call";
|
|
3579
|
+
if (kind === "human") return inputKind === "human-task";
|
|
3580
|
+
return inputKind === "agent-task";
|
|
3581
|
+
}
|
|
3582
|
+
function outcomeStatus(outcome) {
|
|
3583
|
+
if (outcome.kind === "result") return "completed";
|
|
3584
|
+
if (outcome.kind === "failure") return "failed";
|
|
3585
|
+
if (outcome.kind === "timeout") return "timeout";
|
|
3586
|
+
if (outcome.kind === "canceled") return "canceled";
|
|
3587
|
+
return "blocked";
|
|
3588
|
+
}
|
|
3589
|
+
function executorOutcomeViewProjectionFromOutcome(outcome, policy) {
|
|
3590
|
+
const sourceRefs = uniqueSourceRefs([
|
|
3591
|
+
ref("executor-outcome", outcome.outcomeId),
|
|
3592
|
+
...outcome.evidenceRefs ?? []
|
|
3593
|
+
]);
|
|
3594
|
+
const summary = projectOutcomeSummary(outcome, policy.maxSummaryChars);
|
|
3595
|
+
const issues = Object.freeze([
|
|
3596
|
+
...outcomeIssues(outcome),
|
|
3597
|
+
...summary.truncated ? [outcomeSummaryTruncationIssue(outcome, summary, policy)] : []
|
|
3598
|
+
]);
|
|
3599
|
+
const view = Object.freeze({
|
|
3600
|
+
kind: "executor-outcome-view",
|
|
3601
|
+
viewId: `${outcome.outcomeId}:${policy.audience}`,
|
|
3602
|
+
audience: policy.audience,
|
|
3603
|
+
outcomeId: outcome.outcomeId,
|
|
3604
|
+
requestId: outcome.requestId,
|
|
3605
|
+
operationId: outcome.operationId,
|
|
3606
|
+
routeId: outcome.routeId,
|
|
3607
|
+
executorId: outcome.executorId,
|
|
3608
|
+
profileId: outcome.profileId,
|
|
3609
|
+
status: outcome.kind,
|
|
3610
|
+
summary: summary.summary,
|
|
3611
|
+
summaryTruncated: summary.truncated,
|
|
3612
|
+
summaryChars: summary.originalChars,
|
|
3613
|
+
summaryLimitChars: summary.limitChars,
|
|
3614
|
+
errorKind: outcomeErrorKind(outcome),
|
|
3615
|
+
retryable: outcomeRetryable(outcome),
|
|
3616
|
+
nextActions: outcomeNextActions(outcome),
|
|
3617
|
+
sourceRefs,
|
|
3618
|
+
materialRefs: outcomeMaterialRefs(outcome),
|
|
3619
|
+
issues: policy.includeIssues && issues.length > 0 ? issues : void 0,
|
|
3620
|
+
usage: policy.includeUsage ? outcome.usage : void 0,
|
|
3621
|
+
metadata: policy.includeMetadata ? outcome.metadata : void 0
|
|
3622
|
+
});
|
|
3623
|
+
return Object.freeze({ view, issues });
|
|
3624
|
+
}
|
|
3625
|
+
function projectOutcomeSummary(outcome, maxChars) {
|
|
3626
|
+
const summary = outcomeSummary(outcome);
|
|
3627
|
+
const limitChars = Math.max(0, maxChars);
|
|
3628
|
+
if (summary.length <= limitChars) {
|
|
3629
|
+
return Object.freeze({
|
|
3630
|
+
summary,
|
|
3631
|
+
truncated: false,
|
|
3632
|
+
originalChars: summary.length,
|
|
3633
|
+
limitChars
|
|
3634
|
+
});
|
|
3635
|
+
}
|
|
3636
|
+
const bounded = limitChars <= 1 ? summary.slice(0, limitChars) : limitChars <= 3 ? summary.slice(0, limitChars) : `${summary.slice(0, limitChars - 3)}...`;
|
|
3637
|
+
return Object.freeze({
|
|
3638
|
+
summary: bounded,
|
|
3639
|
+
truncated: true,
|
|
3640
|
+
originalChars: summary.length,
|
|
3641
|
+
limitChars
|
|
3642
|
+
});
|
|
3643
|
+
}
|
|
3644
|
+
function outcomeSummaryTruncationIssue(outcome, summary, policy) {
|
|
3645
|
+
return dataIssue(
|
|
3646
|
+
"executor-outcome-view-summary-truncated",
|
|
3647
|
+
"ExecutorOutcome view summary was truncated; inspect material refs or the source outcome for full detail",
|
|
3648
|
+
{
|
|
3649
|
+
subjectId: outcome.requestId,
|
|
3650
|
+
refs: [ref("executor-outcome", outcome.outcomeId)],
|
|
3651
|
+
severity: "warning",
|
|
3652
|
+
details: {
|
|
3653
|
+
audience: policy.audience,
|
|
3654
|
+
outcomeId: outcome.outcomeId,
|
|
3655
|
+
originalChars: summary.originalChars,
|
|
3656
|
+
limitChars: summary.limitChars
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
);
|
|
3660
|
+
}
|
|
3661
|
+
function outcomeSummary(outcome) {
|
|
3662
|
+
if (outcome.kind === "result") {
|
|
3663
|
+
if (outcome.result.summary !== void 0 && outcome.result.summary.length > 0)
|
|
3664
|
+
return outcome.result.summary;
|
|
3665
|
+
return `Executor result '${outcome.result.kind}' is available via source refs`;
|
|
3666
|
+
}
|
|
3667
|
+
if (outcome.kind === "failure") return outcome.error.message;
|
|
3668
|
+
if (outcome.kind === "blocked") {
|
|
3669
|
+
const needKinds = outcome.needs.map((need) => need.kind).join(", ");
|
|
3670
|
+
return needKinds.length > 0 ? `Executor blocked: ${needKinds}` : "Executor blocked";
|
|
3671
|
+
}
|
|
3672
|
+
if (outcome.kind === "timeout") {
|
|
3673
|
+
return outcome.timeoutMs === void 0 ? "Executor timed out" : `Executor timed out after ${outcome.timeoutMs}ms`;
|
|
3674
|
+
}
|
|
3675
|
+
return outcome.reason ?? "Executor canceled";
|
|
3676
|
+
}
|
|
3677
|
+
function outcomeErrorKind(outcome) {
|
|
3678
|
+
if (outcome.kind === "failure") return outcome.error.code;
|
|
3679
|
+
if (outcome.kind === "timeout") return "timeout";
|
|
3680
|
+
if (outcome.kind === "blocked") return outcome.needs[0]?.kind ?? "blocked";
|
|
3681
|
+
if (outcome.kind === "canceled") return "canceled";
|
|
3682
|
+
return void 0;
|
|
3683
|
+
}
|
|
3684
|
+
function outcomeRetryable(outcome) {
|
|
3685
|
+
if (outcome.kind === "failure" || outcome.kind === "timeout") return outcome.retryable;
|
|
3686
|
+
return void 0;
|
|
3687
|
+
}
|
|
3688
|
+
function outcomeIssues(outcome) {
|
|
3689
|
+
if (outcome.kind === "failure") return Object.freeze([outcome.error, ...outcome.issues ?? []]);
|
|
3690
|
+
return outcome.issues ?? [];
|
|
3691
|
+
}
|
|
3692
|
+
function outcomeNextActions(outcome) {
|
|
3693
|
+
if (outcome.kind === "blocked") return Object.freeze(outcome.needs.map((need) => need.kind));
|
|
3694
|
+
if ((outcome.kind === "failure" || outcome.kind === "timeout") && outcome.retryable === true) {
|
|
3695
|
+
return Object.freeze(["retry-or-route"]);
|
|
3696
|
+
}
|
|
3697
|
+
return void 0;
|
|
3698
|
+
}
|
|
3699
|
+
function outcomeMaterialRefs(outcome) {
|
|
3700
|
+
const refs = outcome.kind === "result" ? [...outcome.result.refs ?? []] : outcome.kind === "blocked" ? outcome.needs.flatMap((need) => [...need.refs ?? []]) : [];
|
|
3701
|
+
return refs.length === 0 ? void 0 : uniqueSourceRefs(refs);
|
|
3702
|
+
}
|
|
3703
|
+
function uniqueSourceRefs(sourceRefs) {
|
|
3704
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3705
|
+
const unique = [];
|
|
3706
|
+
for (const sourceRef of sourceRefs) {
|
|
3707
|
+
const key = `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
|
|
3708
|
+
if (seen.has(key)) continue;
|
|
3709
|
+
seen.add(key);
|
|
3710
|
+
unique.push(sourceRef);
|
|
3711
|
+
}
|
|
3712
|
+
return Object.freeze(unique);
|
|
3713
|
+
}
|
|
3714
|
+
function emitStatus(ctx, state, request, status, sourceRefs, issues) {
|
|
3715
|
+
const fact = {
|
|
3716
|
+
kind: "status",
|
|
3717
|
+
requestId: request.requestId,
|
|
3718
|
+
operationId: request.operationId,
|
|
3719
|
+
effectRunId: request.effectRunId,
|
|
3720
|
+
status,
|
|
3721
|
+
sourceRefs,
|
|
3722
|
+
issues
|
|
3723
|
+
};
|
|
3724
|
+
state.auditSeq += 1;
|
|
3725
|
+
ctx.down([
|
|
3726
|
+
["DATA", { kind: "status", status: fact }],
|
|
3727
|
+
[
|
|
3728
|
+
"DATA",
|
|
3729
|
+
{
|
|
3730
|
+
kind: "audit",
|
|
3731
|
+
audit: {
|
|
3732
|
+
id: `${request.requestId}:status:${state.auditSeq}`,
|
|
3733
|
+
kind: "agent-request-status",
|
|
3734
|
+
subjectId: request.requestId,
|
|
3735
|
+
sourceRefs,
|
|
3736
|
+
metadata: { status }
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
]
|
|
3740
|
+
]);
|
|
3741
|
+
}
|
|
3742
|
+
function emitStatusOnce(ctx, state, key, request, status, sourceRefs, issues) {
|
|
3743
|
+
if (state.statusKeys.has(key)) return;
|
|
3744
|
+
state.statusKeys.add(key);
|
|
3745
|
+
emitStatus(ctx, state, request, status, sourceRefs, issues);
|
|
3746
|
+
}
|
|
3747
|
+
function emitIssue(ctx, state, code, message, subjectId, refs) {
|
|
3748
|
+
state.issueSeq += 1;
|
|
3749
|
+
const issue = dataIssue(code, message, { subjectId, refs });
|
|
3750
|
+
state.auditSeq += 1;
|
|
3751
|
+
ctx.down([
|
|
3752
|
+
["DATA", { kind: "issue", issue }],
|
|
3753
|
+
[
|
|
3754
|
+
"DATA",
|
|
3755
|
+
{
|
|
3756
|
+
kind: "audit",
|
|
3757
|
+
audit: {
|
|
3758
|
+
id: `${subjectId ?? "request"}:issue:${state.auditSeq}`,
|
|
3759
|
+
kind: "agent-request-issue",
|
|
3760
|
+
subjectId,
|
|
3761
|
+
issueCode: code,
|
|
3762
|
+
message,
|
|
3763
|
+
sourceRefs: refs
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
]
|
|
3767
|
+
]);
|
|
3768
|
+
}
|
|
3769
|
+
function emitIssueOnce(ctx, state, key, code, message, subjectId, refs) {
|
|
3770
|
+
if (state.issueKeys.has(key)) return;
|
|
3771
|
+
state.issueKeys.add(key);
|
|
3772
|
+
emitIssue(ctx, state, code, message, subjectId, refs);
|
|
3773
|
+
}
|
|
3774
|
+
function emitInterpreterIssue(ctx, seq, outcome, code, message) {
|
|
3775
|
+
const issue = dataIssue(code, message, {
|
|
3776
|
+
subjectId: outcome.requestId,
|
|
3777
|
+
refs: [ref("executor-outcome", outcome.outcomeId)]
|
|
3778
|
+
});
|
|
3779
|
+
ctx.down([
|
|
3780
|
+
["DATA", { kind: "issue", issue }],
|
|
3781
|
+
[
|
|
3782
|
+
"DATA",
|
|
3783
|
+
{
|
|
3784
|
+
kind: "audit",
|
|
3785
|
+
audit: {
|
|
3786
|
+
id: `${outcome.outcomeId}:agent-decision-issue:${seq}`,
|
|
3787
|
+
kind: "agent-decision-issue",
|
|
3788
|
+
subjectId: outcome.requestId,
|
|
3789
|
+
issueCode: code,
|
|
3790
|
+
message,
|
|
3791
|
+
sourceRefs: [ref("executor-outcome", outcome.outcomeId)]
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
]
|
|
3795
|
+
]);
|
|
3796
|
+
}
|
|
3797
|
+
function validateAgentDecision(raw, outcome) {
|
|
3798
|
+
if (!isRecord(raw)) return "AgentDecision must be an object";
|
|
3799
|
+
const kind = raw.kind;
|
|
3800
|
+
if (kind !== "continue" && kind !== "final" && kind !== "blocked") {
|
|
3801
|
+
return "AgentDecision kind must be continue, final, or blocked";
|
|
3802
|
+
}
|
|
3803
|
+
if (typeof raw.decisionId !== "string" || raw.decisionId.length === 0)
|
|
3804
|
+
return "AgentDecision decisionId must be a non-empty string";
|
|
3805
|
+
if (raw.effectRunId === void 0 || typeof raw.effectRunId !== "string" || raw.effectRunId.length === 0)
|
|
3806
|
+
return "AgentDecision effectRunId must be a non-empty string";
|
|
3807
|
+
if (typeof raw.agentRunId !== "string" || raw.agentRunId.length === 0)
|
|
3808
|
+
return "AgentDecision agentRunId must be a non-empty string";
|
|
3809
|
+
const source2 = raw.source;
|
|
3810
|
+
if (!isRecord(source2) || source2.requestId !== outcome.requestId || source2.operationId !== outcome.operationId || source2.outcomeId !== outcome.outcomeId) {
|
|
3811
|
+
return "AgentDecision source must match the ExecutorOutcome requestId, operationId, and outcomeId";
|
|
3812
|
+
}
|
|
3813
|
+
if (kind === "continue") {
|
|
3814
|
+
if (!Array.isArray(raw.next)) return "AgentDecision.continue next must be an array";
|
|
3815
|
+
for (const proposal of raw.next) {
|
|
3816
|
+
if (!isAgentRequestProposalLike(proposal, raw.effectRunId)) {
|
|
3817
|
+
return "AgentDecision.continue next entries must be AgentRequestProposal-like objects";
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
return raw;
|
|
3821
|
+
}
|
|
3822
|
+
if (kind === "final") {
|
|
3823
|
+
if (!isRecord(raw.output) || typeof raw.output.kind !== "string")
|
|
3824
|
+
return "AgentDecision.final output must be an envelope with kind";
|
|
3825
|
+
return raw;
|
|
3826
|
+
}
|
|
3827
|
+
if (!Array.isArray(raw.needs)) return "AgentDecision.blocked needs must be an array";
|
|
3828
|
+
for (const need of raw.needs) {
|
|
3829
|
+
if (!isAgentNeedLike(need))
|
|
3830
|
+
return "AgentDecision.blocked needs entries must be AgentNeed-like objects";
|
|
3831
|
+
}
|
|
3832
|
+
return raw;
|
|
3833
|
+
}
|
|
3834
|
+
function isAgentRequestProposalLike(value, effectRunId) {
|
|
3835
|
+
if (!isRecord(value)) return false;
|
|
3836
|
+
if (value.kind !== "proposal") return false;
|
|
3837
|
+
if (typeof value.proposalId !== "string" || value.proposalId.length === 0) return false;
|
|
3838
|
+
if (value.effectRunId !== effectRunId) return false;
|
|
3839
|
+
return value.requestKind === "context" || value.requestKind === "prompt" || value.requestKind === "executor";
|
|
3840
|
+
}
|
|
3841
|
+
function isAgentNeedLike(value) {
|
|
3842
|
+
return isRecord(value) && typeof value.kind === "string" && value.kind.length > 0;
|
|
3843
|
+
}
|
|
3844
|
+
function candidateFromDecision(decision, state, completedAtMs) {
|
|
3845
|
+
const run = state.runs.get(decision.effectRunId);
|
|
3846
|
+
if (run === void 0) return void 0;
|
|
3847
|
+
if (!decisionSourceRequestTerminal(decision, state)) return void 0;
|
|
3848
|
+
const requiredPending = requiredPendingRequests(decision.effectRunId, state);
|
|
3849
|
+
if (decision.kind === "final") {
|
|
3850
|
+
if (requiredPending.length > 0) {
|
|
3851
|
+
return void 0;
|
|
3852
|
+
}
|
|
3853
|
+
return {
|
|
3854
|
+
kind: "effect-run-result",
|
|
3855
|
+
resultId: `${decision.effectRunId}:result`,
|
|
3856
|
+
status: "completed",
|
|
3857
|
+
effectRunId: decision.effectRunId,
|
|
3858
|
+
subjectRefs: run.subjectRefs,
|
|
3859
|
+
operationId: decision.source.operationId,
|
|
3860
|
+
sourceRefs: [
|
|
3861
|
+
ref("agent-decision", decision.decisionId),
|
|
3862
|
+
ref("executor-outcome", decision.source.outcomeId)
|
|
3863
|
+
],
|
|
3864
|
+
completedAtMs,
|
|
3865
|
+
output: decision.output
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
if (decision.kind === "blocked" && requiredPending.length === 0) {
|
|
3869
|
+
return {
|
|
3870
|
+
kind: "effect-run-result",
|
|
3871
|
+
resultId: `${decision.effectRunId}:result`,
|
|
3872
|
+
status: "blocked",
|
|
3873
|
+
effectRunId: decision.effectRunId,
|
|
3874
|
+
subjectRefs: run.subjectRefs,
|
|
3875
|
+
operationId: decision.source.operationId,
|
|
3876
|
+
sourceRefs: [
|
|
3877
|
+
ref("agent-decision", decision.decisionId),
|
|
3878
|
+
ref("executor-outcome", decision.source.outcomeId)
|
|
3879
|
+
],
|
|
3880
|
+
completedAtMs,
|
|
3881
|
+
needs: decision.needs
|
|
3882
|
+
};
|
|
3883
|
+
}
|
|
3884
|
+
return void 0;
|
|
3885
|
+
}
|
|
3886
|
+
function acceptEffectRunResultCandidate(ctx, state, candidate) {
|
|
3887
|
+
if (!state.runs.has(candidate.effectRunId)) {
|
|
3888
|
+
emitEffectRunIssue(
|
|
3889
|
+
ctx,
|
|
3890
|
+
state,
|
|
3891
|
+
"unknown-effect-run-result-candidate",
|
|
3892
|
+
`EffectRunResult candidate '${candidate.resultId}' references unknown EffectRun '${candidate.effectRunId}'`,
|
|
3893
|
+
candidate.effectRunId,
|
|
3894
|
+
candidate.sourceRefs
|
|
3895
|
+
);
|
|
3896
|
+
return;
|
|
3897
|
+
}
|
|
3898
|
+
const existing = state.resultsByEffectRun.get(candidate.effectRunId);
|
|
3899
|
+
if (existing !== void 0) {
|
|
3900
|
+
state.issueSeq += 1;
|
|
3901
|
+
const duplicate = sameTerminalResult(existing, candidate);
|
|
3902
|
+
const code = duplicate ? "duplicate-effect-run-result" : "conflicting-effect-run-result";
|
|
3903
|
+
const issue = dataIssue(
|
|
3904
|
+
code,
|
|
3905
|
+
`EffectRun '${candidate.effectRunId}' already has a terminal result`,
|
|
3906
|
+
{
|
|
3907
|
+
subjectId: candidate.effectRunId,
|
|
3908
|
+
refs: candidate.sourceRefs
|
|
3909
|
+
}
|
|
3910
|
+
);
|
|
3911
|
+
ctx.down([
|
|
3912
|
+
["DATA", { kind: "issue", issue }],
|
|
3913
|
+
[
|
|
3914
|
+
"DATA",
|
|
3915
|
+
{
|
|
3916
|
+
kind: "audit",
|
|
3917
|
+
audit: {
|
|
3918
|
+
id: `${candidate.effectRunId}:${code}:${state.issueSeq}`,
|
|
3919
|
+
kind: duplicate ? "effect-run-result-duplicate" : "effect-run-result-conflict",
|
|
3920
|
+
subjectId: candidate.effectRunId,
|
|
3921
|
+
issueCode: issue.code,
|
|
3922
|
+
sourceRefs: candidate.sourceRefs
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
]
|
|
3926
|
+
]);
|
|
3927
|
+
return;
|
|
3928
|
+
}
|
|
3929
|
+
state.resultsByEffectRun.set(candidate.effectRunId, candidate);
|
|
3930
|
+
ctx.down([
|
|
3931
|
+
["DATA", { kind: "result", result: candidate }],
|
|
3932
|
+
[
|
|
3933
|
+
"DATA",
|
|
3934
|
+
{
|
|
3935
|
+
kind: "status",
|
|
3936
|
+
status: {
|
|
3937
|
+
effectRunId: candidate.effectRunId,
|
|
3938
|
+
state: candidate.status,
|
|
3939
|
+
requiredPending: [],
|
|
3940
|
+
requiredTerminal: requiredTerminalRequests(candidate.effectRunId, state),
|
|
3941
|
+
sourceRefs: candidate.sourceRefs
|
|
3942
|
+
}
|
|
3943
|
+
}
|
|
3944
|
+
],
|
|
3945
|
+
[
|
|
3946
|
+
"DATA",
|
|
3947
|
+
{
|
|
3948
|
+
kind: "audit",
|
|
3949
|
+
audit: {
|
|
3950
|
+
id: `${candidate.effectRunId}:terminal-result`,
|
|
3951
|
+
kind: "effect-run-terminal-result",
|
|
3952
|
+
subjectId: candidate.effectRunId,
|
|
3953
|
+
sourceRefs: candidate.sourceRefs,
|
|
3954
|
+
metadata: { status: candidate.status }
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3957
|
+
]
|
|
3958
|
+
]);
|
|
3959
|
+
}
|
|
3960
|
+
function emitEffectRunStatus(ctx, effectRunId, state, requiredPending, requiredTerminal) {
|
|
3961
|
+
ctx.down([
|
|
3962
|
+
[
|
|
3963
|
+
"DATA",
|
|
3964
|
+
{
|
|
3965
|
+
kind: "status",
|
|
3966
|
+
status: { effectRunId, state, requiredPending, requiredTerminal }
|
|
3967
|
+
}
|
|
3968
|
+
]
|
|
3969
|
+
]);
|
|
3970
|
+
}
|
|
3971
|
+
function requiredPendingRequests(effectRunId, state) {
|
|
3972
|
+
const pending = [];
|
|
3973
|
+
for (const request of state.requests.values()) {
|
|
3974
|
+
if (request.effectRunId !== effectRunId || !request.required) continue;
|
|
3975
|
+
const statusFact = matchingStatusForRequest(state, request);
|
|
3976
|
+
const status = statusFact?.status;
|
|
3977
|
+
if (status === void 0 || !isTerminalRequestStatus(status)) pending.push(request.requestId);
|
|
3978
|
+
}
|
|
3979
|
+
return pending;
|
|
3980
|
+
}
|
|
3981
|
+
function requiredTerminalRequests(effectRunId, state) {
|
|
3982
|
+
const terminal = [];
|
|
3983
|
+
for (const request of state.requests.values()) {
|
|
3984
|
+
if (request.effectRunId !== effectRunId || !request.required) continue;
|
|
3985
|
+
const statusFact = matchingStatusForRequest(state, request);
|
|
3986
|
+
const status = statusFact?.status;
|
|
3987
|
+
if (status !== void 0 && isTerminalRequestStatus(status)) terminal.push(request.requestId);
|
|
3988
|
+
}
|
|
3989
|
+
return terminal;
|
|
3990
|
+
}
|
|
3991
|
+
function isTerminalRequestStatus(status) {
|
|
3992
|
+
return status === "completed" || status === "failed" || status === "blocked" || status === "canceled" || status === "timeout" || status === "waived" || status === "retry-exhausted";
|
|
3993
|
+
}
|
|
3994
|
+
function decisionSourceRequestTerminal(decision, state) {
|
|
3995
|
+
const request = state.requests.get(decision.source.requestId);
|
|
3996
|
+
if (request === void 0) return false;
|
|
3997
|
+
if (request.effectRunId !== decision.effectRunId || request.operationId !== decision.source.operationId) {
|
|
3998
|
+
return false;
|
|
3999
|
+
}
|
|
4000
|
+
const status = matchingStatusForRequest(state, request)?.status;
|
|
4001
|
+
return status !== void 0 && isTerminalRequestStatus(status);
|
|
4002
|
+
}
|
|
4003
|
+
function acceptRequestStatus(ctx, state, status) {
|
|
4004
|
+
const request = state.requests.get(status.requestId);
|
|
4005
|
+
if (request !== void 0 && !statusMatchesRequest(status, request)) {
|
|
4006
|
+
emitEffectRunIssue(
|
|
4007
|
+
ctx,
|
|
4008
|
+
state,
|
|
4009
|
+
"stale-request-status",
|
|
4010
|
+
`AgentRequest status for '${status.requestId}' did not match its issued effectRun/operation identity`,
|
|
4011
|
+
request.effectRunId,
|
|
4012
|
+
[ref("agent-request", status.requestId)]
|
|
4013
|
+
);
|
|
4014
|
+
return;
|
|
4015
|
+
}
|
|
4016
|
+
state.statusByRequest.set(status.requestId, status);
|
|
4017
|
+
}
|
|
4018
|
+
function matchingStatusForRequest(state, request) {
|
|
4019
|
+
const status = state.statusByRequest.get(request.requestId);
|
|
4020
|
+
if (status === void 0) return void 0;
|
|
4021
|
+
return statusMatchesRequest(status, request) ? status : void 0;
|
|
4022
|
+
}
|
|
4023
|
+
function statusMatchesRequest(status, request) {
|
|
4024
|
+
return status.effectRunId === request.effectRunId && (status.operationId === void 0 || status.operationId === request.operationId);
|
|
4025
|
+
}
|
|
4026
|
+
function emitEffectRunIssue(ctx, state, code, message, subjectId, sourceRefs) {
|
|
4027
|
+
state.issueSeq += 1;
|
|
4028
|
+
const issue = dataIssue(code, message, { subjectId, refs: sourceRefs });
|
|
4029
|
+
ctx.down([
|
|
4030
|
+
["DATA", { kind: "issue", issue }],
|
|
4031
|
+
[
|
|
4032
|
+
"DATA",
|
|
4033
|
+
{
|
|
4034
|
+
kind: "audit",
|
|
4035
|
+
audit: {
|
|
4036
|
+
id: `${subjectId ?? "effect-run"}:${code}:${state.issueSeq}`,
|
|
4037
|
+
kind: "effect-run-issue",
|
|
4038
|
+
subjectId,
|
|
4039
|
+
issueCode: code,
|
|
4040
|
+
message,
|
|
4041
|
+
sourceRefs
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
]
|
|
4045
|
+
]);
|
|
4046
|
+
}
|
|
4047
|
+
function sameTerminalResult(a, b) {
|
|
4048
|
+
return a.status === b.status && a.resultId === b.resultId && JSON.stringify(a) === JSON.stringify(b);
|
|
4049
|
+
}
|
|
4050
|
+
function emptyEffectRunCompletionState() {
|
|
4051
|
+
return {
|
|
4052
|
+
runs: /* @__PURE__ */ new Map(),
|
|
4053
|
+
requests: /* @__PURE__ */ new Map(),
|
|
4054
|
+
statusByRequest: /* @__PURE__ */ new Map(),
|
|
4055
|
+
decisions: /* @__PURE__ */ new Map(),
|
|
4056
|
+
resultsByEffectRun: /* @__PURE__ */ new Map(),
|
|
4057
|
+
issueSeq: 0
|
|
4058
|
+
};
|
|
4059
|
+
}
|
|
4060
|
+
function emptyAgentRequestViewsState() {
|
|
4061
|
+
return {
|
|
4062
|
+
requestsById: /* @__PURE__ */ new Map(),
|
|
4063
|
+
requestsByEffectRun: /* @__PURE__ */ new Map(),
|
|
4064
|
+
statusByRequest: /* @__PURE__ */ new Map(),
|
|
4065
|
+
issues: [],
|
|
4066
|
+
audit: [],
|
|
4067
|
+
auditSeq: 0
|
|
4068
|
+
};
|
|
4069
|
+
}
|
|
4070
|
+
function cloneAgentRequestViewsState(state) {
|
|
4071
|
+
return {
|
|
4072
|
+
requestsById: new Map(state.requestsById),
|
|
4073
|
+
requestsByEffectRun: new Map(Array.from(state.requestsByEffectRun, ([k, v]) => [k, [...v]])),
|
|
4074
|
+
statusByRequest: new Map(state.statusByRequest),
|
|
4075
|
+
issues: [...state.issues],
|
|
4076
|
+
audit: [...state.audit],
|
|
4077
|
+
auditSeq: state.auditSeq
|
|
4078
|
+
};
|
|
4079
|
+
}
|
|
4080
|
+
function reduceAgentRequestViews(state, fact) {
|
|
4081
|
+
state.auditSeq += 1;
|
|
4082
|
+
if (fact.kind === "issued") {
|
|
4083
|
+
state.requestsById.set(fact.requestId, fact);
|
|
4084
|
+
const requestIds = state.requestsByEffectRun.get(fact.effectRunId) ?? [];
|
|
4085
|
+
if (!requestIds.includes(fact.requestId)) requestIds.push(fact.requestId);
|
|
4086
|
+
state.requestsByEffectRun.set(fact.effectRunId, requestIds);
|
|
4087
|
+
state.statusByRequest.set(fact.requestId, {
|
|
4088
|
+
kind: "status",
|
|
4089
|
+
requestId: fact.requestId,
|
|
4090
|
+
operationId: fact.operationId,
|
|
4091
|
+
effectRunId: fact.effectRunId,
|
|
4092
|
+
status: "issued",
|
|
4093
|
+
sourceRefs: [ref("agent-request", fact.requestId)]
|
|
4094
|
+
});
|
|
4095
|
+
} else if (fact.kind === "status") {
|
|
4096
|
+
state.statusByRequest.set(fact.requestId, fact);
|
|
4097
|
+
if (fact.issues !== void 0) state.issues.push(...fact.issues);
|
|
4098
|
+
} else if (fact.kind === "rejected") {
|
|
4099
|
+
state.issues.push(fact.issue);
|
|
4100
|
+
}
|
|
4101
|
+
state.audit.push({
|
|
4102
|
+
id: `agent-request-ledger:${state.auditSeq}`,
|
|
4103
|
+
kind: `agent-request-${fact.kind}`,
|
|
4104
|
+
subjectId: "requestId" in fact ? fact.requestId : fact.proposalId
|
|
4105
|
+
});
|
|
4106
|
+
}
|
|
4107
|
+
function freezeAgentRequestViews(state) {
|
|
4108
|
+
const pending = Array.from(state.requestsById.values()).filter((request) => {
|
|
4109
|
+
const status = state.statusByRequest.get(request.requestId)?.status;
|
|
4110
|
+
return status === void 0 || !isTerminalRequestStatus(status);
|
|
4111
|
+
});
|
|
4112
|
+
const awaitingProvider = pending.filter(
|
|
4113
|
+
(request) => state.statusByRequest.get(request.requestId)?.status === "awaiting-provider"
|
|
4114
|
+
);
|
|
4115
|
+
return {
|
|
4116
|
+
requestsById: new Map(state.requestsById),
|
|
4117
|
+
requestsByEffectRun: new Map(
|
|
4118
|
+
Array.from(state.requestsByEffectRun, ([key, value]) => [key, Object.freeze([...value])])
|
|
4119
|
+
),
|
|
4120
|
+
statusByRequest: new Map(state.statusByRequest),
|
|
4121
|
+
pending: Object.freeze(pending),
|
|
4122
|
+
awaitingProvider: Object.freeze(awaitingProvider),
|
|
4123
|
+
issues: Object.freeze([...state.issues]),
|
|
4124
|
+
audit: Object.freeze([...state.audit])
|
|
4125
|
+
};
|
|
4126
|
+
}
|
|
4127
|
+
function projectRuntimeFact(graph, runtime, name, factory, pick) {
|
|
4128
|
+
return graph.node(
|
|
4129
|
+
[runtime],
|
|
4130
|
+
(ctx) => {
|
|
4131
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
4132
|
+
const typed = fact;
|
|
4133
|
+
const value = pick(typed);
|
|
4134
|
+
if (value !== void 0) ctx.down([["DATA", value]]);
|
|
4135
|
+
}
|
|
4136
|
+
},
|
|
4137
|
+
{ name, factory }
|
|
4138
|
+
);
|
|
4139
|
+
}
|
|
4140
|
+
function forEachDepBatch(ctx, start, count, fn) {
|
|
4141
|
+
for (let i = 0; i < count; i += 1) {
|
|
4142
|
+
for (const value of depBatch(ctx, start + i) ?? []) fn(value);
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4145
|
+
function dataIssue(code, message, opts = {}) {
|
|
4146
|
+
return {
|
|
4147
|
+
kind: "issue",
|
|
4148
|
+
code,
|
|
4149
|
+
message,
|
|
4150
|
+
severity: opts.severity ?? "error",
|
|
4151
|
+
subjectId: opts.subjectId,
|
|
4152
|
+
refs: opts.refs?.map((r) => `${r.kind}:${r.id}`),
|
|
4153
|
+
details: opts.details
|
|
4154
|
+
};
|
|
4155
|
+
}
|
|
4156
|
+
function ref(kind, id) {
|
|
4157
|
+
return { kind, id };
|
|
4158
|
+
}
|
|
4159
|
+
function isRecord(value) {
|
|
4160
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4161
|
+
}
|
|
4162
|
+
|
|
4163
|
+
// src/orchestration/work-item-runtime.ts
|
|
4164
|
+
function workItemEffectRunProjector(graph, opts) {
|
|
4165
|
+
const name = opts.name ?? "workItemEffectRuns";
|
|
4166
|
+
const runtime = graph.node(
|
|
4167
|
+
[opts.workItems, opts.effectRequests],
|
|
4168
|
+
(ctx) => {
|
|
4169
|
+
const state = ctx.state.get() ?? emptyWorkItemEffectRunState();
|
|
4170
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4171
|
+
const workItem = raw;
|
|
4172
|
+
state.workItems.set(workItem.workItemId, workItem);
|
|
4173
|
+
}
|
|
4174
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
4175
|
+
const request = raw;
|
|
4176
|
+
state.requests.set(request.requestId, request);
|
|
4177
|
+
const requestRefs = workItemEffectRequestRefs(request);
|
|
4178
|
+
state.statusSeq += 1;
|
|
4179
|
+
state.auditSeq += 1;
|
|
4180
|
+
ctx.down([
|
|
4181
|
+
[
|
|
4182
|
+
"DATA",
|
|
4183
|
+
{
|
|
4184
|
+
kind: "status",
|
|
4185
|
+
status: {
|
|
4186
|
+
kind: "work-item-status",
|
|
4187
|
+
statusId: `${request.workItemId}:effect-request-pending:${state.statusSeq}`,
|
|
4188
|
+
workItemId: request.workItemId,
|
|
4189
|
+
effectRunId: request.effectRunId,
|
|
4190
|
+
requestId: request.requestId,
|
|
4191
|
+
state: "effect-request-pending",
|
|
4192
|
+
sourceRefs: requestRefs,
|
|
4193
|
+
metadata: { effectKind: request.effectKind }
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
],
|
|
4197
|
+
[
|
|
4198
|
+
"DATA",
|
|
4199
|
+
{
|
|
4200
|
+
kind: "audit",
|
|
4201
|
+
audit: {
|
|
4202
|
+
id: `${request.workItemId}:effect-request-pending:${state.auditSeq}`,
|
|
4203
|
+
kind: "work-item-effect-request-pending",
|
|
4204
|
+
subjectId: request.workItemId,
|
|
4205
|
+
sourceRefs: requestRefs,
|
|
4206
|
+
metadata: { effectRunId: request.effectRunId, effectKind: request.effectKind }
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4209
|
+
]
|
|
4210
|
+
]);
|
|
4211
|
+
const workItem = state.workItems.get(request.workItemId);
|
|
4212
|
+
if (workItem === void 0) {
|
|
4213
|
+
emitWorkItemEffectRunIssue(
|
|
4214
|
+
ctx,
|
|
4215
|
+
state,
|
|
4216
|
+
`unknown-work-item:${request.requestId}`,
|
|
4217
|
+
"unknown-work-item-effect-request",
|
|
4218
|
+
`WorkItemEffectRequested '${request.requestId}' references unknown WorkItem '${request.workItemId}'`,
|
|
4219
|
+
request.workItemId,
|
|
4220
|
+
requestRefs
|
|
4221
|
+
);
|
|
4222
|
+
continue;
|
|
4223
|
+
}
|
|
4224
|
+
const existingEffectRunId = state.effectRunsByRequest.get(request.requestId);
|
|
4225
|
+
if (existingEffectRunId !== void 0) {
|
|
4226
|
+
emitWorkItemEffectRunIssue(
|
|
4227
|
+
ctx,
|
|
4228
|
+
state,
|
|
4229
|
+
`duplicate-effect-request:${request.requestId}`,
|
|
4230
|
+
"duplicate-work-item-effect-request",
|
|
4231
|
+
`WorkItemEffectRequested '${request.requestId}' was already mapped to EffectRun '${existingEffectRunId}'`,
|
|
4232
|
+
request.workItemId,
|
|
4233
|
+
requestRefs
|
|
4234
|
+
);
|
|
4235
|
+
continue;
|
|
4236
|
+
}
|
|
4237
|
+
if (state.seededEffectRunIds.has(request.effectRunId)) {
|
|
4238
|
+
emitWorkItemEffectRunIssue(
|
|
4239
|
+
ctx,
|
|
4240
|
+
state,
|
|
4241
|
+
`duplicate-effect-run:${request.effectRunId}:${request.requestId}`,
|
|
4242
|
+
"duplicate-work-item-effect-run",
|
|
4243
|
+
`EffectRun '${request.effectRunId}' was already seeded from another WorkItemEffectRequested fact`,
|
|
4244
|
+
request.workItemId,
|
|
4245
|
+
requestRefs
|
|
4246
|
+
);
|
|
4247
|
+
continue;
|
|
4248
|
+
}
|
|
4249
|
+
state.effectRunsByRequest.set(request.requestId, request.effectRunId);
|
|
4250
|
+
state.seededEffectRunIds.add(request.effectRunId);
|
|
4251
|
+
const run = effectRun({
|
|
4252
|
+
effectRunId: request.effectRunId,
|
|
4253
|
+
agentRunId: request.agentRunId,
|
|
4254
|
+
subjectRefs: [ref2("work-item", request.workItemId)],
|
|
4255
|
+
goal: request.goal,
|
|
4256
|
+
sourceRefs: [
|
|
4257
|
+
ref2("work-item", request.workItemId),
|
|
4258
|
+
ref2("work-item-effect-request", request.requestId),
|
|
4259
|
+
...request.sourceRefs ?? []
|
|
4260
|
+
],
|
|
4261
|
+
policyRefs: request.policyRefs,
|
|
4262
|
+
limits: request.limits,
|
|
4263
|
+
createdBy: request.createdBy,
|
|
4264
|
+
createdAtMs: request.createdAtMs,
|
|
4265
|
+
metadata: {
|
|
4266
|
+
...request.metadata ?? {},
|
|
4267
|
+
effectKind: request.effectKind,
|
|
4268
|
+
idempotencyKey: request.idempotencyKey
|
|
4269
|
+
}
|
|
4270
|
+
});
|
|
4271
|
+
state.statusSeq += 1;
|
|
4272
|
+
state.auditSeq += 1;
|
|
4273
|
+
ctx.down([
|
|
4274
|
+
["DATA", { kind: "effect-run", effectRun: run }],
|
|
4275
|
+
[
|
|
4276
|
+
"DATA",
|
|
4277
|
+
{
|
|
4278
|
+
kind: "status",
|
|
4279
|
+
status: {
|
|
4280
|
+
kind: "work-item-status",
|
|
4281
|
+
statusId: `${request.workItemId}:effect-run-seeded:${state.statusSeq}`,
|
|
4282
|
+
workItemId: request.workItemId,
|
|
4283
|
+
effectRunId: request.effectRunId,
|
|
4284
|
+
requestId: request.requestId,
|
|
4285
|
+
state: "effect-run-seeded",
|
|
4286
|
+
sourceRefs: run.sourceRefs
|
|
4287
|
+
}
|
|
4288
|
+
}
|
|
4289
|
+
],
|
|
4290
|
+
[
|
|
4291
|
+
"DATA",
|
|
4292
|
+
{
|
|
4293
|
+
kind: "audit",
|
|
4294
|
+
audit: {
|
|
4295
|
+
id: `${request.workItemId}:effect-run-seeded:${state.auditSeq}`,
|
|
4296
|
+
kind: "work-item-effect-run-seeded",
|
|
4297
|
+
subjectId: request.workItemId,
|
|
4298
|
+
sourceRefs: run.sourceRefs,
|
|
4299
|
+
metadata: { effectRunId: request.effectRunId, effectKind: request.effectKind }
|
|
4300
|
+
}
|
|
4301
|
+
}
|
|
4302
|
+
]
|
|
4303
|
+
]);
|
|
4304
|
+
}
|
|
4305
|
+
ctx.state.set(state);
|
|
4306
|
+
},
|
|
4307
|
+
{ name: `${name}/runtime`, factory: "workItemEffectRunProjector" }
|
|
4308
|
+
);
|
|
4309
|
+
return {
|
|
4310
|
+
effectRuns: projectRuntimeFact2(
|
|
4311
|
+
graph,
|
|
4312
|
+
runtime,
|
|
4313
|
+
`${name}/effectRuns`,
|
|
4314
|
+
"workItemEffectRuns",
|
|
4315
|
+
(fact) => fact.kind === "effect-run" ? fact.effectRun : void 0
|
|
4316
|
+
),
|
|
4317
|
+
status: projectRuntimeFact2(
|
|
4318
|
+
graph,
|
|
4319
|
+
runtime,
|
|
4320
|
+
`${name}/status`,
|
|
4321
|
+
"workItemEffectRunStatus",
|
|
4322
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
4323
|
+
),
|
|
4324
|
+
issues: projectRuntimeFact2(
|
|
4325
|
+
graph,
|
|
4326
|
+
runtime,
|
|
4327
|
+
`${name}/issues`,
|
|
4328
|
+
"workItemEffectRunIssues",
|
|
4329
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
4330
|
+
),
|
|
4331
|
+
audit: projectRuntimeFact2(
|
|
4332
|
+
graph,
|
|
4333
|
+
runtime,
|
|
4334
|
+
`${name}/audit`,
|
|
4335
|
+
"workItemEffectRunAudit",
|
|
4336
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
4337
|
+
),
|
|
4338
|
+
views: graph.node(
|
|
4339
|
+
[opts.effectRequests, runtime],
|
|
4340
|
+
(ctx) => {
|
|
4341
|
+
const state = ctx.state.get() ?? {
|
|
4342
|
+
pendingEffectRequests: /* @__PURE__ */ new Map(),
|
|
4343
|
+
settledRequestIds: /* @__PURE__ */ new Set(),
|
|
4344
|
+
issues: [],
|
|
4345
|
+
audit: []
|
|
4346
|
+
};
|
|
4347
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4348
|
+
const request = raw;
|
|
4349
|
+
if (!state.settledRequestIds.has(request.requestId))
|
|
4350
|
+
state.pendingEffectRequests.set(request.requestId, request);
|
|
4351
|
+
}
|
|
4352
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
4353
|
+
const fact = raw;
|
|
4354
|
+
if (fact.kind === "effect-run") {
|
|
4355
|
+
for (const request of state.pendingEffectRequests.values()) {
|
|
4356
|
+
if (request.effectRunId === fact.effectRun.effectRunId) {
|
|
4357
|
+
state.pendingEffectRequests.delete(request.requestId);
|
|
4358
|
+
state.settledRequestIds.add(request.requestId);
|
|
4359
|
+
break;
|
|
4360
|
+
}
|
|
4361
|
+
}
|
|
4362
|
+
} else if (fact.kind === "issue") {
|
|
4363
|
+
deletePendingWorkItemEffectRequest(state, fact.issue.refs);
|
|
4364
|
+
state.issues.push(fact.issue);
|
|
4365
|
+
} else if (fact.kind === "audit") state.audit.push(fact.audit);
|
|
4366
|
+
}
|
|
4367
|
+
ctx.state.set(state);
|
|
4368
|
+
ctx.down([["DATA", freezeWorkItemEffectRequestViews(state)]]);
|
|
4369
|
+
},
|
|
4370
|
+
{ name: `${name}/views`, factory: "workItemEffectRequestViews" }
|
|
4371
|
+
)
|
|
4372
|
+
};
|
|
4373
|
+
}
|
|
4374
|
+
function workItemEffectResultMapper(graph, opts) {
|
|
4375
|
+
const name = opts.name ?? "workItemEffectResultMapper";
|
|
4376
|
+
const policyDeps = opts.mappingPolicies ?? [];
|
|
4377
|
+
const deps = [
|
|
4378
|
+
opts.workItems,
|
|
4379
|
+
opts.effectRuns,
|
|
4380
|
+
opts.effectRunResults,
|
|
4381
|
+
...opts.effectRequests === void 0 ? [] : [opts.effectRequests],
|
|
4382
|
+
...policyDeps
|
|
4383
|
+
];
|
|
4384
|
+
const effectRequestIndex = 3;
|
|
4385
|
+
const policyStart = effectRequestIndex + (opts.effectRequests === void 0 ? 0 : 1);
|
|
4386
|
+
const now = opts.now ?? Date.now;
|
|
4387
|
+
const runtime = graph.node(
|
|
4388
|
+
deps,
|
|
4389
|
+
(ctx) => {
|
|
4390
|
+
const state = ctx.state.get() ?? emptyWorkItemEvidenceState();
|
|
4391
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4392
|
+
const workItem = raw;
|
|
4393
|
+
state.workItems.set(workItem.workItemId, workItem);
|
|
4394
|
+
}
|
|
4395
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
4396
|
+
const run = raw;
|
|
4397
|
+
state.effectRuns.set(run.effectRunId, run);
|
|
4398
|
+
const workItemRef = singleWorkItemRef([
|
|
4399
|
+
...run.subjectRefs ?? [],
|
|
4400
|
+
...run.sourceRefs ?? []
|
|
4401
|
+
]);
|
|
4402
|
+
if (workItemRef !== void 0)
|
|
4403
|
+
state.effectRunWorkItems.set(run.effectRunId, workItemRef.id);
|
|
4404
|
+
}
|
|
4405
|
+
if (opts.effectRequests !== void 0) {
|
|
4406
|
+
for (const raw of depBatch(ctx, effectRequestIndex) ?? []) {
|
|
4407
|
+
const request = raw;
|
|
4408
|
+
state.pendingEffectRequests.set(request.requestId, request);
|
|
4409
|
+
const existing = state.requestsByEffectRun.get(request.effectRunId);
|
|
4410
|
+
if (existing !== void 0 && existing.requestId !== request.requestId) {
|
|
4411
|
+
const ambiguous = state.ambiguousRequestsByEffectRun.get(request.effectRunId) ?? [
|
|
4412
|
+
existing
|
|
4413
|
+
];
|
|
4414
|
+
if (!ambiguous.some((item) => item.requestId === request.requestId))
|
|
4415
|
+
ambiguous.push(request);
|
|
4416
|
+
state.ambiguousRequestsByEffectRun.set(request.effectRunId, ambiguous);
|
|
4417
|
+
emitWorkItemEvidenceIssue(
|
|
4418
|
+
ctx,
|
|
4419
|
+
state,
|
|
4420
|
+
`duplicate-effect-request:${request.effectRunId}:${request.requestId}`,
|
|
4421
|
+
"duplicate-work-item-effect-request",
|
|
4422
|
+
`EffectRun '${request.effectRunId}' has multiple WorkItemEffectRequested facts`,
|
|
4423
|
+
request.workItemId,
|
|
4424
|
+
uniqueSourceRefs2(ambiguous.flatMap(workItemEffectRequestRefs))
|
|
4425
|
+
);
|
|
4426
|
+
} else {
|
|
4427
|
+
state.requestsByEffectRun.set(request.effectRunId, request);
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
}
|
|
4431
|
+
forEachPolicyDepBatch(ctx, policyStart, policyDeps.length, (raw) => {
|
|
4432
|
+
const policy = raw;
|
|
4433
|
+
state.policies.set(policy.policyId, policy);
|
|
4434
|
+
});
|
|
4435
|
+
for (const raw of depBatch(ctx, 2) ?? []) {
|
|
4436
|
+
const result = raw;
|
|
4437
|
+
mapEffectRunResultToWorkItemEvidence(ctx, state, result, now());
|
|
4438
|
+
}
|
|
4439
|
+
ctx.state.set(state);
|
|
4440
|
+
},
|
|
4441
|
+
{ name: `${name}/runtime`, factory: "workItemEffectResultMapper" }
|
|
4442
|
+
);
|
|
4443
|
+
return {
|
|
4444
|
+
evidence: projectRuntimeFact2(
|
|
4445
|
+
graph,
|
|
4446
|
+
runtime,
|
|
4447
|
+
`${name}/evidence`,
|
|
4448
|
+
"workItemEvidenceRecorded",
|
|
4449
|
+
(fact) => fact.kind === "evidence" ? fact.evidence : void 0
|
|
4450
|
+
),
|
|
4451
|
+
status: projectRuntimeFact2(
|
|
4452
|
+
graph,
|
|
4453
|
+
runtime,
|
|
4454
|
+
`${name}/status`,
|
|
4455
|
+
"workItemEvidenceStatus",
|
|
4456
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
4457
|
+
),
|
|
4458
|
+
issues: projectRuntimeFact2(
|
|
4459
|
+
graph,
|
|
4460
|
+
runtime,
|
|
4461
|
+
`${name}/issues`,
|
|
4462
|
+
"workItemEvidenceIssues",
|
|
4463
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
4464
|
+
),
|
|
4465
|
+
audit: projectRuntimeFact2(
|
|
4466
|
+
graph,
|
|
4467
|
+
runtime,
|
|
4468
|
+
`${name}/audit`,
|
|
4469
|
+
"workItemEvidenceAudit",
|
|
4470
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
4471
|
+
),
|
|
4472
|
+
views: graph.node(
|
|
4473
|
+
[...opts.effectRequests === void 0 ? [] : [opts.effectRequests], runtime],
|
|
4474
|
+
(ctx) => {
|
|
4475
|
+
const state = ctx.state.get() ?? {
|
|
4476
|
+
evidenceByWorkItem: /* @__PURE__ */ new Map(),
|
|
4477
|
+
latestEvidenceByEffectRun: /* @__PURE__ */ new Map(),
|
|
4478
|
+
pendingEffectRequests: /* @__PURE__ */ new Map(),
|
|
4479
|
+
settledEffectRunIds: /* @__PURE__ */ new Set(),
|
|
4480
|
+
settledRequestIds: /* @__PURE__ */ new Set(),
|
|
4481
|
+
issues: [],
|
|
4482
|
+
audit: []
|
|
4483
|
+
};
|
|
4484
|
+
if (opts.effectRequests !== void 0) {
|
|
4485
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4486
|
+
const request = raw;
|
|
4487
|
+
if (!state.settledRequestIds.has(request.requestId) && !state.settledEffectRunIds.has(request.effectRunId))
|
|
4488
|
+
state.pendingEffectRequests.set(request.requestId, request);
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
const runtimeIndex = opts.effectRequests === void 0 ? 0 : 1;
|
|
4492
|
+
for (const raw of depBatch(ctx, runtimeIndex) ?? []) {
|
|
4493
|
+
const fact = raw;
|
|
4494
|
+
if (fact.kind === "evidence") {
|
|
4495
|
+
const evidence = fact.evidence;
|
|
4496
|
+
const byWorkItem = state.evidenceByWorkItem.get(evidence.workItemId) ?? [];
|
|
4497
|
+
byWorkItem.push(evidence);
|
|
4498
|
+
state.evidenceByWorkItem.set(evidence.workItemId, byWorkItem);
|
|
4499
|
+
state.latestEvidenceByEffectRun.set(evidence.effectRunId, evidence);
|
|
4500
|
+
for (const request of state.pendingEffectRequests.values()) {
|
|
4501
|
+
if (request.effectRunId === evidence.effectRunId) {
|
|
4502
|
+
state.pendingEffectRequests.delete(request.requestId);
|
|
4503
|
+
state.settledRequestIds.add(request.requestId);
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
state.settledEffectRunIds.add(evidence.effectRunId);
|
|
4507
|
+
} else if (fact.kind === "issue") {
|
|
4508
|
+
deletePendingWorkItemEffectRequest(state, fact.issue.refs);
|
|
4509
|
+
state.issues.push(fact.issue);
|
|
4510
|
+
} else if (fact.kind === "audit") state.audit.push(fact.audit);
|
|
4511
|
+
}
|
|
4512
|
+
ctx.state.set(state);
|
|
4513
|
+
ctx.down([["DATA", freezeWorkItemEvidenceViews(state)]]);
|
|
4514
|
+
},
|
|
4515
|
+
{ name: `${name}/views`, factory: "workItemEvidenceViews" }
|
|
4516
|
+
)
|
|
4517
|
+
};
|
|
4518
|
+
}
|
|
4519
|
+
function workItemDomainActionProposalProjector(graph, opts) {
|
|
4520
|
+
const name = opts.name ?? "workItemDomainActionProposals";
|
|
4521
|
+
const now = opts.now ?? Date.now;
|
|
4522
|
+
const policyStart = 3;
|
|
4523
|
+
const runtime = graph.node(
|
|
4524
|
+
[opts.workItems, opts.evidence, opts.effectRunResults, ...opts.mappingPolicies],
|
|
4525
|
+
(ctx) => {
|
|
4526
|
+
const state = ctx.state.get() ?? emptyWorkItemDomainActionProposalState();
|
|
4527
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4528
|
+
const workItem = raw;
|
|
4529
|
+
state.workItems.set(workItem.workItemId, workItem);
|
|
4530
|
+
}
|
|
4531
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
4532
|
+
const evidence = raw;
|
|
4533
|
+
if (state.evidence.has(evidence.evidenceId)) {
|
|
4534
|
+
emitWorkItemActionProposalIssue(
|
|
4535
|
+
ctx,
|
|
4536
|
+
state,
|
|
4537
|
+
`duplicate-action-proposal-evidence:${evidence.evidenceId}`,
|
|
4538
|
+
"duplicate-work-item-action-proposal-evidence",
|
|
4539
|
+
`WorkItemEvidenceRecorded '${evidence.evidenceId}' was already seen by the action proposal projector`,
|
|
4540
|
+
evidence.workItemId,
|
|
4541
|
+
workItemEvidenceOnlyRefs(evidence)
|
|
4542
|
+
);
|
|
4543
|
+
continue;
|
|
4544
|
+
}
|
|
4545
|
+
state.evidence.set(evidence.evidenceId, evidence);
|
|
4546
|
+
}
|
|
4547
|
+
for (const raw of depBatch(ctx, 2) ?? []) {
|
|
4548
|
+
const result = raw;
|
|
4549
|
+
if (state.results.has(result.resultId)) {
|
|
4550
|
+
emitWorkItemActionProposalIssue(
|
|
4551
|
+
ctx,
|
|
4552
|
+
state,
|
|
4553
|
+
`duplicate-action-proposal-result:${result.resultId}`,
|
|
4554
|
+
"duplicate-work-item-action-proposal-result",
|
|
4555
|
+
`EffectRunResult '${result.resultId}' was already seen by the action proposal projector`,
|
|
4556
|
+
workItemIdForEffectRunResult(state, result),
|
|
4557
|
+
workItemResultRefs(result)
|
|
4558
|
+
);
|
|
4559
|
+
continue;
|
|
4560
|
+
}
|
|
4561
|
+
state.results.set(result.resultId, result);
|
|
4562
|
+
}
|
|
4563
|
+
forEachPolicyDepBatch(ctx, policyStart, opts.mappingPolicies.length, (raw) => {
|
|
4564
|
+
const policy = raw;
|
|
4565
|
+
state.policies.set(policy.policyId, policy);
|
|
4566
|
+
});
|
|
4567
|
+
evaluateWorkItemDomainActionProposals(ctx, state, now());
|
|
4568
|
+
ctx.state.set(state);
|
|
4569
|
+
},
|
|
4570
|
+
{ name: `${name}/runtime`, factory: "workItemDomainActionProposalProjector", partial: true }
|
|
4571
|
+
);
|
|
4572
|
+
return {
|
|
4573
|
+
proposals: projectRuntimeFact2(
|
|
4574
|
+
graph,
|
|
4575
|
+
runtime,
|
|
4576
|
+
`${name}/proposals`,
|
|
4577
|
+
"workItemDomainActionProposals",
|
|
4578
|
+
(fact) => fact.kind === "proposal" ? fact.proposal : void 0
|
|
4579
|
+
),
|
|
4580
|
+
status: projectRuntimeFact2(
|
|
4581
|
+
graph,
|
|
4582
|
+
runtime,
|
|
4583
|
+
`${name}/status`,
|
|
4584
|
+
"workItemDomainActionProposalStatus",
|
|
4585
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
4586
|
+
),
|
|
4587
|
+
issues: projectRuntimeFact2(
|
|
4588
|
+
graph,
|
|
4589
|
+
runtime,
|
|
4590
|
+
`${name}/issues`,
|
|
4591
|
+
"workItemDomainActionProposalIssues",
|
|
4592
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
4593
|
+
),
|
|
4594
|
+
audit: projectRuntimeFact2(
|
|
4595
|
+
graph,
|
|
4596
|
+
runtime,
|
|
4597
|
+
`${name}/audit`,
|
|
4598
|
+
"workItemDomainActionProposalAudit",
|
|
4599
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
4600
|
+
),
|
|
4601
|
+
views: graph.node(
|
|
4602
|
+
[runtime],
|
|
4603
|
+
(ctx) => {
|
|
4604
|
+
const state = ctx.state.get() ?? {
|
|
4605
|
+
proposalsByWorkItem: /* @__PURE__ */ new Map(),
|
|
4606
|
+
proposalsByEvidence: /* @__PURE__ */ new Map(),
|
|
4607
|
+
issues: [],
|
|
4608
|
+
audit: []
|
|
4609
|
+
};
|
|
4610
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4611
|
+
const fact = raw;
|
|
4612
|
+
if (fact.kind === "proposal") {
|
|
4613
|
+
const proposal = fact.proposal;
|
|
4614
|
+
const byWorkItem = state.proposalsByWorkItem.get(proposal.workItemId) ?? [];
|
|
4615
|
+
byWorkItem.push(proposal);
|
|
4616
|
+
state.proposalsByWorkItem.set(proposal.workItemId, byWorkItem);
|
|
4617
|
+
const byEvidence = state.proposalsByEvidence.get(proposal.evidenceId) ?? [];
|
|
4618
|
+
byEvidence.push(proposal);
|
|
4619
|
+
state.proposalsByEvidence.set(proposal.evidenceId, byEvidence);
|
|
4620
|
+
} else if (fact.kind === "issue") state.issues.push(fact.issue);
|
|
4621
|
+
else if (fact.kind === "audit") state.audit.push(fact.audit);
|
|
4622
|
+
}
|
|
4623
|
+
ctx.state.set(state);
|
|
4624
|
+
ctx.down([["DATA", freezeWorkItemDomainActionProposalViews(state)]]);
|
|
4625
|
+
},
|
|
4626
|
+
{ name: `${name}/views`, factory: "workItemDomainActionProposalViews" }
|
|
4627
|
+
)
|
|
4628
|
+
};
|
|
4629
|
+
}
|
|
4630
|
+
function workItemDomainActionAdmissionProjector(graph, opts) {
|
|
4631
|
+
const name = opts.name ?? "workItemDomainActionAdmissions";
|
|
4632
|
+
const policyDeps = opts.admissionPolicies ?? [];
|
|
4633
|
+
const policyStart = 2;
|
|
4634
|
+
const now = opts.now ?? Date.now;
|
|
4635
|
+
const runtime = graph.node(
|
|
4636
|
+
[opts.proposals, opts.decisions, ...policyDeps],
|
|
4637
|
+
(ctx) => {
|
|
4638
|
+
const state = ctx.state.get() ?? emptyWorkItemDomainActionAdmissionState();
|
|
4639
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4640
|
+
const proposal = raw;
|
|
4641
|
+
if (state.proposals.has(proposal.proposalId)) {
|
|
4642
|
+
emitWorkItemAdmissionIssue(
|
|
4643
|
+
ctx,
|
|
4644
|
+
state,
|
|
4645
|
+
`duplicate-admission-proposal:${proposal.proposalId}`,
|
|
4646
|
+
"duplicate-work-item-domain-action-proposal",
|
|
4647
|
+
`WorkItemDomainActionProposal '${proposal.proposalId}' was already seen by the admission projector`,
|
|
4648
|
+
proposal.workItemId,
|
|
4649
|
+
workItemAdmissionProposalRefs(proposal)
|
|
4650
|
+
);
|
|
4651
|
+
continue;
|
|
4652
|
+
}
|
|
4653
|
+
state.proposals.set(proposal.proposalId, proposal);
|
|
4654
|
+
}
|
|
4655
|
+
forEachPolicyDepBatch(ctx, policyStart, policyDeps.length, (raw) => {
|
|
4656
|
+
const policy = raw;
|
|
4657
|
+
state.policies.set(policy.policyId, policy);
|
|
4658
|
+
});
|
|
4659
|
+
for (const raw of depBatch(ctx, 1) ?? []) {
|
|
4660
|
+
const decision = raw;
|
|
4661
|
+
if (state.decisions.has(decision.decisionId)) {
|
|
4662
|
+
emitWorkItemAdmissionIssue(
|
|
4663
|
+
ctx,
|
|
4664
|
+
state,
|
|
4665
|
+
`duplicate-admission-decision:${decision.decisionId}`,
|
|
4666
|
+
"duplicate-work-item-domain-action-admission-decision",
|
|
4667
|
+
`WorkItemDomainActionAdmissionDecision '${decision.decisionId}' was already seen by the admission projector`,
|
|
4668
|
+
decision.proposalId,
|
|
4669
|
+
workItemAdmissionDecisionRefs(decision)
|
|
4670
|
+
);
|
|
4671
|
+
continue;
|
|
4672
|
+
}
|
|
4673
|
+
state.decisions.set(decision.decisionId, decision);
|
|
4674
|
+
}
|
|
4675
|
+
evaluateWorkItemDomainActionAdmissions(ctx, state, now());
|
|
4676
|
+
ctx.state.set(state);
|
|
4677
|
+
},
|
|
4678
|
+
{ name: `${name}/runtime`, factory: "workItemDomainActionAdmissionProjector", partial: true }
|
|
4679
|
+
);
|
|
4680
|
+
return {
|
|
4681
|
+
admissions: projectRuntimeFact2(
|
|
4682
|
+
graph,
|
|
4683
|
+
runtime,
|
|
4684
|
+
`${name}/admissions`,
|
|
4685
|
+
"workItemDomainActionAdmissions",
|
|
4686
|
+
(fact) => fact.kind === "admission" ? fact.admission : void 0
|
|
4687
|
+
),
|
|
4688
|
+
status: projectRuntimeFact2(
|
|
4689
|
+
graph,
|
|
4690
|
+
runtime,
|
|
4691
|
+
`${name}/status`,
|
|
4692
|
+
"workItemDomainActionAdmissionStatus",
|
|
4693
|
+
(fact) => fact.kind === "status" ? fact.status : void 0
|
|
4694
|
+
),
|
|
4695
|
+
issues: projectRuntimeFact2(
|
|
4696
|
+
graph,
|
|
4697
|
+
runtime,
|
|
4698
|
+
`${name}/issues`,
|
|
4699
|
+
"workItemDomainActionAdmissionIssues",
|
|
4700
|
+
(fact) => fact.kind === "issue" ? fact.issue : void 0
|
|
4701
|
+
),
|
|
4702
|
+
audit: projectRuntimeFact2(
|
|
4703
|
+
graph,
|
|
4704
|
+
runtime,
|
|
4705
|
+
`${name}/audit`,
|
|
4706
|
+
"workItemDomainActionAdmissionAudit",
|
|
4707
|
+
(fact) => fact.kind === "audit" ? fact.audit : void 0
|
|
4708
|
+
),
|
|
4709
|
+
views: graph.node(
|
|
4710
|
+
[runtime],
|
|
4711
|
+
(ctx) => {
|
|
4712
|
+
const state = ctx.state.get() ?? {
|
|
4713
|
+
admissionsByProposal: /* @__PURE__ */ new Map(),
|
|
4714
|
+
admissionsByWorkItem: /* @__PURE__ */ new Map(),
|
|
4715
|
+
issues: [],
|
|
4716
|
+
audit: []
|
|
4717
|
+
};
|
|
4718
|
+
for (const raw of depBatch(ctx, 0) ?? []) {
|
|
4719
|
+
const fact = raw;
|
|
4720
|
+
if (fact.kind === "admission") {
|
|
4721
|
+
const admission = fact.admission;
|
|
4722
|
+
state.admissionsByProposal.set(admission.proposalId, admission);
|
|
4723
|
+
const byWorkItem = state.admissionsByWorkItem.get(admission.workItemId) ?? [];
|
|
4724
|
+
byWorkItem.push(admission);
|
|
4725
|
+
state.admissionsByWorkItem.set(admission.workItemId, byWorkItem);
|
|
4726
|
+
} else if (fact.kind === "issue") state.issues.push(fact.issue);
|
|
4727
|
+
else if (fact.kind === "audit") state.audit.push(fact.audit);
|
|
4728
|
+
}
|
|
4729
|
+
ctx.state.set(state);
|
|
4730
|
+
ctx.down([["DATA", freezeWorkItemDomainActionAdmissionViews(state)]]);
|
|
4731
|
+
},
|
|
4732
|
+
{ name: `${name}/views`, factory: "workItemDomainActionAdmissionViews" }
|
|
4733
|
+
)
|
|
4734
|
+
};
|
|
4735
|
+
}
|
|
4736
|
+
function mapEffectRunResultToWorkItemEvidence(ctx, state, result, recordedAtMs) {
|
|
4737
|
+
const run = state.effectRuns.get(result.effectRunId);
|
|
4738
|
+
if (run === void 0) {
|
|
4739
|
+
emitWorkItemEvidenceIssue(
|
|
4740
|
+
ctx,
|
|
4741
|
+
state,
|
|
4742
|
+
`unknown-effect-run:${result.resultId}`,
|
|
4743
|
+
"unknown-effect-run-result",
|
|
4744
|
+
`EffectRunResult '${result.resultId}' references unknown EffectRun '${result.effectRunId}'`,
|
|
4745
|
+
result.effectRunId,
|
|
4746
|
+
result.sourceRefs
|
|
4747
|
+
);
|
|
4748
|
+
return;
|
|
4749
|
+
}
|
|
4750
|
+
const staleEffectRunRef = (result.sourceRefs ?? []).find(
|
|
4751
|
+
(sourceRef) => sourceRef.kind === "effect-run" && sourceRef.id !== result.effectRunId
|
|
4752
|
+
);
|
|
4753
|
+
if (staleEffectRunRef !== void 0) {
|
|
4754
|
+
emitWorkItemEvidenceIssue(
|
|
4755
|
+
ctx,
|
|
4756
|
+
state,
|
|
4757
|
+
`stale-effect-run-ref:${result.resultId}`,
|
|
4758
|
+
"stale-effect-run-source-ref",
|
|
4759
|
+
`EffectRunResult '${result.resultId}' carries a stale EffectRun source ref '${staleEffectRunRef.id}'`,
|
|
4760
|
+
result.effectRunId,
|
|
4761
|
+
result.sourceRefs
|
|
4762
|
+
);
|
|
4763
|
+
return;
|
|
4764
|
+
}
|
|
4765
|
+
const runWorkItemRef = singleWorkItemRef([...run.subjectRefs ?? [], ...run.sourceRefs ?? []]);
|
|
4766
|
+
const resultWorkItemRefs = distinctWorkItemRefs([
|
|
4767
|
+
...result.subjectRefs ?? [],
|
|
4768
|
+
...result.sourceRefs ?? []
|
|
4769
|
+
]);
|
|
4770
|
+
if (resultWorkItemRefs.length > 1) {
|
|
4771
|
+
emitWorkItemEvidenceIssue(
|
|
4772
|
+
ctx,
|
|
4773
|
+
state,
|
|
4774
|
+
`ambiguous-work-item-ref:${result.resultId}`,
|
|
4775
|
+
"stale-work-item-source-ref",
|
|
4776
|
+
`EffectRunResult '${result.resultId}' carries multiple WorkItem refs`,
|
|
4777
|
+
resultWorkItemRefs[0]?.id,
|
|
4778
|
+
workItemResultRefs(result)
|
|
4779
|
+
);
|
|
4780
|
+
return;
|
|
4781
|
+
}
|
|
4782
|
+
const resultWorkItemRef = resultWorkItemRefs[0];
|
|
4783
|
+
if (runWorkItemRef !== void 0 && resultWorkItemRef !== void 0 && runWorkItemRef.id !== resultWorkItemRef.id) {
|
|
4784
|
+
emitWorkItemEvidenceIssue(
|
|
4785
|
+
ctx,
|
|
4786
|
+
state,
|
|
4787
|
+
`stale-work-item-ref:${result.resultId}`,
|
|
4788
|
+
"stale-work-item-source-ref",
|
|
4789
|
+
`EffectRunResult '${result.resultId}' WorkItem ref '${resultWorkItemRef.id}' does not match EffectRun '${result.effectRunId}'`,
|
|
4790
|
+
resultWorkItemRef.id,
|
|
4791
|
+
workItemResultRefs(result)
|
|
4792
|
+
);
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4795
|
+
const workItemId = resultWorkItemRef?.id ?? runWorkItemRef?.id ?? state.effectRunWorkItems.get(result.effectRunId);
|
|
4796
|
+
if (workItemId === void 0) {
|
|
4797
|
+
emitWorkItemEvidenceIssue(
|
|
4798
|
+
ctx,
|
|
4799
|
+
state,
|
|
4800
|
+
`missing-work-item-ref:${result.resultId}`,
|
|
4801
|
+
"missing-work-item-source-ref",
|
|
4802
|
+
`EffectRunResult '${result.resultId}' cannot be mapped without a WorkItem source ref`,
|
|
4803
|
+
result.effectRunId,
|
|
4804
|
+
workItemResultRefs(result)
|
|
4805
|
+
);
|
|
4806
|
+
return;
|
|
4807
|
+
}
|
|
4808
|
+
if (!state.workItems.has(workItemId)) {
|
|
4809
|
+
emitWorkItemEvidenceIssue(
|
|
4810
|
+
ctx,
|
|
4811
|
+
state,
|
|
4812
|
+
`unknown-work-item:${result.resultId}`,
|
|
4813
|
+
"unknown-work-item-evidence-target",
|
|
4814
|
+
`EffectRunResult '${result.resultId}' references unseeded WorkItem '${workItemId}'`,
|
|
4815
|
+
workItemId,
|
|
4816
|
+
workItemResultRefs(result)
|
|
4817
|
+
);
|
|
4818
|
+
return;
|
|
4819
|
+
}
|
|
4820
|
+
const request = state.requestsByEffectRun.get(result.effectRunId);
|
|
4821
|
+
const ambiguousRequests = state.ambiguousRequestsByEffectRun.get(result.effectRunId);
|
|
4822
|
+
if (ambiguousRequests !== void 0) {
|
|
4823
|
+
const refs2 = uniqueSourceRefs2([
|
|
4824
|
+
...workItemResultRefs(result),
|
|
4825
|
+
...ambiguousRequests.flatMap(workItemEffectRequestRefs)
|
|
4826
|
+
]);
|
|
4827
|
+
emitWorkItemEvidenceIssue(
|
|
4828
|
+
ctx,
|
|
4829
|
+
state,
|
|
4830
|
+
`ambiguous-effect-request:${result.effectRunId}:${result.resultId}`,
|
|
4831
|
+
"duplicate-work-item-effect-request",
|
|
4832
|
+
`EffectRun '${result.effectRunId}' has ambiguous WorkItemEffectRequested facts`,
|
|
4833
|
+
workItemId,
|
|
4834
|
+
refs2
|
|
4835
|
+
);
|
|
4836
|
+
clearPendingWorkItemEffectRequestsForRun(state, result.effectRunId);
|
|
4837
|
+
return;
|
|
4838
|
+
}
|
|
4839
|
+
const policyIssue = workItemMappingPolicyIssue(state, request, run);
|
|
4840
|
+
if (policyIssue !== void 0) {
|
|
4841
|
+
emitWorkItemEvidenceIssue(
|
|
4842
|
+
ctx,
|
|
4843
|
+
state,
|
|
4844
|
+
`${policyIssue.code}:${result.resultId}`,
|
|
4845
|
+
policyIssue.code,
|
|
4846
|
+
policyIssue.message,
|
|
4847
|
+
workItemId,
|
|
4848
|
+
workItemMappingPolicyIssueRefs(result, run, request)
|
|
4849
|
+
);
|
|
4850
|
+
clearPendingWorkItemEffectRequestsForRun(state, result.effectRunId);
|
|
4851
|
+
return;
|
|
4852
|
+
}
|
|
4853
|
+
if (state.latestEvidenceByEffectRun.has(result.effectRunId)) {
|
|
4854
|
+
emitWorkItemEvidenceIssue(
|
|
4855
|
+
ctx,
|
|
4856
|
+
state,
|
|
4857
|
+
`duplicate-evidence:${result.effectRunId}:${result.resultId}`,
|
|
4858
|
+
"duplicate-work-item-evidence",
|
|
4859
|
+
`EffectRun '${result.effectRunId}' already recorded WorkItem evidence`,
|
|
4860
|
+
workItemId,
|
|
4861
|
+
workItemResultRefs(result)
|
|
4862
|
+
);
|
|
4863
|
+
return;
|
|
4864
|
+
}
|
|
4865
|
+
const evidence = workItemEvidenceFromResult(result, run, workItemId, request, recordedAtMs);
|
|
4866
|
+
const byWorkItem = state.evidenceByWorkItem.get(workItemId) ?? [];
|
|
4867
|
+
byWorkItem.push(evidence);
|
|
4868
|
+
state.evidenceByWorkItem.set(workItemId, byWorkItem);
|
|
4869
|
+
state.latestEvidenceByEffectRun.set(result.effectRunId, evidence);
|
|
4870
|
+
clearPendingWorkItemEffectRequestsForRun(state, result.effectRunId);
|
|
4871
|
+
state.statusSeq += 1;
|
|
4872
|
+
state.auditSeq += 1;
|
|
4873
|
+
const refs = evidence.sourceRefs;
|
|
4874
|
+
const status = {
|
|
4875
|
+
kind: "work-item-status",
|
|
4876
|
+
statusId: `${workItemId}:evidence-recorded:${state.statusSeq}`,
|
|
4877
|
+
workItemId,
|
|
4878
|
+
state: "evidence-recorded",
|
|
4879
|
+
sourceRefs: refs,
|
|
4880
|
+
effectRunId: result.effectRunId,
|
|
4881
|
+
evidenceId: evidence.evidenceId,
|
|
4882
|
+
issues: result.issues,
|
|
4883
|
+
metadata: { resultStatus: result.status }
|
|
4884
|
+
};
|
|
4885
|
+
const audit = {
|
|
4886
|
+
id: `${workItemId}:evidence-recorded:${state.auditSeq}`,
|
|
4887
|
+
kind: "work-item-evidence-recorded",
|
|
4888
|
+
subjectId: workItemId,
|
|
4889
|
+
sourceRefs: refs,
|
|
4890
|
+
metadata: {
|
|
4891
|
+
effectRunId: result.effectRunId,
|
|
4892
|
+
effectRunResultId: result.resultId,
|
|
4893
|
+
resultStatus: result.status
|
|
4894
|
+
}
|
|
4895
|
+
};
|
|
4896
|
+
state.audit.push(audit);
|
|
4897
|
+
ctx.down([
|
|
4898
|
+
["DATA", { kind: "evidence", evidence }],
|
|
4899
|
+
["DATA", { kind: "status", status }],
|
|
4900
|
+
["DATA", { kind: "audit", audit }]
|
|
4901
|
+
]);
|
|
4902
|
+
}
|
|
4903
|
+
function evaluateWorkItemDomainActionProposals(ctx, state, proposedAtMs) {
|
|
4904
|
+
for (const evidence of state.evidence.values()) {
|
|
4905
|
+
const result = state.results.get(evidence.effectRunResultId);
|
|
4906
|
+
if (result === void 0) {
|
|
4907
|
+
emitWorkItemActionProposalIssue(
|
|
4908
|
+
ctx,
|
|
4909
|
+
state,
|
|
4910
|
+
`missing-action-proposal-result:${evidence.evidenceId}:${evidence.effectRunResultId}`,
|
|
4911
|
+
"missing-work-item-action-proposal-result",
|
|
4912
|
+
`WorkItemEvidenceRecorded '${evidence.evidenceId}' references missing EffectRunResult '${evidence.effectRunResultId}'`,
|
|
4913
|
+
evidence.workItemId,
|
|
4914
|
+
workItemEvidenceOnlyRefs(evidence)
|
|
4915
|
+
);
|
|
4916
|
+
continue;
|
|
4917
|
+
}
|
|
4918
|
+
if (result.effectRunId !== evidence.effectRunId || result.status !== evidence.status) {
|
|
4919
|
+
emitWorkItemActionProposalIssue(
|
|
4920
|
+
ctx,
|
|
4921
|
+
state,
|
|
4922
|
+
`stale-action-proposal-result:${evidence.evidenceId}:${result.resultId}`,
|
|
4923
|
+
"stale-work-item-action-proposal-result",
|
|
4924
|
+
`WorkItemEvidenceRecorded '${evidence.evidenceId}' does not match EffectRunResult '${result.resultId}'`,
|
|
4925
|
+
evidence.workItemId,
|
|
4926
|
+
workItemActionProposalRefs(evidence, result)
|
|
4927
|
+
);
|
|
4928
|
+
continue;
|
|
4929
|
+
}
|
|
4930
|
+
if (!state.workItems.has(evidence.workItemId)) {
|
|
4931
|
+
emitWorkItemActionProposalIssue(
|
|
4932
|
+
ctx,
|
|
4933
|
+
state,
|
|
4934
|
+
`unknown-action-proposal-work-item:${evidence.evidenceId}`,
|
|
4935
|
+
"unknown-work-item-action-proposal-target",
|
|
4936
|
+
`WorkItemEvidenceRecorded '${evidence.evidenceId}' references unseeded WorkItem '${evidence.workItemId}'`,
|
|
4937
|
+
evidence.workItemId,
|
|
4938
|
+
workItemActionProposalRefs(evidence, result)
|
|
4939
|
+
);
|
|
4940
|
+
continue;
|
|
4941
|
+
}
|
|
4942
|
+
const policyIds = referencedWorkItemMappingPolicyIds(evidence);
|
|
4943
|
+
for (const policyId of policyIds) {
|
|
4944
|
+
const policy = state.policies.get(policyId);
|
|
4945
|
+
if (policy === void 0) {
|
|
4946
|
+
emitWorkItemActionProposalIssue(
|
|
4947
|
+
ctx,
|
|
4948
|
+
state,
|
|
4949
|
+
`missing-action-proposal-policy:${evidence.evidenceId}:${policyId}`,
|
|
4950
|
+
"missing-work-item-action-proposal-policy",
|
|
4951
|
+
`WorkItemEffectMappingPolicy '${policyId}' was referenced for WorkItem action proposals but not present`,
|
|
4952
|
+
evidence.workItemId,
|
|
4953
|
+
workItemActionProposalRefs(evidence, result)
|
|
4954
|
+
);
|
|
4955
|
+
continue;
|
|
4956
|
+
}
|
|
4957
|
+
const effectKind = effectKindFromMetadata(evidence.metadata) ?? effectKindFromMetadata(result.metadata);
|
|
4958
|
+
if (!policyAppliesToRequest(policy, effectKind)) {
|
|
4959
|
+
emitWorkItemActionProposalIssue(
|
|
4960
|
+
ctx,
|
|
4961
|
+
state,
|
|
4962
|
+
`action-proposal-policy-mismatch:${evidence.evidenceId}:${policy.policyId}`,
|
|
4963
|
+
"work-item-action-proposal-policy-mismatch",
|
|
4964
|
+
`WorkItemEffectMappingPolicy '${policy.policyId}' does not apply to effectKind '${effectKind ?? "unknown"}'`,
|
|
4965
|
+
evidence.workItemId,
|
|
4966
|
+
workItemActionProposalRefs(evidence, result, policy)
|
|
4967
|
+
);
|
|
4968
|
+
continue;
|
|
4969
|
+
}
|
|
4970
|
+
for (const [index, spec] of (policy.actionProposals ?? []).entries()) {
|
|
4971
|
+
emitWorkItemDomainActionProposal(
|
|
4972
|
+
ctx,
|
|
4973
|
+
state,
|
|
4974
|
+
evidence,
|
|
4975
|
+
result,
|
|
4976
|
+
policy,
|
|
4977
|
+
spec,
|
|
4978
|
+
index,
|
|
4979
|
+
proposedAtMs
|
|
4980
|
+
);
|
|
4981
|
+
}
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
function emitWorkItemDomainActionProposal(ctx, state, evidence, result, policy, spec, index, proposedAtMs) {
|
|
4986
|
+
const key = `${evidence.evidenceId}:${policy.policyId}:${index}:${spec.actionKind}`;
|
|
4987
|
+
if (state.proposedKeys.has(key)) return;
|
|
4988
|
+
if (spec.behavior !== void 0 && spec.behavior !== "propose") {
|
|
4989
|
+
emitWorkItemActionProposalIssue(
|
|
4990
|
+
ctx,
|
|
4991
|
+
state,
|
|
4992
|
+
`unsupported-action-proposal-behavior:${key}`,
|
|
4993
|
+
"unsupported-work-item-action-proposal-behavior",
|
|
4994
|
+
`WorkItemEffectMappingPolicy '${policy.policyId}' uses unsupported action proposal behavior '${spec.behavior}'`,
|
|
4995
|
+
evidence.workItemId,
|
|
4996
|
+
workItemActionProposalRefs(evidence, result, policy)
|
|
4997
|
+
);
|
|
4998
|
+
return;
|
|
4999
|
+
}
|
|
5000
|
+
if (spec.actionKind.length === 0) {
|
|
5001
|
+
emitWorkItemActionProposalIssue(
|
|
5002
|
+
ctx,
|
|
5003
|
+
state,
|
|
5004
|
+
`malformed-action-proposal:${key}`,
|
|
5005
|
+
"malformed-work-item-action-proposal",
|
|
5006
|
+
`WorkItemEffectMappingPolicy '${policy.policyId}' has an empty actionKind`,
|
|
5007
|
+
evidence.workItemId,
|
|
5008
|
+
workItemActionProposalRefs(evidence, result, policy)
|
|
5009
|
+
);
|
|
5010
|
+
return;
|
|
5011
|
+
}
|
|
5012
|
+
if (spec.statuses !== void 0 && !spec.statuses.includes(evidence.status)) return;
|
|
5013
|
+
const outputKind = evidence.output?.kind;
|
|
5014
|
+
if (spec.outputKinds !== void 0 && (outputKind === void 0 || !spec.outputKinds.includes(outputKind)))
|
|
5015
|
+
return;
|
|
5016
|
+
state.proposedKeys.add(key);
|
|
5017
|
+
state.statusSeq += 1;
|
|
5018
|
+
state.auditSeq += 1;
|
|
5019
|
+
const proposal = {
|
|
5020
|
+
kind: "work-item-domain-action-proposal",
|
|
5021
|
+
proposalId: `${evidence.workItemId}:${evidence.effectRunId}:${evidence.effectRunResultId}:${policy.policyId}:${index}:${spec.actionKind}`,
|
|
5022
|
+
workItemId: evidence.workItemId,
|
|
5023
|
+
actionKind: spec.actionKind,
|
|
5024
|
+
effectRunId: evidence.effectRunId,
|
|
5025
|
+
effectRunResultId: evidence.effectRunResultId,
|
|
5026
|
+
evidenceId: evidence.evidenceId,
|
|
5027
|
+
policyId: policy.policyId,
|
|
5028
|
+
payload: workItemActionProposalPayload(spec, evidence, result),
|
|
5029
|
+
reason: spec.reason ?? evidence.reason ?? resultReason(result),
|
|
5030
|
+
sourceRefs: workItemActionProposalRefs(evidence, result, policy),
|
|
5031
|
+
proposedAtMs,
|
|
5032
|
+
metadata: {
|
|
5033
|
+
...policy.metadata ?? {},
|
|
5034
|
+
...spec.metadata ?? {},
|
|
5035
|
+
resultStatus: evidence.status
|
|
5036
|
+
}
|
|
5037
|
+
};
|
|
5038
|
+
const status = {
|
|
5039
|
+
kind: "work-item-status",
|
|
5040
|
+
statusId: `${evidence.workItemId}:domain-action-proposed:${state.statusSeq}`,
|
|
5041
|
+
workItemId: evidence.workItemId,
|
|
5042
|
+
state: "domain-action-proposed",
|
|
5043
|
+
sourceRefs: proposal.sourceRefs,
|
|
5044
|
+
effectRunId: evidence.effectRunId,
|
|
5045
|
+
evidenceId: evidence.evidenceId,
|
|
5046
|
+
proposalId: proposal.proposalId,
|
|
5047
|
+
metadata: { actionKind: spec.actionKind, policyId: policy.policyId }
|
|
5048
|
+
};
|
|
5049
|
+
const audit = {
|
|
5050
|
+
id: `${evidence.workItemId}:domain-action-proposed:${state.auditSeq}`,
|
|
5051
|
+
kind: "work-item-domain-action-proposed",
|
|
5052
|
+
subjectId: evidence.workItemId,
|
|
5053
|
+
sourceRefs: proposal.sourceRefs,
|
|
5054
|
+
metadata: {
|
|
5055
|
+
actionKind: spec.actionKind,
|
|
5056
|
+
effectRunId: evidence.effectRunId,
|
|
5057
|
+
effectRunResultId: evidence.effectRunResultId,
|
|
5058
|
+
evidenceId: evidence.evidenceId,
|
|
5059
|
+
policyId: policy.policyId,
|
|
5060
|
+
proposalId: proposal.proposalId
|
|
5061
|
+
}
|
|
5062
|
+
};
|
|
5063
|
+
ctx.down([
|
|
5064
|
+
["DATA", { kind: "proposal", proposal }],
|
|
5065
|
+
["DATA", { kind: "status", status }],
|
|
5066
|
+
["DATA", { kind: "audit", audit }]
|
|
5067
|
+
]);
|
|
5068
|
+
}
|
|
5069
|
+
function evaluateWorkItemDomainActionAdmissions(ctx, state, admittedAtMs) {
|
|
5070
|
+
let emitted = true;
|
|
5071
|
+
let passes = 0;
|
|
5072
|
+
while (emitted && passes <= state.decisions.size) {
|
|
5073
|
+
emitted = false;
|
|
5074
|
+
passes += 1;
|
|
5075
|
+
for (const decision of state.decisions.values()) {
|
|
5076
|
+
if (state.terminalDecisionIds.has(decision.decisionId)) continue;
|
|
5077
|
+
emitted = evaluateWorkItemDomainActionAdmission(ctx, state, decision, admittedAtMs) || emitted;
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
function evaluateWorkItemDomainActionAdmission(ctx, state, decision, admittedAtMs) {
|
|
5082
|
+
const proposal = state.proposals.get(decision.proposalId);
|
|
5083
|
+
const proposalRefs = workItemAdmissionDecisionRefs(decision, proposal);
|
|
5084
|
+
const subjectId = proposal?.workItemId ?? decision.proposalId;
|
|
5085
|
+
if (proposal === void 0) {
|
|
5086
|
+
emitWorkItemAdmissionIssue(
|
|
5087
|
+
ctx,
|
|
5088
|
+
state,
|
|
5089
|
+
`missing-admission-proposal:${decision.decisionId}:${decision.proposalId}`,
|
|
5090
|
+
"missing-work-item-domain-action-admission-proposal",
|
|
5091
|
+
`WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references missing proposal '${decision.proposalId}'`,
|
|
5092
|
+
subjectId,
|
|
5093
|
+
proposalRefs
|
|
5094
|
+
);
|
|
5095
|
+
return false;
|
|
5096
|
+
}
|
|
5097
|
+
const staleProposalRef = (decision.sourceRefs ?? []).find(
|
|
5098
|
+
(sourceRef) => sourceRef.kind === "work-item-domain-action-proposal" && sourceRef.id !== decision.proposalId && sourceRef.id !== decision.targetProposalId
|
|
5099
|
+
);
|
|
5100
|
+
if (staleProposalRef !== void 0) {
|
|
5101
|
+
emitWorkItemAdmissionIssue(
|
|
5102
|
+
ctx,
|
|
5103
|
+
state,
|
|
5104
|
+
`stale-admission-proposal-ref:${decision.decisionId}:${staleProposalRef.id}`,
|
|
5105
|
+
"stale-work-item-domain-action-admission-proposal-ref",
|
|
5106
|
+
`WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries stale proposal ref '${staleProposalRef.id}'`,
|
|
5107
|
+
proposal.workItemId,
|
|
5108
|
+
proposalRefs
|
|
5109
|
+
);
|
|
5110
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5111
|
+
return false;
|
|
5112
|
+
}
|
|
5113
|
+
const policy = admissionPolicyForDecision(state, decision);
|
|
5114
|
+
if (typeof policy === "string") {
|
|
5115
|
+
emitWorkItemAdmissionIssue(
|
|
5116
|
+
ctx,
|
|
5117
|
+
state,
|
|
5118
|
+
`${policy}:${decision.decisionId}:${decision.policyId ?? "missing"}`,
|
|
5119
|
+
policy,
|
|
5120
|
+
admissionPolicyIssueMessage(policy, decision),
|
|
5121
|
+
proposal.workItemId,
|
|
5122
|
+
proposalRefs
|
|
5123
|
+
);
|
|
5124
|
+
if (policy === "stale-work-item-domain-action-admission-policy-ref")
|
|
5125
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5126
|
+
return false;
|
|
5127
|
+
}
|
|
5128
|
+
if (policy !== void 0) {
|
|
5129
|
+
const policyIssue = validateWorkItemAdmissionPolicy(policy, decision, proposal);
|
|
5130
|
+
if (policyIssue !== void 0) {
|
|
5131
|
+
emitWorkItemAdmissionIssue(
|
|
5132
|
+
ctx,
|
|
5133
|
+
state,
|
|
5134
|
+
`${policyIssue.code}:${decision.decisionId}:${policy.policyId}`,
|
|
5135
|
+
policyIssue.code,
|
|
5136
|
+
policyIssue.message,
|
|
5137
|
+
proposal.workItemId,
|
|
5138
|
+
workItemAdmissionDecisionRefs(decision, proposal, policy)
|
|
5139
|
+
);
|
|
5140
|
+
return false;
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
const mergeIssue = validateWorkItemAdmissionMergeTarget(state, decision);
|
|
5144
|
+
if (mergeIssue !== void 0) {
|
|
5145
|
+
emitWorkItemAdmissionIssue(
|
|
5146
|
+
ctx,
|
|
5147
|
+
state,
|
|
5148
|
+
`${mergeIssue.code}:${decision.decisionId}:${decision.targetProposalId ?? ""}:${decision.targetAdmissionId ?? ""}`,
|
|
5149
|
+
mergeIssue.code,
|
|
5150
|
+
mergeIssue.message,
|
|
5151
|
+
proposal.workItemId,
|
|
5152
|
+
proposalRefs
|
|
5153
|
+
);
|
|
5154
|
+
if (mergeIssue.code !== "unknown-work-item-domain-action-admission-merge-target")
|
|
5155
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5156
|
+
return false;
|
|
5157
|
+
}
|
|
5158
|
+
if (state.admissionsById.has(decision.admissionId)) {
|
|
5159
|
+
emitWorkItemAdmissionIssue(
|
|
5160
|
+
ctx,
|
|
5161
|
+
state,
|
|
5162
|
+
`duplicate-admission-id:${decision.admissionId}`,
|
|
5163
|
+
"duplicate-work-item-domain-action-admission",
|
|
5164
|
+
`WorkItemDomainActionAdmission '${decision.admissionId}' was already emitted`,
|
|
5165
|
+
proposal.workItemId,
|
|
5166
|
+
proposalRefs
|
|
5167
|
+
);
|
|
5168
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5169
|
+
return false;
|
|
5170
|
+
}
|
|
5171
|
+
if (state.admissionsByProposal.has(decision.proposalId)) {
|
|
5172
|
+
emitWorkItemAdmissionIssue(
|
|
5173
|
+
ctx,
|
|
5174
|
+
state,
|
|
5175
|
+
`duplicate-admission-proposal-decision:${decision.proposalId}:${decision.decisionId}`,
|
|
5176
|
+
"duplicate-work-item-domain-action-admission-proposal",
|
|
5177
|
+
`WorkItemDomainActionProposal '${decision.proposalId}' already has an admission decision`,
|
|
5178
|
+
proposal.workItemId,
|
|
5179
|
+
proposalRefs
|
|
5180
|
+
);
|
|
5181
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5182
|
+
return false;
|
|
5183
|
+
}
|
|
5184
|
+
const admissionState = admissionStateForOutcome(decision.outcome);
|
|
5185
|
+
if (admissionState === void 0) {
|
|
5186
|
+
emitWorkItemAdmissionIssue(
|
|
5187
|
+
ctx,
|
|
5188
|
+
state,
|
|
5189
|
+
`unsupported-admission-outcome:${decision.decisionId}:${String(decision.outcome)}`,
|
|
5190
|
+
"unsupported-work-item-domain-action-admission-outcome",
|
|
5191
|
+
`WorkItemDomainActionAdmissionDecision '${decision.decisionId}' uses unsupported outcome '${String(decision.outcome)}'`,
|
|
5192
|
+
proposal.workItemId,
|
|
5193
|
+
proposalRefs
|
|
5194
|
+
);
|
|
5195
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5196
|
+
return false;
|
|
5197
|
+
}
|
|
5198
|
+
const admission = {
|
|
5199
|
+
kind: "work-item-domain-action-admission",
|
|
5200
|
+
admissionId: decision.admissionId,
|
|
5201
|
+
proposalId: proposal.proposalId,
|
|
5202
|
+
workItemId: proposal.workItemId,
|
|
5203
|
+
actionKind: proposal.actionKind,
|
|
5204
|
+
state: admissionState,
|
|
5205
|
+
decisionId: decision.decisionId,
|
|
5206
|
+
policyId: decision.policyId,
|
|
5207
|
+
reason: decision.reason,
|
|
5208
|
+
targetProposalId: decision.targetProposalId,
|
|
5209
|
+
targetAdmissionId: decision.targetAdmissionId,
|
|
5210
|
+
sourceRefs: workItemAdmissionDecisionRefs(decision, proposal, policy),
|
|
5211
|
+
admittedAtMs: decision.decidedAtMs ?? admittedAtMs,
|
|
5212
|
+
metadata: {
|
|
5213
|
+
...proposal.metadata ?? {},
|
|
5214
|
+
...policy?.metadata ?? {},
|
|
5215
|
+
...decision.metadata ?? {}
|
|
5216
|
+
}
|
|
5217
|
+
};
|
|
5218
|
+
state.admissionsById.set(admission.admissionId, admission);
|
|
5219
|
+
state.admissionsByProposal.set(admission.proposalId, admission);
|
|
5220
|
+
state.terminalDecisionIds.add(decision.decisionId);
|
|
5221
|
+
state.statusSeq += 1;
|
|
5222
|
+
state.auditSeq += 1;
|
|
5223
|
+
const statusState = workItemAdmissionStatusState(admission.state);
|
|
5224
|
+
const status = {
|
|
5225
|
+
kind: "work-item-status",
|
|
5226
|
+
statusId: `${proposal.workItemId}:${statusState}:${state.statusSeq}`,
|
|
5227
|
+
workItemId: proposal.workItemId,
|
|
5228
|
+
state: statusState,
|
|
5229
|
+
sourceRefs: admission.sourceRefs,
|
|
5230
|
+
effectRunId: proposal.effectRunId,
|
|
5231
|
+
evidenceId: proposal.evidenceId,
|
|
5232
|
+
proposalId: proposal.proposalId,
|
|
5233
|
+
metadata: {
|
|
5234
|
+
actionKind: proposal.actionKind,
|
|
5235
|
+
admissionId: admission.admissionId,
|
|
5236
|
+
decisionId: decision.decisionId,
|
|
5237
|
+
policyId: decision.policyId
|
|
5238
|
+
}
|
|
5239
|
+
};
|
|
5240
|
+
const audit = {
|
|
5241
|
+
id: `${proposal.workItemId}:${statusState}:${state.auditSeq}`,
|
|
5242
|
+
kind: `work-item-domain-action-${admission.state}`,
|
|
5243
|
+
subjectId: proposal.workItemId,
|
|
5244
|
+
sourceRefs: admission.sourceRefs,
|
|
5245
|
+
metadata: {
|
|
5246
|
+
actionKind: proposal.actionKind,
|
|
5247
|
+
admissionId: admission.admissionId,
|
|
5248
|
+
decisionId: decision.decisionId,
|
|
5249
|
+
policyId: decision.policyId,
|
|
5250
|
+
proposalId: proposal.proposalId
|
|
5251
|
+
}
|
|
5252
|
+
};
|
|
5253
|
+
ctx.down([
|
|
5254
|
+
["DATA", { kind: "admission", admission }],
|
|
5255
|
+
["DATA", { kind: "status", status }],
|
|
5256
|
+
["DATA", { kind: "audit", audit }]
|
|
5257
|
+
]);
|
|
5258
|
+
return true;
|
|
5259
|
+
}
|
|
5260
|
+
function workItemEvidenceFromResult(result, run, workItemId, request, recordedAtMs) {
|
|
5261
|
+
const base = {
|
|
5262
|
+
kind: "work-item-evidence-recorded",
|
|
5263
|
+
evidenceId: `${workItemId}:${result.effectRunId}:${result.resultId}`,
|
|
5264
|
+
workItemId,
|
|
5265
|
+
requestId: request?.requestId,
|
|
5266
|
+
effectRunId: result.effectRunId,
|
|
5267
|
+
effectRunResultId: result.resultId,
|
|
5268
|
+
executionInputRevision: request?.executionInputRevision,
|
|
5269
|
+
planId: request?.planId,
|
|
5270
|
+
planMemberId: request?.planMemberId,
|
|
5271
|
+
status: result.status,
|
|
5272
|
+
sourceRefs: uniqueSourceRefs2([
|
|
5273
|
+
ref2("work-item", workItemId),
|
|
5274
|
+
ref2("effect-run", result.effectRunId),
|
|
5275
|
+
ref2("effect-run-result", result.resultId),
|
|
5276
|
+
...run.sourceRefs ?? [],
|
|
5277
|
+
...run.subjectRefs ?? [],
|
|
5278
|
+
...run.policyRefs ?? [],
|
|
5279
|
+
...result.sourceRefs ?? [],
|
|
5280
|
+
...result.subjectRefs ?? []
|
|
5281
|
+
]),
|
|
5282
|
+
issues: result.issues,
|
|
5283
|
+
auditRefs: result.auditRefs,
|
|
5284
|
+
recordedAtMs,
|
|
5285
|
+
metadata: {
|
|
5286
|
+
...result.metadata ?? {},
|
|
5287
|
+
...request?.requestId === void 0 ? {} : { requestId: request.requestId },
|
|
5288
|
+
...request?.executionInputRevision === void 0 ? {} : { executionInputRevision: request.executionInputRevision },
|
|
5289
|
+
...request?.planId === void 0 ? {} : { planId: request.planId },
|
|
5290
|
+
...request?.planMemberId === void 0 ? {} : { planMemberId: request.planMemberId }
|
|
5291
|
+
}
|
|
5292
|
+
};
|
|
5293
|
+
if (result.status === "completed") return { ...base, output: result.output };
|
|
5294
|
+
if (result.status === "failed") return { ...base, error: result.error };
|
|
5295
|
+
if (result.status === "blocked") return { ...base, needs: result.needs };
|
|
5296
|
+
if (result.status === "timeout") return { ...base, timeoutMs: result.timeoutMs };
|
|
5297
|
+
if (result.status === "canceled" || result.status === "waived")
|
|
5298
|
+
return { ...base, reason: result.reason };
|
|
5299
|
+
return base;
|
|
5300
|
+
}
|
|
5301
|
+
function workItemMappingPolicyIssue(state, request, run) {
|
|
5302
|
+
const context = workItemMappingPolicyContext(request, run);
|
|
5303
|
+
const referencedPolicyIds = context.policyRefs.filter((sourceRef) => sourceRef.kind === "work-item-effect-mapping-policy").map((sourceRef) => sourceRef.id);
|
|
5304
|
+
for (const policyId of referencedPolicyIds) {
|
|
5305
|
+
const policy = state.policies.get(policyId);
|
|
5306
|
+
if (policy === void 0) {
|
|
5307
|
+
return {
|
|
5308
|
+
code: "missing-work-item-effect-mapping-policy",
|
|
5309
|
+
message: `WorkItemEffectMappingPolicy '${policyId}' was required but not present`
|
|
5310
|
+
};
|
|
5311
|
+
}
|
|
5312
|
+
const issue = validateWorkItemMappingPolicy(policy, context.effectKind);
|
|
5313
|
+
if (issue !== void 0) return issue;
|
|
5314
|
+
}
|
|
5315
|
+
return void 0;
|
|
5316
|
+
}
|
|
5317
|
+
function validateWorkItemMappingPolicy(policy, effectKind) {
|
|
5318
|
+
if (!policyAppliesToRequest(policy, effectKind)) {
|
|
5319
|
+
return {
|
|
5320
|
+
code: "work-item-effect-mapping-policy-mismatch",
|
|
5321
|
+
message: `WorkItemEffectMappingPolicy '${policy.policyId}' does not apply to effectKind '${effectKind ?? "unknown"}'`
|
|
5322
|
+
};
|
|
5323
|
+
}
|
|
5324
|
+
const behavior = policy.evidence?.behavior ?? "record";
|
|
5325
|
+
if (behavior !== "record") {
|
|
5326
|
+
return {
|
|
5327
|
+
code: "unsupported-work-item-evidence-behavior",
|
|
5328
|
+
message: `WorkItemEffectMappingPolicy '${policy.policyId}' uses unsupported evidence behavior '${behavior}'`
|
|
5329
|
+
};
|
|
5330
|
+
}
|
|
5331
|
+
return void 0;
|
|
5332
|
+
}
|
|
5333
|
+
function admissionPolicyForDecision(state, decision) {
|
|
5334
|
+
if (decision.policyId === void 0) return void 0;
|
|
5335
|
+
const stalePolicyRef = (decision.sourceRefs ?? []).find(
|
|
5336
|
+
(sourceRef) => sourceRef.kind === "work-item-domain-action-admission-policy" && sourceRef.id !== decision.policyId
|
|
5337
|
+
);
|
|
5338
|
+
if (stalePolicyRef !== void 0) return "stale-work-item-domain-action-admission-policy-ref";
|
|
5339
|
+
return state.policies.get(decision.policyId) ?? "missing-work-item-domain-action-admission-policy";
|
|
5340
|
+
}
|
|
5341
|
+
function admissionPolicyIssueMessage(code, decision) {
|
|
5342
|
+
if (code === "missing-work-item-domain-action-admission-policy") {
|
|
5343
|
+
return `WorkItemDomainActionAdmissionPolicy '${decision.policyId}' was referenced for WorkItem action admission but not present`;
|
|
5344
|
+
}
|
|
5345
|
+
return `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries a stale admission policy source ref`;
|
|
5346
|
+
}
|
|
5347
|
+
function validateWorkItemAdmissionPolicy(policy, decision, proposal) {
|
|
5348
|
+
if (policy.actionKinds !== void 0 && !policy.actionKinds.includes(proposal.actionKind)) {
|
|
5349
|
+
return {
|
|
5350
|
+
code: "work-item-domain-action-admission-policy-mismatch",
|
|
5351
|
+
message: `WorkItemDomainActionAdmissionPolicy '${policy.policyId}' does not apply to actionKind '${proposal.actionKind}'`
|
|
5352
|
+
};
|
|
5353
|
+
}
|
|
5354
|
+
if (policy.allowedOutcomes !== void 0 && !policy.allowedOutcomes.includes(decision.outcome)) {
|
|
5355
|
+
return {
|
|
5356
|
+
code: "unsupported-work-item-domain-action-admission-outcome",
|
|
5357
|
+
message: `WorkItemDomainActionAdmissionPolicy '${policy.policyId}' does not allow outcome '${decision.outcome}'`
|
|
5358
|
+
};
|
|
5359
|
+
}
|
|
5360
|
+
return void 0;
|
|
5361
|
+
}
|
|
5362
|
+
function validateWorkItemAdmissionMergeTarget(state, decision) {
|
|
5363
|
+
const hasTargetProposal = decision.targetProposalId !== void 0;
|
|
5364
|
+
const hasTargetAdmission = decision.targetAdmissionId !== void 0;
|
|
5365
|
+
if (decision.outcome !== "merge") {
|
|
5366
|
+
if (hasTargetProposal || hasTargetAdmission) {
|
|
5367
|
+
return {
|
|
5368
|
+
code: "ambiguous-work-item-domain-action-admission-merge-target",
|
|
5369
|
+
message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' carries a merge target for non-merge outcome '${decision.outcome}'`
|
|
5370
|
+
};
|
|
5371
|
+
}
|
|
5372
|
+
return void 0;
|
|
5373
|
+
}
|
|
5374
|
+
if (hasTargetProposal === hasTargetAdmission) {
|
|
5375
|
+
return {
|
|
5376
|
+
code: "ambiguous-work-item-domain-action-admission-merge-target",
|
|
5377
|
+
message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' must reference exactly one merge target`
|
|
5378
|
+
};
|
|
5379
|
+
}
|
|
5380
|
+
if (decision.targetProposalId === decision.proposalId) {
|
|
5381
|
+
return {
|
|
5382
|
+
code: "ambiguous-work-item-domain-action-admission-merge-target",
|
|
5383
|
+
message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' cannot merge a proposal into itself`
|
|
5384
|
+
};
|
|
5385
|
+
}
|
|
5386
|
+
if (decision.targetProposalId !== void 0 && !state.proposals.has(decision.targetProposalId)) {
|
|
5387
|
+
return {
|
|
5388
|
+
code: "unknown-work-item-domain-action-admission-merge-target",
|
|
5389
|
+
message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references unknown target proposal '${decision.targetProposalId}'`
|
|
5390
|
+
};
|
|
5391
|
+
}
|
|
5392
|
+
if (decision.targetAdmissionId !== void 0 && !state.admissionsById.has(decision.targetAdmissionId)) {
|
|
5393
|
+
return {
|
|
5394
|
+
code: "unknown-work-item-domain-action-admission-merge-target",
|
|
5395
|
+
message: `WorkItemDomainActionAdmissionDecision '${decision.decisionId}' references unknown target admission '${decision.targetAdmissionId}'`
|
|
5396
|
+
};
|
|
5397
|
+
}
|
|
5398
|
+
return void 0;
|
|
5399
|
+
}
|
|
5400
|
+
function admissionStateForOutcome(outcome) {
|
|
5401
|
+
if (outcome === "admit") return "admitted";
|
|
5402
|
+
if (outcome === "reject") return "rejected";
|
|
5403
|
+
if (outcome === "defer") return "deferred";
|
|
5404
|
+
if (outcome === "merge") return "merged";
|
|
5405
|
+
return void 0;
|
|
5406
|
+
}
|
|
5407
|
+
function workItemAdmissionStatusState(state) {
|
|
5408
|
+
if (state === "admitted") return "domain-action-admitted";
|
|
5409
|
+
if (state === "rejected") return "domain-action-rejected";
|
|
5410
|
+
if (state === "deferred") return "domain-action-deferred";
|
|
5411
|
+
return "domain-action-merged";
|
|
5412
|
+
}
|
|
5413
|
+
function policyAppliesToRequest(policy, effectKind) {
|
|
5414
|
+
return policy.effectKinds === void 0 || effectKind !== void 0 && policy.effectKinds.includes(effectKind);
|
|
5415
|
+
}
|
|
5416
|
+
function workItemMappingPolicyContext(request, run) {
|
|
5417
|
+
return {
|
|
5418
|
+
policyRefs: request?.policyRefs ?? run.policyRefs ?? [],
|
|
5419
|
+
effectKind: request?.effectKind ?? effectKindFromRun(run)
|
|
5420
|
+
};
|
|
5421
|
+
}
|
|
5422
|
+
function effectKindFromRun(run) {
|
|
5423
|
+
const effectKind = run.metadata?.effectKind;
|
|
5424
|
+
return typeof effectKind === "string" ? effectKind : void 0;
|
|
5425
|
+
}
|
|
5426
|
+
function workItemMappingPolicyIssueRefs(result, run, request) {
|
|
5427
|
+
return uniqueSourceRefs2([
|
|
5428
|
+
...workItemResultRefs(result),
|
|
5429
|
+
...request === void 0 ? [...run.sourceRefs ?? [], ...run.subjectRefs ?? [], ...run.policyRefs ?? []] : workItemEffectRequestRefs(request)
|
|
5430
|
+
]);
|
|
5431
|
+
}
|
|
5432
|
+
function clearPendingWorkItemEffectRequestsForRun(state, effectRunId) {
|
|
5433
|
+
for (const pendingRequest of state.pendingEffectRequests.values()) {
|
|
5434
|
+
if (pendingRequest.effectRunId === effectRunId)
|
|
5435
|
+
state.pendingEffectRequests.delete(pendingRequest.requestId);
|
|
5436
|
+
}
|
|
5437
|
+
}
|
|
5438
|
+
function emitWorkItemEffectRunIssue(ctx, state, key, code, message, subjectId, sourceRefs) {
|
|
5439
|
+
if (state.issueKeys.has(key)) return;
|
|
5440
|
+
state.issueKeys.add(key);
|
|
5441
|
+
state.issueSeq += 1;
|
|
5442
|
+
state.statusSeq += 1;
|
|
5443
|
+
state.auditSeq += 1;
|
|
5444
|
+
const issue = dataIssue2(code, message, { subjectId, refs: sourceRefs });
|
|
5445
|
+
const status = {
|
|
5446
|
+
kind: "work-item-status",
|
|
5447
|
+
statusId: `${subjectId ?? "work-item"}:mapping-issue:${state.statusSeq}`,
|
|
5448
|
+
workItemId: subjectId ?? "unknown",
|
|
5449
|
+
state: "mapping-issue",
|
|
5450
|
+
sourceRefs,
|
|
5451
|
+
issues: [issue]
|
|
5452
|
+
};
|
|
5453
|
+
const audit = {
|
|
5454
|
+
id: `${subjectId ?? "work-item"}:${code}:${state.auditSeq}`,
|
|
5455
|
+
kind: "work-item-effect-run-issue",
|
|
5456
|
+
subjectId,
|
|
5457
|
+
issueCode: code,
|
|
5458
|
+
message,
|
|
5459
|
+
sourceRefs
|
|
5460
|
+
};
|
|
5461
|
+
state.issues.push(issue);
|
|
5462
|
+
state.audit.push(audit);
|
|
5463
|
+
ctx.down([
|
|
5464
|
+
["DATA", { kind: "issue", issue }],
|
|
5465
|
+
["DATA", { kind: "status", status }],
|
|
5466
|
+
["DATA", { kind: "audit", audit }]
|
|
5467
|
+
]);
|
|
5468
|
+
}
|
|
5469
|
+
function emitWorkItemEvidenceIssue(ctx, state, key, code, message, subjectId, sourceRefs) {
|
|
5470
|
+
if (state.issueKeys.has(key)) return;
|
|
5471
|
+
state.issueKeys.add(key);
|
|
5472
|
+
state.issueSeq += 1;
|
|
5473
|
+
state.statusSeq += 1;
|
|
5474
|
+
state.auditSeq += 1;
|
|
5475
|
+
const issue = dataIssue2(code, message, { subjectId, refs: sourceRefs });
|
|
5476
|
+
const status = {
|
|
5477
|
+
kind: "work-item-status",
|
|
5478
|
+
statusId: `${subjectId ?? "work-item"}:mapping-issue:${state.statusSeq}`,
|
|
5479
|
+
workItemId: subjectId ?? "unknown",
|
|
5480
|
+
state: "mapping-issue",
|
|
5481
|
+
sourceRefs,
|
|
5482
|
+
issues: [issue]
|
|
5483
|
+
};
|
|
5484
|
+
const audit = {
|
|
5485
|
+
id: `${subjectId ?? "work-item"}:${code}:${state.auditSeq}`,
|
|
5486
|
+
kind: "work-item-evidence-mapping-issue",
|
|
5487
|
+
subjectId,
|
|
5488
|
+
issueCode: code,
|
|
5489
|
+
message,
|
|
5490
|
+
sourceRefs
|
|
5491
|
+
};
|
|
5492
|
+
state.issues.push(issue);
|
|
5493
|
+
state.audit.push(audit);
|
|
5494
|
+
ctx.down([
|
|
5495
|
+
["DATA", { kind: "issue", issue }],
|
|
5496
|
+
["DATA", { kind: "status", status }],
|
|
5497
|
+
["DATA", { kind: "audit", audit }]
|
|
5498
|
+
]);
|
|
5499
|
+
}
|
|
5500
|
+
function emitWorkItemActionProposalIssue(ctx, state, key, code, message, subjectId, sourceRefs) {
|
|
5501
|
+
if (state.issueKeys.has(key)) return;
|
|
5502
|
+
state.issueKeys.add(key);
|
|
5503
|
+
state.issueSeq += 1;
|
|
5504
|
+
state.statusSeq += 1;
|
|
5505
|
+
state.auditSeq += 1;
|
|
5506
|
+
const issue = dataIssue2(code, message, { subjectId, refs: sourceRefs });
|
|
5507
|
+
const status = {
|
|
5508
|
+
kind: "work-item-status",
|
|
5509
|
+
statusId: `${subjectId ?? "work-item"}:mapping-issue:${state.statusSeq}`,
|
|
5510
|
+
workItemId: subjectId ?? "unknown",
|
|
5511
|
+
state: "mapping-issue",
|
|
5512
|
+
sourceRefs,
|
|
5513
|
+
issues: [issue]
|
|
5514
|
+
};
|
|
5515
|
+
const audit = {
|
|
5516
|
+
id: `${subjectId ?? "work-item"}:${code}:${state.auditSeq}`,
|
|
5517
|
+
kind: "work-item-action-proposal-issue",
|
|
5518
|
+
subjectId,
|
|
5519
|
+
issueCode: code,
|
|
5520
|
+
message,
|
|
5521
|
+
sourceRefs
|
|
5522
|
+
};
|
|
5523
|
+
ctx.down([
|
|
5524
|
+
["DATA", { kind: "issue", issue }],
|
|
5525
|
+
["DATA", { kind: "status", status }],
|
|
5526
|
+
["DATA", { kind: "audit", audit }]
|
|
5527
|
+
]);
|
|
5528
|
+
}
|
|
5529
|
+
function emitWorkItemAdmissionIssue(ctx, state, key, code, message, subjectId, sourceRefs) {
|
|
5530
|
+
if (state.issueKeys.has(key)) return;
|
|
5531
|
+
state.issueKeys.add(key);
|
|
5532
|
+
state.issueSeq += 1;
|
|
5533
|
+
state.statusSeq += 1;
|
|
5534
|
+
state.auditSeq += 1;
|
|
5535
|
+
const issue = dataIssue2(code, message, { subjectId, refs: sourceRefs });
|
|
5536
|
+
const status = {
|
|
5537
|
+
kind: "work-item-status",
|
|
5538
|
+
statusId: `${subjectId ?? "work-item"}:mapping-issue:${state.statusSeq}`,
|
|
5539
|
+
workItemId: subjectId ?? "unknown",
|
|
5540
|
+
state: "mapping-issue",
|
|
5541
|
+
sourceRefs,
|
|
5542
|
+
issues: [issue]
|
|
5543
|
+
};
|
|
5544
|
+
const audit = {
|
|
5545
|
+
id: `${subjectId ?? "work-item"}:${code}:${state.auditSeq}`,
|
|
5546
|
+
kind: "work-item-domain-action-admission-issue",
|
|
5547
|
+
subjectId,
|
|
5548
|
+
issueCode: code,
|
|
5549
|
+
message,
|
|
5550
|
+
sourceRefs
|
|
5551
|
+
};
|
|
5552
|
+
ctx.down([
|
|
5553
|
+
["DATA", { kind: "issue", issue }],
|
|
5554
|
+
["DATA", { kind: "status", status }],
|
|
5555
|
+
["DATA", { kind: "audit", audit }]
|
|
5556
|
+
]);
|
|
5557
|
+
}
|
|
5558
|
+
function emptyWorkItemEffectRunState() {
|
|
5559
|
+
return {
|
|
5560
|
+
workItems: /* @__PURE__ */ new Map(),
|
|
5561
|
+
requests: /* @__PURE__ */ new Map(),
|
|
5562
|
+
effectRunsByRequest: /* @__PURE__ */ new Map(),
|
|
5563
|
+
seededEffectRunIds: /* @__PURE__ */ new Set(),
|
|
5564
|
+
issues: [],
|
|
5565
|
+
audit: [],
|
|
5566
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
5567
|
+
statusSeq: 0,
|
|
5568
|
+
issueSeq: 0,
|
|
5569
|
+
auditSeq: 0
|
|
5570
|
+
};
|
|
5571
|
+
}
|
|
5572
|
+
function emptyWorkItemEvidenceState() {
|
|
5573
|
+
return {
|
|
5574
|
+
workItems: /* @__PURE__ */ new Map(),
|
|
5575
|
+
effectRuns: /* @__PURE__ */ new Map(),
|
|
5576
|
+
effectRunWorkItems: /* @__PURE__ */ new Map(),
|
|
5577
|
+
evidenceByWorkItem: /* @__PURE__ */ new Map(),
|
|
5578
|
+
latestEvidenceByEffectRun: /* @__PURE__ */ new Map(),
|
|
5579
|
+
pendingEffectRequests: /* @__PURE__ */ new Map(),
|
|
5580
|
+
requestsByEffectRun: /* @__PURE__ */ new Map(),
|
|
5581
|
+
ambiguousRequestsByEffectRun: /* @__PURE__ */ new Map(),
|
|
5582
|
+
policies: /* @__PURE__ */ new Map(),
|
|
5583
|
+
issues: [],
|
|
5584
|
+
audit: [],
|
|
5585
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
5586
|
+
statusSeq: 0,
|
|
5587
|
+
issueSeq: 0,
|
|
5588
|
+
auditSeq: 0
|
|
5589
|
+
};
|
|
5590
|
+
}
|
|
5591
|
+
function emptyWorkItemDomainActionProposalState() {
|
|
5592
|
+
return {
|
|
5593
|
+
workItems: /* @__PURE__ */ new Map(),
|
|
5594
|
+
evidence: /* @__PURE__ */ new Map(),
|
|
5595
|
+
results: /* @__PURE__ */ new Map(),
|
|
5596
|
+
policies: /* @__PURE__ */ new Map(),
|
|
5597
|
+
proposedKeys: /* @__PURE__ */ new Set(),
|
|
5598
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
5599
|
+
statusSeq: 0,
|
|
5600
|
+
issueSeq: 0,
|
|
5601
|
+
auditSeq: 0
|
|
5602
|
+
};
|
|
5603
|
+
}
|
|
5604
|
+
function emptyWorkItemDomainActionAdmissionState() {
|
|
5605
|
+
return {
|
|
5606
|
+
proposals: /* @__PURE__ */ new Map(),
|
|
5607
|
+
policies: /* @__PURE__ */ new Map(),
|
|
5608
|
+
decisions: /* @__PURE__ */ new Map(),
|
|
5609
|
+
admissionsById: /* @__PURE__ */ new Map(),
|
|
5610
|
+
admissionsByProposal: /* @__PURE__ */ new Map(),
|
|
5611
|
+
terminalDecisionIds: /* @__PURE__ */ new Set(),
|
|
5612
|
+
issueKeys: /* @__PURE__ */ new Set(),
|
|
5613
|
+
statusSeq: 0,
|
|
5614
|
+
issueSeq: 0,
|
|
5615
|
+
auditSeq: 0
|
|
5616
|
+
};
|
|
5617
|
+
}
|
|
5618
|
+
function freezeWorkItemEffectRequestViews(state) {
|
|
5619
|
+
return {
|
|
5620
|
+
pendingEffectRequests: Object.freeze(Array.from(state.pendingEffectRequests.values())),
|
|
5621
|
+
issues: Object.freeze([...state.issues]),
|
|
5622
|
+
audit: Object.freeze([...state.audit])
|
|
5623
|
+
};
|
|
5624
|
+
}
|
|
5625
|
+
function freezeWorkItemEvidenceViews(state) {
|
|
5626
|
+
return {
|
|
5627
|
+
evidenceByWorkItem: new Map(
|
|
5628
|
+
Array.from(state.evidenceByWorkItem, ([key, value]) => [key, Object.freeze([...value])])
|
|
5629
|
+
),
|
|
5630
|
+
latestEvidenceByEffectRun: new Map(state.latestEvidenceByEffectRun),
|
|
5631
|
+
issues: Object.freeze([...state.issues]),
|
|
5632
|
+
audit: Object.freeze([...state.audit]),
|
|
5633
|
+
pendingEffectRequests: Object.freeze(Array.from(state.pendingEffectRequests.values()))
|
|
5634
|
+
};
|
|
5635
|
+
}
|
|
5636
|
+
function freezeWorkItemDomainActionProposalViews(state) {
|
|
5637
|
+
return {
|
|
5638
|
+
proposalsByWorkItem: new Map(
|
|
5639
|
+
Array.from(state.proposalsByWorkItem, ([key, value]) => [key, Object.freeze([...value])])
|
|
5640
|
+
),
|
|
5641
|
+
proposalsByEvidence: new Map(
|
|
5642
|
+
Array.from(state.proposalsByEvidence, ([key, value]) => [key, Object.freeze([...value])])
|
|
5643
|
+
),
|
|
5644
|
+
issues: Object.freeze([...state.issues]),
|
|
5645
|
+
audit: Object.freeze([...state.audit])
|
|
5646
|
+
};
|
|
5647
|
+
}
|
|
5648
|
+
function freezeWorkItemDomainActionAdmissionViews(state) {
|
|
5649
|
+
return {
|
|
5650
|
+
admissionsByProposal: new Map(state.admissionsByProposal),
|
|
5651
|
+
admissionsByWorkItem: new Map(
|
|
5652
|
+
Array.from(state.admissionsByWorkItem, ([key, value]) => [key, Object.freeze([...value])])
|
|
5653
|
+
),
|
|
5654
|
+
issues: Object.freeze([...state.issues]),
|
|
5655
|
+
audit: Object.freeze([...state.audit])
|
|
5656
|
+
};
|
|
5657
|
+
}
|
|
5658
|
+
function deletePendingWorkItemEffectRequest(state, refs) {
|
|
5659
|
+
for (const requestRef of refs?.filter((value) => value.startsWith("work-item-effect-request:")) ?? []) {
|
|
5660
|
+
const requestId = requestRef.slice("work-item-effect-request:".length);
|
|
5661
|
+
state.pendingEffectRequests.delete(requestId);
|
|
5662
|
+
state.settledRequestIds.add(requestId);
|
|
5663
|
+
}
|
|
5664
|
+
}
|
|
5665
|
+
function workItemEffectRequestRefs(request) {
|
|
5666
|
+
return [
|
|
5667
|
+
ref2("work-item", request.workItemId),
|
|
5668
|
+
ref2("work-item-effect-request", request.requestId),
|
|
5669
|
+
...request.sourceRefs ?? []
|
|
5670
|
+
];
|
|
5671
|
+
}
|
|
5672
|
+
function workItemResultRefs(result) {
|
|
5673
|
+
return [
|
|
5674
|
+
ref2("effect-run", result.effectRunId),
|
|
5675
|
+
ref2("effect-run-result", result.resultId),
|
|
5676
|
+
...result.sourceRefs ?? [],
|
|
5677
|
+
...result.subjectRefs ?? []
|
|
5678
|
+
];
|
|
5679
|
+
}
|
|
5680
|
+
function workItemActionProposalRefs(evidence, result, policy) {
|
|
5681
|
+
return uniqueSourceRefs2([
|
|
5682
|
+
ref2("work-item", evidence.workItemId),
|
|
5683
|
+
ref2("effect-run", evidence.effectRunId),
|
|
5684
|
+
ref2("effect-run-result", evidence.effectRunResultId),
|
|
5685
|
+
ref2("work-item-evidence", evidence.evidenceId),
|
|
5686
|
+
...policy === void 0 ? [] : [ref2("work-item-effect-mapping-policy", policy.policyId)],
|
|
5687
|
+
...evidence.sourceRefs ?? [],
|
|
5688
|
+
...result.sourceRefs ?? [],
|
|
5689
|
+
...result.subjectRefs ?? []
|
|
5690
|
+
]);
|
|
5691
|
+
}
|
|
5692
|
+
function workItemAdmissionProposalRefs(proposal) {
|
|
5693
|
+
return uniqueSourceRefs2([
|
|
5694
|
+
ref2("work-item", proposal.workItemId),
|
|
5695
|
+
ref2("work-item-domain-action-proposal", proposal.proposalId),
|
|
5696
|
+
ref2("effect-run", proposal.effectRunId),
|
|
5697
|
+
ref2("effect-run-result", proposal.effectRunResultId),
|
|
5698
|
+
ref2("work-item-evidence", proposal.evidenceId),
|
|
5699
|
+
ref2("work-item-effect-mapping-policy", proposal.policyId),
|
|
5700
|
+
...proposal.sourceRefs ?? []
|
|
5701
|
+
]);
|
|
5702
|
+
}
|
|
5703
|
+
function workItemAdmissionDecisionRefs(decision, proposal, policy) {
|
|
5704
|
+
return uniqueSourceRefs2([
|
|
5705
|
+
...proposal === void 0 ? [] : workItemAdmissionProposalRefs(proposal),
|
|
5706
|
+
ref2("work-item-domain-action-admission-decision", decision.decisionId),
|
|
5707
|
+
ref2("work-item-domain-action-admission", decision.admissionId),
|
|
5708
|
+
ref2("work-item-domain-action-proposal", decision.proposalId),
|
|
5709
|
+
...decision.policyId === void 0 ? [] : [ref2("work-item-domain-action-admission-policy", decision.policyId)],
|
|
5710
|
+
...policy === void 0 ? [] : [ref2("work-item-domain-action-admission-policy", policy.policyId)],
|
|
5711
|
+
...decision.targetProposalId === void 0 ? [] : [ref2("work-item-domain-action-proposal", decision.targetProposalId)],
|
|
5712
|
+
...decision.targetAdmissionId === void 0 ? [] : [ref2("work-item-domain-action-admission", decision.targetAdmissionId)],
|
|
5713
|
+
...decision.sourceRefs ?? []
|
|
5714
|
+
]);
|
|
5715
|
+
}
|
|
5716
|
+
function workItemEvidenceOnlyRefs(evidence) {
|
|
5717
|
+
return uniqueSourceRefs2([
|
|
5718
|
+
ref2("work-item", evidence.workItemId),
|
|
5719
|
+
ref2("effect-run", evidence.effectRunId),
|
|
5720
|
+
ref2("effect-run-result", evidence.effectRunResultId),
|
|
5721
|
+
ref2("work-item-evidence", evidence.evidenceId),
|
|
5722
|
+
...evidence.sourceRefs ?? []
|
|
5723
|
+
]);
|
|
5724
|
+
}
|
|
5725
|
+
function referencedWorkItemMappingPolicyIds(evidence) {
|
|
5726
|
+
const refs = uniqueSourceRefs2([...evidence.sourceRefs ?? []]);
|
|
5727
|
+
return refs.filter((sourceRef) => sourceRef.kind === "work-item-effect-mapping-policy").map((sourceRef) => sourceRef.id);
|
|
5728
|
+
}
|
|
5729
|
+
function effectKindFromMetadata(metadata) {
|
|
5730
|
+
const effectKind = metadata?.effectKind;
|
|
5731
|
+
return typeof effectKind === "string" ? effectKind : void 0;
|
|
5732
|
+
}
|
|
5733
|
+
function workItemActionProposalPayload(spec, evidence, result) {
|
|
5734
|
+
if (spec.payload !== void 0) return spec.payload;
|
|
5735
|
+
const payloadFrom = spec.payloadFrom;
|
|
5736
|
+
if (payloadFrom === void 0) return void 0;
|
|
5737
|
+
if (payloadFrom === "effect-run-result")
|
|
5738
|
+
return { kind: "effect-run-result-ref", resultId: result.resultId };
|
|
5739
|
+
if (payloadFrom === "output") return evidence.output;
|
|
5740
|
+
return { kind: "work-item-evidence-ref", evidenceId: evidence.evidenceId };
|
|
5741
|
+
}
|
|
5742
|
+
function resultReason(result) {
|
|
5743
|
+
if (result.status === "canceled" || result.status === "waived") return result.reason;
|
|
5744
|
+
return void 0;
|
|
5745
|
+
}
|
|
5746
|
+
function workItemIdForEffectRunResult(state, result) {
|
|
5747
|
+
for (const evidence of state.evidence.values()) {
|
|
5748
|
+
if (evidence.effectRunResultId === result.resultId && evidence.effectRunId === result.effectRunId)
|
|
5749
|
+
return evidence.workItemId;
|
|
5750
|
+
}
|
|
5751
|
+
return void 0;
|
|
5752
|
+
}
|
|
5753
|
+
function uniqueSourceRefs2(sourceRefs) {
|
|
5754
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5755
|
+
const unique = [];
|
|
5756
|
+
for (const sourceRef of sourceRefs) {
|
|
5757
|
+
const key = sourceRefKey(sourceRef);
|
|
5758
|
+
if (seen.has(key)) continue;
|
|
5759
|
+
seen.add(key);
|
|
5760
|
+
unique.push(sourceRef);
|
|
5761
|
+
}
|
|
5762
|
+
return unique;
|
|
5763
|
+
}
|
|
5764
|
+
function sourceRefKey(sourceRef) {
|
|
5765
|
+
return `${sourceRef.kind}:${sourceRef.id}:${JSON.stringify(sourceRef.metadata ?? {})}`;
|
|
5766
|
+
}
|
|
5767
|
+
function distinctWorkItemRefs(sourceRefs) {
|
|
5768
|
+
const refs = /* @__PURE__ */ new Map();
|
|
5769
|
+
for (const sourceRef of sourceRefs ?? []) {
|
|
5770
|
+
if (sourceRef.kind === "work-item") refs.set(sourceRef.id, sourceRef);
|
|
5771
|
+
}
|
|
5772
|
+
return Array.from(refs.values());
|
|
5773
|
+
}
|
|
5774
|
+
function singleWorkItemRef(sourceRefs) {
|
|
5775
|
+
const matches = distinctWorkItemRefs(sourceRefs);
|
|
5776
|
+
return matches.length === 1 ? matches[0] : void 0;
|
|
5777
|
+
}
|
|
5778
|
+
function projectRuntimeFact2(graph, runtime, name, factory, pick) {
|
|
5779
|
+
return graph.node(
|
|
5780
|
+
[runtime],
|
|
5781
|
+
(ctx) => {
|
|
5782
|
+
for (const fact of depBatch(ctx, 0) ?? []) {
|
|
5783
|
+
const typed = fact;
|
|
5784
|
+
const value = pick(typed);
|
|
5785
|
+
if (value !== void 0) ctx.down([["DATA", value]]);
|
|
5786
|
+
}
|
|
5787
|
+
},
|
|
5788
|
+
{ name, factory }
|
|
5789
|
+
);
|
|
5790
|
+
}
|
|
5791
|
+
function forEachPolicyDepBatch(ctx, start, count, fn) {
|
|
5792
|
+
for (let i = 0; i < count; i += 1) {
|
|
5793
|
+
for (const value of depBatch(ctx, start + i) ?? []) fn(value);
|
|
5794
|
+
}
|
|
5795
|
+
}
|
|
5796
|
+
function dataIssue2(code, message, opts = {}) {
|
|
5797
|
+
return {
|
|
5798
|
+
kind: "issue",
|
|
5799
|
+
code,
|
|
5800
|
+
message,
|
|
5801
|
+
severity: opts.severity ?? "error",
|
|
5802
|
+
subjectId: opts.subjectId,
|
|
5803
|
+
refs: opts.refs?.map((r) => `${r.kind}:${r.id}`),
|
|
5804
|
+
details: opts.details
|
|
5805
|
+
};
|
|
5806
|
+
}
|
|
5807
|
+
function ref2(kind, id) {
|
|
5808
|
+
return { kind, id };
|
|
5809
|
+
}
|
|
5810
|
+
|
|
2556
5811
|
// src/orchestration/index.ts
|
|
2557
5812
|
var processCommandSources = /* @__PURE__ */ new WeakMap();
|
|
2558
5813
|
function retryStatusBundle(graph, events, opts = {}) {
|
|
@@ -3525,17 +6780,36 @@ function errorMessage(error) {
|
|
|
3525
6780
|
}
|
|
3526
6781
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3527
6782
|
0 && (module.exports = {
|
|
6783
|
+
admitAgentRequestProposal,
|
|
6784
|
+
agentRequestLedgerViews,
|
|
6785
|
+
agentRequestProposalFromDecision,
|
|
3528
6786
|
backoffDelayMs,
|
|
3529
6787
|
breakerBundle,
|
|
3530
6788
|
constantBackoff,
|
|
6789
|
+
effectRun,
|
|
6790
|
+
effectRunCompletionProjector,
|
|
6791
|
+
executorOutcomeViewProjector,
|
|
6792
|
+
fakeExecutorBlocked,
|
|
6793
|
+
fakeExecutorCanceled,
|
|
6794
|
+
fakeExecutorFailure,
|
|
6795
|
+
fakeExecutorResult,
|
|
6796
|
+
fakeExecutorTimeout,
|
|
6797
|
+
issueAgentRequest,
|
|
6798
|
+
localBuiltinToolProviderCatalog,
|
|
3531
6799
|
nextRetryDelayMs,
|
|
3532
6800
|
noBackoff,
|
|
3533
6801
|
processBundle,
|
|
3534
6802
|
processEffectRunner,
|
|
3535
6803
|
rateLimitBundle,
|
|
6804
|
+
requestSatisfactionProjector,
|
|
3536
6805
|
retryPolicy,
|
|
3537
6806
|
retryStatusBundle,
|
|
3538
6807
|
shouldRetry,
|
|
3539
|
-
|
|
6808
|
+
structuredAgentDecisionInterpreter,
|
|
6809
|
+
timeoutBundle,
|
|
6810
|
+
workItemDomainActionAdmissionProjector,
|
|
6811
|
+
workItemDomainActionProposalProjector,
|
|
6812
|
+
workItemEffectResultMapper,
|
|
6813
|
+
workItemEffectRunProjector
|
|
3540
6814
|
});
|
|
3541
6815
|
//# sourceMappingURL=index.cjs.map
|