machinaos 0.0.76 → 0.0.77

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 (390) hide show
  1. package/README.md +142 -106
  2. package/client/dist/assets/ActionBar-DAHXJmEU.js +1 -0
  3. package/client/dist/assets/ApiKeyInput-DljozMIZ.js +1 -0
  4. package/client/dist/assets/ApiKeyPanel-BLCwKv-F.js +1 -0
  5. package/client/dist/assets/ApiUsageSection-FWVtg8Sd.js +1 -0
  6. package/client/dist/assets/EmailPanel-Cb1y_sxm.js +1 -0
  7. package/client/dist/assets/OAuthPanel-BUvQtzRH.js +1 -0
  8. package/client/dist/assets/QrPairingPanel-DgHdW1GW.js +1 -0
  9. package/client/dist/assets/RateLimitSection-B2lBVQs0.js +1 -0
  10. package/client/dist/assets/StatusCard-BlufvZD-.js +1 -0
  11. package/client/dist/assets/index-DNx1tG6T.js +232 -0
  12. package/client/dist/assets/index-bhvWG-f4.css +1 -0
  13. package/client/dist/assets/vendor-flow-apeQB2hf.js +1 -0
  14. package/client/dist/assets/vendor-icons-BPyNc2rK.js +22 -0
  15. package/client/dist/assets/vendor-markdown-Bx_GU1E7.js +62 -0
  16. package/client/dist/assets/vendor-misc-4my8ai2A.js +1 -0
  17. package/client/dist/assets/vendor-query-to9T1kjL.js +1 -0
  18. package/client/dist/assets/vendor-radix-BGeDhy8U.js +56 -0
  19. package/client/dist/assets/vendor-react-CxXU_nq3.js +1 -0
  20. package/client/dist/index.html +37 -3
  21. package/client/index.html +28 -1
  22. package/client/package.json +5 -1
  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/machina/commands/build.py +51 -7
  138. package/machina/pyproject.toml +4 -0
  139. package/machina/supervisor.py +12 -2
  140. package/machina/tree.py +71 -21
  141. package/package.json +1 -1
  142. package/scripts/install.js +16 -1
  143. package/server/config/ai_cli_providers.json +54 -0
  144. package/server/config/credential_providers.json +109 -2
  145. package/server/config/llm_defaults.json +24 -0
  146. package/server/config/model_registry.json +338 -499
  147. package/server/config/node_allowlist.json +16 -1
  148. package/server/config/pricing.json +8 -0
  149. package/server/constants.py +38 -15
  150. package/server/core/container.py +2 -2
  151. package/server/core/credentials_database.py +35 -2
  152. package/server/core/logging.py +4 -3
  153. package/server/main.py +99 -13
  154. package/server/models/node_metadata.py +1 -0
  155. package/server/nodejs/package.json +4 -2
  156. package/server/nodes/README.md +31 -4
  157. package/server/nodes/agent/_inline.py +2 -0
  158. package/server/nodes/agent/_specialized.py +6 -3
  159. package/server/nodes/agent/ai_agent.py +13 -3
  160. package/server/nodes/agent/chat_agent.py +6 -3
  161. package/server/nodes/agent/claude_code_agent.py +287 -75
  162. package/server/nodes/agent/codex_agent.py +239 -0
  163. package/server/nodes/agent/deep_agent.py +3 -3
  164. package/server/nodes/agent/rlm_agent.py +3 -3
  165. package/server/nodes/android/__init__.py +31 -1
  166. package/server/nodes/android/_base.py +9 -5
  167. package/server/{services/android_service.py → nodes/android/_dispatcher.py} +2 -2
  168. package/server/nodes/android/_handlers.py +154 -0
  169. package/server/nodes/android/_option_loaders.py +44 -0
  170. package/server/nodes/android/_refresh.py +127 -0
  171. package/server/{services/android → nodes/android/_relay}/client.py +4 -4
  172. package/server/{routers/android.py → nodes/android/_router.py} +7 -7
  173. package/server/nodes/browser/browser.py +2 -2
  174. package/server/nodes/code/_base.py +6 -2
  175. package/server/nodes/code/_claude_code.py +134 -0
  176. package/server/nodes/document/embedding_generator.py +3 -3
  177. package/server/nodes/document/http_scraper.py +3 -3
  178. package/server/nodes/document/vector_store.py +5 -5
  179. package/server/nodes/email/__init__.py +11 -1
  180. package/server/nodes/email/_filters.py +21 -0
  181. package/server/{services/himalaya_service.py → nodes/email/_himalaya.py} +6 -10
  182. package/server/{services/email_service.py → nodes/email/_service.py} +9 -13
  183. package/server/nodes/email/email_read.py +1 -1
  184. package/server/nodes/email/email_receive.py +54 -5
  185. package/server/nodes/email/email_send.py +1 -1
  186. package/server/nodes/filesystem/shell.py +24 -1
  187. package/server/nodes/google/__init__.py +55 -1
  188. package/server/{services/handlers/google_auth.py → nodes/google/_auth_helper.py} +8 -5
  189. package/server/nodes/google/_base.py +2 -2
  190. package/server/nodes/google/_credentials.py +5 -5
  191. package/server/nodes/google/_filters.py +25 -0
  192. package/server/nodes/google/_handlers.py +57 -0
  193. package/server/{services/google_oauth.py → nodes/google/_oauth.py} +195 -162
  194. package/server/nodes/google/_option_loaders.py +107 -0
  195. package/server/nodes/google/_refresh.py +66 -0
  196. package/server/nodes/google/_router.py +131 -0
  197. package/server/nodes/google/gmail_receive.py +41 -4
  198. package/server/nodes/groups.py +1 -0
  199. package/server/nodes/location/_credentials.py +45 -1
  200. package/server/{services/maps.py → nodes/location/_service.py} +18 -3
  201. package/server/nodes/location/gmaps_create.py +4 -4
  202. package/server/nodes/location/gmaps_locations.py +4 -4
  203. package/server/nodes/location/gmaps_nearby_places.py +4 -4
  204. package/server/nodes/model/_base.py +8 -3
  205. package/server/nodes/model/_credentials.py +96 -8
  206. package/server/nodes/model/_local_validator.py +345 -0
  207. package/server/nodes/model/lmstudio_chat_model.py +23 -0
  208. package/server/nodes/model/ollama_chat_model.py +25 -0
  209. package/server/nodes/proxy/_usage.py +2 -2
  210. package/server/nodes/proxy/proxy_config.py +14 -14
  211. package/server/nodes/proxy/proxy_request.py +4 -4
  212. package/server/nodes/scraper/_credentials.py +29 -1
  213. package/server/nodes/scraper/apify_actor.py +9 -9
  214. package/server/nodes/scraper/crawlee_scraper.py +5 -5
  215. package/server/nodes/search/brave_search.py +4 -0
  216. package/server/nodes/search/perplexity_search.py +9 -0
  217. package/server/nodes/search/serper_search.py +3 -0
  218. package/server/nodes/skill/simple_memory.py +12 -0
  219. package/server/nodes/social/_base.py +2 -2
  220. package/server/nodes/stripe/__init__.py +46 -0
  221. package/server/nodes/stripe/_credentials.py +33 -0
  222. package/server/nodes/stripe/_handlers.py +270 -0
  223. package/server/nodes/stripe/_install.py +127 -0
  224. package/server/nodes/stripe/_source.py +174 -0
  225. package/server/nodes/stripe/stripe_action.py +81 -0
  226. package/server/nodes/stripe/stripe_receive.py +92 -0
  227. package/server/nodes/telegram/_credentials.py +52 -1
  228. package/server/nodes/telegram/_handlers.py +19 -18
  229. package/server/nodes/telegram/_service.py +134 -32
  230. package/server/nodes/telegram/telegram_send.py +5 -6
  231. package/server/nodes/text/file_handler.py +2 -2
  232. package/server/nodes/text/text_generator.py +2 -2
  233. package/server/nodes/tool/agent_builder.py +630 -0
  234. package/server/nodes/tool/task_manager.py +144 -2
  235. package/server/nodes/twitter/__init__.py +38 -1
  236. package/server/nodes/twitter/_base.py +7 -7
  237. package/server/nodes/twitter/_credentials.py +1 -1
  238. package/server/nodes/twitter/_filters.py +37 -0
  239. package/server/nodes/twitter/_handlers.py +77 -0
  240. package/server/nodes/twitter/_oauth.py +124 -0
  241. package/server/nodes/twitter/_refresh.py +78 -0
  242. package/server/nodes/twitter/_router.py +29 -0
  243. package/server/nodes/twitter/twitter_receive.py +4 -0
  244. package/server/nodes/visuals.json +64 -19
  245. package/server/nodes/whatsapp/__init__.py +45 -5
  246. package/server/nodes/whatsapp/_base.py +3 -3
  247. package/server/nodes/whatsapp/_filters.py +137 -0
  248. package/server/nodes/whatsapp/_handlers.py +167 -0
  249. package/server/nodes/whatsapp/_option_loaders.py +68 -0
  250. package/server/nodes/whatsapp/_refresh.py +62 -0
  251. package/server/nodes/whatsapp/_runtime.py +1 -1
  252. package/server/pyproject.toml +21 -0
  253. package/server/routers/schemas.py +2 -2
  254. package/server/routers/webhook.py +26 -9
  255. package/server/routers/websocket.py +149 -810
  256. package/server/services/ai.py +89 -8
  257. package/server/services/auth.py +220 -43
  258. package/server/services/claude_oauth.py +126 -100
  259. package/server/services/cli_agent/__init__.py +78 -0
  260. package/server/services/cli_agent/_handlers.py +237 -0
  261. package/server/services/cli_agent/config.py +112 -0
  262. package/server/services/cli_agent/factory.py +48 -0
  263. package/server/services/cli_agent/lockfile.py +141 -0
  264. package/server/services/cli_agent/mcp_server.py +482 -0
  265. package/server/services/cli_agent/protocol.py +173 -0
  266. package/server/services/cli_agent/providers/__init__.py +9 -0
  267. package/server/services/cli_agent/providers/anthropic_claude.py +419 -0
  268. package/server/services/cli_agent/providers/google_gemini.py +80 -0
  269. package/server/services/cli_agent/providers/openai_codex.py +310 -0
  270. package/server/services/cli_agent/service.py +607 -0
  271. package/server/services/cli_agent/session.py +618 -0
  272. package/server/services/cli_agent/types.py +227 -0
  273. package/server/services/cli_agent/workflow_tools.py +233 -0
  274. package/server/services/credential_registry.py +26 -1
  275. package/server/services/deployment/manager.py +26 -145
  276. package/server/services/deployment/poll_registry.py +59 -0
  277. package/server/services/event_waiter.py +76 -246
  278. package/server/services/events/__init__.py +54 -0
  279. package/server/services/events/cli.py +78 -0
  280. package/server/services/events/daemon.py +163 -0
  281. package/server/services/events/envelope.py +281 -0
  282. package/server/services/events/lifecycle.py +99 -0
  283. package/server/services/events/oauth_lifecycle.py +534 -0
  284. package/server/services/events/polling.py +60 -0
  285. package/server/services/events/push.py +36 -0
  286. package/server/services/events/source.py +63 -0
  287. package/server/services/events/triggers.py +118 -0
  288. package/server/services/events/verifiers/__init__.py +25 -0
  289. package/server/services/events/verifiers/base.py +28 -0
  290. package/server/services/events/verifiers/github.py +25 -0
  291. package/server/services/events/verifiers/hmac_basic.py +32 -0
  292. package/server/services/events/verifiers/standard_webhooks.py +47 -0
  293. package/server/services/events/verifiers/stripe.py +42 -0
  294. package/server/services/events/webhook.py +105 -0
  295. package/server/services/handlers/tools.py +28 -186
  296. package/server/services/llm/config.py +7 -0
  297. package/server/services/llm/factory.py +8 -2
  298. package/server/services/memory/__init__.py +52 -0
  299. package/server/services/memory/jsonl.py +80 -0
  300. package/server/services/memory/markdown.py +65 -0
  301. package/server/services/memory/state.py +112 -0
  302. package/server/services/memory/vector_store.py +40 -0
  303. package/server/services/model_registry.py +76 -0
  304. package/server/services/node_allowlist.py +71 -15
  305. package/server/services/node_executor.py +2 -2
  306. package/server/services/node_output_schemas.py +21 -10
  307. package/server/services/node_spec.py +1 -1
  308. package/server/services/oauth_utils.py +1 -1
  309. package/server/services/plugin/__init__.py +2 -0
  310. package/server/services/plugin/base.py +44 -2
  311. package/server/services/plugin/credential.py +288 -1
  312. package/server/services/plugin/deps.py +105 -0
  313. package/server/services/plugin/edge_walker.py +12 -4
  314. package/server/services/plugin/oauth.py +381 -0
  315. package/server/services/plugin/polling.py +247 -0
  316. package/server/services/plugin/registry.py +145 -0
  317. package/server/services/plugin/singleton.py +65 -0
  318. package/server/services/plugin/ws.py +81 -0
  319. package/server/services/process_service.py +31 -2
  320. package/server/services/status_broadcaster.py +155 -238
  321. package/server/services/temporal/workflow.py +7 -7
  322. package/server/services/workflow.py +21 -3
  323. package/server/services/ws_handler_registry.py +111 -28
  324. package/server/skills/GUIDE.md +16 -1
  325. package/server/skills/assistant/agent-builder-skill/SKILL.md +166 -0
  326. package/server/skills/payments_agent/stripe-skill/SKILL.md +306 -0
  327. package/server/tests/credentials/test_auth_service.py +16 -9
  328. package/server/tests/credentials/test_credential_broadcasts.py +219 -0
  329. package/server/tests/credentials/test_google_oauth.py +6 -6
  330. package/server/tests/credentials/test_oauth_utils.py +1 -1
  331. package/server/tests/credentials/test_twitter_oauth.py +2 -2
  332. package/server/tests/credentials/test_websocket_handlers.py +44 -20
  333. package/server/tests/llm/test_factory.py +1 -0
  334. package/server/tests/llm/test_wiring.py +5 -1
  335. package/server/tests/nodes/_compat.py +24 -24
  336. package/server/tests/nodes/test_agent_builder.py +439 -0
  337. package/server/tests/nodes/test_ai_tools.py +18 -14
  338. package/server/tests/nodes/test_code_fs_process.py +17 -8
  339. package/server/tests/nodes/test_email.py +10 -9
  340. package/server/tests/nodes/test_google_workspace.py +2 -2
  341. package/server/tests/nodes/test_specialized_agents.py +100 -53
  342. package/server/tests/nodes/test_stripe_plugin.py +293 -0
  343. package/server/tests/nodes/test_telegram_social.py +4 -4
  344. package/server/tests/nodes/test_twitter.py +1 -1
  345. package/server/tests/nodes/test_web_automation.py +2 -2
  346. package/server/tests/nodes/test_whatsapp.py +9 -9
  347. package/server/tests/services/cli_agent/__init__.py +0 -0
  348. package/server/tests/services/cli_agent/test_mcp_server.py +432 -0
  349. package/server/tests/services/cli_agent/test_providers.py +358 -0
  350. package/server/tests/services/cli_agent/test_service.py +298 -0
  351. package/server/tests/services/memory/__init__.py +0 -0
  352. package/server/tests/services/memory/test_jsonl.py +188 -0
  353. package/server/tests/services/test_events.py +333 -0
  354. package/server/tests/test_node_spec.py +56 -16
  355. package/server/tests/test_plugin_helpers.py +116 -0
  356. package/server/tests/test_plugin_self_containment.py +486 -0
  357. package/server/tests/test_status_broadcasts.py +425 -0
  358. package/workflows/{AI Assistant_workflow-1777421105154-0m4snkzjf.json → AI Assistant_workflow-1778504793388-ou1m1tz2x.json } +70 -266
  359. package/workflows/{AI Employee_workflow-1777720598005-u4cm858dv.json → AI Employee_example_workflow-1777720598005-u4cm858dv.json } +112 -112
  360. package/workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json +709 -0
  361. package/client/dist/assets/ActionBar-vzPpSR77.js +0 -1
  362. package/client/dist/assets/ApiKeyInput-Ds7AKFe8.js +0 -1
  363. package/client/dist/assets/ApiKeyPanel-gfblELep.js +0 -1
  364. package/client/dist/assets/ApiUsageSection-BMNWTe2r.js +0 -1
  365. package/client/dist/assets/EmailPanel-B1Om64p5.js +0 -1
  366. package/client/dist/assets/OAuthPanel-CXyQYGBz.js +0 -1
  367. package/client/dist/assets/QrPairingPanel-BgNuI1we.js +0 -1
  368. package/client/dist/assets/RateLimitSection-YYK8sx1T.js +0 -1
  369. package/client/dist/assets/StatusCard-DuYA5hJR.js +0 -1
  370. package/client/dist/assets/index-D9tZfgvi.js +0 -363
  371. package/client/dist/assets/index-al7snTkG.css +0 -1
  372. package/client/src/components/credentials/providers.tsx +0 -177
  373. package/server/routers/google.py +0 -277
  374. package/server/routers/maps.py +0 -142
  375. package/server/routers/twitter.py +0 -365
  376. package/server/services/claude_code_service.py +0 -106
  377. package/server/services/memory.py +0 -159
  378. package/server/services/node_option_loaders/__init__.py +0 -77
  379. package/server/services/node_option_loaders/android_loaders.py +0 -55
  380. package/server/services/node_option_loaders/google_loaders.py +0 -97
  381. package/server/services/node_option_loaders/whatsapp_loaders.py +0 -69
  382. package/server/services/twitter_oauth.py +0 -411
  383. package/server/services/websocket_client.py +0 -29
  384. /package/server/{services/android → nodes/android/_relay}/__init__.py +0 -0
  385. /package/server/{services/android → nodes/android/_relay}/broadcaster.py +0 -0
  386. /package/server/{services/android → nodes/android/_relay}/manager.py +0 -0
  387. /package/server/{services/android → nodes/android/_relay}/protocol.py +0 -0
  388. /package/server/{services/browser_service.py → nodes/browser/_service.py} +0 -0
  389. /package/server/{services/whatsapp_service.py → nodes/whatsapp/_service.py} +0 -0
  390. /package/server/skills/{task_agent → assistant}/write-todos-skill/SKILL.md +0 -0
package/README.md CHANGED
@@ -5,149 +5,185 @@
5
5
  <a href="https://discord.gg/c9pCJ7d8Ce" target="_blank"><img src="https://img.shields.io/discord/1455977012308086895?logo=discord&logoColor=white&label=Discord" alt="Discord"></a>
6
6
  <a href="https://deepwiki.com/trohitg/MachinaOS" target="_blank"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
7
7
 
8
- Personal AI Assistant/Co-Employees that Perform Human Like Tasks. Connect AI Assistant to your email, calendar, messages, phone, and more.
8
+ Your own AI assistant that does real work. Drag, drop, and connect AI agents to your email, calendar, messages, phone, and 50+ other services. Runs on your own machine — your data stays with you.
9
9
 
10
- Mashup of N8N + Openclaw but with better visibility of what it's doing and also tighter control of what your AI Assistant can do.
11
-
12
- ## See It In Action ↓
13
-
14
- https://github.com/user-attachments/assets/a30979e0-8066-4412-b466-cc3a70bcf3dd
15
-
16
- ## Full Capabilities ↓
17
-
18
- https://github.com/user-attachments/assets/9785aefb-9424-4a80-bd83-bb1205fc70af
19
-
20
- ## Prerequisites
21
-
22
- - **Node.js 22+** - https://nodejs.org/
23
- - **Python 3.12+** - https://python.org/
10
+ No code required. No subscription. No usage limits. Bring your own API keys (or run models locally with Ollama / LM Studio for free).
24
11
 
25
12
  ## Quick Start
26
13
 
14
+ **Prerequisites:** Node.js 22+, Python 3.12+
15
+
27
16
  ```bash
28
17
  npm install -g machinaos
29
18
  machina start
30
19
  ```
31
20
 
32
- Open http://localhost:3000
21
+ Open http://localhost:3000 and click **Credentials** to connect your first AI provider.
33
22
 
34
23
  <details>
35
- <summary><b>One-Line Install (auto-installs dependencies)</b></summary>
24
+ <summary><b>Run from source (for contributors)</b></summary>
36
25
 
37
- **Linux/macOS:**
38
26
  ```bash
39
- curl -fsSL https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.sh | bash
27
+ npm install -g pnpm
28
+ git clone https://github.com/trohitg/MachinaOS.git
29
+ cd MachinaOS
30
+ pnpm install
31
+ pnpm run dev
40
32
  ```
41
33
 
42
- **Windows (PowerShell):**
43
- ```powershell
44
- iwr -useb https://raw.githubusercontent.com/trohitg/MachinaOS/main/install.ps1 | iex
45
- ```
34
+ The `dev` task starts the Python backend, Vite client, WhatsApp service, and Temporal in parallel. See [SETUP.md](docs-internal/SETUP.md) and [SCRIPTS.md](docs-internal/SCRIPTS.md) for details, and [CONTRIBUTING.md](CONTRIBUTING.md) for the codebase map and contribution recipes.
46
35
 
47
36
  </details>
48
37
 
49
- <details>
50
- <summary><b>Clone & Run (for developers)</b></summary>
38
+ ## See It In Action ↓
51
39
 
52
- Development from source requires [pnpm](https://pnpm.io/) (enforced by `scripts/preinstall.js` via `pnpm-workspace.yaml`):
40
+ https://github.com/user-attachments/assets/5ee81bb3-12cf-4755-8532-7470c6f1d841
53
41
 
54
- ```bash
55
- npm install -g pnpm # one-time
56
- git clone https://github.com/trohitg/MachinaOS.git
57
- cd MachinaOS
58
- pnpm install
59
- pnpm run build
60
- pnpm run dev
61
- ```
42
+ ## Full Capabilities ↓
62
43
 
63
- </details>
44
+ https://github.com/user-attachments/assets/5798fe61-8d26-4d3a-90aa-189bf4eec79f
45
+
46
+ ## How It Works
47
+
48
+ [![How MachinaOS Works](docs/diagrams/how-it-works.svg)](https://raw.githubusercontent.com/trohitg/MachinaOS/main/docs/diagrams/how-it-works.svg)
49
+
50
+ Pick nodes from the palette, drag them onto a canvas, connect them with lines, give your AI agent some memory and skills, and hit Play. Or **deploy** the workflow so it runs forever in the background — waiting for emails, responding to messages, checking in on a schedule, doing the work you'd rather not.
51
+
52
+ ## Three Workflows You Get on Day One
53
+
54
+ [![Default workflows that ship with MachinaOS](docs/diagrams/default-workflows.svg)](https://raw.githubusercontent.com/trohitg/MachinaOS/main/docs/diagrams/default-workflows.svg)
55
+
56
+ The first time you open MachinaOS, three example workflows load automatically. Open them on the canvas to see exactly how the pieces fit together, then edit any node and save your own version.
64
57
 
65
58
  ## What You Can Build
66
59
 
67
- ### Personal AI Assistants
68
- Create AI agents that remember conversations, use tools, and work together. Choose from OpenAI, Claude, Gemini, DeepSeek, Kimi, Mistral, Groq, and 200+ models via OpenRouter.
69
-
70
- ### Automate Your Google Workspace
71
- - Send and search emails
72
- - Create calendar events
73
- - Upload files to Drive
74
- - Update spreadsheets
75
- - Manage tasks and contacts
76
-
77
- ### Universal Email (IMAP/SMTP)
78
- - Send, read, search, and manage emails via the Himalaya CLI
79
- - Works with Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, or any custom IMAP/SMTP server
80
- - Polling-based trigger for incoming email workflows
81
-
82
- ### Control Your Devices
83
- - Send WhatsApp messages automatically
84
- - Post to Twitter/X
85
- - Send Telegram messages via bot
86
- - Control your Android phone (WiFi, Bluetooth, apps, camera)
87
- - Schedule tasks and reminders
88
-
89
- ### Browse the Web
90
- - Interactive browser automation with accessibility-tree navigation (agent-browser)
91
- - Web scraping with BeautifulSoup or Playwright (crawlee)
92
- - Route requests through residential proxies with geo-targeting
93
- - Run Apify actors for social media and search engine scraping
94
- - DuckDuckGo, Brave, Serper (Google), and Perplexity search
95
-
96
- ### Plan Complex Tasks
97
- - `writeTodos` tool lets any AI agent create and update structured task lists
98
- - Real-time checklist rendering in the UI
99
- - Plan-work-update loop with `pending` / `in_progress` / `completed` states
100
-
101
- ### Process Documents
102
- - Parse PDFs and documents
103
- - Search your files with AI
104
-
105
- ### Build Agent Teams
60
+ ### Personal AI assistants that remember
61
+ Build a chat assistant that knows your calendar, reads your inbox, and follows up on tasks. Conversations are saved as readable markdown so you can edit what your agent remembers. Long-term memory uses vector search so years of conversation stay accessible.
106
62
 
107
- ```
108
- +------------------+
109
- | AI Employee |
110
- | (Team Lead) |
111
- +--------+---------+
112
- | input-teammates
113
- +-----------------+------------------+
114
- | | |
115
- +------v------+ +------v------+ +-------v-----+
116
- | Coding Agent| | Web Agent | | Task Agent |
117
- +-------------+ +-------------+ +-------------+
118
- ```
63
+ ### Agent teams that delegate
64
+ Hire an **AI Employee** as a team lead. Connect specialized agents — a Coding Agent, a Web Agent, a Productivity Agent — and the team lead automatically figures out who to delegate which subtask to. Each agent has its own memory, tools, and skills.
119
65
 
120
- - **AI Employee / Orchestrator** - Team lead agents for coordinating multiple specialized agents
121
- - **Intelligent Delegation** - AI decides when to delegate based on task context
122
- - **Delegation Tools** - Connected agents become `delegate_to_*` tools automatically
123
- - **16 Specialized Agents** - Android, Coding, Web, Task, Social, Travel, Tool, Productivity, Payments, Consumer, Autonomous, Orchestrator, AI Employee, RLM, Claude Code, Deep Agent
124
- - **Team Monitor** - Real-time visualization of team operations
66
+ ### Task automations that run themselves
67
+ Schedule recurring jobs ("every weekday at 9 AM, summarize my unread emails"), respond to incoming events ("when a customer texts on WhatsApp, draft a reply"), or build complex multi-step pipelines that run in the background. Workflows run reliably even if your computer restarts.
125
68
 
126
- ### Run Code & Manage Processes
127
- - Execute Python, JavaScript, and TypeScript code
128
- - Persistent Node.js server for fast JS/TS execution
129
- - **Process Manager** - Start, stop, and manage long-running processes (dev servers, watchers, build tools) with output streaming to Terminal tab
130
- - OS-specific terminal skills (Bash, PowerShell, WSL)
69
+ ### Email, calendar, and document workflows
70
+ - Send and search Gmail, schedule and update Calendar events
71
+ - Upload to Drive, edit Sheets, manage Tasks and Contacts
72
+ - Read inbox via IMAP from Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, or any custom server
73
+ - Parse PDFs and documents into searchable knowledge bases
131
74
 
132
- ## Visual Workflow Builder
75
+ ### Messaging across every platform
76
+ Send and receive on **WhatsApp** (with newsletter channels, groups, contacts), **Telegram** (with bot owner detection), **Twitter/X** (post, reply, search, look up users), and a unified social node that abstracts over Discord, Slack, Signal, SMS, Matrix, Teams, and more.
133
77
 
134
- Drag-and-drop interface to connect AI models, services, and triggers. No code required.
78
+ ### Phone control from a workflow
79
+ Pair your Android phone via QR code and control it from any agent: read battery + network status, launch apps, toggle WiFi / Bluetooth / airplane mode, take photos, read environmental sensors, manage media playback. 16 device services available.
135
80
 
136
- ## Configuration
81
+ ### Web automation & research
82
+ - **Interactive browser** with accessibility-tree navigation (click, type, screenshot) — your agent can use websites the way you do
83
+ - **Web scraping** with Crawlee (static + JavaScript-rendered pages) and Apify actors (Instagram, TikTok, LinkedIn, Facebook, YouTube, Google Search)
84
+ - **Search APIs**: DuckDuckGo (free), Brave, Serper (Google), Perplexity (AI answers with citations)
85
+ - **Residential proxies** with geo-targeting and automatic provider rotation
137
86
 
138
- Click **Credentials** in the toolbar to add your API keys for AI providers, Google, WhatsApp, and Twitter.
87
+ ### Code execution that's actually safe
88
+ Run Python, JavaScript, and TypeScript code from any workflow. Each workflow gets its own isolated workspace folder — no chance of an agent touching files outside its sandbox. The **Process Manager** node owns long-running tasks like dev servers, builds, and watchers, with live output streaming to a Terminal tab in the UI.
139
89
 
140
- ## Documentation
90
+ ### Pay bills, take payments
91
+ **Stripe** integration with action node (charge customers, manage subscriptions) and webhook receiver (react to payment events in real time). Same pattern works for any service with a CLI.
141
92
 
142
- Full docs: https://docs.zeenie.xyz/
93
+ ### Build your own knowledge base
94
+ RAG pipeline out of the box: parse PDFs and HTML, chunk into searchable pieces, embed locally or via OpenAI, store in ChromaDB / Qdrant / Pinecone, and query from any agent.
143
95
 
144
- ## Community
96
+ ## AI Capabilities
97
+
98
+ ### 11 LLM providers — bring your own keys or run locally
99
+
100
+ | Provider | Notes |
101
+ |--------------|--------------------------------------------------------------------------|
102
+ | OpenAI | GPT-5 family, GPT-4.1, o-series reasoning models, GPT-4o |
103
+ | Anthropic | Claude Opus 4.x, Sonnet 4.x, Haiku 4.5 — with extended thinking |
104
+ | Google | Gemini 3 Pro/Flash, 2.5 Pro/Flash — with reasoning budgets |
105
+ | DeepSeek | DeepSeek V3, DeepSeek Reasoner |
106
+ | Kimi | Kimi K2.5, Kimi K2 Thinking |
107
+ | Mistral | Mistral Large/Small, Codestral |
108
+ | Groq | Llama 3/4, Qwen3, GPT-OSS (ultra-fast inference) |
109
+ | Cerebras | Llama 3.1, Qwen-3-235b (custom AI hardware) |
110
+ | OpenRouter | 200+ models via one unified API |
111
+ | **Ollama** | Run any local model on your machine — free, private, offline |
112
+ | **LM Studio**| Run any local model with a desktop app — free, private, offline |
113
+
114
+ Local providers (Ollama, LM Studio) are first-class — context length, vision support, and tool-use capability are detected automatically from your running server. No paid API needed.
115
+
116
+ ### 17 specialized agent types
117
+
118
+ Pick the right agent for the job:
119
+
120
+ | Agent | Specialized for |
121
+ |--------------------|--------------------------------------------------------------------------|
122
+ | **AI Employee** / **Orchestrator** | Team leads that coordinate other agents |
123
+ | Android Agent | Phone control |
124
+ | Web Agent | Browser automation, scraping, search |
125
+ | Coding Agent | Writing and running code (Python / JS / TS) |
126
+ | Productivity Agent | Gmail, Calendar, Drive, Sheets, Tasks, Contacts |
127
+ | Social Agent | WhatsApp, Telegram, Twitter messaging |
128
+ | Task Agent | Scheduling, reminders, cron jobs |
129
+ | Travel Agent | Maps, location lookup, planning |
130
+ | Payments Agent | Stripe + financial workflows |
131
+ | Consumer Agent | Customer support, order management |
132
+ | Deep Agent | LangChain DeepAgents with filesystem tools + sub-agent delegation |
133
+ | Claude Code Agent | Anthropic's Claude Code CLI for advanced coding sessions |
134
+ | Codex Agent | OpenAI Codex CLI integration |
135
+ | RLM Agent | Recursive Language Model — write code that calls itself recursively |
136
+ | Autonomous Agent | Code-mode loops that reduce token usage 80-98% |
137
+ | Tool Agent | General-purpose tool orchestration |
138
+
139
+ Team leads automatically expose every connected agent as a `delegate_to_*` tool — the AI decides who to hand work off to based on the task.
140
+
141
+ ### Skills you can edit yourself
145
142
 
146
- Join our [Discord](https://discord.gg/NHUEQVSC) for help, feedback, and updates.
143
+ Skills are short markdown files that teach an agent how to do something well — when to use which tool, what arguments to pass, common mistakes to avoid. Edit them in the UI; the changes apply immediately. Built-in skills cover Android control, Google Workspace, social messaging, web research, coding, terminal use (Bash, PowerShell, WSL, Nushell), and more.
147
144
 
148
- ## Contributing
145
+ ### Memory that scales with your context window
146
+
147
+ Agents track token usage and automatically compact long conversations when you hit half your model's context limit. Compaction summarizes in five sections — Task Overview, Current State, Important Discoveries, Next Steps, Context to Preserve — so the agent picks up exactly where it left off. For Anthropic and OpenAI, native API compaction is used; everywhere else, the agent summarizes itself.
148
+
149
+ ### Cost tracking, built in
150
+
151
+ Every LLM call and API request is tracked with USD cost. See per-provider spend in the Credentials panel. Configure your own pricing in `pricing.json` if you switch providers mid-flight.
152
+
153
+ ## The Canvas
154
+
155
+ - **10 visual themes** — light, dark, Renaissance, Greek, Edo, Steampunk, Atomic, Cyber, Wasteland, Rot, Plague, Surveillance — each with its own icon set, sound pack, and decorative ornaments. Pick the vibe that matches your workflow.
156
+ - **Drag-to-map outputs** from one node's output directly onto another's input fields.
157
+ - **Live execution animations** — nodes glow while running, show iteration count for AI agents, and surface errors inline.
158
+ - **Multi-tab Console** — chat with trigger nodes, watch console logs, and view terminal output side by side.
159
+ - **Component palette** with search, categories, and a Normal/Dev mode toggle that hides advanced nodes when you don't need them.
160
+ - **5-step onboarding wizard** for first-time users, replayable any time from Settings.
161
+
162
+ ## Quick Setup Tour
163
+
164
+ 1. **Install** with `npm install -g machinaos` (or run from source)
165
+ 2. **Start** with `machina start` — opens at http://localhost:3000
166
+ 3. **Connect a provider** — click the **Credentials** button, paste an API key or click through OAuth
167
+ 4. **Drag a node** from the left palette onto the canvas
168
+ 5. **Connect** outputs to inputs by dragging between handles
169
+ 6. **Run** by clicking the play button on any node, or **Deploy** the whole workflow to run on its own forever
170
+
171
+ If anything goes wrong, the [Discord](https://discord.gg/c9pCJ7d8Ce) community is the fastest way to get help.
172
+
173
+ ## For Developers
174
+
175
+ Want to add a node, LLM provider, skill, or integration? One Python file = one node. The backend owns all the schemas; the frontend renders from them automatically. No frontend code required for most extensions.
176
+
177
+ - **[CONTRIBUTING.md](CONTRIBUTING.md)** — codebase map, architecture diagrams, contribution recipes
178
+ - **[server/nodes/README.md](server/nodes/README.md)** — 5-minute plugin recipe + folder map
179
+ - **[docs-internal/](docs-internal/)** — deep-dive architecture docs (execution engine, Temporal, LLM layer, credentials, event system, performance, build pipeline)
180
+ - **[CLAUDE.md](CLAUDE.md)** — comprehensive project memory (great for AI-assisted contributions)
181
+ - **Hosted docs:** https://docs.zeenie.xyz/
182
+ - **DeepWiki:** https://deepwiki.com/trohitg/MachinaOS
183
+
184
+ ## Community
149
185
 
150
- Want to add a node, LLM provider, skill, or integration? See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the codebase map, architecture diagrams, development setup, and step-by-step recipes for common contributions.
186
+ [Discord](https://discord.gg/c9pCJ7d8Ce) help, feature requests, and design discussions.
151
187
 
152
188
  ## License
153
189
 
@@ -0,0 +1 @@
1
+ import{f as u,n as d,o as p,p as m,q as f,r as g,k as x}from"./index-DNx1tG6T.js";import{j as l}from"./vendor-radix-BGeDhy8U.js";import{ac as b}from"./vendor-icons-BPyNc2rK.js";function h(r){const t=u.c(7),a=d(),n=p(),s=m(),i=f(),o=g();if(!r)return null;let e;return t[0]!==n||t[1]!==i||t[2]!==r||t[3]!==s||t[4]!==o||t[5]!==a?(e={whatsapp:a,android:n,twitter:s,google:i,telegram:o}[r]??null,t[0]=n,t[1]=i,t[2]=r,t[3]=s,t[4]=o,t[5]=a,t[6]=e):e=t[6],e}const y=r=>{const t=u.c(7),{actions:a,loading:n}=r;let s;if(t[0]!==a||t[1]!==n){let o;t[3]!==n?(o=e=>{const c=n===e.key;return l.jsxs(x,{intent:e.intent,onClick:e.onClick,disabled:e.disabled||c,children:[c?l.jsx(b,{className:"h-4 w-4 animate-spin"}):e.icon,e.label]},e.key)},t[3]=n,t[4]=o):o=t[4],s=a.filter(j).map(o),t[0]=a,t[1]=n,t[2]=s}else s=t[2];let i;return t[5]!==s?(i=l.jsx("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:s}),t[5]=s,t[6]=i):i=t[6],i};function j(r){return!r.hidden}export{y as A,h as u};
@@ -0,0 +1 @@
1
+ import{j as s}from"./vendor-radix-BGeDhy8U.js";import{b as j}from"./vendor-react-CxXU_nq3.js";import{I as u,B as c}from"./index-DNx1tG6T.js";import{bb as d,bc as N,ac as b,aj as v,ap as w,aa as y}from"./vendor-icons-BPyNc2rK.js";const I=({value:l,onChange:n,onSave:m,onDelete:i,placeholder:x="Enter API key...",loading:o=!1,isStored:a=!1,disabled:e=!1,saveLabel:h="Validate",savedLabel:p="Valid"})=>{const[t,f]=j.useState(!1);return s.jsxs("div",{className:"flex w-full items-stretch gap-1",children:[s.jsxs("div",{className:"relative flex-1",children:[s.jsx(u,{type:t?"text":"password",value:l,onChange:r=>n(r.target.value),placeholder:x,disabled:e,className:"font-mono pr-9"}),s.jsx("button",{type:"button",onClick:()=>f(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide key":"Show key",children:t?s.jsx(d,{className:"h-4 w-4"}):s.jsx(N,{className:"h-4 w-4"})})]}),s.jsxs(c,{variant:"default",onClick:m,disabled:!l.trim()||e||o,children:[o?s.jsx(b,{className:"h-4 w-4 animate-spin"}):a?s.jsx(v,{className:"h-4 w-4"}):s.jsx(w,{className:"h-4 w-4"}),a?p:h]}),a&&i&&s.jsx(c,{variant:"destructive",size:"icon",onClick:i,disabled:e,children:s.jsx(y,{className:"h-4 w-4"})})]})};export{I as A};
@@ -0,0 +1 @@
1
+ import{j as s}from"./vendor-radix-BGeDhy8U.js";import{u as E,A as V,a as P,b as U,c as z,d as R,e as K,B as H,f as F,N as M,C as O,g as q,h as G,i as I,j as T,L as J,I as Q,k as W}from"./index-DNx1tG6T.js";import{A as X}from"./ApiKeyInput-DljozMIZ.js";import{u as Y,P as Z}from"./RateLimitSection-B2lBVQs0.js";import{b as A}from"./vendor-react-CxXU_nq3.js";import{ba as ee,ac as L,b7 as se,aj as ae}from"./vendor-icons-BPyNc2rK.js";import{A as te}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const D=N=>{const e=F.c(8),{label:t,value:p,className:a}=N;let l;e[0]!==t?(l=s.jsx("span",{className:"text-xs text-muted-foreground",children:t}),e[0]=t,e[1]=l):l=e[1];const n=`text-lg font-semibold ${a??""}`;let i;e[2]!==n||e[3]!==p?(i=s.jsx("span",{className:n,children:p}),e[2]=n,e[3]=p,e[4]=i):i=e[4];let o;return e[5]!==l||e[6]!==i?(o=s.jsxs("div",{className:"flex flex-col",children:[l,i]}),e[5]=l,e[6]=i,e[7]=o):o=e[7],o},le=({providerId:N,providerName:e})=>{const{getProviderUsageSummary:t,isConnected:p}=E(),[a,l]=A.useState(null),[n,i]=A.useState(!1),[o,h]=A.useState(!1),d=A.useCallback(async()=>{if(p){i(!0);try{const r=await t();l(r.find(c=>c.provider===N)??null)}finally{i(!1)}}},[p,N,t]);return A.useEffect(()=>{o&&d()},[o,d]),s.jsx(V,{type:"single",collapsible:!0,onValueChange:r=>h(r==="usage"),children:s.jsxs(P,{value:"usage",children:[s.jsx(U,{children:s.jsxs("span",{className:"flex items-center gap-2",children:[s.jsx(ee,{className:"h-4 w-4"})," Usage & Costs"]})}),s.jsx(z,{children:n?s.jsx("div",{className:"flex justify-center p-4",children:s.jsx(L,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):!a||a.execution_count===0?s.jsx(R,{variant:"info",children:s.jsxs(K,{children:["No usage data yet for ",e]})}):s.jsxs("div",{className:"flex w-full flex-col gap-4",children:[s.jsxs("div",{className:"flex flex-wrap gap-4",children:[s.jsx(D,{label:"Total Tokens",value:a.total_tokens.toLocaleString(),className:"text-dracula-cyan"}),s.jsx(D,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),s.jsx(D,{label:"Executions",value:a.execution_count,className:"text-dracula-purple"})]}),s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsxs("div",{className:"grid grid-cols-2 divide-x divide-border border-b border-border",children:[s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Input Tokens"}),s.jsxs("div",{children:[a.total_input_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_input_cost.toFixed(4),")"]})]})]}),s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("div",{className:"text-xs text-muted-foreground",children:"Output Tokens"}),s.jsxs("div",{children:[a.total_output_tokens.toLocaleString()," ",s.jsxs("span",{className:"ml-1 text-dracula-green",children:["($",a.total_output_cost.toFixed(4),")"]})]})]})]}),a.total_cache_cost>0&&s.jsxs("div",{className:"px-3 py-2 text-sm",children:[s.jsx("span",{className:"text-xs text-muted-foreground",children:"Cache Cost: "}),s.jsxs("span",{className:"text-dracula-green",children:["$",a.total_cache_cost.toFixed(4)]})]})]}),a.models.length>1&&s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[s.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"By Model"}),s.jsx("div",{className:"divide-y divide-border",children:a.models.map(r=>s.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[s.jsx("code",{className:"text-xs",children:r.model}),s.jsxs("span",{className:"text-dracula-green",children:["$",r.total_cost.toFixed(4)]})]},r.model))})]}),s.jsxs(H,{size:"sm",variant:"outline",onClick:d,disabled:n,children:[n?s.jsx(L,{className:"h-3 w-3 animate-spin"}):s.jsx(se,{className:"h-3 w-3"}),"Refresh"]})]})})]})})},ve=N=>{const e=F.c(71),{config:t,visible:p}=N,a=Y(t,p),l=t.fields?.[0];let n,i,o,h;if(e[0]!==t.color||e[1]!==t.fields||e[2]!==t.iconRef||e[3]!==t.id||e[4]!==t.name||e[5]!==l||e[6]!==a.actions||e[7]!==a.error||e[8]!==a.form||e[9]!==a.loading||e[10]!==a.stored||e[11]!==a.values){const _=(t.fields??[]).slice(1),g=l?a.values[l.key]??"":"",x=a.stored;n="flex flex-col gap-5 p-5";let m;e[16]!==t.color?(m={color:t.color},e[16]=t.color,e[17]=m):m=e[17];let u;e[18]!==t.iconRef?(u=s.jsx(M,{icon:t.iconRef,className:"h-12 w-12 text-2xl"}),e[18]=t.iconRef,e[19]=u):u=e[19];let f;e[20]!==m||e[21]!==u?(f=s.jsx("div",{className:"rounded-lg bg-tint-soft",style:m,children:u}),e[20]=m,e[21]=u,e[22]=f):f=e[22];let j;e[23]!==t.name?(j=s.jsx(O,{className:"text-lg",children:t.name}),e[23]=t.name,e[24]=j):j=e[24];let b;e[25]!==f||e[26]!==j?(b=s.jsxs("div",{className:"flex items-center gap-3",children:[f,j]}),e[25]=f,e[26]=j,e[27]=b):b=e[27];let C;e[28]!==x?(C=x&&s.jsxs(q,{variant:"success",className:"gap-1",children:[s.jsx(ae,{className:"h-3 w-3"}),"Connected"]}),e[28]=x,e[29]=C):C=e[29];let k;e[30]!==C||e[31]!==b?(k=s.jsxs(G,{className:"flex flex-row items-center justify-between gap-3 space-y-0 pb-3",children:[b,C]}),e[30]=C,e[31]=b,e[32]=k):k=e[32];let S;e[33]!==t.id||e[34]!==l||e[35]!==g||e[36]!==a.actions||e[37]!==a.form||e[38]!==a.loading||e[39]!==x?(S=l&&s.jsx(X,{value:g,onChange:v=>a.form.setFieldValue(l.key,v),onSave:()=>a.actions.validate(t.id,g.trim()),onDelete:x?async()=>{await a.actions.remove(t.id),l.key!=="apiKey"&&await a.actions.remove(l.key)}:void 0,placeholder:l.placeholder,loading:a.loading==="validate",isStored:x,saveLabel:l.key==="apiKey"?"Validate":"Fetch",savedLabel:l.key==="apiKey"?"Valid":"Connected"}),e[33]=t.id,e[34]=l,e[35]=g,e[36]=a.actions,e[37]=a.form,e[38]=a.loading,e[39]=x,e[40]=S):S=e[40];let w;e[41]!==S?(w=s.jsx(I,{children:S}),e[41]=S,e[42]=w):w=e[42],e[43]!==k||e[44]!==w?(i=s.jsxs(T,{children:[k,w]}),e[43]=k,e[44]=w,e[45]=i):i=e[45],e[46]!==a.error?(o=a.error&&s.jsx(R,{variant:"destructive",children:s.jsx(K,{children:a.error})}),e[46]=a.error,e[47]=o):o=e[47];let $;e[48]!==a.actions||e[49]!==a.form||e[50]!==a.loading||e[51]!==a.values?($=v=>s.jsx(ie,{fieldKey:v.key,label:v.label,placeholder:v.placeholder,help:v.help,secret:v.secret,value:a.values[v.key]??"",onChange:B=>a.form.setFieldValue(v.key,B),onSave:()=>a.actions.save(v.key,a.values[v.key]??""),loading:a.loading==="save"},v.key),e[48]=a.actions,e[49]=a.form,e[50]=a.loading,e[51]=a.values,e[52]=$):$=e[52],h=_.map($),e[0]=t.color,e[1]=t.fields,e[2]=t.iconRef,e[3]=t.id,e[4]=t.name,e[5]=l,e[6]=a.actions,e[7]=a.error,e[8]=a.form,e[9]=a.loading,e[10]=a.stored,e[11]=a.values,e[12]=n,e[13]=i,e[14]=o,e[15]=h}else n=e[12],i=e[13],o=e[14],h=e[15];let d;e[53]!==t.hasDefaults||e[54]!==t.id?(d=t.hasDefaults&&s.jsx(Z,{providerId:t.id}),e[53]=t.hasDefaults,e[54]=t.id,e[55]=d):d=e[55];let r;e[56]!==t.hasDefaults||e[57]!==t.id||e[58]!==t.name?(r=t.hasDefaults&&s.jsx(le,{providerId:t.id,providerName:t.name}),e[56]=t.hasDefaults,e[57]=t.id,e[58]=t.name,e[59]=r):r=e[59];let c;e[60]!==t.name||e[61]!==t.usageService?(c=t.usageService&&s.jsx(te,{service:t.usageService,serviceName:t.name}),e[60]=t.name,e[61]=t.usageService,e[62]=c):c=e[62];let y;return e[63]!==n||e[64]!==i||e[65]!==o||e[66]!==h||e[67]!==d||e[68]!==r||e[69]!==c?(y=s.jsxs("div",{className:n,children:[i,o,h,d,r,c]}),e[63]=n,e[64]=i,e[65]=o,e[66]=h,e[67]=d,e[68]=r,e[69]=c,e[70]=y):y=e[70],y},ie=N=>{const e=F.c(23),{fieldKey:t,label:p,placeholder:a,help:l,secret:n,value:i,onChange:o,onSave:h,loading:d}=N,r=`cred-${t}`;let c;e[0]!==p||e[1]!==r?(c=s.jsx(J,{htmlFor:r,className:"text-sm font-medium",children:p}),e[0]=p,e[1]=r,e[2]=c):c=e[2];const y=`cred-${t}`,_=n?"password":"text";let g;e[3]!==o?(g=b=>o(b.target.value),e[3]=o,e[4]=g):g=e[4];let x;e[5]!==a||e[6]!==y||e[7]!==_||e[8]!==g||e[9]!==i?(x=s.jsx(Q,{id:y,type:_,value:i,onChange:g,placeholder:a,className:"flex-1"}),e[5]=a,e[6]=y,e[7]=_,e[8]=g,e[9]=i,e[10]=x):x=e[10];let m;e[11]!==d||e[12]!==h?(m=s.jsx(W,{intent:"save",onClick:h,disabled:d,children:"Save"}),e[11]=d,e[12]=h,e[13]=m):m=e[13];let u;e[14]!==x||e[15]!==m?(u=s.jsxs("div",{className:"flex gap-2",children:[x,m]}),e[14]=x,e[15]=m,e[16]=u):u=e[16];let f;e[17]!==l?(f=l&&s.jsx("p",{className:"text-xs text-muted-foreground",children:l}),e[17]=l,e[18]=f):f=e[18];let j;return e[19]!==c||e[20]!==u||e[21]!==f?(j=s.jsx(T,{children:s.jsxs(I,{className:"flex flex-col gap-2 pt-4",children:[c,u,f]})}),e[19]=c,e[20]=u,e[21]=f,e[22]=j):j=e[22],j};export{ve as default};
@@ -0,0 +1 @@
1
+ import{j as e}from"./vendor-radix-BGeDhy8U.js";import{u as h,g as u,A as g,a as b,b as v,c as N,d as y,e as w,B as A,f as C}from"./index-DNx1tG6T.js";import{b as x}from"./vendor-react-CxXU_nq3.js";import{ba as _,ac as f,b7 as S}from"./vendor-icons-BPyNc2rK.js";const E=({service:d,serviceName:s})=>{const{getAPIUsageSummary:c,isConnected:i}=h(),[a,l]=x.useState(null),[o,t]=x.useState(!1),r=x.useCallback(async()=>{if(i){t(!0);try{const n=await c(d);l(n.find(j=>j.service===d)??null)}finally{t(!1)}}},[i,d,c]);x.useEffect(()=>{r()},[r]);const p=a?e.jsxs(u,{variant:"success",children:["$",a.total_cost.toFixed(4)]}):null;return e.jsx(g,{type:"single",collapsible:!0,children:e.jsxs(b,{value:"usage",children:[e.jsx(v,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(_,{className:"h-4 w-4 text-dracula-yellow"}),"API Usage & Costs ",p]})}),e.jsx(N,{children:o?e.jsx("div",{className:"flex justify-center p-4",children:e.jsx(f,{className:"h-4 w-4 animate-spin text-muted-foreground"})}):a?e.jsxs("div",{className:"flex w-full flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-wrap gap-4",children:[e.jsx(m,{label:"Total Cost",value:`$${a.total_cost.toFixed(4)}`,className:"text-dracula-green"}),e.jsx(m,{label:"API Calls",value:a.execution_count,className:"text-dracula-cyan"}),e.jsx(m,{label:"Resources",value:a.total_resources,className:"text-dracula-purple"})]}),a.operations?.length>0&&e.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[e.jsx("div",{className:"border-b border-border bg-muted px-3 py-1.5 text-xs font-semibold",children:"Operations Breakdown"}),e.jsx("div",{className:"divide-y divide-border",children:a.operations.map(n=>e.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[e.jsx("code",{className:"text-xs text-muted-foreground",children:n.operation}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(u,{variant:"outline",children:[n.resource_count," resources"]}),e.jsxs(u,{variant:"success",children:["$",n.total_cost.toFixed(4)]})]})]},n.operation))})]}),e.jsxs(A,{size:"sm",variant:"outline",onClick:r,disabled:o,children:[o?e.jsx(f,{className:"h-3 w-3 animate-spin"}):e.jsx(S,{className:"h-3 w-3"}),"Refresh"]})]}):e.jsx(y,{variant:"info",children:e.jsxs(w,{children:["No usage data yet. Use ",s," nodes in your workflows to track costs."]})})})]})})},m=d=>{const s=C.c(8),{label:c,value:i,className:a}=d;let l;s[0]!==c?(l=e.jsx("span",{className:"text-xs text-muted-foreground",children:c}),s[0]=c,s[1]=l):l=s[1];const o=`text-lg font-semibold ${a??""}`;let t;s[2]!==o||s[3]!==i?(t=e.jsx("span",{className:o,children:i}),s[2]=o,s[3]=i,s[4]=t):t=s[4];let r;return s[5]!==l||s[6]!==t?(r=e.jsxs("div",{className:"flex flex-col",children:[l,t]}),s[5]=l,s[6]=t,s[7]=r):r=s[7],r};export{E as A};
@@ -0,0 +1 @@
1
+ import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as l,h as B}from"./vendor-react-CxXU_nq3.js";import{v as G,P as I,R as j,_ as Y,T as z,u as J,t as Q,N as W,F as X,w as m,x as n,y as d,z as Z,D as c,E as $,G as ee,H as se,J as ae,M as p,I as f,K as re,d as oe,e as te,k as M}from"./index-DNx1tG6T.js";import{S as ie}from"./StatusCard-BlufvZD-.js";import{bb as le,bc as me,ac as F}from"./vendor-icons-BPyNc2rK.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const R=[{label:"Gmail",value:"gmail"},{label:"Outlook / Office 365",value:"outlook"},{label:"Yahoo Mail",value:"yahoo"},{label:"iCloud Mail",value:"icloud"},{label:"ProtonMail (Bridge)",value:"protonmail"},{label:"Fastmail",value:"fastmail"},{label:"Custom / Self-hosted",value:"custom"}],ne={gmail:"Use an App Password from Google Account > Security > 2-Step Verification.",outlook:"Use your account password or an App Password.",yahoo:"Use an App Password from Yahoo Account Security.",icloud:"Use an App-Specific Password from your Apple ID.",protonmail:"Requires ProtonMail Bridge running locally (127.0.0.1).",fastmail:"Use an App Password from Settings > Privacy & Security.",custom:"Enter credentials for your self-hosted IMAP/SMTP server below."},de=R.map(u=>u.value);function ce(u){return G({provider:Y(de),address:j().min(1,"Email address is required").pipe(z("Enter a valid email address")),password:u?j().min(1,"Password is required"):j().optional(),imapHost:j().optional(),imapPort:I().int().min(1).max(65535).optional(),smtpHost:j().optional(),smtpPort:I().int().min(1).max(65535).optional()}).superRefine((x,o)=>{x.provider==="custom"&&(x.imapHost?.trim()||o.addIssue({code:"custom",path:["imapHost"],message:"IMAP host is required for custom provider"}),x.smtpHost?.trim()||o.addIssue({code:"custom",path:["smtpHost"],message:"SMTP host is required for custom provider"}))})}const T={provider:"gmail",address:"",password:"",imapHost:"",imapPort:993,smtpHost:"",smtpPort:465},we=({config:u,visible:x})=>{const{saveApiKey:o,getStoredApiKey:h,hasStoredKey:k,removeApiKey:t,isConnected:_}=J(),[i,v]=l.useState(!1),[b,S]=l.useState(""),[P,g]=l.useState(null),[N,w]=l.useState(null),[y,U]=l.useState(!1),V=l.useMemo(()=>ce(!i),[i]),r=B({resolver:Q(V),defaultValues:T,mode:"onSubmit"}),A=r.watch("provider");l.useEffect(()=>{if(!x||!_)return;let s=!1;return(async()=>{try{const[a,H,K,L,E,q,C]=await Promise.all([h("email_provider"),h("email_address"),k("email_password"),h("email_imap_host"),h("email_imap_port"),h("email_smtp_host"),h("email_smtp_port")]);if(s)return;r.reset({provider:a||"gmail",address:H||"",password:"",imapHost:L||"",imapPort:E?parseInt(E,10):993,smtpHost:q||"",smtpPort:C?parseInt(C,10):465}),S(H||""),v(K)}catch{s||v(!1)}})(),()=>{s=!0}},[x,_]);const O=async s=>{g("save"),w(null);try{await o("email_provider",s.provider),await o("email_address",s.address.trim()),s.password?.trim()&&await o("email_password",s.password.trim()),s.provider==="custom"&&(s.imapHost&&await o("email_imap_host",s.imapHost.trim()),s.imapPort!=null&&await o("email_imap_port",String(s.imapPort)),s.smtpHost&&await o("email_smtp_host",s.smtpHost.trim()),s.smtpPort!=null&&await o("email_smtp_port",String(s.smtpPort))),v(!0),S(s.address.trim()),r.setValue("password","")}catch(a){w(a.message||"Failed to save email credentials")}finally{g(null)}},D=async()=>{g("remove"),w(null);try{await Promise.all([t("email_password"),t("email_address"),t("email_provider"),t("email_imap_host"),t("email_imap_port"),t("email_smtp_host"),t("email_smtp_port")]),v(!1),S(""),r.reset(T)}catch(s){w(s.message||"Failed to remove credentials")}finally{g(null)}};return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[e.jsx(ie,{icon:e.jsx(W,{icon:u.iconRef,className:"h-6 w-6 text-2xl"}),title:u.name,status:{stored:i,address:b},rows:[{label:"Status",ok:s=>s.stored,trueText:"Configured",falseText:"Not configured"},...i&&b?[{label:"Account",ok:()=>!0,trueText:b,falseText:""}]:[]]}),e.jsx(X,{...r,children:e.jsxs("form",{id:"email-form",onSubmit:r.handleSubmit(O),className:"flex flex-col gap-4",children:[e.jsx(m,{control:r.control,name:"provider",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Provider"}),e.jsxs(Z,{value:s.value,onValueChange:s.onChange,children:[e.jsx(c,{children:e.jsx($,{children:e.jsx(ee,{placeholder:"Choose a provider"})})}),e.jsx(se,{children:R.map(a=>e.jsx(ae,{value:a.value,children:a.label},a.value))})]}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"address",render:({field:s})=>e.jsxs(n,{children:[e.jsx(d,{children:"Email Address"}),e.jsx(c,{children:e.jsx(f,{placeholder:"you@example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"password",render:({field:s})=>e.jsxs(n,{children:[e.jsxs(d,{className:"flex items-center gap-2",children:["Password",i&&e.jsx("span",{className:"text-xs font-normal text-muted-foreground",children:"(leave blank to keep existing)"})]}),e.jsx(c,{children:e.jsxs("div",{className:"relative",children:[e.jsx(f,{type:y?"text":"password",placeholder:i?"••••••••":"App password or account password",className:"font-mono pr-9",...s}),e.jsx("button",{type:"button",onClick:()=>U(a=>!a),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":y?"Hide password":"Show password",children:y?e.jsx(le,{className:"h-4 w-4"}):e.jsx(me,{className:"h-4 w-4"})})]})}),e.jsx(re,{children:ne[A]}),e.jsx(p,{})]})}),A==="custom"&&e.jsxs("div",{className:"rounded-md border border-border bg-muted p-3",children:[e.jsx("div",{className:"mb-3 text-sm font-medium",children:"Custom IMAP / SMTP"}),e.jsxs("div",{className:"flex gap-3",children:[e.jsx(m,{control:r.control,name:"imapHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"IMAP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"imap.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"imapPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"IMAP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]}),e.jsxs("div",{className:"mt-3 flex gap-3",children:[e.jsx(m,{control:r.control,name:"smtpHost",render:({field:s})=>e.jsxs(n,{className:"flex-[2]",children:[e.jsx(d,{children:"SMTP Host"}),e.jsx(c,{children:e.jsx(f,{placeholder:"smtp.example.com",...s})}),e.jsx(p,{})]})}),e.jsx(m,{control:r.control,name:"smtpPort",render:({field:s})=>e.jsxs(n,{className:"flex-1",children:[e.jsx(d,{children:"SMTP Port"}),e.jsx(c,{children:e.jsx(f,{type:"number",min:1,max:65535,...s,value:s.value??"",onChange:a=>s.onChange(a.target.value===""?void 0:Number(a.target.value))})}),e.jsx(p,{})]})})]})]})]})}),N&&e.jsx(oe,{variant:"destructive",children:e.jsx(te,{children:N})}),e.jsx("div",{className:"flex-1"}),e.jsxs("div",{className:"flex justify-center gap-2 border-t border-border pt-3",children:[e.jsxs(M,{intent:"save",type:"submit",form:"email-form",disabled:P==="save",children:[P==="save"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Save"]}),i&&e.jsxs(M,{intent:"stop",type:"button",onClick:D,disabled:P==="remove",children:[P==="remove"&&e.jsx(F,{className:"h-4 w-4 animate-spin"}),"Remove"]})]})]})};export{we as default};
@@ -0,0 +1 @@
1
+ import{j as l}from"./vendor-radix-BGeDhy8U.js";import{f as O,L as P,I as B,k as D,d as H,e as z,N as Y}from"./index-DNx1tG6T.js";import{u as G}from"./RateLimitSection-B2lBVQs0.js";import{A as J,u as K}from"./ActionBar-DAHXJmEU.js";import{b as I}from"./vendor-react-CxXU_nq3.js";import{bb as M,bc as Q,ac as W,aq as X}from"./vendor-icons-BPyNc2rK.js";import{S as Z}from"./StatusCard-BlufvZD-.js";import{A as ee}from"./ApiUsageSection-FWVtg8Sd.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-misc-4my8ai2A.js";import"./vendor-markdown-Bx_GU1E7.js";const te=i=>{const e=O.c(7),{fields:t,form:c}=i;let s;if(e[0]!==t||e[1]!==c){let n;e[3]!==c?(n=o=>l.jsx(se,{field:o,form:c},o.key),e[3]=c,e[4]=n):n=e[4],s=t.map(n),e[0]=t,e[1]=c,e[2]=s}else s=e[2];let a;return e[5]!==s?(a=l.jsx("div",{className:"flex w-full flex-col gap-3",children:s}),e[5]=s,e[6]=a):a=e[6],a},se=({field:i,form:e})=>{const[t,c]=I.useState(!1),s=e.getFieldValue(i.key)??"",[a,n]=I.useState(s),o=!!i.secret;return I.useEffect(()=>{!a&&s&&n(s)},[s]),l.jsxs("div",{className:"grid gap-1.5",children:[l.jsxs(P,{htmlFor:`field-${i.key}`,className:"text-xs",children:[i.label,i.required&&l.jsx("span",{className:"ml-1 text-destructive",children:"*"})]}),l.jsxs("div",{className:"relative",children:[l.jsx(B,{id:`field-${i.key}`,type:o&&!t?"password":"text",value:a,onChange:r=>{const d=r.target.value;n(d),e.setFieldValue(i.key,d)},placeholder:i.placeholder,className:o?"font-mono pr-9":"font-mono"}),o&&l.jsx("button",{type:"button",onClick:()=>c(r=>!r),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":t?"Hide value":"Show value",children:t?l.jsx(M,{className:"h-4 w-4"}):l.jsx(Q,{className:"h-4 w-4"})})]})]})},le=i=>{const e=O.c(50),{config:t,form:c,connected:s,stored:a,loading:n,error:o,icon:r,onSaveCredentials:d,onLogin:u,onLogout:m,onRefresh:x,extraSection:h}=i,g=!!t.fields?.length;let v;e[0]!==s?(v={label:"Status",ok:()=>s,trueText:"Connected",falseText:"Not Connected"},e[0]=s,e[1]=v):v=e[1];let f;e[2]!==g||e[3]!==a?(f=g?[{label:"Credentials",ok:()=>a,trueText:"Configured",falseText:"Not configured"}]:[],e[2]=g,e[3]=a,e[4]=f):f=e[4];let p;e[5]!==v||e[6]!==f?(p=[v,...f],e[5]=v,e[6]=f,e[7]=p):p=e[7];const E=p,_=`Login with ${t.name}`,U=g&&!a;let b;e[8]!==s||e[9]!==u||e[10]!==_||e[11]!==U?(b={key:"login",label:_,intent:"save",onClick:u,disabled:U,hidden:s},e[8]=s,e[9]=u,e[10]=_,e[11]=U,e[12]=b):b=e[12];const V=!s;let j;e[13]!==m||e[14]!==V?(j={key:"logout",label:"Disconnect",intent:"stop",onClick:m,hidden:V},e[13]=m,e[14]=V,e[15]=j):j=e[15];let R;e[16]===Symbol.for("react.memo_cache_sentinel")?(R=l.jsx(X,{className:"h-4 w-4"}),e[16]=R):R=e[16];let k;e[17]!==x?(k={key:"refresh",label:"Refresh",intent:"save",onClick:x,icon:R},e[17]=x,e[18]=k):k=e[18];let L;e[19]!==k||e[20]!==b||e[21]!==j?(L=[b,j,k],e[19]=k,e[20]=b,e[21]=j,e[22]=L):L=e[22];const q=L,A=n==="save";let N;e[23]!==t.name||e[24]!==r||e[25]!==E?(N=l.jsx(Z,{icon:r,title:t.name,rows:E,status:null}),e[23]=t.name,e[24]=r,e[25]=E,e[26]=N):N=e[26];let S;e[27]!==t.callbackUrl||e[28]!==t.fields||e[29]!==t.instructions||e[30]!==s||e[31]!==c||e[32]!==A||e[33]!==d?(S=!s&&t.fields&&l.jsxs("div",{className:"flex w-full flex-col gap-3",children:[l.jsx(te,{fields:t.fields,form:c}),l.jsxs(D,{intent:"secret",onClick:d,disabled:A,children:[A&&l.jsx(W,{className:"h-4 w-4 animate-spin"}),"Save Credentials"]}),t.instructions&&l.jsxs("div",{className:"text-xs leading-relaxed text-muted-foreground",children:[t.instructions,t.callbackUrl&&l.jsxs(l.Fragment,{children:[l.jsx("br",{}),"Callback URL:"," ",l.jsx("code",{className:"text-accent",children:t.callbackUrl})]})]})]}),e[27]=t.callbackUrl,e[28]=t.fields,e[29]=t.instructions,e[30]=s,e[31]=c,e[32]=A,e[33]=d,e[34]=S):S=e[34];let C;e[35]!==o?(C=o&&l.jsx(H,{variant:"destructive",children:l.jsx(z,{children:o})}),e[35]=o,e[36]=C):C=e[36];const T=s?t.account_label?`Connected as ${t.account_label}.`:`Your ${t.name} account is connected.`:a||!g?"Click Login to authorize.":"Enter your credentials above to get started.";let y;e[37]!==T?(y=l.jsx("div",{className:"rounded-md border border-accent/30 bg-accent/10 p-3",children:l.jsx("div",{className:"text-sm leading-relaxed text-muted-foreground",children:T})}),e[37]=T,e[38]=y):y=e[38];let F;e[39]===Symbol.for("react.memo_cache_sentinel")?(F=l.jsx("div",{className:"flex-1"}),e[39]=F):F=e[39];let w;e[40]!==q||e[41]!==n?(w=l.jsx(J,{actions:q,loading:n}),e[40]=q,e[41]=n,e[42]=w):w=e[42];let $;return e[43]!==h||e[44]!==N||e[45]!==S||e[46]!==C||e[47]!==y||e[48]!==w?($=l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4",children:[N,S,C,y,h,F,w]}),e[43]=h,e[44]=N,e[45]=S,e[46]=C,e[47]=y,e[48]=w,e[49]=$):$=e[49],$},ge=i=>{const e=O.c(25),{config:t,visible:c}=i,s=G(t,c),a=K(t.statusHook),n=a?!!a.connected:!!t.stored;let o;e[0]!==t.iconRef?(o=l.jsx(Y,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),e[0]=t.iconRef,e[1]=o):o=e[1];let r;e[2]!==t.fields||e[3]!==s?(r=()=>{const g=t.fields?.find(f=>f.required&&!s.form.getFieldValue(f.key)?.trim());if(g){s.setError(`${g.label} is required`);return}const v=s.form.getFieldsValue();s.execute("save",async()=>{for(const f of t.fields){const p=v[f.key]?.trim();p&&await s.actions.save(f.key,p)}return s.setStored(!0),{success:!0}})},e[2]=t.fields,e[3]=s,e[4]=r):r=e[4];let d,u,m;e[5]!==s.actions?(d=()=>s.actions.oauthLogin(),u=()=>s.actions.oauthLogout(),m=()=>s.actions.oauthRefresh(),e[5]=s.actions,e[6]=d,e[7]=u,e[8]=m):(d=e[6],u=e[7],m=e[8]);let x;e[9]!==t.name||e[10]!==t.usageService?(x=t.usageService&&l.jsx(ee,{service:t.usageService,serviceName:t.name}),e[9]=t.name,e[10]=t.usageService,e[11]=x):x=e[11];let h;return e[12]!==t||e[13]!==n||e[14]!==s.error||e[15]!==s.form||e[16]!==s.loading||e[17]!==s.stored||e[18]!==o||e[19]!==r||e[20]!==d||e[21]!==u||e[22]!==m||e[23]!==x?(h=l.jsx("div",{className:"flex min-h-0 flex-1 flex-col p-5",children:l.jsx(le,{config:t,form:s.form,connected:n,stored:s.stored,loading:s.loading,error:s.error,icon:o,onSaveCredentials:r,onLogin:d,onLogout:u,onRefresh:m,extraSection:x})}),e[12]=t,e[13]=n,e[14]=s.error,e[15]=s.form,e[16]=s.loading,e[17]=s.stored,e[18]=o,e[19]=r,e[20]=d,e[21]=u,e[22]=m,e[23]=x,e[24]=h):h=e[24],h};export{ge as default};
@@ -0,0 +1 @@
1
+ import{j as e}from"./vendor-radix-BGeDhy8U.js";import{b as d,R as Q}from"./vendor-react-CxXU_nq3.js";import{d as S,l as k,e as _,m as w,N as A}from"./index-DNx1tG6T.js";import{A as v}from"./ApiKeyInput-DljozMIZ.js";import{Q as E}from"./vendor-misc-4my8ai2A.js";import{aj as W,ac as F,bd as M,ag as b}from"./vendor-icons-BPyNc2rK.js";import{u as T,R as q}from"./RateLimitSection-B2lBVQs0.js";import{u as L,A as D}from"./ActionBar-DAHXJmEU.js";import{S as P}from"./StatusCard-BlufvZD-.js";import"./vendor-flow-apeQB2hf.js";import"./vendor-query-to9T1kjL.js";import"./vendor-markdown-Bx_GU1E7.js";const V=t=>t.length<100?!1:t.startsWith("data:image/")||t.startsWith("iVBOR")||t.startsWith("/9j/")?!0:t.length>5e3?/^[A-Za-z0-9+/=]+$/.test(t):!1,B=({value:t,isConnected:c=!1,size:s=280,loading:a=!1,connectedTitle:u="Connected",connectedSubtitle:x="No QR code needed",emptyText:h="QR code not available"})=>{if(c)return e.jsxs("div",{className:"flex flex-col items-center gap-3 p-8 text-center",children:[e.jsx(W,{className:"h-10 w-10 text-success"}),e.jsx("div",{className:"text-base font-semibold",children:u}),e.jsx("div",{className:"text-sm text-muted-foreground",children:x})]});if(a)return e.jsxs("div",{className:"p-10 text-center",children:[e.jsx(F,{className:"mx-auto h-8 w-8 animate-spin text-muted-foreground"}),e.jsx("div",{className:"mt-4 text-sm text-muted-foreground",children:"Waiting for QR code..."})]});if(!t)return e.jsxs("div",{className:"p-10 text-center text-muted-foreground",children:[e.jsx(M,{className:"mx-auto h-12 w-12 opacity-30"}),e.jsx("div",{className:"mt-4",children:h})]});if(V(t)){const o=t.startsWith("data:")?t:`data:image/png;base64,${t}`;return e.jsx("div",{className:"p-4 text-center",children:e.jsx("img",{src:o,alt:"QR Code",style:{width:s,height:s,imageRendering:"pixelated"}})})}return e.jsx(I,{value:t,size:s})},I=({value:t,size:c})=>{const[s,a]=d.useState(null);return d.useEffect(()=>{a(null)},[t]),s?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):e.jsx(G,{onError:u=>a(u),children:e.jsx("div",{className:"p-4 text-center",children:e.jsx(E,{value:t,size:c,level:"L"})})})};class G extends Q.Component{constructor(c){super(c),this.state={hasError:!1}}static getDerivedStateFromError(c){return{hasError:!0}}componentDidCatch(c){console.error("[QRCodeDisplay] QR code rendering error:",c.message),this.props.onError(c.message)}render(){return this.state.hasError?e.jsx("div",{className:"p-6 text-center",children:e.jsxs(S,{variant:"warning",children:[e.jsx(b,{className:"h-4 w-4"}),e.jsx(k,{children:"QR Code Error"}),e.jsx(_,{children:"The QR code data is too large to display. Please try refreshing or reconnecting."})]})}):this.props.children}}const H=()=>{const{getWhatsAppStatus:t,getWhatsAppQR:c,sendWhatsAppMessage:s,startWhatsAppConnection:a,restartWhatsAppConnection:u,isConnected:x}=w(),[h,o]=d.useState(!1),[y,n]=d.useState(null),[p,j]=d.useState(null),m=d.useCallback(async()=>{o(!0),n(null);try{const r=await t();return j(r),r}catch(r){const l=r.message||"Failed to get status";return n(l),{connected:!1}}finally{o(!1)}},[t]),C=d.useCallback(async()=>{o(!0),n(null);try{const r=await c();return r.connected&&j({connected:!0}),r}catch(r){const l=r.message||"Failed to get QR code";return n(l),{connected:!1,message:l}}finally{o(!1)}},[c]),R=d.useCallback(async(r,l)=>{o(!0),n(null);try{const f=await s(r,l);return!f.success&&f.error&&n(f.error),f}catch(f){const N=f.message||"Failed to send message";return n(N),{success:!1,error:N}}finally{o(!1)}},[s]),i=d.useCallback(async()=>{o(!0),n(null);try{const r=await a();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to start connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[a]),g=d.useCallback(async()=>{o(!0),n(null);try{const r=await u();return!r.success&&r.message&&n(r.message),r}catch(r){const l=r.message||"Failed to restart connection";return n(l),{success:!1,message:l}}finally{o(!1)}},[u]);return{getStatus:m,getQRCode:C,sendMessage:R,startConnection:i,restartConnection:g,isLoading:h,lastError:y,connectionStatus:p,isConnected:x}},re=({config:t,visible:c})=>{const s=T(t,c),a=L(t.statusHook),{startConnection:u,restartConnection:x,getStatus:h}=H(),{sendRequest:o,setAndroidStatus:y}=w(),n=t.qr,p=n.isConnected(a),j=a?.[n.qrField],m=t.fields?.[0],C=d.useMemo(()=>({start:()=>s.execute("start",u),restart:()=>s.execute("restart",x),refresh:()=>s.execute("refresh",h),connect:()=>s.execute("connect",async()=>{const i=s.form.getFieldValue("android_remote")?.trim();if(!i){s.setError("No API key configured");return}const g=await o("android_relay_connect",{url:"",api_key:i});return g.qr_data&&y(r=>({...r,connected:!0,paired:!1,qr_data:g.qr_data,session_token:g.session_token||r.session_token})),g}),disconnect:()=>s.execute("disconnect",()=>o("android_relay_disconnect",{}))}),[s,u,x,h,o,y]),R=(t.actions??[]).map(i=>({key:i.key,label:i.label,intent:i.intent,onClick:C[i.key]??(()=>{}),hidden:i.hidden?.(a,s.stored),disabled:i.disabled?.(a,s.stored)}));return e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4 p-5",children:[m&&e.jsx(v,{value:s.form.getFieldValue(m.key)||"",onChange:i=>s.form.setFieldValue(m.key,i),onSave:()=>s.actions.save(m.key,(s.form.getFieldValue(m.key)??"").trim()).then(()=>s.setStored(!0)),onDelete:()=>s.actions.remove(m.key),placeholder:m.placeholder,loading:s.loading==="save",isStored:s.stored}),t.statusRows&&e.jsx(P,{icon:e.jsx(A,{icon:t.iconRef,className:"h-6 w-6 text-2xl"}),title:t.name,rows:t.statusRows,status:a}),e.jsxs("div",{className:"flex min-h-[300px] flex-1 flex-col items-center justify-center rounded-lg bg-muted p-5",children:[e.jsx(B,{value:j,isConnected:p,size:280,connectedTitle:n.connectedTitle,connectedSubtitle:n.connectedSubtitle(a),loading:n.isLoading(a),emptyText:n.emptyText(a,s.stored)}),!p&&j&&e.jsx("div",{className:"mt-3 text-sm text-muted-foreground",children:n.scanText})]}),t.hasRateLimits&&p&&e.jsx(q,{}),s.error&&e.jsx(S,{variant:"destructive",children:e.jsx(_,{children:s.error})}),e.jsx(D,{actions:R,loading:s.loading})]})};export{re as default};
@@ -0,0 +1 @@
1
+ import{b as o,h as le}from"./vendor-react-CxXU_nq3.js";import{a as pe,u as je}from"./vendor-query-to9T1kjL.js";import{u as re,m as se,s as G,S as ge,t as oe,v as ie,A as ce,a as de,b as ue,c as me,F as xe,w as _,x as w,y as S,z as J,D as C,E as Y,G as I,H as X,J as O,K as D,M as Q,g as B,I as $,O as Z,B as ee,_ as ne,P as b,Q as H,R as ye,d as _e,e as ve,f as be}from"./index-DNx1tG6T.js";import{j as e}from"./vendor-radix-BGeDhy8U.js";import{ab as we,ac as he}from"./vendor-icons-BPyNc2rK.js";const W={};function Ve(n,l){const x=pe(),[h,j]=o.useState(null),[p,c]=o.useState(null),[F,v]=o.useState(!1);o.useEffect(()=>{c(null),j(null),v(!1)},[n.id]);const{validateApiKey:u,saveApiKey:y,removeApiKey:A,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g,isConnected:T}=re(),{sendRequest:k}=se(),E=je({queryKey:G.credentialValues.byProvider(n.id).queryKey,queryFn:async()=>{if(!n.fields)return{values:W,hadStored:!1};const t=await Promise.all(n.fields.map(async K=>{const fe=K.key==="apiKey"?n.id:K.key,ae=await k("get_stored_api_key",{provider:fe});return{key:K.key,hasKey:ae.hasKey,apiKey:ae.apiKey}})),f={};let m=!1;for(const K of t)K.apiKey&&(f[K.key]=K.apiKey),K.hasKey&&(m=!0);return{values:f,hadStored:m}},enabled:l&&T&&!!n.fields,staleTime:ge.FOREVER}),L=E.data?.values??W,M=o.useRef(L);M.current=L;const N=n.id,q=o.useCallback(t=>{x.setQueryData(G.credentialValues.byProvider(N).queryKey,f=>({values:t(f?.values??W),hadStored:f?.hadStored??!1}))},[x,N]),z=o.useMemo(()=>({getFieldValue:t=>M.current[t],getFieldsValue:()=>({...M.current}),setFieldValue:(t,f)=>{q(m=>({...m,[t]:f}))},setFieldsValue:t=>{q(f=>({...f,...t}))},resetFields:()=>q(()=>W)}),[q]);(E.data?.hadStored??!1)&&!F&&v(!0);const r=o.useCallback(async(t,f)=>{j(t),c(null);try{const m=await f();return m&&!m.success&&m.error&&c(m.error),m}catch(m){c(m.message||`Failed: ${t}`);return}finally{j(null)}},[]),V=o.useCallback(()=>x.invalidateQueries({queryKey:G.credentialValues.byProvider(N).queryKey}),[x,N]);return{form:z,values:L,loading:h,error:p,stored:F,setStored:v,setError:c,execute:r,actions:{validate:(t,f)=>r("validate",async()=>{const m=await u(t,f);return m?.isValid&&(v(!0),await V()),m}),save:(t,f)=>r("save",async()=>{const m=await y(t,f);return m?.isValid&&(v(!0),await V()),m}),remove:t=>r("remove",async()=>{await A(t),v(!1),await V()}),oauthLogin:()=>r("login",async()=>{const t=await k(n.ws.login,{});return t.success&&t.url&&window.open(t.url,"_blank"),t}),oauthLogout:()=>r("logout",()=>k(n.ws.logout,{})),oauthRefresh:()=>r("refresh",()=>k(n.ws.status,{})),sendWs:(t,f)=>r(t,()=>k(t,f??{}))},isConnected:T,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g}}const Se=ie({default_model:ye().optional().default(""),temperature:b().optional(),max_tokens:b().int().min(1).optional(),thinking_enabled:H().optional().default(!1),thinking_budget:b().int().min(1024).max(16e3).optional(),reasoning_effort:ne(["low","medium","high"]).optional(),reasoning_format:ne(["parsed","hidden"]).optional()}),Ke=({providerId:n})=>{const{getProviderDefaults:l,saveProviderDefaults:x,getStoredModels:h,getModelConstraints:j,isConnected:p}=re(),{apiKeyStatuses:c}=se(),F=c[n],[v,u]=o.useState([]),[y,A]=o.useState(null),[R,P]=o.useState(!1),i=le({resolver:oe(Se),defaultValues:{}}),a=i.watch("default_model"),d=i.watch("thinking_enabled"),{isDirty:g}=i.formState;o.useEffect(()=>{if(!p)return;u([]),A(null);let s=!1;return(async()=>{P(!0);try{const[r,V]=await Promise.all([l(n),h(n)]);s||(i.reset(r??{}),u(V??[]))}finally{s||P(!1)}})(),()=>{s=!0}},[n,p,F]),o.useEffect(()=>{if(!p||!a)return;let s=!1;return j(a,n).then(r=>{s||(A(r),r?.max_output_tokens&&i.getValues("max_tokens")!==r.max_output_tokens&&i.setValue("max_tokens",r.max_output_tokens,{shouldDirty:!1}))}),()=>{s=!0}},[a,n,p]);const T=o.useCallback(async s=>{P(!0);try{await x(n,s)&&i.reset(s)}finally{P(!1)}},[n,x,i]),[k,E]=y?.temperature_range??[0,2],L=y?.max_output_tokens,M=y?.thinking_type,N=y?.supports_thinking,q=y?.is_reasoning_model&&k===E,z=s=>r=>{const V=r.target.value;s.onChange(V===""?void 0:Number(V))};return e.jsx(ce,{type:"single",collapsible:!0,defaultValue:"defaults",children:e.jsxs(de,{value:"defaults",children:[e.jsx(ue,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-4 w-4"})," Default Parameters"]})}),e.jsx(me,{children:e.jsx("div",{className:R?"pointer-events-none opacity-60":"",children:e.jsx(xe,{...i,children:e.jsxs("form",{id:`provider-defaults-form-${n}`,onSubmit:i.handleSubmit(T),className:"flex flex-col gap-3",children:[e.jsx(_,{control:i.control,name:"default_model",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Default Model"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{children:e.jsx(I,{placeholder:v.length?"Select model":"Validate API key first"})})}),e.jsx(X,{children:v.map(r=>e.jsx(O,{value:r,children:r},r))})]}),e.jsx(D,{children:"Model used when none specified"}),e.jsx(Q,{})]})}),y&&e.jsxs("div",{className:"flex flex-wrap items-center gap-1.5",children:[L!=null&&e.jsxs(B,{variant:"success",children:["Max Output: ",L.toLocaleString()]}),y.context_length!=null&&e.jsxs(B,{variant:"info",children:["Context: ",y.context_length.toLocaleString()]}),e.jsxs(B,{variant:"secondary",children:["Temp: ",k,"-",E]}),N&&e.jsxs(B,{variant:"warning",children:["Thinking: ",M]}),y.is_reasoning_model&&e.jsx(B,{variant:"outline",children:"Reasoning"})]}),!q&&e.jsx(_,{control:i.control,name:"temperature",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Temperature"}),e.jsx(C,{children:e.jsx($,{type:"number",min:k,max:E,step:.1,className:"w-24",value:s.value??"",onChange:z(s)})}),e.jsxs(D,{children:["Controls randomness (",k,"-",E,")"]}),e.jsx(Q,{})]})}),e.jsx(_,{control:i.control,name:"max_tokens",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Max Tokens"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1,max:L||void 0,className:"w-32",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:L!=null?`Up to ${L.toLocaleString()}`:"Maximum response length"}),e.jsx(Q,{})]})}),N&&e.jsx(_,{control:i.control,name:"thinking_enabled",render:({field:s})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:"Thinking / Reasoning"}),e.jsxs(D,{children:["Extended thinking (",M,")"]})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!s.value,onCheckedChange:s.onChange})})]})}),N&&M==="budget"&&d&&e.jsx(_,{control:i.control,name:"thinking_budget",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Thinking Budget"}),e.jsx(C,{children:e.jsx($,{type:"number",min:1024,max:16e3,className:"w-28",value:s.value??"",onChange:z(s)})}),e.jsx(D,{children:"Token budget (1024-16000)"}),e.jsx(Q,{})]})}),N&&M==="effort"&&d&&e.jsx(_,{control:i.control,name:"reasoning_effort",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Effort"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"low",children:"Low"}),e.jsx(O,{value:"medium",children:"Medium"}),e.jsx(O,{value:"high",children:"High"})]})]}),e.jsx(D,{children:"Low, medium, or high"}),e.jsx(Q,{})]})}),N&&M==="format"&&d&&e.jsx(_,{control:i.control,name:"reasoning_format",render:({field:s})=>e.jsxs(w,{children:[e.jsx(S,{children:"Reasoning Format"}),e.jsxs(J,{value:s.value??"",onValueChange:s.onChange,children:[e.jsx(C,{children:e.jsx(Y,{className:"w-32",children:e.jsx(I,{placeholder:"Select"})})}),e.jsxs(X,{children:[e.jsx(O,{value:"parsed",children:"Parsed"}),e.jsx(O,{value:"hidden",children:"Hidden"})]})]}),e.jsx(D,{children:"Parsed or hidden"}),e.jsx(Q,{})]})}),e.jsxs(ee,{type:"submit",disabled:!g||R,variant:g?"default":"outline",className:"w-full",children:[R&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Defaults"]})]})})})})]})})},Ce=ie({enabled:H().default(!1),min_delay_ms:b().int().min(0).optional(),max_delay_ms:b().int().min(0).optional(),typing_delay_ms:b().int().min(0).optional(),link_extra_delay_ms:b().int().min(0).optional(),max_messages_per_minute:b().int().min(0).optional(),max_messages_per_hour:b().int().min(0).optional(),max_new_contacts_per_day:b().int().min(0).optional(),simulate_typing:H().optional(),randomize_delays:H().optional(),pause_on_low_response:H().optional(),response_rate_threshold:b().min(0).max(1).optional()}),U=n=>{const l=be.c(7),{label:x,value:h}=n;let j;l[0]!==x?(j=e.jsx("span",{className:"text-xs text-muted-foreground",children:x}),l[0]=x,l[1]=j):j=l[1];let p;l[2]!==h?(p=e.jsx("span",{className:"text-lg font-semibold",children:h}),l[2]=h,l[3]=p):p=l[3];let c;return l[4]!==j||l[5]!==p?(c=e.jsxs("div",{className:"flex flex-col",children:[j,p]}),l[4]=j,l[5]=p,l[6]=c):c=l[6],c},te=n=>l=>{const x=l.target.value;n.onChange(x===""?void 0:Number(x))},De=()=>{const{getWhatsAppRateLimitConfig:n,setWhatsAppRateLimitConfig:l,unpauseWhatsAppRateLimit:x}=se(),[h,j]=o.useState(null),[p,c]=o.useState(!1),[F,v]=o.useState(!1),u=le({resolver:oe(Ce),defaultValues:{enabled:!1}}),y=u.watch("pause_on_low_response"),{isDirty:A}=u.formState,R=o.useCallback(async()=>{c(!0);try{const a=await n();a.success&&a.config&&(u.reset(a.config),j(a.stats??null),v(!0))}finally{c(!1)}},[u,n]);o.useEffect(()=>{R()},[R]);const P=o.useCallback(async a=>{c(!0);try{const d=await l(a);d.success&&d.config&&u.reset(d.config)}finally{c(!1)}},[u,l]),i=o.useCallback(async()=>{c(!0);try{const a=await x();a.success&&a.stats&&j(a.stats)}finally{c(!1)}},[x]);return e.jsx(ce,{type:"single",collapsible:!0,children:e.jsxs(de,{value:"ratelimits",children:[e.jsx(ue,{children:e.jsxs("div",{className:"flex w-full items-center justify-between gap-2",children:[e.jsx("span",{children:"Rate Limits"}),e.jsx(_,{control:u.control,name:"enabled",render:({field:a})=>e.jsx("span",{onClick:d=>d.stopPropagation(),children:e.jsx(Z,{checked:!!a.value,onCheckedChange:a.onChange})})})]})}),e.jsx(me,{children:F?e.jsx(xe,{...u,children:e.jsxs("form",{onSubmit:u.handleSubmit(P),className:"flex flex-col gap-3",children:[h&&e.jsxs("div",{className:"mb-3 flex flex-wrap gap-4",children:[e.jsx(U,{label:"Last Minute",value:h.messages_sent_last_minute}),e.jsx(U,{label:"Last Hour",value:h.messages_sent_last_hour}),e.jsx(U,{label:"Today",value:h.messages_sent_today}),e.jsx(U,{label:"New Contacts",value:h.new_contacts_today}),e.jsx(U,{label:"Responses",value:h.responses_received}),e.jsx(U,{label:"Response Rate",value:`${Math.round((h.response_rate||0)*100)}%`})]}),h?.is_paused&&e.jsx(_e,{variant:"warning",children:e.jsxs(ve,{className:"flex items-center justify-between gap-3",children:[e.jsx("span",{children:h.pause_reason||"Paused"}),e.jsx(ee,{size:"sm",variant:"outline",type:"button",onClick:i,children:"Unpause"})]})}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Delays (milliseconds)"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["min_delay_ms","Min Delay"],["max_delay_ms","Max Delay"],["typing_delay_ms","Typing Duration"],["link_extra_delay_ms","Link Extra Delay"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-28",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Message Limits"}),e.jsx("div",{className:"flex flex-wrap gap-3",children:[["max_messages_per_minute","Per Minute"],["max_messages_per_hour","Per Hour"],["max_new_contacts_per_day","New Contacts/Day"]].map(([a,d])=>e.jsx(_,{control:u.control,name:a,render:({field:g})=>e.jsxs(w,{children:[e.jsx(S,{className:"text-xs",children:d}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,className:"w-32",value:g.value??"",onChange:te(g)})})]})},a))}),e.jsx("div",{className:"text-xs font-medium text-muted-foreground",children:"Behavior"}),e.jsxs("div",{className:"flex w-full flex-col gap-2",children:[[["simulate_typing","Simulate Typing","Show typing indicator before sending"],["randomize_delays","Randomize Delays","Add variance between min/max delay"],["pause_on_low_response","Pause on Low Response","Auto-pause if response rate drops below threshold"]].map(([a,d,g])=>e.jsx(_,{control:u.control,name:a,render:({field:T})=>e.jsxs(w,{className:"flex flex-row items-center justify-between rounded-md border border-border p-3",children:[e.jsxs("div",{className:"space-y-0.5",children:[e.jsx(S,{children:d}),e.jsx(D,{children:g})]}),e.jsx(C,{children:e.jsx(Z,{checked:!!T.value,onCheckedChange:T.onChange})})]})},a)),y&&e.jsx(_,{control:u.control,name:"response_rate_threshold",render:({field:a})=>e.jsxs(w,{children:[e.jsx(S,{children:"Response Rate Threshold (%)"}),e.jsx(C,{children:e.jsx($,{type:"number",min:0,max:100,value:Math.round((a.value??.3)*100),onChange:d=>{const g=d.target.value;a.onChange(g===""?void 0:Number(g)/100)}})})]})})]}),e.jsxs(ee,{type:"submit",disabled:!A||p,variant:A?"default":"outline",className:"w-full",children:[p&&e.jsx(he,{className:"h-4 w-4 animate-spin"}),"Save Changes"]})]})}):e.jsx("div",{className:"flex justify-center p-4 text-sm text-muted-foreground",children:"Loading..."})})]})})};export{Ke as P,De as R,Ve as u};
@@ -0,0 +1 @@
1
+ import{j as s}from"./vendor-radix-BGeDhy8U.js";import{f as b,g}from"./index-DNx1tG6T.js";const h=p=>{const e=b.c(15),{icon:c,title:m,rows:x,status:o}=p;let t;e[0]!==m?(t=s.jsx("span",{children:m}),e[0]=m,e[1]=t):t=e[1];let r;e[2]!==c||e[3]!==t?(r=s.jsxs("div",{className:"flex items-center gap-2 border-b border-border bg-muted px-3 py-2 text-sm font-semibold",children:[c,t]}),e[2]=c,e[3]=t,e[4]=r):r=e[4];let i;if(e[5]!==x||e[6]!==o){let n;e[8]!==o?(n=l=>{const f=l.ok(o),u=f?"success":l.warn?"warning":"destructive";return s.jsxs("div",{className:"grid grid-cols-[1fr_auto] items-center gap-3 px-3 py-2 text-sm",children:[s.jsx("span",{className:"text-muted-foreground",children:l.label}),s.jsx(g,{variant:u,children:f?l.trueText:l.falseText})]},l.label)},e[8]=o,e[9]=n):n=e[9],i=x.map(n),e[5]=x,e[6]=o,e[7]=i}else i=e[7];let d;e[10]!==i?(d=s.jsx("div",{className:"divide-y divide-border",children:i}),e[10]=i,e[11]=d):d=e[11];let a;return e[12]!==r||e[13]!==d?(a=s.jsxs("div",{className:"overflow-hidden rounded-md border border-border",children:[r,d]}),e[12]=r,e[13]=d,e[14]=a):a=e[14],a};export{h as S};