@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,650 @@
1
+ import { useMemo, useCallback, useState, useEffect, useRef } from 'react';
2
+ import { GraphNodeType, type ReactFlowNodeData } from '@invect/core/types';
3
+ import {
4
+ Dialog,
5
+ DialogClose,
6
+ DialogContent,
7
+ DialogDescription,
8
+ DialogTitle,
9
+ } from '../../ui/dialog';
10
+ import { X } from 'lucide-react';
11
+ import { nanoid } from 'nanoid';
12
+ import { ResizablePanelGroup, ResizableHandle } from '../../ui/resizable';
13
+ import { cn } from '../../../lib/utils';
14
+ import { useNodeRegistry } from '../../../contexts/NodeRegistryContext';
15
+ import {
16
+ useCredentials,
17
+ useCreateCredential,
18
+ useUpdateCredential,
19
+ useTestCredential,
20
+ useStartOAuth2Flow,
21
+ useHandleOAuth2Callback,
22
+ } from '../../../api/credentials.api';
23
+ import { useExecuteFlowToNode, useTestNode } from '../../../api/executions.api';
24
+ import { useTestMapper } from '../../../api/node-data.api';
25
+ import { CreateCredentialModal } from '../../credentials/CreateCredentialModal';
26
+ import { EditCredentialModal } from '../../credentials/EditCredentialModal';
27
+ import type { Credential } from '../../../api/types';
28
+
29
+ import { formatNodeTypeLabel, getIconComponent } from './utils';
30
+ import { useNodeConfigState } from './use-node-config-state';
31
+ import { updateReferenceIdForDisplayName } from '../../../utils/nodeReferenceUtils';
32
+ import { useFlowActions } from '../../../routes/flow-route-layout';
33
+ import { usePreviewState, useNodeExecution } from './hooks';
34
+ import { useUpstreamSlots } from './hooks/use-upstream-slots';
35
+ import { InputPanel, OutputPanel, ConfigurationPanel } from './panels';
36
+ import { useFlowEditorStore } from '../flow-editor.store';
37
+ import type { ToolDefinition, AddedToolInstance } from '../../nodes/ToolSelectorModal';
38
+
39
+ interface NodeConfigPanelProps {
40
+ nodeId: string | null;
41
+ flowId: string;
42
+ open: boolean;
43
+ onOpenChange: (open: boolean) => void;
44
+ portalContainer?: HTMLElement | null;
45
+ /** Available agent tools — only needed for AGENT node type */
46
+ availableTools?: ToolDefinition[];
47
+ /** If set, open the Tools tab with this instance pre-selected */
48
+ initialToolInstanceId?: string | null;
49
+ }
50
+
51
+ export function NodeConfigPanel({
52
+ nodeId,
53
+ flowId,
54
+ open,
55
+ onOpenChange,
56
+ portalContainer,
57
+ availableTools = [],
58
+ initialToolInstanceId,
59
+ }: NodeConfigPanelProps) {
60
+ const { getNodeDefinition } = useNodeRegistry();
61
+
62
+ // Use Zustand store for all node state (single source of truth)
63
+ const updateNodeDataInStore = useFlowEditorStore((s) => s.updateNodeData);
64
+ const storeNodes = useFlowEditorStore((s) => s.nodes);
65
+
66
+ // Find the current node from our Zustand store
67
+ const node = useMemo(() => {
68
+ if (!nodeId) {
69
+ return null;
70
+ }
71
+ return storeNodes.find((n) => n.id === nodeId) ?? null;
72
+ }, [nodeId, storeNodes]);
73
+
74
+ // Access node data - cast to ReactFlowNodeData for proper typing
75
+ // At runtime, nodes from the server always have this shape
76
+ const nodeData = node?.data as ReactFlowNodeData | undefined;
77
+ const nodeType = nodeData?.type ?? GraphNodeType.TEMPLATE_STRING;
78
+ const nodeParams = nodeData?.params ?? {};
79
+ const definition = node ? getNodeDefinition(nodeType) : undefined;
80
+
81
+ // Callback for backend resolution to write params back to Zustand
82
+ const handleResolvedParams = useCallback(
83
+ (nid: string, params: Record<string, unknown>) => {
84
+ updateNodeDataInStore(nid, { params } as Partial<ReactFlowNodeData>);
85
+ },
86
+ [updateNodeDataInStore],
87
+ );
88
+
89
+ // Node configuration state (validation, dynamic fields)
90
+ // values are derived from node.data.params (Zustand) — single source of truth
91
+ const {
92
+ definition: activeDefinition,
93
+ values: formValues,
94
+ warnings: configWarnings,
95
+ errors: configErrors,
96
+ updateField,
97
+ isUpdating: isConfigUpdating,
98
+ } = useNodeConfigState({
99
+ node: node ?? null,
100
+ nodeType,
101
+ definition,
102
+ onParamsChange: handleResolvedParams,
103
+ });
104
+
105
+ const flowActions = useFlowActions();
106
+ const executeFlowToNodeMutation = useExecuteFlowToNode();
107
+ const testNodeMutation = useTestNode();
108
+ const testMapperMutation = useTestMapper();
109
+
110
+ // Upstream slots — replaces computeInputFromEdges + handleRunUpstreamNode
111
+ const upstream = useUpstreamSlots({ nodeId, flowId });
112
+
113
+ // Preview state (input/output)
114
+ const previewState = usePreviewState({ nodeId, updateNodeData: updateNodeDataInStore });
115
+
116
+ // Credential modal state
117
+ const [isCreateCredentialOpen, setIsCreateCredentialOpen] = useState(false);
118
+ const [activeCredentialField, setActiveCredentialField] = useState<string | null>(null);
119
+
120
+ // Edit credential state
121
+ const [editingCredential, setEditingCredential] = useState<Credential | null>(null);
122
+ const updateCredentialMutation = useUpdateCredential();
123
+
124
+ // OAuth refresh state
125
+ const testCredentialMutation = useTestCredential();
126
+ const startOAuth2Flow = useStartOAuth2Flow();
127
+ const handleOAuth2Callback = useHandleOAuth2Callback();
128
+ const [refreshingCredentialId, setRefreshingCredentialId] = useState<string | null>(null);
129
+ const [oauthPopupWindow, setOAuthPopupWindow] = useState<Window | null>(null);
130
+ const oauthCallbackParamsRef = useRef<{ credentialId: string } | null>(null);
131
+
132
+ // Listen for OAuth callback message from popup (for credential refresh)
133
+ useEffect(() => {
134
+ const handleMessage = async (event: MessageEvent) => {
135
+ if (event.origin !== window.location.origin) {
136
+ return;
137
+ }
138
+ const { type, code, state, error } = event.data;
139
+ if (type !== 'oauth2_callback') {
140
+ return;
141
+ }
142
+
143
+ if (oauthPopupWindow && !oauthPopupWindow.closed) {
144
+ oauthPopupWindow.close();
145
+ }
146
+ setOAuthPopupWindow(null);
147
+
148
+ if (error || !code || !state) {
149
+ setRefreshingCredentialId(null);
150
+ return;
151
+ }
152
+
153
+ try {
154
+ await handleOAuth2Callback.mutateAsync({ code, state });
155
+ } catch {
156
+ // Credential cache is invalidated by the mutation hook on success
157
+ }
158
+ setRefreshingCredentialId(null);
159
+ };
160
+
161
+ window.addEventListener('message', handleMessage);
162
+ return () => window.removeEventListener('message', handleMessage);
163
+ }, [oauthPopupWindow, handleOAuth2Callback]);
164
+
165
+ // Check if popup was closed without completing
166
+ useEffect(() => {
167
+ if (!oauthPopupWindow) {
168
+ return;
169
+ }
170
+ const check = setInterval(() => {
171
+ if (oauthPopupWindow.closed) {
172
+ clearInterval(check);
173
+ setOAuthPopupWindow(null);
174
+ setRefreshingCredentialId(null);
175
+ }
176
+ }, 500);
177
+ return () => clearInterval(check);
178
+ }, [oauthPopupWindow]);
179
+
180
+ // Mapper config state — stored in node data as `mapper`
181
+ const mapperConfig = (nodeData as Record<string, unknown> | undefined)?.mapper as
182
+ | {
183
+ enabled: boolean;
184
+ expression: string;
185
+ mode: 'auto' | 'iterate' | 'reshape';
186
+ outputMode: 'array' | 'object' | 'first' | 'last' | 'concat';
187
+ keyField?: string;
188
+ concurrency: number;
189
+ onEmpty: 'skip' | 'error';
190
+ }
191
+ | undefined;
192
+
193
+ const handleMapperChange = useCallback(
194
+ (config: typeof mapperConfig) => {
195
+ if (!nodeId) {
196
+ return;
197
+ }
198
+ updateNodeDataInStore(nodeId, { mapper: config } as Partial<ReactFlowNodeData>);
199
+ },
200
+ [nodeId, updateNodeDataInStore],
201
+ );
202
+
203
+ // Parse current input for mapper testing
204
+ const parsedInputData = useMemo(() => {
205
+ const raw = upstream.slots.length > 0 ? upstream.inputPreviewJson : previewState.inputPreview;
206
+ try {
207
+ const parsed = JSON.parse(raw);
208
+ return typeof parsed === 'object' && parsed !== null ? parsed : {};
209
+ } catch {
210
+ return {};
211
+ }
212
+ }, [upstream.slots.length, upstream.inputPreviewJson, previewState.inputPreview]);
213
+
214
+ const handleTestMapper = useCallback(
215
+ (request: {
216
+ expression: string;
217
+ incomingData: Record<string, unknown>;
218
+ mode?: 'auto' | 'iterate' | 'reshape';
219
+ }) => {
220
+ testMapperMutation.mutate(request);
221
+ },
222
+ [testMapperMutation],
223
+ );
224
+
225
+ // Node execution
226
+ const execution = useNodeExecution({
227
+ nodeId,
228
+ flowId,
229
+ nodeType,
230
+ nodeParams: nodeParams as Record<string, unknown>,
231
+ executeFlowToNodeMutation,
232
+ testNodeMutation,
233
+ flowActions,
234
+ updateNodeData: updateNodeDataInStore,
235
+ isTestMode: previewState.isTestMode,
236
+ inputPreview: previewState.inputPreview,
237
+ onExecutionComplete: useCallback(
238
+ (newInput: string, newOutput: string) => {
239
+ previewState.updateFromExecution(newInput, newOutput);
240
+ },
241
+ [previewState],
242
+ ),
243
+ });
244
+
245
+ // Credentials
246
+ const {
247
+ data: credentials = [],
248
+ isLoading: credentialsLoading,
249
+ isError: credentialsError,
250
+ refetch: refetchCredentials,
251
+ } = useCredentials({ includeShared: true }, { enabled: open });
252
+
253
+ const createCredentialMutation = useCreateCredential();
254
+
255
+ // Compute required OAuth scopes from the current node's credential field definition
256
+ const currentNodeRequiredScopes = useMemo(() => {
257
+ const credField = (activeDefinition?.paramFields ?? []).find(
258
+ (f) => f.type === 'credential' && f.requiredScopes?.length,
259
+ );
260
+ return credField?.requiredScopes;
261
+ }, [activeDefinition]);
262
+
263
+ // Derived display values
264
+ const displayName = (nodeData?.display_name as string) || definition?.label || 'Untitled Node';
265
+ const Icon = useMemo(
266
+ () => getIconComponent(activeDefinition?.icon || definition?.icon),
267
+ [activeDefinition?.icon, definition?.icon],
268
+ );
269
+ const categoryColor = 'bg-primary text-primary-foreground';
270
+ const nodeTypeLabel = useMemo(() => formatNodeTypeLabel(nodeType), [nodeType]);
271
+
272
+ // Model-specific status message
273
+ const modelStatusMessage = useMemo(() => {
274
+ if (nodeType !== GraphNodeType.MODEL) {
275
+ return '';
276
+ }
277
+
278
+ const selectedCredentialId = (formValues.credentialId as string) || '';
279
+ const providerLabel =
280
+ typeof formValues.provider === 'string' ? (formValues.provider as string) : '';
281
+ const visibleFields = (activeDefinition?.paramFields || []).filter((f) => !f.hidden);
282
+ const modelField = visibleFields.find((f) => f.name === 'model');
283
+
284
+ if (!selectedCredentialId) {
285
+ return 'Select a credential to load provider-specific models.';
286
+ }
287
+ if (isConfigUpdating) {
288
+ return 'Updating configuration...';
289
+ }
290
+ if (configErrors.length) {
291
+ return configErrors[0];
292
+ }
293
+ if (!providerLabel) {
294
+ return 'Detecting provider from credential...';
295
+ }
296
+ if (modelField?.disabled) {
297
+ return `No models available for provider ${providerLabel}.`;
298
+ }
299
+ return `Detected provider: ${providerLabel}`;
300
+ }, [nodeType, formValues, activeDefinition, isConfigUpdating, configErrors]);
301
+
302
+ // Handlers
303
+ const handleLabelChange = useCallback(
304
+ (newLabel: string) => {
305
+ if (!nodeId) {
306
+ return;
307
+ }
308
+ const allNodes = storeNodes;
309
+ const referenceId = updateReferenceIdForDisplayName(newLabel, nodeId, allNodes);
310
+ updateNodeDataInStore(nodeId, { display_name: newLabel, reference_id: referenceId });
311
+ },
312
+ [nodeId, updateNodeDataInStore, storeNodes],
313
+ );
314
+
315
+ const handleFieldChange = useCallback(
316
+ (fieldName: string, value: unknown) => {
317
+ if (!nodeId) {
318
+ return;
319
+ }
320
+ // Write to Zustand (single source of truth)
321
+ const currentNode = storeNodes.find((n) => n.id === nodeId);
322
+ const currentParams = (currentNode?.data as ReactFlowNodeData | undefined)?.params ?? {};
323
+ const newParams = { ...currentParams, [fieldName]: value } as ReactFlowNodeData['params'];
324
+ updateNodeDataInStore(nodeId, { params: newParams });
325
+
326
+ // Trigger backend resolution for credential/provider changes
327
+ updateField(fieldName, value);
328
+ },
329
+ [nodeId, updateNodeDataInStore, updateField, storeNodes],
330
+ );
331
+
332
+ const handleAddNewCredential = useCallback((fieldName: string) => {
333
+ setActiveCredentialField(fieldName);
334
+ setIsCreateCredentialOpen(true);
335
+ }, []);
336
+
337
+ const handleCloseCredentialModal = useCallback(() => {
338
+ setIsCreateCredentialOpen(false);
339
+ setActiveCredentialField(null);
340
+ }, []);
341
+
342
+ const handleCreateCredential = useCallback(
343
+ (input: Parameters<typeof createCredentialMutation.mutate>[0]) => {
344
+ createCredentialMutation.mutate(input, {
345
+ onSuccess: (createdCredential) => {
346
+ if (activeCredentialField) {
347
+ handleFieldChange(activeCredentialField, createdCredential.id);
348
+ }
349
+ handleCloseCredentialModal();
350
+ },
351
+ });
352
+ },
353
+ [
354
+ createCredentialMutation,
355
+ activeCredentialField,
356
+ handleFieldChange,
357
+ handleCloseCredentialModal,
358
+ ],
359
+ );
360
+
361
+ // Edit credential handler
362
+ const handleEditCredential = useCallback((credential: Credential) => {
363
+ setEditingCredential(credential);
364
+ }, []);
365
+
366
+ const handleCloseEditCredential = useCallback(() => {
367
+ setEditingCredential(null);
368
+ }, []);
369
+
370
+ const handleUpdateCredential = useCallback(
371
+ (data: Parameters<typeof updateCredentialMutation.mutate>[0]['data']) => {
372
+ if (!editingCredential) {
373
+ return;
374
+ }
375
+ updateCredentialMutation.mutate(
376
+ { id: editingCredential.id, data },
377
+ { onSuccess: () => setEditingCredential(null) },
378
+ );
379
+ },
380
+ [editingCredential, updateCredentialMutation],
381
+ );
382
+
383
+ // OAuth refresh handler: test credential → if fails → start re-auth flow
384
+ const handleRefreshOAuthCredential = useCallback(
385
+ async (credential: Credential) => {
386
+ setRefreshingCredentialId(credential.id);
387
+ oauthCallbackParamsRef.current = { credentialId: credential.id };
388
+
389
+ try {
390
+ // First test the credential
391
+ const testResult = await testCredentialMutation.mutateAsync(credential.id);
392
+ if (testResult.success) {
393
+ // Credential is valid, just refresh credentials list
394
+ setRefreshingCredentialId(null);
395
+ refetchCredentials();
396
+ return;
397
+ }
398
+ } catch {
399
+ // Test failed — proceed to re-authorize
400
+ }
401
+
402
+ // Start OAuth re-auth flow
403
+ try {
404
+ const result = await startOAuth2Flow.mutateAsync({
405
+ existingCredentialId: credential.id,
406
+ redirectUri: `${window.location.origin}/oauth/callback`,
407
+ returnUrl: window.location.href,
408
+ scopes: currentNodeRequiredScopes,
409
+ });
410
+
411
+ const width = 600;
412
+ const height = 700;
413
+ const left = window.screenX + (window.outerWidth - width) / 2;
414
+ const top = window.screenY + (window.outerHeight - height) / 2;
415
+
416
+ const popup = window.open(
417
+ result.authorizationUrl,
418
+ `oauth2_refresh_${credential.id}`,
419
+ `width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no,location=no,status=no`,
420
+ );
421
+
422
+ if (!popup) {
423
+ setRefreshingCredentialId(null);
424
+ return;
425
+ }
426
+
427
+ setOAuthPopupWindow(popup);
428
+ } catch {
429
+ setRefreshingCredentialId(null);
430
+ }
431
+ },
432
+ [testCredentialMutation, startOAuth2Flow, refetchCredentials, currentNodeRequiredScopes],
433
+ );
434
+
435
+ // ── Agent Tool Handlers (only used when nodeType is AGENT) ──────
436
+
437
+ const addedTools = useMemo<AddedToolInstance[]>(() => {
438
+ return (nodeParams.addedTools as AddedToolInstance[]) ?? [];
439
+ }, [nodeParams]);
440
+
441
+ const handleAddTool = useCallback(
442
+ (toolId: string): string => {
443
+ if (!nodeId) {
444
+ return '';
445
+ }
446
+ const toolDef = availableTools.find((t) => t.id === toolId);
447
+ if (!toolDef) {
448
+ return '';
449
+ }
450
+
451
+ const instanceId = nanoid();
452
+ const newInstance: AddedToolInstance = {
453
+ instanceId,
454
+ toolId,
455
+ name: toolDef.name,
456
+ description: toolDef.description,
457
+ params: {},
458
+ };
459
+
460
+ const currentNode = storeNodes.find((n) => n.id === nodeId);
461
+ const currentParams = (currentNode?.data as ReactFlowNodeData | undefined)?.params ?? {};
462
+ const currentTools =
463
+ ((currentParams as Record<string, unknown>).addedTools as AddedToolInstance[]) ?? [];
464
+ updateNodeDataInStore(nodeId, {
465
+ params: { ...currentParams, addedTools: [...currentTools, newInstance] },
466
+ });
467
+ return instanceId;
468
+ },
469
+ [nodeId, availableTools, storeNodes, updateNodeDataInStore],
470
+ );
471
+
472
+ const handleRemoveTool = useCallback(
473
+ (instanceId: string) => {
474
+ if (!nodeId) {
475
+ return;
476
+ }
477
+ const currentNode = storeNodes.find((n) => n.id === nodeId);
478
+ const currentParams = (currentNode?.data as ReactFlowNodeData | undefined)?.params ?? {};
479
+ const currentTools =
480
+ ((currentParams as Record<string, unknown>).addedTools as AddedToolInstance[]) ?? [];
481
+ updateNodeDataInStore(nodeId, {
482
+ params: {
483
+ ...currentParams,
484
+ addedTools: currentTools.filter((t) => t.instanceId !== instanceId),
485
+ },
486
+ });
487
+ },
488
+ [nodeId, storeNodes, updateNodeDataInStore],
489
+ );
490
+
491
+ const handleUpdateTool = useCallback(
492
+ (instanceId: string, updates: Partial<Omit<AddedToolInstance, 'instanceId' | 'toolId'>>) => {
493
+ if (!nodeId) {
494
+ return;
495
+ }
496
+ const currentNode = storeNodes.find((n) => n.id === nodeId);
497
+ const currentParams = (currentNode?.data as ReactFlowNodeData | undefined)?.params ?? {};
498
+ const currentTools =
499
+ ((currentParams as Record<string, unknown>).addedTools as AddedToolInstance[]) ?? [];
500
+ updateNodeDataInStore(nodeId, {
501
+ params: {
502
+ ...currentParams,
503
+ addedTools: currentTools.map((t) =>
504
+ t.instanceId === instanceId ? { ...t, ...updates } : t,
505
+ ),
506
+ },
507
+ });
508
+ },
509
+ [nodeId, storeNodes, updateNodeDataInStore],
510
+ );
511
+
512
+ const agentToolsProps = useMemo(() => {
513
+ if (nodeType !== GraphNodeType.AGENT) {
514
+ return undefined;
515
+ }
516
+ return {
517
+ availableTools,
518
+ addedTools,
519
+ onAddTool: handleAddTool,
520
+ onRemoveTool: handleRemoveTool,
521
+ onUpdateTool: handleUpdateTool,
522
+ initialToolInstanceId: initialToolInstanceId ?? null,
523
+ };
524
+ }, [
525
+ nodeType,
526
+ availableTools,
527
+ addedTools,
528
+ handleAddTool,
529
+ handleRemoveTool,
530
+ handleUpdateTool,
531
+ initialToolInstanceId,
532
+ ]);
533
+
534
+ return (
535
+ <>
536
+ <Dialog open={open} onOpenChange={onOpenChange}>
537
+ <DialogContent
538
+ container={portalContainer}
539
+ showCloseButton={false}
540
+ className={cn(
541
+ 'h-[90vh] max-h-[90vh] overflow-hidden flex flex-col p-0 bg-card border-border',
542
+ 'sm:max-w-[95vw] w-[95vw]',
543
+ )}
544
+ >
545
+ <DialogTitle className="sr-only">Configure {displayName} node</DialogTitle>
546
+ <DialogDescription className="sr-only">
547
+ Review node inputs, mapper settings, configuration, and output preview for the
548
+ {` ${displayName} `}
549
+ node.
550
+ </DialogDescription>
551
+ {node ? (
552
+ <>
553
+ <ResizablePanelGroup direction="horizontal" className="flex-1 min-h-0 gap-0">
554
+ <InputPanel
555
+ value={
556
+ upstream.slots.length > 0
557
+ ? upstream.inputPreviewJson
558
+ : previewState.inputPreview
559
+ }
560
+ onChange={previewState.handleInputPreviewChange}
561
+ error={previewState.inputError}
562
+ isTestMode={previewState.isTestMode}
563
+ onReset={previewState.handleResetTestMode}
564
+ upstreamSlots={upstream.slots}
565
+ onRunSlot={upstream.runSlot}
566
+ onRunAll={upstream.runAllUnresolved}
567
+ unresolvedCount={upstream.unresolvedCount}
568
+ isAnyLoading={upstream.isAnyLoading}
569
+ mapperValue={mapperConfig}
570
+ onMapperChange={handleMapperChange}
571
+ mapperAvailableVariables={upstream.upstreamVariables}
572
+ onTestMapper={handleTestMapper}
573
+ mapperPreviewResult={testMapperMutation.data ?? null}
574
+ isTestingMapper={testMapperMutation.isPending}
575
+ mapperInputData={parsedInputData}
576
+ portalContainer={portalContainer}
577
+ />
578
+
579
+ <ResizableHandle withHandle />
580
+
581
+ <ConfigurationPanel
582
+ definition={activeDefinition}
583
+ formValues={formValues}
584
+ onFieldChange={handleFieldChange}
585
+ credentials={credentials}
586
+ credentialsLoading={credentialsLoading}
587
+ credentialsError={credentialsError}
588
+ onRefreshCredentials={() => refetchCredentials()}
589
+ onAddNewCredential={handleAddNewCredential}
590
+ onEditCredential={handleEditCredential}
591
+ onRefreshOAuthCredential={handleRefreshOAuthCredential}
592
+ refreshingCredentialId={refreshingCredentialId}
593
+ configWarnings={configWarnings}
594
+ configErrors={configErrors}
595
+ runError={execution.runError}
596
+ fieldErrors={execution.fieldErrors ?? undefined}
597
+ nodeType={nodeType}
598
+ modelStatusMessage={modelStatusMessage}
599
+ portalContainer={portalContainer}
600
+ upstreamVariables={upstream.upstreamVariables}
601
+ inputData={parsedInputData}
602
+ headerLabel={displayName}
603
+ onHeaderLabelChange={handleLabelChange}
604
+ headerNodeTypeLabel={nodeTypeLabel}
605
+ HeaderIcon={Icon}
606
+ headerCategoryColor={categoryColor}
607
+ onRunNode={execution.runNode}
608
+ isRunning={execution.isRunning}
609
+ agentTools={agentToolsProps}
610
+ />
611
+
612
+ <ResizableHandle withHandle />
613
+
614
+ <OutputPanel
615
+ value={previewState.outputPreview}
616
+ onChange={previewState.handleOutputPreviewChange}
617
+ error={execution.outputError}
618
+ />
619
+ </ResizablePanelGroup>
620
+ </>
621
+ ) : (
622
+ <div className="text-sm text-muted-foreground">Select a node to configure.</div>
623
+ )}
624
+ <DialogClose className="absolute bottom-4 right-4 z-50 flex items-center gap-1.5 rounded-full bg-foreground/10 hover:bg-foreground/15 backdrop-blur-sm px-3 py-1.5 text-xs font-medium text-foreground/70 hover:text-foreground transition-colors shadow-md">
625
+ <X className="w-3.5 h-3.5" />
626
+ Close
627
+ </DialogClose>
628
+ </DialogContent>
629
+ </Dialog>
630
+
631
+ <CreateCredentialModal
632
+ open={isCreateCredentialOpen}
633
+ onClose={handleCloseCredentialModal}
634
+ onSubmit={handleCreateCredential}
635
+ isLoading={createCredentialMutation.isPending}
636
+ portalContainer={portalContainer}
637
+ />
638
+
639
+ {editingCredential && (
640
+ <EditCredentialModal
641
+ credential={editingCredential}
642
+ open={true}
643
+ onClose={handleCloseEditCredential}
644
+ onSubmit={handleUpdateCredential}
645
+ isLoading={updateCredentialMutation.isPending}
646
+ />
647
+ )}
648
+ </>
649
+ );
650
+ }