@codemation/core 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -0
- package/dist/{CostCatalogContract-B9aYIqJu.d.cts → CostCatalogContract-Dwo-ZamG.d.cts} +2 -2
- package/dist/EngineRuntimeRegistration.types-BiNasx3G.d.cts +54 -0
- package/dist/EngineRuntimeRegistration.types-Dq4ucrdo.d.ts +21 -0
- package/dist/{InMemoryRunDataFactory-C3rIszrW.d.cts → InMemoryRunDataFactory-D2U9azmZ.d.cts} +2 -20
- package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs.map → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs.map} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js → InMemoryRunEventBusRegistry-Layt2xgm.js} +1 -1
- package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js.map → InMemoryRunEventBusRegistry-Layt2xgm.js.map} +1 -1
- package/dist/{ItemsInputNormalizer-UCpn7luX.d.cts → ItemsInputNormalizer-A5txcOWX.d.cts} +3 -98
- package/dist/{ItemsInputNormalizer-B9SdLG24.cjs → ItemsInputNormalizer-C1fv3sMW.cjs} +2 -2
- package/dist/ItemsInputNormalizer-C1fv3sMW.cjs.map +1 -0
- package/dist/{ItemsInputNormalizer-DoOawd9R.d.ts → ItemsInputNormalizer-D2vrMrX1.d.ts} +2 -62
- package/dist/{ItemsInputNormalizer-CZEODg94.js → ItemsInputNormalizer-fUYo4GLV.js} +2 -2
- package/dist/ItemsInputNormalizer-fUYo4GLV.js.map +1 -0
- package/dist/{RunIntentService-0f3ICjAz.d.cts → RunIntentService-DKxuHTUz.d.cts} +2 -15
- package/dist/{RunIntentService-Dx_HHxDX.d.ts → RunIntentService-DrpKli2k.d.ts} +2 -22
- package/dist/{agentMcpTypes-B11B3Hd-.d.cts → agentMcpTypes-BHX4RQCC.d.cts} +24 -524
- package/dist/bootstrap/index.cjs +9 -5
- package/dist/bootstrap/index.d.cts +32 -106
- package/dist/bootstrap/index.d.ts +18 -17
- package/dist/bootstrap/index.js +6 -5
- package/dist/{bootstrap-Be0LB0nh.cjs → bootstrap-CTB53rEF.cjs} +9 -60
- package/dist/bootstrap-CTB53rEF.cjs.map +1 -0
- package/dist/{bootstrap-pSQdsMfa.js → bootstrap-DmqKheCI.js} +6 -57
- package/dist/bootstrap-DmqKheCI.js.map +1 -0
- package/dist/browser.cjs +12 -11
- package/dist/browser.d.cts +4 -4
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +3 -2
- package/dist/contracts-7L1wJHdk.cjs +569 -0
- package/dist/contracts-7L1wJHdk.cjs.map +1 -0
- package/dist/contracts-CjJ5CZ7N.js +447 -0
- package/dist/contracts-CjJ5CZ7N.js.map +1 -0
- package/dist/contracts.cjs +9 -2
- package/dist/contracts.d.cts +5 -5
- package/dist/contracts.d.ts +2 -2
- package/dist/contracts.js +3 -2
- package/dist/{executionPersistenceContracts-CX9Ql8N1.d.cts → deploymentManifestTypes-B8CDmZZK.d.cts} +65 -81
- package/dist/di-C6Ubf9o5.cjs +179 -0
- package/dist/di-C6Ubf9o5.cjs.map +1 -0
- package/dist/di-Cjiil7U-.js +114 -0
- package/dist/di-Cjiil7U-.js.map +1 -0
- package/dist/{index-CbJdbIHe.d.ts → index-CRv3_pY3.d.ts} +87 -870
- package/dist/{index-uPnD9EE6.d.ts → index-mnLS0iQl.d.ts} +27 -400
- package/dist/index.cjs +44 -115
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -524
- package/dist/index.d.ts +5 -5
- package/dist/index.js +21 -98
- package/dist/index.js.map +1 -1
- package/dist/{params-Dwl10Ws9.d.cts → params-CrK4iuG1.d.cts} +2 -11
- package/dist/{runtime-CSunvf7A.js → runtime-CBFDpmiz.js} +46 -679
- package/dist/runtime-CBFDpmiz.js.map +1 -0
- package/dist/{runtime-n2tqRwaf.cjs → runtime-Due-FOZ2.cjs} +69 -752
- package/dist/runtime-Due-FOZ2.cjs.map +1 -0
- package/dist/testing.cjs +8 -40
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +3 -32
- package/dist/testing.d.ts +3 -32
- package/dist/testing.js +6 -38
- package/dist/testing.js.map +1 -1
- package/dist/{di-DhwtDRgs.cjs → workflowTypes-BW6Hhee7.cjs} +4 -229
- package/dist/workflowTypes-BW6Hhee7.cjs.map +1 -0
- package/dist/{di-CEV6wTc4.js → workflowTypes-DZtBTmKf.js} +3 -162
- package/dist/workflowTypes-DZtBTmKf.js.map +1 -0
- package/package.json +1 -1
- package/src/ai/AgentConnectionNodeCollector.ts +0 -4
- package/src/ai/AgentMessageConfigNormalizerFactory.ts +0 -4
- package/src/ai/AiHost.ts +0 -38
- package/src/ai/CallableToolConfig.ts +0 -9
- package/src/ai/CallableToolKindToken.ts +0 -4
- package/src/authoring/callableTool.types.ts +0 -3
- package/src/authoring/defineCollection.types.ts +0 -11
- package/src/authoring/defineHumanApprovalNode.types.ts +0 -116
- package/src/authoring/defineNode.types.ts +0 -25
- package/src/authoring/definePollingTrigger.types.ts +18 -152
- package/src/authoring/definePollingTriggerInternals.ts +0 -4
- package/src/authoring/nodeBaseOptions.types.ts +0 -14
- package/src/binaries/boundedReadBinary.types.ts +0 -16
- package/src/bootstrap/index.ts +8 -2
- package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +0 -5
- package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +0 -23
- package/src/browser.ts +0 -3
- package/src/contracts/AgentBindError.ts +0 -5
- package/src/contracts/Clock.ts +0 -1
- package/src/contracts/CodemationTelemetryAttributeNames.ts +0 -10
- package/src/contracts/NoOpAgentMcpIntegration.ts +0 -6
- package/src/contracts/NoOpTelemetrySpanScope.ts +0 -7
- package/src/contracts/RetryPolicy.ts +0 -2
- package/src/contracts/agentMcpTypes.ts +0 -34
- package/src/contracts/assertionTypes.ts +0 -33
- package/src/contracts/baseTypes.ts +0 -6
- package/src/contracts/collectionTypes.ts +0 -25
- package/src/contracts/credentialTypes.ts +13 -60
- package/src/contracts/deploymentManifestTypes.ts +158 -0
- package/src/contracts/dispatchTypes.ts +29 -0
- package/src/contracts/executionPersistenceContracts.ts +0 -33
- package/src/contracts/hitlSeamTypes.ts +0 -14
- package/src/contracts/humanTaskStoreTypes.ts +0 -2
- package/src/contracts/inboxChannelTypes.ts +0 -9
- package/src/contracts/index.ts +3 -0
- package/src/contracts/itemExpr.ts +0 -18
- package/src/contracts/itemMeta.ts +0 -3
- package/src/contracts/mcpTypes.ts +0 -16
- package/src/contracts/retryPolicySpec.types.ts +0 -10
- package/src/contracts/runFinishedAtFactory.ts +0 -1
- package/src/contracts/runTypes.ts +0 -74
- package/src/contracts/runtimeTypes.ts +4 -131
- package/src/contracts/telemetryTypes.ts +0 -7
- package/src/contracts/testTriggerTypes.ts +0 -43
- package/src/contracts/triggerInvokerTypes.ts +6 -0
- package/src/contracts/webhookTypes.ts +0 -8
- package/src/contracts/workflowActivationPolicy.ts +0 -5
- package/src/contracts/workflowTypes.ts +4 -86
- package/src/contracts/workspaceFileTypes.ts +0 -72
- package/src/contracts.ts +18 -10
- package/src/credentials/CredentialMaterialProvider.types.ts +0 -28
- package/src/credentials/ManagedCredentialMaterialWriteError.ts +0 -6
- package/src/credentials/ManagedMaterialFetchError.ts +0 -6
- package/src/credentials/OAuthFlowExecutor.types.ts +0 -15
- package/src/di/CoreTokens.ts +2 -6
- package/src/events/ConnectionInvocationEventPublisher.ts +0 -7
- package/src/events/NodeEventPublisher.ts +0 -1
- package/src/events/runEvents.ts +0 -8
- package/src/execution/ActivationEnqueueService.ts +0 -10
- package/src/execution/ChildExecutionScopeFactory.ts +0 -13
- package/src/execution/FanInMergeByOriginMerger.ts +0 -11
- package/src/execution/InProcessRetryRunner.ts +0 -1
- package/src/execution/ItemExprResolver.ts +0 -3
- package/src/execution/NodeActivationRequestComposer.ts +0 -3
- package/src/execution/NodeActivationRequestInputPreparer.ts +0 -5
- package/src/execution/NodeExecutionSnapshotFactory.ts +0 -1
- package/src/execution/NodeExecutor.ts +1 -17
- package/src/execution/NodeSuspensionHandler.ts +1 -39
- package/src/execution/PersistedRunStateTerminalBuilder.ts +0 -5
- package/src/execution/RunSuspendedError.ts +0 -10
- package/src/execution/WorkflowRunExecutionContextFactory.ts +0 -3
- package/src/orchestration/AbortControllerFactory.ts +0 -4
- package/src/orchestration/Engine.ts +0 -9
- package/src/orchestration/NodeExecutionRequestHandlerService.ts +3 -4
- package/src/orchestration/RunContinuationService.ts +7 -39
- package/src/orchestration/RunStartService.ts +0 -7
- package/src/orchestration/TestSuiteOrchestrator.ts +0 -18
- package/src/orchestration/TestSuiteRunIdFactory.ts +0 -4
- package/src/orchestration/TriggerRuntimeService.ts +3 -2
- package/src/planning/CurrentStateFrontierPlanner.ts +0 -1
- package/src/planning/RunQueuePlanner.ts +0 -6
- package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +0 -8
- package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +0 -3
- package/src/runStorage/RunSummaryMapper.ts +0 -1
- package/src/runtime/EngineFactory.ts +6 -11
- package/src/runtime/RunIntentService.ts +0 -4
- package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +0 -4
- package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +0 -4
- package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +0 -4
- package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +0 -1
- package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +0 -4
- package/src/runtime-types/runtimeTypeDecorators.types.ts +0 -12
- package/src/scheduler/ConfigDrivenOffloadPolicy.ts +0 -1
- package/src/scheduler/DefaultDrivingScheduler.ts +0 -6
- package/src/scheduler/InlineDrivingScheduler.ts +0 -13
- package/src/serialization/ItemsInputNormalizer.ts +0 -5
- package/src/testing/CapturingScheduler.ts +0 -3
- package/src/testing/EngineTestKitRunIdFactory.ts +0 -3
- package/src/testing/ItemHarnessNode.ts +0 -3
- package/src/testing/ItemHarnessNodeConfig.ts +0 -4
- package/src/testing/PrefixedSequentialIdGenerator.ts +0 -3
- package/src/testing/RegistrarEngineTestKit.types.ts +0 -2
- package/src/testing/RejectingCredentialSessionService.ts +0 -4
- package/src/testing/SubWorkflowRunnerTestNode.ts +0 -3
- package/src/testing/WorkflowTestHarnessManualTrigger.ts +0 -3
- package/src/testing/WorkflowTestKitBuilder.ts +0 -4
- package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +0 -3
- package/src/testing.ts +0 -3
- package/src/triggers/polling/PollingTriggerDedupWindow.ts +0 -4
- package/src/triggers/polling/PollingTriggerLogger.ts +0 -5
- package/src/triggers/polling/PollingTriggerRuntime.ts +0 -5
- package/src/types/index.ts +0 -6
- package/src/validation/WorkflowEdgePortValidator.ts +0 -5
- package/src/workflow/definition/ConnectionInvocationIdFactory.ts +0 -7
- package/src/workflow/definition/ConnectionNodeIdFactory.ts +0 -6
- package/src/workflow/definition/NodeIterationIdFactory.ts +0 -13
- package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +0 -6
- package/src/workflow/dsl/ChainCursorResolver.ts +0 -20
- package/src/workflow/dsl/NodeIdSlugifier.ts +0 -9
- package/src/workflow/dsl/WhenBuilder.ts +0 -17
- package/src/workflow/dsl/WorkflowDefinitionError.ts +0 -9
- package/src/workflow/dsl/workflowBuilderTypes.ts +0 -24
- package/src/workflowSnapshots/MissingRuntimeParityGuard.ts +24 -0
- package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +0 -6
- package/src/workflowSnapshots/WorkflowParityMismatchError.ts +18 -0
- package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +0 -5
- package/src/workflowSnapshots/index.ts +3 -0
- package/dist/EngineRuntimeRegistration.types-BYAmGMdS.d.cts +0 -81
- package/dist/EngineRuntimeRegistration.types-CVLI8DsJ.d.ts +0 -44
- package/dist/ItemsInputNormalizer-B9SdLG24.cjs.map +0 -1
- package/dist/ItemsInputNormalizer-CZEODg94.js.map +0 -1
- package/dist/bootstrap-Be0LB0nh.cjs.map +0 -1
- package/dist/bootstrap-pSQdsMfa.js.map +0 -1
- package/dist/contracts-CK0x6w_G.cjs +0 -74
- package/dist/contracts-CK0x6w_G.cjs.map +0 -1
- package/dist/contracts-DXdfTdpW.js +0 -50
- package/dist/contracts-DXdfTdpW.js.map +0 -1
- package/dist/di-CEV6wTc4.js.map +0 -1
- package/dist/di-DhwtDRgs.cjs.map +0 -1
- package/dist/runtime-CSunvf7A.js.map +0 -1
- package/dist/runtime-n2tqRwaf.cjs.map +0 -1
|
@@ -15,69 +15,27 @@ import { SuspensionRequest } from "../contracts/runtimeTypes";
|
|
|
15
15
|
import { defineNode } from "./defineNode.types";
|
|
16
16
|
import type { DefinedNode } from "./defineNode.types";
|
|
17
17
|
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Public types
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Decision shape merged into `item.json` after a HITL approval task resolves.
|
|
24
|
-
*
|
|
25
|
-
* - `"approved"` / `"rejected"` — from a human decision (uses `approvedPredicate`).
|
|
26
|
-
* - `"timed-out"` — timeout fired with `onTimeout: "halt"`.
|
|
27
|
-
* - `"auto-accepted"` — timeout fired with `onTimeout: "auto-accept"`.
|
|
28
|
-
*/
|
|
29
18
|
export interface HumanApprovalDecisionResult {
|
|
30
19
|
readonly status: "approved" | "rejected" | "timed-out" | "auto-accepted";
|
|
31
|
-
/** Identity of the person who decided; absent for automated outcomes. */
|
|
32
20
|
readonly actor?: HumanTaskActor;
|
|
33
|
-
/** ISO 8601 timestamp of the decision. */
|
|
34
21
|
readonly decidedAt?: Date;
|
|
35
|
-
/** Optional free-text note from the reviewer. */
|
|
36
22
|
readonly note?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Full raw decision payload (only present for `"approved"` / `"rejected"`).
|
|
39
|
-
* Shape is determined by the channel's `decisionSchema`.
|
|
40
|
-
*/
|
|
41
23
|
readonly payload?: Record<string, unknown>;
|
|
42
24
|
}
|
|
43
25
|
|
|
44
|
-
/**
|
|
45
|
-
* Output item shape emitted by a `defineHumanApprovalNode`-based node.
|
|
46
|
-
* Original `item.json` fields are preserved and `decision` is merged in.
|
|
47
|
-
* If the input `item.json` already contained a `decision` key it is **overwritten**.
|
|
48
|
-
*/
|
|
49
26
|
export type HumanApprovalOutputJson<TInputJson extends Record<string, unknown>> = TInputJson & {
|
|
50
27
|
readonly decision: HumanApprovalDecisionResult;
|
|
51
28
|
};
|
|
52
29
|
|
|
53
|
-
/**
|
|
54
|
-
* Extends {@link DefinedNode} with the `humanApprovalToolBehavior` metadata marker.
|
|
55
|
-
* Story 10 reads this field when attaching the node as an agent tool.
|
|
56
|
-
*/
|
|
57
30
|
export interface DefinedHumanApprovalNode<
|
|
58
31
|
TKey extends string,
|
|
59
32
|
TConfig extends CredentialJsonRecord,
|
|
60
33
|
TInputJson extends Record<string, unknown>,
|
|
61
34
|
TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
|
|
62
35
|
> extends DefinedNode<TKey, TConfig, TInputJson, HumanApprovalOutputJson<TInputJson>, TBindings> {
|
|
63
|
-
/**
|
|
64
|
-
* Behavior hint consumed by the agent runtime (story 10) when this node is attached as a tool.
|
|
65
|
-
* `"return"` (default) — return the rejection to the agent as a tool result.
|
|
66
|
-
* `"halt"` — halt the agent run on rejection.
|
|
67
|
-
*
|
|
68
|
-
* Standalone DSL usage ignores this field.
|
|
69
|
-
*/
|
|
70
36
|
readonly humanApprovalToolBehavior: { onRejected: "return" | "halt" };
|
|
71
37
|
}
|
|
72
38
|
|
|
73
|
-
// ---------------------------------------------------------------------------
|
|
74
|
-
// isHumanApprovalNode predicate
|
|
75
|
-
// ---------------------------------------------------------------------------
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Returns `true` when `node` was created by {@link defineHumanApprovalNode}.
|
|
79
|
-
* Uses the `humanApprovalToolBehavior` typed field as the discriminant.
|
|
80
|
-
*/
|
|
81
39
|
export function isHumanApprovalNode(
|
|
82
40
|
node: unknown,
|
|
83
41
|
): node is DefinedHumanApprovalNode<string, Record<string, unknown>, Record<string, unknown>, undefined> {
|
|
@@ -89,57 +47,6 @@ export function isHumanApprovalNode(
|
|
|
89
47
|
);
|
|
90
48
|
}
|
|
91
49
|
|
|
92
|
-
// ---------------------------------------------------------------------------
|
|
93
|
-
// defineHumanApprovalNode
|
|
94
|
-
// ---------------------------------------------------------------------------
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Authoring helper that compiles a HITL approval channel down to a regular
|
|
98
|
-
* {@link defineNode}-backed node with `SuspensionRequest` semantics.
|
|
99
|
-
*
|
|
100
|
-
* **Fast-forward decision semantics:**
|
|
101
|
-
* - On the first `execute` call (no `ctx.resumeContext`): throws a `SuspensionRequest`
|
|
102
|
-
* that calls the author's `deliver`. The engine persists the suspension and continues.
|
|
103
|
-
* - On resume (`ctx.resumeContext` set): calls `onDecision`/`onTimeout` as appropriate,
|
|
104
|
-
* merges a `decision` key into `item.json`, and returns an item with the original
|
|
105
|
-
* `binary` map passed by reference (no copy).
|
|
106
|
-
*
|
|
107
|
-
* **Output shape per item:**
|
|
108
|
-
* ```ts
|
|
109
|
-
* // Input: { json: { invoiceId: 42 }, binary?: {...} }
|
|
110
|
-
* // Output: { json: { invoiceId: 42, decision: { status: "approved", actor, decidedAt } }, binary: <unchanged> }
|
|
111
|
-
* ```
|
|
112
|
-
* If `item.json` already has a `decision` key it is **overwritten**. Namespace as
|
|
113
|
-
* needed if your schema reserves that key for another purpose.
|
|
114
|
-
*
|
|
115
|
-
* **Predicate persistence:**
|
|
116
|
-
* The `approvedPredicate` function is NOT serialized to the suspension record (except
|
|
117
|
-
* as an audit-only string via `toString()`). On resume, the workflow definition is
|
|
118
|
-
* reloaded from code at process start and the predicate closure is rebuilt naturally.
|
|
119
|
-
* If a deploy ships a changed predicate between suspend and resume, the *new* predicate
|
|
120
|
-
* runs — document this in your runbook when the predicate carries business logic that
|
|
121
|
-
* may change across deploys.
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* ```ts
|
|
125
|
-
* export const slackApprovalNode = defineHumanApprovalNode({
|
|
126
|
-
* key: "my-plugin.slackApproval",
|
|
127
|
-
* title: "Slack Approval",
|
|
128
|
-
* channel: "slack",
|
|
129
|
-
* configSchema: z.object({ channel: z.string(), message: z.string() }),
|
|
130
|
-
* decisionSchema: z.object({ approved: z.boolean(), note: z.string().optional() }),
|
|
131
|
-
*
|
|
132
|
-
* async deliver({ task, config, item }, ctx) {
|
|
133
|
-
* const ts = await postSlackMessage(config.channel, `Approve? <${task.resumeUrl}>`);
|
|
134
|
-
* return { channel: config.channel, ts };
|
|
135
|
-
* },
|
|
136
|
-
*
|
|
137
|
-
* async onDecision({ decision, actor, delivery }, ctx) {
|
|
138
|
-
* await updateSlackMessage(delivery.channel, delivery.ts, decision.approved ? "✅" : "❌");
|
|
139
|
-
* },
|
|
140
|
-
* });
|
|
141
|
-
* ```
|
|
142
|
-
*/
|
|
143
50
|
export function defineHumanApprovalNode<
|
|
144
51
|
TKey extends string,
|
|
145
52
|
TConfig extends CredentialJsonRecord,
|
|
@@ -159,16 +66,8 @@ export function defineHumanApprovalNode<
|
|
|
159
66
|
decisionSchema: ZodType<TDecision>;
|
|
160
67
|
credentials?: TBindings;
|
|
161
68
|
|
|
162
|
-
/**
|
|
163
|
-
* Custom predicate that decides whether a decision counts as "approved".
|
|
164
|
-
* When omitted, the helper checks if `decisionSchema` is a Zod object with an
|
|
165
|
-
* `approved: boolean` field; if so it uses `decision.approved === true`.
|
|
166
|
-
* If neither holds, `defineHumanApprovalNode` throws at **definition time** (not runtime).
|
|
167
|
-
*/
|
|
168
69
|
approvedPredicate?: (decision: TDecision) => boolean;
|
|
169
|
-
/** Default suspension timeout. Defaults to `"24h"`. */
|
|
170
70
|
defaultTimeout?: Duration;
|
|
171
|
-
/** What to do when the task times out. Defaults to `"halt"`. */
|
|
172
71
|
defaultOnTimeout?: "halt" | "auto-accept";
|
|
173
72
|
|
|
174
73
|
inspectorSummary?: (config: TConfig) => ReadonlyArray<NodeInspectorSummaryRow> | undefined;
|
|
@@ -204,16 +103,11 @@ export function defineHumanApprovalNode<
|
|
|
204
103
|
ctx: ExecutionContext,
|
|
205
104
|
) => Promise<void>;
|
|
206
105
|
}): DefinedHumanApprovalNode<TKey, TConfig, TInputJson, TBindings> {
|
|
207
|
-
// Resolve the approved predicate at definition time so we throw early when
|
|
208
|
-
// the schema is ambiguous.
|
|
209
106
|
const resolvedPredicate = resolveApprovedPredicate(opts.decisionSchema, opts.approvedPredicate);
|
|
210
107
|
|
|
211
108
|
const timeout = opts.defaultTimeout ?? "24h";
|
|
212
109
|
const onTimeout = opts.defaultOnTimeout ?? "halt";
|
|
213
110
|
|
|
214
|
-
// TOutputJson is `unknown` here because `execute` returns an Item-shaped object
|
|
215
|
-
// that the engine's NodeOutputNormalizer converts to the proper output. The public
|
|
216
|
-
// interface's DefinedHumanApprovalNode carries the correct output type for DSL use.
|
|
217
111
|
const inner = defineNode<TKey, TConfig, TInputJson, unknown, TBindings>({
|
|
218
112
|
key: opts.key,
|
|
219
113
|
title: opts.title,
|
|
@@ -226,7 +120,6 @@ export function defineHumanApprovalNode<
|
|
|
226
120
|
|
|
227
121
|
async execute(args, { config, execution: ctx }) {
|
|
228
122
|
if (!ctx.resumeContext) {
|
|
229
|
-
// First pass — suspend.
|
|
230
123
|
const subject = buildSubject(opts.title, args.item, ctx);
|
|
231
124
|
throw new SuspensionRequest({
|
|
232
125
|
decisionSchema: opts.decisionSchema,
|
|
@@ -236,7 +129,6 @@ export function defineHumanApprovalNode<
|
|
|
236
129
|
metadata: {
|
|
237
130
|
channel: opts.channel,
|
|
238
131
|
nodeKey: opts.key,
|
|
239
|
-
// Stored for audit only; never re-evaluated. See JSDoc on defineHumanApprovalNode.
|
|
240
132
|
approvedPredicateSource: opts.approvedPredicate?.toString() ?? null,
|
|
241
133
|
},
|
|
242
134
|
deliver: (handle: HumanTaskHandle) =>
|
|
@@ -252,7 +144,6 @@ export function defineHumanApprovalNode<
|
|
|
252
144
|
});
|
|
253
145
|
}
|
|
254
146
|
|
|
255
|
-
// Resume pass.
|
|
256
147
|
return await handleResume(
|
|
257
148
|
args.item,
|
|
258
149
|
ctx.resumeContext,
|
|
@@ -270,10 +161,6 @@ export function defineHumanApprovalNode<
|
|
|
270
161
|
}) as unknown as DefinedHumanApprovalNode<TKey, TConfig, TInputJson, TBindings>;
|
|
271
162
|
}
|
|
272
163
|
|
|
273
|
-
// ---------------------------------------------------------------------------
|
|
274
|
-
// Internal helpers (module-private)
|
|
275
|
-
// ---------------------------------------------------------------------------
|
|
276
|
-
|
|
277
164
|
function resolveApprovedPredicate<TDecision extends Record<string, unknown>>(
|
|
278
165
|
schema: ZodType<TDecision>,
|
|
279
166
|
predicate: ((d: TDecision) => boolean) | undefined,
|
|
@@ -281,7 +168,6 @@ function resolveApprovedPredicate<TDecision extends Record<string, unknown>>(
|
|
|
281
168
|
if (predicate) {
|
|
282
169
|
return predicate;
|
|
283
170
|
}
|
|
284
|
-
// Zod 4: ZodObject exposes `.shape` directly as an object (not a function).
|
|
285
171
|
const shape = (schema as unknown as ZodObject<Record<string, ZodType>>).shape;
|
|
286
172
|
if (shape && typeof shape === "object" && "approved" in shape) {
|
|
287
173
|
return (d) => (d as { approved?: unknown }).approved === true;
|
|
@@ -310,7 +196,6 @@ function mergeDecision(
|
|
|
310
196
|
): { json: Record<string, unknown>; binary: Item["binary"]; meta: Item["meta"] } {
|
|
311
197
|
return {
|
|
312
198
|
json: { ...(item.json as Record<string, unknown>), decision },
|
|
313
|
-
// binary is passed by reference — no copy. See defineHumanApprovalNode JSDoc.
|
|
314
199
|
binary: item.binary,
|
|
315
200
|
meta: item.meta,
|
|
316
201
|
};
|
|
@@ -355,7 +240,6 @@ async function handleResume<TDecision extends Record<string, unknown>, TDelivery
|
|
|
355
240
|
return mergeDecision(item, { status, decidedAt: dec.at });
|
|
356
241
|
}
|
|
357
242
|
|
|
358
|
-
// dec.kind === "decided"
|
|
359
243
|
const parsed = decisionSchema.parse(dec.value);
|
|
360
244
|
await onDecision?.(
|
|
361
245
|
{
|
|
@@ -57,10 +57,6 @@ export interface DefinedNodeRunContext<
|
|
|
57
57
|
readonly execution: NodeExecutionContext<RunnableNodeConfig<TConfig, unknown>>;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/**
|
|
61
|
-
* Arguments for {@link defineNode} `execute` (engine `ctx` matches {@link RunnableNode.execute};
|
|
62
|
-
* the second callback parameter adds {@link DefinedNodeRunContext} for credential accessors).
|
|
63
|
-
*/
|
|
64
60
|
export type DefineNodeExecuteArgs<TConfig extends CredentialJsonRecord, TInputJson> = Readonly<{
|
|
65
61
|
input: TInputJson;
|
|
66
62
|
item: Item;
|
|
@@ -93,9 +89,6 @@ export interface DefinedNode<
|
|
|
93
89
|
register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;
|
|
94
90
|
}
|
|
95
91
|
|
|
96
|
-
/**
|
|
97
|
-
* Plugin / DSL-friendly node: per-item `execute` with optional {@link RunnableNodeConfig.inputSchema}.
|
|
98
|
-
*/
|
|
99
92
|
export interface DefineNodeOptions<
|
|
100
93
|
TKey extends string,
|
|
101
94
|
TConfig extends CredentialJsonRecord,
|
|
@@ -106,27 +99,12 @@ export interface DefineNodeOptions<
|
|
|
106
99
|
readonly key: TKey;
|
|
107
100
|
readonly title: string;
|
|
108
101
|
readonly description?: string;
|
|
109
|
-
/**
|
|
110
|
-
* Canvas icon for this node (same contract as `NodeConfigBase.icon` on runnable configs).
|
|
111
|
-
* The Next host resolves Lucide (`lucide:…`), built-in SVGs (`builtin:…`), Simple Icons (`si:…`), and image URLs (`https:`, `data:`, `/…`).
|
|
112
|
-
*/
|
|
113
102
|
readonly icon?: string;
|
|
114
|
-
/** Default values / form hints for **static** node configuration (credentials, retry, IDs), not per-item payload. */
|
|
115
103
|
readonly input?: Readonly<Record<keyof TConfig & string, unknown>>;
|
|
116
104
|
readonly configSchema?: z.ZodType<TConfig>;
|
|
117
105
|
readonly credentials?: TBindings;
|
|
118
|
-
/**
|
|
119
|
-
* Validates **`input`** (engine also accepts `inputSchema` on the node class).
|
|
120
|
-
*/
|
|
121
106
|
readonly inputSchema?: ZodType<TInputJson>;
|
|
122
|
-
/** Preserve inbound `item.binary` when `execute` returns plain JSON or item-shaped results without `binary`. */
|
|
123
107
|
readonly keepBinaries?: boolean;
|
|
124
|
-
/**
|
|
125
|
-
* Static configuration summary surfaced in the workflow inspector — see
|
|
126
|
-
* {@link import("../contracts/workflowTypes").NodeConfigBase.inspectorSummary}.
|
|
127
|
-
*
|
|
128
|
-
* Receives the static config; returns 2–6 short label/value pairs (or `undefined` to skip).
|
|
129
|
-
*/
|
|
130
108
|
readonly inspectorSummary?: (
|
|
131
109
|
args: Readonly<{ config: TConfig }>,
|
|
132
110
|
) => ReadonlyArray<NodeInspectorSummaryRow> | undefined;
|
|
@@ -136,9 +114,6 @@ export interface DefineNodeOptions<
|
|
|
136
114
|
): MaybePromise<TOutputJson>;
|
|
137
115
|
}
|
|
138
116
|
|
|
139
|
-
/**
|
|
140
|
-
* Batch-oriented defined node: `run` receives all item JSON once (last item in activation); emits one output per input row.
|
|
141
|
-
*/
|
|
142
117
|
export interface DefineBatchNodeOptions<
|
|
143
118
|
TKey extends string,
|
|
144
119
|
TConfig extends CredentialJsonRecord,
|
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* definePollingTrigger — declarative helper for authoring polling triggers.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors the ergonomics of `defineNode` / `defineRestNode` / `defineCredential`.
|
|
5
|
-
* Plugin authors supply a `poll` function plus metadata; the helper synthesises the
|
|
6
|
-
* two internal classes (`DefinedPollingTriggerRuntime` + `DefinedPollingTriggerConfig`)
|
|
7
|
-
* that the engine's trigger machinery requires. Internal classes, DI annotations, and
|
|
8
|
-
* `PollingTriggerRuntime` wiring are hidden from the plugin-author surface entirely.
|
|
9
|
-
*/
|
|
10
1
|
import type {
|
|
11
2
|
Items,
|
|
3
|
+
JsonObject,
|
|
12
4
|
JsonValue,
|
|
13
5
|
NodeExecutionContext,
|
|
14
6
|
NodeInspectorSummaryRow,
|
|
15
7
|
NodeOutputs,
|
|
8
|
+
PollingTriggerConfig,
|
|
16
9
|
TestableTriggerNode,
|
|
17
10
|
TriggerNodeConfig,
|
|
18
11
|
TriggerSetupContext,
|
|
@@ -29,15 +22,8 @@ import {
|
|
|
29
22
|
} from "./definePollingTriggerInternals";
|
|
30
23
|
import type { ZodType } from "zod";
|
|
31
24
|
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
// Public types
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
|
|
36
25
|
type MaybePromise<TValue> = TValue | Promise<TValue>;
|
|
37
26
|
|
|
38
|
-
/**
|
|
39
|
-
* Context passed into the `poll` callback on each tick.
|
|
40
|
-
*/
|
|
41
27
|
export interface DefinePollingTriggerPollContext<
|
|
42
28
|
TConfig extends CredentialJsonRecord,
|
|
43
29
|
TState extends JsonValue | undefined,
|
|
@@ -48,36 +34,17 @@ export interface DefinePollingTriggerPollContext<
|
|
|
48
34
|
readonly credentials: DefinedNodeCredentialAccessors<TBindings>;
|
|
49
35
|
}
|
|
50
36
|
|
|
51
|
-
/**
|
|
52
|
-
* What `poll` must return each tick.
|
|
53
|
-
*/
|
|
54
37
|
export interface DefinePollingTriggerPollResult<TItemJson, TState extends JsonValue | undefined> {
|
|
55
|
-
/**
|
|
56
|
-
* New items to emit. Each item may carry an optional `dedupKey`; duplicate keys are
|
|
57
|
-
* filtered out against a rolling dedup window (managed internally by the runtime).
|
|
58
|
-
* Items without a `dedupKey` are always emitted.
|
|
59
|
-
*/
|
|
60
38
|
readonly items: ReadonlyArray<{ json: TItemJson; dedupKey?: string }>;
|
|
61
|
-
/** Persisted as the trigger's setup state for the next tick. */
|
|
62
39
|
readonly nextState: TState;
|
|
63
40
|
}
|
|
64
41
|
|
|
65
|
-
/**
|
|
66
|
-
* Context passed into the `execute` callback for post-emit enrichment (e.g. fetching
|
|
67
|
-
* attachment bytes). Mirrors `NodeExecutionContext` so plugin authors use familiar patterns.
|
|
68
|
-
*/
|
|
69
42
|
export type DefinePollingTriggerExecuteContext<TConfig extends TriggerNodeConfig<any, any>> =
|
|
70
43
|
NodeExecutionContext<TConfig>;
|
|
71
44
|
|
|
72
|
-
/**
|
|
73
|
-
* Context passed into the `testItems` callback.
|
|
74
|
-
*/
|
|
75
45
|
export type DefinePollingTriggerTestItemsContext<TConfig extends TriggerNodeConfig<any, any>> =
|
|
76
46
|
TriggerTestItemsContext<TConfig>;
|
|
77
47
|
|
|
78
|
-
/**
|
|
79
|
-
* Options accepted by `definePollingTrigger`.
|
|
80
|
-
*/
|
|
81
48
|
export interface DefinePollingTriggerOptions<
|
|
82
49
|
TKey extends string,
|
|
83
50
|
TConfig extends CredentialJsonRecord,
|
|
@@ -85,77 +52,30 @@ export interface DefinePollingTriggerOptions<
|
|
|
85
52
|
TState extends JsonValue | undefined,
|
|
86
53
|
TBindings extends DefinedNodeCredentialBindings | undefined = undefined,
|
|
87
54
|
> {
|
|
88
|
-
/**
|
|
89
|
-
* Unique node-token-id-style key, e.g. `"msgraph-mail.on-new-mail"`.
|
|
90
|
-
* Used as the persisted runtime type name — must be stable across deployments.
|
|
91
|
-
*/
|
|
92
55
|
readonly key: TKey;
|
|
56
|
+
readonly packageName?: string;
|
|
93
57
|
readonly title: string;
|
|
94
58
|
readonly description?: string;
|
|
95
|
-
/** Canvas icon (same contract as `NodeConfigBase.icon`). */
|
|
96
59
|
readonly icon?: string;
|
|
97
|
-
/**
|
|
98
|
-
* Zod schema for the trigger's user-facing configuration.
|
|
99
|
-
* When provided, the returned `create()` method is typed against the inferred config type.
|
|
100
|
-
*/
|
|
101
60
|
readonly configSchema?: ZodType<TConfig>;
|
|
102
|
-
/** Credential bindings keyed by slot (same format as `defineNode`). */
|
|
103
61
|
readonly credentials?: TBindings;
|
|
104
|
-
/**
|
|
105
|
-
* Static configuration summary surfaced in the workflow inspector — see
|
|
106
|
-
* {@link import("../contracts/workflowTypes").NodeConfigBase.inspectorSummary}.
|
|
107
|
-
*
|
|
108
|
-
* Receives the static config; returns 2–6 short label/value pairs (or `undefined` to skip).
|
|
109
|
-
*/
|
|
110
62
|
readonly inspectorSummary?: (
|
|
111
63
|
args: Readonly<{ config: TConfig }>,
|
|
112
64
|
) => ReadonlyArray<NodeInspectorSummaryRow> | undefined;
|
|
113
|
-
/**
|
|
114
|
-
* Called once when the trigger arms (or re-arms after a server restart) to provide the
|
|
115
|
-
* initial value for `state` when no persisted state exists.
|
|
116
|
-
*/
|
|
117
65
|
initialState?(): TState;
|
|
118
|
-
/**
|
|
119
|
-
* Polling interval in milliseconds. The runtime enforces a minimum of 25 ms.
|
|
120
|
-
* @default 60_000
|
|
121
|
-
*/
|
|
122
66
|
readonly pollIntervalMs?: number;
|
|
123
|
-
/**
|
|
124
|
-
* The per-tick poll logic. Called by the runtime each interval.
|
|
125
|
-
* Must return new items plus the next persisted state.
|
|
126
|
-
*/
|
|
127
67
|
poll(
|
|
128
68
|
pollCtx: DefinePollingTriggerPollContext<TConfig, TState, TBindings>,
|
|
129
69
|
): MaybePromise<DefinePollingTriggerPollResult<TItemJson, TState>>;
|
|
130
|
-
/**
|
|
131
|
-
* Optional post-emit enrichment step (runs in the normal node-execute phase after the
|
|
132
|
-
* trigger fires and the workflow run starts). Use for expensive per-item work such as
|
|
133
|
-
* fetching attachment bytes via `ctx.binary.attach`. When omitted, the trigger passes
|
|
134
|
-
* items through unchanged.
|
|
135
|
-
*/
|
|
136
70
|
execute?(
|
|
137
71
|
items: Items<TItemJson>,
|
|
138
72
|
ctx: NodeExecutionContext<DefinedPollingTriggerConfig<TConfig, TItemJson>>,
|
|
139
73
|
): MaybePromise<NodeOutputs>;
|
|
140
|
-
/**
|
|
141
|
-
* Optional implementation for the workflow UI's "Test" button. Should return a small
|
|
142
|
-
* sample of current items without consulting or mutating polling state.
|
|
143
|
-
*/
|
|
144
74
|
testItems?(
|
|
145
75
|
ctx: TriggerTestItemsContext<DefinedPollingTriggerConfig<TConfig, TItemJson>>,
|
|
146
76
|
): MaybePromise<Items<TItemJson>>;
|
|
147
77
|
}
|
|
148
78
|
|
|
149
|
-
// ---------------------------------------------------------------------------
|
|
150
|
-
// DefinedPollingTrigger (returned object)
|
|
151
|
-
// ---------------------------------------------------------------------------
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* The object returned by `definePollingTrigger`. Register it via
|
|
155
|
-
* `definePlugin({ nodes: [myTrigger] })` or call `.register(ctx)` directly.
|
|
156
|
-
*
|
|
157
|
-
* `poll` is also directly callable for unit-testing — no runtime needed.
|
|
158
|
-
*/
|
|
159
79
|
export interface DefinedPollingTrigger<
|
|
160
80
|
TKey extends string,
|
|
161
81
|
TConfig extends CredentialJsonRecord,
|
|
@@ -167,45 +87,22 @@ export interface DefinedPollingTrigger<
|
|
|
167
87
|
readonly key: TKey;
|
|
168
88
|
readonly title: string;
|
|
169
89
|
readonly description?: string;
|
|
170
|
-
/**
|
|
171
|
-
* Create the trigger config for use in workflow definitions.
|
|
172
|
-
* @param cfg - User-facing trigger configuration.
|
|
173
|
-
* @param name - Display name (defaults to `title`).
|
|
174
|
-
* @param idOrOptions - Optional stable node id, or `{ id?, description? }` authoring options
|
|
175
|
-
* (a bare string id still works — back-compat).
|
|
176
|
-
*/
|
|
177
90
|
create(
|
|
178
91
|
cfg: TConfig,
|
|
179
92
|
name?: string,
|
|
180
93
|
idOrOptions?: string | NodeBaseOptions,
|
|
181
94
|
): DefinedPollingTriggerConfig<TConfig, TItemJson>;
|
|
182
|
-
/**
|
|
183
|
-
* Test seam: call `poll` directly without starting the runtime.
|
|
184
|
-
* Returns `{ items, nextState }` just like the real runtime receives.
|
|
185
|
-
*/
|
|
186
95
|
poll(
|
|
187
96
|
pollCtx: Omit<DefinePollingTriggerPollContext<TConfig, TState, TBindings>, "credentials"> & {
|
|
188
97
|
credentials?: DefinedNodeCredentialAccessors<TBindings>;
|
|
189
98
|
},
|
|
190
99
|
): MaybePromise<DefinePollingTriggerPollResult<TItemJson, TState>>;
|
|
191
|
-
/** Registers the synthesised runtime class with the plugin container. */
|
|
192
100
|
register(context: { registerNode<TValue>(token: TypeToken<TValue>, implementation?: TypeToken<TValue>): void }): void;
|
|
193
101
|
}
|
|
194
102
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* TriggerNodeConfig produced by `DefinedPollingTrigger.create(...)`.
|
|
201
|
-
* Holds user configuration and credential requirements for the engine.
|
|
202
|
-
* The setup state type is opaque `JsonValue | undefined` — the runtime
|
|
203
|
-
* uses an internal wrapped shape that plugin authors never see.
|
|
204
|
-
*/
|
|
205
|
-
export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, TItemJson> implements TriggerNodeConfig<
|
|
206
|
-
TItemJson,
|
|
207
|
-
JsonValue | undefined
|
|
208
|
-
> {
|
|
103
|
+
export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, TItemJson>
|
|
104
|
+
implements TriggerNodeConfig<TItemJson, JsonValue | undefined>, PollingTriggerConfig
|
|
105
|
+
{
|
|
209
106
|
readonly kind = "trigger" as const;
|
|
210
107
|
readonly type: TypeToken<unknown>;
|
|
211
108
|
readonly icon: string | undefined;
|
|
@@ -222,6 +119,7 @@ export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, T
|
|
|
222
119
|
private readonly inspectorSummaryFn?: (
|
|
223
120
|
args: Readonly<{ config: TConfig }>,
|
|
224
121
|
) => ReadonlyArray<NodeInspectorSummaryRow> | undefined,
|
|
122
|
+
private readonly defaultPollIntervalMs?: number,
|
|
225
123
|
) {
|
|
226
124
|
this.type = typeToken;
|
|
227
125
|
this.icon = icon;
|
|
@@ -234,16 +132,20 @@ export class DefinedPollingTriggerConfig<TConfig extends CredentialJsonRecord, T
|
|
|
234
132
|
return this.credentialRequirements;
|
|
235
133
|
}
|
|
236
134
|
|
|
135
|
+
getTriggerPollConfig(): Readonly<{ config: JsonObject; pollIntervalMs?: number }> {
|
|
136
|
+
const cfgPollInterval = (this.cfg as Partial<{ pollIntervalMs: number }>).pollIntervalMs;
|
|
137
|
+
const resolvedInterval = cfgPollInterval ?? this.defaultPollIntervalMs;
|
|
138
|
+
return {
|
|
139
|
+
config: this.cfg as unknown as JsonObject,
|
|
140
|
+
pollIntervalMs: resolvedInterval,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
237
144
|
inspectorSummary(): ReadonlyArray<NodeInspectorSummaryRow> | undefined {
|
|
238
145
|
return this.inspectorSummaryFn?.({ config: this.cfg });
|
|
239
146
|
}
|
|
240
147
|
}
|
|
241
148
|
|
|
242
|
-
// ---------------------------------------------------------------------------
|
|
243
|
-
// Internal wrapped state helpers
|
|
244
|
-
// ---------------------------------------------------------------------------
|
|
245
|
-
|
|
246
|
-
/** Opaque shape stored in the trigger setup state repository. @internal */
|
|
247
149
|
interface InternalWrappedState {
|
|
248
150
|
readonly userState: JsonValue | undefined;
|
|
249
151
|
readonly seenKeys: ReadonlyArray<string>;
|
|
@@ -258,32 +160,6 @@ function isWrappedState(value: unknown): value is InternalWrappedState {
|
|
|
258
160
|
);
|
|
259
161
|
}
|
|
260
162
|
|
|
261
|
-
// ---------------------------------------------------------------------------
|
|
262
|
-
// Implementation factory
|
|
263
|
-
// ---------------------------------------------------------------------------
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Declarative helper for authoring polling triggers.
|
|
267
|
-
*
|
|
268
|
-
* ```ts
|
|
269
|
-
* export const onNewMail = definePollingTrigger({
|
|
270
|
-
* key: "my-plugin.on-new-mail",
|
|
271
|
-
* title: "On new mail",
|
|
272
|
-
* configSchema: z.object({ folder: z.string() }),
|
|
273
|
-
* credentials: { auth: myOAuthCredentialType },
|
|
274
|
-
* initialState: () => ({ lastSeenId: undefined }),
|
|
275
|
-
* pollIntervalMs: 60_000,
|
|
276
|
-
* async poll({ config, state, credentials }) {
|
|
277
|
-
* const session = await credentials.auth();
|
|
278
|
-
* const messages = await fetchMessages(session, config.folder, state.lastSeenId);
|
|
279
|
-
* return {
|
|
280
|
-
* items: messages.map(m => ({ json: m, dedupKey: m.id })),
|
|
281
|
-
* nextState: { lastSeenId: messages[0]?.id ?? state.lastSeenId },
|
|
282
|
-
* };
|
|
283
|
-
* },
|
|
284
|
-
* });
|
|
285
|
-
* ```
|
|
286
|
-
*/
|
|
287
163
|
export function definePollingTrigger<
|
|
288
164
|
TKey extends string,
|
|
289
165
|
TConfig extends CredentialJsonRecord,
|
|
@@ -298,10 +174,6 @@ export function definePollingTrigger<
|
|
|
298
174
|
|
|
299
175
|
type TConfig_ = DefinedPollingTriggerConfig<TConfig, TItemJson>;
|
|
300
176
|
|
|
301
|
-
// ---------------------------------------------------------------------------
|
|
302
|
-
// Synthesised runtime class (implements TestableTriggerNode)
|
|
303
|
-
// ---------------------------------------------------------------------------
|
|
304
|
-
|
|
305
177
|
const DefinedPollingTriggerRuntime = class implements TestableTriggerNode<TConfig_> {
|
|
306
178
|
readonly kind = "trigger" as const;
|
|
307
179
|
readonly outputPorts = ["main"] as const;
|
|
@@ -311,7 +183,6 @@ export function definePollingTrigger<
|
|
|
311
183
|
const intervalMs =
|
|
312
184
|
(cfg as Partial<{ pollIntervalMs: number }>).pollIntervalMs ?? options.pollIntervalMs ?? DEFAULT_INTERVAL_MS;
|
|
313
185
|
|
|
314
|
-
// Unwrap previously persisted state, or create the initial wrapped state.
|
|
315
186
|
const persisted = ctx.previousState;
|
|
316
187
|
const existingWrapped: InternalWrappedState | undefined = isWrappedState(persisted) ? persisted : undefined;
|
|
317
188
|
const seedWrapped: InternalWrappedState = existingWrapped ?? {
|
|
@@ -337,7 +208,6 @@ export function definePollingTrigger<
|
|
|
337
208
|
credentials: credentialAccessors,
|
|
338
209
|
});
|
|
339
210
|
|
|
340
|
-
// Dedup: filter items whose dedupKey is already seen
|
|
341
211
|
const newItems: Array<{ json: TItemJson }> = [];
|
|
342
212
|
const newKeys: string[] = [];
|
|
343
213
|
for (const item of pollResult.items) {
|
|
@@ -350,7 +220,6 @@ export function definePollingTrigger<
|
|
|
350
220
|
newItems.push({ json: item.json });
|
|
351
221
|
}
|
|
352
222
|
|
|
353
|
-
// Merge keys, cap the window at 2000 to bound state size
|
|
354
223
|
const allKeys = [...wrapped.seenKeys, ...newKeys];
|
|
355
224
|
const cappedKeys = allKeys.length > 2000 ? allKeys.slice(allKeys.length - 2000) : allKeys;
|
|
356
225
|
|
|
@@ -384,11 +253,7 @@ export function definePollingTrigger<
|
|
|
384
253
|
}
|
|
385
254
|
};
|
|
386
255
|
|
|
387
|
-
persistedNode({ name: options.key })(DefinedPollingTriggerRuntime);
|
|
388
|
-
|
|
389
|
-
// ---------------------------------------------------------------------------
|
|
390
|
-
// Returned definition object
|
|
391
|
-
// ---------------------------------------------------------------------------
|
|
256
|
+
persistedNode({ name: options.key, packageName: options.packageName })(DefinedPollingTriggerRuntime);
|
|
392
257
|
|
|
393
258
|
const definition: DefinedPollingTrigger<TKey, TConfig, TItemJson, TState, TBindings> = {
|
|
394
259
|
kind: "defined-polling-trigger",
|
|
@@ -411,6 +276,7 @@ export function definePollingTrigger<
|
|
|
411
276
|
options.inspectorSummary as
|
|
412
277
|
| ((args: Readonly<{ config: TConfig }>) => ReadonlyArray<NodeInspectorSummaryRow> | undefined)
|
|
413
278
|
| undefined,
|
|
279
|
+
options.pollIntervalMs,
|
|
414
280
|
);
|
|
415
281
|
},
|
|
416
282
|
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared internal helpers for defineNode and definePollingTrigger.
|
|
3
|
-
* Not part of the public API — import only from authoring helpers.
|
|
4
|
-
*/
|
|
5
1
|
import type { AnyCredentialType, CredentialRequirement, CredentialTypeId } from "../contracts/credentialTypes";
|
|
6
2
|
import type { NodeExecutionContext } from "../contracts/runtimeTypes";
|
|
7
3
|
import type { RunnableNodeConfig } from "../contracts/workflowTypes";
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core-local copy of the per-instance authoring options every `define*` factory's `create(...)`
|
|
3
|
-
* accepts in its trailing argument: a stable `id` plus a plain-language `description` (the
|
|
4
|
-
* non-technical "what does this step do" line surfaced in the node sidebar).
|
|
5
|
-
*
|
|
6
|
-
* `description` is a first-class option — passed inline exactly like `id` — and is threaded onto
|
|
7
|
-
* the config instance as an OWN ENUMERABLE field so it flows into the persisted workflow snapshot
|
|
8
|
-
* (`WorkflowSnapshotCodec` serializes via `JSON.parse(JSON.stringify(config))`, which only captures
|
|
9
|
-
* own enumerable properties — never a getter).
|
|
10
|
-
*
|
|
11
|
-
* `@codemation/core-nodes` declares an identical `NodeBaseOptions` for its bare-id built-in nodes;
|
|
12
|
-
* core keeps its own copy because core must not depend on `@codemation/core-nodes` (dependency
|
|
13
|
-
* direction). The two types are structurally identical by design.
|
|
14
|
-
*/
|
|
15
1
|
export interface NodeBaseOptions {
|
|
16
2
|
readonly id?: string;
|
|
17
3
|
readonly description?: string;
|
|
@@ -2,19 +2,6 @@ import type { BinaryAttachment, BinaryStorage } from "../types";
|
|
|
2
2
|
import type { BinaryStorageReadResult } from "../types";
|
|
3
3
|
import { BINARY_DEFAULT_MAX_BYTES } from "../contracts/runtimeTypes";
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Reads all bytes from an already-opened binary stream into a contiguous `Uint8Array`.
|
|
7
|
-
*
|
|
8
|
-
* Safety contract:
|
|
9
|
-
* - `attachment.size` is checked against `maxBytes` *before* any allocation (no OOM).
|
|
10
|
-
* - A single buffer of exactly `attachment.size` is pre-allocated; the stream fills it
|
|
11
|
-
* directly — no chunks array, no doubling.
|
|
12
|
-
* - A byte-count mismatch between the declared size and actual stream content is an error.
|
|
13
|
-
*
|
|
14
|
-
* This is the single canonical implementation; `ExecutionBinaryService.getBytes`,
|
|
15
|
-
* `getText`, and `getJson` all delegate here. The per-package `readBinaryBody` helpers
|
|
16
|
-
* in `core-nodes` and `core-nodes-ocr` have been removed in favour of this function.
|
|
17
|
-
*/
|
|
18
5
|
export async function boundedReadBinary(
|
|
19
6
|
result: BinaryStorageReadResult,
|
|
20
7
|
attachment: BinaryAttachment,
|
|
@@ -49,7 +36,6 @@ export async function boundedReadBinary(
|
|
|
49
36
|
return out;
|
|
50
37
|
}
|
|
51
38
|
|
|
52
|
-
/** Shared implementation of `getBytes` used by both binary-service classes. */
|
|
53
39
|
export async function readBinaryAsBytes(
|
|
54
40
|
storage: BinaryStorage,
|
|
55
41
|
attachment: BinaryAttachment,
|
|
@@ -62,7 +48,6 @@ export async function readBinaryAsBytes(
|
|
|
62
48
|
return boundedReadBinary(result, attachment, maxBytes);
|
|
63
49
|
}
|
|
64
50
|
|
|
65
|
-
/** Shared implementation of `getText` used by both binary-service classes. */
|
|
66
51
|
export async function readBinaryAsText(
|
|
67
52
|
storage: BinaryStorage,
|
|
68
53
|
attachment: BinaryAttachment,
|
|
@@ -72,7 +57,6 @@ export async function readBinaryAsText(
|
|
|
72
57
|
return new TextDecoder().decode(bytes);
|
|
73
58
|
}
|
|
74
59
|
|
|
75
|
-
/** Shared implementation of `getJson` used by both binary-service classes. */
|
|
76
60
|
export async function readBinaryAsJson<T = unknown>(
|
|
77
61
|
storage: BinaryStorage,
|
|
78
62
|
attachment: BinaryAttachment,
|
package/src/bootstrap/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Composition-root engine graph and advanced runtime wiring. Not part of the main `@codemation/core` barrel. */
|
|
2
1
|
export { Engine } from "../orchestration/Engine";
|
|
3
2
|
export {
|
|
4
3
|
AbortControllerFactory,
|
|
@@ -57,4 +56,11 @@ export {
|
|
|
57
56
|
WorkflowStoragePolicyEvaluator,
|
|
58
57
|
type EngineExecutionLimitsPolicyConfig,
|
|
59
58
|
} from "../policies";
|
|
60
|
-
export {
|
|
59
|
+
export {
|
|
60
|
+
MissingRuntimeParityGuard,
|
|
61
|
+
MissingRuntimeTriggerToken,
|
|
62
|
+
PersistedWorkflowTokenRegistry,
|
|
63
|
+
WorkflowParityMismatchError,
|
|
64
|
+
type MissingRuntimeNodeDetail,
|
|
65
|
+
} from "../workflowSnapshots";
|
|
66
|
+
export { WorkflowSnapshotCodec } from "../workflowSnapshots/WorkflowSnapshotCodec";
|