@codemation/core 0.8.1 → 0.10.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 (100) hide show
  1. package/CHANGELOG.md +380 -0
  2. package/dist/{EngineRuntimeRegistration.types-BP6tsaNP.d.ts → EngineRuntimeRegistration.types-D1fyApMI.d.ts} +2 -2
  3. package/dist/{EngineWorkflowRunnerService-DzOCa1BW.d.cts → EngineRuntimeRegistration.types-pB3FnzqR.d.cts} +17 -17
  4. package/dist/{InMemoryRunDataFactory-1iz7_SnO.d.cts → InMemoryRunDataFactory-Xw7v4-sj.d.cts} +31 -29
  5. package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs +47 -0
  6. package/dist/InMemoryRunEventBusRegistry-VM3OWnHo.cjs.map +1 -0
  7. package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js +41 -0
  8. package/dist/InMemoryRunEventBusRegistry-sM4z4n_i.js.map +1 -0
  9. package/dist/{RunIntentService-BqhmdoA1.d.ts → RunIntentService-BE9CAkbf.d.ts} +966 -471
  10. package/dist/{RunIntentService-S-1lW-gS.d.cts → RunIntentService-siBSjaaY.d.cts} +859 -493
  11. package/dist/bootstrap/index.cjs +5 -2
  12. package/dist/bootstrap/index.d.cts +212 -135
  13. package/dist/bootstrap/index.d.ts +4 -4
  14. package/dist/bootstrap/index.js +3 -3
  15. package/dist/{bootstrap-Bx1u4cbS.cjs → bootstrap-Cm5ruQxx.cjs} +253 -2
  16. package/dist/bootstrap-Cm5ruQxx.cjs.map +1 -0
  17. package/dist/{bootstrap-BoknFKnw.js → bootstrap-D3r505ko.js} +236 -3
  18. package/dist/bootstrap-D3r505ko.js.map +1 -0
  19. package/dist/{index-CVs9rVhl.d.ts → index-DeLl1Tne.d.ts} +632 -230
  20. package/dist/index.cjs +323 -176
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +544 -91
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +299 -166
  25. package/dist/index.js.map +1 -1
  26. package/dist/{runtime-DUW6tIJ1.js → runtime-BGNbRnqs.js} +934 -75
  27. package/dist/runtime-BGNbRnqs.js.map +1 -0
  28. package/dist/{runtime-Dvo2ru5A.cjs → runtime-DKXJwTNv.cjs} +1028 -73
  29. package/dist/runtime-DKXJwTNv.cjs.map +1 -0
  30. package/dist/testing.cjs +4 -4
  31. package/dist/testing.cjs.map +1 -1
  32. package/dist/testing.d.cts +2 -2
  33. package/dist/testing.d.ts +2 -2
  34. package/dist/testing.js +3 -3
  35. package/package.json +7 -2
  36. package/src/ai/AiHost.ts +42 -14
  37. package/src/authoring/DefinedCollectionRegistry.ts +17 -0
  38. package/src/authoring/defineCollection.types.ts +181 -0
  39. package/src/authoring/definePollingTrigger.types.ts +396 -0
  40. package/src/authoring/definePollingTriggerInternals.ts +74 -0
  41. package/src/authoring/index.ts +19 -0
  42. package/src/bootstrap/index.ts +9 -0
  43. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +8 -0
  44. package/src/browser.ts +1 -0
  45. package/src/contracts/CodemationTelemetryAttributeNames.ts +6 -0
  46. package/src/contracts/NoOpNodeExecutionTelemetry.ts +2 -11
  47. package/src/contracts/NoOpTelemetrySpanScope.ts +46 -10
  48. package/src/contracts/assertionTypes.ts +63 -0
  49. package/src/contracts/baseTypes.ts +12 -0
  50. package/src/contracts/collectionTypes.ts +44 -0
  51. package/src/contracts/credentialTypes.ts +23 -1
  52. package/src/contracts/executionPersistenceContracts.ts +30 -0
  53. package/src/contracts/index.ts +4 -0
  54. package/src/contracts/runTypes.ts +37 -1
  55. package/src/contracts/runtimeTypes.ts +42 -0
  56. package/src/contracts/telemetryTypes.ts +8 -0
  57. package/src/contracts/testTriggerTypes.ts +66 -0
  58. package/src/contracts/workflowTypes.ts +36 -7
  59. package/src/contracts.ts +59 -0
  60. package/src/events/ConnectionInvocationEventPublisher.ts +46 -0
  61. package/src/events/index.ts +1 -0
  62. package/src/events/runEvents.ts +74 -0
  63. package/src/execution/ChildExecutionScopeFactory.ts +55 -0
  64. package/src/execution/DefaultExecutionContextFactory.ts +6 -0
  65. package/src/execution/ExecutionTelemetryCostTrackingDecoratorFactory.ts +18 -0
  66. package/src/execution/NodeExecutor.ts +10 -2
  67. package/src/execution/NodeInstanceFactory.ts +13 -1
  68. package/src/execution/NodeInstantiationError.ts +16 -0
  69. package/src/execution/NodeRunStateWriter.ts +7 -0
  70. package/src/execution/NodeRunStateWriterFactory.ts +7 -0
  71. package/src/execution/WorkflowRunExecutionContextFactory.ts +3 -0
  72. package/src/execution/index.ts +2 -0
  73. package/src/index.ts +8 -0
  74. package/src/orchestration/AbortControllerFactory.ts +9 -0
  75. package/src/orchestration/NodeExecutionRequestHandlerService.ts +1 -0
  76. package/src/orchestration/RunContinuationService.ts +3 -0
  77. package/src/orchestration/RunStartService.ts +122 -3
  78. package/src/orchestration/TestSuiteOrchestrator.ts +350 -0
  79. package/src/orchestration/TestSuiteRunIdFactory.ts +11 -0
  80. package/src/orchestration/TriggerRuntimeService.ts +34 -7
  81. package/src/orchestration/index.ts +9 -0
  82. package/src/runtime/EngineFactory.ts +12 -0
  83. package/src/triggers/polling/PollingTriggerDedupWindow.ts +23 -0
  84. package/src/triggers/polling/PollingTriggerLogger.ts +18 -0
  85. package/src/triggers/polling/PollingTriggerRuntime.ts +122 -0
  86. package/src/triggers/polling/index.ts +5 -0
  87. package/src/types/index.ts +12 -9
  88. package/src/workflow/definition/NodeIterationIdFactory.ts +26 -0
  89. package/src/workflow/dsl/NodeIdSlugifier.ts +18 -0
  90. package/src/workflow/dsl/WorkflowBuilder.ts +71 -3
  91. package/src/workflow/dsl/WorkflowDefinitionError.ts +15 -0
  92. package/src/workflow/index.ts +3 -0
  93. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs +0 -262
  94. package/dist/InMemoryRunEventBusRegistry-B0_C4OnP.cjs.map +0 -1
  95. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js +0 -238
  96. package/dist/InMemoryRunEventBusRegistry-C2U83Hmv.js.map +0 -1
  97. package/dist/bootstrap-BoknFKnw.js.map +0 -1
  98. package/dist/bootstrap-Bx1u4cbS.cjs.map +0 -1
  99. package/dist/runtime-DUW6tIJ1.js.map +0 -1
  100. package/dist/runtime-Dvo2ru5A.cjs.map +0 -1
@@ -164,6 +164,56 @@ function chatModel(options = {}) {
164
164
  return InjectableRuntimeDecoratorComposer.compose("chatModel", options, require("url").pathToFileURL(__filename).href);
165
165
  }
166
166
 
167
+ //#endregion
168
+ //#region src/ai/NodeBackedToolConfig.ts
169
+ var NodeBackedToolConfig = class {
170
+ type;
171
+ toolKind = "nodeBacked";
172
+ description;
173
+ presentation;
174
+ inputSchemaValue;
175
+ outputSchemaValue;
176
+ mapInputValue;
177
+ mapOutputValue;
178
+ constructor(name, node$1, options) {
179
+ this.name = name;
180
+ this.node = node$1;
181
+ this.type = node$1.type;
182
+ this.description = options.description;
183
+ this.presentation = options.presentation;
184
+ this.inputSchemaValue = options.inputSchema;
185
+ this.outputSchemaValue = options.outputSchema;
186
+ this.mapInputValue = options.mapInput;
187
+ this.mapOutputValue = options.mapOutput;
188
+ }
189
+ getCredentialRequirements() {
190
+ return this.node.getCredentialRequirements?.() ?? [];
191
+ }
192
+ getInputSchema() {
193
+ return this.inputSchemaValue;
194
+ }
195
+ getOutputSchema() {
196
+ return this.outputSchemaValue;
197
+ }
198
+ toNodeItem(args) {
199
+ const mapped = this.mapInputValue?.(args) ?? args.input;
200
+ if (this.isItem(mapped)) return mapped;
201
+ return { json: mapped };
202
+ }
203
+ toToolOutput(args) {
204
+ const raw = this.mapOutputValue?.(args) ?? this.readDefaultToolOutput(args.outputs);
205
+ return this.outputSchemaValue.parse(raw);
206
+ }
207
+ readDefaultToolOutput(outputs) {
208
+ const firstMainItem = outputs.main?.[0];
209
+ if (!firstMainItem) throw new Error(`Node-backed tool "${this.name}" did not produce a main output item.`);
210
+ return firstMainItem.json;
211
+ }
212
+ isItem(value) {
213
+ return typeof value === "object" && value !== null && "json" in value;
214
+ }
215
+ };
216
+
167
217
  //#endregion
168
218
  //#region src/contracts/itemExpr.ts
169
219
  const ITEM_EXPR_BRAND = Symbol.for("codemation.itemExpr");
@@ -232,6 +282,27 @@ async function resolveItemExprsForExecution(config, nodeCtx, item, itemIndex, it
232
282
  return await resolveItemExprsInUnknown(config, exprArgs);
233
283
  }
234
284
 
285
+ //#endregion
286
+ //#region src/ai/AgentConfigInspectorFactory.ts
287
+ var AgentConfigInspector = class {
288
+ static isAgentNodeConfig(config) {
289
+ if (!config) return false;
290
+ const candidate = config;
291
+ return !!candidate.chatModel && this.hasCompatibleMessageConfiguration(candidate);
292
+ }
293
+ static hasCompatibleMessageConfiguration(candidate) {
294
+ const messages = candidate.messages;
295
+ if (messages === void 0 || messages === null) return false;
296
+ if (Array.isArray(messages)) return messages.length > 0;
297
+ if (typeof messages === "object") {
298
+ if (isItemExpr(messages)) return true;
299
+ const o = messages;
300
+ return Array.isArray(o.prompt) && o.prompt.length > 0 || typeof o.buildMessages === "function";
301
+ }
302
+ return false;
303
+ }
304
+ };
305
+
235
306
  //#endregion
236
307
  //#region src/workflow/definition/ConnectionNodeIdFactory.ts
237
308
  /**
@@ -282,6 +353,369 @@ var ConnectionNodeIdFactory = class {
282
353
  }
283
354
  };
284
355
 
356
+ //#endregion
357
+ //#region src/ai/AgentConnectionNodeCollector.ts
358
+ const AgentConnectionNodeCollector = new class {
359
+ collect(parentNodeId, agentConfig) {
360
+ const collected = [];
361
+ this.collectInto(parentNodeId, agentConfig, collected);
362
+ return collected;
363
+ }
364
+ collectInto(parentNodeId, agentConfig, collected) {
365
+ collected.push({
366
+ nodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(parentNodeId),
367
+ parentNodeId,
368
+ connectionName: "llm",
369
+ role: "languageModel",
370
+ name: agentConfig.chatModel.presentation?.label ?? agentConfig.chatModel.name,
371
+ typeName: agentConfig.chatModel.name,
372
+ icon: agentConfig.chatModel.presentation?.icon,
373
+ credentialSource: agentConfig.chatModel
374
+ });
375
+ for (const tool$1 of agentConfig.tools ?? []) {
376
+ const toolNodeId = ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, tool$1.name);
377
+ const isNestedAgent = this.isNodeBackedAgentTool(tool$1);
378
+ collected.push({
379
+ nodeId: toolNodeId,
380
+ parentNodeId,
381
+ connectionName: "tools",
382
+ role: isNestedAgent ? "nestedAgent" : "tool",
383
+ name: tool$1.presentation?.label ?? tool$1.name,
384
+ typeName: tool$1.name,
385
+ icon: tool$1.presentation?.icon,
386
+ credentialSource: tool$1
387
+ });
388
+ this.collectNestedAgentTools(toolNodeId, tool$1, collected);
389
+ }
390
+ }
391
+ collectNestedAgentTools(toolNodeId, tool$1, collected) {
392
+ if (!this.isNodeBackedAgentTool(tool$1)) return;
393
+ const innerAgent = tool$1 instanceof NodeBackedToolConfig ? tool$1.node : tool$1.node;
394
+ this.collectInto(toolNodeId, innerAgent, collected);
395
+ }
396
+ /**
397
+ * After JSON round-trip (persisted snapshots), tools are plain objects — `instanceof NodeBackedToolConfig` fails.
398
+ * Detect node-backed tools structurally via {@link NodeBackedToolConfig#toolKind}.
399
+ */
400
+ isNodeBackedAgentTool(tool$1) {
401
+ if (tool$1 instanceof NodeBackedToolConfig) return AgentConfigInspector.isAgentNodeConfig(tool$1.node);
402
+ if (!tool$1 || typeof tool$1 !== "object") return false;
403
+ const t = tool$1;
404
+ if (t.toolKind !== "nodeBacked") return false;
405
+ return AgentConfigInspector.isAgentNodeConfig(t.node);
406
+ }
407
+ }();
408
+
409
+ //#endregion
410
+ //#region src/workflow/dsl/WhenBuilder.ts
411
+ var WhenBuilder = class WhenBuilder {
412
+ constructor(wf, from, branchPort) {
413
+ this.wf = wf;
414
+ this.from = from;
415
+ this.branchPort = branchPort;
416
+ }
417
+ addBranch(steps) {
418
+ const created = [];
419
+ let prev = null;
420
+ for (const cfg of steps) {
421
+ const ref = this.wf.add(cfg);
422
+ created.push(ref);
423
+ if (!prev) this.wf.connect(this.from, ref, this.branchPort, "in");
424
+ else this.wf.connect(prev, ref, "main", "in");
425
+ prev = ref;
426
+ }
427
+ for (const cfg of steps) {
428
+ const maybe = cfg;
429
+ if (!Array.isArray(maybe.upstreamRefs) || maybe.upstreamRefs.length === 0) continue;
430
+ maybe.upstreamRefs = maybe.upstreamRefs.map((r) => {
431
+ if (typeof r !== "string") return r;
432
+ const nodeId = created[parseInt(r.slice(1), 10)]?.id;
433
+ return nodeId ? { nodeId } : { nodeId: r };
434
+ });
435
+ }
436
+ return this;
437
+ }
438
+ when = (branch, steps, ...more) => {
439
+ const list = Array.isArray(steps) ? steps : [steps, ...more];
440
+ const port = branch ? "true" : "false";
441
+ const b = new WhenBuilder(this.wf, this.from, port);
442
+ b.addBranch(list);
443
+ return b;
444
+ };
445
+ build() {
446
+ return this.wf.build();
447
+ }
448
+ };
449
+
450
+ //#endregion
451
+ //#region src/workflow/dsl/ChainCursorResolver.ts
452
+ var ChainCursor = class ChainCursor {
453
+ constructor(wf, endpoints) {
454
+ this.wf = wf;
455
+ this.endpoints = endpoints;
456
+ }
457
+ then(config) {
458
+ const next = this.wf.add(config);
459
+ const inputPortHint = this.resolveSharedInputPortHint();
460
+ for (const e of this.endpoints) this.wf.connect(e.node, next, e.output);
461
+ return new ChainCursor(this.wf, [{
462
+ node: next,
463
+ output: "main",
464
+ ...inputPortHint ? { inputPortHint } : {}
465
+ }]);
466
+ }
467
+ thenIntoInputHints(config) {
468
+ const next = this.wf.add(config);
469
+ for (const e of this.endpoints) this.wf.connect(e.node, next, e.output, e.inputPortHint ?? "in");
470
+ return new ChainCursor(this.wf, [{
471
+ node: next,
472
+ output: "main"
473
+ }]);
474
+ }
475
+ when = ((arg1, steps, ...more) => {
476
+ if (this.endpoints.length !== 1) throw new Error("ChainCursor.when(...) is only supported from a single cursor endpoint");
477
+ const cursor = this.endpoints[0].node;
478
+ if (typeof arg1 === "boolean") {
479
+ const list = Array.isArray(steps) ? steps : steps ? [steps, ...more] : more;
480
+ const port = arg1 ? "true" : "false";
481
+ const b = new WhenBuilder(this.wf, cursor, port);
482
+ b.addBranch(list);
483
+ return b;
484
+ }
485
+ const branches = arg1;
486
+ const wfAny = this.wf;
487
+ const buildBranch = (port, branchSteps) => {
488
+ const list = branchSteps ?? [];
489
+ let prev = null;
490
+ for (const cfg of list) {
491
+ const ref = wfAny.add(cfg);
492
+ if (!prev) wfAny.connect(cursor, ref, port, "in");
493
+ else wfAny.connect(prev, ref, "main", "in");
494
+ prev = ref;
495
+ }
496
+ if (!prev) return {
497
+ end: cursor,
498
+ endOutput: port,
499
+ inputPortHint: port
500
+ };
501
+ return {
502
+ end: prev,
503
+ endOutput: "main",
504
+ inputPortHint: port
505
+ };
506
+ };
507
+ const t = buildBranch("true", branches.true);
508
+ const f = buildBranch("false", branches.false);
509
+ return new ChainCursor(this.wf, [{
510
+ node: t.end,
511
+ output: t.endOutput,
512
+ inputPortHint: t.inputPortHint
513
+ }, {
514
+ node: f.end,
515
+ output: f.endOutput,
516
+ inputPortHint: f.inputPortHint
517
+ }]);
518
+ });
519
+ route(branches) {
520
+ if (this.endpoints.length !== 1) throw new Error("ChainCursor.route(...) is only supported from a single cursor endpoint");
521
+ const cursor = this.endpoints[0];
522
+ const nextEndpoints = [];
523
+ for (const [port, branchFactory] of Object.entries(branches)) {
524
+ if (!branchFactory) continue;
525
+ const builtBranch = branchFactory(new ChainCursor(this.wf, [{
526
+ node: cursor.node,
527
+ output: port,
528
+ inputPortHint: port
529
+ }]));
530
+ if (!builtBranch) continue;
531
+ nextEndpoints.push(...builtBranch.endpoints);
532
+ }
533
+ return new ChainCursor(this.wf, nextEndpoints);
534
+ }
535
+ build() {
536
+ return this.wf.build();
537
+ }
538
+ resolveSharedInputPortHint() {
539
+ const first = this.endpoints[0]?.inputPortHint;
540
+ if (!first) return;
541
+ return this.endpoints.every((endpoint) => endpoint.inputPortHint === first) ? first : void 0;
542
+ }
543
+ };
544
+
545
+ //#endregion
546
+ //#region src/workflow/dsl/NodeIdSlugifier.ts
547
+ /**
548
+ * Converts a human-readable node label into a stable, URL-safe identifier segment.
549
+ *
550
+ * Rules:
551
+ * - Lowercase the entire string.
552
+ * - Replace every run of characters outside `[a-z0-9]` with a single `-`.
553
+ * - Strip any leading or trailing `-` characters.
554
+ * - Return `""` for blank/empty input.
555
+ */
556
+ const NodeIdSlugifier = { slugify(label) {
557
+ if (!label) return "";
558
+ return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
559
+ } };
560
+
561
+ //#endregion
562
+ //#region src/workflow/dsl/WorkflowDefinitionError.ts
563
+ /**
564
+ * Thrown by {@link WorkflowBuilder.build} when the workflow definition is structurally invalid.
565
+ *
566
+ * Common causes:
567
+ * - A node has an empty effective id (label is blank and no explicit `id` was given).
568
+ * - Two or more nodes share the same effective id (label slugs collide or explicit ids clash).
569
+ *
570
+ * Fix: provide an explicit `id:` on the offending node configs.
571
+ */
572
+ var WorkflowDefinitionError = class extends Error {
573
+ constructor(message) {
574
+ super(message);
575
+ this.name = "WorkflowDefinitionError";
576
+ }
577
+ };
578
+
579
+ //#endregion
580
+ //#region src/workflow/dsl/WorkflowBuilder.ts
581
+ var WorkflowBuilder = class {
582
+ nodes = [];
583
+ edges = [];
584
+ constructor(meta, options) {
585
+ this.meta = meta;
586
+ this.options = options;
587
+ }
588
+ add(config) {
589
+ const id = config.id ?? NodeIdSlugifier.slugify(config.name ?? "");
590
+ this.nodes.push({
591
+ id,
592
+ kind: config.kind,
593
+ type: config.type,
594
+ name: config.name,
595
+ config
596
+ });
597
+ return {
598
+ id,
599
+ kind: config.kind,
600
+ name: config.name
601
+ };
602
+ }
603
+ connect(from, to, fromOutput = "main", toInput = "in") {
604
+ this.edges.push({
605
+ from: {
606
+ nodeId: from.id,
607
+ output: fromOutput
608
+ },
609
+ to: {
610
+ nodeId: to.id,
611
+ input: toInput
612
+ }
613
+ });
614
+ }
615
+ trigger(config) {
616
+ const ref = this.add(config);
617
+ return new ChainCursor(this, [{
618
+ node: ref,
619
+ output: "main"
620
+ }]);
621
+ }
622
+ start(config) {
623
+ const ref = this.add(config);
624
+ return new ChainCursor(this, [{
625
+ node: ref,
626
+ output: "main"
627
+ }]);
628
+ }
629
+ build() {
630
+ this.validateNodeIds();
631
+ return {
632
+ ...this.meta,
633
+ nodes: this.nodes,
634
+ edges: this.edges
635
+ };
636
+ }
637
+ validateNodeIds() {
638
+ const entries = [];
639
+ for (const node$1 of this.nodes) {
640
+ const tokenName = typeof node$1.type === "function" ? node$1.type.name : String(node$1.type);
641
+ entries.push({
642
+ nodeId: node$1.id,
643
+ tokenName,
644
+ label: node$1.name ?? ""
645
+ });
646
+ if (AgentConfigInspector.isAgentNodeConfig(node$1.config)) for (const child of AgentConnectionNodeCollector.collect(node$1.id, node$1.config)) entries.push({
647
+ nodeId: child.nodeId,
648
+ tokenName: child.typeName,
649
+ label: child.name
650
+ });
651
+ }
652
+ const emptyIds = [];
653
+ const seenIds = /* @__PURE__ */ new Map();
654
+ const duplicateIds = [];
655
+ for (const entry of entries) {
656
+ if (!entry.nodeId) {
657
+ emptyIds.push(entry);
658
+ continue;
659
+ }
660
+ const existing = seenIds.get(entry.nodeId);
661
+ if (existing) {
662
+ if (!duplicateIds.includes(existing)) duplicateIds.push(existing);
663
+ duplicateIds.push(entry);
664
+ } else seenIds.set(entry.nodeId, entry);
665
+ }
666
+ if (emptyIds.length === 0 && duplicateIds.length === 0) return;
667
+ const lines = ["WorkflowBuilder.build() found invalid node ids:"];
668
+ if (emptyIds.length > 0) {
669
+ lines.push(" Empty ids (label is blank and no explicit id was given):");
670
+ for (const e of emptyIds) lines.push(` - type "${e.tokenName}" label "${e.label}"`);
671
+ }
672
+ if (duplicateIds.length > 0) {
673
+ lines.push(" Duplicate ids:");
674
+ for (const e of duplicateIds) lines.push(` - id "${e.nodeId}" type "${e.tokenName}" label "${e.label}"`);
675
+ }
676
+ lines.push(" Fix: set an explicit `id:` on each offending node config.");
677
+ throw new WorkflowDefinitionError(lines.join("\n"));
678
+ }
679
+ };
680
+
681
+ //#endregion
682
+ //#region src/workflow/definition/ConnectionInvocationIdFactory.ts
683
+ /**
684
+ * Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).
685
+ */
686
+ var ConnectionInvocationIdFactory = class {
687
+ static create() {
688
+ return `cinv_${(0, node_crypto.randomUUID)()}`;
689
+ }
690
+ /** Deterministic id for tests when a stable sequence is needed. */
691
+ static createForTest(runId, connectionNodeId, sequence) {
692
+ return `cinv_${runId}_${connectionNodeId}_${sequence}`;
693
+ }
694
+ };
695
+
696
+ //#endregion
697
+ //#region src/workflow/definition/NodeIterationIdFactory.ts
698
+ /**
699
+ * Unique ids for one per-item iteration of a runnable node's execute loop.
700
+ *
701
+ * Activations are per-batch (one scheduled execution of a node, possibly with N items).
702
+ * Iterations refine that to one identifier per item-index inside the batch loop, so per-item
703
+ * connection invocations and telemetry can be grouped without time-window heuristics.
704
+ */
705
+ var NodeIterationIdFactory = class {
706
+ static create() {
707
+ return `iter_${(0, node_crypto.randomUUID)()}`;
708
+ }
709
+ /** Deterministic id for tests when a stable sequence is needed. */
710
+ static createForTest(seed, sequence) {
711
+ return `iter_${seed}_${sequence}`;
712
+ }
713
+ /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */
714
+ static createForConnection(connectionNodeId, sequence) {
715
+ return `iter_${connectionNodeId}_${sequence}`;
716
+ }
717
+ };
718
+
285
719
  //#endregion
286
720
  //#region src/workflow/definition/WorkflowExecutableNodeClassifier.ts
287
721
  /**
@@ -342,6 +776,69 @@ var WorkflowExecutableNodeClassifierFactory = class {
342
776
  }
343
777
  };
344
778
 
779
+ //#endregion
780
+ //#region src/workflow/graph/ExecutableGraph.ts
781
+ var ExecutableGraph = class {
782
+ outgoingByNodeAndPort = /* @__PURE__ */ new Map();
783
+ constructor(def) {
784
+ for (const e of def.edges) {
785
+ const byPort = this.outgoingByNodeAndPort.get(e.from.nodeId) ?? /* @__PURE__ */ new Map();
786
+ const next = byPort.get(e.from.output) ?? [];
787
+ next.push({
788
+ nodeId: e.to.nodeId,
789
+ input: e.to.input
790
+ });
791
+ byPort.set(e.from.output, next);
792
+ this.outgoingByNodeAndPort.set(e.from.nodeId, byPort);
793
+ }
794
+ }
795
+ next(nodeId, output) {
796
+ return this.outgoingByNodeAndPort.get(nodeId)?.get(output) ?? [];
797
+ }
798
+ };
799
+
800
+ //#endregion
801
+ //#region src/workflow/graph/DefaultWorkflowGraphFactory.ts
802
+ var DefaultWorkflowGraphFactory = class {
803
+ create(def) {
804
+ return new ExecutableGraph(def);
805
+ }
806
+ };
807
+
808
+ //#endregion
809
+ //#region src/events/ConnectionInvocationEventPublisher.ts
810
+ /**
811
+ * Publishes per-invocation lifecycle records onto the run {@link RunEventBus}.
812
+ *
813
+ * Surgical, per-invocation events let the UI update the right-side inspector
814
+ * timeline as each LLM round / tool call transitions through `running` → `completed`
815
+ * (or `failed`) without depending on a coarse `runSaved` poll.
816
+ */
817
+ var ConnectionInvocationEventPublisher = class {
818
+ constructor(eventBus, parent) {
819
+ this.eventBus = eventBus;
820
+ this.parent = parent;
821
+ }
822
+ async publish(record) {
823
+ if (!this.eventBus) return;
824
+ const kind = this.kindFor(record);
825
+ if (!kind) return;
826
+ await this.eventBus.publish({
827
+ kind,
828
+ runId: record.runId,
829
+ workflowId: record.workflowId,
830
+ parent: this.parent,
831
+ at: record.updatedAt,
832
+ record
833
+ });
834
+ }
835
+ kindFor(record) {
836
+ if (record.status === "running" || record.status === "queued") return "connectionInvocationStarted";
837
+ if (record.status === "completed") return "connectionInvocationCompleted";
838
+ if (record.status === "failed") return "connectionInvocationFailed";
839
+ }
840
+ };
841
+
345
842
  //#endregion
346
843
  //#region src/events/NodeEventPublisher.ts
347
844
  /** Publishes node lifecycle snapshots onto the run {@link RunEventBus}. */
@@ -660,6 +1157,48 @@ var ActivationEnqueueService = class {
660
1157
  }
661
1158
  };
662
1159
 
1160
+ //#endregion
1161
+ //#region src/execution/ChildExecutionScopeFactory.ts
1162
+ /**
1163
+ * Builds a re-rooted child execution context for sub-agent (and other deeply-nested) invocations.
1164
+ *
1165
+ * At the orchestrator's `agent.tool.call` boundary the inner runtime needs a ctx whose:
1166
+ * - `nodeId` is the tool's connection node id (so inner LLM/tool connection ids derive correctly),
1167
+ * - `activationId` is fresh (so its connection-invocation rows are uniquely identifiable),
1168
+ * - `telemetry` parents children under the tool-call span (not the orchestrator's node span),
1169
+ * - `binary` is scoped to the new (nodeId, activationId),
1170
+ * - `parentInvocationId` points back to the tool-call invocation for downstream lineage.
1171
+ *
1172
+ * Registered via factory in {@link EngineRuntimeRegistrar} so constructors stay free of parameter
1173
+ * decorators (Next/SWC and coverage tooling cannot parse them on in-repo sources).
1174
+ */
1175
+ var ChildExecutionScopeFactory = class {
1176
+ constructor(activationIdFactory) {
1177
+ this.activationIdFactory = activationIdFactory;
1178
+ }
1179
+ forSubAgent(args) {
1180
+ const childActivationId = this.activationIdFactory.makeActivationId();
1181
+ const childTelemetry = args.parentSpan.asNodeTelemetry({
1182
+ nodeId: args.childNodeId,
1183
+ activationId: childActivationId
1184
+ });
1185
+ const childBinary = args.parentCtx.binary.forNode({
1186
+ nodeId: args.childNodeId,
1187
+ activationId: childActivationId
1188
+ });
1189
+ return {
1190
+ ...args.parentCtx,
1191
+ nodeId: args.childNodeId,
1192
+ activationId: childActivationId,
1193
+ config: args.childConfig,
1194
+ telemetry: childTelemetry,
1195
+ binary: childBinary,
1196
+ parentInvocationId: args.parentInvocationId,
1197
+ iterationId: void 0
1198
+ };
1199
+ }
1200
+ };
1201
+
663
1202
  //#endregion
664
1203
  //#region src/contracts/itemMeta.ts
665
1204
  /**
@@ -800,6 +1339,20 @@ var NodeActivationRequestInputPreparer = class {
800
1339
  }
801
1340
  };
802
1341
 
1342
+ //#endregion
1343
+ //#region src/execution/NodeInstantiationError.ts
1344
+ var NodeInstantiationError = class extends Error {
1345
+ name = "NodeInstantiationError";
1346
+ originalError;
1347
+ constructor(nodeId, nodeType, originalError) {
1348
+ super(`Failed to instantiate node "${nodeId}" (type ${nodeType}): ${originalError.message}`);
1349
+ this.nodeId = nodeId;
1350
+ this.nodeType = nodeType;
1351
+ this.originalError = originalError;
1352
+ this.stack = originalError.stack;
1353
+ }
1354
+ };
1355
+
803
1356
  //#endregion
804
1357
  //#region src/execution/CredentialResolverFactory.ts
805
1358
  var CredentialResolverFactory = class {
@@ -960,31 +1513,54 @@ var NoOpTelemetryArtifactReference = class {
960
1513
 
961
1514
  //#endregion
962
1515
  //#region src/contracts/NoOpTelemetrySpanScope.ts
1516
+ /**
1517
+ * Standalone no-op {@link NodeExecutionTelemetry} value used as the return for `asNodeTelemetry`.
1518
+ *
1519
+ * Defined here (instead of in `NoOpNodeExecutionTelemetry.ts`) so that {@link NoOpTelemetrySpanScope}
1520
+ * can return it without importing the other module — both no-ops share this leaf.
1521
+ */
1522
+ const noOpNodeExecutionTelemetry = {
1523
+ traceId: "00000000000000000000000000000000",
1524
+ spanId: "0000000000000000",
1525
+ addSpanEvent(_) {},
1526
+ recordMetric(_) {},
1527
+ attachArtifact(_) {
1528
+ return NoOpTelemetryArtifactReference.value;
1529
+ },
1530
+ end(_ = {}) {},
1531
+ asNodeTelemetry(_) {
1532
+ return noOpNodeExecutionTelemetry;
1533
+ },
1534
+ forNode(_) {
1535
+ return noOpNodeExecutionTelemetry;
1536
+ },
1537
+ startChildSpan(_) {
1538
+ return noOpTelemetrySpanScope;
1539
+ }
1540
+ };
1541
+ const noOpTelemetrySpanScope = {
1542
+ traceId: "00000000000000000000000000000000",
1543
+ spanId: "0000000000000000",
1544
+ addSpanEvent(_) {},
1545
+ recordMetric(_) {},
1546
+ attachArtifact(_) {
1547
+ return NoOpTelemetryArtifactReference.value;
1548
+ },
1549
+ end(_ = {}) {},
1550
+ asNodeTelemetry(_) {
1551
+ return noOpNodeExecutionTelemetry;
1552
+ }
1553
+ };
963
1554
  var NoOpTelemetrySpanScope = class {
964
- static value = {
965
- traceId: "00000000000000000000000000000000",
966
- spanId: "0000000000000000",
967
- addSpanEvent(_) {},
968
- recordMetric(_) {},
969
- attachArtifact(_) {
970
- return NoOpTelemetryArtifactReference.value;
971
- },
972
- end(_ = {}) {}
973
- };
1555
+ static value = noOpTelemetrySpanScope;
1556
+ /** Internal: the shared no-op {@link NodeExecutionTelemetry} that {@link NoOpNodeExecutionTelemetry} re-exposes. */
1557
+ static nodeExecutionTelemetryValue = noOpNodeExecutionTelemetry;
974
1558
  };
975
1559
 
976
1560
  //#endregion
977
1561
  //#region src/contracts/NoOpNodeExecutionTelemetry.ts
978
- var NoOpNodeExecutionTelemetry = class NoOpNodeExecutionTelemetry {
979
- static value = {
980
- ...NoOpTelemetrySpanScope.value,
981
- forNode(_) {
982
- return NoOpNodeExecutionTelemetry.value;
983
- },
984
- startChildSpan(_) {
985
- return NoOpTelemetrySpanScope.value;
986
- }
987
- };
1562
+ var NoOpNodeExecutionTelemetry = class {
1563
+ static value = NoOpTelemetrySpanScope.nodeExecutionTelemetryValue;
988
1564
  };
989
1565
 
990
1566
  //#endregion
@@ -1012,6 +1588,28 @@ var NoOpExecutionTelemetryFactory = class {
1012
1588
  }
1013
1589
  };
1014
1590
 
1591
+ //#endregion
1592
+ //#region src/contracts/runFinishedAtFactory.ts
1593
+ /** Derives workflow end time from persisted run root or node snapshots for run listings. */
1594
+ var RunFinishedAtFactory = class {
1595
+ static resolveIso(state) {
1596
+ if (state.finishedAt && state.status !== "running" && state.status !== "pending") return state.finishedAt;
1597
+ if (state.status === "running" || state.status === "pending") return;
1598
+ let max;
1599
+ for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
1600
+ return max;
1601
+ }
1602
+ };
1603
+
1604
+ //#endregion
1605
+ //#region src/contracts/workflowActivationPolicy.ts
1606
+ /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
1607
+ var AllWorkflowsActiveWorkflowActivationPolicy = class {
1608
+ isActive(_workflowId) {
1609
+ return true;
1610
+ }
1611
+ };
1612
+
1015
1613
  //#endregion
1016
1614
  //#region src/contracts/CodemationTelemetryAttributeNames.ts
1017
1615
  var CodemationTelemetryAttributeNames = class {
@@ -1025,6 +1623,12 @@ var CodemationTelemetryAttributeNames = class {
1025
1623
  static connectionInvocationId = "codemation.connection.invocation_id";
1026
1624
  static toolName = "codemation.tool.name";
1027
1625
  static traceParentRunId = "codemation.parent.run.id";
1626
+ /** Per-item iteration that emitted this span/metric. Set on spans recorded inside a runnable per-item loop. */
1627
+ static iterationId = "codemation.iteration.id";
1628
+ /** Item index (0-based) of the iteration. */
1629
+ static iterationIndex = "codemation.iteration.index";
1630
+ /** Set when this span/metric was recorded under a sub-agent triggered by an outer LLM/tool call. */
1631
+ static parentInvocationId = "codemation.parent.invocation_id";
1028
1632
  };
1029
1633
 
1030
1634
  //#endregion
@@ -1050,19 +1654,6 @@ var CodemationTelemetryMetricNames = class {
1050
1654
  static gmailAttachmentBytes = "codemation.gmail.attachment_bytes";
1051
1655
  };
1052
1656
 
1053
- //#endregion
1054
- //#region src/contracts/runFinishedAtFactory.ts
1055
- /** Derives workflow end time from persisted run root or node snapshots for run listings. */
1056
- var RunFinishedAtFactory = class {
1057
- static resolveIso(state) {
1058
- if (state.finishedAt && state.status !== "running" && state.status !== "pending") return state.finishedAt;
1059
- if (state.status === "running" || state.status === "pending") return;
1060
- let max;
1061
- for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
1062
- return max;
1063
- }
1064
- };
1065
-
1066
1657
  //#endregion
1067
1658
  //#region src/contracts/workflowTypes.ts
1068
1659
  function nodeRef(nodeId) {
@@ -1070,15 +1661,6 @@ function nodeRef(nodeId) {
1070
1661
  }
1071
1662
  const branchRef = (index) => `$${index}`;
1072
1663
 
1073
- //#endregion
1074
- //#region src/contracts/workflowActivationPolicy.ts
1075
- /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
1076
- var AllWorkflowsActiveWorkflowActivationPolicy = class {
1077
- isActive(_workflowId) {
1078
- return true;
1079
- }
1080
- };
1081
-
1082
1664
  //#endregion
1083
1665
  //#region src/execution/ExecutionTelemetryCostTrackingDecoratorFactory.ts
1084
1666
  var ExecutionTelemetryCostTrackingDecoratorFactory = class {
@@ -1118,6 +1700,13 @@ var ExecutionTelemetryCostTrackingDecoratorFactory = class {
1118
1700
  telemetry: nodeTelemetry,
1119
1701
  costTracking: args.costTracking.forScope(nodeTelemetry)
1120
1702
  });
1703
+ },
1704
+ asNodeTelemetry: (rescope) => {
1705
+ const nodeTelemetry = args.telemetry.asNodeTelemetry(rescope);
1706
+ return this.decorateNodeExecutionTelemetry({
1707
+ telemetry: nodeTelemetry,
1708
+ costTracking: args.costTracking.forScope(nodeTelemetry)
1709
+ });
1121
1710
  }
1122
1711
  };
1123
1712
  }
@@ -1129,7 +1718,14 @@ var ExecutionTelemetryCostTrackingDecoratorFactory = class {
1129
1718
  addSpanEvent: (event) => args.scope.addSpanEvent(event),
1130
1719
  recordMetric: (metric) => args.scope.recordMetric(metric),
1131
1720
  attachArtifact: (artifact) => args.scope.attachArtifact(artifact),
1132
- end: (endArgs) => args.scope.end(endArgs)
1721
+ end: (endArgs) => args.scope.end(endArgs),
1722
+ asNodeTelemetry: (rescope) => {
1723
+ const nodeTelemetry = args.scope.asNodeTelemetry(rescope);
1724
+ return this.decorateNodeExecutionTelemetry({
1725
+ telemetry: nodeTelemetry,
1726
+ costTracking: args.costTracking.forScope(nodeTelemetry)
1727
+ });
1728
+ }
1133
1729
  };
1134
1730
  }
1135
1731
  };
@@ -1138,11 +1734,12 @@ var ExecutionTelemetryCostTrackingDecoratorFactory = class {
1138
1734
  //#region src/execution/DefaultExecutionContextFactory.ts
1139
1735
  var DefaultExecutionContextFactory = class {
1140
1736
  telemetryDecoratorFactory = new ExecutionTelemetryCostTrackingDecoratorFactory();
1141
- constructor(binaryStorage = new UnavailableBinaryStorage(), telemetryFactory = new NoOpExecutionTelemetryFactory(), costTrackingFactory = new NoOpCostTrackingTelemetryFactory(), currentDate = () => /* @__PURE__ */ new Date()) {
1737
+ constructor(binaryStorage = new UnavailableBinaryStorage(), telemetryFactory = new NoOpExecutionTelemetryFactory(), costTrackingFactory = new NoOpCostTrackingTelemetryFactory(), currentDate = () => /* @__PURE__ */ new Date(), collections) {
1142
1738
  this.binaryStorage = binaryStorage;
1143
1739
  this.telemetryFactory = telemetryFactory;
1144
1740
  this.costTrackingFactory = costTrackingFactory;
1145
1741
  this.currentDate = currentDate;
1742
+ this.collections = collections;
1146
1743
  }
1147
1744
  create(args) {
1148
1745
  const baseTelemetry = args.telemetry ?? this.telemetryFactory.create({
@@ -1167,7 +1764,9 @@ var DefaultExecutionContextFactory = class {
1167
1764
  nodeState: args.nodeState,
1168
1765
  telemetry,
1169
1766
  binary: new DefaultExecutionBinaryService(this.binaryStorage, args.workflowId, args.runId, this.currentDate),
1170
- getCredential: args.getCredential
1767
+ getCredential: args.getCredential,
1768
+ testContext: args.testContext,
1769
+ collections: this.collections
1171
1770
  };
1172
1771
  }
1173
1772
  };
@@ -1600,13 +2199,17 @@ var NodeExecutor = class {
1600
2199
  const parsed = inputSchema.parse(item.json);
1601
2200
  const runnableCtx = request.ctx;
1602
2201
  const resolvedCtx = await this.itemExprResolver.resolveConfigForItem(runnableCtx, item, i, inputBatch);
1603
- const ctx = this.pickExecutionContext(runnableCtx, resolvedCtx);
2202
+ const iterationCtx = {
2203
+ ...this.pickExecutionContext(runnableCtx, resolvedCtx),
2204
+ iterationId: NodeIterationIdFactory.create(),
2205
+ itemIndex: i
2206
+ };
1604
2207
  const args = {
1605
2208
  input: parsed,
1606
2209
  item,
1607
2210
  itemIndex: i,
1608
2211
  items: inputBatch,
1609
- ctx
2212
+ ctx: iterationCtx
1610
2213
  };
1611
2214
  const raw = await Promise.resolve(node$1.execute(args));
1612
2215
  const normalized = this.outputNormalizer.normalizeExecuteResult({
@@ -2000,7 +2603,12 @@ var NodeInstanceFactory = class {
2000
2603
  }
2001
2604
  createNodes(workflow) {
2002
2605
  const nodeInstances = /* @__PURE__ */ new Map();
2003
- for (const definition of workflow.nodes) nodeInstances.set(definition.id, this.createNode(definition));
2606
+ for (const definition of workflow.nodes) try {
2607
+ nodeInstances.set(definition.id, this.createNode(definition));
2608
+ } catch (err) {
2609
+ if (err instanceof NodeInstantiationError) throw err;
2610
+ throw new NodeInstantiationError(definition.id, typeof definition.type === "function" ? definition.type.name : String(definition.type), err instanceof Error ? err : new Error(String(err)));
2611
+ }
2004
2612
  return nodeInstances;
2005
2613
  }
2006
2614
  createNode(definition) {
@@ -2025,12 +2633,13 @@ var NodeInstanceFactoryFactory = class {
2025
2633
  //#region src/execution/NodeRunStateWriter.ts
2026
2634
  var NodeRunStateWriter = class {
2027
2635
  chain = Promise.resolve();
2028
- constructor(workflowExecutionRepository, runId, workflowId, parent, publishNodeEvent) {
2636
+ constructor(workflowExecutionRepository, runId, workflowId, parent, publishNodeEvent, publishConnectionInvocationEvent) {
2029
2637
  this.workflowExecutionRepository = workflowExecutionRepository;
2030
2638
  this.runId = runId;
2031
2639
  this.workflowId = workflowId;
2032
2640
  this.parent = parent;
2033
2641
  this.publishNodeEvent = publishNodeEvent;
2642
+ this.publishConnectionInvocationEvent = publishConnectionInvocationEvent;
2034
2643
  }
2035
2644
  markQueued(args) {
2036
2645
  return this.enqueue(async () => {
@@ -2127,12 +2736,16 @@ var NodeRunStateWriter = class {
2127
2736
  queuedAt: args.queuedAt,
2128
2737
  startedAt: args.startedAt,
2129
2738
  finishedAt: args.finishedAt,
2130
- updatedAt
2739
+ updatedAt,
2740
+ iterationId: args.iterationId,
2741
+ itemIndex: args.itemIndex,
2742
+ parentInvocationId: args.parentInvocationId
2131
2743
  };
2132
2744
  await this.workflowExecutionRepository.save({
2133
2745
  ...state,
2134
2746
  connectionInvocations: [...state.connectionInvocations ?? [], record]
2135
2747
  });
2748
+ if (this.publishConnectionInvocationEvent) await this.publishConnectionInvocationEvent(record);
2136
2749
  });
2137
2750
  }
2138
2751
  enqueue(work) {
@@ -2159,13 +2772,17 @@ var NodeRunStateWriter = class {
2159
2772
  //#endregion
2160
2773
  //#region src/execution/NodeRunStateWriterFactory.ts
2161
2774
  var NodeRunStateWriterFactory = class {
2162
- constructor(workflowExecutionRepository, nodeEventPublisher) {
2775
+ constructor(workflowExecutionRepository, nodeEventPublisher, eventBus) {
2163
2776
  this.workflowExecutionRepository = workflowExecutionRepository;
2164
2777
  this.nodeEventPublisher = nodeEventPublisher;
2778
+ this.eventBus = eventBus;
2165
2779
  }
2166
2780
  create(runId, workflowId, parent) {
2781
+ const connectionInvocationEventPublisher = new ConnectionInvocationEventPublisher(this.eventBus, parent);
2167
2782
  return new NodeRunStateWriter(this.workflowExecutionRepository, runId, workflowId, parent, async (kind, snapshot) => {
2168
2783
  await this.nodeEventPublisher.publish(kind, snapshot);
2784
+ }, async (record) => {
2785
+ await connectionInvocationEventPublisher.publish(record);
2169
2786
  });
2170
2787
  }
2171
2788
  };
@@ -2290,7 +2907,8 @@ var WorkflowRunExecutionContextFactory = class {
2290
2907
  engineMaxSubworkflowDepth: args.engineMaxSubworkflowDepth,
2291
2908
  data: args.data,
2292
2909
  nodeState: args.nodeState,
2293
- getCredential: this.credentialResolverFactory.create(args.workflowId, args.nodeId)
2910
+ getCredential: this.credentialResolverFactory.create(args.workflowId, args.nodeId),
2911
+ testContext: args.testContext
2294
2912
  });
2295
2913
  }
2296
2914
  };
@@ -2457,7 +3075,8 @@ var RunContinuationService = class {
2457
3075
  engineMaxNodeActivations: limits.engineMaxNodeActivations,
2458
3076
  engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
2459
3077
  data,
2460
- nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
3078
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent),
3079
+ testContext: state.executionOptions?.testContext
2461
3080
  });
2462
3081
  data.setOutputs(args.nodeId, args.outputs);
2463
3082
  const completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -2978,7 +3597,8 @@ var RunContinuationService = class {
2978
3597
  engineMaxNodeActivations: webhookLimits.engineMaxNodeActivations,
2979
3598
  engineMaxSubworkflowDepth: webhookLimits.engineMaxSubworkflowDepth,
2980
3599
  data,
2981
- nodeState: this.nodeStatePublisherFactory.create(args.state.runId, args.state.workflowId, args.state.parent)
3600
+ nodeState: this.nodeStatePublisherFactory.create(args.state.runId, args.state.workflowId, args.state.parent),
3601
+ testContext: args.state.executionOptions?.testContext
2982
3602
  });
2983
3603
  const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
2984
3604
  next,
@@ -3069,7 +3689,8 @@ var RunContinuationService = class {
3069
3689
  engineMaxNodeActivations: limits.engineMaxNodeActivations,
3070
3690
  engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
3071
3691
  data,
3072
- nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
3692
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent),
3693
+ testContext: state.executionOptions?.testContext
3073
3694
  });
3074
3695
  const activationId = pendingExecution.activationId;
3075
3696
  return {
@@ -3461,7 +4082,7 @@ var RunPolicySnapshotFactory = class {
3461
4082
  //#endregion
3462
4083
  //#region src/orchestration/RunStartService.ts
3463
4084
  var RunStartService = class {
3464
- constructor(runIdFactory, workflowExecutionRepository, runDataFactory, workflowSnapshotFactory, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, workflowPolicyRuntimeDefaults, executionLimitsPolicy) {
4085
+ constructor(runIdFactory, workflowExecutionRepository, runDataFactory, workflowSnapshotFactory, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, workflowPolicyRuntimeDefaults, executionLimitsPolicy, nodeEventPublisher, persistedRunStateTerminalBuilder) {
3465
4086
  this.runIdFactory = runIdFactory;
3466
4087
  this.workflowExecutionRepository = workflowExecutionRepository;
3467
4088
  this.runDataFactory = runDataFactory;
@@ -3475,6 +4096,8 @@ var RunStartService = class {
3475
4096
  this.waiters = waiters;
3476
4097
  this.workflowPolicyRuntimeDefaults = workflowPolicyRuntimeDefaults;
3477
4098
  this.executionLimitsPolicy = executionLimitsPolicy;
4099
+ this.nodeEventPublisher = nodeEventPublisher;
4100
+ this.persistedRunStateTerminalBuilder = persistedRunStateTerminalBuilder;
3478
4101
  }
3479
4102
  async runWorkflow(workflow, startAt, items, parent, executionOptions, persistedStateOverrides) {
3480
4103
  const runId = this.runIdFactory.makeRunId();
@@ -3505,9 +4128,28 @@ var RunStartService = class {
3505
4128
  engineMaxNodeActivations: mergedExecutionOptions.maxNodeActivations,
3506
4129
  engineMaxSubworkflowDepth: mergedExecutionOptions.maxSubworkflowDepth,
3507
4130
  data,
3508
- nodeState: this.nodeStatePublisherFactory.create(runId, workflow.id, parent)
4131
+ nodeState: this.nodeStatePublisherFactory.create(runId, workflow.id, parent),
4132
+ testContext: mergedExecutionOptions.testContext
3509
4133
  });
3510
- const { topology, planner } = this.planningFactory.create(workflow);
4134
+ let planning;
4135
+ try {
4136
+ planning = this.planningFactory.create(workflow);
4137
+ } catch (err) {
4138
+ if (err instanceof NodeInstantiationError) return await this.failRunDuringPlanning({
4139
+ runId,
4140
+ workflowId: workflow.id,
4141
+ startedAt,
4142
+ parent,
4143
+ executionOptions: mergedExecutionOptions,
4144
+ control: void 0,
4145
+ workflowSnapshot,
4146
+ mutableState,
4147
+ policySnapshot,
4148
+ err
4149
+ });
4150
+ throw err;
4151
+ }
4152
+ const { topology, planner } = planning;
3511
4153
  const startDefinition = topology.defsById.get(startAt);
3512
4154
  if (!startDefinition) throw new Error(`Unknown start nodeId: ${startAt}`);
3513
4155
  const initialNodeSnapshotsByNodeId = {};
@@ -3586,7 +4228,25 @@ var RunStartService = class {
3586
4228
  policySnapshot,
3587
4229
  engineCounters: { completedNodeActivations: 0 }
3588
4230
  });
3589
- const { topology, planner } = this.planningFactory.create(request.workflow);
4231
+ let planningFromState;
4232
+ try {
4233
+ planningFromState = this.planningFactory.create(request.workflow);
4234
+ } catch (err) {
4235
+ if (err instanceof NodeInstantiationError) return await this.failRunDuringPlanning({
4236
+ runId,
4237
+ workflowId: request.workflow.id,
4238
+ startedAt,
4239
+ parent: request.parent,
4240
+ executionOptions: mergedExecutionOptions,
4241
+ control,
4242
+ workflowSnapshot,
4243
+ mutableState,
4244
+ policySnapshot,
4245
+ err
4246
+ });
4247
+ throw err;
4248
+ }
4249
+ const { topology, planner } = planningFromState;
3590
4250
  const plan = CurrentStateFrontierPlanner.createFromTopology(topology).plan({
3591
4251
  currentState: this.createRunCurrentState(request.currentState, mutableState),
3592
4252
  stopCondition: control.stopCondition,
@@ -3604,7 +4264,8 @@ var RunStartService = class {
3604
4264
  engineMaxNodeActivations: mergedExecutionOptions.maxNodeActivations,
3605
4265
  engineMaxSubworkflowDepth: mergedExecutionOptions.maxSubworkflowDepth,
3606
4266
  data,
3607
- nodeState: this.nodeStatePublisherFactory.create(runId, request.workflow.id, request.parent)
4267
+ nodeState: this.nodeStatePublisherFactory.create(runId, request.workflow.id, request.parent),
4268
+ testContext: mergedExecutionOptions.testContext
3608
4269
  });
3609
4270
  return await this.scheduleInitialPlan({
3610
4271
  runId,
@@ -3626,7 +4287,7 @@ var RunStartService = class {
3626
4287
  return {
3627
4288
  outputsByNode: { ...currentState?.outputsByNode ?? {} },
3628
4289
  nodeSnapshotsByNodeId: { ...currentState?.nodeSnapshotsByNodeId ?? {} },
3629
- connectionInvocations: currentState?.connectionInvocations ? [...currentState.connectionInvocations] : void 0,
4290
+ connectionInvocations: [],
3630
4291
  mutableState: mutableState ?? currentState?.mutableState
3631
4292
  };
3632
4293
  }
@@ -3779,6 +4440,57 @@ var RunStartService = class {
3779
4440
  this.waiters.resolveRunCompletion(result);
3780
4441
  return result;
3781
4442
  }
4443
+ async failRunDuringPlanning(args) {
4444
+ const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
4445
+ const failedSnapshot = NodeExecutionSnapshotFactory.failed({
4446
+ previous: void 0,
4447
+ runId: args.runId,
4448
+ workflowId: args.workflowId,
4449
+ nodeId: args.err.nodeId,
4450
+ activationId: "planning_failure",
4451
+ parent: args.parent,
4452
+ finishedAt,
4453
+ inputsByPort: {},
4454
+ error: args.err
4455
+ });
4456
+ const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
4457
+ state: {
4458
+ runId: args.runId,
4459
+ workflowId: args.workflowId,
4460
+ startedAt: args.startedAt,
4461
+ parent: args.parent,
4462
+ executionOptions: args.executionOptions,
4463
+ control: args.control,
4464
+ workflowSnapshot: args.workflowSnapshot,
4465
+ mutableState: args.mutableState,
4466
+ policySnapshot: args.policySnapshot,
4467
+ engineCounters: { completedNodeActivations: 0 },
4468
+ status: "pending",
4469
+ pending: void 0,
4470
+ queue: [],
4471
+ outputsByNode: {},
4472
+ nodeSnapshotsByNodeId: {},
4473
+ connectionInvocations: []
4474
+ },
4475
+ engineCounters: { completedNodeActivations: 0 },
4476
+ status: "failed",
4477
+ queue: [],
4478
+ outputsByNode: {},
4479
+ nodeSnapshotsByNodeId: { [args.err.nodeId]: failedSnapshot },
4480
+ finishedAtIso: finishedAt
4481
+ });
4482
+ await this.workflowExecutionRepository.save(failedState);
4483
+ await this.nodeEventPublisher.publish("nodeFailed", failedSnapshot);
4484
+ const result = {
4485
+ runId: args.runId,
4486
+ workflowId: args.workflowId,
4487
+ startedAt: args.startedAt,
4488
+ status: "failed",
4489
+ error: { message: args.err.message }
4490
+ };
4491
+ this.waiters.resolveRunCompletion(result);
4492
+ return result;
4493
+ }
3782
4494
  };
3783
4495
 
3784
4496
  //#endregion
@@ -4252,6 +4964,128 @@ var InMemoryRunDataFactory = class {
4252
4964
  }
4253
4965
  };
4254
4966
 
4967
+ //#endregion
4968
+ //#region src/triggers/polling/PollingTriggerDedupWindow.ts
4969
+ /**
4970
+ * Merges processed-ID windows for polling triggers, capping the total to avoid unbounded growth.
4971
+ * Plugin code receives an instance of this class via {@link PollingTriggerHandle.dedup}.
4972
+ */
4973
+ var PollingTriggerDedupWindow = class PollingTriggerDedupWindow {
4974
+ static defaultCapN = 2e3;
4975
+ merge(previous, incoming, capN = PollingTriggerDedupWindow.defaultCapN) {
4976
+ const merged = new Set(previous);
4977
+ for (const id of incoming) merged.add(id);
4978
+ const result = [...merged];
4979
+ if (result.length <= capN) return result;
4980
+ return result.slice(result.length - capN);
4981
+ }
4982
+ };
4983
+
4984
+ //#endregion
4985
+ //#region src/triggers/polling/PollingTriggerRuntime.ts
4986
+ /**
4987
+ * Generic polling-trigger runtime. Owns the set-interval loop, overlap guard, and persistence.
4988
+ * Constructed by {@link import("../../runtime/EngineFactory").EngineFactory} and exposed to plugin
4989
+ * authors via {@link import("../../contracts/runtimeTypes").TriggerSetupContext}.polling.
4990
+ */
4991
+ var PollingTriggerRuntime = class {
4992
+ activeTriggers = /* @__PURE__ */ new Set();
4993
+ intervalsByTrigger = /* @__PURE__ */ new Map();
4994
+ busyTriggers = /* @__PURE__ */ new Set();
4995
+ constructor(triggerSetupStateRepository, logger) {
4996
+ this.triggerSetupStateRepository = triggerSetupStateRepository;
4997
+ this.logger = logger;
4998
+ }
4999
+ async start(args) {
5000
+ let first;
5001
+ try {
5002
+ first = await this.runCycle(args, { seedState: args.seedState });
5003
+ } catch (err) {
5004
+ this.logError(`Polling trigger initial cycle failed for ${this.describe(args.trigger)}`, err);
5005
+ }
5006
+ this.ensureLoop(args);
5007
+ return first;
5008
+ }
5009
+ async stop(trigger) {
5010
+ const key = this.toKey(trigger);
5011
+ const interval = this.intervalsByTrigger.get(key);
5012
+ if (interval !== void 0) {
5013
+ clearInterval(interval);
5014
+ this.intervalsByTrigger.delete(key);
5015
+ }
5016
+ this.busyTriggers.delete(key);
5017
+ this.activeTriggers.delete(key);
5018
+ this.logger.debug(`Polling trigger stopped for ${this.describe(trigger)}`);
5019
+ }
5020
+ ensureLoop(args) {
5021
+ const key = this.toKey(args.trigger);
5022
+ if (this.activeTriggers.has(key)) {
5023
+ this.logger.debug(`Polling trigger already active for ${this.describe(args.trigger)}`);
5024
+ return;
5025
+ }
5026
+ this.activeTriggers.add(key);
5027
+ const intervalMs = Math.max(args.intervalMs, 25);
5028
+ const interval = setInterval(() => {
5029
+ this.runCycle(args, { seedState: void 0 }).catch((err) => {
5030
+ this.logError(`Polling trigger cycle failed for ${this.describe(args.trigger)}`, err);
5031
+ });
5032
+ }, intervalMs);
5033
+ this.intervalsByTrigger.set(key, interval);
5034
+ this.logger.info(`Polling trigger started for ${this.describe(args.trigger)} (interval ${intervalMs}ms)`);
5035
+ }
5036
+ async runCycle(args, opts) {
5037
+ const key = this.toKey(args.trigger);
5038
+ if (this.busyTriggers.has(key)) {
5039
+ this.logger.debug(`Polling trigger skipping overlapping tick for ${this.describe(args.trigger)}`);
5040
+ return;
5041
+ }
5042
+ this.busyTriggers.add(key);
5043
+ try {
5044
+ const loaded = await this.triggerSetupStateRepository.load(args.trigger);
5045
+ const previousState = loaded !== void 0 ? loaded.state : opts.seedState;
5046
+ const controller = new AbortController();
5047
+ const { items, nextState } = await args.runCycle({
5048
+ previousState,
5049
+ signal: controller.signal
5050
+ });
5051
+ await this.triggerSetupStateRepository.save({
5052
+ trigger: args.trigger,
5053
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
5054
+ state: nextState
5055
+ });
5056
+ if (items.length > 0) {
5057
+ this.logger.info(`Polling trigger emitting ${items.length} item(s) for ${this.describe(args.trigger)}`);
5058
+ await args.emit(items);
5059
+ }
5060
+ return nextState;
5061
+ } finally {
5062
+ this.busyTriggers.delete(key);
5063
+ }
5064
+ }
5065
+ toKey(trigger) {
5066
+ return `${trigger.workflowId}:${trigger.nodeId}`;
5067
+ }
5068
+ describe(trigger) {
5069
+ return `${trigger.workflowId}.${trigger.nodeId}`;
5070
+ }
5071
+ logError(message, error) {
5072
+ if (error instanceof Error) {
5073
+ this.logger.error(message, error);
5074
+ return;
5075
+ }
5076
+ this.logger.error(`${message}: ${String(error)}`);
5077
+ }
5078
+ };
5079
+
5080
+ //#endregion
5081
+ //#region src/triggers/polling/PollingTriggerLogger.ts
5082
+ var NoOpPollingTriggerLogger = class {
5083
+ info() {}
5084
+ warn() {}
5085
+ error() {}
5086
+ debug() {}
5087
+ };
5088
+
4255
5089
  //#endregion
4256
5090
  //#region src/orchestration/NodeExecutionRequestHandlerService.ts
4257
5091
  var NodeExecutionRequestHandlerService = class {
@@ -4291,7 +5125,8 @@ var NodeExecutionRequestHandlerService = class {
4291
5125
  engineMaxNodeActivations: limits.engineMaxNodeActivations,
4292
5126
  engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
4293
5127
  data,
4294
- nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, resolvedParent)
5128
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, resolvedParent),
5129
+ testContext: state.executionOptions?.testContext
4295
5130
  });
4296
5131
  const inputsByPort = pendingExecution.inputsByPort;
4297
5132
  const portKeys = Object.keys(inputsByPort);
@@ -4681,7 +5516,7 @@ var EngineWorkflowPlanningFactory = class {
4681
5516
  var TriggerRuntimeService = class {
4682
5517
  credentialResolverFactory;
4683
5518
  triggerCleanupHandlesByKey = /* @__PURE__ */ new Map();
4684
- constructor(workflowRepository, workflowActivationPolicy, runIdFactory, runDataFactory, executionContextFactory, credentialResolverFactory, nodeExecutionStatePublisherFactory, nodeResolver, triggerSetupStateRepository, emitHandler, executionLimitsPolicy, diagnostics) {
5519
+ constructor(workflowRepository, workflowActivationPolicy, runIdFactory, runDataFactory, executionContextFactory, credentialResolverFactory, nodeExecutionStatePublisherFactory, nodeResolver, triggerSetupStateRepository, emitHandler, executionLimitsPolicy, diagnostics, pollingTriggerRuntime, pollingTriggerDedupWindow) {
4685
5520
  this.workflowRepository = workflowRepository;
4686
5521
  this.workflowActivationPolicy = workflowActivationPolicy;
4687
5522
  this.runIdFactory = runIdFactory;
@@ -4693,6 +5528,8 @@ var TriggerRuntimeService = class {
4693
5528
  this.emitHandler = emitHandler;
4694
5529
  this.executionLimitsPolicy = executionLimitsPolicy;
4695
5530
  this.diagnostics = diagnostics;
5531
+ this.pollingTriggerRuntime = pollingTriggerRuntime;
5532
+ this.pollingTriggerDedupWindow = pollingTriggerDedupWindow;
4696
5533
  this.credentialResolverFactory = credentialResolverFactory;
4697
5534
  }
4698
5535
  async startTriggers() {
@@ -4748,6 +5585,7 @@ var TriggerRuntimeService = class {
4748
5585
  async startTriggersForWorkflow(wf) {
4749
5586
  for (const def of wf.nodes) {
4750
5587
  if (def.kind !== "trigger") continue;
5588
+ if (def.config.triggerKind === "test") continue;
4751
5589
  const node$1 = this.nodeResolver.resolve(def.type);
4752
5590
  const data = this.runDataFactory.create();
4753
5591
  const triggerRunId = this.runIdFactory.makeRunId();
@@ -4757,6 +5595,9 @@ var TriggerRuntimeService = class {
4757
5595
  };
4758
5596
  await this.stopTrigger(trigger);
4759
5597
  const previousState = await this.triggerSetupStateRepository.load(trigger);
5598
+ const emit = this.emitHandler.emit.bind(this.emitHandler, wf, def.id);
5599
+ const registerCleanup = this.registerTriggerCleanupHandle.bind(this, trigger);
5600
+ const polling = this.buildPollingHandle(trigger, emit);
4760
5601
  let nextState;
4761
5602
  try {
4762
5603
  nextState = await node$1.setup({
@@ -4769,12 +5610,9 @@ var TriggerRuntimeService = class {
4769
5610
  trigger,
4770
5611
  config: def.config,
4771
5612
  previousState: previousState?.state,
4772
- registerCleanup: (cleanup) => {
4773
- this.registerTriggerCleanupHandle(trigger, cleanup);
4774
- },
4775
- emit: async (items) => {
4776
- await this.emitHandler.emit(wf, def.id, items);
4777
- }
5613
+ registerCleanup,
5614
+ emit,
5615
+ polling
4778
5616
  });
4779
5617
  } catch (triggerError) {
4780
5618
  await this.stopTrigger(trigger);
@@ -4793,6 +5631,7 @@ var TriggerRuntimeService = class {
4793
5631
  async stopTriggersForWorkflow(workflow) {
4794
5632
  for (const node$1 of workflow.nodes) {
4795
5633
  if (node$1.kind !== "trigger") continue;
5634
+ if (node$1.config.triggerKind === "test") continue;
4796
5635
  await this.stopTrigger({
4797
5636
  workflowId: workflow.id,
4798
5637
  nodeId: node$1.id
@@ -4833,6 +5672,7 @@ var TriggerRuntimeService = class {
4833
5672
  const out = [];
4834
5673
  for (const def of wf.nodes) {
4835
5674
  if (def.kind !== "trigger") continue;
5675
+ if (def.config.triggerKind === "test") continue;
4836
5676
  out.push(this.describeTriggerNode(def));
4837
5677
  }
4838
5678
  return out;
@@ -4850,6 +5690,22 @@ var TriggerRuntimeService = class {
4850
5690
  if (this.diagnostics) this.diagnostics.warn(message);
4851
5691
  else console.warn(`[engine] ${message}`);
4852
5692
  }
5693
+ buildPollingHandle(trigger, emit) {
5694
+ const runtime = this.pollingTriggerRuntime;
5695
+ return {
5696
+ dedup: this.pollingTriggerDedupWindow,
5697
+ start: async (args) => {
5698
+ this.registerTriggerCleanupHandle(trigger, { stop: async () => {
5699
+ await runtime.stop(trigger);
5700
+ } });
5701
+ return runtime.start({
5702
+ trigger,
5703
+ emit,
5704
+ ...args
5705
+ });
5706
+ }
5707
+ };
5708
+ }
4853
5709
  isTestableTriggerNode(node$1) {
4854
5710
  return typeof node$1.getTestItems === "function";
4855
5711
  }
@@ -4986,7 +5842,7 @@ var EngineFactory = class {
4986
5842
  const waiters = new EngineWaiters();
4987
5843
  const credentialResolverFactory = new CredentialResolverFactory(deps.credentialSessions);
4988
5844
  const nodeEventPublisher = new NodeEventPublisher(deps.eventBus);
4989
- const nodeStatePublisherFactory = new NodeRunStateWriterFactory(deps.workflowExecutionRepository, nodeEventPublisher);
5845
+ const nodeStatePublisherFactory = new NodeRunStateWriterFactory(deps.workflowExecutionRepository, nodeEventPublisher, deps.eventBus);
4990
5846
  const planningFactory = new EngineWorkflowPlanningFactory(deps.workflowNodeInstanceFactory);
4991
5847
  const executionLimitsPolicy = deps.executionLimitsPolicy ?? new EngineExecutionLimitsPolicy();
4992
5848
  const workflowSnapshotCodec = deps.workflowSnapshotCodec ?? new WorkflowSnapshotCodec(deps.tokenRegistry);
@@ -5001,12 +5857,15 @@ var EngineFactory = class {
5001
5857
  const storagePolicyEvaluator = new WorkflowStoragePolicyEvaluator(deps.nodeResolver);
5002
5858
  const terminalPersistence = new RunTerminalPersistenceCoordinator(deps.workflowExecutionRepository, storagePolicyEvaluator);
5003
5859
  const policyErrorServices = new WorkflowPolicyErrorServices(deps.nodeResolver);
5004
- const runStartService = new RunStartService(deps.runIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, workflowSnapshotCodec, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, deps.workflowPolicyRuntimeDefaults, executionLimitsPolicy);
5860
+ const runStartService = new RunStartService(deps.runIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, workflowSnapshotCodec, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, deps.workflowPolicyRuntimeDefaults, executionLimitsPolicy, nodeEventPublisher, persistedRunStateTerminalBuilder);
5005
5861
  const runContinuationService = new RunContinuationService(deps.activationIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy);
5006
5862
  const nodeExecutionRequestHandler = new NodeExecutionRequestHandlerService(deps.workflowExecutionRepository, workflowSnapshotResolver, deps.runDataFactory, runExecutionContextFactory, nodeStatePublisherFactory, nodeActivationRequestComposer, deps.nodeExecutor, runContinuationService, executionLimitsPolicy);
5863
+ const pollingTriggerLogger = deps.pollingTriggerLogger ?? new NoOpPollingTriggerLogger();
5864
+ const pollingTriggerDedupWindow = new PollingTriggerDedupWindow();
5865
+ const pollingTriggerRuntime = new PollingTriggerRuntime(deps.triggerSetupStateRepository, pollingTriggerLogger);
5007
5866
  const triggerRuntime = new TriggerRuntimeService(deps.workflowRepository, deps.workflowActivationPolicy, deps.runIdFactory, deps.runDataFactory, deps.executionContextFactory, credentialResolverFactory, nodeStatePublisherFactory, deps.nodeResolver, deps.triggerSetupStateRepository, { emit: async (workflow, triggerNodeId, items) => {
5008
5867
  await runStartService.runWorkflow(workflow, triggerNodeId, items, void 0);
5009
- } }, executionLimitsPolicy, deps.triggerRuntimeDiagnostics);
5868
+ } }, executionLimitsPolicy, deps.triggerRuntimeDiagnostics, pollingTriggerRuntime, pollingTriggerDedupWindow);
5010
5869
  const engine = new Engine({
5011
5870
  liveWorkflowRepository: deps.liveWorkflowRepository,
5012
5871
  tokenRegistry: deps.tokenRegistry,
@@ -5297,6 +6156,18 @@ var WorkflowRepositoryWebhookTriggerMatcherFactory = class {
5297
6156
  };
5298
6157
 
5299
6158
  //#endregion
6159
+ Object.defineProperty(exports, 'AgentConfigInspector', {
6160
+ enumerable: true,
6161
+ get: function () {
6162
+ return AgentConfigInspector;
6163
+ }
6164
+ });
6165
+ Object.defineProperty(exports, 'AgentConnectionNodeCollector', {
6166
+ enumerable: true,
6167
+ get: function () {
6168
+ return AgentConnectionNodeCollector;
6169
+ }
6170
+ });
5300
6171
  Object.defineProperty(exports, 'AllWorkflowsActiveWorkflowActivationPolicy', {
5301
6172
  enumerable: true,
5302
6173
  get: function () {
@@ -5309,6 +6180,18 @@ Object.defineProperty(exports, 'CatalogBackedCostTrackingTelemetryFactory', {
5309
6180
  return CatalogBackedCostTrackingTelemetryFactory;
5310
6181
  }
5311
6182
  });
6183
+ Object.defineProperty(exports, 'ChainCursor', {
6184
+ enumerable: true,
6185
+ get: function () {
6186
+ return ChainCursor;
6187
+ }
6188
+ });
6189
+ Object.defineProperty(exports, 'ChildExecutionScopeFactory', {
6190
+ enumerable: true,
6191
+ get: function () {
6192
+ return ChildExecutionScopeFactory;
6193
+ }
6194
+ });
5312
6195
  Object.defineProperty(exports, 'CodemationTelemetryAttributeNames', {
5313
6196
  enumerable: true,
5314
6197
  get: function () {
@@ -5327,6 +6210,18 @@ Object.defineProperty(exports, 'ConfigDrivenOffloadPolicy', {
5327
6210
  return ConfigDrivenOffloadPolicy;
5328
6211
  }
5329
6212
  });
6213
+ Object.defineProperty(exports, 'ConnectionInvocationEventPublisher', {
6214
+ enumerable: true,
6215
+ get: function () {
6216
+ return ConnectionInvocationEventPublisher;
6217
+ }
6218
+ });
6219
+ Object.defineProperty(exports, 'ConnectionInvocationIdFactory', {
6220
+ enumerable: true,
6221
+ get: function () {
6222
+ return ConnectionInvocationIdFactory;
6223
+ }
6224
+ });
5330
6225
  Object.defineProperty(exports, 'ConnectionNodeIdFactory', {
5331
6226
  enumerable: true,
5332
6227
  get: function () {
@@ -5387,6 +6282,12 @@ Object.defineProperty(exports, 'DefaultExecutionContextFactory', {
5387
6282
  return DefaultExecutionContextFactory;
5388
6283
  }
5389
6284
  });
6285
+ Object.defineProperty(exports, 'DefaultWorkflowGraphFactory', {
6286
+ enumerable: true,
6287
+ get: function () {
6288
+ return DefaultWorkflowGraphFactory;
6289
+ }
6290
+ });
5390
6291
  Object.defineProperty(exports, 'ENGINE_EXECUTION_LIMITS_DEFAULTS', {
5391
6292
  enumerable: true,
5392
6293
  get: function () {
@@ -5531,6 +6432,12 @@ Object.defineProperty(exports, 'NoOpNodeExecutionTelemetry', {
5531
6432
  return NoOpNodeExecutionTelemetry;
5532
6433
  }
5533
6434
  });
6435
+ Object.defineProperty(exports, 'NoOpPollingTriggerLogger', {
6436
+ enumerable: true,
6437
+ get: function () {
6438
+ return NoOpPollingTriggerLogger;
6439
+ }
6440
+ });
5534
6441
  Object.defineProperty(exports, 'NoOpTelemetryArtifactReference', {
5535
6442
  enumerable: true,
5536
6443
  get: function () {
@@ -5549,6 +6456,12 @@ Object.defineProperty(exports, 'NoRetryPolicy', {
5549
6456
  return NoRetryPolicy;
5550
6457
  }
5551
6458
  });
6459
+ Object.defineProperty(exports, 'NodeBackedToolConfig', {
6460
+ enumerable: true,
6461
+ get: function () {
6462
+ return NodeBackedToolConfig;
6463
+ }
6464
+ });
5552
6465
  Object.defineProperty(exports, 'NodeEventPublisher', {
5553
6466
  enumerable: true,
5554
6467
  get: function () {
@@ -5567,6 +6480,12 @@ Object.defineProperty(exports, 'NodeExecutorFactory', {
5567
6480
  return NodeExecutorFactory;
5568
6481
  }
5569
6482
  });
6483
+ Object.defineProperty(exports, 'NodeIdSlugifier', {
6484
+ enumerable: true,
6485
+ get: function () {
6486
+ return NodeIdSlugifier;
6487
+ }
6488
+ });
5570
6489
  Object.defineProperty(exports, 'NodeInstanceFactory', {
5571
6490
  enumerable: true,
5572
6491
  get: function () {
@@ -5579,6 +6498,12 @@ Object.defineProperty(exports, 'NodeInstanceFactoryFactory', {
5579
6498
  return NodeInstanceFactoryFactory;
5580
6499
  }
5581
6500
  });
6501
+ Object.defineProperty(exports, 'NodeIterationIdFactory', {
6502
+ enumerable: true,
6503
+ get: function () {
6504
+ return NodeIterationIdFactory;
6505
+ }
6506
+ });
5582
6507
  Object.defineProperty(exports, 'NodeOutputNormalizer', {
5583
6508
  enumerable: true,
5584
6509
  get: function () {
@@ -5603,6 +6528,18 @@ Object.defineProperty(exports, 'PersistedWorkflowTokenRegistry', {
5603
6528
  return PersistedWorkflowTokenRegistry;
5604
6529
  }
5605
6530
  });
6531
+ Object.defineProperty(exports, 'PollingTriggerDedupWindow', {
6532
+ enumerable: true,
6533
+ get: function () {
6534
+ return PollingTriggerDedupWindow;
6535
+ }
6536
+ });
6537
+ Object.defineProperty(exports, 'PollingTriggerRuntime', {
6538
+ enumerable: true,
6539
+ get: function () {
6540
+ return PollingTriggerRuntime;
6541
+ }
6542
+ });
5606
6543
  Object.defineProperty(exports, 'RetryPolicy', {
5607
6544
  enumerable: true,
5608
6545
  get: function () {
@@ -5663,6 +6600,24 @@ Object.defineProperty(exports, 'UnavailableBinaryStorage', {
5663
6600
  return UnavailableBinaryStorage;
5664
6601
  }
5665
6602
  });
6603
+ Object.defineProperty(exports, 'WhenBuilder', {
6604
+ enumerable: true,
6605
+ get: function () {
6606
+ return WhenBuilder;
6607
+ }
6608
+ });
6609
+ Object.defineProperty(exports, 'WorkflowBuilder', {
6610
+ enumerable: true,
6611
+ get: function () {
6612
+ return WorkflowBuilder;
6613
+ }
6614
+ });
6615
+ Object.defineProperty(exports, 'WorkflowDefinitionError', {
6616
+ enumerable: true,
6617
+ get: function () {
6618
+ return WorkflowDefinitionError;
6619
+ }
6620
+ });
5666
6621
  Object.defineProperty(exports, 'WorkflowExecutableNodeClassifier', {
5667
6622
  enumerable: true,
5668
6623
  get: function () {
@@ -5795,4 +6750,4 @@ Object.defineProperty(exports, 'tool', {
5795
6750
  return tool;
5796
6751
  }
5797
6752
  });
5798
- //# sourceMappingURL=runtime-Dvo2ru5A.cjs.map
6753
+ //# sourceMappingURL=runtime-DKXJwTNv.cjs.map