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,193 @@
1
+ """HTTP node handlers - HTTP Request and Webhook Response."""
2
+
3
+ import json
4
+ import time
5
+ from datetime import datetime
6
+ from typing import Dict, Any
7
+ from core.logging import get_logger
8
+
9
+ logger = get_logger(__name__)
10
+
11
+
12
+ async def handle_http_request(
13
+ node_id: str,
14
+ node_type: str,
15
+ parameters: Dict[str, Any],
16
+ context: Dict[str, Any]
17
+ ) -> Dict[str, Any]:
18
+ """Handle HTTP request node execution.
19
+
20
+ Makes HTTP requests to external APIs.
21
+
22
+ Args:
23
+ node_id: The node ID
24
+ node_type: The node type (httpRequest)
25
+ parameters: Resolved parameters
26
+ context: Execution context
27
+
28
+ Returns:
29
+ Execution result dict with response data
30
+ """
31
+ import httpx
32
+ start_time = time.time()
33
+
34
+ try:
35
+ method = parameters.get('method', 'GET')
36
+ url = parameters.get('url', '')
37
+ headers_str = parameters.get('headers', '{}')
38
+ body = parameters.get('body', '')
39
+ timeout = float(parameters.get('timeout', 30))
40
+
41
+ if not url:
42
+ raise ValueError("URL is required")
43
+
44
+ # Parse headers JSON
45
+ try:
46
+ headers = json.loads(headers_str) if headers_str else {}
47
+ except json.JSONDecodeError:
48
+ headers = {}
49
+
50
+ logger.info("[HTTP Request] Executing", node_id=node_id, method=method, url=url)
51
+
52
+ async with httpx.AsyncClient() as client:
53
+ kwargs = {
54
+ 'method': method,
55
+ 'url': url,
56
+ 'headers': headers,
57
+ 'timeout': timeout
58
+ }
59
+
60
+ # Add body for POST/PUT/PATCH
61
+ if method in ['POST', 'PUT', 'PATCH'] and body:
62
+ try:
63
+ kwargs['json'] = json.loads(body)
64
+ except json.JSONDecodeError:
65
+ kwargs['content'] = body
66
+
67
+ response = await client.request(**kwargs)
68
+
69
+ # Parse response data
70
+ try:
71
+ response_data = response.json()
72
+ except:
73
+ response_data = response.text
74
+
75
+ result_data = {
76
+ "status": response.status_code,
77
+ "data": response_data,
78
+ "headers": dict(response.headers),
79
+ "url": str(response.url),
80
+ "method": method
81
+ }
82
+
83
+ return {
84
+ "success": response.status_code < 400,
85
+ "node_id": node_id,
86
+ "node_type": "httpRequest",
87
+ "result": result_data,
88
+ "execution_time": time.time() - start_time,
89
+ "timestamp": datetime.now().isoformat()
90
+ }
91
+
92
+ except Exception as e:
93
+ if "TimeoutException" in type(e).__name__:
94
+ logger.error("HTTP request timed out", node_id=node_id, url=parameters.get('url'))
95
+ return {
96
+ "success": False,
97
+ "node_id": node_id,
98
+ "node_type": "httpRequest",
99
+ "error": f"Request timed out after {parameters.get('timeout', 30)} seconds",
100
+ "execution_time": time.time() - start_time,
101
+ "timestamp": datetime.now().isoformat()
102
+ }
103
+ logger.error("HTTP request failed", node_id=node_id, error=str(e))
104
+ return {
105
+ "success": False,
106
+ "node_id": node_id,
107
+ "node_type": "httpRequest",
108
+ "error": str(e),
109
+ "execution_time": time.time() - start_time,
110
+ "timestamp": datetime.now().isoformat()
111
+ }
112
+
113
+
114
+ async def handle_webhook_response(
115
+ node_id: str,
116
+ node_type: str,
117
+ parameters: Dict[str, Any],
118
+ context: Dict[str, Any],
119
+ connected_outputs: Dict[str, Any] = None
120
+ ) -> Dict[str, Any]:
121
+ """Handle webhook response node execution.
122
+
123
+ Sends response back to waiting webhook caller.
124
+
125
+ Args:
126
+ node_id: The node ID
127
+ node_type: The node type (webhookResponse)
128
+ parameters: Resolved parameters
129
+ context: Execution context
130
+ connected_outputs: Outputs from connected nodes
131
+
132
+ Returns:
133
+ Execution result dict
134
+ """
135
+ from routers.webhook import resolve_webhook_response
136
+ start_time = time.time()
137
+
138
+ try:
139
+ status_code = int(parameters.get('statusCode', 200))
140
+ response_body = parameters.get('responseBody', '')
141
+ content_type = parameters.get('contentType', 'application/json')
142
+
143
+ # Resolve template variables in response body
144
+ if response_body and connected_outputs:
145
+ for node_type_key, output_data in connected_outputs.items():
146
+ if isinstance(output_data, dict):
147
+ for key, value in output_data.items():
148
+ template = f"{{{{input.{key}}}}}"
149
+ response_body = response_body.replace(template, str(value))
150
+ # Also support {{nodeType.key}} format
151
+ template_alt = f"{{{{{node_type_key}.{key}}}}}"
152
+ response_body = response_body.replace(template_alt, str(value))
153
+
154
+ # If response body is empty, serialize connected outputs as JSON
155
+ if not response_body and connected_outputs:
156
+ # Get the first connected output
157
+ first_output = next(iter(connected_outputs.values()), {})
158
+ response_body = json.dumps(first_output, default=str)
159
+
160
+ logger.info("[Webhook Response] Sending", node_id=node_id, status_code=status_code,
161
+ content_type=content_type, body_length=len(response_body))
162
+
163
+ # Resolve the pending webhook response
164
+ resolve_webhook_response(node_id, {
165
+ 'statusCode': status_code,
166
+ 'body': response_body,
167
+ 'contentType': content_type
168
+ })
169
+
170
+ return {
171
+ "success": True,
172
+ "node_id": node_id,
173
+ "node_type": "webhookResponse",
174
+ "result": {
175
+ "sent": True,
176
+ "statusCode": status_code,
177
+ "contentType": content_type,
178
+ "bodyLength": len(response_body)
179
+ },
180
+ "execution_time": time.time() - start_time,
181
+ "timestamp": datetime.now().isoformat()
182
+ }
183
+
184
+ except Exception as e:
185
+ logger.error("Webhook response failed", node_id=node_id, error=str(e))
186
+ return {
187
+ "success": False,
188
+ "node_id": node_id,
189
+ "node_type": "webhookResponse",
190
+ "error": str(e),
191
+ "execution_time": time.time() - start_time,
192
+ "timestamp": datetime.now().isoformat()
193
+ }
@@ -0,0 +1,105 @@
1
+ """Polyglot node handlers - execute nodes via polyglot-server plugin registry.
2
+
3
+ This module provides handlers for routing node execution to polyglot-server.
4
+ It is designed to be optionally integrated without modifying the existing
5
+ workflow execution flow.
6
+
7
+ Usage:
8
+ # Optional integration - only if polyglot-server is running
9
+ from services.handlers.polyglot import handle_polyglot_node, POLYGLOT_NODE_TYPES
10
+ """
11
+
12
+ import time
13
+ from datetime import datetime
14
+ from typing import Dict, Any
15
+
16
+ from core.logging import get_logger
17
+
18
+ logger = get_logger(__name__)
19
+
20
+
21
+ async def handle_polyglot_node(
22
+ node_id: str,
23
+ node_type: str,
24
+ parameters: Dict[str, Any],
25
+ context: Dict[str, Any],
26
+ polyglot_client, # Injected via functools.partial
27
+ ) -> Dict[str, Any]:
28
+ """Execute a workflow node via polyglot-server plugin registry.
29
+
30
+ Args:
31
+ node_id: The workflow node ID
32
+ node_type: The node type (e.g., 'discordNode', 'telegramNode')
33
+ parameters: Resolved node parameters
34
+ context: Execution context
35
+ polyglot_client: PolyglotClient instance
36
+
37
+ Returns:
38
+ Execution result dict
39
+ """
40
+ start_time = time.time()
41
+
42
+ # Extract plugin name from node_type
43
+ plugin_name = node_type.replace("Node", "").lower()
44
+ action = parameters.get("action", "default")
45
+ params = {k: v for k, v in parameters.items() if k != "action"}
46
+
47
+ logger.info(
48
+ "[Polyglot] Executing plugin",
49
+ node_id=node_id,
50
+ plugin=plugin_name,
51
+ action=action,
52
+ )
53
+
54
+ try:
55
+ result = await polyglot_client.execute(plugin_name, action, params)
56
+ execution_time = time.time() - start_time
57
+
58
+ if result.get("success", False):
59
+ return {
60
+ "success": True,
61
+ "node_id": node_id,
62
+ "node_type": node_type,
63
+ "result": result.get("result", {}),
64
+ "timestamp": datetime.now().isoformat(),
65
+ "execution_time": execution_time,
66
+ }
67
+ else:
68
+ return {
69
+ "success": False,
70
+ "node_id": node_id,
71
+ "node_type": node_type,
72
+ "error": result.get("error", "Unknown error"),
73
+ "timestamp": datetime.now().isoformat(),
74
+ "execution_time": execution_time,
75
+ }
76
+
77
+ except Exception as e:
78
+ return {
79
+ "success": False,
80
+ "node_id": node_id,
81
+ "node_type": node_type,
82
+ "error": str(e),
83
+ "timestamp": datetime.now().isoformat(),
84
+ "execution_time": time.time() - start_time,
85
+ }
86
+
87
+
88
+ # Node types that can be routed to polyglot-server (for future use)
89
+ POLYGLOT_NODE_TYPES = frozenset([
90
+ "discordNode",
91
+ "telegramNode",
92
+ "slackNode",
93
+ "signalNode",
94
+ "notionNode",
95
+ "todoistNode",
96
+ "gmailNode",
97
+ "outlookNode",
98
+ "twitterNode",
99
+ "instagramNode",
100
+ "linkedinNode",
101
+ "dalleNode",
102
+ "stableDiffusionNode",
103
+ "githubNode",
104
+ "gitlabNode",
105
+ ])