machinaos 0.0.76 → 0.0.78

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 (393) hide show
  1. package/README.md +143 -107
  2. package/client/dist/assets/ActionBar-Du2MSFSz.js +1 -0
  3. package/client/dist/assets/ApiKeyInput-k2LBmBjb.js +1 -0
  4. package/client/dist/assets/ApiKeyPanel-C_bV9U0X.js +1 -0
  5. package/client/dist/assets/ApiUsageSection-CmVfwZzL.js +1 -0
  6. package/client/dist/assets/EmailPanel-CeKIMGu-.js +1 -0
  7. package/client/dist/assets/OAuthPanel-KA3t3Q2K.js +1 -0
  8. package/client/dist/assets/QrPairingPanel-NgNpJNuk.js +1 -0
  9. package/client/dist/assets/RateLimitSection-Du5YNVIA.js +1 -0
  10. package/client/dist/assets/StatusCard-DNLyayXc.js +1 -0
  11. package/client/dist/assets/index-DQ0nwhec.js +257 -0
  12. package/client/dist/assets/index-DxmbVskS.css +1 -0
  13. package/client/dist/assets/vendor-flow-CZmBvHRo.js +1 -0
  14. package/client/dist/assets/vendor-icons-CVrPjN2Q.js +22 -0
  15. package/client/dist/assets/vendor-markdown-CRou3yQ5.js +62 -0
  16. package/client/dist/assets/vendor-misc-C4VxKHs5.js +1 -0
  17. package/client/dist/assets/vendor-query-SzWcOU0G.js +1 -0
  18. package/client/dist/assets/vendor-radix-Dnos29jG.js +56 -0
  19. package/client/dist/assets/vendor-react-DvWIbVx0.js +1 -0
  20. package/client/dist/index.html +37 -3
  21. package/client/index.html +28 -1
  22. package/client/package.json +44 -40
  23. package/client/src/App.tsx +2 -0
  24. package/client/src/Dashboard.tsx +157 -45
  25. package/client/src/ParameterPanel.tsx +3 -5
  26. package/client/src/adapters/nodeSpecToDescription.ts +1 -0
  27. package/client/src/assets/icons/NodeIcon.tsx +32 -0
  28. package/client/src/assets/icons/index.ts +4 -0
  29. package/client/src/assets/icons/stripe.svg +1 -0
  30. package/client/src/assets/icons/themedGlyphs.ts +404 -0
  31. package/client/src/components/AIAgentNode.tsx +77 -53
  32. package/client/src/components/GenericNode.tsx +34 -52
  33. package/client/src/components/OutputPanel.tsx +64 -147
  34. package/client/src/components/ParameterRenderer.tsx +5 -3
  35. package/client/src/components/SkillEditorModal.tsx +9 -18
  36. package/client/src/components/SquareNode.tsx +97 -115
  37. package/client/src/components/StartNode.tsx +32 -42
  38. package/client/src/components/SvgFilterDefs.tsx +54 -0
  39. package/client/src/components/TeamMonitorNode.tsx +12 -14
  40. package/client/src/components/ToolkitNode.tsx +35 -60
  41. package/client/src/components/TriggerNode.tsx +43 -77
  42. package/client/src/components/__tests__/CredentialsModal.test.tsx +49 -45
  43. package/client/src/components/credentials/CredentialsModal.tsx +98 -30
  44. package/client/src/components/credentials/CredentialsPalette.tsx +73 -5
  45. package/client/src/components/credentials/catalogueAdapter.ts +17 -1
  46. package/client/src/components/credentials/panels/ApiKeyPanel.tsx +102 -37
  47. package/client/src/components/credentials/panels/EmailPanel.tsx +7 -19
  48. package/client/src/components/credentials/panels/OAuthPanel.tsx +5 -1
  49. package/client/src/components/credentials/panels/QrPairingPanel.tsx +1 -3
  50. package/client/src/components/credentials/primitives/ActionBar.tsx +7 -11
  51. package/client/src/components/credentials/primitives/OAuthConnect.tsx +19 -28
  52. package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +24 -3
  53. package/client/src/components/credentials/types.ts +12 -2
  54. package/client/src/components/credentials/useCredentialPanel.ts +43 -19
  55. package/client/src/components/icons/AIProviderIcons.tsx +16 -0
  56. package/client/src/components/onboarding/OnboardingWizard.tsx +23 -63
  57. package/client/src/components/onboarding/nodeRoleClasses.ts +23 -0
  58. package/client/src/components/onboarding/steps/CanvasStep.tsx +15 -21
  59. package/client/src/components/onboarding/steps/ConceptsStep.tsx +2 -11
  60. package/client/src/components/onboarding/steps/GetStartedStep.tsx +2 -10
  61. package/client/src/components/parameterPanel/InputSection.tsx +9 -7
  62. package/client/src/components/parameterPanel/MasterSkillEditor.tsx +84 -198
  63. package/client/src/components/parameterPanel/MiddleSection.tsx +57 -80
  64. package/client/src/components/parameterPanel/ToolSchemaEditor.tsx +31 -25
  65. package/client/src/components/parameterPanel/__tests__/InputSection.test.tsx +7 -2
  66. package/client/src/components/ui/AIResultModal.tsx +1 -1
  67. package/client/src/components/ui/CollapsibleSection.tsx +9 -5
  68. package/client/src/components/ui/CommandPalette.tsx +147 -0
  69. package/client/src/components/ui/CommandPaletteHost.tsx +189 -0
  70. package/client/src/components/ui/ComponentItem.tsx +13 -7
  71. package/client/src/components/ui/ComponentPalette.tsx +24 -13
  72. package/client/src/components/ui/ConsolePanel.tsx +19 -11
  73. package/client/src/components/ui/DropCap.tsx +28 -0
  74. package/client/src/components/ui/EditableNodeLabel.tsx +10 -2
  75. package/client/src/components/ui/InputNodesPanel.tsx +1 -1
  76. package/client/src/components/ui/Modal.tsx +38 -6
  77. package/client/src/components/ui/OutputDisplayPanel.tsx +1 -1
  78. package/client/src/components/ui/SettingsPanel.tsx +42 -13
  79. package/client/src/components/ui/StatusBar.tsx +108 -0
  80. package/client/src/components/ui/ThemeSwitcher.tsx +109 -0
  81. package/client/src/components/ui/TopToolbar.tsx +42 -25
  82. package/client/src/components/ui/WorkflowSidebar.tsx +32 -16
  83. package/client/src/components/ui/action-button.tsx +40 -15
  84. package/client/src/components/ui/button.tsx +24 -1
  85. package/client/src/components/ui/dropdown-menu.tsx +24 -2
  86. package/client/src/components/ui/input.tsx +19 -2
  87. package/client/src/components/ui/select.tsx +15 -0
  88. package/client/src/components/ui/textarea.tsx +15 -2
  89. package/client/src/contexts/AuthContext.tsx +148 -109
  90. package/client/src/contexts/ThemeContext.tsx +93 -17
  91. package/client/src/contexts/WebSocketContext.tsx +373 -206
  92. package/client/src/contexts/__tests__/AuthContext.test.tsx +221 -0
  93. package/client/src/hooks/__tests__/useDragVariable.test.ts +7 -1
  94. package/client/src/hooks/__tests__/useWorkflowOpsListener.test.ts +142 -0
  95. package/client/src/hooks/useAppTheme.ts +209 -7
  96. package/client/src/hooks/useAutoSkillEdges.ts +7 -2
  97. package/client/src/hooks/useCatalogueQuery.ts +67 -1
  98. package/client/src/hooks/useDragVariable.ts +1 -1
  99. package/client/src/hooks/useNodeAllowlist.ts +115 -8
  100. package/client/src/hooks/useOnboarding.ts +20 -8
  101. package/client/src/hooks/useParameterPanel.ts +2 -1
  102. package/client/src/hooks/useReactFlowNodes.ts +2 -1
  103. package/client/src/hooks/useSound.ts +185 -0
  104. package/client/src/hooks/useWorkflowManagement.ts +6 -8
  105. package/client/src/hooks/useWorkflowOpsListener.ts +90 -0
  106. package/client/src/index.css +65 -3
  107. package/client/src/lib/__tests__/connectionConfig.test.ts +91 -0
  108. package/client/src/lib/aiModelProviders.ts +8 -0
  109. package/client/src/lib/connectionConfig.ts +107 -0
  110. package/client/src/lib/queryPersist.ts +13 -5
  111. package/client/src/lib/sound.ts +393 -0
  112. package/client/src/main.tsx +20 -0
  113. package/client/src/store/useAppStore.ts +26 -0
  114. package/client/src/styles/canvasAnimations.ts +37 -36
  115. package/client/src/styles/theme.ts +36 -20
  116. package/client/src/test/setup.ts +1 -0
  117. package/client/src/themes/atomic.css +253 -0
  118. package/client/src/themes/base.css +373 -0
  119. package/client/src/themes/cyber.css +890 -0
  120. package/client/src/themes/dark.css +70 -0
  121. package/client/src/themes/edo.css +246 -0
  122. package/client/src/themes/greek.css +293 -0
  123. package/client/src/themes/light.css +78 -0
  124. package/client/src/themes/plague.css +253 -0
  125. package/client/src/themes/renaissance.css +727 -0
  126. package/client/src/themes/rot.css +249 -0
  127. package/client/src/themes/steampunk.css +272 -0
  128. package/client/src/themes/surveillance.css +289 -0
  129. package/client/src/themes/wasteland.css +250 -0
  130. package/client/src/types/INodeProperties.ts +5 -0
  131. package/client/src/types/NodeTypes.ts +11 -1
  132. package/client/src/types/__tests__/cloudEvents.test.ts +99 -0
  133. package/client/src/types/cloudEvents.ts +78 -0
  134. package/client/src/vite-env.d.ts +7 -0
  135. package/client/tsconfig.json +1 -1
  136. package/client/vite.config.js +62 -2
  137. package/install.ps1 +1 -1
  138. package/install.sh +1 -1
  139. package/machina/commands/build.py +51 -7
  140. package/machina/pyproject.toml +4 -0
  141. package/machina/supervisor.py +12 -2
  142. package/machina/tree.py +71 -21
  143. package/package.json +4 -4
  144. package/scripts/install.js +16 -1
  145. package/server/config/ai_cli_providers.json +54 -0
  146. package/server/config/credential_providers.json +109 -2
  147. package/server/config/llm_defaults.json +24 -0
  148. package/server/config/model_registry.json +338 -499
  149. package/server/config/node_allowlist.json +16 -1
  150. package/server/config/pricing.json +8 -0
  151. package/server/constants.py +38 -15
  152. package/server/core/container.py +2 -2
  153. package/server/core/credentials_database.py +35 -2
  154. package/server/core/logging.py +4 -3
  155. package/server/main.py +99 -13
  156. package/server/models/node_metadata.py +1 -0
  157. package/server/nodejs/package.json +8 -6
  158. package/server/nodejs/src/index.ts +22 -5
  159. package/server/nodes/README.md +31 -4
  160. package/server/nodes/agent/_inline.py +2 -0
  161. package/server/nodes/agent/_specialized.py +6 -3
  162. package/server/nodes/agent/ai_agent.py +13 -3
  163. package/server/nodes/agent/chat_agent.py +6 -3
  164. package/server/nodes/agent/claude_code_agent.py +287 -75
  165. package/server/nodes/agent/codex_agent.py +239 -0
  166. package/server/nodes/agent/deep_agent.py +3 -3
  167. package/server/nodes/agent/rlm_agent.py +3 -3
  168. package/server/nodes/android/__init__.py +31 -1
  169. package/server/nodes/android/_base.py +9 -5
  170. package/server/{services/android_service.py → nodes/android/_dispatcher.py} +2 -2
  171. package/server/nodes/android/_handlers.py +154 -0
  172. package/server/nodes/android/_option_loaders.py +44 -0
  173. package/server/nodes/android/_refresh.py +127 -0
  174. package/server/{services/android → nodes/android/_relay}/client.py +4 -4
  175. package/server/{routers/android.py → nodes/android/_router.py} +27 -8
  176. package/server/nodes/browser/browser.py +2 -2
  177. package/server/nodes/code/_base.py +6 -2
  178. package/server/nodes/code/_claude_code.py +134 -0
  179. package/server/nodes/document/embedding_generator.py +3 -3
  180. package/server/nodes/document/http_scraper.py +3 -3
  181. package/server/nodes/document/vector_store.py +5 -5
  182. package/server/nodes/email/__init__.py +11 -1
  183. package/server/nodes/email/_filters.py +21 -0
  184. package/server/{services/himalaya_service.py → nodes/email/_himalaya.py} +6 -10
  185. package/server/{services/email_service.py → nodes/email/_service.py} +9 -13
  186. package/server/nodes/email/email_read.py +1 -1
  187. package/server/nodes/email/email_receive.py +54 -5
  188. package/server/nodes/email/email_send.py +1 -1
  189. package/server/nodes/filesystem/shell.py +24 -1
  190. package/server/nodes/google/__init__.py +55 -1
  191. package/server/{services/handlers/google_auth.py → nodes/google/_auth_helper.py} +8 -5
  192. package/server/nodes/google/_base.py +2 -2
  193. package/server/nodes/google/_credentials.py +5 -5
  194. package/server/nodes/google/_filters.py +25 -0
  195. package/server/nodes/google/_handlers.py +57 -0
  196. package/server/{services/google_oauth.py → nodes/google/_oauth.py} +195 -162
  197. package/server/nodes/google/_option_loaders.py +107 -0
  198. package/server/nodes/google/_refresh.py +66 -0
  199. package/server/nodes/google/_router.py +131 -0
  200. package/server/nodes/google/gmail_receive.py +41 -4
  201. package/server/nodes/groups.py +1 -0
  202. package/server/nodes/location/_credentials.py +45 -1
  203. package/server/{services/maps.py → nodes/location/_service.py} +18 -3
  204. package/server/nodes/location/gmaps_create.py +4 -4
  205. package/server/nodes/location/gmaps_locations.py +4 -4
  206. package/server/nodes/location/gmaps_nearby_places.py +4 -4
  207. package/server/nodes/model/_base.py +8 -3
  208. package/server/nodes/model/_credentials.py +96 -8
  209. package/server/nodes/model/_local_validator.py +345 -0
  210. package/server/nodes/model/lmstudio_chat_model.py +23 -0
  211. package/server/nodes/model/ollama_chat_model.py +25 -0
  212. package/server/nodes/proxy/_usage.py +2 -2
  213. package/server/nodes/proxy/proxy_config.py +14 -14
  214. package/server/nodes/proxy/proxy_request.py +4 -4
  215. package/server/nodes/scraper/_credentials.py +29 -1
  216. package/server/nodes/scraper/apify_actor.py +9 -9
  217. package/server/nodes/scraper/crawlee_scraper.py +5 -5
  218. package/server/nodes/search/brave_search.py +4 -0
  219. package/server/nodes/search/perplexity_search.py +9 -0
  220. package/server/nodes/search/serper_search.py +3 -0
  221. package/server/nodes/skill/simple_memory.py +12 -0
  222. package/server/nodes/social/_base.py +2 -2
  223. package/server/nodes/stripe/__init__.py +46 -0
  224. package/server/nodes/stripe/_credentials.py +33 -0
  225. package/server/nodes/stripe/_handlers.py +270 -0
  226. package/server/nodes/stripe/_install.py +127 -0
  227. package/server/nodes/stripe/_source.py +174 -0
  228. package/server/nodes/stripe/stripe_action.py +81 -0
  229. package/server/nodes/stripe/stripe_receive.py +92 -0
  230. package/server/nodes/telegram/_credentials.py +52 -1
  231. package/server/nodes/telegram/_handlers.py +19 -18
  232. package/server/nodes/telegram/_service.py +134 -32
  233. package/server/nodes/telegram/telegram_send.py +5 -6
  234. package/server/nodes/text/file_handler.py +2 -2
  235. package/server/nodes/text/text_generator.py +2 -2
  236. package/server/nodes/tool/agent_builder.py +630 -0
  237. package/server/nodes/tool/task_manager.py +144 -2
  238. package/server/nodes/twitter/__init__.py +38 -1
  239. package/server/nodes/twitter/_base.py +7 -7
  240. package/server/nodes/twitter/_credentials.py +1 -1
  241. package/server/nodes/twitter/_filters.py +37 -0
  242. package/server/nodes/twitter/_handlers.py +77 -0
  243. package/server/nodes/twitter/_oauth.py +124 -0
  244. package/server/nodes/twitter/_refresh.py +78 -0
  245. package/server/nodes/twitter/_router.py +29 -0
  246. package/server/nodes/twitter/twitter_receive.py +4 -0
  247. package/server/nodes/visuals.json +64 -19
  248. package/server/nodes/whatsapp/__init__.py +45 -5
  249. package/server/nodes/whatsapp/_base.py +3 -3
  250. package/server/nodes/whatsapp/_filters.py +137 -0
  251. package/server/nodes/whatsapp/_handlers.py +167 -0
  252. package/server/nodes/whatsapp/_option_loaders.py +68 -0
  253. package/server/nodes/whatsapp/_refresh.py +62 -0
  254. package/server/nodes/whatsapp/_runtime.py +1 -1
  255. package/server/pyproject.toml +29 -7
  256. package/server/routers/schemas.py +2 -2
  257. package/server/routers/webhook.py +26 -9
  258. package/server/routers/websocket.py +149 -810
  259. package/server/services/ai.py +89 -8
  260. package/server/services/auth.py +220 -43
  261. package/server/services/claude_oauth.py +126 -100
  262. package/server/services/cli_agent/__init__.py +78 -0
  263. package/server/services/cli_agent/_handlers.py +237 -0
  264. package/server/services/cli_agent/config.py +112 -0
  265. package/server/services/cli_agent/factory.py +48 -0
  266. package/server/services/cli_agent/lockfile.py +141 -0
  267. package/server/services/cli_agent/mcp_server.py +482 -0
  268. package/server/services/cli_agent/protocol.py +173 -0
  269. package/server/services/cli_agent/providers/__init__.py +9 -0
  270. package/server/services/cli_agent/providers/anthropic_claude.py +419 -0
  271. package/server/services/cli_agent/providers/google_gemini.py +80 -0
  272. package/server/services/cli_agent/providers/openai_codex.py +310 -0
  273. package/server/services/cli_agent/service.py +607 -0
  274. package/server/services/cli_agent/session.py +618 -0
  275. package/server/services/cli_agent/types.py +227 -0
  276. package/server/services/cli_agent/workflow_tools.py +233 -0
  277. package/server/services/credential_registry.py +26 -1
  278. package/server/services/deployment/manager.py +26 -145
  279. package/server/services/deployment/poll_registry.py +59 -0
  280. package/server/services/event_waiter.py +76 -246
  281. package/server/services/events/__init__.py +54 -0
  282. package/server/services/events/cli.py +78 -0
  283. package/server/services/events/daemon.py +163 -0
  284. package/server/services/events/envelope.py +281 -0
  285. package/server/services/events/lifecycle.py +99 -0
  286. package/server/services/events/oauth_lifecycle.py +534 -0
  287. package/server/services/events/polling.py +60 -0
  288. package/server/services/events/push.py +36 -0
  289. package/server/services/events/source.py +63 -0
  290. package/server/services/events/triggers.py +118 -0
  291. package/server/services/events/verifiers/__init__.py +25 -0
  292. package/server/services/events/verifiers/base.py +28 -0
  293. package/server/services/events/verifiers/github.py +25 -0
  294. package/server/services/events/verifiers/hmac_basic.py +32 -0
  295. package/server/services/events/verifiers/standard_webhooks.py +47 -0
  296. package/server/services/events/verifiers/stripe.py +42 -0
  297. package/server/services/events/webhook.py +105 -0
  298. package/server/services/handlers/tools.py +28 -186
  299. package/server/services/llm/config.py +7 -0
  300. package/server/services/llm/factory.py +8 -2
  301. package/server/services/memory/__init__.py +52 -0
  302. package/server/services/memory/jsonl.py +80 -0
  303. package/server/services/memory/markdown.py +65 -0
  304. package/server/services/memory/state.py +112 -0
  305. package/server/services/memory/vector_store.py +40 -0
  306. package/server/services/model_registry.py +76 -0
  307. package/server/services/node_allowlist.py +71 -15
  308. package/server/services/node_executor.py +2 -2
  309. package/server/services/node_output_schemas.py +21 -10
  310. package/server/services/node_spec.py +1 -1
  311. package/server/services/oauth_utils.py +1 -1
  312. package/server/services/plugin/__init__.py +2 -0
  313. package/server/services/plugin/base.py +44 -2
  314. package/server/services/plugin/credential.py +288 -1
  315. package/server/services/plugin/deps.py +105 -0
  316. package/server/services/plugin/edge_walker.py +12 -4
  317. package/server/services/plugin/oauth.py +381 -0
  318. package/server/services/plugin/polling.py +247 -0
  319. package/server/services/plugin/registry.py +145 -0
  320. package/server/services/plugin/singleton.py +65 -0
  321. package/server/services/plugin/ws.py +81 -0
  322. package/server/services/process_service.py +31 -2
  323. package/server/services/status_broadcaster.py +155 -238
  324. package/server/services/temporal/workflow.py +7 -7
  325. package/server/services/workflow.py +21 -3
  326. package/server/services/ws_handler_registry.py +111 -28
  327. package/server/skills/GUIDE.md +16 -1
  328. package/server/skills/assistant/agent-builder-skill/SKILL.md +166 -0
  329. package/server/skills/payments_agent/stripe-skill/SKILL.md +306 -0
  330. package/server/tests/credentials/test_auth_service.py +16 -9
  331. package/server/tests/credentials/test_credential_broadcasts.py +219 -0
  332. package/server/tests/credentials/test_google_oauth.py +6 -6
  333. package/server/tests/credentials/test_oauth_utils.py +1 -1
  334. package/server/tests/credentials/test_twitter_oauth.py +2 -2
  335. package/server/tests/credentials/test_websocket_handlers.py +44 -20
  336. package/server/tests/llm/test_factory.py +1 -0
  337. package/server/tests/llm/test_wiring.py +5 -1
  338. package/server/tests/nodes/_compat.py +24 -24
  339. package/server/tests/nodes/test_agent_builder.py +439 -0
  340. package/server/tests/nodes/test_ai_tools.py +18 -14
  341. package/server/tests/nodes/test_code_fs_process.py +17 -8
  342. package/server/tests/nodes/test_email.py +10 -9
  343. package/server/tests/nodes/test_google_workspace.py +2 -2
  344. package/server/tests/nodes/test_specialized_agents.py +100 -53
  345. package/server/tests/nodes/test_stripe_plugin.py +293 -0
  346. package/server/tests/nodes/test_telegram_social.py +4 -4
  347. package/server/tests/nodes/test_twitter.py +1 -1
  348. package/server/tests/nodes/test_web_automation.py +2 -2
  349. package/server/tests/nodes/test_whatsapp.py +9 -9
  350. package/server/tests/services/cli_agent/__init__.py +0 -0
  351. package/server/tests/services/cli_agent/test_mcp_server.py +432 -0
  352. package/server/tests/services/cli_agent/test_providers.py +358 -0
  353. package/server/tests/services/cli_agent/test_service.py +298 -0
  354. package/server/tests/services/memory/__init__.py +0 -0
  355. package/server/tests/services/memory/test_jsonl.py +188 -0
  356. package/server/tests/services/test_events.py +333 -0
  357. package/server/tests/test_node_spec.py +56 -16
  358. package/server/tests/test_plugin_helpers.py +116 -0
  359. package/server/tests/test_plugin_self_containment.py +486 -0
  360. package/server/tests/test_status_broadcasts.py +425 -0
  361. package/workflows/{AI Assistant_workflow-1777421105154-0m4snkzjf.json → AI Assistant_workflow-1778504793388-ou1m1tz2x.json } +70 -266
  362. package/workflows/{AI Employee_workflow-1777720598005-u4cm858dv.json → AI Employee_example_workflow-1777720598005-u4cm858dv.json } +112 -112
  363. package/workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json +709 -0
  364. package/client/dist/assets/ActionBar-vzPpSR77.js +0 -1
  365. package/client/dist/assets/ApiKeyInput-Ds7AKFe8.js +0 -1
  366. package/client/dist/assets/ApiKeyPanel-gfblELep.js +0 -1
  367. package/client/dist/assets/ApiUsageSection-BMNWTe2r.js +0 -1
  368. package/client/dist/assets/EmailPanel-B1Om64p5.js +0 -1
  369. package/client/dist/assets/OAuthPanel-CXyQYGBz.js +0 -1
  370. package/client/dist/assets/QrPairingPanel-BgNuI1we.js +0 -1
  371. package/client/dist/assets/RateLimitSection-YYK8sx1T.js +0 -1
  372. package/client/dist/assets/StatusCard-DuYA5hJR.js +0 -1
  373. package/client/dist/assets/index-D9tZfgvi.js +0 -363
  374. package/client/dist/assets/index-al7snTkG.css +0 -1
  375. package/client/src/components/credentials/providers.tsx +0 -177
  376. package/server/routers/google.py +0 -277
  377. package/server/routers/maps.py +0 -142
  378. package/server/routers/twitter.py +0 -365
  379. package/server/services/claude_code_service.py +0 -106
  380. package/server/services/memory.py +0 -159
  381. package/server/services/node_option_loaders/__init__.py +0 -77
  382. package/server/services/node_option_loaders/android_loaders.py +0 -55
  383. package/server/services/node_option_loaders/google_loaders.py +0 -97
  384. package/server/services/node_option_loaders/whatsapp_loaders.py +0 -69
  385. package/server/services/twitter_oauth.py +0 -411
  386. package/server/services/websocket_client.py +0 -29
  387. /package/server/{services/android → nodes/android/_relay}/__init__.py +0 -0
  388. /package/server/{services/android → nodes/android/_relay}/broadcaster.py +0 -0
  389. /package/server/{services/android → nodes/android/_relay}/manager.py +0 -0
  390. /package/server/{services/android → nodes/android/_relay}/protocol.py +0 -0
  391. /package/server/{services/browser_service.py → nodes/browser/_service.py} +0 -0
  392. /package/server/{services/whatsapp_service.py → nodes/whatsapp/_service.py} +0 -0
  393. /package/server/skills/{task_agent → assistant}/write-todos-skill/SKILL.md +0 -0
@@ -0,0 +1,419 @@
1
+ """Anthropic Claude Code CLI provider.
2
+
3
+ Reference implementation for the `AICliProvider` Protocol. Full feature
4
+ set: sessions, resume, budget, turns, allowed_tools, permission_mode,
5
+ MCP lockfile, cost-in-JSON.
6
+
7
+ Subprocess: ``claude -p <prompt> --output-format stream-json --verbose
8
+ --include-partial-messages --include-hook-events --ide
9
+ [--session-id|--resume <UUID>] --model ... --max-turns ...
10
+ --max-budget-usd ... --allowedTools ... --permission-mode ...
11
+ --append-system-prompt ... [--effort ...] [--fallback-model ...]
12
+ [--add-dir ...] [--disallowedTools ...] [--agent ...]``
13
+
14
+ Binary + auth: shared with the auth surface via
15
+ ``services.claude_oauth.claude_binary_path()`` — single project-local
16
+ install at ``<repo>/data/claude-machina/npm/`` and ``CLAUDE_CONFIG_DIR``
17
+ set on the spawn env so the agent picks up the same credentials the
18
+ Login button wrote.
19
+
20
+ Final event: ``type == "result"`` carries ``total_cost_usd``,
21
+ ``duration_ms``, ``num_turns``, ``session_id``, and the assistant's
22
+ ``result`` string.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import json
28
+ from pathlib import Path
29
+ from typing import Any, Dict, List, Optional
30
+
31
+ from core.logging import get_logger
32
+
33
+ from services.claude_oauth import claude_binary_path
34
+ from services.cli_agent.config import get_provider_config
35
+ from services.cli_agent.protocol import CanonicalUsage
36
+ from services.cli_agent.types import ClaudeTaskSpec
37
+
38
+ logger = get_logger(__name__)
39
+
40
+ NAME = "claude"
41
+
42
+
43
+ class AnthropicClaudeProvider:
44
+ """`AICliProvider` for Anthropic's Claude Code CLI."""
45
+
46
+ def __init__(self) -> None:
47
+ cfg = get_provider_config(NAME)
48
+ if cfg is None:
49
+ raise RuntimeError(
50
+ f"Provider config missing for {NAME!r}. Check ai_cli_providers.json."
51
+ )
52
+ self.name = NAME
53
+ self.package_name = cfg.package_name
54
+ self.binary_name = cfg.binary_name
55
+ self.ide_lock_env_var = cfg.ide_lock_env_var
56
+ self.ide_lockfile_dir = cfg.ide_lockfile_dir
57
+ self._defaults = cfg.defaults
58
+ self._supports = cfg.supports
59
+ self._login_argv = cfg.login_argv
60
+ self._auth_status_argv = cfg.auth_status_argv
61
+
62
+ # ---- spawn surface ---------------------------------------------------
63
+
64
+ def binary_path(self) -> Path:
65
+ """Resolve the project-local `claude` binary.
66
+
67
+ Delegates to ``services.claude_oauth.claude_binary_path`` — same
68
+ path used by the credentials Login button. Lazy-installs into
69
+ ``<repo>/data/claude-machina/npm/`` on first miss. Raises
70
+ ``FileNotFoundError`` if ``npm`` isn't on PATH.
71
+ """
72
+ return Path(claude_binary_path())
73
+
74
+ def headless_argv(
75
+ self,
76
+ task: Any, # ClaudeTaskSpec
77
+ *,
78
+ defaults: Dict[str, Any],
79
+ mcp_endpoint_url: Optional[str] = None,
80
+ mcp_bearer_token: Optional[str] = None,
81
+ connected_tool_names: Optional[List[str]] = None,
82
+ ) -> List[str]:
83
+ """Build the full argv (binary + flags) for one task.
84
+
85
+ ``mcp_endpoint_url`` + ``mcp_bearer_token`` (if both set) are
86
+ emitted as a ``--mcp-config <json>`` block so the spawned
87
+ ``claude -p`` registers MachinaOs's MCP server. The ``--ide`` /
88
+ lockfile path is for interactive IDE-host scenarios; in headless
89
+ mode the documented mechanism is ``--mcp-config`` (see
90
+ https://code.claude.com/docs/en/mcp)."""
91
+ if not isinstance(task, ClaudeTaskSpec):
92
+ raise TypeError(
93
+ "AnthropicClaudeProvider.headless_argv requires ClaudeTaskSpec, "
94
+ f"got {type(task).__name__}"
95
+ )
96
+
97
+ argv: List[str] = [str(self.binary_path())]
98
+
99
+ argv += [
100
+ "-p", task.prompt,
101
+ "--output-format", "stream-json",
102
+ "--verbose", # required by Claude CLI when using stream-json with --print
103
+ "--include-partial-messages",
104
+ "--include-hook-events", # surface SessionStart / hooks into stream-json
105
+ ]
106
+
107
+ # MCP server registration — headless path. The shape mirrors
108
+ # the Claude Code MCP doc's ``mcp.json`` example and the
109
+ # ``claude mcp add --transport http <name> <url> --header
110
+ # "Authorization: Bearer ..."`` invocation.
111
+ if mcp_endpoint_url and mcp_bearer_token:
112
+ # `alwaysLoad: true` opts this server out of MCP tool-search
113
+ # deferral so all `mcp__machinaos__*` tools enter context at
114
+ # session start instead of waiting for a `ToolSearch` call
115
+ # that the agent often doesn't make
116
+ # (https://code.claude.com/docs/en/mcp#scale-with-mcp-tool-search).
117
+ # Startup blocks <=5s waiting for the FastMCP connection;
118
+ # acceptable since our server is already up before spawn.
119
+ mcp_payload = json.dumps({
120
+ "mcpServers": {
121
+ "machinaos": {
122
+ "type": "http",
123
+ "url": mcp_endpoint_url,
124
+ "headers": {
125
+ "Authorization": f"Bearer {mcp_bearer_token}",
126
+ },
127
+ "alwaysLoad": True,
128
+ }
129
+ }
130
+ })
131
+ argv += ["--mcp-config", mcp_payload, "--strict-mcp-config"]
132
+
133
+ # Model
134
+ model = (
135
+ task.model
136
+ or defaults.get("default_model")
137
+ or self._defaults.get("default_model", "claude-sonnet-4-6")
138
+ )
139
+ argv += ["--model", model]
140
+
141
+ # Session / resume — `resume_session_id` wins if both are set,
142
+ # since "resume" implies the user has a prior session.
143
+ if task.resume_session_id:
144
+ argv += ["--resume", task.resume_session_id]
145
+ elif task.session_id:
146
+ argv += ["--session-id", task.session_id]
147
+
148
+ # Max turns
149
+ max_turns = (
150
+ task.max_turns
151
+ if task.max_turns is not None
152
+ else int(defaults.get(
153
+ "default_max_turns",
154
+ self._defaults.get("default_max_turns", 10),
155
+ ))
156
+ )
157
+ argv += ["--max-turns", str(max_turns)]
158
+
159
+ # Budget (USD)
160
+ max_budget = (
161
+ task.max_budget_usd
162
+ if task.max_budget_usd is not None
163
+ else float(defaults.get(
164
+ "default_max_budget_usd",
165
+ self._defaults.get("default_max_budget_usd", 5.0),
166
+ ))
167
+ )
168
+ if max_budget > 0:
169
+ argv += ["--max-budget-usd", str(max_budget)]
170
+
171
+ # Allowed tools — built-in defaults plus every workflow tool we
172
+ # exposed via the per-batch FastMCP bridge. Without the
173
+ # `mcp__machinaos__<name>` entries here, claude sees the tools
174
+ # in `tools/list` but is denied permission when it tries to
175
+ # invoke them ("I don't have permission to run a web search…")
176
+ # because `--permission-mode acceptEdits` only auto-permits
177
+ # Edit; everything else falls through to the allowlist.
178
+ # Default fallback includes:
179
+ # - Read,Edit,Bash,Glob,Grep,Write — filesystem + shell escape hatches
180
+ # - Skill — invoke materialised `.claude/skills/<name>/SKILL.md`
181
+ # - WebSearch,WebFetch — escape hatches when no MCP tool matches
182
+ # `ToolSearch` is intentionally NOT here: it's permission-free per
183
+ # https://code.claude.com/docs/en/tools-reference#built-in-tools.
184
+ allowed = task.allowed_tools or defaults.get(
185
+ "default_allowed_tools",
186
+ self._defaults.get(
187
+ "default_allowed_tools",
188
+ "Read,Edit,Bash,Glob,Grep,Write,Skill,WebSearch,WebFetch",
189
+ ),
190
+ )
191
+ allowed_list: List[str] = (
192
+ [t.strip() for t in allowed.split(",") if t.strip()]
193
+ if allowed else []
194
+ )
195
+ if connected_tool_names:
196
+ allowed_list += [
197
+ f"mcp__machinaos__{name}" for name in connected_tool_names
198
+ ]
199
+ # Always permit MachinaOs's built-in MCP tools so the agent can
200
+ # discover skills + read workspace files without prompting.
201
+ allowed_list += [
202
+ "mcp__machinaos__getWorkspaceFiles",
203
+ "mcp__machinaos__listSkills",
204
+ "mcp__machinaos__getSkill",
205
+ "mcp__machinaos__getCredential",
206
+ "mcp__machinaos__broadcastLog",
207
+ ]
208
+ if allowed_list:
209
+ argv += ["--allowedTools", ",".join(allowed_list)]
210
+
211
+ # Permission mode (default acceptEdits)
212
+ perm = task.permission_mode or defaults.get(
213
+ "default_permission_mode",
214
+ self._defaults.get("default_permission_mode", "acceptEdits"),
215
+ )
216
+ if perm:
217
+ argv += ["--permission-mode", perm]
218
+
219
+ # System prompt — appended to Claude Code's built-in system prompt
220
+ if task.system_prompt:
221
+ argv += ["--append-system-prompt", task.system_prompt]
222
+ logger.info(
223
+ "[CC-Agent argv] --append-system-prompt (task) "
224
+ "length=%d preview=%r",
225
+ len(task.system_prompt), task.system_prompt[:200],
226
+ )
227
+
228
+ # Connected-tools steering directive — ensures the agent prefers
229
+ # wired MCP tools over built-in escape hatches (WebSearch,
230
+ # WebFetch, Bash) when their purpose matches the user's request.
231
+ # Mirrors Cursor's per-request rule prepend pattern
232
+ # (https://cursor.com/docs/rules). Multiple `--append-system-prompt`
233
+ # flags concatenate per the CLI reference.
234
+ if connected_tool_names:
235
+ tool_list = ", ".join(
236
+ f"mcp__machinaos__{name}" for name in connected_tool_names
237
+ )
238
+ directive = (
239
+ f"Workflow tools wired to this agent: {tool_list}. "
240
+ "Prefer them over built-in equivalents (WebSearch, "
241
+ "WebFetch, Bash) when the user's request matches their "
242
+ "purpose."
243
+ )
244
+ argv += ["--append-system-prompt", directive]
245
+ logger.info(
246
+ "[CC-Agent argv] --append-system-prompt (tools-directive) "
247
+ "length=%d",
248
+ len(directive),
249
+ )
250
+
251
+ # Optional per-task overrides (documented at code.claude.com/docs/en/cli-reference)
252
+ if task.effort:
253
+ argv += ["--effort", task.effort]
254
+ if task.fallback_model:
255
+ argv += ["--fallback-model", task.fallback_model]
256
+ for path in task.add_dir:
257
+ argv += ["--add-dir", path]
258
+ if task.disallowed_tools:
259
+ argv += ["--disallowedTools", task.disallowed_tools]
260
+ if task.agent:
261
+ argv += ["--agent", task.agent]
262
+
263
+ return argv
264
+
265
+ # ---- native auth -----------------------------------------------------
266
+
267
+ def login_argv(self) -> List[str]:
268
+ return list(self._login_argv) or ["claude", "login"]
269
+
270
+ def auth_status_argv(self) -> Optional[List[str]]:
271
+ return list(self._auth_status_argv) if self._auth_status_argv else None
272
+
273
+ def detect_auth_error(self, stderr: str, exit_code: int) -> bool:
274
+ """True if stderr/exit_code indicate the user isn't logged in."""
275
+ if not stderr and exit_code == 0:
276
+ return False
277
+ markers = (
278
+ "Please run 'claude login'",
279
+ "Please run `claude login`",
280
+ "Not authenticated",
281
+ "Authentication required",
282
+ "401 Unauthorized",
283
+ "Invalid API key",
284
+ )
285
+ return any(m in stderr for m in markers)
286
+
287
+ # ---- streaming output parsing ---------------------------------------
288
+
289
+ def parse_event(self, line: str) -> Optional[Dict[str, Any]]:
290
+ line = line.strip()
291
+ if not line:
292
+ return None
293
+ try:
294
+ return json.loads(line)
295
+ except json.JSONDecodeError:
296
+ return None
297
+
298
+ def is_final_event(self, event: Dict[str, Any]) -> bool:
299
+ return event.get("type") == "result"
300
+
301
+ def event_to_session_result(
302
+ self,
303
+ events: List[Dict[str, Any]],
304
+ stderr: str,
305
+ exit_code: int,
306
+ ) -> Dict[str, Any]:
307
+ """Reconstruct shared result fields from the event stream."""
308
+ final = next(
309
+ (e for e in reversed(events) if e.get("type") == "result"),
310
+ None,
311
+ )
312
+
313
+ # Session ID can come from `system.init` or `result`
314
+ session_id: Optional[str] = None
315
+ for evt in events:
316
+ sid = evt.get("session_id")
317
+ if sid:
318
+ session_id = sid
319
+ break
320
+
321
+ tool_calls = sum(
322
+ 1 for evt in events
323
+ if evt.get("type") == "tool_use"
324
+ or (evt.get("type") == "assistant" and self._has_tool_use(evt))
325
+ )
326
+
327
+ provider_data: Dict[str, Any] = {}
328
+ for evt in events:
329
+ if evt.get("type") == "assistant":
330
+ msg = evt.get("message") or {}
331
+ rd = msg.get("reasoning_details") or msg.get("thinking")
332
+ if rd is not None:
333
+ provider_data.setdefault("reasoning_details", rd)
334
+ break
335
+
336
+ success = exit_code == 0 and final is not None
337
+ error: Optional[str] = None
338
+ if exit_code != 0:
339
+ error = stderr.strip()[-2000:] or f"claude exited with code {exit_code}"
340
+ elif final is None:
341
+ error = "no result event received"
342
+
343
+ response = ""
344
+ cost: Optional[float] = None
345
+ duration_ms: Optional[int] = None
346
+ num_turns: Optional[int] = None
347
+ if final:
348
+ response = str(final.get("result") or "")
349
+ cost = final.get("total_cost_usd")
350
+ duration_ms = final.get("duration_ms")
351
+ num_turns = final.get("num_turns")
352
+ if final.get("subtype") == "error":
353
+ success = False
354
+ error = error or response or "result event reports error"
355
+
356
+ cu = self.canonical_usage(events)
357
+
358
+ return {
359
+ "session_id": session_id,
360
+ "response": response,
361
+ "cost_usd": cost,
362
+ "duration_ms": duration_ms,
363
+ "num_turns": num_turns,
364
+ "tool_calls": tool_calls,
365
+ "canonical_usage": cu,
366
+ "provider_data": provider_data,
367
+ "success": success,
368
+ "error": error,
369
+ }
370
+
371
+ def canonical_usage(self, events: List[Dict[str, Any]]) -> CanonicalUsage:
372
+ """Pull token counts from the `result` event's `usage` block.
373
+
374
+ Anthropic shape:
375
+ {
376
+ "input_tokens": int,
377
+ "output_tokens": int,
378
+ "cache_creation_input_tokens": int,
379
+ "cache_read_input_tokens": int,
380
+ }
381
+ """
382
+ final = next(
383
+ (e for e in reversed(events) if e.get("type") == "result"),
384
+ None,
385
+ )
386
+ if not final:
387
+ return CanonicalUsage()
388
+
389
+ usage = final.get("usage") or {}
390
+ request_count = (
391
+ int(final.get("num_turns") or 0)
392
+ or sum(1 for e in events if e.get("type") == "assistant")
393
+ )
394
+ return CanonicalUsage(
395
+ input_tokens=int(usage.get("input_tokens", 0)),
396
+ output_tokens=int(usage.get("output_tokens", 0)),
397
+ cache_read=int(usage.get("cache_read_input_tokens", 0)),
398
+ cache_write=int(usage.get("cache_creation_input_tokens", 0)),
399
+ reasoning_tokens=0, # Claude doesn't expose this separately
400
+ request_count=request_count,
401
+ )
402
+
403
+ # ---- feature gating --------------------------------------------------
404
+
405
+ def supports(self, feature: str) -> bool:
406
+ return feature in self._supports
407
+
408
+ # ---- internals -------------------------------------------------------
409
+
410
+ @staticmethod
411
+ def _has_tool_use(event: Dict[str, Any]) -> bool:
412
+ msg = event.get("message") or {}
413
+ content = msg.get("content")
414
+ if isinstance(content, list):
415
+ return any(
416
+ isinstance(blk, dict) and blk.get("type") == "tool_use"
417
+ for blk in content
418
+ )
419
+ return False
@@ -0,0 +1,80 @@
1
+ """Google Gemini CLI provider — v2 stub.
2
+
3
+ The factory raises ``NotImplementedError`` for ``"gemini"`` in v1, but
4
+ the type+config layer is wired so v2 activation is mechanical (replace
5
+ this stub, drop the factory branch). See `cli_agent_framework.md` →
6
+ "v2 follow-up — Gemini activation" for the full v2 PR shape.
7
+
8
+ Reference for v2 implementation:
9
+ - argv: ``gemini --prompt <p> --output-format stream-json --model ...
10
+ [--session-id <UUID>] [--resume latest|<idx>|<UUID>] [--yolo] [--sandbox]``
11
+ - Final event: ``type == "result"`` (from
12
+ ``packages/cli/src/nonInteractiveCli.ts:JsonStreamEventType.RESULT``)
13
+ - ``result`` event carries ``session_id`` + ``stats.duration_ms``
14
+ - Exit code 1 = ``FatalAuthenticationError``
15
+ - Auth: ``gemini auth login`` writes ``~/.gemini/``
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from pathlib import Path
21
+ from typing import Any, Dict, List, Optional
22
+
23
+ from services.cli_agent.protocol import CanonicalUsage
24
+
25
+
26
+ class GoogleGeminiProvider:
27
+ """v2 stub. Constructed only via direct instantiation in tests; the
28
+ factory bypasses this class entirely and raises NotImplementedError."""
29
+
30
+ name = "gemini"
31
+
32
+ def __init__(self) -> None:
33
+ raise NotImplementedError(
34
+ "GoogleGeminiProvider is a v2 stub. The factory raises "
35
+ "NotImplementedError for 'gemini' in v1."
36
+ )
37
+
38
+ # The Protocol surface below is declared so static type-checkers see
39
+ # the class as a complete `AICliProvider`. None of these are reachable
40
+ # because `__init__` raises.
41
+
42
+ package_name: str = "@google/gemini-cli"
43
+ binary_name: str = "gemini"
44
+ ide_lock_env_var: Optional[str] = "GEMINI_IDE_LOCK"
45
+ ide_lockfile_dir: Optional[Path] = None # config.py expands to <tmpdir>/gemini/ide
46
+
47
+ def binary_path(self) -> Path: # pragma: no cover
48
+ raise NotImplementedError
49
+
50
+ def headless_argv(self, task: Any, *, defaults: Dict[str, Any]) -> List[str]: # pragma: no cover
51
+ raise NotImplementedError
52
+
53
+ def login_argv(self) -> List[str]: # pragma: no cover
54
+ return ["gemini", "auth", "login"]
55
+
56
+ def auth_status_argv(self) -> Optional[List[str]]: # pragma: no cover
57
+ return ["gemini", "--version"]
58
+
59
+ def detect_auth_error(self, stderr: str, exit_code: int) -> bool: # pragma: no cover
60
+ return exit_code == 1 and "FatalAuthenticationError" in stderr
61
+
62
+ def parse_event(self, line: str) -> Optional[Dict[str, Any]]: # pragma: no cover
63
+ raise NotImplementedError
64
+
65
+ def is_final_event(self, event: Dict[str, Any]) -> bool: # pragma: no cover
66
+ return event.get("type") == "result"
67
+
68
+ def event_to_session_result(
69
+ self,
70
+ events: List[Dict[str, Any]],
71
+ stderr: str,
72
+ exit_code: int,
73
+ ) -> Dict[str, Any]: # pragma: no cover
74
+ raise NotImplementedError
75
+
76
+ def canonical_usage(self, events: List[Dict[str, Any]]) -> CanonicalUsage: # pragma: no cover
77
+ return CanonicalUsage()
78
+
79
+ def supports(self, feature: str) -> bool: # pragma: no cover
80
+ return feature in {"session_id", "resume", "sandbox", "mcp_runtime", "ide_lockfile"}