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
@@ -26,7 +26,6 @@ Tools deferred to v2: ``getDiagnostics``, ``executeCode``.
26
26
  from __future__ import annotations
27
27
 
28
28
  import contextvars
29
- import logging
30
29
  import secrets
31
30
  from dataclasses import dataclass, field
32
31
  from pathlib import Path
@@ -35,7 +34,6 @@ from typing import Any, Awaitable, Callable, Dict, List, Optional, Set
35
34
  from starlette.middleware.base import BaseHTTPMiddleware
36
35
  from starlette.requests import Request
37
36
  from starlette.responses import JSONResponse, Response
38
- from starlette.routing import Mount
39
37
 
40
38
  from core.logging import get_logger
41
39
 
@@ -46,6 +44,7 @@ logger = get_logger(__name__)
46
44
  # BatchContext + token registry
47
45
  # ---------------------------------------------------------------------------
48
46
 
47
+
49
48
  @dataclass
50
49
  class BatchContext:
51
50
  """Scoping data attached to one batch's bearer token.
@@ -54,6 +53,7 @@ class BatchContext:
54
53
  ``finally`` block. Tools dereference the calling batch via the
55
54
  bearer token in `Authorization` header.
56
55
  """
56
+
57
57
  workflow_id: str
58
58
  node_id: str
59
59
  workspace_dir: Path
@@ -91,15 +91,18 @@ def register_batch(token: str, ctx: BatchContext) -> None:
91
91
  _active_tokens[token] = ctx
92
92
  tool_names = [t.get("node_type") for t in ctx.connected_tools]
93
93
  logger.info(
94
- "[CC-Agent MCP register_batch] node=%s wf=%s token=%s... "
95
- "skills=%d tools=%d creds=%d %s",
96
- ctx.node_id, ctx.workflow_id, token[:8],
97
- len(ctx.connected_skill_names), len(ctx.connected_tools),
94
+ "[CC-Agent MCP register_batch] node=%s wf=%s token=%s... " "skills=%d tools=%d creds=%d %s",
95
+ ctx.node_id,
96
+ ctx.workflow_id,
97
+ token[:8],
98
+ len(ctx.connected_skill_names),
99
+ len(ctx.connected_tools),
98
100
  len(ctx.allowed_credentials),
99
101
  f"tools={tool_names}" if tool_names else "(no tools wired)",
100
102
  )
101
103
  # Per-batch workflow-tool exposure lives in workflow_tools.py.
102
104
  from services.cli_agent.workflow_tools import expose_workflow_tools
105
+
103
106
  expose_workflow_tools(ctx.connected_tools)
104
107
 
105
108
 
@@ -111,6 +114,7 @@ def unregister_batch(token: str) -> None:
111
114
  return
112
115
  logger.debug("[CC-Agent MCP] unregistered batch token=%s...", token[:8])
113
116
  from services.cli_agent.workflow_tools import unexpose_workflow_tools
117
+
114
118
  unexpose_workflow_tools(ctx.connected_tools)
115
119
 
116
120
 
@@ -118,6 +122,72 @@ def lookup_batch(token: str) -> Optional[BatchContext]:
118
122
  return _active_tokens.get(token)
119
123
 
120
124
 
125
+ def rebind_batch(
126
+ token: str,
127
+ *,
128
+ connected_tools: Optional[List[Dict[str, Any]]] = None,
129
+ connected_skill_names: Optional[Set[str]] = None,
130
+ allowed_credentials: Optional[Set[str]] = None,
131
+ workspace_dir: Optional[Path] = None,
132
+ ) -> Optional[BatchContext]:
133
+ """In-place rebind of an existing batch's surface.
134
+
135
+ Used by :class:`ClaudeSessionPool` on warm-subprocess reuse:
136
+ claude bakes the bearer token into its argv at spawn time (via
137
+ ``--mcp-config``), so a warm subprocess keeps hitting the SAME
138
+ token across batches. If the operator disconnects a tool between
139
+ batches, the bearer-token's :class:`BatchContext` must be updated
140
+ in place — otherwise the per-handler scope check in
141
+ ``workflow_tools._build_handler`` still sees the stale
142
+ ``connected_tools`` and lets disconnected tools fire.
143
+
144
+ For ``connected_tools``: refcount diff is applied to FastMCP — any
145
+ node_type that's in the OLD list but not the new gets one
146
+ :func:`unexpose_workflow_tools` decrement (may remove the tool
147
+ from FastMCP when its refcount hits zero); any node_type that's
148
+ new gets one :func:`expose_workflow_tools` increment. Tools that
149
+ survive in both lists are left alone but their ``parameters`` /
150
+ ``label`` fields are refreshed via the in-place list assignment.
151
+
152
+ Returns the rebound context, or ``None`` if the token is unknown.
153
+ """
154
+ ctx = _active_tokens.get(token)
155
+ if ctx is None:
156
+ return None
157
+ if connected_tools is not None:
158
+ from services.cli_agent.workflow_tools import (
159
+ expose_workflow_tools,
160
+ unexpose_workflow_tools,
161
+ )
162
+
163
+ old_by_type = {t.get("node_type"): t for t in ctx.connected_tools if t.get("node_type")}
164
+ new_by_type = {t.get("node_type"): t for t in connected_tools if t.get("node_type")}
165
+ added = [v for k, v in new_by_type.items() if k not in old_by_type]
166
+ removed = [v for k, v in old_by_type.items() if k not in new_by_type]
167
+ if removed:
168
+ unexpose_workflow_tools(removed)
169
+ if added:
170
+ expose_workflow_tools(added)
171
+ ctx.connected_tools = list(connected_tools)
172
+ logger.info(
173
+ "[CC-Agent MCP rebind_batch] node=%s wf=%s token=%s... " "+%d -%d kept=%d (now %d tools)",
174
+ ctx.node_id,
175
+ ctx.workflow_id,
176
+ token[:8],
177
+ len(added),
178
+ len(removed),
179
+ len(old_by_type.keys() & new_by_type.keys()),
180
+ len(ctx.connected_tools),
181
+ )
182
+ if connected_skill_names is not None:
183
+ ctx.connected_skill_names = set(connected_skill_names)
184
+ if allowed_credentials is not None:
185
+ ctx.allowed_credentials = set(allowed_credentials)
186
+ if workspace_dir is not None:
187
+ ctx.workspace_dir = Path(workspace_dir).resolve()
188
+ return ctx
189
+
190
+
121
191
  def active_batch_count() -> int:
122
192
  return len(_active_tokens)
123
193
 
@@ -126,18 +196,13 @@ def active_batch_count() -> int:
126
196
  # ContextVar — thread/task-local handle to the current batch
127
197
  # ---------------------------------------------------------------------------
128
198
 
129
- _current_batch: contextvars.ContextVar[Optional[BatchContext]] = (
130
- contextvars.ContextVar("machina_current_batch", default=None)
131
- )
199
+ _current_batch: contextvars.ContextVar[Optional[BatchContext]] = contextvars.ContextVar("machina_current_batch", default=None)
132
200
 
133
201
 
134
202
  def _require_batch() -> BatchContext:
135
203
  ctx = _current_batch.get()
136
204
  if ctx is None:
137
- raise RuntimeError(
138
- "MCP tool called without an active batch context. "
139
- "This indicates the auth middleware was bypassed."
140
- )
205
+ raise RuntimeError("MCP tool called without an active batch context. " "This indicates the auth middleware was bypassed.")
141
206
  return ctx
142
207
 
143
208
 
@@ -152,6 +217,7 @@ def _require_batch() -> BatchContext:
152
217
  # Auth middleware
153
218
  # ---------------------------------------------------------------------------
154
219
 
220
+
155
221
  class _BearerAuthMiddleware(BaseHTTPMiddleware):
156
222
  """Validate `Authorization: Bearer <token>` against the registry.
157
223
 
@@ -173,9 +239,7 @@ class _BearerAuthMiddleware(BaseHTTPMiddleware):
173
239
  if path.endswith("/healthz"):
174
240
  return await call_next(request)
175
241
 
176
- auth = request.headers.get("authorization") or request.headers.get(
177
- "Authorization"
178
- )
242
+ auth = request.headers.get("authorization") or request.headers.get("Authorization")
179
243
  token: Optional[str] = None
180
244
  if auth and auth.lower().startswith("bearer "):
181
245
  token = auth[7:].strip() or None
@@ -186,7 +250,10 @@ class _BearerAuthMiddleware(BaseHTTPMiddleware):
186
250
  "[CC-Agent MCP auth] %s %s -> 401 (no Bearer token; "
187
251
  "auth_header=%r ua=%r) — claude CLI either didn't read the "
188
252
  "lockfile or is hitting the wrong URL.",
189
- method, path, auth, ua,
253
+ method,
254
+ path,
255
+ auth,
256
+ ua,
190
257
  )
191
258
  return JSONResponse(
192
259
  {"error": "missing or malformed Authorization header"},
@@ -196,9 +263,10 @@ class _BearerAuthMiddleware(BaseHTTPMiddleware):
196
263
  ctx = lookup_batch(token)
197
264
  if ctx is None:
198
265
  logger.warning(
199
- "[CC-Agent MCP auth] %s %s -> 401 (token=%s... not in "
200
- "active registry — batch may have ended)",
201
- method, path, token[:8],
266
+ "[CC-Agent MCP auth] %s %s -> 401 (token=%s... not in " "active registry — batch may have ended)",
267
+ method,
268
+ path,
269
+ token[:8],
202
270
  )
203
271
  return JSONResponse(
204
272
  {"error": "invalid or expired token"},
@@ -207,7 +275,11 @@ class _BearerAuthMiddleware(BaseHTTPMiddleware):
207
275
 
208
276
  logger.info(
209
277
  "[CC-Agent MCP auth] %s %s -> OK (node=%s wf=%s token=%s...)",
210
- method, path, ctx.node_id, ctx.workflow_id, token[:8],
278
+ method,
279
+ path,
280
+ ctx.node_id,
281
+ ctx.workflow_id,
282
+ token[:8],
211
283
  )
212
284
 
213
285
  reset_token = _current_batch.set(ctx)
@@ -221,6 +293,7 @@ class _BearerAuthMiddleware(BaseHTTPMiddleware):
221
293
  # Tool registration helper — defers FastMCP import so module import is cheap
222
294
  # ---------------------------------------------------------------------------
223
295
 
296
+
224
297
  def _build_tools(mcp: Any) -> None: # FastMCP type
225
298
  """Register the 5 v1 tools on a `FastMCP` instance."""
226
299
 
@@ -272,9 +345,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
272
345
  }
273
346
  if read and p.stat().st_size <= max_bytes:
274
347
  try:
275
- info["content"] = p.read_text(
276
- encoding="utf-8", errors="replace"
277
- )
348
+ info["content"] = p.read_text(encoding="utf-8", errors="replace")
278
349
  except OSError as exc:
279
350
  info["read_error"] = str(exc)
280
351
  entries.append(info)
@@ -301,6 +372,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
301
372
  ctx = _require_batch()
302
373
  try:
303
374
  from services.skill_loader import get_skill_loader
375
+
304
376
  loader = get_skill_loader()
305
377
  registry = loader.scan_skills()
306
378
  results = []
@@ -308,15 +380,14 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
308
380
  meta = registry.get(name)
309
381
  if meta is None:
310
382
  continue
311
- results.append({
312
- "name": meta.name,
313
- "description": meta.description,
314
- "allowed_tools": list(meta.allowed_tools),
315
- "category": (
316
- meta.metadata.get("category")
317
- if isinstance(meta.metadata, dict) else None
318
- ),
319
- })
383
+ results.append(
384
+ {
385
+ "name": meta.name,
386
+ "description": meta.description,
387
+ "allowed_tools": list(meta.allowed_tools),
388
+ "category": (meta.metadata.get("category") if isinstance(meta.metadata, dict) else None),
389
+ }
390
+ )
320
391
  return {"skills": results}
321
392
  except Exception as exc: # pragma: no cover
322
393
  logger.exception("[CC-Agent MCP] listSkills failed")
@@ -339,6 +410,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
339
410
  }
340
411
  try:
341
412
  from services.skill_loader import get_skill_loader
413
+
342
414
  loader = get_skill_loader()
343
415
  skill = loader.load_skill(name)
344
416
  if skill is None:
@@ -375,6 +447,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
375
447
  }
376
448
  try:
377
449
  from core.container import container
450
+
378
451
  auth = container.auth_service()
379
452
  value = await auth.get_api_key(name)
380
453
  if not value:
@@ -413,6 +486,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
413
486
  broadcaster = ctx.broadcaster
414
487
  if broadcaster is None:
415
488
  from services.status_broadcaster import get_status_broadcaster
489
+
416
490
  broadcaster = get_status_broadcaster()
417
491
  payload = {
418
492
  "source": source or f"mcp:{ctx.node_id}",
@@ -432,7 +506,7 @@ def _build_tools(mcp: Any) -> None: # FastMCP type
432
506
 
433
507
  _app_singleton: Optional[Any] = None # Starlette app
434
508
  _mcp_singleton: Optional[Any] = None # FastMCP instance — used by per-batch
435
- # dynamic tool (un)registration.
509
+ # dynamic tool (un)registration.
436
510
 
437
511
 
438
512
  def get_mcp_app() -> Any:
@@ -471,6 +545,7 @@ def get_mcp_app() -> Any:
471
545
  # Test/diagnostic helpers (used by tests + verification step #11/#12)
472
546
  # ---------------------------------------------------------------------------
473
547
 
548
+
474
549
  def _reset_for_tests() -> None: # pragma: no cover
475
550
  """Wipe the token registry + per-batch workflow-tool refcounts.
476
551
  ONLY use in tests."""
@@ -479,4 +554,5 @@ def _reset_for_tests() -> None: # pragma: no cover
479
554
  _app_singleton = None
480
555
  _mcp_singleton = None
481
556
  from services.cli_agent.workflow_tools import _reset_for_tests as _wt_reset
557
+
482
558
  _wt_reset()
@@ -25,6 +25,7 @@ from typing import Any, Dict, List, Optional, Protocol, runtime_checkable
25
25
  # Shared data types
26
26
  # ---------------------------------------------------------------------------
27
27
 
28
+
28
29
  @dataclass
29
30
  class CanonicalUsage:
30
31
  """Vendor-normalised token counts.
@@ -34,6 +35,7 @@ class CanonicalUsage:
34
35
  differently) maps into this so the existing `services/pricing.py`
35
36
  can compute USD without per-vendor branches.
36
37
  """
38
+
37
39
  input_tokens: int = 0
38
40
  output_tokens: int = 0
39
41
  cache_read: int = 0
@@ -48,6 +50,7 @@ class SessionResult:
48
50
 
49
51
  Shared keys are the schema; vendor extras live in `provider_data`.
50
52
  """
53
+
51
54
  task_id: str
52
55
  session_id: Optional[str] = None
53
56
  provider: str = ""
@@ -68,6 +71,7 @@ class SessionResult:
68
71
  @dataclass
69
72
  class BatchResult:
70
73
  """Aggregated result returned by `AICliService.run_batch()`."""
74
+
71
75
  tasks: List[SessionResult] = field(default_factory=list)
72
76
  n_tasks: int = 0
73
77
  n_succeeded: int = 0
@@ -83,48 +87,57 @@ class BatchResult:
83
87
  # Provider protocol (structural typing)
84
88
  # ---------------------------------------------------------------------------
85
89
 
90
+
86
91
  @runtime_checkable
87
92
  class AICliProvider(Protocol):
88
93
  """Structural Protocol for an AI CLI provider.
89
94
 
90
95
  Concrete classes:
91
- - `providers.anthropic_claude.AnthropicClaudeProvider`
96
+ - `nodes.agent.claude_code_agent._provider.AnthropicClaudeProvider`
92
97
  - `providers.openai_codex.OpenAICodexProvider`
93
98
  - `providers.google_gemini.GoogleGeminiProvider` (v2 stub)
94
99
  """
95
100
 
96
- name: str # "claude" | "codex" | "gemini"
97
- package_name: str # npm package
98
- binary_name: str # "claude" | "codex" | "gemini"
99
- ide_lock_env_var: Optional[str] # CLAUDE_IDE_LOCK | GEMINI_IDE_LOCK | None
100
- ide_lockfile_dir: Optional[Path] # ~/.claude/ide | <tmpdir>/gemini/ide
101
+ name: str # "claude" | "codex" | "gemini"
102
+ package_name: str # npm package
103
+ binary_name: str # "claude" | "codex" | "gemini"
104
+ ide_lock_env_var: Optional[str] # CLAUDE_IDE_LOCK | GEMINI_IDE_LOCK | None
105
+ ide_lockfile_dir: Optional[Path] # <MACHINA_CLAUDE_DIR>/ide | <tmpdir>/gemini/ide
101
106
 
102
107
  # ---- spawn surface ---------------------------------------------------
103
108
 
104
- def binary_path(self) -> Path: ...
109
+ def binary_path(self) -> Path:
110
+ ...
105
111
  # Resolve the CLI binary. Resolution chain (Composio pattern):
106
112
  # 1) shutil.which(<binary_name>)
107
113
  # 2) `npx --yes <package_name>` shim path
108
114
  # Raises FileNotFoundError if neither is available.
109
115
 
110
- def headless_argv(self, task: Any, *, defaults: Dict[str, Any]) -> List[str]: ...
111
- # Build the full argv (binary + flags) for a headless run of
112
- # `task` (a `<Provider>TaskSpec` Pydantic model). `defaults`
113
- # comes from `ai_cli_providers.json` for this provider.
116
+ def interactive_argv(self, task: Any, *, defaults: Dict[str, Any]) -> List[str]:
117
+ ...
118
+ # Build the full argv (binary + flags) for spawning a session
119
+ # over `task` (a `<Provider>TaskSpec` Pydantic model). For
120
+ # Claude, this is the interactive-TUI shape (no `-p`, prompt as
121
+ # positional after `--`); for Codex, it's `codex exec --json`
122
+ # since that's Codex's automation surface. `defaults` comes
123
+ # from `ai_cli_providers.json` for this provider.
114
124
 
115
125
  # ---- native auth (no token wrapping) --------------------------------
116
126
 
117
- def login_argv(self) -> List[str]: ...
127
+ def login_argv(self) -> List[str]:
128
+ ...
118
129
  # CLI's own login command, e.g. ["claude", "login"]. Spawned
119
130
  # interactively from the Credentials Modal. CLI stores its own
120
131
  # credentials in `~/.claude/`, `~/.codex/`, `~/.gemini/`.
121
132
 
122
- def auth_status_argv(self) -> Optional[List[str]]: ...
133
+ def auth_status_argv(self) -> Optional[List[str]]:
134
+ ...
123
135
  # No-op invocation to verify auth, e.g. ["claude", "--print", "-p", "ok"].
124
136
  # Returns None if no cheap probe exists; in that case the framework
125
137
  # infers from the first session's stderr.
126
138
 
127
- def detect_auth_error(self, stderr: str, exit_code: int) -> bool: ...
139
+ def detect_auth_error(self, stderr: str, exit_code: int) -> bool:
140
+ ...
128
141
  # Match "not logged in" patterns:
129
142
  # Claude: "Please run 'claude login'"
130
143
  # Codex: HTTP 401 / "OPENAI_API_KEY not set"
@@ -132,11 +145,13 @@ class AICliProvider(Protocol):
132
145
 
133
146
  # ---- streaming output parsing ---------------------------------------
134
147
 
135
- def parse_event(self, line: str) -> Optional[Dict[str, Any]]: ...
148
+ def parse_event(self, line: str) -> Optional[Dict[str, Any]]:
149
+ ...
136
150
  # Parse a single NDJSON line from stdout. Return None for
137
151
  # un-parseable garbage.
138
152
 
139
- def is_final_event(self, event: Dict[str, Any]) -> bool: ...
153
+ def is_final_event(self, event: Dict[str, Any]) -> bool:
154
+ ...
140
155
  # True if this event marks end-of-task. For Claude: `type=="result"`.
141
156
  # For Gemini: `type=="result"`. For Codex: `type=="complete"` or
142
157
  # heuristic fallback.
@@ -146,7 +161,8 @@ class AICliProvider(Protocol):
146
161
  events: List[Dict[str, Any]],
147
162
  stderr: str,
148
163
  exit_code: int,
149
- ) -> Dict[str, Any]: ...
164
+ ) -> Dict[str, Any]:
165
+ ...
150
166
  # Reconstruct a partial dict of `SessionResult` fields from the
151
167
  # event stream. Returns:
152
168
  # {
@@ -161,13 +177,15 @@ class AICliProvider(Protocol):
161
177
  # bloating the shared schema. Pattern from
162
178
  # Hermes agent/transports/types.py NormalizedResponse.
163
179
 
164
- def canonical_usage(self, events: List[Dict[str, Any]]) -> CanonicalUsage: ...
180
+ def canonical_usage(self, events: List[Dict[str, Any]]) -> CanonicalUsage:
181
+ ...
165
182
  # Normalise vendor token-counting into the shared `CanonicalUsage`
166
183
  # shape. Pattern from Hermes agent/usage_pricing.py.
167
184
 
168
185
  # ---- feature gating --------------------------------------------------
169
186
 
170
- def supports(self, feature: str) -> bool: ...
187
+ def supports(self, feature: str) -> bool:
188
+ ...
171
189
  # Feature flags consulted by the session/service layer.
172
190
  # Recognised: "max_budget", "max_turns", "session_id", "resume",
173
191
  # "mcp_runtime", "json_cost", "ide_lockfile", "sandbox".
@@ -1,9 +1,13 @@
1
- """Concrete `AICliProvider` implementations.
1
+ """Concrete `AICliProvider` implementations that still live under the
2
+ generic framework (i.e. haven't been migrated to the canonical
3
+ plugin-folder layout yet):
2
4
 
3
- - `anthropic_claude.AnthropicClaudeProvider` — full v1 surface
4
5
  - `openai_codex.OpenAICodexProvider` — sandbox-first, no session
5
6
  - `google_gemini.GoogleGeminiProvider` — v2 stub raising NotImplementedError
6
7
 
7
- Imports are intentionally not eager `factory.create_cli_provider()`
8
- lazy-imports each one.
8
+ The claude provider has moved to its plugin folder
9
+ (``server/nodes/agent/claude_code_agent/_provider.py``) and is
10
+ discovered via the ``register_provider`` registry. The codex
11
+ provider will follow once `codex_agent` adopts the per-plugin
12
+ folder structure.
9
13
  """
@@ -30,10 +30,7 @@ class GoogleGeminiProvider:
30
30
  name = "gemini"
31
31
 
32
32
  def __init__(self) -> None:
33
- raise NotImplementedError(
34
- "GoogleGeminiProvider is a v2 stub. The factory raises "
35
- "NotImplementedError for 'gemini' in v1."
36
- )
33
+ raise NotImplementedError("GoogleGeminiProvider is a v2 stub. The factory raises " "NotImplementedError for 'gemini' in v1.")
37
34
 
38
35
  # The Protocol surface below is declared so static type-checkers see
39
36
  # the class as a complete `AICliProvider`. None of these are reachable
@@ -47,7 +44,16 @@ class GoogleGeminiProvider:
47
44
  def binary_path(self) -> Path: # pragma: no cover
48
45
  raise NotImplementedError
49
46
 
50
- def headless_argv(self, task: Any, *, defaults: Dict[str, Any]) -> List[str]: # pragma: no cover
47
+ def interactive_argv(
48
+ self,
49
+ task: Any,
50
+ *,
51
+ defaults: Dict[str, Any],
52
+ mcp_endpoint_url: Optional[str] = None,
53
+ mcp_bearer_token: Optional[str] = None,
54
+ connected_tool_names: Optional[List[str]] = None,
55
+ include_prompt: bool = True,
56
+ ) -> List[str]: # pragma: no cover
51
57
  raise NotImplementedError
52
58
 
53
59
  def login_argv(self) -> List[str]: # pragma: no cover
@@ -46,9 +46,15 @@ NAME = "codex"
46
46
 
47
47
  # Best-effort markers for Codex's "stream-end" / "task complete" event.
48
48
  # Update if/when OpenAI publishes a stable schema.
49
- _FINAL_EVENT_TYPES = frozenset({
50
- "complete", "task_complete", "done", "finished", "result",
51
- })
49
+ _FINAL_EVENT_TYPES = frozenset(
50
+ {
51
+ "complete",
52
+ "task_complete",
53
+ "done",
54
+ "finished",
55
+ "result",
56
+ }
57
+ )
52
58
 
53
59
  _AUTH_ERROR_MARKERS = (
54
60
  "OPENAI_API_KEY not set",
@@ -68,9 +74,7 @@ class OpenAICodexProvider:
68
74
  def __init__(self) -> None:
69
75
  cfg = get_provider_config(NAME)
70
76
  if cfg is None:
71
- raise RuntimeError(
72
- f"Provider config missing for {NAME!r}. Check ai_cli_providers.json."
73
- )
77
+ raise RuntimeError(f"Provider config missing for {NAME!r}. Check ai_cli_providers.json.")
74
78
  self.name = NAME
75
79
  self.package_name = cfg.package_name
76
80
  self.binary_name = cfg.binary_name
@@ -93,21 +97,29 @@ class OpenAICodexProvider:
93
97
  return Path(npx)
94
98
 
95
99
  raise FileNotFoundError(
96
- f"Neither {self.binary_name!r} nor 'npx' found in PATH. "
97
- f"Install with: npm install -g {self.package_name}"
100
+ f"Neither {self.binary_name!r} nor 'npx' found in PATH. " f"Install with: npm install -g {self.package_name}"
98
101
  )
99
102
 
100
- def headless_argv(
103
+ def interactive_argv(
101
104
  self,
102
105
  task: Any, # CodexTaskSpec
103
106
  *,
104
107
  defaults: Dict[str, Any],
108
+ mcp_endpoint_url: Optional[str] = None,
109
+ mcp_bearer_token: Optional[str] = None,
110
+ connected_tool_names: Optional[List[str]] = None,
111
+ include_prompt: bool = True,
105
112
  ) -> List[str]:
113
+ """Build the codex spawn argv. Codex's automation surface is
114
+ ``codex exec --json`` (not a TUI mode like claude); this method
115
+ keeps the name aligned with the Protocol while emitting Codex's
116
+ documented non-interactive form. MCP bridging params are accepted
117
+ for Protocol uniformity but unused (codex's MCP config lives in
118
+ ``~/.codex/config.toml``). ``include_prompt`` is honoured so the
119
+ session pool can spawn without an initial prompt."""
120
+ _ = (mcp_endpoint_url, mcp_bearer_token, connected_tool_names)
106
121
  if not isinstance(task, CodexTaskSpec):
107
- raise TypeError(
108
- "OpenAICodexProvider.headless_argv requires CodexTaskSpec, "
109
- f"got {type(task).__name__}"
110
- )
122
+ raise TypeError("OpenAICodexProvider.interactive_argv requires CodexTaskSpec, " f"got {type(task).__name__}")
111
123
 
112
124
  which_codex = shutil.which(self.binary_name)
113
125
  if which_codex:
@@ -115,18 +127,12 @@ class OpenAICodexProvider:
115
127
  else:
116
128
  npx = shutil.which("npx")
117
129
  if not npx:
118
- raise FileNotFoundError(
119
- f"Neither {self.binary_name!r} nor 'npx' found in PATH"
120
- )
130
+ raise FileNotFoundError(f"Neither {self.binary_name!r} nor 'npx' found in PATH")
121
131
  argv = [npx, "--yes", self.package_name]
122
132
 
123
133
  argv += ["exec", "--json"]
124
134
 
125
- model = (
126
- task.model
127
- or defaults.get("default_model")
128
- or self._defaults.get("default_model", "gpt-5.2-codex")
129
- )
135
+ model = task.model or defaults.get("default_model") or self._defaults.get("default_model", "gpt-5.2-codex")
130
136
  argv += ["--model", model]
131
137
 
132
138
  sandbox = task.sandbox or defaults.get(
@@ -144,11 +150,11 @@ class OpenAICodexProvider:
144
150
  # System prompt — Codex doesn't have a dedicated --system-prompt
145
151
  # flag in `exec`. Prepend it to the user prompt with a clear
146
152
  # divider when present.
147
- prompt = task.prompt
148
- if task.system_prompt:
149
- prompt = f"<system>\n{task.system_prompt}\n</system>\n\n{task.prompt}"
150
-
151
- argv += [prompt]
153
+ if include_prompt and task.prompt:
154
+ prompt = task.prompt
155
+ if task.system_prompt:
156
+ prompt = f"<system>\n{task.system_prompt}\n</system>\n\n{task.prompt}"
157
+ argv += [prompt]
152
158
  return argv
153
159
 
154
160
  # ---- native auth -----------------------------------------------------
@@ -195,10 +201,7 @@ class OpenAICodexProvider:
195
201
  response = self._extract_response(events)
196
202
  provider_data = self._extract_provider_data(events)
197
203
 
198
- tool_calls = sum(
199
- 1 for e in events
200
- if e.get("type") in ("tool_call", "tool_use", "function_call")
201
- )
204
+ tool_calls = sum(1 for e in events if e.get("type") in ("tool_call", "tool_use", "function_call"))
202
205
 
203
206
  success = exit_code == 0
204
207
  error: Optional[str] = None
@@ -240,10 +243,7 @@ class OpenAICodexProvider:
240
243
  def canonical_usage(self, events: List[Dict[str, Any]]) -> CanonicalUsage:
241
244
  # Codex doesn't expose token counts in `--json` output. Return zeros.
242
245
  # If a future Codex schema adds usage, extract here.
243
- request_count = sum(
244
- 1 for e in events
245
- if e.get("type") in ("assistant", "message", "response")
246
- )
246
+ request_count = sum(1 for e in events if e.get("type") in ("assistant", "message", "response"))
247
247
  return CanonicalUsage(request_count=request_count)
248
248
 
249
249
  # ---- feature gating --------------------------------------------------