@codemation/core 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/{CostCatalogContract-B9aYIqJu.d.cts → CostCatalogContract-Dwo-ZamG.d.cts} +2 -2
  3. package/dist/EngineRuntimeRegistration.types-BiNasx3G.d.cts +54 -0
  4. package/dist/EngineRuntimeRegistration.types-Dq4ucrdo.d.ts +21 -0
  5. package/dist/{InMemoryRunDataFactory-C3rIszrW.d.cts → InMemoryRunDataFactory-D2U9azmZ.d.cts} +2 -20
  6. package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs} +1 -1
  7. package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs.map → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs.map} +1 -1
  8. package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js → InMemoryRunEventBusRegistry-Layt2xgm.js} +1 -1
  9. package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js.map → InMemoryRunEventBusRegistry-Layt2xgm.js.map} +1 -1
  10. package/dist/{ItemsInputNormalizer-UCpn7luX.d.cts → ItemsInputNormalizer-A5txcOWX.d.cts} +3 -98
  11. package/dist/{ItemsInputNormalizer-B9SdLG24.cjs → ItemsInputNormalizer-C1fv3sMW.cjs} +2 -2
  12. package/dist/ItemsInputNormalizer-C1fv3sMW.cjs.map +1 -0
  13. package/dist/{ItemsInputNormalizer-DoOawd9R.d.ts → ItemsInputNormalizer-D2vrMrX1.d.ts} +2 -62
  14. package/dist/{ItemsInputNormalizer-CZEODg94.js → ItemsInputNormalizer-fUYo4GLV.js} +2 -2
  15. package/dist/ItemsInputNormalizer-fUYo4GLV.js.map +1 -0
  16. package/dist/{RunIntentService-0f3ICjAz.d.cts → RunIntentService-DKxuHTUz.d.cts} +2 -15
  17. package/dist/{RunIntentService-Dx_HHxDX.d.ts → RunIntentService-DrpKli2k.d.ts} +2 -22
  18. package/dist/{agentMcpTypes-B11B3Hd-.d.cts → agentMcpTypes-BHX4RQCC.d.cts} +24 -524
  19. package/dist/bootstrap/index.cjs +9 -5
  20. package/dist/bootstrap/index.d.cts +32 -106
  21. package/dist/bootstrap/index.d.ts +18 -17
  22. package/dist/bootstrap/index.js +6 -5
  23. package/dist/{bootstrap-Be0LB0nh.cjs → bootstrap-CTB53rEF.cjs} +9 -60
  24. package/dist/bootstrap-CTB53rEF.cjs.map +1 -0
  25. package/dist/{bootstrap-pSQdsMfa.js → bootstrap-DmqKheCI.js} +6 -57
  26. package/dist/bootstrap-DmqKheCI.js.map +1 -0
  27. package/dist/browser.cjs +12 -11
  28. package/dist/browser.d.cts +4 -4
  29. package/dist/browser.d.ts +3 -3
  30. package/dist/browser.js +3 -2
  31. package/dist/contracts-7L1wJHdk.cjs +569 -0
  32. package/dist/contracts-7L1wJHdk.cjs.map +1 -0
  33. package/dist/contracts-CjJ5CZ7N.js +447 -0
  34. package/dist/contracts-CjJ5CZ7N.js.map +1 -0
  35. package/dist/contracts.cjs +9 -2
  36. package/dist/contracts.d.cts +5 -5
  37. package/dist/contracts.d.ts +2 -2
  38. package/dist/contracts.js +3 -2
  39. package/dist/{executionPersistenceContracts-CX9Ql8N1.d.cts → deploymentManifestTypes-B8CDmZZK.d.cts} +65 -81
  40. package/dist/di-C6Ubf9o5.cjs +179 -0
  41. package/dist/di-C6Ubf9o5.cjs.map +1 -0
  42. package/dist/di-Cjiil7U-.js +114 -0
  43. package/dist/di-Cjiil7U-.js.map +1 -0
  44. package/dist/{index-CbJdbIHe.d.ts → index-CRv3_pY3.d.ts} +87 -870
  45. package/dist/{index-uPnD9EE6.d.ts → index-mnLS0iQl.d.ts} +27 -400
  46. package/dist/index.cjs +44 -115
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +17 -524
  49. package/dist/index.d.ts +5 -5
  50. package/dist/index.js +21 -98
  51. package/dist/index.js.map +1 -1
  52. package/dist/{params-Dwl10Ws9.d.cts → params-CrK4iuG1.d.cts} +2 -11
  53. package/dist/{runtime-CSunvf7A.js → runtime-CBFDpmiz.js} +46 -679
  54. package/dist/runtime-CBFDpmiz.js.map +1 -0
  55. package/dist/{runtime-n2tqRwaf.cjs → runtime-Due-FOZ2.cjs} +69 -752
  56. package/dist/runtime-Due-FOZ2.cjs.map +1 -0
  57. package/dist/testing.cjs +8 -40
  58. package/dist/testing.cjs.map +1 -1
  59. package/dist/testing.d.cts +3 -32
  60. package/dist/testing.d.ts +3 -32
  61. package/dist/testing.js +6 -38
  62. package/dist/testing.js.map +1 -1
  63. package/dist/{di-DhwtDRgs.cjs → workflowTypes-BW6Hhee7.cjs} +4 -229
  64. package/dist/workflowTypes-BW6Hhee7.cjs.map +1 -0
  65. package/dist/{di-CEV6wTc4.js → workflowTypes-DZtBTmKf.js} +3 -162
  66. package/dist/workflowTypes-DZtBTmKf.js.map +1 -0
  67. package/package.json +1 -1
  68. package/src/ai/AgentConnectionNodeCollector.ts +0 -4
  69. package/src/ai/AgentMessageConfigNormalizerFactory.ts +0 -4
  70. package/src/ai/AiHost.ts +0 -38
  71. package/src/ai/CallableToolConfig.ts +0 -9
  72. package/src/ai/CallableToolKindToken.ts +0 -4
  73. package/src/authoring/callableTool.types.ts +0 -3
  74. package/src/authoring/defineCollection.types.ts +0 -11
  75. package/src/authoring/defineHumanApprovalNode.types.ts +0 -116
  76. package/src/authoring/defineNode.types.ts +0 -25
  77. package/src/authoring/definePollingTrigger.types.ts +18 -152
  78. package/src/authoring/definePollingTriggerInternals.ts +0 -4
  79. package/src/authoring/nodeBaseOptions.types.ts +0 -14
  80. package/src/binaries/boundedReadBinary.types.ts +0 -16
  81. package/src/bootstrap/index.ts +8 -2
  82. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +0 -5
  83. package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +0 -23
  84. package/src/browser.ts +0 -3
  85. package/src/contracts/AgentBindError.ts +0 -5
  86. package/src/contracts/Clock.ts +0 -1
  87. package/src/contracts/CodemationTelemetryAttributeNames.ts +0 -10
  88. package/src/contracts/NoOpAgentMcpIntegration.ts +0 -6
  89. package/src/contracts/NoOpTelemetrySpanScope.ts +0 -7
  90. package/src/contracts/RetryPolicy.ts +0 -2
  91. package/src/contracts/agentMcpTypes.ts +0 -34
  92. package/src/contracts/assertionTypes.ts +0 -33
  93. package/src/contracts/baseTypes.ts +0 -6
  94. package/src/contracts/collectionTypes.ts +0 -25
  95. package/src/contracts/credentialTypes.ts +13 -60
  96. package/src/contracts/deploymentManifestTypes.ts +158 -0
  97. package/src/contracts/dispatchTypes.ts +29 -0
  98. package/src/contracts/executionPersistenceContracts.ts +0 -33
  99. package/src/contracts/hitlSeamTypes.ts +0 -14
  100. package/src/contracts/humanTaskStoreTypes.ts +0 -2
  101. package/src/contracts/inboxChannelTypes.ts +0 -9
  102. package/src/contracts/index.ts +3 -0
  103. package/src/contracts/itemExpr.ts +0 -18
  104. package/src/contracts/itemMeta.ts +0 -3
  105. package/src/contracts/mcpTypes.ts +0 -16
  106. package/src/contracts/retryPolicySpec.types.ts +0 -10
  107. package/src/contracts/runFinishedAtFactory.ts +0 -1
  108. package/src/contracts/runTypes.ts +0 -74
  109. package/src/contracts/runtimeTypes.ts +4 -131
  110. package/src/contracts/telemetryTypes.ts +0 -7
  111. package/src/contracts/testTriggerTypes.ts +0 -43
  112. package/src/contracts/triggerInvokerTypes.ts +6 -0
  113. package/src/contracts/webhookTypes.ts +0 -8
  114. package/src/contracts/workflowActivationPolicy.ts +0 -5
  115. package/src/contracts/workflowTypes.ts +4 -86
  116. package/src/contracts/workspaceFileTypes.ts +0 -72
  117. package/src/contracts.ts +18 -10
  118. package/src/credentials/CredentialMaterialProvider.types.ts +0 -28
  119. package/src/credentials/ManagedCredentialMaterialWriteError.ts +0 -6
  120. package/src/credentials/ManagedMaterialFetchError.ts +0 -6
  121. package/src/credentials/OAuthFlowExecutor.types.ts +0 -15
  122. package/src/di/CoreTokens.ts +2 -6
  123. package/src/events/ConnectionInvocationEventPublisher.ts +0 -7
  124. package/src/events/NodeEventPublisher.ts +0 -1
  125. package/src/events/runEvents.ts +0 -8
  126. package/src/execution/ActivationEnqueueService.ts +0 -10
  127. package/src/execution/ChildExecutionScopeFactory.ts +0 -13
  128. package/src/execution/FanInMergeByOriginMerger.ts +0 -11
  129. package/src/execution/InProcessRetryRunner.ts +0 -1
  130. package/src/execution/ItemExprResolver.ts +0 -3
  131. package/src/execution/NodeActivationRequestComposer.ts +0 -3
  132. package/src/execution/NodeActivationRequestInputPreparer.ts +0 -5
  133. package/src/execution/NodeExecutionSnapshotFactory.ts +0 -1
  134. package/src/execution/NodeExecutor.ts +1 -17
  135. package/src/execution/NodeSuspensionHandler.ts +1 -39
  136. package/src/execution/PersistedRunStateTerminalBuilder.ts +0 -5
  137. package/src/execution/RunSuspendedError.ts +0 -10
  138. package/src/execution/WorkflowRunExecutionContextFactory.ts +0 -3
  139. package/src/orchestration/AbortControllerFactory.ts +0 -4
  140. package/src/orchestration/Engine.ts +0 -9
  141. package/src/orchestration/NodeExecutionRequestHandlerService.ts +3 -4
  142. package/src/orchestration/RunContinuationService.ts +7 -39
  143. package/src/orchestration/RunStartService.ts +0 -7
  144. package/src/orchestration/TestSuiteOrchestrator.ts +0 -18
  145. package/src/orchestration/TestSuiteRunIdFactory.ts +0 -4
  146. package/src/orchestration/TriggerRuntimeService.ts +3 -2
  147. package/src/planning/CurrentStateFrontierPlanner.ts +0 -1
  148. package/src/planning/RunQueuePlanner.ts +0 -6
  149. package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +0 -8
  150. package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +0 -3
  151. package/src/runStorage/RunSummaryMapper.ts +0 -1
  152. package/src/runtime/EngineFactory.ts +6 -11
  153. package/src/runtime/RunIntentService.ts +0 -4
  154. package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +0 -4
  155. package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +0 -4
  156. package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +0 -4
  157. package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +0 -1
  158. package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +0 -4
  159. package/src/runtime-types/runtimeTypeDecorators.types.ts +0 -12
  160. package/src/scheduler/ConfigDrivenOffloadPolicy.ts +0 -1
  161. package/src/scheduler/DefaultDrivingScheduler.ts +0 -6
  162. package/src/scheduler/InlineDrivingScheduler.ts +0 -13
  163. package/src/serialization/ItemsInputNormalizer.ts +0 -5
  164. package/src/testing/CapturingScheduler.ts +0 -3
  165. package/src/testing/EngineTestKitRunIdFactory.ts +0 -3
  166. package/src/testing/ItemHarnessNode.ts +0 -3
  167. package/src/testing/ItemHarnessNodeConfig.ts +0 -4
  168. package/src/testing/PrefixedSequentialIdGenerator.ts +0 -3
  169. package/src/testing/RegistrarEngineTestKit.types.ts +0 -2
  170. package/src/testing/RejectingCredentialSessionService.ts +0 -4
  171. package/src/testing/SubWorkflowRunnerTestNode.ts +0 -3
  172. package/src/testing/WorkflowTestHarnessManualTrigger.ts +0 -3
  173. package/src/testing/WorkflowTestKitBuilder.ts +0 -4
  174. package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +0 -3
  175. package/src/testing.ts +0 -3
  176. package/src/triggers/polling/PollingTriggerDedupWindow.ts +0 -4
  177. package/src/triggers/polling/PollingTriggerLogger.ts +0 -5
  178. package/src/triggers/polling/PollingTriggerRuntime.ts +0 -5
  179. package/src/types/index.ts +0 -6
  180. package/src/validation/WorkflowEdgePortValidator.ts +0 -5
  181. package/src/workflow/definition/ConnectionInvocationIdFactory.ts +0 -7
  182. package/src/workflow/definition/ConnectionNodeIdFactory.ts +0 -6
  183. package/src/workflow/definition/NodeIterationIdFactory.ts +0 -13
  184. package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +0 -6
  185. package/src/workflow/dsl/ChainCursorResolver.ts +0 -20
  186. package/src/workflow/dsl/NodeIdSlugifier.ts +0 -9
  187. package/src/workflow/dsl/WhenBuilder.ts +0 -17
  188. package/src/workflow/dsl/WorkflowDefinitionError.ts +0 -9
  189. package/src/workflow/dsl/workflowBuilderTypes.ts +0 -24
  190. package/src/workflowSnapshots/MissingRuntimeParityGuard.ts +24 -0
  191. package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +0 -6
  192. package/src/workflowSnapshots/WorkflowParityMismatchError.ts +18 -0
  193. package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +0 -5
  194. package/src/workflowSnapshots/index.ts +3 -0
  195. package/dist/EngineRuntimeRegistration.types-BYAmGMdS.d.cts +0 -81
  196. package/dist/EngineRuntimeRegistration.types-CVLI8DsJ.d.ts +0 -44
  197. package/dist/ItemsInputNormalizer-B9SdLG24.cjs.map +0 -1
  198. package/dist/ItemsInputNormalizer-CZEODg94.js.map +0 -1
  199. package/dist/bootstrap-Be0LB0nh.cjs.map +0 -1
  200. package/dist/bootstrap-pSQdsMfa.js.map +0 -1
  201. package/dist/contracts-CK0x6w_G.cjs +0 -74
  202. package/dist/contracts-CK0x6w_G.cjs.map +0 -1
  203. package/dist/contracts-DXdfTdpW.js +0 -50
  204. package/dist/contracts-DXdfTdpW.js.map +0 -1
  205. package/dist/di-CEV6wTc4.js.map +0 -1
  206. package/dist/di-DhwtDRgs.cjs.map +0 -1
  207. package/dist/runtime-CSunvf7A.js.map +0 -1
  208. package/dist/runtime-n2tqRwaf.cjs.map +0 -1
@@ -24,14 +24,6 @@ export class InlineDrivingScheduler implements NodeActivationScheduler {
24
24
  this.continuation = continuation;
25
25
  }
26
26
 
27
- /**
28
- * Prevents new drain cycles from being scheduled and waits for all currently-running
29
- * drains to complete. Call before closing the DB connection or rolling back test transactions
30
- * to ensure no in-flight writes hit a closed/rolled-back connection.
31
- *
32
- * Bounded: only the drains already in-flight at call time are awaited. Runs that keep
33
- * re-scheduling will not schedule new work once stopped is set.
34
- */
35
27
  async stop(): Promise<void> {
36
28
  this.stopped = true;
37
29
  if (this.activeDrainPromises.size > 0) {
@@ -58,9 +50,6 @@ export class InlineDrivingScheduler implements NodeActivationScheduler {
58
50
  this.scheduledRuns.delete(runId);
59
51
  try {
60
52
  const q = this.queuesByRunId.get(runId) ?? [];
61
- // Process exactly one activation per drain so the event loop gets a full cycle
62
- // (poll phase → I/O) between activations. Synchronous SQLite writes otherwise
63
- // block HTTP responses and WS frames for the entire run duration.
64
53
  if (q.length === 0) return;
65
54
  const next = q.shift()!;
66
55
  const { request } = next;
@@ -98,8 +87,6 @@ export class InlineDrivingScheduler implements NodeActivationScheduler {
98
87
  return;
99
88
  }
100
89
  this.scheduledRuns.add(runId);
101
- // Use setImmediate so the activation fires in the check phase (after poll/I/O),
102
- // giving queued HTTP writes and WS frames a chance to flush between activations.
103
90
  setImmediate(() => {
104
91
  this.scheduledRuns.delete(runId);
105
92
  if (this.stopped) return;
@@ -1,11 +1,6 @@
1
1
  import type { Item, Items } from "../contracts/workflowTypes";
2
2
  import { injectable } from "../di";
3
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
4
  @injectable()
10
5
  export class ItemsInputNormalizer {
11
6
  normalize(raw: unknown): Items {
@@ -1,8 +1,5 @@
1
1
  import type { NodeExecutionRequest, NodeExecutionScheduler } from "../types";
2
2
 
3
- /**
4
- * Test scheduler that records enqueue requests without executing a real queue.
5
- */
6
3
  export class CapturingScheduler implements NodeExecutionScheduler {
7
4
  lastRequest: NodeExecutionRequest | undefined;
8
5
  requests: NodeExecutionRequest[] = [];
@@ -1,8 +1,5 @@
1
1
  import type { RunIdFactory } from "../types";
2
2
 
3
- /**
4
- * @internal Test harness id factory shared by registrar kit wiring.
5
- */
6
3
  export class EngineTestKitRunIdFactory implements RunIdFactory {
7
4
  private runCounter = 0;
8
5
  private activationCounter = 0;
@@ -2,9 +2,6 @@ import type { Item, RunnableNode, RunnableNodeExecuteArgs } from "../types";
2
2
 
3
3
  import type { ItemHarnessNodeConfig } from "./ItemHarnessNodeConfig";
4
4
 
5
- /**
6
- * Item-mode harness node for engine tests (see {@link ItemHarnessNodeConfig}).
7
- */
8
5
  export class ItemHarnessNode implements RunnableNode<ItemHarnessNodeConfig<any, any>> {
9
6
  readonly kind = "node" as const;
10
7
  readonly outputPorts = ["main"] as const;
@@ -5,10 +5,6 @@ import type { Item, Items, NodeExecutionContext, RunnableNodeConfig } from "../t
5
5
 
6
6
  import { ItemHarnessNode } from "./ItemHarnessNode";
7
7
 
8
- /**
9
- * Item-mode harness node config for engine tests: engine applies {@link RunnableNodeConfig.inputSchema},
10
- * then {@link ItemHarnessNode.execute} per item.
11
- */
12
8
  export class ItemHarnessNodeConfig<TIn = unknown, TOut = unknown> implements RunnableNodeConfig<TIn, TOut> {
13
9
  readonly kind = "node" as const;
14
10
  readonly type: TypeToken<unknown> = ItemHarnessNode;
@@ -1,6 +1,3 @@
1
- /**
2
- * Deterministic `run_1`, `act_1`-style ids for test harness factories.
3
- */
4
1
  export class PrefixedSequentialIdGenerator {
5
2
  private n = 0;
6
3
 
@@ -39,12 +39,10 @@ export type EngineTestKitOptions = Partial<{
39
39
  makeRunId: () => string;
40
40
  makeActivationId: () => string;
41
41
  workflowRunner: EngineWorkflowRunnerService;
42
- /** Passed to engine factory so integration tests can assert host-configured limits propagate. */
43
42
  executionLimitsPolicy: EngineExecutionLimitsPolicy;
44
43
  }>;
45
44
 
46
45
  export type RegistrarEngineTestKitOptions = EngineTestKitOptions & {
47
- /** Passed to {@link EngineRuntimeRegistrar.register}. */
48
46
  registrarOptions?: EngineRuntimeRegistrationOptions;
49
47
  };
50
48
 
@@ -1,9 +1,5 @@
1
1
  import type { CredentialSessionService } from "../contracts/credentialTypes";
2
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
3
  export class RejectingCredentialSessionService implements CredentialSessionService {
8
4
  async getSession<TSession = unknown>(
9
5
  args: Readonly<{ workflowId: string; nodeId: string; slotKey: string }>,
@@ -4,9 +4,6 @@ import type { TypeToken } from "../di";
4
4
  import type { Item, NodeId, RunnableNode, RunnableNodeConfig, RunnableNodeExecuteArgs, WorkflowId } from "../types";
5
5
  import { emitPorts } from "../contracts/emitPorts";
6
6
 
7
- /**
8
- * Test harness subworkflow runner (mirrors integration patterns; lives under {@link "@codemation/core/testing"}).
9
- */
10
7
  export class SubWorkflowRunnerConfig<TInputJson = unknown, TOutputJson = unknown> implements RunnableNodeConfig<
11
8
  TInputJson,
12
9
  TOutputJson
@@ -9,9 +9,6 @@ import type {
9
9
  TriggerSetupContext,
10
10
  } from "../types";
11
11
 
12
- /**
13
- * Minimal pass-through manual trigger for {@link WorkflowTestKit.runNode}; emits input items unchanged.
14
- */
15
12
  export class WorkflowTestHarnessManualTriggerConfig implements TriggerNodeConfig<unknown> {
16
13
  readonly kind = "trigger" as const;
17
14
  readonly type: TypeToken<unknown> = WorkflowTestHarnessManualTriggerNode;
@@ -41,10 +41,6 @@ export class WorkflowTestKit {
41
41
  return this.handle.runStore;
42
42
  }
43
43
 
44
- /**
45
- * Registers {@link import("../authoring/defineNode.types").DefinedNode} implementations on the same DI container used by the engine
46
- * (same pattern as `plugin.register({ registerNode })` in the host).
47
- */
48
44
  registerDefinedNodes(definitions: ReadonlyArray<DefinedNodeRegistration>): void {
49
45
  const ctx = this.nodeRegistrationContextFactory.create(this.handle.dependencyContainer);
50
46
  for (const def of definitions) {
@@ -6,9 +6,6 @@ import { WorkflowTestHarnessManualTriggerConfig } from "./WorkflowTestHarnessMan
6
6
  const defaultInlineWorkflowId = "codemation.testing.workflowkit.inline" as WorkflowId;
7
7
  const defaultInlineWorkflowName = "WorkflowTestKit inline";
8
8
 
9
- /**
10
- * Builds the minimal trigger → runnable workflow used by {@link import("./WorkflowTestKit").WorkflowTestKit.runNode}.
11
- */
12
9
  export class WorkflowTestKitRunNodeWorkflowFactory {
13
10
  build(args: { node: RunnableNodeConfig; workflowId?: WorkflowId; workflowName?: string }): WorkflowDefinition {
14
11
  const workflowId = args.workflowId ?? defaultInlineWorkflowId;
package/src/testing.ts CHANGED
@@ -1,6 +1,3 @@
1
- /**
2
- * Test-only adapters and helpers. Not part of the supported production public API.
3
- */
4
1
  export { InMemoryLiveWorkflowRepository } from "./runtime/InMemoryLiveWorkflowRepository";
5
2
  export { WorkflowSnapshotCodec as PersistedWorkflowSnapshotFactory } from "./workflowSnapshots/WorkflowSnapshotCodec";
6
3
  export { RejectingCredentialSessionService } from "./testing/RejectingCredentialSessionService";
@@ -1,7 +1,3 @@
1
- /**
2
- * Merges processed-ID windows for polling triggers, capping the total to avoid unbounded growth.
3
- * Plugin code receives an instance of this class via {@link PollingTriggerHandle.dedup}.
4
- */
5
1
  export class PollingTriggerDedupWindow {
6
2
  static readonly defaultCapN = 2000;
7
3
 
@@ -1,8 +1,3 @@
1
- /**
2
- * Minimal logger surface for the polling-trigger runtime.
3
- * Hosts supply this via {@link EngineDeps.pollingTriggerLogger};
4
- * when absent the runtime is silent.
5
- */
6
1
  export interface PollingTriggerLogger {
7
2
  info(message: string): void;
8
3
  warn(message: string): void;
@@ -19,11 +19,6 @@ export interface PollingTriggerStartArgs<TState, TItem> {
19
19
  emit: (items: Items) => Promise<void>;
20
20
  }
21
21
 
22
- /**
23
- * Generic polling-trigger runtime. Owns the set-interval loop, overlap guard, and persistence.
24
- * Constructed by {@link import("../../runtime/EngineFactory").EngineFactory} and exposed to plugin
25
- * authors via {@link import("../../contracts/runtimeTypes").TriggerSetupContext}.polling.
26
- */
27
22
  export class PollingTriggerRuntime {
28
23
  private readonly activeTriggers = new Set<string>();
29
24
  private readonly intervalsByTrigger = new Map<string, ReturnType<typeof setInterval>>();
@@ -1,9 +1,7 @@
1
- // Re-export pure-type contracts first (available via @codemation/core/contracts subpath)
2
1
  export * from "../contracts";
3
2
  export * from "../contracts/mcpTypes";
4
3
  export type { CollectionStore, CollectionsContext } from "../contracts/collectionTypes";
5
4
 
6
- // Additional runtime exports not included in contracts (factory classes, DSL builders, etc.)
7
5
  export * from "../contracts/emitPorts";
8
6
  export * from "../contracts/itemMeta";
9
7
  export * from "../contracts/itemExpr";
@@ -17,10 +15,6 @@ export * from "../contracts/NoOpCostTrackingTelemetryFactory";
17
15
  export * from "../contracts/NoOpExecutionTelemetryFactory";
18
16
  export * from "../contracts/runFinishedAtFactory";
19
17
  export * from "../contracts/workflowActivationPolicy";
20
- // telemetryTypes and workflowTypes also have runtime exports (No-Op telemetry classes,
21
- // attribute-name registries, `nodeRef` factory, unique-symbol type tags) — `contracts.ts`
22
- // already re-exports them with `export type *` for the slim subpath; re-export with the
23
- // full `export *` here so back-compat for `@codemation/core` (root) consumers is preserved.
24
18
  export * from "../contracts/telemetryTypes";
25
19
  export * from "../contracts/workflowTypes";
26
20
  export * from "../workflow";
@@ -34,10 +34,6 @@ export class WorkflowEdgePortValidator {
34
34
  return { valid: errors.length === 0, errors };
35
35
  }
36
36
 
37
- /**
38
- * Returns the declared output ports for a node, or null if the node is
39
- * unknown / has no declared ports (legacy nodes — treat as unconstrained).
40
- */
41
37
  private allowedOutputPorts(node: NodeDefinition | undefined): ReadonlyArray<string> | null {
42
38
  if (!node) {
43
39
  return null;
@@ -46,7 +42,6 @@ export class WorkflowEdgePortValidator {
46
42
  if (declared && declared.length > 0) {
47
43
  return declared as string[];
48
44
  }
49
- // No declared ports — treat as unconstrained (legacy nodes default to "main").
50
45
  return null;
51
46
  }
52
47
  }
@@ -1,17 +1,10 @@
1
1
  import type { NodeId } from "../../types";
2
2
 
3
- /**
4
- * Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).
5
- *
6
- * Uses Web Crypto's `randomUUID` so this module is safe in browser-bundle contexts —
7
- * paired with `NodeIterationIdFactory` which had the same `node:crypto` regression.
8
- */
9
3
  export class ConnectionInvocationIdFactory {
10
4
  static create(): string {
11
5
  return `cinv_${globalThis.crypto.randomUUID()}`;
12
6
  }
13
7
 
14
- /** Deterministic id for tests when a stable sequence is needed. */
15
8
  static createForTest(runId: string, connectionNodeId: NodeId, sequence: number): string {
16
9
  return `cinv_${runId}_${connectionNodeId}_${sequence}`;
17
10
  }
@@ -1,9 +1,5 @@
1
1
  import type { NodeId } from "../../types";
2
2
 
3
- /**
4
- * Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).
5
- * These are stable across loads.
6
- */
7
3
  export class ConnectionNodeIdFactory {
8
4
  static readonly connectionSegment = "__conn__" as const;
9
5
 
@@ -77,12 +73,10 @@ export class ConnectionNodeIdFactory {
77
73
  return { parentNodeId, normalizedToolName };
78
74
  }
79
75
 
80
- /** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
81
76
  static isConnectionOwnedDescendantOf(parentNodeId: NodeId, nodeId: NodeId): boolean {
82
77
  return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
83
78
  }
84
79
 
85
- /** Normalizes a tool display name to a stable id segment. */
86
80
  static normalizeToolName(toolName: string): string {
87
81
  return (
88
82
  toolName
@@ -1,27 +1,14 @@
1
1
  import type { NodeId } from "../../types";
2
2
 
3
- /**
4
- * Unique ids for one per-item iteration of a runnable node's execute loop.
5
- *
6
- * Activations are per-batch (one scheduled execution of a node, possibly with N items).
7
- * Iterations refine that to one identifier per item-index inside the batch loop, so per-item
8
- * connection invocations and telemetry can be grouped without time-window heuristics.
9
- *
10
- * Uses Web Crypto's `randomUUID` (Node 19+ and all modern browsers) so this module is safe
11
- * to include in the browser entry. Importing `node:crypto` here previously leaked into the
12
- * canvas client bundle through `browser.ts` and OOM'd consumers' Turbopack builds.
13
- */
14
3
  export class NodeIterationIdFactory {
15
4
  static create(): string {
16
5
  return `iter_${globalThis.crypto.randomUUID()}`;
17
6
  }
18
7
 
19
- /** Deterministic id for tests when a stable sequence is needed. */
20
8
  static createForTest(seed: string, sequence: number): string {
21
9
  return `iter_${seed}_${sequence}`;
22
10
  }
23
11
 
24
- /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */
25
12
  static createForConnection(connectionNodeId: NodeId, sequence: number): string {
26
13
  return `iter_${connectionNodeId}_${sequence}`;
27
14
  }
@@ -1,8 +1,5 @@
1
1
  import type { NodeDefinition, NodeId, WorkflowDefinition } from "../../types";
2
2
 
3
- /**
4
- * Derives which workflow nodes participate in the main execution graph vs connection-only children.
5
- */
6
3
  export class WorkflowExecutableNodeClassifier {
7
4
  private readonly connectionOwnedIds: ReadonlySet<NodeId>;
8
5
 
@@ -32,9 +29,6 @@ export class WorkflowExecutableNodeClassifier {
32
29
  return ids;
33
30
  }
34
31
 
35
- /**
36
- * Resolves the default start node: first trigger, else first executable node with no incoming edges from executable nodes.
37
- */
38
32
  findDefaultExecutableStartNodeId(workflow: WorkflowDefinition): NodeId {
39
33
  const firstTrigger = workflow.nodes.find((n) => n.kind === "trigger" && this.isExecutableNodeId(n.id))?.id;
40
34
  if (firstTrigger) return firstTrigger;
@@ -57,11 +57,6 @@ export class ChainCursor<TCurrentJson> {
57
57
  ]);
58
58
  }
59
59
 
60
- /**
61
- * Append a step whose output is MERGED onto `item.json` (shallow, output-wins) instead of
62
- * replacing it — so earlier fields (e.g. trigger metadata) survive a transform/OCR/extraction
63
- * node. Use for any node in a pipeline where you need data from before it.
64
- */
65
60
  thenMerge<TOutputJson, TConfig extends RunnableNodeConfig<TCurrentJson, TOutputJson>>(
66
61
  config: TConfig,
67
62
  ): ChainCursor<TCurrentJson & RunnableNodeOutputJson<TConfig>> {
@@ -150,21 +145,6 @@ export class ChainCursor<TCurrentJson> {
150
145
  return new ChainCursor<TNextJson>(this.wf, nextEndpoints);
151
146
  }
152
147
 
153
- /**
154
- * Chainable shorthand for `.then(node.create(config, metadata?.name, metadata?.nodeId))`.
155
- *
156
- * Signals to readers that this step suspends the run and waits for a human decision.
157
- * Throws at workflow-build time if `node` was not created via `defineHumanApprovalNode`.
158
- *
159
- * @example
160
- * ```ts
161
- * workflow
162
- * .trigger(...)
163
- * .humanApproval(inboxApproval, { title: "Approve?", body: "...", priority: "normal" })
164
- * .then(nextStep.create(...))
165
- * .build();
166
- * ```
167
- */
168
148
  humanApproval<
169
149
  TKey extends string,
170
150
  TConfig extends Record<string, unknown>,
@@ -1,12 +1,3 @@
1
- /**
2
- * Converts a human-readable node label into a stable, URL-safe identifier segment.
3
- *
4
- * Rules:
5
- * - Lowercase the entire string.
6
- * - Replace every run of characters outside `[a-z0-9]` with a single `-`.
7
- * - Strip any leading or trailing `-` characters.
8
- * - Return `""` for blank/empty input.
9
- */
10
1
  export const NodeIdSlugifier = {
11
2
  slugify(label: string): string {
12
3
  if (!label) return "";
@@ -15,18 +15,15 @@ import { WorkflowBuilder } from "./WorkflowBuilder";
15
15
  import { ChainCursor } from "./ChainCursorResolver";
16
16
  import type { AnyRunnableNodeConfig, BooleanWhenOverloads, ValidStepSequence } from "./workflowBuilderTypes";
17
17
 
18
- /** Structurally identical to ChainCursorResolver's (unexported) ChainCursorEndpoint. */
19
18
  type WhenEndpoint = Readonly<{ node: NodeRef; output: OutputPortKey; inputPortHint?: InputPortKey }>;
20
19
 
21
20
  export class WhenBuilder<TCurrentJson> {
22
- /** Tail endpoint of the arm this builder added (set by addBranch). */
23
21
  private armEndpoint: WhenEndpoint | undefined;
24
22
 
25
23
  constructor(
26
24
  private readonly wf: WorkflowBuilder,
27
25
  private readonly from: NodeRef,
28
26
  private readonly branchPort: OutputPortKey,
29
- /** Tails of arms added by earlier `.when(...)` calls in this chain. */
30
27
  private readonly priorEndpoints: ReadonlyArray<WhenEndpoint> = [],
31
28
  ) {}
32
29
 
@@ -56,8 +53,6 @@ export class WhenBuilder<TCurrentJson> {
56
53
  });
57
54
  }
58
55
 
59
- // An empty arm rejoins straight from the `from` node's branch port (mirrors the
60
- // object-form `buildBranch` returning `{ end: cursor, endOutput: port }`).
61
56
  this.armEndpoint = prev
62
57
  ? { node: prev, output: "main", inputPortHint: this.branchPort }
63
58
  : { node: this.from, output: this.branchPort, inputPortHint: this.branchPort };
@@ -77,23 +72,12 @@ export class WhenBuilder<TCurrentJson> {
77
72
  return b;
78
73
  };
79
74
 
80
- /**
81
- * Continue the trunk after a boolean `.when(...)` branch chain, auto-merging EVERY branch
82
- * tail accumulated across the chain into the next node — the same fan-in the object form
83
- * produces. Typed as `ChainCursor<TCurrentJson>` (the pre-branch item type): boolean arms
84
- * carry no output guard so the merged item type is underdetermined — use the object form
85
- * `.when({ true: [...], false: [...] })` when you need a precise merged type inline.
86
- */
87
75
  then<TOutputJson, TConfig extends RunnableNodeConfig<TCurrentJson, TOutputJson>>(
88
76
  config: TConfig,
89
77
  ): ChainCursor<RunnableNodeOutputJson<TConfig>> {
90
78
  return this.toCursor().then(config);
91
79
  }
92
80
 
93
- /**
94
- * Chainable human-approval step after a boolean `.when(...)` branch chain — merges every
95
- * branch tail into the approval node. Mirrors `ChainCursor.humanApproval`.
96
- */
97
81
  humanApproval<
98
82
  TKey extends string,
99
83
  TConfig extends Record<string, unknown>,
@@ -110,7 +94,6 @@ export class WhenBuilder<TCurrentJson> {
110
94
  return this.wf.build();
111
95
  }
112
96
 
113
- /** Endpoints of every arm added so far in this chain (prior arms + this one). */
114
97
  private get accumulatedEndpoints(): ReadonlyArray<WhenEndpoint> {
115
98
  return this.armEndpoint ? [...this.priorEndpoints, this.armEndpoint] : this.priorEndpoints;
116
99
  }
@@ -1,12 +1,3 @@
1
- /**
2
- * Thrown by {@link WorkflowBuilder.build} when the workflow definition is structurally invalid.
3
- *
4
- * Common causes:
5
- * - A node has an empty effective id (label is blank and no explicit `id` was given).
6
- * - Two or more nodes share the same effective id (label slugs collide or explicit ids clash).
7
- *
8
- * Fix: provide an explicit `id:` on the offending node configs.
9
- */
10
1
  export class WorkflowDefinitionError extends Error {
11
2
  constructor(message: string) {
12
3
  super(message);
@@ -1,29 +1,5 @@
1
1
  import type { RunnableNodeConfig, RunnableNodeOutputJson, TriggerNodeConfig } from "../../types";
2
2
 
3
- /**
4
- * Flags a node's config so its output is MERGED onto `item.json` (shallow, output-wins) instead of
5
- * replacing it — the config-level twin of {@link ChainCursor.thenMerge}.
6
- *
7
- * Unlike `.thenMerge` (a cursor method that only works on the trunk), `mergeForward` operates on a
8
- * bare config, so it is usable in ANY position — including inside a `.when({ true: [...] })` branch
9
- * arm, where the steps are a flat array of configs (not a cursor). Wrap a payload-REPLACING node
10
- * (e.g. an extractor) in `mergeForward(node.create(...))` so prior fields survive into the next step.
11
- *
12
- * The OUTPUT type becomes `TIn & TOut` (the intersection), mirroring `.thenMerge`'s return type at
13
- * the config level — so the next step in the branch array sees both the prior fields and the node's
14
- * output. The INPUT type stays `TIn` (the node still receives the pre-merge item).
15
- *
16
- * @example
17
- * ```ts
18
- * workflow
19
- * .trigger(...)
20
- * .when({
21
- * true: [mergeForward(extractor.create(...))], // output merges onto item.json; { a } survives
22
- * false: [...],
23
- * })
24
- * .build();
25
- * ```
26
- */
27
3
  export function mergeForward<TIn, TOut>(config: RunnableNodeConfig<TIn, TOut>): RunnableNodeConfig<TIn, TIn & TOut> {
28
4
  (config as { mergeJson?: boolean }).mergeJson = true;
29
5
  return config as unknown as RunnableNodeConfig<TIn, TIn & TOut>;
@@ -0,0 +1,24 @@
1
+ import type { NodeId, WorkflowDefinition } from "../types";
2
+
3
+ import { MissingRuntimeExecutionMarker } from "./MissingRuntimeExecutionMarker";
4
+ import { type MissingRuntimeNodeDetail, WorkflowParityMismatchError } from "./WorkflowParityMismatchError";
5
+
6
+ export class MissingRuntimeParityGuard {
7
+ constructor(private readonly marker: MissingRuntimeExecutionMarker) {}
8
+
9
+ assertNone(workflow: WorkflowDefinition, nodeIds?: ReadonlyArray<NodeId>): void {
10
+ const candidates = nodeIds ? workflow.nodes.filter((n) => nodeIds.includes(n.id)) : workflow.nodes;
11
+
12
+ const missing: MissingRuntimeNodeDetail[] = candidates
13
+ .filter((n) => this.marker.isMarked(n.config))
14
+ .map((n) => ({
15
+ nodeId: n.id,
16
+ kind: n.kind as "node" | "trigger",
17
+ missingTokenId: (n.config as Partial<{ missingTokenId: string }>).missingTokenId,
18
+ }));
19
+
20
+ if (missing.length > 0) {
21
+ throw new WorkflowParityMismatchError(missing);
22
+ }
23
+ }
24
+ }
@@ -8,9 +8,6 @@ export class PersistedWorkflowTokenRegistry {
8
8
  private readonly tokensById = new Map<PersistedTokenId, TypeToken<unknown>>();
9
9
  private readonly tokenIdsByToken = new Map<TypeToken<unknown>, PersistedTokenId>();
10
10
 
11
- /**
12
- * Register a token with its package ID. Token ID is inferred as `packageId::tokenName`.
13
- */
14
11
  register(type: TypeToken<unknown>, packageId: string, persistedNameOverride?: string): PersistedTokenId {
15
12
  const tokenName = persistedNameOverride ?? this.displayNameForTypeToken(type);
16
13
  const tokenId = `${packageId}::${tokenName}` as PersistedTokenId;
@@ -19,9 +16,6 @@ export class PersistedWorkflowTokenRegistry {
19
16
  return tokenId;
20
17
  }
21
18
 
22
- /**
23
- * Register all decorated runtime types discovered in workflows.
24
- */
25
19
  registerFromWorkflows(workflows: ReadonlyArray<WorkflowDefinition>): void {
26
20
  for (const workflow of workflows) {
27
21
  for (const node of workflow.nodes) {
@@ -0,0 +1,18 @@
1
+ import type { NodeId } from "../types";
2
+
3
+ export type MissingRuntimeNodeDetail = {
4
+ nodeId: NodeId;
5
+ kind: "node" | "trigger";
6
+ missingTokenId: string | undefined;
7
+ };
8
+
9
+ export class WorkflowParityMismatchError extends Error {
10
+ readonly name = "WorkflowParityMismatchError";
11
+ readonly missingNodes: ReadonlyArray<MissingRuntimeNodeDetail>;
12
+
13
+ constructor(missingNodes: ReadonlyArray<MissingRuntimeNodeDetail>) {
14
+ const labels = missingNodes.map((n) => `${n.nodeId} (token: ${n.missingTokenId ?? "unknown"})`).join(", ");
15
+ super(`Workflow parity mismatch: nodes resolve to MissingRuntime and cannot execute: ${labels}`);
16
+ this.missingNodes = missingNodes;
17
+ }
18
+ }
@@ -72,10 +72,6 @@ export class WorkflowSnapshotCodec {
72
72
  }
73
73
  }
74
74
 
75
- /**
76
- * Safely call `config.inspectorSummary()` and return a plain JSON-safe array, or undefined.
77
- * Returns undefined if the method is absent, throws, or produces no valid rows.
78
- */
79
75
  private safeInspectorSummary(
80
76
  config: NodeConfigBase,
81
77
  ): ReadonlyArray<Readonly<{ label: string; value: string }>> | undefined {
@@ -167,7 +163,6 @@ export class WorkflowSnapshotCodec {
167
163
  hydrated[key] = value;
168
164
  }
169
165
  }
170
- // Preserve symbol-keyed brands (e.g. itemExpr / emitPorts) and other runtime-only keys.
171
166
  for (const sym of Object.getOwnPropertySymbols(liveRecord)) {
172
167
  hydrated[sym] = liveRecord[sym];
173
168
  }
@@ -3,10 +3,13 @@ export { MissingRuntimeFallbacks } from "./MissingRuntimeFallbacksFactory";
3
3
  export { MissingRuntimeNode } from "./MissingRuntimeNode";
4
4
  export { MissingRuntimeNodeConfig } from "./MissingRuntimeNodeConfig";
5
5
  export { MissingRuntimeNodeToken } from "./MissingRuntimeNodeToken";
6
+ export { MissingRuntimeParityGuard } from "./MissingRuntimeParityGuard";
6
7
  export { MissingRuntimeTrigger } from "./MissingRuntimeTrigger";
7
8
  export { MissingRuntimeTriggerConfig } from "./MissingRuntimeTriggerConfig";
8
9
  export { MissingRuntimeTriggerToken } from "./MissingRuntimeTriggerToken";
9
10
  export { PersistedRuntimeTypeIdFactory } from "./PersistedRuntimeTypeIdFactory";
10
11
  export { PersistedWorkflowTokenRegistry } from "./PersistedWorkflowTokenRegistryFactory";
12
+ export { WorkflowParityMismatchError } from "./WorkflowParityMismatchError";
13
+ export type { MissingRuntimeNodeDetail } from "./WorkflowParityMismatchError";
11
14
  export { WorkflowSnapshotCodec } from "./WorkflowSnapshotCodec";
12
15
  export { WorkflowSnapshotResolver } from "./WorkflowSnapshotResolver";