@invect/ui 0.0.1

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 (419) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/dist/Invect-CWpIwZ5F.js +92738 -0
  4. package/dist/Invect.d.ts +25 -0
  5. package/dist/InvectShell.d.ts +14 -0
  6. package/dist/api/agent-tools.api.d.ts +1 -0
  7. package/dist/api/client.d.ts +207 -0
  8. package/dist/api/credentials.api.d.ts +47 -0
  9. package/dist/api/executions.api.d.ts +43 -0
  10. package/dist/api/flows.api.d.ts +100 -0
  11. package/dist/api/index.d.ts +9 -0
  12. package/dist/api/node-data.api.d.ts +66 -0
  13. package/dist/api/query-keys.d.ts +22 -0
  14. package/dist/api/triggers.api.d.ts +44 -0
  15. package/dist/api/types.d.ts +147 -0
  16. package/dist/api/use-flow-run-stream.d.ts +12 -0
  17. package/dist/assets/invect-branding.d.ts +4 -0
  18. package/dist/assets/provider-icons/index.d.ts +8 -0
  19. package/dist/babel-C9OtljFZ.js +9721 -0
  20. package/dist/components/PageLayout.d.ts +17 -0
  21. package/dist/components/chat/ChatInput.d.ts +17 -0
  22. package/dist/components/chat/ChatMessageList.d.ts +14 -0
  23. package/dist/components/chat/ChatModelSelector.d.ts +11 -0
  24. package/dist/components/chat/ChatPanel.d.ts +19 -0
  25. package/dist/components/chat/ChatPromptOverlay.d.ts +13 -0
  26. package/dist/components/chat/ChatProviderSelector.d.ts +9 -0
  27. package/dist/components/chat/ChatSettingsPanel.d.ts +11 -0
  28. package/dist/components/chat/InlineCredentialSetup.d.ts +9 -0
  29. package/dist/components/chat/MarkdownRenderer.d.ts +7 -0
  30. package/dist/components/chat/chat-memory.d.ts +21 -0
  31. package/dist/components/chat/chat.store.d.ts +416 -0
  32. package/dist/components/chat/index.d.ts +5 -0
  33. package/dist/components/chat/use-chat.d.ts +28 -0
  34. package/dist/components/credentials/CreateCredentialModal.d.ts +13 -0
  35. package/dist/components/credentials/CredentialDetailDialog.d.ts +17 -0
  36. package/dist/components/credentials/EditCredentialModal.d.ts +11 -0
  37. package/dist/components/credentials/OAuth2ConnectButton.d.ts +38 -0
  38. package/dist/components/credentials/OAuth2ProviderSelector.d.ts +15 -0
  39. package/dist/components/credentials/credential-utils.d.ts +12 -0
  40. package/dist/components/credentials/index.d.ts +9 -0
  41. package/dist/components/dashboard/FailedRunsAlert.d.ts +3 -0
  42. package/dist/components/dashboard/FlowCard.d.ts +7 -0
  43. package/dist/components/dashboard/RecentActivityTable.d.ts +9 -0
  44. package/dist/components/dashboard/StatCard.d.ts +10 -0
  45. package/dist/components/dashboard/index.d.ts +5 -0
  46. package/dist/components/dashboard/status-helpers.d.ts +5 -0
  47. package/dist/components/flow-editor/ActionsSidebar.d.ts +2 -0
  48. package/dist/components/flow-editor/FlowEditor.d.ts +21 -0
  49. package/dist/components/flow-editor/FlowHeader.d.ts +9 -0
  50. package/dist/components/flow-editor/FlowLayout.d.ts +24 -0
  51. package/dist/components/flow-editor/ModeSwitcher.d.ts +7 -0
  52. package/dist/components/flow-editor/NodeSidebar.d.ts +24 -0
  53. package/dist/components/flow-editor/RunControls.d.ts +12 -0
  54. package/dist/components/flow-editor/ToolConfigPanel.d.ts +16 -0
  55. package/dist/components/flow-editor/ValidationPanel.d.ts +5 -0
  56. package/dist/components/flow-editor/flow-editor.store.d.ts +1 -0
  57. package/dist/components/flow-editor/index.d.ts +6 -0
  58. package/dist/components/flow-editor/inline-edit.d.ts +10 -0
  59. package/dist/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.d.ts +26 -0
  60. package/dist/components/flow-editor/node-config-panel/CredentialCombobox.d.ts +21 -0
  61. package/dist/components/flow-editor/node-config-panel/CredentialsSection.d.ts +19 -0
  62. package/dist/components/flow-editor/node-config-panel/DroppableInput.d.ts +20 -0
  63. package/dist/components/flow-editor/node-config-panel/DynamicSelectField.d.ts +22 -0
  64. package/dist/components/flow-editor/node-config-panel/JsonPreviewPanel.d.ts +25 -0
  65. package/dist/components/flow-editor/node-config-panel/NodeConfigPanel.d.ts +14 -0
  66. package/dist/components/flow-editor/node-config-panel/NodeConfigPanelHeader.d.ts +15 -0
  67. package/dist/components/flow-editor/node-config-panel/ParametersSection.d.ts +16 -0
  68. package/dist/components/flow-editor/node-config-panel/SearchableSelectField.d.ts +17 -0
  69. package/dist/components/flow-editor/node-config-panel/SwitchCasesField.d.ts +18 -0
  70. package/dist/components/flow-editor/node-config-panel/hooks/index.d.ts +2 -0
  71. package/dist/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.d.ts +24 -0
  72. package/dist/components/flow-editor/node-config-panel/hooks/use-node-execution.d.ts +46 -0
  73. package/dist/components/flow-editor/node-config-panel/hooks/use-upstream-slots.d.ts +16 -0
  74. package/dist/components/flow-editor/node-config-panel/panels/AgentToolsPanel.d.ts +18 -0
  75. package/dist/components/flow-editor/node-config-panel/panels/ConfigurationPanel.d.ts +49 -0
  76. package/dist/components/flow-editor/node-config-panel/panels/DataMapperPane.d.ts +40 -0
  77. package/dist/components/flow-editor/node-config-panel/panels/InputPanel.d.ts +49 -0
  78. package/dist/components/flow-editor/node-config-panel/panels/OutputPanel.d.ts +7 -0
  79. package/dist/components/flow-editor/node-config-panel/panels/index.d.ts +4 -0
  80. package/dist/components/flow-editor/node-config-panel/types.d.ts +19 -0
  81. package/dist/components/flow-editor/node-config-panel/use-node-config-panel-store.d.ts +49 -0
  82. package/dist/components/flow-editor/node-config-panel/use-node-config-state.d.ts +26 -0
  83. package/dist/components/flow-editor/node-config-panel/use-run-node.d.ts +16 -0
  84. package/dist/components/flow-editor/node-config-panel/utils.d.ts +9 -0
  85. package/dist/components/flow-editor/serialize-to-sdk.d.ts +20 -0
  86. package/dist/components/flow-editor/toolbar-context.d.ts +2 -0
  87. package/dist/components/flow-editor/use-copy-paste.d.ts +7 -0
  88. package/dist/components/flow-editor/use-copy-paste.types.d.ts +38 -0
  89. package/dist/components/flow-editor/use-flow-editor.d.ts +44 -0
  90. package/dist/components/flow-runs-table/FlowRunsTable.d.ts +6 -0
  91. package/dist/components/flow-runs-table/index.d.ts +1 -0
  92. package/dist/components/flow-viewer/FlowRunsView.d.ts +7 -0
  93. package/dist/components/flow-viewer/FlowStatusView.d.ts +21 -0
  94. package/dist/components/flow-viewer/RunSelector.d.ts +13 -0
  95. package/dist/components/flow-viewer/RunsSidebar.d.ts +14 -0
  96. package/dist/components/flow-viewer/agent-tool-executions-list.d.ts +7 -0
  97. package/dist/components/flow-viewer/index.d.ts +1 -0
  98. package/dist/components/flow-viewer/logs-panel.d.ts +18 -0
  99. package/dist/components/flow-viewer/use-execution-log-data.d.ts +113 -0
  100. package/dist/components/graph/BatchFlowEdge.d.ts +33 -0
  101. package/dist/components/graph/LayoutSelector.d.ts +9 -0
  102. package/dist/components/graph/index.d.ts +47 -0
  103. package/dist/components/graph/styleUtils.d.ts +124 -0
  104. package/dist/components/nodes/AgentConfigPanel.d.ts +24 -0
  105. package/dist/components/nodes/AgentNode.d.ts +8 -0
  106. package/dist/components/nodes/AgentToolsBox.d.ts +41 -0
  107. package/dist/components/nodes/NodeAppendix.d.ts +19 -0
  108. package/dist/components/nodes/NodeStatusIndicator.d.ts +30 -0
  109. package/dist/components/nodes/NodeViewContext.d.ts +18 -0
  110. package/dist/components/nodes/ToolParamField.d.ts +28 -0
  111. package/dist/components/nodes/ToolSelectorModal.d.ts +80 -0
  112. package/dist/components/nodes/ToolSelectorParts.d.ts +30 -0
  113. package/dist/components/nodes/UniversalNode.d.ts +2 -0
  114. package/dist/components/nodes/createContextAwareNodes.d.ts +6 -0
  115. package/dist/components/nodes/index.d.ts +22 -0
  116. package/dist/components/nodes/nodeRegistry.d.ts +13 -0
  117. package/dist/components/nodes/withNodeContext.d.ts +7 -0
  118. package/dist/components/shared/InvectLoader.d.ts +8 -0
  119. package/dist/components/shared/InvectLogo.d.ts +9 -0
  120. package/dist/components/shared/ProviderIcon.d.ts +23 -0
  121. package/dist/components/side-menu/side-menu.d.ts +4 -0
  122. package/dist/components/sidebar/BaseSidebar.d.ts +17 -0
  123. package/dist/components/sidebar/index.d.ts +1 -0
  124. package/dist/components/triggers/CronPreview.d.ts +12 -0
  125. package/dist/components/triggers/index.d.ts +1 -0
  126. package/dist/components/ui/alert-dialog.d.ts +18 -0
  127. package/dist/components/ui/badge.d.ts +9 -0
  128. package/dist/components/ui/button.d.ts +13 -0
  129. package/dist/components/ui/card.d.ts +9 -0
  130. package/dist/components/ui/codemirror-js-editor.d.ts +25 -0
  131. package/dist/components/ui/codemirror-json-editor.d.ts +18 -0
  132. package/dist/components/ui/codemirror-nunjucks-editor.d.ts +13 -0
  133. package/dist/components/ui/codemirror-vscode-theme.d.ts +24 -0
  134. package/dist/components/ui/collapsible.d.ts +6 -0
  135. package/dist/components/ui/command.d.ts +18 -0
  136. package/dist/components/ui/dialog.d.ts +18 -0
  137. package/dist/components/ui/dropdown-menu.d.ts +25 -0
  138. package/dist/components/ui/empty-state.d.ts +21 -0
  139. package/dist/components/ui/input.d.ts +3 -0
  140. package/dist/components/ui/label.d.ts +4 -0
  141. package/dist/components/ui/popover.d.ts +10 -0
  142. package/dist/components/ui/resizable.d.ts +8 -0
  143. package/dist/components/ui/scroll-area.d.ts +5 -0
  144. package/dist/components/ui/select.d.ts +18 -0
  145. package/dist/components/ui/separator.d.ts +4 -0
  146. package/dist/components/ui/slider.d.ts +4 -0
  147. package/dist/components/ui/switch.d.ts +3 -0
  148. package/dist/components/ui/table.d.ts +10 -0
  149. package/dist/components/ui/textarea.d.ts +3 -0
  150. package/dist/components/ui/tooltip.d.ts +7 -0
  151. package/dist/components/ui/tree-view.d.ts +107 -0
  152. package/dist/contexts/AgentToolCallbacksContext.d.ts +23 -0
  153. package/dist/contexts/ApiContext.d.ts +11 -0
  154. package/dist/contexts/FlowDataContext.d.ts +9 -0
  155. package/dist/contexts/NodeRegistryContext.d.ts +14 -0
  156. package/dist/contexts/PluginRegistryContext.d.ts +39 -0
  157. package/dist/contexts/ThemeProvider.d.ts +18 -0
  158. package/dist/contexts/ValidationContext.d.ts +22 -0
  159. package/dist/demo/DemoInvect.d.ts +11 -0
  160. package/dist/demo/FlowViewer.d.ts +31 -0
  161. package/dist/demo/demo-api-client.d.ts +33 -0
  162. package/dist/demo/index.d.ts +6 -0
  163. package/dist/demo/sample-data.d.ts +1538 -0
  164. package/dist/demo.d.ts +2 -0
  165. package/dist/demo.js +2774 -0
  166. package/dist/estree-ClbRfS-1.js +7076 -0
  167. package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
  168. package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  169. package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
  170. package/dist/fonts/iosevka-latin-400-normal.woff2 +0 -0
  171. package/dist/hooks/index.d.ts +1 -0
  172. package/dist/hooks/use-document-title.d.ts +1 -0
  173. package/dist/hooks/use-flow-data.d.ts +22 -0
  174. package/dist/hooks/use-invect-portal-class.d.ts +21 -0
  175. package/dist/hooks/useFlowEditorStore.d.ts +1 -0
  176. package/dist/index.css +3 -0
  177. package/dist/index.d.ts +22 -0
  178. package/dist/index.js +717 -0
  179. package/dist/lib/utils.d.ts +2 -0
  180. package/dist/prettier.d.ts +13 -0
  181. package/dist/routes/all-flow-runs.d.ts +5 -0
  182. package/dist/routes/credentials.d.ts +5 -0
  183. package/dist/routes/flow-route-layout.d.ts +19 -0
  184. package/dist/routes/flow-runs.d.ts +5 -0
  185. package/dist/routes/flow.d.ts +5 -0
  186. package/dist/routes/home.d.ts +5 -0
  187. package/dist/services/index.d.ts +1 -0
  188. package/dist/standalone-C3Df7W52.js +3463 -0
  189. package/dist/stores/executionViewStore.d.ts +64 -0
  190. package/dist/stores/flow-editor.store.d.ts +137 -0
  191. package/dist/stores/flowEditorStore.d.ts +1 -0
  192. package/dist/stores/index.d.ts +2 -0
  193. package/dist/stores/uiStore.d.ts +45 -0
  194. package/dist/types/agent-tools.types.d.ts +53 -0
  195. package/dist/types/index.d.ts +2 -0
  196. package/dist/types/node-definition.types.d.ts +85 -0
  197. package/dist/types/plugin.types.d.ts +100 -0
  198. package/dist/utils/credentialBranding.d.ts +8 -0
  199. package/dist/utils/credentialFiltering.d.ts +20 -0
  200. package/dist/utils/flowTransformations.d.ts +16 -0
  201. package/dist/utils/layoutUtils.d.ts +23 -0
  202. package/dist/utils/nodeReferenceUtils.d.ts +37 -0
  203. package/dist/vendor.d.ts +5 -0
  204. package/package.json +130 -0
  205. package/src/.DS_Store +0 -0
  206. package/src/Invect.tsx +229 -0
  207. package/src/InvectShell.tsx +55 -0
  208. package/src/api/agent-tools.api.ts +23 -0
  209. package/src/api/client.ts +899 -0
  210. package/src/api/credentials.api.ts +197 -0
  211. package/src/api/executions.api.ts +228 -0
  212. package/src/api/flows.api.ts +195 -0
  213. package/src/api/index.ts +17 -0
  214. package/src/api/node-data.api.ts +167 -0
  215. package/src/api/query-keys.ts +44 -0
  216. package/src/api/triggers.api.ts +120 -0
  217. package/src/api/types.ts +212 -0
  218. package/src/api/use-flow-run-stream.ts +206 -0
  219. package/src/app.css +560 -0
  220. package/src/assets/.DS_Store +0 -0
  221. package/src/assets/favicon.ico +0 -0
  222. package/src/assets/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
  223. package/src/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
  224. package/src/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
  225. package/src/assets/fonts/iosevka-latin-400-normal.woff2 +0 -0
  226. package/src/assets/invect-branding.ts +51 -0
  227. package/src/assets/provider-icons/anthropic.svg +1 -0
  228. package/src/assets/provider-icons/anthropic_light.svg +1 -0
  229. package/src/assets/provider-icons/github.svg +1 -0
  230. package/src/assets/provider-icons/github_light.svg +1 -0
  231. package/src/assets/provider-icons/gmail.svg +1 -0
  232. package/src/assets/provider-icons/google_calendar.svg +1 -0
  233. package/src/assets/provider-icons/google_docs.svg +1 -0
  234. package/src/assets/provider-icons/google_drive.svg +1 -0
  235. package/src/assets/provider-icons/google_sheets.svg +1 -0
  236. package/src/assets/provider-icons/index.ts +55 -0
  237. package/src/assets/provider-icons/linear.svg +1 -0
  238. package/src/assets/provider-icons/openai.svg +1 -0
  239. package/src/assets/provider-icons/postgres.svg +1 -0
  240. package/src/assets/provider-icons/slack.svg +1 -0
  241. package/src/assets/small-loader-dark.svg +22 -0
  242. package/src/assets/small-loader-light.svg +22 -0
  243. package/src/assets/small.svg +7 -0
  244. package/src/components/.DS_Store +0 -0
  245. package/src/components/PageLayout.tsx +55 -0
  246. package/src/components/chat/ChatInput.tsx +115 -0
  247. package/src/components/chat/ChatMessageList.tsx +788 -0
  248. package/src/components/chat/ChatModelSelector.tsx +208 -0
  249. package/src/components/chat/ChatPanel.tsx +243 -0
  250. package/src/components/chat/ChatPromptOverlay.tsx +150 -0
  251. package/src/components/chat/ChatProviderSelector.tsx +135 -0
  252. package/src/components/chat/ChatSettingsPanel.tsx +277 -0
  253. package/src/components/chat/InlineCredentialSetup.tsx +343 -0
  254. package/src/components/chat/MarkdownRenderer.tsx +140 -0
  255. package/src/components/chat/chat-memory.ts +88 -0
  256. package/src/components/chat/chat.store.ts +479 -0
  257. package/src/components/chat/index.ts +5 -0
  258. package/src/components/chat/use-chat.ts +473 -0
  259. package/src/components/credentials/CreateCredentialModal.tsx +609 -0
  260. package/src/components/credentials/CredentialDetailDialog.tsx +882 -0
  261. package/src/components/credentials/EditCredentialModal.tsx +399 -0
  262. package/src/components/credentials/OAuth2ConnectButton.tsx +288 -0
  263. package/src/components/credentials/OAuth2ProviderSelector.tsx +360 -0
  264. package/src/components/credentials/credential-utils.ts +99 -0
  265. package/src/components/credentials/index.ts +10 -0
  266. package/src/components/dashboard/FailedRunsAlert.tsx +67 -0
  267. package/src/components/dashboard/FlowCard.tsx +64 -0
  268. package/src/components/dashboard/RecentActivityTable.tsx +92 -0
  269. package/src/components/dashboard/StatCard.tsx +32 -0
  270. package/src/components/dashboard/index.ts +5 -0
  271. package/src/components/dashboard/status-helpers.tsx +102 -0
  272. package/src/components/flow-editor/ActionsSidebar.tsx +503 -0
  273. package/src/components/flow-editor/FlowEditor.tsx +1002 -0
  274. package/src/components/flow-editor/FlowHeader.tsx +87 -0
  275. package/src/components/flow-editor/FlowLayout.tsx +117 -0
  276. package/src/components/flow-editor/ModeSwitcher.tsx +49 -0
  277. package/src/components/flow-editor/NodeSidebar.tsx +343 -0
  278. package/src/components/flow-editor/RunControls.tsx +109 -0
  279. package/src/components/flow-editor/ToolConfigPanel.tsx +434 -0
  280. package/src/components/flow-editor/ValidationPanel.tsx +167 -0
  281. package/src/components/flow-editor/flow-editor.store.ts +2 -0
  282. package/src/components/flow-editor/index.ts +6 -0
  283. package/src/components/flow-editor/inline-edit.tsx +111 -0
  284. package/src/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.tsx +334 -0
  285. package/src/components/flow-editor/node-config-panel/CredentialCombobox.tsx +217 -0
  286. package/src/components/flow-editor/node-config-panel/CredentialsSection.tsx +154 -0
  287. package/src/components/flow-editor/node-config-panel/DroppableInput.tsx +45 -0
  288. package/src/components/flow-editor/node-config-panel/DynamicSelectField.tsx +223 -0
  289. package/src/components/flow-editor/node-config-panel/JsonPreviewPanel.tsx +134 -0
  290. package/src/components/flow-editor/node-config-panel/NodeConfigPanel.tsx +650 -0
  291. package/src/components/flow-editor/node-config-panel/NodeConfigPanelHeader.tsx +91 -0
  292. package/src/components/flow-editor/node-config-panel/ParametersSection.tsx +144 -0
  293. package/src/components/flow-editor/node-config-panel/SearchableSelectField.tsx +126 -0
  294. package/src/components/flow-editor/node-config-panel/SwitchCasesField.tsx +212 -0
  295. package/src/components/flow-editor/node-config-panel/hooks/index.ts +2 -0
  296. package/src/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.ts +284 -0
  297. package/src/components/flow-editor/node-config-panel/hooks/use-node-execution.ts +287 -0
  298. package/src/components/flow-editor/node-config-panel/hooks/use-upstream-slots.ts +310 -0
  299. package/src/components/flow-editor/node-config-panel/panels/AgentToolsPanel.tsx +837 -0
  300. package/src/components/flow-editor/node-config-panel/panels/ConfigurationPanel.tsx +383 -0
  301. package/src/components/flow-editor/node-config-panel/panels/DataMapperPane.tsx +456 -0
  302. package/src/components/flow-editor/node-config-panel/panels/InputPanel.tsx +338 -0
  303. package/src/components/flow-editor/node-config-panel/panels/OutputPanel.tsx +109 -0
  304. package/src/components/flow-editor/node-config-panel/panels/index.ts +4 -0
  305. package/src/components/flow-editor/node-config-panel/types.ts +20 -0
  306. package/src/components/flow-editor/node-config-panel/use-node-config-panel-store.ts +283 -0
  307. package/src/components/flow-editor/node-config-panel/use-node-config-state.ts +172 -0
  308. package/src/components/flow-editor/node-config-panel/use-run-node.ts +147 -0
  309. package/src/components/flow-editor/node-config-panel/utils.ts +73 -0
  310. package/src/components/flow-editor/serialize-to-sdk.ts +204 -0
  311. package/src/components/flow-editor/toolbar-context.ts +9 -0
  312. package/src/components/flow-editor/use-copy-paste.ts +575 -0
  313. package/src/components/flow-editor/use-copy-paste.types.ts +35 -0
  314. package/src/components/flow-editor/use-flow-editor.ts +241 -0
  315. package/src/components/flow-runs-table/FlowRunsTable.tsx +631 -0
  316. package/src/components/flow-runs-table/index.ts +1 -0
  317. package/src/components/flow-viewer/FlowRunsView.tsx +268 -0
  318. package/src/components/flow-viewer/FlowStatusView.tsx +351 -0
  319. package/src/components/flow-viewer/RunSelector.tsx +422 -0
  320. package/src/components/flow-viewer/RunsSidebar.tsx +125 -0
  321. package/src/components/flow-viewer/agent-tool-executions-list.tsx +298 -0
  322. package/src/components/flow-viewer/index.ts +1 -0
  323. package/src/components/flow-viewer/logs-panel.tsx +567 -0
  324. package/src/components/flow-viewer/use-execution-log-data.ts +374 -0
  325. package/src/components/graph/BatchFlowEdge.tsx +229 -0
  326. package/src/components/graph/LayoutSelector.tsx +42 -0
  327. package/src/components/graph/index.ts +61 -0
  328. package/src/components/graph/styleUtils.ts +375 -0
  329. package/src/components/nodes/.DS_Store +0 -0
  330. package/src/components/nodes/AgentConfigPanel.tsx +1033 -0
  331. package/src/components/nodes/AgentNode.tsx +298 -0
  332. package/src/components/nodes/AgentToolsBox.tsx +193 -0
  333. package/src/components/nodes/NodeAppendix.tsx +98 -0
  334. package/src/components/nodes/NodeStatusIndicator.tsx +74 -0
  335. package/src/components/nodes/NodeViewContext.tsx +45 -0
  336. package/src/components/nodes/ToolParamField.tsx +282 -0
  337. package/src/components/nodes/ToolSelectorModal.tsx +648 -0
  338. package/src/components/nodes/ToolSelectorParts.tsx +505 -0
  339. package/src/components/nodes/UniversalNode.tsx +356 -0
  340. package/src/components/nodes/createContextAwareNodes.ts +19 -0
  341. package/src/components/nodes/index.ts +45 -0
  342. package/src/components/nodes/nodeRegistry.ts +50 -0
  343. package/src/components/nodes/withNodeContext.tsx +55 -0
  344. package/src/components/shared/InvectLoader.tsx +59 -0
  345. package/src/components/shared/InvectLogo.tsx +59 -0
  346. package/src/components/shared/ProviderIcon.tsx +115 -0
  347. package/src/components/side-menu/side-menu.tsx +267 -0
  348. package/src/components/sidebar/BaseSidebar.tsx +148 -0
  349. package/src/components/sidebar/index.ts +1 -0
  350. package/src/components/triggers/CronPreview.tsx +243 -0
  351. package/src/components/triggers/index.ts +1 -0
  352. package/src/components/ui/alert-dialog.tsx +152 -0
  353. package/src/components/ui/badge.tsx +39 -0
  354. package/src/components/ui/button.tsx +58 -0
  355. package/src/components/ui/card.tsx +75 -0
  356. package/src/components/ui/codemirror-js-editor.tsx +432 -0
  357. package/src/components/ui/codemirror-json-editor.tsx +816 -0
  358. package/src/components/ui/codemirror-nunjucks-editor.tsx +451 -0
  359. package/src/components/ui/codemirror-vscode-theme.ts +243 -0
  360. package/src/components/ui/collapsible.tsx +12 -0
  361. package/src/components/ui/command.tsx +162 -0
  362. package/src/components/ui/dialog.tsx +140 -0
  363. package/src/components/ui/dropdown-menu.tsx +232 -0
  364. package/src/components/ui/empty-state.tsx +93 -0
  365. package/src/components/ui/input.tsx +26 -0
  366. package/src/components/ui/label.tsx +19 -0
  367. package/src/components/ui/popover.tsx +53 -0
  368. package/src/components/ui/resizable.tsx +61 -0
  369. package/src/components/ui/scroll-area.tsx +56 -0
  370. package/src/components/ui/select.tsx +179 -0
  371. package/src/components/ui/separator.tsx +26 -0
  372. package/src/components/ui/slider.tsx +58 -0
  373. package/src/components/ui/switch.tsx +22 -0
  374. package/src/components/ui/table.tsx +90 -0
  375. package/src/components/ui/textarea.tsx +23 -0
  376. package/src/components/ui/tooltip.tsx +54 -0
  377. package/src/components/ui/tree-view.tsx +574 -0
  378. package/src/contexts/AgentToolCallbacksContext.tsx +31 -0
  379. package/src/contexts/ApiContext.tsx +51 -0
  380. package/src/contexts/FlowDataContext.tsx +21 -0
  381. package/src/contexts/NodeRegistryContext.tsx +54 -0
  382. package/src/contexts/PluginRegistryContext.tsx +182 -0
  383. package/src/contexts/ThemeProvider.tsx +106 -0
  384. package/src/contexts/ValidationContext.tsx +122 -0
  385. package/src/demo/DemoInvect.tsx +42 -0
  386. package/src/demo/FlowViewer.tsx +294 -0
  387. package/src/demo/demo-api-client.ts +246 -0
  388. package/src/demo/index.ts +28 -0
  389. package/src/demo/sample-data.ts +1980 -0
  390. package/src/hooks/index.ts +1 -0
  391. package/src/hooks/use-document-title.ts +8 -0
  392. package/src/hooks/use-flow-data.ts +144 -0
  393. package/src/hooks/use-invect-portal-class.ts +27 -0
  394. package/src/hooks/useFlowEditorStore.ts +2 -0
  395. package/src/index.ts +70 -0
  396. package/src/lib/utils.ts +6 -0
  397. package/src/prettier.d.ts +13 -0
  398. package/src/routes/all-flow-runs.tsx +27 -0
  399. package/src/routes/credentials.tsx +362 -0
  400. package/src/routes/flow-route-layout.tsx +113 -0
  401. package/src/routes/flow-runs.tsx +22 -0
  402. package/src/routes/flow.tsx +22 -0
  403. package/src/routes/home.tsx +282 -0
  404. package/src/services/index.ts +6 -0
  405. package/src/stores/executionViewStore.ts +211 -0
  406. package/src/stores/flow-editor.store.ts +738 -0
  407. package/src/stores/flowEditorStore.ts +2 -0
  408. package/src/stores/index.ts +10 -0
  409. package/src/stores/uiStore.ts +189 -0
  410. package/src/types/agent-tools.types.ts +64 -0
  411. package/src/types/index.ts +5 -0
  412. package/src/types/node-definition.types.ts +104 -0
  413. package/src/types/plugin.types.ts +123 -0
  414. package/src/utils/credentialBranding.ts +116 -0
  415. package/src/utils/credentialFiltering.ts +68 -0
  416. package/src/utils/flowTransformations.ts +137 -0
  417. package/src/utils/layoutUtils.ts +127 -0
  418. package/src/utils/nodeReferenceUtils.ts +135 -0
  419. package/src/vendor.d.ts +7 -0
@@ -0,0 +1,283 @@
1
+ import { create } from 'zustand';
2
+ import type { FlowRunResult } from '@invect/core/types';
3
+ import { parseJson, stringifyJson } from './utils';
4
+
5
+ /**
6
+ * State for the node config panel
7
+ */
8
+ interface NodeConfigPanelState {
9
+ // Panel state
10
+ nodeId: string | null;
11
+ flowId: string | null;
12
+
13
+ // Input/Output previews
14
+ inputPreview: string;
15
+ outputPreview: string;
16
+ inputError: string | null;
17
+ outputError: string | null;
18
+
19
+ // Test mode
20
+ isTestMode: boolean;
21
+ originalInputPreview: string | null;
22
+
23
+ // Execution state
24
+ isRunningNode: boolean;
25
+ runError: string | null;
26
+
27
+ // Credential modal
28
+ isCreateCredentialOpen: boolean;
29
+ activeCredentialField: string | null;
30
+ }
31
+
32
+ /**
33
+ * Actions for the node config panel
34
+ */
35
+ interface NodeConfigPanelActions {
36
+ // Initialization
37
+ initializeForNode: (
38
+ nodeId: string,
39
+ flowId: string,
40
+ initialInput: string,
41
+ initialOutput: string,
42
+ ) => void;
43
+ reset: () => void;
44
+
45
+ // Input preview
46
+ setInputPreview: (value: string) => void;
47
+ setInputError: (error: string | null) => void;
48
+
49
+ // Output preview
50
+ setOutputPreview: (value: string) => void;
51
+ setOutputError: (error: string | null) => void;
52
+
53
+ // Test mode
54
+ enterTestMode: () => void;
55
+ exitTestMode: () => void;
56
+ resetTestMode: () => void;
57
+
58
+ // Execution
59
+ setIsRunningNode: (isRunning: boolean) => void;
60
+ setRunError: (error: string | null) => void;
61
+
62
+ // Credential modal
63
+ openCreateCredentialModal: (fieldName: string) => void;
64
+ closeCreateCredentialModal: () => void;
65
+
66
+ // Execution result handlers
67
+ handleTestModeSuccess: (output: unknown) => void;
68
+ handleNormalModeSuccess: (
69
+ result: FlowRunResult,
70
+ nodeId: string,
71
+ updateNodeData: (nodeId: string, data: Record<string, unknown>) => void,
72
+ ) => void;
73
+ handleExecutionError: (error: string) => void;
74
+ }
75
+
76
+ type NodeConfigPanelStore = NodeConfigPanelState & NodeConfigPanelActions;
77
+
78
+ const initialState: NodeConfigPanelState = {
79
+ nodeId: null,
80
+ flowId: null,
81
+ inputPreview: '{}',
82
+ outputPreview: '{}',
83
+ inputError: null,
84
+ outputError: null,
85
+ isTestMode: false,
86
+ originalInputPreview: null,
87
+ isRunningNode: false,
88
+ runError: null,
89
+ isCreateCredentialOpen: false,
90
+ activeCredentialField: null,
91
+ };
92
+
93
+ /**
94
+ * Extract the output value from a node execution result
95
+ */
96
+ function extractOutputValue(nodeOutput: unknown): unknown {
97
+ if (!nodeOutput || typeof nodeOutput !== 'object') {
98
+ return null;
99
+ }
100
+
101
+ const typedOutput = nodeOutput as { data?: { variables?: Record<string, { value: unknown }> } };
102
+
103
+ if (typedOutput.data?.variables?.output) {
104
+ const outputVar = typedOutput.data.variables.output;
105
+ return outputVar && typeof outputVar === 'object' && 'value' in outputVar
106
+ ? outputVar.value
107
+ : outputVar;
108
+ }
109
+
110
+ if (typedOutput.data?.variables) {
111
+ const firstVar = Object.values(typedOutput.data.variables)[0];
112
+ return firstVar && typeof firstVar === 'object' && 'value' in firstVar
113
+ ? firstVar.value
114
+ : firstVar;
115
+ }
116
+
117
+ return null;
118
+ }
119
+
120
+ /**
121
+ * Format output for display - strings as-is, objects as JSON
122
+ */
123
+ function formatOutputForDisplay(output: unknown): string {
124
+ if (typeof output === 'string') {
125
+ return output;
126
+ }
127
+ return stringifyJson(output);
128
+ }
129
+
130
+ /**
131
+ * Zustand store for node config panel state management
132
+ */
133
+ export const useNodeConfigPanelStore = create<NodeConfigPanelStore>((set, get) => ({
134
+ ...initialState,
135
+
136
+ initializeForNode: (nodeId, flowId, initialInput, initialOutput) => {
137
+ set({
138
+ nodeId,
139
+ flowId,
140
+ inputPreview: initialInput,
141
+ outputPreview: initialOutput,
142
+ originalInputPreview: initialInput,
143
+ inputError: null,
144
+ outputError: null,
145
+ isTestMode: false,
146
+ runError: null,
147
+ });
148
+ },
149
+
150
+ reset: () => {
151
+ set(initialState);
152
+ },
153
+
154
+ setInputPreview: (value) => {
155
+ const { originalInputPreview } = get();
156
+ const isTestMode = originalInputPreview !== null && value !== originalInputPreview;
157
+
158
+ set({
159
+ inputPreview: value,
160
+ inputError: null,
161
+ isTestMode,
162
+ });
163
+ },
164
+
165
+ setInputError: (error) => {
166
+ set({ inputError: error });
167
+ },
168
+
169
+ setOutputPreview: (value) => {
170
+ set({
171
+ outputPreview: value,
172
+ outputError: null,
173
+ });
174
+ },
175
+
176
+ setOutputError: (error) => {
177
+ set({ outputError: error });
178
+ },
179
+
180
+ enterTestMode: () => {
181
+ set({ isTestMode: true });
182
+ },
183
+
184
+ exitTestMode: () => {
185
+ set({ isTestMode: false });
186
+ },
187
+
188
+ resetTestMode: () => {
189
+ const { originalInputPreview } = get();
190
+ if (originalInputPreview !== null) {
191
+ set({
192
+ inputPreview: originalInputPreview,
193
+ isTestMode: false,
194
+ });
195
+ }
196
+ },
197
+
198
+ setIsRunningNode: (isRunning) => {
199
+ set({ isRunningNode: isRunning });
200
+ },
201
+
202
+ setRunError: (error) => {
203
+ set({ runError: error });
204
+ },
205
+
206
+ openCreateCredentialModal: (fieldName) => {
207
+ set({
208
+ isCreateCredentialOpen: true,
209
+ activeCredentialField: fieldName,
210
+ });
211
+ },
212
+
213
+ closeCreateCredentialModal: () => {
214
+ set({
215
+ isCreateCredentialOpen: false,
216
+ activeCredentialField: null,
217
+ });
218
+ },
219
+
220
+ handleTestModeSuccess: (output) => {
221
+ const displayValue = formatOutputForDisplay(output);
222
+ set({
223
+ outputPreview: displayValue,
224
+ outputError: null,
225
+ runError: null,
226
+ });
227
+ },
228
+
229
+ handleNormalModeSuccess: (result, nodeId, updateNodeData) => {
230
+ // Update input/output data for all executed nodes from traces
231
+ if (result.traces && Array.isArray(result.traces)) {
232
+ for (const trace of result.traces) {
233
+ const traceNodeId = trace.nodeId;
234
+ if (!traceNodeId) {
235
+ continue;
236
+ }
237
+
238
+ const traceInputs = trace.inputs;
239
+ const traceOutput = extractOutputValue(trace.outputs);
240
+
241
+ updateNodeData(traceNodeId, {
242
+ previewInput: traceInputs,
243
+ previewOutput: traceOutput,
244
+ });
245
+ }
246
+ }
247
+
248
+ // Update local state for the current node's output display
249
+ const nodeOutput = result.outputs?.[nodeId];
250
+ const output = extractOutputValue(nodeOutput);
251
+ const displayValue = formatOutputForDisplay(output);
252
+
253
+ // Update input preview from the current node's trace
254
+ const currentTrace = result.traces?.find((t: { nodeId: string }) => t.nodeId === nodeId);
255
+ const newInputPreview = currentTrace?.inputs
256
+ ? stringifyJson(currentTrace.inputs)
257
+ : get().inputPreview;
258
+
259
+ set({
260
+ outputPreview: displayValue,
261
+ outputError: null,
262
+ runError: null,
263
+ inputPreview: newInputPreview,
264
+ originalInputPreview: newInputPreview,
265
+ isTestMode: false,
266
+ });
267
+ },
268
+
269
+ handleExecutionError: (error) => {
270
+ set({
271
+ runError: error,
272
+ outputError: error,
273
+ });
274
+ },
275
+ }));
276
+
277
+ /**
278
+ * Hook to get parsed input data for test mode execution
279
+ */
280
+ export function useParsedInputPreview(): Record<string, unknown> {
281
+ const inputPreview = useNodeConfigPanelStore((state) => state.inputPreview);
282
+ return parseJson(inputPreview, () => ({})) || {};
283
+ }
@@ -0,0 +1,172 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import type { Node } from '@xyflow/react';
3
+ import type { NodeDefinition } from '../../../types/node-definition.types';
4
+ import { useResolveNodeDefinition } from '../../../api/node-data.api';
5
+
6
+ interface UseNodeConfigStateOptions {
7
+ node: Node<Record<string, unknown>> | null;
8
+ nodeType: string;
9
+ definition?: NodeDefinition;
10
+ /** Callback to persist params back to Zustand. Required for backend resolution writes. */
11
+ onParamsChange?: (nodeId: string, params: Record<string, unknown>) => void;
12
+ }
13
+
14
+ interface UseNodeConfigStateResult {
15
+ definition?: NodeDefinition;
16
+ values: Record<string, unknown>;
17
+ warnings: string[];
18
+ errors: string[];
19
+ updateField: (fieldName: string, value: unknown) => void;
20
+ isUpdating: boolean;
21
+ }
22
+
23
+ function buildDefaultParams(definition?: NodeDefinition): Record<string, unknown> {
24
+ if (!definition?.paramFields?.length) {
25
+ return {};
26
+ }
27
+
28
+ return definition.paramFields.reduce<Record<string, unknown>>((acc, field) => {
29
+ if (field.defaultValue !== undefined) {
30
+ acc[field.name] = field.defaultValue;
31
+ }
32
+ return acc;
33
+ }, {});
34
+ }
35
+
36
+ /**
37
+ * Hook for node configuration state — reads params from the node (Zustand)
38
+ * and provides validation, backend config resolution, and field update.
39
+ *
40
+ * After Phase 1.3 refactor: `values` is derived from node.data.params (Zustand),
41
+ * NOT stored locally. This eliminates the dual-source-of-truth problem.
42
+ */
43
+ export function useNodeConfigState({
44
+ node,
45
+ nodeType,
46
+ definition,
47
+ onParamsChange,
48
+ }: UseNodeConfigStateOptions): UseNodeConfigStateResult {
49
+ const nodeDefinitionResolver = useResolveNodeDefinition();
50
+ const nodeId = node?.id ?? null;
51
+
52
+ const [activeDefinition, setActiveDefinition] = useState<NodeDefinition | undefined>(definition);
53
+ const [warnings, setWarnings] = useState<string[]>([]);
54
+ const [errors, setErrors] = useState<string[]>([]);
55
+
56
+ const lastRequestIdRef = useRef(0);
57
+ const resolveDefinitionRef = useRef<
58
+ (params: Record<string, unknown>, change?: { field: string; value: unknown }) => void
59
+ >(() => {
60
+ // noop placeholder until ready
61
+ });
62
+
63
+ // Read params directly from the node (Zustand is the single source of truth)
64
+ const nodeParams = node?.data?.params as Record<string, unknown> | undefined;
65
+ const defaults = useMemo(() => buildDefaultParams(definition), [definition]);
66
+ const values = useMemo(() => ({ ...defaults, ...nodeParams }), [defaults, nodeParams]);
67
+
68
+ const hasNode = Boolean(node);
69
+
70
+ // Stable ref for onParamsChange to avoid re-creating resolveDefinition
71
+ const onParamsChangeRef = useRef(onParamsChange);
72
+ onParamsChangeRef.current = onParamsChange;
73
+
74
+ const resolveDefinition = useCallback(
75
+ (params: Record<string, unknown>, change?: { field: string; value: unknown }) => {
76
+ const requestId = ++lastRequestIdRef.current;
77
+
78
+ nodeDefinitionResolver.mutate(
79
+ {
80
+ nodeType,
81
+ nodeId,
82
+ params,
83
+ changeField: change?.field,
84
+ changeValue: change?.value,
85
+ },
86
+ {
87
+ onSuccess: (response) => {
88
+ if (requestId !== lastRequestIdRef.current) {
89
+ return;
90
+ }
91
+
92
+ setActiveDefinition(response.definition ?? definition);
93
+ setWarnings(response.warnings ?? []);
94
+ setErrors(response.errors ?? []);
95
+
96
+ // Write resolved params back to Zustand (e.g. provider detection sets model list)
97
+ if (response.params && nodeId && onParamsChangeRef.current) {
98
+ onParamsChangeRef.current(nodeId, response.params);
99
+ }
100
+ },
101
+ onError: (error) => {
102
+ if (requestId !== lastRequestIdRef.current) {
103
+ return;
104
+ }
105
+
106
+ setErrors([
107
+ error instanceof Error ? error.message : 'Failed to resolve node definition',
108
+ ]);
109
+ },
110
+ },
111
+ );
112
+ },
113
+ [nodeDefinitionResolver, nodeType, nodeId, definition],
114
+ );
115
+
116
+ useEffect(() => {
117
+ resolveDefinitionRef.current = resolveDefinition;
118
+ }, [resolveDefinition]);
119
+
120
+ useEffect(() => {
121
+ setActiveDefinition(definition);
122
+ }, [definition]);
123
+
124
+ // Reset transient state when node changes; trigger initial backend resolution if needed
125
+ const nodeParamsSignature = useMemo(() => JSON.stringify(nodeParams ?? {}), [nodeParams]);
126
+ useEffect(() => {
127
+ if (!hasNode) {
128
+ setWarnings([]);
129
+ setErrors([]);
130
+ lastRequestIdRef.current = 0;
131
+ return;
132
+ }
133
+
134
+ setWarnings([]);
135
+ setErrors([]);
136
+
137
+ // Call the backend config resolution when the node has a credential
138
+ // that needs provider detection (e.g. model selection, batch processing toggle).
139
+ const credentialId =
140
+ typeof values.credentialId === 'string' && values.credentialId
141
+ ? values.credentialId
142
+ : undefined;
143
+ if (credentialId) {
144
+ resolveDefinitionRef.current(values, { field: 'credentialId', value: credentialId });
145
+ }
146
+ }, [hasNode, nodeId, nodeParamsSignature, nodeType]);
147
+
148
+ // Fields that should trigger a backend config update when changed
149
+ const FIELDS_REQUIRING_CONFIG_UPDATE = new Set(['credentialId', 'provider']);
150
+
151
+ const updateField = useCallback(
152
+ (fieldName: string, value: unknown) => {
153
+ // Compute next params from current values
154
+ const next = { ...values, [fieldName]: value };
155
+
156
+ // Only call the backend config update for fields that need dynamic resolution
157
+ if (FIELDS_REQUIRING_CONFIG_UPDATE.has(fieldName)) {
158
+ resolveDefinitionRef.current(next, { field: fieldName, value });
159
+ }
160
+ },
161
+ [values],
162
+ );
163
+
164
+ return {
165
+ definition: activeDefinition,
166
+ values,
167
+ warnings,
168
+ errors,
169
+ updateField,
170
+ isUpdating: nodeDefinitionResolver.isPending,
171
+ };
172
+ }
@@ -0,0 +1,147 @@
1
+ import { useCallback } from 'react';
2
+ import { GraphNodeType } from '@invect/core/types';
3
+ import { useApiClient } from '../../../contexts/ApiContext';
4
+ import { useFlowActions } from '../../../routes/flow-route-layout';
5
+ import { useNodeConfigPanelStore, useParsedInputPreview } from './use-node-config-panel-store';
6
+
7
+ interface UseRunNodeOptions {
8
+ nodeId: string | null;
9
+ flowId: string;
10
+ nodeType: GraphNodeType;
11
+ nodeParams: Record<string, unknown>;
12
+ updateNodeData: (nodeId: string, data: Record<string, unknown>) => void;
13
+ }
14
+
15
+ /**
16
+ * Hook that handles all node execution logic (both test mode and normal mode)
17
+ */
18
+ export function useRunNode({
19
+ nodeId,
20
+ flowId,
21
+ nodeType,
22
+ nodeParams,
23
+ updateNodeData,
24
+ }: UseRunNodeOptions) {
25
+ const apiClient = useApiClient();
26
+ const flowActions = useFlowActions();
27
+ const parsedInput = useParsedInputPreview();
28
+
29
+ const {
30
+ isTestMode,
31
+ isRunningNode,
32
+ setIsRunningNode,
33
+ handleTestModeSuccess,
34
+ handleNormalModeSuccess,
35
+ handleExecutionError,
36
+ setRunError,
37
+ setOutputError,
38
+ } = useNodeConfigPanelStore();
39
+
40
+ const runNode = useCallback(async () => {
41
+ if (!apiClient || !nodeId || !flowId) {
42
+ return;
43
+ }
44
+
45
+ setIsRunningNode(true);
46
+ setRunError(null);
47
+ setOutputError(null);
48
+
49
+ try {
50
+ // Auto-save flow before running to ensure backend has latest nodes
51
+ if (flowActions?.onSave) {
52
+ const saveSucceeded = await flowActions.onSave({ skipSuccessToast: true });
53
+ if (!saveSucceeded) {
54
+ handleExecutionError(
55
+ 'Failed to save flow. Please fix any validation errors and try again.',
56
+ );
57
+ setIsRunningNode(false);
58
+ return;
59
+ }
60
+ }
61
+
62
+ if (isTestMode) {
63
+ // Test mode: Use testNode API with custom input (skip upstream nodes)
64
+ const result = await apiClient.testNode(nodeType, nodeParams, parsedInput);
65
+
66
+ if (result.success && result.output) {
67
+ // Extract output value
68
+ const typedOutput = result.output as {
69
+ data?: { variables?: Record<string, { value: unknown }> };
70
+ };
71
+ let output: unknown = null;
72
+
73
+ if (typedOutput.data?.variables?.output) {
74
+ const outputVar = typedOutput.data.variables.output;
75
+ output =
76
+ outputVar && typeof outputVar === 'object' && 'value' in outputVar
77
+ ? outputVar.value
78
+ : outputVar;
79
+ } else if (typedOutput.data?.variables) {
80
+ const firstVar = Object.values(typedOutput.data.variables)[0];
81
+ output =
82
+ firstVar && typeof firstVar === 'object' && 'value' in firstVar
83
+ ? firstVar.value
84
+ : firstVar;
85
+ } else {
86
+ output = result.output;
87
+ }
88
+
89
+ handleTestModeSuccess(output);
90
+ updateNodeData(nodeId, { previewOutput: output });
91
+ } else {
92
+ handleExecutionError(result.error || 'Test execution failed');
93
+ }
94
+ } else {
95
+ // Normal mode: Execute the flow up to this node
96
+ // Always use direct execution (no batch processing) when running from node config panel
97
+ const result = await apiClient.executeFlowToNode(
98
+ flowId,
99
+ nodeId,
100
+ {},
101
+ { useBatchProcessing: false },
102
+ );
103
+
104
+ if (result.status === 'SUCCESS') {
105
+ handleNormalModeSuccess(result, nodeId, updateNodeData);
106
+ } else if (result.status === 'PAUSED_FOR_BATCH') {
107
+ handleExecutionError(
108
+ 'Execution paused for batch processing. Check the Runs view for status.',
109
+ );
110
+ } else {
111
+ // Extract the most specific error available
112
+ const specificError =
113
+ (result as { nodeErrors?: Record<string, string> }).nodeErrors?.[nodeId] ||
114
+ result.error ||
115
+ 'Node execution failed';
116
+ handleExecutionError(specificError);
117
+ }
118
+ }
119
+ } catch (error) {
120
+ const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
121
+ handleExecutionError(errorMessage);
122
+ } finally {
123
+ setIsRunningNode(false);
124
+ }
125
+ }, [
126
+ apiClient,
127
+ nodeId,
128
+ flowId,
129
+ flowActions,
130
+ isTestMode,
131
+ nodeType,
132
+ nodeParams,
133
+ parsedInput,
134
+ updateNodeData,
135
+ setIsRunningNode,
136
+ setRunError,
137
+ setOutputError,
138
+ handleTestModeSuccess,
139
+ handleNormalModeSuccess,
140
+ handleExecutionError,
141
+ ]);
142
+
143
+ return {
144
+ runNode,
145
+ isRunningNode,
146
+ };
147
+ }
@@ -0,0 +1,73 @@
1
+ import * as Icons from 'lucide-react';
2
+
3
+ export const getIconComponent = (iconName?: string) => {
4
+ if (!iconName) {
5
+ return Icons.Zap;
6
+ }
7
+ // @ts-ignore - Dynamic lookup of Lucide icons by name
8
+ return Icons[iconName] || Icons.Zap;
9
+ };
10
+
11
+ export const formatNodeTypeLabel = (value: string) => {
12
+ // For action-based types like "gmail.list_messages", show just the action part
13
+ const actionPart = value.includes('.') ? (value.split('.').pop() ?? value) : value;
14
+ return actionPart.toLowerCase().replace(/_/g, ' ');
15
+ };
16
+
17
+ export const stringifyJson = (value: unknown) => {
18
+ try {
19
+ if (typeof value === 'string') {
20
+ return value;
21
+ }
22
+ return JSON.stringify(value ?? {}, null, 2);
23
+ } catch {
24
+ return '{}';
25
+ }
26
+ };
27
+
28
+ export const parseJson = (
29
+ raw: string,
30
+ setError: (value: string | null) => void,
31
+ ): Record<string, unknown> | null => {
32
+ if (!raw.trim()) {
33
+ setError(null);
34
+ return {};
35
+ }
36
+
37
+ try {
38
+ const parsed = JSON.parse(raw);
39
+ setError(null);
40
+ return parsed;
41
+ } catch {
42
+ setError('Invalid JSON');
43
+ return null;
44
+ }
45
+ };
46
+
47
+ /**
48
+ * Extract the primary output value from the structured node output format.
49
+ * Handles the `{ data: { variables: { output: { value } } } }` wrapper.
50
+ */
51
+ export function extractOutputValue(nodeOutput: unknown): unknown {
52
+ if (!nodeOutput || typeof nodeOutput !== 'object') {
53
+ return null;
54
+ }
55
+
56
+ const typedOutput = nodeOutput as { data?: { variables?: Record<string, { value: unknown }> } };
57
+
58
+ if (typedOutput.data?.variables?.output) {
59
+ const outputVar = typedOutput.data.variables.output;
60
+ return outputVar && typeof outputVar === 'object' && 'value' in outputVar
61
+ ? outputVar.value
62
+ : outputVar;
63
+ }
64
+
65
+ if (typedOutput.data?.variables) {
66
+ const firstVar = Object.values(typedOutput.data.variables)[0];
67
+ return firstVar && typeof firstVar === 'object' && 'value' in firstVar
68
+ ? firstVar.value
69
+ : firstVar;
70
+ }
71
+
72
+ return null;
73
+ }