@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,284 @@
1
+ import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
2
+ import type { Node, Edge } from '@xyflow/react';
3
+ import { parseJson, stringifyJson } from '../utils';
4
+ import { useFlowEditorStore } from '../../flow-editor.store';
5
+ import type { ReactFlowNodeData } from '@invect/core/types';
6
+
7
+ /**
8
+ * Generate a slug from a label string (snake_case, alphanumeric only)
9
+ */
10
+ function generateSlug(label: string): string {
11
+ return label
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9]+/g, '_')
14
+ .replace(/^_+|_+$/g, '')
15
+ .substring(0, 50);
16
+ }
17
+
18
+ /**
19
+ * Compute input data for a node based on its incoming edges.
20
+ * Maps output data from source nodes using their reference_id as keys.
21
+ * Structure matches the backend's buildIncomingDataObject format for template resolution.
22
+ *
23
+ * Example output:
24
+ * {
25
+ * "some_node": { output: "value from some_node" },
26
+ * "other_node": { output: "value from other_node" }
27
+ * }
28
+ */
29
+ // Extended node data type that includes preview-related properties
30
+ // These are runtime properties added during editing, not part of the base ReactFlowNodeData type
31
+ interface ExtendedNodeData {
32
+ id?: string;
33
+ type?: string;
34
+ display_name?: string;
35
+ reference_id?: string;
36
+ status?: string;
37
+ executionStatus?: string;
38
+ executionError?: string;
39
+ executionOutput?: unknown;
40
+ params?: Record<string, unknown>;
41
+ inputs?: unknown;
42
+ outputs?: unknown;
43
+ // Preview/editor-specific properties
44
+ previewInput?: unknown;
45
+ previewOutput?: unknown;
46
+ mockInputData?: unknown;
47
+ mockOutputData?: unknown;
48
+ lastInputs?: unknown;
49
+ exampleInput?: unknown;
50
+ exampleOutput?: unknown;
51
+ }
52
+
53
+ function computeInputFromEdges(
54
+ targetNodeId: string,
55
+ nodes: Node[],
56
+ edges: Edge[],
57
+ ): Record<string, unknown> {
58
+ const incomingEdges = edges.filter((edge) => edge.target === targetNodeId);
59
+
60
+ if (incomingEdges.length === 0) {
61
+ return {};
62
+ }
63
+
64
+ const inputData: Record<string, unknown> = {};
65
+
66
+ for (const edge of incomingEdges) {
67
+ const sourceNode = nodes.find((n) => n.id === edge.source);
68
+ if (!sourceNode) {
69
+ continue;
70
+ }
71
+
72
+ // Cast to access ReactFlowNodeData properties at runtime
73
+ const sourceNodeData = sourceNode.data as ExtendedNodeData;
74
+ const displayName = sourceNodeData.display_name || sourceNode.id;
75
+
76
+ // Use reference_id if available, otherwise generate slug from display name
77
+ const slug = sourceNodeData.reference_id || generateSlug(displayName);
78
+
79
+ // Get the output data from the source node
80
+ const sourceOutput =
81
+ sourceNodeData.previewOutput ??
82
+ sourceNodeData.executionOutput ??
83
+ sourceNodeData.mockOutputData ??
84
+ sourceNodeData.exampleOutput;
85
+
86
+ if (sourceOutput !== undefined && sourceOutput !== null) {
87
+ // Map directly: { slug: outputValue }
88
+ // This allows templates to use {{ slug }} directly for the output value
89
+ inputData[slug] = sourceOutput;
90
+ } else {
91
+ // Source node has not been run yet - show placeholder
92
+ inputData[slug] = `[NO DATA]`;
93
+ }
94
+ }
95
+
96
+ return inputData;
97
+ }
98
+
99
+ interface UsePreviewStateOptions {
100
+ nodeId: string | null;
101
+ updateNodeData: (nodeId: string, data: Partial<ReactFlowNodeData>) => void;
102
+ }
103
+
104
+ export function usePreviewState({ nodeId, updateNodeData }: UsePreviewStateOptions) {
105
+ // Use Zustand store as source of truth instead of React Flow's internal store
106
+ const nodes = useFlowEditorStore((s) => s.nodes);
107
+ const edges = useFlowEditorStore((s) => s.edges);
108
+
109
+ // Find the current node from our store
110
+ const node = useMemo(() => {
111
+ if (!nodeId) {
112
+ return null;
113
+ }
114
+ return nodes.find((n) => n.id === nodeId) ?? null;
115
+ }, [nodeId, nodes]);
116
+
117
+ const [inputPreview, setInputPreview] = useState('');
118
+ const [outputPreview, setOutputPreview] = useState('');
119
+ const [inputError, setInputError] = useState<string | null>(null);
120
+ const [outputError, setOutputError] = useState<string | null>(null);
121
+
122
+ // Test mode state
123
+ const [isTestMode, setIsTestMode] = useState(false);
124
+ const [originalInputPreview, setOriginalInputPreview] = useState<string | null>(null);
125
+
126
+ const prevNodeIdRef = useRef<string | null>(null);
127
+
128
+ // Initialize previews when node changes
129
+ useEffect(() => {
130
+ const nodeIdChanged = prevNodeIdRef.current !== nodeId;
131
+ prevNodeIdRef.current = nodeId;
132
+
133
+ if (!node || !nodeId) {
134
+ setInputPreview('');
135
+ setOutputPreview('');
136
+ setInputError(null);
137
+ setOutputError(null);
138
+ setIsTestMode(false);
139
+ setOriginalInputPreview(null);
140
+ return;
141
+ }
142
+
143
+ if (nodeIdChanged) {
144
+ // Cast to extended type to access preview properties
145
+ const currentNodeData = node.data as ExtendedNodeData;
146
+ const computedInput = computeInputFromEdges(nodeId, nodes, edges);
147
+ const hasComputedInput = Object.keys(computedInput).length > 0;
148
+
149
+ let initialInput: string;
150
+ if (currentNodeData.previewInput) {
151
+ initialInput = stringifyJson(currentNodeData.previewInput);
152
+ } else if (hasComputedInput) {
153
+ initialInput = stringifyJson(computedInput);
154
+ } else {
155
+ initialInput = stringifyJson(
156
+ currentNodeData.mockInputData ??
157
+ currentNodeData.lastInputs ??
158
+ currentNodeData.exampleInput ??
159
+ {},
160
+ );
161
+ }
162
+
163
+ setInputPreview(initialInput);
164
+ setOriginalInputPreview(initialInput);
165
+ setIsTestMode(false);
166
+
167
+ setOutputPreview(
168
+ stringifyJson(
169
+ currentNodeData.previewOutput ??
170
+ currentNodeData.executionOutput ??
171
+ currentNodeData.mockOutputData ??
172
+ currentNodeData.exampleOutput ??
173
+ {},
174
+ ),
175
+ );
176
+
177
+ setInputError(null);
178
+ setOutputError(null);
179
+ }
180
+ }, [nodeId, nodes, edges, node]);
181
+
182
+ const handleInputPreviewChange = useCallback(
183
+ (value: string) => {
184
+ setInputPreview(value);
185
+ setInputError(null);
186
+
187
+ if (originalInputPreview !== null && value !== originalInputPreview) {
188
+ setIsTestMode(true);
189
+ } else if (value === originalInputPreview) {
190
+ setIsTestMode(false);
191
+ }
192
+
193
+ if (nodeId) {
194
+ const parsed = parseJson(value, setInputError);
195
+ if (parsed !== null) {
196
+ // Note: previewInput is an extended property, cast is needed
197
+ updateNodeData(nodeId, { previewInput: parsed } as Partial<ReactFlowNodeData>);
198
+ }
199
+ }
200
+ },
201
+ [nodeId, updateNodeData, originalInputPreview],
202
+ );
203
+
204
+ const handleOutputPreviewChange = useCallback(
205
+ (value: string) => {
206
+ setOutputPreview(value);
207
+ setOutputError(null);
208
+
209
+ if (nodeId) {
210
+ const parsed = parseJson(value, setOutputError);
211
+ if (parsed !== null) {
212
+ // Note: previewOutput is an extended property, cast is needed
213
+ updateNodeData(nodeId, { previewOutput: parsed } as Partial<ReactFlowNodeData>);
214
+ }
215
+ }
216
+ },
217
+ [nodeId, updateNodeData],
218
+ );
219
+
220
+ const handleResetTestMode = useCallback(() => {
221
+ if (originalInputPreview !== null) {
222
+ setInputPreview(originalInputPreview);
223
+ setIsTestMode(false);
224
+
225
+ if (nodeId) {
226
+ const parsed = parseJson(originalInputPreview, setInputError);
227
+ if (parsed !== null) {
228
+ // Note: previewInput is an extended property, cast is needed
229
+ updateNodeData(nodeId, { previewInput: parsed } as Partial<ReactFlowNodeData>);
230
+ }
231
+ }
232
+ }
233
+ }, [originalInputPreview, nodeId, updateNodeData]);
234
+
235
+ const updateFromExecution = useCallback((newInput: string, newOutput: string) => {
236
+ setInputPreview(newInput);
237
+ setOriginalInputPreview(newInput);
238
+ setOutputPreview(newOutput);
239
+ setIsTestMode(false);
240
+ }, []);
241
+
242
+ // Refresh input preview from edges (used after running upstream nodes)
243
+ const refreshInputFromEdges = useCallback(() => {
244
+ if (!nodeId) {
245
+ return;
246
+ }
247
+
248
+ const computedInput = computeInputFromEdges(nodeId, nodes, edges);
249
+ const newInputStr = stringifyJson(computedInput);
250
+
251
+ setInputPreview(newInputStr);
252
+ setOriginalInputPreview(newInputStr);
253
+ setIsTestMode(false);
254
+ setInputError(null);
255
+ }, [nodeId, nodes, edges]);
256
+
257
+ // Get upstream variable names (reference IDs from connected upstream nodes)
258
+ const upstreamVariables = useMemo(() => {
259
+ if (!nodeId) {
260
+ return [];
261
+ }
262
+ const computedInput = computeInputFromEdges(nodeId, nodes, edges);
263
+ return Object.keys(computedInput);
264
+ }, [nodeId, nodes, edges]);
265
+
266
+ return {
267
+ inputPreview,
268
+ outputPreview,
269
+ inputError,
270
+ outputError,
271
+ isTestMode,
272
+ originalInputPreview,
273
+ upstreamVariables,
274
+ setInputPreview,
275
+ setOutputPreview,
276
+ setInputError,
277
+ setOutputError,
278
+ handleInputPreviewChange,
279
+ handleOutputPreviewChange,
280
+ handleResetTestMode,
281
+ updateFromExecution,
282
+ refreshInputFromEdges,
283
+ };
284
+ }
@@ -0,0 +1,287 @@
1
+ import { useCallback, useState } from 'react';
2
+ import { parseJson, stringifyJson } from '../utils';
3
+ import type { UseMutationResult } from '@tanstack/react-query';
4
+
5
+ // Options for save operation
6
+ interface SaveOptions {
7
+ skipSuccessToast?: boolean;
8
+ }
9
+
10
+ // Flow actions interface
11
+ interface FlowActions {
12
+ onExecute: () => Promise<void>;
13
+ isExecuting: boolean;
14
+ isDirty?: boolean;
15
+ onSave?: (options?: SaveOptions) => Promise<boolean>;
16
+ isSaving?: boolean;
17
+ }
18
+
19
+ interface ExecutionResult {
20
+ success: boolean;
21
+ output?: unknown;
22
+ error?: string;
23
+ fieldErrors?: Record<string, string>;
24
+ traces?: Array<{
25
+ nodeId: string;
26
+ inputs: unknown;
27
+ outputs: unknown;
28
+ }>;
29
+ }
30
+
31
+ // Type for the executeFlowToNode mutation
32
+ type ExecuteFlowToNodeMutation = UseMutationResult<
33
+ unknown,
34
+ Error,
35
+ {
36
+ flowId: string;
37
+ nodeId: string;
38
+ inputs?: Record<string, unknown>;
39
+ options?: { useBatchProcessing?: boolean };
40
+ }
41
+ >;
42
+
43
+ // Type for the testNode mutation
44
+ type TestNodeMutation = UseMutationResult<
45
+ unknown,
46
+ Error,
47
+ {
48
+ nodeType: string;
49
+ params: Record<string, unknown>;
50
+ inputs: Record<string, unknown>;
51
+ }
52
+ >;
53
+
54
+ interface UseNodeExecutionOptions {
55
+ nodeId: string | null;
56
+ flowId: string;
57
+ nodeType: string;
58
+ nodeParams: Record<string, unknown>;
59
+ executeFlowToNodeMutation: ExecuteFlowToNodeMutation;
60
+ testNodeMutation?: TestNodeMutation;
61
+ flowActions: FlowActions | null;
62
+ updateNodeData: (nodeId: string, data: Record<string, unknown>) => void;
63
+ isTestMode: boolean;
64
+ inputPreview: string;
65
+ onExecutionComplete: (input: string, output: string) => void;
66
+ }
67
+
68
+ /**
69
+ * Extract output value from the structured node output format
70
+ */
71
+ function extractOutputValue(nodeOutput: unknown): unknown {
72
+ if (!nodeOutput || typeof nodeOutput !== 'object') {
73
+ return null;
74
+ }
75
+
76
+ const typedOutput = nodeOutput as { data?: { variables?: Record<string, { value: unknown }> } };
77
+
78
+ if (typedOutput.data?.variables?.output) {
79
+ const outputVar = typedOutput.data.variables.output;
80
+ return outputVar && typeof outputVar === 'object' && 'value' in outputVar
81
+ ? outputVar.value
82
+ : outputVar;
83
+ }
84
+
85
+ if (typedOutput.data?.variables) {
86
+ const firstVar = Object.values(typedOutput.data.variables)[0];
87
+ return firstVar && typeof firstVar === 'object' && 'value' in firstVar
88
+ ? firstVar.value
89
+ : firstVar;
90
+ }
91
+
92
+ return null;
93
+ }
94
+
95
+ /**
96
+ * Parse Zod prettifyError output to extract per-field error messages.
97
+ * Zod v4 errors look like: "✕ Invalid input: expected string, received undefined\n → at to"
98
+ * Multiple errors are separated by newlines.
99
+ */
100
+ function parseFieldErrorsFromString(errorStr: string): Record<string, string> | null {
101
+ const fieldErrors: Record<string, string> = {};
102
+ // Split on the arrow marker and extract "message → at fieldName" pairs
103
+ const parts = errorStr.split('→');
104
+ for (let i = 1; i < parts.length; i++) {
105
+ const afterArrow = parts[i].match(/^\s*at\s+(\w+)/);
106
+ if (!afterArrow) {
107
+ continue;
108
+ }
109
+ const fieldName = afterArrow[1];
110
+ // Message is everything in the previous part (after any prior field match)
111
+ const rawMessage = (parts[i - 1] ?? '').replace(/\n[ \t]*$/, '');
112
+ // Take the last line as the message (handles multi-error strings)
113
+ const lastLine = rawMessage.split('\n').pop() ?? '';
114
+ const message = lastLine.replace(/^[✕×]\s*/, '').trim();
115
+ if (fieldName && message) {
116
+ fieldErrors[fieldName] = message;
117
+ }
118
+ }
119
+ return Object.keys(fieldErrors).length > 0 ? fieldErrors : null;
120
+ }
121
+
122
+ export function useNodeExecution({
123
+ nodeId,
124
+ flowId,
125
+ nodeType,
126
+ nodeParams,
127
+ executeFlowToNodeMutation,
128
+ testNodeMutation,
129
+ flowActions,
130
+ updateNodeData,
131
+ isTestMode,
132
+ inputPreview,
133
+ onExecutionComplete,
134
+ }: UseNodeExecutionOptions) {
135
+ const [isRunning, setIsRunning] = useState(false);
136
+ const [runError, setRunError] = useState<string | null>(null);
137
+ const [outputError, setOutputError] = useState<string | null>(null);
138
+ const [fieldErrors, setFieldErrors] = useState<Record<string, string> | null>(null);
139
+
140
+ const runNode = useCallback(async () => {
141
+ if (!nodeId || !flowId) {
142
+ return;
143
+ }
144
+
145
+ setIsRunning(true);
146
+ setRunError(null);
147
+ setOutputError(null);
148
+ setFieldErrors(null);
149
+
150
+ try {
151
+ // Auto-save flow before running
152
+ if (flowActions?.onSave) {
153
+ const saveSucceeded = await flowActions.onSave({ skipSuccessToast: true });
154
+ if (!saveSucceeded) {
155
+ setRunError('Failed to save flow. Please fix any validation errors and try again.');
156
+ setOutputError('Save failed - check node configuration');
157
+ setIsRunning(false);
158
+ return;
159
+ }
160
+ }
161
+
162
+ if (isTestMode) {
163
+ // Test mode: run single node with custom input
164
+ if (!testNodeMutation) {
165
+ setRunError('Test mode is not available');
166
+ setOutputError('Test mode is not available');
167
+ setIsRunning(false);
168
+ return;
169
+ }
170
+
171
+ const testInput = parseJson(inputPreview, () => ({})) || {};
172
+ const result = (await testNodeMutation.mutateAsync({
173
+ nodeType,
174
+ params: nodeParams,
175
+ inputs: testInput,
176
+ })) as ExecutionResult;
177
+
178
+ if (result.success && result.output) {
179
+ const output = extractOutputValue(result.output) ?? result.output;
180
+ const displayValue = typeof output === 'string' ? output : stringifyJson(output);
181
+
182
+ updateNodeData(nodeId, { previewOutput: output });
183
+ onExecutionComplete(inputPreview, displayValue);
184
+ } else {
185
+ setRunError(result.error || 'Test execution failed');
186
+ setOutputError(result.error || 'Test execution failed');
187
+ if (result.fieldErrors) {
188
+ setFieldErrors(result.fieldErrors);
189
+ }
190
+ }
191
+ } else {
192
+ // Normal mode: run flow up to this node
193
+ const result = (await executeFlowToNodeMutation.mutateAsync({
194
+ flowId,
195
+ nodeId,
196
+ inputs: {},
197
+ options: { useBatchProcessing: false },
198
+ })) as {
199
+ status: string;
200
+ error?: string;
201
+ nodeErrors?: Record<string, string>;
202
+ traces?: Array<{ nodeId: string; inputs: unknown; outputs: unknown; error?: string }>;
203
+ outputs?: Record<string, unknown>;
204
+ };
205
+
206
+ if (result.status === 'SUCCESS') {
207
+ // Update all executed nodes from traces
208
+ if (result.traces && Array.isArray(result.traces)) {
209
+ for (const trace of result.traces) {
210
+ const traceNodeId = trace.nodeId;
211
+ if (!traceNodeId) {
212
+ continue;
213
+ }
214
+
215
+ const traceOutput = extractOutputValue(trace.outputs);
216
+ updateNodeData(traceNodeId, {
217
+ previewInput: trace.inputs,
218
+ previewOutput: traceOutput,
219
+ });
220
+ }
221
+ }
222
+
223
+ // Get current node's output
224
+ const nodeOutput = result.outputs?.[nodeId];
225
+ const output = extractOutputValue(nodeOutput);
226
+ const displayValue = typeof output === 'string' ? output : stringifyJson(output);
227
+
228
+ // Get current node's input from trace
229
+ const currentTrace = result.traces?.find((t: { nodeId: string }) => t.nodeId === nodeId);
230
+ const newInputPreview = currentTrace?.inputs
231
+ ? stringifyJson(currentTrace.inputs)
232
+ : inputPreview;
233
+
234
+ onExecutionComplete(newInputPreview, displayValue);
235
+ } else if (result.status === 'PAUSED_FOR_BATCH') {
236
+ setRunError('Execution paused for batch processing. Check the Runs view for status.');
237
+ setOutputError('Waiting for batch processing...');
238
+ } else {
239
+ // Extract the most specific error available:
240
+ // 1. Error for this specific node from nodeErrors
241
+ // 2. Top-level error from the result
242
+ // 3. Error from the failed trace
243
+ // 4. Generic fallback
244
+ const specificError =
245
+ result.nodeErrors?.[nodeId] ||
246
+ result.error ||
247
+ result.traces?.find((t) => t.error)?.error ||
248
+ 'Node execution failed';
249
+ setRunError(specificError);
250
+ setOutputError(specificError);
251
+ // Try to parse field-specific errors from the error string
252
+ const parsed = parseFieldErrorsFromString(specificError);
253
+ if (parsed) {
254
+ setFieldErrors(parsed);
255
+ }
256
+ }
257
+ }
258
+ } catch (error) {
259
+ const errorMessage = error instanceof Error ? error.message : 'An unexpected error occurred';
260
+ setRunError(errorMessage);
261
+ setOutputError(errorMessage);
262
+ } finally {
263
+ setIsRunning(false);
264
+ }
265
+ }, [
266
+ executeFlowToNodeMutation,
267
+ testNodeMutation,
268
+ nodeId,
269
+ flowId,
270
+ flowActions,
271
+ isTestMode,
272
+ inputPreview,
273
+ nodeType,
274
+ nodeParams,
275
+ updateNodeData,
276
+ onExecutionComplete,
277
+ ]);
278
+
279
+ return {
280
+ isRunning,
281
+ runError,
282
+ outputError,
283
+ fieldErrors,
284
+ runNode,
285
+ setOutputError,
286
+ };
287
+ }