machinaos 0.0.78 → 0.0.80

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 (743) hide show
  1. package/.env.template +74 -5
  2. package/{workflows/AI Assistant_workflow-1778504793388-ou1m1tz2x.json → .machina/workflows/AI Assistant_example_workflow-1779017037684-e2e5da7a.json } +164 -105
  3. package/{workflows/AI Employee_example_workflow-1777720598005-u4cm858dv.json → .machina/workflows/AI Employee_example_workflow-1779102911870-cbc76c82.json } +582 -328
  4. package/{workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json → .machina/workflows/Claude Assistant_example_workflow-1779095939967-2369cff4.json } +152 -83
  5. package/README.md +5 -2
  6. package/bin/cli.js +2 -2
  7. package/{machina → cli}/__main__.py +11 -7
  8. package/cli/_common.py +122 -0
  9. package/cli/buildenv.py +40 -0
  10. package/cli/cli.py +204 -0
  11. package/{machina → cli}/colors.py +10 -2
  12. package/cli/commands/__init__.py +1 -0
  13. package/cli/commands/_temporal_specs.py +59 -0
  14. package/{machina → cli}/commands/build.py +35 -45
  15. package/cli/commands/clean.py +141 -0
  16. package/cli/commands/daemon/__init__.py +47 -0
  17. package/cli/commands/daemon/_state.py +97 -0
  18. package/cli/commands/daemon/restart.py +14 -0
  19. package/cli/commands/daemon/start.py +49 -0
  20. package/cli/commands/daemon/status.py +20 -0
  21. package/cli/commands/daemon/stop.py +22 -0
  22. package/{machina → cli}/commands/dev.py +32 -42
  23. package/{machina → cli}/commands/docs.py +13 -11
  24. package/{machina → cli}/commands/start.py +69 -62
  25. package/{machina → cli}/commands/stop.py +7 -10
  26. package/{machina → cli}/commands/version.py +12 -6
  27. package/cli/config.py +170 -0
  28. package/cli/platform_.py +169 -0
  29. package/{machina → cli}/ports.py +42 -3
  30. package/{machina → cli}/run.py +29 -2
  31. package/{machina → cli}/supervisor.py +29 -12
  32. package/{machina → cli}/tcp.py +6 -2
  33. package/{machina → cli}/tree.py +38 -11
  34. package/client/dist/assets/{ActionBar-Du2MSFSz.js → ActionBar-Cjr3TF7g.js} +1 -1
  35. package/client/dist/assets/{ApiKeyInput-k2LBmBjb.js → ApiKeyInput-DIJE2PVA.js} +1 -1
  36. package/client/dist/assets/{ApiKeyPanel-C_bV9U0X.js → ApiKeyPanel-CPmye7uh.js} +1 -1
  37. package/client/dist/assets/{ApiUsageSection-CmVfwZzL.js → ApiUsageSection-TF_7gH2D.js} +1 -1
  38. package/client/dist/assets/{EmailPanel-CeKIMGu-.js → EmailPanel-Bs-xvbKR.js} +1 -1
  39. package/client/dist/assets/{OAuthPanel-KA3t3Q2K.js → OAuthPanel-BDtVJhAV.js} +1 -1
  40. package/client/dist/assets/{QrPairingPanel-NgNpJNuk.js → QrPairingPanel-BwJehTuZ.js} +1 -1
  41. package/client/dist/assets/{RateLimitSection-Du5YNVIA.js → RateLimitSection-CfNOoPIS.js} +1 -1
  42. package/client/dist/assets/{StatusCard-DNLyayXc.js → StatusCard-DkwIrgdP.js} +1 -1
  43. package/client/dist/assets/index-P2FzntoL.js +165 -0
  44. package/client/dist/index.html +1 -1
  45. package/client/package.json +1 -1
  46. package/client/src/Dashboard.tsx +128 -76
  47. package/client/src/adapters/nodeSpecToDescription.ts +7 -0
  48. package/client/src/assets/icons/index.test.ts +10 -0
  49. package/client/src/assets/icons/index.ts +16 -3
  50. package/client/src/components/AIAgentNode.tsx +8 -8
  51. package/client/src/components/ParameterRenderer.tsx +6 -3
  52. package/client/src/components/SkillEditorModal.tsx +1 -0
  53. package/client/src/components/credentials/panels/EmailPanel.tsx +2 -0
  54. package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +2 -0
  55. package/client/src/components/credentials/sections/RateLimitSection.tsx +1 -0
  56. package/client/src/components/icons/AIProviderIcons.tsx +1 -0
  57. package/client/src/components/maps/GoogleMapsPicker.tsx +1 -0
  58. package/client/src/components/parameterPanel/InputSection.tsx +1 -0
  59. package/client/src/components/parameterPanel/MasterSkillEditor.tsx +1 -0
  60. package/client/src/components/parameterPanel/OutputSection.tsx +1 -0
  61. package/client/src/components/ui/ComponentPalette.tsx +1 -0
  62. package/client/src/components/ui/MapSelector.tsx +1 -0
  63. package/client/src/components/ui/NodeContextMenu.tsx +3 -3
  64. package/client/src/components/ui/SettingsPanel.tsx +1 -0
  65. package/client/src/components/ui/action-button.tsx +1 -0
  66. package/client/src/components/ui/badge.tsx +1 -0
  67. package/client/src/components/ui/button.tsx +1 -0
  68. package/client/src/components/ui/form.tsx +1 -0
  69. package/client/src/components/ui/tabs.tsx +1 -0
  70. package/client/src/contexts/AuthContext.tsx +1 -0
  71. package/client/src/contexts/ThemeContext.tsx +1 -0
  72. package/client/src/contexts/WebSocketContext.tsx +104 -34
  73. package/client/src/hooks/__tests__/useApiKeys.test.ts +2 -2
  74. package/client/src/hooks/useReactFlowNodes.ts +1 -0
  75. package/client/src/hooks/useWorkflowValidation.ts +142 -0
  76. package/client/src/lib/nodeSpec.ts +1 -0
  77. package/client/src/test/providers.tsx +1 -0
  78. package/client/src/types/__tests__/cloudEvents.test.ts +5 -2
  79. package/client/src/types/cloudEvents.ts +19 -7
  80. package/client/src/utils/nodeUtils.ts +1 -1
  81. package/client/src/utils/workflow.ts +8 -2
  82. package/client/src/utils/workflowExport.ts +60 -3
  83. package/package.json +24 -23
  84. package/scripts/install.js +16 -27
  85. package/scripts/migrate_icons.py +3 -1
  86. package/scripts/migrate_skill_icons.py +6 -7
  87. package/scripts/postinstall.js +11 -9
  88. package/server/config/ai_cli_providers.json +2 -3
  89. package/server/config/credential_providers.json +15 -15
  90. package/server/config/llm_defaults.json +1 -1
  91. package/server/config/model_registry.json +416 -611
  92. package/server/constants.py +285 -223
  93. package/server/core/__init__.py +1 -1
  94. package/server/core/cache.py +9 -29
  95. package/server/core/cleanup.py +12 -24
  96. package/server/core/config.py +148 -24
  97. package/server/core/container.py +68 -59
  98. package/server/core/credential_backends.py +5 -13
  99. package/server/core/credentials_database.py +13 -43
  100. package/server/core/database.py +292 -353
  101. package/server/core/health.py +4 -5
  102. package/server/core/logging.py +241 -87
  103. package/server/core/paths.py +285 -0
  104. package/server/core/tracing.py +2 -8
  105. package/server/gunicorn.conf.py +1 -0
  106. package/server/main.py +150 -74
  107. package/server/middleware/auth.py +18 -24
  108. package/server/models/__init__.py +1 -1
  109. package/server/models/auth.py +5 -12
  110. package/server/models/database.py +36 -68
  111. package/server/models/node_metadata.py +25 -18
  112. package/server/nodejs/dist/index.js +107 -0
  113. package/server/nodes/README.md +11 -5
  114. package/server/nodes/__init__.py +1 -1
  115. package/server/nodes/_visuals.py +146 -14
  116. package/server/nodes/agent/_events.py +124 -0
  117. package/server/nodes/agent/_handles.py +15 -29
  118. package/server/nodes/agent/_inline.py +28 -25
  119. package/server/nodes/agent/_specialized.py +30 -15
  120. package/server/nodes/agent/{ai_agent.py → ai_agent/__init__.py} +33 -17
  121. package/server/nodes/agent/ai_agent/meta.json +3 -0
  122. package/server/nodes/agent/{ai_employee.py → ai_employee/__init__.py} +5 -2
  123. package/server/nodes/agent/ai_employee/meta.json +3 -0
  124. package/server/nodes/agent/{android_agent.py → android_agent/__init__.py} +1 -1
  125. package/server/nodes/agent/android_agent/meta.json +3 -0
  126. package/server/nodes/agent/{autonomous_agent.py → autonomous_agent/__init__.py} +2 -1
  127. package/server/nodes/agent/autonomous_agent/meta.json +3 -0
  128. package/server/nodes/agent/{chat_agent.py → chat_agent/__init__.py} +29 -12
  129. package/server/nodes/agent/chat_agent/meta.json +3 -0
  130. package/server/nodes/agent/{claude_code_agent.py → claude_code_agent/__init__.py} +192 -95
  131. package/server/nodes/agent/claude_code_agent/_handlers.py +169 -0
  132. package/server/{services/claude_oauth.py → nodes/agent/claude_code_agent/_oauth.py} +26 -13
  133. package/server/nodes/agent/claude_code_agent/_pool.py +1020 -0
  134. package/server/nodes/agent/claude_code_agent/_provider.py +513 -0
  135. package/server/nodes/agent/claude_code_agent/_skills.py +245 -0
  136. package/server/nodes/agent/claude_code_agent/meta.json +3 -0
  137. package/server/nodes/agent/{codex_agent.py → codex_agent/__init__.py} +26 -35
  138. package/server/nodes/agent/codex_agent/meta.json +3 -0
  139. package/server/nodes/agent/{coding_agent.py → coding_agent/__init__.py} +1 -1
  140. package/server/nodes/agent/coding_agent/meta.json +3 -0
  141. package/server/nodes/agent/{consumer_agent.py → consumer_agent/__init__.py} +1 -1
  142. package/server/nodes/agent/consumer_agent/meta.json +3 -0
  143. package/server/nodes/agent/{orchestrator_agent.py → orchestrator_agent/__init__.py} +5 -2
  144. package/server/nodes/agent/orchestrator_agent/meta.json +3 -0
  145. package/server/nodes/agent/{payments_agent.py → payments_agent/__init__.py} +1 -1
  146. package/server/nodes/agent/payments_agent/meta.json +3 -0
  147. package/server/nodes/agent/{productivity_agent.py → productivity_agent/__init__.py} +1 -1
  148. package/server/nodes/agent/productivity_agent/meta.json +3 -0
  149. package/server/nodes/agent/{rlm_agent.py → rlm_agent/__init__.py} +18 -17
  150. package/server/nodes/agent/rlm_agent/meta.json +3 -0
  151. package/server/nodes/agent/{social_agent.py → social_agent/__init__.py} +1 -1
  152. package/server/nodes/agent/social_agent/meta.json +3 -0
  153. package/server/nodes/agent/{task_agent.py → task_agent/__init__.py} +1 -1
  154. package/server/nodes/agent/task_agent/meta.json +3 -0
  155. package/server/nodes/agent/{tool_agent.py → tool_agent/__init__.py} +1 -1
  156. package/server/nodes/agent/tool_agent/meta.json +3 -0
  157. package/server/nodes/agent/{travel_agent.py → travel_agent/__init__.py} +1 -1
  158. package/server/nodes/agent/travel_agent/meta.json +3 -0
  159. package/server/nodes/agent/{web_agent.py → web_agent/__init__.py} +1 -1
  160. package/server/nodes/agent/web_agent/meta.json +3 -0
  161. package/server/nodes/android/__init__.py +24 -0
  162. package/server/nodes/android/_base.py +93 -76
  163. package/server/nodes/android/_dispatcher.py +140 -223
  164. package/server/nodes/android/_events.py +154 -0
  165. package/server/nodes/android/_handlers.py +13 -7
  166. package/server/nodes/android/_option_loaders.py +1 -4
  167. package/server/nodes/android/_refresh.py +27 -37
  168. package/server/nodes/android/_relay/broadcaster.py +25 -41
  169. package/server/nodes/android/_relay/client.py +23 -42
  170. package/server/nodes/android/_relay/manager.py +1 -0
  171. package/server/nodes/android/_relay/protocol.py +6 -0
  172. package/server/nodes/android/_router.py +48 -133
  173. package/server/nodes/android/{airplane_mode_control.py → airplane_mode_control/__init__.py} +2 -1
  174. package/server/nodes/android/airplane_mode_control/meta.json +3 -0
  175. package/server/nodes/android/{app_launcher.py → app_launcher/__init__.py} +2 -1
  176. package/server/nodes/android/app_launcher/meta.json +3 -0
  177. package/server/nodes/android/{app_list.py → app_list/__init__.py} +2 -1
  178. package/server/nodes/android/app_list/meta.json +3 -0
  179. package/server/nodes/android/{audio_automation.py → audio_automation/__init__.py} +2 -1
  180. package/server/nodes/android/audio_automation/meta.json +3 -0
  181. package/server/nodes/android/{battery_monitor.py → battery_monitor/__init__.py} +2 -1
  182. package/server/nodes/android/battery_monitor/meta.json +3 -0
  183. package/server/nodes/android/{bluetooth_automation.py → bluetooth_automation/__init__.py} +2 -1
  184. package/server/nodes/android/bluetooth_automation/meta.json +3 -0
  185. package/server/nodes/android/{camera_control.py → camera_control/__init__.py} +2 -1
  186. package/server/nodes/android/camera_control/meta.json +3 -0
  187. package/server/nodes/android/{device_state_automation.py → device_state_automation/__init__.py} +2 -1
  188. package/server/nodes/android/device_state_automation/meta.json +3 -0
  189. package/server/nodes/android/{environmental_sensors.py → environmental_sensors/__init__.py} +2 -1
  190. package/server/nodes/android/environmental_sensors/meta.json +3 -0
  191. package/server/nodes/android/{location.py → location/__init__.py} +2 -1
  192. package/server/nodes/android/location/meta.json +3 -0
  193. package/server/nodes/android/{media_control.py → media_control/__init__.py} +2 -1
  194. package/server/nodes/android/media_control/meta.json +3 -0
  195. package/server/nodes/android/{motion_detection.py → motion_detection/__init__.py} +2 -1
  196. package/server/nodes/android/motion_detection/meta.json +3 -0
  197. package/server/nodes/android/{network_monitor.py → network_monitor/__init__.py} +2 -1
  198. package/server/nodes/android/network_monitor/meta.json +3 -0
  199. package/server/nodes/android/{screen_control_automation.py → screen_control_automation/__init__.py} +2 -1
  200. package/server/nodes/android/screen_control_automation/meta.json +3 -0
  201. package/server/nodes/android/{system_info.py → system_info/__init__.py} +2 -1
  202. package/server/nodes/android/system_info/meta.json +3 -0
  203. package/server/nodes/android/{wifi_automation.py → wifi_automation/__init__.py} +2 -1
  204. package/server/nodes/android/wifi_automation/meta.json +3 -0
  205. package/server/nodes/browser/__init__.py +22 -1
  206. package/server/nodes/browser/_install.py +63 -0
  207. package/server/nodes/browser/_service.py +21 -25
  208. package/server/nodes/browser/{browser.py → browser/__init__.py} +58 -25
  209. package/server/nodes/browser/browser/meta.json +3 -0
  210. package/server/nodes/chat/{chat_history.py → chat_history/__init__.py} +2 -4
  211. package/server/nodes/chat/chat_history/meta.json +3 -0
  212. package/server/nodes/chat/{chat_send.py → chat_send/__init__.py} +2 -4
  213. package/server/nodes/chat/chat_send/icon.svg +1 -0
  214. package/server/nodes/chat/chat_send/meta.json +3 -0
  215. package/server/nodes/code/_base.py +1 -1
  216. package/server/nodes/code/{javascript_executor.py → javascript_executor/__init__.py} +5 -5
  217. package/server/nodes/code/javascript_executor/meta.json +3 -0
  218. package/server/nodes/code/{python_executor.py → python_executor/__init__.py} +32 -14
  219. package/server/nodes/code/python_executor/meta.json +3 -0
  220. package/server/nodes/code/{typescript_executor.py → typescript_executor/__init__.py} +5 -5
  221. package/server/nodes/code/typescript_executor/meta.json +3 -0
  222. package/server/nodes/document/{document_parser.py → document_parser/__init__.py} +26 -15
  223. package/server/nodes/document/document_parser/meta.json +3 -0
  224. package/server/nodes/document/{embedding_generator.py → embedding_generator/__init__.py} +16 -9
  225. package/server/nodes/document/embedding_generator/meta.json +3 -0
  226. package/server/nodes/document/{file_downloader.py → file_downloader/__init__.py} +30 -20
  227. package/server/nodes/document/file_downloader/meta.json +3 -0
  228. package/server/nodes/document/{http_scraper.py → http_scraper/__init__.py} +31 -21
  229. package/server/nodes/document/http_scraper/meta.json +3 -0
  230. package/server/nodes/document/{text_chunker.py → text_chunker/__init__.py} +17 -12
  231. package/server/nodes/document/text_chunker/meta.json +3 -0
  232. package/server/nodes/document/{vector_store.py → vector_store/__init__.py} +88 -72
  233. package/server/nodes/document/vector_store/meta.json +3 -0
  234. package/server/nodes/email/__init__.py +9 -2
  235. package/server/nodes/email/_events.py +54 -0
  236. package/server/nodes/email/_filters.py +3 -3
  237. package/server/nodes/email/_himalaya.py +95 -50
  238. package/server/nodes/email/_service.py +23 -13
  239. package/server/nodes/email/{email_read.py → email_read/__init__.py} +23 -11
  240. package/server/nodes/email/email_read/icon.svg +6 -0
  241. package/server/nodes/email/email_read/meta.json +3 -0
  242. package/server/nodes/email/{email_receive.py → email_receive/__init__.py} +45 -23
  243. package/server/nodes/email/email_receive/meta.json +3 -0
  244. package/server/nodes/email/{email_send.py → email_send/__init__.py} +13 -7
  245. package/server/nodes/email/email_send/meta.json +3 -0
  246. package/server/nodes/filesystem/_backend.py +1 -5
  247. package/server/nodes/filesystem/{file_modify.py → file_modify/__init__.py} +10 -5
  248. package/server/nodes/filesystem/file_modify/meta.json +3 -0
  249. package/server/nodes/filesystem/{file_read.py → file_read/__init__.py} +7 -3
  250. package/server/nodes/filesystem/file_read/meta.json +3 -0
  251. package/server/nodes/filesystem/{fs_search.py → fs_search/__init__.py} +11 -3
  252. package/server/nodes/filesystem/fs_search/meta.json +3 -0
  253. package/server/nodes/filesystem/{shell.py → shell/__init__.py} +12 -5
  254. package/server/nodes/filesystem/shell/meta.json +3 -0
  255. package/server/nodes/google/__init__.py +12 -0
  256. package/server/nodes/google/_auth_helper.py +7 -13
  257. package/server/nodes/google/_base.py +14 -11
  258. package/server/nodes/google/_credentials.py +2 -1
  259. package/server/nodes/google/_events.py +47 -0
  260. package/server/nodes/google/_filters.py +3 -3
  261. package/server/nodes/google/_gmail.py +70 -47
  262. package/server/nodes/google/_handlers.py +3 -1
  263. package/server/nodes/google/_oauth.py +25 -11
  264. package/server/nodes/google/_option_loaders.py +9 -30
  265. package/server/nodes/google/_refresh.py +8 -12
  266. package/server/nodes/google/_router.py +4 -5
  267. package/server/nodes/google/{calendar.py → calendar/__init__.py} +87 -64
  268. package/server/nodes/google/calendar/meta.json +3 -0
  269. package/server/nodes/google/{contacts.py → contacts/__init__.py} +84 -72
  270. package/server/nodes/google/contacts/meta.json +3 -0
  271. package/server/nodes/google/{drive.py → drive/__init__.py} +87 -72
  272. package/server/nodes/google/drive/meta.json +3 -0
  273. package/server/nodes/google/{gmail.py → gmail/__init__.py} +73 -39
  274. package/server/nodes/google/gmail/meta.json +3 -0
  275. package/server/nodes/google/{gmail_receive.py → gmail_receive/__init__.py} +31 -24
  276. package/server/nodes/google/gmail_receive/icon.svg +7 -0
  277. package/server/nodes/google/gmail_receive/meta.json +3 -0
  278. package/server/nodes/google/google.svg +7 -0
  279. package/server/nodes/google/{sheets.py → sheets/__init__.py} +54 -42
  280. package/server/nodes/google/sheets/meta.json +3 -0
  281. package/server/nodes/google/{tasks.py → tasks/__init__.py} +56 -43
  282. package/server/nodes/google/tasks/meta.json +3 -0
  283. package/server/nodes/groups.py +28 -28
  284. package/server/nodes/location/__init__.py +31 -1
  285. package/server/nodes/location/_credentials.py +1 -6
  286. package/server/nodes/location/_service.py +88 -107
  287. package/server/nodes/location/{gmaps_create.py → gmaps_create/__init__.py} +6 -6
  288. package/server/nodes/location/gmaps_create/meta.json +3 -0
  289. package/server/nodes/location/{gmaps_locations.py → gmaps_locations/__init__.py} +8 -6
  290. package/server/nodes/location/gmaps_locations/meta.json +3 -0
  291. package/server/nodes/location/{gmaps_nearby_places.py → gmaps_nearby_places/__init__.py} +8 -6
  292. package/server/nodes/location/gmaps_nearby_places/meta.json +3 -0
  293. package/server/nodes/model/_base.py +10 -7
  294. package/server/nodes/model/_credentials.py +10 -10
  295. package/server/nodes/model/_local_validator.py +28 -24
  296. package/server/nodes/model/{anthropic_chat_model.py → anthropic_chat_model/__init__.py} +5 -3
  297. package/server/nodes/model/anthropic_chat_model/meta.json +3 -0
  298. package/server/nodes/model/{cerebras_chat_model.py → cerebras_chat_model/__init__.py} +5 -3
  299. package/server/nodes/model/cerebras_chat_model/meta.json +3 -0
  300. package/server/nodes/model/{deepseek_chat_model.py → deepseek_chat_model/__init__.py} +8 -4
  301. package/server/nodes/model/deepseek_chat_model/meta.json +3 -0
  302. package/server/nodes/model/{gemini_chat_model.py → gemini_chat_model/__init__.py} +5 -3
  303. package/server/nodes/model/gemini_chat_model/meta.json +3 -0
  304. package/server/nodes/model/{groq_chat_model.py → groq_chat_model/__init__.py} +2 -2
  305. package/server/nodes/model/groq_chat_model/meta.json +3 -0
  306. package/server/nodes/model/{kimi_chat_model.py → kimi_chat_model/__init__.py} +2 -2
  307. package/server/nodes/model/kimi_chat_model/meta.json +3 -0
  308. package/server/nodes/model/{lmstudio_chat_model.py → lmstudio_chat_model/__init__.py} +2 -2
  309. package/server/nodes/model/lmstudio_chat_model/meta.json +3 -0
  310. package/server/nodes/model/{mistral_chat_model.py → mistral_chat_model/__init__.py} +2 -2
  311. package/server/nodes/model/mistral_chat_model/meta.json +3 -0
  312. package/server/nodes/model/{ollama_chat_model.py → ollama_chat_model/__init__.py} +2 -2
  313. package/server/nodes/model/ollama_chat_model/meta.json +3 -0
  314. package/server/nodes/model/{openai_chat_model.py → openai_chat_model/__init__.py} +8 -4
  315. package/server/nodes/model/openai_chat_model/meta.json +3 -0
  316. package/server/nodes/model/{openrouter_chat_model.py → openrouter_chat_model/__init__.py} +8 -4
  317. package/server/nodes/model/openrouter_chat_model/meta.json +3 -0
  318. package/server/nodes/proxy/_usage.py +14 -15
  319. package/server/nodes/proxy/{proxy_config.py → proxy_config/__init__.py} +39 -30
  320. package/server/nodes/proxy/proxy_config/meta.json +3 -0
  321. package/server/nodes/proxy/{proxy_request.py → proxy_request/__init__.py} +30 -16
  322. package/server/nodes/proxy/proxy_request/meta.json +3 -0
  323. package/server/nodes/proxy/{proxy_status.py → proxy_status/__init__.py} +2 -0
  324. package/server/nodes/proxy/proxy_status/meta.json +3 -0
  325. package/server/nodes/scheduler/{cron_scheduler.py → cron_scheduler/__init__.py} +96 -23
  326. package/server/nodes/scheduler/cron_scheduler/_workflow.py +155 -0
  327. package/server/nodes/scheduler/cron_scheduler/meta.json +3 -0
  328. package/server/nodes/scheduler/{timer.py → timer/__init__.py} +6 -5
  329. package/server/nodes/scheduler/timer/meta.json +3 -0
  330. package/server/nodes/scraper/_credentials.py +0 -1
  331. package/server/nodes/scraper/{apify_actor.py → apify_actor/__init__.py} +44 -35
  332. package/server/nodes/scraper/apify_actor/icon.svg +5 -0
  333. package/server/nodes/scraper/apify_actor/meta.json +3 -0
  334. package/server/nodes/scraper/{crawlee_scraper.py → crawlee_scraper/__init__.py} +96 -57
  335. package/server/nodes/scraper/crawlee_scraper/meta.json +3 -0
  336. package/server/nodes/search/{brave_search.py → brave_search/__init__.py} +6 -5
  337. package/server/nodes/search/brave_search/icon.svg +3 -0
  338. package/server/nodes/search/brave_search/meta.json +3 -0
  339. package/server/nodes/search/{duckduckgo_search.py → duckduckgo_search/__init__.py} +17 -6
  340. package/server/nodes/search/duckduckgo_search/meta.json +3 -0
  341. package/server/nodes/search/{perplexity_search.py → perplexity_search/__init__.py} +4 -5
  342. package/server/nodes/search/perplexity_search/icon.svg +3 -0
  343. package/server/nodes/search/perplexity_search/meta.json +3 -0
  344. package/server/nodes/search/{serper_search.py → serper_search/__init__.py} +32 -25
  345. package/server/nodes/search/serper_search/icon.svg +3 -0
  346. package/server/nodes/search/serper_search/meta.json +3 -0
  347. package/server/nodes/skill/__init__.py +21 -1
  348. package/server/nodes/skill/_expander.py +75 -0
  349. package/server/nodes/skill/{master_skill.py → master_skill/__init__.py} +2 -8
  350. package/server/nodes/skill/master_skill/_events.py +84 -0
  351. package/server/nodes/skill/master_skill/meta.json +3 -0
  352. package/server/nodes/skill/{simple_memory.py → simple_memory/__init__.py} +8 -16
  353. package/server/nodes/skill/simple_memory/meta.json +3 -0
  354. package/server/nodes/social/_base.py +223 -231
  355. package/server/nodes/social/{social_receive.py → social_receive/__init__.py} +38 -13
  356. package/server/nodes/social/social_receive/meta.json +3 -0
  357. package/server/nodes/social/{social_send.py → social_send/__init__.py} +71 -29
  358. package/server/nodes/social/social_send/icon.svg +1 -0
  359. package/server/nodes/social/social_send/meta.json +3 -0
  360. package/server/nodes/stripe/__init__.py +7 -3
  361. package/server/nodes/stripe/_credentials.py +0 -1
  362. package/server/nodes/stripe/_handlers.py +18 -7
  363. package/server/nodes/stripe/_install.py +14 -15
  364. package/server/nodes/stripe/_source.py +5 -5
  365. package/server/nodes/stripe/icon.svg +1 -0
  366. package/server/nodes/stripe/meta.json +3 -0
  367. package/server/nodes/stripe/stripe_action.py +4 -4
  368. package/server/nodes/stripe/stripe_receive.py +6 -9
  369. package/server/nodes/telegram/__init__.py +13 -0
  370. package/server/nodes/telegram/_credentials.py +2 -7
  371. package/server/nodes/telegram/_events.py +167 -0
  372. package/server/nodes/telegram/_filters.py +3 -11
  373. package/server/nodes/telegram/_handlers.py +17 -7
  374. package/server/nodes/telegram/_refresh.py +24 -34
  375. package/server/nodes/telegram/_service.py +29 -45
  376. package/server/nodes/telegram/meta.json +3 -0
  377. package/server/nodes/telegram/telegram.svg +3 -0
  378. package/server/nodes/telegram/telegram_receive.py +38 -18
  379. package/server/nodes/telegram/telegram_send.py +21 -19
  380. package/server/nodes/text/{file_handler.py → file_handler/__init__.py} +7 -1
  381. package/server/nodes/text/file_handler/meta.json +3 -0
  382. package/server/nodes/text/{text_generator.py → text_generator/__init__.py} +2 -1
  383. package/server/nodes/text/text_generator/meta.json +3 -0
  384. package/server/nodes/tool/{agent_builder.py → agent_builder/__init__.py} +105 -100
  385. package/server/nodes/tool/agent_builder/_events.py +91 -0
  386. package/server/nodes/tool/agent_builder/meta.json +3 -0
  387. package/server/nodes/tool/{calculator_tool.py → calculator_tool/__init__.py} +19 -7
  388. package/server/nodes/tool/calculator_tool/meta.json +3 -0
  389. package/server/nodes/tool/{current_time_tool.py → current_time_tool/__init__.py} +6 -4
  390. package/server/nodes/tool/current_time_tool/meta.json +3 -0
  391. package/server/nodes/tool/{task_manager.py → task_manager/__init__.py} +17 -18
  392. package/server/nodes/tool/task_manager/meta.json +3 -0
  393. package/server/nodes/tool/{write_todos.py → write_todos/__init__.py} +20 -6
  394. package/server/nodes/tool/write_todos/meta.json +3 -0
  395. package/server/nodes/trigger/{chat_trigger.py → chat_trigger/__init__.py} +11 -7
  396. package/server/nodes/trigger/chat_trigger/_events.py +53 -0
  397. package/server/nodes/trigger/chat_trigger/meta.json +3 -0
  398. package/server/nodes/trigger/{task_trigger.py → task_trigger/__init__.py} +10 -7
  399. package/server/nodes/trigger/task_trigger/meta.json +3 -0
  400. package/server/nodes/trigger/{webhook_trigger.py → webhook_trigger/__init__.py} +10 -7
  401. package/server/nodes/trigger/webhook_trigger/_events.py +54 -0
  402. package/server/nodes/trigger/webhook_trigger/meta.json +3 -0
  403. package/server/nodes/twitter/__init__.py +7 -1
  404. package/server/nodes/twitter/_base.py +86 -61
  405. package/server/nodes/twitter/_credentials.py +7 -5
  406. package/server/nodes/twitter/_events.py +101 -0
  407. package/server/nodes/twitter/_filters.py +9 -9
  408. package/server/nodes/twitter/_handlers.py +3 -1
  409. package/server/nodes/twitter/_oauth.py +1 -2
  410. package/server/nodes/twitter/_refresh.py +8 -12
  411. package/server/nodes/twitter/{twitter_receive.py → twitter_receive/__init__.py} +7 -7
  412. package/server/nodes/twitter/twitter_receive/icon.svg +1 -0
  413. package/server/nodes/twitter/twitter_receive/meta.json +3 -0
  414. package/server/nodes/twitter/{twitter_search.py → twitter_search/__init__.py} +16 -11
  415. package/server/nodes/twitter/twitter_search/icon.svg +1 -0
  416. package/server/nodes/twitter/twitter_search/meta.json +3 -0
  417. package/server/nodes/twitter/{twitter_send.py → twitter_send/__init__.py} +60 -27
  418. package/server/nodes/twitter/twitter_send/icon.svg +1 -0
  419. package/server/nodes/twitter/twitter_send/meta.json +3 -0
  420. package/server/nodes/twitter/{twitter_user.py → twitter_user/__init__.py} +34 -19
  421. package/server/nodes/twitter/twitter_user/icon.svg +1 -0
  422. package/server/nodes/twitter/twitter_user/meta.json +3 -0
  423. package/server/nodes/utility/{console.py → console/__init__.py} +17 -22
  424. package/server/nodes/utility/console/meta.json +3 -0
  425. package/server/nodes/utility/{http_request.py → http_request/__init__.py} +9 -6
  426. package/server/nodes/utility/http_request/meta.json +3 -0
  427. package/server/nodes/utility/{process_manager.py → process_manager/__init__.py} +10 -6
  428. package/server/nodes/utility/process_manager/meta.json +3 -0
  429. package/server/nodes/utility/team_monitor/meta.json +3 -0
  430. package/server/nodes/utility/{webhook_response.py → webhook_response/__init__.py} +12 -7
  431. package/server/nodes/utility/webhook_response/meta.json +3 -0
  432. package/server/nodes/visuals.json +69 -251
  433. package/server/nodes/whatsapp/__init__.py +24 -0
  434. package/server/nodes/whatsapp/_base.py +283 -338
  435. package/server/nodes/whatsapp/_credentials.py +44 -0
  436. package/server/nodes/whatsapp/_events.py +277 -0
  437. package/server/nodes/whatsapp/_filters.py +36 -37
  438. package/server/nodes/whatsapp/_handlers.py +2 -0
  439. package/server/nodes/whatsapp/_option_loaders.py +1 -3
  440. package/server/nodes/whatsapp/_refresh.py +13 -18
  441. package/server/nodes/whatsapp/_runtime.py +9 -6
  442. package/server/nodes/whatsapp/_service.py +89 -152
  443. package/server/nodes/whatsapp/meta.json +3 -0
  444. package/server/nodes/whatsapp/whatsapp_db.py +116 -54
  445. package/server/nodes/whatsapp/whatsapp_receive.py +30 -13
  446. package/server/nodes/whatsapp/whatsapp_send.py +60 -37
  447. package/server/nodes/workflow/{start.py → start/__init__.py} +1 -4
  448. package/server/nodes/workflow/start/meta.json +3 -0
  449. package/server/package-lock.json +3 -3
  450. package/server/package.json +3 -0
  451. package/server/pyproject.toml +39 -10
  452. package/server/requirements.txt +3 -5
  453. package/server/routers/__init__.py +1 -1
  454. package/server/routers/auth.py +16 -56
  455. package/server/routers/database.py +27 -50
  456. package/server/routers/nodejs_compat.py +25 -87
  457. package/server/routers/schemas.py +66 -2
  458. package/server/routers/webhook.py +12 -12
  459. package/server/routers/websocket.py +312 -1716
  460. package/server/routers/workflow.py +28 -53
  461. package/server/scripts/smoke_test_skills.py +178 -0
  462. package/server/services/__init__.py +1 -1
  463. package/server/services/_supervisor/process.py +9 -3
  464. package/server/services/_supervisor/registry.py +3 -3
  465. package/server/services/_supervisor/util.py +1 -1
  466. package/server/services/agent_team.py +15 -43
  467. package/server/services/agent_teams/__init__.py +17 -0
  468. package/server/services/agent_teams/handlers.py +195 -0
  469. package/server/services/ai.py +853 -1108
  470. package/server/services/auth.py +10 -34
  471. package/server/services/chat_client.py +5 -34
  472. package/server/services/circuit_breaker.py +2 -6
  473. package/server/services/cli_agent/__init__.py +28 -4
  474. package/server/services/cli_agent/_cli_auth.py +61 -0
  475. package/server/services/cli_agent/_handlers.py +24 -183
  476. package/server/services/cli_agent/config.py +5 -8
  477. package/server/services/cli_agent/factory.py +168 -22
  478. package/server/services/cli_agent/jsonl_watcher.py +380 -0
  479. package/server/services/cli_agent/lockfile.py +9 -2
  480. package/server/services/cli_agent/mcp_server.py +110 -34
  481. package/server/services/cli_agent/protocol.py +37 -19
  482. package/server/services/cli_agent/providers/__init__.py +8 -4
  483. package/server/services/cli_agent/providers/google_gemini.py +11 -5
  484. package/server/services/cli_agent/providers/openai_codex.py +34 -34
  485. package/server/services/cli_agent/service.py +245 -83
  486. package/server/services/cli_agent/session.py +409 -229
  487. package/server/services/cli_agent/transports/__init__.py +47 -0
  488. package/server/services/cli_agent/transports/base.py +111 -0
  489. package/server/services/cli_agent/transports/posix.py +196 -0
  490. package/server/services/cli_agent/transports/windows.py +189 -0
  491. package/server/services/cli_agent/types.py +45 -18
  492. package/server/services/cli_agent/workflow_tools.py +28 -15
  493. package/server/services/compaction.py +68 -52
  494. package/server/services/credential_registry.py +6 -20
  495. package/server/services/credentials/__init__.py +18 -0
  496. package/server/services/credentials/handlers.py +196 -0
  497. package/server/services/deployment/__init__.py +12 -1
  498. package/server/services/deployment/canary_registry.py +137 -0
  499. package/server/services/deployment/handlers.py +382 -0
  500. package/server/services/deployment/manager.py +653 -163
  501. package/server/services/deployment/poll_registry.py +2 -6
  502. package/server/services/deployment/state.py +2 -0
  503. package/server/services/deployment/triggers.py +87 -93
  504. package/server/services/event_waiter.py +47 -54
  505. package/server/services/events/__init__.py +11 -0
  506. package/server/services/events/admin_handlers.py +368 -0
  507. package/server/services/events/daemon.py +3 -1
  508. package/server/services/events/dispatch.py +188 -0
  509. package/server/services/events/envelope.py +264 -45
  510. package/server/services/events/oauth_lifecycle.py +98 -42
  511. package/server/services/events/triggers.py +3 -13
  512. package/server/services/events/verifiers/hmac_basic.py +1 -1
  513. package/server/services/events/verifiers/standard_webhooks.py +2 -4
  514. package/server/services/events/webhook.py +2 -3
  515. package/server/services/example_loader.py +73 -15
  516. package/server/services/execution/cache.py +36 -76
  517. package/server/services/execution/conditions.py +7 -20
  518. package/server/services/execution/dlq.py +20 -24
  519. package/server/services/execution/executor.py +234 -265
  520. package/server/services/execution/models.py +40 -46
  521. package/server/services/execution/recovery.py +23 -46
  522. package/server/services/handlers/__init__.py +12 -16
  523. package/server/services/handlers/todo.py +3 -6
  524. package/server/services/handlers/tools.py +143 -194
  525. package/server/services/handlers/triggers.py +24 -23
  526. package/server/services/llm/config.py +10 -1
  527. package/server/services/llm/factory.py +16 -4
  528. package/server/services/llm/messages.py +1 -5
  529. package/server/services/llm/protocol.py +9 -1
  530. package/server/services/llm/providers/anthropic.py +23 -12
  531. package/server/services/llm/providers/gemini.py +43 -22
  532. package/server/services/llm/providers/openai.py +14 -6
  533. package/server/services/llm/providers/openrouter.py +6 -1
  534. package/server/services/markdown_formatter.py +1 -2
  535. package/server/services/memory/__init__.py +2 -2
  536. package/server/services/memory/jsonl.py +6 -2
  537. package/server/services/memory/markdown.py +6 -6
  538. package/server/services/memory/state.py +6 -5
  539. package/server/services/memory_store.py +8 -12
  540. package/server/services/model_registry.py +22 -20
  541. package/server/services/node_executor.py +85 -80
  542. package/server/services/node_output_schemas.py +4 -7
  543. package/server/services/node_registry.py +40 -4
  544. package/server/services/node_spec.py +3 -7
  545. package/server/services/nodejs_client.py +4 -14
  546. package/server/services/oauth_utils.py +11 -7
  547. package/server/services/parameter_resolver.py +30 -36
  548. package/server/services/plugin/base.py +321 -38
  549. package/server/services/plugin/connection.py +12 -7
  550. package/server/services/plugin/credential.py +80 -22
  551. package/server/services/plugin/edge_walker.py +128 -105
  552. package/server/services/plugin/identifiers.py +48 -0
  553. package/server/services/plugin/interceptor.py +1 -1
  554. package/server/services/plugin/oauth.py +25 -21
  555. package/server/services/plugin/operation.py +1 -1
  556. package/server/services/plugin/polling.py +151 -26
  557. package/server/services/plugin/registry.py +52 -4
  558. package/server/services/plugin/routing.py +6 -9
  559. package/server/services/plugin/scaling.py +36 -18
  560. package/server/services/plugin/service_factories.py +95 -0
  561. package/server/services/plugin/shutdown_hooks.py +103 -0
  562. package/server/services/plugin/social_provider_registry.py +80 -0
  563. package/server/services/plugin/ws.py +2 -1
  564. package/server/services/pricing.py +26 -40
  565. package/server/services/pricing_handlers.py +90 -0
  566. package/server/services/process_service.py +33 -32
  567. package/server/services/proxy/models.py +15 -9
  568. package/server/services/proxy/service.py +26 -40
  569. package/server/services/rlm/adapters.py +43 -40
  570. package/server/services/rlm/constants.py +9 -9
  571. package/server/services/rlm/service.py +57 -45
  572. package/server/services/scheduler.py +8 -39
  573. package/server/services/settings/__init__.py +16 -0
  574. package/server/services/settings/handlers.py +275 -0
  575. package/server/services/skill_loader.py +53 -45
  576. package/server/services/skill_prompt.py +8 -6
  577. package/server/services/skills/__init__.py +23 -0
  578. package/server/services/skills/handlers.py +479 -0
  579. package/server/services/status_broadcaster.py +314 -291
  580. package/server/services/temporal/__init__.py +22 -1
  581. package/server/services/temporal/_handlers.py +65 -0
  582. package/server/services/temporal/_install.py +158 -0
  583. package/server/services/temporal/_refresh.py +57 -0
  584. package/server/services/temporal/_retry_policies.py +85 -0
  585. package/server/services/temporal/_runtime.py +181 -0
  586. package/server/services/temporal/_supervised_runtime.py +102 -0
  587. package/server/services/temporal/activities.py +168 -11
  588. package/server/services/temporal/agent_activities.py +683 -0
  589. package/server/services/temporal/agent_workflow.py +601 -0
  590. package/server/services/temporal/client.py +58 -13
  591. package/server/services/temporal/executor.py +2 -3
  592. package/server/services/temporal/plugin_activities.py +37 -2
  593. package/server/services/temporal/plugin_registry.py +82 -0
  594. package/server/services/temporal/polling_trigger_workflow.py +267 -0
  595. package/server/services/temporal/schedules.py +220 -0
  596. package/server/services/temporal/search_attributes.py +177 -0
  597. package/server/services/temporal/trigger_listener_workflow.py +378 -0
  598. package/server/services/temporal/worker.py +111 -18
  599. package/server/services/temporal/workflow.py +259 -40
  600. package/server/services/temporal/ws_client.py +22 -11
  601. package/server/services/text.py +14 -28
  602. package/server/services/tracked_http.py +29 -49
  603. package/server/services/user_auth.py +7 -21
  604. package/server/services/workflow.py +28 -20
  605. package/server/services/workflow_import.py +351 -0
  606. package/server/services/workflow_ops.py +4 -0
  607. package/server/services/workflow_storage/__init__.py +18 -0
  608. package/server/services/workflow_storage/handlers.py +132 -0
  609. package/server/services/workflow_validator.py +209 -0
  610. package/server/services/ws_handler_registry.py +80 -9
  611. package/server/skills/assistant/agent-builder-skill/SKILL.md +6 -6
  612. package/server/tests/conftest.py +54 -3
  613. package/server/tests/credentials/test_auth_service.py +9 -21
  614. package/server/tests/credentials/test_credential_broadcasts.py +116 -22
  615. package/server/tests/credentials/test_credentials_database.py +12 -38
  616. package/server/tests/credentials/test_encryption.py +3 -9
  617. package/server/tests/credentials/test_google_oauth.py +1 -3
  618. package/server/tests/credentials/test_oauth_utils.py +31 -38
  619. package/server/tests/credentials/test_twitter_oauth.py +1 -3
  620. package/server/tests/credentials/test_websocket_handlers.py +37 -72
  621. package/server/tests/fixtures/tool_names_snapshot.json +78 -0
  622. package/server/tests/llm/test_factory.py +12 -4
  623. package/server/tests/llm/test_providers.py +25 -32
  624. package/server/tests/llm/test_wiring.py +27 -22
  625. package/server/tests/nodes/_compat.py +4 -5
  626. package/server/tests/nodes/_harness.py +31 -24
  627. package/server/tests/nodes/_mocks.py +2 -6
  628. package/server/tests/nodes/test_agent_builder.py +43 -35
  629. package/server/tests/nodes/test_ai_agents.py +29 -24
  630. package/server/tests/nodes/test_ai_chat_models.py +3 -9
  631. package/server/tests/nodes/test_ai_tools.py +29 -24
  632. package/server/tests/nodes/test_android.py +34 -64
  633. package/server/tests/nodes/test_chat_utility.py +2 -2
  634. package/server/tests/nodes/test_code_fs_process.py +26 -84
  635. package/server/tests/nodes/test_document.py +23 -47
  636. package/server/tests/nodes/test_email.py +88 -51
  637. package/server/tests/nodes/test_google_workspace.py +26 -20
  638. package/server/tests/nodes/test_http_proxy.py +43 -89
  639. package/server/tests/nodes/test_search.py +3 -9
  640. package/server/tests/nodes/test_specialized_agents.py +58 -162
  641. package/server/tests/nodes/test_stripe_plugin.py +25 -5
  642. package/server/tests/nodes/test_telegram_social.py +33 -37
  643. package/server/tests/nodes/test_twitter.py +59 -150
  644. package/server/tests/nodes/test_web_automation.py +21 -51
  645. package/server/tests/nodes/test_whatsapp.py +13 -19
  646. package/server/tests/nodes/test_workflow_triggers.py +16 -45
  647. package/server/tests/services/cli_agent/test_claude_session_events.py +201 -0
  648. package/server/tests/services/cli_agent/test_jsonl_watcher.py +190 -0
  649. package/server/tests/services/cli_agent/test_mcp_server.py +67 -29
  650. package/server/tests/services/cli_agent/test_providers.py +236 -47
  651. package/server/tests/services/cli_agent/test_service.py +9 -7
  652. package/server/tests/services/memory/test_jsonl.py +30 -25
  653. package/server/tests/services/test_events.py +26 -7
  654. package/server/tests/services/test_identifiers.py +122 -0
  655. package/server/tests/services/test_process_lifecycle.py +129 -0
  656. package/server/tests/services/test_supervisor.py +0 -1
  657. package/server/tests/temporal/__init__.py +0 -0
  658. package/server/tests/temporal/test_agent_workflow.py +215 -0
  659. package/server/tests/temporal/test_dispatch.py +231 -0
  660. package/server/tests/test_admin_handlers.py +394 -0
  661. package/server/tests/test_auto_skill.py +4 -2
  662. package/server/tests/test_canary_registry.py +310 -0
  663. package/server/tests/test_chat_trigger_canary_producer.py +101 -0
  664. package/server/tests/test_cloudevents_node_parameters.py +129 -0
  665. package/server/tests/test_credential_icon.py +115 -0
  666. package/server/tests/test_cron_canary.py +511 -0
  667. package/server/tests/test_deployment_canary_listener.py +692 -0
  668. package/server/tests/test_event_framework_phase_a.py +537 -0
  669. package/server/tests/test_no_raw_prints.py +131 -0
  670. package/server/tests/test_node_spec.py +196 -103
  671. package/server/tests/test_parameter_resolver.py +20 -20
  672. package/server/tests/test_plugin_contract.py +76 -49
  673. package/server/tests/test_plugin_helpers.py +0 -1
  674. package/server/tests/test_plugin_self_containment.py +40 -47
  675. package/server/tests/test_polling_trigger_workflow.py +572 -0
  676. package/server/tests/test_retry_policies.py +146 -0
  677. package/server/tests/test_service_factories.py +168 -0
  678. package/server/tests/test_shutdown_hooks.py +199 -0
  679. package/server/tests/test_social_provider_registry.py +177 -0
  680. package/server/tests/test_status_broadcasts.py +214 -63
  681. package/server/tests/test_task_trigger_canary_producer.py +131 -0
  682. package/server/tests/test_telegram_trigger_canary_producer.py +113 -0
  683. package/server/tests/test_tool_registry.py +110 -0
  684. package/server/tests/test_trigger_listener_workflow.py +365 -0
  685. package/server/tests/test_whatsapp_trigger_canary_producer.py +164 -0
  686. package/server/tests/test_workflow_ops.py +1 -3
  687. package/server/tests/test_workflow_validator.py +791 -0
  688. package/server/uv.lock +3539 -0
  689. package/client/dist/assets/index-DQ0nwhec.js +0 -257
  690. package/client/src/assets/icons/apify/index.ts +0 -19
  691. package/client/src/assets/icons/browser/index.ts +0 -17
  692. package/client/src/assets/icons/email/index.ts +0 -22
  693. package/client/src/assets/icons/google/index.ts +0 -34
  694. package/client/src/assets/icons/llm/deepseek.svg +0 -1
  695. package/client/src/assets/icons/llm/index.ts +0 -18
  696. package/client/src/assets/icons/llm/kimi.svg +0 -1
  697. package/client/src/assets/icons/llm/mistral.svg +0 -1
  698. package/client/src/assets/icons/search/index.ts +0 -28
  699. package/client/src/assets/icons/telegram/index.ts +0 -19
  700. package/machina/buildenv.py +0 -44
  701. package/machina/cli.py +0 -55
  702. package/machina/commands/__init__.py +0 -1
  703. package/machina/commands/clean.py +0 -80
  704. package/machina/commands/daemon.py +0 -150
  705. package/machina/config.py +0 -93
  706. package/machina/platform_.py +0 -37
  707. package/machina/pyproject.toml +0 -33
  708. package/server/nodes/agent/deep_agent.py +0 -103
  709. package/server/services/agents/__init__.py +0 -9
  710. package/server/services/agents/adapters.py +0 -199
  711. package/server/services/agents/constants.py +0 -10
  712. package/server/services/agents/service.py +0 -297
  713. package/server/services/cli_agent/providers/anthropic_claude.py +0 -419
  714. /package/{machina → cli}/README.md +0 -0
  715. /package/{machina → cli}/__init__.py +0 -0
  716. /package/{client/src/assets/icons/apify → server/credentials/icons}/apify.svg +0 -0
  717. /package/{client/src/assets/icons/search/brave.svg → server/credentials/icons/brave_search.svg} +0 -0
  718. /package/{client/src/assets/icons/email/read.svg → server/credentials/icons/email_himalaya.svg} +0 -0
  719. /package/{client/src/assets/icons/search → server/credentials/icons}/perplexity.svg +0 -0
  720. /package/{client/src/assets/icons/search/google.svg → server/credentials/icons/serper.svg} +0 -0
  721. /package/{client/src/assets → server/credentials}/icons/stripe.svg +0 -0
  722. /package/{client/src/assets/icons/twitter/x.svg → server/credentials/icons/twitter.svg} +0 -0
  723. /package/{client/src/assets/icons/browser/chrome.svg → server/nodes/browser/browser/icon.svg} +0 -0
  724. /package/{client/src/assets/icons/chat/chat.svg → server/nodes/chat/chat_history/icon.svg} +0 -0
  725. /package/{client/src/assets/icons/code/javascript.svg → server/nodes/code/javascript_executor/icon.svg} +0 -0
  726. /package/{client/src/assets/icons/code/python.svg → server/nodes/code/python_executor/icon.svg} +0 -0
  727. /package/{client/src/assets/icons/code/typescript.svg → server/nodes/code/typescript_executor/icon.svg} +0 -0
  728. /package/{client/src/assets/icons/email/receive.svg → server/nodes/email/email_receive/icon.svg} +0 -0
  729. /package/{client/src/assets/icons/email/send.svg → server/nodes/email/email_send/icon.svg} +0 -0
  730. /package/{client/src/assets/icons/google/calendar.svg → server/nodes/google/calendar/icon.svg} +0 -0
  731. /package/{client/src/assets/icons/google/contacts.svg → server/nodes/google/contacts/icon.svg} +0 -0
  732. /package/{client/src/assets/icons/google/drive.svg → server/nodes/google/drive/icon.svg} +0 -0
  733. /package/{client/src/assets/icons/google/gmail.svg → server/nodes/google/gmail/icon.svg} +0 -0
  734. /package/{client/src/assets/icons/google/sheets.svg → server/nodes/google/sheets/icon.svg} +0 -0
  735. /package/{client/src/assets/icons/google/tasks.svg → server/nodes/google/tasks/icon.svg} +0 -0
  736. /package/{client/src/assets/icons/search/duckduckgo.svg → server/nodes/search/duckduckgo_search/icon.svg} +0 -0
  737. /package/{client/src/assets/icons/social/social.svg → server/nodes/social/social_receive/icon.svg} +0 -0
  738. /package/{client/src/assets/icons/telegram/telegram.svg → server/nodes/telegram/icon.svg} +0 -0
  739. /package/server/nodes/utility/{team_monitor.py → team_monitor/__init__.py} +0 -0
  740. /package/{client/src/assets/icons/whatsapp/whatsapp-db.svg → server/nodes/whatsapp/icon_whatsappDb.svg} +0 -0
  741. /package/{client/src/assets/icons/whatsapp/whatsapp-receive.svg → server/nodes/whatsapp/icon_whatsappReceive.svg} +0 -0
  742. /package/{client/src/assets/icons/whatsapp/whatsapp-send.svg → server/nodes/whatsapp/icon_whatsappSend.svg} +0 -0
  743. /package/{client/src/assets/icons → server/nodes}/whatsapp/whatsapp.svg +0 -0
@@ -5,8 +5,6 @@ Each tool type has its own handler function that processes the tool call
5
5
  and returns results.
6
6
  """
7
7
 
8
- import math
9
- import json
10
8
  import asyncio
11
9
  import uuid
12
10
  import hashlib
@@ -20,6 +18,7 @@ if TYPE_CHECKING:
20
18
 
21
19
  logger = get_logger(__name__)
22
20
 
21
+
23
22
  def _plugin_connection_factory(plugin_cls, context):
24
23
  """Build a per-call :class:`Connection` factory bound to a plugin
25
24
  class's declared credentials. Mirrors
@@ -35,10 +34,7 @@ def _plugin_connection_factory(plugin_cls, context):
35
34
  def factory(credential_id: str):
36
35
  cred_cls = creds_by_id.get(credential_id)
37
36
  if cred_cls is None:
38
- raise RuntimeError(
39
- f"Plugin {plugin_cls.type} did not declare credential "
40
- f"'{credential_id}' but tried to use it."
41
- )
37
+ raise RuntimeError(f"Plugin {plugin_cls.type} did not declare credential " f"'{credential_id}' but tried to use it.")
42
38
  return Connection(cred_cls, user_id=user_id, session_id=session_id)
43
39
 
44
40
  return factory
@@ -70,8 +66,7 @@ def is_node_in_active_delegation(node_id: str) -> bool:
70
66
  return _active_delegated_nodes.get(node_id, 0) > 0
71
67
 
72
68
 
73
- async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
74
- config: Dict[str, Any]) -> Dict[str, Any]:
69
+ async def execute_tool(tool_name: str, tool_args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
75
70
  """Execute a tool by name and own the tool node's status lifecycle.
76
71
 
77
72
  This is the single source of truth for the tool node's
@@ -100,12 +95,13 @@ async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
100
95
  from services.status_broadcaster import get_status_broadcaster
101
96
 
102
97
  broadcaster = get_status_broadcaster()
103
- node_id = config.get('node_id')
104
- workflow_id = config.get('workflow_id')
98
+ node_id = config.get("node_id")
99
+ workflow_id = config.get("workflow_id")
105
100
 
106
101
  if node_id and broadcaster:
107
102
  await broadcaster.update_node_status(
108
- node_id, "executing",
103
+ node_id,
104
+ "executing",
109
105
  {"message": f"Executing {tool_name}"},
110
106
  workflow_id=workflow_id,
111
107
  )
@@ -116,50 +112,48 @@ async def execute_tool(tool_name: str, tool_args: Dict[str, Any],
116
112
  logger.error("[Tool] Execution failed: %s", tool_name, exc_info=True)
117
113
  if node_id and broadcaster:
118
114
  await broadcaster.update_node_status(
119
- node_id, "error",
115
+ node_id,
116
+ "error",
120
117
  {"message": f"{tool_name} failed", "error": str(e)},
121
118
  workflow_id=workflow_id,
122
119
  )
123
120
  raise
124
121
 
125
- handler_owns_lifecycle = (
126
- isinstance(result, dict)
127
- and result.get("status") in ("delegated", "ALREADY_DELEGATED")
128
- )
122
+ handler_owns_lifecycle = isinstance(result, dict) and result.get("status") in ("delegated", "ALREADY_DELEGATED")
129
123
  if node_id and broadcaster and not handler_owns_lifecycle:
130
124
  await broadcaster.update_node_status(
131
- node_id, "success",
125
+ node_id,
126
+ "success",
132
127
  {"message": f"{tool_name} completed", "result": result},
133
128
  workflow_id=workflow_id,
134
129
  )
135
130
  return result
136
131
 
137
132
 
138
- async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
139
- config: Dict[str, Any]) -> Dict[str, Any]:
133
+ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
140
134
  """Route a tool call to the right handler based on ``node_type``.
141
135
 
142
136
  Pure dispatch — no broadcasting. Lifecycle is owned by
143
137
  :func:`execute_tool`.
144
138
  """
145
- node_type = config.get('node_type', '')
146
- node_params = config.get('parameters', {})
139
+ node_type = config.get("node_type", "")
140
+ node_params = config.get("parameters", {})
147
141
 
148
142
  # Execution context for tool handlers. Includes canvas state
149
143
  # (nodes/edges/workflow_id) that callers (chat_tool_executor in
150
- # ai.py / rlm adapter / deepagents adapter) plumb in via `config`.
144
+ # ai.py / rlm adapter) plumb in via `config`.
151
145
  # Tools that need canvas awareness (e.g. agentBuilder.inspect_canvas)
152
146
  # read these via NodeContext.nodes / .edges / .workflow_id; tools
153
147
  # that don't simply ignore them.
154
148
  context = {
155
- 'workspace_dir': config.get('workspace_dir', ''),
156
- 'nodes': config.get('nodes', []),
157
- 'edges': config.get('edges', []),
158
- 'workflow_id': config.get('workflow_id'),
159
- 'parent_node_id': config.get('parent_node_id'),
149
+ "workspace_dir": config.get("workspace_dir", ""),
150
+ "nodes": config.get("nodes", []),
151
+ "edges": config.get("edges", []),
152
+ "workflow_id": config.get("workflow_id"),
153
+ "parent_node_id": config.get("parent_node_id"),
160
154
  }
161
155
 
162
- logger.info("[Tool] Executing '%s' (node_type=%s, workspace=%s)", tool_name, node_type, context['workspace_dir'])
156
+ logger.info("[Tool] Executing '%s' (node_type=%s, workspace=%s)", tool_name, node_type, context["workspace_dir"])
163
157
 
164
158
  # ----------------------------------------------------------------
165
159
  # Plugin fast-path (Wave 11.B.1): if this node_type is a
@@ -177,17 +171,16 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
177
171
  # prompt) expect for delegation tools.
178
172
  # ----------------------------------------------------------------
179
173
  from services.node_registry import get_node_class
180
- plugin_cls = (
181
- None if node_type in AI_AGENT_TYPES
182
- else get_node_class(node_type)
183
- )
174
+
175
+ plugin_cls = None if node_type in AI_AGENT_TYPES else get_node_class(node_type)
184
176
  if plugin_cls is not None:
185
177
  from services.plugin import NodeContext
178
+
186
179
  instance = plugin_cls()
187
180
  ctx = NodeContext.from_legacy(
188
- node_id=config.get('node_id', f'tool_{node_type}'),
181
+ node_id=config.get("node_id", f"tool_{node_type}"),
189
182
  node_type=node_type,
190
- context={**context, 'parameters': node_params},
183
+ context={**context, "parameters": node_params},
191
184
  connection_factory=_plugin_connection_factory(plugin_cls, context),
192
185
  )
193
186
  return await instance.execute_as_tool(tool_args, node_params, ctx)
@@ -205,36 +198,42 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
205
198
  # also need LLM-arg translation that doesn't fit the plugin Params
206
199
  # shape. Both dispatchers live with their domain on
207
200
  # nodes/android/_base.py (Wave 11.E.3 move).
208
- if node_type == 'androidTool':
201
+ if node_type == "androidTool":
209
202
  from nodes.android._base import execute_android_toolkit
203
+
210
204
  return await execute_android_toolkit(tool_args, config)
211
205
  if node_type in ANDROID_SERVICE_NODE_TYPES:
212
206
  from nodes.android._base import execute_android_service_tool
207
+
213
208
  return await execute_android_service_tool(tool_args, config)
214
209
 
215
210
  # taskManager: dispatcher reads through to the agent-delegation
216
211
  # tracking dicts (_delegated_tasks / _delegation_results) defined
217
212
  # below in this module. The operation matrix moved to the plugin
218
213
  # (Wave 11.I, milestone O).
219
- if node_type == 'taskManager':
214
+ if node_type == "taskManager":
220
215
  from nodes.tool.task_manager import _execute_task_manager
216
+
221
217
  return await _execute_task_manager(tool_args, config)
222
218
 
223
219
  # proxyConfig: 10-operation matrix lives on the plugin
224
220
  # (nodes/proxy/proxy_config.execute_proxy_config). Plugin params win.
225
- if node_type == 'proxyConfig':
221
+ if node_type == "proxyConfig":
226
222
  from nodes.proxy.proxy_config import execute_proxy_config
227
- merged = {**config.get('parameters', {}), **tool_args}
223
+
224
+ merged = {**config.get("parameters", {}), **tool_args}
228
225
  return await execute_proxy_config(merged)
229
226
 
230
227
  # Built-in: Check delegated task results
231
228
  # Auto-injected when parent has delegation tools
232
- if node_type == '_builtin_check_delegated_tasks':
229
+ if node_type == "_builtin_check_delegated_tasks":
233
230
  return await _execute_check_delegated_tasks(tool_args, config)
234
231
 
235
- # AI Agent delegation (fire-and-forget async delegation)
236
- # Includes specialized agents: android_agent, coding_agent, web_agent, task_agent, social_agent, autonomous_agent
237
- if node_type in ('aiAgent', 'chatAgent', 'android_agent', 'coding_agent', 'web_agent', 'task_agent', 'social_agent', 'travel_agent', 'tool_agent', 'productivity_agent', 'payments_agent', 'consumer_agent', 'autonomous_agent', 'orchestrator_agent', 'ai_employee', 'rlm_agent', 'claude_code_agent', 'deep_agent'):
232
+ # AI Agent delegation (fire-and-forget async delegation).
233
+ # ``AI_AGENT_TYPES`` (imported above from ``constants``) is the
234
+ # canonical 18-entry frozenset; a new agent type added there picks
235
+ # up delegation support without touching this dispatcher.
236
+ if node_type in AI_AGENT_TYPES:
238
237
  return await _execute_delegated_agent(tool_args, config)
239
238
 
240
239
  # Generic fallback for unknown node types
@@ -246,14 +245,6 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
246
245
  # nodes/tool/calculator_tool.py CalculatorToolNode.calculate().
247
246
 
248
247
 
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
248
  # _execute_duckduckgo_search: Wave 11.C moved logic to
258
249
  # nodes/search/duckduckgo_search.py DuckDuckGoSearchNode.search(). Wave
259
250
  # 11.I milestone O moved the flat (args, config) -> dict shim used by
@@ -264,10 +255,6 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
264
255
  # now routes through the plugin fast-path (nodes/whatsapp/*.py).
265
256
 
266
257
 
267
-
268
-
269
-
270
-
271
258
  # Wave 11.D.10: _execute_geocoding / _execute_nearby_places deleted.
272
259
  # gmaps_locations + gmaps_nearby_places now route through the plugin
273
260
  # fast-path (nodes/location/*.py).
@@ -282,16 +269,7 @@ async def _dispatch_tool(tool_name: str, tool_args: Dict[str, Any],
282
269
  # (nodes/google/*.py). These functions were defined but unreferenced.
283
270
 
284
271
 
285
-
286
-
287
-
288
-
289
-
290
-
291
-
292
-
293
- async def _execute_generic(args: Dict[str, Any],
294
- config: Dict[str, Any]) -> Dict[str, Any]:
272
+ async def _execute_generic(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
295
273
  """Execute a generic tool (fallback handler).
296
274
 
297
275
  For node types without specific handlers, this returns the input
@@ -305,15 +283,14 @@ async def _execute_generic(args: Dict[str, Any],
305
283
  Dict with input echoed and node info
306
284
  """
307
285
  return {
308
- "input": args.get('input', ''),
309
- "node_type": config.get('node_type'),
310
- "node_id": config.get('node_id'),
311
- "message": "Generic tool executed - no specific handler for this node type"
286
+ "input": args.get("input", ""),
287
+ "node_type": config.get("node_type"),
288
+ "node_id": config.get("node_id"),
289
+ "message": "Generic tool executed - no specific handler for this node type",
312
290
  }
313
291
 
314
292
 
315
- async def _execute_delegated_agent(args: Dict[str, Any],
316
- config: Dict[str, Any]) -> Dict[str, Any]:
293
+ async def _execute_delegated_agent(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
317
294
  """Delegate a task to a child AI Agent (fire-and-forget pattern).
318
295
 
319
296
  This spawns the child agent as an asyncio background task and returns
@@ -329,26 +306,26 @@ async def _execute_delegated_agent(args: Dict[str, Any],
329
306
  """
330
307
  from services.status_broadcaster import get_status_broadcaster
331
308
 
332
- node_id = config.get('node_id')
333
- node_type = config.get('node_type')
334
- workflow_id = config.get('workflow_id')
335
- task_description = args.get('task', '')
336
- task_context = args.get('context', '')
309
+ node_id = config.get("node_id")
310
+ node_type = config.get("node_type")
311
+ workflow_id = config.get("workflow_id")
312
+ task_description = args.get("task", "")
313
+ task_context = args.get("context", "")
337
314
 
338
315
  # Get injected services
339
- ai_service = config.get('ai_service')
340
- database = config.get('database')
341
- nodes = config.get('nodes', [])
342
- edges = config.get('edges', [])
316
+ ai_service = config.get("ai_service")
317
+ database = config.get("database")
318
+ nodes = config.get("nodes", [])
319
+ edges = config.get("edges", [])
343
320
 
344
321
  if not ai_service or not database:
345
322
  return {
346
323
  "error": "Agent delegation requires ai_service and database in config",
347
- "hint": "Ensure nodes/edges are passed to tool config"
324
+ "hint": "Ensure nodes/edges are passed to tool config",
348
325
  }
349
326
 
350
327
  # Get parent node ID for duplicate tracking
351
- parent_node_id = config.get('parent_node_id', '')
328
+ parent_node_id = config.get("parent_node_id", "")
352
329
 
353
330
  # Generate hash of task to detect duplicate delegation attempts
354
331
  task_hash = hashlib.md5(f"{task_description}:{task_context}".encode()).hexdigest()[:16]
@@ -362,7 +339,7 @@ async def _execute_delegated_agent(args: Dict[str, Any],
362
339
  "success": True,
363
340
  "status": "ALREADY_DELEGATED",
364
341
  "task_id": existing_task_id,
365
- "agent_name": config.get('parameters', {}).get('label', node_type),
342
+ "agent_name": config.get("parameters", {}).get("label", node_type),
366
343
  "result": (
367
344
  f"This task was ALREADY delegated (task_id: {existing_task_id}). "
368
345
  f"Do NOT call this tool again. Use 'check_delegated_tasks' to check status."
@@ -388,44 +365,41 @@ async def _execute_delegated_agent(args: Dict[str, Any],
388
365
 
389
366
  # Inject API key - delegated agents bypass NodeExecutor._inject_api_keys,
390
367
  # so we must resolve the key here from the credential store
391
- if not child_params.get('api_key'):
368
+ if not child_params.get("api_key"):
392
369
  from constants import detect_ai_provider
370
+
393
371
  provider = detect_ai_provider(node_type, child_params)
394
372
  key = await ai_service.auth.get_api_key(provider, "default")
395
373
  if key:
396
- child_params['api_key'] = key
374
+ child_params["api_key"] = key
397
375
  logger.debug(f"[Delegated Agent] Injected API key for provider={provider}")
398
376
 
399
377
  # Inject default model if not set
400
- if not child_params.get('model'):
378
+ if not child_params.get("model"):
401
379
  from constants import detect_ai_provider
380
+
402
381
  provider = detect_ai_provider(node_type, child_params)
403
382
  models = await ai_service.auth.get_stored_models(provider, "default")
404
383
  if models:
405
- child_params['model'] = models[0]
384
+ child_params["model"] = models[0]
406
385
 
407
386
  # Task goes into system_message (directive), context data goes into prompt.
408
387
  # Schema-canonical key is snake_case; drop any pre-migration camelCase
409
388
  # mirror so the saved-params dict downstream uses the canonical key.
410
- child_params['system_message'] = task_description
411
- child_params.pop('systemMessage', None)
412
- child_params['prompt'] = task_context if task_context else task_description
389
+ child_params["system_message"] = task_description
390
+ child_params.pop("systemMessage", None)
391
+ child_params["prompt"] = task_context if task_context else task_description
413
392
 
414
393
  # Create execution context for child agent
415
- child_context = {
416
- 'nodes': nodes,
417
- 'edges': edges,
418
- 'workflow_id': workflow_id,
419
- 'outputs': {},
420
- 'parent_task_id': task_id
421
- }
394
+ child_context = {"nodes": nodes, "edges": edges, "workflow_id": workflow_id, "outputs": {}, "parent_task_id": task_id}
422
395
 
423
396
  broadcaster = get_status_broadcaster()
424
- agent_label = child_params.get('label', node_type)
397
+ agent_label = child_params.get("label", node_type)
425
398
 
426
399
  logger.info(f"[Delegated Agent] Starting task {task_id} for '{agent_label}' (node: {node_id})")
427
- logger.debug(f"[Delegated Agent] Context: {len(nodes)} nodes, {len(edges)} edges, "
428
- f"edge_targets={set(e.get('target') for e in edges)}")
400
+ logger.debug(
401
+ f"[Delegated Agent] Context: {len(nodes)} nodes, {len(edges)} edges, " f"edge_targets={set(e.get('target') for e in edges)}"
402
+ )
429
403
 
430
404
  # Define the background coroutine
431
405
  async def run_child_agent():
@@ -434,12 +408,8 @@ async def _execute_delegated_agent(args: Dict[str, Any],
434
408
  await broadcaster.update_node_status(
435
409
  node_id,
436
410
  "executing",
437
- {
438
- "phase": "delegated_task",
439
- "task_id": task_id,
440
- "message": f"Working on: {task_description[:100]}..."
441
- },
442
- workflow_id=workflow_id
411
+ {"phase": "delegated_task", "task_id": task_id, "message": f"Working on: {task_description[:100]}..."},
412
+ workflow_id=workflow_id,
443
413
  )
444
414
 
445
415
  # Execute the child agent via its own plugin class.
@@ -455,27 +425,22 @@ async def _execute_delegated_agent(args: Dict[str, Any],
455
425
  raise RuntimeError(f"Unknown delegated agent type: {node_type}")
456
426
  instance = plugin_cls()
457
427
  child_ctx = NodeContext.from_legacy(
458
- node_id=node_id, node_type=node_type, context=child_context,
428
+ node_id=node_id,
429
+ node_type=node_type,
430
+ context=child_context,
459
431
  )
460
432
  result = await instance.execute(node_id, child_params, child_ctx)
461
433
 
462
434
  logger.info(f"[Delegated Agent] Task {task_id} completed: success={result.get('success')}")
463
435
 
464
436
  # Check if child agent actually succeeded
465
- if not result.get('success'):
437
+ if not result.get("success"):
466
438
  # Child agent returned failure - treat as error
467
- error_msg = result.get('error', 'Child agent returned failure')
439
+ error_msg = result.get("error", "Child agent returned failure")
468
440
  logger.warning(f"[Delegated Agent] Task {task_id} returned success=False: {error_msg}")
469
441
 
470
442
  await broadcaster.update_node_status(
471
- node_id,
472
- "error",
473
- {
474
- "phase": "delegated_error",
475
- "task_id": task_id,
476
- "error": error_msg
477
- },
478
- workflow_id=workflow_id
443
+ node_id, "error", {"phase": "delegated_error", "task_id": task_id, "error": error_msg}, workflow_id=workflow_id
479
444
  )
480
445
 
481
446
  # Cache error for parent retrieval
@@ -496,43 +461,40 @@ async def _execute_delegated_agent(args: Dict[str, Any],
496
461
  output_name="delegation_result",
497
462
  data={
498
463
  "task_id": task_id,
499
- "parent_node_id": config.get('parent_node_id', ''),
464
+ "parent_node_id": config.get("parent_node_id", ""),
500
465
  "agent_name": agent_label,
501
466
  "status": "error",
502
467
  "error": error_msg,
503
- }
468
+ },
504
469
  )
505
470
 
506
- # Dispatch error event for trigger nodes
507
- await broadcaster.send_custom_event('task_completed', {
508
- 'task_id': task_id,
509
- 'status': 'error',
510
- 'agent_name': agent_label,
511
- 'agent_node_id': node_id,
512
- 'parent_node_id': config.get('parent_node_id', ''),
513
- 'error': error_msg,
514
- 'workflow_id': workflow_id,
515
- })
471
+ # Dispatch error event for trigger nodes — Wave 12 B8.
472
+ from nodes.agent._events import broadcast_agent_task_failed
473
+
474
+ await broadcast_agent_task_failed(
475
+ task_id=task_id,
476
+ agent_name=agent_label,
477
+ agent_node_id=node_id,
478
+ parent_node_id=config.get("parent_node_id", ""),
479
+ workflow_id=workflow_id,
480
+ error=error_msg,
481
+ )
516
482
 
517
483
  return result
518
484
 
519
485
  # Success case - extract response properly
520
- response_text = result.get('result', {}).get('response', '')
486
+ response_text = result.get("result", {}).get("response", "")
521
487
  if not response_text:
522
488
  # Fallback: try to stringify the result dict
523
- response_text = str(result.get('result', '')) if result.get('result') else 'No response generated'
489
+ response_text = str(result.get("result", "")) if result.get("result") else "No response generated"
524
490
 
525
491
  # Broadcast completion
526
- response_preview = response_text[:200] if response_text else ''
492
+ response_preview = response_text[:200] if response_text else ""
527
493
  await broadcaster.update_node_status(
528
494
  node_id,
529
495
  "success",
530
- {
531
- "phase": "delegated_complete",
532
- "task_id": task_id,
533
- "result_summary": response_preview
534
- },
535
- workflow_id=workflow_id
496
+ {"phase": "delegated_complete", "task_id": task_id, "result_summary": response_preview},
497
+ workflow_id=workflow_id,
536
498
  )
537
499
 
538
500
  # Cache result for parent retrieval (Layer 2: in-memory)
@@ -553,37 +515,31 @@ async def _execute_delegated_agent(args: Dict[str, Any],
553
515
  output_name="delegation_result",
554
516
  data={
555
517
  "task_id": task_id,
556
- "parent_node_id": config.get('parent_node_id', ''),
518
+ "parent_node_id": config.get("parent_node_id", ""),
557
519
  "agent_name": agent_label,
558
520
  "status": "completed",
559
521
  "result": response_text,
560
- }
522
+ },
561
523
  )
562
524
 
563
- # Dispatch task_completed event for trigger nodes
564
- await broadcaster.send_custom_event('task_completed', {
565
- 'task_id': task_id,
566
- 'status': 'completed',
567
- 'agent_name': agent_label,
568
- 'agent_node_id': node_id,
569
- 'parent_node_id': config.get('parent_node_id', ''),
570
- 'result': response_text,
571
- 'workflow_id': workflow_id,
572
- })
525
+ # Dispatch task_completed event for trigger nodes — Wave 12 B8.
526
+ from nodes.agent._events import broadcast_agent_task_completed
527
+
528
+ await broadcast_agent_task_completed(
529
+ task_id=task_id,
530
+ agent_name=agent_label,
531
+ agent_node_id=node_id,
532
+ parent_node_id=config.get("parent_node_id", ""),
533
+ workflow_id=workflow_id,
534
+ result=response_text,
535
+ )
573
536
 
574
537
  return result
575
538
 
576
539
  except Exception as e:
577
540
  logger.error(f"[Delegated Agent] Task {task_id} failed: {e}")
578
541
  await broadcaster.update_node_status(
579
- node_id,
580
- "error",
581
- {
582
- "phase": "delegated_error",
583
- "task_id": task_id,
584
- "error": str(e)
585
- },
586
- workflow_id=workflow_id
542
+ node_id, "error", {"phase": "delegated_error", "task_id": task_id, "error": str(e)}, workflow_id=workflow_id
587
543
  )
588
544
 
589
545
  # Cache error for parent retrieval (Layer 2: in-memory)
@@ -604,23 +560,24 @@ async def _execute_delegated_agent(args: Dict[str, Any],
604
560
  output_name="delegation_result",
605
561
  data={
606
562
  "task_id": task_id,
607
- "parent_node_id": config.get('parent_node_id', ''),
563
+ "parent_node_id": config.get("parent_node_id", ""),
608
564
  "agent_name": agent_label,
609
565
  "status": "error",
610
566
  "error": str(e),
611
- }
567
+ },
612
568
  )
613
569
 
614
- # Dispatch task_completed event for trigger nodes (error case)
615
- await broadcaster.send_custom_event('task_completed', {
616
- 'task_id': task_id,
617
- 'status': 'error',
618
- 'agent_name': agent_label,
619
- 'agent_node_id': node_id,
620
- 'parent_node_id': config.get('parent_node_id', ''),
621
- 'error': str(e),
622
- 'workflow_id': workflow_id,
623
- })
570
+ # Dispatch task_completed event for trigger nodes (error case) — Wave 12 B8.
571
+ from nodes.agent._events import broadcast_agent_task_failed
572
+
573
+ await broadcast_agent_task_failed(
574
+ task_id=task_id,
575
+ agent_name=agent_label,
576
+ agent_node_id=node_id,
577
+ parent_node_id=config.get("parent_node_id", ""),
578
+ workflow_id=workflow_id,
579
+ error=str(e),
580
+ )
624
581
 
625
582
  return {"success": False, "error": str(e)}
626
583
 
@@ -658,8 +615,7 @@ async def _execute_delegated_agent(args: Dict[str, Any],
658
615
  }
659
616
 
660
617
 
661
- async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
662
- database=None) -> Dict[str, Any]:
618
+ async def get_delegated_task_status(task_ids: Optional[List[str]] = None, database=None) -> Dict[str, Any]:
663
619
  """Check status and retrieve results of delegated tasks.
664
620
 
665
621
  3-layer lookup: live tasks -> memory cache -> DB (NodeOutput).
@@ -674,9 +630,7 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
674
630
  """
675
631
  if not task_ids:
676
632
  # Return all known from memory
677
- task_ids = list(set(
678
- list(_delegated_tasks.keys()) + list(_delegation_results.keys())
679
- ))
633
+ task_ids = list(set(list(_delegated_tasks.keys()) + list(_delegation_results.keys())))
680
634
 
681
635
  tasks = []
682
636
  db_lookup_ids = []
@@ -691,7 +645,7 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
691
645
  # Task finished -- extract result via task.result()
692
646
  try:
693
647
  result = live_task.result()
694
- response = result.get('result', {}).get('response', str(result.get('result', '')))
648
+ response = result.get("result", {}).get("response", str(result.get("result", "")))
695
649
  tasks.append({"task_id": tid, "status": "completed", "result": response})
696
650
  except Exception as e:
697
651
  tasks.append({"task_id": tid, "status": "error", "error": str(e)})
@@ -709,21 +663,20 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
709
663
  # DB fallback for results not in memory (cross-restart)
710
664
  if db_lookup_ids and database:
711
665
  for tid in list(db_lookup_ids):
712
- db_result = await database.get_node_output_by_session(
713
- session_id=f"delegation_{tid}",
714
- output_name="delegation_result"
715
- )
666
+ db_result = await database.get_node_output_by_session(session_id=f"delegation_{tid}", output_name="delegation_result")
716
667
  if db_result:
717
- data = db_result.get('data', {})
668
+ data = db_result.get("data", {})
718
669
  result_data = data.get("result", {})
719
670
  response_text = result_data.get("response", str(result_data)) if isinstance(result_data, dict) else str(result_data)
720
- tasks.append({
721
- "task_id": tid,
722
- "status": data.get("status", "completed"),
723
- "agent_name": data.get("agent_name", ""),
724
- "result": response_text,
725
- "error": data.get("error"),
726
- })
671
+ tasks.append(
672
+ {
673
+ "task_id": tid,
674
+ "status": data.get("status", "completed"),
675
+ "agent_name": data.get("agent_name", ""),
676
+ "result": response_text,
677
+ "error": data.get("error"),
678
+ }
679
+ )
727
680
  db_lookup_ids.remove(tid)
728
681
 
729
682
  # Remaining IDs not found anywhere
@@ -733,15 +686,14 @@ async def get_delegated_task_status(task_ids: Optional[List[str]] = None,
733
686
  return {"tasks": tasks}
734
687
 
735
688
 
736
- async def _execute_check_delegated_tasks(args: Dict[str, Any],
737
- config: Dict[str, Any]) -> Dict[str, Any]:
689
+ async def _execute_check_delegated_tasks(args: Dict[str, Any], config: Dict[str, Any]) -> Dict[str, Any]:
738
690
  """LLM-callable tool: check on delegated child agents.
739
691
 
740
692
  Returns status and results for previously delegated tasks.
741
693
  Follows Celery AsyncResult / Ray ObjectRef patterns.
742
694
  """
743
- task_ids = args.get('task_ids')
744
- database = config.get('database')
695
+ task_ids = args.get("task_ids")
696
+ database = config.get("database")
745
697
  result = await get_delegated_task_status(task_ids=task_ids, database=database)
746
698
 
747
699
  formatted = []
@@ -785,6 +737,3 @@ async def _execute_check_delegated_tasks(args: Dict[str, Any],
785
737
  # now route through the plugin fast-path in execute_tool which calls
786
738
  # the BaseNode.execute_as_tool method on the plugin class.
787
739
  # _execute_serper_search_tool stays until serperSearch is migrated.
788
-
789
-
790
-