@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,298 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo, useCallback, useState } from 'react';
|
|
4
|
+
import { Handle, Position, type NodeProps } from '@xyflow/react';
|
|
5
|
+
import { Card } from '../ui/card';
|
|
6
|
+
import { useNodeRegistry } from '../../contexts/NodeRegistryContext';
|
|
7
|
+
import { GraphNodeType, NodeExecutionStatus } from '@invect/core/types';
|
|
8
|
+
import { cn } from '../../lib/utils';
|
|
9
|
+
import { Loader2, Bot } from 'lucide-react';
|
|
10
|
+
import { NodeAppendix, type AppendixPosition } from './NodeAppendix';
|
|
11
|
+
import { AgentToolsBox } from './AgentToolsBox';
|
|
12
|
+
import type { ToolDefinition, AddedToolInstance } from './ToolSelectorModal';
|
|
13
|
+
import { useAgentToolCallbacks } from '../../contexts/AgentToolCallbacksContext';
|
|
14
|
+
|
|
15
|
+
// Stable style objects for Handles - avoids creating new objects on every render
|
|
16
|
+
const INPUT_HANDLE_STYLE = { top: '50%', transform: 'translate(-54%, -50%)' } as const;
|
|
17
|
+
const OUTPUT_HANDLE_STYLE_SINGLE = { top: '50%', transform: 'translate(54%, -50%)' } as const;
|
|
18
|
+
const OUTPUT_HANDLE_INNER_STYLE = { transform: 'translateX(54%)' } as const;
|
|
19
|
+
const HANDLE_CLASS =
|
|
20
|
+
'!bg-background !w-4 !h-4 !border-2 !border-muted-foreground !rounded-full !transition-colors hover:!bg-muted hover:!border-foreground !shadow-none !ring-0';
|
|
21
|
+
|
|
22
|
+
interface AgentNodeData extends Record<string, unknown> {
|
|
23
|
+
type?: GraphNodeType;
|
|
24
|
+
display_name?: string;
|
|
25
|
+
executionStatus?: NodeExecutionStatus;
|
|
26
|
+
params?: {
|
|
27
|
+
/** Added tool instances with their configurations */
|
|
28
|
+
addedTools?: AddedToolInstance[];
|
|
29
|
+
/** All available tools (populated by parent for tool resolution) */
|
|
30
|
+
availableTools?: ToolDefinition[];
|
|
31
|
+
toolsPosition?: AppendixPosition;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
};
|
|
34
|
+
// Event handlers (injected by FlowEditor)
|
|
35
|
+
/** Opens the tool selector modal */
|
|
36
|
+
onOpenToolSelector?: () => void;
|
|
37
|
+
/** Opens the tool selector modal with "show selected" filter enabled */
|
|
38
|
+
onShowMoreTools?: () => void;
|
|
39
|
+
/** Removes a tool instance from this node */
|
|
40
|
+
onRemoveTool?: (instanceId: string) => void;
|
|
41
|
+
/** Called when user clicks on a tool (to configure it) */
|
|
42
|
+
onToolClick?: (tool: AddedToolInstance) => void;
|
|
43
|
+
onToolsPositionChange?: (position: AppendixPosition) => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Loading placeholder shown while node definition is being fetched.
|
|
48
|
+
*/
|
|
49
|
+
const AgentNodeLoadingPlaceholder = memo(
|
|
50
|
+
({ data, selected }: { data: AgentNodeData; selected: boolean }) => {
|
|
51
|
+
const label = data.display_name || 'AI Agent';
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Card
|
|
55
|
+
className={`relative w-[240px] h-[60px] flex-row py-0 items-center cursor-move transition-colors bg-card hover:bg-card/80 ${
|
|
56
|
+
selected
|
|
57
|
+
? 'border-blue-500 dark:border-blue-400 shadow-lg shadow-blue-500/25 dark:shadow-blue-400/30'
|
|
58
|
+
: 'border-sidebar-ring hover:border-muted-foreground'
|
|
59
|
+
}`}
|
|
60
|
+
>
|
|
61
|
+
<Handle
|
|
62
|
+
id="input"
|
|
63
|
+
type="target"
|
|
64
|
+
position={Position.Left}
|
|
65
|
+
style={INPUT_HANDLE_STYLE}
|
|
66
|
+
className={HANDLE_CLASS}
|
|
67
|
+
/>
|
|
68
|
+
|
|
69
|
+
<div className="flex items-center gap-3 px-3 py-0 overflow-hidden">
|
|
70
|
+
<div className="flex items-center justify-center w-10 h-10 shrink-0 rounded-xl bg-muted">
|
|
71
|
+
<Loader2 className="w-5 h-5 animate-spin text-muted-foreground" />
|
|
72
|
+
</div>
|
|
73
|
+
<div className="flex-1 min-w-0">
|
|
74
|
+
<div className="text-xs font-semibold tracking-tight truncate text-card-foreground">
|
|
75
|
+
{label}
|
|
76
|
+
</div>
|
|
77
|
+
<div className="font-mono text-xs tracking-tight truncate text-muted-foreground">
|
|
78
|
+
AGENT
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<Handle
|
|
84
|
+
id="output"
|
|
85
|
+
type="source"
|
|
86
|
+
position={Position.Right}
|
|
87
|
+
style={OUTPUT_HANDLE_STYLE_SINGLE}
|
|
88
|
+
className={HANDLE_CLASS}
|
|
89
|
+
/>
|
|
90
|
+
</Card>
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
AgentNodeLoadingPlaceholder.displayName = 'AgentNodeLoadingPlaceholder';
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* AgentNode - A specialized node for AI Agents with an attached tools box
|
|
99
|
+
*
|
|
100
|
+
* This node renders like the UniversalNode but with an additional "appendix"
|
|
101
|
+
* panel that displays and manages the tools available to the agent.
|
|
102
|
+
*/
|
|
103
|
+
export const AgentNode = memo(({ id, data, selected }: NodeProps) => {
|
|
104
|
+
const typedData = data as AgentNodeData;
|
|
105
|
+
const nodeType = GraphNodeType.AGENT;
|
|
106
|
+
|
|
107
|
+
const { getNodeDefinition, isLoading: registryLoading } = useNodeRegistry();
|
|
108
|
+
const definition = getNodeDefinition(nodeType);
|
|
109
|
+
|
|
110
|
+
// Read callbacks and available tools from context instead of data injection.
|
|
111
|
+
// This avoids the parent having to remap ALL nodes just to inject these into Agent data.
|
|
112
|
+
const toolCallbacks = useAgentToolCallbacks();
|
|
113
|
+
|
|
114
|
+
// Local state for tools position (can be controlled externally via data.params.toolsPosition)
|
|
115
|
+
const [localToolsPosition, setLocalToolsPosition] = useState<AppendixPosition>('bottom');
|
|
116
|
+
const toolsPosition = typedData.params?.toolsPosition ?? localToolsPosition;
|
|
117
|
+
|
|
118
|
+
// Available tools from context (provided by FlowEditor), falling back to data injection for non-editor views
|
|
119
|
+
const availableTools: ToolDefinition[] =
|
|
120
|
+
toolCallbacks?.availableTools ?? typedData.params?.availableTools ?? [];
|
|
121
|
+
|
|
122
|
+
// Get added tool instances from params
|
|
123
|
+
const addedTools: AddedToolInstance[] = typedData.params?.addedTools ?? [];
|
|
124
|
+
|
|
125
|
+
// Handle position change
|
|
126
|
+
const handlePositionChange = useCallback(
|
|
127
|
+
(position: AppendixPosition) => {
|
|
128
|
+
setLocalToolsPosition(position);
|
|
129
|
+
typedData.onToolsPositionChange?.(position);
|
|
130
|
+
},
|
|
131
|
+
[typedData],
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Show loading placeholder if registry is still loading or definition not found
|
|
135
|
+
if (registryLoading || !definition) {
|
|
136
|
+
return <AgentNodeLoadingPlaceholder data={typedData} selected={selected ?? false} />;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const label = typedData.display_name || definition.label || 'AI Agent';
|
|
140
|
+
|
|
141
|
+
// Agent nodes always use green/AI color
|
|
142
|
+
const iconColorClass = 'bg-green-500/15 text-green-600 dark:text-green-400';
|
|
143
|
+
|
|
144
|
+
// Get handle definitions from the node definition
|
|
145
|
+
const inputHandle = definition.input;
|
|
146
|
+
const outputs = definition.outputs || [];
|
|
147
|
+
|
|
148
|
+
const hasIncomingHandle = !!inputHandle;
|
|
149
|
+
|
|
150
|
+
// Check execution status for running state
|
|
151
|
+
const isRunning =
|
|
152
|
+
typedData.executionStatus === NodeExecutionStatus.RUNNING ||
|
|
153
|
+
typedData.executionStatus === NodeExecutionStatus.PENDING ||
|
|
154
|
+
typedData.executionStatus === NodeExecutionStatus.BATCH_SUBMITTED;
|
|
155
|
+
const isSuccess = typedData.executionStatus === NodeExecutionStatus.SUCCESS;
|
|
156
|
+
const isError = typedData.executionStatus === NodeExecutionStatus.FAILED;
|
|
157
|
+
const isSkipped = typedData.executionStatus === NodeExecutionStatus.SKIPPED;
|
|
158
|
+
|
|
159
|
+
const outputHandleConfigs = outputs.map((output, index) => {
|
|
160
|
+
if (outputs.length === 1) {
|
|
161
|
+
return { output, topPercent: 50 };
|
|
162
|
+
}
|
|
163
|
+
const EDGE_OFFSET = 28;
|
|
164
|
+
const availableSpace = 100 - EDGE_OFFSET * 2;
|
|
165
|
+
const topPercent = EDGE_OFFSET + (index / (outputs.length - 1)) * availableSpace;
|
|
166
|
+
return { output, topPercent };
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// Compute border class for the tools appendix to match the node state
|
|
170
|
+
const appendixBorderClass = isRunning
|
|
171
|
+
? 'border-primary'
|
|
172
|
+
: isSuccess
|
|
173
|
+
? 'border-success'
|
|
174
|
+
: isError
|
|
175
|
+
? 'border-destructive'
|
|
176
|
+
: isSkipped
|
|
177
|
+
? 'border-dashed border-muted-foreground/50'
|
|
178
|
+
: selected
|
|
179
|
+
? 'node-selected'
|
|
180
|
+
: 'border-sidebar-ring group-hover:border-primary/60';
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<div className="relative group">
|
|
184
|
+
{/* Main node card */}
|
|
185
|
+
<Card
|
|
186
|
+
className={cn(
|
|
187
|
+
'relative w-[200px] h-[60px] flex-row py-0 items-center cursor-move transition-colors node-hover-bg bg-card',
|
|
188
|
+
// Default border
|
|
189
|
+
!isRunning &&
|
|
190
|
+
!isSuccess &&
|
|
191
|
+
!isError &&
|
|
192
|
+
!isSkipped &&
|
|
193
|
+
'border-sidebar-ring group-hover:border-primary/60',
|
|
194
|
+
// Running state - animated gradient border
|
|
195
|
+
isRunning && 'node-running-border animate-node-border rounded-xl',
|
|
196
|
+
// Success state - green border
|
|
197
|
+
isSuccess && 'border-2 border-success',
|
|
198
|
+
// Error state - red border
|
|
199
|
+
isError && 'border-2 border-destructive',
|
|
200
|
+
// Skipped state - greyed out with dashed border
|
|
201
|
+
isSkipped && 'border-2 border-dashed border-muted-foreground/50 opacity-50',
|
|
202
|
+
// Selection state - change existing border color to blue for visibility
|
|
203
|
+
selected && !isRunning && !isSuccess && !isError && !isSkipped && 'node-selected',
|
|
204
|
+
)}
|
|
205
|
+
>
|
|
206
|
+
{/* Unified Input Handle */}
|
|
207
|
+
{hasIncomingHandle && (
|
|
208
|
+
<Handle
|
|
209
|
+
id={inputHandle?.id || 'input'}
|
|
210
|
+
type="target"
|
|
211
|
+
position={Position.Left}
|
|
212
|
+
style={INPUT_HANDLE_STYLE}
|
|
213
|
+
className={HANDLE_CLASS}
|
|
214
|
+
/>
|
|
215
|
+
)}
|
|
216
|
+
|
|
217
|
+
<div className="flex items-center gap-3 px-3 py-0 overflow-hidden">
|
|
218
|
+
<div
|
|
219
|
+
className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl ${iconColorClass}`}
|
|
220
|
+
>
|
|
221
|
+
<Bot className="w-6 h-6" />
|
|
222
|
+
</div>
|
|
223
|
+
<div className="flex-1 min-w-0">
|
|
224
|
+
<div className="text-xs font-semibold tracking-tight truncate text-card-foreground">
|
|
225
|
+
{label}
|
|
226
|
+
</div>
|
|
227
|
+
<div className="font-mono text-xs tracking-tight truncate text-muted-foreground">
|
|
228
|
+
{nodeType}
|
|
229
|
+
</div>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
{/* Output Handles */}
|
|
234
|
+
{outputHandleConfigs.map(({ output, topPercent }) => {
|
|
235
|
+
const showLabel = outputs.length > 1;
|
|
236
|
+
return (
|
|
237
|
+
<div
|
|
238
|
+
key={output.id}
|
|
239
|
+
className="absolute right-0"
|
|
240
|
+
style={{ top: `${topPercent}%`, transform: 'translateY(-50%)' }}
|
|
241
|
+
>
|
|
242
|
+
<div className="relative flex items-center">
|
|
243
|
+
<Handle
|
|
244
|
+
id={output.id}
|
|
245
|
+
type="source"
|
|
246
|
+
position={Position.Right}
|
|
247
|
+
style={OUTPUT_HANDLE_INNER_STYLE}
|
|
248
|
+
className="!relative !bg-background !w-4 !h-4 !border-2 !border-muted-foreground !rounded-full !transition-colors hover:!bg-muted hover:!border-foreground !shadow-none !ring-0"
|
|
249
|
+
/>
|
|
250
|
+
{showLabel && (
|
|
251
|
+
<div className="absolute px-1 text-xs border rounded left-8 text-card-foreground whitespace-nowrap bg-card border-sidebar-ring">
|
|
252
|
+
{output.label}
|
|
253
|
+
</div>
|
|
254
|
+
)}
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
);
|
|
258
|
+
})}
|
|
259
|
+
</Card>
|
|
260
|
+
|
|
261
|
+
{/* Tools Appendix - attached to the node */}
|
|
262
|
+
<NodeAppendix
|
|
263
|
+
position={toolsPosition}
|
|
264
|
+
onPositionChange={handlePositionChange}
|
|
265
|
+
showPositionToggle={true}
|
|
266
|
+
borderClassName={appendixBorderClass}
|
|
267
|
+
>
|
|
268
|
+
<AgentToolsBox
|
|
269
|
+
tools={addedTools}
|
|
270
|
+
availableTools={availableTools}
|
|
271
|
+
selectedInstanceId={
|
|
272
|
+
toolCallbacks?.selectedToolNodeId === id ? toolCallbacks.selectedToolInstanceId : null
|
|
273
|
+
}
|
|
274
|
+
onAddTool={
|
|
275
|
+
toolCallbacks
|
|
276
|
+
? () => toolCallbacks.onOpenToolSelector(id)
|
|
277
|
+
: typedData.onOpenToolSelector
|
|
278
|
+
}
|
|
279
|
+
onShowMore={
|
|
280
|
+
toolCallbacks ? () => toolCallbacks.onShowMoreTools(id) : typedData.onShowMoreTools
|
|
281
|
+
}
|
|
282
|
+
onToolClick={
|
|
283
|
+
toolCallbacks
|
|
284
|
+
? (tool: AddedToolInstance) => toolCallbacks.onToolClick(id, tool.instanceId)
|
|
285
|
+
: typedData.onToolClick
|
|
286
|
+
}
|
|
287
|
+
onRemoveTool={
|
|
288
|
+
toolCallbacks
|
|
289
|
+
? (instanceId: string) => toolCallbacks.onRemoveTool(id, instanceId)
|
|
290
|
+
: typedData.onRemoveTool
|
|
291
|
+
}
|
|
292
|
+
/>
|
|
293
|
+
</NodeAppendix>
|
|
294
|
+
</div>
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
AgentNode.displayName = 'AgentNode';
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { Plus, Settings } from 'lucide-react';
|
|
5
|
+
import { cn } from '../../lib/utils';
|
|
6
|
+
import { ProviderIcon } from '../shared/ProviderIcon';
|
|
7
|
+
import type { AddedToolInstance, ToolDefinition } from './ToolSelectorModal';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tool category for organization in UI
|
|
11
|
+
* Matches AgentToolCategory from @invect/core
|
|
12
|
+
*/
|
|
13
|
+
export type ToolCategory = 'data' | 'web' | 'code' | 'utility' | 'custom';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Simplified tool definition for display in the UI
|
|
17
|
+
* @deprecated Use AddedToolInstance instead
|
|
18
|
+
*/
|
|
19
|
+
export interface AgentToolDisplay {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
category: ToolCategory;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface AgentToolsBoxProps {
|
|
26
|
+
/** Tool instances currently attached to the agent */
|
|
27
|
+
tools: AddedToolInstance[];
|
|
28
|
+
/** Available tool definitions for resolving category info */
|
|
29
|
+
availableTools: ToolDefinition[];
|
|
30
|
+
/** Currently selected tool instance ID (being configured) */
|
|
31
|
+
selectedInstanceId?: string | null;
|
|
32
|
+
/** Called when user clicks "Add Tool" button */
|
|
33
|
+
onAddTool?: () => void;
|
|
34
|
+
/** Called when user wants to see all selected tools (opens modal with filter) */
|
|
35
|
+
onShowMore?: () => void;
|
|
36
|
+
/** Called when user clicks on a tool (to configure it) */
|
|
37
|
+
onToolClick?: (tool: AddedToolInstance) => void;
|
|
38
|
+
/** Called when user clicks remove button on a tool */
|
|
39
|
+
onRemoveTool?: (instanceId: string) => void;
|
|
40
|
+
/** Additional CSS classes */
|
|
41
|
+
className?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Maximum visible tools in grid (2 columns x 3 rows)
|
|
45
|
+
const MAX_VISIBLE_TOOLS = 6;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* ToolTile - Compact square tile for displaying a tool in the grid
|
|
49
|
+
*/
|
|
50
|
+
const ToolTile = memo(function ToolTile({
|
|
51
|
+
tool,
|
|
52
|
+
toolDef,
|
|
53
|
+
isSelected,
|
|
54
|
+
onToolClick,
|
|
55
|
+
onRemoveTool: _onRemoveTool,
|
|
56
|
+
}: {
|
|
57
|
+
tool: AddedToolInstance;
|
|
58
|
+
toolDef: ToolDefinition | undefined;
|
|
59
|
+
isSelected?: boolean;
|
|
60
|
+
onToolClick?: (tool: AddedToolInstance) => void;
|
|
61
|
+
onRemoveTool?: (instanceId: string) => void;
|
|
62
|
+
}) {
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
className={cn(
|
|
66
|
+
'group relative flex flex-row items-center p-1 gap-1 rounded-md border cursor-pointer transition-colors w-[99px]',
|
|
67
|
+
'hover:bg-accent hover:border-accent-foreground/20',
|
|
68
|
+
isSelected && 'bg-accent border-primary ring-1 ring-primary/30',
|
|
69
|
+
)}
|
|
70
|
+
onClick={() => onToolClick?.(tool)}
|
|
71
|
+
title={tool.name}
|
|
72
|
+
>
|
|
73
|
+
{toolDef?.provider?.svgIcon || toolDef?.provider?.icon || toolDef?.provider?.id ? (
|
|
74
|
+
<ProviderIcon
|
|
75
|
+
providerId={toolDef?.provider?.id}
|
|
76
|
+
svgIcon={toolDef?.provider?.svgIcon}
|
|
77
|
+
icon={toolDef?.provider?.icon}
|
|
78
|
+
className="w-5 h-5 shrink-0"
|
|
79
|
+
/>
|
|
80
|
+
) : null}
|
|
81
|
+
<span className="text-[10px] truncate w-full">{tool.name}</span>
|
|
82
|
+
</div>
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* AgentToolsBox - Displays and manages tools attached to an AI Agent node
|
|
88
|
+
*
|
|
89
|
+
* Renders as a compact grid showing tool tiles with category-based styling.
|
|
90
|
+
* Shows max 2x3 grid with "show more" button if there are more tools.
|
|
91
|
+
*/
|
|
92
|
+
export const AgentToolsBox = memo(function AgentToolsBox({
|
|
93
|
+
tools,
|
|
94
|
+
availableTools,
|
|
95
|
+
selectedInstanceId,
|
|
96
|
+
onAddTool,
|
|
97
|
+
onShowMore,
|
|
98
|
+
onToolClick,
|
|
99
|
+
onRemoveTool,
|
|
100
|
+
className,
|
|
101
|
+
}: AgentToolsBoxProps) {
|
|
102
|
+
const isEmpty = tools.length === 0;
|
|
103
|
+
const hasMoreTools = tools.length > MAX_VISIBLE_TOOLS;
|
|
104
|
+
const visibleTools = hasMoreTools ? tools.slice(0, MAX_VISIBLE_TOOLS - 1) : tools;
|
|
105
|
+
const hiddenCount = tools.length - visibleTools.length;
|
|
106
|
+
|
|
107
|
+
// Helper to get tool definition by toolId
|
|
108
|
+
const getToolDef = (toolId: string) => availableTools.find((t) => t.id === toolId);
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div className={cn('w-[220px] p-2', className)}>
|
|
112
|
+
{/* Header - only show if we have tools */}
|
|
113
|
+
{!isEmpty && (
|
|
114
|
+
<div className="mb-2 text-xs font-medium text-muted-foreground">Tools ({tools.length})</div>
|
|
115
|
+
)}
|
|
116
|
+
|
|
117
|
+
{isEmpty ? (
|
|
118
|
+
/* Empty state - prominent add button */
|
|
119
|
+
onAddTool && (
|
|
120
|
+
<button
|
|
121
|
+
onClick={(e) => {
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
onAddTool();
|
|
125
|
+
}}
|
|
126
|
+
className="flex flex-col items-center justify-center w-full gap-2 p-4 transition-all border-2 border-dashed rounded-lg border-muted-foreground/30 text-muted-foreground hover:border-primary/50 hover:text-primary hover:bg-primary/5"
|
|
127
|
+
>
|
|
128
|
+
<div className="flex items-center justify-center w-10 h-10 rounded-full bg-muted">
|
|
129
|
+
<Plus className="w-5 h-5" />
|
|
130
|
+
</div>
|
|
131
|
+
<div className="text-center">
|
|
132
|
+
<div className="text-xs font-medium">Add Tools</div>
|
|
133
|
+
<div className="text-[10px] opacity-70">Give the agent capabilities</div>
|
|
134
|
+
</div>
|
|
135
|
+
</button>
|
|
136
|
+
)
|
|
137
|
+
) : (
|
|
138
|
+
/* Tools grid */
|
|
139
|
+
<div className="space-y-2">
|
|
140
|
+
<div className="grid grid-cols-2 gap-1.5">
|
|
141
|
+
{visibleTools.map((tool) => (
|
|
142
|
+
<ToolTile
|
|
143
|
+
key={tool.instanceId}
|
|
144
|
+
tool={tool}
|
|
145
|
+
toolDef={getToolDef(tool.toolId)}
|
|
146
|
+
isSelected={selectedInstanceId === tool.instanceId}
|
|
147
|
+
onToolClick={onToolClick}
|
|
148
|
+
onRemoveTool={onRemoveTool}
|
|
149
|
+
/>
|
|
150
|
+
))}
|
|
151
|
+
|
|
152
|
+
{/* Show more button - takes place of last tile when there are more tools */}
|
|
153
|
+
{hasMoreTools && (
|
|
154
|
+
<button
|
|
155
|
+
onClick={(e) => {
|
|
156
|
+
e.stopPropagation();
|
|
157
|
+
e.preventDefault();
|
|
158
|
+
onShowMore?.();
|
|
159
|
+
}}
|
|
160
|
+
className="flex items-center justify-center transition-colors border border-dashed rounded-md cursor-pointer border-muted-foreground/50 text-muted-foreground hover:border-primary hover:text-primary hover:bg-primary/5"
|
|
161
|
+
title={`Show ${hiddenCount} more tools`}
|
|
162
|
+
>
|
|
163
|
+
<span className="text-[10px]">+{hiddenCount} more</span>
|
|
164
|
+
</button>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
{/* Configure button */}
|
|
169
|
+
{onAddTool && (
|
|
170
|
+
<button
|
|
171
|
+
onClick={(e) => {
|
|
172
|
+
e.stopPropagation();
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
onAddTool();
|
|
175
|
+
}}
|
|
176
|
+
className="flex items-center justify-center gap-1.5 rounded-md border border-dashed border-muted-foreground/50 px-2 py-1.5 text-xs text-muted-foreground hover:border-muted-foreground hover:text-foreground transition-colors w-full"
|
|
177
|
+
>
|
|
178
|
+
<Settings className="w-3 h-3" />
|
|
179
|
+
<span>Configure</span>
|
|
180
|
+
</button>
|
|
181
|
+
)}
|
|
182
|
+
</div>
|
|
183
|
+
)}
|
|
184
|
+
|
|
185
|
+
{/* Empty state - only show if no add button */}
|
|
186
|
+
{isEmpty && !onAddTool && (
|
|
187
|
+
<div className="text-xs italic text-muted-foreground/60">No tools configured</div>
|
|
188
|
+
)}
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
AgentToolsBox.displayName = 'AgentToolsBox';
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
import { MoveVertical, MoveHorizontal } from 'lucide-react';
|
|
3
|
+
import { cn } from '../../lib/utils';
|
|
4
|
+
|
|
5
|
+
export type AppendixPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
6
|
+
|
|
7
|
+
interface NodeAppendixProps {
|
|
8
|
+
position?: AppendixPosition;
|
|
9
|
+
onPositionChange?: (position: AppendixPosition) => void;
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Override the default border class (e.g. for selected/hover/state colours) */
|
|
13
|
+
borderClassName?: string;
|
|
14
|
+
/** Whether to show the position toggle button */
|
|
15
|
+
showPositionToggle?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const positionClasses: Record<AppendixPosition, string> = {
|
|
19
|
+
top: 'bottom-full left-1/2 -translate-x-1/2 mb-2 flex-col-reverse',
|
|
20
|
+
bottom: 'top-full left-1/2 -translate-x-1/2 mt-2 flex-col',
|
|
21
|
+
left: 'right-full top-1/2 -translate-y-1/2 mr-2 flex-row-reverse',
|
|
22
|
+
right: 'left-full top-1/2 -translate-y-1/2 ml-2 flex-row',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const connectorClasses: Record<AppendixPosition, string> = {
|
|
26
|
+
top: 'w-px h-2 mx-auto',
|
|
27
|
+
bottom: 'w-px h-2 mx-auto',
|
|
28
|
+
left: 'h-px w-2 my-auto',
|
|
29
|
+
right: 'h-px w-2 my-auto',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const positionCycle: AppendixPosition[] = ['bottom', 'right', 'top', 'left'];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* NodeAppendix - A reusable component that renders an attached panel to a node
|
|
36
|
+
*
|
|
37
|
+
* Used to display additional content like tools, configurations, or previews
|
|
38
|
+
* that are visually connected to a node but rendered outside its bounds.
|
|
39
|
+
*/
|
|
40
|
+
export const NodeAppendix = memo(function NodeAppendix({
|
|
41
|
+
position = 'bottom',
|
|
42
|
+
onPositionChange,
|
|
43
|
+
children,
|
|
44
|
+
className,
|
|
45
|
+
borderClassName,
|
|
46
|
+
showPositionToggle = true,
|
|
47
|
+
}: NodeAppendixProps) {
|
|
48
|
+
const handlePositionToggle = () => {
|
|
49
|
+
if (!onPositionChange) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const currentIndex = positionCycle.indexOf(position);
|
|
53
|
+
const nextIndex = (currentIndex + 1) % positionCycle.length;
|
|
54
|
+
onPositionChange(positionCycle[nextIndex]);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const isVertical = position === 'top' || position === 'bottom';
|
|
58
|
+
const ToggleIcon = isVertical ? MoveVertical : MoveHorizontal;
|
|
59
|
+
|
|
60
|
+
const resolvedBorderClass = borderClassName || 'border-sidebar-ring';
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div className={cn('absolute flex items-center nowheel nopan', positionClasses[position])}>
|
|
64
|
+
{/* Connector line */}
|
|
65
|
+
<div className={cn('bg-sidebar-ring', connectorClasses[position])} />
|
|
66
|
+
|
|
67
|
+
{/* Content container */}
|
|
68
|
+
<div
|
|
69
|
+
className={cn(
|
|
70
|
+
'relative rounded-lg border bg-card shadow-md nodrag transition-colors',
|
|
71
|
+
resolvedBorderClass,
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
>
|
|
75
|
+
{/* Position toggle button */}
|
|
76
|
+
{showPositionToggle && onPositionChange && (
|
|
77
|
+
<button
|
|
78
|
+
onClick={(e) => {
|
|
79
|
+
e.stopPropagation();
|
|
80
|
+
handlePositionToggle();
|
|
81
|
+
}}
|
|
82
|
+
className={cn(
|
|
83
|
+
'absolute z-10 flex items-center justify-center w-5 h-5 transition-colors border rounded-full -top-2 -right-2 bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground',
|
|
84
|
+
resolvedBorderClass,
|
|
85
|
+
)}
|
|
86
|
+
title="Change position"
|
|
87
|
+
>
|
|
88
|
+
<ToggleIcon className="w-3 h-3" />
|
|
89
|
+
</button>
|
|
90
|
+
)}
|
|
91
|
+
|
|
92
|
+
{children}
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
NodeAppendix.displayName = 'NodeAppendix';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cn } from '../../lib/utils';
|
|
3
|
+
|
|
4
|
+
export type NodeStatusIndicatorStatus = 'initial' | 'loading' | 'success' | 'error';
|
|
5
|
+
export type NodeStatusIndicatorLoadingVariant = 'border' | 'overlay';
|
|
6
|
+
|
|
7
|
+
interface NodeStatusIndicatorProps {
|
|
8
|
+
status: NodeStatusIndicatorStatus;
|
|
9
|
+
loadingVariant?: NodeStatusIndicatorLoadingVariant;
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
className?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A node wrapper that indicates the status of a node via a border effect.
|
|
16
|
+
*
|
|
17
|
+
* Status can be:
|
|
18
|
+
* - "initial" - no status indicator (default state)
|
|
19
|
+
* - "loading" - animated conic gradient border that rotates
|
|
20
|
+
* - "success" - green border
|
|
21
|
+
* - "error" - red border
|
|
22
|
+
*
|
|
23
|
+
* Loading variants:
|
|
24
|
+
* - "border" - animated gradient border around the node (default)
|
|
25
|
+
* - "overlay" - full overlay with spinner
|
|
26
|
+
*
|
|
27
|
+
* The animated border uses CSS @property for the conic gradient angle animation.
|
|
28
|
+
* This is supported in Chrome/Chromium browsers. Firefox will show a static gradient.
|
|
29
|
+
*/
|
|
30
|
+
export function NodeStatusIndicator({
|
|
31
|
+
status,
|
|
32
|
+
loadingVariant = 'border',
|
|
33
|
+
children,
|
|
34
|
+
className,
|
|
35
|
+
}: NodeStatusIndicatorProps) {
|
|
36
|
+
// For initial status, just render children without any wrapper styling
|
|
37
|
+
if (status === 'initial') {
|
|
38
|
+
return <div className={className}>{children}</div>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const isLoading = status === 'loading';
|
|
42
|
+
const isSuccess = status === 'success';
|
|
43
|
+
const isError = status === 'error';
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className={cn('relative node-status-active', className)}>
|
|
47
|
+
{/* Status border wrapper */}
|
|
48
|
+
<div
|
|
49
|
+
className={cn(
|
|
50
|
+
'relative rounded-xl',
|
|
51
|
+
// Success state - static green border
|
|
52
|
+
isSuccess && 'ring-2 ring-green-500 ring-offset-0 ring-offset-background',
|
|
53
|
+
// Error state - static red border
|
|
54
|
+
isError && 'ring-2 ring-red-500 ring-offset-0 ring-offset-background',
|
|
55
|
+
// Loading state with border variant - animated gradient border using CSS @property
|
|
56
|
+
isLoading &&
|
|
57
|
+
loadingVariant === 'border' &&
|
|
58
|
+
'node-running-border rounded-xl border border-transparent animate-node-border',
|
|
59
|
+
)}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
{/* Loading overlay variant */}
|
|
65
|
+
{isLoading && loadingVariant === 'overlay' && (
|
|
66
|
+
<div className="absolute inset-0 flex items-center justify-center rounded-lg bg-background/60 backdrop-blur-[1px]">
|
|
67
|
+
<div className="w-6 h-6 border-2 rounded-full border-t-transparent border-primary animate-spin" />
|
|
68
|
+
</div>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
NodeStatusIndicator.displayName = 'NodeStatusIndicator';
|