@nodetool-ai/node-sdk 0.7.0-rc.23 → 0.8.1
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/README.md +34 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/base-node.d.ts +253 -13
- package/dist/base-node.d.ts.map +1 -1
- package/dist/base-node.js +337 -49
- package/dist/base-node.js.map +1 -1
- package/dist/class-name-to-title.d.ts +26 -0
- package/dist/class-name-to-title.d.ts.map +1 -0
- package/dist/class-name-to-title.js +59 -0
- package/dist/class-name-to-title.js.map +1 -0
- package/dist/code-analysis.d.ts +222 -0
- package/dist/code-analysis.d.ts.map +1 -0
- package/dist/code-analysis.js +803 -0
- package/dist/code-analysis.js.map +1 -0
- package/dist/code-body.d.ts +61 -0
- package/dist/code-body.d.ts.map +1 -0
- package/dist/code-body.js +288 -0
- package/dist/code-body.js.map +1 -0
- package/dist/code-node-validation.d.ts +67 -0
- package/dist/code-node-validation.d.ts.map +1 -0
- package/dist/code-node-validation.js +540 -0
- package/dist/code-node-validation.js.map +1 -0
- package/dist/content-card.d.ts +30 -0
- package/dist/content-card.d.ts.map +1 -0
- package/dist/content-card.js +68 -0
- package/dist/content-card.js.map +1 -0
- package/dist/correlation-validation.d.ts +19 -0
- package/dist/correlation-validation.d.ts.map +1 -0
- package/dist/correlation-validation.js +101 -0
- package/dist/correlation-validation.js.map +1 -0
- package/dist/cost-estimate.d.ts +244 -0
- package/dist/cost-estimate.d.ts.map +1 -0
- package/dist/cost-estimate.js +636 -0
- package/dist/cost-estimate.js.map +1 -0
- package/dist/decorators.d.ts.map +1 -1
- package/dist/decorators.js +4 -1
- package/dist/decorators.js.map +1 -1
- package/dist/docs/nodes.d.ts.map +1 -1
- package/dist/docs/nodes.js +3 -2
- package/dist/docs/nodes.js.map +1 -1
- package/dist/docs/overview.d.ts.map +1 -1
- package/dist/docs/overview.js +4 -3
- package/dist/docs/overview.js.map +1 -1
- package/dist/docs/workflows.d.ts.map +1 -1
- package/dist/docs/workflows.js +10 -9
- package/dist/docs/workflows.js.map +1 -1
- package/dist/field-classification.d.ts +31 -0
- package/dist/field-classification.d.ts.map +1 -0
- package/dist/field-classification.js +58 -0
- package/dist/field-classification.js.map +1 -0
- package/dist/graph-validation.d.ts +239 -0
- package/dist/graph-validation.d.ts.map +1 -0
- package/dist/graph-validation.js +1165 -0
- package/dist/graph-validation.js.map +1 -0
- package/dist/index.d.ts +27 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/js-script-link.d.ts +53 -0
- package/dist/js-script-link.d.ts.map +1 -0
- package/dist/js-script-link.js +58 -0
- package/dist/js-script-link.js.map +1 -0
- package/dist/js-script-materialize.d.ts +52 -0
- package/dist/js-script-materialize.d.ts.map +1 -0
- package/dist/js-script-materialize.js +24 -0
- package/dist/js-script-materialize.js.map +1 -0
- package/dist/manifest-node-values.d.ts +106 -0
- package/dist/manifest-node-values.d.ts.map +1 -0
- package/dist/manifest-node-values.js +195 -0
- package/dist/manifest-node-values.js.map +1 -0
- package/dist/metadata.d.ts +73 -3
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +132 -49
- package/dist/metadata.js.map +1 -1
- package/dist/node-metadata.d.ts.map +1 -1
- package/dist/node-metadata.js +58 -56
- package/dist/node-metadata.js.map +1 -1
- package/dist/node-type-inventory.d.ts +51 -0
- package/dist/node-type-inventory.d.ts.map +1 -0
- package/dist/node-type-inventory.js +121 -0
- package/dist/node-type-inventory.js.map +1 -0
- package/dist/nodes/test-nodes.d.ts +77 -30
- package/dist/nodes/test-nodes.d.ts.map +1 -1
- package/dist/nodes/test-nodes.js +2 -34
- package/dist/nodes/test-nodes.js.map +1 -1
- package/dist/pack-loader.d.ts +202 -0
- package/dist/pack-loader.d.ts.map +1 -0
- package/dist/pack-loader.js +529 -0
- package/dist/pack-loader.js.map +1 -0
- package/dist/package-registry-client.d.ts.map +1 -1
- package/dist/package-registry-client.js +15 -6
- package/dist/package-registry-client.js.map +1 -1
- package/dist/port-types.d.ts +15 -0
- package/dist/port-types.d.ts.map +1 -0
- package/dist/port-types.js +72 -0
- package/dist/port-types.js.map +1 -0
- package/dist/pricing-bundle.d.ts +83 -0
- package/dist/pricing-bundle.d.ts.map +1 -0
- package/dist/pricing-bundle.js +82 -0
- package/dist/pricing-bundle.js.map +1 -0
- package/dist/pricing-params.d.ts +59 -0
- package/dist/pricing-params.d.ts.map +1 -0
- package/dist/pricing-params.js +282 -0
- package/dist/pricing-params.js.map +1 -0
- package/dist/python-package-scan.d.ts +8 -0
- package/dist/python-package-scan.d.ts.map +1 -1
- package/dist/python-package-scan.js +21 -8
- package/dist/python-package-scan.js.map +1 -1
- package/dist/registry.d.ts +105 -2
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +393 -30
- package/dist/registry.js.map +1 -1
- package/dist/sandbox-bridge-packs.d.ts +39 -0
- package/dist/sandbox-bridge-packs.d.ts.map +1 -0
- package/dist/sandbox-bridge-packs.js +249 -0
- package/dist/sandbox-bridge-packs.js.map +1 -0
- package/dist/sandbox-catalog-host.d.ts +31 -0
- package/dist/sandbox-catalog-host.d.ts.map +1 -0
- package/dist/sandbox-catalog-host.js +78 -0
- package/dist/sandbox-catalog-host.js.map +1 -0
- package/dist/sandbox-module-catalog.d.ts +14 -0
- package/dist/sandbox-module-catalog.d.ts.map +1 -0
- package/dist/sandbox-module-catalog.js +402 -0
- package/dist/sandbox-module-catalog.js.map +1 -0
- package/dist/sandbox-npm-artifacts.d.ts +56 -0
- package/dist/sandbox-npm-artifacts.d.ts.map +1 -0
- package/dist/sandbox-npm-artifacts.js +17 -0
- package/dist/sandbox-npm-artifacts.js.map +1 -0
- package/dist/sandbox-pack-discovery.d.ts +93 -0
- package/dist/sandbox-pack-discovery.d.ts.map +1 -0
- package/dist/sandbox-pack-discovery.js +807 -0
- package/dist/sandbox-pack-discovery.js.map +1 -0
- package/dist/search.d.ts +29 -1
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +136 -9
- package/dist/search.js.map +1 -1
- package/dist/type-compat.d.ts +36 -0
- package/dist/type-compat.d.ts.map +1 -0
- package/dist/type-compat.js +98 -0
- package/dist/type-compat.js.map +1 -0
- package/dist/type-predicates.d.ts +25 -0
- package/dist/type-predicates.d.ts.map +1 -0
- package/dist/type-predicates.js +31 -0
- package/dist/type-predicates.js.map +1 -0
- package/dist/validation.d.ts +18 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +70 -11
- package/dist/validation.js.map +1 -1
- package/dist/workflow-document-tools.d.ts +34 -0
- package/dist/workflow-document-tools.d.ts.map +1 -0
- package/dist/workflow-document-tools.js +357 -0
- package/dist/workflow-document-tools.js.map +1 -0
- package/dist/workflow-interface.d.ts +62 -0
- package/dist/workflow-interface.d.ts.map +1 -0
- package/dist/workflow-interface.js +351 -0
- package/dist/workflow-interface.js.map +1 -0
- package/package.json +67 -10
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @nodetool-ai/node-sdk
|
|
2
|
+
|
|
3
|
+
The node authoring SDK: `BaseNode`, the `@prop` decorator, `NodeRegistry`, the
|
|
4
|
+
type system, and node metadata/validation.
|
|
5
|
+
|
|
6
|
+
## Responsibilities
|
|
7
|
+
|
|
8
|
+
- `BaseNode` — base class all workflow nodes extend.
|
|
9
|
+
- `@prop` decorator + metadata reflection for declaring typed node properties.
|
|
10
|
+
- `NodeRegistry` — registration and lookup; `createNodeValidator()` for pre-flight
|
|
11
|
+
graph validation.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { BaseNode, prop } from "@nodetool-ai/node-sdk";
|
|
17
|
+
|
|
18
|
+
export class MyNode extends BaseNode {
|
|
19
|
+
static readonly nodeType = "my.Node";
|
|
20
|
+
@prop({ type: "str", default: "" }) declare text: string;
|
|
21
|
+
async process() { return { output: this.text }; }
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> This package uses decorators and loads from `dist/`. After changing it, run
|
|
26
|
+
> `npm run build:packages` before `npm run dev`.
|
|
27
|
+
|
|
28
|
+
## Develop
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run build --workspace=packages/node-sdk
|
|
32
|
+
npm run test --workspace=packages/node-sdk
|
|
33
|
+
npm run lint --workspace=packages/node-sdk
|
|
34
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2026-09-28T09:19:05.979Z
|
package/dist/base-node.d.ts
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
import type { NodeDescriptor,
|
|
1
|
+
import type { DynamicSlotMeta, InputMode, NodeDescriptor, NodeEffect, OutputCorrelation, Platform } from "@nodetool-ai/protocol";
|
|
2
2
|
import type { NodeExecutor } from "@nodetool-ai/kernel";
|
|
3
|
-
import type { ProcessingContext, StreamingInputs, StreamingOutputs } from "@nodetool-ai/runtime";
|
|
3
|
+
import type { ProcessingContext, StreamingInputs, StreamingOutputs, TriggerEvent } from "@nodetool-ai/runtime";
|
|
4
|
+
import type { TypeMetadata } from "./metadata.js";
|
|
4
5
|
import { type NodePropertyValidationIssue } from "./validation.js";
|
|
6
|
+
/**
|
|
7
|
+
* Coerce an incoming property value to fit the declared type.
|
|
8
|
+
*
|
|
9
|
+
* The only coercion today: when the declared type is `list[T]` and the
|
|
10
|
+
* value is a non-null scalar (not an array), wrap it in a one-element
|
|
11
|
+
* array. This lets a single upstream value flow into a list-typed input
|
|
12
|
+
* (e.g. a single Image into a `list[image]` slot) without a manual
|
|
13
|
+
* wrapper node.
|
|
14
|
+
*/
|
|
15
|
+
/** A URI string promoted to the tagged asset reference its slot declares. */
|
|
16
|
+
export interface CoercedAssetRef {
|
|
17
|
+
type: string;
|
|
18
|
+
uri: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function coerceToDeclaredType<TValue>(value: TValue, declaredType: string): TValue | TValue[] | CoercedAssetRef;
|
|
21
|
+
/**
|
|
22
|
+
* Coerce a value against a typed dynamic slot's declared type. Slots with no
|
|
23
|
+
* resolvable type string pass the value through untouched (legacy `any` slot).
|
|
24
|
+
*/
|
|
25
|
+
export declare function coerceToSlotType<TValue>(value: TValue, slot: DynamicSlotMeta | undefined): TValue | TValue[] | CoercedAssetRef;
|
|
5
26
|
export interface DeclaredOutputTypes {
|
|
6
27
|
[name: string]: string;
|
|
7
28
|
}
|
|
@@ -14,6 +35,17 @@ export interface NodeValidationOptions {
|
|
|
14
35
|
connectedHandles?: ReadonlySet<string> | ReadonlyArray<string>;
|
|
15
36
|
/** Node id to attach to issues. Defaults to the node's __node_id. */
|
|
16
37
|
nodeId?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Typed dynamic input slot declarations for this node instance
|
|
40
|
+
* (`Node.dynamic_inputs`). Slots absent from this map are untyped legacy
|
|
41
|
+
* slots and are never validated.
|
|
42
|
+
*/
|
|
43
|
+
dynamicSlots?: Record<string, DynamicSlotMeta>;
|
|
44
|
+
/**
|
|
45
|
+
* Inline values of the dynamic properties (`Node.dynamic_properties`).
|
|
46
|
+
* Defaults to the dynamic entries of `properties` when omitted.
|
|
47
|
+
*/
|
|
48
|
+
dynamicValues?: Record<string, unknown>;
|
|
17
49
|
}
|
|
18
50
|
export type NodeClass = {
|
|
19
51
|
new (properties?: Record<string, unknown>): BaseNode;
|
|
@@ -21,19 +53,62 @@ export type NodeClass = {
|
|
|
21
53
|
title: string;
|
|
22
54
|
description: string;
|
|
23
55
|
layout?: string;
|
|
56
|
+
body?: string;
|
|
24
57
|
recommendedModels?: unknown[];
|
|
25
|
-
|
|
58
|
+
inlineFields?: string[];
|
|
59
|
+
inputFields?: string[];
|
|
26
60
|
requiredSettings?: string[];
|
|
27
61
|
requiredRuntimes?: string[];
|
|
28
62
|
isStreamingInput: boolean;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Per-instance override of {@link isStreamingInput}. See
|
|
65
|
+
* `BaseNode.resolveStreamingInput`.
|
|
66
|
+
*/
|
|
67
|
+
resolveStreamingInput?: (node: {
|
|
68
|
+
properties?: Record<string, unknown>;
|
|
69
|
+
}) => boolean;
|
|
70
|
+
isTrigger: boolean;
|
|
71
|
+
alwaysEmitOutputUpdates?: boolean;
|
|
72
|
+
inputMode?: InputMode;
|
|
73
|
+
outputCorrelation?: Record<string, OutputCorrelation>;
|
|
74
|
+
supportsDynamicInputs: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Types a user may pick for a dynamic input slot on this node. Unset means
|
|
77
|
+
* the full type palette. Surfaced as `allowed_dynamic_slot_types`.
|
|
78
|
+
*/
|
|
79
|
+
allowedDynamicSlotTypes?: TypeMetadata[];
|
|
32
80
|
isControlled: boolean;
|
|
33
|
-
|
|
81
|
+
isJoinNode: boolean;
|
|
34
82
|
supportsDynamicOutputs?: boolean;
|
|
35
83
|
autoSaveAsset: boolean;
|
|
84
|
+
/** Opt-in: re-running with identical inputs is safe. See `BaseNode.retrySafe`. */
|
|
85
|
+
retrySafe: boolean;
|
|
86
|
+
cacheTtl?: number | "forever";
|
|
87
|
+
effect?: NodeEffect;
|
|
88
|
+
primaryOutput?: string;
|
|
36
89
|
modelPacks?: unknown[];
|
|
90
|
+
/**
|
|
91
|
+
* Deployment platforms this node supports. See `@nodetool-ai/protocol`'s
|
|
92
|
+
* Platform type. Unset is treated as ["node"].
|
|
93
|
+
*/
|
|
94
|
+
platforms?: readonly Platform[];
|
|
95
|
+
/**
|
|
96
|
+
* Requires a WebGPU device when run in the browser. The in-browser runner
|
|
97
|
+
* routes graphs containing these nodes to the server (where a GPU is always
|
|
98
|
+
* available via Dawn) when `navigator.gpu` is unavailable, instead of failing
|
|
99
|
+
* the run. Server execution is unaffected. Set via `tagAsBrowserGpu`.
|
|
100
|
+
*/
|
|
101
|
+
requiresGpu?: boolean;
|
|
102
|
+
deprecated: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Hide from node-discovery UIs (palette, search) while keeping the node
|
|
105
|
+
* registered and runnable. Unlike `deprecated` (which down-ranks and badges
|
|
106
|
+
* a still-discoverable node), a hidden node is filtered out of the palette
|
|
107
|
+
* entirely. Used for internal nodes the user never adds by hand. Set via a
|
|
108
|
+
* `static readonly hidden = true` on the node class.
|
|
109
|
+
*/
|
|
110
|
+
hidden?: boolean;
|
|
111
|
+
replacedBy?: string;
|
|
37
112
|
metadataOutputTypes?: DeclaredOutputTypes;
|
|
38
113
|
outputTypes: DeclaredOutputTypes;
|
|
39
114
|
getDeclaredProperties(): Array<{
|
|
@@ -61,32 +136,181 @@ type BaseNodeKey = keyof BaseNode | "dynamicProps";
|
|
|
61
136
|
* ```
|
|
62
137
|
*/
|
|
63
138
|
export type NodeProps<T extends BaseNode> = Partial<Pick<T, Exclude<keyof T, BaseNodeKey | `__${string}` | `_${string}`>>>;
|
|
139
|
+
/**
|
|
140
|
+
* True if a class is a streaming-output node. Streaming is purely structural:
|
|
141
|
+
*
|
|
142
|
+
* 1. Subclass overrides `genProcess` → it yields multiple values.
|
|
143
|
+
* 2. Any output handle declares `forward`, `iteration`, or `chunk`
|
|
144
|
+
* correlation → the node emits per-input or per-iteration. `single`
|
|
145
|
+
* and `aggregate` correlations indicate one value per execution.
|
|
146
|
+
*
|
|
147
|
+
* This lets pure-`process()` filter/reroute/forward nodes (IfNode, Output,
|
|
148
|
+
* FilterNone, etc.) declare streaming via correlation alone, and generator
|
|
149
|
+
* nodes (ForEach, Collection, GetVariable) via the `genProcess` override —
|
|
150
|
+
* no flag needed. Mirrors the Python side, which derives the same boolean
|
|
151
|
+
* solely from whether `gen_process` is overridden.
|
|
152
|
+
*/
|
|
153
|
+
/**
|
|
154
|
+
* What {@link hasStreamingOutput} reads. Written as the two members it touches
|
|
155
|
+
* so the abstract `typeof BaseNode` — which cannot satisfy `NodeClass`'s
|
|
156
|
+
* concrete constructor — can be passed as well as a registered node class.
|
|
157
|
+
*/
|
|
158
|
+
type StreamingOutputSource = Pick<NodeClass, "outputCorrelation"> & {
|
|
159
|
+
prototype: BaseNode;
|
|
160
|
+
};
|
|
161
|
+
export declare const hasStreamingOutput: (cls: StreamingOutputSource) => boolean;
|
|
64
162
|
export declare abstract class BaseNode {
|
|
65
163
|
static readonly nodeType: string;
|
|
66
164
|
static readonly title: string;
|
|
67
165
|
static readonly description: string;
|
|
68
166
|
static readonly layout: string | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Node body renderer key. Set to "content_card" to render a media/text-forward
|
|
169
|
+
* content card instead of the generic input/output body. Generator packages
|
|
170
|
+
* typically derive this from the primary output type on a shared base class
|
|
171
|
+
* (mirrors the Python `_body`/`body()` convention).
|
|
172
|
+
*/
|
|
173
|
+
static readonly body: string | undefined;
|
|
69
174
|
static readonly recommendedModels: unknown[] | undefined;
|
|
70
|
-
static readonly
|
|
175
|
+
static readonly inlineFields: string[] | undefined;
|
|
176
|
+
static readonly inputFields: string[] | undefined;
|
|
71
177
|
static readonly requiredSettings: string[] | undefined;
|
|
72
178
|
static readonly requiredRuntimes: string[] | undefined;
|
|
73
179
|
static readonly isStreamingInput: boolean;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Decide {@link isStreamingInput} per node instance, from its saved
|
|
182
|
+
* properties. Unset on every node whose mode is a property of the type;
|
|
183
|
+
* declared only where one type covers both modes — the Code node, where the
|
|
184
|
+
* body decides (`usesStreamInputContract(node.properties.code)`).
|
|
185
|
+
*
|
|
186
|
+
* Both hydration paths consult it ahead of the static
|
|
187
|
+
* (`hydrateGraphNodeFlags`, and `Graph.loadFromDict` via the resolver's
|
|
188
|
+
* `resolveInstanceFlags`), and re-read it on every hydration, so editing the
|
|
189
|
+
* body flips the mode with no saved flag involved.
|
|
190
|
+
*/
|
|
191
|
+
static readonly resolveStreamingInput: ((node: {
|
|
192
|
+
properties?: Record<string, unknown>;
|
|
193
|
+
}) => boolean) | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* Marks a trigger node. Triggers compile to `trigger_registrations` on
|
|
196
|
+
* workflow activation, and when a run starts because of a delivered event
|
|
197
|
+
* (`RunJobRequest.trigger_event` targeting this node) the kernel calls
|
|
198
|
+
* {@link emitTriggerEvent} instead of the live-listening `genProcess`
|
|
199
|
+
* loop. Runs without a trigger event keep today's streaming behavior
|
|
200
|
+
* (in-editor live test). See
|
|
201
|
+
* docs/superpowers/specs/2026-07-10-trigger-wakeup-redesign.md.
|
|
202
|
+
*/
|
|
203
|
+
static readonly isTrigger: boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Emit output_update for this node's handles even when they are connected
|
|
206
|
+
* onward. The runner suppresses output_update for connected handles by
|
|
207
|
+
* default; nodes whose updates feed a UI surface regardless of patching
|
|
208
|
+
* (e.g. the realtime audio monitor) opt in.
|
|
209
|
+
*/
|
|
210
|
+
static readonly alwaysEmitOutputUpdates: boolean;
|
|
211
|
+
static readonly inputMode: InputMode | undefined;
|
|
212
|
+
static readonly outputCorrelation: Record<string, OutputCorrelation> | undefined;
|
|
213
|
+
static readonly supportsDynamicInputs: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Restricts the types a user may pick when declaring a dynamic input slot on
|
|
216
|
+
* this node (see `Node.dynamic_inputs`). Unset means the full type palette.
|
|
217
|
+
* Emitted as `allowed_dynamic_slot_types` in node metadata.
|
|
218
|
+
*/
|
|
219
|
+
static readonly allowedDynamicSlotTypes: TypeMetadata[] | undefined;
|
|
77
220
|
static readonly isControlled: boolean;
|
|
78
|
-
|
|
221
|
+
/**
|
|
222
|
+
* `Zip` and `Cross` set this to true so static correlation analysis allows
|
|
223
|
+
* incomparable input scopes on these nodes only. See
|
|
224
|
+
* docs/correlation-design.md §7.
|
|
225
|
+
*/
|
|
226
|
+
static readonly isJoinNode: boolean;
|
|
79
227
|
static readonly supportsDynamicOutputs: boolean | undefined;
|
|
80
228
|
static readonly autoSaveAsset: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Whether re-running this node with identical inputs is safe. An opt-in:
|
|
231
|
+
* unknown means unsafe. Cost tracking cannot see external writes — a
|
|
232
|
+
* Publish/Upsert/Notify node can complete its side effect and then throw,
|
|
233
|
+
* recording nothing — so a node nobody classified loses a safe retry rather
|
|
234
|
+
* than gaining an unsafe one. The workflow supervisor offers `retry` only
|
|
235
|
+
* for a node that declares this. See docs/workflow-supervisor-design.md §5.3.
|
|
236
|
+
*/
|
|
237
|
+
static readonly retrySafe: boolean;
|
|
238
|
+
/**
|
|
239
|
+
* Per-type cache lifetime for partial runs ("Run Node", "Run from here", "Run
|
|
240
|
+
* selected"). Only consulted for Computed nodes (Constants are always live;
|
|
241
|
+
* Generatives reuse generation history). `"forever"` = pure deterministic
|
|
242
|
+
* (reuse while inputs match); a finite number = seconds the cached result
|
|
243
|
+
* stays fresh before re-running (time-sensitive, e.g. a web fetch);
|
|
244
|
+
* unset / `0` = never reuse. `"forever"` is a string sentinel — never
|
|
245
|
+
* `Infinity`, which JSON-serializes to `null` and would silently flip a pure
|
|
246
|
+
* node to never-cache. See docs/superpowers/specs/2026-06-27-run-subgraph-caching.md §4.
|
|
247
|
+
*/
|
|
248
|
+
static readonly cacheTtl: number | "forever" | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* What running this node does to the world, which decides whether a reactive
|
|
251
|
+
* run (a slider drag, an input change in a mini app) may execute it without
|
|
252
|
+
* an explicit action:
|
|
253
|
+
* "pure" — output depends only on inputs; safe to re-run at any rate
|
|
254
|
+
* "read" — reads external state but changes nothing
|
|
255
|
+
* "write" — mutates state the user can observe (a file, a document)
|
|
256
|
+
* "external" — leaves the system (sends mail, calls a paid API)
|
|
257
|
+
* Reactive runs traverse "pure" and "read" only. The default is the
|
|
258
|
+
* conservative "external", so a node nobody has classified never fires off a
|
|
259
|
+
* slider drag. `cacheTtl: "forever"` implies "pure".
|
|
260
|
+
*/
|
|
261
|
+
static readonly effect: NodeEffect;
|
|
262
|
+
/**
|
|
263
|
+
* Names the output slot that carries this node's "primary" generation — the
|
|
264
|
+
* value persisted as its saved generation and previewed by the content card.
|
|
265
|
+
* Unset falls back to the first declared output. See `auto_save_asset` and the
|
|
266
|
+
* autosave path in the websocket runner.
|
|
267
|
+
*/
|
|
268
|
+
static readonly primaryOutput: string | undefined;
|
|
81
269
|
static readonly modelPacks: unknown[] | undefined;
|
|
270
|
+
/**
|
|
271
|
+
* Deployment platforms this node supports. Defaults to ["node"]; nodes
|
|
272
|
+
* that work in V8 isolates should claim "workers" and/or "edge"
|
|
273
|
+
* explicitly. See `@nodetool-ai/protocol`'s Platform type.
|
|
274
|
+
*/
|
|
275
|
+
static readonly platforms: readonly Platform[] | undefined;
|
|
276
|
+
/**
|
|
277
|
+
* Requires a WebGPU device in the browser (set via `tagAsBrowserGpu`). The
|
|
278
|
+
* in-browser runner routes graphs with these nodes to the server when
|
|
279
|
+
* `navigator.gpu` is unavailable. Unset/undefined means no GPU requirement.
|
|
280
|
+
*/
|
|
281
|
+
static readonly requiresGpu: boolean | undefined;
|
|
282
|
+
static readonly deprecated: boolean;
|
|
283
|
+
/**
|
|
284
|
+
* Hidden from node-discovery UIs but still registered/runnable (see the
|
|
285
|
+
* `hidden` field on NodeClass). Unset/false means normally discoverable.
|
|
286
|
+
*/
|
|
287
|
+
static readonly hidden: boolean | undefined;
|
|
288
|
+
static readonly replacedBy: string | undefined;
|
|
82
289
|
static readonly metadataOutputTypes: DeclaredOutputTypes | undefined;
|
|
83
290
|
static readonly outputTypes: DeclaredOutputTypes;
|
|
84
291
|
__node_id: string;
|
|
85
292
|
__node_name: string;
|
|
86
293
|
protected dynamicProps: Map<string, unknown>;
|
|
294
|
+
/**
|
|
295
|
+
* Typed declarations for the dynamic slots of this node instance, injected by
|
|
296
|
+
* the registry as the `_dynamic_inputs` framework property. `dynamicProps`
|
|
297
|
+
* holds the values; this holds the types. A slot missing here is an untyped
|
|
298
|
+
* legacy slot and behaves exactly as before typed slots existed.
|
|
299
|
+
*/
|
|
300
|
+
protected dynamicSlotMeta: Map<string, DynamicSlotMeta>;
|
|
301
|
+
/**
|
|
302
|
+
* Framework-injected internals (resolved `_secrets`, the `_control_context`,
|
|
303
|
+
* …). Kept separate from `dynamicProps` so reserved `_`-prefixed values never
|
|
304
|
+
* leak into user-facing dynamic-input iteration (prompt template vars, API
|
|
305
|
+
* args) or into `serialize()`. Read/written through getDynamic/setDynamic,
|
|
306
|
+
* which route `_`-prefixed keys here.
|
|
307
|
+
*/
|
|
308
|
+
private _internalProps;
|
|
87
309
|
constructor(properties?: Record<string, unknown>);
|
|
88
310
|
static getDeclaredProperties(): import("./decorators.js").DeclaredPropertyMetadata[];
|
|
89
|
-
static getDeclaredOutputs():
|
|
311
|
+
static getDeclaredOutputs(): {
|
|
312
|
+
[name: string]: string;
|
|
313
|
+
};
|
|
90
314
|
/**
|
|
91
315
|
* Validate a property bag against this node's declared @prop metadata.
|
|
92
316
|
*
|
|
@@ -107,6 +331,8 @@ export declare abstract class BaseNode {
|
|
|
107
331
|
deserialize(data: Record<string, unknown>): void;
|
|
108
332
|
setDynamic(key: string, value: unknown): void;
|
|
109
333
|
getDynamic<T = unknown>(key: string): T | undefined;
|
|
334
|
+
/** Declared types of this instance's dynamic slots, keyed by slot name. */
|
|
335
|
+
getDynamicSlots(): ReadonlyMap<string, DynamicSlotMeta>;
|
|
110
336
|
initialize(): Promise<void>;
|
|
111
337
|
preProcess(): Promise<void>;
|
|
112
338
|
finalize(): Promise<void>;
|
|
@@ -127,6 +353,20 @@ export declare abstract class BaseNode {
|
|
|
127
353
|
* push results via `outputs.emit()`.
|
|
128
354
|
*/
|
|
129
355
|
run?(inputs: StreamingInputs, outputs: StreamingOutputs, context?: ProcessingContext): Promise<void>;
|
|
356
|
+
/**
|
|
357
|
+
* Trigger entry point — called instead of `genProcess()` when the run
|
|
358
|
+
* carries a `trigger_event` for this node (see the `isTrigger` static).
|
|
359
|
+
* The default maps the keys of an object payload onto this node's
|
|
360
|
+
* declared output slots and drops everything else. Trigger subclasses
|
|
361
|
+
* override this to shape their adapter payloads (webhook envelope,
|
|
362
|
+
* synthesized tick, file-watch event) onto their specific slots.
|
|
363
|
+
*/
|
|
364
|
+
emitTriggerEvent(event: TriggerEvent, outputs: StreamingOutputs): Promise<void>;
|
|
365
|
+
/**
|
|
366
|
+
* Resolve requiredSettings from the context's secret store. Returns an
|
|
367
|
+
* empty record when nothing is required or nothing resolves.
|
|
368
|
+
*/
|
|
369
|
+
private _resolveSecrets;
|
|
130
370
|
/**
|
|
131
371
|
* Resolve requiredSettings from the context's secret store and inject
|
|
132
372
|
* them as `inputs._secrets` so node process() can access API keys.
|
package/dist/base-node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-node.d.ts","sourceRoot":"","sources":["../src/base-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"base-node.d.ts","sourceRoot":"","sources":["../src/base-node.ts"],"names":[],"mappings":"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"}
|