@codemation/core 0.11.0 → 0.12.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 (101) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/CostCatalogContract-DD7fQ4FF.d.cts +19 -0
  3. package/dist/{EngineRuntimeRegistration.types-MPYWsEM0.d.cts → EngineRuntimeRegistration.types-DTV5_7Jw.d.cts} +3 -2
  4. package/dist/{EngineRuntimeRegistration.types-BZ_1XWAJ.d.ts → EngineRuntimeRegistration.types-Dl92Hdoi.d.ts} +2 -2
  5. package/dist/InMemoryRunDataFactory-qMiYjhCK.d.cts +202 -0
  6. package/dist/{InMemoryRunEventBusRegistry-sM4z4n_i.js → InMemoryRunEventBusRegistry-Bwunvt1T.js} +1 -1
  7. package/dist/{InMemoryRunEventBusRegistry-sM4z4n_i.js.map → InMemoryRunEventBusRegistry-Bwunvt1T.js.map} +1 -1
  8. package/dist/{InMemoryRunEventBusRegistry-VM3OWnHo.cjs → InMemoryRunEventBusRegistry-Sa86VxuV.cjs} +1 -1
  9. package/dist/{InMemoryRunEventBusRegistry-VM3OWnHo.cjs.map → InMemoryRunEventBusRegistry-Sa86VxuV.cjs.map} +1 -1
  10. package/dist/ItemsInputNormalizer-BhuxvZh5.js +36 -0
  11. package/dist/ItemsInputNormalizer-BhuxvZh5.js.map +1 -0
  12. package/dist/ItemsInputNormalizer-C09a7iFP.d.ts +321 -0
  13. package/dist/ItemsInputNormalizer-DLaD6rTl.d.cts +407 -0
  14. package/dist/ItemsInputNormalizer-Div-fb6a.cjs +43 -0
  15. package/dist/ItemsInputNormalizer-Div-fb6a.cjs.map +1 -0
  16. package/dist/RunIntentService-BOSGwmqn.d.ts +299 -0
  17. package/dist/RunIntentService-CWMMrAP4.d.cts +220 -0
  18. package/dist/{RunIntentService-MUHJ1bhO.d.cts → agentMcpTypes-DUmniLOY.d.cts} +183 -206
  19. package/dist/bootstrap/index.cjs +4 -2
  20. package/dist/bootstrap/index.d.cts +63 -5
  21. package/dist/bootstrap/index.d.ts +5 -4
  22. package/dist/bootstrap/index.js +4 -2
  23. package/dist/{bootstrap-Dgzsjoj7.js → bootstrap-CKTMMNmL.js} +174 -3
  24. package/dist/bootstrap-CKTMMNmL.js.map +1 -0
  25. package/dist/{bootstrap-dVmpU1ju.cjs → bootstrap-D460dCgS.cjs} +209 -36
  26. package/dist/bootstrap-D460dCgS.cjs.map +1 -0
  27. package/dist/browser.cjs +17 -0
  28. package/dist/browser.d.cts +4 -0
  29. package/dist/browser.d.ts +3 -0
  30. package/dist/browser.js +4 -0
  31. package/dist/contracts-CK0x6w_G.cjs +74 -0
  32. package/dist/contracts-CK0x6w_G.cjs.map +1 -0
  33. package/dist/contracts-DXdfTdpW.js +50 -0
  34. package/dist/contracts-DXdfTdpW.js.map +1 -0
  35. package/dist/contracts.cjs +6 -0
  36. package/dist/contracts.d.cts +5 -0
  37. package/dist/contracts.d.ts +2 -0
  38. package/dist/contracts.js +3 -0
  39. package/dist/di-DdsgWfVy.js +405 -0
  40. package/dist/di-DdsgWfVy.js.map +1 -0
  41. package/dist/di-tO6R7VJV.cjs +524 -0
  42. package/dist/di-tO6R7VJV.cjs.map +1 -0
  43. package/dist/executionPersistenceContracts-DenJJK2T.d.cts +275 -0
  44. package/dist/{index-Bes88mxT.d.ts → index-BZDhEQ6W.d.ts} +278 -415
  45. package/dist/{RunIntentService-BrEq6Jm6.d.ts → index-CSKKuK60.d.ts} +441 -286
  46. package/dist/index.cjs +97 -250
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +395 -803
  49. package/dist/index.d.ts +5 -3
  50. package/dist/index.js +58 -224
  51. package/dist/index.js.map +1 -1
  52. package/dist/params-DqRvku2h.d.cts +44 -0
  53. package/dist/{runtime-Duf3ClPw.js → runtime-BPZgnZ9G.js} +591 -382
  54. package/dist/runtime-BPZgnZ9G.js.map +1 -0
  55. package/dist/{runtime-vH0EeZzH.cjs → runtime-CyW9c9XM.cjs} +651 -500
  56. package/dist/runtime-CyW9c9XM.cjs.map +1 -0
  57. package/dist/testing.cjs +23 -21
  58. package/dist/testing.cjs.map +1 -1
  59. package/dist/testing.d.cts +3 -2
  60. package/dist/testing.d.ts +3 -2
  61. package/dist/testing.js +5 -3
  62. package/dist/testing.js.map +1 -1
  63. package/package.json +9 -5
  64. package/src/ai/AgentConnectionNodeCollector.ts +1 -1
  65. package/src/authoring/defineHumanApprovalNode.types.ts +379 -0
  66. package/src/authoring/index.ts +6 -0
  67. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +29 -0
  68. package/src/contracts/CodemationTelemetryAttributeNames.ts +10 -0
  69. package/src/contracts/credentialTypes.ts +10 -0
  70. package/src/contracts/hitlSeamTypes.ts +34 -0
  71. package/src/contracts/humanTaskStoreTypes.ts +48 -0
  72. package/src/contracts/inboxChannelTypes.ts +58 -0
  73. package/src/contracts/index.ts +3 -0
  74. package/src/contracts/runTypes.ts +61 -3
  75. package/src/contracts/runtimeTypes.ts +112 -0
  76. package/src/credentials/CredentialMaterialProvider.types.ts +61 -0
  77. package/src/credentials/ManagedCredentialMaterialWriteError.ts +14 -0
  78. package/src/credentials/ManagedMaterialFetchError.ts +16 -0
  79. package/src/execution/ActivationEnqueueService.ts +16 -0
  80. package/src/execution/DefaultExecutionContextFactory.ts +11 -0
  81. package/src/execution/NodeExecutionSnapshotFactory.ts +7 -1
  82. package/src/execution/NodeExecutor.ts +60 -1
  83. package/src/execution/NodeExecutorFactory.ts +12 -2
  84. package/src/execution/NodeSuspensionHandler.ts +220 -0
  85. package/src/execution/PersistedRunStateTerminalBuilder.ts +5 -2
  86. package/src/execution/RunStateSemantics.ts +5 -0
  87. package/src/execution/RunSuspendedError.ts +21 -0
  88. package/src/index.ts +40 -0
  89. package/src/orchestration/Engine.ts +12 -2
  90. package/src/orchestration/EngineWaiters.ts +1 -1
  91. package/src/orchestration/NodeExecutionRequestHandlerService.ts +25 -2
  92. package/src/orchestration/RunContinuationService.ts +226 -2
  93. package/src/orchestration/TestSuiteOrchestrator.ts +5 -4
  94. package/src/runtime/RunIntentService.ts +3 -0
  95. package/src/workflow/dsl/ChainCursorResolver.ts +36 -0
  96. package/tsdown.config.ts +1 -1
  97. package/dist/InMemoryRunDataFactory-hmkh0lzR.d.cts +0 -138
  98. package/dist/bootstrap-Dgzsjoj7.js.map +0 -1
  99. package/dist/bootstrap-dVmpU1ju.cjs.map +0 -1
  100. package/dist/runtime-Duf3ClPw.js.map +0 -1
  101. package/dist/runtime-vH0EeZzH.cjs.map +0 -1
@@ -1,32 +1,33 @@
1
- import "reflect-metadata";
2
- import { container as container$1, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
1
+ import { C as resolveItemExprsForExecution, T as ConnectionNodeIdFactory, _ as NodeIterationIdFactory, a as injectable, b as AgentConfigInspector, g as CredentialUnboundError, h as SuspensionRequest, v as AgentConnectionNodeCollector } from "./di-DdsgWfVy.js";
3
2
  import { ZodError, z } from "zod";
4
3
  import { ReadableStream } from "node:stream/web";
5
4
  import { createHash } from "node:crypto";
6
5
 
7
- //#region src/di/CoreTokens.ts
8
- const CoreTokens = {
9
- PersistedWorkflowTokenRegistry: Symbol.for("codemation.core.PersistedWorkflowTokenRegistry"),
10
- CredentialSessionService: Symbol.for("codemation.core.CredentialSessionService"),
11
- CredentialTypeRegistry: Symbol.for("codemation.core.CredentialTypeRegistry"),
12
- WorkflowRunnerService: Symbol.for("codemation.core.WorkflowRunnerService"),
13
- LiveWorkflowRepository: Symbol.for("codemation.core.LiveWorkflowRepository"),
14
- WorkflowRepository: Symbol.for("codemation.core.WorkflowRepository"),
15
- NodeResolver: Symbol.for("codemation.core.NodeResolver"),
16
- WorkflowNodeInstanceFactory: Symbol.for("codemation.core.WorkflowNodeInstanceFactory"),
17
- RunIdFactory: Symbol.for("codemation.core.RunIdFactory"),
18
- ActivationIdFactory: Symbol.for("codemation.core.ActivationIdFactory"),
19
- WorkflowExecutionRepository: Symbol.for("codemation.core.WorkflowExecutionRepository"),
20
- TriggerSetupStateRepository: Symbol.for("codemation.core.TriggerSetupStateRepository"),
21
- NodeActivationScheduler: Symbol.for("codemation.core.NodeActivationScheduler"),
22
- RunDataFactory: Symbol.for("codemation.core.RunDataFactory"),
23
- ExecutionContextFactory: Symbol.for("codemation.core.ExecutionContextFactory"),
24
- RunEventBus: Symbol.for("codemation.core.RunEventBus"),
25
- BinaryStorage: Symbol.for("codemation.core.BinaryStorage"),
26
- WebhookBasePath: Symbol.for("codemation.core.WebhookBasePath"),
27
- EngineExecutionLimitsPolicy: Symbol.for("codemation.core.EngineExecutionLimitsPolicy"),
28
- WorkflowActivationPolicy: Symbol.for("codemation.core.WorkflowActivationPolicy"),
29
- AgentMcpIntegration: Symbol.for("codemation.core.AgentMcpIntegration")
6
+ //#region src/contracts/humanTaskStoreTypes.ts
7
+ const HumanTaskStoreToken = Symbol.for("codemation.core.HumanTaskStore");
8
+
9
+ //#endregion
10
+ //#region src/contracts/hitlSeamTypes.ts
11
+ const HitlResumeTokenSignerToken = Symbol.for("codemation.core.HitlResumeTokenSigner");
12
+ const HitlTimeoutJobSchedulerToken = Symbol.for("codemation.core.HitlTimeoutJobScheduler");
13
+ /**
14
+ * Optional workspace ID injected into NodeSuspensionHandler in managed mode (T7 security fix).
15
+ * Allows the handler to stamp the workspaceId on each HumanTaskRecord so HitlCallbackHandler
16
+ * can assert workspace identity independently of the HMAC middleware.
17
+ * Not registered in non-managed mode; NodeSuspensionHandler defaults to null.
18
+ */
19
+ const HitlWorkspaceIdToken = Symbol.for("codemation.core.HitlWorkspaceId");
20
+
21
+ //#endregion
22
+ //#region src/authoring/DefinedNodeRegistry.ts
23
+ var DefinedNodeRegistry = class {
24
+ static definitions = /* @__PURE__ */ new Map();
25
+ static register(definition) {
26
+ this.definitions.set(definition.key, definition);
27
+ }
28
+ static resolve(key) {
29
+ return this.definitions.get(key);
30
+ }
30
31
  };
31
32
 
32
33
  //#endregion
@@ -139,287 +140,303 @@ function chatModel(options = {}) {
139
140
  }
140
141
 
141
142
  //#endregion
142
- //#region src/ai/NodeBackedToolConfig.ts
143
- var NodeBackedToolConfig = class {
144
- type;
145
- toolKind = "nodeBacked";
146
- description;
147
- presentation;
148
- inputSchemaValue;
149
- outputSchemaValue;
150
- mapInputValue;
151
- mapOutputValue;
152
- constructor(name, node$1, options) {
153
- this.name = name;
154
- this.node = node$1;
155
- this.type = node$1.type;
156
- this.description = options.description;
157
- this.presentation = options.presentation;
158
- this.inputSchemaValue = options.inputSchema;
159
- this.outputSchemaValue = options.outputSchema;
160
- this.mapInputValue = options.mapInput;
161
- this.mapOutputValue = options.mapOutput;
162
- }
163
- getCredentialRequirements() {
164
- return this.node.getCredentialRequirements?.() ?? [];
165
- }
166
- getInputSchema() {
167
- return this.inputSchemaValue;
168
- }
169
- getOutputSchema() {
170
- return this.outputSchemaValue;
171
- }
172
- toNodeItem(args) {
173
- const mapped = this.mapInputValue?.(args) ?? args.input;
174
- if (this.isItem(mapped)) return mapped;
175
- return { json: mapped };
176
- }
177
- toToolOutput(args) {
178
- const raw = this.mapOutputValue?.(args) ?? this.readDefaultToolOutput(args.outputs);
179
- return this.outputSchemaValue.parse(raw);
180
- }
181
- readDefaultToolOutput(outputs) {
182
- const firstMainItem = outputs.main?.[0];
183
- if (!firstMainItem) throw new Error(`Node-backed tool "${this.name}" did not produce a main output item.`);
184
- return firstMainItem.json;
185
- }
186
- isItem(value) {
187
- return typeof value === "object" && value !== null && "json" in value;
143
+ //#region src/authoring/defineNode.types.ts
144
+ const definedNodeCredentialRequirementFactory = {
145
+ create(bindings) {
146
+ if (!bindings) return [];
147
+ return Object.entries(bindings).map(([slotKey, binding]) => {
148
+ if (typeof binding === "string" || this.isCredentialType(binding)) return {
149
+ slotKey,
150
+ label: this.humanize(slotKey),
151
+ acceptedTypes: [this.resolveTypeId(binding)]
152
+ };
153
+ const types = Array.isArray(binding.type) ? binding.type : [binding.type];
154
+ return {
155
+ slotKey,
156
+ label: binding.label ?? this.humanize(slotKey),
157
+ acceptedTypes: types.map((entry) => this.resolveTypeId(entry)),
158
+ optional: binding.optional,
159
+ helpText: binding.helpText,
160
+ helpUrl: binding.helpUrl
161
+ };
162
+ });
163
+ },
164
+ isCredentialType(value) {
165
+ return Boolean(value) && typeof value === "object" && "definition" in value && typeof value.definition?.typeId === "string";
166
+ },
167
+ resolveTypeId(type) {
168
+ return typeof type === "string" ? type : type.definition.typeId;
169
+ },
170
+ humanize(key) {
171
+ return key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().replace(/^./, (character) => character.toUpperCase());
188
172
  }
189
173
  };
190
-
191
- //#endregion
192
- //#region src/contracts/itemExpr.ts
193
- const ITEM_EXPR_BRAND = Symbol.for("codemation.itemExpr");
194
- function itemExpr(fn) {
195
- return {
196
- [ITEM_EXPR_BRAND]: true,
197
- fn
174
+ const definedNodeCredentialAccessorFactory = { create(bindings, ctx) {
175
+ if (!bindings) return {};
176
+ const entries = Object.keys(bindings).map((slotKey) => [slotKey, () => ctx.getCredential(slotKey)]);
177
+ return Object.fromEntries(entries);
178
+ } };
179
+ function defineNode(options) {
180
+ const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);
181
+ const DefinedNodeRuntime = class {
182
+ kind = "node";
183
+ outputPorts = ["main"];
184
+ inputSchema = options.inputSchema;
185
+ async execute(args) {
186
+ const ctx = args.ctx;
187
+ const context = {
188
+ config: ctx.config.config,
189
+ credentials: definedNodeCredentialAccessorFactory.create(options.credentials, ctx),
190
+ execution: ctx
191
+ };
192
+ const payload = {
193
+ input: args.input,
194
+ item: args.item,
195
+ itemIndex: args.itemIndex,
196
+ items: args.items,
197
+ ctx
198
+ };
199
+ return await options.execute(payload, context);
200
+ }
198
201
  };
199
- }
200
- function isItemExpr(value) {
201
- if (typeof value !== "object" || value === null) return false;
202
- const v = value;
203
- if (v[ITEM_EXPR_BRAND] === true) return true;
204
- const keys = Object.keys(v);
205
- if (keys.length === 1 && keys[0] === "fn" && typeof v.fn === "function") return true;
206
- for (const sym of Object.getOwnPropertySymbols(v)) if (sym.description === "codemation.itemExpr" && v[sym] === true) return true;
207
- return false;
208
- }
209
- function containsItemExprInUnknown(value, seen = /* @__PURE__ */ new WeakSet()) {
210
- if (isItemExpr(value)) return true;
211
- if (value === null || typeof value !== "object") return false;
212
- if (seen.has(value)) return false;
213
- seen.add(value);
214
- if (Array.isArray(value)) return value.some((entry) => containsItemExprInUnknown(entry, seen));
215
- for (const entry of Object.values(value)) if (containsItemExprInUnknown(entry, seen)) return true;
216
- return false;
217
- }
218
- /**
219
- * Deep-resolves {@link itemExpr} leaves. Returns a new graph (does not mutate the original config object).
220
- */
221
- async function resolveItemExprsInUnknown(value, args, seen = /* @__PURE__ */ new WeakSet()) {
222
- if (isItemExpr(value)) return await Promise.resolve(value.fn(args));
223
- if (value === null || typeof value !== "object") return value;
224
- if (seen.has(value)) return value;
225
- seen.add(value);
226
- if (Array.isArray(value)) {
227
- const out$1 = [];
228
- for (let i = 0; i < value.length; i++) out$1.push(await resolveItemExprsInUnknown(value[i], args, seen));
229
- return out$1;
230
- }
231
- const rec = value;
232
- const entries = Object.entries(rec);
233
- const proto = Object.getPrototypeOf(value);
234
- if (proto !== Object.prototype && proto !== null && entries.length === 0) return value;
235
- const out = Object.create(proto);
236
- for (const [k, v] of entries) out[k] = await resolveItemExprsInUnknown(v, args, seen);
237
- return out;
238
- }
239
- /**
240
- * Clones runnable config (best-effort) so per-item {@link itemExpr} resolution never mutates shared instances.
241
- */
242
- async function resolveItemExprsForExecution(config, nodeCtx, item, itemIndex, items) {
243
- const exprArgs = {
244
- item,
245
- itemIndex,
246
- items,
247
- ctx: {
248
- runId: nodeCtx.runId,
249
- workflowId: nodeCtx.workflowId,
250
- nodeId: nodeCtx.nodeId,
251
- activationId: nodeCtx.activationId,
252
- data: nodeCtx.data
202
+ node({ name: options.key })(DefinedNodeRuntime);
203
+ const DefinedRunnableNodeConfig = class {
204
+ kind = "node";
205
+ type = DefinedNodeRuntime;
206
+ icon = options.icon;
207
+ inputSchema = options.inputSchema;
208
+ keepBinaries = options.keepBinaries ?? false;
209
+ constructor(name, config, id) {
210
+ this.name = name;
211
+ this.id = id;
212
+ this.config = config;
213
+ }
214
+ config;
215
+ getCredentialRequirements() {
216
+ return credentialRequirements;
217
+ }
218
+ inspectorSummary() {
219
+ return options.inspectorSummary?.({ config: this.config });
253
220
  }
254
221
  };
255
- if (!containsItemExprInUnknown(config)) return;
256
- return await resolveItemExprsInUnknown(config, exprArgs);
222
+ const definition = {
223
+ kind: "defined-node",
224
+ key: options.key,
225
+ title: options.title,
226
+ description: options.description,
227
+ create(config, name = options.title, id) {
228
+ return new DefinedRunnableNodeConfig(name, config, id);
229
+ },
230
+ register(context) {
231
+ context.registerNode(DefinedNodeRuntime);
232
+ }
233
+ };
234
+ DefinedNodeRegistry.register(definition);
235
+ return definition;
257
236
  }
258
-
259
- //#endregion
260
- //#region src/ai/AgentConfigInspectorFactory.ts
261
- var AgentConfigInspector = class {
262
- static isAgentNodeConfig(config) {
263
- if (!config) return false;
264
- const candidate = config;
265
- return !!candidate.chatModel && this.hasCompatibleMessageConfiguration(candidate);
266
- }
267
- static hasCompatibleMessageConfiguration(candidate) {
268
- const messages = candidate.messages;
269
- if (messages === void 0 || messages === null) return false;
270
- if (Array.isArray(messages)) return messages.length > 0;
271
- if (typeof messages === "object") {
272
- if (isItemExpr(messages)) return true;
273
- const o = messages;
274
- return Array.isArray(o.prompt) && o.prompt.length > 0 || typeof o.buildMessages === "function";
237
+ function defineBatchNode(options) {
238
+ const credentialRequirements = definedNodeCredentialRequirementFactory.create(options.credentials);
239
+ const DefinedNodeRuntime = class {
240
+ kind = "node";
241
+ outputPorts = ["main"];
242
+ async execute(args) {
243
+ if (args.itemIndex !== args.items.length - 1) return [];
244
+ const ctx = args.ctx;
245
+ const context = {
246
+ config: ctx.config.config,
247
+ credentials: definedNodeCredentialAccessorFactory.create(options.credentials, ctx),
248
+ execution: ctx
249
+ };
250
+ return [...await options.run(args.items.map((item) => item.json), context)];
275
251
  }
276
- return false;
277
- }
278
- };
252
+ };
253
+ node({ name: options.key })(DefinedNodeRuntime);
254
+ const DefinedRunnableNodeConfig = class {
255
+ kind = "node";
256
+ type = DefinedNodeRuntime;
257
+ icon = options.icon;
258
+ constructor(name, config, id) {
259
+ this.name = name;
260
+ this.id = id;
261
+ this.config = config;
262
+ }
263
+ config;
264
+ getCredentialRequirements() {
265
+ return credentialRequirements;
266
+ }
267
+ inspectorSummary() {
268
+ return options.inspectorSummary?.({ config: this.config });
269
+ }
270
+ };
271
+ const definition = {
272
+ kind: "defined-node",
273
+ key: options.key,
274
+ title: options.title,
275
+ description: options.description,
276
+ create(config, name = options.title, id) {
277
+ return new DefinedRunnableNodeConfig(name, config, id);
278
+ },
279
+ register(context) {
280
+ context.registerNode(DefinedNodeRuntime);
281
+ }
282
+ };
283
+ DefinedNodeRegistry.register(definition);
284
+ return definition;
285
+ }
279
286
 
280
287
  //#endregion
281
- //#region src/workflow/definition/ConnectionNodeIdFactory.ts
288
+ //#region src/authoring/defineHumanApprovalNode.types.ts
282
289
  /**
283
- * Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).
284
- * These are stable across loads.
290
+ * Returns `true` when `node` was created by {@link defineHumanApprovalNode}.
291
+ * Uses the `humanApprovalToolBehavior` typed field as the discriminant.
285
292
  */
286
- var ConnectionNodeIdFactory = class {
287
- static connectionSegment = "__conn__";
288
- static languageModelConnectionNodeId(parentNodeId) {
289
- return `${parentNodeId}${this.connectionSegment}llm`;
290
- }
291
- static toolConnectionNodeId(parentNodeId, toolName) {
292
- const normalized = this.normalizeToolName(toolName);
293
- return `${parentNodeId}${this.connectionSegment}tool${this.connectionSegment}${normalized}`;
294
- }
295
- static mcpConnectionNodeId(parentNodeId, serverId) {
296
- return `${parentNodeId}${this.connectionSegment}mcp${this.connectionSegment}${serverId}`;
297
- }
298
- static isMcpConnectionNodeId(nodeId) {
299
- return nodeId.includes(`${this.connectionSegment}mcp${this.connectionSegment}`);
300
- }
301
- static parseMcpConnectionNodeId(nodeId) {
302
- if (!this.isMcpConnectionNodeId(nodeId)) return;
303
- const marker = `${this.connectionSegment}mcp${this.connectionSegment}`;
304
- const idx = nodeId.lastIndexOf(marker);
305
- if (idx < 0) return;
306
- const parentNodeId = nodeId.slice(0, idx);
307
- const serverId = nodeId.slice(idx + marker.length);
308
- if (!parentNodeId || !serverId) return;
309
- return {
310
- parentNodeId,
311
- serverId
312
- };
313
- }
314
- static isLanguageModelConnectionNodeId(nodeId) {
315
- return nodeId.endsWith(`${this.connectionSegment}llm`);
316
- }
317
- static isToolConnectionNodeId(nodeId) {
318
- return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);
319
- }
320
- static parseLanguageModelConnectionNodeId(nodeId) {
321
- if (!this.isLanguageModelConnectionNodeId(nodeId)) return;
322
- const suffix = `${this.connectionSegment}llm`;
323
- const parentNodeId = nodeId.slice(0, -suffix.length);
324
- return parentNodeId ? { parentNodeId } : void 0;
325
- }
326
- static parseToolConnectionNodeId(nodeId) {
327
- if (!this.isToolConnectionNodeId(nodeId)) return;
328
- const marker = `${this.connectionSegment}tool${this.connectionSegment}`;
329
- const idx = nodeId.lastIndexOf(marker);
330
- if (idx < 0) return;
331
- const parentNodeId = nodeId.slice(0, idx);
332
- const normalizedToolName = nodeId.slice(idx + marker.length);
333
- if (!parentNodeId || !normalizedToolName) return;
334
- return {
335
- parentNodeId,
336
- normalizedToolName
337
- };
338
- }
339
- /** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
340
- static isConnectionOwnedDescendantOf(parentNodeId, nodeId) {
341
- return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
342
- }
343
- /** Normalizes a tool display name to a stable id segment. */
344
- static normalizeToolName(toolName) {
345
- return toolName.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "tool";
346
- }
347
- };
348
-
349
- //#endregion
350
- //#region src/ai/AgentConnectionNodeCollector.ts
351
- const AgentConnectionNodeCollector = new class {
352
- collect(parentNodeId, agentConfig, mcpServerResolver) {
353
- const collected = [];
354
- this.collectInto(parentNodeId, agentConfig, collected, mcpServerResolver);
355
- return collected;
356
- }
357
- collectInto(parentNodeId, agentConfig, collected, mcpServerResolver) {
358
- collected.push({
359
- nodeId: ConnectionNodeIdFactory.languageModelConnectionNodeId(parentNodeId),
360
- parentNodeId,
361
- connectionName: "llm",
362
- role: "languageModel",
363
- name: agentConfig.chatModel.presentation?.label ?? agentConfig.chatModel.name,
364
- typeName: agentConfig.chatModel.name,
365
- icon: agentConfig.chatModel.presentation?.icon,
366
- credentialSource: agentConfig.chatModel
367
- });
368
- for (const tool$1 of agentConfig.tools ?? []) {
369
- const toolNodeId = ConnectionNodeIdFactory.toolConnectionNodeId(parentNodeId, tool$1.name);
370
- const isNestedAgent = this.isNodeBackedAgentTool(tool$1);
371
- collected.push({
372
- nodeId: toolNodeId,
373
- parentNodeId,
374
- connectionName: "tools",
375
- role: isNestedAgent ? "nestedAgent" : "tool",
376
- name: tool$1.presentation?.label ?? tool$1.name,
377
- typeName: tool$1.name,
378
- icon: tool$1.presentation?.icon,
379
- credentialSource: tool$1
380
- });
381
- this.collectNestedAgentTools(toolNodeId, tool$1, collected, mcpServerResolver);
382
- }
383
- if (mcpServerResolver) {
384
- const mcpServers = agentConfig.mcpServers;
385
- for (const serverId of mcpServers ?? []) {
386
- const decl = mcpServerResolver(serverId);
387
- if (!decl) continue;
388
- const acceptedTypes = decl.acceptedCredentialTypes ?? [];
389
- collected.push({
390
- nodeId: ConnectionNodeIdFactory.mcpConnectionNodeId(parentNodeId, serverId),
391
- parentNodeId,
392
- connectionName: "tools",
393
- role: "tool",
394
- name: decl.displayName,
395
- typeName: serverId,
396
- icon: "lucide:plug",
397
- credentialSource: { getCredentialRequirements: () => [{
398
- slotKey: "credential",
399
- label: decl.displayName,
400
- acceptedTypes
401
- }] }
293
+ function isHumanApprovalNode(node$1) {
294
+ return typeof node$1 === "object" && node$1 !== null && "humanApprovalToolBehavior" in node$1 && typeof node$1.humanApprovalToolBehavior === "object";
295
+ }
296
+ /**
297
+ * Authoring helper that compiles a HITL approval channel down to a regular
298
+ * {@link defineNode}-backed node with `SuspensionRequest` semantics.
299
+ *
300
+ * **Fast-forward decision semantics:**
301
+ * - On the first `execute` call (no `ctx.resumeContext`): throws a `SuspensionRequest`
302
+ * that calls the author's `deliver`. The engine persists the suspension and continues.
303
+ * - On resume (`ctx.resumeContext` set): calls `onDecision`/`onTimeout` as appropriate,
304
+ * merges a `decision` key into `item.json`, and returns an item with the original
305
+ * `binary` map passed by reference (no copy).
306
+ *
307
+ * **Output shape per item:**
308
+ * ```ts
309
+ * // Input: { json: { invoiceId: 42 }, binary?: {...} }
310
+ * // Output: { json: { invoiceId: 42, decision: { status: "approved", actor, decidedAt } }, binary: <unchanged> }
311
+ * ```
312
+ * If `item.json` already has a `decision` key it is **overwritten**. Namespace as
313
+ * needed if your schema reserves that key for another purpose.
314
+ *
315
+ * **Predicate persistence:**
316
+ * The `approvedPredicate` function is NOT serialized to the suspension record (except
317
+ * as an audit-only string via `toString()`). On resume, the workflow definition is
318
+ * reloaded from code at process start and the predicate closure is rebuilt naturally.
319
+ * If a deploy ships a changed predicate between suspend and resume, the *new* predicate
320
+ * runs — document this in your runbook when the predicate carries business logic that
321
+ * may change across deploys.
322
+ *
323
+ * @example
324
+ * ```ts
325
+ * export const slackApprovalNode = defineHumanApprovalNode({
326
+ * key: "my-plugin.slackApproval",
327
+ * title: "Slack Approval",
328
+ * channel: "slack",
329
+ * configSchema: z.object({ channel: z.string(), message: z.string() }),
330
+ * decisionSchema: z.object({ approved: z.boolean(), note: z.string().optional() }),
331
+ *
332
+ * async deliver({ task, config, item }, ctx) {
333
+ * const ts = await postSlackMessage(config.channel, `Approve? <${task.resumeUrl}>`);
334
+ * return { channel: config.channel, ts };
335
+ * },
336
+ *
337
+ * async onDecision({ decision, actor, delivery }, ctx) {
338
+ * await updateSlackMessage(delivery.channel, delivery.ts, decision.approved ? "✅" : "❌");
339
+ * },
340
+ * });
341
+ * ```
342
+ */
343
+ function defineHumanApprovalNode(opts) {
344
+ const resolvedPredicate = resolveApprovedPredicate(opts.decisionSchema, opts.approvedPredicate);
345
+ const timeout = opts.defaultTimeout ?? "24h";
346
+ const onTimeout = opts.defaultOnTimeout ?? "halt";
347
+ const inner = defineNode({
348
+ key: opts.key,
349
+ title: opts.title,
350
+ description: opts.description,
351
+ icon: opts.icon,
352
+ configSchema: opts.configSchema,
353
+ inputSchema: opts.inputSchema,
354
+ credentials: opts.credentials,
355
+ inspectorSummary: opts.inspectorSummary ? ({ config }) => opts.inspectorSummary(config) : void 0,
356
+ async execute(args, { config, execution: ctx }) {
357
+ if (!ctx.resumeContext) {
358
+ const subject = buildSubject(opts.title, args.item, ctx);
359
+ throw new SuspensionRequest({
360
+ decisionSchema: opts.decisionSchema,
361
+ timeout,
362
+ onTimeout,
363
+ subject,
364
+ metadata: {
365
+ channel: opts.channel,
366
+ nodeKey: opts.key,
367
+ approvedPredicateSource: opts.approvedPredicate?.toString() ?? null
368
+ },
369
+ deliver: (handle) => opts.deliver({
370
+ task: handle,
371
+ config,
372
+ input: args.input,
373
+ item: args.item
374
+ }, ctx)
402
375
  });
403
376
  }
377
+ return await handleResume(args.item, ctx.resumeContext, opts.decisionSchema, resolvedPredicate, opts.onDecision, opts.onTimeout, ctx);
404
378
  }
379
+ });
380
+ return Object.assign(inner, { humanApprovalToolBehavior: { onRejected: "return" } });
381
+ }
382
+ function resolveApprovedPredicate(schema, predicate) {
383
+ if (predicate) return predicate;
384
+ const shape = schema.shape;
385
+ if (shape && typeof shape === "object" && "approved" in shape) return (d) => d.approved === true;
386
+ throw new Error("defineHumanApprovalNode: decisionSchema has no \"approved\" field and no approvedPredicate was provided. Either add { approved: z.boolean() } to the decision schema or supply approvedPredicate explicitly.");
387
+ }
388
+ function buildSubject(title, item, ctx) {
389
+ return {
390
+ title,
391
+ summary: "",
392
+ attributes: {
393
+ workflowId: ctx.workflowId,
394
+ nodeId: ctx.nodeId,
395
+ item: item.json
396
+ }
397
+ };
398
+ }
399
+ function mergeDecision(item, decision) {
400
+ return {
401
+ json: {
402
+ ...item.json,
403
+ decision
404
+ },
405
+ binary: item.binary,
406
+ meta: item.meta
407
+ };
408
+ }
409
+ async function handleResume(item, resumeContext, decisionSchema, resolvedPredicate, onDecision, onTimeoutCb, ctx) {
410
+ const { decision: dec, delivery, task } = resumeContext;
411
+ if (dec.kind === "timed_out" || dec.kind === "auto_accepted") {
412
+ const policy = dec.kind === "auto_accepted" ? "auto-accept" : "halt";
413
+ await onTimeoutCb?.({
414
+ task,
415
+ delivery,
416
+ item,
417
+ policy
418
+ }, ctx);
419
+ return mergeDecision(item, {
420
+ status: dec.kind === "auto_accepted" ? "auto-accepted" : "timed-out",
421
+ decidedAt: dec.at
422
+ });
405
423
  }
406
- collectNestedAgentTools(toolNodeId, tool$1, collected, mcpServerResolver) {
407
- if (!this.isNodeBackedAgentTool(tool$1)) return;
408
- const innerAgent = tool$1 instanceof NodeBackedToolConfig ? tool$1.node : tool$1.node;
409
- this.collectInto(toolNodeId, innerAgent, collected, mcpServerResolver);
410
- }
411
- /**
412
- * After JSON round-trip (persisted snapshots), tools are plain objects — `instanceof NodeBackedToolConfig` fails.
413
- * Detect node-backed tools structurally via {@link NodeBackedToolConfig#toolKind}.
414
- */
415
- isNodeBackedAgentTool(tool$1) {
416
- if (tool$1 instanceof NodeBackedToolConfig) return AgentConfigInspector.isAgentNodeConfig(tool$1.node);
417
- if (!tool$1 || typeof tool$1 !== "object") return false;
418
- const t = tool$1;
419
- if (t.toolKind !== "nodeBacked") return false;
420
- return AgentConfigInspector.isAgentNodeConfig(t.node);
421
- }
422
- }();
424
+ const parsed = decisionSchema.parse(dec.value);
425
+ await onDecision?.({
426
+ decision: parsed,
427
+ actor: dec.actor,
428
+ task,
429
+ delivery,
430
+ item
431
+ }, ctx);
432
+ return mergeDecision(item, {
433
+ status: resolvedPredicate(parsed) ? "approved" : "rejected",
434
+ actor: dec.actor,
435
+ decidedAt: dec.decidedAt,
436
+ note: parsed.note,
437
+ payload: parsed
438
+ });
439
+ }
423
440
 
424
441
  //#endregion
425
442
  //#region src/workflow/dsl/WhenBuilder.ts
@@ -547,6 +564,25 @@ var ChainCursor = class ChainCursor {
547
564
  }
548
565
  return new ChainCursor(this.wf, nextEndpoints);
549
566
  }
567
+ /**
568
+ * Chainable shorthand for `.then(node.create(config, metadata?.name, metadata?.nodeId))`.
569
+ *
570
+ * Signals to readers that this step suspends the run and waits for a human decision.
571
+ * Throws at workflow-build time if `node` was not created via `defineHumanApprovalNode`.
572
+ *
573
+ * @example
574
+ * ```ts
575
+ * workflow
576
+ * .trigger(...)
577
+ * .humanApproval(inboxApproval, { title: "Approve?", body: "...", priority: "normal" })
578
+ * .then(nextStep.create(...))
579
+ * .build();
580
+ * ```
581
+ */
582
+ humanApproval(node$1, config, metadata) {
583
+ if (!isHumanApprovalNode(node$1)) throw new Error(`.humanApproval() requires a node created via defineHumanApprovalNode (got '${node$1.key ?? String(node$1)}').`);
584
+ return this.then(node$1.create(config, metadata?.name, metadata?.nodeId));
585
+ }
550
586
  build() {
551
587
  return this.wf.build();
552
588
  }
@@ -711,33 +747,6 @@ var ConnectionInvocationIdFactory = class {
711
747
  }
712
748
  };
713
749
 
714
- //#endregion
715
- //#region src/workflow/definition/NodeIterationIdFactory.ts
716
- /**
717
- * Unique ids for one per-item iteration of a runnable node's execute loop.
718
- *
719
- * Activations are per-batch (one scheduled execution of a node, possibly with N items).
720
- * Iterations refine that to one identifier per item-index inside the batch loop, so per-item
721
- * connection invocations and telemetry can be grouped without time-window heuristics.
722
- *
723
- * Uses Web Crypto's `randomUUID` (Node 19+ and all modern browsers) so this module is safe
724
- * to include in the browser entry. Importing `node:crypto` here previously leaked into the
725
- * canvas client bundle through `browser.ts` and OOM'd consumers' Turbopack builds.
726
- */
727
- var NodeIterationIdFactory = class {
728
- static create() {
729
- return `iter_${globalThis.crypto.randomUUID()}`;
730
- }
731
- /** Deterministic id for tests when a stable sequence is needed. */
732
- static createForTest(seed, sequence) {
733
- return `iter_${seed}_${sequence}`;
734
- }
735
- /** Deterministic id derived from a connection node id (for sub-agent / tool-call scopes). */
736
- static createForConnection(connectionNodeId, sequence) {
737
- return `iter_${connectionNodeId}_${sequence}`;
738
- }
739
- };
740
-
741
750
  //#endregion
742
751
  //#region src/workflow/definition/WorkflowExecutableNodeClassifier.ts
743
752
  /**
@@ -1040,7 +1049,7 @@ var NodeExecutionSnapshotFactory = class {
1040
1049
  nodeId: args.nodeId,
1041
1050
  activationId: args.activationId,
1042
1051
  parent: args.parent,
1043
- status: "completed",
1052
+ status: args.hitlStatus ?? "completed",
1044
1053
  queuedAt: args.previous?.queuedAt,
1045
1054
  startedAt,
1046
1055
  finishedAt: args.finishedAt,
@@ -1167,7 +1176,9 @@ var ActivationEnqueueService = class {
1167
1176
  nodeSnapshotsByNodeId: {
1168
1177
  ...args.previousNodeSnapshotsByNodeId,
1169
1178
  [args.request.nodeId]: queuedSnapshot
1170
- }
1179
+ },
1180
+ ...args.suspension !== void 0 ? { suspension: args.suspension } : {},
1181
+ ...args.pendingResume !== void 0 ? { pendingResume: args.pendingResume } : {}
1171
1182
  });
1172
1183
  await this.dispatchPreparedActivation(preparedDispatch);
1173
1184
  return {
@@ -1419,20 +1430,6 @@ var DefaultAsyncSleeper = class {
1419
1430
  }
1420
1431
  };
1421
1432
 
1422
- //#endregion
1423
- //#region src/contracts/NoOpAgentMcpIntegration.ts
1424
- /**
1425
- * No-op implementation of AgentMcpIntegration.
1426
- * Registered by the core engine runtime as a fallback when the host does not
1427
- * supply a real implementation (e.g. in unit tests or headless engine setups).
1428
- * Always returns an empty tool map so the agent runs with node-backed tools only.
1429
- */
1430
- var NoOpAgentMcpIntegration = class {
1431
- async prepareMcpTools() {
1432
- return /* @__PURE__ */ new Map();
1433
- }
1434
- };
1435
-
1436
1433
  //#endregion
1437
1434
  //#region src/contracts/emitPorts.ts
1438
1435
  const EMIT_PORTS_BRAND = Symbol.for("codemation.emitPorts");
@@ -1495,21 +1492,6 @@ var ExpRetryPolicy = class {
1495
1492
  }
1496
1493
  };
1497
1494
 
1498
- //#endregion
1499
- //#region src/contracts/credentialTypes.ts
1500
- var CredentialUnboundError = class CredentialUnboundError extends Error {
1501
- constructor(bindingKey, acceptedTypes = []) {
1502
- super(CredentialUnboundError.createMessage(bindingKey, acceptedTypes));
1503
- this.bindingKey = bindingKey;
1504
- this.acceptedTypes = acceptedTypes;
1505
- this.name = "CredentialUnboundError";
1506
- }
1507
- static createMessage(bindingKey, acceptedTypes) {
1508
- const acceptedTypesSuffix = acceptedTypes.length > 0 ? ` Accepted credential types: ${acceptedTypes.join(", ")}.` : "";
1509
- return `Credential slot "${bindingKey.slotKey}" is not bound for workflow ${bindingKey.workflowId} node ${bindingKey.nodeId}.${acceptedTypesSuffix}`;
1510
- }
1511
- };
1512
-
1513
1495
  //#endregion
1514
1496
  //#region src/contracts/CostTrackingTelemetryContract.ts
1515
1497
  const CostTrackingTelemetryMetricNames = {
@@ -1631,19 +1613,6 @@ var NoOpExecutionTelemetryFactory = class {
1631
1613
  }
1632
1614
  };
1633
1615
 
1634
- //#endregion
1635
- //#region src/contracts/runFinishedAtFactory.ts
1636
- /** Derives workflow end time from persisted run root or node snapshots for run listings. */
1637
- var RunFinishedAtFactory = class {
1638
- static resolveIso(state) {
1639
- if (state.finishedAt && state.status !== "running" && state.status !== "pending") return state.finishedAt;
1640
- if (state.status === "running" || state.status === "pending") return;
1641
- let max;
1642
- for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
1643
- return max;
1644
- }
1645
- };
1646
-
1647
1616
  //#endregion
1648
1617
  //#region src/contracts/workflowActivationPolicy.ts
1649
1618
  /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
@@ -1676,6 +1645,16 @@ var CodemationTelemetryAttributeNames = class {
1676
1645
  static mcpServerId = "mcp.server_id";
1677
1646
  /** MCP tool name on spans created for callTool invocations. */
1678
1647
  static mcpToolName = "mcp.tool_name";
1648
+ /** Terminal node-execution status (e.g. `"hitl-approved"`, `"hitl-rejected"`) on HITL outcome spans. */
1649
+ static nodeExecutionStatus = "codemation.node.execution_status";
1650
+ /** Populated on run-halted spans; discriminates the halt reason (e.g. `"hitl-rejected"`). */
1651
+ static runHaltReason = "codemation.run.halt_reason";
1652
+ /** Human task ID on `hitl.task.*` span events. */
1653
+ static hitlTaskId = "codemation.hitl.task_id";
1654
+ /** HITL channel name (e.g. `"inbox"`, `"control-plane-inbox"`) on `hitl.task.*` span events. */
1655
+ static hitlChannel = "codemation.hitl.channel";
1656
+ /** Decision outcome (e.g. `"approved"`, `"rejected"`) on `hitl.task.decided` span events. */
1657
+ static hitlDecisionStatus = "codemation.hitl.decision_status";
1679
1658
  };
1680
1659
 
1681
1660
  //#endregion
@@ -1701,13 +1680,6 @@ var CodemationTelemetryMetricNames = class {
1701
1680
  static gmailAttachmentBytes = "codemation.gmail.attachment_bytes";
1702
1681
  };
1703
1682
 
1704
- //#endregion
1705
- //#region src/contracts/workflowTypes.ts
1706
- function nodeRef(nodeId) {
1707
- return nodeId;
1708
- }
1709
- const branchRef = (index) => `$${index}`;
1710
-
1711
1683
  //#endregion
1712
1684
  //#region src/execution/ExecutionTelemetryCostTrackingDecoratorFactory.ts
1713
1685
  var ExecutionTelemetryCostTrackingDecoratorFactory = class {
@@ -1781,12 +1753,13 @@ var ExecutionTelemetryCostTrackingDecoratorFactory = class {
1781
1753
  //#region src/execution/DefaultExecutionContextFactory.ts
1782
1754
  var DefaultExecutionContextFactory = class {
1783
1755
  telemetryDecoratorFactory = new ExecutionTelemetryCostTrackingDecoratorFactory();
1784
- constructor(binaryStorage = new UnavailableBinaryStorage(), telemetryFactory = new NoOpExecutionTelemetryFactory(), costTrackingFactory = new NoOpCostTrackingTelemetryFactory(), currentDate = () => /* @__PURE__ */ new Date(), collections) {
1756
+ constructor(binaryStorage = new UnavailableBinaryStorage(), telemetryFactory = new NoOpExecutionTelemetryFactory(), costTrackingFactory = new NoOpCostTrackingTelemetryFactory(), currentDate = () => /* @__PURE__ */ new Date(), collections, nodeResolver) {
1785
1757
  this.binaryStorage = binaryStorage;
1786
1758
  this.telemetryFactory = telemetryFactory;
1787
1759
  this.costTrackingFactory = costTrackingFactory;
1788
1760
  this.currentDate = currentDate;
1789
1761
  this.collections = collections;
1762
+ this.nodeResolver = nodeResolver;
1790
1763
  }
1791
1764
  create(args) {
1792
1765
  const baseTelemetry = args.telemetry ?? this.telemetryFactory.create({
@@ -1813,7 +1786,11 @@ var DefaultExecutionContextFactory = class {
1813
1786
  binary: new DefaultExecutionBinaryService(this.binaryStorage, args.workflowId, args.runId, this.currentDate),
1814
1787
  getCredential: args.getCredential,
1815
1788
  testContext: args.testContext,
1816
- collections: this.collections
1789
+ collections: this.collections,
1790
+ resolve: (token) => {
1791
+ if (!this.nodeResolver) throw new Error("ExecutionContext.resolve() is not available: no NodeResolver was provided to DefaultExecutionContextFactory.");
1792
+ return this.nodeResolver.resolve(token);
1793
+ }
1817
1794
  };
1818
1795
  }
1819
1796
  };
@@ -2155,6 +2132,27 @@ var NodeActivationRequestComposer = class {
2155
2132
  }
2156
2133
  };
2157
2134
 
2135
+ //#endregion
2136
+ //#region src/execution/RunSuspendedError.ts
2137
+ /**
2138
+ * Internal sentinel thrown by {@link NodeSuspensionHandler} after persisting a suspension
2139
+ * entry. `NodeExecutionRequestHandlerService` catches this specifically and returns cleanly —
2140
+ * no continuation call, preventing `resumeFromNodeResult` / `resumeFromNodeError` from
2141
+ * overwriting the `"suspended"` run status.
2142
+ *
2143
+ * The `Error` suffix satisfies the ESLint `no-manual-di-new` allowlist. This is NOT a
2144
+ * user-facing error — it is an engine-internal control-flow primitive and should NOT be
2145
+ * exported from the public barrel.
2146
+ */
2147
+ var RunSuspendedError = class extends Error {
2148
+ constructor(runId, taskId) {
2149
+ super(`RunSuspendedError: run ${runId} suspended on task ${taskId}`);
2150
+ this.runId = runId;
2151
+ this.taskId = taskId;
2152
+ this.name = "RunSuspendedError";
2153
+ }
2154
+ };
2155
+
2158
2156
  //#endregion
2159
2157
  //#region src/execution/NodeExecutor.ts
2160
2158
  var NodeExecutor = class {
@@ -2162,9 +2160,11 @@ var NodeExecutor = class {
2162
2160
  outputNormalizer = new NodeOutputNormalizer();
2163
2161
  itemExprResolver;
2164
2162
  outputBehaviorResolver;
2165
- constructor(nodeInstanceFactory, retryRunner, itemExprResolver, outputBehaviorResolver) {
2163
+ constructor(nodeInstanceFactory, retryRunner, itemExprResolver, outputBehaviorResolver, suspensionHandler, loadRunState) {
2166
2164
  this.nodeInstanceFactory = nodeInstanceFactory;
2167
2165
  this.retryRunner = retryRunner;
2166
+ this.suspensionHandler = suspensionHandler;
2167
+ this.loadRunState = loadRunState;
2168
2168
  this.itemExprResolver = itemExprResolver ?? new ItemExprResolver();
2169
2169
  this.outputBehaviorResolver = outputBehaviorResolver ?? new RunnableOutputBehaviorResolver();
2170
2170
  }
@@ -2264,6 +2264,7 @@ var NodeExecutor = class {
2264
2264
  });
2265
2265
  }
2266
2266
  const byPort = {};
2267
+ let hasSuspension = false;
2267
2268
  for (let i = 0; i < inputBatch.length; i++) {
2268
2269
  const item = inputBatch[i];
2269
2270
  this.assertItemJsonNotTopLevelArray(request.nodeId, item);
@@ -2282,7 +2283,28 @@ var NodeExecutor = class {
2282
2283
  items: inputBatch,
2283
2284
  ctx: iterationCtx
2284
2285
  };
2285
- const raw = await Promise.resolve(node$1.execute(args));
2286
+ let raw;
2287
+ try {
2288
+ raw = await Promise.resolve(node$1.execute(args));
2289
+ } catch (e) {
2290
+ if (e instanceof SuspensionRequest || e instanceof Error && e.name === "SuspensionRequest" && typeof e.request === "object") {
2291
+ if (!this.suspensionHandler || !this.loadRunState) throw new Error(`Node ${request.nodeId} threw SuspensionRequest but this NodeExecutor has no suspensionHandler configured.`, { cause: e });
2292
+ const state = await this.loadRunState(request.runId);
2293
+ if (!state) throw new Error(`NodeExecutor: run state not found for runId ${request.runId} during suspension`, { cause: e });
2294
+ await this.suspensionHandler.handle({
2295
+ runId: request.runId,
2296
+ nodeId: request.nodeId,
2297
+ activationId: request.activationId,
2298
+ itemIndex: i,
2299
+ suspensionRequest: e,
2300
+ state,
2301
+ telemetry: iterationCtx.telemetry
2302
+ });
2303
+ hasSuspension = true;
2304
+ continue;
2305
+ }
2306
+ throw e;
2307
+ }
2286
2308
  const normalized = this.outputNormalizer.normalizeExecuteResult({
2287
2309
  baseItem: item,
2288
2310
  raw,
@@ -2295,6 +2317,7 @@ var NodeExecutor = class {
2295
2317
  byPort[port] = list;
2296
2318
  }
2297
2319
  }
2320
+ if (hasSuspension) throw new RunSuspendedError(request.runId, "unknown");
2298
2321
  return byPort;
2299
2322
  }
2300
2323
  /** Use resolver ctx only when {@link NodeExecutionContext.config} is non-nullish. */
@@ -2321,8 +2344,8 @@ var NodeExecutor = class {
2321
2344
  //#endregion
2322
2345
  //#region src/execution/NodeExecutorFactory.ts
2323
2346
  var NodeExecutorFactory = class {
2324
- create(workflowNodeInstanceFactory, retryRunner, outputBehaviorResolver) {
2325
- return new NodeExecutor(workflowNodeInstanceFactory, retryRunner, void 0, outputBehaviorResolver);
2347
+ create(workflowNodeInstanceFactory, retryRunner, outputBehaviorResolver, suspensionHandler, loadRunState) {
2348
+ return new NodeExecutor(workflowNodeInstanceFactory, retryRunner, void 0, outputBehaviorResolver, suspensionHandler, loadRunState);
2326
2349
  }
2327
2350
  };
2328
2351
 
@@ -2915,6 +2938,7 @@ var PersistedRunStateTerminalBuilder = class {
2915
2938
  ...args.state,
2916
2939
  engineCounters: args.engineCounters,
2917
2940
  status: args.status,
2941
+ reason: args.reason,
2918
2942
  pending: void 0,
2919
2943
  queue: args.queue,
2920
2944
  outputsByNode: args.outputsByNode,
@@ -3197,6 +3221,7 @@ var RunContinuationService = class {
3197
3221
  });
3198
3222
  data.setOutputs(args.nodeId, args.outputs);
3199
3223
  const completedAt = (/* @__PURE__ */ new Date()).toISOString();
3224
+ const hitlResolution = this.resolveHitlStatus(args.outputs);
3200
3225
  const completedSnapshot = this.semantics.createFinishedSnapshot({
3201
3226
  workflow: wf,
3202
3227
  previous: state.nodeSnapshotsByNodeId?.[args.nodeId],
@@ -3207,8 +3232,41 @@ var RunContinuationService = class {
3207
3232
  parent: state.parent,
3208
3233
  finishedAt: completedAt,
3209
3234
  inputsByPort: pendingExecution.inputsByPort,
3210
- outputs: args.outputs
3235
+ outputs: args.outputs,
3236
+ hitlStatus: hitlResolution?.nodeStatus
3211
3237
  });
3238
+ if (hitlResolution?.halt) {
3239
+ const haltedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
3240
+ state,
3241
+ engineCounters: state.engineCounters ?? { completedNodeActivations: 0 },
3242
+ status: "halted",
3243
+ reason: hitlResolution.reason,
3244
+ queue: [],
3245
+ outputsByNode: data.dump(),
3246
+ nodeSnapshotsByNodeId: {
3247
+ ...state.nodeSnapshotsByNodeId ?? {},
3248
+ [args.nodeId]: completedSnapshot
3249
+ },
3250
+ finishedAtIso: completedAt
3251
+ });
3252
+ await this.workflowExecutionRepository.save(haltedState);
3253
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
3254
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
3255
+ workflow: wf,
3256
+ state: haltedState,
3257
+ finalStatus: "failed",
3258
+ finishedAt: completedAt
3259
+ });
3260
+ const result = {
3261
+ runId: state.runId,
3262
+ workflowId: state.workflowId,
3263
+ startedAt: state.startedAt,
3264
+ status: "halted",
3265
+ reason: hitlResolution.reason
3266
+ };
3267
+ this.waiters.resolveRunCompletion(result);
3268
+ return result;
3269
+ }
3212
3270
  const completedActivations = (state.engineCounters?.completedNodeActivations ?? 0) + 1;
3213
3271
  const engineCounters = { completedNodeActivations: completedActivations };
3214
3272
  const maxNodeActivations = state.executionOptions?.maxNodeActivations ?? this.executionLimitsPolicy.createRootExecutionOptions().maxNodeActivations;
@@ -3509,13 +3567,114 @@ var RunContinuationService = class {
3509
3567
  status: "failed",
3510
3568
  error: { message: "Run failed" }
3511
3569
  };
3570
+ if (existing?.status === "halted") return {
3571
+ runId: existing.runId,
3572
+ workflowId: existing.workflowId,
3573
+ startedAt: existing.startedAt,
3574
+ status: "halted",
3575
+ reason: existing.reason ?? "hitl-rejected"
3576
+ };
3512
3577
  const result = await this.waiters.waitForCompletion(runId);
3513
- if (result.status !== "completed" && result.status !== "failed") throw new Error(`Unexpected run completion status: ${result.status}`);
3578
+ if (result.status !== "completed" && result.status !== "failed" && result.status !== "halted") throw new Error(`Unexpected run completion status: ${result.status}`);
3514
3579
  return result;
3515
3580
  }
3516
3581
  async waitForWebhookResponse(runId) {
3517
3582
  return await this.waiters.waitForWebhookResponse(runId);
3518
3583
  }
3584
+ /**
3585
+ * Re-activate a previously suspended run item with a human decision.
3586
+ *
3587
+ * Called by the HITL resume endpoint. This method:
3588
+ * 1. Loads `PersistedRunState` and locates the suspension entry by `taskId`.
3589
+ * 2. Removes the entry from the `suspension` array; if empty, run stays `"suspended"` until
3590
+ * enqueue flips it to `"pending"`.
3591
+ * 3. Writes `pendingResume` onto the state so `NodeExecutionRequestHandlerService` can
3592
+ * splice `resumeContext` into the node's execution context.
3593
+ * 4. Reconstructs the original input from `outputsByNode` of the upstream node and
3594
+ * enqueues a new activation via `activationEnqueueService`.
3595
+ *
3596
+ * @throws if the run is not found, not suspended, or the `taskId` is unknown.
3597
+ */
3598
+ async resumeRun(args) {
3599
+ const state = await this.workflowExecutionRepository.load(args.runId);
3600
+ if (!state) throw new Error(`Unknown runId: ${args.runId}`);
3601
+ if (state.status !== "suspended") throw new Error(`Run ${args.runId} is not suspended (status: ${state.status})`);
3602
+ const suspensionEntry = (state.suspension ?? []).find((s) => s.taskId === args.taskId);
3603
+ if (!suspensionEntry) throw new Error(`No suspension entry with taskId "${args.taskId}" found on run ${args.runId}`);
3604
+ const wf = this.resolvePersistedWorkflow(state);
3605
+ if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
3606
+ const { topology, planner } = this.planningFactory.create(wf);
3607
+ const def = topology.defsById.get(suspensionEntry.nodeId);
3608
+ if (!def || def.kind !== "node") throw new Error(`Node ${suspensionEntry.nodeId} is not a runnable node`);
3609
+ const data = this.runDataFactory.create(state.outputsByNode);
3610
+ const limits = this.resolveEngineLimitsFromState(state);
3611
+ const base = this.runExecutionContextFactory.create({
3612
+ runId: state.runId,
3613
+ workflowId: state.workflowId,
3614
+ nodeId: suspensionEntry.nodeId,
3615
+ parent: state.parent,
3616
+ policySnapshot: state.policySnapshot,
3617
+ subworkflowDepth: state.executionOptions?.subworkflowDepth ?? 0,
3618
+ engineMaxNodeActivations: limits.engineMaxNodeActivations,
3619
+ engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
3620
+ data,
3621
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent),
3622
+ testContext: state.executionOptions?.testContext
3623
+ });
3624
+ const parentEdges = wf.edges.filter((e) => e.to.nodeId === suspensionEntry.nodeId);
3625
+ const parentNodeId = parentEdges[0]?.from.nodeId;
3626
+ const parentOutputPort = parentEdges[0]?.from.output ?? "main";
3627
+ const allParentItems = parentNodeId ? data.getOutputItems(parentNodeId, parentOutputPort) ?? [] : [];
3628
+ const resumeInput = allParentItems.length > suspensionEntry.itemIndex ? [allParentItems[suspensionEntry.itemIndex]] : allParentItems;
3629
+ const newActivationId = this.activationIdFactory.makeActivationId();
3630
+ const pendingResume = {
3631
+ activationId: newActivationId,
3632
+ nodeId: suspensionEntry.nodeId,
3633
+ resumeContext: args.resumeContext
3634
+ };
3635
+ const remainingSuspensions = (state.suspension ?? []).filter((s) => s.taskId !== args.taskId);
3636
+ const baseWithResume = {
3637
+ ...base,
3638
+ resumeContext: args.resumeContext
3639
+ };
3640
+ const batchId = `resume_${newActivationId}`;
3641
+ const request = this.nodeActivationRequestComposer.createSingleFromDefinitionWithActivation({
3642
+ activationId: newActivationId,
3643
+ runId: state.runId,
3644
+ workflowId: state.workflowId,
3645
+ parent: state.parent,
3646
+ executionOptions: state.executionOptions,
3647
+ base: baseWithResume,
3648
+ data,
3649
+ definition: {
3650
+ id: suspensionEntry.nodeId,
3651
+ config: def.config
3652
+ },
3653
+ batchId,
3654
+ input: resumeInput
3655
+ });
3656
+ const { result, queuedSnapshot } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
3657
+ runId: state.runId,
3658
+ workflowId: state.workflowId,
3659
+ startedAt: state.startedAt,
3660
+ parent: state.parent,
3661
+ executionOptions: state.executionOptions,
3662
+ control: state.control,
3663
+ workflowSnapshot: state.workflowSnapshot,
3664
+ mutableState: state.mutableState,
3665
+ policySnapshot: state.policySnapshot,
3666
+ pendingQueue: [],
3667
+ request,
3668
+ previousNodeSnapshotsByNodeId: state.nodeSnapshotsByNodeId ?? {},
3669
+ planner,
3670
+ engineCounters: state.engineCounters,
3671
+ connectionInvocations: state.connectionInvocations ?? [],
3672
+ suspension: remainingSuspensions.length > 0 ? remainingSuspensions : void 0,
3673
+ pendingResume
3674
+ });
3675
+ await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
3676
+ return result;
3677
+ }
3519
3678
  async resumeFromWebhookControl(args) {
3520
3679
  const data = this.runDataFactory.create(args.state.outputsByNode);
3521
3680
  const { topology, planner } = this.planningFactory.create(args.workflow);
@@ -3902,6 +4061,34 @@ var RunContinuationService = class {
3902
4061
  this.waiters.resolveRunCompletion(result);
3903
4062
  return result;
3904
4063
  }
4064
+ /**
4065
+ * Inspects node outputs for a `decision.status` written by `defineHumanApprovalNode`.
4066
+ * Returns the first-class HITL node status and halt classification, or `undefined`
4067
+ * when the node is not a HITL approval node.
4068
+ */
4069
+ resolveHitlStatus(outputs) {
4070
+ const firstItem = outputs?.main?.[0];
4071
+ const decisionStatus = firstItem && typeof firstItem === "object" && "json" in firstItem && firstItem.json && typeof firstItem.json === "object" && "decision" in firstItem.json && firstItem.json.decision && typeof firstItem.json.decision === "object" && "status" in firstItem.json.decision ? firstItem.json.decision.status : void 0;
4072
+ if (!decisionStatus) return void 0;
4073
+ if (decisionStatus === "approved") return {
4074
+ nodeStatus: "hitl-approved",
4075
+ halt: false
4076
+ };
4077
+ if (decisionStatus === "auto-accepted") return {
4078
+ nodeStatus: "hitl-auto-accepted",
4079
+ halt: false
4080
+ };
4081
+ if (decisionStatus === "rejected") return {
4082
+ nodeStatus: "hitl-rejected",
4083
+ halt: true,
4084
+ reason: "hitl-rejected"
4085
+ };
4086
+ if (decisionStatus === "timed-out") return {
4087
+ nodeStatus: "hitl-timeout",
4088
+ halt: true,
4089
+ reason: "hitl-timeout"
4090
+ };
4091
+ }
3905
4092
  formatNodeLabel(args) {
3906
4093
  const tokenName = typeof args.definition?.type === "function" ? args.definition.type.name : "Node";
3907
4094
  return args.definition?.name ? `"${args.definition.name}" (${tokenName}:${args.nodeId})` : `${tokenName}:${args.nodeId}`;
@@ -5254,13 +5441,19 @@ var NodeExecutionRequestHandlerService = class {
5254
5441
  const portKeys = Object.keys(inputsByPort);
5255
5442
  const kind = portKeys.length === 1 && portKeys[0] === "in" ? "single" : "multi";
5256
5443
  const batchId = pendingExecution.batchId ?? "batch_1";
5444
+ const pendingResume = state.pendingResume;
5445
+ const resumeContext = pendingResume?.activationId === request.activationId && pendingResume?.nodeId === request.nodeId ? pendingResume.resumeContext : void 0;
5446
+ const baseWithResume = resumeContext != null ? {
5447
+ ...base,
5448
+ resumeContext
5449
+ } : base;
5257
5450
  const activationRequest = kind === "multi" ? this.nodeActivationRequestComposer.createMultiFromDefinitionWithActivation({
5258
5451
  activationId: request.activationId,
5259
5452
  runId: request.runId,
5260
5453
  workflowId: request.workflowId,
5261
5454
  parent: resolvedParent,
5262
5455
  executionOptions: request.executionOptions ?? state.executionOptions,
5263
- base,
5456
+ base: baseWithResume,
5264
5457
  data,
5265
5458
  definition: {
5266
5459
  id: definition.id,
@@ -5274,7 +5467,7 @@ var NodeExecutionRequestHandlerService = class {
5274
5467
  workflowId: request.workflowId,
5275
5468
  parent: resolvedParent,
5276
5469
  executionOptions: request.executionOptions ?? state.executionOptions,
5277
- base,
5470
+ base: baseWithResume,
5278
5471
  data,
5279
5472
  definition: {
5280
5473
  id: definition.id,
@@ -5283,6 +5476,13 @@ var NodeExecutionRequestHandlerService = class {
5283
5476
  batchId,
5284
5477
  input: inputsByPort.in ?? request.input ?? []
5285
5478
  });
5479
+ if (resumeContext != null) {
5480
+ const clearedState = await this.workflowExecutionRepository.load(request.runId);
5481
+ if (clearedState?.pendingResume?.activationId === request.activationId) await this.workflowExecutionRepository.save({
5482
+ ...clearedState,
5483
+ pendingResume: void 0
5484
+ });
5485
+ }
5286
5486
  await this.continuation.markNodeRunning({
5287
5487
  runId: activationRequest.runId,
5288
5488
  activationId: activationRequest.activationId,
@@ -5293,6 +5493,7 @@ var NodeExecutionRequestHandlerService = class {
5293
5493
  try {
5294
5494
  outputs = await this.nodeExecutor.execute(activationRequest);
5295
5495
  } catch (error) {
5496
+ if (error instanceof RunSuspendedError) return;
5296
5497
  await this.resumeAfterExecutionError(activationRequest, this.asError(error));
5297
5498
  return;
5298
5499
  }
@@ -5853,7 +6054,7 @@ var EngineWaiters = class {
5853
6054
  });
5854
6055
  }
5855
6056
  resolveRunCompletion(result) {
5856
- if (result.status !== "completed" && result.status !== "failed") return;
6057
+ if (result.status !== "completed" && result.status !== "failed" && result.status !== "halted") return;
5857
6058
  const list = this.completionWaiters.get(result.runId);
5858
6059
  if (!list || list.length === 0) return;
5859
6060
  this.completionWaiters.delete(result.runId);
@@ -5947,6 +6148,13 @@ var Engine = class {
5947
6148
  async waitForWebhookResponse(runId) {
5948
6149
  return await this.deps.runContinuationService.waitForWebhookResponse(runId);
5949
6150
  }
6151
+ /**
6152
+ * Re-activate a suspended run item with a human decision (HITL).
6153
+ * The HTTP resume endpoint calls this; this method exposes the engine primitive.
6154
+ */
6155
+ async resumeRun(args) {
6156
+ return await this.deps.runContinuationService.resumeRun(args);
6157
+ }
5950
6158
  async handleNodeExecutionRequest(request) {
5951
6159
  await this.deps.nodeExecutionRequestHandler.handleNodeExecutionRequest(request);
5952
6160
  }
@@ -6154,6 +6362,7 @@ var RunIntentService = class {
6154
6362
  };
6155
6363
  return await Promise.race([this.engine.waitForWebhookResponse(scheduled.runId), this.engine.waitForCompletion(scheduled.runId).then((completed) => {
6156
6364
  if (completed.status === "failed") throw new Error(completed.error.message);
6365
+ if (completed.status === "halted") throw new Error(`Run halted: ${completed.reason}`);
6157
6366
  return {
6158
6367
  runId: completed.runId,
6159
6368
  workflowId: completed.workflowId,
@@ -6278,5 +6487,5 @@ var WorkflowRepositoryWebhookTriggerMatcherFactory = class {
6278
6487
  };
6279
6488
 
6280
6489
  //#endregion
6281
- export { NoOpCostTrackingTelemetryFactory as $, registry as $t, PersistedWorkflowTokenRegistry as A, ConnectionNodeIdFactory as At, DefaultExecutionContextFactory as B, tool as Bt, DefaultDrivingScheduler as C, ConnectionInvocationIdFactory as Ct, NodeInstanceFactoryFactory as D, ChainCursor as Dt, StaticCostCatalog as E, NodeIdSlugifier as Et, RunnableOutputBehaviorResolver as F, resolveItemExprsInUnknown as Ft, CodemationTelemetryAttributeNames as G, container$1 as Gt, nodeRef as H, PersistedRuntimeTypeMetadataStore as Ht, NodeOutputNormalizer as I, NodeBackedToolConfig as It, NoOpExecutionTelemetryFactory as J, injectAll as Jt, AllWorkflowsActiveWorkflowActivationPolicy as K, delay as Kt, ItemExprResolver as L, chatModel as Lt, NodeExecutorFactory as M, isItemExpr as Mt, NodeExecutor as N, itemExpr as Nt, NodeInstanceFactory as O, WhenBuilder as Ot, InProcessRetryRunnerFactory as P, resolveItemExprsForExecution as Pt, NoOpTelemetryArtifactReference as Q, predicateAwareClassFactory as Qt, InProcessRetryRunner as R, getPersistedRuntimeTypeMetadata as Rt, HintOnlyOffloadPolicy as S, NodeIterationIdFactory as St, RunPolicySnapshotFactory as T, WorkflowDefinitionError as Tt, CodemationTelemetryMetricNames as U, StackTraceCallSitePathResolver as Ut, branchRef as V, InjectableRuntimeDecoratorComposer as Vt, GenAiTelemetryAttributeNames as W, PersistedRuntimeTypeNameResolver as Wt, NoOpNodeExecutionTelemetry as X, instanceCachingFactory as Xt, NoOpExecutionTelemetry as Y, injectable as Yt, NoOpTelemetrySpanScope as Z, instancePerContainerCachingFactory as Zt, RunTerminalPersistenceCoordinator as _, NodeEventPublisher as _t, InMemoryLiveWorkflowRepository as a, RetryPolicy as at, LocalOnlyScheduler as b, WorkflowExecutableNodeClassifierFactory as bt, EngineFactory as c, isPortsEmission as ct, PollingTriggerRuntime as d, DefaultAsyncSleeper as dt, singleton as en, NoOpCostTrackingTelemetry as et, PollingTriggerDedupWindow as f, CredentialResolverFactory as ft, WorkflowPolicyErrorServices as g, UnavailableBinaryStorage as gt, WorkflowStoragePolicyEvaluator as h, DefaultExecutionBinaryService as ht, RunIntentService as i, ExpRetryPolicy as it, MissingRuntimeTriggerToken as j, AgentConfigInspector as jt, WorkflowSnapshotCodec as k, AgentConnectionNodeCollector as kt, Engine as l, isUnbrandedPortsEmissionShape as lt, InMemoryBinaryStorage as m, ChildExecutionScopeFactory as mt, WorkflowRepositoryWebhookTriggerMatcher as n, CostTrackingTelemetryMetricNames as nt, EngineWorkflowRunnerServiceFactory as o, NoRetryPolicy as ot, InMemoryRunDataFactory as p, getOriginIndexFromItem as pt, RunFinishedAtFactory as q, inject as qt, RunIntentServiceFactory as r, CredentialUnboundError as rt, EngineWorkflowRunnerService as s, emitPorts as st, WorkflowRepositoryWebhookTriggerMatcherFactory as t, CoreTokens as tn, CostTrackingTelemetryAttributeNames as tt, NoOpPollingTriggerLogger as u, NoOpAgentMcpIntegration as ut, ENGINE_EXECUTION_LIMITS_DEFAULTS as v, ConnectionInvocationEventPublisher as vt, ConfigDrivenOffloadPolicy as w, WorkflowBuilder as wt, InlineDrivingScheduler as x, WorkflowExecutableNodeClassifier as xt, EngineExecutionLimitsPolicy as y, DefaultWorkflowGraphFactory as yt, CatalogBackedCostTrackingTelemetryFactory as z, node as zt };
6282
- //# sourceMappingURL=runtime-Duf3ClPw.js.map
6490
+ export { CostTrackingTelemetryAttributeNames as $, PersistedWorkflowTokenRegistry as A, node as At, CatalogBackedCostTrackingTelemetryFactory as B, HumanTaskStoreToken as Bt, DefaultDrivingScheduler as C, WhenBuilder as Ct, NodeInstanceFactoryFactory as D, defineNode as Dt, StaticCostCatalog as E, defineBatchNode as Et, InProcessRetryRunnerFactory as F, PersistedRuntimeTypeNameResolver as Ft, AllWorkflowsActiveWorkflowActivationPolicy as G, CodemationTelemetryMetricNames as H, RunnableOutputBehaviorResolver as I, DefinedNodeRegistry as It, NoOpNodeExecutionTelemetry as J, NoOpExecutionTelemetryFactory as K, NodeOutputNormalizer as L, HitlResumeTokenSignerToken as Lt, NodeExecutorFactory as M, InjectableRuntimeDecoratorComposer as Mt, NodeExecutor as N, PersistedRuntimeTypeMetadataStore as Nt, NodeInstanceFactory as O, chatModel as Ot, RunSuspendedError as P, StackTraceCallSitePathResolver as Pt, NoOpCostTrackingTelemetry as Q, ItemExprResolver as R, HitlTimeoutJobSchedulerToken as Rt, HintOnlyOffloadPolicy as S, ChainCursor as St, RunPolicySnapshotFactory as T, isHumanApprovalNode as Tt, GenAiTelemetryAttributeNames as U, DefaultExecutionContextFactory as V, CodemationTelemetryAttributeNames as W, NoOpTelemetryArtifactReference as X, NoOpTelemetrySpanScope as Y, NoOpCostTrackingTelemetryFactory as Z, RunTerminalPersistenceCoordinator as _, WorkflowExecutableNodeClassifier as _t, InMemoryLiveWorkflowRepository as a, isPortsEmission as at, LocalOnlyScheduler as b, WorkflowDefinitionError as bt, EngineFactory as c, CredentialResolverFactory as ct, PollingTriggerRuntime as d, DefaultExecutionBinaryService as dt, CostTrackingTelemetryMetricNames as et, PollingTriggerDedupWindow as f, UnavailableBinaryStorage as ft, WorkflowPolicyErrorServices as g, WorkflowExecutableNodeClassifierFactory as gt, WorkflowStoragePolicyEvaluator as h, DefaultWorkflowGraphFactory as ht, RunIntentService as i, emitPorts as it, MissingRuntimeTriggerToken as j, tool as jt, WorkflowSnapshotCodec as k, getPersistedRuntimeTypeMetadata as kt, Engine as l, getOriginIndexFromItem as lt, InMemoryBinaryStorage as m, ConnectionInvocationEventPublisher as mt, WorkflowRepositoryWebhookTriggerMatcher as n, RetryPolicy as nt, EngineWorkflowRunnerServiceFactory as o, isUnbrandedPortsEmissionShape as ot, InMemoryRunDataFactory as p, NodeEventPublisher as pt, NoOpExecutionTelemetry as q, RunIntentServiceFactory as r, NoRetryPolicy as rt, EngineWorkflowRunnerService as s, DefaultAsyncSleeper as st, WorkflowRepositoryWebhookTriggerMatcherFactory as t, ExpRetryPolicy as tt, NoOpPollingTriggerLogger as u, ChildExecutionScopeFactory as ut, ENGINE_EXECUTION_LIMITS_DEFAULTS as v, ConnectionInvocationIdFactory as vt, ConfigDrivenOffloadPolicy as w, defineHumanApprovalNode as wt, InlineDrivingScheduler as x, NodeIdSlugifier as xt, EngineExecutionLimitsPolicy as y, WorkflowBuilder as yt, InProcessRetryRunner as z, HitlWorkspaceIdToken as zt };
6491
+ //# sourceMappingURL=runtime-BPZgnZ9G.js.map