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
@@ -49,6 +49,8 @@ from telegram.error import BadRequest, NetworkError
49
49
  from telegram.ext import Application, ContextTypes, MessageHandler, filters
50
50
  from telegram.helpers import escape_markdown
51
51
 
52
+ from services.plugin.singleton import ServiceSingleton
53
+
52
54
  from ._credentials import TelegramCredential
53
55
 
54
56
  logger = logging.getLogger(__name__)
@@ -99,10 +101,14 @@ def _split_text(text: str, limit: int) -> list[str]:
99
101
  return chunks
100
102
 
101
103
 
102
- class TelegramService:
103
- """Singleton service for Telegram bot operations."""
104
+ class TelegramService(ServiceSingleton):
105
+ """Singleton service for Telegram bot operations.
106
+
107
+ Inherits :meth:`ServiceSingleton.instance` for the lazy accessor.
108
+ Overrides :meth:`reset_instance` because telegram has a side effect
109
+ on reset — it must drain the bot's polling task before clearing.
110
+ """
104
111
 
105
- _instance: Optional["TelegramService"] = None
106
112
  _lock = asyncio.Lock()
107
113
 
108
114
  def __init__(self):
@@ -115,15 +121,10 @@ class TelegramService:
115
121
  self._owner_chat_id: Optional[int] = None
116
122
 
117
123
  @classmethod
118
- def get_instance(cls) -> "TelegramService":
119
- if cls._instance is None:
120
- cls._instance = cls()
121
- return cls._instance
122
-
123
- @classmethod
124
- async def reset_instance(cls):
125
- if cls._instance:
126
- await cls._instance.disconnect()
124
+ async def reset_instance(cls): # type: ignore[override]
125
+ existing = cls.__dict__.get("_instance")
126
+ if existing is not None:
127
+ await existing.disconnect()
127
128
  cls._instance = None
128
129
 
129
130
  @property
@@ -256,12 +257,11 @@ class TelegramService:
256
257
  }
257
258
  logger.info(f"[Telegram] Bot validated: @{me.username} (ID: {me.id})")
258
259
 
259
- self._polling_task = asyncio.create_task(self._run_polling())
260
- self._connected = True
261
-
262
- await self._broadcast_status()
263
-
264
- # Hydrate runtime owner_chat_id from stored credential.
260
+ # Hydrate runtime owner_chat_id from stored credential
261
+ # BEFORE polling starts so the pre-poll peek below can
262
+ # short-circuit when we already know the owner. (Was
263
+ # previously after polling -- race-prone with the
264
+ # capture path in _on_message_received.)
265
265
  saved_owner = secrets.get("telegram_owner_chat_id")
266
266
  if saved_owner is None:
267
267
  try:
@@ -276,6 +276,28 @@ class TelegramService:
276
276
  except (TypeError, ValueError):
277
277
  pass
278
278
 
279
+ # Pre-poll peek for historical owner capture.
280
+ # Polling starts with drop_pending_updates=True
281
+ # (correct hygiene for operational events -- we do
282
+ # not want stale group spam replaying on every
283
+ # restart) but that ALSO drops any DM the user sent
284
+ # before the bot connected. Without this peek the
285
+ # only path to owner capture is "DM the bot AFTER
286
+ # polling has started", which is the surprising UX
287
+ # that produces "Bot owner not detected" on every
288
+ # fresh setup. get_updates() with no offset returns
289
+ # the same pending queue without advancing it, so
290
+ # the subsequent start_polling drop-pass is a no-op
291
+ # for these messages -- they were going to be
292
+ # dropped anyway, we just inspect them first.
293
+ if self._owner_chat_id is None:
294
+ await self._capture_owner_from_pending_updates()
295
+
296
+ self._polling_task = asyncio.create_task(self._run_polling())
297
+ self._connected = True
298
+
299
+ await self._broadcast_status()
300
+
279
301
  logger.info(f"[Telegram] Connected and polling started for @{me.username}")
280
302
  return {
281
303
  "success": True,
@@ -354,36 +376,116 @@ class TelegramService:
354
376
  self._connected = False
355
377
  await self._broadcast_status()
356
378
 
379
+ async def _capture_owner_from_pending_updates(self) -> None:
380
+ """Inspect the bot's pending update queue (24h Telegram retention)
381
+ for any private message and capture the owner if found. Called
382
+ from connect() before polling starts -- after polling begins the
383
+ ``drop_pending_updates=True`` flag throws these away unread.
384
+
385
+ Uses the same atomic-write-through invariant as
386
+ ``_on_message_received``: persist FIRST, set in-memory only on
387
+ successful persist, so a restart can re-capture cleanly if the
388
+ DB write fails.
389
+ """
390
+ try:
391
+ # offset=None / 0 returns the queue without advancing the
392
+ # confirmed offset. allowed_updates=["message"] skips
393
+ # callback_query / poll / inline_query payloads we don't
394
+ # care about for owner capture.
395
+ pending = await self._bot.get_updates(
396
+ timeout=0,
397
+ allowed_updates=["message"],
398
+ )
399
+ except Exception as e:
400
+ logger.warning(
401
+ f"[Telegram] Pre-poll owner-capture peek failed "
402
+ f"({type(e).__name__}): {e}. Owner capture will fall "
403
+ f"back to live polling once the user DMs the bot.",
404
+ )
405
+ return
406
+
407
+ for upd in pending:
408
+ m = upd.message
409
+ if not (m and m.chat and m.chat.type == "private" and m.from_user):
410
+ continue
411
+ captured_id = m.from_user.id
412
+ try:
413
+ from services.plugin.deps import get_auth_service
414
+ await get_auth_service().store_api_key(
415
+ "telegram_owner_chat_id",
416
+ str(captured_id),
417
+ models=[],
418
+ )
419
+ except Exception as persist_err:
420
+ logger.error(
421
+ f"[Telegram] FAILED to persist retroactively-captured "
422
+ f"owner {captured_id}: {persist_err}. Workaround: "
423
+ f"set TELEGRAM_OWNER_CHAT_ID={captured_id} in .env",
424
+ exc_info=True,
425
+ )
426
+ return
427
+ self._owner_chat_id = captured_id
428
+ logger.info(
429
+ f"[Telegram] Owner retroactively captured from pending "
430
+ f"updates: @{m.from_user.username} (ID: {captured_id})"
431
+ )
432
+ return
433
+
357
434
  async def _on_message_received(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
358
435
  try:
359
436
  if not update.message:
360
437
  return
361
438
  msg = update.message
362
439
 
363
- # Auto-capture bot owner from first private message
440
+ # Auto-capture bot owner from first private message.
441
+ # ATOMIC WRITE-THROUGH: persist to credentials DB FIRST, set
442
+ # in-memory only on success. The previous order
443
+ # (in-memory then await persist, with WARNING-level logging
444
+ # of failures) had a silent failure mode: if the persist
445
+ # raised, the rest of the process lifetime worked correctly,
446
+ # then the next restart wiped in-memory and DB had nothing
447
+ # -- subsequent telegramSend(recipient_type=self) failed
448
+ # forever with "Bot owner not detected" and no trace of
449
+ # what went wrong. The new order preserves the invariant
450
+ # "in-memory has owner => DB has owner" so a restart can
451
+ # always re-capture from the next inbound private message.
364
452
  if (
365
453
  self._owner_chat_id is None
366
454
  and msg.chat.type == "private"
367
455
  and msg.from_user
368
456
  ):
369
- self._owner_chat_id = msg.from_user.id
370
- logger.info(
371
- f"[Telegram] Owner detected: @{msg.from_user.username} "
372
- f"(ID: {msg.from_user.id})"
373
- )
457
+ captured_id = msg.from_user.id
458
+ persist_ok = False
374
459
  try:
375
- from core.container import container
376
- auth = container.auth_service()
377
- await auth.store_api_key(
460
+ from services.plugin.deps import get_auth_service
461
+ await get_auth_service().store_api_key(
378
462
  "telegram_owner_chat_id",
379
- str(msg.from_user.id),
463
+ str(captured_id),
380
464
  models=[],
381
465
  )
466
+ persist_ok = True
382
467
  except Exception as persist_err:
383
- logger.warning(
384
- f"[Telegram] Failed to persist owner chat_id: {persist_err}"
468
+ # ERROR-level so the failure surfaces in default
469
+ # uvicorn output, not just DEBUG. Includes the
470
+ # captured id so the user can manually set
471
+ # TELEGRAM_OWNER_CHAT_ID in .env as an immediate
472
+ # workaround. exc_info=True so the underlying
473
+ # cause (encryption not initialised, DB locked,
474
+ # disk full, ...) is visible.
475
+ logger.error(
476
+ f"[Telegram] FAILED to persist owner chat_id "
477
+ f"{captured_id}: {persist_err}. The bot will not "
478
+ f"recover this binding on restart. Workaround: "
479
+ f"set TELEGRAM_OWNER_CHAT_ID={captured_id} in .env",
480
+ exc_info=True,
385
481
  )
386
- await self._broadcast_status()
482
+ if persist_ok:
483
+ self._owner_chat_id = captured_id
484
+ logger.info(
485
+ f"[Telegram] Owner detected and persisted: "
486
+ f"@{msg.from_user.username} (ID: {captured_id})"
487
+ )
488
+ await self._broadcast_status()
387
489
 
388
490
  event_data = self._format_message(msg)
389
491
  logger.info(
@@ -727,4 +829,4 @@ class TelegramService:
727
829
 
728
830
  def get_telegram_service() -> TelegramService:
729
831
  """Get TelegramService singleton instance."""
730
- return TelegramService.get_instance()
832
+ return TelegramService.instance()
@@ -1,7 +1,7 @@
1
1
  """Telegram Send — Wave 11.C migration.
2
2
 
3
- Dual-purpose: workflow ActionNode + AI tool. The Telegram bot token
4
- lives in ``auth_service`` under ``telegram_bot_token``. Plugin
3
+ Workflow-only ActionNode (no AI-tool exposure). The Telegram bot
4
+ token lives in ``auth_service`` under ``telegram_bot_token``. Plugin
5
5
  delegates to the legacy ``handle_telegram_send`` handler during
6
6
  thin-migration; 11.E converts to a declarative ``TelegramCredential``.
7
7
  """
@@ -148,7 +148,7 @@ class TelegramSendNode(ActionNode):
148
148
  type = "telegramSend"
149
149
  display_name = "Telegram Send"
150
150
  subtitle = "Send Message"
151
- group = ("social", "tool")
151
+ group = ("social",)
152
152
  description = "Send text, photo, document, location, or contact via Telegram bot"
153
153
  component_kind = "square"
154
154
  handles = (
@@ -160,7 +160,6 @@ class TelegramSendNode(ActionNode):
160
160
  annotations = {"destructive": False, "readonly": False, "open_world": True}
161
161
  credentials = (TelegramCredential,)
162
162
  task_queue = TaskQueue.MESSAGING
163
- usable_as_tool = True
164
163
 
165
164
  Params = TelegramSendParams
166
165
  Output = TelegramSendOutput
@@ -183,8 +182,8 @@ class TelegramSendNode(ActionNode):
183
182
  chat_id = service.owner_chat_id
184
183
  if not chat_id:
185
184
  try:
186
- from core.container import container
187
- saved = await container.auth_service().get_api_key("telegram_owner_chat_id")
185
+ from services.plugin.deps import get_auth_service
186
+ saved = await get_auth_service().get_api_key("telegram_owner_chat_id")
188
187
  if saved:
189
188
  owner_id = int(saved)
190
189
  await service.set_owner(owner_id)
@@ -63,9 +63,9 @@ class FileHandlerNode(ActionNode):
63
63
 
64
64
  @Operation("wrap")
65
65
  async def wrap(self, ctx: NodeContext, params: FileHandlerParams) -> Any:
66
- from core.container import container
66
+ from services.plugin.deps import get_text_service
67
67
 
68
- text_service = container.text_service()
68
+ text_service = get_text_service()
69
69
  # Pass schema-canonical snake_case through to the service. The
70
70
  # service's *output* dict still carries camelCase keys
71
71
  # (`fileName` / `fileType`) by historical wire contract -- the
@@ -44,9 +44,9 @@ class TextGeneratorNode(ActionNode):
44
44
 
45
45
  @Operation("generate")
46
46
  async def generate(self, ctx: NodeContext, params: TextGeneratorParams) -> Any:
47
- from core.container import container
47
+ from services.plugin.deps import get_text_service
48
48
 
49
- text_service = container.text_service()
49
+ text_service = get_text_service()
50
50
  response = await text_service.execute_text_generator(
51
51
  ctx.node_id, params.model_dump(),
52
52
  )