@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,11 +1,11 @@
1
- export type { DiagnosticSeverity, DiagnosticCategory, Diagnostic, CanvasValidationResult, ValidationResult } from "./diagnostics";
2
- export {
3
- computeNodeDiagnostics,
4
- computeEdgeDiagnostics,
5
- validateChannel,
6
- validateMemory,
7
- validateModel,
8
- validateFunction,
9
- validateFunctionOutputs,
10
- validateWorkflowState,
11
- } from "./diagnostics";
1
+ export type { DiagnosticSeverity, DiagnosticCategory, Diagnostic, CanvasValidationResult, ValidationResult } from "./diagnostics";
2
+ export {
3
+ computeNodeDiagnostics,
4
+ computeEdgeDiagnostics,
5
+ validateChannel,
6
+ validateMemory,
7
+ validateModel,
8
+ validateFunction,
9
+ validateFunctionOutputs,
10
+ validateWorkflowState,
11
+ } from "./diagnostics";
package/src/edge/Edge.ts CHANGED
@@ -1,23 +1,23 @@
1
- import type { Expression } from "../api";
2
-
3
- export interface EdgeData extends Record<string, unknown> {
4
- prompt?: Expression; // agentTask and agentDelegate
5
- description?: string; // agentChoice and agentDelegate
6
- }
7
-
8
- /**
9
- * Full domain edge entity held on a {@link Canvas}: connectivity topology plus
10
- * the optional {@link EdgeData} payload. Low-level core fns that read only
11
- * connectivity accept it directly, and the editor's React Flow `Edge[]` is
12
- * structurally assignable
13
- * without an adapter (core stays free of `@xyflow/react`).
14
- */
15
- export interface Edge {
16
- id: string;
17
- type?: string;
18
- source: string;
19
- sourceHandle?: string | null;
20
- target: string;
21
- targetHandle?: string | null;
22
- data?: EdgeData;
23
- }
1
+ import type { Expression } from "../api";
2
+
3
+ export interface EdgeData extends Record<string, unknown> {
4
+ prompt?: Expression; // agentTask and agentDelegate
5
+ description?: string; // agentChoice and agentDelegate
6
+ }
7
+
8
+ /**
9
+ * Full domain edge entity held on a {@link Canvas}: connectivity topology plus
10
+ * the optional {@link EdgeData} payload. Low-level core fns that read only
11
+ * connectivity accept it directly, and the editor's React Flow `Edge[]` is
12
+ * structurally assignable
13
+ * without an adapter (core stays free of `@xyflow/react`).
14
+ */
15
+ export interface Edge {
16
+ id: string;
17
+ type?: string;
18
+ source: string;
19
+ sourceHandle?: string | null;
20
+ target: string;
21
+ targetHandle?: string | null;
22
+ data?: EdgeData;
23
+ }
@@ -1,45 +1,45 @@
1
- import { Parameter } from "../parameter";
2
- import type { EdgeType } from "./EdgeType";
3
-
4
- export interface EdgeDefinition {
5
- label: string;
6
- description: string;
7
- parameters: Parameter[];
8
- }
9
-
10
- export const EDGE_DEFINITIONS: Record<EdgeType, EdgeDefinition> = {
11
- agentTask: {
12
- label: "Task",
13
- description: "Assigns a task to an agent with a prompt",
14
- parameters: [{ id: "prompt", label: "Prompt", description: "", type: "expression", expressionType: "string", default: { expression: "", references: [], dataType: "string" } }],
15
- },
16
- agentChoice: {
17
- label: "Choice",
18
- description: "A path the agent can choose based on its description",
19
- parameters: [
20
- { id: "description", label: "Description", description: "", type: "string", default: "When should the agent take this path?" },
21
- ],
22
- },
23
- agentDelegate: {
24
- label: "Delegation",
25
- description: "Lets an agent hand off control to another agent",
26
- parameters: [
27
- { id: "description", label: "Description", description: "", type: "string", default: "When should the agent take this path?" },
28
- { id: "prompt", label: "Prompt", description: "", type: "expression", expressionType: "string", default: { expression: "", references: [], dataType: "string" } },
29
- ],
30
- },
31
- control: {
32
- label: "Control",
33
- description: "Sequential control flow between nodes",
34
- parameters: [],
35
- },
36
- tool: {
37
- label: "Tool",
38
- description: "Tool connection between nodes",
39
- parameters: [],
40
- },
41
- };
42
-
43
- export function getEdgeDefinition(type: EdgeType): EdgeDefinition {
44
- return EDGE_DEFINITIONS[type];
45
- }
1
+ import { Parameter } from "../parameter";
2
+ import type { EdgeType } from "./EdgeType";
3
+
4
+ export interface EdgeDefinition {
5
+ label: string;
6
+ description: string;
7
+ parameters: Parameter[];
8
+ }
9
+
10
+ export const EDGE_DEFINITIONS: Record<EdgeType, EdgeDefinition> = {
11
+ agentTask: {
12
+ label: "Task",
13
+ description: "Assigns a task to an agent with a prompt",
14
+ parameters: [{ id: "prompt", label: "Prompt", description: "", type: "expression", expressionType: "string", default: { expression: "", references: [], dataType: "string" } }],
15
+ },
16
+ agentChoice: {
17
+ label: "Choice",
18
+ description: "A path the agent can choose based on its description",
19
+ parameters: [
20
+ { id: "description", label: "Description", description: "", type: "string", default: "When should the agent take this path?" },
21
+ ],
22
+ },
23
+ agentDelegate: {
24
+ label: "Delegation",
25
+ description: "Lets an agent hand off control to another agent",
26
+ parameters: [
27
+ { id: "description", label: "Description", description: "", type: "string", default: "When should the agent take this path?" },
28
+ { id: "prompt", label: "Prompt", description: "", type: "expression", expressionType: "string", default: { expression: "", references: [], dataType: "string" } },
29
+ ],
30
+ },
31
+ control: {
32
+ label: "Control",
33
+ description: "Sequential control flow between nodes",
34
+ parameters: [],
35
+ },
36
+ tool: {
37
+ label: "Tool",
38
+ description: "Tool connection between nodes",
39
+ parameters: [],
40
+ },
41
+ };
42
+
43
+ export function getEdgeDefinition(type: EdgeType): EdgeDefinition {
44
+ return EDGE_DEFINITIONS[type];
45
+ }
@@ -1,19 +1,19 @@
1
- // Edge taxonomy: a plain control/tool edge, or one of the three agent-specific
2
- // control-flow refinements resolved at connection time from source/target context.
3
- // Node port handles themselves only carry `control` or `tool`. Tool edges have no
4
- // agent-specific variant — every tool edge points at an agent by construction.
5
- export type EdgeType = "control" | "tool" | "agentTask" | "agentChoice" | "agentDelegate";
6
-
7
- // All types that behave like control flow (horizontal bezier, side ports)
8
- export type ControlFlowType = "control" | "agentTask" | "agentChoice" | "agentDelegate";
9
-
10
- // All types that behave like tool connections (vertical bezier, top/bottom ports)
11
- export type ToolFlowType = "tool";
12
-
13
- export function isControlFlow(type: EdgeType): type is ControlFlowType {
14
- return type === "control" || type === "agentTask" || type === "agentChoice" || type === "agentDelegate";
15
- }
16
-
17
- export function isToolFlow(type: EdgeType): type is ToolFlowType {
18
- return type === "tool";
19
- }
1
+ // Edge taxonomy: a plain control/tool edge, or one of the three agent-specific
2
+ // control-flow refinements resolved at connection time from source/target context.
3
+ // Node port handles themselves only carry `control` or `tool`. Tool edges have no
4
+ // agent-specific variant — every tool edge points at an agent by construction.
5
+ export type EdgeType = "control" | "tool" | "agentTask" | "agentChoice" | "agentDelegate";
6
+
7
+ // All types that behave like control flow (horizontal bezier, side ports)
8
+ export type ControlFlowType = "control" | "agentTask" | "agentChoice" | "agentDelegate";
9
+
10
+ // All types that behave like tool connections (vertical bezier, top/bottom ports)
11
+ export type ToolFlowType = "tool";
12
+
13
+ export function isControlFlow(type: EdgeType): type is ControlFlowType {
14
+ return type === "control" || type === "agentTask" || type === "agentChoice" || type === "agentDelegate";
15
+ }
16
+
17
+ export function isToolFlow(type: EdgeType): type is ToolFlowType {
18
+ return type === "tool";
19
+ }
package/src/edge/index.ts CHANGED
@@ -1,8 +1,8 @@
1
- // Public surface of the edge module. The base type (EdgeData) lives in
2
- // ./Edge; this file is a barrel only. Mirrors channel/memory/model.
3
-
4
- export type { EdgeData, Edge } from "./Edge";
5
- export { type EdgeDefinition, getEdgeDefinition, EDGE_DEFINITIONS } from "./EdgeDefinition";
6
- export { type EdgeType, type ControlFlowType, type ToolFlowType, isControlFlow, isToolFlow } from "./EdgeType";
7
- export { serialize, deserialize } from "./serialization";
8
- export type { ApiEdge } from "./serialization";
1
+ // Public surface of the edge module. The base type (EdgeData) lives in
2
+ // ./Edge; this file is a barrel only. Mirrors channel/memory/model.
3
+
4
+ export type { EdgeData, Edge } from "./Edge";
5
+ export { type EdgeDefinition, getEdgeDefinition, EDGE_DEFINITIONS } from "./EdgeDefinition";
6
+ export { type EdgeType, type ControlFlowType, type ToolFlowType, isControlFlow, isToolFlow } from "./EdgeType";
7
+ export { serialize, deserialize } from "./serialization";
8
+ export type { ApiEdge } from "./serialization";
@@ -1,83 +1,83 @@
1
- import type { Schemas } from "../api";
2
- import type { Edge, EdgeData } from "./Edge";
3
- import type { EdgeType } from "./EdgeType";
4
-
5
- export type ApiEdge = Schemas["Edge"];
6
-
7
- /**
8
- * Serialize a domain {@link Edge} to the api `Edge`. The `id` is preserved
9
- * (the api requires it). Edge-type-conditional metadata (`prompt`,
10
- * `description`) is reattached from the edge's `data` payload.
11
- */
12
- export function serialize(edge: Edge): ApiEdge {
13
- const sourceHandle = edge.sourceHandle || "";
14
- const targetHandle = edge.targetHandle || "";
15
- const edgeType = edge.type as EdgeType | undefined;
16
- const from = { nodeId: edge.source, port: sourceHandle };
17
- const to = { nodeId: edge.target, port: targetHandle };
18
-
19
- switch (edgeType) {
20
- case "agentTask":
21
- return {
22
- id: edge.id,
23
- type: "agentTask",
24
- from,
25
- to,
26
- prompt: (edge.data?.prompt as Schemas["Expression"]) ?? { expression: "", references: [], dataType: "string" },
27
- };
28
- case "agentChoice":
29
- return {
30
- id: edge.id,
31
- type: "agentChoice",
32
- from,
33
- to,
34
- ...(edge.data?.description ? { description: edge.data.description as string } : {}),
35
- };
36
- case "agentDelegate":
37
- return {
38
- id: edge.id,
39
- type: "agentDelegate",
40
- from,
41
- to,
42
- ...(edge.data?.prompt ? { prompt: edge.data.prompt as Schemas["Expression"] } : {}),
43
- ...(edge.data?.description ? { description: edge.data.description as string } : {}),
44
- };
45
- case "control":
46
- return { id: edge.id, type: "control", from, to };
47
- case "tool":
48
- return { id: edge.id, type: "tool", from, to };
49
- default:
50
- return {
51
- id: edge.id,
52
- type: sourceHandle.startsWith("ctrl") || targetHandle.startsWith("ctrl") ? "control" : "tool",
53
- from,
54
- to,
55
- };
56
- }
57
- }
58
-
59
- /**
60
- * Convert an api `Edge` into a domain {@link Edge}. The api's `id` is preserved
61
- * verbatim (earlier code synthesized `e${index+1}`, breaking roundtrip
62
- * identity). Edge-type-conditional metadata (`prompt` on agentTask/agentDelegate;
63
- * `description` on agentChoice/agentDelegate) is folded into `data` as
64
- * {@link EdgeData}.
65
- */
66
- export function deserialize(apiEdge: ApiEdge): Edge {
67
- let data: EdgeData | undefined;
68
- if ((apiEdge.type === "agentTask" || apiEdge.type === "agentDelegate") && apiEdge.prompt) {
69
- data = { ...data, prompt: apiEdge.prompt };
70
- }
71
- if ((apiEdge.type === "agentChoice" || apiEdge.type === "agentDelegate") && apiEdge.description) {
72
- data = { ...data, description: apiEdge.description };
73
- }
74
- return {
75
- id: apiEdge.id,
76
- type: apiEdge.type,
77
- source: apiEdge.from.nodeId,
78
- sourceHandle: apiEdge.from.port,
79
- target: apiEdge.to.nodeId,
80
- targetHandle: apiEdge.to.port,
81
- ...(data ? { data } : {}),
82
- };
83
- }
1
+ import type { Schemas } from "../api";
2
+ import type { Edge, EdgeData } from "./Edge";
3
+ import type { EdgeType } from "./EdgeType";
4
+
5
+ export type ApiEdge = Schemas["Edge"];
6
+
7
+ /**
8
+ * Serialize a domain {@link Edge} to the api `Edge`. The `id` is preserved
9
+ * (the api requires it). Edge-type-conditional metadata (`prompt`,
10
+ * `description`) is reattached from the edge's `data` payload.
11
+ */
12
+ export function serialize(edge: Edge): ApiEdge {
13
+ const sourceHandle = edge.sourceHandle || "";
14
+ const targetHandle = edge.targetHandle || "";
15
+ const edgeType = edge.type as EdgeType | undefined;
16
+ const from = { nodeId: edge.source, port: sourceHandle };
17
+ const to = { nodeId: edge.target, port: targetHandle };
18
+
19
+ switch (edgeType) {
20
+ case "agentTask":
21
+ return {
22
+ id: edge.id,
23
+ type: "agentTask",
24
+ from,
25
+ to,
26
+ prompt: (edge.data?.prompt as Schemas["Expression"]) ?? { expression: "", references: [], dataType: "string" },
27
+ };
28
+ case "agentChoice":
29
+ return {
30
+ id: edge.id,
31
+ type: "agentChoice",
32
+ from,
33
+ to,
34
+ ...(edge.data?.description ? { description: edge.data.description as string } : {}),
35
+ };
36
+ case "agentDelegate":
37
+ return {
38
+ id: edge.id,
39
+ type: "agentDelegate",
40
+ from,
41
+ to,
42
+ ...(edge.data?.prompt ? { prompt: edge.data.prompt as Schemas["Expression"] } : {}),
43
+ ...(edge.data?.description ? { description: edge.data.description as string } : {}),
44
+ };
45
+ case "control":
46
+ return { id: edge.id, type: "control", from, to };
47
+ case "tool":
48
+ return { id: edge.id, type: "tool", from, to };
49
+ default:
50
+ return {
51
+ id: edge.id,
52
+ type: sourceHandle.startsWith("ctrl") || targetHandle.startsWith("ctrl") ? "control" : "tool",
53
+ from,
54
+ to,
55
+ };
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Convert an api `Edge` into a domain {@link Edge}. The api's `id` is preserved
61
+ * verbatim (earlier code synthesized `e${index+1}`, breaking roundtrip
62
+ * identity). Edge-type-conditional metadata (`prompt` on agentTask/agentDelegate;
63
+ * `description` on agentChoice/agentDelegate) is folded into `data` as
64
+ * {@link EdgeData}.
65
+ */
66
+ export function deserialize(apiEdge: ApiEdge): Edge {
67
+ let data: EdgeData | undefined;
68
+ if ((apiEdge.type === "agentTask" || apiEdge.type === "agentDelegate") && apiEdge.prompt) {
69
+ data = { ...data, prompt: apiEdge.prompt };
70
+ }
71
+ if ((apiEdge.type === "agentChoice" || apiEdge.type === "agentDelegate") && apiEdge.description) {
72
+ data = { ...data, description: apiEdge.description };
73
+ }
74
+ return {
75
+ id: apiEdge.id,
76
+ type: apiEdge.type,
77
+ source: apiEdge.from.nodeId,
78
+ sourceHandle: apiEdge.from.port,
79
+ target: apiEdge.to.nodeId,
80
+ targetHandle: apiEdge.to.port,
81
+ ...(data ? { data } : {}),
82
+ };
83
+ }
@@ -1,4 +1,4 @@
1
- export type { ParseResult } from "./parser";
2
- export { parseExpression } from "./parser";
3
- export type { ResolvedExpr } from "./types";
4
- export { resolveExpression, isExpression } from "./types";
1
+ export type { ParseResult } from "./parser";
2
+ export { parseExpression } from "./parser";
3
+ export type { ResolvedExpr } from "./types";
4
+ export { resolveExpression, isExpression } from "./types";