@codemation/node-example 0.0.32 → 0.0.34
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 +14 -0
- package/dist/index.d.cts +298 -162
- package/dist/index.d.ts +298 -162
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @codemation/node-example
|
|
2
2
|
|
|
3
|
+
## 0.0.34
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`4902978`](https://github.com/MadeRelevant/codemation/commit/49029782243ece59ab6aa5bb46396db445cad47c), [`6566d55`](https://github.com/MadeRelevant/codemation/commit/6566d55c829f6631357ac95052b0852e86092ac5), [`a77505f`](https://github.com/MadeRelevant/codemation/commit/a77505f331d7d3892f3c1c8f19dc37952b4d96bd), [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb), [`2c0723f`](https://github.com/MadeRelevant/codemation/commit/2c0723fb1670e842c272939b5db73d4b95b25535), [`fb9f7fe`](https://github.com/MadeRelevant/codemation/commit/fb9f7fed9bf5a3d6b0c5f78a30027be3ab7bcaca), [`2c0723f`](https://github.com/MadeRelevant/codemation/commit/2c0723fb1670e842c272939b5db73d4b95b25535), [`6fc7d3f`](https://github.com/MadeRelevant/codemation/commit/6fc7d3fe95f8d88386c16971fffa8dd3faa7704f), [`781c146`](https://github.com/MadeRelevant/codemation/commit/781c146eb9d8bb8bdbc1963ea2a4b9abe4b7bfbf), [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb), [`11616ae`](https://github.com/MadeRelevant/codemation/commit/11616aefb91d4b96b7eb9af4b935eec055a8a7bb)]:
|
|
8
|
+
- @codemation/core@2.0.0
|
|
9
|
+
|
|
10
|
+
## 0.0.33
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`ed75183`](https://github.com/MadeRelevant/codemation/commit/ed75183f51ae71b06aa2e57ae4fc48ce9db2e4ce)]:
|
|
15
|
+
- @codemation/core@1.0.1
|
|
16
|
+
|
|
3
17
|
## 0.0.32
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,75 @@
|
|
|
1
1
|
import { ReadableStream } from "node:stream/web";
|
|
2
|
-
import { InjectionToken as TypeToken } from "tsyringe";
|
|
3
2
|
import { ZodType } from "zod";
|
|
3
|
+
import { InjectionToken as TypeToken } from "tsyringe";
|
|
4
4
|
|
|
5
|
+
//#region ../core/src/contracts/baseTypes.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Minimal base types that have no dependencies on other contracts.
|
|
8
|
+
* Used by credentialTypes, workflowTypes, and other contract layers
|
|
9
|
+
* to avoid circular dependencies.
|
|
10
|
+
*/
|
|
11
|
+
type WorkflowId = string;
|
|
12
|
+
type NodeId = string;
|
|
13
|
+
type OutputPortKey = string;
|
|
14
|
+
type InputPortKey = string;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region ../core/src/contracts/credentialTypes.d.ts
|
|
17
|
+
type CredentialTypeId = string;
|
|
18
|
+
type CredentialRequirement = Readonly<{
|
|
19
|
+
slotKey: string;
|
|
20
|
+
label: string;
|
|
21
|
+
acceptedTypes: ReadonlyArray<CredentialTypeId>;
|
|
22
|
+
optional?: true;
|
|
23
|
+
helpText?: string;
|
|
24
|
+
helpUrl?: string;
|
|
25
|
+
}>;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region ../core/src/contracts/runTypes.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Test-suite linkage for a run. When set, this run was started by a TestSuiteOrchestrator
|
|
30
|
+
* as one test case inside a TestSuiteRun. The `IsTestRun` node and host-side persisters key
|
|
31
|
+
* off the presence of this field. Subworkflow runs inherit it from their parent run.
|
|
32
|
+
*/
|
|
33
|
+
interface RunTestContext {
|
|
34
|
+
readonly testSuiteRunId: string;
|
|
35
|
+
readonly testCaseIndex: number;
|
|
36
|
+
/**
|
|
37
|
+
* Optional human-friendly label for this test case (e.g. an email subject when fixtures
|
|
38
|
+
* are loaded from a mailbox). Resolved per item by `TestTrigger.caseLabel(item)` if set,
|
|
39
|
+
* persisted on `Run.test_case_label` so the Tests-tab tree-table can show "RFQ for batch 14"
|
|
40
|
+
* instead of "run_1777755971399_bbb86beac1396".
|
|
41
|
+
*/
|
|
42
|
+
readonly testCaseLabel?: string;
|
|
43
|
+
}
|
|
44
|
+
type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
|
|
45
|
+
type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
|
|
46
|
+
interface NodeExecutionError {
|
|
47
|
+
message: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
stack?: string;
|
|
50
|
+
details?: JsonValue;
|
|
51
|
+
}
|
|
52
|
+
/** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
|
|
53
|
+
type ConnectionInvocationId = string;
|
|
54
|
+
/** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
|
|
55
|
+
type ConnectionInvocationAppendArgs = Readonly<{
|
|
56
|
+
invocationId: ConnectionInvocationId;
|
|
57
|
+
connectionNodeId: NodeId;
|
|
58
|
+
parentAgentNodeId: NodeId;
|
|
59
|
+
parentAgentActivationId: NodeActivationId;
|
|
60
|
+
status: NodeExecutionStatus;
|
|
61
|
+
managedInput?: JsonValue;
|
|
62
|
+
managedOutput?: JsonValue;
|
|
63
|
+
error?: NodeExecutionError;
|
|
64
|
+
queuedAt?: string;
|
|
65
|
+
startedAt?: string;
|
|
66
|
+
finishedAt?: string;
|
|
67
|
+
iterationId?: NodeIterationId;
|
|
68
|
+
itemIndex?: number;
|
|
69
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
70
|
+
}>;
|
|
71
|
+
//#endregion
|
|
5
72
|
//#region ../core/src/contracts/retryPolicySpec.types.d.ts
|
|
6
|
-
|
|
7
73
|
/**
|
|
8
74
|
* In-process retry policy for runnable nodes. Serialized configs use the same
|
|
9
75
|
* `kind` discriminator (`JSON.stringify` / persisted workflows).
|
|
@@ -31,6 +97,147 @@ interface ExponentialRetryPolicySpec {
|
|
|
31
97
|
readonly jitter?: boolean;
|
|
32
98
|
}
|
|
33
99
|
//#endregion
|
|
100
|
+
//#region ../core/src/contracts/workflowTypes.d.ts
|
|
101
|
+
type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
|
|
102
|
+
__codemationNodeJson?: TJson;
|
|
103
|
+
}>;
|
|
104
|
+
type NodeKind = "trigger" | "node";
|
|
105
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
106
|
+
interface JsonObject {
|
|
107
|
+
readonly [key: string]: JsonValue;
|
|
108
|
+
}
|
|
109
|
+
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
110
|
+
type JsonArray = ReadonlyArray<JsonValue>;
|
|
111
|
+
interface NodeConfigBase {
|
|
112
|
+
readonly kind: NodeKind;
|
|
113
|
+
readonly type: TypeToken<unknown>;
|
|
114
|
+
readonly name?: string;
|
|
115
|
+
readonly id?: NodeId;
|
|
116
|
+
readonly icon?: string;
|
|
117
|
+
readonly execution?: Readonly<{
|
|
118
|
+
hint?: "local" | "worker";
|
|
119
|
+
queue?: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** In-process execute retries (runnable nodes). Triggers typically omit this. */
|
|
122
|
+
readonly retryPolicy?: RetryPolicySpec;
|
|
123
|
+
/** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
|
|
124
|
+
readonly nodeErrorHandler?: NodeErrorHandlerSpec;
|
|
125
|
+
/**
|
|
126
|
+
* When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
|
|
127
|
+
* Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
|
|
128
|
+
* main batches skip downstream execution and propagate the empty path.
|
|
129
|
+
*/
|
|
130
|
+
readonly continueWhenEmptyOutput?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
|
|
133
|
+
* Use for dynamic routers (Switch) and future error ports.
|
|
134
|
+
*/
|
|
135
|
+
readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
|
|
136
|
+
readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
|
|
137
|
+
getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
|
|
138
|
+
/**
|
|
139
|
+
* Marker: this node emits {@link import("./assertionTypes").AssertionResult}-shaped items on its
|
|
140
|
+
* `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for
|
|
141
|
+
* `nodeCompleted` events from nodes with this flag set, and persist their output items as
|
|
142
|
+
* TestAssertion records (only when the run carries a `testContext`). Set on assertion node
|
|
143
|
+
* configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).
|
|
144
|
+
*/
|
|
145
|
+
readonly emitsAssertions?: true;
|
|
146
|
+
}
|
|
147
|
+
declare const runnableNodeInputType: unique symbol;
|
|
148
|
+
declare const runnableNodeOutputType: unique symbol;
|
|
149
|
+
/**
|
|
150
|
+
* Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
|
|
151
|
+
* **`TOutputJson`** is emitted `item.json` on outputs.
|
|
152
|
+
*/
|
|
153
|
+
interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
|
|
154
|
+
readonly kind: "node";
|
|
155
|
+
readonly [runnableNodeInputType]?: TInputJson$1;
|
|
156
|
+
readonly [runnableNodeOutputType]?: TOutputJson$1;
|
|
157
|
+
/**
|
|
158
|
+
* Optional Zod input contract for {@link RunnableNode} when not set on the node class.
|
|
159
|
+
* Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
|
|
160
|
+
*/
|
|
161
|
+
readonly inputSchema?: ZodType<TInputJson$1>;
|
|
162
|
+
/**
|
|
163
|
+
* When an activation receives **zero** input items, the engine normally runs `execute` zero times.
|
|
164
|
+
* Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
|
|
165
|
+
* Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
|
|
166
|
+
*/
|
|
167
|
+
readonly emptyBatchExecution?: "skip" | "runOnce";
|
|
168
|
+
}
|
|
169
|
+
type PairedItemRef = Readonly<{
|
|
170
|
+
nodeId: NodeId;
|
|
171
|
+
output: OutputPortKey;
|
|
172
|
+
itemIndex: number;
|
|
173
|
+
}>;
|
|
174
|
+
type BinaryPreviewKind = "image" | "audio" | "video" | "download";
|
|
175
|
+
type BinaryAttachment = Readonly<{
|
|
176
|
+
id: string;
|
|
177
|
+
storageKey: string;
|
|
178
|
+
mimeType: string;
|
|
179
|
+
size: number;
|
|
180
|
+
storageDriver: string;
|
|
181
|
+
previewKind: BinaryPreviewKind;
|
|
182
|
+
createdAt: string;
|
|
183
|
+
runId: RunId;
|
|
184
|
+
workflowId: WorkflowId;
|
|
185
|
+
nodeId: NodeId;
|
|
186
|
+
activationId: NodeActivationId;
|
|
187
|
+
filename?: string;
|
|
188
|
+
sha256?: string;
|
|
189
|
+
}>;
|
|
190
|
+
type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
|
|
191
|
+
type Item<TJson = unknown> = Readonly<{
|
|
192
|
+
json: TJson;
|
|
193
|
+
binary?: ItemBinary;
|
|
194
|
+
meta?: Readonly<Record<string, unknown>>;
|
|
195
|
+
paired?: ReadonlyArray<PairedItemRef>;
|
|
196
|
+
}>;
|
|
197
|
+
type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
|
|
198
|
+
type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
|
|
199
|
+
type RunId = string;
|
|
200
|
+
type NodeActivationId = string;
|
|
201
|
+
/**
|
|
202
|
+
* One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
|
|
203
|
+
* per-item connection invocations and telemetry. Undefined when the executing node is a batch
|
|
204
|
+
* node or trigger that does not iterate items.
|
|
205
|
+
*/
|
|
206
|
+
type NodeIterationId = string;
|
|
207
|
+
interface ParentExecutionRef {
|
|
208
|
+
runId: RunId;
|
|
209
|
+
workflowId: WorkflowId;
|
|
210
|
+
nodeId: NodeId;
|
|
211
|
+
/** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
|
|
212
|
+
subworkflowDepth?: number;
|
|
213
|
+
/** Effective max node activations from the parent run (propagated to child policy merge). */
|
|
214
|
+
engineMaxNodeActivations?: number;
|
|
215
|
+
/** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
|
|
216
|
+
engineMaxSubworkflowDepth?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Test-suite linkage inherited by the child subworkflow run. Set by whichever node
|
|
219
|
+
* spawns the subworkflow when its own `ctx.testContext` is present, so assertions
|
|
220
|
+
* emitted inside a subworkflow land under the correct parent test case.
|
|
221
|
+
*/
|
|
222
|
+
testContext?: RunTestContext;
|
|
223
|
+
}
|
|
224
|
+
interface RunDataSnapshot {
|
|
225
|
+
getOutputs(nodeId: NodeId): NodeOutputs | undefined;
|
|
226
|
+
getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
|
|
227
|
+
getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
|
|
228
|
+
}
|
|
229
|
+
interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
|
|
230
|
+
readonly kind: "single" | "multi";
|
|
231
|
+
readonly items: Items;
|
|
232
|
+
readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
|
|
233
|
+
readonly ctx: NodeExecutionContext<TConfig>;
|
|
234
|
+
readonly error: Error;
|
|
235
|
+
}
|
|
236
|
+
interface NodeErrorHandler {
|
|
237
|
+
handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
|
|
238
|
+
}
|
|
239
|
+
type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
|
|
240
|
+
//#endregion
|
|
34
241
|
//#region ../core/src/contracts/telemetryTypes.d.ts
|
|
35
242
|
type TelemetryAttributePrimitive = string | number | boolean | null;
|
|
36
243
|
interface TelemetryAttributes {
|
|
@@ -87,6 +294,17 @@ interface TelemetrySpanScope extends TelemetryScope {
|
|
|
87
294
|
readonly traceId: string;
|
|
88
295
|
readonly spanId: string;
|
|
89
296
|
end(args?: TelemetrySpanEnd): Promise<void> | void;
|
|
297
|
+
/**
|
|
298
|
+
* Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
|
|
299
|
+
* Children created via the returned telemetry's `startChildSpan` get this span as their parent.
|
|
300
|
+
*
|
|
301
|
+
* Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
|
|
302
|
+
* span instead of the orchestrator's node-level span.
|
|
303
|
+
*/
|
|
304
|
+
asNodeTelemetry(args: Readonly<{
|
|
305
|
+
nodeId: NodeId;
|
|
306
|
+
activationId: NodeActivationId;
|
|
307
|
+
}>): NodeExecutionTelemetry;
|
|
90
308
|
}
|
|
91
309
|
interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
|
|
92
310
|
startChildSpan(args: TelemetryChildSpanStart): TelemetrySpanScope;
|
|
@@ -123,31 +341,70 @@ interface CostTrackingTelemetry {
|
|
|
123
341
|
forScope(scope: TelemetryScope): CostTrackingTelemetry;
|
|
124
342
|
}
|
|
125
343
|
//#endregion
|
|
126
|
-
//#region ../core/src/contracts/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
344
|
+
//#region ../core/src/contracts/collectionTypes.d.ts
|
|
345
|
+
/**
|
|
346
|
+
* Represents a typed store for a single collection.
|
|
347
|
+
* All rows include auto-managed id, created_at, and updated_at fields.
|
|
348
|
+
*/
|
|
349
|
+
interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
|
|
350
|
+
/**
|
|
351
|
+
* Insert a new row. id, created_at, and updated_at are auto-populated.
|
|
352
|
+
*/
|
|
353
|
+
insert(row: TRow): Promise<TRow & {
|
|
354
|
+
id: string;
|
|
355
|
+
created_at: Date;
|
|
356
|
+
updated_at: Date;
|
|
357
|
+
}>;
|
|
358
|
+
/**
|
|
359
|
+
* Get a single row by id.
|
|
360
|
+
*/
|
|
361
|
+
get(id: string): Promise<(TRow & {
|
|
362
|
+
id: string;
|
|
363
|
+
created_at: Date;
|
|
364
|
+
updated_at: Date;
|
|
365
|
+
}) | null>;
|
|
366
|
+
/**
|
|
367
|
+
* Find a single row matching the provided filter.
|
|
368
|
+
*/
|
|
369
|
+
findOne(filter: Partial<TRow>): Promise<(TRow & {
|
|
370
|
+
id: string;
|
|
371
|
+
created_at: Date;
|
|
372
|
+
updated_at: Date;
|
|
373
|
+
}) | null>;
|
|
374
|
+
/**
|
|
375
|
+
* List rows with optional pagination and filtering.
|
|
376
|
+
*/
|
|
377
|
+
list(opts?: {
|
|
378
|
+
limit?: number;
|
|
379
|
+
offset?: number;
|
|
380
|
+
where?: Partial<TRow>;
|
|
381
|
+
}): Promise<{
|
|
382
|
+
rows: ReadonlyArray<TRow & {
|
|
383
|
+
id: string;
|
|
384
|
+
created_at: Date;
|
|
385
|
+
updated_at: Date;
|
|
386
|
+
}>;
|
|
387
|
+
total: number;
|
|
388
|
+
}>;
|
|
389
|
+
/**
|
|
390
|
+
* Update a row by id with partial data.
|
|
391
|
+
*/
|
|
392
|
+
update(id: string, patch: Partial<TRow>): Promise<TRow & {
|
|
393
|
+
id: string;
|
|
394
|
+
created_at: Date;
|
|
395
|
+
updated_at: Date;
|
|
396
|
+
}>;
|
|
397
|
+
/**
|
|
398
|
+
* Delete a row by id. Hard delete only (no soft delete).
|
|
399
|
+
*/
|
|
400
|
+
delete(id: string): Promise<{
|
|
401
|
+
deleted: boolean;
|
|
402
|
+
}>;
|
|
134
403
|
}
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
type
|
|
139
|
-
invocationId: ConnectionInvocationId;
|
|
140
|
-
connectionNodeId: NodeId;
|
|
141
|
-
parentAgentNodeId: NodeId;
|
|
142
|
-
parentAgentActivationId: NodeActivationId;
|
|
143
|
-
status: NodeExecutionStatus;
|
|
144
|
-
managedInput?: JsonValue;
|
|
145
|
-
managedOutput?: JsonValue;
|
|
146
|
-
error?: NodeExecutionError;
|
|
147
|
-
queuedAt?: string;
|
|
148
|
-
startedAt?: string;
|
|
149
|
-
finishedAt?: string;
|
|
150
|
-
}>;
|
|
404
|
+
/**
|
|
405
|
+
* Runtime collections context: keyed by collection name.
|
|
406
|
+
*/
|
|
407
|
+
type CollectionsContext = Readonly<Record<string, CollectionStore>>;
|
|
151
408
|
//#endregion
|
|
152
409
|
//#region ../core/src/contracts/runtimeTypes.d.ts
|
|
153
410
|
interface NodeExecutionStatePublisher {
|
|
@@ -214,6 +471,21 @@ interface ExecutionContext {
|
|
|
214
471
|
telemetry: ExecutionTelemetry;
|
|
215
472
|
binary: ExecutionBinaryService;
|
|
216
473
|
getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
|
|
474
|
+
/** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
|
|
475
|
+
iterationId?: NodeIterationId;
|
|
476
|
+
/** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
|
|
477
|
+
itemIndex?: number;
|
|
478
|
+
/** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
|
|
479
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
480
|
+
/**
|
|
481
|
+
* Present iff the run was started by a TestSuiteOrchestrator. The {@link IsTestRunNode}
|
|
482
|
+
* branches on this; assertion-emitting nodes use it to decide whether to record results.
|
|
483
|
+
*/
|
|
484
|
+
testContext?: RunTestContext;
|
|
485
|
+
/**
|
|
486
|
+
* Collections registered in the codemation config, keyed by collection name.
|
|
487
|
+
*/
|
|
488
|
+
readonly collections?: CollectionsContext;
|
|
217
489
|
}
|
|
218
490
|
interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfigBase> extends ExecutionContext {
|
|
219
491
|
nodeId: NodeId;
|
|
@@ -249,142 +521,6 @@ interface RunnableNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNo
|
|
|
249
521
|
execute(args: RunnableNodeExecuteArgs<TConfig, TInputJson$1>): Promise<unknown> | unknown;
|
|
250
522
|
}
|
|
251
523
|
//#endregion
|
|
252
|
-
//#region ../core/src/contracts/workflowTypes.d.ts
|
|
253
|
-
type WorkflowId = string;
|
|
254
|
-
type NodeId = string;
|
|
255
|
-
type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
|
|
256
|
-
__codemationNodeJson?: TJson;
|
|
257
|
-
}>;
|
|
258
|
-
type OutputPortKey = string;
|
|
259
|
-
type InputPortKey = string;
|
|
260
|
-
type NodeKind = "trigger" | "node";
|
|
261
|
-
type JsonPrimitive = string | number | boolean | null;
|
|
262
|
-
interface JsonObject {
|
|
263
|
-
readonly [key: string]: JsonValue;
|
|
264
|
-
}
|
|
265
|
-
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
266
|
-
type JsonArray = ReadonlyArray<JsonValue>;
|
|
267
|
-
interface NodeConfigBase {
|
|
268
|
-
readonly kind: NodeKind;
|
|
269
|
-
readonly type: TypeToken<unknown>;
|
|
270
|
-
readonly name?: string;
|
|
271
|
-
readonly id?: NodeId;
|
|
272
|
-
readonly icon?: string;
|
|
273
|
-
readonly execution?: Readonly<{
|
|
274
|
-
hint?: "local" | "worker";
|
|
275
|
-
queue?: string;
|
|
276
|
-
}>;
|
|
277
|
-
/** In-process execute retries (runnable nodes). Triggers typically omit this. */
|
|
278
|
-
readonly retryPolicy?: RetryPolicySpec;
|
|
279
|
-
/** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
|
|
280
|
-
readonly nodeErrorHandler?: NodeErrorHandlerSpec;
|
|
281
|
-
/**
|
|
282
|
-
* When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
|
|
283
|
-
* Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
|
|
284
|
-
* main batches skip downstream execution and propagate the empty path.
|
|
285
|
-
*/
|
|
286
|
-
readonly continueWhenEmptyOutput?: boolean;
|
|
287
|
-
/**
|
|
288
|
-
* Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
|
|
289
|
-
* Use for dynamic routers (Switch) and future error ports.
|
|
290
|
-
*/
|
|
291
|
-
readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
|
|
292
|
-
readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
|
|
293
|
-
getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
|
|
294
|
-
}
|
|
295
|
-
declare const runnableNodeInputType: unique symbol;
|
|
296
|
-
declare const runnableNodeOutputType: unique symbol;
|
|
297
|
-
/**
|
|
298
|
-
* Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
|
|
299
|
-
* **`TOutputJson`** is emitted `item.json` on outputs.
|
|
300
|
-
*/
|
|
301
|
-
interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
|
|
302
|
-
readonly kind: "node";
|
|
303
|
-
readonly [runnableNodeInputType]?: TInputJson$1;
|
|
304
|
-
readonly [runnableNodeOutputType]?: TOutputJson$1;
|
|
305
|
-
/**
|
|
306
|
-
* Optional Zod input contract for {@link RunnableNode} when not set on the node class.
|
|
307
|
-
* Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
|
|
308
|
-
*/
|
|
309
|
-
readonly inputSchema?: ZodType<TInputJson$1>;
|
|
310
|
-
/**
|
|
311
|
-
* When an activation receives **zero** input items, the engine normally runs `execute` zero times.
|
|
312
|
-
* Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
|
|
313
|
-
* Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
|
|
314
|
-
*/
|
|
315
|
-
readonly emptyBatchExecution?: "skip" | "runOnce";
|
|
316
|
-
}
|
|
317
|
-
type PairedItemRef = Readonly<{
|
|
318
|
-
nodeId: NodeId;
|
|
319
|
-
output: OutputPortKey;
|
|
320
|
-
itemIndex: number;
|
|
321
|
-
}>;
|
|
322
|
-
type BinaryPreviewKind = "image" | "audio" | "video" | "download";
|
|
323
|
-
type BinaryAttachment = Readonly<{
|
|
324
|
-
id: string;
|
|
325
|
-
storageKey: string;
|
|
326
|
-
mimeType: string;
|
|
327
|
-
size: number;
|
|
328
|
-
storageDriver: string;
|
|
329
|
-
previewKind: BinaryPreviewKind;
|
|
330
|
-
createdAt: string;
|
|
331
|
-
runId: RunId;
|
|
332
|
-
workflowId: WorkflowId;
|
|
333
|
-
nodeId: NodeId;
|
|
334
|
-
activationId: NodeActivationId;
|
|
335
|
-
filename?: string;
|
|
336
|
-
sha256?: string;
|
|
337
|
-
}>;
|
|
338
|
-
type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
|
|
339
|
-
type Item<TJson = unknown> = Readonly<{
|
|
340
|
-
json: TJson;
|
|
341
|
-
binary?: ItemBinary;
|
|
342
|
-
meta?: Readonly<Record<string, unknown>>;
|
|
343
|
-
paired?: ReadonlyArray<PairedItemRef>;
|
|
344
|
-
}>;
|
|
345
|
-
type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
|
|
346
|
-
type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
|
|
347
|
-
type RunId = string;
|
|
348
|
-
type NodeActivationId = string;
|
|
349
|
-
interface ParentExecutionRef {
|
|
350
|
-
runId: RunId;
|
|
351
|
-
workflowId: WorkflowId;
|
|
352
|
-
nodeId: NodeId;
|
|
353
|
-
/** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
|
|
354
|
-
subworkflowDepth?: number;
|
|
355
|
-
/** Effective max node activations from the parent run (propagated to child policy merge). */
|
|
356
|
-
engineMaxNodeActivations?: number;
|
|
357
|
-
/** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
|
|
358
|
-
engineMaxSubworkflowDepth?: number;
|
|
359
|
-
}
|
|
360
|
-
interface RunDataSnapshot {
|
|
361
|
-
getOutputs(nodeId: NodeId): NodeOutputs | undefined;
|
|
362
|
-
getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
|
|
363
|
-
getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
|
|
364
|
-
}
|
|
365
|
-
interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
|
|
366
|
-
readonly kind: "single" | "multi";
|
|
367
|
-
readonly items: Items;
|
|
368
|
-
readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
|
|
369
|
-
readonly ctx: NodeExecutionContext<TConfig>;
|
|
370
|
-
readonly error: Error;
|
|
371
|
-
}
|
|
372
|
-
interface NodeErrorHandler {
|
|
373
|
-
handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
|
|
374
|
-
}
|
|
375
|
-
type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
|
|
376
|
-
//#endregion
|
|
377
|
-
//#region ../core/src/contracts/credentialTypes.d.ts
|
|
378
|
-
type CredentialTypeId = string;
|
|
379
|
-
type CredentialRequirement = Readonly<{
|
|
380
|
-
slotKey: string;
|
|
381
|
-
label: string;
|
|
382
|
-
acceptedTypes: ReadonlyArray<CredentialTypeId>;
|
|
383
|
-
optional?: true;
|
|
384
|
-
helpText?: string;
|
|
385
|
-
helpUrl?: string;
|
|
386
|
-
}>;
|
|
387
|
-
//#endregion
|
|
388
524
|
//#region src/ExampleUppercaseNode.d.ts
|
|
389
525
|
declare class ExampleUppercaseNode implements RunnableNode<ExampleUppercase<Record<string, unknown>, string>> {
|
|
390
526
|
kind: "node";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,75 @@
|
|
|
1
1
|
import { ReadableStream } from "node:stream/web";
|
|
2
|
-
import { InjectionToken as TypeToken } from "tsyringe";
|
|
3
2
|
import { ZodType } from "zod";
|
|
3
|
+
import { InjectionToken as TypeToken } from "tsyringe";
|
|
4
4
|
|
|
5
|
+
//#region ../core/src/contracts/baseTypes.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Minimal base types that have no dependencies on other contracts.
|
|
8
|
+
* Used by credentialTypes, workflowTypes, and other contract layers
|
|
9
|
+
* to avoid circular dependencies.
|
|
10
|
+
*/
|
|
11
|
+
type WorkflowId = string;
|
|
12
|
+
type NodeId = string;
|
|
13
|
+
type OutputPortKey = string;
|
|
14
|
+
type InputPortKey = string;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region ../core/src/contracts/credentialTypes.d.ts
|
|
17
|
+
type CredentialTypeId = string;
|
|
18
|
+
type CredentialRequirement = Readonly<{
|
|
19
|
+
slotKey: string;
|
|
20
|
+
label: string;
|
|
21
|
+
acceptedTypes: ReadonlyArray<CredentialTypeId>;
|
|
22
|
+
optional?: true;
|
|
23
|
+
helpText?: string;
|
|
24
|
+
helpUrl?: string;
|
|
25
|
+
}>;
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region ../core/src/contracts/runTypes.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Test-suite linkage for a run. When set, this run was started by a TestSuiteOrchestrator
|
|
30
|
+
* as one test case inside a TestSuiteRun. The `IsTestRun` node and host-side persisters key
|
|
31
|
+
* off the presence of this field. Subworkflow runs inherit it from their parent run.
|
|
32
|
+
*/
|
|
33
|
+
interface RunTestContext {
|
|
34
|
+
readonly testSuiteRunId: string;
|
|
35
|
+
readonly testCaseIndex: number;
|
|
36
|
+
/**
|
|
37
|
+
* Optional human-friendly label for this test case (e.g. an email subject when fixtures
|
|
38
|
+
* are loaded from a mailbox). Resolved per item by `TestTrigger.caseLabel(item)` if set,
|
|
39
|
+
* persisted on `Run.test_case_label` so the Tests-tab tree-table can show "RFQ for batch 14"
|
|
40
|
+
* instead of "run_1777755971399_bbb86beac1396".
|
|
41
|
+
*/
|
|
42
|
+
readonly testCaseLabel?: string;
|
|
43
|
+
}
|
|
44
|
+
type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
|
|
45
|
+
type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
|
|
46
|
+
interface NodeExecutionError {
|
|
47
|
+
message: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
stack?: string;
|
|
50
|
+
details?: JsonValue;
|
|
51
|
+
}
|
|
52
|
+
/** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
|
|
53
|
+
type ConnectionInvocationId = string;
|
|
54
|
+
/** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
|
|
55
|
+
type ConnectionInvocationAppendArgs = Readonly<{
|
|
56
|
+
invocationId: ConnectionInvocationId;
|
|
57
|
+
connectionNodeId: NodeId;
|
|
58
|
+
parentAgentNodeId: NodeId;
|
|
59
|
+
parentAgentActivationId: NodeActivationId;
|
|
60
|
+
status: NodeExecutionStatus;
|
|
61
|
+
managedInput?: JsonValue;
|
|
62
|
+
managedOutput?: JsonValue;
|
|
63
|
+
error?: NodeExecutionError;
|
|
64
|
+
queuedAt?: string;
|
|
65
|
+
startedAt?: string;
|
|
66
|
+
finishedAt?: string;
|
|
67
|
+
iterationId?: NodeIterationId;
|
|
68
|
+
itemIndex?: number;
|
|
69
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
70
|
+
}>;
|
|
71
|
+
//#endregion
|
|
5
72
|
//#region ../core/src/contracts/retryPolicySpec.types.d.ts
|
|
6
|
-
|
|
7
73
|
/**
|
|
8
74
|
* In-process retry policy for runnable nodes. Serialized configs use the same
|
|
9
75
|
* `kind` discriminator (`JSON.stringify` / persisted workflows).
|
|
@@ -31,6 +97,147 @@ interface ExponentialRetryPolicySpec {
|
|
|
31
97
|
readonly jitter?: boolean;
|
|
32
98
|
}
|
|
33
99
|
//#endregion
|
|
100
|
+
//#region ../core/src/contracts/workflowTypes.d.ts
|
|
101
|
+
type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
|
|
102
|
+
__codemationNodeJson?: TJson;
|
|
103
|
+
}>;
|
|
104
|
+
type NodeKind = "trigger" | "node";
|
|
105
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
106
|
+
interface JsonObject {
|
|
107
|
+
readonly [key: string]: JsonValue;
|
|
108
|
+
}
|
|
109
|
+
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
110
|
+
type JsonArray = ReadonlyArray<JsonValue>;
|
|
111
|
+
interface NodeConfigBase {
|
|
112
|
+
readonly kind: NodeKind;
|
|
113
|
+
readonly type: TypeToken<unknown>;
|
|
114
|
+
readonly name?: string;
|
|
115
|
+
readonly id?: NodeId;
|
|
116
|
+
readonly icon?: string;
|
|
117
|
+
readonly execution?: Readonly<{
|
|
118
|
+
hint?: "local" | "worker";
|
|
119
|
+
queue?: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** In-process execute retries (runnable nodes). Triggers typically omit this. */
|
|
122
|
+
readonly retryPolicy?: RetryPolicySpec;
|
|
123
|
+
/** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
|
|
124
|
+
readonly nodeErrorHandler?: NodeErrorHandlerSpec;
|
|
125
|
+
/**
|
|
126
|
+
* When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
|
|
127
|
+
* Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
|
|
128
|
+
* main batches skip downstream execution and propagate the empty path.
|
|
129
|
+
*/
|
|
130
|
+
readonly continueWhenEmptyOutput?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
|
|
133
|
+
* Use for dynamic routers (Switch) and future error ports.
|
|
134
|
+
*/
|
|
135
|
+
readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
|
|
136
|
+
readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
|
|
137
|
+
getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
|
|
138
|
+
/**
|
|
139
|
+
* Marker: this node emits {@link import("./assertionTypes").AssertionResult}-shaped items on its
|
|
140
|
+
* `main` port. The TestSuiteOrchestrator (and host-side TestAssertionPersister) listen for
|
|
141
|
+
* `nodeCompleted` events from nodes with this flag set, and persist their output items as
|
|
142
|
+
* TestAssertion records (only when the run carries a `testContext`). Set on assertion node
|
|
143
|
+
* configs (e.g. `AssertionNodeConfig`, `StringEqualsAssertionNodeConfig`).
|
|
144
|
+
*/
|
|
145
|
+
readonly emitsAssertions?: true;
|
|
146
|
+
}
|
|
147
|
+
declare const runnableNodeInputType: unique symbol;
|
|
148
|
+
declare const runnableNodeOutputType: unique symbol;
|
|
149
|
+
/**
|
|
150
|
+
* Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
|
|
151
|
+
* **`TOutputJson`** is emitted `item.json` on outputs.
|
|
152
|
+
*/
|
|
153
|
+
interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
|
|
154
|
+
readonly kind: "node";
|
|
155
|
+
readonly [runnableNodeInputType]?: TInputJson$1;
|
|
156
|
+
readonly [runnableNodeOutputType]?: TOutputJson$1;
|
|
157
|
+
/**
|
|
158
|
+
* Optional Zod input contract for {@link RunnableNode} when not set on the node class.
|
|
159
|
+
* Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
|
|
160
|
+
*/
|
|
161
|
+
readonly inputSchema?: ZodType<TInputJson$1>;
|
|
162
|
+
/**
|
|
163
|
+
* When an activation receives **zero** input items, the engine normally runs `execute` zero times.
|
|
164
|
+
* Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
|
|
165
|
+
* Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
|
|
166
|
+
*/
|
|
167
|
+
readonly emptyBatchExecution?: "skip" | "runOnce";
|
|
168
|
+
}
|
|
169
|
+
type PairedItemRef = Readonly<{
|
|
170
|
+
nodeId: NodeId;
|
|
171
|
+
output: OutputPortKey;
|
|
172
|
+
itemIndex: number;
|
|
173
|
+
}>;
|
|
174
|
+
type BinaryPreviewKind = "image" | "audio" | "video" | "download";
|
|
175
|
+
type BinaryAttachment = Readonly<{
|
|
176
|
+
id: string;
|
|
177
|
+
storageKey: string;
|
|
178
|
+
mimeType: string;
|
|
179
|
+
size: number;
|
|
180
|
+
storageDriver: string;
|
|
181
|
+
previewKind: BinaryPreviewKind;
|
|
182
|
+
createdAt: string;
|
|
183
|
+
runId: RunId;
|
|
184
|
+
workflowId: WorkflowId;
|
|
185
|
+
nodeId: NodeId;
|
|
186
|
+
activationId: NodeActivationId;
|
|
187
|
+
filename?: string;
|
|
188
|
+
sha256?: string;
|
|
189
|
+
}>;
|
|
190
|
+
type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
|
|
191
|
+
type Item<TJson = unknown> = Readonly<{
|
|
192
|
+
json: TJson;
|
|
193
|
+
binary?: ItemBinary;
|
|
194
|
+
meta?: Readonly<Record<string, unknown>>;
|
|
195
|
+
paired?: ReadonlyArray<PairedItemRef>;
|
|
196
|
+
}>;
|
|
197
|
+
type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
|
|
198
|
+
type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
|
|
199
|
+
type RunId = string;
|
|
200
|
+
type NodeActivationId = string;
|
|
201
|
+
/**
|
|
202
|
+
* One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
|
|
203
|
+
* per-item connection invocations and telemetry. Undefined when the executing node is a batch
|
|
204
|
+
* node or trigger that does not iterate items.
|
|
205
|
+
*/
|
|
206
|
+
type NodeIterationId = string;
|
|
207
|
+
interface ParentExecutionRef {
|
|
208
|
+
runId: RunId;
|
|
209
|
+
workflowId: WorkflowId;
|
|
210
|
+
nodeId: NodeId;
|
|
211
|
+
/** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
|
|
212
|
+
subworkflowDepth?: number;
|
|
213
|
+
/** Effective max node activations from the parent run (propagated to child policy merge). */
|
|
214
|
+
engineMaxNodeActivations?: number;
|
|
215
|
+
/** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
|
|
216
|
+
engineMaxSubworkflowDepth?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Test-suite linkage inherited by the child subworkflow run. Set by whichever node
|
|
219
|
+
* spawns the subworkflow when its own `ctx.testContext` is present, so assertions
|
|
220
|
+
* emitted inside a subworkflow land under the correct parent test case.
|
|
221
|
+
*/
|
|
222
|
+
testContext?: RunTestContext;
|
|
223
|
+
}
|
|
224
|
+
interface RunDataSnapshot {
|
|
225
|
+
getOutputs(nodeId: NodeId): NodeOutputs | undefined;
|
|
226
|
+
getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
|
|
227
|
+
getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
|
|
228
|
+
}
|
|
229
|
+
interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
|
|
230
|
+
readonly kind: "single" | "multi";
|
|
231
|
+
readonly items: Items;
|
|
232
|
+
readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
|
|
233
|
+
readonly ctx: NodeExecutionContext<TConfig>;
|
|
234
|
+
readonly error: Error;
|
|
235
|
+
}
|
|
236
|
+
interface NodeErrorHandler {
|
|
237
|
+
handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
|
|
238
|
+
}
|
|
239
|
+
type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
|
|
240
|
+
//#endregion
|
|
34
241
|
//#region ../core/src/contracts/telemetryTypes.d.ts
|
|
35
242
|
type TelemetryAttributePrimitive = string | number | boolean | null;
|
|
36
243
|
interface TelemetryAttributes {
|
|
@@ -87,6 +294,17 @@ interface TelemetrySpanScope extends TelemetryScope {
|
|
|
87
294
|
readonly traceId: string;
|
|
88
295
|
readonly spanId: string;
|
|
89
296
|
end(args?: TelemetrySpanEnd): Promise<void> | void;
|
|
297
|
+
/**
|
|
298
|
+
* Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
|
|
299
|
+
* Children created via the returned telemetry's `startChildSpan` get this span as their parent.
|
|
300
|
+
*
|
|
301
|
+
* Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
|
|
302
|
+
* span instead of the orchestrator's node-level span.
|
|
303
|
+
*/
|
|
304
|
+
asNodeTelemetry(args: Readonly<{
|
|
305
|
+
nodeId: NodeId;
|
|
306
|
+
activationId: NodeActivationId;
|
|
307
|
+
}>): NodeExecutionTelemetry;
|
|
90
308
|
}
|
|
91
309
|
interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
|
|
92
310
|
startChildSpan(args: TelemetryChildSpanStart): TelemetrySpanScope;
|
|
@@ -123,31 +341,70 @@ interface CostTrackingTelemetry {
|
|
|
123
341
|
forScope(scope: TelemetryScope): CostTrackingTelemetry;
|
|
124
342
|
}
|
|
125
343
|
//#endregion
|
|
126
|
-
//#region ../core/src/contracts/
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
344
|
+
//#region ../core/src/contracts/collectionTypes.d.ts
|
|
345
|
+
/**
|
|
346
|
+
* Represents a typed store for a single collection.
|
|
347
|
+
* All rows include auto-managed id, created_at, and updated_at fields.
|
|
348
|
+
*/
|
|
349
|
+
interface CollectionStore<TRow extends Record<string, unknown> = Record<string, unknown>> {
|
|
350
|
+
/**
|
|
351
|
+
* Insert a new row. id, created_at, and updated_at are auto-populated.
|
|
352
|
+
*/
|
|
353
|
+
insert(row: TRow): Promise<TRow & {
|
|
354
|
+
id: string;
|
|
355
|
+
created_at: Date;
|
|
356
|
+
updated_at: Date;
|
|
357
|
+
}>;
|
|
358
|
+
/**
|
|
359
|
+
* Get a single row by id.
|
|
360
|
+
*/
|
|
361
|
+
get(id: string): Promise<(TRow & {
|
|
362
|
+
id: string;
|
|
363
|
+
created_at: Date;
|
|
364
|
+
updated_at: Date;
|
|
365
|
+
}) | null>;
|
|
366
|
+
/**
|
|
367
|
+
* Find a single row matching the provided filter.
|
|
368
|
+
*/
|
|
369
|
+
findOne(filter: Partial<TRow>): Promise<(TRow & {
|
|
370
|
+
id: string;
|
|
371
|
+
created_at: Date;
|
|
372
|
+
updated_at: Date;
|
|
373
|
+
}) | null>;
|
|
374
|
+
/**
|
|
375
|
+
* List rows with optional pagination and filtering.
|
|
376
|
+
*/
|
|
377
|
+
list(opts?: {
|
|
378
|
+
limit?: number;
|
|
379
|
+
offset?: number;
|
|
380
|
+
where?: Partial<TRow>;
|
|
381
|
+
}): Promise<{
|
|
382
|
+
rows: ReadonlyArray<TRow & {
|
|
383
|
+
id: string;
|
|
384
|
+
created_at: Date;
|
|
385
|
+
updated_at: Date;
|
|
386
|
+
}>;
|
|
387
|
+
total: number;
|
|
388
|
+
}>;
|
|
389
|
+
/**
|
|
390
|
+
* Update a row by id with partial data.
|
|
391
|
+
*/
|
|
392
|
+
update(id: string, patch: Partial<TRow>): Promise<TRow & {
|
|
393
|
+
id: string;
|
|
394
|
+
created_at: Date;
|
|
395
|
+
updated_at: Date;
|
|
396
|
+
}>;
|
|
397
|
+
/**
|
|
398
|
+
* Delete a row by id. Hard delete only (no soft delete).
|
|
399
|
+
*/
|
|
400
|
+
delete(id: string): Promise<{
|
|
401
|
+
deleted: boolean;
|
|
402
|
+
}>;
|
|
134
403
|
}
|
|
135
|
-
/**
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
type
|
|
139
|
-
invocationId: ConnectionInvocationId;
|
|
140
|
-
connectionNodeId: NodeId;
|
|
141
|
-
parentAgentNodeId: NodeId;
|
|
142
|
-
parentAgentActivationId: NodeActivationId;
|
|
143
|
-
status: NodeExecutionStatus;
|
|
144
|
-
managedInput?: JsonValue;
|
|
145
|
-
managedOutput?: JsonValue;
|
|
146
|
-
error?: NodeExecutionError;
|
|
147
|
-
queuedAt?: string;
|
|
148
|
-
startedAt?: string;
|
|
149
|
-
finishedAt?: string;
|
|
150
|
-
}>;
|
|
404
|
+
/**
|
|
405
|
+
* Runtime collections context: keyed by collection name.
|
|
406
|
+
*/
|
|
407
|
+
type CollectionsContext = Readonly<Record<string, CollectionStore>>;
|
|
151
408
|
//#endregion
|
|
152
409
|
//#region ../core/src/contracts/runtimeTypes.d.ts
|
|
153
410
|
interface NodeExecutionStatePublisher {
|
|
@@ -214,6 +471,21 @@ interface ExecutionContext {
|
|
|
214
471
|
telemetry: ExecutionTelemetry;
|
|
215
472
|
binary: ExecutionBinaryService;
|
|
216
473
|
getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
|
|
474
|
+
/** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
|
|
475
|
+
iterationId?: NodeIterationId;
|
|
476
|
+
/** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
|
|
477
|
+
itemIndex?: number;
|
|
478
|
+
/** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
|
|
479
|
+
parentInvocationId?: ConnectionInvocationId;
|
|
480
|
+
/**
|
|
481
|
+
* Present iff the run was started by a TestSuiteOrchestrator. The {@link IsTestRunNode}
|
|
482
|
+
* branches on this; assertion-emitting nodes use it to decide whether to record results.
|
|
483
|
+
*/
|
|
484
|
+
testContext?: RunTestContext;
|
|
485
|
+
/**
|
|
486
|
+
* Collections registered in the codemation config, keyed by collection name.
|
|
487
|
+
*/
|
|
488
|
+
readonly collections?: CollectionsContext;
|
|
217
489
|
}
|
|
218
490
|
interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfigBase> extends ExecutionContext {
|
|
219
491
|
nodeId: NodeId;
|
|
@@ -249,142 +521,6 @@ interface RunnableNode<TConfig extends RunnableNodeConfig<any, any> = RunnableNo
|
|
|
249
521
|
execute(args: RunnableNodeExecuteArgs<TConfig, TInputJson$1>): Promise<unknown> | unknown;
|
|
250
522
|
}
|
|
251
523
|
//#endregion
|
|
252
|
-
//#region ../core/src/contracts/workflowTypes.d.ts
|
|
253
|
-
type WorkflowId = string;
|
|
254
|
-
type NodeId = string;
|
|
255
|
-
type NodeIdRef<TJson = unknown> = NodeId & Readonly<{
|
|
256
|
-
__codemationNodeJson?: TJson;
|
|
257
|
-
}>;
|
|
258
|
-
type OutputPortKey = string;
|
|
259
|
-
type InputPortKey = string;
|
|
260
|
-
type NodeKind = "trigger" | "node";
|
|
261
|
-
type JsonPrimitive = string | number | boolean | null;
|
|
262
|
-
interface JsonObject {
|
|
263
|
-
readonly [key: string]: JsonValue;
|
|
264
|
-
}
|
|
265
|
-
type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
|
266
|
-
type JsonArray = ReadonlyArray<JsonValue>;
|
|
267
|
-
interface NodeConfigBase {
|
|
268
|
-
readonly kind: NodeKind;
|
|
269
|
-
readonly type: TypeToken<unknown>;
|
|
270
|
-
readonly name?: string;
|
|
271
|
-
readonly id?: NodeId;
|
|
272
|
-
readonly icon?: string;
|
|
273
|
-
readonly execution?: Readonly<{
|
|
274
|
-
hint?: "local" | "worker";
|
|
275
|
-
queue?: string;
|
|
276
|
-
}>;
|
|
277
|
-
/** In-process execute retries (runnable nodes). Triggers typically omit this. */
|
|
278
|
-
readonly retryPolicy?: RetryPolicySpec;
|
|
279
|
-
/** Recover from execute failures; return outputs to continue, or rethrow to fail the node. */
|
|
280
|
-
readonly nodeErrorHandler?: NodeErrorHandlerSpec;
|
|
281
|
-
/**
|
|
282
|
-
* When true, edges carrying zero items on an output port still schedule single-input downstream nodes.
|
|
283
|
-
* Decided from the **source** node that produced the (empty) output. Default (false/undefined): empty
|
|
284
|
-
* main batches skip downstream execution and propagate the empty path.
|
|
285
|
-
*/
|
|
286
|
-
readonly continueWhenEmptyOutput?: boolean;
|
|
287
|
-
/**
|
|
288
|
-
* Declared I/O port names for canvas authoring (unioned with ports inferred from edges).
|
|
289
|
-
* Use for dynamic routers (Switch) and future error ports.
|
|
290
|
-
*/
|
|
291
|
-
readonly declaredOutputPorts?: ReadonlyArray<OutputPortKey>;
|
|
292
|
-
readonly declaredInputPorts?: ReadonlyArray<InputPortKey>;
|
|
293
|
-
getCredentialRequirements?(): ReadonlyArray<CredentialRequirement>;
|
|
294
|
-
}
|
|
295
|
-
declare const runnableNodeInputType: unique symbol;
|
|
296
|
-
declare const runnableNodeOutputType: unique symbol;
|
|
297
|
-
/**
|
|
298
|
-
* Runnable node: **`TInputJson`** is what **`inputSchema`** validates on **`item.json`** (the wire payload).
|
|
299
|
-
* **`TOutputJson`** is emitted `item.json` on outputs.
|
|
300
|
-
*/
|
|
301
|
-
interface RunnableNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> extends NodeConfigBase {
|
|
302
|
-
readonly kind: "node";
|
|
303
|
-
readonly [runnableNodeInputType]?: TInputJson$1;
|
|
304
|
-
readonly [runnableNodeOutputType]?: TOutputJson$1;
|
|
305
|
-
/**
|
|
306
|
-
* Optional Zod input contract for {@link RunnableNode} when not set on the node class.
|
|
307
|
-
* Resolution order: node instance `inputSchema`, then config `inputSchema`, then `z.unknown()`.
|
|
308
|
-
*/
|
|
309
|
-
readonly inputSchema?: ZodType<TInputJson$1>;
|
|
310
|
-
/**
|
|
311
|
-
* When an activation receives **zero** input items, the engine normally runs `execute` zero times.
|
|
312
|
-
* Set to **`runOnce`** to run `execute` once with an empty `items` batch (and a synthetic wire item for schema parsing).
|
|
313
|
-
* Used by batch-style callback nodes (built-in `Callback`) so `callback([], ctx)` still runs.
|
|
314
|
-
*/
|
|
315
|
-
readonly emptyBatchExecution?: "skip" | "runOnce";
|
|
316
|
-
}
|
|
317
|
-
type PairedItemRef = Readonly<{
|
|
318
|
-
nodeId: NodeId;
|
|
319
|
-
output: OutputPortKey;
|
|
320
|
-
itemIndex: number;
|
|
321
|
-
}>;
|
|
322
|
-
type BinaryPreviewKind = "image" | "audio" | "video" | "download";
|
|
323
|
-
type BinaryAttachment = Readonly<{
|
|
324
|
-
id: string;
|
|
325
|
-
storageKey: string;
|
|
326
|
-
mimeType: string;
|
|
327
|
-
size: number;
|
|
328
|
-
storageDriver: string;
|
|
329
|
-
previewKind: BinaryPreviewKind;
|
|
330
|
-
createdAt: string;
|
|
331
|
-
runId: RunId;
|
|
332
|
-
workflowId: WorkflowId;
|
|
333
|
-
nodeId: NodeId;
|
|
334
|
-
activationId: NodeActivationId;
|
|
335
|
-
filename?: string;
|
|
336
|
-
sha256?: string;
|
|
337
|
-
}>;
|
|
338
|
-
type ItemBinary = Readonly<Record<string, BinaryAttachment>>;
|
|
339
|
-
type Item<TJson = unknown> = Readonly<{
|
|
340
|
-
json: TJson;
|
|
341
|
-
binary?: ItemBinary;
|
|
342
|
-
meta?: Readonly<Record<string, unknown>>;
|
|
343
|
-
paired?: ReadonlyArray<PairedItemRef>;
|
|
344
|
-
}>;
|
|
345
|
-
type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
|
|
346
|
-
type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
|
|
347
|
-
type RunId = string;
|
|
348
|
-
type NodeActivationId = string;
|
|
349
|
-
interface ParentExecutionRef {
|
|
350
|
-
runId: RunId;
|
|
351
|
-
workflowId: WorkflowId;
|
|
352
|
-
nodeId: NodeId;
|
|
353
|
-
/** Subworkflow depth of the **spawning** run (0 = root). Passed when starting a child run. */
|
|
354
|
-
subworkflowDepth?: number;
|
|
355
|
-
/** Effective max node activations from the parent run (propagated to child policy merge). */
|
|
356
|
-
engineMaxNodeActivations?: number;
|
|
357
|
-
/** Effective max subworkflow depth from the parent run (propagated to child policy merge). */
|
|
358
|
-
engineMaxSubworkflowDepth?: number;
|
|
359
|
-
}
|
|
360
|
-
interface RunDataSnapshot {
|
|
361
|
-
getOutputs(nodeId: NodeId): NodeOutputs | undefined;
|
|
362
|
-
getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
|
|
363
|
-
getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
|
|
364
|
-
}
|
|
365
|
-
interface NodeErrorHandlerArgs<TConfig extends NodeConfigBase = NodeConfigBase> {
|
|
366
|
-
readonly kind: "single" | "multi";
|
|
367
|
-
readonly items: Items;
|
|
368
|
-
readonly inputsByPort: Readonly<Record<InputPortKey, Items>> | undefined;
|
|
369
|
-
readonly ctx: NodeExecutionContext<TConfig>;
|
|
370
|
-
readonly error: Error;
|
|
371
|
-
}
|
|
372
|
-
interface NodeErrorHandler {
|
|
373
|
-
handle<TConfig extends NodeConfigBase>(args: NodeErrorHandlerArgs<TConfig>): Promise<NodeOutputs>;
|
|
374
|
-
}
|
|
375
|
-
type NodeErrorHandlerSpec = TypeToken<NodeErrorHandler> | NodeErrorHandler;
|
|
376
|
-
//#endregion
|
|
377
|
-
//#region ../core/src/contracts/credentialTypes.d.ts
|
|
378
|
-
type CredentialTypeId = string;
|
|
379
|
-
type CredentialRequirement = Readonly<{
|
|
380
|
-
slotKey: string;
|
|
381
|
-
label: string;
|
|
382
|
-
acceptedTypes: ReadonlyArray<CredentialTypeId>;
|
|
383
|
-
optional?: true;
|
|
384
|
-
helpText?: string;
|
|
385
|
-
helpUrl?: string;
|
|
386
|
-
}>;
|
|
387
|
-
//#endregion
|
|
388
524
|
//#region src/ExampleUppercaseNode.d.ts
|
|
389
525
|
declare class ExampleUppercaseNode implements RunnableNode<ExampleUppercase<Record<string, unknown>, string>> {
|
|
390
526
|
kind: "node";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemation/node-example",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.34",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
}
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@codemation/core": "
|
|
31
|
+
"@codemation/core": "2.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^25.3.5",
|