machinaos 0.0.78 → 0.0.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (743) hide show
  1. package/.env.template +74 -5
  2. package/{workflows/AI Assistant_workflow-1778504793388-ou1m1tz2x.json → .machina/workflows/AI Assistant_example_workflow-1779017037684-e2e5da7a.json } +164 -105
  3. package/{workflows/AI Employee_example_workflow-1777720598005-u4cm858dv.json → .machina/workflows/AI Employee_example_workflow-1779102911870-cbc76c82.json } +582 -328
  4. package/{workflows/Claude Assistant_workflow-1778380124051-mdibn807c.json → .machina/workflows/Claude Assistant_example_workflow-1779095939967-2369cff4.json } +152 -83
  5. package/README.md +5 -2
  6. package/bin/cli.js +2 -2
  7. package/{machina → cli}/__main__.py +11 -7
  8. package/cli/_common.py +122 -0
  9. package/cli/buildenv.py +40 -0
  10. package/cli/cli.py +204 -0
  11. package/{machina → cli}/colors.py +10 -2
  12. package/cli/commands/__init__.py +1 -0
  13. package/cli/commands/_temporal_specs.py +59 -0
  14. package/{machina → cli}/commands/build.py +35 -45
  15. package/cli/commands/clean.py +141 -0
  16. package/cli/commands/daemon/__init__.py +47 -0
  17. package/cli/commands/daemon/_state.py +97 -0
  18. package/cli/commands/daemon/restart.py +14 -0
  19. package/cli/commands/daemon/start.py +49 -0
  20. package/cli/commands/daemon/status.py +20 -0
  21. package/cli/commands/daemon/stop.py +22 -0
  22. package/{machina → cli}/commands/dev.py +32 -42
  23. package/{machina → cli}/commands/docs.py +13 -11
  24. package/{machina → cli}/commands/start.py +69 -62
  25. package/{machina → cli}/commands/stop.py +7 -10
  26. package/{machina → cli}/commands/version.py +12 -6
  27. package/cli/config.py +170 -0
  28. package/cli/platform_.py +169 -0
  29. package/{machina → cli}/ports.py +42 -3
  30. package/{machina → cli}/run.py +29 -2
  31. package/{machina → cli}/supervisor.py +29 -12
  32. package/{machina → cli}/tcp.py +6 -2
  33. package/{machina → cli}/tree.py +38 -11
  34. package/client/dist/assets/{ActionBar-Du2MSFSz.js → ActionBar-Cjr3TF7g.js} +1 -1
  35. package/client/dist/assets/{ApiKeyInput-k2LBmBjb.js → ApiKeyInput-DIJE2PVA.js} +1 -1
  36. package/client/dist/assets/{ApiKeyPanel-C_bV9U0X.js → ApiKeyPanel-CPmye7uh.js} +1 -1
  37. package/client/dist/assets/{ApiUsageSection-CmVfwZzL.js → ApiUsageSection-TF_7gH2D.js} +1 -1
  38. package/client/dist/assets/{EmailPanel-CeKIMGu-.js → EmailPanel-Bs-xvbKR.js} +1 -1
  39. package/client/dist/assets/{OAuthPanel-KA3t3Q2K.js → OAuthPanel-BDtVJhAV.js} +1 -1
  40. package/client/dist/assets/{QrPairingPanel-NgNpJNuk.js → QrPairingPanel-BwJehTuZ.js} +1 -1
  41. package/client/dist/assets/{RateLimitSection-Du5YNVIA.js → RateLimitSection-CfNOoPIS.js} +1 -1
  42. package/client/dist/assets/{StatusCard-DNLyayXc.js → StatusCard-DkwIrgdP.js} +1 -1
  43. package/client/dist/assets/index-P2FzntoL.js +165 -0
  44. package/client/dist/index.html +1 -1
  45. package/client/package.json +1 -1
  46. package/client/src/Dashboard.tsx +128 -76
  47. package/client/src/adapters/nodeSpecToDescription.ts +7 -0
  48. package/client/src/assets/icons/index.test.ts +10 -0
  49. package/client/src/assets/icons/index.ts +16 -3
  50. package/client/src/components/AIAgentNode.tsx +8 -8
  51. package/client/src/components/ParameterRenderer.tsx +6 -3
  52. package/client/src/components/SkillEditorModal.tsx +1 -0
  53. package/client/src/components/credentials/panels/EmailPanel.tsx +2 -0
  54. package/client/src/components/credentials/sections/ProviderDefaultsSection.tsx +2 -0
  55. package/client/src/components/credentials/sections/RateLimitSection.tsx +1 -0
  56. package/client/src/components/icons/AIProviderIcons.tsx +1 -0
  57. package/client/src/components/maps/GoogleMapsPicker.tsx +1 -0
  58. package/client/src/components/parameterPanel/InputSection.tsx +1 -0
  59. package/client/src/components/parameterPanel/MasterSkillEditor.tsx +1 -0
  60. package/client/src/components/parameterPanel/OutputSection.tsx +1 -0
  61. package/client/src/components/ui/ComponentPalette.tsx +1 -0
  62. package/client/src/components/ui/MapSelector.tsx +1 -0
  63. package/client/src/components/ui/NodeContextMenu.tsx +3 -3
  64. package/client/src/components/ui/SettingsPanel.tsx +1 -0
  65. package/client/src/components/ui/action-button.tsx +1 -0
  66. package/client/src/components/ui/badge.tsx +1 -0
  67. package/client/src/components/ui/button.tsx +1 -0
  68. package/client/src/components/ui/form.tsx +1 -0
  69. package/client/src/components/ui/tabs.tsx +1 -0
  70. package/client/src/contexts/AuthContext.tsx +1 -0
  71. package/client/src/contexts/ThemeContext.tsx +1 -0
  72. package/client/src/contexts/WebSocketContext.tsx +104 -34
  73. package/client/src/hooks/__tests__/useApiKeys.test.ts +2 -2
  74. package/client/src/hooks/useReactFlowNodes.ts +1 -0
  75. package/client/src/hooks/useWorkflowValidation.ts +142 -0
  76. package/client/src/lib/nodeSpec.ts +1 -0
  77. package/client/src/test/providers.tsx +1 -0
  78. package/client/src/types/__tests__/cloudEvents.test.ts +5 -2
  79. package/client/src/types/cloudEvents.ts +19 -7
  80. package/client/src/utils/nodeUtils.ts +1 -1
  81. package/client/src/utils/workflow.ts +8 -2
  82. package/client/src/utils/workflowExport.ts +60 -3
  83. package/package.json +24 -23
  84. package/scripts/install.js +16 -27
  85. package/scripts/migrate_icons.py +3 -1
  86. package/scripts/migrate_skill_icons.py +6 -7
  87. package/scripts/postinstall.js +11 -9
  88. package/server/config/ai_cli_providers.json +2 -3
  89. package/server/config/credential_providers.json +15 -15
  90. package/server/config/llm_defaults.json +1 -1
  91. package/server/config/model_registry.json +416 -611
  92. package/server/constants.py +285 -223
  93. package/server/core/__init__.py +1 -1
  94. package/server/core/cache.py +9 -29
  95. package/server/core/cleanup.py +12 -24
  96. package/server/core/config.py +148 -24
  97. package/server/core/container.py +68 -59
  98. package/server/core/credential_backends.py +5 -13
  99. package/server/core/credentials_database.py +13 -43
  100. package/server/core/database.py +292 -353
  101. package/server/core/health.py +4 -5
  102. package/server/core/logging.py +241 -87
  103. package/server/core/paths.py +285 -0
  104. package/server/core/tracing.py +2 -8
  105. package/server/gunicorn.conf.py +1 -0
  106. package/server/main.py +150 -74
  107. package/server/middleware/auth.py +18 -24
  108. package/server/models/__init__.py +1 -1
  109. package/server/models/auth.py +5 -12
  110. package/server/models/database.py +36 -68
  111. package/server/models/node_metadata.py +25 -18
  112. package/server/nodejs/dist/index.js +107 -0
  113. package/server/nodes/README.md +11 -5
  114. package/server/nodes/__init__.py +1 -1
  115. package/server/nodes/_visuals.py +146 -14
  116. package/server/nodes/agent/_events.py +124 -0
  117. package/server/nodes/agent/_handles.py +15 -29
  118. package/server/nodes/agent/_inline.py +28 -25
  119. package/server/nodes/agent/_specialized.py +30 -15
  120. package/server/nodes/agent/{ai_agent.py → ai_agent/__init__.py} +33 -17
  121. package/server/nodes/agent/ai_agent/meta.json +3 -0
  122. package/server/nodes/agent/{ai_employee.py → ai_employee/__init__.py} +5 -2
  123. package/server/nodes/agent/ai_employee/meta.json +3 -0
  124. package/server/nodes/agent/{android_agent.py → android_agent/__init__.py} +1 -1
  125. package/server/nodes/agent/android_agent/meta.json +3 -0
  126. package/server/nodes/agent/{autonomous_agent.py → autonomous_agent/__init__.py} +2 -1
  127. package/server/nodes/agent/autonomous_agent/meta.json +3 -0
  128. package/server/nodes/agent/{chat_agent.py → chat_agent/__init__.py} +29 -12
  129. package/server/nodes/agent/chat_agent/meta.json +3 -0
  130. package/server/nodes/agent/{claude_code_agent.py → claude_code_agent/__init__.py} +192 -95
  131. package/server/nodes/agent/claude_code_agent/_handlers.py +169 -0
  132. package/server/{services/claude_oauth.py → nodes/agent/claude_code_agent/_oauth.py} +26 -13
  133. package/server/nodes/agent/claude_code_agent/_pool.py +1020 -0
  134. package/server/nodes/agent/claude_code_agent/_provider.py +513 -0
  135. package/server/nodes/agent/claude_code_agent/_skills.py +245 -0
  136. package/server/nodes/agent/claude_code_agent/meta.json +3 -0
  137. package/server/nodes/agent/{codex_agent.py → codex_agent/__init__.py} +26 -35
  138. package/server/nodes/agent/codex_agent/meta.json +3 -0
  139. package/server/nodes/agent/{coding_agent.py → coding_agent/__init__.py} +1 -1
  140. package/server/nodes/agent/coding_agent/meta.json +3 -0
  141. package/server/nodes/agent/{consumer_agent.py → consumer_agent/__init__.py} +1 -1
  142. package/server/nodes/agent/consumer_agent/meta.json +3 -0
  143. package/server/nodes/agent/{orchestrator_agent.py → orchestrator_agent/__init__.py} +5 -2
  144. package/server/nodes/agent/orchestrator_agent/meta.json +3 -0
  145. package/server/nodes/agent/{payments_agent.py → payments_agent/__init__.py} +1 -1
  146. package/server/nodes/agent/payments_agent/meta.json +3 -0
  147. package/server/nodes/agent/{productivity_agent.py → productivity_agent/__init__.py} +1 -1
  148. package/server/nodes/agent/productivity_agent/meta.json +3 -0
  149. package/server/nodes/agent/{rlm_agent.py → rlm_agent/__init__.py} +18 -17
  150. package/server/nodes/agent/rlm_agent/meta.json +3 -0
  151. package/server/nodes/agent/{social_agent.py → social_agent/__init__.py} +1 -1
  152. package/server/nodes/agent/social_agent/meta.json +3 -0
  153. package/server/nodes/agent/{task_agent.py → task_agent/__init__.py} +1 -1
  154. package/server/nodes/agent/task_agent/meta.json +3 -0
  155. package/server/nodes/agent/{tool_agent.py → tool_agent/__init__.py} +1 -1
  156. package/server/nodes/agent/tool_agent/meta.json +3 -0
  157. package/server/nodes/agent/{travel_agent.py → travel_agent/__init__.py} +1 -1
  158. package/server/nodes/agent/travel_agent/meta.json +3 -0
  159. package/server/nodes/agent/{web_agent.py → web_agent/__init__.py} +1 -1
  160. package/server/nodes/agent/web_agent/meta.json +3 -0
  161. package/server/nodes/android/__init__.py +24 -0
  162. package/server/nodes/android/_base.py +93 -76
  163. package/server/nodes/android/_dispatcher.py +140 -223
  164. package/server/nodes/android/_events.py +154 -0
  165. package/server/nodes/android/_handlers.py +13 -7
  166. package/server/nodes/android/_option_loaders.py +1 -4
  167. package/server/nodes/android/_refresh.py +27 -37
  168. package/server/nodes/android/_relay/broadcaster.py +25 -41
  169. package/server/nodes/android/_relay/client.py +23 -42
  170. package/server/nodes/android/_relay/manager.py +1 -0
  171. package/server/nodes/android/_relay/protocol.py +6 -0
  172. package/server/nodes/android/_router.py +48 -133
  173. package/server/nodes/android/{airplane_mode_control.py → airplane_mode_control/__init__.py} +2 -1
  174. package/server/nodes/android/airplane_mode_control/meta.json +3 -0
  175. package/server/nodes/android/{app_launcher.py → app_launcher/__init__.py} +2 -1
  176. package/server/nodes/android/app_launcher/meta.json +3 -0
  177. package/server/nodes/android/{app_list.py → app_list/__init__.py} +2 -1
  178. package/server/nodes/android/app_list/meta.json +3 -0
  179. package/server/nodes/android/{audio_automation.py → audio_automation/__init__.py} +2 -1
  180. package/server/nodes/android/audio_automation/meta.json +3 -0
  181. package/server/nodes/android/{battery_monitor.py → battery_monitor/__init__.py} +2 -1
  182. package/server/nodes/android/battery_monitor/meta.json +3 -0
  183. package/server/nodes/android/{bluetooth_automation.py → bluetooth_automation/__init__.py} +2 -1
  184. package/server/nodes/android/bluetooth_automation/meta.json +3 -0
  185. package/server/nodes/android/{camera_control.py → camera_control/__init__.py} +2 -1
  186. package/server/nodes/android/camera_control/meta.json +3 -0
  187. package/server/nodes/android/{device_state_automation.py → device_state_automation/__init__.py} +2 -1
  188. package/server/nodes/android/device_state_automation/meta.json +3 -0
  189. package/server/nodes/android/{environmental_sensors.py → environmental_sensors/__init__.py} +2 -1
  190. package/server/nodes/android/environmental_sensors/meta.json +3 -0
  191. package/server/nodes/android/{location.py → location/__init__.py} +2 -1
  192. package/server/nodes/android/location/meta.json +3 -0
  193. package/server/nodes/android/{media_control.py → media_control/__init__.py} +2 -1
  194. package/server/nodes/android/media_control/meta.json +3 -0
  195. package/server/nodes/android/{motion_detection.py → motion_detection/__init__.py} +2 -1
  196. package/server/nodes/android/motion_detection/meta.json +3 -0
  197. package/server/nodes/android/{network_monitor.py → network_monitor/__init__.py} +2 -1
  198. package/server/nodes/android/network_monitor/meta.json +3 -0
  199. package/server/nodes/android/{screen_control_automation.py → screen_control_automation/__init__.py} +2 -1
  200. package/server/nodes/android/screen_control_automation/meta.json +3 -0
  201. package/server/nodes/android/{system_info.py → system_info/__init__.py} +2 -1
  202. package/server/nodes/android/system_info/meta.json +3 -0
  203. package/server/nodes/android/{wifi_automation.py → wifi_automation/__init__.py} +2 -1
  204. package/server/nodes/android/wifi_automation/meta.json +3 -0
  205. package/server/nodes/browser/__init__.py +22 -1
  206. package/server/nodes/browser/_install.py +63 -0
  207. package/server/nodes/browser/_service.py +21 -25
  208. package/server/nodes/browser/{browser.py → browser/__init__.py} +58 -25
  209. package/server/nodes/browser/browser/meta.json +3 -0
  210. package/server/nodes/chat/{chat_history.py → chat_history/__init__.py} +2 -4
  211. package/server/nodes/chat/chat_history/meta.json +3 -0
  212. package/server/nodes/chat/{chat_send.py → chat_send/__init__.py} +2 -4
  213. package/server/nodes/chat/chat_send/icon.svg +1 -0
  214. package/server/nodes/chat/chat_send/meta.json +3 -0
  215. package/server/nodes/code/_base.py +1 -1
  216. package/server/nodes/code/{javascript_executor.py → javascript_executor/__init__.py} +5 -5
  217. package/server/nodes/code/javascript_executor/meta.json +3 -0
  218. package/server/nodes/code/{python_executor.py → python_executor/__init__.py} +32 -14
  219. package/server/nodes/code/python_executor/meta.json +3 -0
  220. package/server/nodes/code/{typescript_executor.py → typescript_executor/__init__.py} +5 -5
  221. package/server/nodes/code/typescript_executor/meta.json +3 -0
  222. package/server/nodes/document/{document_parser.py → document_parser/__init__.py} +26 -15
  223. package/server/nodes/document/document_parser/meta.json +3 -0
  224. package/server/nodes/document/{embedding_generator.py → embedding_generator/__init__.py} +16 -9
  225. package/server/nodes/document/embedding_generator/meta.json +3 -0
  226. package/server/nodes/document/{file_downloader.py → file_downloader/__init__.py} +30 -20
  227. package/server/nodes/document/file_downloader/meta.json +3 -0
  228. package/server/nodes/document/{http_scraper.py → http_scraper/__init__.py} +31 -21
  229. package/server/nodes/document/http_scraper/meta.json +3 -0
  230. package/server/nodes/document/{text_chunker.py → text_chunker/__init__.py} +17 -12
  231. package/server/nodes/document/text_chunker/meta.json +3 -0
  232. package/server/nodes/document/{vector_store.py → vector_store/__init__.py} +88 -72
  233. package/server/nodes/document/vector_store/meta.json +3 -0
  234. package/server/nodes/email/__init__.py +9 -2
  235. package/server/nodes/email/_events.py +54 -0
  236. package/server/nodes/email/_filters.py +3 -3
  237. package/server/nodes/email/_himalaya.py +95 -50
  238. package/server/nodes/email/_service.py +23 -13
  239. package/server/nodes/email/{email_read.py → email_read/__init__.py} +23 -11
  240. package/server/nodes/email/email_read/icon.svg +6 -0
  241. package/server/nodes/email/email_read/meta.json +3 -0
  242. package/server/nodes/email/{email_receive.py → email_receive/__init__.py} +45 -23
  243. package/server/nodes/email/email_receive/meta.json +3 -0
  244. package/server/nodes/email/{email_send.py → email_send/__init__.py} +13 -7
  245. package/server/nodes/email/email_send/meta.json +3 -0
  246. package/server/nodes/filesystem/_backend.py +1 -5
  247. package/server/nodes/filesystem/{file_modify.py → file_modify/__init__.py} +10 -5
  248. package/server/nodes/filesystem/file_modify/meta.json +3 -0
  249. package/server/nodes/filesystem/{file_read.py → file_read/__init__.py} +7 -3
  250. package/server/nodes/filesystem/file_read/meta.json +3 -0
  251. package/server/nodes/filesystem/{fs_search.py → fs_search/__init__.py} +11 -3
  252. package/server/nodes/filesystem/fs_search/meta.json +3 -0
  253. package/server/nodes/filesystem/{shell.py → shell/__init__.py} +12 -5
  254. package/server/nodes/filesystem/shell/meta.json +3 -0
  255. package/server/nodes/google/__init__.py +12 -0
  256. package/server/nodes/google/_auth_helper.py +7 -13
  257. package/server/nodes/google/_base.py +14 -11
  258. package/server/nodes/google/_credentials.py +2 -1
  259. package/server/nodes/google/_events.py +47 -0
  260. package/server/nodes/google/_filters.py +3 -3
  261. package/server/nodes/google/_gmail.py +70 -47
  262. package/server/nodes/google/_handlers.py +3 -1
  263. package/server/nodes/google/_oauth.py +25 -11
  264. package/server/nodes/google/_option_loaders.py +9 -30
  265. package/server/nodes/google/_refresh.py +8 -12
  266. package/server/nodes/google/_router.py +4 -5
  267. package/server/nodes/google/{calendar.py → calendar/__init__.py} +87 -64
  268. package/server/nodes/google/calendar/meta.json +3 -0
  269. package/server/nodes/google/{contacts.py → contacts/__init__.py} +84 -72
  270. package/server/nodes/google/contacts/meta.json +3 -0
  271. package/server/nodes/google/{drive.py → drive/__init__.py} +87 -72
  272. package/server/nodes/google/drive/meta.json +3 -0
  273. package/server/nodes/google/{gmail.py → gmail/__init__.py} +73 -39
  274. package/server/nodes/google/gmail/meta.json +3 -0
  275. package/server/nodes/google/{gmail_receive.py → gmail_receive/__init__.py} +31 -24
  276. package/server/nodes/google/gmail_receive/icon.svg +7 -0
  277. package/server/nodes/google/gmail_receive/meta.json +3 -0
  278. package/server/nodes/google/google.svg +7 -0
  279. package/server/nodes/google/{sheets.py → sheets/__init__.py} +54 -42
  280. package/server/nodes/google/sheets/meta.json +3 -0
  281. package/server/nodes/google/{tasks.py → tasks/__init__.py} +56 -43
  282. package/server/nodes/google/tasks/meta.json +3 -0
  283. package/server/nodes/groups.py +28 -28
  284. package/server/nodes/location/__init__.py +31 -1
  285. package/server/nodes/location/_credentials.py +1 -6
  286. package/server/nodes/location/_service.py +88 -107
  287. package/server/nodes/location/{gmaps_create.py → gmaps_create/__init__.py} +6 -6
  288. package/server/nodes/location/gmaps_create/meta.json +3 -0
  289. package/server/nodes/location/{gmaps_locations.py → gmaps_locations/__init__.py} +8 -6
  290. package/server/nodes/location/gmaps_locations/meta.json +3 -0
  291. package/server/nodes/location/{gmaps_nearby_places.py → gmaps_nearby_places/__init__.py} +8 -6
  292. package/server/nodes/location/gmaps_nearby_places/meta.json +3 -0
  293. package/server/nodes/model/_base.py +10 -7
  294. package/server/nodes/model/_credentials.py +10 -10
  295. package/server/nodes/model/_local_validator.py +28 -24
  296. package/server/nodes/model/{anthropic_chat_model.py → anthropic_chat_model/__init__.py} +5 -3
  297. package/server/nodes/model/anthropic_chat_model/meta.json +3 -0
  298. package/server/nodes/model/{cerebras_chat_model.py → cerebras_chat_model/__init__.py} +5 -3
  299. package/server/nodes/model/cerebras_chat_model/meta.json +3 -0
  300. package/server/nodes/model/{deepseek_chat_model.py → deepseek_chat_model/__init__.py} +8 -4
  301. package/server/nodes/model/deepseek_chat_model/meta.json +3 -0
  302. package/server/nodes/model/{gemini_chat_model.py → gemini_chat_model/__init__.py} +5 -3
  303. package/server/nodes/model/gemini_chat_model/meta.json +3 -0
  304. package/server/nodes/model/{groq_chat_model.py → groq_chat_model/__init__.py} +2 -2
  305. package/server/nodes/model/groq_chat_model/meta.json +3 -0
  306. package/server/nodes/model/{kimi_chat_model.py → kimi_chat_model/__init__.py} +2 -2
  307. package/server/nodes/model/kimi_chat_model/meta.json +3 -0
  308. package/server/nodes/model/{lmstudio_chat_model.py → lmstudio_chat_model/__init__.py} +2 -2
  309. package/server/nodes/model/lmstudio_chat_model/meta.json +3 -0
  310. package/server/nodes/model/{mistral_chat_model.py → mistral_chat_model/__init__.py} +2 -2
  311. package/server/nodes/model/mistral_chat_model/meta.json +3 -0
  312. package/server/nodes/model/{ollama_chat_model.py → ollama_chat_model/__init__.py} +2 -2
  313. package/server/nodes/model/ollama_chat_model/meta.json +3 -0
  314. package/server/nodes/model/{openai_chat_model.py → openai_chat_model/__init__.py} +8 -4
  315. package/server/nodes/model/openai_chat_model/meta.json +3 -0
  316. package/server/nodes/model/{openrouter_chat_model.py → openrouter_chat_model/__init__.py} +8 -4
  317. package/server/nodes/model/openrouter_chat_model/meta.json +3 -0
  318. package/server/nodes/proxy/_usage.py +14 -15
  319. package/server/nodes/proxy/{proxy_config.py → proxy_config/__init__.py} +39 -30
  320. package/server/nodes/proxy/proxy_config/meta.json +3 -0
  321. package/server/nodes/proxy/{proxy_request.py → proxy_request/__init__.py} +30 -16
  322. package/server/nodes/proxy/proxy_request/meta.json +3 -0
  323. package/server/nodes/proxy/{proxy_status.py → proxy_status/__init__.py} +2 -0
  324. package/server/nodes/proxy/proxy_status/meta.json +3 -0
  325. package/server/nodes/scheduler/{cron_scheduler.py → cron_scheduler/__init__.py} +96 -23
  326. package/server/nodes/scheduler/cron_scheduler/_workflow.py +155 -0
  327. package/server/nodes/scheduler/cron_scheduler/meta.json +3 -0
  328. package/server/nodes/scheduler/{timer.py → timer/__init__.py} +6 -5
  329. package/server/nodes/scheduler/timer/meta.json +3 -0
  330. package/server/nodes/scraper/_credentials.py +0 -1
  331. package/server/nodes/scraper/{apify_actor.py → apify_actor/__init__.py} +44 -35
  332. package/server/nodes/scraper/apify_actor/icon.svg +5 -0
  333. package/server/nodes/scraper/apify_actor/meta.json +3 -0
  334. package/server/nodes/scraper/{crawlee_scraper.py → crawlee_scraper/__init__.py} +96 -57
  335. package/server/nodes/scraper/crawlee_scraper/meta.json +3 -0
  336. package/server/nodes/search/{brave_search.py → brave_search/__init__.py} +6 -5
  337. package/server/nodes/search/brave_search/icon.svg +3 -0
  338. package/server/nodes/search/brave_search/meta.json +3 -0
  339. package/server/nodes/search/{duckduckgo_search.py → duckduckgo_search/__init__.py} +17 -6
  340. package/server/nodes/search/duckduckgo_search/meta.json +3 -0
  341. package/server/nodes/search/{perplexity_search.py → perplexity_search/__init__.py} +4 -5
  342. package/server/nodes/search/perplexity_search/icon.svg +3 -0
  343. package/server/nodes/search/perplexity_search/meta.json +3 -0
  344. package/server/nodes/search/{serper_search.py → serper_search/__init__.py} +32 -25
  345. package/server/nodes/search/serper_search/icon.svg +3 -0
  346. package/server/nodes/search/serper_search/meta.json +3 -0
  347. package/server/nodes/skill/__init__.py +21 -1
  348. package/server/nodes/skill/_expander.py +75 -0
  349. package/server/nodes/skill/{master_skill.py → master_skill/__init__.py} +2 -8
  350. package/server/nodes/skill/master_skill/_events.py +84 -0
  351. package/server/nodes/skill/master_skill/meta.json +3 -0
  352. package/server/nodes/skill/{simple_memory.py → simple_memory/__init__.py} +8 -16
  353. package/server/nodes/skill/simple_memory/meta.json +3 -0
  354. package/server/nodes/social/_base.py +223 -231
  355. package/server/nodes/social/{social_receive.py → social_receive/__init__.py} +38 -13
  356. package/server/nodes/social/social_receive/meta.json +3 -0
  357. package/server/nodes/social/{social_send.py → social_send/__init__.py} +71 -29
  358. package/server/nodes/social/social_send/icon.svg +1 -0
  359. package/server/nodes/social/social_send/meta.json +3 -0
  360. package/server/nodes/stripe/__init__.py +7 -3
  361. package/server/nodes/stripe/_credentials.py +0 -1
  362. package/server/nodes/stripe/_handlers.py +18 -7
  363. package/server/nodes/stripe/_install.py +14 -15
  364. package/server/nodes/stripe/_source.py +5 -5
  365. package/server/nodes/stripe/icon.svg +1 -0
  366. package/server/nodes/stripe/meta.json +3 -0
  367. package/server/nodes/stripe/stripe_action.py +4 -4
  368. package/server/nodes/stripe/stripe_receive.py +6 -9
  369. package/server/nodes/telegram/__init__.py +13 -0
  370. package/server/nodes/telegram/_credentials.py +2 -7
  371. package/server/nodes/telegram/_events.py +167 -0
  372. package/server/nodes/telegram/_filters.py +3 -11
  373. package/server/nodes/telegram/_handlers.py +17 -7
  374. package/server/nodes/telegram/_refresh.py +24 -34
  375. package/server/nodes/telegram/_service.py +29 -45
  376. package/server/nodes/telegram/meta.json +3 -0
  377. package/server/nodes/telegram/telegram.svg +3 -0
  378. package/server/nodes/telegram/telegram_receive.py +38 -18
  379. package/server/nodes/telegram/telegram_send.py +21 -19
  380. package/server/nodes/text/{file_handler.py → file_handler/__init__.py} +7 -1
  381. package/server/nodes/text/file_handler/meta.json +3 -0
  382. package/server/nodes/text/{text_generator.py → text_generator/__init__.py} +2 -1
  383. package/server/nodes/text/text_generator/meta.json +3 -0
  384. package/server/nodes/tool/{agent_builder.py → agent_builder/__init__.py} +105 -100
  385. package/server/nodes/tool/agent_builder/_events.py +91 -0
  386. package/server/nodes/tool/agent_builder/meta.json +3 -0
  387. package/server/nodes/tool/{calculator_tool.py → calculator_tool/__init__.py} +19 -7
  388. package/server/nodes/tool/calculator_tool/meta.json +3 -0
  389. package/server/nodes/tool/{current_time_tool.py → current_time_tool/__init__.py} +6 -4
  390. package/server/nodes/tool/current_time_tool/meta.json +3 -0
  391. package/server/nodes/tool/{task_manager.py → task_manager/__init__.py} +17 -18
  392. package/server/nodes/tool/task_manager/meta.json +3 -0
  393. package/server/nodes/tool/{write_todos.py → write_todos/__init__.py} +20 -6
  394. package/server/nodes/tool/write_todos/meta.json +3 -0
  395. package/server/nodes/trigger/{chat_trigger.py → chat_trigger/__init__.py} +11 -7
  396. package/server/nodes/trigger/chat_trigger/_events.py +53 -0
  397. package/server/nodes/trigger/chat_trigger/meta.json +3 -0
  398. package/server/nodes/trigger/{task_trigger.py → task_trigger/__init__.py} +10 -7
  399. package/server/nodes/trigger/task_trigger/meta.json +3 -0
  400. package/server/nodes/trigger/{webhook_trigger.py → webhook_trigger/__init__.py} +10 -7
  401. package/server/nodes/trigger/webhook_trigger/_events.py +54 -0
  402. package/server/nodes/trigger/webhook_trigger/meta.json +3 -0
  403. package/server/nodes/twitter/__init__.py +7 -1
  404. package/server/nodes/twitter/_base.py +86 -61
  405. package/server/nodes/twitter/_credentials.py +7 -5
  406. package/server/nodes/twitter/_events.py +101 -0
  407. package/server/nodes/twitter/_filters.py +9 -9
  408. package/server/nodes/twitter/_handlers.py +3 -1
  409. package/server/nodes/twitter/_oauth.py +1 -2
  410. package/server/nodes/twitter/_refresh.py +8 -12
  411. package/server/nodes/twitter/{twitter_receive.py → twitter_receive/__init__.py} +7 -7
  412. package/server/nodes/twitter/twitter_receive/icon.svg +1 -0
  413. package/server/nodes/twitter/twitter_receive/meta.json +3 -0
  414. package/server/nodes/twitter/{twitter_search.py → twitter_search/__init__.py} +16 -11
  415. package/server/nodes/twitter/twitter_search/icon.svg +1 -0
  416. package/server/nodes/twitter/twitter_search/meta.json +3 -0
  417. package/server/nodes/twitter/{twitter_send.py → twitter_send/__init__.py} +60 -27
  418. package/server/nodes/twitter/twitter_send/icon.svg +1 -0
  419. package/server/nodes/twitter/twitter_send/meta.json +3 -0
  420. package/server/nodes/twitter/{twitter_user.py → twitter_user/__init__.py} +34 -19
  421. package/server/nodes/twitter/twitter_user/icon.svg +1 -0
  422. package/server/nodes/twitter/twitter_user/meta.json +3 -0
  423. package/server/nodes/utility/{console.py → console/__init__.py} +17 -22
  424. package/server/nodes/utility/console/meta.json +3 -0
  425. package/server/nodes/utility/{http_request.py → http_request/__init__.py} +9 -6
  426. package/server/nodes/utility/http_request/meta.json +3 -0
  427. package/server/nodes/utility/{process_manager.py → process_manager/__init__.py} +10 -6
  428. package/server/nodes/utility/process_manager/meta.json +3 -0
  429. package/server/nodes/utility/team_monitor/meta.json +3 -0
  430. package/server/nodes/utility/{webhook_response.py → webhook_response/__init__.py} +12 -7
  431. package/server/nodes/utility/webhook_response/meta.json +3 -0
  432. package/server/nodes/visuals.json +69 -251
  433. package/server/nodes/whatsapp/__init__.py +24 -0
  434. package/server/nodes/whatsapp/_base.py +283 -338
  435. package/server/nodes/whatsapp/_credentials.py +44 -0
  436. package/server/nodes/whatsapp/_events.py +277 -0
  437. package/server/nodes/whatsapp/_filters.py +36 -37
  438. package/server/nodes/whatsapp/_handlers.py +2 -0
  439. package/server/nodes/whatsapp/_option_loaders.py +1 -3
  440. package/server/nodes/whatsapp/_refresh.py +13 -18
  441. package/server/nodes/whatsapp/_runtime.py +9 -6
  442. package/server/nodes/whatsapp/_service.py +89 -152
  443. package/server/nodes/whatsapp/meta.json +3 -0
  444. package/server/nodes/whatsapp/whatsapp_db.py +116 -54
  445. package/server/nodes/whatsapp/whatsapp_receive.py +30 -13
  446. package/server/nodes/whatsapp/whatsapp_send.py +60 -37
  447. package/server/nodes/workflow/{start.py → start/__init__.py} +1 -4
  448. package/server/nodes/workflow/start/meta.json +3 -0
  449. package/server/package-lock.json +3 -3
  450. package/server/package.json +3 -0
  451. package/server/pyproject.toml +39 -10
  452. package/server/requirements.txt +3 -5
  453. package/server/routers/__init__.py +1 -1
  454. package/server/routers/auth.py +16 -56
  455. package/server/routers/database.py +27 -50
  456. package/server/routers/nodejs_compat.py +25 -87
  457. package/server/routers/schemas.py +66 -2
  458. package/server/routers/webhook.py +12 -12
  459. package/server/routers/websocket.py +312 -1716
  460. package/server/routers/workflow.py +28 -53
  461. package/server/scripts/smoke_test_skills.py +178 -0
  462. package/server/services/__init__.py +1 -1
  463. package/server/services/_supervisor/process.py +9 -3
  464. package/server/services/_supervisor/registry.py +3 -3
  465. package/server/services/_supervisor/util.py +1 -1
  466. package/server/services/agent_team.py +15 -43
  467. package/server/services/agent_teams/__init__.py +17 -0
  468. package/server/services/agent_teams/handlers.py +195 -0
  469. package/server/services/ai.py +853 -1108
  470. package/server/services/auth.py +10 -34
  471. package/server/services/chat_client.py +5 -34
  472. package/server/services/circuit_breaker.py +2 -6
  473. package/server/services/cli_agent/__init__.py +28 -4
  474. package/server/services/cli_agent/_cli_auth.py +61 -0
  475. package/server/services/cli_agent/_handlers.py +24 -183
  476. package/server/services/cli_agent/config.py +5 -8
  477. package/server/services/cli_agent/factory.py +168 -22
  478. package/server/services/cli_agent/jsonl_watcher.py +380 -0
  479. package/server/services/cli_agent/lockfile.py +9 -2
  480. package/server/services/cli_agent/mcp_server.py +110 -34
  481. package/server/services/cli_agent/protocol.py +37 -19
  482. package/server/services/cli_agent/providers/__init__.py +8 -4
  483. package/server/services/cli_agent/providers/google_gemini.py +11 -5
  484. package/server/services/cli_agent/providers/openai_codex.py +34 -34
  485. package/server/services/cli_agent/service.py +245 -83
  486. package/server/services/cli_agent/session.py +409 -229
  487. package/server/services/cli_agent/transports/__init__.py +47 -0
  488. package/server/services/cli_agent/transports/base.py +111 -0
  489. package/server/services/cli_agent/transports/posix.py +196 -0
  490. package/server/services/cli_agent/transports/windows.py +189 -0
  491. package/server/services/cli_agent/types.py +45 -18
  492. package/server/services/cli_agent/workflow_tools.py +28 -15
  493. package/server/services/compaction.py +68 -52
  494. package/server/services/credential_registry.py +6 -20
  495. package/server/services/credentials/__init__.py +18 -0
  496. package/server/services/credentials/handlers.py +196 -0
  497. package/server/services/deployment/__init__.py +12 -1
  498. package/server/services/deployment/canary_registry.py +137 -0
  499. package/server/services/deployment/handlers.py +382 -0
  500. package/server/services/deployment/manager.py +653 -163
  501. package/server/services/deployment/poll_registry.py +2 -6
  502. package/server/services/deployment/state.py +2 -0
  503. package/server/services/deployment/triggers.py +87 -93
  504. package/server/services/event_waiter.py +47 -54
  505. package/server/services/events/__init__.py +11 -0
  506. package/server/services/events/admin_handlers.py +368 -0
  507. package/server/services/events/daemon.py +3 -1
  508. package/server/services/events/dispatch.py +188 -0
  509. package/server/services/events/envelope.py +264 -45
  510. package/server/services/events/oauth_lifecycle.py +98 -42
  511. package/server/services/events/triggers.py +3 -13
  512. package/server/services/events/verifiers/hmac_basic.py +1 -1
  513. package/server/services/events/verifiers/standard_webhooks.py +2 -4
  514. package/server/services/events/webhook.py +2 -3
  515. package/server/services/example_loader.py +73 -15
  516. package/server/services/execution/cache.py +36 -76
  517. package/server/services/execution/conditions.py +7 -20
  518. package/server/services/execution/dlq.py +20 -24
  519. package/server/services/execution/executor.py +234 -265
  520. package/server/services/execution/models.py +40 -46
  521. package/server/services/execution/recovery.py +23 -46
  522. package/server/services/handlers/__init__.py +12 -16
  523. package/server/services/handlers/todo.py +3 -6
  524. package/server/services/handlers/tools.py +143 -194
  525. package/server/services/handlers/triggers.py +24 -23
  526. package/server/services/llm/config.py +10 -1
  527. package/server/services/llm/factory.py +16 -4
  528. package/server/services/llm/messages.py +1 -5
  529. package/server/services/llm/protocol.py +9 -1
  530. package/server/services/llm/providers/anthropic.py +23 -12
  531. package/server/services/llm/providers/gemini.py +43 -22
  532. package/server/services/llm/providers/openai.py +14 -6
  533. package/server/services/llm/providers/openrouter.py +6 -1
  534. package/server/services/markdown_formatter.py +1 -2
  535. package/server/services/memory/__init__.py +2 -2
  536. package/server/services/memory/jsonl.py +6 -2
  537. package/server/services/memory/markdown.py +6 -6
  538. package/server/services/memory/state.py +6 -5
  539. package/server/services/memory_store.py +8 -12
  540. package/server/services/model_registry.py +22 -20
  541. package/server/services/node_executor.py +85 -80
  542. package/server/services/node_output_schemas.py +4 -7
  543. package/server/services/node_registry.py +40 -4
  544. package/server/services/node_spec.py +3 -7
  545. package/server/services/nodejs_client.py +4 -14
  546. package/server/services/oauth_utils.py +11 -7
  547. package/server/services/parameter_resolver.py +30 -36
  548. package/server/services/plugin/base.py +321 -38
  549. package/server/services/plugin/connection.py +12 -7
  550. package/server/services/plugin/credential.py +80 -22
  551. package/server/services/plugin/edge_walker.py +128 -105
  552. package/server/services/plugin/identifiers.py +48 -0
  553. package/server/services/plugin/interceptor.py +1 -1
  554. package/server/services/plugin/oauth.py +25 -21
  555. package/server/services/plugin/operation.py +1 -1
  556. package/server/services/plugin/polling.py +151 -26
  557. package/server/services/plugin/registry.py +52 -4
  558. package/server/services/plugin/routing.py +6 -9
  559. package/server/services/plugin/scaling.py +36 -18
  560. package/server/services/plugin/service_factories.py +95 -0
  561. package/server/services/plugin/shutdown_hooks.py +103 -0
  562. package/server/services/plugin/social_provider_registry.py +80 -0
  563. package/server/services/plugin/ws.py +2 -1
  564. package/server/services/pricing.py +26 -40
  565. package/server/services/pricing_handlers.py +90 -0
  566. package/server/services/process_service.py +33 -32
  567. package/server/services/proxy/models.py +15 -9
  568. package/server/services/proxy/service.py +26 -40
  569. package/server/services/rlm/adapters.py +43 -40
  570. package/server/services/rlm/constants.py +9 -9
  571. package/server/services/rlm/service.py +57 -45
  572. package/server/services/scheduler.py +8 -39
  573. package/server/services/settings/__init__.py +16 -0
  574. package/server/services/settings/handlers.py +275 -0
  575. package/server/services/skill_loader.py +53 -45
  576. package/server/services/skill_prompt.py +8 -6
  577. package/server/services/skills/__init__.py +23 -0
  578. package/server/services/skills/handlers.py +479 -0
  579. package/server/services/status_broadcaster.py +314 -291
  580. package/server/services/temporal/__init__.py +22 -1
  581. package/server/services/temporal/_handlers.py +65 -0
  582. package/server/services/temporal/_install.py +158 -0
  583. package/server/services/temporal/_refresh.py +57 -0
  584. package/server/services/temporal/_retry_policies.py +85 -0
  585. package/server/services/temporal/_runtime.py +181 -0
  586. package/server/services/temporal/_supervised_runtime.py +102 -0
  587. package/server/services/temporal/activities.py +168 -11
  588. package/server/services/temporal/agent_activities.py +683 -0
  589. package/server/services/temporal/agent_workflow.py +601 -0
  590. package/server/services/temporal/client.py +58 -13
  591. package/server/services/temporal/executor.py +2 -3
  592. package/server/services/temporal/plugin_activities.py +37 -2
  593. package/server/services/temporal/plugin_registry.py +82 -0
  594. package/server/services/temporal/polling_trigger_workflow.py +267 -0
  595. package/server/services/temporal/schedules.py +220 -0
  596. package/server/services/temporal/search_attributes.py +177 -0
  597. package/server/services/temporal/trigger_listener_workflow.py +378 -0
  598. package/server/services/temporal/worker.py +111 -18
  599. package/server/services/temporal/workflow.py +259 -40
  600. package/server/services/temporal/ws_client.py +22 -11
  601. package/server/services/text.py +14 -28
  602. package/server/services/tracked_http.py +29 -49
  603. package/server/services/user_auth.py +7 -21
  604. package/server/services/workflow.py +28 -20
  605. package/server/services/workflow_import.py +351 -0
  606. package/server/services/workflow_ops.py +4 -0
  607. package/server/services/workflow_storage/__init__.py +18 -0
  608. package/server/services/workflow_storage/handlers.py +132 -0
  609. package/server/services/workflow_validator.py +209 -0
  610. package/server/services/ws_handler_registry.py +80 -9
  611. package/server/skills/assistant/agent-builder-skill/SKILL.md +6 -6
  612. package/server/tests/conftest.py +54 -3
  613. package/server/tests/credentials/test_auth_service.py +9 -21
  614. package/server/tests/credentials/test_credential_broadcasts.py +116 -22
  615. package/server/tests/credentials/test_credentials_database.py +12 -38
  616. package/server/tests/credentials/test_encryption.py +3 -9
  617. package/server/tests/credentials/test_google_oauth.py +1 -3
  618. package/server/tests/credentials/test_oauth_utils.py +31 -38
  619. package/server/tests/credentials/test_twitter_oauth.py +1 -3
  620. package/server/tests/credentials/test_websocket_handlers.py +37 -72
  621. package/server/tests/fixtures/tool_names_snapshot.json +78 -0
  622. package/server/tests/llm/test_factory.py +12 -4
  623. package/server/tests/llm/test_providers.py +25 -32
  624. package/server/tests/llm/test_wiring.py +27 -22
  625. package/server/tests/nodes/_compat.py +4 -5
  626. package/server/tests/nodes/_harness.py +31 -24
  627. package/server/tests/nodes/_mocks.py +2 -6
  628. package/server/tests/nodes/test_agent_builder.py +43 -35
  629. package/server/tests/nodes/test_ai_agents.py +29 -24
  630. package/server/tests/nodes/test_ai_chat_models.py +3 -9
  631. package/server/tests/nodes/test_ai_tools.py +29 -24
  632. package/server/tests/nodes/test_android.py +34 -64
  633. package/server/tests/nodes/test_chat_utility.py +2 -2
  634. package/server/tests/nodes/test_code_fs_process.py +26 -84
  635. package/server/tests/nodes/test_document.py +23 -47
  636. package/server/tests/nodes/test_email.py +88 -51
  637. package/server/tests/nodes/test_google_workspace.py +26 -20
  638. package/server/tests/nodes/test_http_proxy.py +43 -89
  639. package/server/tests/nodes/test_search.py +3 -9
  640. package/server/tests/nodes/test_specialized_agents.py +58 -162
  641. package/server/tests/nodes/test_stripe_plugin.py +25 -5
  642. package/server/tests/nodes/test_telegram_social.py +33 -37
  643. package/server/tests/nodes/test_twitter.py +59 -150
  644. package/server/tests/nodes/test_web_automation.py +21 -51
  645. package/server/tests/nodes/test_whatsapp.py +13 -19
  646. package/server/tests/nodes/test_workflow_triggers.py +16 -45
  647. package/server/tests/services/cli_agent/test_claude_session_events.py +201 -0
  648. package/server/tests/services/cli_agent/test_jsonl_watcher.py +190 -0
  649. package/server/tests/services/cli_agent/test_mcp_server.py +67 -29
  650. package/server/tests/services/cli_agent/test_providers.py +236 -47
  651. package/server/tests/services/cli_agent/test_service.py +9 -7
  652. package/server/tests/services/memory/test_jsonl.py +30 -25
  653. package/server/tests/services/test_events.py +26 -7
  654. package/server/tests/services/test_identifiers.py +122 -0
  655. package/server/tests/services/test_process_lifecycle.py +129 -0
  656. package/server/tests/services/test_supervisor.py +0 -1
  657. package/server/tests/temporal/__init__.py +0 -0
  658. package/server/tests/temporal/test_agent_workflow.py +215 -0
  659. package/server/tests/temporal/test_dispatch.py +231 -0
  660. package/server/tests/test_admin_handlers.py +394 -0
  661. package/server/tests/test_auto_skill.py +4 -2
  662. package/server/tests/test_canary_registry.py +310 -0
  663. package/server/tests/test_chat_trigger_canary_producer.py +101 -0
  664. package/server/tests/test_cloudevents_node_parameters.py +129 -0
  665. package/server/tests/test_credential_icon.py +115 -0
  666. package/server/tests/test_cron_canary.py +511 -0
  667. package/server/tests/test_deployment_canary_listener.py +692 -0
  668. package/server/tests/test_event_framework_phase_a.py +537 -0
  669. package/server/tests/test_no_raw_prints.py +131 -0
  670. package/server/tests/test_node_spec.py +196 -103
  671. package/server/tests/test_parameter_resolver.py +20 -20
  672. package/server/tests/test_plugin_contract.py +76 -49
  673. package/server/tests/test_plugin_helpers.py +0 -1
  674. package/server/tests/test_plugin_self_containment.py +40 -47
  675. package/server/tests/test_polling_trigger_workflow.py +572 -0
  676. package/server/tests/test_retry_policies.py +146 -0
  677. package/server/tests/test_service_factories.py +168 -0
  678. package/server/tests/test_shutdown_hooks.py +199 -0
  679. package/server/tests/test_social_provider_registry.py +177 -0
  680. package/server/tests/test_status_broadcasts.py +214 -63
  681. package/server/tests/test_task_trigger_canary_producer.py +131 -0
  682. package/server/tests/test_telegram_trigger_canary_producer.py +113 -0
  683. package/server/tests/test_tool_registry.py +110 -0
  684. package/server/tests/test_trigger_listener_workflow.py +365 -0
  685. package/server/tests/test_whatsapp_trigger_canary_producer.py +164 -0
  686. package/server/tests/test_workflow_ops.py +1 -3
  687. package/server/tests/test_workflow_validator.py +791 -0
  688. package/server/uv.lock +3539 -0
  689. package/client/dist/assets/index-DQ0nwhec.js +0 -257
  690. package/client/src/assets/icons/apify/index.ts +0 -19
  691. package/client/src/assets/icons/browser/index.ts +0 -17
  692. package/client/src/assets/icons/email/index.ts +0 -22
  693. package/client/src/assets/icons/google/index.ts +0 -34
  694. package/client/src/assets/icons/llm/deepseek.svg +0 -1
  695. package/client/src/assets/icons/llm/index.ts +0 -18
  696. package/client/src/assets/icons/llm/kimi.svg +0 -1
  697. package/client/src/assets/icons/llm/mistral.svg +0 -1
  698. package/client/src/assets/icons/search/index.ts +0 -28
  699. package/client/src/assets/icons/telegram/index.ts +0 -19
  700. package/machina/buildenv.py +0 -44
  701. package/machina/cli.py +0 -55
  702. package/machina/commands/__init__.py +0 -1
  703. package/machina/commands/clean.py +0 -80
  704. package/machina/commands/daemon.py +0 -150
  705. package/machina/config.py +0 -93
  706. package/machina/platform_.py +0 -37
  707. package/machina/pyproject.toml +0 -33
  708. package/server/nodes/agent/deep_agent.py +0 -103
  709. package/server/services/agents/__init__.py +0 -9
  710. package/server/services/agents/adapters.py +0 -199
  711. package/server/services/agents/constants.py +0 -10
  712. package/server/services/agents/service.py +0 -297
  713. package/server/services/cli_agent/providers/anthropic_claude.py +0 -419
  714. /package/{machina → cli}/README.md +0 -0
  715. /package/{machina → cli}/__init__.py +0 -0
  716. /package/{client/src/assets/icons/apify → server/credentials/icons}/apify.svg +0 -0
  717. /package/{client/src/assets/icons/search/brave.svg → server/credentials/icons/brave_search.svg} +0 -0
  718. /package/{client/src/assets/icons/email/read.svg → server/credentials/icons/email_himalaya.svg} +0 -0
  719. /package/{client/src/assets/icons/search → server/credentials/icons}/perplexity.svg +0 -0
  720. /package/{client/src/assets/icons/search/google.svg → server/credentials/icons/serper.svg} +0 -0
  721. /package/{client/src/assets → server/credentials}/icons/stripe.svg +0 -0
  722. /package/{client/src/assets/icons/twitter/x.svg → server/credentials/icons/twitter.svg} +0 -0
  723. /package/{client/src/assets/icons/browser/chrome.svg → server/nodes/browser/browser/icon.svg} +0 -0
  724. /package/{client/src/assets/icons/chat/chat.svg → server/nodes/chat/chat_history/icon.svg} +0 -0
  725. /package/{client/src/assets/icons/code/javascript.svg → server/nodes/code/javascript_executor/icon.svg} +0 -0
  726. /package/{client/src/assets/icons/code/python.svg → server/nodes/code/python_executor/icon.svg} +0 -0
  727. /package/{client/src/assets/icons/code/typescript.svg → server/nodes/code/typescript_executor/icon.svg} +0 -0
  728. /package/{client/src/assets/icons/email/receive.svg → server/nodes/email/email_receive/icon.svg} +0 -0
  729. /package/{client/src/assets/icons/email/send.svg → server/nodes/email/email_send/icon.svg} +0 -0
  730. /package/{client/src/assets/icons/google/calendar.svg → server/nodes/google/calendar/icon.svg} +0 -0
  731. /package/{client/src/assets/icons/google/contacts.svg → server/nodes/google/contacts/icon.svg} +0 -0
  732. /package/{client/src/assets/icons/google/drive.svg → server/nodes/google/drive/icon.svg} +0 -0
  733. /package/{client/src/assets/icons/google/gmail.svg → server/nodes/google/gmail/icon.svg} +0 -0
  734. /package/{client/src/assets/icons/google/sheets.svg → server/nodes/google/sheets/icon.svg} +0 -0
  735. /package/{client/src/assets/icons/google/tasks.svg → server/nodes/google/tasks/icon.svg} +0 -0
  736. /package/{client/src/assets/icons/search/duckduckgo.svg → server/nodes/search/duckduckgo_search/icon.svg} +0 -0
  737. /package/{client/src/assets/icons/social/social.svg → server/nodes/social/social_receive/icon.svg} +0 -0
  738. /package/{client/src/assets/icons/telegram/telegram.svg → server/nodes/telegram/icon.svg} +0 -0
  739. /package/server/nodes/utility/{team_monitor.py → team_monitor/__init__.py} +0 -0
  740. /package/{client/src/assets/icons/whatsapp/whatsapp-db.svg → server/nodes/whatsapp/icon_whatsappDb.svg} +0 -0
  741. /package/{client/src/assets/icons/whatsapp/whatsapp-receive.svg → server/nodes/whatsapp/icon_whatsappReceive.svg} +0 -0
  742. /package/{client/src/assets/icons/whatsapp/whatsapp-send.svg → server/nodes/whatsapp/icon_whatsappSend.svg} +0 -0
  743. /package/{client/src/assets/icons → server/nodes}/whatsapp/whatsapp.svg +0 -0
@@ -7,13 +7,22 @@ same battle-tested ``psutil`` paths that are already in production.
7
7
  from __future__ import annotations
8
8
 
9
9
  import os
10
+ import signal
10
11
  import sys
11
12
  import subprocess
13
+ import time
12
14
  from dataclasses import dataclass
13
15
 
14
16
  import psutil
15
17
 
16
18
 
19
+ # Post-kill grace before re-checking the port. Windows can lag a few
20
+ # hundred ms releasing the listener socket after the bound process
21
+ # dies — without this, ``kill_port`` reports the port still in use
22
+ # even though the kill succeeded.
23
+ _POST_KILL_RECHECK_DELAY = 0.5
24
+
25
+
17
26
  @dataclass
18
27
  class KillResult:
19
28
  port: int
@@ -50,10 +59,30 @@ def find_pids_by_port(port: int) -> set[int]:
50
59
 
51
60
 
52
61
  def kill_pid(pid: int, *, graceful_timeout: float = 3.0) -> bool:
53
- """Terminate ``pid`` gracefully, then force-kill on timeout."""
62
+ """Terminate ``pid`` gracefully, then force-kill on timeout.
63
+
64
+ Windows: send ``CTRL_BREAK_EVENT`` first so daemons spawned with
65
+ ``CREATE_NEW_PROCESS_GROUP`` (the supervisor's children — see
66
+ ``cli/tree.py:new_session_kwargs``) get a real shutdown signal and
67
+ can release listener sockets cleanly. ``proc.terminate()``
68
+ (= ``TerminateProcess``) is the fallback for processes that weren't
69
+ spawned with a process group — equivalent to SIGKILL, leaves the
70
+ OS holding sockets briefly. Same pattern as
71
+ ``cli/supervisor.py:_stop_proc``.
72
+
73
+ POSIX: plain ``proc.terminate()`` (SIGTERM).
74
+ """
54
75
  try:
55
76
  proc = psutil.Process(pid)
56
- proc.terminate()
77
+ if sys.platform == "win32":
78
+ try:
79
+ os.kill(pid, signal.CTRL_BREAK_EVENT)
80
+ except (OSError, ProcessLookupError):
81
+ # Target wasn't in its own process group — fall back
82
+ # to TerminateProcess via psutil.terminate.
83
+ proc.terminate()
84
+ else:
85
+ proc.terminate()
57
86
  try:
58
87
  proc.wait(timeout=graceful_timeout)
59
88
  except psutil.TimeoutExpired:
@@ -64,7 +93,15 @@ def kill_pid(pid: int, *, graceful_timeout: float = 3.0) -> bool:
64
93
 
65
94
 
66
95
  def kill_port(port: int) -> KillResult:
67
- """Kill anything listening on ``port`` and report whether the port is free."""
96
+ """Kill anything listening on ``port`` and report whether the port is free.
97
+
98
+ Post-kill recheck sleeps ``_POST_KILL_RECHECK_DELAY`` because Windows
99
+ can lag a few hundred ms releasing the listener socket after the
100
+ bound process dies — without this, ``temporal server start-dev``'s
101
+ UI port (8080) frequently re-reports as in-use immediately after the
102
+ gRPC port kill, even though the kill on temporal.exe (one process
103
+ binds both ports — per docs.temporal.io/cli/server) succeeded.
104
+ """
68
105
  my_pid = os.getpid()
69
106
  killed: list[int] = []
70
107
  for pid in find_pids_by_port(port):
@@ -72,6 +109,8 @@ def kill_port(port: int) -> KillResult:
72
109
  continue
73
110
  if kill_pid(pid):
74
111
  killed.append(pid)
112
+ if killed:
113
+ time.sleep(_POST_KILL_RECHECK_DELAY)
75
114
  port_free = not find_pids_by_port(port)
76
115
  return KillResult(port=port, killed_pids=killed, port_free=port_free)
77
116
 
@@ -1,4 +1,4 @@
1
- """Shared subprocess helpers used across ``machina.commands``.
1
+ """Shared subprocess helpers used across ``cli.commands``.
2
2
 
3
3
  Two patterns covering ~95% of subprocess use in this CLI:
4
4
 
@@ -23,7 +23,7 @@ from pathlib import Path
23
23
 
24
24
  import typer
25
25
 
26
- from machina.colors import console
26
+ from cli.colors import console
27
27
 
28
28
 
29
29
  def which_argv(argv: list[str]) -> list[str]:
@@ -40,6 +40,33 @@ def which_argv(argv: list[str]) -> list[str]:
40
40
  return [shutil.which(argv[0]) or argv[0], *argv[1:]]
41
41
 
42
42
 
43
+ def uv_run(*args: str) -> list[str]:
44
+ """Standardized argv for executing a command inside the workspace
45
+ ``.venv`` via ``uv run``.
46
+
47
+ ``uv run`` is the documented subcommand for executing commands
48
+ against a uv project / workspace environment
49
+ (https://docs.astral.sh/uv/reference/cli/#uv-run). With the workspace
50
+ declared in the repo-root ``pyproject.toml``, ``uv sync`` materialises
51
+ one shared ``.venv`` at the workspace root and installs every member
52
+ (currently ``server/``) editable into it -- so ``python -m
53
+ services.*`` resolves out of that single environment
54
+ (https://docs.astral.sh/uv/concepts/projects/sync/).
55
+
56
+ ``--no-sync`` skips the per-invocation lockfile re-check that ``uv
57
+ run`` does by default. ``machina build`` is the single place that
58
+ actually re-syncs; every other entry point (start, dev, daemon,
59
+ supervised runtimes, preflight) trusts the lockfile and just
60
+ activates the env. This is the documented optimisation for hot
61
+ spawn paths (https://docs.astral.sh/uv/reference/cli/#uv-run).
62
+
63
+ All ``uv run ...`` invocations in this CLI MUST go through this
64
+ helper -- never inline ``["uv", "run", ...]`` argv lists -- so the
65
+ flags + semantics stay uniform.
66
+ """
67
+ return ["uv", "run", "--no-sync", *args]
68
+
69
+
43
70
  def run(
44
71
  argv: list[str],
45
72
  *,
@@ -30,16 +30,16 @@ from typing import Iterable, Optional
30
30
 
31
31
  import anyio
32
32
 
33
- from machina.colors import emit, next_color
34
- from machina.run import which_argv
35
- from machina.tcp import wait_for_tcp_port
36
- from machina.tree import add_to_job, kill_tree, new_session_kwargs
33
+ from cli.colors import emit, next_color
34
+ from cli.run import which_argv
35
+ from cli.tcp import wait_for_tcp_port
36
+ from cli.tree import add_to_job, kill_tree, new_session_kwargs
37
37
 
38
38
 
39
39
  class RestartPolicy(enum.Enum):
40
40
  NEVER = "never"
41
- ON_CRASH = "on_crash" # restart only on non-healthy exit
42
- ALWAYS = "always" # restart on any exit
41
+ ON_CRASH = "on_crash" # restart only on non-healthy exit
42
+ ALWAYS = "always" # restart on any exit
43
43
 
44
44
 
45
45
  @dataclass
@@ -184,7 +184,19 @@ class Manager:
184
184
  await anyio.sleep_forever()
185
185
 
186
186
  async def _stop_proc(self, proc: anyio.abc.Process, spec: ServiceSpec) -> None:
187
- """SIGTERM (POSIX) / TerminateProcess (Win) -> wait grace -> tree-kill.
187
+ """Graceful stop -> wait grace -> tree-kill.
188
+
189
+ POSIX: ``proc.terminate()`` sends ``SIGTERM`` to the child.
190
+
191
+ Windows: ``os.kill(pid, CTRL_BREAK_EVENT)`` — the only Win32
192
+ signal-equivalent that lets a child run cleanup handlers. We
193
+ spawn every child with ``CREATE_NEW_PROCESS_GROUP``
194
+ (``cli/tree.py:new_session_kwargs``) so ``CTRL_BREAK_EVENT`` is
195
+ deliverable. The alternative — ``proc.terminate()`` — maps to
196
+ ``TerminateProcess()``, which is an instant hard kill (exit
197
+ code 1, no flush, no atexit, no buffer drain). That's what was
198
+ making temporal log ``stopped (exit 1)`` on every Ctrl+C.
199
+ See https://docs.python.org/3/library/subprocess.html#subprocess.CREATE_NEW_PROCESS_GROUP.
188
200
 
189
201
  Wrapped in ``CancelScope(shield=True)`` -- this is the anyio-
190
202
  documented idiom for cleanup that must run to completion during
@@ -200,8 +212,11 @@ class Manager:
200
212
  emit(spec.name, color, "stopping", stream="stderr")
201
213
  with anyio.CancelScope(shield=True):
202
214
  try:
203
- proc.terminate()
204
- except ProcessLookupError:
215
+ if sys.platform == "win32":
216
+ os.kill(proc.pid, signal.CTRL_BREAK_EVENT)
217
+ else:
218
+ proc.terminate()
219
+ except (ProcessLookupError, OSError):
205
220
  return
206
221
  with anyio.move_on_after(spec.terminate_grace_seconds):
207
222
  await proc.wait()
@@ -348,7 +363,9 @@ class Manager:
348
363
  spec.ready_port, # type: ignore[arg-type]
349
364
  timeout=spec.ready_timeout,
350
365
  )
351
- msg = f"ready on port {spec.ready_port}" if ok else f"timed out waiting for port {spec.ready_port}"
366
+ msg = (
367
+ f"ready on port {spec.ready_port}"
368
+ if ok
369
+ else f"timed out waiting for port {spec.ready_port}"
370
+ )
352
371
  emit(spec.name, spec.color or "white", msg)
353
-
354
-
@@ -7,7 +7,9 @@ import socket
7
7
  import time
8
8
 
9
9
 
10
- async def probe_tcp_port(port: int, host: str = "127.0.0.1", *, timeout: float = 0.5) -> bool:
10
+ async def probe_tcp_port(
11
+ port: int, host: str = "127.0.0.1", *, timeout: float = 0.5
12
+ ) -> bool:
11
13
  """Return True iff a TCP connection to ``host:port`` succeeds within ``timeout``."""
12
14
  try:
13
15
  _, writer = await asyncio.wait_for(
@@ -39,7 +41,9 @@ async def wait_for_tcp_port(
39
41
  return False
40
42
 
41
43
 
42
- def probe_tcp_port_sync(port: int, host: str = "127.0.0.1", *, timeout: float = 0.5) -> bool:
44
+ def probe_tcp_port_sync(
45
+ port: int, host: str = "127.0.0.1", *, timeout: float = 0.5
46
+ ) -> bool:
43
47
  """Synchronous variant for places that aren't already in an event loop."""
44
48
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45
49
  sock.settimeout(timeout)
@@ -1,12 +1,29 @@
1
1
  """Cross-platform process-tree control.
2
2
 
3
- The single most important pattern from VS Code's process model:
4
- guarantee that supervised children die when the supervisor dies. On
5
- POSIX we use ``setsid`` + ``killpg``. On Windows we use a Job Object
6
- with ``JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`` so the OS atomically reaps
7
- every descendant when the supervisor handle closes.
3
+ Two cooperating mechanisms guarantee supervised children die when we
4
+ want them to (gracefully) AND die when the supervisor dies (forcibly):
5
+
6
+ POSIX:
7
+ - ``setsid`` makes each child a process-group leader so ``killpg``
8
+ reaches the whole descendant tree.
9
+
10
+ Windows:
11
+ - ``CREATE_NEW_PROCESS_GROUP`` (per-child) so the supervisor can
12
+ target each child with ``CTRL_BREAK_EVENT`` for graceful shutdown
13
+ without the signal also reaching the supervisor itself
14
+ (https://docs.python.org/3/library/subprocess.html#subprocess.CREATE_NEW_PROCESS_GROUP).
15
+ Required because ``proc.terminate()`` on Windows is
16
+ ``TerminateProcess()`` — an instant hard kill that leaves no time
17
+ for cleanup and forces exit code 1.
18
+ - A single Job Object with ``JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`` for
19
+ automatic atomic tree-kill if the supervisor dies abnormally.
20
+ Children created by ``CreateProcess`` auto-inherit the job, so
21
+ grandchildren are reaped without manual tree walks
22
+ (https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects).
8
23
 
9
24
  References:
25
+ - https://docs.python.org/3/library/subprocess.html#subprocess.CREATE_NEW_PROCESS_GROUP
26
+ - https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects
10
27
  - https://nikhilism.com/post/2017/windows-job-objects-process-tree-management/
11
28
  - microsoft/node-pty (uses Job Objects in production)
12
29
  """
@@ -15,23 +32,31 @@ from __future__ import annotations
15
32
 
16
33
  import os
17
34
  import signal
35
+ import subprocess
18
36
  import sys
19
37
  from typing import Optional
20
38
 
21
39
  import psutil
22
40
 
23
41
 
24
- # ---------------------------------------------------------------- POSIX
42
+ # ---------------------------------------------------------------- POSIX / Windows spawn kwargs
43
+
25
44
 
26
45
  def new_session_kwargs() -> dict:
27
- """``Popen``/``open_process`` kwargs to start the child in a new session.
46
+ """``Popen``/``open_process`` kwargs to spawn the child in its own group.
47
+
48
+ POSIX: ``start_new_session=True`` (``setsid``) makes the child a
49
+ process-group leader so ``killpg`` reaches the whole tree.
28
50
 
29
- Empty dict on Windows; uses ``start_new_session`` on POSIX so the
30
- child is the leader of its own process group and ``killpg`` reaches
31
- the entire descendant tree.
51
+ Windows: ``creationflags=CREATE_NEW_PROCESS_GROUP`` so the child can
52
+ receive ``CTRL_BREAK_EVENT`` from the supervisor without the console
53
+ Ctrl+C also reaching it. Without this flag, ``proc.terminate()`` on
54
+ Windows falls back to ``TerminateProcess()`` (instant hard kill,
55
+ exit 1, no cleanup chance) — what we're trying to avoid for daemons
56
+ like temporal that buffer state.
32
57
  """
33
58
  if sys.platform == "win32":
34
- return {}
59
+ return {"creationflags": subprocess.CREATE_NEW_PROCESS_GROUP}
35
60
  return {"start_new_session": True}
36
61
 
37
62
 
@@ -47,6 +72,7 @@ def signal_group(pid: int, sig: signal.Signals = signal.SIGTERM) -> None:
47
72
 
48
73
  # ---------------------------------------------------------------- Windows Job Object
49
74
 
75
+
50
76
  class _JobObject:
51
77
  """Lazy-imported wrapper around a Windows Job Object.
52
78
 
@@ -154,6 +180,7 @@ def add_to_job(pid: int) -> bool:
154
180
 
155
181
  # --------------------------------------------------------------- Tree kill
156
182
 
183
+
157
184
  def kill_tree(pid: int) -> None:
158
185
  """Cross-platform tree-kill via psutil. Defensive against races."""
159
186
  try:
@@ -1 +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-DQ0nwhec.js";import{j as l}from"./vendor-query-SzWcOU0G.js";import{q as b}from"./vendor-icons-CVrPjN2Q.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};
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-P2FzntoL.js";import{j as l}from"./vendor-query-SzWcOU0G.js";import{q as b}from"./vendor-icons-CVrPjN2Q.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};
@@ -1 +1 @@
1
- import{a as u,j as s}from"./vendor-query-SzWcOU0G.js";import{I as j,B as o}from"./index-DQ0nwhec.js";import{ay as d,az as v,q as y,v as N,B as w,T as k}from"./vendor-icons-CVrPjN2Q.js";const E=({value:l,onChange:c,onSave:m,onDelete:i,placeholder:x="Enter API key...",loading:n=!1,isStored:a=!1,disabled:e=!1,saveLabel:h="Validate",savedLabel:f="Valid"})=>{const[t,p]=u.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(j,{type:t?"text":"password",value:l,onChange:r=>c(r.target.value),placeholder:x,disabled:e,className:"font-mono pr-9"}),s.jsx("button",{type:"button",onClick:()=>p(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(v,{className:"h-4 w-4"})})]}),s.jsxs(o,{variant:"default",onClick:m,disabled:!l.trim()||e||n,children:[n?s.jsx(y,{className:"h-4 w-4 animate-spin"}):a?s.jsx(N,{className:"h-4 w-4"}):s.jsx(w,{className:"h-4 w-4"}),a?f:h]}),a&&i&&s.jsx(o,{variant:"destructive",size:"icon",onClick:i,disabled:e,children:s.jsx(k,{className:"h-4 w-4"})})]})};export{E as A};
1
+ import{a as u,j as s}from"./vendor-query-SzWcOU0G.js";import{I as j,B as o}from"./index-P2FzntoL.js";import{ay as d,az as v,q as y,v as N,B as w,T as k}from"./vendor-icons-CVrPjN2Q.js";const E=({value:l,onChange:c,onSave:m,onDelete:i,placeholder:x="Enter API key...",loading:n=!1,isStored:a=!1,disabled:e=!1,saveLabel:h="Validate",savedLabel:f="Valid"})=>{const[t,p]=u.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(j,{type:t?"text":"password",value:l,onChange:r=>c(r.target.value),placeholder:x,disabled:e,className:"font-mono pr-9"}),s.jsx("button",{type:"button",onClick:()=>p(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(v,{className:"h-4 w-4"})})]}),s.jsxs(o,{variant:"default",onClick:m,disabled:!l.trim()||e||n,children:[n?s.jsx(y,{className:"h-4 w-4 animate-spin"}):a?s.jsx(N,{className:"h-4 w-4"}):s.jsx(w,{className:"h-4 w-4"}),a?f:h]}),a&&i&&s.jsx(o,{variant:"destructive",size:"icon",onClick:i,disabled:e,children:s.jsx(k,{className:"h-4 w-4"})})]})};export{E as A};
@@ -1 +1 @@
1
- import{a as A,j as s}from"./vendor-query-SzWcOU0G.js";import{u as E,A as V,a as P,b as U,c as q,d as R,e as K,B as z,f as F,N as H,C as M,g as O,h as G,i as I,j as T,L as J,I as Q,k as W}from"./index-DQ0nwhec.js";import{A as X}from"./ApiKeyInput-k2LBmBjb.js";import{u as Y,P as Z}from"./RateLimitSection-Du5YNVIA.js";import{ax as ee,q as L,au as se,v as ae}from"./vendor-icons-CVrPjN2Q.js";import{A as te}from"./ApiUsageSection-CmVfwZzL.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(q,{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(z,{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(H,{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(M,{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(O,{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};
1
+ import{a as A,j as s}from"./vendor-query-SzWcOU0G.js";import{u as E,A as V,a as P,b as U,c as q,d as R,e as K,B as z,f as F,N as H,C as M,g as O,h as G,i as I,j as T,L as J,I as Q,k as W}from"./index-P2FzntoL.js";import{A as X}from"./ApiKeyInput-DIJE2PVA.js";import{u as Y,P as Z}from"./RateLimitSection-CfNOoPIS.js";import{ax as ee,q as L,au as se,v as ae}from"./vendor-icons-CVrPjN2Q.js";import{A as te}from"./ApiUsageSection-TF_7gH2D.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(q,{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(z,{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(H,{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(M,{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(O,{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};
@@ -1 +1 @@
1
- import{a as x,j as e}from"./vendor-query-SzWcOU0G.js";import{u as h,g as u,A as g,a as v,b as N,c as b,d as y,e as w,B as A,f as C}from"./index-DQ0nwhec.js";import{ax as _,q as f,au as S}from"./vendor-icons-CVrPjN2Q.js";const R=({service:d,serviceName:s})=>{const{getAPIUsageSummary:o,isConnected:n}=h(),[a,l]=x.useState(null),[c,t]=x.useState(!1),r=x.useCallback(async()=>{if(n){t(!0);try{const i=await o(d);l(i.find(j=>j.service===d)??null)}finally{t(!1)}}},[n,d,o]);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(v,{value:"usage",children:[e.jsx(N,{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(b,{children:c?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(i=>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:i.operation}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(u,{variant:"outline",children:[i.resource_count," resources"]}),e.jsxs(u,{variant:"success",children:["$",i.total_cost.toFixed(4)]})]})]},i.operation))})]}),e.jsxs(A,{size:"sm",variant:"outline",onClick:r,disabled:c,children:[c?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:o,value:n,className:a}=d;let l;s[0]!==o?(l=e.jsx("span",{className:"text-xs text-muted-foreground",children:o}),s[0]=o,s[1]=l):l=s[1];const c=`text-lg font-semibold ${a??""}`;let t;s[2]!==c||s[3]!==n?(t=e.jsx("span",{className:c,children:n}),s[2]=c,s[3]=n,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{R as A};
1
+ import{a as x,j as e}from"./vendor-query-SzWcOU0G.js";import{u as h,g as u,A as g,a as v,b as N,c as b,d as y,e as w,B as A,f as C}from"./index-P2FzntoL.js";import{ax as _,q as f,au as S}from"./vendor-icons-CVrPjN2Q.js";const R=({service:d,serviceName:s})=>{const{getAPIUsageSummary:o,isConnected:n}=h(),[a,l]=x.useState(null),[c,t]=x.useState(!1),r=x.useCallback(async()=>{if(n){t(!0);try{const i=await o(d);l(i.find(j=>j.service===d)??null)}finally{t(!1)}}},[n,d,o]);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(v,{value:"usage",children:[e.jsx(N,{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(b,{children:c?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(i=>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:i.operation}),e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsxs(u,{variant:"outline",children:[i.resource_count," resources"]}),e.jsxs(u,{variant:"success",children:["$",i.total_cost.toFixed(4)]})]})]},i.operation))})]}),e.jsxs(A,{size:"sm",variant:"outline",onClick:r,disabled:c,children:[c?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:o,value:n,className:a}=d;let l;s[0]!==o?(l=e.jsx("span",{className:"text-xs text-muted-foreground",children:o}),s[0]=o,s[1]=l):l=s[1];const c=`text-lg font-semibold ${a??""}`;let t;s[2]!==c||s[3]!==n?(t=e.jsx("span",{className:c,children:n}),s[2]=c,s[3]=n,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{R as A};
@@ -1 +1 @@
1
- import{a as l,j as e}from"./vendor-query-SzWcOU0G.js";import{c as B}from"./vendor-react-DvWIbVx0.js";import{O as G,P as I,R as j,T as z,_ as Y,u as J,t as Q,N as W,F as X,v as m,w as n,x as d,y as Z,z as c,D as $,E as ee,G as se,H as ae,K as p,I as f,J as re,d as oe,e as te,k as M}from"./index-DQ0nwhec.js";import{S as ie}from"./StatusCard-DNLyayXc.js";import{ay as le,az as me,q as F}from"./vendor-icons-CVrPjN2Q.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.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),[S,b]=l.useState(""),[P,g]=l.useState(null),[N,w]=l.useState(null),[y,O]=l.useState(!1),U=l.useMemo(()=>ce(!i),[i]),r=B({resolver:Q(U),defaultValues:T,mode:"onSubmit"}),A=r.watch("provider");l.useEffect(()=>{if(!x||!_)return;let s=!1;return(async()=>{try{const[a,H,K,q,E,L,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:q||"",imapPort:E?parseInt(E,10):993,smtpHost:L||"",smtpPort:C?parseInt(C,10):465}),b(H||""),v(K)}catch{s||v(!1)}})(),()=>{s=!0}},[x,_]);const V=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),b(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),b(""),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:S},rows:[{label:"Status",ok:s=>s.stored,trueText:"Configured",falseText:"Not configured"},...i&&S?[{label:"Account",ok:()=>!0,trueText:S,falseText:""}]:[]]}),e.jsx(X,{...r,children:e.jsxs("form",{id:"email-form",onSubmit:r.handleSubmit(V),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:()=>O(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};
1
+ import{a as l,j as e}from"./vendor-query-SzWcOU0G.js";import{c as B}from"./vendor-react-DvWIbVx0.js";import{O as G,P as I,R as f,T as z,_ as Y,u as J,t as Q,N as W,F as X,v as m,w as n,x as d,y as Z,z as c,D as $,E as ee,G as se,H as ae,K as p,I as j,J as re,d as oe,e as te,k as M}from"./index-P2FzntoL.js";import{S as ie}from"./StatusCard-DkwIrgdP.js";import{ay as le,az as me,q as F}from"./vendor-icons-CVrPjN2Q.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.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:f().min(1,"Email address is required").pipe(z("Enter a valid email address")),password:u?f().min(1,"Password is required"):f().optional(),imapHost:f().optional(),imapPort:I().int().min(1).max(65535).optional(),smtpHost:f().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:y}=J(),[i,v]=l.useState(!1),[S,_]=l.useState(""),[P,g]=l.useState(null),[N,w]=l.useState(null),[b,O]=l.useState(!1),U=l.useMemo(()=>ce(!i),[i]),r=B({resolver:Q(U),defaultValues:T,mode:"onSubmit"}),A=r.watch("provider");l.useEffect(()=>{if(!x||!y)return;let s=!1;return(async()=>{try{const[a,H,K,q,E,L,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:q||"",imapPort:E?parseInt(E,10):993,smtpHost:L||"",smtpPort:C?parseInt(C,10):465}),_(H||""),v(K)}catch{s||v(!1)}})(),()=>{s=!0}},[x,y]);const V=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.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),_(""),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:S},rows:[{label:"Status",ok:s=>s.stored,trueText:"Configured",falseText:"Not configured"},...i&&S?[{label:"Account",ok:()=>!0,trueText:S,falseText:""}]:[]]}),e.jsx(X,{...r,children:e.jsxs("form",{id:"email-form",onSubmit:r.handleSubmit(V),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(j,{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(j,{type:b?"text":"password",placeholder:i?"••••••••":"App password or account password",className:"font-mono pr-9",...s}),e.jsx("button",{type:"button",onClick:()=>O(a=>!a),className:"absolute top-1/2 right-2 -translate-y-1/2 text-muted-foreground hover:text-foreground","aria-label":b?"Hide password":"Show password",children:b?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(j,{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(j,{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(j,{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(j,{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};
@@ -1 +1 @@
1
- import{j as l,a as I}from"./vendor-query-SzWcOU0G.js";import{f as O,L as P,I as z,k as B,d as D,e as H,N as Y}from"./index-DQ0nwhec.js";import{u as G}from"./RateLimitSection-Du5YNVIA.js";import{A as J,u as K}from"./ActionBar-Du2MSFSz.js";import{ay as M,az as Q,q as W,R as X}from"./vendor-icons-CVrPjN2Q.js";import{S as Z}from"./StatusCard-DNLyayXc.js";import{A as ee}from"./ApiUsageSection-CmVfwZzL.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(z,{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 j;e[8]!==s||e[9]!==u||e[10]!==_||e[11]!==U?(j={key:"login",label:_,intent:"save",onClick:u,disabled:U,hidden:s},e[8]=s,e[9]=u,e[10]=_,e[11]=U,e[12]=j):j=e[12];const V=!s;let b;e[13]!==m||e[14]!==V?(b={key:"logout",label:"Disconnect",intent:"stop",onClick:m,hidden:V},e[13]=m,e[14]=V,e[15]=b):b=e[15];let w;e[16]===Symbol.for("react.memo_cache_sentinel")?(w=l.jsx(X,{className:"h-4 w-4"}),e[16]=w):w=e[16];let k;e[17]!==x?(k={key:"refresh",label:"Refresh",intent:"save",onClick:x,icon:w},e[17]=x,e[18]=k):k=e[18];let L;e[19]!==k||e[20]!==j||e[21]!==b?(L=[j,b,k],e[19]=k,e[20]=j,e[21]=b,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(B,{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 y;e[35]!==o?(y=o&&l.jsx(D,{variant:"destructive",children:l.jsx(H,{children:o})}),e[35]=o,e[36]=y):y=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 C;e[37]!==T?(C=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]=C):C=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 R;e[40]!==q||e[41]!==n?(R=l.jsx(J,{actions:q,loading:n}),e[40]=q,e[41]=n,e[42]=R):R=e[42];let $;return e[43]!==h||e[44]!==N||e[45]!==S||e[46]!==y||e[47]!==C||e[48]!==R?($=l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4",children:[N,S,y,C,h,F,R]}),e[43]=h,e[44]=N,e[45]=S,e[46]=y,e[47]=C,e[48]=R,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};
1
+ import{j as l,a as I}from"./vendor-query-SzWcOU0G.js";import{f as O,L as P,I as z,k as B,d as D,e as H,N as Y}from"./index-P2FzntoL.js";import{u as G}from"./RateLimitSection-CfNOoPIS.js";import{A as J,u as K}from"./ActionBar-Cjr3TF7g.js";import{ay as M,az as Q,q as W,R as X}from"./vendor-icons-CVrPjN2Q.js";import{S as Z}from"./StatusCard-DkwIrgdP.js";import{A as ee}from"./ApiUsageSection-TF_7gH2D.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-misc-C4VxKHs5.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(z,{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 j;e[8]!==s||e[9]!==u||e[10]!==_||e[11]!==U?(j={key:"login",label:_,intent:"save",onClick:u,disabled:U,hidden:s},e[8]=s,e[9]=u,e[10]=_,e[11]=U,e[12]=j):j=e[12];const V=!s;let b;e[13]!==m||e[14]!==V?(b={key:"logout",label:"Disconnect",intent:"stop",onClick:m,hidden:V},e[13]=m,e[14]=V,e[15]=b):b=e[15];let w;e[16]===Symbol.for("react.memo_cache_sentinel")?(w=l.jsx(X,{className:"h-4 w-4"}),e[16]=w):w=e[16];let k;e[17]!==x?(k={key:"refresh",label:"Refresh",intent:"save",onClick:x,icon:w},e[17]=x,e[18]=k):k=e[18];let L;e[19]!==k||e[20]!==j||e[21]!==b?(L=[j,b,k],e[19]=k,e[20]=j,e[21]=b,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(B,{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 y;e[35]!==o?(y=o&&l.jsx(D,{variant:"destructive",children:l.jsx(H,{children:o})}),e[35]=o,e[36]=y):y=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 C;e[37]!==T?(C=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]=C):C=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 R;e[40]!==q||e[41]!==n?(R=l.jsx(J,{actions:q,loading:n}),e[40]=q,e[41]=n,e[42]=R):R=e[42];let $;return e[43]!==h||e[44]!==N||e[45]!==S||e[46]!==y||e[47]!==C||e[48]!==R?($=l.jsxs("div",{className:"flex min-h-0 flex-1 flex-col gap-4",children:[N,S,y,C,h,F,R]}),e[43]=h,e[44]=N,e[45]=S,e[46]=y,e[47]=C,e[48]=R,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};
@@ -1 +1 @@
1
- import{j as e,a as d,R as b}from"./vendor-query-SzWcOU0G.js";import{d as S,l as k,e as _,m as w,N as A}from"./index-DQ0nwhec.js";import{A as v}from"./ApiKeyInput-k2LBmBjb.js";import{Q as E}from"./vendor-misc-C4VxKHs5.js";import{v as W,q as F,aA as q,t as Q}from"./vendor-icons-CVrPjN2Q.js";import{u as M,R as T}from"./RateLimitSection-Du5YNVIA.js";import{u as L,A as D}from"./ActionBar-Du2MSFSz.js";import{S as P}from"./StatusCard-DNLyayXc.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(q,{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(Q,{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 b.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(Q,{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),[j,n]=d.useState(null),[p,y]=d.useState(null),m=d.useCallback(async()=>{o(!0),n(null);try{const r=await t();return y(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&&y({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:j,connectionStatus:p,isConnected:x}},re=({config:t,visible:c})=>{const s=M(t,c),a=L(t.statusHook),{startConnection:u,restartConnection:x,getStatus:h}=H(),{sendRequest:o,setAndroidStatus:j}=w(),n=t.qr,p=n.isConnected(a),y=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&&j(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,j]),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:y,isConnected:p,size:280,connectedTitle:n.connectedTitle,connectedSubtitle:n.connectedSubtitle(a),loading:n.isLoading(a),emptyText:n.emptyText(a,s.stored)}),!p&&y&&e.jsx("div",{className:"mt-3 text-sm text-muted-foreground",children:n.scanText})]}),t.hasRateLimits&&p&&e.jsx(T,{}),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};
1
+ import{j as e,a as d,R as b}from"./vendor-query-SzWcOU0G.js";import{d as S,l as k,e as _,m as w,N as A}from"./index-P2FzntoL.js";import{A as v}from"./ApiKeyInput-DIJE2PVA.js";import{Q as E}from"./vendor-misc-C4VxKHs5.js";import{v as W,q as F,aA as q,t as Q}from"./vendor-icons-CVrPjN2Q.js";import{u as M,R as T}from"./RateLimitSection-CfNOoPIS.js";import{u as L,A as D}from"./ActionBar-Cjr3TF7g.js";import{S as P}from"./StatusCard-DkwIrgdP.js";import"./vendor-flow-CZmBvHRo.js";import"./vendor-radix-Dnos29jG.js";import"./vendor-markdown-CRou3yQ5.js";import"./vendor-react-DvWIbVx0.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(q,{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(Q,{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 b.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(Q,{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),[j,n]=d.useState(null),[p,y]=d.useState(null),m=d.useCallback(async()=>{o(!0),n(null);try{const r=await t();return y(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&&y({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:j,connectionStatus:p,isConnected:x}},re=({config:t,visible:c})=>{const s=M(t,c),a=L(t.statusHook),{startConnection:u,restartConnection:x,getStatus:h}=H(),{sendRequest:o,setAndroidStatus:j}=w(),n=t.qr,p=n.isConnected(a),y=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&&j(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,j]),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:y,isConnected:p,size:280,connectedTitle:n.connectedTitle,connectedSubtitle:n.connectedSubtitle(a),loading:n.isLoading(a),emptyText:n.emptyText(a,s.stored)}),!p&&y&&e.jsx("div",{className:"mt-3 text-sm text-muted-foreground",children:n.scanText})]}),t.hasRateLimits&&p&&e.jsx(T,{}),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};
@@ -1 +1 @@
1
- import{d as pe,a as o,u as je,j as e}from"./vendor-query-SzWcOU0G.js";import{u as le,m as se,s as G,S as ge,t as re,A as oe,a as ie,b as ce,c as de,F as ue,v as _,w,x as S,y as J,z as C,D as Y,E as I,G as X,H as O,J as D,K as Q,g as B,I as $,M as Z,B as ee,O as me,_ as ne,P as b,Q as H,R as ye,d as _e,e as ve,f as be}from"./index-DQ0nwhec.js";import{c as xe}from"./vendor-react-DvWIbVx0.js";import{S as we,q as he}from"./vendor-icons-CVrPjN2Q.js";const W={};function Pe(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}=le(),{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=me({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()}),Ve=({providerId:n})=>{const{getProviderDefaults:l,saveProviderDefaults:x,getStoredModels:h,getModelConstraints:j,isConnected:p}=le(),{apiKeyStatuses:c}=se(),F=c[n],[v,u]=o.useState([]),[y,A]=o.useState(null),[R,P]=o.useState(!1),i=xe({resolver:re(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(oe,{type:"single",collapsible:!0,defaultValue:"defaults",children:e.jsxs(ie,{value:"defaults",children:[e.jsx(ce,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-4 w-4"})," Default Parameters"]})}),e.jsx(de,{children:e.jsx("div",{className:R?"pointer-events-none opacity-60":"",children:e.jsx(ue,{...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=me({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))},Ke=()=>{const{getWhatsAppRateLimitConfig:n,setWhatsAppRateLimitConfig:l,unpauseWhatsAppRateLimit:x}=se(),[h,j]=o.useState(null),[p,c]=o.useState(!1),[F,v]=o.useState(!1),u=xe({resolver:re(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(oe,{type:"single",collapsible:!0,children:e.jsxs(ie,{value:"ratelimits",children:[e.jsx(ce,{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(de,{children:F?e.jsx(ue,{...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{Ve as P,Ke as R,Pe as u};
1
+ import{d as fe,a as o,u as je,j as e}from"./vendor-query-SzWcOU0G.js";import{u as le,m as se,s as G,S as ge,t as re,A as oe,a as ie,b as ce,c as de,F as ue,v as _,w,x as S,y as J,z as C,D as Y,E as I,G as X,H as O,J as D,K as Q,g as B,I as $,M as Z,B as ee,O as me,_ as ne,P as b,Q as H,R as ye,d as _e,e as ve,f as be}from"./index-P2FzntoL.js";import{c as xe}from"./vendor-react-DvWIbVx0.js";import{S as we,q as he}from"./vendor-icons-CVrPjN2Q.js";const W={};function Pe(n,l){const x=fe(),[h,j]=o.useState(null),[f,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}=le(),{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 pe=K.key==="apiKey"?n.id:K.key,ae=await k("get_stored_api_key",{provider:pe});return{key:K.key,hasKey:ae.hasKey,apiKey:ae.apiKey}})),p={};let m=!1;for(const K of t)K.apiKey&&(p[K.key]=K.apiKey),K.hasKey&&(m=!0);return{values:p,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,p=>({values:t(p?.values??W),hadStored:p?.hadStored??!1}))},[x,N]),z=o.useMemo(()=>({getFieldValue:t=>M.current[t],getFieldsValue:()=>({...M.current}),setFieldValue:(t,p)=>{q(m=>({...m,[t]:p}))},setFieldsValue:t=>{q(p=>({...p,...t}))},resetFields:()=>q(()=>W)}),[q]);(E.data?.hadStored??!1)&&!F&&v(!0);const r=o.useCallback(async(t,p)=>{j(t),c(null);try{const m=await p();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:f,stored:F,setStored:v,setError:c,execute:r,actions:{validate:(t,p)=>r("validate",async()=>{const m=await u(t,p);return m?.isValid&&(v(!0),await V()),m}),save:(t,p)=>r("save",async()=>{const m=await y(t,p);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,p)=>r(t,()=>k(t,p??{}))},isConnected:T,getProviderDefaults:R,saveProviderDefaults:P,getProviderUsageSummary:i,getAPIUsageSummary:a,getStoredModels:d,getModelConstraints:g}}const Se=me({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()}),Ve=({providerId:n})=>{const{getProviderDefaults:l,saveProviderDefaults:x,getStoredModels:h,getModelConstraints:j,isConnected:f}=le(),{apiKeyStatuses:c}=se(),F=c[n],[v,u]=o.useState([]),[y,A]=o.useState(null),[R,P]=o.useState(!1),i=xe({resolver:re(Se),defaultValues:{}}),a=i.watch("default_model"),d=i.watch("thinking_enabled"),{isDirty:g}=i.formState;o.useEffect(()=>{if(!f)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,f,F]),o.useEffect(()=>{if(!f||!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,f]);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(oe,{type:"single",collapsible:!0,defaultValue:"defaults",children:e.jsxs(ie,{value:"defaults",children:[e.jsx(ce,{children:e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx(we,{className:"h-4 w-4"})," Default Parameters"]})}),e.jsx(de,{children:e.jsx("div",{className:R?"pointer-events-none opacity-60":"",children:e.jsx(ue,{...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=me({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 f;l[2]!==h?(f=e.jsx("span",{className:"text-lg font-semibold",children:h}),l[2]=h,l[3]=f):f=l[3];let c;return l[4]!==j||l[5]!==f?(c=e.jsxs("div",{className:"flex flex-col",children:[j,f]}),l[4]=j,l[5]=f,l[6]=c):c=l[6],c},te=n=>l=>{const x=l.target.value;n.onChange(x===""?void 0:Number(x))},Ke=()=>{const{getWhatsAppRateLimitConfig:n,setWhatsAppRateLimitConfig:l,unpauseWhatsAppRateLimit:x}=se(),[h,j]=o.useState(null),[f,c]=o.useState(!1),[F,v]=o.useState(!1),u=xe({resolver:re(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(oe,{type:"single",collapsible:!0,children:e.jsxs(ie,{value:"ratelimits",children:[e.jsx(ce,{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(de,{children:F?e.jsx(ue,{...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||f,variant:A?"default":"outline",className:"w-full",children:[f&&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{Ve as P,Ke as R,Pe as u};
@@ -1 +1 @@
1
- import{j as s}from"./vendor-query-SzWcOU0G.js";import{f as b,g}from"./index-DQ0nwhec.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};
1
+ import{j as s}from"./vendor-query-SzWcOU0G.js";import{f as b,g}from"./index-P2FzntoL.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};