@codemation/core 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 +30 -0
- package/dist/EngineExecutionLimitsPolicy-8MEFIYx1.d.cts +160 -0
- package/dist/EngineExecutionLimitsPolicy-BWAXW9D6.d.cts +160 -0
- package/dist/EngineExecutionLimitsPolicy-Bp8PS1Ss.d.cts +159 -0
- package/dist/EngineExecutionLimitsPolicy-CLxcN-D2.d.ts +159 -0
- package/dist/EngineExecutionLimitsPolicy-DZXuix51.d.ts +160 -0
- package/dist/EngineExecutionLimitsPolicy-Gfz6ngFd.d.ts +160 -0
- package/dist/EngineFactory-CBnntY3J.cjs +3152 -0
- package/dist/EngineFactory-CBnntY3J.cjs.map +1 -0
- package/dist/EngineFactory-Cwn3R2YA.js +3087 -0
- package/dist/EngineFactory-Cwn3R2YA.js.map +1 -0
- package/dist/EngineFactory-DWCnNocp.js +3063 -0
- package/dist/EngineFactory-DWCnNocp.js.map +1 -0
- package/dist/EngineFactory-DhPFou4p.cjs +3188 -0
- package/dist/EngineFactory-DhPFou4p.cjs.map +1 -0
- package/dist/EngineFactory-l_9xmBtv.cjs +3190 -0
- package/dist/EngineFactory-l_9xmBtv.cjs.map +1 -0
- package/dist/EngineFactory-w-aOWuqh.js +3089 -0
- package/dist/EngineFactory-w-aOWuqh.js.map +1 -0
- package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js +18 -0
- package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js.map +1 -0
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs +151 -0
- package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs.map +1 -0
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js +139 -0
- package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js.map +1 -0
- package/dist/InMemoryLiveWorkflowRepository-CULNqv96.d.ts +1300 -0
- package/dist/InMemoryLiveWorkflowRepository-D6eiiXxF.d.cts +1168 -0
- package/dist/InMemoryLiveWorkflowRepository-D7l8cjdZ.d.cts +1130 -0
- package/dist/InMemoryLiveWorkflowRepository-DL7LmC9S.d.ts +1340 -0
- package/dist/InMemoryLiveWorkflowRepository-jnv-OnOP.d.ts +1300 -0
- package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs +24 -0
- package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs.map +1 -0
- package/dist/InMemoryLiveWorkflowRepository-xr7b4kvi.d.ts +1338 -0
- package/dist/InMemoryWorkflowCatalog-BIdFpwbK.d.ts +1205 -0
- package/dist/InMemoryWorkflowCatalog-BW00_3N3.d.cts +12 -0
- package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs +24 -0
- package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs.map +1 -0
- package/dist/InMemoryWorkflowCatalog-BrG0ApMO.d.cts +1115 -0
- package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js +139 -0
- package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js.map +1 -0
- package/dist/InMemoryWorkflowCatalog-C-EJlJ7y.d.cts +1120 -0
- package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs +24 -0
- package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs.map +1 -0
- package/dist/InMemoryWorkflowCatalog-CZ0kZpOv.d.ts +1289 -0
- package/dist/InMemoryWorkflowCatalog-C_ACeLyW.d.cts +1119 -0
- package/dist/InMemoryWorkflowCatalog-CiHWIu5E.d.cts +12 -0
- package/dist/InMemoryWorkflowCatalog-CkH7gkya.js +18 -0
- package/dist/InMemoryWorkflowCatalog-CkH7gkya.js.map +1 -0
- package/dist/InMemoryWorkflowCatalog-CnpZVJM9.d.ts +1205 -0
- package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js +18 -0
- package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js.map +1 -0
- package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs +151 -0
- package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs.map +1 -0
- package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js +18 -0
- package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js.map +1 -0
- package/dist/InMemoryWorkflowCatalog-D5nCp2yZ.d.ts +1267 -0
- package/dist/InMemoryWorkflowCatalog-DIq0bjqN.d.ts +12 -0
- package/dist/InMemoryWorkflowCatalog-DLgaEaw_.d.ts +1288 -0
- package/dist/InMemoryWorkflowCatalog-DNBFdK-x.d.cts +1120 -0
- package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs +24 -0
- package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs.map +1 -0
- package/dist/InMemoryWorkflowCatalog-DS4-eX6i.d.cts +1118 -0
- package/dist/InMemoryWorkflowCatalog-DdVfy8MY.d.ts +12 -0
- package/dist/InMemoryWorkflowCatalog-DeVZu3g8.d.ts +12 -0
- package/dist/InMemoryWorkflowCatalog-GxkQjvt5.d.ts +1200 -0
- package/dist/InMemoryWorkflowCatalog-qaVRn1Lc.d.cts +1115 -0
- package/dist/InMemoryWorkflowCatalog-z1aIT4TC.d.cts +12 -0
- package/dist/InMemoryWorkflowRegistry-BBuOovLL.d.ts +1007 -0
- package/dist/InMemoryWorkflowRegistry-BIFnSl3k.d.ts +1201 -0
- package/dist/InMemoryWorkflowRegistry-BnGilthz.d.ts +1137 -0
- package/dist/InMemoryWorkflowRegistry-CEp5I8No.d.ts +1146 -0
- package/dist/InMemoryWorkflowRegistry-CHyMB9jW.d.cts +976 -0
- package/dist/InMemoryWorkflowRegistry-CUN7K86m.d.cts +1061 -0
- package/dist/InMemoryWorkflowRegistry-CVfHyELh.d.cts +971 -0
- package/dist/InMemoryWorkflowRegistry-CXXJrwAr.d.cts +1052 -0
- package/dist/InMemoryWorkflowRegistry-DDGfPTJy.d.ts +1013 -0
- package/dist/InMemoryWorkflowRegistry-DnYSOoT5.d.ts +1120 -0
- package/dist/InMemoryWorkflowRegistry-Dp5GiFF2.d.cts +1035 -0
- package/dist/InMemoryWorkflowRegistry-DypDBeOw.d.cts +1116 -0
- package/dist/InMemoryWorkflowRegistry-SzwJCAxT.d.ts +1012 -0
- package/dist/InMemoryWorkflowRegistry-jupvqyGc.d.cts +977 -0
- package/dist/InMemoryWorkflowRegistry-rAdKVWYT.d.ts +1117 -0
- package/dist/InProcessRetryRunner-BBNPkXjy.d.cts +292 -0
- package/dist/PersistedWorkflowSnapshotFactory-7RkOL3Kg.d.ts +14 -0
- package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs +141 -0
- package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js +118 -0
- package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js +123 -0
- package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js +101 -0
- package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs +131 -0
- package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js +103 -0
- package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js +119 -0
- package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs +131 -0
- package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs +131 -0
- package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js +103 -0
- package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs +131 -0
- package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs +107 -0
- package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js +119 -0
- package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs +130 -0
- package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js +123 -0
- package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js +119 -0
- package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js +102 -0
- package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs +141 -0
- package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js +119 -0
- package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs +109 -0
- package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs +109 -0
- package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs.map +1 -0
- package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs +108 -0
- package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs.map +1 -0
- package/dist/RunIntentService-1EE6N8ZL.cjs +963 -0
- package/dist/RunIntentService-1EE6N8ZL.cjs.map +1 -0
- package/dist/RunIntentService-2ivFmNQh.cjs +3462 -0
- package/dist/RunIntentService-2ivFmNQh.cjs.map +1 -0
- package/dist/RunIntentService-B0sUL5q-.js +761 -0
- package/dist/RunIntentService-B0sUL5q-.js.map +1 -0
- package/dist/RunIntentService-BFVbsOcg.js +3131 -0
- package/dist/RunIntentService-BFVbsOcg.js.map +1 -0
- package/dist/RunIntentService-BsBOwpVN.cjs +1051 -0
- package/dist/RunIntentService-BsBOwpVN.cjs.map +1 -0
- package/dist/RunIntentService-CSk3ETyn.js +858 -0
- package/dist/RunIntentService-CSk3ETyn.js.map +1 -0
- package/dist/RunIntentService-Ckn3u3tA.d.cts +326 -0
- package/dist/RunIntentService-DEo6GTTo.d.cts +289 -0
- package/dist/RunIntentService-DKrGtL0B.js +782 -0
- package/dist/RunIntentService-DKrGtL0B.js.map +1 -0
- package/dist/RunIntentService-DNOJc1R7.cjs +942 -0
- package/dist/RunIntentService-DNOJc1R7.cjs.map +1 -0
- package/dist/RunIntentService-Dq3pV53j.d.cts +289 -0
- package/dist/RunIntentService-NKobsfMQ.d.cts +274 -0
- package/dist/WorkflowSnapshotCodec-C3fuuS_R.d.cts +22 -0
- package/dist/WorkflowSnapshotCodec-CUudUo6f.js +123 -0
- package/dist/WorkflowSnapshotCodec-CUudUo6f.js.map +1 -0
- package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs +129 -0
- package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs.map +1 -0
- package/dist/WorkflowSnapshotCodec-DLiXQNvV.d.cts +22 -0
- package/dist/WorkflowSnapshotCodec-DNtdrZ7l.d.cts +22 -0
- package/dist/WorkflowSnapshotCodec-DTdWkoW_.d.cts +22 -0
- package/dist/bootstrap/index.cjs +1028 -0
- package/dist/bootstrap/index.cjs.map +1 -0
- package/dist/bootstrap/index.d.cts +311 -0
- package/dist/bootstrap/index.d.ts +83 -0
- package/dist/bootstrap/index.js +994 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/credentialTypes-B5h3dI7r.d.cts +1107 -0
- package/dist/credentialTypes-B9okPCVo.d.cts +963 -0
- package/dist/credentialTypes-BFL70rgZ.d.cts +964 -0
- package/dist/credentialTypes-BGkh1O07.d.ts +1010 -0
- package/dist/credentialTypes-BNLi4Q7u.d.ts +1030 -0
- package/dist/credentialTypes-CeSoZGj3.d.cts +994 -0
- package/dist/credentialTypes-CpHc32Ig.d.cts +984 -0
- package/dist/credentialTypes-D0m7MQQl.d.cts +1107 -0
- package/dist/credentialTypes-D4nL2sUd.d.ts +1000 -0
- package/dist/credentialTypes-DBYK2Qbu.d.ts +999 -0
- package/dist/credentialTypes-DMJVy0r1.d.ts +1000 -0
- package/dist/credentialTypes-DhUAjYQp.d.ts +1020 -0
- package/dist/credentialTypes-gGITj5KL.d.cts +964 -0
- package/dist/credentialTypes-r3KVBJBE.d.cts +974 -0
- package/dist/diTokens-ClO27tjK.cjs +34 -0
- package/dist/diTokens-ClO27tjK.cjs.map +1 -0
- package/dist/diTokens-CoHBkwG6.js +28 -0
- package/dist/diTokens-CoHBkwG6.js.map +1 -0
- package/dist/index-6Doxmfnd.d.ts +857 -0
- package/dist/index-9g6Pfe9Z.d.ts +689 -0
- package/dist/index-AZ72Ej-K.d.ts +920 -0
- package/dist/index-BEk9V-q-.d.ts +667 -0
- package/dist/index-Bjt7_7oS.d.ts +1192 -0
- package/dist/index-CFGxsYXy.d.ts +708 -0
- package/dist/index-C_u8xFgn.d.ts +690 -0
- package/dist/index-CpbfsvOJ.d.ts +1192 -0
- package/dist/index-CsReNJN_.d.ts +859 -0
- package/dist/index-D5iNnXaW.d.ts +667 -0
- package/dist/index-DD_Eft1q.d.ts +708 -0
- package/dist/index-DiSYUe0G.d.ts +1192 -0
- package/dist/index-gIcH60sp.d.ts +674 -0
- package/dist/index.cjs +520 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +345 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +412 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime-BIvd-1JA.cjs +4112 -0
- package/dist/runtime-BIvd-1JA.cjs.map +1 -0
- package/dist/runtime-D3eWKSQK.cjs +3986 -0
- package/dist/runtime-D3eWKSQK.cjs.map +1 -0
- package/dist/runtime-Dvp4xAjg.js +3799 -0
- package/dist/runtime-Dvp4xAjg.js.map +1 -0
- package/dist/runtime-vc76SSAa.js +3685 -0
- package/dist/runtime-vc76SSAa.js.map +1 -0
- package/dist/runtimeTypes-BK0b8SaG.d.cts +884 -0
- package/dist/runtimeTypes-CoYZkYQq.d.cts +851 -0
- package/dist/runtimeTypes-D-Pm0Uas.d.cts +849 -0
- package/dist/testing.cjs +18 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +19 -0
- package/dist/testing.d.ts +18 -0
- package/dist/testing.js +16 -0
- package/dist/testing.js.map +1 -0
- package/dist/types-Cb5UK7Y6.d.ts +857 -0
- package/package.json +66 -0
- package/src/ai/AiHost.ts +115 -0
- package/src/binaries/DefaultExecutionBinaryServiceFactory.ts +37 -0
- package/src/binaries/DefaultNodeBinaryAttachmentServiceFactory.ts +120 -0
- package/src/binaries/UnavailableBinaryStorage.ts +19 -0
- package/src/binaries/index.ts +2 -0
- package/src/bootstrap/index.ts +46 -0
- package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +180 -0
- package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +43 -0
- package/src/bootstrap/runtime/index.ts +6 -0
- package/src/browser.ts +8 -0
- package/src/contracts/Clock.ts +10 -0
- package/src/contracts/ExpRetryPolicy.ts +23 -0
- package/src/contracts/NoRetryPolicy.ts +5 -0
- package/src/contracts/RetryPolicy.ts +23 -0
- package/src/contracts/credentialTypes.ts +194 -0
- package/src/contracts/index.ts +6 -0
- package/src/contracts/retryPolicySpec.types.ts +30 -0
- package/src/contracts/runFinishedAtFactory.ts +19 -0
- package/src/contracts/runTypes.ts +314 -0
- package/src/contracts/runtimeTypes.ts +373 -0
- package/src/contracts/webhookTypes.ts +49 -0
- package/src/contracts/workflowActivationPolicy.ts +16 -0
- package/src/contracts/workflowTypes.ts +280 -0
- package/src/di/CoreTokens.ts +60 -0
- package/src/di/index.ts +24 -0
- package/src/events/EventPublishingWorkflowExecutionRepository.ts +67 -0
- package/src/events/InMemoryRunEventBusRegistry.ts +37 -0
- package/src/events/InMemoryRunEventSubscription.ts +9 -0
- package/src/events/NodeEventPublisher.ts +22 -0
- package/src/events/index.ts +4 -0
- package/src/events/runEvents.ts +54 -0
- package/src/execution/ActivationEnqueueService.ts +125 -0
- package/src/execution/CredentialResolverFactory.ts +39 -0
- package/src/execution/DefaultAsyncSleeper.ts +9 -0
- package/src/execution/DefaultExecutionContextFactory.ts +48 -0
- package/src/execution/InProcessRetryRunner.ts +115 -0
- package/src/execution/InProcessRetryRunnerFactory.ts +8 -0
- package/src/execution/NodeActivationRequestComposer.ts +113 -0
- package/src/execution/NodeExecutionSnapshotFactory.ts +152 -0
- package/src/execution/NodeExecutor.ts +43 -0
- package/src/execution/NodeExecutorFactory.ts +10 -0
- package/src/execution/NodeInputsByPortFactory.ts +14 -0
- package/src/execution/NodeInstanceFactory.ts +32 -0
- package/src/execution/NodeInstanceFactoryFactory.ts +9 -0
- package/src/execution/NodeRunStateWriter.ts +185 -0
- package/src/execution/NodeRunStateWriterFactory.ts +29 -0
- package/src/execution/PersistedRunStateTerminalBuilder.ts +25 -0
- package/src/execution/RunStateSemantics.ts +158 -0
- package/src/execution/WorkflowRunExecutionContextFactory.ts +45 -0
- package/src/execution/asyncSleeper.types.ts +3 -0
- package/src/execution/index.ts +26 -0
- package/src/index.ts +18 -0
- package/src/orchestration/Engine.ts +229 -0
- package/src/orchestration/EngineWaiters.ts +37 -0
- package/src/orchestration/RunContinuationService.ts +810 -0
- package/src/orchestration/RunStartService.ts +449 -0
- package/src/orchestration/TriggerRuntimeService.ts +260 -0
- package/src/orchestration/index.ts +5 -0
- package/src/planning/CurrentStateFrontierPlanner.ts +400 -0
- package/src/planning/EngineWorkflowPlanningFactory.ts +63 -0
- package/src/planning/RunQueuePlanner.ts +302 -0
- package/src/planning/WorkflowTopologyPlanner.ts +77 -0
- package/src/planning/index.ts +4 -0
- package/src/policies/WorkflowPolicyErrorServices.ts +38 -0
- package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +66 -0
- package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +14 -0
- package/src/policies/index.ts +10 -0
- package/src/policies/storage/RunPolicySnapshotFactory.ts +23 -0
- package/src/policies/storage/RunTerminalPersistenceCoordinator.ts +29 -0
- package/src/policies/storage/WorkflowStoragePolicyEvaluator.ts +39 -0
- package/src/runStorage/BinaryBodyBufferReader.ts +57 -0
- package/src/runStorage/BinaryBodyReadableStreamFactory.ts +21 -0
- package/src/runStorage/InMemoryBinaryStorageRegistry.ts +53 -0
- package/src/runStorage/InMemoryRunData.ts +33 -0
- package/src/runStorage/InMemoryRunDataFactory.ts +8 -0
- package/src/runStorage/InMemoryWorkflowExecutionRepository.ts +95 -0
- package/src/runStorage/RunSummaryMapper.ts +17 -0
- package/src/runStorage/index.ts +7 -0
- package/src/runtime/EngineFactory.ts +151 -0
- package/src/runtime/EngineWorkflowRunnerService.ts +39 -0
- package/src/runtime/EngineWorkflowRunnerServiceFactory.ts +11 -0
- package/src/runtime/InMemoryLiveWorkflowRepository.ts +20 -0
- package/src/runtime/RunIntentService.ts +175 -0
- package/src/runtime/RunIntentServiceFactory.ts +11 -0
- package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +144 -0
- package/src/runtime/WorkflowRepositoryWebhookTriggerMatcherFactory.ts +13 -0
- package/src/runtime/index.ts +9 -0
- package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +25 -0
- package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +46 -0
- package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +14 -0
- package/src/runtime-types/StackTraceCallSitePathResolver.ts +25 -0
- package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +33 -0
- package/src/runtime-types/runtimeTypeDecorators.types.ts +46 -0
- package/src/scheduler/ConfigDrivenOffloadPolicy.ts +28 -0
- package/src/scheduler/DefaultDrivingScheduler.ts +100 -0
- package/src/scheduler/HintOnlyOffloadPolicy.ts +9 -0
- package/src/scheduler/InlineDrivingScheduler.ts +145 -0
- package/src/scheduler/InlineDrivingSchedulerFactory.ts +9 -0
- package/src/scheduler/LocalOnlyScheduler.ts +7 -0
- package/src/serialization/ItemsInputNormalizer.ts +36 -0
- package/src/testing/RejectingCredentialSessionService.ts +15 -0
- package/src/testing.ts +6 -0
- package/src/types/index.ts +12 -0
- package/src/workflow/definition/ConnectionInvocationIdFactory.ts +17 -0
- package/src/workflow/definition/ConnectionNodeIdFactory.ts +42 -0
- package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +71 -0
- package/src/workflow/definition/WorkflowExecutableNodeClassifierFactory.ts +9 -0
- package/src/workflow/dsl/ChainCursorResolver.ts +103 -0
- package/src/workflow/dsl/WhenBuilder.ts +57 -0
- package/src/workflow/dsl/WorkflowBuilder.ts +55 -0
- package/src/workflow/dsl/workflowBuilderTypes.ts +63 -0
- package/src/workflow/graph/DefaultWorkflowGraphFactory.ts +8 -0
- package/src/workflow/graph/ExecutableGraph.ts +24 -0
- package/src/workflow/index.ts +11 -0
- package/src/workflowSnapshots/MissingRuntimeExecutionMarker.ts +5 -0
- package/src/workflowSnapshots/MissingRuntimeFallbacksFactory.ts +27 -0
- package/src/workflowSnapshots/MissingRuntimeNode.ts +12 -0
- package/src/workflowSnapshots/MissingRuntimeNodeConfig.ts +14 -0
- package/src/workflowSnapshots/MissingRuntimeNodeToken.ts +1 -0
- package/src/workflowSnapshots/MissingRuntimeTrigger.ts +16 -0
- package/src/workflowSnapshots/MissingRuntimeTriggerConfig.ts +14 -0
- package/src/workflowSnapshots/MissingRuntimeTriggerToken.ts +1 -0
- package/src/workflowSnapshots/PersistedRuntimeTypeIdFactory.ts +19 -0
- package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +89 -0
- package/src/workflowSnapshots/PersistedWorkflowTokenRegistryFactory.ts +2 -0
- package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +177 -0
- package/src/workflowSnapshots/WorkflowSnapshotResolver.ts +102 -0
- package/src/workflowSnapshots/index.ts +12 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +10 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NodeConfigBase, NodeId, NodeOffloadPolicy, NodeSchedulerDecision, WorkflowId } from "../types";
|
|
2
|
+
|
|
3
|
+
export class HintOnlyOffloadPolicy implements NodeOffloadPolicy {
|
|
4
|
+
decide(args: { workflowId: WorkflowId; nodeId: NodeId; config: NodeConfigBase }): NodeSchedulerDecision {
|
|
5
|
+
const hint = args.config.execution?.hint;
|
|
6
|
+
if (hint === "worker") return { mode: "worker", queue: args.config.execution?.queue };
|
|
7
|
+
return { mode: "local" };
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NodeActivationContinuation,
|
|
3
|
+
NodeActivationReceipt,
|
|
4
|
+
NodeActivationRequest,
|
|
5
|
+
NodeActivationScheduler,
|
|
6
|
+
RunId,
|
|
7
|
+
} from "../types";
|
|
8
|
+
import { NodeExecutor } from "../execution/NodeExecutor";
|
|
9
|
+
|
|
10
|
+
export class InlineDrivingScheduler implements NodeActivationScheduler {
|
|
11
|
+
private continuation: NodeActivationContinuation | undefined;
|
|
12
|
+
private readonly drainingRuns = new Set<RunId>();
|
|
13
|
+
private readonly queuesByRunId = new Map<
|
|
14
|
+
RunId,
|
|
15
|
+
Array<Readonly<{ request: NodeActivationRequest; receipt: NodeActivationReceipt }>>
|
|
16
|
+
>();
|
|
17
|
+
private readonly scheduledRuns = new Set<RunId>();
|
|
18
|
+
private seq = 0;
|
|
19
|
+
|
|
20
|
+
constructor(private readonly nodeExecutor: NodeExecutor) {}
|
|
21
|
+
|
|
22
|
+
setContinuation(continuation: NodeActivationContinuation): void {
|
|
23
|
+
this.continuation = continuation;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async enqueue(request: NodeActivationRequest): Promise<NodeActivationReceipt> {
|
|
27
|
+
const receipt: NodeActivationReceipt = { receiptId: `inline_${++this.seq}`, mode: "local" };
|
|
28
|
+
const q = this.queuesByRunId.get(request.runId) ?? [];
|
|
29
|
+
q.push({ request, receipt });
|
|
30
|
+
this.queuesByRunId.set(request.runId, q);
|
|
31
|
+
|
|
32
|
+
return receipt;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
notifyPendingStatePersisted(runId: RunId): void {
|
|
36
|
+
if ((this.queuesByRunId.get(runId)?.length ?? 0) === 0) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.scheduleDrain(runId);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private async drainRun(runId: RunId): Promise<void> {
|
|
43
|
+
if (this.drainingRuns.has(runId)) return;
|
|
44
|
+
this.drainingRuns.add(runId);
|
|
45
|
+
this.scheduledRuns.delete(runId);
|
|
46
|
+
try {
|
|
47
|
+
const q = this.queuesByRunId.get(runId) ?? [];
|
|
48
|
+
while (q.length > 0) {
|
|
49
|
+
const next = q.shift()!;
|
|
50
|
+
const { request } = next;
|
|
51
|
+
|
|
52
|
+
const cont = this.continuation;
|
|
53
|
+
if (!cont) throw new Error("InlineDrivingScheduler is missing a continuation (setContinuation was not called)");
|
|
54
|
+
|
|
55
|
+
await cont.markNodeRunning({
|
|
56
|
+
runId: request.runId,
|
|
57
|
+
activationId: request.activationId,
|
|
58
|
+
nodeId: request.nodeId,
|
|
59
|
+
inputsByPort: request.kind === "multi" ? request.inputsByPort : { in: request.input },
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
let outputs;
|
|
63
|
+
try {
|
|
64
|
+
outputs = await this.nodeExecutor.execute(request);
|
|
65
|
+
} catch (e) {
|
|
66
|
+
await this.resumeAfterExecutionError(cont, request, this.asError(e));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
await this.resumeAfterExecutionResult(cont, request, outputs ?? {});
|
|
71
|
+
}
|
|
72
|
+
} finally {
|
|
73
|
+
if ((this.queuesByRunId.get(runId)?.length ?? 0) === 0) this.queuesByRunId.delete(runId);
|
|
74
|
+
this.drainingRuns.delete(runId);
|
|
75
|
+
if ((this.queuesByRunId.get(runId)?.length ?? 0) > 0) {
|
|
76
|
+
this.scheduleDrain(runId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private scheduleDrain(runId: RunId): void {
|
|
82
|
+
if (this.drainingRuns.has(runId) || this.scheduledRuns.has(runId)) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.scheduledRuns.add(runId);
|
|
86
|
+
setTimeout(() => {
|
|
87
|
+
this.scheduledRuns.delete(runId);
|
|
88
|
+
void this.drainRun(runId);
|
|
89
|
+
}, 0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private async resumeAfterExecutionResult(
|
|
93
|
+
continuation: NodeActivationContinuation,
|
|
94
|
+
request: NodeActivationRequest,
|
|
95
|
+
outputs: unknown,
|
|
96
|
+
): Promise<void> {
|
|
97
|
+
try {
|
|
98
|
+
await continuation.resumeFromNodeResult({
|
|
99
|
+
runId: request.runId,
|
|
100
|
+
activationId: request.activationId,
|
|
101
|
+
nodeId: request.nodeId,
|
|
102
|
+
outputs: outputs as any,
|
|
103
|
+
});
|
|
104
|
+
} catch (e) {
|
|
105
|
+
this.rethrowUnlessIgnorableContinuationError(e);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private async resumeAfterExecutionError(
|
|
110
|
+
continuation: NodeActivationContinuation,
|
|
111
|
+
request: NodeActivationRequest,
|
|
112
|
+
error: Error,
|
|
113
|
+
): Promise<void> {
|
|
114
|
+
try {
|
|
115
|
+
await continuation.resumeFromNodeError({
|
|
116
|
+
runId: request.runId,
|
|
117
|
+
activationId: request.activationId,
|
|
118
|
+
nodeId: request.nodeId,
|
|
119
|
+
error,
|
|
120
|
+
});
|
|
121
|
+
} catch (e) {
|
|
122
|
+
this.rethrowUnlessIgnorableContinuationError(e);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private asError(e: unknown): Error {
|
|
127
|
+
return e instanceof Error ? e : new Error(String(e));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private rethrowUnlessIgnorableContinuationError(e: unknown): void {
|
|
131
|
+
if (this.isIgnorableContinuationError(e)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
throw this.asError(e);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private isIgnorableContinuationError(e: unknown): boolean {
|
|
138
|
+
const message = this.asError(e).message;
|
|
139
|
+
return (
|
|
140
|
+
message.includes(" is not pending") ||
|
|
141
|
+
message.includes("activationId mismatch") ||
|
|
142
|
+
message.includes("nodeId mismatch")
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NodeExecutor } from "../execution/NodeExecutor";
|
|
2
|
+
|
|
3
|
+
import { InlineDrivingScheduler } from "./InlineDrivingScheduler";
|
|
4
|
+
|
|
5
|
+
export class InlineDrivingSchedulerFactory {
|
|
6
|
+
create(nodeExecutor: NodeExecutor): InlineDrivingScheduler {
|
|
7
|
+
return new InlineDrivingScheduler(nodeExecutor);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { NodeExecutionRequest, NodeExecutionScheduler } from "../types";
|
|
2
|
+
|
|
3
|
+
export class LocalOnlyScheduler implements NodeExecutionScheduler {
|
|
4
|
+
async enqueue(_request: NodeExecutionRequest): Promise<{ receiptId: string }> {
|
|
5
|
+
throw new Error("No worker scheduler configured");
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Item, Items } from "../contracts/workflowTypes";
|
|
2
|
+
import { injectable } from "../di";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Normalizes external inputs into the engine's canonical `Items` shape.
|
|
6
|
+
* Used at host and builder boundaries where callers may provide either a raw value,
|
|
7
|
+
* a single item-like object, or an array of item-like values.
|
|
8
|
+
*/
|
|
9
|
+
@injectable()
|
|
10
|
+
export class ItemsInputNormalizer {
|
|
11
|
+
normalize(raw: unknown): Items {
|
|
12
|
+
if (raw === undefined || raw === null) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
if (Array.isArray(raw)) {
|
|
16
|
+
return raw.map((value) => this.normalizeItem(value));
|
|
17
|
+
}
|
|
18
|
+
return [this.normalizeItem(raw)];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private normalizeItem(raw: unknown): Item {
|
|
22
|
+
if (!this.isItem(raw)) {
|
|
23
|
+
return { json: raw };
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
json: raw.json,
|
|
27
|
+
...(raw.binary === undefined ? {} : { binary: raw.binary }),
|
|
28
|
+
...(raw.meta === undefined ? {} : { meta: raw.meta }),
|
|
29
|
+
...(raw.paired === undefined ? {} : { paired: raw.paired }),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private isItem(raw: unknown): raw is Item {
|
|
34
|
+
return typeof raw === "object" && raw !== null && Object.prototype.hasOwnProperty.call(raw, "json");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CredentialSessionService } from "../contracts/credentialTypes";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test harness default: rejects any credential lookup so missing bindings fail loudly.
|
|
5
|
+
* Prefer registering a real {@link CredentialSessionService} in integration scenarios.
|
|
6
|
+
*/
|
|
7
|
+
export class RejectingCredentialSessionService implements CredentialSessionService {
|
|
8
|
+
async getSession<TSession = unknown>(
|
|
9
|
+
args: Readonly<{ workflowId: string; nodeId: string; slotKey: string }>,
|
|
10
|
+
): Promise<TSession> {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Credential sessions are unavailable for workflow ${args.workflowId} node ${args.nodeId} slot "${args.slotKey}". Register a real CredentialSessionService implementation before executing workflows.`,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only adapters and helpers. Not part of the supported production public API.
|
|
3
|
+
*/
|
|
4
|
+
export { InMemoryLiveWorkflowRepository } from "./runtime/InMemoryLiveWorkflowRepository";
|
|
5
|
+
export { WorkflowSnapshotCodec as PersistedWorkflowSnapshotFactory } from "./workflowSnapshots/WorkflowSnapshotCodec";
|
|
6
|
+
export { RejectingCredentialSessionService } from "./testing/RejectingCredentialSessionService";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "../contracts/retryPolicySpec.types";
|
|
2
|
+
export * from "../contracts/NoRetryPolicy";
|
|
3
|
+
export * from "../contracts/RetryPolicy";
|
|
4
|
+
export * from "../contracts/ExpRetryPolicy";
|
|
5
|
+
export * from "../contracts/credentialTypes";
|
|
6
|
+
export * from "../contracts/runtimeTypes";
|
|
7
|
+
export * from "../contracts/runFinishedAtFactory";
|
|
8
|
+
export * from "../contracts/runTypes";
|
|
9
|
+
export * from "../contracts/webhookTypes";
|
|
10
|
+
export * from "../contracts/workflowTypes";
|
|
11
|
+
export * from "../contracts/workflowActivationPolicy";
|
|
12
|
+
export * from "../workflow";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import type { NodeId } from "../../types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).
|
|
7
|
+
*/
|
|
8
|
+
export class ConnectionInvocationIdFactory {
|
|
9
|
+
static create(): string {
|
|
10
|
+
return `cinv_${randomUUID()}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Deterministic id for tests when a stable sequence is needed. */
|
|
14
|
+
static createForTest(runId: string, connectionNodeId: NodeId, sequence: number): string {
|
|
15
|
+
return `cinv_${runId}_${connectionNodeId}_${sequence}`;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { NodeId } from "../../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).
|
|
5
|
+
* These are stable across loads.
|
|
6
|
+
*/
|
|
7
|
+
export class ConnectionNodeIdFactory {
|
|
8
|
+
static readonly connectionSegment = "__conn__" as const;
|
|
9
|
+
|
|
10
|
+
static languageModelConnectionNodeId(parentNodeId: NodeId): NodeId {
|
|
11
|
+
return `${parentNodeId}${this.connectionSegment}llm`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static toolConnectionNodeId(parentNodeId: NodeId, toolName: string): NodeId {
|
|
15
|
+
const normalized = this.normalizeToolName(toolName);
|
|
16
|
+
return `${parentNodeId}${this.connectionSegment}tool${this.connectionSegment}${normalized}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static isLanguageModelConnectionNodeId(nodeId: NodeId): boolean {
|
|
20
|
+
return nodeId.endsWith(`${this.connectionSegment}llm`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static isToolConnectionNodeId(nodeId: NodeId): boolean {
|
|
24
|
+
return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
|
|
28
|
+
static isConnectionOwnedDescendantOf(parentNodeId: NodeId, nodeId: NodeId): boolean {
|
|
29
|
+
return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Normalizes a tool display name to a stable id segment. */
|
|
33
|
+
static normalizeToolName(toolName: string): string {
|
|
34
|
+
return (
|
|
35
|
+
toolName
|
|
36
|
+
.trim()
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
39
|
+
.replace(/^_+|_+$/g, "") || "tool"
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { NodeDefinition, NodeId, WorkflowDefinition } from "../../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Derives which workflow nodes participate in the main execution graph vs connection-only children.
|
|
5
|
+
*/
|
|
6
|
+
export class WorkflowExecutableNodeClassifier {
|
|
7
|
+
private readonly connectionOwnedIds: ReadonlySet<NodeId>;
|
|
8
|
+
|
|
9
|
+
constructor(workflow: WorkflowDefinition) {
|
|
10
|
+
this.connectionOwnedIds = this.collectConnectionOwnedIds(workflow);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
isConnectionOwnedNodeId(nodeId: NodeId): boolean {
|
|
14
|
+
return this.connectionOwnedIds.has(nodeId);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
isExecutableNodeId(nodeId: NodeId): boolean {
|
|
18
|
+
return !this.connectionOwnedIds.has(nodeId);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
filterExecutableNodeDefinitions(nodes: ReadonlyArray<NodeDefinition>): ReadonlyArray<NodeDefinition> {
|
|
22
|
+
return nodes.filter((n) => this.isExecutableNodeId(n.id));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private collectConnectionOwnedIds(workflow: WorkflowDefinition): ReadonlySet<NodeId> {
|
|
26
|
+
const ids = new Set<NodeId>();
|
|
27
|
+
for (const connection of workflow.connections ?? []) {
|
|
28
|
+
for (const childId of connection.childNodeIds) {
|
|
29
|
+
ids.add(childId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return ids;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolves the default start node: first trigger, else first executable node with no incoming edges from executable nodes.
|
|
37
|
+
*/
|
|
38
|
+
findDefaultExecutableStartNodeId(workflow: WorkflowDefinition): NodeId {
|
|
39
|
+
const firstTrigger = workflow.nodes.find((n) => n.kind === "trigger" && this.isExecutableNodeId(n.id))?.id;
|
|
40
|
+
if (firstTrigger) return firstTrigger;
|
|
41
|
+
|
|
42
|
+
const incoming = new Map<NodeId, number>();
|
|
43
|
+
for (const n of workflow.nodes) {
|
|
44
|
+
if (this.isExecutableNodeId(n.id)) incoming.set(n.id, 0);
|
|
45
|
+
}
|
|
46
|
+
for (const e of workflow.edges) {
|
|
47
|
+
if (!this.isExecutableNodeId(e.from.nodeId) || !this.isExecutableNodeId(e.to.nodeId)) continue;
|
|
48
|
+
incoming.set(e.to.nodeId, (incoming.get(e.to.nodeId) ?? 0) + 1);
|
|
49
|
+
}
|
|
50
|
+
const start = workflow.nodes.find((n) => this.isExecutableNodeId(n.id) && (incoming.get(n.id) ?? 0) === 0)?.id;
|
|
51
|
+
return (
|
|
52
|
+
start ??
|
|
53
|
+
workflow.nodes.find((n) => this.isExecutableNodeId(n.id))?.id ??
|
|
54
|
+
(() => {
|
|
55
|
+
throw new Error(`Workflow ${workflow.id} has no executable nodes`);
|
|
56
|
+
})()
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
firstExecutableNodeIdInDefinitionOrder(workflow: WorkflowDefinition): NodeId | undefined {
|
|
61
|
+
return workflow.nodes.find((n) => this.isExecutableNodeId(n.id))?.id;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
lastExecutableNodeIdInDefinitionOrder(workflow: WorkflowDefinition): NodeId {
|
|
65
|
+
for (let i = workflow.nodes.length - 1; i >= 0; i--) {
|
|
66
|
+
const n = workflow.nodes[i]!;
|
|
67
|
+
if (this.isExecutableNodeId(n.id)) return n.id;
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Workflow ${workflow.id} has no executable nodes`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WorkflowDefinition } from "../../types";
|
|
2
|
+
|
|
3
|
+
import { WorkflowExecutableNodeClassifier } from "./WorkflowExecutableNodeClassifier";
|
|
4
|
+
|
|
5
|
+
export class WorkflowExecutableNodeClassifierFactory {
|
|
6
|
+
static create(workflow: WorkflowDefinition): WorkflowExecutableNodeClassifier {
|
|
7
|
+
return new WorkflowExecutableNodeClassifier(workflow);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NodeRef,
|
|
3
|
+
OutputPortKey,
|
|
4
|
+
RunnableNodeConfig,
|
|
5
|
+
RunnableNodeOutputJson,
|
|
6
|
+
WorkflowDefinition,
|
|
7
|
+
} from "../../types";
|
|
8
|
+
|
|
9
|
+
import { WorkflowBuilder } from "./WorkflowBuilder";
|
|
10
|
+
import { WhenBuilder } from "./WhenBuilder";
|
|
11
|
+
import type {
|
|
12
|
+
AnyRunnableNodeConfig,
|
|
13
|
+
BooleanWhenOverloads,
|
|
14
|
+
BranchOutputGuard,
|
|
15
|
+
BranchStepsArg,
|
|
16
|
+
StepSequenceOutput,
|
|
17
|
+
} from "./workflowBuilderTypes";
|
|
18
|
+
|
|
19
|
+
type ChainCursorWhenOverloads<TCurrentJson> = BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> & {
|
|
20
|
+
<
|
|
21
|
+
TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,
|
|
22
|
+
TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,
|
|
23
|
+
>(
|
|
24
|
+
branches: Readonly<{
|
|
25
|
+
true?: TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> ? BranchStepsArg<TCurrentJson, TTrueSteps> : never;
|
|
26
|
+
false?: TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig>
|
|
27
|
+
? BranchStepsArg<TCurrentJson, TFalseSteps>
|
|
28
|
+
: never;
|
|
29
|
+
}> &
|
|
30
|
+
BranchOutputGuard<TCurrentJson, TTrueSteps, TFalseSteps>,
|
|
31
|
+
): ChainCursor<StepSequenceOutput<TCurrentJson, TTrueSteps>>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export class ChainCursor<TCurrentJson> {
|
|
35
|
+
constructor(
|
|
36
|
+
private readonly wf: WorkflowBuilder,
|
|
37
|
+
private readonly cursor: NodeRef,
|
|
38
|
+
private readonly cursorOutput: OutputPortKey,
|
|
39
|
+
) {}
|
|
40
|
+
|
|
41
|
+
then<TConfig extends RunnableNodeConfig<TCurrentJson, any>>(
|
|
42
|
+
config: TConfig,
|
|
43
|
+
): ChainCursor<RunnableNodeOutputJson<TConfig>> {
|
|
44
|
+
const next = (this.wf as any).add(config) as NodeRef;
|
|
45
|
+
(this.wf as any).connect(this.cursor, next, this.cursorOutput);
|
|
46
|
+
return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this.wf, next, "main");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
readonly when: ChainCursorWhenOverloads<TCurrentJson> = ((
|
|
50
|
+
arg1:
|
|
51
|
+
| boolean
|
|
52
|
+
| Readonly<{ true?: ReadonlyArray<AnyRunnableNodeConfig>; false?: ReadonlyArray<AnyRunnableNodeConfig> }>,
|
|
53
|
+
steps?: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,
|
|
54
|
+
...more: AnyRunnableNodeConfig[]
|
|
55
|
+
): WhenBuilder<TCurrentJson> | ChainCursor<TCurrentJson> => {
|
|
56
|
+
if (typeof arg1 === "boolean") {
|
|
57
|
+
const list = Array.isArray(steps) ? steps : steps ? [steps, ...more] : more;
|
|
58
|
+
const port: OutputPortKey = arg1 ? "true" : "false";
|
|
59
|
+
const b = new WhenBuilder<TCurrentJson>(this.wf, this.cursor, port);
|
|
60
|
+
b.addBranch(list);
|
|
61
|
+
return b;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const branches = arg1;
|
|
65
|
+
const makeMerge = (this.wf as any).options?.makeMergeNode as ((name: string) => AnyRunnableNodeConfig) | undefined;
|
|
66
|
+
if (!makeMerge) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'WorkflowBuilder is missing options.makeMergeNode (required for when({true,false}). Use createWorkflowBuilder from "@codemation/core-nodes".',
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const wfAny = this.wf as any;
|
|
73
|
+
|
|
74
|
+
const buildBranch = (
|
|
75
|
+
port: OutputPortKey,
|
|
76
|
+
branchSteps: ReadonlyArray<AnyRunnableNodeConfig> | undefined,
|
|
77
|
+
): Readonly<{ end: NodeRef; endOutput: OutputPortKey }> => {
|
|
78
|
+
const list = branchSteps ?? [];
|
|
79
|
+
let prev: NodeRef | null = null;
|
|
80
|
+
for (const cfg of list) {
|
|
81
|
+
const ref = wfAny.add(cfg) as NodeRef;
|
|
82
|
+
if (!prev) wfAny.connect(this.cursor, ref, port, "in");
|
|
83
|
+
else wfAny.connect(prev, ref, "main", "in");
|
|
84
|
+
prev = ref;
|
|
85
|
+
}
|
|
86
|
+
if (!prev) return { end: this.cursor, endOutput: port };
|
|
87
|
+
return { end: prev, endOutput: "main" };
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const t = buildBranch("true", branches.true);
|
|
91
|
+
const f = buildBranch("false", branches.false);
|
|
92
|
+
|
|
93
|
+
const merge = wfAny.add(makeMerge("Merge (auto)")) as NodeRef;
|
|
94
|
+
wfAny.connect(t.end, merge, t.endOutput, "true");
|
|
95
|
+
wfAny.connect(f.end, merge, f.endOutput, "false");
|
|
96
|
+
|
|
97
|
+
return new ChainCursor<TCurrentJson>(this.wf, merge, "main");
|
|
98
|
+
}) as ChainCursorWhenOverloads<TCurrentJson>;
|
|
99
|
+
|
|
100
|
+
build(): WorkflowDefinition {
|
|
101
|
+
return this.wf.build();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { NodeId, NodeRef, OutputPortKey, UpstreamRefPlaceholder, WorkflowDefinition } from "../../types";
|
|
2
|
+
|
|
3
|
+
import { WorkflowBuilder } from "./WorkflowBuilder";
|
|
4
|
+
import type { AnyRunnableNodeConfig, BooleanWhenOverloads, ValidStepSequence } from "./workflowBuilderTypes";
|
|
5
|
+
|
|
6
|
+
export class WhenBuilder<TCurrentJson> {
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly wf: WorkflowBuilder,
|
|
9
|
+
private readonly from: NodeRef,
|
|
10
|
+
private readonly branchPort: OutputPortKey,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
addBranch<TSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(
|
|
14
|
+
steps: TSteps & ValidStepSequence<TCurrentJson, TSteps>,
|
|
15
|
+
): this {
|
|
16
|
+
const created: NodeRef[] = [];
|
|
17
|
+
|
|
18
|
+
let prev: NodeRef | null = null;
|
|
19
|
+
for (const cfg of steps) {
|
|
20
|
+
const ref = (this.wf as any).add(cfg) as NodeRef;
|
|
21
|
+
created.push(ref);
|
|
22
|
+
if (!prev) (this.wf as any).connect(this.from, ref, this.branchPort, "in");
|
|
23
|
+
else (this.wf as any).connect(prev, ref, "main", "in");
|
|
24
|
+
prev = ref;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
for (const cfg of steps) {
|
|
28
|
+
const maybe = cfg as unknown as { upstreamRefs?: Array<{ nodeId: NodeId } | UpstreamRefPlaceholder> };
|
|
29
|
+
if (!Array.isArray(maybe.upstreamRefs) || maybe.upstreamRefs.length === 0) continue;
|
|
30
|
+
|
|
31
|
+
maybe.upstreamRefs = maybe.upstreamRefs.map((r) => {
|
|
32
|
+
if (typeof r !== "string") return r;
|
|
33
|
+
const idx = parseInt(r.slice(1), 10);
|
|
34
|
+
const nodeId = created[idx]?.id;
|
|
35
|
+
return nodeId ? { nodeId } : { nodeId: r };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
readonly when: BooleanWhenOverloads<TCurrentJson, WhenBuilder<TCurrentJson>> = (
|
|
43
|
+
branch: boolean,
|
|
44
|
+
steps: ReadonlyArray<AnyRunnableNodeConfig> | AnyRunnableNodeConfig,
|
|
45
|
+
...more: AnyRunnableNodeConfig[]
|
|
46
|
+
): WhenBuilder<TCurrentJson> => {
|
|
47
|
+
const list = Array.isArray(steps) ? steps : [steps, ...more];
|
|
48
|
+
const port: OutputPortKey = branch ? "true" : "false";
|
|
49
|
+
const b = new WhenBuilder<TCurrentJson>(this.wf, this.from, port);
|
|
50
|
+
b.addBranch(list);
|
|
51
|
+
return b;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
build(): WorkflowDefinition {
|
|
55
|
+
return this.wf.build();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InputPortKey,
|
|
3
|
+
NodeConfigBase,
|
|
4
|
+
NodeDefinition,
|
|
5
|
+
NodeRef,
|
|
6
|
+
OutputPortKey,
|
|
7
|
+
RunnableNodeOutputJson,
|
|
8
|
+
TriggerNodeOutputJson,
|
|
9
|
+
WorkflowDefinition,
|
|
10
|
+
WorkflowId,
|
|
11
|
+
} from "../../types";
|
|
12
|
+
|
|
13
|
+
import { ChainCursor } from "./ChainCursorResolver";
|
|
14
|
+
import type { AnyRunnableNodeConfig, AnyTriggerNodeConfig } from "./workflowBuilderTypes";
|
|
15
|
+
|
|
16
|
+
export class WorkflowBuilder {
|
|
17
|
+
private readonly nodes: NodeDefinition[] = [];
|
|
18
|
+
private readonly edges: WorkflowDefinition["edges"] = [];
|
|
19
|
+
private seq = 0;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
private readonly meta: { id: WorkflowId; name: string },
|
|
23
|
+
private readonly options?: Readonly<{
|
|
24
|
+
makeMergeNode?: (name: string) => AnyRunnableNodeConfig;
|
|
25
|
+
}>,
|
|
26
|
+
) {}
|
|
27
|
+
|
|
28
|
+
private add(config: NodeConfigBase): NodeRef {
|
|
29
|
+
const tokenName = typeof config.type === "function" ? config.type.name : String(config.type);
|
|
30
|
+
const id = config.id ?? `${tokenName}:${++this.seq}`;
|
|
31
|
+
this.nodes.push({ id, kind: config.kind, type: config.type, name: config.name, config });
|
|
32
|
+
return { id, kind: config.kind, name: config.name };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private connect(from: NodeRef, to: NodeRef, fromOutput: OutputPortKey = "main", toInput: InputPortKey = "in"): void {
|
|
36
|
+
this.edges.push({ from: { nodeId: from.id, output: fromOutput }, to: { nodeId: to.id, input: toInput } });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
trigger<TConfig extends AnyTriggerNodeConfig>(config: TConfig): ChainCursor<TriggerNodeOutputJson<TConfig>> {
|
|
40
|
+
const ref = this.add(config);
|
|
41
|
+
return new ChainCursor<TriggerNodeOutputJson<TConfig>>(this, ref, "main");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
start<TConfig extends AnyRunnableNodeConfig>(config: TConfig): ChainCursor<RunnableNodeOutputJson<TConfig>> {
|
|
45
|
+
const ref = this.add(config);
|
|
46
|
+
return new ChainCursor<RunnableNodeOutputJson<TConfig>>(this, ref, "main");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
build(): WorkflowDefinition {
|
|
50
|
+
return { ...this.meta, nodes: this.nodes, edges: this.edges };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { ChainCursor } from "./ChainCursorResolver";
|
|
55
|
+
export { WhenBuilder } from "./WhenBuilder";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { RunnableNodeConfig, RunnableNodeOutputJson, TriggerNodeConfig } from "../../types";
|
|
2
|
+
|
|
3
|
+
export type AnyRunnableNodeConfig = RunnableNodeConfig<any, any>;
|
|
4
|
+
|
|
5
|
+
export type AnyTriggerNodeConfig = TriggerNodeConfig<any>;
|
|
6
|
+
|
|
7
|
+
export type ValidStepSequence<
|
|
8
|
+
TCurrentJson,
|
|
9
|
+
TSteps extends ReadonlyArray<AnyRunnableNodeConfig>,
|
|
10
|
+
> = TSteps extends readonly []
|
|
11
|
+
? readonly []
|
|
12
|
+
: TSteps extends readonly [infer TFirst, ...infer TRest]
|
|
13
|
+
? TFirst extends RunnableNodeConfig<TCurrentJson, infer TNextJson>
|
|
14
|
+
? TRest extends ReadonlyArray<AnyRunnableNodeConfig>
|
|
15
|
+
? readonly [TFirst, ...ValidStepSequence<TNextJson, TRest>]
|
|
16
|
+
: never
|
|
17
|
+
: never
|
|
18
|
+
: TSteps;
|
|
19
|
+
|
|
20
|
+
export type StepSequenceOutput<TCurrentJson, TSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined> =
|
|
21
|
+
TSteps extends ReadonlyArray<AnyRunnableNodeConfig>
|
|
22
|
+
? TSteps extends readonly []
|
|
23
|
+
? TCurrentJson
|
|
24
|
+
: TSteps extends readonly [infer TFirst, ...infer TRest]
|
|
25
|
+
? TFirst extends RunnableNodeConfig<TCurrentJson, infer TNextJson>
|
|
26
|
+
? TRest extends ReadonlyArray<AnyRunnableNodeConfig>
|
|
27
|
+
? StepSequenceOutput<TNextJson, TRest>
|
|
28
|
+
: never
|
|
29
|
+
: never
|
|
30
|
+
: TCurrentJson
|
|
31
|
+
: TCurrentJson;
|
|
32
|
+
|
|
33
|
+
type TypesMatch<TLeft, TRight> = [TLeft] extends [TRight] ? ([TRight] extends [TLeft] ? true : false) : false;
|
|
34
|
+
|
|
35
|
+
export type BranchOutputGuard<
|
|
36
|
+
TCurrentJson,
|
|
37
|
+
TTrueSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,
|
|
38
|
+
TFalseSteps extends ReadonlyArray<AnyRunnableNodeConfig> | undefined,
|
|
39
|
+
> =
|
|
40
|
+
TypesMatch<StepSequenceOutput<TCurrentJson, TTrueSteps>, StepSequenceOutput<TCurrentJson, TFalseSteps>> extends true
|
|
41
|
+
? unknown
|
|
42
|
+
: never;
|
|
43
|
+
|
|
44
|
+
export type BranchStepsArg<TCurrentJson, TSteps extends ReadonlyArray<AnyRunnableNodeConfig>> = TSteps &
|
|
45
|
+
ValidStepSequence<TCurrentJson, TSteps>;
|
|
46
|
+
|
|
47
|
+
export type BranchMoreArgs<
|
|
48
|
+
TCurrentJson,
|
|
49
|
+
TFirstStep extends RunnableNodeConfig<TCurrentJson, any>,
|
|
50
|
+
TRestSteps extends ReadonlyArray<AnyRunnableNodeConfig>,
|
|
51
|
+
> = TRestSteps & ValidStepSequence<RunnableNodeOutputJson<TFirstStep>, TRestSteps>;
|
|
52
|
+
|
|
53
|
+
export type BooleanWhenOverloads<TCurrentJson, TReturn> = {
|
|
54
|
+
<TSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(
|
|
55
|
+
branch: boolean,
|
|
56
|
+
steps: BranchStepsArg<TCurrentJson, TSteps>,
|
|
57
|
+
): TReturn;
|
|
58
|
+
<TFirstStep extends RunnableNodeConfig<TCurrentJson, any>, TRestSteps extends ReadonlyArray<AnyRunnableNodeConfig>>(
|
|
59
|
+
branch: boolean,
|
|
60
|
+
step: TFirstStep,
|
|
61
|
+
...more: BranchMoreArgs<TCurrentJson, TFirstStep, TRestSteps>
|
|
62
|
+
): TReturn;
|
|
63
|
+
};
|