@foresthubai/workflow-core 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -202
- package/NOTICE +14 -14
- package/README.md +63 -63
- package/dist/api/workflow.d.ts +2 -2
- package/dist/api/workflow.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/index.ts +11 -11
- package/src/api/workflow.ts +607 -607
- package/src/channel/Channel.ts +11 -11
- package/src/channel/ChannelDefinition.ts +76 -76
- package/src/channel/index.ts +6 -6
- package/src/channel/serialization.ts +68 -68
- package/src/deploy/index.ts +1 -1
- package/src/deploy/requirements.test.ts +61 -61
- package/src/deploy/requirements.ts +41 -41
- package/src/diagnostics/__fixtures__/diagnosticFixtures.ts +158 -158
- package/src/diagnostics/diagnostics.test.ts +878 -878
- package/src/diagnostics/diagnostics.ts +936 -936
- package/src/diagnostics/index.ts +11 -11
- package/src/edge/Edge.ts +23 -23
- package/src/edge/EdgeDefinition.ts +45 -45
- package/src/edge/EdgeType.ts +19 -19
- package/src/edge/index.ts +8 -8
- package/src/edge/serialization.ts +83 -83
- package/src/expression/index.ts +4 -4
- package/src/expression/parser.ts +362 -362
- package/src/expression/types.ts +30 -30
- package/src/function/FunctionDeclaration.ts +54 -54
- package/src/function/index.ts +3 -3
- package/src/function/serialization.ts +40 -40
- package/src/globals.d.ts +9 -9
- package/src/id/index.ts +8 -8
- package/src/index.ts +22 -22
- package/src/memory/Memory.ts +15 -15
- package/src/memory/MemoryDefinition.ts +16 -16
- package/src/memory/MemoryFileDefinition.ts +37 -37
- package/src/memory/MemoryRegistry.ts +35 -35
- package/src/memory/VectorDatabaseDefinition.ts +21 -21
- package/src/memory/index.ts +8 -8
- package/src/memory/serialization.ts +47 -47
- package/src/migration/index.ts +4 -4
- package/src/migration/migrate.test.ts +44 -44
- package/src/migration/migrate.ts +58 -58
- package/src/migration/migrations.ts +24 -24
- package/src/migration/version.ts +9 -9
- package/src/model/LLMModelDefinition.ts +12 -12
- package/src/model/Model.ts +39 -39
- package/src/model/ModelDefinition.ts +15 -15
- package/src/model/ModelRegistry.ts +33 -33
- package/src/model/index.ts +7 -7
- package/src/model/serialization.ts +30 -30
- package/src/node/AgentNode.ts +82 -82
- package/src/node/DataNode.ts +41 -41
- package/src/node/FunctionNode.ts +76 -76
- package/src/node/InputNode.ts +185 -185
- package/src/node/LogicNode.ts +33 -33
- package/src/node/MqttNode.ts +127 -127
- package/src/node/Node.ts +61 -61
- package/src/node/NodeDefinition.ts +37 -37
- package/src/node/NodeRegistry.ts +85 -85
- package/src/node/OutputNode.ts +87 -87
- package/src/node/ToolNode.ts +32 -32
- package/src/node/TriggerNode.ts +272 -272
- package/src/node/constants.ts +16 -16
- package/src/node/index.ts +26 -26
- package/src/node/methods.ts +278 -278
- package/src/node/serialization.ts +544 -544
- package/src/parameter/OutputParameter.ts +68 -68
- package/src/parameter/Parameter.ts +243 -243
- package/src/parameter/index.ts +33 -33
- package/src/variable/Variable.ts +10 -10
- package/src/variable/index.ts +16 -16
- package/src/variable/operations.ts +106 -106
- package/src/workflow/Workflow.ts +41 -41
- package/src/workflow/index.ts +3 -3
- package/src/workflow/serialization.test.ts +240 -240
- package/src/workflow/serialization.ts +242 -242
package/src/expression/types.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import type { NodeOutput } from "../node";
|
|
2
|
-
import type { DataType, Expression } from "../api";
|
|
3
|
-
import type { Variable } from "../variable";
|
|
4
|
-
import { refToLookupKey } from "../variable";
|
|
5
|
-
|
|
6
|
-
// ResolvedExpr represents an expression with its variable references resolved to runtime variables
|
|
7
|
-
export interface ResolvedExpr {
|
|
8
|
-
expression: string; // The expression string with variable references, e.g. "${} + ${}"
|
|
9
|
-
variables: (NodeOutput | null)[]; // List of variables used in the expression (null if stale/invalid)
|
|
10
|
-
expectedType: DataType; // The expected data type of the expression result
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Resolve an expression by converting variable references to runtime variables
|
|
14
|
-
export function resolveExpression(apiExpr: Expression, availableVars: Record<string, Variable>): ResolvedExpr {
|
|
15
|
-
return {
|
|
16
|
-
expression: apiExpr.expression,
|
|
17
|
-
expectedType: apiExpr.dataType,
|
|
18
|
-
variables: apiExpr.references.map((ref) => {
|
|
19
|
-
if (!ref.varId) return null;
|
|
20
|
-
const key = refToLookupKey(ref);
|
|
21
|
-
const v = availableVars[key];
|
|
22
|
-
return v ? { name: v.name, dataType: v.dataType } : null;
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Check if a value is an expression (has references array)
|
|
28
|
-
export function isExpression(value: unknown): value is Expression {
|
|
29
|
-
return typeof value === "object" && value !== null && "expression" in value && "references" in value;
|
|
30
|
-
}
|
|
1
|
+
import type { NodeOutput } from "../node";
|
|
2
|
+
import type { DataType, Expression } from "../api";
|
|
3
|
+
import type { Variable } from "../variable";
|
|
4
|
+
import { refToLookupKey } from "../variable";
|
|
5
|
+
|
|
6
|
+
// ResolvedExpr represents an expression with its variable references resolved to runtime variables
|
|
7
|
+
export interface ResolvedExpr {
|
|
8
|
+
expression: string; // The expression string with variable references, e.g. "${} + ${}"
|
|
9
|
+
variables: (NodeOutput | null)[]; // List of variables used in the expression (null if stale/invalid)
|
|
10
|
+
expectedType: DataType; // The expected data type of the expression result
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Resolve an expression by converting variable references to runtime variables
|
|
14
|
+
export function resolveExpression(apiExpr: Expression, availableVars: Record<string, Variable>): ResolvedExpr {
|
|
15
|
+
return {
|
|
16
|
+
expression: apiExpr.expression,
|
|
17
|
+
expectedType: apiExpr.dataType,
|
|
18
|
+
variables: apiExpr.references.map((ref) => {
|
|
19
|
+
if (!ref.varId) return null;
|
|
20
|
+
const key = refToLookupKey(ref);
|
|
21
|
+
const v = availableVars[key];
|
|
22
|
+
return v ? { name: v.name, dataType: v.dataType } : null;
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Check if a value is an expression (has references array)
|
|
28
|
+
export function isExpression(value: unknown): value is Expression {
|
|
29
|
+
return typeof value === "object" && value !== null && "expression" in value && "references" in value;
|
|
30
|
+
}
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import type { Expression, Schemas } from "../api";
|
|
2
|
-
import type { ApiVariable } from "../variable";
|
|
3
|
-
import type { DataType } from "../parameter";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The flat call-site signature of a function: identity + version + ports, with no
|
|
7
|
-
* expressions (the contract's `FunctionInfo`, used both inside `Function` on the wire
|
|
8
|
-
* and here in the domain). It is the snapshot a {@link FunctionCallNode} caches — to
|
|
9
|
-
* detect drift against the live declaration and render its ports without a registry
|
|
10
|
-
* lookup — and the shape {@link buildFunctionNodeDef} consumes.
|
|
11
|
-
*/
|
|
12
|
-
export type FunctionInfo = Schemas["FunctionInfo"];
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* A function output: its declaration (`uid`/`name`/`dataType`) bundled with the
|
|
16
|
-
* `expression` that produces it (evaluated in callee scope at the function's end).
|
|
17
|
-
* Acts as a supertype of {@link ApiVariable}.
|
|
18
|
-
*/
|
|
19
|
-
export interface OutputAssignment {
|
|
20
|
-
uid: string;
|
|
21
|
-
name: string;
|
|
22
|
-
dataType: DataType;
|
|
23
|
-
expression: Expression;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* The domain function declaration: a signature with its outputs bundled
|
|
28
|
-
* (declaration + assignment per output).
|
|
29
|
-
* Separate from the function body (which is a canvas of nodes, edges, variables).
|
|
30
|
-
*/
|
|
31
|
-
export interface FunctionDeclaration {
|
|
32
|
-
id: string;
|
|
33
|
-
version: number;
|
|
34
|
-
name: string;
|
|
35
|
-
arguments: ApiVariable[];
|
|
36
|
-
outputs: OutputAssignment[];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Project a declaration to the flat call-site signature, dropping the expressions
|
|
41
|
-
* (the caller has no business storing the callee's internals). Used only when
|
|
42
|
-
* crossing from declaration to a call-site snapshot — dropping or migrating a
|
|
43
|
-
* `FunctionCall` node — and by serialization. Never used to represent a function
|
|
44
|
-
* within the domain.
|
|
45
|
-
*/
|
|
46
|
-
export function toFunctionInfo(fn: FunctionDeclaration): FunctionInfo {
|
|
47
|
-
return {
|
|
48
|
-
id: fn.id,
|
|
49
|
-
version: fn.version,
|
|
50
|
-
name: fn.name,
|
|
51
|
-
arguments: fn.arguments,
|
|
52
|
-
returns: fn.outputs.map(({ uid, name, dataType }) => ({ uid, name, dataType })),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
1
|
+
import type { Expression, Schemas } from "../api";
|
|
2
|
+
import type { ApiVariable } from "../variable";
|
|
3
|
+
import type { DataType } from "../parameter";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The flat call-site signature of a function: identity + version + ports, with no
|
|
7
|
+
* expressions (the contract's `FunctionInfo`, used both inside `Function` on the wire
|
|
8
|
+
* and here in the domain). It is the snapshot a {@link FunctionCallNode} caches — to
|
|
9
|
+
* detect drift against the live declaration and render its ports without a registry
|
|
10
|
+
* lookup — and the shape {@link buildFunctionNodeDef} consumes.
|
|
11
|
+
*/
|
|
12
|
+
export type FunctionInfo = Schemas["FunctionInfo"];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A function output: its declaration (`uid`/`name`/`dataType`) bundled with the
|
|
16
|
+
* `expression` that produces it (evaluated in callee scope at the function's end).
|
|
17
|
+
* Acts as a supertype of {@link ApiVariable}.
|
|
18
|
+
*/
|
|
19
|
+
export interface OutputAssignment {
|
|
20
|
+
uid: string;
|
|
21
|
+
name: string;
|
|
22
|
+
dataType: DataType;
|
|
23
|
+
expression: Expression;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The domain function declaration: a signature with its outputs bundled
|
|
28
|
+
* (declaration + assignment per output).
|
|
29
|
+
* Separate from the function body (which is a canvas of nodes, edges, variables).
|
|
30
|
+
*/
|
|
31
|
+
export interface FunctionDeclaration {
|
|
32
|
+
id: string;
|
|
33
|
+
version: number;
|
|
34
|
+
name: string;
|
|
35
|
+
arguments: ApiVariable[];
|
|
36
|
+
outputs: OutputAssignment[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Project a declaration to the flat call-site signature, dropping the expressions
|
|
41
|
+
* (the caller has no business storing the callee's internals). Used only when
|
|
42
|
+
* crossing from declaration to a call-site snapshot — dropping or migrating a
|
|
43
|
+
* `FunctionCall` node — and by serialization. Never used to represent a function
|
|
44
|
+
* within the domain.
|
|
45
|
+
*/
|
|
46
|
+
export function toFunctionInfo(fn: FunctionDeclaration): FunctionInfo {
|
|
47
|
+
return {
|
|
48
|
+
id: fn.id,
|
|
49
|
+
version: fn.version,
|
|
50
|
+
name: fn.name,
|
|
51
|
+
arguments: fn.arguments,
|
|
52
|
+
returns: fn.outputs.map(({ uid, name, dataType }) => ({ uid, name, dataType })),
|
|
53
|
+
};
|
|
54
|
+
}
|
package/src/function/index.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { OutputAssignment, FunctionDeclaration, FunctionInfo } from "./FunctionDeclaration";
|
|
2
|
-
export { toFunctionInfo } from "./FunctionDeclaration";
|
|
3
|
-
export { serialize, deserialize } from "./serialization";
|
|
1
|
+
export type { OutputAssignment, FunctionDeclaration, FunctionInfo } from "./FunctionDeclaration";
|
|
2
|
+
export { toFunctionInfo } from "./FunctionDeclaration";
|
|
3
|
+
export { serialize, deserialize } from "./serialization";
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import type { Expression } from "../api";
|
|
2
|
-
import type { FunctionDeclaration, FunctionInfo } from "./FunctionDeclaration";
|
|
3
|
-
import { toFunctionInfo } from "./FunctionDeclaration";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The two wire pieces a {@link FunctionDeclaration} splits into. The contract keeps
|
|
7
|
-
* the signature (`functionInfo`) and the return-value expressions (`outputAssignments`)
|
|
8
|
-
* apart; the domain bundles them on `outputs`. The function *body*
|
|
9
|
-
* (nodes/edges/declaredVariables) is added separately by the workflow serializer —
|
|
10
|
-
* this only handles the declaration ⇄ wire mapping.
|
|
11
|
-
*/
|
|
12
|
-
export interface SerializedFunction {
|
|
13
|
-
functionInfo: FunctionInfo;
|
|
14
|
-
outputAssignments: Record<string, Expression>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Domain declaration → wire pieces: flatten the signature and lift each output's
|
|
18
|
-
* expression into the `outputAssignments` map keyed by output uid. */
|
|
19
|
-
export function serialize(fn: FunctionDeclaration): SerializedFunction {
|
|
20
|
-
const outputAssignments: Record<string, Expression> = {};
|
|
21
|
-
for (const o of fn.outputs) outputAssignments[o.uid] = o.expression;
|
|
22
|
-
return { functionInfo: toFunctionInfo(fn), outputAssignments };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Wire pieces → domain declaration: bundle each `return` with its assignment. A
|
|
26
|
-
* return with no stored assignment gets an empty expression of the right dataType. */
|
|
27
|
-
export function deserialize(functionInfo: FunctionInfo, outputAssignments: Record<string, Expression>): FunctionDeclaration {
|
|
28
|
-
return {
|
|
29
|
-
id: functionInfo.id,
|
|
30
|
-
version: functionInfo.version,
|
|
31
|
-
name: functionInfo.name,
|
|
32
|
-
arguments: functionInfo.arguments,
|
|
33
|
-
outputs: functionInfo.returns.map((r) => ({
|
|
34
|
-
uid: r.uid,
|
|
35
|
-
name: r.name,
|
|
36
|
-
dataType: r.dataType,
|
|
37
|
-
expression: outputAssignments[r.uid] ?? { expression: "", references: [], dataType: r.dataType },
|
|
38
|
-
})),
|
|
39
|
-
};
|
|
40
|
-
}
|
|
1
|
+
import type { Expression } from "../api";
|
|
2
|
+
import type { FunctionDeclaration, FunctionInfo } from "./FunctionDeclaration";
|
|
3
|
+
import { toFunctionInfo } from "./FunctionDeclaration";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The two wire pieces a {@link FunctionDeclaration} splits into. The contract keeps
|
|
7
|
+
* the signature (`functionInfo`) and the return-value expressions (`outputAssignments`)
|
|
8
|
+
* apart; the domain bundles them on `outputs`. The function *body*
|
|
9
|
+
* (nodes/edges/declaredVariables) is added separately by the workflow serializer —
|
|
10
|
+
* this only handles the declaration ⇄ wire mapping.
|
|
11
|
+
*/
|
|
12
|
+
export interface SerializedFunction {
|
|
13
|
+
functionInfo: FunctionInfo;
|
|
14
|
+
outputAssignments: Record<string, Expression>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Domain declaration → wire pieces: flatten the signature and lift each output's
|
|
18
|
+
* expression into the `outputAssignments` map keyed by output uid. */
|
|
19
|
+
export function serialize(fn: FunctionDeclaration): SerializedFunction {
|
|
20
|
+
const outputAssignments: Record<string, Expression> = {};
|
|
21
|
+
for (const o of fn.outputs) outputAssignments[o.uid] = o.expression;
|
|
22
|
+
return { functionInfo: toFunctionInfo(fn), outputAssignments };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Wire pieces → domain declaration: bundle each `return` with its assignment. A
|
|
26
|
+
* return with no stored assignment gets an empty expression of the right dataType. */
|
|
27
|
+
export function deserialize(functionInfo: FunctionInfo, outputAssignments: Record<string, Expression>): FunctionDeclaration {
|
|
28
|
+
return {
|
|
29
|
+
id: functionInfo.id,
|
|
30
|
+
version: functionInfo.version,
|
|
31
|
+
name: functionInfo.name,
|
|
32
|
+
arguments: functionInfo.arguments,
|
|
33
|
+
outputs: functionInfo.returns.map((r) => ({
|
|
34
|
+
uid: r.uid,
|
|
35
|
+
name: r.name,
|
|
36
|
+
dataType: r.dataType,
|
|
37
|
+
expression: outputAssignments[r.uid] ?? { expression: "", references: [], dataType: r.dataType },
|
|
38
|
+
})),
|
|
39
|
+
};
|
|
40
|
+
}
|
package/src/globals.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This package drops the `DOM` lib (see tsconfig.json) to stay headless, so the
|
|
3
|
-
* Web Crypto `crypto` global is untyped. It exists at runtime everywhere we run
|
|
4
|
-
* — browsers, Node >= 19, Deno, Bun — so we declare only the one member we use
|
|
5
|
-
* rather than pulling in `DOM` or `@types/node` and their global scope.
|
|
6
|
-
*/
|
|
7
|
-
declare const crypto: {
|
|
8
|
-
randomUUID(): `${string}-${string}-${string}-${string}-${string}`;
|
|
9
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* This package drops the `DOM` lib (see tsconfig.json) to stay headless, so the
|
|
3
|
+
* Web Crypto `crypto` global is untyped. It exists at runtime everywhere we run
|
|
4
|
+
* — browsers, Node >= 19, Deno, Bun — so we declare only the one member we use
|
|
5
|
+
* rather than pulling in `DOM` or `@types/node` and their global scope.
|
|
6
|
+
*/
|
|
7
|
+
declare const crypto: {
|
|
8
|
+
randomUUID(): `${string}-${string}-${string}-${string}-${string}`;
|
|
9
|
+
};
|
package/src/id/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Centralized UID creation for every entity in a workflow — nodes, edges,
|
|
3
|
-
* channels, memory, models, declared variables, function arguments, and
|
|
4
|
-
* function canvases. IDs are opaque.
|
|
5
|
-
*/
|
|
6
|
-
export function generateId(): string {
|
|
7
|
-
return crypto.randomUUID();
|
|
8
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Centralized UID creation for every entity in a workflow — nodes, edges,
|
|
3
|
+
* channels, memory, models, declared variables, function arguments, and
|
|
4
|
+
* function canvases. IDs are opaque.
|
|
5
|
+
*/
|
|
6
|
+
export function generateId(): string {
|
|
7
|
+
return crypto.randomUUID();
|
|
8
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { deserialize } from "./workflow/serialization";
|
|
2
|
-
import { validateWorkflowState, type ValidationResult } from "./diagnostics/diagnostics";
|
|
3
|
-
import type { ApiWorkflow } from "./workflow/Workflow";
|
|
4
|
-
|
|
5
|
-
// Api-layer types consumers use directly (no domain twin). Sourced from `api`
|
|
6
|
-
// so they're available at the package root rather than via a domain subpath.
|
|
7
|
-
// (`FunctionInfo` is the exception — it's the flat twin of the domain
|
|
8
|
-
// `FunctionDeclaration`, so it lives on the `function` subpath, not here.)
|
|
9
|
-
export type { DataType, Reference, Expression } from "./api";
|
|
10
|
-
|
|
11
|
-
// Format versioning: load persisted documents through `migrate` before
|
|
12
|
-
// deserializing.
|
|
13
|
-
export { migrate, CURRENT_SCHEMA_VERSION } from "./migration";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Validate a workflow against the headless validator.
|
|
17
|
-
* Pure: no I/O, no Zustand, no React, no DOM. Runnable in Node, a CLI, or
|
|
18
|
-
* a Claude Code skill.
|
|
19
|
-
*/
|
|
20
|
-
export function validateWorkflow(workflow: ApiWorkflow): ValidationResult {
|
|
21
|
-
return validateWorkflowState(deserialize(workflow));
|
|
22
|
-
}
|
|
1
|
+
import { deserialize } from "./workflow/serialization";
|
|
2
|
+
import { validateWorkflowState, type ValidationResult } from "./diagnostics/diagnostics";
|
|
3
|
+
import type { ApiWorkflow } from "./workflow/Workflow";
|
|
4
|
+
|
|
5
|
+
// Api-layer types consumers use directly (no domain twin). Sourced from `api`
|
|
6
|
+
// so they're available at the package root rather than via a domain subpath.
|
|
7
|
+
// (`FunctionInfo` is the exception — it's the flat twin of the domain
|
|
8
|
+
// `FunctionDeclaration`, so it lives on the `function` subpath, not here.)
|
|
9
|
+
export type { DataType, Reference, Expression } from "./api";
|
|
10
|
+
|
|
11
|
+
// Format versioning: load persisted documents through `migrate` before
|
|
12
|
+
// deserializing.
|
|
13
|
+
export { migrate, CURRENT_SCHEMA_VERSION } from "./migration";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Validate a workflow against the headless validator.
|
|
17
|
+
* Pure: no I/O, no Zustand, no React, no DOM. Runnable in Node, a CLI, or
|
|
18
|
+
* a Claude Code skill.
|
|
19
|
+
*/
|
|
20
|
+
export function validateWorkflow(workflow: ApiWorkflow): ValidationResult {
|
|
21
|
+
return validateWorkflowState(deserialize(workflow));
|
|
22
|
+
}
|
package/src/memory/Memory.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { Schemas } from "../api";
|
|
2
|
-
|
|
3
|
-
export type MemoryType = "MemoryFile" | "VectorDatabase";
|
|
4
|
-
|
|
5
|
-
export const ALL_MEMORY_TYPES: MemoryType[] = ["MemoryFile", "VectorDatabase"];
|
|
6
|
-
|
|
7
|
-
export interface Memory {
|
|
8
|
-
id: string;
|
|
9
|
-
label: string;
|
|
10
|
-
type: MemoryType;
|
|
11
|
-
arguments: Record<string, unknown>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/** Reference from an agent node to a declared MemoryFile, with access mode. Round-trips 1:1 with the API. */
|
|
15
|
-
export type MemoryRef = Schemas["MemoryRef"];
|
|
1
|
+
import type { Schemas } from "../api";
|
|
2
|
+
|
|
3
|
+
export type MemoryType = "MemoryFile" | "VectorDatabase";
|
|
4
|
+
|
|
5
|
+
export const ALL_MEMORY_TYPES: MemoryType[] = ["MemoryFile", "VectorDatabase"];
|
|
6
|
+
|
|
7
|
+
export interface Memory {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
type: MemoryType;
|
|
11
|
+
arguments: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Reference from an agent node to a declared MemoryFile, with access mode. Round-trips 1:1 with the API. */
|
|
15
|
+
export type MemoryRef = Schemas["MemoryRef"];
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import type { Parameter } from "../parameter";
|
|
2
|
-
import type { MemoryType } from "./Memory";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Static, per-type metadata for a memory variant. Mirrors NodeDefinition:
|
|
6
|
-
* one definition object per MemoryType, registered in MemoryRegistry — unlike
|
|
7
|
-
* channels, which use a single union definition gated by activation rules.
|
|
8
|
-
* `label` is a top-level instance field (edited like a channel label), so it is
|
|
9
|
-
* never a parameter here.
|
|
10
|
-
*/
|
|
11
|
-
export interface MemoryDefinition {
|
|
12
|
-
type: MemoryType;
|
|
13
|
-
label: string;
|
|
14
|
-
description: string;
|
|
15
|
-
parameters: Parameter[];
|
|
16
|
-
}
|
|
1
|
+
import type { Parameter } from "../parameter";
|
|
2
|
+
import type { MemoryType } from "./Memory";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Static, per-type metadata for a memory variant. Mirrors NodeDefinition:
|
|
6
|
+
* one definition object per MemoryType, registered in MemoryRegistry — unlike
|
|
7
|
+
* channels, which use a single union definition gated by activation rules.
|
|
8
|
+
* `label` is a top-level instance field (edited like a channel label), so it is
|
|
9
|
+
* never a parameter here.
|
|
10
|
+
*/
|
|
11
|
+
export interface MemoryDefinition {
|
|
12
|
+
type: MemoryType;
|
|
13
|
+
label: string;
|
|
14
|
+
description: string;
|
|
15
|
+
parameters: Parameter[];
|
|
16
|
+
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Agent-scoped durable text storage. The instance `label` (edited like a channel
|
|
5
|
-
* label) is the identifier the LLM sees in tool calls, so it is not a parameter.
|
|
6
|
-
* The config panel renders these parameters via ParameterEditor, same as channels.
|
|
7
|
-
*/
|
|
8
|
-
export const MemoryFileDefinition: MemoryDefinition = {
|
|
9
|
-
type: "MemoryFile",
|
|
10
|
-
label: "Memory File",
|
|
11
|
-
description: "Durable text storage an agent can read and write",
|
|
12
|
-
parameters: [
|
|
13
|
-
{
|
|
14
|
-
id: "description",
|
|
15
|
-
label: "Description",
|
|
16
|
-
description: "What this memory file is for (shown to the LLM as tool description)",
|
|
17
|
-
type: "string",
|
|
18
|
-
multiline: true,
|
|
19
|
-
optional: true,
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
id: "content",
|
|
23
|
-
label: "Initial Content",
|
|
24
|
-
description: "Seed content written on fresh deploy; existing rows keep their content on redeploy",
|
|
25
|
-
type: "string",
|
|
26
|
-
multiline: true,
|
|
27
|
-
optional: true,
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
id: "maxSizeBytes",
|
|
31
|
-
label: "Max Size (bytes)",
|
|
32
|
-
description: "Byte cap on writes; leave empty for unlimited",
|
|
33
|
-
type: "int",
|
|
34
|
-
optional: true,
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
};
|
|
1
|
+
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Agent-scoped durable text storage. The instance `label` (edited like a channel
|
|
5
|
+
* label) is the identifier the LLM sees in tool calls, so it is not a parameter.
|
|
6
|
+
* The config panel renders these parameters via ParameterEditor, same as channels.
|
|
7
|
+
*/
|
|
8
|
+
export const MemoryFileDefinition: MemoryDefinition = {
|
|
9
|
+
type: "MemoryFile",
|
|
10
|
+
label: "Memory File",
|
|
11
|
+
description: "Durable text storage an agent can read and write",
|
|
12
|
+
parameters: [
|
|
13
|
+
{
|
|
14
|
+
id: "description",
|
|
15
|
+
label: "Description",
|
|
16
|
+
description: "What this memory file is for (shown to the LLM as tool description)",
|
|
17
|
+
type: "string",
|
|
18
|
+
multiline: true,
|
|
19
|
+
optional: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "content",
|
|
23
|
+
label: "Initial Content",
|
|
24
|
+
description: "Seed content written on fresh deploy; existing rows keep their content on redeploy",
|
|
25
|
+
type: "string",
|
|
26
|
+
multiline: true,
|
|
27
|
+
optional: true,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "maxSizeBytes",
|
|
31
|
+
label: "Max Size (bytes)",
|
|
32
|
+
description: "Byte cap on writes; leave empty for unlimited",
|
|
33
|
+
type: "int",
|
|
34
|
+
optional: true,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import type { MemoryType } from "./Memory";
|
|
2
|
-
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
3
|
-
import { MemoryFileDefinition } from "./MemoryFileDefinition";
|
|
4
|
-
import { VectorDatabaseDefinition } from "./VectorDatabaseDefinition";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Central registry for memory variant definitions (one per MemoryType).
|
|
8
|
-
* Mirrors NodeRegistry.
|
|
9
|
-
*/
|
|
10
|
-
class MemoryDefinitionRegistry {
|
|
11
|
-
private memories: Map<MemoryType, MemoryDefinition> = new Map();
|
|
12
|
-
private initialized = false;
|
|
13
|
-
|
|
14
|
-
initialize() {
|
|
15
|
-
if (this.initialized) return;
|
|
16
|
-
this.register(MemoryFileDefinition);
|
|
17
|
-
this.register(VectorDatabaseDefinition);
|
|
18
|
-
this.initialized = true;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
private register(definition: MemoryDefinition) {
|
|
22
|
-
this.memories.set(definition.type, definition);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
getAll(): MemoryDefinition[] {
|
|
26
|
-
return Array.from(this.memories.values());
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
getByType(type: MemoryType): MemoryDefinition | undefined {
|
|
30
|
-
return this.memories.get(type);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const MemoryRegistry = new MemoryDefinitionRegistry();
|
|
35
|
-
MemoryRegistry.initialize();
|
|
1
|
+
import type { MemoryType } from "./Memory";
|
|
2
|
+
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
3
|
+
import { MemoryFileDefinition } from "./MemoryFileDefinition";
|
|
4
|
+
import { VectorDatabaseDefinition } from "./VectorDatabaseDefinition";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Central registry for memory variant definitions (one per MemoryType).
|
|
8
|
+
* Mirrors NodeRegistry.
|
|
9
|
+
*/
|
|
10
|
+
class MemoryDefinitionRegistry {
|
|
11
|
+
private memories: Map<MemoryType, MemoryDefinition> = new Map();
|
|
12
|
+
private initialized = false;
|
|
13
|
+
|
|
14
|
+
initialize() {
|
|
15
|
+
if (this.initialized) return;
|
|
16
|
+
this.register(MemoryFileDefinition);
|
|
17
|
+
this.register(VectorDatabaseDefinition);
|
|
18
|
+
this.initialized = true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private register(definition: MemoryDefinition) {
|
|
22
|
+
this.memories.set(definition.type, definition);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getAll(): MemoryDefinition[] {
|
|
26
|
+
return Array.from(this.memories.values());
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getByType(type: MemoryType): MemoryDefinition | undefined {
|
|
30
|
+
return this.memories.get(type);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const MemoryRegistry = new MemoryDefinitionRegistry();
|
|
35
|
+
MemoryRegistry.initialize();
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* RAG knowledge base referenced from Retriever nodes. Only descriptive config
|
|
5
|
-
* lives here; the backend collection it binds to is supplied at deploy time.
|
|
6
|
-
*/
|
|
7
|
-
export const VectorDatabaseDefinition: MemoryDefinition = {
|
|
8
|
-
type: "VectorDatabase",
|
|
9
|
-
label: "Vector Database",
|
|
10
|
-
description: "RAG knowledge base that Retriever nodes can query",
|
|
11
|
-
parameters: [
|
|
12
|
-
{
|
|
13
|
-
id: "description",
|
|
14
|
-
label: "Description",
|
|
15
|
-
description: "What this knowledge base contains",
|
|
16
|
-
type: "string",
|
|
17
|
-
multiline: true,
|
|
18
|
-
optional: true,
|
|
19
|
-
},
|
|
20
|
-
],
|
|
21
|
-
};
|
|
1
|
+
import type { MemoryDefinition } from "./MemoryDefinition";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* RAG knowledge base referenced from Retriever nodes. Only descriptive config
|
|
5
|
+
* lives here; the backend collection it binds to is supplied at deploy time.
|
|
6
|
+
*/
|
|
7
|
+
export const VectorDatabaseDefinition: MemoryDefinition = {
|
|
8
|
+
type: "VectorDatabase",
|
|
9
|
+
label: "Vector Database",
|
|
10
|
+
description: "RAG knowledge base that Retriever nodes can query",
|
|
11
|
+
parameters: [
|
|
12
|
+
{
|
|
13
|
+
id: "description",
|
|
14
|
+
label: "Description",
|
|
15
|
+
description: "What this knowledge base contains",
|
|
16
|
+
type: "string",
|
|
17
|
+
multiline: true,
|
|
18
|
+
optional: true,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
package/src/memory/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export type { MemoryType, Memory, MemoryRef } from "./Memory";
|
|
2
|
-
export { ALL_MEMORY_TYPES } from "./Memory";
|
|
3
|
-
export type { MemoryDefinition } from "./MemoryDefinition";
|
|
4
|
-
export { MemoryFileDefinition } from "./MemoryFileDefinition";
|
|
5
|
-
export { VectorDatabaseDefinition } from "./VectorDatabaseDefinition";
|
|
6
|
-
export { MemoryRegistry } from "./MemoryRegistry";
|
|
7
|
-
export { serialize, deserialize } from "./serialization";
|
|
8
|
-
export type { ApiMemory } from "./serialization";
|
|
1
|
+
export type { MemoryType, Memory, MemoryRef } from "./Memory";
|
|
2
|
+
export { ALL_MEMORY_TYPES } from "./Memory";
|
|
3
|
+
export type { MemoryDefinition } from "./MemoryDefinition";
|
|
4
|
+
export { MemoryFileDefinition } from "./MemoryFileDefinition";
|
|
5
|
+
export { VectorDatabaseDefinition } from "./VectorDatabaseDefinition";
|
|
6
|
+
export { MemoryRegistry } from "./MemoryRegistry";
|
|
7
|
+
export { serialize, deserialize } from "./serialization";
|
|
8
|
+
export type { ApiMemory } from "./serialization";
|