@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.
- package/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/Invect-CWpIwZ5F.js +92738 -0
- package/dist/Invect.d.ts +25 -0
- package/dist/InvectShell.d.ts +14 -0
- package/dist/api/agent-tools.api.d.ts +1 -0
- package/dist/api/client.d.ts +207 -0
- package/dist/api/credentials.api.d.ts +47 -0
- package/dist/api/executions.api.d.ts +43 -0
- package/dist/api/flows.api.d.ts +100 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/node-data.api.d.ts +66 -0
- package/dist/api/query-keys.d.ts +22 -0
- package/dist/api/triggers.api.d.ts +44 -0
- package/dist/api/types.d.ts +147 -0
- package/dist/api/use-flow-run-stream.d.ts +12 -0
- package/dist/assets/invect-branding.d.ts +4 -0
- package/dist/assets/provider-icons/index.d.ts +8 -0
- package/dist/babel-C9OtljFZ.js +9721 -0
- package/dist/components/PageLayout.d.ts +17 -0
- package/dist/components/chat/ChatInput.d.ts +17 -0
- package/dist/components/chat/ChatMessageList.d.ts +14 -0
- package/dist/components/chat/ChatModelSelector.d.ts +11 -0
- package/dist/components/chat/ChatPanel.d.ts +19 -0
- package/dist/components/chat/ChatPromptOverlay.d.ts +13 -0
- package/dist/components/chat/ChatProviderSelector.d.ts +9 -0
- package/dist/components/chat/ChatSettingsPanel.d.ts +11 -0
- package/dist/components/chat/InlineCredentialSetup.d.ts +9 -0
- package/dist/components/chat/MarkdownRenderer.d.ts +7 -0
- package/dist/components/chat/chat-memory.d.ts +21 -0
- package/dist/components/chat/chat.store.d.ts +416 -0
- package/dist/components/chat/index.d.ts +5 -0
- package/dist/components/chat/use-chat.d.ts +28 -0
- package/dist/components/credentials/CreateCredentialModal.d.ts +13 -0
- package/dist/components/credentials/CredentialDetailDialog.d.ts +17 -0
- package/dist/components/credentials/EditCredentialModal.d.ts +11 -0
- package/dist/components/credentials/OAuth2ConnectButton.d.ts +38 -0
- package/dist/components/credentials/OAuth2ProviderSelector.d.ts +15 -0
- package/dist/components/credentials/credential-utils.d.ts +12 -0
- package/dist/components/credentials/index.d.ts +9 -0
- package/dist/components/dashboard/FailedRunsAlert.d.ts +3 -0
- package/dist/components/dashboard/FlowCard.d.ts +7 -0
- package/dist/components/dashboard/RecentActivityTable.d.ts +9 -0
- package/dist/components/dashboard/StatCard.d.ts +10 -0
- package/dist/components/dashboard/index.d.ts +5 -0
- package/dist/components/dashboard/status-helpers.d.ts +5 -0
- package/dist/components/flow-editor/ActionsSidebar.d.ts +2 -0
- package/dist/components/flow-editor/FlowEditor.d.ts +21 -0
- package/dist/components/flow-editor/FlowHeader.d.ts +9 -0
- package/dist/components/flow-editor/FlowLayout.d.ts +24 -0
- package/dist/components/flow-editor/ModeSwitcher.d.ts +7 -0
- package/dist/components/flow-editor/NodeSidebar.d.ts +24 -0
- package/dist/components/flow-editor/RunControls.d.ts +12 -0
- package/dist/components/flow-editor/ToolConfigPanel.d.ts +16 -0
- package/dist/components/flow-editor/ValidationPanel.d.ts +5 -0
- package/dist/components/flow-editor/flow-editor.store.d.ts +1 -0
- package/dist/components/flow-editor/index.d.ts +6 -0
- package/dist/components/flow-editor/inline-edit.d.ts +10 -0
- package/dist/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.d.ts +26 -0
- package/dist/components/flow-editor/node-config-panel/CredentialCombobox.d.ts +21 -0
- package/dist/components/flow-editor/node-config-panel/CredentialsSection.d.ts +19 -0
- package/dist/components/flow-editor/node-config-panel/DroppableInput.d.ts +20 -0
- package/dist/components/flow-editor/node-config-panel/DynamicSelectField.d.ts +22 -0
- package/dist/components/flow-editor/node-config-panel/JsonPreviewPanel.d.ts +25 -0
- package/dist/components/flow-editor/node-config-panel/NodeConfigPanel.d.ts +14 -0
- package/dist/components/flow-editor/node-config-panel/NodeConfigPanelHeader.d.ts +15 -0
- package/dist/components/flow-editor/node-config-panel/ParametersSection.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/SearchableSelectField.d.ts +17 -0
- package/dist/components/flow-editor/node-config-panel/SwitchCasesField.d.ts +18 -0
- package/dist/components/flow-editor/node-config-panel/hooks/index.d.ts +2 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.d.ts +24 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-node-execution.d.ts +46 -0
- package/dist/components/flow-editor/node-config-panel/hooks/use-upstream-slots.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/panels/AgentToolsPanel.d.ts +18 -0
- package/dist/components/flow-editor/node-config-panel/panels/ConfigurationPanel.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/panels/DataMapperPane.d.ts +40 -0
- package/dist/components/flow-editor/node-config-panel/panels/InputPanel.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/panels/OutputPanel.d.ts +7 -0
- package/dist/components/flow-editor/node-config-panel/panels/index.d.ts +4 -0
- package/dist/components/flow-editor/node-config-panel/types.d.ts +19 -0
- package/dist/components/flow-editor/node-config-panel/use-node-config-panel-store.d.ts +49 -0
- package/dist/components/flow-editor/node-config-panel/use-node-config-state.d.ts +26 -0
- package/dist/components/flow-editor/node-config-panel/use-run-node.d.ts +16 -0
- package/dist/components/flow-editor/node-config-panel/utils.d.ts +9 -0
- package/dist/components/flow-editor/serialize-to-sdk.d.ts +20 -0
- package/dist/components/flow-editor/toolbar-context.d.ts +2 -0
- package/dist/components/flow-editor/use-copy-paste.d.ts +7 -0
- package/dist/components/flow-editor/use-copy-paste.types.d.ts +38 -0
- package/dist/components/flow-editor/use-flow-editor.d.ts +44 -0
- package/dist/components/flow-runs-table/FlowRunsTable.d.ts +6 -0
- package/dist/components/flow-runs-table/index.d.ts +1 -0
- package/dist/components/flow-viewer/FlowRunsView.d.ts +7 -0
- package/dist/components/flow-viewer/FlowStatusView.d.ts +21 -0
- package/dist/components/flow-viewer/RunSelector.d.ts +13 -0
- package/dist/components/flow-viewer/RunsSidebar.d.ts +14 -0
- package/dist/components/flow-viewer/agent-tool-executions-list.d.ts +7 -0
- package/dist/components/flow-viewer/index.d.ts +1 -0
- package/dist/components/flow-viewer/logs-panel.d.ts +18 -0
- package/dist/components/flow-viewer/use-execution-log-data.d.ts +113 -0
- package/dist/components/graph/BatchFlowEdge.d.ts +33 -0
- package/dist/components/graph/LayoutSelector.d.ts +9 -0
- package/dist/components/graph/index.d.ts +47 -0
- package/dist/components/graph/styleUtils.d.ts +124 -0
- package/dist/components/nodes/AgentConfigPanel.d.ts +24 -0
- package/dist/components/nodes/AgentNode.d.ts +8 -0
- package/dist/components/nodes/AgentToolsBox.d.ts +41 -0
- package/dist/components/nodes/NodeAppendix.d.ts +19 -0
- package/dist/components/nodes/NodeStatusIndicator.d.ts +30 -0
- package/dist/components/nodes/NodeViewContext.d.ts +18 -0
- package/dist/components/nodes/ToolParamField.d.ts +28 -0
- package/dist/components/nodes/ToolSelectorModal.d.ts +80 -0
- package/dist/components/nodes/ToolSelectorParts.d.ts +30 -0
- package/dist/components/nodes/UniversalNode.d.ts +2 -0
- package/dist/components/nodes/createContextAwareNodes.d.ts +6 -0
- package/dist/components/nodes/index.d.ts +22 -0
- package/dist/components/nodes/nodeRegistry.d.ts +13 -0
- package/dist/components/nodes/withNodeContext.d.ts +7 -0
- package/dist/components/shared/InvectLoader.d.ts +8 -0
- package/dist/components/shared/InvectLogo.d.ts +9 -0
- package/dist/components/shared/ProviderIcon.d.ts +23 -0
- package/dist/components/side-menu/side-menu.d.ts +4 -0
- package/dist/components/sidebar/BaseSidebar.d.ts +17 -0
- package/dist/components/sidebar/index.d.ts +1 -0
- package/dist/components/triggers/CronPreview.d.ts +12 -0
- package/dist/components/triggers/index.d.ts +1 -0
- package/dist/components/ui/alert-dialog.d.ts +18 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/button.d.ts +13 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/codemirror-js-editor.d.ts +25 -0
- package/dist/components/ui/codemirror-json-editor.d.ts +18 -0
- package/dist/components/ui/codemirror-nunjucks-editor.d.ts +13 -0
- package/dist/components/ui/codemirror-vscode-theme.d.ts +24 -0
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/command.d.ts +18 -0
- package/dist/components/ui/dialog.d.ts +18 -0
- package/dist/components/ui/dropdown-menu.d.ts +25 -0
- package/dist/components/ui/empty-state.d.ts +21 -0
- package/dist/components/ui/input.d.ts +3 -0
- package/dist/components/ui/label.d.ts +4 -0
- package/dist/components/ui/popover.d.ts +10 -0
- package/dist/components/ui/resizable.d.ts +8 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/select.d.ts +18 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/slider.d.ts +4 -0
- package/dist/components/ui/switch.d.ts +3 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/textarea.d.ts +3 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/ui/tree-view.d.ts +107 -0
- package/dist/contexts/AgentToolCallbacksContext.d.ts +23 -0
- package/dist/contexts/ApiContext.d.ts +11 -0
- package/dist/contexts/FlowDataContext.d.ts +9 -0
- package/dist/contexts/NodeRegistryContext.d.ts +14 -0
- package/dist/contexts/PluginRegistryContext.d.ts +39 -0
- package/dist/contexts/ThemeProvider.d.ts +18 -0
- package/dist/contexts/ValidationContext.d.ts +22 -0
- package/dist/demo/DemoInvect.d.ts +11 -0
- package/dist/demo/FlowViewer.d.ts +31 -0
- package/dist/demo/demo-api-client.d.ts +33 -0
- package/dist/demo/index.d.ts +6 -0
- package/dist/demo/sample-data.d.ts +1538 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.js +2774 -0
- package/dist/estree-ClbRfS-1.js +7076 -0
- package/dist/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/dist/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/iosevka-latin-400-normal.woff2 +0 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-document-title.d.ts +1 -0
- package/dist/hooks/use-flow-data.d.ts +22 -0
- package/dist/hooks/use-invect-portal-class.d.ts +21 -0
- package/dist/hooks/useFlowEditorStore.d.ts +1 -0
- package/dist/index.css +3 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +717 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/prettier.d.ts +13 -0
- package/dist/routes/all-flow-runs.d.ts +5 -0
- package/dist/routes/credentials.d.ts +5 -0
- package/dist/routes/flow-route-layout.d.ts +19 -0
- package/dist/routes/flow-runs.d.ts +5 -0
- package/dist/routes/flow.d.ts +5 -0
- package/dist/routes/home.d.ts +5 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/standalone-C3Df7W52.js +3463 -0
- package/dist/stores/executionViewStore.d.ts +64 -0
- package/dist/stores/flow-editor.store.d.ts +137 -0
- package/dist/stores/flowEditorStore.d.ts +1 -0
- package/dist/stores/index.d.ts +2 -0
- package/dist/stores/uiStore.d.ts +45 -0
- package/dist/types/agent-tools.types.d.ts +53 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/node-definition.types.d.ts +85 -0
- package/dist/types/plugin.types.d.ts +100 -0
- package/dist/utils/credentialBranding.d.ts +8 -0
- package/dist/utils/credentialFiltering.d.ts +20 -0
- package/dist/utils/flowTransformations.d.ts +16 -0
- package/dist/utils/layoutUtils.d.ts +23 -0
- package/dist/utils/nodeReferenceUtils.d.ts +37 -0
- package/dist/vendor.d.ts +5 -0
- package/package.json +130 -0
- package/src/.DS_Store +0 -0
- package/src/Invect.tsx +229 -0
- package/src/InvectShell.tsx +55 -0
- package/src/api/agent-tools.api.ts +23 -0
- package/src/api/client.ts +899 -0
- package/src/api/credentials.api.ts +197 -0
- package/src/api/executions.api.ts +228 -0
- package/src/api/flows.api.ts +195 -0
- package/src/api/index.ts +17 -0
- package/src/api/node-data.api.ts +167 -0
- package/src/api/query-keys.ts +44 -0
- package/src/api/triggers.api.ts +120 -0
- package/src/api/types.ts +212 -0
- package/src/api/use-flow-run-stream.ts +206 -0
- package/src/app.css +560 -0
- package/src/assets/.DS_Store +0 -0
- package/src/assets/favicon.ico +0 -0
- package/src/assets/fonts/geist-cyrillic-wght-normal.woff2 +0 -0
- package/src/assets/fonts/geist-latin-ext-wght-normal.woff2 +0 -0
- package/src/assets/fonts/geist-latin-wght-normal.woff2 +0 -0
- package/src/assets/fonts/iosevka-latin-400-normal.woff2 +0 -0
- package/src/assets/invect-branding.ts +51 -0
- package/src/assets/provider-icons/anthropic.svg +1 -0
- package/src/assets/provider-icons/anthropic_light.svg +1 -0
- package/src/assets/provider-icons/github.svg +1 -0
- package/src/assets/provider-icons/github_light.svg +1 -0
- package/src/assets/provider-icons/gmail.svg +1 -0
- package/src/assets/provider-icons/google_calendar.svg +1 -0
- package/src/assets/provider-icons/google_docs.svg +1 -0
- package/src/assets/provider-icons/google_drive.svg +1 -0
- package/src/assets/provider-icons/google_sheets.svg +1 -0
- package/src/assets/provider-icons/index.ts +55 -0
- package/src/assets/provider-icons/linear.svg +1 -0
- package/src/assets/provider-icons/openai.svg +1 -0
- package/src/assets/provider-icons/postgres.svg +1 -0
- package/src/assets/provider-icons/slack.svg +1 -0
- package/src/assets/small-loader-dark.svg +22 -0
- package/src/assets/small-loader-light.svg +22 -0
- package/src/assets/small.svg +7 -0
- package/src/components/.DS_Store +0 -0
- package/src/components/PageLayout.tsx +55 -0
- package/src/components/chat/ChatInput.tsx +115 -0
- package/src/components/chat/ChatMessageList.tsx +788 -0
- package/src/components/chat/ChatModelSelector.tsx +208 -0
- package/src/components/chat/ChatPanel.tsx +243 -0
- package/src/components/chat/ChatPromptOverlay.tsx +150 -0
- package/src/components/chat/ChatProviderSelector.tsx +135 -0
- package/src/components/chat/ChatSettingsPanel.tsx +277 -0
- package/src/components/chat/InlineCredentialSetup.tsx +343 -0
- package/src/components/chat/MarkdownRenderer.tsx +140 -0
- package/src/components/chat/chat-memory.ts +88 -0
- package/src/components/chat/chat.store.ts +479 -0
- package/src/components/chat/index.ts +5 -0
- package/src/components/chat/use-chat.ts +473 -0
- package/src/components/credentials/CreateCredentialModal.tsx +609 -0
- package/src/components/credentials/CredentialDetailDialog.tsx +882 -0
- package/src/components/credentials/EditCredentialModal.tsx +399 -0
- package/src/components/credentials/OAuth2ConnectButton.tsx +288 -0
- package/src/components/credentials/OAuth2ProviderSelector.tsx +360 -0
- package/src/components/credentials/credential-utils.ts +99 -0
- package/src/components/credentials/index.ts +10 -0
- package/src/components/dashboard/FailedRunsAlert.tsx +67 -0
- package/src/components/dashboard/FlowCard.tsx +64 -0
- package/src/components/dashboard/RecentActivityTable.tsx +92 -0
- package/src/components/dashboard/StatCard.tsx +32 -0
- package/src/components/dashboard/index.ts +5 -0
- package/src/components/dashboard/status-helpers.tsx +102 -0
- package/src/components/flow-editor/ActionsSidebar.tsx +503 -0
- package/src/components/flow-editor/FlowEditor.tsx +1002 -0
- package/src/components/flow-editor/FlowHeader.tsx +87 -0
- package/src/components/flow-editor/FlowLayout.tsx +117 -0
- package/src/components/flow-editor/ModeSwitcher.tsx +49 -0
- package/src/components/flow-editor/NodeSidebar.tsx +343 -0
- package/src/components/flow-editor/RunControls.tsx +109 -0
- package/src/components/flow-editor/ToolConfigPanel.tsx +434 -0
- package/src/components/flow-editor/ValidationPanel.tsx +167 -0
- package/src/components/flow-editor/flow-editor.store.ts +2 -0
- package/src/components/flow-editor/index.ts +6 -0
- package/src/components/flow-editor/inline-edit.tsx +111 -0
- package/src/components/flow-editor/node-config-panel/ConfigFieldWithTemplate.tsx +334 -0
- package/src/components/flow-editor/node-config-panel/CredentialCombobox.tsx +217 -0
- package/src/components/flow-editor/node-config-panel/CredentialsSection.tsx +154 -0
- package/src/components/flow-editor/node-config-panel/DroppableInput.tsx +45 -0
- package/src/components/flow-editor/node-config-panel/DynamicSelectField.tsx +223 -0
- package/src/components/flow-editor/node-config-panel/JsonPreviewPanel.tsx +134 -0
- package/src/components/flow-editor/node-config-panel/NodeConfigPanel.tsx +650 -0
- package/src/components/flow-editor/node-config-panel/NodeConfigPanelHeader.tsx +91 -0
- package/src/components/flow-editor/node-config-panel/ParametersSection.tsx +144 -0
- package/src/components/flow-editor/node-config-panel/SearchableSelectField.tsx +126 -0
- package/src/components/flow-editor/node-config-panel/SwitchCasesField.tsx +212 -0
- package/src/components/flow-editor/node-config-panel/hooks/index.ts +2 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-node-config-panel-state.ts +284 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-node-execution.ts +287 -0
- package/src/components/flow-editor/node-config-panel/hooks/use-upstream-slots.ts +310 -0
- package/src/components/flow-editor/node-config-panel/panels/AgentToolsPanel.tsx +837 -0
- package/src/components/flow-editor/node-config-panel/panels/ConfigurationPanel.tsx +383 -0
- package/src/components/flow-editor/node-config-panel/panels/DataMapperPane.tsx +456 -0
- package/src/components/flow-editor/node-config-panel/panels/InputPanel.tsx +338 -0
- package/src/components/flow-editor/node-config-panel/panels/OutputPanel.tsx +109 -0
- package/src/components/flow-editor/node-config-panel/panels/index.ts +4 -0
- package/src/components/flow-editor/node-config-panel/types.ts +20 -0
- package/src/components/flow-editor/node-config-panel/use-node-config-panel-store.ts +283 -0
- package/src/components/flow-editor/node-config-panel/use-node-config-state.ts +172 -0
- package/src/components/flow-editor/node-config-panel/use-run-node.ts +147 -0
- package/src/components/flow-editor/node-config-panel/utils.ts +73 -0
- package/src/components/flow-editor/serialize-to-sdk.ts +204 -0
- package/src/components/flow-editor/toolbar-context.ts +9 -0
- package/src/components/flow-editor/use-copy-paste.ts +575 -0
- package/src/components/flow-editor/use-copy-paste.types.ts +35 -0
- package/src/components/flow-editor/use-flow-editor.ts +241 -0
- package/src/components/flow-runs-table/FlowRunsTable.tsx +631 -0
- package/src/components/flow-runs-table/index.ts +1 -0
- package/src/components/flow-viewer/FlowRunsView.tsx +268 -0
- package/src/components/flow-viewer/FlowStatusView.tsx +351 -0
- package/src/components/flow-viewer/RunSelector.tsx +422 -0
- package/src/components/flow-viewer/RunsSidebar.tsx +125 -0
- package/src/components/flow-viewer/agent-tool-executions-list.tsx +298 -0
- package/src/components/flow-viewer/index.ts +1 -0
- package/src/components/flow-viewer/logs-panel.tsx +567 -0
- package/src/components/flow-viewer/use-execution-log-data.ts +374 -0
- package/src/components/graph/BatchFlowEdge.tsx +229 -0
- package/src/components/graph/LayoutSelector.tsx +42 -0
- package/src/components/graph/index.ts +61 -0
- package/src/components/graph/styleUtils.ts +375 -0
- package/src/components/nodes/.DS_Store +0 -0
- package/src/components/nodes/AgentConfigPanel.tsx +1033 -0
- package/src/components/nodes/AgentNode.tsx +298 -0
- package/src/components/nodes/AgentToolsBox.tsx +193 -0
- package/src/components/nodes/NodeAppendix.tsx +98 -0
- package/src/components/nodes/NodeStatusIndicator.tsx +74 -0
- package/src/components/nodes/NodeViewContext.tsx +45 -0
- package/src/components/nodes/ToolParamField.tsx +282 -0
- package/src/components/nodes/ToolSelectorModal.tsx +648 -0
- package/src/components/nodes/ToolSelectorParts.tsx +505 -0
- package/src/components/nodes/UniversalNode.tsx +356 -0
- package/src/components/nodes/createContextAwareNodes.ts +19 -0
- package/src/components/nodes/index.ts +45 -0
- package/src/components/nodes/nodeRegistry.ts +50 -0
- package/src/components/nodes/withNodeContext.tsx +55 -0
- package/src/components/shared/InvectLoader.tsx +59 -0
- package/src/components/shared/InvectLogo.tsx +59 -0
- package/src/components/shared/ProviderIcon.tsx +115 -0
- package/src/components/side-menu/side-menu.tsx +267 -0
- package/src/components/sidebar/BaseSidebar.tsx +148 -0
- package/src/components/sidebar/index.ts +1 -0
- package/src/components/triggers/CronPreview.tsx +243 -0
- package/src/components/triggers/index.ts +1 -0
- package/src/components/ui/alert-dialog.tsx +152 -0
- package/src/components/ui/badge.tsx +39 -0
- package/src/components/ui/button.tsx +58 -0
- package/src/components/ui/card.tsx +75 -0
- package/src/components/ui/codemirror-js-editor.tsx +432 -0
- package/src/components/ui/codemirror-json-editor.tsx +816 -0
- package/src/components/ui/codemirror-nunjucks-editor.tsx +451 -0
- package/src/components/ui/codemirror-vscode-theme.ts +243 -0
- package/src/components/ui/collapsible.tsx +12 -0
- package/src/components/ui/command.tsx +162 -0
- package/src/components/ui/dialog.tsx +140 -0
- package/src/components/ui/dropdown-menu.tsx +232 -0
- package/src/components/ui/empty-state.tsx +93 -0
- package/src/components/ui/input.tsx +26 -0
- package/src/components/ui/label.tsx +19 -0
- package/src/components/ui/popover.tsx +53 -0
- package/src/components/ui/resizable.tsx +61 -0
- package/src/components/ui/scroll-area.tsx +56 -0
- package/src/components/ui/select.tsx +179 -0
- package/src/components/ui/separator.tsx +26 -0
- package/src/components/ui/slider.tsx +58 -0
- package/src/components/ui/switch.tsx +22 -0
- package/src/components/ui/table.tsx +90 -0
- package/src/components/ui/textarea.tsx +23 -0
- package/src/components/ui/tooltip.tsx +54 -0
- package/src/components/ui/tree-view.tsx +574 -0
- package/src/contexts/AgentToolCallbacksContext.tsx +31 -0
- package/src/contexts/ApiContext.tsx +51 -0
- package/src/contexts/FlowDataContext.tsx +21 -0
- package/src/contexts/NodeRegistryContext.tsx +54 -0
- package/src/contexts/PluginRegistryContext.tsx +182 -0
- package/src/contexts/ThemeProvider.tsx +106 -0
- package/src/contexts/ValidationContext.tsx +122 -0
- package/src/demo/DemoInvect.tsx +42 -0
- package/src/demo/FlowViewer.tsx +294 -0
- package/src/demo/demo-api-client.ts +246 -0
- package/src/demo/index.ts +28 -0
- package/src/demo/sample-data.ts +1980 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-document-title.ts +8 -0
- package/src/hooks/use-flow-data.ts +144 -0
- package/src/hooks/use-invect-portal-class.ts +27 -0
- package/src/hooks/useFlowEditorStore.ts +2 -0
- package/src/index.ts +70 -0
- package/src/lib/utils.ts +6 -0
- package/src/prettier.d.ts +13 -0
- package/src/routes/all-flow-runs.tsx +27 -0
- package/src/routes/credentials.tsx +362 -0
- package/src/routes/flow-route-layout.tsx +113 -0
- package/src/routes/flow-runs.tsx +22 -0
- package/src/routes/flow.tsx +22 -0
- package/src/routes/home.tsx +282 -0
- package/src/services/index.ts +6 -0
- package/src/stores/executionViewStore.ts +211 -0
- package/src/stores/flow-editor.store.ts +738 -0
- package/src/stores/flowEditorStore.ts +2 -0
- package/src/stores/index.ts +10 -0
- package/src/stores/uiStore.ts +189 -0
- package/src/types/agent-tools.types.ts +64 -0
- package/src/types/index.ts +5 -0
- package/src/types/node-definition.types.ts +104 -0
- package/src/types/plugin.types.ts +123 -0
- package/src/utils/credentialBranding.ts +116 -0
- package/src/utils/credentialFiltering.ts +68 -0
- package/src/utils/flowTransformations.ts +137 -0
- package/src/utils/layoutUtils.ts +127 -0
- package/src/utils/nodeReferenceUtils.ts +135 -0
- package/src/vendor.d.ts +7 -0
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo, useState, useMemo, useEffect, useCallback } from 'react';
|
|
4
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '../ui/dialog';
|
|
6
|
+
|
|
7
|
+
import { Button } from '../ui/button';
|
|
8
|
+
import { ScrollArea } from '../ui/scroll-area';
|
|
9
|
+
import { Badge } from '../ui/badge';
|
|
10
|
+
import { Search, X, Tag } from 'lucide-react';
|
|
11
|
+
import { cn } from '../../lib/utils';
|
|
12
|
+
import { ProviderIcon } from '../shared/ProviderIcon';
|
|
13
|
+
import { CreateCredentialModal } from '../credentials/CreateCredentialModal';
|
|
14
|
+
import { OAuth2ProviderSelector } from '../credentials/OAuth2ProviderSelector';
|
|
15
|
+
import { useCreateCredential } from '../../api/credentials.api';
|
|
16
|
+
import type { AddCredentialRequest } from './ToolParamField';
|
|
17
|
+
import type { CreateCredentialInput, Credential } from '../../api/types';
|
|
18
|
+
import {
|
|
19
|
+
BrowseToolCard,
|
|
20
|
+
AddedToolTile,
|
|
21
|
+
ToolDetailsPanel,
|
|
22
|
+
categoryConfig,
|
|
23
|
+
categoryOrder,
|
|
24
|
+
} from './ToolSelectorParts';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tool category for organization in UI
|
|
28
|
+
*/
|
|
29
|
+
export type ToolCategory = 'data' | 'web' | 'code' | 'utility' | 'custom';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Full tool definition with schema information
|
|
33
|
+
*/
|
|
34
|
+
export interface ToolDefinition {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
category: ToolCategory;
|
|
39
|
+
/** Tags for filtering */
|
|
40
|
+
tags?: string[];
|
|
41
|
+
/** JSON Schema for tool inputs */
|
|
42
|
+
inputSchema?: Record<string, unknown>;
|
|
43
|
+
/** Documentation URL */
|
|
44
|
+
docsUrl?: string;
|
|
45
|
+
/** Whether this tool is enabled by default */
|
|
46
|
+
enabledByDefault?: boolean;
|
|
47
|
+
/** If this tool is backed by a node, this is the node type */
|
|
48
|
+
nodeType?: string;
|
|
49
|
+
/** Provider information for grouping and branding */
|
|
50
|
+
provider?: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
icon: string;
|
|
54
|
+
/** Raw SVG markup for custom provider branding */
|
|
55
|
+
svgIcon?: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* An instance of a tool that has been added to the agent.
|
|
61
|
+
* Multiple instances of the same tool can exist with different configurations.
|
|
62
|
+
*/
|
|
63
|
+
export interface AddedToolInstance {
|
|
64
|
+
/** Unique instance ID */
|
|
65
|
+
instanceId: string;
|
|
66
|
+
/** Reference to the base tool definition */
|
|
67
|
+
toolId: string;
|
|
68
|
+
/** Custom name for this instance (defaults to tool name) */
|
|
69
|
+
name: string;
|
|
70
|
+
/** Custom description for this instance (defaults to tool description) */
|
|
71
|
+
description: string;
|
|
72
|
+
/** Tool-specific configuration parameters */
|
|
73
|
+
params: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface ToolSelectorModalProps {
|
|
77
|
+
open: boolean;
|
|
78
|
+
onOpenChange: (open: boolean) => void;
|
|
79
|
+
/** All available tools */
|
|
80
|
+
availableTools: ToolDefinition[];
|
|
81
|
+
/** Currently added tool instances */
|
|
82
|
+
addedTools: AddedToolInstance[];
|
|
83
|
+
/** Called when a tool is added. Returns the new instance ID. */
|
|
84
|
+
onAddTool: (toolId: string) => string;
|
|
85
|
+
/** Called when a tool instance is removed */
|
|
86
|
+
onRemoveTool: (instanceId: string) => void;
|
|
87
|
+
/** Called when a tool instance is updated */
|
|
88
|
+
onUpdateTool: (
|
|
89
|
+
instanceId: string,
|
|
90
|
+
updates: Partial<Omit<AddedToolInstance, 'instanceId' | 'toolId'>>,
|
|
91
|
+
) => void;
|
|
92
|
+
/** Portal container for rendering the modal (needed when inside ReactFlow) */
|
|
93
|
+
portalContainer?: HTMLElement | null;
|
|
94
|
+
/** If true, start with focus on added tools section */
|
|
95
|
+
initialShowSelected?: boolean;
|
|
96
|
+
/** If provided, auto-select this tool instance when modal opens */
|
|
97
|
+
initialSelectedInstanceId?: string | null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Custom hook for debounced value
|
|
102
|
+
*/
|
|
103
|
+
function useDebounce<T>(value: T, delay: number): T {
|
|
104
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
105
|
+
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
const handler = setTimeout(() => {
|
|
108
|
+
setDebouncedValue(value);
|
|
109
|
+
}, delay);
|
|
110
|
+
|
|
111
|
+
return () => {
|
|
112
|
+
clearTimeout(handler);
|
|
113
|
+
};
|
|
114
|
+
}, [value, delay]);
|
|
115
|
+
|
|
116
|
+
return debouncedValue;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* ToolSelectorModal - Modal for managing agent tools
|
|
120
|
+
*
|
|
121
|
+
* Layout:
|
|
122
|
+
* - Left side (60%):
|
|
123
|
+
* - Top: Search bar + category tabs + tag filters
|
|
124
|
+
* - Middle: Browse available tools grid
|
|
125
|
+
* - Horizontal divider (when tools added)
|
|
126
|
+
* - Bottom: Added tools (horizontally scrollable)
|
|
127
|
+
* - Right side (40%): Tool details/configuration panel
|
|
128
|
+
*/
|
|
129
|
+
export const ToolSelectorModal = memo(function ToolSelectorModal({
|
|
130
|
+
open,
|
|
131
|
+
onOpenChange,
|
|
132
|
+
availableTools,
|
|
133
|
+
addedTools,
|
|
134
|
+
onAddTool,
|
|
135
|
+
onRemoveTool,
|
|
136
|
+
onUpdateTool,
|
|
137
|
+
portalContainer,
|
|
138
|
+
initialShowSelected: _initialShowSelected = false,
|
|
139
|
+
initialSelectedInstanceId = null,
|
|
140
|
+
}: ToolSelectorModalProps) {
|
|
141
|
+
const queryClient = useQueryClient();
|
|
142
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
143
|
+
// Selection can be either a browse tool (toolId) or an added instance (instanceId)
|
|
144
|
+
const [selectedBrowseToolId, setSelectedBrowseToolId] = useState<string | null>(null);
|
|
145
|
+
const [selectedInstanceId, setSelectedInstanceId] = useState<string | null>(null);
|
|
146
|
+
const [selectedCategory, setSelectedCategory] = useState<ToolCategory | 'all'>('all');
|
|
147
|
+
const [selectedTags, setSelectedTags] = useState<string[]>([]);
|
|
148
|
+
|
|
149
|
+
// Credential modal state
|
|
150
|
+
const [isCreateCredentialOpen, setIsCreateCredentialOpen] = useState(false);
|
|
151
|
+
const [isOAuth2SelectorOpen, setIsOAuth2SelectorOpen] = useState(false);
|
|
152
|
+
const [activeCredentialField, setActiveCredentialField] = useState<string | null>(null);
|
|
153
|
+
const [activeOAuth2Providers, setActiveOAuth2Providers] = useState<string[] | null>(null);
|
|
154
|
+
const createCredentialMutation = useCreateCredential();
|
|
155
|
+
|
|
156
|
+
// Debounce search query (300ms delay)
|
|
157
|
+
const debouncedSearchQuery = useDebounce(searchQuery, 300);
|
|
158
|
+
|
|
159
|
+
// Extract all unique tags from tools
|
|
160
|
+
const allTags = useMemo(() => {
|
|
161
|
+
const tagSet = new Set<string>();
|
|
162
|
+
for (const tool of availableTools) {
|
|
163
|
+
if (tool.tags) {
|
|
164
|
+
for (const tag of tool.tags) {
|
|
165
|
+
tagSet.add(tag);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return Array.from(tagSet).sort();
|
|
170
|
+
}, [availableTools]);
|
|
171
|
+
|
|
172
|
+
// Toggle tag selection
|
|
173
|
+
const toggleTag = useCallback((tag: string) => {
|
|
174
|
+
setSelectedTags((prev) =>
|
|
175
|
+
prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag],
|
|
176
|
+
);
|
|
177
|
+
}, []);
|
|
178
|
+
|
|
179
|
+
// Clear all tag filters
|
|
180
|
+
const clearTagFilters = useCallback(() => {
|
|
181
|
+
setSelectedTags([]);
|
|
182
|
+
}, []);
|
|
183
|
+
|
|
184
|
+
// Filter tools based on search, category, and tags
|
|
185
|
+
const filteredBrowseTools = useMemo(() => {
|
|
186
|
+
let tools = availableTools;
|
|
187
|
+
|
|
188
|
+
// Filter by category
|
|
189
|
+
if (selectedCategory !== 'all') {
|
|
190
|
+
tools = tools.filter((t) => t.category === selectedCategory);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Filter by tags (must match ALL selected tags)
|
|
194
|
+
if (selectedTags.length > 0) {
|
|
195
|
+
tools = tools.filter((t) => {
|
|
196
|
+
if (!t.tags) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return selectedTags.every((tag) => t.tags?.includes(tag) ?? false);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Filter by debounced search query
|
|
204
|
+
if (debouncedSearchQuery.trim()) {
|
|
205
|
+
const query = debouncedSearchQuery.toLowerCase();
|
|
206
|
+
tools = tools.filter(
|
|
207
|
+
(t) =>
|
|
208
|
+
t.name.toLowerCase().includes(query) ||
|
|
209
|
+
t.description.toLowerCase().includes(query) ||
|
|
210
|
+
t.id.toLowerCase().includes(query) ||
|
|
211
|
+
(t.tags && t.tags.some((tag) => tag.toLowerCase().includes(query))),
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return tools;
|
|
216
|
+
}, [availableTools, debouncedSearchQuery, selectedCategory, selectedTags]);
|
|
217
|
+
|
|
218
|
+
// Group browse tools by provider for display (matching NodeSidebar pattern)
|
|
219
|
+
const { providerGroups, sortedProviderIds } = useMemo(() => {
|
|
220
|
+
const byProvider: Record<
|
|
221
|
+
string,
|
|
222
|
+
{ name: string; icon?: string; svgIcon?: string; tools: ToolDefinition[] }
|
|
223
|
+
> = {};
|
|
224
|
+
for (const tool of filteredBrowseTools) {
|
|
225
|
+
const providerId = tool.provider?.id ?? tool.category;
|
|
226
|
+
if (!byProvider[providerId]) {
|
|
227
|
+
byProvider[providerId] = {
|
|
228
|
+
name: tool.provider?.name ?? categoryConfig[tool.category]?.label ?? tool.category,
|
|
229
|
+
icon: tool.provider?.icon,
|
|
230
|
+
svgIcon: tool.provider?.svgIcon,
|
|
231
|
+
tools: [],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
byProvider[providerId].tools.push(tool);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Sort: core-like providers first, then alphabetical
|
|
238
|
+
const providerOrder = ['core', 'ai', 'logic', 'data', 'utility', 'io'];
|
|
239
|
+
const sorted = Object.keys(byProvider).sort((a, b) => {
|
|
240
|
+
const idxA = providerOrder.indexOf(a);
|
|
241
|
+
const idxB = providerOrder.indexOf(b);
|
|
242
|
+
if (idxA !== -1 && idxB !== -1) {
|
|
243
|
+
return idxA - idxB;
|
|
244
|
+
}
|
|
245
|
+
if (idxA !== -1) {
|
|
246
|
+
return -1;
|
|
247
|
+
}
|
|
248
|
+
if (idxB !== -1) {
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
return byProvider[a].name.localeCompare(byProvider[b].name);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
return { providerGroups: byProvider, sortedProviderIds: sorted };
|
|
255
|
+
}, [filteredBrowseTools]);
|
|
256
|
+
|
|
257
|
+
// Get selected tool/instance for details panel
|
|
258
|
+
const selectedBrowseTool = selectedBrowseToolId
|
|
259
|
+
? (availableTools.find((t) => t.id === selectedBrowseToolId) ?? null)
|
|
260
|
+
: null;
|
|
261
|
+
const selectedInstance = selectedInstanceId
|
|
262
|
+
? (addedTools.find((t) => t.instanceId === selectedInstanceId) ?? null)
|
|
263
|
+
: null;
|
|
264
|
+
const selectedInstanceToolDef = selectedInstance
|
|
265
|
+
? (availableTools.find((t) => t.id === selectedInstance.toolId) ?? null)
|
|
266
|
+
: null;
|
|
267
|
+
|
|
268
|
+
// Count tools per category (for tabs)
|
|
269
|
+
const categoryCounts = useMemo(() => {
|
|
270
|
+
const counts: Record<ToolCategory | 'all', number> = {
|
|
271
|
+
all: availableTools.length,
|
|
272
|
+
data: 0,
|
|
273
|
+
web: 0,
|
|
274
|
+
code: 0,
|
|
275
|
+
utility: 0,
|
|
276
|
+
custom: 0,
|
|
277
|
+
};
|
|
278
|
+
for (const tool of availableTools) {
|
|
279
|
+
counts[tool.category]++;
|
|
280
|
+
}
|
|
281
|
+
return counts;
|
|
282
|
+
}, [availableTools]);
|
|
283
|
+
|
|
284
|
+
// Handle selecting a browse tool (clears instance selection)
|
|
285
|
+
const handleSelectBrowseTool = useCallback((toolId: string) => {
|
|
286
|
+
setSelectedBrowseToolId(toolId);
|
|
287
|
+
setSelectedInstanceId(null);
|
|
288
|
+
}, []);
|
|
289
|
+
|
|
290
|
+
// Handle selecting an added instance (clears browse selection)
|
|
291
|
+
const handleSelectInstance = useCallback((instanceId: string) => {
|
|
292
|
+
setSelectedInstanceId(instanceId);
|
|
293
|
+
setSelectedBrowseToolId(null);
|
|
294
|
+
}, []);
|
|
295
|
+
|
|
296
|
+
// Handle adding a tool and auto-selecting it
|
|
297
|
+
const handleAddTool = useCallback(
|
|
298
|
+
(toolId: string) => {
|
|
299
|
+
const instanceId = onAddTool(toolId);
|
|
300
|
+
// Auto-select the newly added tool to show config
|
|
301
|
+
setSelectedInstanceId(instanceId);
|
|
302
|
+
setSelectedBrowseToolId(null);
|
|
303
|
+
},
|
|
304
|
+
[onAddTool],
|
|
305
|
+
);
|
|
306
|
+
|
|
307
|
+
// Handle opening credential modal (either OAuth2 or regular)
|
|
308
|
+
const handleAddCredential = useCallback((request: AddCredentialRequest) => {
|
|
309
|
+
setActiveCredentialField(request.fieldName);
|
|
310
|
+
|
|
311
|
+
if (request.oauth2Providers && request.oauth2Providers.length > 0) {
|
|
312
|
+
// OAuth2 credential - open OAuth2 provider selector
|
|
313
|
+
setActiveOAuth2Providers(request.oauth2Providers);
|
|
314
|
+
setIsOAuth2SelectorOpen(true);
|
|
315
|
+
} else {
|
|
316
|
+
// Regular credential - open standard create modal
|
|
317
|
+
setIsCreateCredentialOpen(true);
|
|
318
|
+
}
|
|
319
|
+
}, []);
|
|
320
|
+
|
|
321
|
+
// Handle closing credential modal
|
|
322
|
+
const handleCloseCredentialModal = useCallback(() => {
|
|
323
|
+
setIsCreateCredentialOpen(false);
|
|
324
|
+
setActiveCredentialField(null);
|
|
325
|
+
}, []);
|
|
326
|
+
|
|
327
|
+
// Handle closing OAuth2 selector
|
|
328
|
+
const handleCloseOAuth2Selector = useCallback(() => {
|
|
329
|
+
setIsOAuth2SelectorOpen(false);
|
|
330
|
+
setActiveCredentialField(null);
|
|
331
|
+
setActiveOAuth2Providers(null);
|
|
332
|
+
}, []);
|
|
333
|
+
|
|
334
|
+
// Handle credential created (from either modal)
|
|
335
|
+
const handleCredentialCreated = useCallback(
|
|
336
|
+
async (createdCredential: Credential) => {
|
|
337
|
+
// Explicitly refetch credentials to ensure the list is up-to-date
|
|
338
|
+
// This is needed because the ToolParamField's useCredentials hook may have stale data
|
|
339
|
+
await queryClient.refetchQueries({ queryKey: ['credentials'] });
|
|
340
|
+
|
|
341
|
+
// If we have a selected instance and active field, update it with the new credential
|
|
342
|
+
// Note: We capture these values before closing modals which clear them
|
|
343
|
+
const fieldToUpdate = activeCredentialField;
|
|
344
|
+
const instanceToUpdate = selectedInstanceId;
|
|
345
|
+
|
|
346
|
+
if (instanceToUpdate && fieldToUpdate) {
|
|
347
|
+
const instance = addedTools.find((t) => t.instanceId === instanceToUpdate);
|
|
348
|
+
if (instance) {
|
|
349
|
+
onUpdateTool(instanceToUpdate, {
|
|
350
|
+
params: { ...instance.params, [fieldToUpdate]: createdCredential.id },
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Close whichever modal is open (this clears activeCredentialField)
|
|
355
|
+
setIsCreateCredentialOpen(false);
|
|
356
|
+
setIsOAuth2SelectorOpen(false);
|
|
357
|
+
setActiveCredentialField(null);
|
|
358
|
+
setActiveOAuth2Providers(null);
|
|
359
|
+
},
|
|
360
|
+
[queryClient, selectedInstanceId, activeCredentialField, addedTools, onUpdateTool],
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
// Handle creating a regular credential (non-OAuth2)
|
|
364
|
+
const handleCreateCredential = useCallback(
|
|
365
|
+
(input: CreateCredentialInput) => {
|
|
366
|
+
createCredentialMutation.mutate(input, {
|
|
367
|
+
onSuccess: (createdCredential) => {
|
|
368
|
+
handleCredentialCreated(createdCredential);
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
[createCredentialMutation, handleCredentialCreated],
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
// Set initial selected instance when modal opens
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
if (open && initialSelectedInstanceId) {
|
|
378
|
+
setSelectedInstanceId(initialSelectedInstanceId);
|
|
379
|
+
setSelectedBrowseToolId(null);
|
|
380
|
+
}
|
|
381
|
+
}, [open, initialSelectedInstanceId]);
|
|
382
|
+
|
|
383
|
+
// Reset state when modal closes
|
|
384
|
+
useEffect(() => {
|
|
385
|
+
if (!open) {
|
|
386
|
+
setSearchQuery('');
|
|
387
|
+
setSelectedBrowseToolId(null);
|
|
388
|
+
setSelectedInstanceId(null);
|
|
389
|
+
setSelectedCategory('all');
|
|
390
|
+
setSelectedTags([]);
|
|
391
|
+
}
|
|
392
|
+
}, [open]);
|
|
393
|
+
|
|
394
|
+
// Determine what to show in details panel
|
|
395
|
+
const detailsTool = selectedInstance ? selectedInstanceToolDef : selectedBrowseTool;
|
|
396
|
+
const detailsInstance = selectedInstance;
|
|
397
|
+
|
|
398
|
+
return (
|
|
399
|
+
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
400
|
+
<DialogContent
|
|
401
|
+
container={portalContainer}
|
|
402
|
+
className="h-[90vh] max-h-[90vh] sm:max-w-[95vw] w-[95vw] p-0 gap-0 flex flex-col bg-card border-border"
|
|
403
|
+
>
|
|
404
|
+
<DialogHeader className="p-4 pb-0 shrink-0">
|
|
405
|
+
<DialogTitle>Manage Agent Tools</DialogTitle>
|
|
406
|
+
<DialogDescription className="sr-only">
|
|
407
|
+
Add, configure, and manage tools for your AI agent
|
|
408
|
+
</DialogDescription>
|
|
409
|
+
</DialogHeader>
|
|
410
|
+
|
|
411
|
+
{/* Main content area */}
|
|
412
|
+
<div className="flex flex-1 min-h-0">
|
|
413
|
+
{/* Left side: Browse tools */}
|
|
414
|
+
<div className="flex flex-col flex-1 min-w-0 border-r">
|
|
415
|
+
{/* Search and filters */}
|
|
416
|
+
<div className="p-4 space-y-3 border-b shrink-0">
|
|
417
|
+
{/* Search bar */}
|
|
418
|
+
<div className="flex gap-3">
|
|
419
|
+
<div className="relative flex-1">
|
|
420
|
+
<Search className="absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 pointer-events-none text-muted-foreground" />
|
|
421
|
+
<input
|
|
422
|
+
type="text"
|
|
423
|
+
placeholder="Search tools by name, description, or tag…"
|
|
424
|
+
value={searchQuery}
|
|
425
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
426
|
+
className="w-full rounded-lg border border-border bg-transparent py-2 pl-9 pr-3 text-sm outline-none placeholder:text-muted-foreground focus:border-primary/50"
|
|
427
|
+
/>
|
|
428
|
+
{searchQuery && (
|
|
429
|
+
<button
|
|
430
|
+
onClick={() => setSearchQuery('')}
|
|
431
|
+
className="absolute -translate-y-1/2 right-3 top-1/2 text-muted-foreground hover:text-foreground"
|
|
432
|
+
>
|
|
433
|
+
<X className="w-4 h-4" />
|
|
434
|
+
</button>
|
|
435
|
+
)}
|
|
436
|
+
</div>
|
|
437
|
+
</div>
|
|
438
|
+
|
|
439
|
+
{/* Category tabs */}
|
|
440
|
+
<div className="flex gap-2 pb-1 overflow-x-auto">
|
|
441
|
+
<Button
|
|
442
|
+
size="sm"
|
|
443
|
+
variant={selectedCategory === 'all' ? 'default' : 'ghost'}
|
|
444
|
+
onClick={() => setSelectedCategory('all')}
|
|
445
|
+
className="shrink-0"
|
|
446
|
+
>
|
|
447
|
+
All ({categoryCounts.all})
|
|
448
|
+
</Button>
|
|
449
|
+
{categoryOrder.map((cat) => {
|
|
450
|
+
const config = categoryConfig[cat];
|
|
451
|
+
const Icon = config.icon;
|
|
452
|
+
const count = categoryCounts[cat];
|
|
453
|
+
if (count === 0) {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
return (
|
|
457
|
+
<Button
|
|
458
|
+
key={cat}
|
|
459
|
+
size="sm"
|
|
460
|
+
variant={selectedCategory === cat ? 'default' : 'ghost'}
|
|
461
|
+
onClick={() => setSelectedCategory(cat)}
|
|
462
|
+
className="shrink-0 gap-1.5"
|
|
463
|
+
>
|
|
464
|
+
<Icon className="h-3.5 w-3.5" />
|
|
465
|
+
{config.label} ({count})
|
|
466
|
+
</Button>
|
|
467
|
+
);
|
|
468
|
+
})}
|
|
469
|
+
</div>
|
|
470
|
+
|
|
471
|
+
{/* Tag filters */}
|
|
472
|
+
{allTags.length > 0 && (
|
|
473
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
474
|
+
<div className="flex items-center gap-1 text-xs text-muted-foreground shrink-0">
|
|
475
|
+
<Tag className="w-3 h-3" />
|
|
476
|
+
<span>Tags:</span>
|
|
477
|
+
</div>
|
|
478
|
+
{allTags.map((tag) => (
|
|
479
|
+
<Badge
|
|
480
|
+
key={tag}
|
|
481
|
+
variant={selectedTags.includes(tag) ? 'default' : 'outline'}
|
|
482
|
+
className={cn(
|
|
483
|
+
'cursor-pointer text-xs transition-colors',
|
|
484
|
+
selectedTags.includes(tag)
|
|
485
|
+
? 'bg-primary text-primary-foreground hover:bg-primary/90'
|
|
486
|
+
: 'hover:bg-muted',
|
|
487
|
+
)}
|
|
488
|
+
onClick={() => toggleTag(tag)}
|
|
489
|
+
>
|
|
490
|
+
{tag}
|
|
491
|
+
{selectedTags.includes(tag) && <X className="w-3 h-3 ml-1" />}
|
|
492
|
+
</Badge>
|
|
493
|
+
))}
|
|
494
|
+
{selectedTags.length > 0 && (
|
|
495
|
+
<Button
|
|
496
|
+
variant="ghost"
|
|
497
|
+
size="sm"
|
|
498
|
+
onClick={clearTagFilters}
|
|
499
|
+
className="h-6 px-2 text-xs"
|
|
500
|
+
>
|
|
501
|
+
Clear all
|
|
502
|
+
</Button>
|
|
503
|
+
)}
|
|
504
|
+
</div>
|
|
505
|
+
)}
|
|
506
|
+
|
|
507
|
+
{/* Active filters summary */}
|
|
508
|
+
{(selectedTags.length > 0 || debouncedSearchQuery || selectedCategory !== 'all') && (
|
|
509
|
+
<div className="text-xs text-muted-foreground">
|
|
510
|
+
Showing {filteredBrowseTools.length} of {availableTools.length} tools
|
|
511
|
+
</div>
|
|
512
|
+
)}
|
|
513
|
+
</div>
|
|
514
|
+
|
|
515
|
+
{/* Browse tools grid — grouped by provider */}
|
|
516
|
+
<ScrollArea className="flex-1">
|
|
517
|
+
<div className="p-4 space-y-6">
|
|
518
|
+
{filteredBrowseTools.length === 0 ? (
|
|
519
|
+
<div className="py-8 text-center text-muted-foreground">
|
|
520
|
+
<Search className="w-8 h-8 mx-auto mb-2 opacity-20" />
|
|
521
|
+
<p className="text-sm">No tools found</p>
|
|
522
|
+
</div>
|
|
523
|
+
) : (
|
|
524
|
+
sortedProviderIds.map((providerId) => {
|
|
525
|
+
const group = providerGroups[providerId];
|
|
526
|
+
return (
|
|
527
|
+
<div key={providerId}>
|
|
528
|
+
<h3 className="flex items-center gap-2 mb-3 text-sm font-medium text-muted-foreground">
|
|
529
|
+
<ProviderIcon
|
|
530
|
+
providerId={providerId}
|
|
531
|
+
svgIcon={group.svgIcon}
|
|
532
|
+
icon={group.icon}
|
|
533
|
+
className="w-5 h-5"
|
|
534
|
+
/>
|
|
535
|
+
{group.name}
|
|
536
|
+
</h3>
|
|
537
|
+
<div className="grid grid-cols-2 gap-3 xl:grid-cols-3">
|
|
538
|
+
{group.tools.map((tool) => (
|
|
539
|
+
<BrowseToolCard
|
|
540
|
+
key={tool.id}
|
|
541
|
+
tool={tool}
|
|
542
|
+
isActive={selectedBrowseToolId === tool.id}
|
|
543
|
+
onAdd={() => handleAddTool(tool.id)}
|
|
544
|
+
onPreview={() => handleSelectBrowseTool(tool.id)}
|
|
545
|
+
/>
|
|
546
|
+
))}
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
);
|
|
550
|
+
})
|
|
551
|
+
)}
|
|
552
|
+
</div>
|
|
553
|
+
</ScrollArea>
|
|
554
|
+
</div>
|
|
555
|
+
|
|
556
|
+
{/* Middle: Added tools vertical list */}
|
|
557
|
+
<div className="flex flex-col w-48 min-h-0 border-r shrink-0 bg-muted/10">
|
|
558
|
+
<div className="p-3 border-b shrink-0">
|
|
559
|
+
<div className="flex items-center gap-2">
|
|
560
|
+
<span className="text-xs font-medium">Added Tools</span>
|
|
561
|
+
<span className="flex items-center justify-center w-5 h-5 text-xs rounded-full bg-primary/10 text-primary">
|
|
562
|
+
{addedTools.length}
|
|
563
|
+
</span>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
<ScrollArea className="flex-1">
|
|
567
|
+
<div className="p-2 space-y-2">
|
|
568
|
+
{addedTools.length === 0 ? (
|
|
569
|
+
<div className="py-6 text-center">
|
|
570
|
+
<div className="text-xs text-muted-foreground">No tools added yet</div>
|
|
571
|
+
<div className="mt-1 text-[10px] text-muted-foreground/60">
|
|
572
|
+
Click + on a tool to add it
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
) : (
|
|
576
|
+
addedTools.map((instance) => {
|
|
577
|
+
const toolDef = availableTools.find((t) => t.id === instance.toolId);
|
|
578
|
+
return (
|
|
579
|
+
<AddedToolTile
|
|
580
|
+
key={instance.instanceId}
|
|
581
|
+
instance={instance}
|
|
582
|
+
toolDef={toolDef}
|
|
583
|
+
isActive={selectedInstanceId === instance.instanceId}
|
|
584
|
+
onSelect={() => handleSelectInstance(instance.instanceId)}
|
|
585
|
+
onRemove={() => onRemoveTool(instance.instanceId)}
|
|
586
|
+
/>
|
|
587
|
+
);
|
|
588
|
+
})
|
|
589
|
+
)}
|
|
590
|
+
</div>
|
|
591
|
+
</ScrollArea>
|
|
592
|
+
</div>
|
|
593
|
+
|
|
594
|
+
{/* Right side: Tool details/config panel */}
|
|
595
|
+
<div className="flex flex-col flex-1 min-h-0 min-w-0 bg-muted/30">
|
|
596
|
+
<ToolDetailsPanel
|
|
597
|
+
tool={detailsTool}
|
|
598
|
+
instance={detailsInstance}
|
|
599
|
+
onAdd={selectedBrowseTool ? () => handleAddTool(selectedBrowseTool.id) : undefined}
|
|
600
|
+
onUpdate={
|
|
601
|
+
selectedInstance
|
|
602
|
+
? (updates) => onUpdateTool(selectedInstance.instanceId, updates)
|
|
603
|
+
: undefined
|
|
604
|
+
}
|
|
605
|
+
onRemove={
|
|
606
|
+
selectedInstance ? () => onRemoveTool(selectedInstance.instanceId) : undefined
|
|
607
|
+
}
|
|
608
|
+
onAddCredential={handleAddCredential}
|
|
609
|
+
portalContainer={portalContainer}
|
|
610
|
+
/>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
613
|
+
|
|
614
|
+
{/* Footer */}
|
|
615
|
+
<div className="flex items-center justify-between p-4 border-t shrink-0">
|
|
616
|
+
<div className="text-sm text-muted-foreground">
|
|
617
|
+
{addedTools.length} tool{addedTools.length !== 1 ? 's' : ''} added
|
|
618
|
+
</div>
|
|
619
|
+
<Button onClick={() => onOpenChange(false)}>Done</Button>
|
|
620
|
+
</div>
|
|
621
|
+
</DialogContent>
|
|
622
|
+
|
|
623
|
+
{/* Regular credential creation modal (for non-OAuth2) */}
|
|
624
|
+
<CreateCredentialModal
|
|
625
|
+
open={isCreateCredentialOpen}
|
|
626
|
+
onClose={handleCloseCredentialModal}
|
|
627
|
+
onSubmit={handleCreateCredential}
|
|
628
|
+
isLoading={createCredentialMutation.isPending}
|
|
629
|
+
portalContainer={portalContainer}
|
|
630
|
+
/>
|
|
631
|
+
|
|
632
|
+
{/* OAuth2 provider selector modal */}
|
|
633
|
+
<OAuth2ProviderSelector
|
|
634
|
+
open={isOAuth2SelectorOpen}
|
|
635
|
+
onOpenChange={(open) => {
|
|
636
|
+
if (!open) {
|
|
637
|
+
handleCloseOAuth2Selector();
|
|
638
|
+
}
|
|
639
|
+
}}
|
|
640
|
+
onCredentialCreated={handleCredentialCreated}
|
|
641
|
+
portalContainer={portalContainer}
|
|
642
|
+
filterProviders={activeOAuth2Providers ?? undefined}
|
|
643
|
+
/>
|
|
644
|
+
</Dialog>
|
|
645
|
+
);
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
ToolSelectorModal.displayName = 'ToolSelectorModal';
|