@foresthubai/workflow-core 0.3.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 (339) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +14 -0
  3. package/README.md +63 -0
  4. package/dist/api/index.d.ts +7 -0
  5. package/dist/api/index.d.ts.map +1 -0
  6. package/dist/api/index.js +2 -0
  7. package/dist/api/index.js.map +1 -0
  8. package/dist/api/workflow.d.ts +607 -0
  9. package/dist/api/workflow.d.ts.map +1 -0
  10. package/dist/api/workflow.js +6 -0
  11. package/dist/api/workflow.js.map +1 -0
  12. package/dist/channel/Channel.d.ts +10 -0
  13. package/dist/channel/Channel.d.ts.map +1 -0
  14. package/dist/channel/Channel.js +2 -0
  15. package/dist/channel/Channel.js.map +1 -0
  16. package/dist/channel/ChannelDefinition.d.ts +27 -0
  17. package/dist/channel/ChannelDefinition.d.ts.map +1 -0
  18. package/dist/channel/ChannelDefinition.js +50 -0
  19. package/dist/channel/ChannelDefinition.js.map +1 -0
  20. package/dist/channel/index.d.ts +7 -0
  21. package/dist/channel/index.d.ts.map +1 -0
  22. package/dist/channel/index.js +4 -0
  23. package/dist/channel/index.js.map +1 -0
  24. package/dist/channel/serialization.d.ts +17 -0
  25. package/dist/channel/serialization.d.ts.map +1 -0
  26. package/dist/channel/serialization.js +63 -0
  27. package/dist/channel/serialization.js.map +1 -0
  28. package/dist/deploy/index.d.ts +2 -0
  29. package/dist/deploy/index.d.ts.map +1 -0
  30. package/dist/deploy/index.js +2 -0
  31. package/dist/deploy/index.js.map +1 -0
  32. package/dist/deploy/requirements.d.ts +17 -0
  33. package/dist/deploy/requirements.d.ts.map +1 -0
  34. package/dist/deploy/requirements.js +41 -0
  35. package/dist/deploy/requirements.js.map +1 -0
  36. package/dist/diagnostics/__fixtures__/diagnosticFixtures.d.ts +28 -0
  37. package/dist/diagnostics/__fixtures__/diagnosticFixtures.d.ts.map +1 -0
  38. package/dist/diagnostics/__fixtures__/diagnosticFixtures.js +125 -0
  39. package/dist/diagnostics/__fixtures__/diagnosticFixtures.js.map +1 -0
  40. package/dist/diagnostics/diagnostics.d.ts +128 -0
  41. package/dist/diagnostics/diagnostics.d.ts.map +1 -0
  42. package/dist/diagnostics/diagnostics.js +783 -0
  43. package/dist/diagnostics/diagnostics.js.map +1 -0
  44. package/dist/diagnostics/index.d.ts +3 -0
  45. package/dist/diagnostics/index.d.ts.map +1 -0
  46. package/dist/diagnostics/index.js +2 -0
  47. package/dist/diagnostics/index.js.map +1 -0
  48. package/dist/edge/Edge.d.ts +22 -0
  49. package/dist/edge/Edge.d.ts.map +1 -0
  50. package/dist/edge/Edge.js +2 -0
  51. package/dist/edge/Edge.js.map +1 -0
  52. package/dist/edge/EdgeDefinition.d.ts +10 -0
  53. package/dist/edge/EdgeDefinition.d.ts.map +1 -0
  54. package/dist/edge/EdgeDefinition.js +36 -0
  55. package/dist/edge/EdgeDefinition.js.map +1 -0
  56. package/dist/edge/EdgeType.d.ts +6 -0
  57. package/dist/edge/EdgeType.d.ts.map +1 -0
  58. package/dist/edge/EdgeType.js +7 -0
  59. package/dist/edge/EdgeType.js.map +1 -0
  60. package/dist/edge/index.d.ts +6 -0
  61. package/dist/edge/index.d.ts.map +1 -0
  62. package/dist/edge/index.js +6 -0
  63. package/dist/edge/index.js.map +1 -0
  64. package/dist/edge/serialization.d.ts +18 -0
  65. package/dist/edge/serialization.d.ts.map +1 -0
  66. package/dist/edge/serialization.js +76 -0
  67. package/dist/edge/serialization.js.map +1 -0
  68. package/dist/expression/index.d.ts +5 -0
  69. package/dist/expression/index.d.ts.map +1 -0
  70. package/dist/expression/index.js +3 -0
  71. package/dist/expression/index.js.map +1 -0
  72. package/dist/expression/parser.d.ts +14 -0
  73. package/dist/expression/parser.d.ts.map +1 -0
  74. package/dist/expression/parser.js +309 -0
  75. package/dist/expression/parser.js.map +1 -0
  76. package/dist/expression/types.d.ts +11 -0
  77. package/dist/expression/types.d.ts.map +1 -0
  78. package/dist/expression/types.js +20 -0
  79. package/dist/expression/types.js.map +1 -0
  80. package/dist/function/FunctionDeclaration.d.ts +43 -0
  81. package/dist/function/FunctionDeclaration.d.ts.map +1 -0
  82. package/dist/function/FunctionDeclaration.js +17 -0
  83. package/dist/function/FunctionDeclaration.js.map +1 -0
  84. package/dist/function/index.d.ts +4 -0
  85. package/dist/function/index.d.ts.map +1 -0
  86. package/dist/function/index.js +3 -0
  87. package/dist/function/index.js.map +1 -0
  88. package/dist/function/serialization.d.ts +20 -0
  89. package/dist/function/serialization.d.ts.map +1 -0
  90. package/dist/function/serialization.js +26 -0
  91. package/dist/function/serialization.js.map +1 -0
  92. package/dist/id/index.d.ts +7 -0
  93. package/dist/id/index.d.ts.map +1 -0
  94. package/dist/id/index.js +9 -0
  95. package/dist/id/index.js.map +1 -0
  96. package/dist/index.d.ts +11 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +14 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/memory/Memory.d.ts +12 -0
  101. package/dist/memory/Memory.d.ts.map +1 -0
  102. package/dist/memory/Memory.js +2 -0
  103. package/dist/memory/Memory.js.map +1 -0
  104. package/dist/memory/MemoryDefinition.d.ts +16 -0
  105. package/dist/memory/MemoryDefinition.d.ts.map +1 -0
  106. package/dist/memory/MemoryDefinition.js +2 -0
  107. package/dist/memory/MemoryDefinition.js.map +1 -0
  108. package/dist/memory/MemoryFileDefinition.d.ts +8 -0
  109. package/dist/memory/MemoryFileDefinition.d.ts.map +1 -0
  110. package/dist/memory/MemoryFileDefinition.js +36 -0
  111. package/dist/memory/MemoryFileDefinition.js.map +1 -0
  112. package/dist/memory/MemoryRegistry.d.ts +17 -0
  113. package/dist/memory/MemoryRegistry.d.ts.map +1 -0
  114. package/dist/memory/MemoryRegistry.js +29 -0
  115. package/dist/memory/MemoryRegistry.js.map +1 -0
  116. package/dist/memory/VectorDatabaseDefinition.d.ts +7 -0
  117. package/dist/memory/VectorDatabaseDefinition.d.ts.map +1 -0
  118. package/dist/memory/VectorDatabaseDefinition.js +20 -0
  119. package/dist/memory/VectorDatabaseDefinition.js.map +1 -0
  120. package/dist/memory/index.d.ts +9 -0
  121. package/dist/memory/index.d.ts.map +1 -0
  122. package/dist/memory/index.js +6 -0
  123. package/dist/memory/index.js.map +1 -0
  124. package/dist/memory/serialization.d.ts +11 -0
  125. package/dist/memory/serialization.d.ts.map +1 -0
  126. package/dist/memory/serialization.js +44 -0
  127. package/dist/memory/serialization.js.map +1 -0
  128. package/dist/migration/index.d.ts +5 -0
  129. package/dist/migration/index.d.ts.map +1 -0
  130. package/dist/migration/index.js +4 -0
  131. package/dist/migration/index.js.map +1 -0
  132. package/dist/migration/migrate.d.ts +11 -0
  133. package/dist/migration/migrate.d.ts.map +1 -0
  134. package/dist/migration/migrate.js +52 -0
  135. package/dist/migration/migrate.js.map +1 -0
  136. package/dist/migration/migrations.d.ts +22 -0
  137. package/dist/migration/migrations.d.ts.map +1 -0
  138. package/dist/migration/migrations.js +10 -0
  139. package/dist/migration/migrations.js.map +1 -0
  140. package/dist/migration/version.d.ts +9 -0
  141. package/dist/migration/version.d.ts.map +1 -0
  142. package/dist/migration/version.js +9 -0
  143. package/dist/migration/version.js.map +1 -0
  144. package/dist/model/LLMModelDefinition.d.ts +7 -0
  145. package/dist/model/LLMModelDefinition.d.ts.map +1 -0
  146. package/dist/model/LLMModelDefinition.js +11 -0
  147. package/dist/model/LLMModelDefinition.js.map +1 -0
  148. package/dist/model/Model.d.ts +21 -0
  149. package/dist/model/Model.d.ts.map +1 -0
  150. package/dist/model/Model.js +15 -0
  151. package/dist/model/Model.js.map +1 -0
  152. package/dist/model/ModelDefinition.d.ts +15 -0
  153. package/dist/model/ModelDefinition.d.ts.map +1 -0
  154. package/dist/model/ModelDefinition.js +2 -0
  155. package/dist/model/ModelDefinition.js.map +1 -0
  156. package/dist/model/ModelRegistry.d.ts +17 -0
  157. package/dist/model/ModelRegistry.d.ts.map +1 -0
  158. package/dist/model/ModelRegistry.js +27 -0
  159. package/dist/model/ModelRegistry.js.map +1 -0
  160. package/dist/model/index.d.ts +8 -0
  161. package/dist/model/index.d.ts.map +1 -0
  162. package/dist/model/index.js +5 -0
  163. package/dist/model/index.js.map +1 -0
  164. package/dist/model/serialization.d.ts +8 -0
  165. package/dist/model/serialization.d.ts.map +1 -0
  166. package/dist/model/serialization.js +25 -0
  167. package/dist/model/serialization.js.map +1 -0
  168. package/dist/node/AgentNode.d.ts +21 -0
  169. package/dist/node/AgentNode.d.ts.map +1 -0
  170. package/dist/node/AgentNode.js +60 -0
  171. package/dist/node/AgentNode.js.map +1 -0
  172. package/dist/node/DataNode.d.ts +14 -0
  173. package/dist/node/DataNode.d.ts.map +1 -0
  174. package/dist/node/DataNode.js +26 -0
  175. package/dist/node/DataNode.js.map +1 -0
  176. package/dist/node/FunctionNode.d.ts +24 -0
  177. package/dist/node/FunctionNode.d.ts.map +1 -0
  178. package/dist/node/FunctionNode.js +44 -0
  179. package/dist/node/FunctionNode.js.map +1 -0
  180. package/dist/node/InputNode.d.ts +46 -0
  181. package/dist/node/InputNode.d.ts.map +1 -0
  182. package/dist/node/InputNode.js +133 -0
  183. package/dist/node/InputNode.js.map +1 -0
  184. package/dist/node/LogicNode.d.ts +13 -0
  185. package/dist/node/LogicNode.d.ts.map +1 -0
  186. package/dist/node/LogicNode.js +19 -0
  187. package/dist/node/LogicNode.js.map +1 -0
  188. package/dist/node/MqttNode.d.ts +27 -0
  189. package/dist/node/MqttNode.d.ts.map +1 -0
  190. package/dist/node/MqttNode.js +96 -0
  191. package/dist/node/MqttNode.js.map +1 -0
  192. package/dist/node/Node.d.ts +49 -0
  193. package/dist/node/Node.d.ts.map +1 -0
  194. package/dist/node/Node.js +9 -0
  195. package/dist/node/Node.js.map +1 -0
  196. package/dist/node/NodeDefinition.d.ts +30 -0
  197. package/dist/node/NodeDefinition.d.ts.map +1 -0
  198. package/dist/node/NodeDefinition.js +2 -0
  199. package/dist/node/NodeDefinition.js.map +1 -0
  200. package/dist/node/NodeRegistry.d.ts +19 -0
  201. package/dist/node/NodeRegistry.d.ts.map +1 -0
  202. package/dist/node/NodeRegistry.js +65 -0
  203. package/dist/node/NodeRegistry.js.map +1 -0
  204. package/dist/node/OutputNode.d.ts +23 -0
  205. package/dist/node/OutputNode.d.ts.map +1 -0
  206. package/dist/node/OutputNode.js +62 -0
  207. package/dist/node/OutputNode.js.map +1 -0
  208. package/dist/node/ToolNode.d.ts +12 -0
  209. package/dist/node/ToolNode.d.ts.map +1 -0
  210. package/dist/node/ToolNode.js +18 -0
  211. package/dist/node/ToolNode.js.map +1 -0
  212. package/dist/node/TriggerNode.d.ts +67 -0
  213. package/dist/node/TriggerNode.d.ts.map +1 -0
  214. package/dist/node/TriggerNode.js +172 -0
  215. package/dist/node/TriggerNode.js.map +1 -0
  216. package/dist/node/constants.d.ts +16 -0
  217. package/dist/node/constants.d.ts.map +1 -0
  218. package/dist/node/constants.js +18 -0
  219. package/dist/node/constants.js.map +1 -0
  220. package/dist/node/index.d.ts +12 -0
  221. package/dist/node/index.d.ts.map +1 -0
  222. package/dist/node/index.js +9 -0
  223. package/dist/node/index.js.map +1 -0
  224. package/dist/node/methods.d.ts +73 -0
  225. package/dist/node/methods.d.ts.map +1 -0
  226. package/dist/node/methods.js +261 -0
  227. package/dist/node/methods.js.map +1 -0
  228. package/dist/node/serialization.d.ts +25 -0
  229. package/dist/node/serialization.d.ts.map +1 -0
  230. package/dist/node/serialization.js +525 -0
  231. package/dist/node/serialization.js.map +1 -0
  232. package/dist/parameter/OutputParameter.d.ts +69 -0
  233. package/dist/parameter/OutputParameter.d.ts.map +1 -0
  234. package/dist/parameter/OutputParameter.js +6 -0
  235. package/dist/parameter/OutputParameter.js.map +1 -0
  236. package/dist/parameter/Parameter.d.ts +152 -0
  237. package/dist/parameter/Parameter.d.ts.map +1 -0
  238. package/dist/parameter/Parameter.js +86 -0
  239. package/dist/parameter/Parameter.js.map +1 -0
  240. package/dist/parameter/index.d.ts +5 -0
  241. package/dist/parameter/index.d.ts.map +1 -0
  242. package/dist/parameter/index.js +3 -0
  243. package/dist/parameter/index.js.map +1 -0
  244. package/dist/variable/Variable.d.ts +25 -0
  245. package/dist/variable/Variable.d.ts.map +1 -0
  246. package/dist/variable/Variable.js +2 -0
  247. package/dist/variable/Variable.js.map +1 -0
  248. package/dist/variable/index.d.ts +3 -0
  249. package/dist/variable/index.d.ts.map +1 -0
  250. package/dist/variable/index.js +5 -0
  251. package/dist/variable/index.js.map +1 -0
  252. package/dist/variable/operations.d.ts +37 -0
  253. package/dist/variable/operations.d.ts.map +1 -0
  254. package/dist/variable/operations.js +88 -0
  255. package/dist/variable/operations.js.map +1 -0
  256. package/dist/workflow/Workflow.d.ts +38 -0
  257. package/dist/workflow/Workflow.d.ts.map +1 -0
  258. package/dist/workflow/Workflow.js +8 -0
  259. package/dist/workflow/Workflow.js.map +1 -0
  260. package/dist/workflow/index.d.ts +4 -0
  261. package/dist/workflow/index.d.ts.map +1 -0
  262. package/dist/workflow/index.js +3 -0
  263. package/dist/workflow/index.js.map +1 -0
  264. package/dist/workflow/serialization.d.ts +43 -0
  265. package/dist/workflow/serialization.d.ts.map +1 -0
  266. package/dist/workflow/serialization.js +215 -0
  267. package/dist/workflow/serialization.js.map +1 -0
  268. package/package.json +105 -0
  269. package/src/api/index.ts +11 -0
  270. package/src/api/workflow.ts +607 -0
  271. package/src/channel/Channel.ts +11 -0
  272. package/src/channel/ChannelDefinition.ts +76 -0
  273. package/src/channel/index.ts +6 -0
  274. package/src/channel/serialization.ts +68 -0
  275. package/src/deploy/index.ts +1 -0
  276. package/src/deploy/requirements.test.ts +61 -0
  277. package/src/deploy/requirements.ts +41 -0
  278. package/src/diagnostics/__fixtures__/diagnosticFixtures.ts +158 -0
  279. package/src/diagnostics/diagnostics.test.ts +878 -0
  280. package/src/diagnostics/diagnostics.ts +936 -0
  281. package/src/diagnostics/index.ts +11 -0
  282. package/src/edge/Edge.ts +23 -0
  283. package/src/edge/EdgeDefinition.ts +45 -0
  284. package/src/edge/EdgeType.ts +19 -0
  285. package/src/edge/index.ts +8 -0
  286. package/src/edge/serialization.ts +83 -0
  287. package/src/expression/index.ts +4 -0
  288. package/src/expression/parser.ts +362 -0
  289. package/src/expression/types.ts +30 -0
  290. package/src/function/FunctionDeclaration.ts +54 -0
  291. package/src/function/index.ts +3 -0
  292. package/src/function/serialization.ts +40 -0
  293. package/src/globals.d.ts +9 -0
  294. package/src/id/index.ts +8 -0
  295. package/src/index.ts +22 -0
  296. package/src/memory/Memory.ts +15 -0
  297. package/src/memory/MemoryDefinition.ts +16 -0
  298. package/src/memory/MemoryFileDefinition.ts +37 -0
  299. package/src/memory/MemoryRegistry.ts +35 -0
  300. package/src/memory/VectorDatabaseDefinition.ts +21 -0
  301. package/src/memory/index.ts +8 -0
  302. package/src/memory/serialization.ts +47 -0
  303. package/src/migration/index.ts +4 -0
  304. package/src/migration/migrate.test.ts +44 -0
  305. package/src/migration/migrate.ts +58 -0
  306. package/src/migration/migrations.ts +24 -0
  307. package/src/migration/version.ts +9 -0
  308. package/src/model/LLMModelDefinition.ts +12 -0
  309. package/src/model/Model.ts +39 -0
  310. package/src/model/ModelDefinition.ts +15 -0
  311. package/src/model/ModelRegistry.ts +33 -0
  312. package/src/model/index.ts +7 -0
  313. package/src/model/serialization.ts +30 -0
  314. package/src/node/AgentNode.ts +82 -0
  315. package/src/node/DataNode.ts +41 -0
  316. package/src/node/FunctionNode.ts +76 -0
  317. package/src/node/InputNode.ts +185 -0
  318. package/src/node/LogicNode.ts +33 -0
  319. package/src/node/MqttNode.ts +127 -0
  320. package/src/node/Node.ts +61 -0
  321. package/src/node/NodeDefinition.ts +37 -0
  322. package/src/node/NodeRegistry.ts +85 -0
  323. package/src/node/OutputNode.ts +87 -0
  324. package/src/node/ToolNode.ts +32 -0
  325. package/src/node/TriggerNode.ts +272 -0
  326. package/src/node/constants.ts +16 -0
  327. package/src/node/index.ts +26 -0
  328. package/src/node/methods.ts +278 -0
  329. package/src/node/serialization.ts +544 -0
  330. package/src/parameter/OutputParameter.ts +68 -0
  331. package/src/parameter/Parameter.ts +243 -0
  332. package/src/parameter/index.ts +33 -0
  333. package/src/variable/Variable.ts +10 -0
  334. package/src/variable/index.ts +16 -0
  335. package/src/variable/operations.ts +106 -0
  336. package/src/workflow/Workflow.ts +41 -0
  337. package/src/workflow/index.ts +3 -0
  338. package/src/workflow/serialization.test.ts +240 -0
  339. package/src/workflow/serialization.ts +242 -0
@@ -0,0 +1,41 @@
1
+ import { NodeBase } from "./Node";
2
+ import type { Expression, Reference } from "../api";
3
+ import { NodeCategory } from "./constants";
4
+ import { NodeDefinition } from "./NodeDefinition";
5
+
6
+ export interface SetVariableNode extends NodeBase {
7
+ type: "SetVariable";
8
+ arguments: {
9
+ variable: Reference | undefined;
10
+ value: Expression;
11
+ };
12
+ }
13
+
14
+ export type DataNodeType = "SetVariable";
15
+ export type DataNode = SetVariableNode;
16
+
17
+ // Node Definitions
18
+
19
+ export const SetVariableNodeDefinition: NodeDefinition = {
20
+ type: "SetVariable",
21
+ label: "Set Variable",
22
+ category: NodeCategory.Data,
23
+ description: "Assign a new value to an existing variable",
24
+ parameters: [
25
+ {
26
+ id: "variable",
27
+ label: "Variable",
28
+ description: "The variable to update",
29
+ type: "variableSelect",
30
+ },
31
+ {
32
+ id: "value",
33
+ label: "Value",
34
+ description: "Expression to assign",
35
+ type: "expression",
36
+ expressionType: "int", // fallback; actual type is derived from the target variable (see fromReference)
37
+ fromReference: "variable",
38
+ default: { expression: "", references: [], dataType: "int" },
39
+ },
40
+ ],
41
+ };
@@ -0,0 +1,76 @@
1
+ import { NodeBase } from "./Node";
2
+ import type { Expression } from "../api";
3
+ import type { FunctionInfo } from "../function";
4
+ import type { DataType } from "../api";
5
+ import { OutputBinding } from "../parameter";
6
+ import { NodeDefinition } from "./NodeDefinition";
7
+ import { NodeCategory } from "./constants";
8
+ import { paramKey } from "../variable";
9
+
10
+ // Function Call Node - invokes a user-defined function.
11
+ // Arguments are flat — keyed by Variable uid. Input argument uids map to Expression,
12
+ // return uids map to OutputBinding. Same shape as every other node, so the rest of
13
+ // the system (parameter editors, output bindings, merge/update) treats FunctionCall
14
+ // uniformly. Outputs are derived on-the-fly via buildFunctionNodeDef from
15
+ // functionInfo.returns — there is no registered NodeDefinition.
16
+ export interface FunctionCallNode extends NodeBase {
17
+ type: "FunctionCall";
18
+ functionInfo: FunctionInfo; // Snapshot at creation; may be stale vs registry
19
+ // Flat bag keyed by Variable uid (Expression for args, OutputBinding for returns),
20
+ // plus the reserved `toolDescription` key (string) for the tool-mode parameter.
21
+ arguments: Record<string, Expression | OutputBinding | string>;
22
+ }
23
+
24
+ export type FunctionCallNodeType = "FunctionCall";
25
+
26
+ // FunctionNodeDefinition extends NodeDefinition with function-specific fields
27
+ // Used by NodeLibrary to create new FunctionCall nodes
28
+ export interface FunctionNodeDefinition extends NodeDefinition {
29
+ type: "FunctionCall";
30
+ functionInfo: FunctionInfo; // Metadata about the function being called
31
+ }
32
+
33
+ /**
34
+ * Build a FunctionCall NodeDefinition from FunctionInfo. Pure — takes an
35
+ * optional translator function so the headless validator can call it without
36
+ * an i18n runtime; workflow-builder passes `i18n.t.bind(i18n)` to get
37
+ * translated descriptions. Defaults to identity (returns the key) when no
38
+ * translator is supplied; validation logic ignores description strings.
39
+ */
40
+ export function buildFunctionNodeDef(
41
+ fn: FunctionInfo,
42
+ t: (key: string, params?: Record<string, unknown>) => string = (key) => key,
43
+ ): FunctionNodeDefinition {
44
+ return {
45
+ type: "FunctionCall",
46
+ functionInfo: fn,
47
+ label: fn.name,
48
+ category: NodeCategory.Function,
49
+ description: t("builder.functionCallDesc", { name: fn.name }),
50
+ parameters: [
51
+ ...fn.arguments.map((param) => ({
52
+ id: paramKey(param),
53
+ label: param.name,
54
+ description: t("builder.functionParamDesc", { name: param.name }),
55
+ type: "expression" as const,
56
+ expressionType: param.dataType as DataType,
57
+ default: { expression: "", references: [], dataType: param.dataType as DataType },
58
+ activationRules: [{ type: "isControlFlow" as const }],
59
+ })),
60
+ {
61
+ id: "toolDescription",
62
+ label: "Tool Description",
63
+ description: "Description shown to the agent when this function is wired as a tool",
64
+ type: "string" as const,
65
+ multiline: true,
66
+ activationRules: [{ type: "isToolInput" as const }],
67
+ },
68
+ ],
69
+ outputs: fn.returns.map((ret) => ({
70
+ id: paramKey(ret),
71
+ label: ret.name,
72
+ type: "static" as const,
73
+ dataType: ret.dataType as DataType,
74
+ })),
75
+ };
76
+ }
@@ -0,0 +1,185 @@
1
+ import { NodeBase } from "./Node";
2
+ import type { Expression } from "../api";
3
+ import { OutputBinding } from "../parameter";
4
+ import { NodeCategory, NodeTag } from "./constants";
5
+ import { NodeDefinition } from "./NodeDefinition";
6
+
7
+ export interface ReadPinNode extends NodeBase {
8
+ type: "ReadPin";
9
+ arguments: {
10
+ pinReference: string | undefined;
11
+ signalType: "digital" | "analog";
12
+ output: OutputBinding;
13
+ toolDescription?: string;
14
+ };
15
+ }
16
+
17
+ export interface SerialReadNode extends NodeBase {
18
+ type: "SerialRead";
19
+ arguments: {
20
+ portReference: string | undefined;
21
+ prompt?: string;
22
+ output: OutputBinding;
23
+ };
24
+ }
25
+
26
+ // Retriever - provides RAG retrieval capability to agents
27
+ export interface RetrieverNode extends NodeBase {
28
+ type: "Retriever";
29
+ arguments: {
30
+ memoryReference: string;
31
+ topK: number | undefined;
32
+ query: Expression;
33
+ output: OutputBinding;
34
+ toolDescription?: string;
35
+ };
36
+ }
37
+
38
+ // WebFetch - fetches a URL and returns extracted text
39
+ export interface WebFetchNode extends NodeBase {
40
+ type: "WebFetch";
41
+ arguments: {
42
+ url: Expression;
43
+ maxChars: number | undefined;
44
+ output: OutputBinding;
45
+ };
46
+ }
47
+
48
+ export type InputNodeType = "ReadPin" | "SerialRead" | "Retriever" | "WebFetch";
49
+ export type InputNode = ReadPinNode | SerialReadNode | RetrieverNode | WebFetchNode;
50
+
51
+ // Node Definitions
52
+
53
+ export const ReadPinNodeDefinition: NodeDefinition = {
54
+ type: "ReadPin",
55
+ label: "Read Pin",
56
+ category: NodeCategory.Input,
57
+ tags: [NodeTag.Pin],
58
+ description: "Read data from a pin",
59
+ outputs: [
60
+ {
61
+ id: "output",
62
+ label: "Pin Value",
63
+ type: "static",
64
+ dataType: (args) => ((args as ReadPinNode["arguments"]).signalType === "digital" ? "bool" : "int"),
65
+ },
66
+ ],
67
+ parameters: [
68
+ {
69
+ id: "pinReference",
70
+ label: "Pin",
71
+ description: "IO pin to read from",
72
+ type: "channelSelect",
73
+ channelType: (args) => ((args as ReadPinNode["arguments"]).signalType === "digital" ? ["GPIOIN"] : ["ADC"]),
74
+ },
75
+ {
76
+ id: "signalType",
77
+ label: "Signal Type",
78
+ description: "Type of signal",
79
+ type: "selection",
80
+ default: "digital",
81
+ options: [
82
+ { value: "digital", label: "Digital" },
83
+ { value: "analog", label: "Analog" },
84
+ ],
85
+ },
86
+ {
87
+ id: "toolDescription",
88
+ label: "Tool Description",
89
+ description: "Description shown to the agent when this node is wired as a tool",
90
+ type: "string",
91
+ multiline: true,
92
+ activationRules: [{ type: "isToolInput" }],
93
+ },
94
+ ],
95
+ };
96
+
97
+ export const RetrieverNodeDefinition: NodeDefinition = {
98
+ type: "Retriever",
99
+ label: "Retriever",
100
+ category: NodeCategory.Input,
101
+ description: "Retrieves relevant documents from a knowledge base",
102
+ outputs: [{ id: "output", label: "Retrieved Documents", type: "static", dataType: "string" }],
103
+ parameters: [
104
+ {
105
+ id: "memoryReference",
106
+ label: "Vector Database",
107
+ description: "The vector database to search",
108
+ type: "memorySelect",
109
+ memoryType: ["VectorDatabase"],
110
+ },
111
+ {
112
+ id: "topK",
113
+ label: "Top K",
114
+ description: "Number of results to retrieve",
115
+ type: "int",
116
+ default: 5,
117
+ },
118
+ {
119
+ id: "query",
120
+ label: "Query",
121
+ description: "Search query expression",
122
+ type: "expression",
123
+ expressionType: "string",
124
+ default: { expression: "", references: [], dataType: "string" },
125
+ },
126
+ {
127
+ id: "toolDescription",
128
+ label: "Tool Description",
129
+ description: "Description shown to the agent when this node is wired as a tool",
130
+ type: "string",
131
+ multiline: true,
132
+ activationRules: [{ type: "isToolInput" }],
133
+ },
134
+ ],
135
+ };
136
+
137
+ export const WebFetchNodeDefinition: NodeDefinition = {
138
+ type: "WebFetch",
139
+ label: "Web Fetch",
140
+ category: NodeCategory.Input,
141
+ description: "Fetches a URL and returns extracted text",
142
+ outputs: [{ id: "output", label: "Fetched Text", type: "static", dataType: "string" }],
143
+ parameters: [
144
+ {
145
+ id: "url",
146
+ label: "URL",
147
+ description: "URL to fetch (http or https)",
148
+ type: "expression",
149
+ expressionType: "string",
150
+ default: { expression: "", references: [], dataType: "string" },
151
+ },
152
+ {
153
+ id: "maxChars",
154
+ label: "Max Characters",
155
+ description: "Maximum characters of extracted text to return",
156
+ type: "int",
157
+ optional: true,
158
+ },
159
+ ],
160
+ };
161
+
162
+ export const SerialReadNodeDefinition: NodeDefinition = {
163
+ type: "SerialRead",
164
+ label: "Serial Read",
165
+ category: NodeCategory.Input,
166
+ tags: [NodeTag.Serial],
167
+ description: "Read string from serial port",
168
+ outputs: [{ id: "output", label: "Serial Data", type: "static", dataType: "string" }],
169
+ parameters: [
170
+ {
171
+ id: "portReference",
172
+ label: "Port",
173
+ description: "Serial port to read from",
174
+ type: "channelSelect",
175
+ channelType: ["UART"],
176
+ },
177
+ {
178
+ id: "prompt",
179
+ label: "Input prompt",
180
+ description: "Prompt for the serial read operation",
181
+ type: "string",
182
+ optional: true,
183
+ },
184
+ ],
185
+ };
@@ -0,0 +1,33 @@
1
+ import { NodeBase } from "./Node";
2
+ import type { Expression } from "../api";
3
+ import { NodeCategory } from "./constants";
4
+ import { NodeDefinition } from "./NodeDefinition";
5
+
6
+ export interface IfNode extends NodeBase {
7
+ type: "If";
8
+ arguments: {
9
+ condition: Expression;
10
+ };
11
+ }
12
+
13
+ export type LogicNodeType = "If";
14
+ export type LogicNode = IfNode;
15
+
16
+ // Node Definitions
17
+
18
+ export const IfNodeDefinition: NodeDefinition = {
19
+ type: "If",
20
+ label: "If Condition Node",
21
+ category: NodeCategory.Logic,
22
+ description: "Conditional branching based on boolean expression",
23
+ parameters: [
24
+ {
25
+ id: "condition",
26
+ label: "Condition",
27
+ description: "Boolean expression (e.g., ${Input_1.value} > 50)",
28
+ type: "expression",
29
+ expressionType: "bool",
30
+ default: { expression: "", references: [], dataType: "bool" },
31
+ },
32
+ ],
33
+ };
@@ -0,0 +1,127 @@
1
+ import { NodeBase } from "./Node";
2
+ import type { Expression } from "../api";
3
+ import { OutputBinding } from "../parameter";
4
+ import { NodeCategory, NodeTag } from "./constants";
5
+ import { NodeDefinition } from "./NodeDefinition";
6
+
7
+ // MQTT Publish - publishes a single value to an MQTT topic
8
+ export interface MqttPublishNode extends NodeBase {
9
+ type: "MqttPublish";
10
+ arguments: {
11
+ channelReference: string;
12
+ dataType: "int" | "float" | "bool" | "string";
13
+ value: Expression;
14
+ qos: "0" | "1" | "2";
15
+ retain: boolean;
16
+ };
17
+ }
18
+
19
+ // On MQTT Message - fires when a message is received on a subscribed topic
20
+ export interface OnMqttMessageNode extends NodeBase {
21
+ type: "OnMqttMessage";
22
+ arguments: {
23
+ channelReference: string;
24
+ dataType: "int" | "float" | "bool" | "string";
25
+ output: OutputBinding;
26
+ };
27
+ }
28
+
29
+ export type MqttNodeType = "MqttPublish" | "OnMqttMessage";
30
+ export type MqttNode = MqttPublishNode | OnMqttMessageNode;
31
+
32
+ // Node Definitions
33
+
34
+ export const MqttPublishNodeDefinition: NodeDefinition = {
35
+ type: "MqttPublish",
36
+ label: "MQTT Publish",
37
+ category: NodeCategory.Output,
38
+ tags: [NodeTag.Network],
39
+ description: "Publish a value to an MQTT topic",
40
+ parameters: [
41
+ {
42
+ id: "channelReference",
43
+ label: "Channel",
44
+ description: "MQTT channel to publish through",
45
+ type: "channelSelect",
46
+ channelType: ["MQTT"],
47
+ },
48
+ {
49
+ id: "dataType",
50
+ label: "Data Type",
51
+ description: "Data type of the value to publish",
52
+ type: "selection",
53
+ options: [
54
+ { value: "int", label: "Integer" },
55
+ { value: "float", label: "Float" },
56
+ { value: "bool", label: "Boolean" },
57
+ { value: "string", label: "String" },
58
+ ],
59
+ default: "string",
60
+ },
61
+ {
62
+ id: "value",
63
+ label: "Value",
64
+ description: "Value to publish",
65
+ type: "expression",
66
+ expressionType: (args) => (args as MqttPublishNode["arguments"]).dataType,
67
+ default: { expression: "", references: [], dataType: "string" },
68
+ },
69
+ {
70
+ id: "qos",
71
+ label: "QoS",
72
+ description: "Quality of Service level",
73
+ type: "selection",
74
+ options: [
75
+ { value: "0", label: "0 - At most once" },
76
+ { value: "1", label: "1 - At least once" },
77
+ { value: "2", label: "2 - Exactly once" },
78
+ ],
79
+ default: "0",
80
+ },
81
+ {
82
+ id: "retain",
83
+ label: "Retain",
84
+ description: "Whether the broker should retain the message",
85
+ type: "bool",
86
+ default: false,
87
+ },
88
+ ],
89
+ };
90
+
91
+ export const OnMqttMessageNodeDefinition: NodeDefinition = {
92
+ type: "OnMqttMessage",
93
+ label: "On MQTT Message",
94
+ category: NodeCategory.Trigger,
95
+ tags: [NodeTag.Network],
96
+ description: "Fires when a message is received on a subscribed MQTT topic",
97
+ outputs: [
98
+ {
99
+ id: "output",
100
+ label: "Message Value",
101
+ type: "static",
102
+ dataType: (args) => (args as OnMqttMessageNode["arguments"]).dataType,
103
+ },
104
+ ],
105
+ parameters: [
106
+ {
107
+ id: "channelReference",
108
+ label: "Channel",
109
+ description: "MQTT channel to subscribe through",
110
+ type: "channelSelect",
111
+ channelType: ["MQTT"],
112
+ },
113
+ {
114
+ id: "dataType",
115
+ label: "Data Type",
116
+ description: "Expected data type of the received message value",
117
+ type: "selection",
118
+ options: [
119
+ { value: "int", label: "Integer" },
120
+ { value: "float", label: "Float" },
121
+ { value: "bool", label: "Boolean" },
122
+ { value: "string", label: "String" },
123
+ ],
124
+ default: "string",
125
+ },
126
+ ],
127
+ };
@@ -0,0 +1,61 @@
1
+ // Domain Node — the base shape every node variant builds on. NodeBase is the
2
+ // generic, untyped-parameters shape used wherever a node is handled generically
3
+ // (e.g. React Flow nodes); NodeData is the discriminated union over the
4
+ // per-variant interfaces (InputNode, AgentNode, …) for strongly-typed work.
5
+ // Mirrors how channel/memory/model keep their base shape in a same-named file and
6
+ // leave index.ts as a pure barrel. The per-variant interfaces import NodeBase
7
+ // from here directly, not via the barrel.
8
+
9
+ import type { DataType } from "../api";
10
+ import { InputNode, InputNodeType } from "./InputNode";
11
+ import { OutputNode, OutputNodeType } from "./OutputNode";
12
+ import { AgentNode, AgentNodeType } from "./AgentNode";
13
+ import { LogicNode, LogicNodeType } from "./LogicNode";
14
+ import { DataNode, DataNodeType } from "./DataNode";
15
+ import { TriggerNode, TriggerNodeType } from "./TriggerNode";
16
+ import { ToolNode, ToolNodeType } from "./ToolNode";
17
+ import { FunctionCallNode, FunctionCallNodeType } from "./FunctionNode";
18
+ import { MqttNode, MqttNodeType } from "./MqttNode";
19
+
20
+ export type NodeOutput = { name: string; dataType: DataType };
21
+ export type NodeType =
22
+ | InputNodeType
23
+ | OutputNodeType
24
+ | AgentNodeType
25
+ | LogicNodeType
26
+ | DataNodeType
27
+ | TriggerNodeType
28
+ | ToolNodeType
29
+ | FunctionCallNodeType
30
+ | MqttNodeType;
31
+
32
+ /**
33
+ * NodeData represents the runtime data for a node in the workflow builder.
34
+ * It is a union type of all specific node types, each with their own typed parameters.
35
+ * Use this type when you need strong typing for a specific node.
36
+ */
37
+ export type NodeData = InputNode | OutputNode | AgentNode | LogicNode | DataNode | TriggerNode | ToolNode | FunctionCallNode | MqttNode;
38
+
39
+ /**
40
+ * Full domain node entity held on a {@link Canvas}: the {@link NodeData}
41
+ * payload plus its canvas layout position, flattened. id/type/arguments/label
42
+ * come from NodeData; only `position` is added. The editor projects this into
43
+ * a React Flow node (adding the display type) at its store boundary.
44
+ */
45
+ export type Node = NodeData & { position: { x: number; y: number } };
46
+
47
+ /**
48
+ * NodeBase is a generic interface for all node instances.
49
+ * It uses an untyped parameters record to allow generic parameter handling (e.g., in React Flow nodes).
50
+ * Narrow to NodeData for specific node operations that require typed parameters.
51
+ *
52
+ * Per-output bindings (emit/assign/discard) live as flat entries inside `arguments`,
53
+ * keyed by the output id — same namespace as parameter values. List output entries
54
+ * (e.g. AgentNode's `outputDeclarations`) bundle their binding alongside their variable
55
+ * declaration as OutputDeclaration[].
56
+ */
57
+ export interface NodeBase extends Record<string, unknown> {
58
+ id: string; // Same as the React Flow node ID
59
+ type: NodeType; // Node discriminator
60
+ label?: string; // User-editable display label (falls back to nodeDefinition.label)
61
+ }
@@ -0,0 +1,37 @@
1
+ import { NodeType } from "./Node";
2
+ import { NodeCategory, NodeTag } from "./constants";
3
+ import { OutputParameter, Parameter } from "../parameter";
4
+
5
+ /**
6
+ * NodeDefinition describes static class-level node metadata.
7
+ * Methods (getPorts) are optional and take no arguments for static port definitions.
8
+ * Instance-dependent behavior lives in NodeBehavior.ts instead.
9
+ */
10
+ export interface NodeDefinition {
11
+ type: NodeType; // Node discriminator
12
+ label: string; // Human-readable, displayed name
13
+ category: NodeCategory; // Category for grouping (e.g., 'Input', 'Output', 'Logic')
14
+ description: string; // Description of what the node does
15
+ parameters: Parameter[]; // Parameter definitions for the node.
16
+ outputs?: OutputParameter[]; // Declarative output definitions — consumed by getNodeAvailableOutput() to compute a node's outputs
17
+ tags?: NodeTag[]; // Cross-cutting subsystem labels (Network, Pin, Serial, ...)
18
+ isUnremovable?: boolean; // Whether the node cannot be added or removed by a user
19
+ isSingleton?: boolean; // Whether only one instance of this node can exist in a canvas
20
+ canBranch?: boolean; // Whether the control output port may fan out to multiple branches (tool output ports are always multi-target)
21
+ }
22
+
23
+ // =============================================================================
24
+ // PORT DEFINITIONS
25
+ // =============================================================================
26
+
27
+ // Port represents a connectable port of a node
28
+ export interface Port {
29
+ id: string;
30
+ type: "control" | "tool";
31
+ label?: string;
32
+ }
33
+
34
+ export interface PortDefinitions {
35
+ input: Port[];
36
+ output: Port[];
37
+ }
@@ -0,0 +1,85 @@
1
+ import { ReadPinNodeDefinition, SerialReadNodeDefinition, RetrieverNodeDefinition, WebFetchNodeDefinition } from "./InputNode";
2
+ import { AgentNodeDefinition } from "./AgentNode";
3
+ import {
4
+ DelayNodeDefinition,
5
+ TickerNodeDefinition,
6
+ AlarmNodeDefinition,
7
+ OnFunctionCallNodeDefinition,
8
+ OnStartupNodeDefinition,
9
+ OnPinEdgeNodeDefinition,
10
+ OnSerialReceiveNodeDefinition,
11
+ OnThresholdNodeDefinition,
12
+ } from "./TriggerNode";
13
+ import { WebSearchToolNodeDefinition } from "./ToolNode";
14
+ import { NodeType } from "./Node";
15
+ import { NodeCategory } from "./constants";
16
+ import { SerialWriteNodeDefinition, WritePinNodeDefinition } from "./OutputNode";
17
+ import { IfNodeDefinition } from "./LogicNode";
18
+ import { SetVariableNodeDefinition } from "./DataNode";
19
+ import { MqttPublishNodeDefinition, OnMqttMessageNodeDefinition } from "./MqttNode";
20
+ import { NodeDefinition } from "./NodeDefinition";
21
+
22
+ /**
23
+ * Central registry for all node definitions.
24
+ */
25
+ class NodeDefinitionRegistry {
26
+ private nodes: Map<NodeType, NodeDefinition> = new Map();
27
+ private initialized = false;
28
+
29
+ initialize() {
30
+ if (this.initialized) return;
31
+
32
+ // Register all nodes
33
+ this.register(ReadPinNodeDefinition);
34
+ this.register(SerialReadNodeDefinition);
35
+ this.register(WritePinNodeDefinition);
36
+ this.register(SerialWriteNodeDefinition);
37
+ this.register(AgentNodeDefinition);
38
+ this.register(IfNodeDefinition);
39
+ this.register(SetVariableNodeDefinition);
40
+ // Register trigger nodes
41
+ this.register(OnFunctionCallNodeDefinition);
42
+ this.register(DelayNodeDefinition);
43
+ this.register(TickerNodeDefinition);
44
+ this.register(AlarmNodeDefinition);
45
+ this.register(OnStartupNodeDefinition);
46
+ this.register(OnPinEdgeNodeDefinition);
47
+ this.register(OnSerialReceiveNodeDefinition);
48
+ this.register(OnThresholdNodeDefinition);
49
+ // Register tool nodes
50
+ this.register(WebSearchToolNodeDefinition);
51
+ // Register input tool nodes
52
+ this.register(RetrieverNodeDefinition);
53
+ this.register(WebFetchNodeDefinition);
54
+ // Register MQTT nodes
55
+ this.register(MqttPublishNodeDefinition);
56
+ this.register(OnMqttMessageNodeDefinition);
57
+
58
+ this.initialized = true;
59
+ }
60
+
61
+ private register(definition: NodeDefinition) {
62
+ this.nodes.set(definition.type, definition);
63
+ }
64
+
65
+ getAll(): NodeDefinition[] {
66
+ return Array.from(this.nodes.values());
67
+ }
68
+
69
+ getAllCategories(): NodeCategory[] {
70
+ const categories = new Set(this.getAll().map((node) => node.category));
71
+ return Array.from(categories).sort();
72
+ }
73
+
74
+ getByType(type: NodeType): NodeDefinition | undefined {
75
+ return this.nodes.get(type);
76
+ }
77
+
78
+ getByCategory(category: NodeCategory): NodeDefinition[] {
79
+ return this.getAll().filter((node) => node.category === category);
80
+ }
81
+ }
82
+
83
+ // Create and initialize the registry
84
+ export const NodeRegistry = new NodeDefinitionRegistry();
85
+ NodeRegistry.initialize();