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
@@ -17,15 +17,15 @@ from typing import Annotated, Any, Dict, List, Literal, Optional, Union
17
17
 
18
18
  from pydantic import BaseModel, ConfigDict, Field
19
19
 
20
- from services.cli_agent.protocol import CanonicalUsage
21
-
22
20
 
23
21
  # ---------------------------------------------------------------------------
24
22
  # Task specs (discriminated union)
25
23
  # ---------------------------------------------------------------------------
26
24
 
25
+
27
26
  class BaseAICliTaskSpec(BaseModel):
28
27
  """Shared fields for every CLI task."""
28
+
29
29
  task_id: Optional[str] = Field(
30
30
  default=None,
31
31
  description="Auto-assigned `t_<8hex>` if omitted.",
@@ -37,15 +37,16 @@ class BaseAICliTaskSpec(BaseModel):
37
37
  )
38
38
  branch: Optional[str] = Field(
39
39
  default=None,
40
- description="Branch name for the per-task git worktree. "
41
- "Auto-named `machina/<task_id>` if omitted.",
40
+ description="Branch name for the per-task git worktree. " "Auto-named `machina/<task_id>` if omitted.",
42
41
  )
43
42
  model: Optional[str] = Field(default=None)
44
43
  timeout_seconds: int = Field(
45
- default=600, ge=10, le=3600,
44
+ default=600,
45
+ ge=10,
46
+ le=3600,
46
47
  description="Hard timeout per task. On expiry the session is "
47
- "terminate_then_kill'd and a diagnostic dump is "
48
- "written to ~/.claude-machina/logs/.",
48
+ "terminate_then_kill'd and a diagnostic dump is "
49
+ "written to ~/.claude-machina/logs/.",
49
50
  )
50
51
  system_prompt: Optional[str] = Field(
51
52
  default=None,
@@ -61,31 +62,51 @@ class BaseAICliTaskSpec(BaseModel):
61
62
  class ClaudeTaskSpec(BaseAICliTaskSpec):
62
63
  """Claude Code CLI task. Full feature set: sessions, resume, budget,
63
64
  turns, allowed_tools, permission_mode."""
65
+
64
66
  provider: Literal["claude"] = "claude"
65
67
  session_id: Optional[str] = Field(
66
68
  default=None,
67
69
  description="Start a named session. Pair with `resume_session_id` "
68
- "to chain conversations.",
70
+ "to chain conversations. Note: silently dropped in "
71
+ "interactive mode (claude assigns its own UUID); "
72
+ "kept for back-compat.",
69
73
  )
70
74
  resume_session_id: Optional[str] = Field(
71
75
  default=None,
72
- description="Resume from a prior session_id (returned in a previous "
73
- "task's `result` event).",
76
+ description="Resume from a specific prior session UUID. Mutually "
77
+ "exclusive with `continue_session`. Generally unset by "
78
+ "claude_code_agent — set `continue_session=True` for "
79
+ "memory-bound runs and let claude find its own latest.",
80
+ )
81
+ continue_session: bool = Field(
82
+ default=False,
83
+ description="Emit `--continue` so claude auto-loads the most "
84
+ "recent conversation under the current cwd (per "
85
+ "code.claude.com/docs/en/cli-reference). The cleaner "
86
+ "alternative to passing a specific UUID via "
87
+ "`resume_session_id` — claude handles session "
88
+ "tracking itself, no UUID round-trip through the "
89
+ "memory node's params required.",
74
90
  )
75
91
  max_turns: Optional[int] = Field(
76
- default=None, ge=1,
92
+ default=None,
93
+ ge=1,
77
94
  description="Per-task turn cap. Defaults to provider config.",
78
95
  )
79
96
  max_budget_usd: Optional[float] = Field(
80
- default=None, ge=0,
97
+ default=None,
98
+ ge=0,
81
99
  description="Per-task USD budget. Defaults to provider config.",
82
100
  )
83
101
  allowed_tools: Optional[str] = Field(
84
102
  default=None,
85
- description="Comma-separated tool list. Defaults to "
86
- "Read,Edit,Bash,Glob,Grep,Write.",
103
+ description="Comma-separated tool list. Default is empty — "
104
+ "claude built-ins (Read/Edit/Bash/Glob/Grep/Write/"
105
+ "Skill/WebSearch/WebFetch) are intentionally NOT in "
106
+ "the allowlist; the agent only gets connected MCP "
107
+ "tools + MachinaOs's own MCP infrastructure tools.",
87
108
  )
88
- permission_mode: Literal["default", "acceptEdits", "plan", "auto", "dontAsk", "bypassPermissions"] = "acceptEdits"
109
+ permission_mode: Literal["default", "acceptEdits", "plan", "auto", "dontAsk", "bypassPermissions"] = "dontAsk"
89
110
 
90
111
  # ---- optional documented CLI flags (cli-reference) ----
91
112
  effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] = Field(
@@ -112,10 +133,9 @@ class ClaudeTaskSpec(BaseAICliTaskSpec):
112
133
 
113
134
  class CodexTaskSpec(BaseAICliTaskSpec):
114
135
  """OpenAI Codex CLI task. Sandbox-first; no session/resume/budget/turns."""
136
+
115
137
  provider: Literal["codex"] = "codex"
116
- sandbox: Literal["read-only", "workspace-write", "danger-full-access"] = (
117
- "workspace-write"
118
- )
138
+ sandbox: Literal["read-only", "workspace-write", "danger-full-access"] = "workspace-write"
119
139
  ask_for_approval: Literal["untrusted", "on-request", "never"] = "never"
120
140
 
121
141
 
@@ -125,6 +145,7 @@ class GeminiTaskSpec(BaseAICliTaskSpec):
125
145
  Schema lives in v1 so the discriminated union JSON Schema for the
126
146
  LLM tool fast-path doesn't change when v2 lands.
127
147
  """
148
+
128
149
  provider: Literal["gemini"] = "gemini"
129
150
  session_id: Optional[str] = None
130
151
  resume: Optional[str] = Field(
@@ -145,8 +166,10 @@ AICliTaskSpec = Annotated[
145
166
  # Result models (Pydantic for serialisation; mirror dataclasses in protocol.py)
146
167
  # ---------------------------------------------------------------------------
147
168
 
169
+
148
170
  class CanonicalUsagePydantic(BaseModel):
149
171
  """Pydantic mirror of `protocol.CanonicalUsage` for output serialisation."""
172
+
150
173
  input_tokens: int = 0
151
174
  output_tokens: int = 0
152
175
  cache_read: int = 0
@@ -157,6 +180,7 @@ class CanonicalUsagePydantic(BaseModel):
157
180
 
158
181
  class SessionResultModel(BaseModel):
159
182
  """Per-task result, JSON-serialisable."""
183
+
160
184
  task_id: str
161
185
  session_id: Optional[str] = None
162
186
  provider: str = ""
@@ -178,6 +202,7 @@ class SessionResultModel(BaseModel):
178
202
 
179
203
  class BatchSummary(BaseModel):
180
204
  """Aggregated batch summary."""
205
+
181
206
  n_tasks: int = 0
182
207
  n_succeeded: int = 0
183
208
  n_failed: int = 0
@@ -188,6 +213,7 @@ class BatchSummary(BaseModel):
188
213
 
189
214
  class BatchResultModel(BaseModel):
190
215
  """Top-level batch result returned by `run_batch()`."""
216
+
191
217
  tasks: List[SessionResultModel] = Field(default_factory=list)
192
218
  summary: BatchSummary = Field(default_factory=BatchSummary)
193
219
  provider: str = ""
@@ -198,6 +224,7 @@ class BatchResultModel(BaseModel):
198
224
  # Helpers
199
225
  # ---------------------------------------------------------------------------
200
226
 
227
+
201
228
  def session_result_to_model(sr: Any) -> SessionResultModel:
202
229
  """Convert a `protocol.SessionResult` dataclass to its Pydantic mirror."""
203
230
  cu = CanonicalUsagePydantic(
@@ -63,9 +63,9 @@ def expose_workflow_tools(connected_tools: List[Dict[str, Any]]) -> None:
63
63
  try:
64
64
  handler = _build_handler(node_type, cls.Params)
65
65
  mcp.add_tool(
66
- handler, name=node_type,
67
- description=(getattr(cls, "description", None)
68
- or f"MachinaOs workflow tool: {node_type}"),
66
+ handler,
67
+ name=node_type,
68
+ description=(getattr(cls, "description", None) or f"MachinaOs workflow tool: {node_type}"),
69
69
  )
70
70
  logger.info("[CC-Agent MCP] exposed mcp__machinaos__%s", node_type)
71
71
  except Exception as exc: # pragma: no cover
@@ -99,9 +99,11 @@ def unexpose_workflow_tools(connected_tools: List[Dict[str, Any]]) -> None:
99
99
  # Internals
100
100
  # ---------------------------------------------------------------------------
101
101
 
102
+
102
103
  def _get_mcp() -> Optional[Any]:
103
104
  """Late import to avoid a circular import with ``mcp_server``."""
104
105
  from services.cli_agent import mcp_server
106
+
105
107
  return mcp_server._mcp_singleton
106
108
 
107
109
 
@@ -130,10 +132,7 @@ def _schedule_list_changed_notify() -> None:
130
132
 
131
133
  async def _do_notify() -> None:
132
134
  try:
133
- session = (
134
- getattr(mcp, "session", None)
135
- or getattr(getattr(mcp, "_mcp_server", None), "session", None)
136
- )
135
+ session = getattr(mcp, "session", None) or getattr(getattr(mcp, "_mcp_server", None), "session", None)
137
136
  if session is not None and hasattr(session, "send_tool_list_changed"):
138
137
  await session.send_tool_list_changed()
139
138
  except Exception as exc:
@@ -168,13 +167,18 @@ def _build_handler(node_type: str, params_cls: type):
168
167
  default = None
169
168
  else:
170
169
  default = finfo.default
171
- parameters.append(inspect.Parameter(
172
- fname, inspect.Parameter.KEYWORD_ONLY,
173
- annotation=finfo.annotation, default=default,
174
- ))
170
+ parameters.append(
171
+ inspect.Parameter(
172
+ fname,
173
+ inspect.Parameter.KEYWORD_ONLY,
174
+ annotation=finfo.annotation,
175
+ default=default,
176
+ )
177
+ )
175
178
 
176
179
  async def _handler(**kwargs: Any) -> Dict[str, Any]:
177
180
  from services.cli_agent.mcp_server import _require_batch
181
+
178
182
  ctx = _require_batch()
179
183
  entry = next(
180
184
  (t for t in ctx.connected_tools if t.get("node_type") == node_type),
@@ -195,9 +199,13 @@ def _build_handler(node_type: str, params_cls: type):
195
199
  args = dict(kwargs)
196
200
  logger.info(
197
201
  "[CC-Agent MCP %s] node=%s wf=%s args_keys=%s",
198
- node_type, ctx.node_id, ctx.workflow_id, list(args.keys()),
202
+ node_type,
203
+ ctx.node_id,
204
+ ctx.workflow_id,
205
+ list(args.keys()),
199
206
  )
200
207
  from services.handlers.tools import execute_tool
208
+
201
209
  config: Dict[str, Any] = {
202
210
  "node_type": node_type,
203
211
  "node_id": entry.get("node_id"),
@@ -211,19 +219,24 @@ def _build_handler(node_type: str, params_cls: type):
211
219
  if "error" in result:
212
220
  logger.warning(
213
221
  "[CC-Agent MCP %s] node=%s ERROR: %s",
214
- node_type, entry.get("node_id"), result.get("error"),
222
+ node_type,
223
+ entry.get("node_id"),
224
+ result.get("error"),
215
225
  )
216
226
  else:
217
227
  logger.info(
218
228
  "[CC-Agent MCP %s] node=%s OK (result_keys=%s)",
219
- node_type, entry.get("node_id"), list(result.keys())[:8],
229
+ node_type,
230
+ entry.get("node_id"),
231
+ list(result.keys())[:8],
220
232
  )
221
233
  return result
222
234
 
223
235
  _handler.__name__ = node_type
224
236
  _handler.__annotations__ = annotations
225
237
  _handler.__signature__ = inspect.Signature( # type: ignore[attr-defined]
226
- parameters, return_annotation=Dict[str, Any],
238
+ parameters,
239
+ return_annotation=Dict[str, Any],
227
240
  )
228
241
  return _handler
229
242
 
@@ -39,13 +39,13 @@ def _extract_text_from_response(content) -> str:
39
39
  text_parts = []
40
40
  for block in content:
41
41
  if isinstance(block, dict):
42
- if block.get('type') == 'text' and block.get('text'):
43
- text_parts.append(block['text'])
44
- elif 'text' in block:
45
- text_parts.append(str(block['text']))
42
+ if block.get("type") == "text" and block.get("text"):
43
+ text_parts.append(block["text"])
44
+ elif "text" in block:
45
+ text_parts.append(str(block["text"]))
46
46
  elif isinstance(block, str):
47
47
  text_parts.append(block)
48
- return '\n'.join(text_parts)
48
+ return "\n".join(text_parts)
49
49
 
50
50
  # Handle string content
51
51
  if isinstance(content, str):
@@ -57,6 +57,7 @@ def _extract_text_from_response(content) -> str:
57
57
 
58
58
  class CompactionConfig(BaseModel):
59
59
  """Provider-agnostic compaction configuration."""
60
+
60
61
  enabled: bool = True
61
62
 
62
63
 
@@ -76,6 +77,7 @@ class CompactionService:
76
77
  """Per-user override from ``user_settings.compaction_ratio``, falling
77
78
  back to ``agent.compaction.ratio`` in ``llm_defaults.json``."""
78
79
  from services.model_registry import get_model_registry
80
+
79
81
  try:
80
82
  settings = await self._db.get_user_settings("default")
81
83
  if settings and "compaction_ratio" in settings:
@@ -95,6 +97,7 @@ class CompactionService:
95
97
  wins over the value returned here.
96
98
  """
97
99
  from services.model_registry import get_model_registry
100
+
98
101
  registry = get_model_registry()
99
102
  if ratio is None:
100
103
  ratio = float(registry.get_agent_defaults()["compaction"]["ratio"])
@@ -108,10 +111,7 @@ class CompactionService:
108
111
  if not threshold:
109
112
  ratio = await self._get_compaction_ratio()
110
113
  threshold = self.get_model_threshold(model, provider, ratio=ratio)
111
- return {
112
- "enabled": self._config.enabled,
113
- "context_token_threshold": threshold
114
- }
114
+ return {"enabled": self._config.enabled, "context_token_threshold": threshold}
115
115
 
116
116
  async def anthropic_api_config(self, threshold: Optional[int] = None, model: str = "", provider: str = "anthropic") -> Dict[str, Any]:
117
117
  """Anthropic Messages API context_management config."""
@@ -120,12 +120,7 @@ class CompactionService:
120
120
  threshold = self.get_model_threshold(model, provider, ratio=ratio)
121
121
  return {
122
122
  "betas": ["compact-2026-01-12"],
123
- "context_management": {
124
- "edits": [{
125
- "type": "compact_20260112",
126
- "trigger": {"type": "input_tokens", "value": threshold}
127
- }]
128
- }
123
+ "context_management": {"edits": [{"type": "compact_20260112", "trigger": {"type": "input_tokens", "value": threshold}}]},
129
124
  }
130
125
 
131
126
  async def openai_config(self, threshold: Optional[int] = None, model: str = "", provider: str = "openai") -> Dict[str, Any]:
@@ -146,35 +141,40 @@ class CompactionService:
146
141
  output_tokens=usage.get("output_tokens", 0),
147
142
  cache_read_tokens=usage.get("cache_read_tokens", 0),
148
143
  cache_creation_tokens=usage.get("cache_creation_tokens", 0),
149
- reasoning_tokens=usage.get("reasoning_tokens", 0)
144
+ reasoning_tokens=usage.get("reasoning_tokens", 0),
150
145
  )
151
146
 
152
147
  # Save token metric with cost fields
153
- await self._db.save_token_metric({
154
- "session_id": session_id,
155
- "node_id": node_id,
156
- "provider": provider,
157
- "model": model,
158
- **usage,
159
- "input_cost": cost["input_cost"],
160
- "output_cost": cost["output_cost"],
161
- "cache_cost": cost["cache_cost"],
162
- "total_cost": cost["total_cost"]
163
- })
148
+ await self._db.save_token_metric(
149
+ {
150
+ "session_id": session_id,
151
+ "node_id": node_id,
152
+ "provider": provider,
153
+ "model": model,
154
+ **usage,
155
+ "input_cost": cost["input_cost"],
156
+ "output_cost": cost["output_cost"],
157
+ "cache_cost": cost["cache_cost"],
158
+ "total_cost": cost["total_cost"],
159
+ }
160
+ )
164
161
 
165
162
  state = await self._db.get_or_create_session_token_state(session_id)
166
163
  new_total = state["cumulative_total"] + usage.get("total_tokens", 0)
167
164
  new_total_cost = state.get("cumulative_total_cost", 0.0) + cost["total_cost"]
168
165
 
169
166
  # Update cumulative state with cost
170
- await self._db.update_session_token_state(session_id, {
171
- "cumulative_input_tokens": state["cumulative_input_tokens"] + usage.get("input_tokens", 0),
172
- "cumulative_output_tokens": state["cumulative_output_tokens"] + usage.get("output_tokens", 0),
173
- "cumulative_total": new_total,
174
- "cumulative_input_cost": state.get("cumulative_input_cost", 0.0) + cost["input_cost"],
175
- "cumulative_output_cost": state.get("cumulative_output_cost", 0.0) + cost["output_cost"],
176
- "cumulative_total_cost": new_total_cost
177
- })
167
+ await self._db.update_session_token_state(
168
+ session_id,
169
+ {
170
+ "cumulative_input_tokens": state["cumulative_input_tokens"] + usage.get("input_tokens", 0),
171
+ "cumulative_output_tokens": state["cumulative_output_tokens"] + usage.get("output_tokens", 0),
172
+ "cumulative_total": new_total,
173
+ "cumulative_input_cost": state.get("cumulative_input_cost", 0.0) + cost["input_cost"],
174
+ "cumulative_output_cost": state.get("cumulative_output_cost", 0.0) + cost["output_cost"],
175
+ "cumulative_total_cost": new_total_cost,
176
+ },
177
+ )
178
178
 
179
179
  # Priority: per-session custom > model-aware (with user ratio) > global default
180
180
  custom = state.get("custom_threshold")
@@ -186,6 +186,7 @@ class CompactionService:
186
186
 
187
187
  # Get the model's full context window size for frontend display
188
188
  from services.model_registry import get_model_registry
189
+
189
190
  registry = get_model_registry()
190
191
  context_length = registry.get_context_length(model, provider)
191
192
 
@@ -195,22 +196,35 @@ class CompactionService:
195
196
  "cost": cost,
196
197
  "threshold": threshold,
197
198
  "context_length": context_length,
198
- "needs_compaction": self._config.enabled and new_total >= threshold
199
+ "needs_compaction": self._config.enabled and new_total >= threshold,
199
200
  }
200
201
 
201
- async def record(self, session_id: str, node_id: str, provider: str, model: str, tokens_before: int, tokens_after: int, summary: Optional[str] = None) -> None:
202
+ async def record(
203
+ self, session_id: str, node_id: str, provider: str, model: str, tokens_before: int, tokens_after: int, summary: Optional[str] = None
204
+ ) -> None:
202
205
  """Record compaction event after native API handles it."""
203
206
  state = await self._db.get_or_create_session_token_state(session_id)
204
- await self._db.save_compaction_event({
205
- "session_id": session_id, "node_id": node_id, "trigger_reason": "native",
206
- "tokens_before": tokens_before, "tokens_after": tokens_after,
207
- "summary_model": model, "summary_provider": provider, "success": True, "summary_content": summary
208
- })
209
- await self._db.update_session_token_state(session_id, {
210
- "cumulative_total": tokens_after,
211
- "last_compaction_at": datetime.now(timezone.utc),
212
- "compaction_count": state["compaction_count"] + 1
213
- })
207
+ await self._db.save_compaction_event(
208
+ {
209
+ "session_id": session_id,
210
+ "node_id": node_id,
211
+ "trigger_reason": "native",
212
+ "tokens_before": tokens_before,
213
+ "tokens_after": tokens_after,
214
+ "summary_model": model,
215
+ "summary_provider": provider,
216
+ "success": True,
217
+ "summary_content": summary,
218
+ }
219
+ )
220
+ await self._db.update_session_token_state(
221
+ session_id,
222
+ {
223
+ "cumulative_total": tokens_after,
224
+ "last_compaction_at": datetime.now(timezone.utc),
225
+ "compaction_count": state["compaction_count"] + 1,
226
+ },
227
+ )
214
228
 
215
229
  async def stats(self, session_id: str, model: str = "", provider: str = "") -> Dict[str, Any]:
216
230
  """Get session statistics.
@@ -229,6 +243,7 @@ class CompactionService:
229
243
  context_length = 0
230
244
  if model and provider:
231
245
  from services.model_registry import get_model_registry
246
+
232
247
  registry = get_model_registry()
233
248
  context_length = registry.get_context_length(model, provider)
234
249
 
@@ -299,17 +314,16 @@ Provide a concise but complete summary."""
299
314
 
300
315
  # Use a reasonable summary size: min(4096, model's max output)
301
316
  from services.model_registry import get_model_registry
317
+
302
318
  model_max = get_model_registry().get_max_output_tokens(model, provider)
303
319
  summary_tokens = min(4096, model_max)
304
320
 
305
- llm = self._ai_service.create_model(
306
- provider=provider, api_key=api_key, model=model,
307
- temperature=0.3, max_tokens=summary_tokens
308
- )
321
+ llm = self._ai_service.create_model(provider=provider, api_key=api_key, model=model, temperature=0.3, max_tokens=summary_tokens)
309
322
 
310
323
  from langchain_core.messages import HumanMessage
324
+
311
325
  response = await llm.ainvoke([HumanMessage(content=prompt)])
312
- raw_content = response.content if hasattr(response, 'content') else str(response)
326
+ raw_content = response.content if hasattr(response, "content") else str(response)
313
327
  summary = _extract_text_from_response(raw_content)
314
328
 
315
329
  new_memory = f"# Conversation Summary (Compacted)\n*Generated: {datetime.now(timezone.utc).isoformat()}*\n\n{summary}"
@@ -326,9 +340,11 @@ Provide a concise but complete summary."""
326
340
 
327
341
  _service: Optional[CompactionService] = None
328
342
 
343
+
329
344
  def get_compaction_service() -> Optional[CompactionService]:
330
345
  return _service
331
346
 
347
+
332
348
  def init_compaction_service(database: "Database", settings: "Settings") -> CompactionService:
333
349
  global _service
334
350
  _service = CompactionService(database, settings)
@@ -64,13 +64,9 @@ class CredentialRegistry:
64
64
  with _CONFIG_PATH.open(encoding="utf-8") as f:
65
65
  self._raw = json.load(f)
66
66
  except FileNotFoundError as e:
67
- raise CredentialRegistryError(
68
- f"credential_providers.json not found at {_CONFIG_PATH}"
69
- ) from e
67
+ raise CredentialRegistryError(f"credential_providers.json not found at {_CONFIG_PATH}") from e
70
68
  except json.JSONDecodeError as e:
71
- raise CredentialRegistryError(
72
- f"credential_providers.json is not valid JSON: {e}"
73
- ) from e
69
+ raise CredentialRegistryError(f"credential_providers.json is not valid JSON: {e}") from e
74
70
  return self._raw
75
71
 
76
72
  def _resolve_all(self) -> Dict[str, Dict[str, Any]]:
@@ -98,13 +94,10 @@ class CredentialRegistry:
98
94
  """Walk the extends chain, deep-merge parent then child overrides."""
99
95
  if provider_id in visiting:
100
96
  raise CredentialRegistryError(
101
- f"extends cycle detected involving provider {provider_id!r}: "
102
- f"{' -> '.join(sorted(visiting))} -> {provider_id}"
97
+ f"extends cycle detected involving provider {provider_id!r}: " f"{' -> '.join(sorted(visiting))} -> {provider_id}"
103
98
  )
104
99
  if provider_id not in raw:
105
- raise CredentialRegistryError(
106
- f"provider {provider_id!r} referenced via extends but not defined"
107
- )
100
+ raise CredentialRegistryError(f"provider {provider_id!r} referenced via extends but not defined")
108
101
 
109
102
  entry = raw[provider_id]
110
103
  extends = entry.get("extends")
@@ -158,10 +151,7 @@ class CredentialRegistry:
158
151
  categories = raw.get("categories", {})
159
152
  if not isinstance(categories, dict):
160
153
  return []
161
- out = [
162
- {"key": key, "label": cfg.get("label", key), "order": cfg.get("order", 0)}
163
- for key, cfg in categories.items()
164
- ]
154
+ out = [{"key": key, "label": cfg.get("label", key), "order": cfg.get("order", 0)} for key, cfg in categories.items()]
165
155
  out.sort(key=lambda c: (c["order"], c["key"]))
166
156
  return out
167
157
 
@@ -238,11 +228,7 @@ def _deep_merge(parent: Dict[str, Any], child: Dict[str, Any]) -> Dict[str, Any]
238
228
  parent_value = result.get(key)
239
229
  if isinstance(parent_value, dict) and isinstance(child_value, dict):
240
230
  result[key] = _deep_merge(parent_value, child_value)
241
- elif (
242
- key in _MERGE_BY_KEY_ARRAYS
243
- and isinstance(parent_value, list)
244
- and isinstance(child_value, list)
245
- ):
231
+ elif key in _MERGE_BY_KEY_ARRAYS and isinstance(parent_value, list) and isinstance(child_value, list):
246
232
  result[key] = _merge_array_by_key(parent_value, child_value)
247
233
  else:
248
234
  result[key] = copy.deepcopy(child_value)
@@ -0,0 +1,18 @@
1
+ """Credential-management WS handlers — Wave 13.5 extraction.
2
+
3
+ Side-effect import registers the 4 credential CRUD handlers
4
+ (validate_api_key / get_stored_api_key / save_api_key / delete_api_key)
5
+ into ``ws_handler_registry``. The per-provider validation logic lives
6
+ in ``services/plugin/credential.py``'s ``CREDENTIAL_REGISTRY``; these
7
+ handlers just shape the request + response envelope around it.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from services.ws_handler_registry import register_ws_handlers as _register_ws_handlers
13
+
14
+ from .handlers import WS_HANDLERS as _CREDENTIALS_WS_HANDLERS
15
+
16
+ _register_ws_handlers(_CREDENTIALS_WS_HANDLERS)
17
+
18
+ __all__ = ["handlers"]