machinaos 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. package/.env.template +71 -0
  2. package/LICENSE +21 -0
  3. package/README.md +87 -0
  4. package/bin/cli.js +159 -0
  5. package/client/.dockerignore +45 -0
  6. package/client/Dockerfile +68 -0
  7. package/client/eslint.config.js +29 -0
  8. package/client/index.html +13 -0
  9. package/client/nginx.conf +66 -0
  10. package/client/package.json +48 -0
  11. package/client/src/App.tsx +27 -0
  12. package/client/src/Dashboard.tsx +1173 -0
  13. package/client/src/ParameterPanel.tsx +301 -0
  14. package/client/src/components/AIAgentNode.tsx +321 -0
  15. package/client/src/components/APIKeyValidator.tsx +118 -0
  16. package/client/src/components/ClaudeChatModelNode.tsx +18 -0
  17. package/client/src/components/ConditionalEdge.tsx +189 -0
  18. package/client/src/components/CredentialsModal.tsx +306 -0
  19. package/client/src/components/EdgeConditionEditor.tsx +443 -0
  20. package/client/src/components/GeminiChatModelNode.tsx +18 -0
  21. package/client/src/components/GenericNode.tsx +357 -0
  22. package/client/src/components/LocationParameterPanel.tsx +154 -0
  23. package/client/src/components/ModelNode.tsx +286 -0
  24. package/client/src/components/OpenAIChatModelNode.tsx +18 -0
  25. package/client/src/components/OutputPanel.tsx +471 -0
  26. package/client/src/components/ParameterRenderer.tsx +1874 -0
  27. package/client/src/components/SkillEditorModal.tsx +417 -0
  28. package/client/src/components/SquareNode.tsx +797 -0
  29. package/client/src/components/StartNode.tsx +250 -0
  30. package/client/src/components/ToolkitNode.tsx +365 -0
  31. package/client/src/components/TriggerNode.tsx +463 -0
  32. package/client/src/components/auth/LoginPage.tsx +247 -0
  33. package/client/src/components/auth/ProtectedRoute.tsx +59 -0
  34. package/client/src/components/base/BaseChatModelNode.tsx +271 -0
  35. package/client/src/components/icons/AIProviderIcons.tsx +50 -0
  36. package/client/src/components/maps/GoogleMapsPicker.tsx +137 -0
  37. package/client/src/components/maps/MapsPreviewPanel.tsx +110 -0
  38. package/client/src/components/maps/index.ts +26 -0
  39. package/client/src/components/parameterPanel/InputSection.tsx +1094 -0
  40. package/client/src/components/parameterPanel/LocationPanelLayout.tsx +65 -0
  41. package/client/src/components/parameterPanel/MapsSection.tsx +92 -0
  42. package/client/src/components/parameterPanel/MiddleSection.tsx +571 -0
  43. package/client/src/components/parameterPanel/OutputSection.tsx +81 -0
  44. package/client/src/components/parameterPanel/ParameterPanelLayout.tsx +82 -0
  45. package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +436 -0
  46. package/client/src/components/parameterPanel/index.ts +42 -0
  47. package/client/src/components/shared/DataPanel.tsx +142 -0
  48. package/client/src/components/shared/JSONTreeRenderer.tsx +106 -0
  49. package/client/src/components/ui/AIResultModal.tsx +204 -0
  50. package/client/src/components/ui/AndroidSettingsPanel.tsx +401 -0
  51. package/client/src/components/ui/CodeEditor.tsx +81 -0
  52. package/client/src/components/ui/CollapsibleSection.tsx +88 -0
  53. package/client/src/components/ui/ComponentItem.tsx +154 -0
  54. package/client/src/components/ui/ComponentPalette.tsx +321 -0
  55. package/client/src/components/ui/ConsolePanel.tsx +1074 -0
  56. package/client/src/components/ui/ErrorBoundary.tsx +196 -0
  57. package/client/src/components/ui/InputNodesPanel.tsx +204 -0
  58. package/client/src/components/ui/MapSelector.tsx +314 -0
  59. package/client/src/components/ui/Modal.tsx +149 -0
  60. package/client/src/components/ui/NodeContextMenu.tsx +192 -0
  61. package/client/src/components/ui/NodeOutputPanel.tsx +1150 -0
  62. package/client/src/components/ui/OutputDisplayPanel.tsx +381 -0
  63. package/client/src/components/ui/SettingsPanel.tsx +243 -0
  64. package/client/src/components/ui/TopToolbar.tsx +736 -0
  65. package/client/src/components/ui/WhatsAppSettingsPanel.tsx +345 -0
  66. package/client/src/components/ui/WorkflowSidebar.tsx +294 -0
  67. package/client/src/config/antdTheme.ts +186 -0
  68. package/client/src/config/api.ts +54 -0
  69. package/client/src/contexts/AuthContext.tsx +221 -0
  70. package/client/src/contexts/ThemeContext.tsx +42 -0
  71. package/client/src/contexts/WebSocketContext.tsx +1971 -0
  72. package/client/src/factories/baseChatModelFactory.ts +256 -0
  73. package/client/src/hooks/useAndroidOperations.ts +164 -0
  74. package/client/src/hooks/useApiKeyValidation.ts +107 -0
  75. package/client/src/hooks/useApiKeys.ts +238 -0
  76. package/client/src/hooks/useAppTheme.ts +17 -0
  77. package/client/src/hooks/useComponentPalette.ts +51 -0
  78. package/client/src/hooks/useCopyPaste.ts +155 -0
  79. package/client/src/hooks/useDragAndDrop.ts +124 -0
  80. package/client/src/hooks/useDragVariable.ts +88 -0
  81. package/client/src/hooks/useExecution.ts +313 -0
  82. package/client/src/hooks/useParameterPanel.ts +176 -0
  83. package/client/src/hooks/useReactFlowNodes.ts +189 -0
  84. package/client/src/hooks/useToolSchema.ts +209 -0
  85. package/client/src/hooks/useWhatsApp.ts +196 -0
  86. package/client/src/hooks/useWorkflowManagement.ts +46 -0
  87. package/client/src/index.css +315 -0
  88. package/client/src/main.tsx +19 -0
  89. package/client/src/nodeDefinitions/aiAgentNodes.ts +336 -0
  90. package/client/src/nodeDefinitions/aiModelNodes.ts +340 -0
  91. package/client/src/nodeDefinitions/androidDeviceNodes.ts +140 -0
  92. package/client/src/nodeDefinitions/androidServiceNodes.ts +383 -0
  93. package/client/src/nodeDefinitions/chatNodes.ts +135 -0
  94. package/client/src/nodeDefinitions/codeNodes.ts +54 -0
  95. package/client/src/nodeDefinitions/documentNodes.ts +379 -0
  96. package/client/src/nodeDefinitions/index.ts +15 -0
  97. package/client/src/nodeDefinitions/locationNodes.ts +463 -0
  98. package/client/src/nodeDefinitions/schedulerNodes.ts +220 -0
  99. package/client/src/nodeDefinitions/skillNodes.ts +211 -0
  100. package/client/src/nodeDefinitions/toolNodes.ts +198 -0
  101. package/client/src/nodeDefinitions/utilityNodes.ts +284 -0
  102. package/client/src/nodeDefinitions/whatsappNodes.ts +865 -0
  103. package/client/src/nodeDefinitions/workflowNodes.ts +41 -0
  104. package/client/src/nodeDefinitions.ts +104 -0
  105. package/client/src/schemas/workflowSchema.ts +264 -0
  106. package/client/src/services/dynamicParameterService.ts +96 -0
  107. package/client/src/services/execution/aiAgentExecutionService.ts +35 -0
  108. package/client/src/services/executionService.ts +232 -0
  109. package/client/src/services/workflowApi.ts +91 -0
  110. package/client/src/store/useAppStore.ts +582 -0
  111. package/client/src/styles/theme.ts +508 -0
  112. package/client/src/styles/zIndex.ts +17 -0
  113. package/client/src/types/ComponentTypes.ts +39 -0
  114. package/client/src/types/EdgeCondition.ts +231 -0
  115. package/client/src/types/INodeProperties.ts +288 -0
  116. package/client/src/types/NodeTypes.ts +28 -0
  117. package/client/src/utils/formatters.ts +33 -0
  118. package/client/src/utils/googleMapsLoader.ts +140 -0
  119. package/client/src/utils/locationUtils.ts +85 -0
  120. package/client/src/utils/nodeUtils.ts +31 -0
  121. package/client/src/utils/workflow.ts +30 -0
  122. package/client/src/utils/workflowExport.ts +120 -0
  123. package/client/src/vite-env.d.ts +12 -0
  124. package/client/tailwind.config.js +60 -0
  125. package/client/tsconfig.json +25 -0
  126. package/client/tsconfig.node.json +11 -0
  127. package/client/vite.config.js +35 -0
  128. package/docker-compose.prod.yml +107 -0
  129. package/docker-compose.yml +104 -0
  130. package/docs-MachinaOs/README.md +85 -0
  131. package/docs-MachinaOs/deployment/docker.mdx +228 -0
  132. package/docs-MachinaOs/deployment/production.mdx +345 -0
  133. package/docs-MachinaOs/docs.json +75 -0
  134. package/docs-MachinaOs/faq.mdx +309 -0
  135. package/docs-MachinaOs/favicon.svg +5 -0
  136. package/docs-MachinaOs/installation.mdx +160 -0
  137. package/docs-MachinaOs/introduction.mdx +114 -0
  138. package/docs-MachinaOs/logo/dark.svg +6 -0
  139. package/docs-MachinaOs/logo/light.svg +6 -0
  140. package/docs-MachinaOs/nodes/ai-agent.mdx +216 -0
  141. package/docs-MachinaOs/nodes/ai-models.mdx +240 -0
  142. package/docs-MachinaOs/nodes/android.mdx +411 -0
  143. package/docs-MachinaOs/nodes/overview.mdx +181 -0
  144. package/docs-MachinaOs/nodes/schedulers.mdx +316 -0
  145. package/docs-MachinaOs/nodes/webhooks.mdx +330 -0
  146. package/docs-MachinaOs/nodes/whatsapp.mdx +305 -0
  147. package/docs-MachinaOs/quickstart.mdx +119 -0
  148. package/docs-MachinaOs/tutorials/ai-agent-workflow.mdx +177 -0
  149. package/docs-MachinaOs/tutorials/android-automation.mdx +242 -0
  150. package/docs-MachinaOs/tutorials/first-workflow.mdx +134 -0
  151. package/docs-MachinaOs/tutorials/whatsapp-automation.mdx +185 -0
  152. package/nul +0 -0
  153. package/package.json +70 -0
  154. package/scripts/build.js +158 -0
  155. package/scripts/check-ports.ps1 +33 -0
  156. package/scripts/clean.js +40 -0
  157. package/scripts/docker.js +93 -0
  158. package/scripts/kill-port.ps1 +154 -0
  159. package/scripts/start.js +210 -0
  160. package/scripts/stop.js +325 -0
  161. package/server/.dockerignore +44 -0
  162. package/server/Dockerfile +45 -0
  163. package/server/constants.py +249 -0
  164. package/server/core/__init__.py +1 -0
  165. package/server/core/cache.py +461 -0
  166. package/server/core/config.py +128 -0
  167. package/server/core/container.py +99 -0
  168. package/server/core/database.py +1211 -0
  169. package/server/core/logging.py +314 -0
  170. package/server/main.py +289 -0
  171. package/server/middleware/__init__.py +5 -0
  172. package/server/middleware/auth.py +89 -0
  173. package/server/models/__init__.py +1 -0
  174. package/server/models/auth.py +52 -0
  175. package/server/models/cache.py +24 -0
  176. package/server/models/database.py +211 -0
  177. package/server/models/nodes.py +455 -0
  178. package/server/package.json +9 -0
  179. package/server/pyproject.toml +72 -0
  180. package/server/requirements.txt +83 -0
  181. package/server/routers/__init__.py +1 -0
  182. package/server/routers/android.py +294 -0
  183. package/server/routers/auth.py +203 -0
  184. package/server/routers/database.py +151 -0
  185. package/server/routers/maps.py +142 -0
  186. package/server/routers/nodejs_compat.py +289 -0
  187. package/server/routers/webhook.py +90 -0
  188. package/server/routers/websocket.py +2127 -0
  189. package/server/routers/whatsapp.py +761 -0
  190. package/server/routers/workflow.py +200 -0
  191. package/server/services/__init__.py +1 -0
  192. package/server/services/ai.py +2415 -0
  193. package/server/services/android/__init__.py +27 -0
  194. package/server/services/android/broadcaster.py +114 -0
  195. package/server/services/android/client.py +608 -0
  196. package/server/services/android/manager.py +78 -0
  197. package/server/services/android/protocol.py +165 -0
  198. package/server/services/android_service.py +588 -0
  199. package/server/services/auth.py +131 -0
  200. package/server/services/chat_client.py +160 -0
  201. package/server/services/deployment/__init__.py +12 -0
  202. package/server/services/deployment/manager.py +706 -0
  203. package/server/services/deployment/state.py +47 -0
  204. package/server/services/deployment/triggers.py +275 -0
  205. package/server/services/event_waiter.py +785 -0
  206. package/server/services/execution/__init__.py +77 -0
  207. package/server/services/execution/cache.py +769 -0
  208. package/server/services/execution/conditions.py +373 -0
  209. package/server/services/execution/dlq.py +132 -0
  210. package/server/services/execution/executor.py +1351 -0
  211. package/server/services/execution/models.py +531 -0
  212. package/server/services/execution/recovery.py +235 -0
  213. package/server/services/handlers/__init__.py +126 -0
  214. package/server/services/handlers/ai.py +355 -0
  215. package/server/services/handlers/android.py +260 -0
  216. package/server/services/handlers/code.py +278 -0
  217. package/server/services/handlers/document.py +598 -0
  218. package/server/services/handlers/http.py +193 -0
  219. package/server/services/handlers/polyglot.py +105 -0
  220. package/server/services/handlers/tools.py +845 -0
  221. package/server/services/handlers/triggers.py +107 -0
  222. package/server/services/handlers/utility.py +822 -0
  223. package/server/services/handlers/whatsapp.py +476 -0
  224. package/server/services/maps.py +289 -0
  225. package/server/services/memory_store.py +103 -0
  226. package/server/services/node_executor.py +375 -0
  227. package/server/services/parameter_resolver.py +218 -0
  228. package/server/services/polyglot_client.py +169 -0
  229. package/server/services/scheduler.py +155 -0
  230. package/server/services/skill_loader.py +417 -0
  231. package/server/services/status_broadcaster.py +826 -0
  232. package/server/services/temporal/__init__.py +23 -0
  233. package/server/services/temporal/activities.py +344 -0
  234. package/server/services/temporal/client.py +76 -0
  235. package/server/services/temporal/executor.py +147 -0
  236. package/server/services/temporal/worker.py +251 -0
  237. package/server/services/temporal/workflow.py +355 -0
  238. package/server/services/temporal/ws_client.py +236 -0
  239. package/server/services/text.py +111 -0
  240. package/server/services/user_auth.py +172 -0
  241. package/server/services/websocket_client.py +29 -0
  242. package/server/services/workflow.py +597 -0
  243. package/server/skills/android-skill/SKILL.md +82 -0
  244. package/server/skills/assistant-personality/SKILL.md +45 -0
  245. package/server/skills/code-skill/SKILL.md +140 -0
  246. package/server/skills/http-skill/SKILL.md +161 -0
  247. package/server/skills/maps-skill/SKILL.md +170 -0
  248. package/server/skills/memory-skill/SKILL.md +154 -0
  249. package/server/skills/scheduler-skill/SKILL.md +84 -0
  250. package/server/skills/whatsapp-skill/SKILL.md +283 -0
  251. package/server/uv.lock +2916 -0
  252. package/server/whatsapp-rpc/.dockerignore +30 -0
  253. package/server/whatsapp-rpc/Dockerfile +44 -0
  254. package/server/whatsapp-rpc/Dockerfile.web +17 -0
  255. package/server/whatsapp-rpc/README.md +139 -0
  256. package/server/whatsapp-rpc/cli.js +95 -0
  257. package/server/whatsapp-rpc/configs/config.yaml +7 -0
  258. package/server/whatsapp-rpc/docker-compose.yml +35 -0
  259. package/server/whatsapp-rpc/docs/API.md +410 -0
  260. package/server/whatsapp-rpc/go.mod +67 -0
  261. package/server/whatsapp-rpc/go.sum +203 -0
  262. package/server/whatsapp-rpc/package.json +30 -0
  263. package/server/whatsapp-rpc/schema.json +1294 -0
  264. package/server/whatsapp-rpc/scripts/clean.cjs +66 -0
  265. package/server/whatsapp-rpc/scripts/cli.js +162 -0
  266. package/server/whatsapp-rpc/src/go/cmd/server/main.go +91 -0
  267. package/server/whatsapp-rpc/src/go/config/config.go +49 -0
  268. package/server/whatsapp-rpc/src/go/rpc/rpc.go +446 -0
  269. package/server/whatsapp-rpc/src/go/rpc/server.go +112 -0
  270. package/server/whatsapp-rpc/src/go/whatsapp/history.go +166 -0
  271. package/server/whatsapp-rpc/src/go/whatsapp/messages.go +390 -0
  272. package/server/whatsapp-rpc/src/go/whatsapp/service.go +2130 -0
  273. package/server/whatsapp-rpc/src/go/whatsapp/types.go +261 -0
  274. package/server/whatsapp-rpc/src/python/pyproject.toml +15 -0
  275. package/server/whatsapp-rpc/src/python/whatsapp_rpc/__init__.py +4 -0
  276. package/server/whatsapp-rpc/src/python/whatsapp_rpc/client.py +427 -0
  277. package/server/whatsapp-rpc/web/app.py +609 -0
  278. package/server/whatsapp-rpc/web/requirements.txt +6 -0
  279. package/server/whatsapp-rpc/web/rpc_client.py +427 -0
  280. package/server/whatsapp-rpc/web/static/openapi.yaml +59 -0
  281. package/server/whatsapp-rpc/web/templates/base.html +150 -0
  282. package/server/whatsapp-rpc/web/templates/contacts.html +240 -0
  283. package/server/whatsapp-rpc/web/templates/dashboard.html +320 -0
  284. package/server/whatsapp-rpc/web/templates/groups.html +328 -0
  285. package/server/whatsapp-rpc/web/templates/messages.html +465 -0
  286. package/server/whatsapp-rpc/web/templates/messaging.html +681 -0
  287. package/server/whatsapp-rpc/web/templates/send.html +259 -0
  288. package/server/whatsapp-rpc/web/templates/settings.html +459 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Edge Condition Types for Runtime Conditional Branching
3
+ *
4
+ * Based on Prefect-style dynamic workflow branching.
5
+ * Conditions are evaluated against node output at runtime to determine
6
+ * which workflow paths to follow.
7
+ */
8
+
9
+ /**
10
+ * Supported comparison operators for edge conditions.
11
+ * Matches backend operators in server/services/execution/conditions.py
12
+ */
13
+ export type ConditionOperator =
14
+ // Equality operators
15
+ | 'eq' // Equal (==)
16
+ | 'neq' // Not equal (!=)
17
+ // Comparison operators (numeric)
18
+ | 'gt' // Greater than (>)
19
+ | 'lt' // Less than (<)
20
+ | 'gte' // Greater than or equal (>=)
21
+ | 'lte' // Less than or equal (<=)
22
+ // String/list contains
23
+ | 'contains' // String/list contains value
24
+ | 'not_contains' // String/list does not contain value
25
+ // Existence checks
26
+ | 'exists' // Field exists and is not None
27
+ | 'not_exists' // Field does not exist or is None
28
+ // Empty checks
29
+ | 'is_empty' // Field is empty (None, "", [], {})
30
+ | 'is_not_empty' // Field is not empty
31
+ // Regex match
32
+ | 'matches' // Regex pattern match
33
+ // List membership
34
+ | 'in' // Value is in list
35
+ | 'not_in' // Value is not in list
36
+ // String prefix/suffix
37
+ | 'starts_with' // String starts with value
38
+ | 'ends_with' // String ends with value
39
+ // Boolean checks
40
+ | 'is_true' // Value is truthy
41
+ | 'is_false' // Value is falsy
42
+ // Type checks
43
+ | 'is_string' // Value is a string
44
+ | 'is_number' // Value is a number
45
+ | 'is_boolean' // Value is a boolean
46
+ | 'is_array' // Value is an array
47
+ | 'is_object'; // Value is an object
48
+
49
+ /**
50
+ * Metadata for each operator - used by UI to render appropriate controls.
51
+ */
52
+ export interface OperatorMetadata {
53
+ label: string;
54
+ description: string;
55
+ requiresValue: boolean;
56
+ valueType?: 'string' | 'number' | 'boolean' | 'array' | 'any';
57
+ }
58
+
59
+ /**
60
+ * Registry of all operators with their metadata.
61
+ * Matches OPERATORS dict in server/services/execution/conditions.py
62
+ */
63
+ export const OPERATORS: Record<ConditionOperator, OperatorMetadata> = {
64
+ // Equality
65
+ eq: { label: 'Equals', description: 'Value equals target', requiresValue: true, valueType: 'any' },
66
+ neq: { label: 'Not Equals', description: 'Value does not equal target', requiresValue: true, valueType: 'any' },
67
+ // Comparison
68
+ gt: { label: 'Greater Than', description: 'Value is greater than target', requiresValue: true, valueType: 'number' },
69
+ lt: { label: 'Less Than', description: 'Value is less than target', requiresValue: true, valueType: 'number' },
70
+ gte: { label: 'Greater or Equal', description: 'Value is greater than or equal to target', requiresValue: true, valueType: 'number' },
71
+ lte: { label: 'Less or Equal', description: 'Value is less than or equal to target', requiresValue: true, valueType: 'number' },
72
+ // Contains
73
+ contains: { label: 'Contains', description: 'String/list contains value', requiresValue: true, valueType: 'string' },
74
+ not_contains: { label: 'Does Not Contain', description: 'String/list does not contain value', requiresValue: true, valueType: 'string' },
75
+ // Existence
76
+ exists: { label: 'Exists', description: 'Field exists and is not null', requiresValue: false },
77
+ not_exists: { label: 'Does Not Exist', description: 'Field does not exist or is null', requiresValue: false },
78
+ // Empty
79
+ is_empty: { label: 'Is Empty', description: 'Value is empty (null, "", [], {})', requiresValue: false },
80
+ is_not_empty: { label: 'Is Not Empty', description: 'Value is not empty', requiresValue: false },
81
+ // Regex
82
+ matches: { label: 'Matches Regex', description: 'Value matches regex pattern', requiresValue: true, valueType: 'string' },
83
+ // List membership
84
+ in: { label: 'In List', description: 'Value is in list', requiresValue: true, valueType: 'array' },
85
+ not_in: { label: 'Not In List', description: 'Value is not in list', requiresValue: true, valueType: 'array' },
86
+ // String prefix/suffix
87
+ starts_with: { label: 'Starts With', description: 'String starts with value', requiresValue: true, valueType: 'string' },
88
+ ends_with: { label: 'Ends With', description: 'String ends with value', requiresValue: true, valueType: 'string' },
89
+ // Boolean
90
+ is_true: { label: 'Is True', description: 'Value is truthy', requiresValue: false },
91
+ is_false: { label: 'Is False', description: 'Value is falsy', requiresValue: false },
92
+ // Type checks
93
+ is_string: { label: 'Is String', description: 'Value is a string', requiresValue: false },
94
+ is_number: { label: 'Is Number', description: 'Value is a number', requiresValue: false },
95
+ is_boolean: { label: 'Is Boolean', description: 'Value is a boolean', requiresValue: false },
96
+ is_array: { label: 'Is Array', description: 'Value is an array', requiresValue: false },
97
+ is_object: { label: 'Is Object', description: 'Value is an object', requiresValue: false },
98
+ };
99
+
100
+ /**
101
+ * Single edge condition - evaluated against source node output.
102
+ */
103
+ export interface EdgeCondition {
104
+ /** Output field to check (supports dot notation: "result.status", "items.0.name") */
105
+ field: string;
106
+ /** Comparison operator */
107
+ operator: ConditionOperator;
108
+ /** Value to compare against (required for operators with requiresValue: true) */
109
+ value?: string | number | boolean | any[];
110
+ }
111
+
112
+ /**
113
+ * Extended edge data with condition support.
114
+ * Used in edge.data field for conditional branching.
115
+ */
116
+ export interface ConditionalEdgeData {
117
+ /** Optional condition for this edge */
118
+ condition?: EdgeCondition;
119
+ /** Display label for the edge (shown on canvas) */
120
+ label?: string;
121
+ /** Logic for multiple conditions (future enhancement) */
122
+ conditionLogic?: 'and' | 'or';
123
+ /** Additional conditions (future enhancement) */
124
+ additionalConditions?: EdgeCondition[];
125
+ }
126
+
127
+ /**
128
+ * React Flow edge with conditional data.
129
+ * Extends the base Edge type with typed data property.
130
+ */
131
+ export interface ConditionalEdge {
132
+ id: string;
133
+ source: string;
134
+ target: string;
135
+ sourceHandle?: string | null;
136
+ targetHandle?: string | null;
137
+ type?: string;
138
+ animated?: boolean;
139
+ style?: React.CSSProperties;
140
+ className?: string;
141
+ data?: ConditionalEdgeData;
142
+ }
143
+
144
+ /**
145
+ * Props for the EdgeConditionEditor component.
146
+ */
147
+ export interface EdgeConditionEditorProps {
148
+ /** The edge being edited */
149
+ edge: ConditionalEdge;
150
+ /** Callback when condition is updated */
151
+ onConditionChange: (condition: EdgeCondition | undefined) => void;
152
+ /** Callback when label is updated */
153
+ onLabelChange: (label: string | undefined) => void;
154
+ /** Available fields from source node output (for autocomplete) */
155
+ availableFields?: string[];
156
+ /** Callback to close the editor */
157
+ onClose: () => void;
158
+ }
159
+
160
+ /**
161
+ * Get operators that don't require a value input.
162
+ */
163
+ export function getNoValueOperators(): ConditionOperator[] {
164
+ return (Object.keys(OPERATORS) as ConditionOperator[]).filter(
165
+ op => !OPERATORS[op].requiresValue
166
+ );
167
+ }
168
+
169
+ /**
170
+ * Get operators that require a value input.
171
+ */
172
+ export function getValueOperators(): ConditionOperator[] {
173
+ return (Object.keys(OPERATORS) as ConditionOperator[]).filter(
174
+ op => OPERATORS[op].requiresValue
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Get operators grouped by category.
180
+ */
181
+ export function getOperatorsByCategory(): Record<string, ConditionOperator[]> {
182
+ return {
183
+ 'Equality': ['eq', 'neq'],
184
+ 'Comparison': ['gt', 'lt', 'gte', 'lte'],
185
+ 'Contains': ['contains', 'not_contains'],
186
+ 'Existence': ['exists', 'not_exists'],
187
+ 'Empty': ['is_empty', 'is_not_empty'],
188
+ 'Pattern': ['matches', 'starts_with', 'ends_with'],
189
+ 'List': ['in', 'not_in'],
190
+ 'Boolean': ['is_true', 'is_false'],
191
+ 'Type': ['is_string', 'is_number', 'is_boolean', 'is_array', 'is_object'],
192
+ };
193
+ }
194
+
195
+ /**
196
+ * Format condition for display (edge label).
197
+ */
198
+ export function formatConditionLabel(condition: EdgeCondition): string {
199
+ const op = OPERATORS[condition.operator];
200
+ if (!op) return '';
201
+
202
+ if (!op.requiresValue) {
203
+ return `${condition.field} ${op.label.toLowerCase()}`;
204
+ }
205
+
206
+ const valueStr = Array.isArray(condition.value)
207
+ ? `[${condition.value.join(', ')}]`
208
+ : String(condition.value);
209
+
210
+ return `${condition.field} ${op.label.toLowerCase()} ${valueStr}`;
211
+ }
212
+
213
+ /**
214
+ * Validate a condition object.
215
+ */
216
+ export function validateCondition(condition: EdgeCondition): { valid: boolean; error?: string } {
217
+ if (!condition.field || condition.field.trim() === '') {
218
+ return { valid: false, error: 'Field is required' };
219
+ }
220
+
221
+ if (!condition.operator || !OPERATORS[condition.operator]) {
222
+ return { valid: false, error: 'Invalid operator' };
223
+ }
224
+
225
+ const op = OPERATORS[condition.operator];
226
+ if (op.requiresValue && (condition.value === undefined || condition.value === '')) {
227
+ return { valid: false, error: 'Value is required for this operator' };
228
+ }
229
+
230
+ return { valid: true };
231
+ }
@@ -0,0 +1,288 @@
1
+ // Modern n8n-inspired node property system
2
+ // Clean implementation with n8n-compatible data flow
3
+
4
+ // ============================================================================
5
+ // DATA FLOW INTERFACES - n8n-compatible data passing between nodes
6
+ // ============================================================================
7
+
8
+ // Binary data interface for files, images, documents, etc.
9
+ export interface IBinaryData {
10
+ mimeType: string;
11
+ fileName?: string;
12
+ directory?: string;
13
+ fileExtension?: string;
14
+ fileSize?: number;
15
+ data: string; // Base64 encoded data
16
+ id?: string;
17
+ }
18
+
19
+ // Core data structure that flows between nodes (n8n-compatible)
20
+ export interface INodeExecutionData {
21
+ json: Record<string, any>; // Main JSON data
22
+ binary?: Record<string, IBinaryData>; // Binary attachments (files, images, etc.)
23
+ pairedItem?: {
24
+ item: number;
25
+ input?: number;
26
+ };
27
+ error?: Error;
28
+ }
29
+
30
+ // Input/Output connection types
31
+ export type NodeConnectionType =
32
+ | 'main' // Standard data connection
33
+ | 'trigger' // Trigger/start connection
34
+ | 'ai' // AI service responses
35
+ | 'file' // File data
36
+ | 'binary' // Binary data specific
37
+ | 'webhook'; // Webhook data
38
+
39
+ // Enhanced output definition with data structure info
40
+ export interface INodeOutputDefinition {
41
+ name: string;
42
+ displayName: string;
43
+ type: NodeConnectionType;
44
+ description: string;
45
+ maxConnections?: number; // How many nodes can connect to this output
46
+ dataStructure?: {
47
+ // Expected JSON structure this output provides
48
+ properties: Record<string, {
49
+ type: 'string' | 'number' | 'boolean' | 'object' | 'array';
50
+ description?: string;
51
+ required?: boolean;
52
+ }>;
53
+ binaryData?: boolean; // Whether this output includes binary data
54
+ };
55
+ }
56
+
57
+ // Enhanced input definition
58
+ export interface INodeInputDefinition {
59
+ name: string;
60
+ displayName: string;
61
+ type: NodeConnectionType;
62
+ description: string;
63
+ required?: boolean;
64
+ maxConnections?: number; // How many connections this input accepts
65
+ acceptedDataTypes?: string[]; // What kind of data this input can handle
66
+ }
67
+
68
+ // ============================================================================
69
+ // PROPERTY DEFINITION INTERFACES
70
+ // ============================================================================
71
+
72
+ export interface INodePropertyOption {
73
+ name: string;
74
+ value: string | number | boolean;
75
+ label?: string;
76
+ description?: string;
77
+ action?: string;
78
+ }
79
+
80
+ export interface INodePropertyCollection {
81
+ displayName: string;
82
+ name: string;
83
+ values: INodeProperties[];
84
+ }
85
+
86
+ export interface INodePropertyTypeOptions {
87
+ loadOptionsMethod?: string;
88
+ loadOptionsDependsOn?: string[];
89
+ multipleValues?: boolean;
90
+ multipleValueButtonText?: string;
91
+ maxValue?: number;
92
+ minValue?: number;
93
+ numberStepSize?: number;
94
+ password?: boolean;
95
+ rows?: number;
96
+ editor?: 'code' | 'json' | 'html' | 'sql';
97
+ editorLanguage?: string;
98
+ // Dynamic parameter options
99
+ dynamicOptions?: boolean;
100
+ dependsOn?: string[];
101
+ // File input options
102
+ accept?: string; // MIME types or file extensions (e.g., 'image/*', '.pdf,.doc')
103
+ }
104
+
105
+ export interface INodePropertyDisplayOptions {
106
+ show?: Record<string, any[]>;
107
+ hide?: Record<string, any[]>;
108
+ }
109
+
110
+ export interface INodePropertyValidation {
111
+ type?: 'regex' | 'email' | 'url' | 'json' | 'apiKey';
112
+ pattern?: string;
113
+ message?: string;
114
+ // API Key validation specific properties
115
+ provider?: string;
116
+ showValidateButton?: boolean;
117
+ }
118
+
119
+ // Core property interface - modern n8n-inspired design
120
+ export interface INodeProperties {
121
+ displayName: string;
122
+ name: string;
123
+ type:
124
+ | 'string'
125
+ | 'number'
126
+ | 'boolean'
127
+ | 'options'
128
+ | 'multiOptions'
129
+ | 'collection'
130
+ | 'fixedCollection'
131
+ | 'color'
132
+ | 'dateTime'
133
+ | 'json'
134
+ | 'notice'
135
+ | 'hidden'
136
+ | 'resourceLocator'
137
+ | 'code'
138
+ | 'file';
139
+
140
+ default?: any;
141
+ description?: string;
142
+ placeholder?: string;
143
+ required?: boolean;
144
+ noDataExpression?: boolean;
145
+
146
+ options?: INodePropertyOption[] | INodePropertyCollection[];
147
+ typeOptions?: INodePropertyTypeOptions;
148
+ displayOptions?: INodePropertyDisplayOptions;
149
+ validation?: INodePropertyValidation[];
150
+ }
151
+
152
+ export interface INodeCredentialDescription {
153
+ name: string;
154
+ required?: boolean;
155
+ displayName?: string;
156
+ }
157
+
158
+ // Resource definition for Resource-Operation pattern
159
+ export interface INodeResourceDefinition {
160
+ name: string;
161
+ displayName: string;
162
+ icon?: string;
163
+ description?: string;
164
+ operations: INodeOperationDefinition[];
165
+ }
166
+
167
+ export interface INodeOperationDefinition {
168
+ name: string;
169
+ displayName: string;
170
+ description?: string;
171
+ action?: string;
172
+ properties: INodeProperties[];
173
+ }
174
+
175
+
176
+ // Main node type description interface
177
+ export interface INodeTypeDescription {
178
+ displayName: string;
179
+ name: string;
180
+ icon: string;
181
+ group: string[];
182
+ version: number;
183
+ subtitle?: string;
184
+ description: string;
185
+ keywords?: string[];
186
+ defaults: {
187
+ name: string;
188
+ color?: string;
189
+ };
190
+ inputs: string[] | INodeInputDefinition[];
191
+ outputs: string[] | INodeOutputDefinition[];
192
+ properties: INodeProperties[];
193
+ credentials?: INodeCredentialDescription[];
194
+ resources?: INodeResourceDefinition[];
195
+ methods?: {
196
+ loadOptions?: Record<string, (this: any) => Promise<INodePropertyOption[]>>;
197
+ };
198
+ }
199
+
200
+ // Node type interface that nodes must implement
201
+ export interface INodeType {
202
+ description: INodeTypeDescription;
203
+ methods?: {
204
+ loadOptions?: Record<string, () => Promise<INodePropertyOption[]>>;
205
+ };
206
+ execute?(inputData: INodeExecutionData[][]): Promise<INodeExecutionData[][]>;
207
+ }
208
+
209
+ // Execution context for nodes
210
+ export interface IExecuteContext {
211
+ nodeId: string;
212
+ nodeType?: string; // Add nodeType to context
213
+ parameters: Record<string, any>;
214
+ inputData: INodeExecutionData[][];
215
+ workflow: {
216
+ id: string;
217
+ name: string;
218
+ };
219
+ connectionType?: NodeConnectionType;
220
+ }
221
+
222
+ // ============================================================================
223
+ // HELPER FUNCTIONS FOR DATA FLOW
224
+ // ============================================================================
225
+
226
+ // Helper to create execution data in n8n format
227
+ export function createNodeExecutionData(json: Record<string, any>, binary?: Record<string, IBinaryData>): INodeExecutionData {
228
+ return {
229
+ json,
230
+ binary,
231
+ pairedItem: { item: 0 }
232
+ };
233
+ }
234
+
235
+ // Helper to create simple text output
236
+ export function createTextOutput(text: string, additionalData?: Record<string, any>): INodeExecutionData[] {
237
+ return [{
238
+ json: {
239
+ text,
240
+ ...additionalData
241
+ }
242
+ }];
243
+ }
244
+
245
+ // Helper to create file output
246
+ export function createFileOutput(filePath: string, fileName: string, mimeType: string, additionalData?: Record<string, any>): INodeExecutionData[] {
247
+ return [{
248
+ json: {
249
+ fileName,
250
+ filePath,
251
+ mimeType,
252
+ ...additionalData
253
+ },
254
+ binary: {
255
+ file: {
256
+ data: '', // Would be populated with actual file data
257
+ fileName,
258
+ mimeType,
259
+ fileSize: 0
260
+ }
261
+ }
262
+ }];
263
+ }
264
+
265
+ // Helper to create AI response output
266
+ export function createAIOutput(response: string, model: string, usage?: any, additionalData?: Record<string, any>): INodeExecutionData[] {
267
+ return [{
268
+ json: {
269
+ response,
270
+ model,
271
+ usage,
272
+ timestamp: new Date().toISOString(),
273
+ ...additionalData
274
+ }
275
+ }];
276
+ }
277
+
278
+ // Helper to create location output
279
+ export function createLocationOutput(latitude: number, longitude: number, additionalData?: Record<string, any>): INodeExecutionData[] {
280
+ return [{
281
+ json: {
282
+ latitude,
283
+ longitude,
284
+ timestamp: new Date().toISOString(),
285
+ ...additionalData
286
+ }
287
+ }];
288
+ }
@@ -0,0 +1,28 @@
1
+ export interface NodeParameter {
2
+ name: string;
3
+ displayName: string;
4
+ type: 'string' | 'number' | 'boolean' | 'select' | 'slider' | 'percentage' | 'file' | 'text' | 'array' | 'options' | 'multiOptions' | 'collection' | 'fixedCollection' | 'color' | 'dateTime' | 'notice' | 'hidden' | 'resourceLocator' | 'code' | 'json';
5
+ default?: any;
6
+ placeholder?: string;
7
+ description?: string;
8
+ options?: Array<{ value: any; label?: string; name?: string }>;
9
+ min?: number;
10
+ max?: number;
11
+ step?: number;
12
+ required?: boolean;
13
+ }
14
+
15
+ export interface NodeOutput {
16
+ name: string;
17
+ displayName: string;
18
+ type: 'string' | 'number' | 'boolean' | 'file' | 'array' | 'object' | string;
19
+ description: string;
20
+ }
21
+
22
+
23
+ export interface NodeData {
24
+ label?: string;
25
+ disabled?: boolean; // Skip execution when true (n8n-style disable)
26
+ customIcon?: string; // Custom icon: emoji, text, or image URL (http://, https://, data:, or /)
27
+ [key: string]: any;
28
+ }
@@ -0,0 +1,33 @@
1
+ // Common utility functions for formatting and clipboard operations
2
+ import { message } from 'antd';
3
+
4
+ /**
5
+ * Copy text to clipboard with error handling
6
+ */
7
+ export const copyToClipboard = async (data: any, successMessage?: string): Promise<boolean> => {
8
+ try {
9
+ const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
10
+ await navigator.clipboard.writeText(text);
11
+ if (successMessage) {
12
+ message.success(successMessage);
13
+ }
14
+ return true;
15
+ } catch (error) {
16
+ console.error('Failed to copy to clipboard:', error);
17
+ return false;
18
+ }
19
+ };
20
+
21
+ /**
22
+ * Format object as JSON string
23
+ */
24
+ export const formatJson = (obj: any, compact: boolean = false): string => {
25
+ return JSON.stringify(obj, null, compact ? 0 : 2);
26
+ };
27
+
28
+ /**
29
+ * Format timestamp to locale string
30
+ */
31
+ export const formatTimestamp = (timestamp: string | number | Date): string => {
32
+ return new Date(timestamp).toLocaleString();
33
+ };