@codemation/core 0.10.1 → 0.11.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 (71) hide show
  1. package/CHANGELOG.md +195 -0
  2. package/dist/{EngineRuntimeRegistration.types-D1fyApMI.d.ts → EngineRuntimeRegistration.types-BZ_1XWAJ.d.ts} +2 -2
  3. package/dist/{EngineRuntimeRegistration.types-pB3FnzqR.d.cts → EngineRuntimeRegistration.types-MPYWsEM0.d.cts} +7 -2
  4. package/dist/{InMemoryRunDataFactory-Xw7v4-sj.d.cts → InMemoryRunDataFactory-hmkh0lzR.d.cts} +8 -3
  5. package/dist/{RunIntentService-BE9CAkbf.d.ts → RunIntentService-BrEq6Jm6.d.ts} +1802 -1605
  6. package/dist/{RunIntentService-siBSjaaY.d.cts → RunIntentService-MUHJ1bhO.d.cts} +1722 -1598
  7. package/dist/bootstrap/index.cjs +2 -2
  8. package/dist/bootstrap/index.d.cts +6 -3
  9. package/dist/bootstrap/index.d.ts +4 -3
  10. package/dist/bootstrap/index.js +2 -2
  11. package/dist/{bootstrap-D3r505ko.js → bootstrap-Dgzsjoj7.js} +7 -2
  12. package/dist/bootstrap-Dgzsjoj7.js.map +1 -0
  13. package/dist/{bootstrap-Cm5ruQxx.cjs → bootstrap-dVmpU1ju.cjs} +7 -2
  14. package/dist/bootstrap-dVmpU1ju.cjs.map +1 -0
  15. package/dist/{index-DeLl1Tne.d.ts → index-Bes88mxT.d.ts} +113 -6
  16. package/dist/index.cjs +71 -3
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +173 -6
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +69 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/{runtime-BGNbRnqs.js → runtime-Duf3ClPw.js} +202 -53
  23. package/dist/runtime-Duf3ClPw.js.map +1 -0
  24. package/dist/{runtime-DKXJwTNv.cjs → runtime-vH0EeZzH.cjs} +208 -53
  25. package/dist/runtime-vH0EeZzH.cjs.map +1 -0
  26. package/dist/testing.cjs +6 -2
  27. package/dist/testing.cjs.map +1 -1
  28. package/dist/testing.d.cts +3 -3
  29. package/dist/testing.d.ts +2 -2
  30. package/dist/testing.js +6 -2
  31. package/dist/testing.js.map +1 -1
  32. package/package.json +4 -13
  33. package/src/ai/AgentConnectionNodeCollector.ts +47 -5
  34. package/src/authoring/defineNode.types.ts +21 -1
  35. package/src/authoring/definePollingTrigger.types.ts +20 -0
  36. package/src/binaries/UnavailableBinaryStorage.ts +6 -0
  37. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +9 -0
  38. package/src/browser.ts +1 -0
  39. package/src/contracts/AgentBindError.ts +11 -0
  40. package/src/contracts/CodemationTelemetryAttributeNames.ts +4 -0
  41. package/src/contracts/NoOpAgentMcpIntegration.ts +13 -0
  42. package/src/contracts/agentMcpTypes.ts +64 -0
  43. package/src/contracts/executionPersistenceContracts.ts +5 -0
  44. package/src/contracts/index.ts +4 -0
  45. package/src/contracts/mcpTypes.ts +29 -0
  46. package/src/contracts/runTypes.ts +13 -0
  47. package/src/contracts/runtimeTypes.ts +10 -0
  48. package/src/contracts/workflowTypes.ts +21 -0
  49. package/src/contracts.ts +3 -0
  50. package/src/credentials/OAuthFlowExecutor.types.ts +45 -0
  51. package/src/di/CoreTokens.ts +7 -0
  52. package/src/execution/InProcessRetryRunner.ts +31 -5
  53. package/src/execution/NodeExecutionSnapshotFactory.ts +3 -0
  54. package/src/execution/NodeExecutor.ts +27 -7
  55. package/src/execution/NodeRunStateWriter.ts +14 -0
  56. package/src/index.ts +10 -0
  57. package/src/orchestration/RunContinuationService.ts +6 -2
  58. package/src/runStorage/InMemoryBinaryStorageRegistry.ts +10 -0
  59. package/src/scheduler/InlineDrivingScheduler.ts +26 -22
  60. package/src/testing/SubWorkflowRunnerTestNode.ts +1 -0
  61. package/src/types/index.ts +1 -0
  62. package/src/validation/WorkflowEdgePortError.types.ts +16 -0
  63. package/src/validation/WorkflowEdgePortValidator.ts +52 -0
  64. package/src/workflow/definition/ConnectionInvocationIdFactory.ts +4 -3
  65. package/src/workflow/definition/ConnectionNodeIdFactory.ts +25 -0
  66. package/src/workflow/definition/NodeIterationIdFactory.ts +5 -3
  67. package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +42 -10
  68. package/dist/bootstrap-Cm5ruQxx.cjs.map +0 -1
  69. package/dist/bootstrap-D3r505ko.js.map +0 -1
  70. package/dist/runtime-BGNbRnqs.js.map +0 -1
  71. package/dist/runtime-DKXJwTNv.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { DependencyContainer as Container, DependencyContainer as DependencyContainer$1, Disposable, InjectionToken as InjectionToken$1, InjectionToken as TypeToken, Lifecycle, RegistrationOptions, container, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
2
1
  import { ReadableStream } from "node:stream/web";
3
2
  import { ZodType } from "zod";
3
+ import { DependencyContainer as Container, DependencyContainer as DependencyContainer$1, Disposable, InjectionToken as InjectionToken$1, InjectionToken as TypeToken, Lifecycle, RegistrationOptions, container, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
4
4
 
5
5
  //#region src/contracts/baseTypes.d.ts
6
6
  /**
@@ -15,1811 +15,1935 @@ type InputPortKey = string;
15
15
  type PersistedTokenId = string;
16
16
  type NodeConnectionName = string;
17
17
  //#endregion
18
- //#region src/contracts/testTriggerTypes.d.ts
18
+ //#region src/triggers/polling/PollingTriggerDedupWindow.d.ts
19
19
  /**
20
- * Identifier minted by the host (or in-memory test runner) for one execution of a test suite.
21
- * One TestSuiteRun produces N child workflow runs, one per item yielded by `generateItems`.
20
+ * Merges processed-ID windows for polling triggers, capping the total to avoid unbounded growth.
21
+ * Plugin code receives an instance of this class via {@link PollingTriggerHandle.dedup}.
22
22
  */
23
- type TestSuiteRunId = string;
23
+ declare class PollingTriggerDedupWindow {
24
+ static readonly defaultCapN = 2000;
25
+ merge(previous: ReadonlyArray<string>, incoming: ReadonlyArray<string>, capN?: number): ReadonlyArray<string>;
26
+ }
27
+ //#endregion
28
+ //#region src/triggers/polling/PollingTriggerLogger.d.ts
24
29
  /**
25
- * Setup context passed to a {@link TestTriggerNodeConfig.generateItems} callback. Distinct from
26
- * {@link import("./runtimeTypes").TriggerSetupContext} on purpose: test triggers are not
27
- * activated by the live trigger lifecycle (webhooks, cron, polling) and never call `emit` —
28
- * the orchestrator pulls from the iterable they return and dispatches one run per item.
30
+ * Minimal logger surface for the polling-trigger runtime.
31
+ * Hosts supply this via {@link EngineDeps.pollingTriggerLogger};
32
+ * when absent the runtime is silent.
29
33
  */
30
- interface TestTriggerSetupContext<TConfig extends TestTriggerNodeConfig<unknown> = TestTriggerNodeConfig<unknown>> {
31
- readonly workflowId: WorkflowId;
32
- readonly nodeId: NodeId;
33
- readonly config: TConfig;
34
- readonly testSuiteRunId: TestSuiteRunId;
34
+ interface PollingTriggerLogger {
35
+ info(message: string): void;
36
+ warn(message: string): void;
37
+ error(message: string, exception?: Error): void;
38
+ debug(message: string): void;
39
+ }
40
+ declare class NoOpPollingTriggerLogger implements PollingTriggerLogger {
41
+ info(): void;
42
+ warn(): void;
43
+ error(): void;
44
+ debug(): void;
45
+ }
46
+ //#endregion
47
+ //#region src/contracts/credentialTypes.d.ts
48
+ type CredentialTypeId = string;
49
+ type CredentialInstanceId = string;
50
+ type CredentialMaterialSourceKind = "db" | "env" | "code";
51
+ type CredentialSetupStatus = "draft" | "ready";
52
+ type CredentialHealthStatus = "unknown" | "healthy" | "failing";
53
+ type CredentialFieldSchema = Readonly<{
54
+ key: string;
55
+ label: string;
56
+ type: "string" | "password" | "textarea" | "json" | "boolean";
57
+ required?: true;
58
+ order?: number;
35
59
  /**
36
- * Resolves a credential session for a slot declared on this trigger's
37
- * {@link import("./workflowTypes").NodeConfigBase.getCredentialRequirements}. Same contract as
38
- * {@link import("./runtimeTypes").ExecutionContext.getCredential}.
60
+ * Where this field appears in the credential dialog. Use `"advanced"` for optional or
61
+ * power-user fields; they render inside a collapsible section (see `CredentialTypeDefinition.advancedSection`).
62
+ * Defaults to `"default"` when omitted.
39
63
  */
40
- getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
41
- /** AbortSignal raised when the suite is cancelled — long-running pulls should bail out. */
42
- readonly signal: AbortSignal;
43
- }
44
- /**
45
- * A trigger config that emits **test cases**. Each item yielded by {@link generateItems}
46
- * becomes one workflow run (with `executionOptions.testContext` set), so 10 yielded items
47
- * → 10 runs marked under the same TestSuiteRun.
48
- *
49
- * The trigger is otherwise a normal {@link TriggerNodeConfig} (so the canvas treats it like
50
- * any other trigger), but its `triggerKind` is `"test"` so the live activation policy skips it.
51
- */
52
- interface TestTriggerNodeConfig<TOutputJson$1 = unknown> extends TriggerNodeConfig<TOutputJson$1, undefined> {
53
- readonly triggerKind: "test";
64
+ visibility?: "default" | "advanced";
65
+ placeholder?: string;
66
+ helpText?: string;
67
+ /** When set, host resolves this field from process.env at runtime; env wins over stored values. */
68
+ envVarName?: string;
54
69
  /**
55
- * Author-supplied async iterable of items, evaluated lazily. Implementations may fetch from
56
- * credentialed APIs, read fixture files, or yield hard-coded items. The orchestrator iterates
57
- * and dispatches one run per item, with concurrency capped by {@link concurrency} (default 4).
70
+ * When set, the dialog shows a copy action for this exact string (e.g. a static OAuth redirect URI
71
+ * pattern or documentation URL). Do not use for secret values.
58
72
  */
59
- generateItems(ctx: TestTriggerSetupContext<TestTriggerNodeConfig<TOutputJson$1>>): AsyncIterable<Item<TOutputJson$1>>;
60
- /** Per-suite-run cap on simultaneously-executing test cases. Default: 4. */
61
- readonly concurrency?: number;
73
+ copyValue?: string;
74
+ /** Accessible label for the copy control (default: Copy). */
75
+ copyButtonLabel?: string;
76
+ }>;
77
+ type CredentialRequirement = Readonly<{
78
+ slotKey: string;
79
+ label: string;
80
+ acceptedTypes: ReadonlyArray<CredentialTypeId>;
81
+ optional?: true;
82
+ helpText?: string;
83
+ helpUrl?: string;
84
+ }>;
85
+ type CredentialBindingKey = Readonly<{
86
+ workflowId: WorkflowId;
87
+ nodeId: NodeId;
88
+ slotKey: string;
89
+ }>;
90
+ type CredentialBinding = Readonly<{
91
+ key: CredentialBindingKey;
92
+ instanceId: CredentialInstanceId;
93
+ updatedAt: string;
94
+ }>;
95
+ type CredentialHealth = Readonly<{
96
+ status: CredentialHealthStatus;
97
+ message?: string;
98
+ testedAt?: string;
99
+ expiresAt?: string;
100
+ details?: Readonly<Record<string, unknown>>;
101
+ }>;
102
+ type OAuth2ProviderFromPublicConfig = Readonly<{
103
+ authorizeUrlFieldKey: string;
104
+ tokenUrlFieldKey: string;
105
+ userInfoUrlFieldKey?: string;
106
+ }>;
107
+ type CredentialOAuth2ScopesFromPublicConfig = Readonly<{
108
+ presetFieldKey: string;
109
+ presetScopes: Readonly<Record<string, ReadonlyArray<string>>>;
110
+ customPresetKey?: string;
111
+ customScopesFieldKey?: string;
112
+ }>;
113
+ type CredentialOAuth2AuthDefinition = Readonly<{
114
+ kind: "oauth2";
115
+ providerId: string;
116
+ scopes: ReadonlyArray<string>;
117
+ scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
118
+ clientIdFieldKey?: string;
119
+ clientSecretFieldKey?: string;
120
+ } | {
121
+ kind: "oauth2";
122
+ providerFromPublicConfig: OAuth2ProviderFromPublicConfig;
123
+ scopes: ReadonlyArray<string>;
124
+ scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
125
+ clientIdFieldKey?: string;
126
+ clientSecretFieldKey?: string;
127
+ } | {
128
+ kind: "oauth2";
62
129
  /**
63
- * Free-form description of where the test cases come from surfaced in the node properties
64
- * panel and the suite-detail header so authors revisiting the workflow six months later
65
- * remember which mailbox / folder / fixture file the cases originate from.
66
- *
67
- * Example: `"All emails in the Gmail label \"test/triage-fixtures\" — 14 messages as of 2026-05-03."`
130
+ * Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.
131
+ * Not used for any registry lookup URLs come from {@link authorizeUrl} / {@link tokenUrl}.
68
132
  */
69
- readonly description?: string;
133
+ providerId: string;
70
134
  /**
71
- * Resolves a human-readable label for one yielded test case (e.g. email subject). The
72
- * orchestrator calls this once per yielded item, persists the result on the run, and the
73
- * Tests-tab UI uses it to render the case row instead of the opaque runId. Return
74
- * `undefined` to fall back to "Case #N".
135
+ * Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime
136
+ * substitutes from the credential's resolved public config (URL-encoded).
137
+ * Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`
75
138
  */
76
- caseLabel?(item: Item<TOutputJson$1>): string | undefined;
77
- }
78
- //#endregion
79
- //#region src/events/runEvents.d.ts
139
+ authorizeUrl: string;
140
+ /** Token endpoint. Same templating rules as {@link authorizeUrl}. */
141
+ tokenUrl: string;
142
+ /** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */
143
+ userInfoUrl?: string;
144
+ scopes: ReadonlyArray<string>;
145
+ scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
146
+ clientIdFieldKey?: string;
147
+ clientSecretFieldKey?: string;
148
+ }>;
149
+ type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;
150
+ type CredentialAdvancedSectionPresentation = Readonly<{
151
+ /** Collapsible section title (default: "Advanced"). */
152
+ title?: string;
153
+ /** Optional short helper text shown inside the section (above the fields). */
154
+ description?: string;
155
+ /** When true, the advanced section starts expanded. Default: false (collapsed). */
156
+ defaultOpen?: boolean;
157
+ }>;
158
+ type CredentialTypeDefinition = Readonly<{
159
+ typeId: CredentialTypeId;
160
+ displayName: string;
161
+ description?: string;
162
+ publicFields?: ReadonlyArray<CredentialFieldSchema>;
163
+ secretFields?: ReadonlyArray<CredentialFieldSchema>;
164
+ /**
165
+ * Optional labels for the collapsible block that contains every field with `visibility: "advanced"`.
166
+ * If omitted, the UI still shows that block with defaults (title "Advanced", collapsed).
167
+ */
168
+ advancedSection?: CredentialAdvancedSectionPresentation;
169
+ supportedSourceKinds?: ReadonlyArray<CredentialMaterialSourceKind>;
170
+ auth?: CredentialAuthDefinition;
171
+ }>;
80
172
  /**
81
- * Outcome of a single test case (one workflow run dispatched by the test-suite orchestrator).
82
- * - `running`: workflow still in flight
83
- * - `succeeded`: workflow completed AND all assertions passed (or no assertions)
84
- * - `failed`: workflow failed OR (workflow completed but ≥1 assertion failed)
85
- * - `errored` / `cancelled`: workflow itself errored or was cancelled
173
+ * JSON-shaped credential field bag (public config, resolved secret material, etc.).
86
174
  */
87
- type TestCaseRunStatus = "running" | "succeeded" | "failed" | "errored" | "cancelled";
88
- /** Aggregate outcome of a TestSuiteRun. */
89
- type TestSuiteRunStatus = "succeeded" | "failed" | "partial" | "errored" | "cancelled";
90
- type RunEvent = Readonly<{
91
- kind: "runCreated";
92
- runId: RunId;
93
- workflowId: WorkflowId;
94
- parent?: ParentExecutionRef;
95
- at: string;
96
- }> | Readonly<{
97
- kind: "runSaved";
98
- runId: RunId;
99
- workflowId: WorkflowId;
100
- parent?: ParentExecutionRef;
101
- at: string;
102
- state: PersistedRunState;
103
- }> | Readonly<{
104
- kind: "nodeQueued";
105
- runId: RunId;
106
- workflowId: WorkflowId;
107
- parent?: ParentExecutionRef;
108
- at: string;
109
- snapshot: NodeExecutionSnapshot;
110
- }> | Readonly<{
111
- kind: "nodeStarted";
112
- runId: RunId;
113
- workflowId: WorkflowId;
114
- parent?: ParentExecutionRef;
115
- at: string;
116
- snapshot: NodeExecutionSnapshot;
117
- }> | Readonly<{
118
- kind: "nodeCompleted";
119
- runId: RunId;
120
- workflowId: WorkflowId;
121
- parent?: ParentExecutionRef;
122
- at: string;
123
- snapshot: NodeExecutionSnapshot;
124
- }> | Readonly<{
125
- kind: "nodeFailed";
126
- runId: RunId;
127
- workflowId: WorkflowId;
128
- parent?: ParentExecutionRef;
129
- at: string;
130
- snapshot: NodeExecutionSnapshot;
131
- }> | Readonly<{
132
- kind: "connectionInvocationStarted";
133
- runId: RunId;
134
- workflowId: WorkflowId;
135
- parent?: ParentExecutionRef;
136
- at: string;
137
- record: ConnectionInvocationRecord;
138
- }> | Readonly<{
139
- kind: "connectionInvocationCompleted";
140
- runId: RunId;
141
- workflowId: WorkflowId;
142
- parent?: ParentExecutionRef;
143
- at: string;
144
- record: ConnectionInvocationRecord;
145
- }> | Readonly<{
146
- kind: "connectionInvocationFailed";
147
- runId: RunId;
148
- workflowId: WorkflowId;
149
- parent?: ParentExecutionRef;
150
- at: string;
151
- record: ConnectionInvocationRecord;
152
- }> | Readonly<{
153
- kind: "testSuiteStarted";
154
- testSuiteRunId: TestSuiteRunId;
155
- workflowId: WorkflowId;
156
- triggerNodeId: string;
157
- triggerNodeName?: string;
158
- concurrency: number;
159
- at: string;
160
- }> | Readonly<{
161
- kind: "testSuiteFinished";
162
- testSuiteRunId: TestSuiteRunId;
163
- workflowId: WorkflowId;
164
- status: TestSuiteRunStatus;
165
- totalCases: number;
166
- passedCases: number;
167
- failedCases: number;
168
- at: string;
169
- }> | Readonly<{
170
- kind: "testCaseStarted";
171
- testSuiteRunId: TestSuiteRunId;
172
- testCaseIndex: number;
173
- runId: RunId;
174
- workflowId: WorkflowId;
175
- testCaseLabel?: string;
176
- at: string;
177
- }> | Readonly<{
178
- kind: "testCaseCompleted";
179
- testSuiteRunId: TestSuiteRunId;
180
- testCaseIndex: number;
181
- runId: RunId;
182
- workflowId: WorkflowId;
183
- status: TestCaseRunStatus;
184
- at: string;
175
+ type CredentialJsonRecord = Readonly<Record<string, unknown>>;
176
+ /**
177
+ * Persisted credential instance with typed `publicConfig`.
178
+ * Hosts may specialize `secretRef` with a stricter union while remaining
179
+ * assignable here for session/test callbacks.
180
+ */
181
+ type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{
182
+ instanceId: CredentialInstanceId;
183
+ typeId: CredentialTypeId;
184
+ displayName: string;
185
+ sourceKind: CredentialMaterialSourceKind;
186
+ publicConfig: TPublicConfig;
187
+ secretRef: CredentialJsonRecord;
188
+ tags: ReadonlyArray<string>;
189
+ setupStatus: CredentialSetupStatus;
190
+ createdAt: string;
191
+ updatedAt: string;
185
192
  }>;
186
- interface RunEventSubscription {
187
- close(): Promise<void>;
193
+ /**
194
+ * Arguments passed to `CredentialType.createSession` and `CredentialType.test`.
195
+ * Declare `TPublicConfig` / `TMaterial` on `CredentialType` so implementations are checked
196
+ * against your credential shapes (similar to `NodeExecutionContext.config` for nodes).
197
+ */
198
+ type CredentialSessionFactoryArgs<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{
199
+ instance: CredentialInstanceRecord<TPublicConfig>;
200
+ material: TMaterial;
201
+ publicConfig: TPublicConfig;
202
+ }>;
203
+ type CredentialSessionFactory<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord, TSession = unknown> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<TSession>;
204
+ type CredentialHealthTester<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<CredentialHealth>;
205
+ /**
206
+ * Full credential type implementation: `definition` (UI/schema), `createSession`, and `test`.
207
+ * Use this at registration and config boundaries; `CredentialTypeDefinition` is only the schema slice.
208
+ */
209
+ type CredentialType<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord, TSession = unknown> = Readonly<{
210
+ definition: CredentialTypeDefinition;
211
+ createSession: CredentialSessionFactory<TPublicConfig, TMaterial, TSession>;
212
+ test: CredentialHealthTester<TPublicConfig, TMaterial>;
213
+ }>;
214
+ /**
215
+ * Credential type with unspecified generics — used for `CodemationConfig.credentialTypes`, the host registry,
216
+ * and anywhere a concrete `CredentialType<YourPublic, YourMaterial, YourSession>` is placed in a heterogeneous list.
217
+ * Using `any` here avoids unsafe `as` casts while keeping typed `satisfies CredentialType<…>` definitions.
218
+ */
219
+ type AnyCredentialType = CredentialType<any, any, unknown>;
220
+ interface CredentialSessionService {
221
+ getSession<TSession = unknown>(args: Readonly<{
222
+ workflowId: WorkflowId;
223
+ nodeId: NodeId;
224
+ slotKey: string;
225
+ }>): Promise<TSession>;
188
226
  }
189
- interface RunEventBus {
190
- publish(event: RunEvent): Promise<void>;
191
- subscribe(onEvent: (event: RunEvent) => void): Promise<RunEventSubscription>;
192
- subscribeToWorkflow(workflowId: WorkflowId, onEvent: (event: RunEvent) => void): Promise<RunEventSubscription>;
227
+ interface CredentialTypeRegistry {
228
+ listTypes(): ReadonlyArray<CredentialTypeDefinition>;
229
+ getType(typeId: CredentialTypeId): CredentialTypeDefinition | undefined;
193
230
  }
194
- //#endregion
195
- //#region src/policies/executionLimits/EngineExecutionLimitsPolicy.d.ts
196
- interface EngineExecutionLimitsPolicyConfig {
197
- readonly defaultMaxNodeActivations: number;
198
- readonly hardMaxNodeActivations: number;
199
- readonly defaultMaxSubworkflowDepth: number;
200
- readonly hardMaxSubworkflowDepth: number;
231
+ declare class CredentialUnboundError extends Error {
232
+ readonly bindingKey: CredentialBindingKey;
233
+ readonly acceptedTypes: ReadonlyArray<CredentialTypeId>;
234
+ constructor(bindingKey: CredentialBindingKey, acceptedTypes?: ReadonlyArray<CredentialTypeId>);
235
+ private static createMessage;
201
236
  }
202
- /** Framework defaults for {@link EngineExecutionLimitsPolicy} (merged with host `runtime.engineExecutionLimits`). */
203
- declare const ENGINE_EXECUTION_LIMITS_DEFAULTS: EngineExecutionLimitsPolicyConfig;
237
+ //#endregion
238
+ //#region src/contracts/collectionTypes.d.ts
204
239
  /**
205
- * Resolves per-run execution limits: defaults, hard ceilings, and subworkflow depth for new runs.
240
+ * Represents a typed store for a single collection.
241
+ * All rows include auto-managed id, created_at, and updated_at fields.
206
242
  */
207
- declare class EngineExecutionLimitsPolicy {
208
- private readonly config;
209
- constructor(config?: EngineExecutionLimitsPolicyConfig);
243
+ interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
210
244
  /**
211
- * Effective options for a new root run (depth 0): defaults merged with engine ceilings.
212
- * Replaces a separate one-method factory for root-run bootstrap.
245
+ * Insert a new row. id, created_at, and updated_at are auto-populated.
213
246
  */
214
- createRootExecutionOptions(): RunExecutionOptions;
215
- mergeExecutionOptionsForNewRun(parent: ParentExecutionRef | undefined, user: RunExecutionOptions | undefined): RunExecutionOptions;
216
- private capNumber;
217
- }
218
- //#endregion
219
- //#region src/di/CoreTokens.d.ts
220
- declare const CoreTokens: {
221
- readonly PersistedWorkflowTokenRegistry: TypeToken<PersistedWorkflowTokenRegistryLike>;
222
- readonly CredentialSessionService: TypeToken<CredentialSessionService>;
223
- readonly CredentialTypeRegistry: TypeToken<CredentialTypeRegistry>;
224
- readonly WorkflowRunnerService: TypeToken<WorkflowRunnerService>;
225
- readonly LiveWorkflowRepository: TypeToken<LiveWorkflowRepository>;
226
- readonly WorkflowRepository: TypeToken<WorkflowRepository>;
227
- readonly NodeResolver: TypeToken<NodeResolver>;
228
- readonly WorkflowNodeInstanceFactory: TypeToken<WorkflowNodeInstanceFactory>;
229
- readonly RunIdFactory: TypeToken<RunIdFactory>;
230
- readonly ActivationIdFactory: TypeToken<ActivationIdFactory>;
231
- readonly WorkflowExecutionRepository: TypeToken<WorkflowExecutionRepository>;
232
- readonly TriggerSetupStateRepository: TypeToken<TriggerSetupStateRepository>;
233
- readonly NodeActivationScheduler: TypeToken<NodeActivationScheduler>;
234
- readonly RunDataFactory: TypeToken<RunDataFactory>;
235
- readonly ExecutionContextFactory: TypeToken<ExecutionContextFactory>;
236
- readonly RunEventBus: TypeToken<RunEventBus>;
237
- readonly BinaryStorage: TypeToken<BinaryStorage>;
238
- readonly WebhookBasePath: TypeToken<string>;
239
- /** Engine execution limits (defaults + optional host overrides). Consumers may bind a custom instance to override. */
240
- readonly EngineExecutionLimitsPolicy: TypeToken<EngineExecutionLimitsPolicy>;
241
- readonly WorkflowActivationPolicy: TypeToken<WorkflowActivationPolicy>;
242
- };
243
- //#endregion
244
- //#region src/contracts/runTypes.d.ts
245
- /**
246
- * Test-suite linkage for a run. When set, this run was started by a TestSuiteOrchestrator
247
- * as one test case inside a TestSuiteRun. The `IsTestRun` node and host-side persisters key
248
- * off the presence of this field. Subworkflow runs inherit it from their parent run.
249
- */
250
- interface RunTestContext {
251
- readonly testSuiteRunId: string;
252
- readonly testCaseIndex: number;
247
+ insert(row: TRow): Promise<TRow & {
248
+ id: string;
249
+ created_at: Date;
250
+ updated_at: Date;
251
+ }>;
253
252
  /**
254
- * Optional human-friendly label for this test case (e.g. an email subject when fixtures
255
- * are loaded from a mailbox). Resolved per item by `TestTrigger.caseLabel(item)` if set,
256
- * persisted on `Run.test_case_label` so the Tests-tab tree-table can show "RFQ for batch 14"
257
- * instead of "run_1777755971399_bbb86beac1396".
253
+ * Get a single row by id.
258
254
  */
259
- readonly testCaseLabel?: string;
260
- }
261
- interface RunExecutionOptions {
262
- /** Run-intent override: force the inline scheduler and bypass node-level offload decisions. */
263
- localOnly?: boolean;
264
- /** Marks runs started from webhook handling so orchestration can apply webhook-specific continuation rules. */
265
- webhook?: boolean;
266
- mode?: "manual" | "debug";
267
- sourceWorkflowId?: WorkflowId;
268
- sourceRunId?: RunId;
269
- derivedFromRunId?: RunId;
270
- isMutable?: boolean;
271
- /** Set by the engine for this run: 0 = root, 1 = first child subworkflow, … */
272
- subworkflowDepth?: number;
273
- /** Effective cap after engine policy merge (successful node completions per run). */
274
- maxNodeActivations?: number;
275
- /** Effective cap after engine policy merge (subworkflow nesting). */
276
- maxSubworkflowDepth?: number;
277
- /** Present iff started by a TestSuiteOrchestrator; propagates to subworkflow runs via {@link ParentExecutionRef.testContext}. */
278
- testContext?: RunTestContext;
279
- }
280
- /** Engine-owned counters persisted with the run (worker-safe). */
281
- interface EngineRunCounters {
282
- completedNodeActivations: number;
283
- }
284
- type RunStopCondition = Readonly<{
285
- kind: "workflowCompleted";
286
- }> | Readonly<{
287
- kind: "nodeCompleted";
288
- nodeId: NodeId;
289
- }>;
290
- interface RunStateResetRequest {
291
- clearFromNodeId: NodeId;
292
- }
293
- interface PersistedRunControlState {
294
- stopCondition?: RunStopCondition;
295
- }
296
- interface PersistedWorkflowSnapshotNode {
297
- id: NodeId;
298
- kind: NodeKind;
299
- name?: string;
300
- nodeTokenId: PersistedTokenId;
301
- configTokenId: PersistedTokenId;
302
- tokenName?: string;
303
- configTokenName?: string;
304
- config: unknown;
305
- }
306
- interface PersistedWorkflowSnapshot {
307
- id: WorkflowId;
308
- name: string;
309
- nodes: ReadonlyArray<PersistedWorkflowSnapshotNode>;
310
- edges: ReadonlyArray<Edge>;
311
- /** When the snapshot was built from a live workflow definition that configured a workflow error handler. */
312
- workflowErrorHandlerConfigured?: boolean;
313
- /** Connection metadata for child nodes not in the execution graph (e.g. AI agent attachments). */
314
- connections?: ReadonlyArray<WorkflowNodeConnection>;
315
- }
316
- type PinnedNodeOutputsByPort = Readonly<Record<OutputPortKey, Items>>;
317
- interface PersistedMutableNodeState {
318
- pinnedOutputsByPort?: PinnedNodeOutputsByPort;
319
- lastDebugInput?: Items;
320
- }
321
- interface PersistedMutableRunState {
322
- nodesById: Readonly<Record<NodeId, PersistedMutableNodeState>>;
323
- }
324
- type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
325
- interface RunQueueEntry {
326
- nodeId: NodeId;
327
- input: Items;
328
- toInput?: InputPortKey;
329
- batchId?: string;
330
- from?: Readonly<{
331
- nodeId: NodeId;
332
- output: OutputPortKey;
255
+ get(id: string): Promise<(TRow & {
256
+ id: string;
257
+ created_at: Date;
258
+ updated_at: Date;
259
+ }) | null>;
260
+ /**
261
+ * Find a single row matching the provided filter.
262
+ */
263
+ findOne(filter: Partial<TRow>): Promise<(TRow & {
264
+ id: string;
265
+ created_at: Date;
266
+ updated_at: Date;
267
+ }) | null>;
268
+ /**
269
+ * List rows with optional pagination and filtering.
270
+ */
271
+ list(opts?: {
272
+ limit?: number;
273
+ offset?: number;
274
+ where?: Partial<TRow>;
275
+ }): Promise<{
276
+ rows: ReadonlyArray<TRow & {
277
+ id: string;
278
+ created_at: Date;
279
+ updated_at: Date;
280
+ }>;
281
+ total: number;
333
282
  }>;
334
- collect?: Readonly<{
335
- expectedInputs: ReadonlyArray<InputPortKey>;
336
- received: Readonly<Record<InputPortKey, Items>>;
283
+ /**
284
+ * Update a row by id with partial data.
285
+ */
286
+ update(id: string, patch: Partial<TRow>): Promise<TRow & {
287
+ id: string;
288
+ created_at: Date;
289
+ updated_at: Date;
290
+ }>;
291
+ /**
292
+ * Delete a row by id. Hard delete only (no soft delete).
293
+ */
294
+ delete(id: string): Promise<{
295
+ deleted: boolean;
337
296
  }>;
338
297
  }
339
- type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
340
- interface NodeExecutionError {
341
- message: string;
342
- name?: string;
343
- stack?: string;
344
- details?: JsonValue;
345
- }
346
- interface NodeExecutionSnapshot {
347
- runId: RunId;
348
- workflowId: WorkflowId;
349
- nodeId: NodeId;
350
- activationId?: NodeActivationId;
351
- parent?: ParentExecutionRef;
352
- status: NodeExecutionStatus;
353
- usedPinnedOutput?: boolean;
354
- queuedAt?: string;
355
- startedAt?: string;
356
- finishedAt?: string;
357
- updatedAt: string;
358
- inputsByPort?: NodeInputsByPort;
359
- outputs?: NodeOutputs;
360
- error?: NodeExecutionError;
361
- }
362
- /** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
363
- type ConnectionInvocationId = string;
364
298
  /**
365
- * One logical LLM or tool call under an owning workflow node (e.g. AI agent).
366
- * The owning node defines what {@link managedInput} and {@link managedOutput} contain.
299
+ * Runtime collections context: keyed by collection name.
367
300
  */
368
- interface ConnectionInvocationRecord {
369
- readonly invocationId: ConnectionInvocationId;
370
- readonly runId: RunId;
371
- readonly workflowId: WorkflowId;
372
- readonly connectionNodeId: NodeId;
373
- readonly parentAgentNodeId: NodeId;
374
- readonly parentAgentActivationId: NodeActivationId;
375
- readonly status: NodeExecutionStatus;
376
- readonly managedInput?: JsonValue;
377
- readonly managedOutput?: JsonValue;
378
- readonly error?: NodeExecutionError;
379
- readonly queuedAt?: string;
380
- readonly startedAt?: string;
381
- readonly finishedAt?: string;
382
- readonly updatedAt: string;
383
- /** Per-item iteration id minted by the engine when this invocation occurred inside a runnable node's per-item loop. */
384
- readonly iterationId?: NodeIterationId;
385
- /** Item index (0-based) of the iteration that produced this invocation. */
386
- readonly itemIndex?: number;
387
- /** When set, this invocation was produced inside a sub-agent triggered by the named parent invocation. */
388
- readonly parentInvocationId?: ConnectionInvocationId;
389
- }
390
- /** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
391
- type ConnectionInvocationAppendArgs = Readonly<{
392
- invocationId: ConnectionInvocationId;
393
- connectionNodeId: NodeId;
394
- parentAgentNodeId: NodeId;
395
- parentAgentActivationId: NodeActivationId;
396
- status: NodeExecutionStatus;
397
- managedInput?: JsonValue;
398
- managedOutput?: JsonValue;
399
- error?: NodeExecutionError;
400
- queuedAt?: string;
401
- startedAt?: string;
402
- finishedAt?: string;
403
- iterationId?: NodeIterationId;
404
- itemIndex?: number;
405
- parentInvocationId?: ConnectionInvocationId;
406
- }>;
407
- interface RunCurrentState {
408
- outputsByNode: Record<NodeId, NodeOutputs>;
409
- nodeSnapshotsByNodeId: Record<NodeId, NodeExecutionSnapshot>;
410
- /** Append-only history of connection-scoped invocations (LLM/tool) for inspector and canvas. */
411
- connectionInvocations?: ReadonlyArray<ConnectionInvocationRecord>;
412
- mutableState?: PersistedMutableRunState;
413
- }
414
- interface CurrentStateExecutionRequest {
415
- workflow: WorkflowDefinition;
416
- items?: Items;
417
- parent?: ParentExecutionRef;
418
- executionOptions?: RunExecutionOptions;
419
- workflowSnapshot?: PersistedWorkflowSnapshot;
420
- mutableState?: PersistedMutableRunState;
421
- currentState?: RunCurrentState;
422
- stopCondition?: RunStopCondition;
423
- reset?: RunStateResetRequest;
301
+ type CollectionsContext = Readonly<Record<string, CollectionStore>>;
302
+ //#endregion
303
+ //#region src/contracts/CostTrackingTelemetryContract.d.ts
304
+ type CostTrackingComponent = "chat" | "ocr" | "rag";
305
+ declare const CostTrackingTelemetryMetricNames: {
306
+ readonly usage: "codemation.cost.usage";
307
+ readonly estimatedCost: "codemation.cost.estimated";
308
+ };
309
+ declare const CostTrackingTelemetryAttributeNames: {
310
+ readonly component: "cost.component";
311
+ readonly provider: "cost.provider";
312
+ readonly operation: "cost.operation";
313
+ readonly pricingKey: "cost.pricing_key";
314
+ readonly usageUnit: "cost.usage_unit";
315
+ readonly currency: "cost.currency";
316
+ readonly currencyScale: "cost.currency_scale";
317
+ readonly estimateKind: "cost.estimate_kind";
318
+ };
319
+ interface CostTrackingUsageRecord {
320
+ readonly component: CostTrackingComponent;
321
+ readonly provider: string;
322
+ readonly operation: string;
323
+ readonly pricingKey: string;
324
+ readonly usageUnit: string;
325
+ readonly quantity: number;
326
+ readonly modelName?: string;
327
+ readonly attributes?: TelemetryAttributes;
424
328
  }
425
- interface ExecutionFrontierPlan {
426
- rootNodeId?: NodeId;
427
- rootNodeInput?: Items;
428
- queue: RunQueueEntry[];
429
- currentState: RunCurrentState;
430
- stopCondition: RunStopCondition;
431
- satisfiedNodeIds: ReadonlyArray<NodeId>;
432
- skippedNodeIds: ReadonlyArray<NodeId>;
433
- clearedNodeIds: ReadonlyArray<NodeId>;
434
- preservedPinnedNodeIds: ReadonlyArray<NodeId>;
329
+ interface CostTrackingPriceQuote {
330
+ readonly currency: string;
331
+ readonly currencyScale: number;
332
+ readonly estimatedAmountMinor: number;
333
+ readonly estimateKind: "catalog";
435
334
  }
436
- type RunStatus = "running" | "pending" | "completed" | "failed";
437
- interface RunSummary {
438
- runId: RunId;
439
- workflowId: WorkflowId;
440
- startedAt: string;
441
- status: RunStatus;
442
- /**
443
- * Test-case status for runs dispatched as part of a TestSuiteRun. Carries the
444
- * assertion-rollup-corrected outcome the test orchestrator persists onto the row, so the
445
- * executions list can show "failed" for a run whose workflow completed cleanly but whose
446
- * assertions caught regressions. Absent for non-test runs and legacy rows.
447
- */
448
- testCaseStatus?: TestCaseRunStatus;
449
- /** ISO timestamp when the run finished (derived from node snapshots or store `updatedAt`); omit while running/pending. */
450
- finishedAt?: string;
451
- parent?: ParentExecutionRef;
452
- executionOptions?: RunExecutionOptions;
335
+ interface CostTrackingTelemetry {
336
+ captureUsage(args: CostTrackingUsageRecord): Promise<CostTrackingPriceQuote | undefined>;
337
+ forScope(scope: TelemetryScope): CostTrackingTelemetry;
453
338
  }
454
- interface PendingNodeExecution {
455
- runId: RunId;
456
- activationId: NodeActivationId;
457
- workflowId: WorkflowId;
458
- nodeId: NodeId;
459
- itemsIn: number;
460
- inputsByPort: NodeInputsByPort;
461
- receiptId: string;
462
- queue?: string;
463
- batchId?: string;
464
- enqueuedAt: string;
339
+ interface CostTrackingTelemetryFactory {
340
+ create(args: Readonly<{
341
+ telemetry: ExecutionTelemetry;
342
+ }>): CostTrackingTelemetry;
465
343
  }
466
- interface PersistedRunSchedulingState {
467
- pending?: PendingNodeExecution;
468
- queue: RunQueueEntry[];
344
+ //#endregion
345
+ //#region src/contracts/NoOpTelemetryArtifactReference.d.ts
346
+ declare class NoOpTelemetryArtifactReference {
347
+ static readonly value: TelemetryArtifactReference;
469
348
  }
470
- interface PersistedRunState {
471
- runId: RunId;
472
- workflowId: WorkflowId;
473
- startedAt: string;
474
- /** Canonical terminal time for listings and retention when persisted on the run root. */
475
- finishedAt?: string;
476
- /** Optimistic concurrency / CAS on the run aggregate (repository may increment on save). */
477
- revision?: number;
478
- parent?: ParentExecutionRef;
479
- executionOptions?: RunExecutionOptions;
480
- control?: PersistedRunControlState;
481
- workflowSnapshot?: PersistedWorkflowSnapshot;
482
- mutableState?: PersistedMutableRunState;
483
- /** Frozen at createRun from workflow + runtime defaults for prune/storage decisions. */
484
- policySnapshot?: PersistedRunPolicySnapshot;
485
- /** Successful node completions so far (for activation budget). */
486
- engineCounters?: EngineRunCounters;
487
- status: RunStatus;
488
- pending?: PendingNodeExecution;
489
- queue: RunQueueEntry[];
490
- outputsByNode: Record<NodeId, NodeOutputs>;
491
- nodeSnapshotsByNodeId: Record<NodeId, NodeExecutionSnapshot>;
492
- /** Append-only history of connection invocations (LLM/tool) nested under owning nodes. */
493
- connectionInvocations?: ReadonlyArray<ConnectionInvocationRecord>;
349
+ //#endregion
350
+ //#region src/contracts/NoOpTelemetrySpanScope.d.ts
351
+ declare class NoOpTelemetrySpanScope {
352
+ static readonly value: TelemetrySpanScope;
353
+ /** Internal: the shared no-op {@link NodeExecutionTelemetry} that {@link NoOpNodeExecutionTelemetry} re-exposes. */
354
+ static readonly nodeExecutionTelemetryValue: NodeExecutionTelemetry;
494
355
  }
495
- interface WorkflowExecutionRepository {
496
- createRun(args: {
356
+ //#endregion
357
+ //#region src/contracts/NoOpNodeExecutionTelemetry.d.ts
358
+ declare class NoOpNodeExecutionTelemetry {
359
+ static readonly value: NodeExecutionTelemetry;
360
+ }
361
+ //#endregion
362
+ //#region src/contracts/NoOpExecutionTelemetry.d.ts
363
+ declare class NoOpExecutionTelemetry {
364
+ static readonly value: ExecutionTelemetry;
365
+ }
366
+ //#endregion
367
+ //#region src/contracts/NoOpExecutionTelemetryFactory.d.ts
368
+ declare class NoOpExecutionTelemetryFactory implements ExecutionTelemetryFactory {
369
+ create(_: Readonly<{
497
370
  runId: RunId;
498
371
  workflowId: WorkflowId;
499
- startedAt: string;
500
372
  parent?: ParentExecutionRef;
501
- executionOptions?: RunExecutionOptions;
502
- control?: PersistedRunControlState;
503
- workflowSnapshot?: PersistedWorkflowSnapshot;
504
- mutableState?: PersistedMutableRunState;
505
373
  policySnapshot?: PersistedRunPolicySnapshot;
506
- engineCounters?: EngineRunCounters;
507
- }): Promise<void>;
508
- load(runId: RunId): Promise<PersistedRunState | undefined>;
509
- loadSchedulingState(runId: RunId): Promise<PersistedRunSchedulingState | undefined>;
510
- save(state: PersistedRunState): Promise<void>;
511
- deleteRun?(runId: RunId): Promise<void>;
374
+ }>): ExecutionTelemetry;
512
375
  }
513
- interface WorkflowExecutionListingRepository {
514
- listRuns(args?: Readonly<{
515
- workflowId?: WorkflowId;
516
- limit?: number;
517
- }>): Promise<ReadonlyArray<RunSummary>>;
376
+ //#endregion
377
+ //#region src/contracts/CodemationTelemetryAttributeNames.d.ts
378
+ declare class CodemationTelemetryAttributeNames {
379
+ static readonly workflowId = "codemation.workflow.id";
380
+ static readonly runId = "codemation.run.id";
381
+ static readonly nodeId = "codemation.node.id";
382
+ static readonly activationId = "codemation.activation.id";
383
+ static readonly nodeType = "codemation.node.type";
384
+ static readonly nodeRole = "codemation.node.role";
385
+ static readonly workflowFolder = "codemation.workflow.folder";
386
+ static readonly connectionInvocationId = "codemation.connection.invocation_id";
387
+ static readonly toolName = "codemation.tool.name";
388
+ static readonly traceParentRunId = "codemation.parent.run.id";
389
+ /** Per-item iteration that emitted this span/metric. Set on spans recorded inside a runnable per-item loop. */
390
+ static readonly iterationId = "codemation.iteration.id";
391
+ /** Item index (0-based) of the iteration. */
392
+ static readonly iterationIndex = "codemation.iteration.index";
393
+ /** Set when this span/metric was recorded under a sub-agent triggered by an outer LLM/tool call. */
394
+ static readonly parentInvocationId = "codemation.parent.invocation_id";
395
+ /** MCP server id on spans created for callTool invocations. */
396
+ static readonly mcpServerId = "mcp.server_id";
397
+ /** MCP tool name on spans created for callTool invocations. */
398
+ static readonly mcpToolName = "mcp.tool_name";
518
399
  }
519
- /** Runs eligible for retention-based pruning (completed or failed, older than cutoff). */
520
- interface RunPruneCandidate {
521
- readonly runId: RunId;
522
- readonly workflowId: WorkflowId;
523
- readonly startedAt: string;
524
- readonly finishedAt: string;
400
+ //#endregion
401
+ //#region src/contracts/GenAiTelemetryAttributeNames.d.ts
402
+ declare class GenAiTelemetryAttributeNames {
403
+ static readonly operationName = "gen_ai.operation.name";
404
+ static readonly requestModel = "gen_ai.request.model";
405
+ static readonly usageInputTokens = "gen_ai.usage.input_tokens";
406
+ static readonly usageOutputTokens = "gen_ai.usage.output_tokens";
407
+ static readonly usageTotalTokens = "gen_ai.usage.total_tokens";
408
+ static readonly usageCacheReadInputTokens = "gen_ai.usage.cache_read.input_tokens";
409
+ static readonly usageCacheCreationInputTokens = "gen_ai.usage.cache_creation.input_tokens";
410
+ static readonly usageReasoningTokens = "codemation.gen_ai.usage.reasoning_tokens";
525
411
  }
526
- interface WorkflowExecutionPruneRepository {
527
- listRunsOlderThan(args: Readonly<{
528
- nowIso: string;
529
- defaultRetentionSeconds: number;
530
- limit?: number;
531
- }>): Promise<ReadonlyArray<RunPruneCandidate>>;
412
+ //#endregion
413
+ //#region src/contracts/CodemationTelemetryMetricNames.d.ts
414
+ declare class CodemationTelemetryMetricNames {
415
+ static readonly agentTurns = "codemation.ai.turns";
416
+ static readonly agentToolCalls = "codemation.ai.tool_calls";
417
+ static readonly gmailMessagesEmitted = "codemation.gmail.messages_emitted";
418
+ static readonly gmailAttachments = "codemation.gmail.attachments";
419
+ static readonly gmailAttachmentBytes = "codemation.gmail.attachment_bytes";
532
420
  }
533
- type RunResult = {
534
- runId: RunId;
535
- workflowId: WorkflowId;
536
- startedAt: string;
537
- status: "completed";
538
- outputs: Items;
539
- } | {
540
- runId: RunId;
541
- workflowId: WorkflowId;
542
- startedAt: string;
543
- status: "pending";
544
- pending: PendingNodeExecution;
545
- } | {
546
- runId: RunId;
547
- workflowId: WorkflowId;
548
- startedAt: string;
549
- status: "failed";
550
- error: {
551
- message: string;
552
- };
553
- };
554
- type WebhookRunResult = Readonly<{
555
- runId: RunId;
556
- workflowId: WorkflowId;
557
- startedAt: string;
558
- runStatus: "pending" | "completed";
559
- response: Items;
560
- }>;
561
- interface PersistedWorkflowTokenRegistryLike {
562
- register(type: TypeToken<unknown>, packageId: string, persistedNameOverride?: string): string;
563
- getTokenId(type: TypeToken<unknown>): string | undefined;
564
- resolve(tokenId: string): TypeToken<unknown> | undefined;
565
- registerFromWorkflows?(workflows: ReadonlyArray<WorkflowDefinition>): void;
421
+ //#endregion
422
+ //#region src/contracts/telemetryTypes.d.ts
423
+ type TelemetryAttributePrimitive = string | number | boolean | null;
424
+ interface TelemetryAttributes {
425
+ readonly [key: string]: TelemetryAttributePrimitive | undefined;
426
+ }
427
+ interface TelemetryMetricRecord {
428
+ readonly name: string;
429
+ readonly value: number;
430
+ readonly unit?: string;
431
+ readonly attributes?: TelemetryAttributes;
432
+ }
433
+ interface TelemetrySpanEventRecord {
434
+ readonly name: string;
435
+ readonly occurredAt?: Date;
436
+ readonly attributes?: TelemetryAttributes;
437
+ }
438
+ interface TelemetryArtifactAttachment {
439
+ readonly kind: string;
440
+ readonly contentType: string;
441
+ readonly previewText?: string;
442
+ readonly previewJson?: JsonValue;
443
+ readonly payloadText?: string;
444
+ readonly payloadJson?: JsonValue;
445
+ readonly bytes?: number;
446
+ readonly truncated?: boolean;
447
+ readonly expiresAt?: Date;
448
+ }
449
+ interface TelemetryArtifactReference {
450
+ readonly artifactId: string;
451
+ readonly traceId?: string;
452
+ readonly spanId?: string;
453
+ }
454
+ interface TelemetrySpanEnd {
455
+ readonly status?: "ok" | "error";
456
+ readonly statusMessage?: string;
457
+ readonly endedAt?: Date;
458
+ readonly attributes?: TelemetryAttributes;
459
+ }
460
+ interface TelemetryChildSpanStart {
461
+ readonly name: string;
462
+ readonly kind?: "internal" | "client";
463
+ readonly startedAt?: Date;
464
+ readonly attributes?: TelemetryAttributes;
465
+ }
466
+ interface TelemetryScope {
467
+ readonly traceId?: string;
468
+ readonly spanId?: string;
469
+ readonly costTracking?: CostTrackingTelemetry;
470
+ addSpanEvent(args: TelemetrySpanEventRecord): Promise<void> | void;
471
+ recordMetric(args: TelemetryMetricRecord): Promise<void> | void;
472
+ attachArtifact(args: TelemetryArtifactAttachment): Promise<TelemetryArtifactReference> | TelemetryArtifactReference;
473
+ }
474
+ interface TelemetrySpanScope extends TelemetryScope {
475
+ readonly traceId: string;
476
+ readonly spanId: string;
477
+ end(args?: TelemetrySpanEnd): Promise<void> | void;
478
+ /**
479
+ * Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
480
+ * Children created via the returned telemetry's `startChildSpan` get this span as their parent.
481
+ *
482
+ * Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
483
+ * span instead of the orchestrator's node-level span.
484
+ */
485
+ asNodeTelemetry(args: Readonly<{
486
+ nodeId: NodeId;
487
+ activationId: NodeActivationId;
488
+ }>): NodeExecutionTelemetry;
566
489
  }
567
- interface RunCompletionNotifier {
568
- resolveRunCompletion(result: RunResult): void;
569
- resolveWebhookResponse(result: WebhookRunResult): void;
490
+ interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
491
+ startChildSpan(args: TelemetryChildSpanStart): TelemetrySpanScope;
570
492
  }
571
- interface RunEventPublisherDeps {
572
- eventBus?: RunEventBus;
493
+ interface ExecutionTelemetry extends TelemetryScope {
494
+ readonly traceId: string;
495
+ readonly spanId: string;
496
+ forNode(args: Readonly<{
497
+ nodeId: NodeId;
498
+ activationId: NodeActivationId;
499
+ }>): NodeExecutionTelemetry;
500
+ }
501
+ interface ExecutionTelemetryFactory {
502
+ create(args: Readonly<{
503
+ runId: RunId;
504
+ workflowId: WorkflowId;
505
+ parent?: ParentExecutionRef;
506
+ policySnapshot?: PersistedRunPolicySnapshot;
507
+ }>): ExecutionTelemetry;
573
508
  }
574
509
  //#endregion
575
- //#region src/triggers/polling/PollingTriggerDedupWindow.d.ts
510
+ //#region src/contracts/workflowActivationPolicy.d.ts
576
511
  /**
577
- * Merges processed-ID windows for polling triggers, capping the total to avoid unbounded growth.
578
- * Plugin code receives an instance of this class via {@link PollingTriggerHandle.dedup}.
512
+ * Host-controlled policy: when false, trigger {@link TriggerNode} setup is skipped and webhook routes
513
+ * for that workflow are not registered (see engine trigger runtime + webhook matcher).
579
514
  */
580
- declare class PollingTriggerDedupWindow {
581
- static readonly defaultCapN = 2000;
582
- merge(previous: ReadonlyArray<string>, incoming: ReadonlyArray<string>, capN?: number): ReadonlyArray<string>;
515
+ interface WorkflowActivationPolicy {
516
+ isActive(workflowId: WorkflowId): boolean;
517
+ }
518
+ /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
519
+ declare class AllWorkflowsActiveWorkflowActivationPolicy implements WorkflowActivationPolicy {
520
+ isActive(_workflowId: WorkflowId): boolean;
583
521
  }
584
522
  //#endregion
585
- //#region src/triggers/polling/PollingTriggerLogger.d.ts
586
- /**
587
- * Minimal logger surface for the polling-trigger runtime.
588
- * Hosts supply this via {@link EngineDeps.pollingTriggerLogger};
589
- * when absent the runtime is silent.
590
- */
591
- interface PollingTriggerLogger {
592
- info(message: string): void;
523
+ //#region src/contracts/webhookTypes.d.ts
524
+ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
525
+ interface WebhookControlSignal {
526
+ readonly __webhookControl: true;
527
+ readonly kind: "respondNow" | "respondNowAndContinue";
528
+ readonly responseItems: Items;
529
+ readonly continueItems?: Items;
530
+ }
531
+ interface WebhookTriggerRoutingDiagnostics {
593
532
  warn(message: string): void;
594
- error(message: string, exception?: Error): void;
595
- debug(message: string): void;
533
+ /** Inactive workflows omitted from the webhook route index (optional; host should wire for clarity at boot/reload). */
534
+ info?(message: string): void;
596
535
  }
597
- declare class NoOpPollingTriggerLogger implements PollingTriggerLogger {
598
- info(): void;
599
- warn(): void;
600
- error(): void;
601
- debug(): void;
536
+ interface TriggerInstanceId {
537
+ workflowId: WorkflowId;
538
+ nodeId: NodeId;
602
539
  }
603
- //#endregion
604
- //#region src/contracts/credentialTypes.d.ts
605
- type CredentialTypeId = string;
606
- type CredentialInstanceId = string;
607
- type CredentialMaterialSourceKind = "db" | "env" | "code";
608
- type CredentialSetupStatus = "draft" | "ready";
609
- type CredentialHealthStatus = "unknown" | "healthy" | "failing";
610
- type CredentialFieldSchema = Readonly<{
611
- key: string;
612
- label: string;
613
- type: "string" | "password" | "textarea" | "json" | "boolean";
614
- required?: true;
615
- order?: number;
616
- /**
617
- * Where this field appears in the credential dialog. Use `"advanced"` for optional or
618
- * power-user fields; they render inside a collapsible section (see `CredentialTypeDefinition.advancedSection`).
619
- * Defaults to `"default"` when omitted.
620
- */
621
- visibility?: "default" | "advanced";
622
- placeholder?: string;
623
- helpText?: string;
624
- /** When set, host resolves this field from process.env at runtime; env wins over stored values. */
625
- envVarName?: string;
626
- /**
627
- * When set, the dialog shows a copy action for this exact string (e.g. a static OAuth redirect URI
628
- * pattern or documentation URL). Do not use for secret values.
629
- */
630
- copyValue?: string;
631
- /** Accessible label for the copy control (default: Copy). */
632
- copyButtonLabel?: string;
633
- }>;
634
- type CredentialRequirement = Readonly<{
635
- slotKey: string;
636
- label: string;
637
- acceptedTypes: ReadonlyArray<CredentialTypeId>;
638
- optional?: true;
639
- helpText?: string;
640
- helpUrl?: string;
641
- }>;
642
- type CredentialBindingKey = Readonly<{
540
+ /** Match for an incoming HTTP request: user-defined URL segment + workflow trigger node. */
541
+ interface WebhookInvocationMatch {
542
+ /** Same value as the webhook trigger's configured endpoint key (URL segment under the webhook base path). */
543
+ endpointPath: string;
643
544
  workflowId: WorkflowId;
644
545
  nodeId: NodeId;
645
- slotKey: string;
646
- }>;
647
- type CredentialBinding = Readonly<{
648
- key: CredentialBindingKey;
649
- instanceId: CredentialInstanceId;
650
- updatedAt: string;
651
- }>;
652
- type CredentialHealth = Readonly<{
653
- status: CredentialHealthStatus;
654
- message?: string;
655
- testedAt?: string;
656
- expiresAt?: string;
657
- details?: Readonly<Record<string, unknown>>;
658
- }>;
659
- type OAuth2ProviderFromPublicConfig = Readonly<{
660
- authorizeUrlFieldKey: string;
661
- tokenUrlFieldKey: string;
662
- userInfoUrlFieldKey?: string;
663
- }>;
664
- type CredentialOAuth2ScopesFromPublicConfig = Readonly<{
665
- presetFieldKey: string;
666
- presetScopes: Readonly<Record<string, ReadonlyArray<string>>>;
667
- customPresetKey?: string;
668
- customScopesFieldKey?: string;
669
- }>;
670
- type CredentialOAuth2AuthDefinition = Readonly<{
671
- kind: "oauth2";
672
- providerId: string;
673
- scopes: ReadonlyArray<string>;
674
- scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
675
- clientIdFieldKey?: string;
676
- clientSecretFieldKey?: string;
677
- } | {
678
- kind: "oauth2";
679
- providerFromPublicConfig: OAuth2ProviderFromPublicConfig;
680
- scopes: ReadonlyArray<string>;
681
- scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
682
- clientIdFieldKey?: string;
683
- clientSecretFieldKey?: string;
546
+ methods: ReadonlyArray<HttpMethod>;
547
+ parseJsonBody?: (body: unknown) => unknown;
548
+ }
549
+ /** Result of resolving an HTTP method + endpoint path against the catalog webhook index (404 vs 405 vs match). */
550
+ type WebhookTriggerResolution = {
551
+ status: "notFound";
684
552
  } | {
685
- kind: "oauth2";
686
- /**
687
- * Free-form provider identifier for telemetry, DB rows, and Better Auth provider naming.
688
- * Not used for any registry lookup — URLs come from {@link authorizeUrl} / {@link tokenUrl}.
689
- */
690
- providerId: string;
691
- /**
692
- * Authorization endpoint. May contain `{publicFieldKey}` placeholders that the runtime
693
- * substitutes from the credential's resolved public config (URL-encoded).
694
- * Example: `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize`
695
- */
696
- authorizeUrl: string;
697
- /** Token endpoint. Same templating rules as {@link authorizeUrl}. */
698
- tokenUrl: string;
699
- /** Optional userinfo endpoint. Same templating rules as {@link authorizeUrl}. */
700
- userInfoUrl?: string;
701
- scopes: ReadonlyArray<string>;
702
- scopesFromPublicConfig?: CredentialOAuth2ScopesFromPublicConfig;
703
- clientIdFieldKey?: string;
704
- clientSecretFieldKey?: string;
705
- }>;
706
- type CredentialAuthDefinition = CredentialOAuth2AuthDefinition;
707
- type CredentialAdvancedSectionPresentation = Readonly<{
708
- /** Collapsible section title (default: "Advanced"). */
709
- title?: string;
710
- /** Optional short helper text shown inside the section (above the fields). */
711
- description?: string;
712
- /** When true, the advanced section starts expanded. Default: false (collapsed). */
713
- defaultOpen?: boolean;
714
- }>;
715
- type CredentialTypeDefinition = Readonly<{
716
- typeId: CredentialTypeId;
717
- displayName: string;
718
- description?: string;
719
- publicFields?: ReadonlyArray<CredentialFieldSchema>;
720
- secretFields?: ReadonlyArray<CredentialFieldSchema>;
721
- /**
722
- * Optional labels for the collapsible block that contains every field with `visibility: "advanced"`.
723
- * If omitted, the UI still shows that block with defaults (title "Advanced", collapsed).
724
- */
725
- advancedSection?: CredentialAdvancedSectionPresentation;
726
- supportedSourceKinds?: ReadonlyArray<CredentialMaterialSourceKind>;
727
- auth?: CredentialAuthDefinition;
728
- }>;
729
- /**
730
- * JSON-shaped credential field bag (public config, resolved secret material, etc.).
731
- */
732
- type CredentialJsonRecord = Readonly<Record<string, unknown>>;
733
- /**
734
- * Persisted credential instance with typed `publicConfig`.
735
- * Hosts may specialize `secretRef` with a stricter union while remaining
736
- * assignable here for session/test callbacks.
737
- */
738
- type CredentialInstanceRecord<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{
739
- instanceId: CredentialInstanceId;
740
- typeId: CredentialTypeId;
741
- displayName: string;
742
- sourceKind: CredentialMaterialSourceKind;
743
- publicConfig: TPublicConfig;
744
- secretRef: CredentialJsonRecord;
745
- tags: ReadonlyArray<string>;
746
- setupStatus: CredentialSetupStatus;
747
- createdAt: string;
748
- updatedAt: string;
749
- }>;
750
- /**
751
- * Arguments passed to `CredentialType.createSession` and `CredentialType.test`.
752
- * Declare `TPublicConfig` / `TMaterial` on `CredentialType` so implementations are checked
753
- * against your credential shapes (similar to `NodeExecutionContext.config` for nodes).
754
- */
755
- type CredentialSessionFactoryArgs<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord> = Readonly<{
756
- instance: CredentialInstanceRecord<TPublicConfig>;
757
- material: TMaterial;
758
- publicConfig: TPublicConfig;
759
- }>;
760
- type CredentialSessionFactory<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord, TSession = unknown> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<TSession>;
761
- type CredentialHealthTester<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord> = (args: CredentialSessionFactoryArgs<TPublicConfig, TMaterial>) => Promise<CredentialHealth>;
762
- /**
763
- * Full credential type implementation: `definition` (UI/schema), `createSession`, and `test`.
764
- * Use this at registration and config boundaries; `CredentialTypeDefinition` is only the schema slice.
765
- */
766
- type CredentialType<TPublicConfig extends CredentialJsonRecord = CredentialJsonRecord, TMaterial extends CredentialJsonRecord = CredentialJsonRecord, TSession = unknown> = Readonly<{
767
- definition: CredentialTypeDefinition;
768
- createSession: CredentialSessionFactory<TPublicConfig, TMaterial, TSession>;
769
- test: CredentialHealthTester<TPublicConfig, TMaterial>;
770
- }>;
553
+ status: "methodNotAllowed";
554
+ match: WebhookInvocationMatch;
555
+ } | {
556
+ status: "ok";
557
+ match: WebhookInvocationMatch;
558
+ };
771
559
  /**
772
- * Credential type with unspecified generics used for `CodemationConfig.credentialTypes`, the host registry,
773
- * and anywhere a concrete `CredentialType<YourPublic, YourMaterial, YourSession>` is placed in a heterogeneous list.
774
- * Using `any` here avoids unsafe `as` casts while keeping typed `satisfies CredentialType<…>` definitions.
560
+ * Resolves webhook routes from workflow definitions (catalog-backed index, no registration at trigger setup).
775
561
  */
776
- type AnyCredentialType = CredentialType<any, any, unknown>;
777
- interface CredentialSessionService {
778
- getSession<TSession = unknown>(args: Readonly<{
562
+ interface WebhookTriggerMatcher {
563
+ match(args: {
564
+ endpointPath: string;
565
+ method: HttpMethod;
566
+ }): WebhookInvocationMatch | undefined;
567
+ lookup(endpointPath: string): WebhookInvocationMatch | undefined;
568
+ onEngineWorkflowsLoaded?(): void;
569
+ onEngineStopped?(): void;
570
+ /** Rebuild route index after activation changes without stopping the engine. */
571
+ reloadWebhookRoutes?(): void;
572
+ }
573
+ //#endregion
574
+ //#region src/contracts/runtimeTypes.d.ts
575
+ interface WorkflowRunnerService {
576
+ runById(args: {
779
577
  workflowId: WorkflowId;
780
- nodeId: NodeId;
781
- slotKey: string;
782
- }>): Promise<TSession>;
578
+ startAt?: NodeId;
579
+ items: Items;
580
+ parent?: ParentExecutionRef;
581
+ }): Promise<RunResult>;
783
582
  }
784
- interface CredentialTypeRegistry {
785
- listTypes(): ReadonlyArray<CredentialTypeDefinition>;
786
- getType(typeId: CredentialTypeId): CredentialTypeDefinition | undefined;
583
+ interface WorkflowRunnerResolver {
584
+ resolve(): WorkflowRunnerService | undefined;
787
585
  }
788
- declare class CredentialUnboundError extends Error {
789
- readonly bindingKey: CredentialBindingKey;
790
- readonly acceptedTypes: ReadonlyArray<CredentialTypeId>;
791
- constructor(bindingKey: CredentialBindingKey, acceptedTypes?: ReadonlyArray<CredentialTypeId>);
792
- private static createMessage;
586
+ interface WorkflowRepository {
587
+ list(): ReadonlyArray<WorkflowDefinition>;
588
+ get(workflowId: WorkflowId): WorkflowDefinition | undefined;
793
589
  }
794
- //#endregion
795
- //#region src/contracts/collectionTypes.d.ts
796
- /**
797
- * Represents a typed store for a single collection.
798
- * All rows include auto-managed id, created_at, and updated_at fields.
799
- */
800
- interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
801
- /**
802
- * Insert a new row. id, created_at, and updated_at are auto-populated.
803
- */
804
- insert(row: TRow): Promise<TRow & {
805
- id: string;
806
- created_at: Date;
807
- updated_at: Date;
808
- }>;
809
- /**
810
- * Get a single row by id.
811
- */
812
- get(id: string): Promise<(TRow & {
813
- id: string;
814
- created_at: Date;
815
- updated_at: Date;
816
- }) | null>;
817
- /**
818
- * Find a single row matching the provided filter.
819
- */
820
- findOne(filter: Partial<TRow>): Promise<(TRow & {
821
- id: string;
822
- created_at: Date;
823
- updated_at: Date;
824
- }) | null>;
590
+ interface LiveWorkflowRepository extends WorkflowRepository {
591
+ setWorkflows(workflows: ReadonlyArray<WorkflowDefinition>): void;
592
+ }
593
+ interface NodeResolver {
594
+ resolve<T>(token: TypeToken<T>): T;
595
+ }
596
+ interface NodeExecutionStatePublisher {
597
+ markQueued(args: {
598
+ nodeId: NodeId;
599
+ activationId?: NodeActivationId;
600
+ inputsByPort?: NodeInputsByPort;
601
+ }): Promise<void>;
602
+ markRunning(args: {
603
+ nodeId: NodeId;
604
+ activationId?: NodeActivationId;
605
+ inputsByPort?: NodeInputsByPort;
606
+ }): Promise<void>;
607
+ markCompleted(args: {
608
+ nodeId: NodeId;
609
+ activationId?: NodeActivationId;
610
+ inputsByPort?: NodeInputsByPort;
611
+ outputs?: NodeOutputs;
612
+ }): Promise<void>;
613
+ markFailed(args: {
614
+ nodeId: NodeId;
615
+ activationId?: NodeActivationId;
616
+ inputsByPort?: NodeInputsByPort;
617
+ error: Error;
618
+ }): Promise<void>;
619
+ appendConnectionInvocation(args: ConnectionInvocationAppendArgs): Promise<void>;
825
620
  /**
826
- * List rows with optional pagination and filtering.
621
+ * Annotates the current snapshot for `nodeId` with the id of the child run spawned by a
622
+ * SubWorkflow invocation. Called from `SubWorkflowNode.execute` after `runById` resolves.
623
+ * The engine's subsequent `markCompleted` call preserves the value via `previous.childRunId`.
827
624
  */
828
- list(opts?: {
829
- limit?: number;
830
- offset?: number;
831
- where?: Partial<TRow>;
832
- }): Promise<{
833
- rows: ReadonlyArray<TRow & {
834
- id: string;
835
- created_at: Date;
836
- updated_at: Date;
837
- }>;
838
- total: number;
839
- }>;
625
+ setChildRunId?(args: {
626
+ nodeId: NodeId;
627
+ childRunId: RunId;
628
+ }): Promise<void>;
629
+ }
630
+ type BinaryBody = ReadableStream<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array | ArrayBuffer;
631
+ interface BinaryStorageWriteRequest {
632
+ storageKey: string;
633
+ body: BinaryBody;
634
+ }
635
+ interface BinaryStorageWriteResult {
636
+ storageKey: string;
637
+ size: number;
638
+ sha256?: string;
639
+ }
640
+ interface BinaryStorageReadResult {
641
+ body: ReadableStream<Uint8Array>;
642
+ size?: number;
643
+ }
644
+ interface BinaryStorageStatResult {
645
+ exists: boolean;
646
+ size?: number;
647
+ }
648
+ interface BinaryStorage {
649
+ readonly driverName: string;
650
+ write(args: BinaryStorageWriteRequest): Promise<BinaryStorageWriteResult>;
651
+ openReadStream(storageKey: string): Promise<BinaryStorageReadResult | undefined>;
652
+ stat(storageKey: string): Promise<BinaryStorageStatResult>;
653
+ delete(storageKey: string): Promise<void>;
654
+ /** Deletes multiple objects in bulk. Keys are batched internally. */
655
+ deleteMany(storageKeys: ReadonlyArray<string>): Promise<void>;
656
+ /** Lists all keys sharing a common prefix. Returns keys in arbitrary order. */
657
+ listByPrefix(prefix: string): Promise<ReadonlyArray<string>>;
658
+ }
659
+ interface BinaryAttachmentCreateRequest {
660
+ name: string;
661
+ body: BinaryBody;
662
+ mimeType: string;
663
+ filename?: string;
664
+ previewKind?: BinaryAttachment["previewKind"];
665
+ }
666
+ interface NodeBinaryAttachmentService extends ExecutionBinaryService {
667
+ attach(args: BinaryAttachmentCreateRequest): Promise<BinaryAttachment>;
668
+ withAttachment<TJson>(item: Item<TJson>, name: string, attachment: BinaryAttachment): Item<TJson>;
669
+ }
670
+ interface ExecutionBinaryService {
671
+ forNode(args: {
672
+ nodeId: NodeId;
673
+ activationId: NodeActivationId;
674
+ }): NodeBinaryAttachmentService;
675
+ openReadStream(attachment: BinaryAttachment): Promise<BinaryStorageReadResult | undefined>;
676
+ }
677
+ interface ExecutionContext {
678
+ runId: RunId;
679
+ workflowId: WorkflowId;
680
+ parent?: ParentExecutionRef;
681
+ /** This run's subworkflow depth (0 = root). */
682
+ subworkflowDepth: number;
683
+ /** Effective activation budget cap for this run (after policy merge). */
684
+ engineMaxNodeActivations: number;
685
+ /** Effective subworkflow nesting cap for this run (after policy merge). */
686
+ engineMaxSubworkflowDepth: number;
687
+ now: () => Date;
688
+ data: RunDataSnapshot;
689
+ nodeState?: NodeExecutionStatePublisher;
690
+ telemetry: ExecutionTelemetry;
691
+ binary: ExecutionBinaryService;
692
+ getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
693
+ /** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
694
+ iterationId?: NodeIterationId;
695
+ /** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
696
+ itemIndex?: number;
697
+ /** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
698
+ parentInvocationId?: ConnectionInvocationId;
840
699
  /**
841
- * Update a row by id with partial data.
700
+ * Present iff the run was started by a TestSuiteOrchestrator. The {@link IsTestRunNode}
701
+ * branches on this; assertion-emitting nodes use it to decide whether to record results.
842
702
  */
843
- update(id: string, patch: Partial<TRow>): Promise<TRow & {
844
- id: string;
845
- created_at: Date;
846
- updated_at: Date;
847
- }>;
703
+ testContext?: RunTestContext;
848
704
  /**
849
- * Delete a row by id. Hard delete only (no soft delete).
705
+ * Collections registered in the codemation config, keyed by collection name.
850
706
  */
851
- delete(id: string): Promise<{
852
- deleted: boolean;
853
- }>;
854
- }
855
- /**
856
- * Runtime collections context: keyed by collection name.
857
- */
858
- type CollectionsContext = Readonly<Record<string, CollectionStore>>;
859
- //#endregion
860
- //#region src/contracts/CostTrackingTelemetryContract.d.ts
861
- type CostTrackingComponent = "chat" | "ocr" | "rag";
862
- declare const CostTrackingTelemetryMetricNames: {
863
- readonly usage: "codemation.cost.usage";
864
- readonly estimatedCost: "codemation.cost.estimated";
865
- };
866
- declare const CostTrackingTelemetryAttributeNames: {
867
- readonly component: "cost.component";
868
- readonly provider: "cost.provider";
869
- readonly operation: "cost.operation";
870
- readonly pricingKey: "cost.pricing_key";
871
- readonly usageUnit: "cost.usage_unit";
872
- readonly currency: "cost.currency";
873
- readonly currencyScale: "cost.currency_scale";
874
- readonly estimateKind: "cost.estimate_kind";
875
- };
876
- interface CostTrackingUsageRecord {
877
- readonly component: CostTrackingComponent;
878
- readonly provider: string;
879
- readonly operation: string;
880
- readonly pricingKey: string;
881
- readonly usageUnit: string;
882
- readonly quantity: number;
883
- readonly modelName?: string;
884
- readonly attributes?: TelemetryAttributes;
707
+ readonly collections?: CollectionsContext;
885
708
  }
886
- interface CostTrackingPriceQuote {
887
- readonly currency: string;
888
- readonly currencyScale: number;
889
- readonly estimatedAmountMinor: number;
890
- readonly estimateKind: "catalog";
709
+ interface ExecutionContextFactory {
710
+ create(args: {
711
+ runId: RunId;
712
+ workflowId: WorkflowId;
713
+ parent?: ParentExecutionRef;
714
+ policySnapshot?: PersistedRunPolicySnapshot;
715
+ subworkflowDepth: number;
716
+ engineMaxNodeActivations: number;
717
+ engineMaxSubworkflowDepth: number;
718
+ data: RunDataSnapshot;
719
+ nodeState?: NodeExecutionStatePublisher;
720
+ telemetry?: ExecutionTelemetry;
721
+ getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
722
+ testContext?: RunTestContext;
723
+ }): ExecutionContext;
891
724
  }
892
- interface CostTrackingTelemetry {
893
- captureUsage(args: CostTrackingUsageRecord): Promise<CostTrackingPriceQuote | undefined>;
894
- forScope(scope: TelemetryScope): CostTrackingTelemetry;
725
+ interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfigBase> extends ExecutionContext {
726
+ nodeId: NodeId;
727
+ activationId: NodeActivationId;
728
+ config: TConfig;
729
+ telemetry: NodeExecutionTelemetry;
730
+ binary: NodeBinaryAttachmentService;
895
731
  }
896
- interface CostTrackingTelemetryFactory {
897
- create(args: Readonly<{
898
- telemetry: ExecutionTelemetry;
899
- }>): CostTrackingTelemetry;
732
+ interface PollingTriggerHandle {
733
+ /**
734
+ * Start the polling loop. The runtime registers its own cleanup handle so callers do not need to
735
+ * call {@link TriggerSetupContext.registerCleanup} for the loop.
736
+ * @returns The state returned by the first cycle (or `undefined` when the overlap guard fired).
737
+ */
738
+ start<TState, TItem>(args: {
739
+ intervalMs: number;
740
+ seedState?: TState;
741
+ runCycle: (cycleCtx: {
742
+ previousState: TState | undefined;
743
+ signal: AbortSignal;
744
+ }) => Promise<{
745
+ items: Items<TItem>;
746
+ nextState: TState;
747
+ }>;
748
+ }): Promise<TState | undefined>;
749
+ /** Convenience dedup-window helper. */
750
+ readonly dedup: PollingTriggerDedupWindow;
900
751
  }
901
- //#endregion
902
- //#region src/contracts/NoOpTelemetryArtifactReference.d.ts
903
- declare class NoOpTelemetryArtifactReference {
904
- static readonly value: TelemetryArtifactReference;
752
+ interface TriggerSetupContext<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>, TSetupState$1 extends JsonValue | undefined = TriggerNodeSetupState<TConfig>> extends ExecutionContext {
753
+ trigger: TriggerInstanceId;
754
+ config: TConfig;
755
+ previousState: TSetupState$1;
756
+ registerCleanup(cleanup: TriggerCleanupHandle): void;
757
+ emit(items: Items): Promise<void>;
758
+ /** Generic polling-trigger surface. Pre-binds trigger id, emit, and registerCleanup. */
759
+ readonly polling: PollingTriggerHandle;
905
760
  }
906
- //#endregion
907
- //#region src/contracts/NoOpTelemetrySpanScope.d.ts
908
- declare class NoOpTelemetrySpanScope {
909
- static readonly value: TelemetrySpanScope;
910
- /** Internal: the shared no-op {@link NodeExecutionTelemetry} that {@link NoOpNodeExecutionTelemetry} re-exposes. */
911
- static readonly nodeExecutionTelemetryValue: NodeExecutionTelemetry;
761
+ interface TriggerTestItemsContext<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>, TSetupState$1 extends JsonValue | undefined = TriggerNodeSetupState<TConfig>> extends ExecutionContext {
762
+ trigger: TriggerInstanceId;
763
+ nodeId: NodeId;
764
+ config: TConfig;
765
+ previousState: TSetupState$1;
912
766
  }
913
- //#endregion
914
- //#region src/contracts/NoOpNodeExecutionTelemetry.d.ts
915
- declare class NoOpNodeExecutionTelemetry {
916
- static readonly value: NodeExecutionTelemetry;
767
+ /**
768
+ * Trigger setup state is intentionally engine-owned so future ownership and
769
+ * leader-election metadata can be coordinated centrally rather than pushed into
770
+ * package-level setup code.
771
+ */
772
+ interface PersistedTriggerSetupState<TState extends JsonValue | undefined = JsonValue | undefined> {
773
+ trigger: TriggerInstanceId;
774
+ updatedAt: string;
775
+ state: TState;
917
776
  }
918
- //#endregion
919
- //#region src/contracts/NoOpExecutionTelemetry.d.ts
920
- declare class NoOpExecutionTelemetry {
921
- static readonly value: ExecutionTelemetry;
777
+ interface TriggerSetupStateRepository {
778
+ load(trigger: TriggerInstanceId): Promise<PersistedTriggerSetupState | undefined>;
779
+ save(state: PersistedTriggerSetupState): Promise<void>;
780
+ delete(trigger: TriggerInstanceId): Promise<void>;
922
781
  }
923
- //#endregion
924
- //#region src/contracts/NoOpExecutionTelemetryFactory.d.ts
925
- declare class NoOpExecutionTelemetryFactory implements ExecutionTelemetryFactory {
926
- create(_: Readonly<{
927
- runId: RunId;
928
- workflowId: WorkflowId;
929
- parent?: ParentExecutionRef;
930
- policySnapshot?: PersistedRunPolicySnapshot;
931
- }>): ExecutionTelemetry;
782
+ interface TriggerCleanupHandle {
783
+ stop(): Promise<void> | void;
932
784
  }
933
- //#endregion
934
- //#region src/contracts/CodemationTelemetryAttributeNames.d.ts
935
- declare class CodemationTelemetryAttributeNames {
936
- static readonly workflowId = "codemation.workflow.id";
937
- static readonly runId = "codemation.run.id";
938
- static readonly nodeId = "codemation.node.id";
939
- static readonly activationId = "codemation.activation.id";
940
- static readonly nodeType = "codemation.node.type";
941
- static readonly nodeRole = "codemation.node.role";
942
- static readonly workflowFolder = "codemation.workflow.folder";
943
- static readonly connectionInvocationId = "codemation.connection.invocation_id";
944
- static readonly toolName = "codemation.tool.name";
945
- static readonly traceParentRunId = "codemation.parent.run.id";
946
- /** Per-item iteration that emitted this span/metric. Set on spans recorded inside a runnable per-item loop. */
947
- static readonly iterationId = "codemation.iteration.id";
948
- /** Item index (0-based) of the iteration. */
949
- static readonly iterationIndex = "codemation.iteration.index";
950
- /** Set when this span/metric was recorded under a sub-agent triggered by an outer LLM/tool call. */
951
- static readonly parentInvocationId = "codemation.parent.invocation_id";
785
+ interface EngineHost {
786
+ credentialSessions: CredentialSessionService;
787
+ workflows?: WorkflowRunnerService;
952
788
  }
953
- //#endregion
954
- //#region src/contracts/GenAiTelemetryAttributeNames.d.ts
955
- declare class GenAiTelemetryAttributeNames {
956
- static readonly operationName = "gen_ai.operation.name";
957
- static readonly requestModel = "gen_ai.request.model";
958
- static readonly usageInputTokens = "gen_ai.usage.input_tokens";
959
- static readonly usageOutputTokens = "gen_ai.usage.output_tokens";
960
- static readonly usageTotalTokens = "gen_ai.usage.total_tokens";
961
- static readonly usageCacheReadInputTokens = "gen_ai.usage.cache_read.input_tokens";
962
- static readonly usageCacheCreationInputTokens = "gen_ai.usage.cache_creation.input_tokens";
963
- static readonly usageReasoningTokens = "codemation.gen_ai.usage.reasoning_tokens";
789
+ /**
790
+ * Per-item runnable node: return JSON, an array to fan-out on `main`, an explicit `Item`, or {@link emitPorts}
791
+ * for multi-port emission. Engine applies `inputSchema.parse(item.json)` and passes the result as `args.input`
792
+ * (wire `item.json` is unchanged). Transform helpers may opt into binary preservation, while routers and
793
+ * pass-through nodes should return explicit items when they need to preserve full item state.
794
+ */
795
+ interface RunnableNodeExecuteArgs<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown> {
796
+ readonly input: TInputJson$1;
797
+ readonly item: Item;
798
+ readonly itemIndex: number;
799
+ readonly items: Items;
800
+ readonly ctx: NodeExecutionContext<TConfig>;
964
801
  }
965
- //#endregion
966
- //#region src/contracts/CodemationTelemetryMetricNames.d.ts
967
- declare class CodemationTelemetryMetricNames {
968
- static readonly agentTurns = "codemation.ai.turns";
969
- static readonly agentToolCalls = "codemation.ai.tool_calls";
970
- static readonly gmailMessagesEmitted = "codemation.gmail.messages_emitted";
971
- static readonly gmailAttachments = "codemation.gmail.attachments";
972
- static readonly gmailAttachmentBytes = "codemation.gmail.attachment_bytes";
802
+ interface RunnableNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown, _TOutputJson = unknown> {
803
+ readonly kind: "node";
804
+ /**
805
+ * Declared output ports (e.g. `["main"]`).
806
+ *
807
+ * Prefer describing dynamic router ports (Switch) and fixed multi-ports (If true/false)
808
+ * via {@link NodeConfigBase.declaredOutputPorts}. Engine defaults to `["main"]` when omitted.
809
+ */
810
+ readonly outputPorts?: ReadonlyArray<OutputPortKey>;
811
+ /** When omitted, engine uses {@link RunnableNodeConfig.inputSchema} or `z.unknown()`. */
812
+ readonly inputSchema?: ZodType<TInputJson$1>;
813
+ execute(args: RunnableNodeExecuteArgs<TConfig, TInputJson$1>): Promise<unknown> | unknown;
973
814
  }
974
- //#endregion
975
- //#region src/contracts/telemetryTypes.d.ts
976
- type TelemetryAttributePrimitive = string | number | boolean | null;
977
- interface TelemetryAttributes {
978
- readonly [key: string]: TelemetryAttributePrimitive | undefined;
815
+ /** @deprecated Use {@link RunnableNode} */
816
+ type ItemNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown, TOutputJson$1 = unknown> = RunnableNode<TConfig, TInputJson$1, TOutputJson$1>;
817
+ interface MultiInputNode<TConfig extends NodeConfigBase = NodeConfigBase> {
818
+ kind: "node";
819
+ /**
820
+ * Declared output ports (typically `["main"]`).
821
+ *
822
+ * Prefer describing ports for authoring/canvas via {@link NodeConfigBase.declaredOutputPorts}.
823
+ * Engine defaults to `["main"]` when omitted.
824
+ */
825
+ outputPorts?: ReadonlyArray<OutputPortKey>;
826
+ executeMulti(inputsByPort: NodeInputsByPort, ctx: NodeExecutionContext<TConfig>): Promise<NodeOutputs>;
979
827
  }
980
- interface TelemetryMetricRecord {
981
- readonly name: string;
982
- readonly value: number;
983
- readonly unit?: string;
984
- readonly attributes?: TelemetryAttributes;
828
+ type TriggerSetupStateFor<TConfig extends TriggerNodeConfig<any, any>> = TriggerNodeSetupState<TConfig>;
829
+ interface TriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> {
830
+ kind: "trigger";
831
+ outputPorts: readonly ["main"];
832
+ setup(ctx: TriggerSetupContext<TConfig>): Promise<TriggerSetupStateFor<TConfig>>;
833
+ execute(items: Items, ctx: NodeExecutionContext<TConfig>): Promise<NodeOutputs>;
985
834
  }
986
- interface TelemetrySpanEventRecord {
987
- readonly name: string;
988
- readonly occurredAt?: Date;
989
- readonly attributes?: TelemetryAttributes;
835
+ interface TestableTriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> extends TriggerNode<TConfig> {
836
+ getTestItems(ctx: TriggerTestItemsContext<TConfig>): Promise<Items>;
990
837
  }
991
- interface TelemetryArtifactAttachment {
992
- readonly kind: string;
993
- readonly contentType: string;
994
- readonly previewText?: string;
995
- readonly previewJson?: JsonValue;
996
- readonly payloadText?: string;
997
- readonly payloadJson?: JsonValue;
998
- readonly bytes?: number;
999
- readonly truncated?: boolean;
1000
- readonly expiresAt?: Date;
838
+ type ExecutableTriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> = TriggerNode<TConfig>;
839
+ interface NodeExecutionRequest {
840
+ runId: RunId;
841
+ activationId: NodeActivationId;
842
+ workflowId: WorkflowId;
843
+ nodeId: NodeId;
844
+ input: Items;
845
+ parent?: ParentExecutionRef;
846
+ queue?: string;
847
+ executionOptions?: RunExecutionOptions;
1001
848
  }
1002
- interface TelemetryArtifactReference {
1003
- readonly artifactId: string;
1004
- readonly traceId?: string;
1005
- readonly spanId?: string;
849
+ interface NodeExecutionScheduler {
850
+ enqueue(request: NodeExecutionRequest): Promise<{
851
+ receiptId: string;
852
+ }>;
853
+ cancel?(receiptId: string): Promise<void>;
1006
854
  }
1007
- interface TelemetrySpanEnd {
1008
- readonly status?: "ok" | "error";
1009
- readonly statusMessage?: string;
1010
- readonly endedAt?: Date;
1011
- readonly attributes?: TelemetryAttributes;
855
+ interface NodeExecutionRequestHandler {
856
+ handleNodeExecutionRequest(request: NodeExecutionRequest): Promise<void>;
1012
857
  }
1013
- interface TelemetryChildSpanStart {
1014
- readonly name: string;
1015
- readonly kind?: "internal" | "client";
1016
- readonly startedAt?: Date;
1017
- readonly attributes?: TelemetryAttributes;
858
+ type NodeActivationRequestBase = Readonly<{
859
+ runId: RunId;
860
+ activationId: NodeActivationId;
861
+ workflowId: WorkflowId;
862
+ nodeId: NodeId;
863
+ parent?: ParentExecutionRef;
864
+ executionOptions?: RunExecutionOptions;
865
+ batchId?: string;
866
+ ctx: NodeExecutionContext;
867
+ }>;
868
+ type NodeActivationRequest = (NodeActivationRequestBase & Readonly<{
869
+ kind: "single";
870
+ input: Items;
871
+ }>) | (NodeActivationRequestBase & Readonly<{
872
+ kind: "multi";
873
+ inputsByPort: NodeInputsByPort;
874
+ }>);
875
+ interface NodeActivationReceipt {
876
+ receiptId: string;
877
+ mode?: "local" | "worker";
878
+ queue?: string;
1018
879
  }
1019
- interface TelemetryScope {
1020
- readonly traceId?: string;
1021
- readonly spanId?: string;
1022
- readonly costTracking?: CostTrackingTelemetry;
1023
- addSpanEvent(args: TelemetrySpanEventRecord): Promise<void> | void;
1024
- recordMetric(args: TelemetryMetricRecord): Promise<void> | void;
1025
- attachArtifact(args: TelemetryArtifactAttachment): Promise<TelemetryArtifactReference> | TelemetryArtifactReference;
880
+ interface PreparedNodeActivationDispatch {
881
+ readonly receipt: NodeActivationReceipt;
882
+ dispatch(): Promise<void>;
1026
883
  }
1027
- interface TelemetrySpanScope extends TelemetryScope {
1028
- readonly traceId: string;
1029
- readonly spanId: string;
1030
- end(args?: TelemetrySpanEnd): Promise<void> | void;
1031
- /**
1032
- * Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
1033
- * Children created via the returned telemetry's `startChildSpan` get this span as their parent.
1034
- *
1035
- * Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
1036
- * span instead of the orchestrator's node-level span.
1037
- */
1038
- asNodeTelemetry(args: Readonly<{
884
+ interface NodeActivationContinuation {
885
+ markNodeRunning(args: {
886
+ runId: RunId;
887
+ activationId: NodeActivationId;
1039
888
  nodeId: NodeId;
889
+ inputsByPort: NodeInputsByPort;
890
+ }): Promise<void>;
891
+ resumeFromNodeResult(args: {
892
+ runId: RunId;
1040
893
  activationId: NodeActivationId;
1041
- }>): NodeExecutionTelemetry;
1042
- }
1043
- interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
1044
- startChildSpan(args: TelemetryChildSpanStart): TelemetrySpanScope;
1045
- }
1046
- interface ExecutionTelemetry extends TelemetryScope {
1047
- readonly traceId: string;
1048
- readonly spanId: string;
1049
- forNode(args: Readonly<{
1050
894
  nodeId: NodeId;
895
+ outputs: NodeOutputs;
896
+ }): Promise<RunResult>;
897
+ resumeFromNodeError(args: {
898
+ runId: RunId;
1051
899
  activationId: NodeActivationId;
1052
- }>): NodeExecutionTelemetry;
900
+ nodeId: NodeId;
901
+ error: Error;
902
+ }): Promise<RunResult>;
1053
903
  }
1054
- interface ExecutionTelemetryFactory {
1055
- create(args: Readonly<{
1056
- runId: RunId;
1057
- workflowId: WorkflowId;
1058
- parent?: ParentExecutionRef;
1059
- policySnapshot?: PersistedRunPolicySnapshot;
1060
- }>): ExecutionTelemetry;
904
+ interface NodeActivationScheduler {
905
+ setContinuation?(continuation: NodeActivationContinuation): void;
906
+ prepareDispatch(request: NodeActivationRequest): Promise<PreparedNodeActivationDispatch>;
907
+ cancel?(receiptId: string): Promise<void>;
1061
908
  }
1062
- //#endregion
1063
- //#region src/contracts/workflowActivationPolicy.d.ts
1064
- /**
1065
- * Host-controlled policy: when false, trigger {@link TriggerNode} setup is skipped and webhook routes
1066
- * for that workflow are not registered (see engine trigger runtime + webhook matcher).
1067
- */
1068
- interface WorkflowActivationPolicy {
1069
- isActive(workflowId: WorkflowId): boolean;
909
+ interface WorkflowNodeInstanceFactory {
910
+ createNodes(workflow: WorkflowDefinition): ReadonlyMap<NodeId, unknown>;
911
+ createByType(type: TypeToken<unknown>): unknown;
1070
912
  }
1071
- /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
1072
- declare class AllWorkflowsActiveWorkflowActivationPolicy implements WorkflowActivationPolicy {
1073
- isActive(_workflowId: WorkflowId): boolean;
913
+ interface NodeExecutor {
914
+ execute(request: NodeActivationRequest): Promise<NodeOutputs>;
1074
915
  }
1075
- //#endregion
1076
- //#region src/contracts/webhookTypes.d.ts
1077
- type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1078
- interface WebhookControlSignal {
1079
- readonly __webhookControl: true;
1080
- readonly kind: "respondNow" | "respondNowAndContinue";
1081
- readonly responseItems: Items;
1082
- readonly continueItems?: Items;
916
+ interface WorkflowSnapshotFactory {
917
+ create(workflow: WorkflowDefinition): PersistedWorkflowSnapshot;
1083
918
  }
1084
- interface WebhookTriggerRoutingDiagnostics {
1085
- warn(message: string): void;
1086
- /** Inactive workflows omitted from the webhook route index (optional; host should wire for clarity at boot/reload). */
1087
- info?(message: string): void;
919
+ interface WorkflowSnapshotResolver {
920
+ resolve(args: {
921
+ workflowId: WorkflowId;
922
+ workflowSnapshot?: PersistedWorkflowSnapshot;
923
+ }): WorkflowDefinition | undefined;
1088
924
  }
1089
- interface TriggerInstanceId {
1090
- workflowId: WorkflowId;
1091
- nodeId: NodeId;
925
+ /** Optional host wiring for trigger lifecycle logs (boot skip + activation sync). */
926
+ interface TriggerRuntimeDiagnostics {
927
+ info(message: string): void;
928
+ warn(message: string): void;
1092
929
  }
1093
- /** Match for an incoming HTTP request: user-defined URL segment + workflow trigger node. */
1094
- interface WebhookInvocationMatch {
1095
- /** Same value as the webhook trigger's configured endpoint key (URL segment under the webhook base path). */
1096
- endpointPath: string;
1097
- workflowId: WorkflowId;
1098
- nodeId: NodeId;
1099
- methods: ReadonlyArray<HttpMethod>;
1100
- parseJsonBody?: (body: unknown) => unknown;
930
+ interface EngineDeps {
931
+ credentialSessions: CredentialSessionService;
932
+ liveWorkflowRepository: LiveWorkflowRepository;
933
+ workflowRepository: WorkflowRepository;
934
+ /** When {@link AllWorkflowsActiveWorkflowActivationPolicy}, all workflows behave as active (tests). */
935
+ workflowActivationPolicy: WorkflowActivationPolicy;
936
+ nodeResolver: NodeResolver;
937
+ triggerSetupStateRepository: TriggerSetupStateRepository;
938
+ webhookTriggerMatcher: WebhookTriggerMatcher;
939
+ runIdFactory: RunIdFactory;
940
+ activationIdFactory: ActivationIdFactory;
941
+ workflowExecutionRepository: WorkflowExecutionRepository;
942
+ activationScheduler: NodeActivationScheduler;
943
+ runDataFactory: RunDataFactory;
944
+ executionContextFactory: ExecutionContextFactory;
945
+ executionTelemetryFactory?: ExecutionTelemetryFactory;
946
+ nodeExecutor: NodeExecutor;
947
+ eventBus?: RunEventBus;
948
+ tokenRegistry: PersistedWorkflowTokenRegistryLike;
949
+ workflowNodeInstanceFactory: WorkflowNodeInstanceFactory;
950
+ /** Defaults for prune/storage snapshot when workflow omits explicit policy fields. */
951
+ workflowPolicyRuntimeDefaults?: WorkflowPolicyRuntimeDefaults;
952
+ /** When set, logs inactive-workflow skips at boot and trigger start/stop on activation changes. */
953
+ triggerRuntimeDiagnostics?: TriggerRuntimeDiagnostics;
954
+ /** When set, the polling-trigger runtime uses this logger for cycle info/debug/error. */
955
+ pollingTriggerLogger?: PollingTriggerLogger;
1101
956
  }
1102
- /** Result of resolving an HTTP method + endpoint path against the catalog webhook index (404 vs 405 vs match). */
1103
- type WebhookTriggerResolution = {
1104
- status: "notFound";
1105
- } | {
1106
- status: "methodNotAllowed";
1107
- match: WebhookInvocationMatch;
1108
- } | {
1109
- status: "ok";
1110
- match: WebhookInvocationMatch;
1111
- };
957
+ //#endregion
958
+ //#region src/contracts/retryPolicySpec.types.d.ts
1112
959
  /**
1113
- * Resolves webhook routes from workflow definitions (catalog-backed index, no registration at trigger setup).
960
+ * In-process retry policy for runnable nodes. Serialized configs use the same
961
+ * `kind` discriminator (`JSON.stringify` / persisted workflows).
962
+ *
963
+ * `maxAttempts` is the total number of tries including the first (e.g. 3 means up to 2 delays after failures).
1114
964
  */
1115
- interface WebhookTriggerMatcher {
1116
- match(args: {
1117
- endpointPath: string;
1118
- method: HttpMethod;
1119
- }): WebhookInvocationMatch | undefined;
1120
- lookup(endpointPath: string): WebhookInvocationMatch | undefined;
1121
- onEngineWorkflowsLoaded?(): void;
1122
- onEngineStopped?(): void;
1123
- /** Rebuild route index after activation changes without stopping the engine. */
1124
- reloadWebhookRoutes?(): void;
1125
- }
1126
- //#endregion
1127
- //#region src/contracts/runtimeTypes.d.ts
1128
- interface WorkflowRunnerService {
1129
- runById(args: {
1130
- workflowId: WorkflowId;
1131
- startAt?: NodeId;
1132
- items: Items;
1133
- parent?: ParentExecutionRef;
1134
- }): Promise<RunResult>;
1135
- }
1136
- interface WorkflowRunnerResolver {
1137
- resolve(): WorkflowRunnerService | undefined;
965
+ type RetryPolicySpec = NoneRetryPolicySpec | FixedRetryPolicySpec | ExponentialRetryPolicySpec;
966
+ interface NoneRetryPolicySpec {
967
+ readonly kind: "none";
1138
968
  }
1139
- interface WorkflowRepository {
1140
- list(): ReadonlyArray<WorkflowDefinition>;
1141
- get(workflowId: WorkflowId): WorkflowDefinition | undefined;
969
+ interface FixedRetryPolicySpec {
970
+ readonly kind: "fixed";
971
+ /** Total attempts including the first execution. Must be >= 1. */
972
+ readonly maxAttempts: number;
973
+ readonly delayMs: number;
1142
974
  }
1143
- interface LiveWorkflowRepository extends WorkflowRepository {
1144
- setWorkflows(workflows: ReadonlyArray<WorkflowDefinition>): void;
975
+ interface ExponentialRetryPolicySpec {
976
+ readonly kind: "exponential";
977
+ /** Total attempts including the first execution. Must be >= 1. */
978
+ readonly maxAttempts: number;
979
+ readonly initialDelayMs: number;
980
+ readonly multiplier: number;
981
+ readonly maxDelayMs?: number;
982
+ /** When true, each delay is multiplied by a random factor in [1, 1.2). */
983
+ readonly jitter?: boolean;
1145
984
  }
1146
- interface NodeResolver {
1147
- resolve<T>(token: TypeToken<T>): T;
985
+ //#endregion
986
+ //#region src/contracts/workflowTypes.d.ts
987
+ type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
988
+ __codemationNodeJson?: TJson;
989
+ }>;
990
+ type NodeKind = "trigger" | "node";
991
+ type JsonPrimitive = string | number | boolean | null;
992
+ interface JsonObject {
993
+ readonly [key: string]: JsonValue;
1148
994
  }
1149
- interface NodeExecutionStatePublisher {
1150
- markQueued(args: {
1151
- nodeId: NodeId;
1152
- activationId?: NodeActivationId;
1153
- inputsByPort?: NodeInputsByPort;
1154
- }): Promise<void>;
1155
- markRunning(args: {
1156
- nodeId: NodeId;
1157
- activationId?: NodeActivationId;
1158
- inputsByPort?: NodeInputsByPort;
1159
- }): Promise<void>;
1160
- markCompleted(args: {
995
+ type JsonValue = JsonPrimitive | JsonObject | JsonArray;
996
+ type JsonArray = ReadonlyArray<JsonValue>;
997
+ /** JSON value that is not a top-level array (nested arrays inside objects are allowed). */
998
+ type JsonNonArray = JsonPrimitive | JsonObject;
999
+ interface Edge {
1000
+ from: {
1161
1001
  nodeId: NodeId;
1162
- activationId?: NodeActivationId;
1163
- inputsByPort?: NodeInputsByPort;
1164
- outputs?: NodeOutputs;
1165
- }): Promise<void>;
1166
- markFailed(args: {
1002
+ output: OutputPortKey;
1003
+ };
1004
+ to: {
1167
1005
  nodeId: NodeId;
1168
- activationId?: NodeActivationId;
1169
- inputsByPort?: NodeInputsByPort;
1170
- error: Error;
1171
- }): Promise<void>;
1172
- appendConnectionInvocation(args: ConnectionInvocationAppendArgs): Promise<void>;
1173
- }
1174
- type BinaryBody = ReadableStream<Uint8Array> | AsyncIterable<Uint8Array> | Uint8Array | ArrayBuffer;
1175
- interface BinaryStorageWriteRequest {
1176
- storageKey: string;
1177
- body: BinaryBody;
1178
- }
1179
- interface BinaryStorageWriteResult {
1180
- storageKey: string;
1181
- size: number;
1182
- sha256?: string;
1183
- }
1184
- interface BinaryStorageReadResult {
1185
- body: ReadableStream<Uint8Array>;
1186
- size?: number;
1187
- }
1188
- interface BinaryStorageStatResult {
1189
- exists: boolean;
1190
- size?: number;
1191
- }
1192
- interface BinaryStorage {
1193
- readonly driverName: string;
1194
- write(args: BinaryStorageWriteRequest): Promise<BinaryStorageWriteResult>;
1195
- openReadStream(storageKey: string): Promise<BinaryStorageReadResult | undefined>;
1196
- stat(storageKey: string): Promise<BinaryStorageStatResult>;
1197
- delete(storageKey: string): Promise<void>;
1006
+ input: InputPortKey;
1007
+ };
1198
1008
  }
1199
- interface BinaryAttachmentCreateRequest {
1200
- name: string;
1201
- body: BinaryBody;
1202
- mimeType: string;
1203
- filename?: string;
1204
- previewKind?: BinaryAttachment["previewKind"];
1009
+ /**
1010
+ * Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}
1011
+ * but are not traversed by the main execution graph. Parents are commonly executable nodes, but may
1012
+ * also be connection-owned nodes for recursive agent attachments.
1013
+ */
1014
+ interface WorkflowNodeConnection {
1015
+ readonly parentNodeId: NodeId;
1016
+ readonly connectionName: NodeConnectionName;
1017
+ readonly childNodeIds: ReadonlyArray<NodeId>;
1205
1018
  }
1206
- interface NodeBinaryAttachmentService extends ExecutionBinaryService {
1207
- attach(args: BinaryAttachmentCreateRequest): Promise<BinaryAttachment>;
1208
- withAttachment<TJson>(item: Item<TJson>, name: string, attachment: BinaryAttachment): Item<TJson>;
1019
+ interface WorkflowDefinition {
1020
+ id: WorkflowId;
1021
+ name: string;
1022
+ nodes: NodeDefinition[];
1023
+ edges: Edge[];
1024
+ /**
1025
+ * Optional metadata: which nodes are connection-owned children (e.g. AI agent `llm` / `tools` slots).
1026
+ * When omitted, all nodes in {@link nodes} are treated as executable for topology.
1027
+ */
1028
+ readonly connections?: ReadonlyArray<WorkflowNodeConnection>;
1029
+ /** Directory + file-stem path under a workflow discovery root (for UI grouping only). */
1030
+ discoveryPathSegments?: readonly string[];
1031
+ /** Retention for run JSON and binaries (seconds). Host/env may supply defaults when omitted. */
1032
+ readonly prunePolicy?: WorkflowPrunePolicySpec;
1033
+ /** Whether to keep run data after completion. Host/env may supply defaults when omitted. */
1034
+ readonly storagePolicy?: WorkflowStoragePolicySpec;
1035
+ /** Invoked after a node fails permanently (retries exhausted) and node error handler did not recover. */
1036
+ readonly workflowErrorHandler?: WorkflowErrorHandlerSpec;
1209
1037
  }
1210
- interface ExecutionBinaryService {
1211
- forNode(args: {
1038
+ interface WorkflowGraph {
1039
+ next(nodeId: NodeId, output: OutputPortKey): ReadonlyArray<Readonly<{
1212
1040
  nodeId: NodeId;
1213
- activationId: NodeActivationId;
1214
- }): NodeBinaryAttachmentService;
1215
- openReadStream(attachment: BinaryAttachment): Promise<BinaryStorageReadResult | undefined>;
1041
+ input: InputPortKey;
1042
+ }>>;
1216
1043
  }
1217
- interface ExecutionContext {
1218
- runId: RunId;
1219
- workflowId: WorkflowId;
1220
- parent?: ParentExecutionRef;
1221
- /** This run's subworkflow depth (0 = root). */
1222
- subworkflowDepth: number;
1223
- /** Effective activation budget cap for this run (after policy merge). */
1224
- engineMaxNodeActivations: number;
1225
- /** Effective subworkflow nesting cap for this run (after policy merge). */
1226
- engineMaxSubworkflowDepth: number;
1227
- now: () => Date;
1228
- data: RunDataSnapshot;
1229
- nodeState?: NodeExecutionStatePublisher;
1230
- telemetry: ExecutionTelemetry;
1231
- binary: ExecutionBinaryService;
1232
- getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
1233
- /** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
1234
- iterationId?: NodeIterationId;
1235
- /** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
1236
- itemIndex?: number;
1237
- /** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
1238
- parentInvocationId?: ConnectionInvocationId;
1044
+ interface WorkflowGraphFactory {
1045
+ create(def: WorkflowDefinition): WorkflowGraph;
1046
+ }
1047
+ interface NodeConfigBase {
1048
+ readonly kind: NodeKind;
1049
+ readonly type: TypeToken<unknown>;
1050
+ readonly name?: string;
1051
+ readonly id?: NodeId;
1052
+ readonly icon?: string;
1053
+ readonly execution?: Readonly<{
1054
+ hint?: "local" | "worker";
1055
+ queue?: string;
1056
+ }>;
1057
+ /** In-process execute retries (runnable nodes). Triggers typically omit this. */
1058
+ readonly retryPolicy?: RetryPolicySpec;
1059
+ /** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
1060
+ readonly nodeErrorHandler?: NodeErrorHandlerSpec;
1239
1061
  /**
1240
- * Present iff the run was started by a TestSuiteOrchestrator. The {@link IsTestRunNode}
1241
- * branches on this; assertion-emitting nodes use it to decide whether to record results.
1062
+ * When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
1063
+ * Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
1064
+ * main batches skip downstream execution and propagate the empty path.
1242
1065
  */
1243
- testContext?: RunTestContext;
1066
+ readonly continueWhenEmptyOutput?: boolean;
1244
1067
  /**
1245
- * Collections registered in the codemation config, keyed by collection name.
1068
+ * Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
1069
+ * Use for dynamic routers (Switch) and future error ports.
1246
1070
  */
1247
- readonly collections?: CollectionsContext;
1248
- }
1249
- interface ExecutionContextFactory {
1250
- create(args: {
1251
- runId: RunId;
1252
- workflowId: WorkflowId;
1253
- parent?: ParentExecutionRef;
1254
- policySnapshot?: PersistedRunPolicySnapshot;
1255
- subworkflowDepth: number;
1256
- engineMaxNodeActivations: number;
1257
- engineMaxSubworkflowDepth: number;
1258
- data: RunDataSnapshot;
1259
- nodeState?: NodeExecutionStatePublisher;
1260
- telemetry?: ExecutionTelemetry;
1261
- getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
1262
- testContext?: RunTestContext;
1263
- }): ExecutionContext;
1264
- }
1265
- interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfigBase> extends ExecutionContext {
1266
- nodeId: NodeId;
1267
- activationId: NodeActivationId;
1268
- config: TConfig;
1269
- telemetry: NodeExecutionTelemetry;
1270
- binary: NodeBinaryAttachmentService;
1271
- }
1272
- interface PollingTriggerHandle {
1071
+ readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
1072
+ readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
1073
+ getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
1273
1074
  /**
1274
- * Start the polling loop. The runtime registers its own cleanup handle so callers do not need to
1275
- * call {@link TriggerSetupContext.registerCleanup} for the loop.
1276
- * @returns The state returned by the first cycle (or `undefined` when the overlap guard fired).
1075
+ * Marker: this node emits {@link import("./assertionTypes").AssertionResult}-shaped items on its
1076
+ * `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for
1077
+ * `nodeCompleted` events from nodes with this flag set, and persist their output items as
1078
+ * TestAssertion records (only when the run carries a `testContext`). Set on assertion node
1079
+ * configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).
1277
1080
  */
1278
- start<TState, TItem>(args: {
1279
- intervalMs: number;
1280
- seedState?: TState;
1281
- runCycle: (cycleCtx: {
1282
- previousState: TState | undefined;
1283
- signal: AbortSignal;
1284
- }) => Promise<{
1285
- items: Items<TItem>;
1286
- nextState: TState;
1287
- }>;
1288
- }): Promise<TState | undefined>;
1289
- /** Convenience dedup-window helper. */
1290
- readonly dedup: PollingTriggerDedupWindow;
1291
- }
1292
- interface TriggerSetupContext<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>, TSetupState$1 extends JsonValue | undefined = TriggerNodeSetupState<TConfig>> extends ExecutionContext {
1293
- trigger: TriggerInstanceId;
1294
- config: TConfig;
1295
- previousState: TSetupState$1;
1296
- registerCleanup(cleanup: TriggerCleanupHandle): void;
1297
- emit(items: Items): Promise<void>;
1298
- /** Generic polling-trigger surface. Pre-binds trigger id, emit, and registerCleanup. */
1299
- readonly polling: PollingTriggerHandle;
1300
- }
1301
- interface TriggerTestItemsContext<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>, TSetupState$1 extends JsonValue | undefined = TriggerNodeSetupState<TConfig>> extends ExecutionContext {
1302
- trigger: TriggerInstanceId;
1303
- nodeId: NodeId;
1304
- config: TConfig;
1305
- previousState: TSetupState$1;
1081
+ readonly emitsAssertions?: true;
1082
+ /**
1083
+ * Static configuration summary surfaced in the workflow inspector — the design-time
1084
+ * "what does this node do" panel that renders before any run telemetry exists.
1085
+ *
1086
+ * Return 2–6 short label/value pairs derived from this config (method + url for an HTTP
1087
+ * call, model + tool list for an agent, schedule + timezone for a cron trigger, etc.).
1088
+ * Values are truncated by the UI; aim for one line each. Return `undefined` to opt out
1089
+ * — the inspector hides the section when no rows are produced.
1090
+ *
1091
+ * Implement on the config class instance so the function can read sibling config fields.
1092
+ * `defineNode({ inspectorSummary })` plumbs through to this.
1093
+ */
1094
+ inspectorSummary?(): ReadonlyArray<NodeInspectorSummaryRow> | undefined;
1306
1095
  }
1307
1096
  /**
1308
- * Trigger setup state is intentionally engine-owned so future ownership and
1309
- * leader-election metadata can be coordinated centrally rather than pushed into
1310
- * package-level setup code.
1097
+ * One row of a node's static configuration summary. See {@link NodeConfigBase.inspectorSummary}.
1311
1098
  */
1312
- interface PersistedTriggerSetupState<TState extends JsonValue | undefined = JsonValue | undefined> {
1313
- trigger: TriggerInstanceId;
1314
- updatedAt: string;
1315
- state: TState;
1316
- }
1317
- interface TriggerSetupStateRepository {
1318
- load(trigger: TriggerInstanceId): Promise<PersistedTriggerSetupState | undefined>;
1319
- save(state: PersistedTriggerSetupState): Promise<void>;
1320
- delete(trigger: TriggerInstanceId): Promise<void>;
1321
- }
1322
- interface TriggerCleanupHandle {
1323
- stop(): Promise<void> | void;
1324
- }
1325
- interface EngineHost {
1326
- credentialSessions: CredentialSessionService;
1327
- workflows?: WorkflowRunnerService;
1099
+ interface NodeInspectorSummaryRow {
1100
+ readonly label: string;
1101
+ readonly value: string;
1328
1102
  }
1103
+ declare const runnableNodeInputType: unique symbol;
1104
+ declare const runnableNodeOutputType: unique symbol;
1105
+ declare const triggerNodeOutputType: unique symbol;
1329
1106
  /**
1330
- * Per-item runnable node: return JSON, an array to fan-out on `main`, an explicit `Item`, or {@link emitPorts}
1331
- * for multi-port emission. Engine applies `inputSchema.parse(item.json)` and passes the result as `args.input`
1332
- * (wire `item.json` is unchanged). Transform helpers may opt into binary preservation, while routers and
1333
- * pass-through nodes should return explicit items when they need to preserve full item state.
1107
+ * Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
1108
+ * **`TOutputJson`** is emitted `item.json` on outputs.
1334
1109
  */
1335
- interface RunnableNodeExecuteArgs<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown> {
1336
- readonly input: TInputJson$1;
1337
- readonly item: Item;
1338
- readonly itemIndex: number;
1339
- readonly items: Items;
1340
- readonly ctx: NodeExecutionContext<TConfig>;
1341
- }
1342
- interface RunnableNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown, _TOutputJson = unknown> {
1110
+ interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
1343
1111
  readonly kind: "node";
1112
+ readonly [runnableNodeInputType]?: TInputJson$1;
1113
+ readonly [runnableNodeOutputType]?: TOutputJson$1;
1344
1114
  /**
1345
- * Declared output ports (e.g. `["main"]`).
1346
- *
1347
- * Prefer describing dynamic router ports (Switch) and fixed multi-ports (If true/false)
1348
- * via {@link NodeConfigBase.declaredOutputPorts}. Engine defaults to `["main"]` when omitted.
1115
+ * Optional Zod input contract for {@link RunnableNode} when not set on the node class.
1116
+ * Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
1349
1117
  */
1350
- readonly outputPorts?: ReadonlyArray<OutputPortKey>;
1351
- /** When omitted, engine uses {@link RunnableNodeConfig.inputSchema} or `z.unknown()`. */
1352
1118
  readonly inputSchema?: ZodType<TInputJson$1>;
1353
- execute(args: RunnableNodeExecuteArgs<TConfig, TInputJson$1>): Promise<unknown> | unknown;
1119
+ /**
1120
+ * When an activation receives **zero** input items, the engine normally runs `execute` zero times.
1121
+ * Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
1122
+ * Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
1123
+ */
1124
+ readonly emptyBatchExecution?: "skip" | "runOnce";
1354
1125
  }
1355
- /** @deprecated Use {@link RunnableNode} */
1356
- type ItemNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNodeConfig<any, any>, TInputJson$1 = unknown, TOutputJson$1 = unknown> = RunnableNode<TConfig, TInputJson$1, TOutputJson$1>;
1357
- interface MultiInputNode<TConfig extends NodeConfigBase = NodeConfigBase> {
1358
- kind: "node";
1126
+ declare const triggerNodeSetupStateType: unique symbol;
1127
+ interface TriggerNodeConfig<TOutputJson$1 = unknown, TSetupState$1 extends JsonValue | undefined = undefined> extends NodeConfigBase {
1128
+ readonly kind: "trigger";
1129
+ readonly [triggerNodeOutputType]?: TOutputJson$1;
1130
+ readonly [triggerNodeSetupStateType]?: TSetupState$1;
1359
1131
  /**
1360
- * Declared output ports (typically `["main"]`).
1361
- *
1362
- * Prefer describing ports for authoring/canvas via {@link NodeConfigBase.declaredOutputPorts}.
1363
- * Engine defaults to `["main"]` when omitted.
1132
+ * Distinguishes triggers driven by the live activation policy (webhooks, cron, polling) from
1133
+ * triggers driven only by the {@link TestSuiteOrchestrator}. `WorkflowActivation` skips
1134
+ * `"test"` triggers; the orchestrator skips `"live"` triggers. Defaults to `"live"` when omitted.
1364
1135
  */
1365
- outputPorts?: ReadonlyArray<OutputPortKey>;
1366
- executeMulti(inputsByPort: NodeInputsByPort, ctx: NodeExecutionContext<TConfig>): Promise<NodeOutputs>;
1136
+ readonly triggerKind?: "live" | "test";
1367
1137
  }
1368
- type TriggerSetupStateFor<TConfig extends TriggerNodeConfig<any, any>> = TriggerNodeSetupState<TConfig>;
1369
- interface TriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> {
1370
- kind: "trigger";
1371
- outputPorts: readonly ["main"];
1372
- setup(ctx: TriggerSetupContext<TConfig>): Promise<TriggerSetupStateFor<TConfig>>;
1373
- execute(items: Items, ctx: NodeExecutionContext<TConfig>): Promise<NodeOutputs>;
1138
+ type RunnableNodeInputJson<TConfig extends RunnableNodeConfig<any, any>> = TConfig extends RunnableNodeConfig<infer TInputJson, any> ? TInputJson : never;
1139
+ type RunnableNodeOutputJson<TConfig extends RunnableNodeConfig<any, any>> = TConfig extends RunnableNodeConfig<any, infer TOutputJson> ? TOutputJson : never;
1140
+ type TriggerNodeOutputJson<TConfig extends TriggerNodeConfig<any, any>> = TConfig extends TriggerNodeConfig<infer TOutputJson, any> ? TOutputJson : never;
1141
+ type TriggerNodeSetupState<TConfig extends TriggerNodeConfig<any, any>> = TConfig extends TriggerNodeConfig<any, infer TSetupState> ? TSetupState : never;
1142
+ interface NodeDefinition {
1143
+ id: NodeId;
1144
+ kind: NodeKind;
1145
+ type: TypeToken<unknown>;
1146
+ name?: string;
1147
+ config: NodeConfigBase;
1374
1148
  }
1375
- interface TestableTriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> extends TriggerNode<TConfig> {
1376
- getTestItems(ctx: TriggerTestItemsContext<TConfig>): Promise<Items>;
1149
+ interface NodeRef {
1150
+ id: NodeId;
1151
+ kind: NodeKind;
1152
+ name?: string;
1377
1153
  }
1378
- type ExecutableTriggerNode<TConfig extends TriggerNodeConfig<any, any> = TriggerNodeConfig<any, any>> = TriggerNode<TConfig>;
1379
- interface NodeExecutionRequest {
1154
+ declare function nodeRef<TJson>(nodeId: NodeId): NodeIdRef<TJson>;
1155
+ type PairedItemRef = Readonly<{
1156
+ nodeId: NodeId;
1157
+ output: OutputPortKey;
1158
+ itemIndex: number;
1159
+ }>;
1160
+ type BinaryPreviewKind = "image" | "audio" | "video" | "download";
1161
+ type BinaryAttachment = Readonly<{
1162
+ id: string;
1163
+ storageKey: string;
1164
+ mimeType: string;
1165
+ size: number;
1166
+ storageDriver: string;
1167
+ previewKind: BinaryPreviewKind;
1168
+ createdAt: string;
1380
1169
  runId: RunId;
1381
- activationId: NodeActivationId;
1382
1170
  workflowId: WorkflowId;
1383
1171
  nodeId: NodeId;
1384
- input: Items;
1385
- parent?: ParentExecutionRef;
1386
- queue?: string;
1387
- executionOptions?: RunExecutionOptions;
1388
- }
1389
- interface NodeExecutionScheduler {
1390
- enqueue(request: NodeExecutionRequest): Promise<{
1391
- receiptId: string;
1392
- }>;
1393
- cancel?(receiptId: string): Promise<void>;
1394
- }
1395
- interface NodeExecutionRequestHandler {
1396
- handleNodeExecutionRequest(request: NodeExecutionRequest): Promise<void>;
1397
- }
1398
- type NodeActivationRequestBase = Readonly<{
1399
- runId: RunId;
1400
1172
  activationId: NodeActivationId;
1173
+ filename?: string;
1174
+ sha256?: string;
1175
+ }>;
1176
+ type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
1177
+ type Item<TJson = unknown> = Readonly<{
1178
+ json: TJson;
1179
+ binary?: ItemBinary;
1180
+ meta?: Readonly<Record<string, unknown>>;
1181
+ paired?: ReadonlyArray<PairedItemRef>;
1182
+ }>;
1183
+ type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
1184
+ type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
1185
+ type RunId = string;
1186
+ type NodeActivationId = string;
1187
+ /**
1188
+ * One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
1189
+ * per-item connection invocations and telemetry. Undefined when the executing node is a batch
1190
+ * node or trigger that does not iterate items.
1191
+ */
1192
+ type NodeIterationId = string;
1193
+ interface ParentExecutionRef {
1194
+ runId: RunId;
1401
1195
  workflowId: WorkflowId;
1402
1196
  nodeId: NodeId;
1403
- parent?: ParentExecutionRef;
1404
- executionOptions?: RunExecutionOptions;
1405
- batchId?: string;
1406
- ctx: NodeExecutionContext;
1407
- }>;
1408
- type NodeActivationRequest = (NodeActivationRequestBase & Readonly<{
1409
- kind: "single";
1410
- input: Items;
1411
- }>) | (NodeActivationRequestBase & Readonly<{
1412
- kind: "multi";
1413
- inputsByPort: NodeInputsByPort;
1414
- }>);
1415
- interface NodeActivationReceipt {
1416
- receiptId: string;
1417
- mode?: "local" | "worker";
1418
- queue?: string;
1197
+ /** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
1198
+ subworkflowDepth?: number;
1199
+ /** Effective max node activations from the parent run (propagated to child policy merge). */
1200
+ engineMaxNodeActivations?: number;
1201
+ /** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
1202
+ engineMaxSubworkflowDepth?: number;
1203
+ /**
1204
+ * Test-suite linkage inherited by the child subworkflow run. Set by whichever node
1205
+ * spawns the subworkflow when its own `ctx.testContext` is present, so assertions
1206
+ * emitted inside a subworkflow land under the correct parent test case.
1207
+ */
1208
+ testContext?: RunTestContext;
1419
1209
  }
1420
- interface PreparedNodeActivationDispatch {
1421
- readonly receipt: NodeActivationReceipt;
1422
- dispatch(): Promise<void>;
1210
+ interface RunDataSnapshot {
1211
+ getOutputs(nodeId: NodeId): NodeOutputs | undefined;
1212
+ getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
1213
+ getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
1423
1214
  }
1424
- interface NodeActivationContinuation {
1425
- markNodeRunning(args: {
1426
- runId: RunId;
1427
- activationId: NodeActivationId;
1428
- nodeId: NodeId;
1429
- inputsByPort: NodeInputsByPort;
1430
- }): Promise<void>;
1431
- resumeFromNodeResult(args: {
1432
- runId: RunId;
1433
- activationId: NodeActivationId;
1434
- nodeId: NodeId;
1435
- outputs: NodeOutputs;
1436
- }): Promise<RunResult>;
1437
- resumeFromNodeError(args: {
1438
- runId: RunId;
1439
- activationId: NodeActivationId;
1440
- nodeId: NodeId;
1441
- error: Error;
1442
- }): Promise<RunResult>;
1215
+ interface MutableRunData extends RunDataSnapshot {
1216
+ setOutputs(nodeId: NodeId, outputs: NodeOutputs): void;
1217
+ dump(): Record<NodeId, NodeOutputs>;
1443
1218
  }
1444
- interface NodeActivationScheduler {
1445
- setContinuation?(continuation: NodeActivationContinuation): void;
1446
- prepareDispatch(request: NodeActivationRequest): Promise<PreparedNodeActivationDispatch>;
1447
- cancel?(receiptId: string): Promise<void>;
1219
+ interface RunDataFactory {
1220
+ create(initial?: Record<NodeId, NodeOutputs>): MutableRunData;
1448
1221
  }
1449
- interface WorkflowNodeInstanceFactory {
1450
- createNodes(workflow: WorkflowDefinition): ReadonlyMap<NodeId, unknown>;
1451
- createByType(type: TypeToken<unknown>): unknown;
1222
+ interface RunIdFactory {
1223
+ makeRunId(): RunId;
1452
1224
  }
1453
- interface NodeExecutor {
1454
- execute(request: NodeActivationRequest): Promise<NodeOutputs>;
1225
+ interface ActivationIdFactory {
1226
+ makeActivationId(): NodeActivationId;
1455
1227
  }
1456
- interface WorkflowSnapshotFactory {
1457
- create(workflow: WorkflowDefinition): PersistedWorkflowSnapshot;
1228
+ type UpstreamRefPlaceholder = `$${number}`;
1229
+ declare const branchRef: (index: number) => UpstreamRefPlaceholder;
1230
+ type ExecutionMode = "local" | "worker";
1231
+ interface NodeSchedulerDecision {
1232
+ mode: ExecutionMode;
1233
+ queue?: string;
1458
1234
  }
1459
- interface WorkflowSnapshotResolver {
1460
- resolve(args: {
1235
+ interface NodeOffloadPolicy {
1236
+ decide(args: {
1461
1237
  workflowId: WorkflowId;
1462
- workflowSnapshot?: PersistedWorkflowSnapshot;
1463
- }): WorkflowDefinition | undefined;
1238
+ nodeId: NodeId;
1239
+ config: NodeConfigBase;
1240
+ }): NodeSchedulerDecision;
1464
1241
  }
1465
- /** Optional host wiring for trigger lifecycle logs (boot skip + activation sync). */
1466
- interface TriggerRuntimeDiagnostics {
1467
- info(message: string): void;
1468
- warn(message: string): void;
1242
+ /** Whether to persist run execution data after the workflow finishes. */
1243
+ type WorkflowStoragePolicyMode = "ALL" | "SUCCESS" | "ERROR" | "NEVER";
1244
+ type WorkflowStoragePolicySpec = WorkflowStoragePolicyMode | TypeToken<WorkflowStoragePolicyResolver>;
1245
+ interface WorkflowStoragePolicyResolver {
1246
+ shouldPersist(args: WorkflowStoragePolicyDecisionArgs): boolean | Promise<boolean>;
1469
1247
  }
1470
- interface EngineDeps {
1471
- credentialSessions: CredentialSessionService;
1472
- liveWorkflowRepository: LiveWorkflowRepository;
1473
- workflowRepository: WorkflowRepository;
1474
- /** When {@link AllWorkflowsActiveWorkflowActivationPolicy}, all workflows behave as active (tests). */
1475
- workflowActivationPolicy: WorkflowActivationPolicy;
1476
- nodeResolver: NodeResolver;
1477
- triggerSetupStateRepository: TriggerSetupStateRepository;
1478
- webhookTriggerMatcher: WebhookTriggerMatcher;
1479
- runIdFactory: RunIdFactory;
1480
- activationIdFactory: ActivationIdFactory;
1481
- workflowExecutionRepository: WorkflowExecutionRepository;
1482
- activationScheduler: NodeActivationScheduler;
1483
- runDataFactory: RunDataFactory;
1484
- executionContextFactory: ExecutionContextFactory;
1485
- executionTelemetryFactory?: ExecutionTelemetryFactory;
1486
- nodeExecutor: NodeExecutor;
1487
- eventBus?: RunEventBus;
1488
- tokenRegistry: PersistedWorkflowTokenRegistryLike;
1489
- workflowNodeInstanceFactory: WorkflowNodeInstanceFactory;
1490
- /** Defaults for prune/storage snapshot when workflow omits explicit policy fields. */
1491
- workflowPolicyRuntimeDefaults?: WorkflowPolicyRuntimeDefaults;
1492
- /** When set, logs inactive-workflow skips at boot and trigger start/stop on activation changes. */
1493
- triggerRuntimeDiagnostics?: TriggerRuntimeDiagnostics;
1494
- /** When set, the polling-trigger runtime uses this logger for cycle info/debug/error. */
1495
- pollingTriggerLogger?: PollingTriggerLogger;
1248
+ interface WorkflowStoragePolicyDecisionArgs {
1249
+ readonly runId: RunId;
1250
+ readonly workflowId: WorkflowId;
1251
+ readonly workflow: WorkflowDefinition;
1252
+ readonly finalStatus: "completed" | "failed";
1253
+ readonly startedAt: string;
1254
+ readonly finishedAt: string;
1496
1255
  }
1497
- //#endregion
1498
- //#region src/contracts/retryPolicySpec.types.d.ts
1499
- /**
1500
- * In-process retry policy for runnable nodes. Serialized configs use the same
1501
- * `kind` discriminator (`JSON.stringify` / persisted workflows).
1502
- *
1503
- * `maxAttempts` is the total number of tries including the first (e.g. 3 means up to 2 delays after failures).
1504
- */
1505
- type RetryPolicySpec = NoneRetryPolicySpec | FixedRetryPolicySpec | ExponentialRetryPolicySpec;
1506
- interface NoneRetryPolicySpec {
1507
- readonly kind: "none";
1256
+ interface WorkflowPrunePolicySpec {
1257
+ readonly runDataRetentionSeconds?: number;
1258
+ readonly binaryRetentionSeconds?: number;
1259
+ readonly telemetrySpanRetentionSeconds?: number;
1260
+ readonly telemetryArtifactRetentionSeconds?: number;
1261
+ readonly telemetryMetricRetentionSeconds?: number;
1508
1262
  }
1509
- interface FixedRetryPolicySpec {
1510
- readonly kind: "fixed";
1511
- /** Total attempts including the first execution. Must be >= 1. */
1512
- readonly maxAttempts: number;
1513
- readonly delayMs: number;
1263
+ interface PersistedRunPolicySnapshot {
1264
+ readonly retentionSeconds?: number;
1265
+ readonly binaryRetentionSeconds?: number;
1266
+ readonly telemetrySpanRetentionSeconds?: number;
1267
+ readonly telemetryArtifactRetentionSeconds?: number;
1268
+ readonly telemetryMetricRetentionSeconds?: number;
1269
+ readonly storagePolicy: WorkflowStoragePolicyMode;
1514
1270
  }
1515
- interface ExponentialRetryPolicySpec {
1516
- readonly kind: "exponential";
1517
- /** Total attempts including the first execution. Must be >= 1. */
1518
- readonly maxAttempts: number;
1519
- readonly initialDelayMs: number;
1520
- readonly multiplier: number;
1521
- readonly maxDelayMs?: number;
1522
- /** When true, each delay is multiplied by a random factor in [1, 1.2). */
1523
- readonly jitter?: boolean;
1271
+ interface WorkflowErrorHandler {
1272
+ onError(ctx: WorkflowErrorContext): void | Promise<void>;
1524
1273
  }
1525
- //#endregion
1526
- //#region src/contracts/workflowTypes.d.ts
1527
- type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
1528
- __codemationNodeJson?: TJson;
1529
- }>;
1530
- type NodeKind = "trigger" | "node";
1531
- type JsonPrimitive = string | number | boolean | null;
1532
- interface JsonObject {
1533
- readonly [key: string]: JsonValue;
1274
+ interface WorkflowErrorContext {
1275
+ readonly runId: RunId;
1276
+ readonly workflowId: WorkflowId;
1277
+ readonly workflow: WorkflowDefinition;
1278
+ readonly failedNodeId: NodeId;
1279
+ readonly error: Error;
1280
+ readonly startedAt: string;
1281
+ readonly finishedAt: string;
1282
+ }
1283
+ type WorkflowErrorHandlerSpec = TypeToken<WorkflowErrorHandler> | WorkflowErrorHandler;
1284
+ interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
1285
+ readonly kind: "single" | "multi";
1286
+ readonly items: Items;
1287
+ readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
1288
+ readonly ctx: NodeExecutionContext<TConfig>;
1289
+ readonly error: Error;
1534
1290
  }
1535
- type JsonValue = JsonPrimitive | JsonObject | JsonArray;
1536
- type JsonArray = ReadonlyArray<JsonValue>;
1537
- /** JSON value that is not a top-level array (nested arrays inside objects are allowed). */
1538
- type JsonNonArray = JsonPrimitive | JsonObject;
1539
- interface Edge {
1540
- from: {
1541
- nodeId: NodeId;
1542
- output: OutputPortKey;
1543
- };
1544
- to: {
1545
- nodeId: NodeId;
1546
- input: InputPortKey;
1547
- };
1291
+ interface NodeErrorHandler {
1292
+ handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
1293
+ }
1294
+ type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
1295
+ /** Runtime defaults when workflow omits prune/storage fields (typically from host env). */
1296
+ interface WorkflowPolicyRuntimeDefaults {
1297
+ readonly retentionSeconds?: number;
1298
+ readonly binaryRetentionSeconds?: number;
1299
+ readonly telemetrySpanRetentionSeconds?: number;
1300
+ readonly telemetryArtifactRetentionSeconds?: number;
1301
+ readonly telemetryMetricRetentionSeconds?: number;
1302
+ readonly storagePolicy?: WorkflowStoragePolicyMode;
1548
1303
  }
1304
+ //#endregion
1305
+ //#region src/contracts/testTriggerTypes.d.ts
1549
1306
  /**
1550
- * Named connection from a parent node to child nodes that exist in {@link WorkflowDefinition.nodes}
1551
- * but are not traversed by the main execution graph. Parents are commonly executable nodes, but may
1552
- * also be connection-owned nodes for recursive agent attachments.
1307
+ * Identifier minted by the host (or in-memory test runner) for one execution of a test suite.
1308
+ * One TestSuiteRun produces N child workflow runs, one per item yielded by `generateItems`.
1553
1309
  */
1554
- interface WorkflowNodeConnection {
1555
- readonly parentNodeId: NodeId;
1556
- readonly connectionName: NodeConnectionName;
1557
- readonly childNodeIds: ReadonlyArray<NodeId>;
1558
- }
1559
- interface WorkflowDefinition {
1560
- id: WorkflowId;
1561
- name: string;
1562
- nodes: NodeDefinition[];
1563
- edges: Edge[];
1310
+ type TestSuiteRunId = string;
1311
+ /**
1312
+ * Setup context passed to a {@link TestTriggerNodeConfig.generateItems} callback. Distinct from
1313
+ * {@link import("./runtimeTypes").TriggerSetupContext} on purpose: test triggers are not
1314
+ * activated by the live trigger lifecycle (webhooks, cron, polling) and never call `emit` —
1315
+ * the orchestrator pulls from the iterable they return and dispatches one run per item.
1316
+ */
1317
+ interface TestTriggerSetupContext<TConfig extends TestTriggerNodeConfig<unknown> = TestTriggerNodeConfig<unknown>> {
1318
+ readonly workflowId: WorkflowId;
1319
+ readonly nodeId: NodeId;
1320
+ readonly config: TConfig;
1321
+ readonly testSuiteRunId: TestSuiteRunId;
1564
1322
  /**
1565
- * Optional metadata: which nodes are connection-owned children (e.g. AI agent `llm` / `tools` slots).
1566
- * When omitted, all nodes in {@link nodes} are treated as executable for topology.
1323
+ * Resolves a credential session for a slot declared on this trigger's
1324
+ * {@link import("./workflowTypes").NodeConfigBase.getCredentialRequirements}. Same contract as
1325
+ * {@link import("./runtimeTypes").ExecutionContext.getCredential}.
1567
1326
  */
1568
- readonly connections?: ReadonlyArray<WorkflowNodeConnection>;
1569
- /** Directory + file-stem path under a workflow discovery root (for UI grouping only). */
1570
- discoveryPathSegments?: readonly string[];
1571
- /** Retention for run JSON and binaries (seconds). Host/env may supply defaults when omitted. */
1572
- readonly prunePolicy?: WorkflowPrunePolicySpec;
1573
- /** Whether to keep run data after completion. Host/env may supply defaults when omitted. */
1574
- readonly storagePolicy?: WorkflowStoragePolicySpec;
1575
- /** Invoked after a node fails permanently (retries exhausted) and node error handler did not recover. */
1576
- readonly workflowErrorHandler?: WorkflowErrorHandlerSpec;
1577
- }
1578
- interface WorkflowGraph {
1579
- next(nodeId: NodeId, output: OutputPortKey): ReadonlyArray<Readonly<{
1580
- nodeId: NodeId;
1581
- input: InputPortKey;
1582
- }>>;
1583
- }
1584
- interface WorkflowGraphFactory {
1585
- create(def: WorkflowDefinition): WorkflowGraph;
1327
+ getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
1328
+ /** AbortSignal raised when the suite is cancelled long-running pulls should bail out. */
1329
+ readonly signal: AbortSignal;
1586
1330
  }
1587
- interface NodeConfigBase {
1588
- readonly kind: NodeKind;
1589
- readonly type: TypeToken<unknown>;
1590
- readonly name?: string;
1591
- readonly id?: NodeId;
1592
- readonly icon?: string;
1593
- readonly execution?: Readonly<{
1594
- hint?: "local" | "worker";
1595
- queue?: string;
1596
- }>;
1597
- /** In-process execute retries (runnable nodes). Triggers typically omit this. */
1598
- readonly retryPolicy?: RetryPolicySpec;
1599
- /** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
1600
- readonly nodeErrorHandler?: NodeErrorHandlerSpec;
1331
+ /**
1332
+ * A trigger config that emits **test cases**. Each item yielded by {@link generateItems}
1333
+ * becomes one workflow run (with `executionOptions.testContext` set), so 10 yielded items
1334
+ * → 10 runs marked under the same TestSuiteRun.
1335
+ *
1336
+ * The trigger is otherwise a normal {@link TriggerNodeConfig} (so the canvas treats it like
1337
+ * any other trigger), but its `triggerKind` is `"test"` so the live activation policy skips it.
1338
+ */
1339
+ interface TestTriggerNodeConfig<TOutputJson$1 = unknown> extends TriggerNodeConfig<TOutputJson$1, undefined> {
1340
+ readonly triggerKind: "test";
1601
1341
  /**
1602
- * When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
1603
- * Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
1604
- * main batches skip downstream execution and propagate the empty path.
1342
+ * Author-supplied async iterable of items, evaluated lazily. Implementations may fetch from
1343
+ * credentialed APIs, read fixture files, or yield hard-coded items. The orchestrator iterates
1344
+ * and dispatches one run per item, with concurrency capped by {@link concurrency} (default 4).
1605
1345
  */
1606
- readonly continueWhenEmptyOutput?: boolean;
1346
+ generateItems(ctx: TestTriggerSetupContext<TestTriggerNodeConfig<TOutputJson$1>>): AsyncIterable<Item<TOutputJson$1>>;
1347
+ /** Per-suite-run cap on simultaneously-executing test cases. Default: 4. */
1348
+ readonly concurrency?: number;
1607
1349
  /**
1608
- * Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
1609
- * Use for dynamic routers (Switch) and future error ports.
1350
+ * Free-form description of where the test cases come from surfaced in the node properties
1351
+ * panel and the suite-detail header so authors revisiting the workflow six months later
1352
+ * remember which mailbox / folder / fixture file the cases originate from.
1353
+ *
1354
+ * Example: `"All emails in the Gmail label \"test/triage-fixtures\" — 14 messages as of 2026-05-03."`
1610
1355
  */
1611
- readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
1612
- readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
1613
- getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
1356
+ readonly description?: string;
1614
1357
  /**
1615
- * Marker: this node emits {@link import("./assertionTypes").AssertionResult}-shaped items on its
1616
- * `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for
1617
- * `nodeCompleted` events from nodes with this flag set, and persist their output items as
1618
- * TestAssertion records (only when the run carries a `testContext`). Set on assertion node
1619
- * configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).
1358
+ * Resolves a human-readable label for one yielded test case (e.g. email subject). The
1359
+ * orchestrator calls this once per yielded item, persists the result on the run, and the
1360
+ * Tests-tab UI uses it to render the case row instead of the opaque runId. Return
1361
+ * `undefined` to fall back to "Case #N".
1620
1362
  */
1621
- readonly emitsAssertions?: true;
1363
+ caseLabel?(item: Item<TOutputJson$1>): string | undefined;
1364
+ }
1365
+ //#endregion
1366
+ //#region src/events/runEvents.d.ts
1367
+ /**
1368
+ * Outcome of a single test case (one workflow run dispatched by the test-suite orchestrator).
1369
+ * - `running`: workflow still in flight
1370
+ * - `succeeded`: workflow completed AND all assertions passed (or no assertions)
1371
+ * - `failed`: workflow failed OR (workflow completed but ≥1 assertion failed)
1372
+ * - `errored` / `cancelled`: workflow itself errored or was cancelled
1373
+ */
1374
+ type TestCaseRunStatus = "running" | "succeeded" | "failed" | "errored" | "cancelled";
1375
+ /** Aggregate outcome of a TestSuiteRun. */
1376
+ type TestSuiteRunStatus = "succeeded" | "failed" | "partial" | "errored" | "cancelled";
1377
+ type RunEvent = Readonly<{
1378
+ kind: "runCreated";
1379
+ runId: RunId;
1380
+ workflowId: WorkflowId;
1381
+ parent?: ParentExecutionRef;
1382
+ at: string;
1383
+ }> | Readonly<{
1384
+ kind: "runSaved";
1385
+ runId: RunId;
1386
+ workflowId: WorkflowId;
1387
+ parent?: ParentExecutionRef;
1388
+ at: string;
1389
+ state: PersistedRunState;
1390
+ }> | Readonly<{
1391
+ kind: "nodeQueued";
1392
+ runId: RunId;
1393
+ workflowId: WorkflowId;
1394
+ parent?: ParentExecutionRef;
1395
+ at: string;
1396
+ snapshot: NodeExecutionSnapshot;
1397
+ }> | Readonly<{
1398
+ kind: "nodeStarted";
1399
+ runId: RunId;
1400
+ workflowId: WorkflowId;
1401
+ parent?: ParentExecutionRef;
1402
+ at: string;
1403
+ snapshot: NodeExecutionSnapshot;
1404
+ }> | Readonly<{
1405
+ kind: "nodeCompleted";
1406
+ runId: RunId;
1407
+ workflowId: WorkflowId;
1408
+ parent?: ParentExecutionRef;
1409
+ at: string;
1410
+ snapshot: NodeExecutionSnapshot;
1411
+ }> | Readonly<{
1412
+ kind: "nodeFailed";
1413
+ runId: RunId;
1414
+ workflowId: WorkflowId;
1415
+ parent?: ParentExecutionRef;
1416
+ at: string;
1417
+ snapshot: NodeExecutionSnapshot;
1418
+ }> | Readonly<{
1419
+ kind: "connectionInvocationStarted";
1420
+ runId: RunId;
1421
+ workflowId: WorkflowId;
1422
+ parent?: ParentExecutionRef;
1423
+ at: string;
1424
+ record: ConnectionInvocationRecord;
1425
+ }> | Readonly<{
1426
+ kind: "connectionInvocationCompleted";
1427
+ runId: RunId;
1428
+ workflowId: WorkflowId;
1429
+ parent?: ParentExecutionRef;
1430
+ at: string;
1431
+ record: ConnectionInvocationRecord;
1432
+ }> | Readonly<{
1433
+ kind: "connectionInvocationFailed";
1434
+ runId: RunId;
1435
+ workflowId: WorkflowId;
1436
+ parent?: ParentExecutionRef;
1437
+ at: string;
1438
+ record: ConnectionInvocationRecord;
1439
+ }> | Readonly<{
1440
+ kind: "testSuiteStarted";
1441
+ testSuiteRunId: TestSuiteRunId;
1442
+ workflowId: WorkflowId;
1443
+ triggerNodeId: string;
1444
+ triggerNodeName?: string;
1445
+ concurrency: number;
1446
+ at: string;
1447
+ }> | Readonly<{
1448
+ kind: "testSuiteFinished";
1449
+ testSuiteRunId: TestSuiteRunId;
1450
+ workflowId: WorkflowId;
1451
+ status: TestSuiteRunStatus;
1452
+ totalCases: number;
1453
+ passedCases: number;
1454
+ failedCases: number;
1455
+ at: string;
1456
+ }> | Readonly<{
1457
+ kind: "testCaseStarted";
1458
+ testSuiteRunId: TestSuiteRunId;
1459
+ testCaseIndex: number;
1460
+ runId: RunId;
1461
+ workflowId: WorkflowId;
1462
+ testCaseLabel?: string;
1463
+ at: string;
1464
+ }> | Readonly<{
1465
+ kind: "testCaseCompleted";
1466
+ testSuiteRunId: TestSuiteRunId;
1467
+ testCaseIndex: number;
1468
+ runId: RunId;
1469
+ workflowId: WorkflowId;
1470
+ status: TestCaseRunStatus;
1471
+ at: string;
1472
+ }>;
1473
+ interface RunEventSubscription {
1474
+ close(): Promise<void>;
1475
+ }
1476
+ interface RunEventBus {
1477
+ publish(event: RunEvent): Promise<void>;
1478
+ subscribe(onEvent: (event: RunEvent) => void): Promise<RunEventSubscription>;
1479
+ subscribeToWorkflow(workflowId: WorkflowId, onEvent: (event: RunEvent) => void): Promise<RunEventSubscription>;
1480
+ }
1481
+ //#endregion
1482
+ //#region src/policies/executionLimits/EngineExecutionLimitsPolicy.d.ts
1483
+ interface EngineExecutionLimitsPolicyConfig {
1484
+ readonly defaultMaxNodeActivations: number;
1485
+ readonly hardMaxNodeActivations: number;
1486
+ readonly defaultMaxSubworkflowDepth: number;
1487
+ readonly hardMaxSubworkflowDepth: number;
1622
1488
  }
1623
- declare const runnableNodeInputType: unique symbol;
1624
- declare const runnableNodeOutputType: unique symbol;
1625
- declare const triggerNodeOutputType: unique symbol;
1489
+ /** Framework defaults for {@link EngineExecutionLimitsPolicy} (merged with host `runtime.engineExecutionLimits`). */
1490
+ declare const ENGINE_EXECUTION_LIMITS_DEFAULTS: EngineExecutionLimitsPolicyConfig;
1626
1491
  /**
1627
- * Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
1628
- * **`TOutputJson`** is emitted `item.json` on outputs.
1492
+ * Resolves per-run execution limits: defaults, hard ceilings, and subworkflow depth for new runs.
1629
1493
  */
1630
- interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
1631
- readonly kind: "node";
1632
- readonly [runnableNodeInputType]?: TInputJson$1;
1633
- readonly [runnableNodeOutputType]?: TOutputJson$1;
1494
+ declare class EngineExecutionLimitsPolicy {
1495
+ private readonly config;
1496
+ constructor(config?: EngineExecutionLimitsPolicyConfig);
1634
1497
  /**
1635
- * Optional Zod input contract for {@link RunnableNode} when not set on the node class.
1636
- * Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
1498
+ * Effective options for a new root run (depth 0): defaults merged with engine ceilings.
1499
+ * Replaces a separate one-method factory for root-run bootstrap.
1637
1500
  */
1638
- readonly inputSchema?: ZodType<TInputJson$1>;
1501
+ createRootExecutionOptions(): RunExecutionOptions;
1502
+ mergeExecutionOptionsForNewRun(parent: ParentExecutionRef | undefined, user: RunExecutionOptions | undefined): RunExecutionOptions;
1503
+ private capNumber;
1504
+ }
1505
+ //#endregion
1506
+ //#region src/di/CoreTokens.d.ts
1507
+ declare const CoreTokens: {
1508
+ readonly PersistedWorkflowTokenRegistry: TypeToken<PersistedWorkflowTokenRegistryLike>;
1509
+ readonly CredentialSessionService: TypeToken<CredentialSessionService>;
1510
+ readonly CredentialTypeRegistry: TypeToken<CredentialTypeRegistry>;
1511
+ readonly WorkflowRunnerService: TypeToken<WorkflowRunnerService>;
1512
+ readonly LiveWorkflowRepository: TypeToken<LiveWorkflowRepository>;
1513
+ readonly WorkflowRepository: TypeToken<WorkflowRepository>;
1514
+ readonly NodeResolver: TypeToken<NodeResolver>;
1515
+ readonly WorkflowNodeInstanceFactory: TypeToken<WorkflowNodeInstanceFactory>;
1516
+ readonly RunIdFactory: TypeToken<RunIdFactory>;
1517
+ readonly ActivationIdFactory: TypeToken<ActivationIdFactory>;
1518
+ readonly WorkflowExecutionRepository: TypeToken<WorkflowExecutionRepository>;
1519
+ readonly TriggerSetupStateRepository: TypeToken<TriggerSetupStateRepository>;
1520
+ readonly NodeActivationScheduler: TypeToken<NodeActivationScheduler>;
1521
+ readonly RunDataFactory: TypeToken<RunDataFactory>;
1522
+ readonly ExecutionContextFactory: TypeToken<ExecutionContextFactory>;
1523
+ readonly RunEventBus: TypeToken<RunEventBus>;
1524
+ readonly BinaryStorage: TypeToken<BinaryStorage>;
1525
+ readonly WebhookBasePath: TypeToken<string>;
1526
+ /** Engine execution limits (defaults + optional host overrides). Consumers may bind a custom instance to override. */
1527
+ readonly EngineExecutionLimitsPolicy: TypeToken<EngineExecutionLimitsPolicy>;
1528
+ readonly WorkflowActivationPolicy: TypeToken<WorkflowActivationPolicy>;
1639
1529
  /**
1640
- * When an activation receives **zero** input items, the engine normally runs `execute` zero times.
1641
- * Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
1642
- * Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
1530
+ * Optional. When registered, AIAgentNode uses it to resolve mcpServers bindings,
1531
+ * validate scopes, open pool connections, and prepare the MCP ToolSet map.
1532
+ * Not registered in the default core bootstrap the host provides the implementation.
1643
1533
  */
1644
- readonly emptyBatchExecution?: "skip" | "runOnce";
1645
- }
1646
- declare const triggerNodeSetupStateType: unique symbol;
1647
- interface TriggerNodeConfig<TOutputJson$1 = unknown, TSetupState$1 extends JsonValue | undefined = undefined> extends NodeConfigBase {
1648
- readonly kind: "trigger";
1649
- readonly [triggerNodeOutputType]?: TOutputJson$1;
1650
- readonly [triggerNodeSetupStateType]?: TSetupState$1;
1534
+ readonly AgentMcpIntegration: TypeToken<AgentMcpIntegration>;
1535
+ };
1536
+ //#endregion
1537
+ //#region src/contracts/runTypes.d.ts
1538
+ /**
1539
+ * Test-suite linkage for a run. When set, this run was started by a TestSuiteOrchestrator
1540
+ * as one test case inside a TestSuiteRun. The `IsTestRun` node and host-side persisters key
1541
+ * off the presence of this field. Subworkflow runs inherit it from their parent run.
1542
+ */
1543
+ interface RunTestContext {
1544
+ readonly testSuiteRunId: string;
1545
+ readonly testCaseIndex: number;
1651
1546
  /**
1652
- * Distinguishes triggers driven by the live activation policy (webhooks, cron, polling) from
1653
- * triggers driven only by the {@link TestSuiteOrchestrator}. `WorkflowActivation` skips
1654
- * `"test"` triggers; the orchestrator skips `"live"` triggers. Defaults to `"live"` when omitted.
1547
+ * Optional human-friendly label for this test case (e.g. an email subject when fixtures
1548
+ * are loaded from a mailbox). Resolved per item by `TestTrigger.caseLabel(item)` if set,
1549
+ * persisted on `Run.test_case_label` so the Tests-tab tree-table can show "RFQ for batch 14"
1550
+ * instead of "run_1777755971399_bbb86beac1396".
1655
1551
  */
1656
- readonly triggerKind?: "live" | "test";
1552
+ readonly testCaseLabel?: string;
1657
1553
  }
1658
- type RunnableNodeInputJson<TConfig extends RunnableNodeConfig<any, any>> = TConfig extends RunnableNodeConfig<infer TInputJson, any> ? TInputJson : never;
1659
- type RunnableNodeOutputJson<TConfig extends RunnableNodeConfig<any, any>> = TConfig extends RunnableNodeConfig<any, infer TOutputJson> ? TOutputJson : never;
1660
- type TriggerNodeOutputJson<TConfig extends TriggerNodeConfig<any, any>> = TConfig extends TriggerNodeConfig<infer TOutputJson, any> ? TOutputJson : never;
1661
- type TriggerNodeSetupState<TConfig extends TriggerNodeConfig<any, any>> = TConfig extends TriggerNodeConfig<any, infer TSetupState> ? TSetupState : never;
1662
- interface NodeDefinition {
1663
- id: NodeId;
1664
- kind: NodeKind;
1665
- type: TypeToken<unknown>;
1666
- name?: string;
1667
- config: NodeConfigBase;
1554
+ interface RunExecutionOptions {
1555
+ /** Run-intent override: force the inline scheduler and bypass node-level offload decisions. */
1556
+ localOnly?: boolean;
1557
+ /** Marks runs started from webhook handling so orchestration can apply webhook-specific continuation rules. */
1558
+ webhook?: boolean;
1559
+ mode?: "manual" | "debug";
1560
+ sourceWorkflowId?: WorkflowId;
1561
+ sourceRunId?: RunId;
1562
+ derivedFromRunId?: RunId;
1563
+ isMutable?: boolean;
1564
+ /** Set by the engine for this run: 0 = root, 1 = first child subworkflow, … */
1565
+ subworkflowDepth?: number;
1566
+ /** Effective cap after engine policy merge (successful node completions per run). */
1567
+ maxNodeActivations?: number;
1568
+ /** Effective cap after engine policy merge (subworkflow nesting). */
1569
+ maxSubworkflowDepth?: number;
1570
+ /** Present iff started by a TestSuiteOrchestrator; propagates to subworkflow runs via {@link ParentExecutionRef.testContext}. */
1571
+ testContext?: RunTestContext;
1668
1572
  }
1669
- interface NodeRef {
1573
+ /** Engine-owned counters persisted with the run (worker-safe). */
1574
+ interface EngineRunCounters {
1575
+ completedNodeActivations: number;
1576
+ }
1577
+ type RunStopCondition = Readonly<{
1578
+ kind: "workflowCompleted";
1579
+ }> | Readonly<{
1580
+ kind: "nodeCompleted";
1581
+ nodeId: NodeId;
1582
+ }>;
1583
+ interface RunStateResetRequest {
1584
+ clearFromNodeId: NodeId;
1585
+ }
1586
+ interface PersistedRunControlState {
1587
+ stopCondition?: RunStopCondition;
1588
+ }
1589
+ interface PersistedWorkflowSnapshotNode {
1670
1590
  id: NodeId;
1671
1591
  kind: NodeKind;
1672
1592
  name?: string;
1593
+ nodeTokenId: PersistedTokenId;
1594
+ configTokenId: PersistedTokenId;
1595
+ tokenName?: string;
1596
+ configTokenName?: string;
1597
+ config: unknown;
1598
+ /** Pre-computed static configuration summary; populated by WorkflowSnapshotCodec. */
1599
+ inspectorSummary?: ReadonlyArray<Readonly<{
1600
+ label: string;
1601
+ value: string;
1602
+ }>>;
1673
1603
  }
1674
- declare function nodeRef<TJson>(nodeId: NodeId): NodeIdRef<TJson>;
1675
- type PairedItemRef = Readonly<{
1604
+ interface PersistedWorkflowSnapshot {
1605
+ id: WorkflowId;
1606
+ name: string;
1607
+ nodes: ReadonlyArray<PersistedWorkflowSnapshotNode>;
1608
+ edges: ReadonlyArray<Edge>;
1609
+ /** When the snapshot was built from a live workflow definition that configured a workflow error handler. */
1610
+ workflowErrorHandlerConfigured?: boolean;
1611
+ /** Connection metadata for child nodes not in the execution graph (e.g. AI agent attachments). */
1612
+ connections?: ReadonlyArray<WorkflowNodeConnection>;
1613
+ }
1614
+ type PinnedNodeOutputsByPort = Readonly<Record<OutputPortKey, Items>>;
1615
+ interface PersistedMutableNodeState {
1616
+ pinnedOutputsByPort?: PinnedNodeOutputsByPort;
1617
+ lastDebugInput?: Items;
1618
+ }
1619
+ interface PersistedMutableRunState {
1620
+ nodesById: Readonly<Record<NodeId, PersistedMutableNodeState>>;
1621
+ }
1622
+ type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
1623
+ interface RunQueueEntry {
1676
1624
  nodeId: NodeId;
1677
- output: OutputPortKey;
1678
- itemIndex: number;
1679
- }>;
1680
- type BinaryPreviewKind = "image" | "audio" | "video" | "download";
1681
- type BinaryAttachment = Readonly<{
1682
- id: string;
1683
- storageKey: string;
1684
- mimeType: string;
1685
- size: number;
1686
- storageDriver: string;
1687
- previewKind: BinaryPreviewKind;
1688
- createdAt: string;
1625
+ input: Items;
1626
+ toInput?: InputPortKey;
1627
+ batchId?: string;
1628
+ from?: Readonly<{
1629
+ nodeId: NodeId;
1630
+ output: OutputPortKey;
1631
+ }>;
1632
+ collect?: Readonly<{
1633
+ expectedInputs: ReadonlyArray<InputPortKey>;
1634
+ received: Readonly<Record<InputPortKey, Items>>;
1635
+ }>;
1636
+ }
1637
+ type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
1638
+ interface NodeExecutionError {
1639
+ message: string;
1640
+ name?: string;
1641
+ stack?: string;
1642
+ details?: JsonValue;
1643
+ }
1644
+ interface NodeExecutionSnapshot {
1689
1645
  runId: RunId;
1690
1646
  workflowId: WorkflowId;
1691
1647
  nodeId: NodeId;
1692
- activationId: NodeActivationId;
1693
- filename?: string;
1694
- sha256?: string;
1695
- }>;
1696
- type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
1697
- type Item<TJson = unknown> = Readonly<{
1698
- json: TJson;
1699
- binary?: ItemBinary;
1700
- meta?: Readonly<Record<string, unknown>>;
1701
- paired?: ReadonlyArray<PairedItemRef>;
1648
+ activationId?: NodeActivationId;
1649
+ parent?: ParentExecutionRef;
1650
+ status: NodeExecutionStatus;
1651
+ usedPinnedOutput?: boolean;
1652
+ queuedAt?: string;
1653
+ startedAt?: string;
1654
+ finishedAt?: string;
1655
+ updatedAt: string;
1656
+ inputsByPort?: NodeInputsByPort;
1657
+ outputs?: NodeOutputs;
1658
+ error?: NodeExecutionError;
1659
+ /**
1660
+ * When the node is a SubWorkflow invocation, the run id of the child run it spawned.
1661
+ * Populated after the child run completes so the UI can deep-link to that specific execution.
1662
+ */
1663
+ childRunId?: RunId;
1664
+ }
1665
+ /** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
1666
+ type ConnectionInvocationId = string;
1667
+ /**
1668
+ * One logical LLM or tool call under an owning workflow node (e.g. AI agent).
1669
+ * The owning node defines what {@link managedInput} and {@link managedOutput} contain.
1670
+ */
1671
+ interface ConnectionInvocationRecord {
1672
+ readonly invocationId: ConnectionInvocationId;
1673
+ readonly runId: RunId;
1674
+ readonly workflowId: WorkflowId;
1675
+ readonly connectionNodeId: NodeId;
1676
+ readonly parentAgentNodeId: NodeId;
1677
+ readonly parentAgentActivationId: NodeActivationId;
1678
+ readonly status: NodeExecutionStatus;
1679
+ readonly managedInput?: JsonValue;
1680
+ readonly managedOutput?: JsonValue;
1681
+ /** Short human-readable description of what this invocation is doing right now (e.g. `"calling search_messages"`). Rendered as a sub-line on the canvas node card. */
1682
+ readonly statusLabel?: string;
1683
+ /** Stable identifier for the thing this invocation acts on (e.g. an MCP tool name like `"search_messages"`). Persists across status transitions so the inspector can show it on completed/failed entries too. Connection nodes that ARE the tool (e.g. node-backed agent tools) leave this unset — the parent node id already identifies the subject. */
1684
+ readonly subjectName?: string;
1685
+ readonly error?: NodeExecutionError;
1686
+ readonly queuedAt?: string;
1687
+ readonly startedAt?: string;
1688
+ readonly finishedAt?: string;
1689
+ readonly updatedAt: string;
1690
+ /** Per-item iteration id minted by the engine when this invocation occurred inside a runnable node's per-item loop. */
1691
+ readonly iterationId?: NodeIterationId;
1692
+ /** Item index (0-based) of the iteration that produced this invocation. */
1693
+ readonly itemIndex?: number;
1694
+ /** When set, this invocation was produced inside a sub-agent triggered by the named parent invocation. */
1695
+ readonly parentInvocationId?: ConnectionInvocationId;
1696
+ }
1697
+ /** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
1698
+ type ConnectionInvocationAppendArgs = Readonly<{
1699
+ invocationId: ConnectionInvocationId;
1700
+ connectionNodeId: NodeId;
1701
+ parentAgentNodeId: NodeId;
1702
+ parentAgentActivationId: NodeActivationId;
1703
+ status: NodeExecutionStatus;
1704
+ managedInput?: JsonValue;
1705
+ managedOutput?: JsonValue;
1706
+ statusLabel?: string;
1707
+ subjectName?: string;
1708
+ error?: NodeExecutionError;
1709
+ queuedAt?: string;
1710
+ startedAt?: string;
1711
+ finishedAt?: string;
1712
+ iterationId?: NodeIterationId;
1713
+ itemIndex?: number;
1714
+ parentInvocationId?: ConnectionInvocationId;
1702
1715
  }>;
1703
- type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
1704
- type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
1705
- type RunId = string;
1706
- type NodeActivationId = string;
1707
- /**
1708
- * One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
1709
- * per-item connection invocations and telemetry. Undefined when the executing node is a batch
1710
- * node or trigger that does not iterate items.
1711
- */
1712
- type NodeIterationId = string;
1713
- interface ParentExecutionRef {
1716
+ interface RunCurrentState {
1717
+ outputsByNode: Record<NodeId, NodeOutputs>;
1718
+ nodeSnapshotsByNodeId: Record<NodeId, NodeExecutionSnapshot>;
1719
+ /** Append-only history of connection-scoped invocations (LLM/tool) for inspector and canvas. */
1720
+ connectionInvocations?: ReadonlyArray<ConnectionInvocationRecord>;
1721
+ mutableState?: PersistedMutableRunState;
1722
+ }
1723
+ interface CurrentStateExecutionRequest {
1724
+ workflow: WorkflowDefinition;
1725
+ items?: Items;
1726
+ parent?: ParentExecutionRef;
1727
+ executionOptions?: RunExecutionOptions;
1728
+ workflowSnapshot?: PersistedWorkflowSnapshot;
1729
+ mutableState?: PersistedMutableRunState;
1730
+ currentState?: RunCurrentState;
1731
+ stopCondition?: RunStopCondition;
1732
+ reset?: RunStateResetRequest;
1733
+ }
1734
+ interface ExecutionFrontierPlan {
1735
+ rootNodeId?: NodeId;
1736
+ rootNodeInput?: Items;
1737
+ queue: RunQueueEntry[];
1738
+ currentState: RunCurrentState;
1739
+ stopCondition: RunStopCondition;
1740
+ satisfiedNodeIds: ReadonlyArray<NodeId>;
1741
+ skippedNodeIds: ReadonlyArray<NodeId>;
1742
+ clearedNodeIds: ReadonlyArray<NodeId>;
1743
+ preservedPinnedNodeIds: ReadonlyArray<NodeId>;
1744
+ }
1745
+ type RunStatus = "running" | "pending" | "completed" | "failed";
1746
+ interface RunSummary {
1714
1747
  runId: RunId;
1715
1748
  workflowId: WorkflowId;
1716
- nodeId: NodeId;
1717
- /** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
1718
- subworkflowDepth?: number;
1719
- /** Effective max node activations from the parent run (propagated to child policy merge). */
1720
- engineMaxNodeActivations?: number;
1721
- /** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
1722
- engineMaxSubworkflowDepth?: number;
1749
+ startedAt: string;
1750
+ status: RunStatus;
1723
1751
  /**
1724
- * Test-suite linkage inherited by the child subworkflow run. Set by whichever node
1725
- * spawns the subworkflow when its own `ctx.testContext` is present, so assertions
1726
- * emitted inside a subworkflow land under the correct parent test case.
1752
+ * Test-case status for runs dispatched as part of a TestSuiteRun. Carries the
1753
+ * assertion-rollup-corrected outcome the test orchestrator persists onto the row, so the
1754
+ * executions list can show "failed" for a run whose workflow completed cleanly but whose
1755
+ * assertions caught regressions. Absent for non-test runs and legacy rows.
1727
1756
  */
1728
- testContext?: RunTestContext;
1729
- }
1730
- interface RunDataSnapshot {
1731
- getOutputs(nodeId: NodeId): NodeOutputs | undefined;
1732
- getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
1733
- getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
1734
- }
1735
- interface MutableRunData extends RunDataSnapshot {
1736
- setOutputs(nodeId: NodeId, outputs: NodeOutputs): void;
1737
- dump(): Record<NodeId, NodeOutputs>;
1738
- }
1739
- interface RunDataFactory {
1740
- create(initial?: Record<NodeId, NodeOutputs>): MutableRunData;
1757
+ testCaseStatus?: TestCaseRunStatus;
1758
+ /** ISO timestamp when the run finished (derived from node snapshots or store `updatedAt`); omit while running/pending. */
1759
+ finishedAt?: string;
1760
+ parent?: ParentExecutionRef;
1761
+ executionOptions?: RunExecutionOptions;
1741
1762
  }
1742
- interface RunIdFactory {
1743
- makeRunId(): RunId;
1763
+ interface PendingNodeExecution {
1764
+ runId: RunId;
1765
+ activationId: NodeActivationId;
1766
+ workflowId: WorkflowId;
1767
+ nodeId: NodeId;
1768
+ itemsIn: number;
1769
+ inputsByPort: NodeInputsByPort;
1770
+ receiptId: string;
1771
+ queue?: string;
1772
+ batchId?: string;
1773
+ enqueuedAt: string;
1744
1774
  }
1745
- interface ActivationIdFactory {
1746
- makeActivationId(): NodeActivationId;
1775
+ interface PersistedRunSchedulingState {
1776
+ pending?: PendingNodeExecution;
1777
+ queue: RunQueueEntry[];
1747
1778
  }
1748
- type UpstreamRefPlaceholder = `$${number}`;
1749
- declare const branchRef: (index: number) => UpstreamRefPlaceholder;
1750
- type ExecutionMode = "local" | "worker";
1751
- interface NodeSchedulerDecision {
1752
- mode: ExecutionMode;
1753
- queue?: string;
1779
+ interface PersistedRunState {
1780
+ runId: RunId;
1781
+ workflowId: WorkflowId;
1782
+ startedAt: string;
1783
+ /** Canonical terminal time for listings and retention when persisted on the run root. */
1784
+ finishedAt?: string;
1785
+ /** Optimistic concurrency / CAS on the run aggregate (repository may increment on save). */
1786
+ revision?: number;
1787
+ parent?: ParentExecutionRef;
1788
+ executionOptions?: RunExecutionOptions;
1789
+ control?: PersistedRunControlState;
1790
+ workflowSnapshot?: PersistedWorkflowSnapshot;
1791
+ mutableState?: PersistedMutableRunState;
1792
+ /** Frozen at createRun from workflow + runtime defaults for prune/storage decisions. */
1793
+ policySnapshot?: PersistedRunPolicySnapshot;
1794
+ /** Successful node completions so far (for activation budget). */
1795
+ engineCounters?: EngineRunCounters;
1796
+ status: RunStatus;
1797
+ pending?: PendingNodeExecution;
1798
+ queue: RunQueueEntry[];
1799
+ outputsByNode: Record<NodeId, NodeOutputs>;
1800
+ nodeSnapshotsByNodeId: Record<NodeId, NodeExecutionSnapshot>;
1801
+ /** Append-only history of connection invocations (LLM/tool) nested under owning nodes. */
1802
+ connectionInvocations?: ReadonlyArray<ConnectionInvocationRecord>;
1754
1803
  }
1755
- interface NodeOffloadPolicy {
1756
- decide(args: {
1804
+ interface WorkflowExecutionRepository {
1805
+ createRun(args: {
1806
+ runId: RunId;
1757
1807
  workflowId: WorkflowId;
1758
- nodeId: NodeId;
1759
- config: NodeConfigBase;
1760
- }): NodeSchedulerDecision;
1808
+ startedAt: string;
1809
+ parent?: ParentExecutionRef;
1810
+ executionOptions?: RunExecutionOptions;
1811
+ control?: PersistedRunControlState;
1812
+ workflowSnapshot?: PersistedWorkflowSnapshot;
1813
+ mutableState?: PersistedMutableRunState;
1814
+ policySnapshot?: PersistedRunPolicySnapshot;
1815
+ engineCounters?: EngineRunCounters;
1816
+ }): Promise<void>;
1817
+ load(runId: RunId): Promise<PersistedRunState | undefined>;
1818
+ loadSchedulingState(runId: RunId): Promise<PersistedRunSchedulingState | undefined>;
1819
+ save(state: PersistedRunState): Promise<void>;
1820
+ deleteRun?(runId: RunId): Promise<void>;
1761
1821
  }
1762
- /** Whether to persist run execution data after the workflow finishes. */
1763
- type WorkflowStoragePolicyMode = "ALL" | "SUCCESS" | "ERROR" | "NEVER";
1764
- type WorkflowStoragePolicySpec = WorkflowStoragePolicyMode | TypeToken<WorkflowStoragePolicyResolver>;
1765
- interface WorkflowStoragePolicyResolver {
1766
- shouldPersist(args: WorkflowStoragePolicyDecisionArgs): boolean | Promise<boolean>;
1822
+ interface WorkflowExecutionListingRepository {
1823
+ listRuns(args?: Readonly<{
1824
+ workflowId?: WorkflowId;
1825
+ limit?: number;
1826
+ }>): Promise<ReadonlyArray<RunSummary>>;
1767
1827
  }
1768
- interface WorkflowStoragePolicyDecisionArgs {
1828
+ /** Runs eligible for retention-based pruning (completed or failed, older than cutoff). */
1829
+ interface RunPruneCandidate {
1769
1830
  readonly runId: RunId;
1770
1831
  readonly workflowId: WorkflowId;
1771
- readonly workflow: WorkflowDefinition;
1772
- readonly finalStatus: "completed" | "failed";
1773
1832
  readonly startedAt: string;
1774
1833
  readonly finishedAt: string;
1775
1834
  }
1776
- interface WorkflowPrunePolicySpec {
1777
- readonly runDataRetentionSeconds?: number;
1778
- readonly binaryRetentionSeconds?: number;
1779
- readonly telemetrySpanRetentionSeconds?: number;
1780
- readonly telemetryArtifactRetentionSeconds?: number;
1781
- readonly telemetryMetricRetentionSeconds?: number;
1782
- }
1783
- interface PersistedRunPolicySnapshot {
1784
- readonly retentionSeconds?: number;
1785
- readonly binaryRetentionSeconds?: number;
1786
- readonly telemetrySpanRetentionSeconds?: number;
1787
- readonly telemetryArtifactRetentionSeconds?: number;
1788
- readonly telemetryMetricRetentionSeconds?: number;
1789
- readonly storagePolicy: WorkflowStoragePolicyMode;
1835
+ interface WorkflowExecutionPruneRepository {
1836
+ listRunsOlderThan(args: Readonly<{
1837
+ nowIso: string;
1838
+ defaultRetentionSeconds: number;
1839
+ limit?: number;
1840
+ }>): Promise<ReadonlyArray<RunPruneCandidate>>;
1790
1841
  }
1791
- interface WorkflowErrorHandler {
1792
- onError(ctx: WorkflowErrorContext): void | Promise<void>;
1842
+ type RunResult = {
1843
+ runId: RunId;
1844
+ workflowId: WorkflowId;
1845
+ startedAt: string;
1846
+ status: "completed";
1847
+ outputs: Items;
1848
+ } | {
1849
+ runId: RunId;
1850
+ workflowId: WorkflowId;
1851
+ startedAt: string;
1852
+ status: "pending";
1853
+ pending: PendingNodeExecution;
1854
+ } | {
1855
+ runId: RunId;
1856
+ workflowId: WorkflowId;
1857
+ startedAt: string;
1858
+ status: "failed";
1859
+ error: {
1860
+ message: string;
1861
+ };
1862
+ };
1863
+ type WebhookRunResult = Readonly<{
1864
+ runId: RunId;
1865
+ workflowId: WorkflowId;
1866
+ startedAt: string;
1867
+ runStatus: "pending" | "completed";
1868
+ response: Items;
1869
+ }>;
1870
+ interface PersistedWorkflowTokenRegistryLike {
1871
+ register(type: TypeToken<unknown>, packageId: string, persistedNameOverride?: string): string;
1872
+ getTokenId(type: TypeToken<unknown>): string | undefined;
1873
+ resolve(tokenId: string): TypeToken<unknown> | undefined;
1874
+ registerFromWorkflows?(workflows: ReadonlyArray<WorkflowDefinition>): void;
1793
1875
  }
1794
- interface WorkflowErrorContext {
1795
- readonly runId: RunId;
1796
- readonly workflowId: WorkflowId;
1797
- readonly workflow: WorkflowDefinition;
1798
- readonly failedNodeId: NodeId;
1799
- readonly error: Error;
1800
- readonly startedAt: string;
1801
- readonly finishedAt: string;
1876
+ interface RunCompletionNotifier {
1877
+ resolveRunCompletion(result: RunResult): void;
1878
+ resolveWebhookResponse(result: WebhookRunResult): void;
1802
1879
  }
1803
- type WorkflowErrorHandlerSpec = TypeToken<WorkflowErrorHandler> | WorkflowErrorHandler;
1804
- interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
1805
- readonly kind: "single" | "multi";
1806
- readonly items: Items;
1807
- readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
1808
- readonly ctx: NodeExecutionContext<TConfig>;
1809
- readonly error: Error;
1880
+ interface RunEventPublisherDeps {
1881
+ eventBus?: RunEventBus;
1810
1882
  }
1811
- interface NodeErrorHandler {
1812
- handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
1883
+ //#endregion
1884
+ //#region src/contracts/agentMcpTypes.d.ts
1885
+ /**
1886
+ * Emitted as a span event when a credential is missing required scopes
1887
+ * (bind-time) or when callTool returns a permission error (runtime).
1888
+ * The credential type id can be looked up from the credential instance when needed.
1889
+ */
1890
+ interface NeedsReconsentEvent {
1891
+ readonly serverId: string;
1892
+ readonly credentialInstanceId: string;
1893
+ readonly missingScopesHint?: readonly string[];
1813
1894
  }
1814
- type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
1815
- /** Runtime defaults when workflow omits prune/storage fields (typically from host env). */
1816
- interface WorkflowPolicyRuntimeDefaults {
1817
- readonly retentionSeconds?: number;
1818
- readonly binaryRetentionSeconds?: number;
1819
- readonly telemetrySpanRetentionSeconds?: number;
1820
- readonly telemetryArtifactRetentionSeconds?: number;
1821
- readonly telemetryMetricRetentionSeconds?: number;
1822
- readonly storagePolicy?: WorkflowStoragePolicyMode;
1895
+ /**
1896
+ * An opaque MCP tool map: keyed by serverId → (toolName tool definition).
1897
+ * Typed as unknown so core does not depend on the AI SDK's ToolSet type.
1898
+ * AIAgentNode (in core-nodes, which does depend on ai) casts this to
1899
+ * ReadonlyMap<string, ToolSet> before passing to DeferredMetaToolStrategyFactory.
1900
+ */
1901
+ type AgentMcpToolMap = ReadonlyMap<string, Readonly<Record<string, unknown>>>;
1902
+ /**
1903
+ * Contract implemented by the host. Resolves MCP server bindings for an agent run
1904
+ * via the standard credential-binding table (one slot per declared server, keyed
1905
+ * by `(workflowId, mcpConnectionNodeId, "credential")`), and returns a ready-to-use
1906
+ * tool map with wrapped execute callbacks for telemetry and 403 detection.
1907
+ * Core-nodes imports this interface so AIAgentNode can inject it without
1908
+ * depending on the host.
1909
+ */
1910
+ interface AgentMcpIntegration {
1911
+ /**
1912
+ * Look up the credential binding per server, validate scopes, open pool
1913
+ * connections, and return a tool map keyed by serverId. Each tool's
1914
+ * execute callback includes:
1915
+ * - Telemetry child span (mcp.server_id, mcp.tool_name attributes)
1916
+ * - 403/permission error detection → emits a NeedsReconsentEvent span event
1917
+ *
1918
+ * Throws `AgentBindError` on validation failures (missing server, unbound
1919
+ * credential slot, missing credential instance, insufficient scopes).
1920
+ */
1921
+ prepareMcpTools(args: {
1922
+ readonly workflowId: WorkflowId;
1923
+ readonly agentNodeId: NodeId;
1924
+ readonly serverIds: ReadonlyArray<string>;
1925
+ readonly pinnedMcpTools: readonly string[];
1926
+ readonly emitSpanEvent: (event: TelemetrySpanEventRecord) => void;
1927
+ readonly startChildSpan: (args: {
1928
+ readonly name: string;
1929
+ readonly attributes?: Record<string, string>;
1930
+ }) => {
1931
+ readonly end: (args?: {
1932
+ status?: "ok" | "error";
1933
+ statusMessage?: string;
1934
+ }) => void;
1935
+ };
1936
+ /** Per-MCP-tool-call invocation appender. Optional; when omitted the wrapper emits only telemetry spans. */
1937
+ readonly appendMcpInvocation?: (args: ConnectionInvocationAppendArgs) => Promise<void>;
1938
+ /** Agent activation id to attach to each invocation record (used by canvas + inspector grouping). */
1939
+ readonly parentAgentActivationId?: NodeActivationId;
1940
+ /** Per-item iteration id when the agent runs inside a per-item loop. */
1941
+ readonly iterationId?: NodeIterationId;
1942
+ /** Item index (0-based) of the iteration that owns these tool calls. */
1943
+ readonly itemIndex?: number;
1944
+ /** Parent invocation id when this agent is itself executing as a sub-agent. */
1945
+ readonly parentInvocationId?: ConnectionInvocationId;
1946
+ }): Promise<AgentMcpToolMap>;
1823
1947
  }
1824
1948
  //#endregion
1825
1949
  //#region src/orchestration/Engine.d.ts
@@ -2024,5 +2148,5 @@ declare class RunIntentService {
2024
2148
  private createWebhookExecutionOptions;
2025
2149
  }
2026
2150
  //#endregion
2027
- export { WorkflowPrunePolicySpec as $, CredentialHealth as $n, RunTestContext as $r, TriggerSetupStateFor as $t, NodeSchedulerDecision as A, TestSuiteRunId as Ai, CodemationTelemetryMetricNames as An, NodeExecutionStatus as Ar, NodeActivationContinuation as At, RunnableNodeOutputJson as B, CostTrackingTelemetry as Bn, PersistedWorkflowTokenRegistryLike as Br, NodeExecutionStatePublisher as Bt, NodeErrorHandlerSpec as C, EngineExecutionLimitsPolicy as Ci, TelemetryAttributes as Cn, ConnectionInvocationId as Cr, ExecutableTriggerNode as Ct, NodeOffloadPolicy as D, RunEventSubscription as Di, TelemetrySpanEnd as Dn, ExecutionFrontierPlan as Dr, ItemNode as Dt, NodeKind as E, RunEventBus as Ei, TelemetryScope as En, EngineRunCounters as Er, ExecutionContextFactory as Et, RunDataSnapshot as F, NodeId as Fi, NoOpNodeExecutionTelemetry as Fn, PersistedRunControlState as Fr, NodeBinaryAttachmentService as Ft, WorkflowDefinition as G, CollectionStore as Gn, RunExecutionOptions as Gr, PreparedNodeActivationDispatch as Gt, TriggerNodeOutputJson as H, CostTrackingTelemetryFactory as Hn, RunCompletionNotifier as Hr, NodeResolver as Ht, RunId as I, OutputPortKey as Ii, NoOpTelemetrySpanScope as In, PersistedRunSchedulingState as Ir, NodeExecutionContext as It, WorkflowErrorHandlerSpec as J, CredentialAdvancedSectionPresentation as Jn, RunResult as Jr, TestableTriggerNode as Jt, WorkflowErrorContext as K, CollectionsContext as Kn, RunPruneCandidate as Kr, RunnableNode as Kt, RunIdFactory as L, PersistedTokenId as Li, NoOpTelemetryArtifactReference as Ln, PersistedRunState as Lr, NodeExecutionRequest as Lt, ParentExecutionRef as M, TestTriggerSetupContext as Mi, CodemationTelemetryAttributeNames as Mn, PendingNodeExecution as Mr, NodeActivationRequest as Mt, PersistedRunPolicySnapshot as N, InputPortKey as Ni, NoOpExecutionTelemetryFactory as Nn, PersistedMutableNodeState as Nr, NodeActivationRequestBase as Nt, NodeOutputs as O, TestCaseRunStatus as Oi, TelemetrySpanEventRecord as On, NodeExecutionError as Or, LiveWorkflowRepository as Ot, RunDataFactory as P, NodeConnectionName as Pi, NoOpExecutionTelemetry as Pn, PersistedMutableRunState as Pr, NodeActivationScheduler as Pt, WorkflowPolicyRuntimeDefaults as Q, CredentialFieldSchema as Qn, RunSummary as Qr, TriggerSetupContext as Qt, RunnableNodeConfig as R, WorkflowId as Ri, CostTrackingComponent as Rn, PersistedWorkflowSnapshot as Rr, NodeExecutionRequestHandler as Rt, NodeErrorHandlerArgs as S, ENGINE_EXECUTION_LIMITS_DEFAULTS as Si, TelemetryAttributePrimitive as Sn, ConnectionInvocationAppendArgs as Sr, EngineHost as St, NodeIterationId as T, RunEvent as Ti, TelemetryMetricRecord as Tn, CurrentStateExecutionRequest as Tr, ExecutionContext as Tt, TriggerNodeSetupState as U, CostTrackingTelemetryMetricNames as Un, RunCurrentState as Ur, PersistedTriggerSetupState as Ut, TriggerNodeConfig as V, CostTrackingTelemetryAttributeNames as Vn, PinnedNodeOutputsByPort as Vr, NodeExecutor as Vt, UpstreamRefPlaceholder as W, CostTrackingUsageRecord as Wn, RunEventPublisherDeps as Wr, PollingTriggerHandle as Wt, WorkflowGraphFactory as X, CredentialBinding as Xn, RunStatus as Xr, TriggerNode as Xt, WorkflowGraph as Y, CredentialAuthDefinition as Yn, RunStateResetRequest as Yr, TriggerCleanupHandle as Yt, WorkflowNodeConnection as Z, CredentialBindingKey as Zn, RunStopCondition as Zr, TriggerRuntimeDiagnostics as Zt, MutableRunData as _, instancePerContainerCachingFactory as _i, ExecutionTelemetry as _n, CredentialUnboundError as _r, BinaryStorageReadResult as _t, BinaryAttachment as a, DependencyContainer$1 as ai, WorkflowRunnerService as an, CredentialMaterialSourceKind as ar, nodeRef as at, NodeDefinition as b, singleton as bi, TelemetryArtifactAttachment as bn, PollingTriggerLogger as br, BinaryStorageWriteResult as bt, ExecutionMode as c, Lifecycle as ci, HttpMethod as cn, CredentialRequirement as cr, triggerNodeOutputType as ct, Items as d, container as di, WebhookInvocationMatch as dn, CredentialSessionService as dr, FixedRetryPolicySpec as dt, WebhookRunResult as ei, TriggerSetupStateRepository as en, CredentialHealthStatus as er, WorkflowStoragePolicyDecisionArgs as et, JsonArray as f, delay as fi, WebhookTriggerMatcher as fn, CredentialSetupStatus as fr, NoneRetryPolicySpec as ft, JsonValue as g, instanceCachingFactory as gi, WorkflowActivationPolicy as gn, CredentialTypeRegistry as gr, BinaryStorage as gt, JsonPrimitive as h, injectable as hi, AllWorkflowsActiveWorkflowActivationPolicy as hn, CredentialTypeId as hr, BinaryBody as ht, ActivationIdFactory as i, Container as ii, WorkflowRunnerResolver as in, CredentialJsonRecord as ir, branchRef as it, PairedItemRef as j, TestTriggerNodeConfig as ji, GenAiTelemetryAttributeNames as jn, NodeInputsByPort as jr, NodeActivationReceipt as jt, NodeRef as k, TestSuiteRunStatus as ki, TelemetrySpanScope as kn, NodeExecutionSnapshot as kr, MultiInputNode as kt, Item as l, RegistrationOptions as li, TriggerInstanceId as ln, CredentialSessionFactory as lr, triggerNodeSetupStateType as lt, JsonObject as m, injectAll as mi, WebhookTriggerRoutingDiagnostics as mn, CredentialTypeDefinition as mr, BinaryAttachmentCreateRequest as mt, InMemoryLiveWorkflowRepository as n, WorkflowExecutionPruneRepository as ni, WorkflowNodeInstanceFactory as nn, CredentialInstanceId as nr, WorkflowStoragePolicyResolver as nt, BinaryPreviewKind as o, Disposable as oi, WorkflowSnapshotFactory as on, CredentialOAuth2AuthDefinition as or, runnableNodeInputType as ot, JsonNonArray as p, inject as pi, WebhookTriggerResolution as pn, CredentialType as pr, RetryPolicySpec as pt, WorkflowErrorHandler as q, AnyCredentialType as qn, RunQueueEntry as qr, RunnableNodeExecuteArgs as qt, Engine as r, WorkflowExecutionRepository as ri, WorkflowRepository as rn, CredentialInstanceRecord as rr, WorkflowStoragePolicySpec as rt, Edge as s, InjectionToken$1 as si, WorkflowSnapshotResolver as sn, CredentialOAuth2ScopesFromPublicConfig as sr, runnableNodeOutputType as st, RunIntentService as t, WorkflowExecutionListingRepository as ti, TriggerTestItemsContext as tn, CredentialHealthTester as tr, WorkflowStoragePolicyMode as tt, ItemBinary as u, TypeToken as ui, WebhookControlSignal as un, CredentialSessionFactoryArgs as ur, ExponentialRetryPolicySpec as ut, NodeActivationId as v, predicateAwareClassFactory as vi, ExecutionTelemetryFactory as vn, OAuth2ProviderFromPublicConfig as vr, BinaryStorageStatResult as vt, NodeIdRef as w, EngineExecutionLimitsPolicyConfig as wi, TelemetryChildSpanStart as wn, ConnectionInvocationRecord as wr, ExecutionBinaryService as wt, NodeErrorHandler as x, CoreTokens as xi, TelemetryArtifactReference as xn, PollingTriggerDedupWindow as xr, EngineDeps as xt, NodeConfigBase as y, registry as yi, NodeExecutionTelemetry as yn, NoOpPollingTriggerLogger as yr, BinaryStorageWriteRequest as yt, RunnableNodeInputJson as z, CostTrackingPriceQuote as zn, PersistedWorkflowSnapshotNode as zr, NodeExecutionScheduler as zt };
2028
- //# sourceMappingURL=RunIntentService-siBSjaaY.d.cts.map
2151
+ export { injectAll as $, NodeExecutionRequestHandler as $n, CostTrackingComponent as $r, RunnableNodeConfig as $t, RunExecutionOptions as A, CredentialTypeId as Ai, BinaryBody as An, AllWorkflowsActiveWorkflowActivationPolicy as Ar, JsonValue as At, WorkflowExecutionListingRepository as B, OutputPortKey as Bi, ExecutionContext as Bn, TelemetryMetricRecord as Br, NodeIterationId as Bt, PersistedWorkflowSnapshot as C, CredentialRequirement as Ci, triggerNodeOutputType as Cn, HttpMethod as Cr, Item as Ct, RunCompletionNotifier as D, CredentialSetupStatus as Di, NoneRetryPolicySpec as Dn, WebhookTriggerMatcher as Dr, JsonNonArray as Dt, PinnedNodeOutputsByPort as E, CredentialSessionService as Ei, FixedRetryPolicySpec as En, WebhookInvocationMatch as Er, JsonArray as Et, RunStatus as F, PollingTriggerLogger as Fi, BinaryStorageWriteResult as Fn, TelemetryArtifactAttachment as Fr, NodeErrorHandler as Ft, Disposable as G, NodeActivationContinuation as Gn, CodemationTelemetryMetricNames as Gr, NodeSchedulerDecision as Gt, WorkflowExecutionRepository as H, WorkflowId as Hi, ItemNode as Hn, TelemetrySpanEnd as Hr, NodeOffloadPolicy as Ht, RunStopCondition as I, PollingTriggerDedupWindow as Ii, EngineDeps as In, TelemetryArtifactReference as Ir, NodeErrorHandlerArgs as It, RegistrationOptions as J, NodeActivationRequestBase as Jn, NoOpExecutionTelemetryFactory as Jr, PersistedRunPolicySnapshot as Jt, InjectionToken$1 as K, NodeActivationReceipt as Kn, GenAiTelemetryAttributeNames as Kr, PairedItemRef as Kt, RunSummary as L, InputPortKey as Li, EngineHost as Ln, TelemetryAttributePrimitive as Lr, NodeErrorHandlerSpec as Lt, RunQueueEntry as M, CredentialUnboundError as Mi, BinaryStorageReadResult as Mn, ExecutionTelemetry as Mr, NodeActivationId as Mt, RunResult as N, OAuth2ProviderFromPublicConfig as Ni, BinaryStorageStatResult as Nn, ExecutionTelemetryFactory as Nr, NodeConfigBase as Nt, RunCurrentState as O, CredentialType as Oi, RetryPolicySpec as On, WebhookTriggerResolution as Or, JsonObject as Ot, RunStateResetRequest as P, NoOpPollingTriggerLogger as Pi, BinaryStorageWriteRequest as Pn, NodeExecutionTelemetry as Pr, NodeDefinition as Pt, inject as Q, NodeExecutionRequest as Qn, NoOpTelemetryArtifactReference as Qr, RunIdFactory as Qt, RunTestContext as R, NodeConnectionName as Ri, ExecutableTriggerNode as Rn, TelemetryAttributes as Rr, NodeIdRef as Rt, PersistedRunState as S, CredentialOAuth2ScopesFromPublicConfig as Si, runnableNodeOutputType as Sn, WorkflowSnapshotResolver as Sr, ExecutionMode as St, PersistedWorkflowTokenRegistryLike as T, CredentialSessionFactoryArgs as Ti, ExponentialRetryPolicySpec as Tn, WebhookControlSignal as Tr, Items as Tt, Container as U, LiveWorkflowRepository as Un, TelemetrySpanEventRecord as Ur, NodeOutputs as Ut, WorkflowExecutionPruneRepository as V, PersistedTokenId as Vi, ExecutionContextFactory as Vn, TelemetryScope as Vr, NodeKind as Vt, DependencyContainer$1 as W, MultiInputNode as Wn, TelemetrySpanScope as Wr, NodeRef as Wt, container as X, NodeBinaryAttachmentService as Xn, NoOpNodeExecutionTelemetry as Xr, RunDataSnapshot as Xt, TypeToken as Y, NodeActivationScheduler as Yn, NoOpExecutionTelemetry as Yr, RunDataFactory as Yt, delay as Z, NodeExecutionContext as Zn, NoOpTelemetrySpanScope as Zr, RunId as Zt, PendingNodeExecution as _, CredentialInstanceId as _i, WorkflowStoragePolicyResolver as _n, WorkflowNodeInstanceFactory as _r, TestTriggerSetupContext as _t, AgentMcpToolMap as a, CostTrackingUsageRecord as ai, UpstreamRefPlaceholder as an, PollingTriggerHandle as ar, singleton as at, PersistedRunControlState as b, CredentialMaterialSourceKind as bi, nodeRef as bn, WorkflowRunnerService as br, BinaryPreviewKind as bt, ConnectionInvocationId as c, AnyCredentialType as ci, WorkflowErrorHandler as cn, RunnableNodeExecuteArgs as cr, EngineExecutionLimitsPolicy as ct, EngineRunCounters as d, CredentialBinding as di, WorkflowGraphFactory as dn, TriggerNode as dr, RunEventBus as dt, CostTrackingPriceQuote as ei, RunnableNodeInputJson as en, NodeExecutionScheduler as er, injectable as et, ExecutionFrontierPlan as f, CredentialBindingKey as fi, WorkflowNodeConnection as fn, TriggerRuntimeDiagnostics as fr, RunEventSubscription as ft, NodeInputsByPort as g, CredentialHealthTester as gi, WorkflowStoragePolicyMode as gn, TriggerTestItemsContext as gr, TestTriggerNodeConfig as gt, NodeExecutionStatus as h, CredentialHealthStatus as hi, WorkflowStoragePolicyDecisionArgs as hn, TriggerSetupStateRepository as hr, TestSuiteRunId as ht, AgentMcpIntegration as i, CostTrackingTelemetryMetricNames as ii, TriggerNodeSetupState as in, PersistedTriggerSetupState as ir, registry as it, RunPruneCandidate as j, CredentialTypeRegistry as ji, BinaryStorage as jn, WorkflowActivationPolicy as jr, MutableRunData as jt, RunEventPublisherDeps as k, CredentialTypeDefinition as ki, BinaryAttachmentCreateRequest as kn, WebhookTriggerRoutingDiagnostics as kr, JsonPrimitive as kt, ConnectionInvocationRecord as l, CredentialAdvancedSectionPresentation as li, WorkflowErrorHandlerSpec as ln, TestableTriggerNode as lr, EngineExecutionLimitsPolicyConfig as lt, NodeExecutionSnapshot as m, CredentialHealth as mi, WorkflowPrunePolicySpec as mn, TriggerSetupStateFor as mr, TestSuiteRunStatus as mt, InMemoryLiveWorkflowRepository as n, CostTrackingTelemetryAttributeNames as ni, TriggerNodeConfig as nn, NodeExecutor as nr, instancePerContainerCachingFactory as nt, NeedsReconsentEvent as o, CollectionStore as oi, WorkflowDefinition as on, PreparedNodeActivationDispatch as or, CoreTokens as ot, NodeExecutionError as p, CredentialFieldSchema as pi, WorkflowPolicyRuntimeDefaults as pn, TriggerSetupContext as pr, TestCaseRunStatus as pt, Lifecycle as q, NodeActivationRequest as qn, CodemationTelemetryAttributeNames as qr, ParentExecutionRef as qt, Engine as r, CostTrackingTelemetryFactory as ri, TriggerNodeOutputJson as rn, NodeResolver as rr, predicateAwareClassFactory as rt, ConnectionInvocationAppendArgs as s, CollectionsContext as si, WorkflowErrorContext as sn, RunnableNode as sr, ENGINE_EXECUTION_LIMITS_DEFAULTS as st, RunIntentService as t, CostTrackingTelemetry as ti, RunnableNodeOutputJson as tn, NodeExecutionStatePublisher as tr, instanceCachingFactory as tt, CurrentStateExecutionRequest as u, CredentialAuthDefinition as ui, WorkflowGraph as un, TriggerCleanupHandle as ur, RunEvent as ut, PersistedMutableNodeState as v, CredentialInstanceRecord as vi, WorkflowStoragePolicySpec as vn, WorkflowRepository as vr, ActivationIdFactory as vt, PersistedWorkflowSnapshotNode as w, CredentialSessionFactory as wi, triggerNodeSetupStateType as wn, TriggerInstanceId as wr, ItemBinary as wt, PersistedRunSchedulingState as x, CredentialOAuth2AuthDefinition as xi, runnableNodeInputType as xn, WorkflowSnapshotFactory as xr, Edge as xt, PersistedMutableRunState as y, CredentialJsonRecord as yi, branchRef as yn, WorkflowRunnerResolver as yr, BinaryAttachment as yt, WebhookRunResult as z, NodeId as zi, ExecutionBinaryService as zn, TelemetryChildSpanStart as zr, NodeInspectorSummaryRow as zt };
2152
+ //# sourceMappingURL=RunIntentService-MUHJ1bhO.d.cts.map