@codemation/core-nodes 1.0.0 → 1.0.2

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/dist/index.d.cts CHANGED
@@ -14,6 +14,69 @@ import { AssistantModelMessage, ModelMessage, ToolModelMessage } from "ai";
14
14
  */
15
15
  type CanvasIconName = string;
16
16
  //#endregion
17
+ //#region ../core/src/contracts/runTypes.d.ts
18
+
19
+ type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
20
+ type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
21
+ interface NodeExecutionError {
22
+ message: string;
23
+ name?: string;
24
+ stack?: string;
25
+ details?: JsonValue;
26
+ }
27
+ /** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
28
+ type ConnectionInvocationId = string;
29
+ /** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
30
+ type ConnectionInvocationAppendArgs = Readonly<{
31
+ invocationId: ConnectionInvocationId;
32
+ connectionNodeId: NodeId;
33
+ parentAgentNodeId: NodeId;
34
+ parentAgentActivationId: NodeActivationId;
35
+ status: NodeExecutionStatus;
36
+ managedInput?: JsonValue;
37
+ managedOutput?: JsonValue;
38
+ error?: NodeExecutionError;
39
+ queuedAt?: string;
40
+ startedAt?: string;
41
+ finishedAt?: string;
42
+ iterationId?: NodeIterationId;
43
+ itemIndex?: number;
44
+ parentInvocationId?: ConnectionInvocationId;
45
+ }>;
46
+ interface PendingNodeExecution {
47
+ runId: RunId;
48
+ activationId: NodeActivationId;
49
+ workflowId: WorkflowId;
50
+ nodeId: NodeId;
51
+ itemsIn: number;
52
+ inputsByPort: NodeInputsByPort;
53
+ receiptId: string;
54
+ queue?: string;
55
+ batchId?: string;
56
+ enqueuedAt: string;
57
+ }
58
+ type RunResult = {
59
+ runId: RunId;
60
+ workflowId: WorkflowId;
61
+ startedAt: string;
62
+ status: "completed";
63
+ outputs: Items;
64
+ } | {
65
+ runId: RunId;
66
+ workflowId: WorkflowId;
67
+ startedAt: string;
68
+ status: "pending";
69
+ pending: PendingNodeExecution;
70
+ } | {
71
+ runId: RunId;
72
+ workflowId: WorkflowId;
73
+ startedAt: string;
74
+ status: "failed";
75
+ error: {
76
+ message: string;
77
+ };
78
+ };
79
+ //#endregion
17
80
  //#region ../core/src/contracts/emitPorts.d.ts
18
81
  declare const EMIT_PORTS_BRAND: unique symbol;
19
82
  type PortsEmission = Readonly<{
@@ -134,6 +197,17 @@ interface TelemetrySpanScope extends TelemetryScope {
134
197
  readonly traceId: string;
135
198
  readonly spanId: string;
136
199
  end(args?: TelemetrySpanEnd): Promise<void> | void;
200
+ /**
201
+ * Lift this span into a {@link NodeExecutionTelemetry} scoped to a different (nodeId, activationId).
202
+ * Children created via the returned telemetry's `startChildSpan` get this span as their parent.
203
+ *
204
+ * Used at the sub-agent boundary so that nested runtime telemetry parents under the agent.tool.call
205
+ * span instead of the orchestrator's node-level span.
206
+ */
207
+ asNodeTelemetry(args: Readonly<{
208
+ nodeId: NodeId;
209
+ activationId: NodeActivationId;
210
+ }>): NodeExecutionTelemetry;
137
211
  }
138
212
  interface NodeExecutionTelemetry extends ExecutionTelemetry, TelemetrySpanScope {
139
213
  startChildSpan(args: TelemetryChildSpanStart): TelemetrySpanScope;
@@ -170,65 +244,6 @@ interface CostTrackingTelemetry {
170
244
  forScope(scope: TelemetryScope): CostTrackingTelemetry;
171
245
  }
172
246
  //#endregion
173
- //#region ../core/src/contracts/runTypes.d.ts
174
- type NodeInputsByPort = Readonly<Record<InputPortKey, Items>>;
175
- type NodeExecutionStatus = "pending" | "queued" | "running" | "completed" | "failed" | "skipped";
176
- interface NodeExecutionError {
177
- message: string;
178
- name?: string;
179
- stack?: string;
180
- details?: JsonValue;
181
- }
182
- /** Stable id for a single connection invocation row in {@link ConnectionInvocationRecord}. */
183
- type ConnectionInvocationId = string;
184
- /** Arguments for appending a {@link ConnectionInvocationRecord} (engine fills run/workflow ids and timestamps). */
185
- type ConnectionInvocationAppendArgs = Readonly<{
186
- invocationId: ConnectionInvocationId;
187
- connectionNodeId: NodeId;
188
- parentAgentNodeId: NodeId;
189
- parentAgentActivationId: NodeActivationId;
190
- status: NodeExecutionStatus;
191
- managedInput?: JsonValue;
192
- managedOutput?: JsonValue;
193
- error?: NodeExecutionError;
194
- queuedAt?: string;
195
- startedAt?: string;
196
- finishedAt?: string;
197
- }>;
198
- interface PendingNodeExecution {
199
- runId: RunId;
200
- activationId: NodeActivationId;
201
- workflowId: WorkflowId;
202
- nodeId: NodeId;
203
- itemsIn: number;
204
- inputsByPort: NodeInputsByPort;
205
- receiptId: string;
206
- queue?: string;
207
- batchId?: string;
208
- enqueuedAt: string;
209
- }
210
- type RunResult = {
211
- runId: RunId;
212
- workflowId: WorkflowId;
213
- startedAt: string;
214
- status: "completed";
215
- outputs: Items;
216
- } | {
217
- runId: RunId;
218
- workflowId: WorkflowId;
219
- startedAt: string;
220
- status: "pending";
221
- pending: PendingNodeExecution;
222
- } | {
223
- runId: RunId;
224
- workflowId: WorkflowId;
225
- startedAt: string;
226
- status: "failed";
227
- error: {
228
- message: string;
229
- };
230
- };
231
- //#endregion
232
247
  //#region ../core/src/contracts/webhookTypes.d.ts
233
248
  type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
234
249
  interface WebhookControlSignal {
@@ -385,6 +400,12 @@ interface ExecutionContext {
385
400
  telemetry: ExecutionTelemetry;
386
401
  binary: ExecutionBinaryService;
387
402
  getCredential<TSession = unknown>(slotKey: string): Promise<TSession>;
403
+ /** Per-item iteration id, set by {@link NodeExecutor} on the ctx passed into runnable `execute`. */
404
+ iterationId?: NodeIterationId;
405
+ /** Item index (0-based) within the current activation's batch; set alongside {@link iterationId}. */
406
+ itemIndex?: number;
407
+ /** When set, this ctx is executing inside a sub-agent triggered by the named parent invocation. */
408
+ parentInvocationId?: ConnectionInvocationId;
388
409
  }
389
410
  interface NodeExecutionContext<TConfig extends NodeConfigBase = NodeConfigBase> extends ExecutionContext {
390
411
  nodeId: NodeId;
@@ -620,6 +641,12 @@ type Items<TJson = unknown> = ReadonlyArray<Item<TJson>>;
620
641
  type NodeOutputs = Partial<Record<OutputPortKey, Items>>;
621
642
  type RunId = string;
622
643
  type NodeActivationId = string;
644
+ /**
645
+ * One per-item iteration of a runnable node's execute loop. Refines `NodeActivationId` for
646
+ * per-item connection invocations and telemetry. Undefined when the executing node is a batch
647
+ * node or trigger that does not iterate items.
648
+ */
649
+ type NodeIterationId = string;
623
650
  interface ParentExecutionRef {
624
651
  runId: RunId;
625
652
  workflowId: WorkflowId;
@@ -636,6 +663,9 @@ interface RunDataSnapshot {
636
663
  getOutputItems<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, output?: OutputPortKey): Items<TJson>;
637
664
  getOutputItem<TJson = unknown>(nodeId: NodeId | NodeIdRef<TJson>, itemIndex: number, output?: OutputPortKey): Item<TJson> | undefined;
638
665
  }
666
+ interface ActivationIdFactory {
667
+ makeActivationId(): NodeActivationId;
668
+ }
639
669
  type UpstreamRefPlaceholder = `$${number}`;
640
670
  /** Whether to persist run execution data after the workflow finishes. */
641
671
  type WorkflowStoragePolicyMode = "ALL" | "SUCCESS" | "ERROR" | "NEVER";
@@ -897,6 +927,15 @@ type ToolExecuteArgs<TConfig extends ToolConfig = ToolConfig, TInput = unknown>
897
927
  item: Item;
898
928
  itemIndex: number;
899
929
  items: Items;
930
+ /**
931
+ * Optional sub-agent boundary hooks: when present, the live `agent.tool.call` span and the
932
+ * planned tool-call invocationId are forwarded so node-backed runtimes can re-root their child
933
+ * execution scope. Plain function tools may safely ignore these hooks.
934
+ */
935
+ hooks?: Readonly<{
936
+ parentSpan?: TelemetrySpanScope;
937
+ parentInvocationId?: ConnectionInvocationId;
938
+ }>;
900
939
  }>;
901
940
  type AgentMessageRole = "system" | "user" | "assistant";
902
941
  type AgentMessageBuildArgs<TInputJson$1 = unknown> = Readonly<{
@@ -1024,6 +1063,29 @@ interface AgentNodeConfig<TInputJson$1 = unknown, TOutputJson$1 = unknown> exten
1024
1063
  readonly outputSchema?: ZodType<TOutputJson$1>;
1025
1064
  }
1026
1065
  //#endregion
1066
+ //#region ../core/src/execution/ChildExecutionScopeFactory.d.ts
1067
+ /**
1068
+ * Builds a re-rooted child execution context for sub-agent (and other deeply-nested) invocations.
1069
+ *
1070
+ * At the orchestrator's `agent.tool.call` boundary the inner runtime needs a ctx whose:
1071
+ * - `nodeId` is the tool's connection node id (so inner LLM/tool connection ids derive correctly),
1072
+ * - `activationId` is fresh (so its connection-invocation rows are uniquely identifiable),
1073
+ * - `telemetry` parents children under the tool-call span (not the orchestrator's node span),
1074
+ * - `binary` is scoped to the new (nodeId, activationId),
1075
+ * - `parentInvocationId` points back to the tool-call invocation for downstream lineage.
1076
+ */
1077
+ declare class ChildExecutionScopeFactory {
1078
+ private readonly activationIdFactory;
1079
+ constructor(activationIdFactory: ActivationIdFactory);
1080
+ forSubAgent<TConfig extends RunnableNodeConfig<any, any>>(args: Readonly<{
1081
+ parentCtx: NodeExecutionContext<TConfig>;
1082
+ childNodeId: NodeId;
1083
+ childConfig: TConfig;
1084
+ parentInvocationId: ConnectionInvocationId;
1085
+ parentSpan: TelemetrySpanScope;
1086
+ }>): NodeExecutionContext<TConfig>;
1087
+ }
1088
+ //#endregion
1027
1089
  //#region ../core/src/execution/ItemExprResolver.d.ts
1028
1090
  /**
1029
1091
  * Resolves {@link import("../contracts/itemExpr").ItemExpr} leaves on runnable config before {@link RunnableNode.execute}.
@@ -1205,19 +1267,31 @@ type ResolvedTool = Readonly<{
1205
1267
  }>;
1206
1268
  /**
1207
1269
  * Per-item binding of a tool: the user config plus the resolved runtime and a snapshot of the
1208
- * original Zod `inputSchema` used to convert to AI SDK `Tool` + OpenAI-strict JSON Schema for
1209
- * repair prompts.
1270
+ * original Zod `inputSchema`.
1271
+ *
1272
+ * `execute` accepts optional `hooks` so the agent coordinator can pass the live `agent.tool.call`
1273
+ * span and the planned tool-call's `invocationId`. Node-backed sub-agent tools use these hooks
1274
+ * via {@link ChildExecutionScopeFactory} to re-root their runtime ctx under the tool-call boundary
1275
+ * (fresh activationId, telemetry parented at the tool-call span, `parentInvocationId` set).
1210
1276
  */
1211
1277
  type ItemScopedToolBinding = Readonly<{
1212
1278
  config: ToolConfig;
1213
1279
  inputSchema: ZodSchemaAny;
1214
- execute(input: unknown): Promise<unknown>;
1280
+ execute(input: unknown, hooks?: ItemScopedToolCallHooks): Promise<unknown>;
1281
+ }>;
1282
+ type ItemScopedToolCallHooks = Readonly<{
1283
+ /** Live agent.tool.call span (used to parent sub-agent telemetry). */
1284
+ parentSpan?: TelemetrySpanScope;
1285
+ /** invocationId of the parent tool call (used to thread `parentInvocationId` through ctx). */
1286
+ parentInvocationId?: ConnectionInvocationId;
1215
1287
  }>;
1216
1288
  type PlannedToolCall = Readonly<{
1217
1289
  binding: ItemScopedToolBinding;
1218
1290
  toolCall: AgentToolCall;
1219
1291
  invocationIndex: number;
1220
1292
  nodeId: string;
1293
+ /** Stable id reused across queued / running / completed connection invocation rows for this tool call. */
1294
+ invocationId: string;
1221
1295
  }>;
1222
1296
  type ExecutedToolCall = Readonly<{
1223
1297
  toolName: string;
@@ -1442,8 +1516,24 @@ declare class NodeBackedToolRuntime {
1442
1516
  private readonly itemExprResolver;
1443
1517
  private readonly outputNormalizer;
1444
1518
  private readonly outputBehaviorResolver;
1445
- constructor(nodeResolver: NodeResolver, itemExprResolver: ItemExprResolver, outputNormalizer: NodeOutputNormalizer, outputBehaviorResolver: RunnableOutputBehaviorResolver);
1519
+ private readonly childExecutionScopeFactory;
1520
+ constructor(nodeResolver: NodeResolver, itemExprResolver: ItemExprResolver, outputNormalizer: NodeOutputNormalizer, outputBehaviorResolver: RunnableOutputBehaviorResolver, childExecutionScopeFactory: ChildExecutionScopeFactory);
1446
1521
  execute(config: NodeBackedToolConfig<any, ZodSchemaAny, ZodSchemaAny>, args: ToolExecuteArgs): Promise<unknown>;
1522
+ /**
1523
+ * Returns a re-rooted child ctx for nested-agent tools (so their LLM/tool connection ids derive
1524
+ * from the tool connection node, telemetry parents under the tool-call span, and connection
1525
+ * invocations carry `parentInvocationId`). Plain runnable tools (non-agent) keep the orchestrator
1526
+ * ctx with only `config` swapped — no nesting concern.
1527
+ *
1528
+ * The caller (`AIAgentNode.createItemScopedTools`) already wraps the orchestrator ctx via
1529
+ * `ConnectionCredentialExecutionContextFactory.forConnectionNode`, so `args.ctx.nodeId` is the
1530
+ * tool's own connection node id (e.g. `AIAgentNode:2__conn__tool__searchInMail`). We pass that
1531
+ * through as the sub-agent's `nodeId`; deriving another `toolConnectionNodeId(args.ctx.nodeId,
1532
+ * config.name)` here would prepend a duplicate `__conn__tool__<name>` segment and exponentially
1533
+ * deepen ids on each invocation, which also breaks credential resolution because user-provided
1534
+ * bindings sit on the single-level connection node id.
1535
+ */
1536
+ private resolveNodeCtx;
1447
1537
  private executeResolvedNode;
1448
1538
  private isRunnableNode;
1449
1539
  private isMultiInputNode;
@@ -1510,6 +1600,14 @@ declare class AIAgentNode implements RunnableNode<AIAgent<any, any>> {
1510
1600
  private invokeStructuredTurn;
1511
1601
  private isZodSchema;
1512
1602
  private resolveCallOptions;
1603
+ /**
1604
+ * Build a no-code-friendly output payload for an LLM round.
1605
+ *
1606
+ * Always includes `content` (matching the canvas snapshot shape used elsewhere) and adds a
1607
+ * `toolCalls` array when the round produced tool calls so the execution inspector surfaces the
1608
+ * planned calls instead of just an empty `""` for tool-only rounds.
1609
+ */
1610
+ private summarizeTurnOutput;
1513
1611
  private extractTurnResult;
1514
1612
  private extractAssistantMessage;
1515
1613
  private extractUsageFromResult;
@@ -1615,6 +1713,7 @@ declare class HttpRequest<TInputJson$1 = Readonly<{
1615
1713
  readonly execution: {
1616
1714
  readonly hint: "local";
1617
1715
  };
1716
+ readonly icon: "lucide:globe";
1618
1717
  constructor(name: string, args?: Readonly<{
1619
1718
  method?: string;
1620
1719
  urlField?: string;
@@ -1647,7 +1746,7 @@ declare class Aggregate<TIn = unknown, TOut = unknown> implements RunnableNodeCo
1647
1746
  readonly hint: "local";
1648
1747
  };
1649
1748
  readonly keepBinaries: true;
1650
- readonly icon: "lucide:layers";
1749
+ readonly icon: "builtin:aggregate-rows";
1651
1750
  constructor(name: string, aggregate: (items: Items<TIn>, ctx: NodeExecutionContext<Aggregate<TIn, TOut>>) => TOut | Promise<TOut>, id?: string | undefined);
1652
1751
  }
1653
1752
  //#endregion
@@ -1688,7 +1787,7 @@ declare class If<TInputJson$1 = unknown> implements RunnableNodeConfig<TInputJso
1688
1787
  readonly execution: {
1689
1788
  readonly hint: "local";
1690
1789
  };
1691
- readonly icon: "lucide:split";
1790
+ readonly icon: "lucide:split@rot=90";
1692
1791
  readonly declaredOutputPorts: readonly ["true", "false"];
1693
1792
  constructor(name: string, predicate: (item: Item<TInputJson$1>, index: number, items: Items<TInputJson$1>, ctx: NodeExecutionContext<If<TInputJson$1>>) => boolean, id?: string | undefined);
1694
1793
  }
@@ -1749,7 +1848,7 @@ declare class Split<TIn = unknown, TElem = unknown> implements RunnableNodeConfi
1749
1848
  * Mirrors {@link MapData}'s empty-output behavior.
1750
1849
  */
1751
1850
  readonly continueWhenEmptyOutput: true;
1752
- readonly icon: "lucide:ungroup";
1851
+ readonly icon: "builtin:split-rows";
1753
1852
  constructor(name: string, getElements: (item: Item<TIn>, ctx: NodeExecutionContext<Split<TIn, TElem>>) => readonly TElem[], id?: string | undefined);
1754
1853
  }
1755
1854
  //#endregion
@@ -1809,6 +1908,7 @@ declare class MapData<TInputJson$1 = unknown, TOutputJson$1 = unknown> implement
1809
1908
  };
1810
1909
  /** Zero mapped items should still allow downstream nodes to run. */
1811
1910
  readonly continueWhenEmptyOutput: true;
1911
+ readonly icon: "lucide:square-pen";
1812
1912
  readonly keepBinaries: boolean;
1813
1913
  constructor(name: string, map: (item: Item<TInputJson$1>, ctx: NodeExecutionContext<MapData<TInputJson$1, TOutputJson$1>>) => TOutputJson$1, options?: MapDataOptions);
1814
1914
  get id(): string | undefined;
@@ -1836,7 +1936,7 @@ declare class Merge<TInputJson$1 = unknown, TOutputJson$1 = TInputJson$1> implem
1836
1936
  readonly id?: string | undefined;
1837
1937
  readonly kind: "node";
1838
1938
  readonly type: TypeToken<unknown>;
1839
- readonly icon: "lucide:git-merge";
1939
+ readonly icon: "lucide:merge@rot=90";
1840
1940
  constructor(name: string, cfg?: Readonly<{
1841
1941
  mode: MergeMode;
1842
1942
  /**
@@ -1863,6 +1963,7 @@ declare class NoOp<TItemJson = unknown> implements RunnableNodeConfig<TItemJson,
1863
1963
  readonly execution: {
1864
1964
  readonly hint: "local";
1865
1965
  };
1966
+ readonly icon: "lucide:circle-dashed";
1866
1967
  constructor(name?: string, id?: string | undefined);
1867
1968
  }
1868
1969
  //#endregion
@@ -1915,6 +2016,7 @@ declare class Wait<TItemJson = unknown> implements RunnableNodeConfig<TItemJson,
1915
2016
  };
1916
2017
  /** Pass-through empty batches should still advance to downstream nodes. */
1917
2018
  readonly continueWhenEmptyOutput: true;
2019
+ readonly icon: "lucide:hourglass";
1918
2020
  constructor(name: string, milliseconds: number, id?: string | undefined);
1919
2021
  }
1920
2022
  //#endregion
@@ -1945,7 +2047,7 @@ declare class WebhookTrigger<TSchema extends WebhookInputSchema | undefined = un
1945
2047
  readonly id?: string | undefined;
1946
2048
  readonly kind: "trigger";
1947
2049
  readonly type: TypeToken<unknown>;
1948
- readonly icon = "lucide:globe";
2050
+ readonly icon = "lucide:webhook";
1949
2051
  constructor(name: string, args: Readonly<{
1950
2052
  endpointKey: string;
1951
2053
  methods: ReadonlyArray<HttpMethod>;