@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,567 @@
1
+ 'use client';
2
+
3
+ import { useState } from 'react';
4
+ import {
5
+ ChevronUp,
6
+ ChevronDown,
7
+ ChevronRight,
8
+ Terminal,
9
+ Clock,
10
+ CheckCircle2,
11
+ XCircle,
12
+ AlertCircle,
13
+ RefreshCw,
14
+ Bot,
15
+ Wrench,
16
+ } from 'lucide-react';
17
+ import { ScrollArea } from '../ui/scroll-area';
18
+ import { Badge } from '../ui/badge';
19
+ import { cn } from '~/lib/utils';
20
+ import {
21
+ ExecutionLogNode,
22
+ ExecutionLogAttempt,
23
+ ExecutionLogToolCall,
24
+ SelectedExecutionAttempt,
25
+ } from './use-execution-log-data';
26
+ import { NodeExecutionStatus, GraphNodeType } from '@invect/core/types';
27
+ import { CodeMirrorJsonEditor } from '../ui/codemirror-json-editor';
28
+ import { RunSelector, RunSelectorItem } from './RunSelector';
29
+
30
+ interface LogsPanelProps {
31
+ nodes: ExecutionLogNode[];
32
+ selectedAttempt: SelectedExecutionAttempt | null;
33
+ onSelectAttempt: (next: SelectedExecutionAttempt) => void;
34
+ isExpanded: boolean;
35
+ onToggle: () => void;
36
+ loading?: boolean;
37
+ /** Runs list for the run selector dropdown */
38
+ runs?: RunSelectorItem[];
39
+ /** Currently selected run ID */
40
+ selectedRunId?: string | null;
41
+ /** Callback when a run is selected from the dropdown */
42
+ onSelectRun?: (runId: string) => void;
43
+ }
44
+
45
+ function StatusIcon({ status, size = 14 }: { status: NodeExecutionStatus; size?: number }) {
46
+ switch (status) {
47
+ case NodeExecutionStatus.SUCCESS:
48
+ return <CheckCircle2 className="flex-shrink-0 text-green-500" size={size} />;
49
+ case NodeExecutionStatus.FAILED:
50
+ return <XCircle className="flex-shrink-0 text-red-500" size={size} />;
51
+ case NodeExecutionStatus.RUNNING:
52
+ return (
53
+ <div className="flex items-center justify-center" style={{ width: size, height: size }}>
54
+ <div
55
+ className="border-2 border-blue-500 rounded-full border-t-transparent animate-spin"
56
+ style={{ width: size, height: size }}
57
+ />
58
+ </div>
59
+ );
60
+ case NodeExecutionStatus.PENDING:
61
+ return <Clock className="flex-shrink-0 text-muted-foreground" size={size} />;
62
+ case NodeExecutionStatus.SKIPPED:
63
+ return <AlertCircle className="flex-shrink-0 text-yellow-500" size={size} />;
64
+ case NodeExecutionStatus.BATCH_SUBMITTED:
65
+ return <RefreshCw className="flex-shrink-0 text-amber-500" size={size} />;
66
+ default:
67
+ return <Clock className="flex-shrink-0 text-muted-foreground" size={size} />;
68
+ }
69
+ }
70
+
71
+ function ToolStatusIcon({ success, size = 12 }: { success: boolean; size?: number }) {
72
+ if (success) {
73
+ return <CheckCircle2 className="flex-shrink-0 text-green-500" size={size} />;
74
+ }
75
+ return <XCircle className="flex-shrink-0 text-red-500" size={size} />;
76
+ }
77
+
78
+ const formatTimestamp = (value?: string) => {
79
+ if (!value) {
80
+ return '—';
81
+ }
82
+ try {
83
+ return new Date(value).toLocaleString();
84
+ } catch {
85
+ return value;
86
+ }
87
+ };
88
+
89
+ const formatDuration = (value?: number) => {
90
+ if (value === undefined) {
91
+ return '—';
92
+ }
93
+ if (value < 1000) {
94
+ return `${value} ms`;
95
+ }
96
+ const seconds = value / 1000;
97
+ if (seconds < 60) {
98
+ return `${seconds.toFixed(1)} s`;
99
+ }
100
+ const minutes = Math.floor(seconds / 60);
101
+ const secs = Math.round(seconds % 60);
102
+ return `${minutes}m ${secs}s`;
103
+ };
104
+
105
+ const hasData = (value?: Record<string, unknown>) => value && Object.keys(value).length > 0;
106
+
107
+ export function LogsPanel({
108
+ nodes,
109
+ selectedAttempt,
110
+ onSelectAttempt,
111
+ isExpanded,
112
+ onToggle,
113
+ loading,
114
+ runs,
115
+ selectedRunId,
116
+ onSelectRun,
117
+ }: LogsPanelProps) {
118
+ const selectedNode = nodes.find((node) => node.nodeId === selectedAttempt?.nodeId) ?? nodes[0];
119
+ const selectedAttemptData =
120
+ selectedNode?.attempts.find((attempt) => attempt.id === selectedAttempt?.attemptId) ??
121
+ selectedNode?.attempts[selectedNode?.attempts.length - 1];
122
+
123
+ // Find selected tool call if any
124
+ const selectedToolCall = selectedAttempt?.toolCallId
125
+ ? selectedAttemptData?.toolCalls?.find((t) => t.id === selectedAttempt.toolCallId)
126
+ : null;
127
+
128
+ const handleSelectNode = (nodeId: string, attemptId: string) => {
129
+ onSelectAttempt({ nodeId, attemptId, toolCallId: undefined });
130
+ };
131
+
132
+ const handleSelectTool = (nodeId: string, attemptId: string, toolCallId: string) => {
133
+ onSelectAttempt({ nodeId, attemptId, toolCallId });
134
+ };
135
+
136
+ return (
137
+ <div
138
+ className={cn(
139
+ 'border-t border-border bg-imp-background text-card-foreground flex flex-col',
140
+ isExpanded ? 'h-full' : 'h-8',
141
+ )}
142
+ >
143
+ <button
144
+ onClick={onToggle}
145
+ className="flex items-center justify-between w-full px-4 py-1 transition-colors cursor-pointer hover:bg-accent/50 shrink-0"
146
+ >
147
+ <div className="flex items-center gap-2">
148
+ <Terminal className="w-4 h-4 text-muted-foreground" />
149
+ <span className="text-sm font-medium">Execution Logs</span>
150
+ <Badge variant="secondary" className="text-xs">
151
+ {loading ? 'Loading…' : `${nodes.length} nodes`}
152
+ </Badge>
153
+ </div>
154
+ {isExpanded ? (
155
+ <ChevronDown className="w-4 h-4 text-muted-foreground" />
156
+ ) : (
157
+ <ChevronUp className="w-4 h-4 text-muted-foreground" />
158
+ )}
159
+ </button>
160
+
161
+ {isExpanded && (
162
+ <div className="flex flex-1 min-h-0 border-t border-border">
163
+ <div className="imp-page border-r border-imp-border bg-imp-background text-imp-foreground w-[280px] shrink-0 flex flex-col">
164
+ {runs && onSelectRun && (
165
+ <div className="px-2 pt-2 pb-1 shrink-0">
166
+ <RunSelector
167
+ runs={runs}
168
+ selectedRunId={selectedRunId ?? null}
169
+ onSelectRun={onSelectRun}
170
+ />
171
+ </div>
172
+ )}
173
+ <ScrollArea className="h-full min-h-0">
174
+ <div className="p-2 space-y-2">
175
+ {loading && nodes.length === 0 && (
176
+ <div className="px-3 py-2 text-sm text-muted-foreground">
177
+ Loading node executions…
178
+ </div>
179
+ )}
180
+ {!loading && nodes.length === 0 && (
181
+ <div className="px-3 py-2 text-sm text-muted-foreground">
182
+ No nodes available for this flow.
183
+ </div>
184
+ )}
185
+ {nodes.map((node) => {
186
+ const latestAttempt = node.attempts[node.attempts.length - 1];
187
+ const nodeSelected =
188
+ selectedAttempt?.nodeId === node.nodeId && !selectedAttempt?.toolCallId;
189
+ const isAgentNode =
190
+ node.nodeType === GraphNodeType.AGENT || node.nodeType === 'AGENT';
191
+ const toolCalls = latestAttempt.toolCalls ?? [];
192
+ return (
193
+ <div
194
+ key={node.nodeId}
195
+ className="border rounded-lg border-border/60 bg-card/40"
196
+ >
197
+ <button
198
+ className={cn(
199
+ 'flex w-full items-center gap-2 px-3 py-2 text-left transition-colors',
200
+ nodeSelected ? 'bg-accent text-accent-foreground' : 'hover:bg-accent/40',
201
+ )}
202
+ onClick={() => handleSelectNode(node.nodeId, latestAttempt.id)}
203
+ >
204
+ <StatusIcon status={latestAttempt.status} />
205
+ <div className="flex-1 min-w-0">
206
+ <div className="text-xs font-medium truncate flex items-center gap-1.5">
207
+ {isAgentNode && (
208
+ <Bot className="h-3 w-3 text-muted-foreground flex-shrink-0" />
209
+ )}
210
+ {node.nodeName}
211
+ </div>
212
+ <div className="text-xs truncate text-muted-foreground">
213
+ {latestAttempt.label}
214
+ </div>
215
+ </div>
216
+ <span className="text-xs text-muted-foreground">
217
+ {formatDuration(latestAttempt.durationMs)}
218
+ </span>
219
+ </button>
220
+
221
+ {/* Nested tool calls for agent nodes */}
222
+ {isAgentNode && toolCalls.length > 0 && (
223
+ <div className="border-t border-border/60 bg-muted/20">
224
+ {toolCalls.map((tool) => {
225
+ const toolSelected =
226
+ selectedAttempt?.nodeId === node.nodeId &&
227
+ selectedAttempt?.toolCallId === tool.id;
228
+ return (
229
+ <button
230
+ key={tool.id}
231
+ onClick={() =>
232
+ handleSelectTool(node.nodeId, latestAttempt.id, tool.id)
233
+ }
234
+ className={cn(
235
+ 'flex w-full items-center gap-2 pl-6 pr-3 py-1.5 text-left text-xs transition-colors',
236
+ toolSelected
237
+ ? 'bg-accent/60 text-accent-foreground'
238
+ : 'hover:bg-accent/30',
239
+ )}
240
+ >
241
+ <Wrench className="h-3 w-3 text-muted-foreground flex-shrink-0" />
242
+ <ToolStatusIcon success={tool.success} size={10} />
243
+ <span className="flex-1 truncate">{tool.toolName}</span>
244
+ <span className="text-muted-foreground">
245
+ {formatDuration(tool.executionTimeMs)}
246
+ </span>
247
+ </button>
248
+ );
249
+ })}
250
+ </div>
251
+ )}
252
+
253
+ {/* Multiple attempts (retries) */}
254
+ {node.attempts.length > 1 && (
255
+ <div className="border-t border-border/60">
256
+ {node.attempts.map((attempt) => {
257
+ const attemptSelected =
258
+ selectedAttempt?.nodeId === node.nodeId &&
259
+ selectedAttempt?.attemptId === attempt.id &&
260
+ !selectedAttempt?.toolCallId;
261
+ return (
262
+ <button
263
+ key={attempt.id}
264
+ onClick={() => handleSelectNode(node.nodeId, attempt.id)}
265
+ className={cn(
266
+ 'flex w-full items-center gap-2 px-4 py-2 text-left text-xs transition-colors',
267
+ attemptSelected
268
+ ? 'bg-accent/60 text-accent-foreground'
269
+ : 'hover:bg-accent/30',
270
+ )}
271
+ >
272
+ <StatusIcon status={attempt.status} size={12} />
273
+ <span className="flex-1 truncate">{attempt.label}</span>
274
+ <span className="text-muted-foreground">
275
+ {formatDuration(attempt.durationMs)}
276
+ </span>
277
+ </button>
278
+ );
279
+ })}
280
+ </div>
281
+ )}
282
+ </div>
283
+ );
284
+ })}
285
+ </div>
286
+ </ScrollArea>
287
+ </div>
288
+
289
+ <div className="flex-1 min-w-0 overflow-hidden bg-imp-background text-imp-foreground">
290
+ <ScrollArea className="h-full">
291
+ {/* Tool Call Detail View */}
292
+ {selectedToolCall ? (
293
+ <ToolCallDetailView tool={selectedToolCall} />
294
+ ) : selectedAttemptData ? (
295
+ <NodeAttemptDetailView
296
+ nodeName={selectedNode?.nodeName ?? ''}
297
+ attempt={selectedAttemptData}
298
+ />
299
+ ) : (
300
+ <div className="flex items-center justify-center h-full text-sm text-muted-foreground">
301
+ {loading
302
+ ? 'Waiting for node executions…'
303
+ : 'Select a node attempt to view details.'}
304
+ </div>
305
+ )}
306
+ </ScrollArea>
307
+ </div>
308
+ </div>
309
+ )}
310
+ </div>
311
+ );
312
+ }
313
+
314
+ /**
315
+ * Detail view for a selected tool call
316
+ */
317
+ function ToolCallDetailView({ tool }: { tool: ExecutionLogToolCall }) {
318
+ const [inputOpen, setInputOpen] = useState(true);
319
+ const [outputOpen, setOutputOpen] = useState(true);
320
+
321
+ return (
322
+ <div className="max-w-full">
323
+ <div className="sticky top-0 z-10 bg-imp-background px-4 py-2 border-b border-border">
324
+ <div className="flex items-center justify-between gap-4">
325
+ <div className="flex items-center gap-2">
326
+ <Wrench className="h-4 w-4 text-muted-foreground" />
327
+ <span className="text-sm font-semibold flex items-center gap-2">
328
+ {tool.toolName}
329
+ <ToolStatusIcon success={tool.success} size={14} />
330
+ </span>
331
+ <span className="text-xs text-muted-foreground">Iteration {tool.iteration}</span>
332
+ </div>
333
+ <div className="flex items-center gap-3 text-xs text-muted-foreground">
334
+ <span>
335
+ <span className="text-foreground/70">Duration</span>{' '}
336
+ {formatDuration(tool.executionTimeMs)}
337
+ </span>
338
+ </div>
339
+ </div>
340
+ </div>
341
+
342
+ <div className="p-4 space-y-4">
343
+ {/* Input */}
344
+ <div className="max-w-full overflow-hidden">
345
+ <button
346
+ type="button"
347
+ onClick={() => setInputOpen(!inputOpen)}
348
+ className="flex items-center gap-1.5 mb-2 text-sm font-semibold text-foreground cursor-pointer hover:text-foreground/80 transition-colors"
349
+ >
350
+ {inputOpen ? (
351
+ <ChevronDown className="size-3.5" />
352
+ ) : (
353
+ <ChevronRight className="size-3.5" />
354
+ )}
355
+ Input
356
+ </button>
357
+ {inputOpen && (
358
+ <div className="max-w-full overflow-hidden border rounded-md border-border">
359
+ <CodeMirrorJsonEditor
360
+ value={JSON.stringify(tool.input, null, 2)}
361
+ readOnly
362
+ disableLinting
363
+ minHeight="60px"
364
+ className="max-w-full"
365
+ />
366
+ </div>
367
+ )}
368
+ </div>
369
+
370
+ {/* Output */}
371
+ {tool.output !== undefined && (
372
+ <div className="max-w-full overflow-hidden">
373
+ <button
374
+ type="button"
375
+ onClick={() => setOutputOpen(!outputOpen)}
376
+ className="flex items-center gap-1.5 mb-2 text-sm font-semibold text-foreground cursor-pointer hover:text-foreground/80 transition-colors"
377
+ >
378
+ {outputOpen ? (
379
+ <ChevronDown className="size-3.5" />
380
+ ) : (
381
+ <ChevronRight className="size-3.5" />
382
+ )}
383
+ Output
384
+ </button>
385
+ {outputOpen && (
386
+ <div className="max-w-full overflow-hidden border rounded-md border-border">
387
+ <CodeMirrorJsonEditor
388
+ value={JSON.stringify(tool.output, null, 2)}
389
+ readOnly
390
+ disableLinting
391
+ minHeight="60px"
392
+ className="max-w-full"
393
+ />
394
+ </div>
395
+ )}
396
+ </div>
397
+ )}
398
+
399
+ {/* Error */}
400
+ {tool.error && (
401
+ <div>
402
+ <div className="mb-2 text-sm font-semibold text-red-500">Error</div>
403
+ <pre className="p-3 text-sm font-mono text-red-500 border rounded-md bg-red-500/10 border-red-500/20 whitespace-pre-wrap break-words max-h-60 overflow-auto">
404
+ {tool.error}
405
+ </pre>
406
+ </div>
407
+ )}
408
+ </div>
409
+ </div>
410
+ );
411
+ }
412
+
413
+ /**
414
+ * Detail view for a selected node attempt
415
+ */
416
+ function NodeAttemptDetailView({
417
+ nodeName,
418
+ attempt,
419
+ }: {
420
+ nodeName: string;
421
+ attempt: ExecutionLogAttempt;
422
+ }) {
423
+ const [inputsOpen, setInputsOpen] = useState(true);
424
+ const [outputsOpen, setOutputsOpen] = useState(true);
425
+
426
+ return (
427
+ <div className="max-w-full">
428
+ <div className="sticky top-0 z-10 bg-imp-background px-4 py-2 border-b border-border">
429
+ <div className="flex items-center justify-between gap-4">
430
+ <div className="flex items-center gap-2">
431
+ <StatusIcon status={attempt.status} size={16} />
432
+ <span className="text-sm font-semibold">{nodeName}</span>
433
+ </div>
434
+ <div className="flex items-center gap-3 text-xs text-muted-foreground">
435
+ <span>
436
+ <span className="text-foreground/70">Started</span>{' '}
437
+ {formatTimestamp(attempt.startedAt)}
438
+ </span>
439
+ <span>
440
+ <span className="text-foreground/70">Duration</span>{' '}
441
+ {formatDuration(attempt.durationMs)}
442
+ </span>
443
+ </div>
444
+ </div>
445
+ </div>
446
+
447
+ <div className="p-4 space-y-4">
448
+ {/* Agent Summary */}
449
+ {attempt.agentMetadata && (
450
+ <div className="p-3 rounded-lg bg-muted/50 border border-border/60">
451
+ <div className="flex items-center gap-2 mb-2">
452
+ <Bot className="h-4 w-4 text-muted-foreground" />
453
+ <span className="text-xs font-medium text-foreground">Agent Summary</span>
454
+ </div>
455
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-3 text-xs">
456
+ <div>
457
+ <span className="text-muted-foreground">Model:</span>{' '}
458
+ <span className="text-foreground font-medium">
459
+ {attempt.agentMetadata.model ?? 'Unknown'}
460
+ </span>
461
+ </div>
462
+ <div>
463
+ <span className="text-muted-foreground">Iterations:</span>{' '}
464
+ <span className="text-foreground font-medium">
465
+ {attempt.agentMetadata.iterations}
466
+ </span>
467
+ </div>
468
+ <div>
469
+ <span className="text-muted-foreground">Tools Used:</span>{' '}
470
+ <span className="text-foreground font-medium">
471
+ {attempt.toolCalls?.length ?? 0}
472
+ </span>
473
+ </div>
474
+ {attempt.agentMetadata.tokenUsage && (
475
+ <div>
476
+ <span className="text-muted-foreground">Tokens:</span>{' '}
477
+ <span className="text-foreground font-medium">
478
+ ~{attempt.agentMetadata.tokenUsage.conversationTokensEstimate.toLocaleString()}
479
+ </span>
480
+ </div>
481
+ )}
482
+ </div>
483
+ {attempt.agentMetadata.finalResponse && (
484
+ <div className="mt-3 pt-3 border-t border-border/60">
485
+ <div className="text-xs font-medium text-muted-foreground mb-1">Final Response</div>
486
+ <div className="text-sm text-foreground whitespace-pre-wrap">
487
+ {attempt.agentMetadata.finalResponse}
488
+ </div>
489
+ </div>
490
+ )}
491
+ </div>
492
+ )}
493
+
494
+ {hasData(attempt.inputs) && (
495
+ <div className="max-w-full overflow-hidden">
496
+ <button
497
+ type="button"
498
+ onClick={() => setInputsOpen(!inputsOpen)}
499
+ className="flex items-center gap-1.5 mb-2 text-sm font-semibold text-foreground cursor-pointer hover:text-foreground/80 transition-colors"
500
+ >
501
+ {inputsOpen ? (
502
+ <ChevronDown className="size-3.5" />
503
+ ) : (
504
+ <ChevronRight className="size-3.5" />
505
+ )}
506
+ {attempt.isLoopIteration ? 'Iteration Input' : 'Inputs'}
507
+ </button>
508
+ {inputsOpen && (
509
+ <div className="max-w-full overflow-hidden border rounded-md border-border">
510
+ <CodeMirrorJsonEditor
511
+ value={JSON.stringify(
512
+ attempt.isLoopIteration && attempt.iterationItem
513
+ ? attempt.iterationItem.value
514
+ : attempt.inputs,
515
+ null,
516
+ 2,
517
+ )}
518
+ readOnly
519
+ disableLinting
520
+ minHeight="60px"
521
+ className="max-w-full"
522
+ />
523
+ </div>
524
+ )}
525
+ </div>
526
+ )}
527
+
528
+ {attempt.outputs && (
529
+ <div className="max-w-full overflow-hidden">
530
+ <button
531
+ type="button"
532
+ onClick={() => setOutputsOpen(!outputsOpen)}
533
+ className="flex items-center gap-1.5 mb-2 text-sm font-semibold text-foreground cursor-pointer hover:text-foreground/80 transition-colors"
534
+ >
535
+ {outputsOpen ? (
536
+ <ChevronDown className="size-3.5" />
537
+ ) : (
538
+ <ChevronRight className="size-3.5" />
539
+ )}
540
+ Outputs
541
+ </button>
542
+ {outputsOpen && (
543
+ <div className="max-w-full overflow-hidden border rounded-md border-border">
544
+ <CodeMirrorJsonEditor
545
+ value={JSON.stringify(attempt.outputs, null, 2)}
546
+ readOnly
547
+ disableLinting
548
+ minHeight="60px"
549
+ className="max-w-full"
550
+ />
551
+ </div>
552
+ )}
553
+ </div>
554
+ )}
555
+
556
+ {attempt.error && (
557
+ <div>
558
+ <div className="mb-2 text-sm font-semibold text-red-500">Error</div>
559
+ <pre className="p-3 text-sm font-mono text-red-500 border rounded-md bg-red-500/10 border-red-500/20 whitespace-pre-wrap break-words max-h-60 overflow-auto">
560
+ {attempt.error}
561
+ </pre>
562
+ </div>
563
+ )}
564
+ </div>
565
+ </div>
566
+ );
567
+ }