@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.
Files changed (77) hide show
  1. package/LICENSE +202 -202
  2. package/NOTICE +14 -14
  3. package/README.md +63 -63
  4. package/dist/api/workflow.d.ts +2 -2
  5. package/dist/api/workflow.d.ts.map +1 -1
  6. package/package.json +1 -1
  7. package/src/api/index.ts +11 -11
  8. package/src/api/workflow.ts +607 -607
  9. package/src/channel/Channel.ts +11 -11
  10. package/src/channel/ChannelDefinition.ts +76 -76
  11. package/src/channel/index.ts +6 -6
  12. package/src/channel/serialization.ts +68 -68
  13. package/src/deploy/index.ts +1 -1
  14. package/src/deploy/requirements.test.ts +61 -61
  15. package/src/deploy/requirements.ts +41 -41
  16. package/src/diagnostics/__fixtures__/diagnosticFixtures.ts +158 -158
  17. package/src/diagnostics/diagnostics.test.ts +878 -878
  18. package/src/diagnostics/diagnostics.ts +936 -936
  19. package/src/diagnostics/index.ts +11 -11
  20. package/src/edge/Edge.ts +23 -23
  21. package/src/edge/EdgeDefinition.ts +45 -45
  22. package/src/edge/EdgeType.ts +19 -19
  23. package/src/edge/index.ts +8 -8
  24. package/src/edge/serialization.ts +83 -83
  25. package/src/expression/index.ts +4 -4
  26. package/src/expression/parser.ts +362 -362
  27. package/src/expression/types.ts +30 -30
  28. package/src/function/FunctionDeclaration.ts +54 -54
  29. package/src/function/index.ts +3 -3
  30. package/src/function/serialization.ts +40 -40
  31. package/src/globals.d.ts +9 -9
  32. package/src/id/index.ts +8 -8
  33. package/src/index.ts +22 -22
  34. package/src/memory/Memory.ts +15 -15
  35. package/src/memory/MemoryDefinition.ts +16 -16
  36. package/src/memory/MemoryFileDefinition.ts +37 -37
  37. package/src/memory/MemoryRegistry.ts +35 -35
  38. package/src/memory/VectorDatabaseDefinition.ts +21 -21
  39. package/src/memory/index.ts +8 -8
  40. package/src/memory/serialization.ts +47 -47
  41. package/src/migration/index.ts +4 -4
  42. package/src/migration/migrate.test.ts +44 -44
  43. package/src/migration/migrate.ts +58 -58
  44. package/src/migration/migrations.ts +24 -24
  45. package/src/migration/version.ts +9 -9
  46. package/src/model/LLMModelDefinition.ts +12 -12
  47. package/src/model/Model.ts +39 -39
  48. package/src/model/ModelDefinition.ts +15 -15
  49. package/src/model/ModelRegistry.ts +33 -33
  50. package/src/model/index.ts +7 -7
  51. package/src/model/serialization.ts +30 -30
  52. package/src/node/AgentNode.ts +82 -82
  53. package/src/node/DataNode.ts +41 -41
  54. package/src/node/FunctionNode.ts +76 -76
  55. package/src/node/InputNode.ts +185 -185
  56. package/src/node/LogicNode.ts +33 -33
  57. package/src/node/MqttNode.ts +127 -127
  58. package/src/node/Node.ts +61 -61
  59. package/src/node/NodeDefinition.ts +37 -37
  60. package/src/node/NodeRegistry.ts +85 -85
  61. package/src/node/OutputNode.ts +87 -87
  62. package/src/node/ToolNode.ts +32 -32
  63. package/src/node/TriggerNode.ts +272 -272
  64. package/src/node/constants.ts +16 -16
  65. package/src/node/index.ts +26 -26
  66. package/src/node/methods.ts +278 -278
  67. package/src/node/serialization.ts +544 -544
  68. package/src/parameter/OutputParameter.ts +68 -68
  69. package/src/parameter/Parameter.ts +243 -243
  70. package/src/parameter/index.ts +33 -33
  71. package/src/variable/Variable.ts +10 -10
  72. package/src/variable/index.ts +16 -16
  73. package/src/variable/operations.ts +106 -106
  74. package/src/workflow/Workflow.ts +41 -41
  75. package/src/workflow/index.ts +3 -3
  76. package/src/workflow/serialization.test.ts +240 -240
  77. package/src/workflow/serialization.ts +242 -242
@@ -1,33 +1,33 @@
1
- export type {
2
- DataType,
3
- FromArgs,
4
- ParameterBase,
5
- BasicParam,
6
- StringParam,
7
- BoolParam,
8
- WeekdaysParam,
9
- SelectionParam,
10
- ExpressionParam,
11
- VariableSelectParam,
12
- ModelSelectParam,
13
- ChannelSelectParam,
14
- MemorySelectParam,
15
- MemoryRefsParam,
16
- ReferenceSelectParam,
17
- Parameter,
18
- ActivationRule,
19
- } from "./Parameter";
20
- export {
21
- unwrapFromArgs,
22
- isReferenceSelectParam,
23
- isParameterActive,
24
- isEmpty,
25
- pruneArguments,
26
- resolveExpressionType,
27
- resolveCapabilities,
28
- resolveChannelTypes,
29
- resolveMemoryTypes,
30
- resolveModelTypes,
31
- } from "./Parameter";
32
- export type { OutputBinding, OutputDeclaration, StaticOutput, OutputList, OutputParameter } from "./OutputParameter";
33
- export { resolveStaticOutputDataType } from "./OutputParameter";
1
+ export type {
2
+ DataType,
3
+ FromArgs,
4
+ ParameterBase,
5
+ BasicParam,
6
+ StringParam,
7
+ BoolParam,
8
+ WeekdaysParam,
9
+ SelectionParam,
10
+ ExpressionParam,
11
+ VariableSelectParam,
12
+ ModelSelectParam,
13
+ ChannelSelectParam,
14
+ MemorySelectParam,
15
+ MemoryRefsParam,
16
+ ReferenceSelectParam,
17
+ Parameter,
18
+ ActivationRule,
19
+ } from "./Parameter";
20
+ export {
21
+ unwrapFromArgs,
22
+ isReferenceSelectParam,
23
+ isParameterActive,
24
+ isEmpty,
25
+ pruneArguments,
26
+ resolveExpressionType,
27
+ resolveCapabilities,
28
+ resolveChannelTypes,
29
+ resolveMemoryTypes,
30
+ resolveModelTypes,
31
+ } from "./Parameter";
32
+ export type { OutputBinding, OutputDeclaration, StaticOutput, OutputList, OutputParameter } from "./OutputParameter";
33
+ export { resolveStaticOutputDataType } from "./OutputParameter";
@@ -1,10 +1,10 @@
1
- import type { Schemas } from "../api";
2
- import type { DataType } from "../api";
3
-
4
- export type ApiVariable = Schemas["Variable"]; // Differentiate from domain variable type
5
-
6
- export type NodeOutputVariable = { kind: "node"; nodeId: string; outputId: string; name: string; dataType: DataType };
7
- export type DeclaredVariable = { kind: "declared"; uid: string; name: string; dataType: DataType; initialValue?: unknown };
8
- export type FunctionArgVariable = { kind: "fnarg"; uid: string; name: string; dataType: DataType };
9
-
10
- export type Variable = NodeOutputVariable | DeclaredVariable | FunctionArgVariable;
1
+ import type { Schemas } from "../api";
2
+ import type { DataType } from "../api";
3
+
4
+ export type ApiVariable = Schemas["Variable"]; // Differentiate from domain variable type
5
+
6
+ export type NodeOutputVariable = { kind: "node"; nodeId: string; outputId: string; name: string; dataType: DataType };
7
+ export type DeclaredVariable = { kind: "declared"; uid: string; name: string; dataType: DataType; initialValue?: unknown };
8
+ export type FunctionArgVariable = { kind: "fnarg"; uid: string; name: string; dataType: DataType };
9
+
10
+ export type Variable = NodeOutputVariable | DeclaredVariable | FunctionArgVariable;
@@ -1,16 +1,16 @@
1
- // Public surface of the variable module. The discriminated-union types live in
2
- // ./Variable; the key/lookup/uid helpers and availability computation live in
3
- // ./operations. This file is a barrel only. Mirrors channel/memory/model.
4
-
5
- export type { ApiVariable, NodeOutputVariable, DeclaredVariable, FunctionArgVariable, Variable } from "./Variable";
6
- export {
7
- varKey,
8
- declaredVarKey,
9
- fnargKey,
10
- nodeOutputVarKey,
11
- refToLookupKey,
12
- ensureUid,
13
- ensureUids,
14
- paramKey,
15
- computeAvailableVariables,
16
- } from "./operations";
1
+ // Public surface of the variable module. The discriminated-union types live in
2
+ // ./Variable; the key/lookup/uid helpers and availability computation live in
3
+ // ./operations. This file is a barrel only. Mirrors channel/memory/model.
4
+
5
+ export type { ApiVariable, NodeOutputVariable, DeclaredVariable, FunctionArgVariable, Variable } from "./Variable";
6
+ export {
7
+ varKey,
8
+ declaredVarKey,
9
+ fnargKey,
10
+ nodeOutputVarKey,
11
+ refToLookupKey,
12
+ ensureUid,
13
+ ensureUids,
14
+ paramKey,
15
+ computeAvailableVariables,
16
+ } from "./operations";
@@ -1,106 +1,106 @@
1
- import type { NodeOutput } from "../node";
2
- import type { Reference } from "../api";
3
- import type { ApiVariable } from "./Variable";
4
- import { isToolFlow, type EdgeType, type Edge } from "../edge";
5
- import { generateId } from "../id";
6
- import type { Variable } from "./Variable";
7
-
8
- // ============================================================================
9
- // Key Helpers
10
- // ============================================================================
11
-
12
- /** Compute the canonical map key for any CanvasVariable (or AvailableVariable). */
13
- export function varKey(v: Variable): string {
14
- switch (v.kind) {
15
- case "node":
16
- return `${v.nodeId}:${v.outputId}`;
17
- case "declared":
18
- return `declared:${v.uid}`;
19
- case "fnarg":
20
- return `fnarg:${v.uid}`;
21
- }
22
- }
23
-
24
- /** Key for a declared variable: `declared:<uid>` */
25
- export function declaredVarKey(uid: string): string {
26
- return `declared:${uid}`;
27
- }
28
-
29
- /** Key for a function argument variable: `fnarg:<uid>` */
30
- export function fnargKey(uid: string): string {
31
- return `fnarg:${uid}`;
32
- }
33
-
34
- /** Key for a node output variable: `<nodeId>:<outputId>` */
35
- export function nodeOutputVarKey(nodeId: string, outputId: string): string {
36
- return `${nodeId}:${outputId}`;
37
- }
38
-
39
- // ============================================================================
40
- // Reference → Lookup Key
41
- // ============================================================================
42
-
43
- /** Convert a Reference to the canonical lookup key used in the variables record. */
44
- export function refToLookupKey(ref: Reference): string {
45
- switch (ref.srcId) {
46
- case "declared":
47
- return declaredVarKey(ref.varId);
48
- case "fnarg":
49
- return fnargKey(ref.varId);
50
- default:
51
- return nodeOutputVarKey(ref.srcId, ref.varId);
52
- }
53
- }
54
-
55
- // ============================================================================
56
- // Variable UID Helpers for dynamic variable definitions (e.g. Agent output definitions)
57
- // ============================================================================
58
-
59
- /** Create a Variable from a NodeOutput by assigning a uid. If it already has a uid, return as-is. */
60
- export function ensureUid(v: NodeOutput | ApiVariable): ApiVariable {
61
- if ("uid" in v && v.uid) return v as ApiVariable;
62
- return { uid: generateId(), name: v.name, dataType: v.dataType };
63
- }
64
-
65
- /** Ensure every NodeOutput/Variable in an array has a uid. */
66
- export function ensureUids(vars: (NodeOutput | ApiVariable)[]): ApiVariable[] {
67
- return vars.map(ensureUid);
68
- }
69
-
70
- /** Get the binding key for a Variable — always its uid. */
71
- export function paramKey(p: ApiVariable): string {
72
- return p.uid;
73
- }
74
-
75
- /**
76
- * Pure function that computes available variables for a canvas from its own
77
- * variables record + edges. Function canvases are self-contained: only their
78
- * own declared variables, node outputs, and function arguments are visible;
79
- * main-canvas state is never merged in.
80
- *
81
- * Only `type`/`target` are read, but the param takes the shared structural
82
- * {@link Edge} so there's one edge shape across core — workflow-builder
83
- * still passes its React Flow `Edge[]` without an adapter, and core stays free
84
- * of `@xyflow/react`.
85
- */
86
- export function computeAvailableVariables(
87
- variables: Record<string, Variable>,
88
- canvasEdges: readonly Edge[],
89
- ): { list: Variable[]; lookup: Record<string, Variable> } {
90
- const list: Variable[] = [];
91
- const lookup: Record<string, Variable> = {};
92
-
93
- // Node outputs routed to a tool port are scoped to the agent — exclude them.
94
- const toolNodeIds = new Set<string>();
95
- for (const edge of canvasEdges) {
96
- if (isToolFlow(edge.type as EdgeType)) toolNodeIds.add(edge.target);
97
- }
98
-
99
- for (const [key, variable] of Object.entries(variables)) {
100
- if (variable.kind === "node" && toolNodeIds.has(variable.nodeId)) continue;
101
- list.push(variable);
102
- lookup[key] = variable;
103
- }
104
-
105
- return { list, lookup };
106
- }
1
+ import type { NodeOutput } from "../node";
2
+ import type { Reference } from "../api";
3
+ import type { ApiVariable } from "./Variable";
4
+ import { isToolFlow, type EdgeType, type Edge } from "../edge";
5
+ import { generateId } from "../id";
6
+ import type { Variable } from "./Variable";
7
+
8
+ // ============================================================================
9
+ // Key Helpers
10
+ // ============================================================================
11
+
12
+ /** Compute the canonical map key for any CanvasVariable (or AvailableVariable). */
13
+ export function varKey(v: Variable): string {
14
+ switch (v.kind) {
15
+ case "node":
16
+ return `${v.nodeId}:${v.outputId}`;
17
+ case "declared":
18
+ return `declared:${v.uid}`;
19
+ case "fnarg":
20
+ return `fnarg:${v.uid}`;
21
+ }
22
+ }
23
+
24
+ /** Key for a declared variable: `declared:<uid>` */
25
+ export function declaredVarKey(uid: string): string {
26
+ return `declared:${uid}`;
27
+ }
28
+
29
+ /** Key for a function argument variable: `fnarg:<uid>` */
30
+ export function fnargKey(uid: string): string {
31
+ return `fnarg:${uid}`;
32
+ }
33
+
34
+ /** Key for a node output variable: `<nodeId>:<outputId>` */
35
+ export function nodeOutputVarKey(nodeId: string, outputId: string): string {
36
+ return `${nodeId}:${outputId}`;
37
+ }
38
+
39
+ // ============================================================================
40
+ // Reference → Lookup Key
41
+ // ============================================================================
42
+
43
+ /** Convert a Reference to the canonical lookup key used in the variables record. */
44
+ export function refToLookupKey(ref: Reference): string {
45
+ switch (ref.srcId) {
46
+ case "declared":
47
+ return declaredVarKey(ref.varId);
48
+ case "fnarg":
49
+ return fnargKey(ref.varId);
50
+ default:
51
+ return nodeOutputVarKey(ref.srcId, ref.varId);
52
+ }
53
+ }
54
+
55
+ // ============================================================================
56
+ // Variable UID Helpers for dynamic variable definitions (e.g. Agent output definitions)
57
+ // ============================================================================
58
+
59
+ /** Create a Variable from a NodeOutput by assigning a uid. If it already has a uid, return as-is. */
60
+ export function ensureUid(v: NodeOutput | ApiVariable): ApiVariable {
61
+ if ("uid" in v && v.uid) return v as ApiVariable;
62
+ return { uid: generateId(), name: v.name, dataType: v.dataType };
63
+ }
64
+
65
+ /** Ensure every NodeOutput/Variable in an array has a uid. */
66
+ export function ensureUids(vars: (NodeOutput | ApiVariable)[]): ApiVariable[] {
67
+ return vars.map(ensureUid);
68
+ }
69
+
70
+ /** Get the binding key for a Variable — always its uid. */
71
+ export function paramKey(p: ApiVariable): string {
72
+ return p.uid;
73
+ }
74
+
75
+ /**
76
+ * Pure function that computes available variables for a canvas from its own
77
+ * variables record + edges. Function canvases are self-contained: only their
78
+ * own declared variables, node outputs, and function arguments are visible;
79
+ * main-canvas state is never merged in.
80
+ *
81
+ * Only `type`/`target` are read, but the param takes the shared structural
82
+ * {@link Edge} so there's one edge shape across core — workflow-builder
83
+ * still passes its React Flow `Edge[]` without an adapter, and core stays free
84
+ * of `@xyflow/react`.
85
+ */
86
+ export function computeAvailableVariables(
87
+ variables: Record<string, Variable>,
88
+ canvasEdges: readonly Edge[],
89
+ ): { list: Variable[]; lookup: Record<string, Variable> } {
90
+ const list: Variable[] = [];
91
+ const lookup: Record<string, Variable> = {};
92
+
93
+ // Node outputs routed to a tool port are scoped to the agent — exclude them.
94
+ const toolNodeIds = new Set<string>();
95
+ for (const edge of canvasEdges) {
96
+ if (isToolFlow(edge.type as EdgeType)) toolNodeIds.add(edge.target);
97
+ }
98
+
99
+ for (const [key, variable] of Object.entries(variables)) {
100
+ if (variable.kind === "node" && toolNodeIds.has(variable.nodeId)) continue;
101
+ list.push(variable);
102
+ lookup[key] = variable;
103
+ }
104
+
105
+ return { list, lookup };
106
+ }
@@ -1,41 +1,41 @@
1
- import type { Channel } from "../channel";
2
- import type { Memory } from "../memory";
3
- import type { Model } from "../model";
4
- import type { Node } from "../node";
5
- import type { FunctionDeclaration } from "../function";
6
- import type { Edge } from "../edge";
7
- import type { Variable } from "../variable";
8
- import type { Schemas } from "../api";
9
-
10
- export type ApiWorkflow = Schemas["Workflow"];
11
-
12
- /**
13
- * The id of the project's main canvas. All other canvas ids identify function
14
- * definitions. Lives here next to {@link Workflow} (which keys canvases
15
- * by this value) so the headless validator can reason about canvas scope
16
- * without depending on a UI store.
17
- */
18
- export const MAIN_CANVAS_ID = "main" as const;
19
-
20
- /**
21
- * In-memory domain state for a workflow, which the headless validator consumes.
22
- * NOT a persistence format, NOT the format the editor uses internally (Zustand stores).
23
- * This format is used as intermediary when importing/exporting to api format and to run validation
24
- */
25
- export interface Workflow {
26
- canvases: Record<string, Canvas>;
27
- functions: Record<string, FunctionDeclaration>;
28
- channels: Record<string, Channel>;
29
- memory: Record<string, Memory>;
30
- models: Record<string, Model>;
31
- }
32
-
33
- /**
34
- * One canvas's worth of in-memory domain state — the body of either the main canvas
35
- * or a function.
36
- */
37
- export interface Canvas {
38
- nodes: Node[];
39
- edges: Edge[];
40
- variables: Record<string, Variable>;
41
- }
1
+ import type { Channel } from "../channel";
2
+ import type { Memory } from "../memory";
3
+ import type { Model } from "../model";
4
+ import type { Node } from "../node";
5
+ import type { FunctionDeclaration } from "../function";
6
+ import type { Edge } from "../edge";
7
+ import type { Variable } from "../variable";
8
+ import type { Schemas } from "../api";
9
+
10
+ export type ApiWorkflow = Schemas["Workflow"];
11
+
12
+ /**
13
+ * The id of the project's main canvas. All other canvas ids identify function
14
+ * definitions. Lives here next to {@link Workflow} (which keys canvases
15
+ * by this value) so the headless validator can reason about canvas scope
16
+ * without depending on a UI store.
17
+ */
18
+ export const MAIN_CANVAS_ID = "main" as const;
19
+
20
+ /**
21
+ * In-memory domain state for a workflow, which the headless validator consumes.
22
+ * NOT a persistence format, NOT the format the editor uses internally (Zustand stores).
23
+ * This format is used as intermediary when importing/exporting to api format and to run validation
24
+ */
25
+ export interface Workflow {
26
+ canvases: Record<string, Canvas>;
27
+ functions: Record<string, FunctionDeclaration>;
28
+ channels: Record<string, Channel>;
29
+ memory: Record<string, Memory>;
30
+ models: Record<string, Model>;
31
+ }
32
+
33
+ /**
34
+ * One canvas's worth of in-memory domain state — the body of either the main canvas
35
+ * or a function.
36
+ */
37
+ export interface Canvas {
38
+ nodes: Node[];
39
+ edges: Edge[];
40
+ variables: Record<string, Variable>;
41
+ }
@@ -1,3 +1,3 @@
1
- export type { ApiWorkflow, Workflow, Canvas } from "./Workflow";
2
- export { MAIN_CANVAS_ID } from "./Workflow";
3
- export { serialize, deserialize, computeVariablesFromNodes } from "./serialization";
1
+ export type { ApiWorkflow, Workflow, Canvas } from "./Workflow";
2
+ export { MAIN_CANVAS_ID } from "./Workflow";
3
+ export { serialize, deserialize, computeVariablesFromNodes } from "./serialization";