@flowdrop/flowdrop 1.0.0
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 +252 -0
- package/dist/adapters/WorkflowAdapter.d.ts +167 -0
- package/dist/adapters/WorkflowAdapter.js +368 -0
- package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +96 -0
- package/dist/adapters/agentspec/AgentSpecAdapter.js +626 -0
- package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
- package/dist/adapters/agentspec/agentAdapter.js +91 -0
- package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
- package/dist/adapters/agentspec/autoLayout.js +127 -0
- package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
- package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
- package/dist/adapters/agentspec/defaultNodeTypes.d.ts +53 -0
- package/dist/adapters/agentspec/defaultNodeTypes.js +561 -0
- package/dist/adapters/agentspec/index.d.ts +37 -0
- package/dist/adapters/agentspec/index.js +39 -0
- package/dist/adapters/agentspec/validator.d.ts +34 -0
- package/dist/adapters/agentspec/validator.js +169 -0
- package/dist/api/enhanced-client.d.ts +183 -0
- package/dist/api/enhanced-client.js +430 -0
- package/dist/components/App.svelte +981 -0
- package/dist/components/App.svelte.d.ts +54 -0
- package/dist/components/CanvasBanner.stories.svelte +29 -0
- package/dist/components/CanvasBanner.stories.svelte.d.ts +27 -0
- package/dist/components/CanvasBanner.svelte +57 -0
- package/dist/components/CanvasBanner.svelte.d.ts +8 -0
- package/dist/components/ConfigForm.svelte +1138 -0
- package/dist/components/ConfigForm.svelte.d.ts +44 -0
- package/dist/components/ConfigModal.svelte +188 -0
- package/dist/components/ConfigModal.svelte.d.ts +13 -0
- package/dist/components/ConfigPanel.stories.svelte +47 -0
- package/dist/components/ConfigPanel.stories.svelte.d.ts +27 -0
- package/dist/components/ConfigPanel.svelte +182 -0
- package/dist/components/ConfigPanel.svelte.d.ts +32 -0
- package/dist/components/ConnectionLine.svelte +32 -0
- package/dist/components/ConnectionLine.svelte.d.ts +3 -0
- package/dist/components/EdgeRefresher.svelte +41 -0
- package/dist/components/EdgeRefresher.svelte.d.ts +9 -0
- package/dist/components/FlowDropZone.svelte +83 -0
- package/dist/components/FlowDropZone.svelte.d.ts +13 -0
- package/dist/components/LoadingSpinner.stories.svelte +30 -0
- package/dist/components/LoadingSpinner.stories.svelte.d.ts +27 -0
- package/dist/components/LoadingSpinner.svelte +36 -0
- package/dist/components/LoadingSpinner.svelte.d.ts +8 -0
- package/dist/components/Logo.stories.svelte +22 -0
- package/dist/components/Logo.stories.svelte.d.ts +27 -0
- package/dist/components/Logo.svelte +102 -0
- package/dist/components/Logo.svelte.d.ts +26 -0
- package/dist/components/LogsSidebar.svelte +563 -0
- package/dist/components/LogsSidebar.svelte.d.ts +17 -0
- package/dist/components/MarkdownDisplay.stories.svelte +36 -0
- package/dist/components/MarkdownDisplay.stories.svelte.d.ts +27 -0
- package/dist/components/MarkdownDisplay.svelte +29 -0
- package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
- package/dist/components/Navbar.stories.svelte +53 -0
- package/dist/components/Navbar.stories.svelte.d.ts +27 -0
- package/dist/components/Navbar.svelte +726 -0
- package/dist/components/Navbar.svelte.d.ts +29 -0
- package/dist/components/NodeSidebar.svelte +762 -0
- package/dist/components/NodeSidebar.svelte.d.ts +9 -0
- package/dist/components/NodeStatusOverlay.stories.svelte +85 -0
- package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +27 -0
- package/dist/components/NodeStatusOverlay.svelte +327 -0
- package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
- package/dist/components/PipelineStatus.svelte +314 -0
- package/dist/components/PipelineStatus.svelte.d.ts +20 -0
- package/dist/components/PortCoordinateTracker.svelte +58 -0
- package/dist/components/PortCoordinateTracker.svelte.d.ts +12 -0
- package/dist/components/ReadOnlyDetails.svelte +170 -0
- package/dist/components/ReadOnlyDetails.svelte.d.ts +25 -0
- package/dist/components/SchemaForm.stories.svelte +116 -0
- package/dist/components/SchemaForm.stories.svelte.d.ts +27 -0
- package/dist/components/SchemaForm.svelte +536 -0
- package/dist/components/SchemaForm.svelte.d.ts +83 -0
- package/dist/components/SettingsModal.svelte +279 -0
- package/dist/components/SettingsModal.svelte.d.ts +23 -0
- package/dist/components/SettingsPanel.svelte +638 -0
- package/dist/components/SettingsPanel.svelte.d.ts +21 -0
- package/dist/components/StatusIcon.stories.svelte +60 -0
- package/dist/components/StatusIcon.stories.svelte.d.ts +27 -0
- package/dist/components/StatusIcon.svelte +119 -0
- package/dist/components/StatusIcon.svelte.d.ts +10 -0
- package/dist/components/StatusLabel.stories.svelte +17 -0
- package/dist/components/StatusLabel.stories.svelte.d.ts +27 -0
- package/dist/components/StatusLabel.svelte +33 -0
- package/dist/components/StatusLabel.svelte.d.ts +7 -0
- package/dist/components/ThemeToggle.stories.svelte +25 -0
- package/dist/components/ThemeToggle.stories.svelte.d.ts +27 -0
- package/dist/components/ThemeToggle.svelte +185 -0
- package/dist/components/ThemeToggle.svelte.d.ts +14 -0
- package/dist/components/UniversalNode.svelte +155 -0
- package/dist/components/UniversalNode.svelte.d.ts +15 -0
- package/dist/components/WorkflowEditor.svelte +1035 -0
- package/dist/components/WorkflowEditor.svelte.d.ts +23 -0
- package/dist/components/form/FormArray.svelte +1049 -0
- package/dist/components/form/FormArray.svelte.d.ts +22 -0
- package/dist/components/form/FormAutocomplete.svelte +1009 -0
- package/dist/components/form/FormAutocomplete.svelte.d.ts +25 -0
- package/dist/components/form/FormCheckboxGroup.stories.svelte +28 -0
- package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormCheckboxGroup.svelte +155 -0
- package/dist/components/form/FormCheckboxGroup.svelte.d.ts +17 -0
- package/dist/components/form/FormCodeEditor.svelte +458 -0
- package/dist/components/form/FormCodeEditor.svelte.d.ts +25 -0
- package/dist/components/form/FormField.svelte +417 -0
- package/dist/components/form/FormField.svelte.d.ts +29 -0
- package/dist/components/form/FormFieldLight.svelte +425 -0
- package/dist/components/form/FormFieldLight.svelte.d.ts +18 -0
- package/dist/components/form/FormFieldWrapper.stories.svelte +53 -0
- package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormFieldWrapper.svelte +125 -0
- package/dist/components/form/FormFieldWrapper.svelte.d.ts +18 -0
- package/dist/components/form/FormFieldset.svelte +142 -0
- package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
- package/dist/components/form/FormMarkdownEditor.svelte +752 -0
- package/dist/components/form/FormMarkdownEditor.svelte.d.ts +33 -0
- package/dist/components/form/FormNumberField.stories.svelte +36 -0
- package/dist/components/form/FormNumberField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormNumberField.svelte +112 -0
- package/dist/components/form/FormNumberField.svelte.d.ts +25 -0
- package/dist/components/form/FormRangeField.stories.svelte +31 -0
- package/dist/components/form/FormRangeField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormRangeField.svelte +246 -0
- package/dist/components/form/FormRangeField.svelte.d.ts +23 -0
- package/dist/components/form/FormSelect.stories.svelte +50 -0
- package/dist/components/form/FormSelect.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormSelect.svelte +129 -0
- package/dist/components/form/FormSelect.svelte.d.ts +20 -0
- package/dist/components/form/FormTemplateEditor.svelte +825 -0
- package/dist/components/form/FormTemplateEditor.svelte.d.ts +41 -0
- package/dist/components/form/FormTextField.stories.svelte +30 -0
- package/dist/components/form/FormTextField.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTextField.svelte +91 -0
- package/dist/components/form/FormTextField.svelte.d.ts +19 -0
- package/dist/components/form/FormTextarea.stories.svelte +34 -0
- package/dist/components/form/FormTextarea.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormTextarea.svelte +97 -0
- package/dist/components/form/FormTextarea.svelte.d.ts +21 -0
- package/dist/components/form/FormToggle.stories.svelte +30 -0
- package/dist/components/form/FormToggle.stories.svelte.d.ts +27 -0
- package/dist/components/form/FormToggle.svelte +126 -0
- package/dist/components/form/FormToggle.svelte.d.ts +19 -0
- package/dist/components/form/FormUISchemaRenderer.svelte +136 -0
- package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
- package/dist/components/form/index.d.ts +50 -0
- package/dist/components/form/index.js +54 -0
- package/dist/components/form/templateAutocomplete.d.ts +29 -0
- package/dist/components/form/templateAutocomplete.js +254 -0
- package/dist/components/form/types.d.ts +485 -0
- package/dist/components/form/types.js +73 -0
- package/dist/components/interrupt/ChoicePrompt.stories.svelte +52 -0
- package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ChoicePrompt.svelte +401 -0
- package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +71 -0
- package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte +292 -0
- package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +25 -0
- package/dist/components/interrupt/FormPrompt.svelte +236 -0
- package/dist/components/interrupt/FormPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/InterruptBubble.svelte +601 -0
- package/dist/components/interrupt/InterruptBubble.svelte.d.ts +16 -0
- package/dist/components/interrupt/ReviewPrompt.stories.svelte +67 -0
- package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/ReviewPrompt.svelte +861 -0
- package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte +47 -0
- package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +27 -0
- package/dist/components/interrupt/TextInputPrompt.svelte +346 -0
- package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +23 -0
- package/dist/components/interrupt/index.d.ts +13 -0
- package/dist/components/interrupt/index.js +15 -0
- package/dist/components/layouts/MainLayout.svelte +718 -0
- package/dist/components/layouts/MainLayout.svelte.d.ts +62 -0
- package/dist/components/nodes/GatewayNode.stories.svelte +108 -0
- package/dist/components/nodes/GatewayNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +591 -0
- package/dist/components/nodes/GatewayNode.svelte.d.ts +15 -0
- package/dist/components/nodes/IdeaNode.stories.svelte +52 -0
- package/dist/components/nodes/IdeaNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/IdeaNode.svelte +455 -0
- package/dist/components/nodes/IdeaNode.svelte.d.ts +24 -0
- package/dist/components/nodes/NotesNode.stories.svelte +76 -0
- package/dist/components/nodes/NotesNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/NotesNode.svelte +378 -0
- package/dist/components/nodes/NotesNode.svelte.d.ts +24 -0
- package/dist/components/nodes/SimpleNode.stories.svelte +159 -0
- package/dist/components/nodes/SimpleNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SimpleNode.svelte +451 -0
- package/dist/components/nodes/SimpleNode.svelte.d.ts +25 -0
- package/dist/components/nodes/SquareNode.stories.svelte +82 -0
- package/dist/components/nodes/SquareNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/SquareNode.svelte +407 -0
- package/dist/components/nodes/SquareNode.svelte.d.ts +25 -0
- package/dist/components/nodes/TerminalNode.stories.svelte +25 -0
- package/dist/components/nodes/TerminalNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/TerminalNode.svelte +690 -0
- package/dist/components/nodes/TerminalNode.svelte.d.ts +25 -0
- package/dist/components/nodes/ToolNode.stories.svelte +189 -0
- package/dist/components/nodes/ToolNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/ToolNode.svelte +471 -0
- package/dist/components/nodes/ToolNode.svelte.d.ts +36 -0
- package/dist/components/nodes/WorkflowNode.stories.svelte +55 -0
- package/dist/components/nodes/WorkflowNode.stories.svelte.d.ts +26 -0
- package/dist/components/nodes/WorkflowNode.svelte +571 -0
- package/dist/components/nodes/WorkflowNode.svelte.d.ts +15 -0
- package/dist/components/playground/ChatPanel.svelte +905 -0
- package/dist/components/playground/ChatPanel.svelte.d.ts +46 -0
- package/dist/components/playground/ExecutionLogs.svelte +488 -0
- package/dist/components/playground/ExecutionLogs.svelte.d.ts +14 -0
- package/dist/components/playground/InputCollector.svelte +444 -0
- package/dist/components/playground/InputCollector.svelte.d.ts +16 -0
- package/dist/components/playground/MessageBubble.stories.svelte +62 -0
- package/dist/components/playground/MessageBubble.stories.svelte.d.ts +27 -0
- package/dist/components/playground/MessageBubble.svelte +633 -0
- package/dist/components/playground/MessageBubble.svelte.d.ts +24 -0
- package/dist/components/playground/Playground.svelte +1075 -0
- package/dist/components/playground/Playground.svelte.d.ts +25 -0
- package/dist/components/playground/PlaygroundModal.svelte +220 -0
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +25 -0
- package/dist/components/playground/SessionManager.svelte +538 -0
- package/dist/components/playground/SessionManager.svelte.d.ts +20 -0
- package/dist/config/agentSpecEndpoints.d.ts +70 -0
- package/dist/config/agentSpecEndpoints.js +65 -0
- package/dist/config/constants.d.ts +43 -0
- package/dist/config/constants.js +31 -0
- package/dist/config/defaultCategories.d.ts +7 -0
- package/dist/config/defaultCategories.js +126 -0
- package/dist/config/defaultPortConfig.d.ts +6 -0
- package/dist/config/defaultPortConfig.js +201 -0
- package/dist/config/endpoints.d.ts +160 -0
- package/dist/config/endpoints.js +146 -0
- package/dist/config/runtimeConfig.d.ts +47 -0
- package/dist/config/runtimeConfig.js +80 -0
- package/dist/core/index.d.ts +75 -0
- package/dist/core/index.js +92 -0
- package/dist/display/index.d.ts +29 -0
- package/dist/display/index.js +36 -0
- package/dist/editor/index.d.ts +95 -0
- package/dist/editor/index.js +138 -0
- package/dist/form/code.d.ts +101 -0
- package/dist/form/code.js +168 -0
- package/dist/form/fieldRegistry.d.ts +169 -0
- package/dist/form/fieldRegistry.js +152 -0
- package/dist/form/full.d.ts +56 -0
- package/dist/form/full.js +80 -0
- package/dist/form/index.d.ts +77 -0
- package/dist/form/index.js +91 -0
- package/dist/form/markdown.d.ts +69 -0
- package/dist/form/markdown.js +103 -0
- package/dist/helpers/nodeLayoutHelper.d.ts +14 -0
- package/dist/helpers/nodeLayoutHelper.js +19 -0
- package/dist/helpers/proximityConnect.d.ts +94 -0
- package/dist/helpers/proximityConnect.js +314 -0
- package/dist/helpers/workflowEditorHelper.d.ts +183 -0
- package/dist/helpers/workflowEditorHelper.js +595 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +64 -0
- package/dist/mocks/app-environment.d.ts +8 -0
- package/dist/mocks/app-environment.js +16 -0
- package/dist/mocks/app-forms.d.ts +2 -0
- package/dist/mocks/app-forms.js +22 -0
- package/dist/mocks/app-navigation.d.ts +5 -0
- package/dist/mocks/app-navigation.js +36 -0
- package/dist/mocks/app-stores.d.ts +14 -0
- package/dist/mocks/app-stores.js +26 -0
- package/dist/playground/index.d.ts +131 -0
- package/dist/playground/index.js +172 -0
- package/dist/playground/mount.d.ts +203 -0
- package/dist/playground/mount.js +235 -0
- package/dist/registry/BaseRegistry.d.ts +92 -0
- package/dist/registry/BaseRegistry.js +124 -0
- package/dist/registry/builtinFormats.d.ts +23 -0
- package/dist/registry/builtinFormats.js +70 -0
- package/dist/registry/builtinNodes.d.ts +77 -0
- package/dist/registry/builtinNodes.js +211 -0
- package/dist/registry/index.d.ts +8 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/nodeComponentRegistry.d.ts +276 -0
- package/dist/registry/nodeComponentRegistry.js +262 -0
- package/dist/registry/plugin.d.ts +215 -0
- package/dist/registry/plugin.js +249 -0
- package/dist/registry/workflowFormatRegistry.d.ts +122 -0
- package/dist/registry/workflowFormatRegistry.js +96 -0
- package/dist/schema/index.d.ts +23 -0
- package/dist/schema/index.js +23 -0
- package/dist/schemas/v1/workflow.schema.json +1078 -0
- package/dist/services/agentSpecExecutionService.d.ts +106 -0
- package/dist/services/agentSpecExecutionService.js +334 -0
- package/dist/services/api.d.ts +115 -0
- package/dist/services/api.js +214 -0
- package/dist/services/apiVariableService.d.ts +114 -0
- package/dist/services/apiVariableService.js +338 -0
- package/dist/services/autoSaveService.d.ts +112 -0
- package/dist/services/autoSaveService.js +227 -0
- package/dist/services/categoriesApi.d.ts +14 -0
- package/dist/services/categoriesApi.js +49 -0
- package/dist/services/draftStorage.d.ts +171 -0
- package/dist/services/draftStorage.js +299 -0
- package/dist/services/dynamicSchemaService.d.ts +108 -0
- package/dist/services/dynamicSchemaService.js +444 -0
- package/dist/services/globalSave.d.ts +69 -0
- package/dist/services/globalSave.js +248 -0
- package/dist/services/historyService.d.ts +208 -0
- package/dist/services/historyService.js +321 -0
- package/dist/services/interruptService.d.ts +133 -0
- package/dist/services/interruptService.js +280 -0
- package/dist/services/nodeExecutionService.d.ts +63 -0
- package/dist/services/nodeExecutionService.js +266 -0
- package/dist/services/playgroundService.d.ts +130 -0
- package/dist/services/playgroundService.js +321 -0
- package/dist/services/portConfigApi.d.ts +14 -0
- package/dist/services/portConfigApi.js +54 -0
- package/dist/services/settingsService.d.ts +92 -0
- package/dist/services/settingsService.js +196 -0
- package/dist/services/toastService.d.ts +156 -0
- package/dist/services/toastService.js +265 -0
- package/dist/services/variableService.d.ts +141 -0
- package/dist/services/variableService.js +463 -0
- package/dist/services/workflowStorage.d.ts +37 -0
- package/dist/services/workflowStorage.js +116 -0
- package/dist/settings/index.d.ts +25 -0
- package/dist/settings/index.js +33 -0
- package/dist/stores/categoriesStore.svelte.d.ts +32 -0
- package/dist/stores/categoriesStore.svelte.js +77 -0
- package/dist/stores/editorStateMachine.svelte.d.ts +42 -0
- package/dist/stores/editorStateMachine.svelte.js +132 -0
- package/dist/stores/historyStore.svelte.d.ts +136 -0
- package/dist/stores/historyStore.svelte.js +207 -0
- package/dist/stores/interruptStore.svelte.d.ts +179 -0
- package/dist/stores/interruptStore.svelte.js +346 -0
- package/dist/stores/playgroundStore.svelte.d.ts +230 -0
- package/dist/stores/playgroundStore.svelte.js +515 -0
- package/dist/stores/portCoordinateStore.svelte.d.ts +66 -0
- package/dist/stores/portCoordinateStore.svelte.js +186 -0
- package/dist/stores/settingsStore.svelte.d.ts +158 -0
- package/dist/stores/settingsStore.svelte.js +544 -0
- package/dist/stores/workflowStore.svelte.d.ts +260 -0
- package/dist/stores/workflowStore.svelte.js +649 -0
- package/dist/stories/CanvasDecorator.svelte +49 -0
- package/dist/stories/CanvasDecorator.svelte.d.ts +8 -0
- package/dist/stories/NodeDecorator.svelte +73 -0
- package/dist/stories/NodeDecorator.svelte.d.ts +8 -0
- package/dist/stories/utils.d.ts +93 -0
- package/dist/stories/utils.js +122 -0
- package/dist/styles/base.css +1300 -0
- package/dist/styles/toast.css +35 -0
- package/dist/styles/tokens.css +475 -0
- package/dist/svelte-app.d.ts +150 -0
- package/dist/svelte-app.js +295 -0
- package/dist/types/agentspec.d.ts +318 -0
- package/dist/types/agentspec.js +48 -0
- package/dist/types/auth.d.ts +263 -0
- package/dist/types/auth.js +229 -0
- package/dist/types/config.d.ts +151 -0
- package/dist/types/config.js +7 -0
- package/dist/types/events.d.ts +190 -0
- package/dist/types/events.js +30 -0
- package/dist/types/index.d.ts +1234 -0
- package/dist/types/index.js +27 -0
- package/dist/types/interrupt.d.ts +390 -0
- package/dist/types/interrupt.js +145 -0
- package/dist/types/interruptState.d.ts +211 -0
- package/dist/types/interruptState.js +308 -0
- package/dist/types/playground.d.ts +351 -0
- package/dist/types/playground.js +95 -0
- package/dist/types/settings.d.ts +189 -0
- package/dist/types/settings.js +97 -0
- package/dist/types/uischema.d.ts +144 -0
- package/dist/types/uischema.js +51 -0
- package/dist/utils/colors.d.ts +288 -0
- package/dist/utils/colors.js +548 -0
- package/dist/utils/config.d.ts +37 -0
- package/dist/utils/config.js +226 -0
- package/dist/utils/connections.d.ts +125 -0
- package/dist/utils/connections.js +414 -0
- package/dist/utils/errors.d.ts +28 -0
- package/dist/utils/errors.js +44 -0
- package/dist/utils/fetchWithAuth.d.ts +25 -0
- package/dist/utils/fetchWithAuth.js +34 -0
- package/dist/utils/handleIds.d.ts +35 -0
- package/dist/utils/handleIds.js +58 -0
- package/dist/utils/handlePositioning.d.ts +31 -0
- package/dist/utils/handlePositioning.js +35 -0
- package/dist/utils/icons.d.ts +106 -0
- package/dist/utils/icons.js +157 -0
- package/dist/utils/logger.d.ts +47 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/nodeStatus.d.ts +53 -0
- package/dist/utils/nodeStatus.js +183 -0
- package/dist/utils/nodeTypes.d.ts +117 -0
- package/dist/utils/nodeTypes.js +244 -0
- package/dist/utils/nodeWrapper.d.ts +39 -0
- package/dist/utils/nodeWrapper.js +62 -0
- package/dist/utils/performanceUtils.d.ts +30 -0
- package/dist/utils/performanceUtils.js +108 -0
- package/dist/utils/sanitize.d.ts +19 -0
- package/dist/utils/sanitize.js +31 -0
- package/dist/utils/uischema.d.ts +52 -0
- package/dist/utils/uischema.js +88 -0
- package/dist/utils/validation.d.ts +29 -0
- package/dist/utils/validation.js +39 -0
- package/package.json +292 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflow Editor Helper
|
|
3
|
+
* Contains business logic for workflow operations
|
|
4
|
+
*/
|
|
5
|
+
import { MarkerType } from '@xyflow/svelte';
|
|
6
|
+
import { hasCycles, hasInvalidCycles, isLoopbackEdge } from '../utils/connections.js';
|
|
7
|
+
import { workflowApi, nodeApi, setEndpointConfig } from '../services/api.js';
|
|
8
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
+
import { workflowActions } from '../stores/workflowStore.svelte.js';
|
|
10
|
+
import { nodeExecutionService } from '../services/nodeExecutionService.js';
|
|
11
|
+
import { WorkflowAdapter } from '../adapters/WorkflowAdapter.js';
|
|
12
|
+
import { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
|
|
13
|
+
import { validateForAgentSpecExport } from '../adapters/agentspec/validator.js';
|
|
14
|
+
import { extractPortId } from '../utils/handleIds.js';
|
|
15
|
+
import { EDGE_MARKER_SIZES } from '../config/constants.js';
|
|
16
|
+
import { logger } from '../utils/logger.js';
|
|
17
|
+
/**
|
|
18
|
+
* Generate a unique node ID based on node type and existing nodes
|
|
19
|
+
* Format: <node_type>.<number>
|
|
20
|
+
* Example: boolean_gateway.1, calculator.2
|
|
21
|
+
*/
|
|
22
|
+
export function generateNodeId(nodeTypeId, existingNodes) {
|
|
23
|
+
// Count how many nodes of this type already exist
|
|
24
|
+
const existingNodeIds = existingNodes
|
|
25
|
+
.filter((node) => node.data?.metadata?.id === nodeTypeId)
|
|
26
|
+
.map((node) => node.id);
|
|
27
|
+
// Extract the numbers from existing IDs with the same prefix
|
|
28
|
+
const existingNumbers = existingNodeIds
|
|
29
|
+
.map((id) => {
|
|
30
|
+
const match = id.match(new RegExp(`^${nodeTypeId}\\.(\\d+)$`));
|
|
31
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
32
|
+
})
|
|
33
|
+
.filter((num) => num > 0);
|
|
34
|
+
// Find the next available number (highest + 1)
|
|
35
|
+
const nextNumber = existingNumbers.length > 0 ? Math.max(...existingNumbers) + 1 : 1;
|
|
36
|
+
return `${nodeTypeId}.${nextNumber}`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Edge styling configuration based on source port data type
|
|
40
|
+
*/
|
|
41
|
+
export class EdgeStylingHelper {
|
|
42
|
+
/**
|
|
43
|
+
* Extract the port ID from a handle ID
|
|
44
|
+
* @param handleId - The handle ID string (e.g., "sample-node.1-output-trigger" or "trigger")
|
|
45
|
+
* @returns The port ID (e.g., "trigger") or the handleId itself for short format
|
|
46
|
+
*/
|
|
47
|
+
static extractPortIdFromHandle(handleId) {
|
|
48
|
+
return extractPortId(handleId);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Check if a port ID matches a dynamic branch in a Gateway node
|
|
52
|
+
* Gateway nodes store branches in config.branches array
|
|
53
|
+
* @param node - The workflow node to check
|
|
54
|
+
* @param portId - The port ID to look up
|
|
55
|
+
* @returns true if the portId matches a gateway branch
|
|
56
|
+
*/
|
|
57
|
+
static isGatewayBranch(node, portId) {
|
|
58
|
+
// Check if this is a gateway node with dynamic branches
|
|
59
|
+
const nodeType = node.data?.metadata?.type || node.type;
|
|
60
|
+
if (nodeType !== 'gateway') {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
// Check if the portId matches a branch name in config.branches
|
|
64
|
+
const branches = node.data?.config?.branches;
|
|
65
|
+
if (!branches || !Array.isArray(branches)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
return branches.some((branch) => branch.name === portId);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get the data type of a port from a node's metadata
|
|
72
|
+
* Also handles dynamic ports like Gateway branches
|
|
73
|
+
* @param node - The workflow node containing the port
|
|
74
|
+
* @param portId - The port ID to look up
|
|
75
|
+
* @param portType - Whether to look in "inputs" or "outputs"
|
|
76
|
+
* @returns The port's dataType or null if not found
|
|
77
|
+
*/
|
|
78
|
+
static getPortDataType(node, portId, portType) {
|
|
79
|
+
// First, check static ports in metadata
|
|
80
|
+
const ports = portType === 'output' ? node.data?.metadata?.outputs : node.data?.metadata?.inputs;
|
|
81
|
+
if (ports && Array.isArray(ports)) {
|
|
82
|
+
const port = ports.find((p) => p.id === portId);
|
|
83
|
+
if (port?.dataType) {
|
|
84
|
+
return port.dataType;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check dynamic ports from config (dynamicInputs/dynamicOutputs)
|
|
88
|
+
const dynamicKey = portType === 'output' ? 'dynamicOutputs' : 'dynamicInputs';
|
|
89
|
+
const dynamicPorts = node.data?.config?.[dynamicKey];
|
|
90
|
+
if (dynamicPorts && Array.isArray(dynamicPorts)) {
|
|
91
|
+
const dynamicPort = dynamicPorts.find((p) => p.name === portId);
|
|
92
|
+
if (dynamicPort?.dataType) {
|
|
93
|
+
return dynamicPort.dataType;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// For output ports, also check dynamic Gateway branches
|
|
97
|
+
// Gateway branches are always trigger type (control flow)
|
|
98
|
+
if (portType === 'output' && this.isGatewayBranch(node, portId)) {
|
|
99
|
+
return 'trigger';
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Determine the edge category based on source port data type
|
|
105
|
+
* Note: This method does not check for loopback edges.
|
|
106
|
+
* Use getEdgeCategoryWithLoopback() for full edge categorization.
|
|
107
|
+
*
|
|
108
|
+
* @param sourcePortDataType - The data type of the source output port
|
|
109
|
+
* @returns The edge category for styling
|
|
110
|
+
*/
|
|
111
|
+
static getEdgeCategory(sourcePortDataType) {
|
|
112
|
+
if (sourcePortDataType === 'trigger') {
|
|
113
|
+
return 'trigger';
|
|
114
|
+
}
|
|
115
|
+
if (sourcePortDataType === 'tool') {
|
|
116
|
+
return 'tool';
|
|
117
|
+
}
|
|
118
|
+
// All other data types (string, number, boolean, array, etc.) are "data" edges
|
|
119
|
+
return 'data';
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Determine the full edge category including loopback detection
|
|
123
|
+
* Loopback edges take precedence over source port data type
|
|
124
|
+
*
|
|
125
|
+
* @param edge - The edge to categorize
|
|
126
|
+
* @param sourcePortDataType - The data type of the source output port
|
|
127
|
+
* @returns The edge category for styling
|
|
128
|
+
*/
|
|
129
|
+
static getEdgeCategoryWithLoopback(edge, sourcePortDataType) {
|
|
130
|
+
// Loopback edges are identified by their target handle
|
|
131
|
+
// Check this first as it takes precedence
|
|
132
|
+
if (isLoopbackEdge(edge)) {
|
|
133
|
+
return 'loopback';
|
|
134
|
+
}
|
|
135
|
+
// Fall back to source port data type categorization
|
|
136
|
+
return this.getEdgeCategory(sourcePortDataType);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Apply custom styling to connection edges based on edge type:
|
|
140
|
+
* - Loopback: Dashed gray line for loop iteration (targets loop_back port)
|
|
141
|
+
* - Trigger ports: Solid black line with arrow
|
|
142
|
+
* - Tool ports: Dashed amber line with arrow
|
|
143
|
+
* - Data ports: Normal gray line with arrow
|
|
144
|
+
*/
|
|
145
|
+
static applyConnectionStyling(edge, sourceNode, targetNode) {
|
|
146
|
+
// Extract port ID from sourceHandle
|
|
147
|
+
const sourcePortId = this.extractPortIdFromHandle(edge.sourceHandle);
|
|
148
|
+
// Get the source port's data type
|
|
149
|
+
const sourcePortDataType = sourcePortId
|
|
150
|
+
? this.getPortDataType(sourceNode, sourcePortId, 'output')
|
|
151
|
+
: null;
|
|
152
|
+
// Determine edge category (loopback takes precedence)
|
|
153
|
+
const edgeCategory = this.getEdgeCategoryWithLoopback(edge, sourcePortDataType);
|
|
154
|
+
// Apply styling based on edge category
|
|
155
|
+
// Marker colors use CSS custom properties so they respond to theme changes automatically
|
|
156
|
+
switch (edgeCategory) {
|
|
157
|
+
case 'loopback':
|
|
158
|
+
// Loopback edges: dashed gray line for loop iteration
|
|
159
|
+
edge.style =
|
|
160
|
+
'stroke: var(--fd-edge-loopback); stroke-dasharray: var(--fd-edge-loopback-dasharray); stroke-width: var(--fd-edge-loopback-width); opacity: var(--fd-edge-loopback-opacity);';
|
|
161
|
+
edge.class = 'flowdrop--edge--loopback';
|
|
162
|
+
edge.markerEnd = {
|
|
163
|
+
type: MarkerType.ArrowClosed,
|
|
164
|
+
...EDGE_MARKER_SIZES.loopback,
|
|
165
|
+
color: 'var(--fd-edge-loopback)'
|
|
166
|
+
};
|
|
167
|
+
break;
|
|
168
|
+
case 'trigger':
|
|
169
|
+
// Trigger edges: solid dark line for control flow
|
|
170
|
+
edge.style = 'stroke: var(--fd-edge-trigger); stroke-width: var(--fd-edge-trigger-width);';
|
|
171
|
+
edge.class = 'flowdrop--edge--trigger';
|
|
172
|
+
edge.markerEnd = {
|
|
173
|
+
type: MarkerType.ArrowClosed,
|
|
174
|
+
...EDGE_MARKER_SIZES.trigger,
|
|
175
|
+
color: 'var(--fd-edge-trigger)'
|
|
176
|
+
};
|
|
177
|
+
break;
|
|
178
|
+
case 'tool':
|
|
179
|
+
// Tool edges: dashed amber line
|
|
180
|
+
edge.style = 'stroke: var(--fd-edge-tool); stroke-dasharray: 5 3;';
|
|
181
|
+
edge.class = 'flowdrop--edge--tool';
|
|
182
|
+
edge.markerEnd = {
|
|
183
|
+
type: MarkerType.ArrowClosed,
|
|
184
|
+
...EDGE_MARKER_SIZES.tool,
|
|
185
|
+
color: 'var(--fd-edge-tool)'
|
|
186
|
+
};
|
|
187
|
+
break;
|
|
188
|
+
case 'data':
|
|
189
|
+
default:
|
|
190
|
+
// Data edges: normal gray line
|
|
191
|
+
edge.style = 'stroke: var(--fd-edge-data);';
|
|
192
|
+
edge.class = 'flowdrop--edge--data';
|
|
193
|
+
edge.markerEnd = {
|
|
194
|
+
type: MarkerType.ArrowClosed,
|
|
195
|
+
...EDGE_MARKER_SIZES.data,
|
|
196
|
+
color: 'var(--fd-edge-data)'
|
|
197
|
+
};
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
// Store metadata in edge data for API and persistence
|
|
201
|
+
edge.data = {
|
|
202
|
+
...edge.data,
|
|
203
|
+
metadata: {
|
|
204
|
+
...(edge.data?.metadata || {}),
|
|
205
|
+
edgeType: edgeCategory,
|
|
206
|
+
sourcePortDataType: sourcePortDataType ?? undefined
|
|
207
|
+
},
|
|
208
|
+
targetNodeType: targetNode.type,
|
|
209
|
+
targetCategory: targetNode.data.metadata.category
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Update existing edges with custom styling rules
|
|
214
|
+
*/
|
|
215
|
+
static updateEdgeStyles(edges, nodes) {
|
|
216
|
+
return edges.map((edge) => {
|
|
217
|
+
// Find source and target nodes
|
|
218
|
+
const sourceNode = nodes.find((node) => node.id === edge.source);
|
|
219
|
+
const targetNode = nodes.find((node) => node.id === edge.target);
|
|
220
|
+
// Create a copy of the edge
|
|
221
|
+
const updatedEdge = { ...edge };
|
|
222
|
+
if (!sourceNode || !targetNode) {
|
|
223
|
+
// Set default edgeType even when nodes are not found
|
|
224
|
+
updatedEdge.data = {
|
|
225
|
+
...updatedEdge.data,
|
|
226
|
+
metadata: {
|
|
227
|
+
...(updatedEdge.data?.metadata || {}),
|
|
228
|
+
edgeType: 'data'
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
return updatedEdge;
|
|
232
|
+
}
|
|
233
|
+
// Apply full styling when nodes are available
|
|
234
|
+
this.applyConnectionStyling(updatedEdge, sourceNode, targetNode);
|
|
235
|
+
return updatedEdge;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Node operations helper
|
|
241
|
+
*/
|
|
242
|
+
export class NodeOperationsHelper {
|
|
243
|
+
/**
|
|
244
|
+
* Load nodes from API
|
|
245
|
+
*/
|
|
246
|
+
static async loadNodesFromApi(providedNodes) {
|
|
247
|
+
// If nodes are provided via props, use them
|
|
248
|
+
if (providedNodes && providedNodes.length > 0) {
|
|
249
|
+
return providedNodes;
|
|
250
|
+
}
|
|
251
|
+
// Otherwise, load from API
|
|
252
|
+
try {
|
|
253
|
+
const fetchedNodes = await nodeApi.getNodes();
|
|
254
|
+
return fetchedNodes;
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
logger.error('Failed to load nodes from API:', error);
|
|
258
|
+
// Use fallback sample nodes
|
|
259
|
+
return [
|
|
260
|
+
{
|
|
261
|
+
id: 'text-input',
|
|
262
|
+
name: 'Text Input',
|
|
263
|
+
category: 'inputs',
|
|
264
|
+
description: 'Simple text input field',
|
|
265
|
+
version: '1.0.0',
|
|
266
|
+
icon: 'mdi:text-box',
|
|
267
|
+
inputs: [],
|
|
268
|
+
outputs: [{ id: 'text', name: 'text', type: 'output', dataType: 'string' }]
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: 'text-output',
|
|
272
|
+
name: 'Text Output',
|
|
273
|
+
category: 'outputs',
|
|
274
|
+
description: 'Display text output',
|
|
275
|
+
version: '1.0.0',
|
|
276
|
+
icon: 'mdi:text-box-outline',
|
|
277
|
+
inputs: [{ id: 'text', name: 'text', type: 'input', dataType: 'string' }],
|
|
278
|
+
outputs: []
|
|
279
|
+
}
|
|
280
|
+
];
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Load node execution information for all nodes in the workflow
|
|
285
|
+
*/
|
|
286
|
+
static async loadNodeExecutionInfo(workflow, pipelineId) {
|
|
287
|
+
if (!workflow?.nodes)
|
|
288
|
+
return {};
|
|
289
|
+
// Only load execution info if we have a pipelineId (for pipeline status mode)
|
|
290
|
+
if (!pipelineId)
|
|
291
|
+
return {};
|
|
292
|
+
try {
|
|
293
|
+
const nodeIds = workflow.nodes.map((node) => node.id);
|
|
294
|
+
const executionInfo = await nodeExecutionService.getMultipleNodeExecutionInfo(nodeIds, pipelineId);
|
|
295
|
+
return executionInfo;
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
logger.error('Failed to load node execution info:', error);
|
|
299
|
+
return {};
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Create a new node from dropped data
|
|
304
|
+
*/
|
|
305
|
+
static createNodeFromDrop(nodeTypeData, position, existingNodes = []) {
|
|
306
|
+
try {
|
|
307
|
+
const parsedData = JSON.parse(nodeTypeData);
|
|
308
|
+
// Handle both old format (with type: "node") and new format (direct NodeMetadata)
|
|
309
|
+
let nodeType;
|
|
310
|
+
let nodeData;
|
|
311
|
+
if (parsedData.type === 'node') {
|
|
312
|
+
// Old format from sidebar
|
|
313
|
+
nodeType = parsedData.nodeData.metadata;
|
|
314
|
+
nodeData = parsedData.nodeData;
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// New format (direct NodeMetadata)
|
|
318
|
+
nodeType = parsedData;
|
|
319
|
+
// Extract initial config from configSchema
|
|
320
|
+
let initialConfig = {};
|
|
321
|
+
if (nodeType.configSchema && typeof nodeType.configSchema === 'object') {
|
|
322
|
+
// If configSchema is a JSON Schema, extract default values
|
|
323
|
+
if (nodeType.configSchema.properties) {
|
|
324
|
+
// JSON Schema format - extract defaults
|
|
325
|
+
Object.entries(nodeType.configSchema.properties).forEach(([key, prop]) => {
|
|
326
|
+
if (prop && typeof prop === 'object' && 'default' in prop) {
|
|
327
|
+
initialConfig[key] = prop.default;
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
// Simple object format - use as is
|
|
333
|
+
initialConfig = { ...nodeType.configSchema };
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
nodeData = {
|
|
337
|
+
label: nodeType.name,
|
|
338
|
+
config: initialConfig,
|
|
339
|
+
metadata: nodeType
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
// Generate node ID based on node type and existing nodes
|
|
343
|
+
const newNodeId = generateNodeId(nodeType.id, existingNodes);
|
|
344
|
+
// All nodes use "universalNode" type
|
|
345
|
+
// UniversalNode component handles internal switching based on metadata and config
|
|
346
|
+
const newNode = {
|
|
347
|
+
id: newNodeId,
|
|
348
|
+
type: 'universalNode',
|
|
349
|
+
position, // Use the position calculated from the drop event
|
|
350
|
+
deletable: true,
|
|
351
|
+
data: {
|
|
352
|
+
...nodeData,
|
|
353
|
+
nodeId: newNodeId // Use the same ID
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
return newNode;
|
|
357
|
+
}
|
|
358
|
+
catch (error) {
|
|
359
|
+
logger.error('Error parsing node data:', error);
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Workflow operations helper
|
|
366
|
+
*/
|
|
367
|
+
export class WorkflowOperationsHelper {
|
|
368
|
+
/**
|
|
369
|
+
* Generate workflow metadata for updates
|
|
370
|
+
*/
|
|
371
|
+
static generateMetadata(existingMetadata) {
|
|
372
|
+
const now = new Date().toISOString();
|
|
373
|
+
return {
|
|
374
|
+
version: '1.0.0',
|
|
375
|
+
createdAt: now,
|
|
376
|
+
...(existingMetadata ?? {}),
|
|
377
|
+
updatedAt: now,
|
|
378
|
+
versionId: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
379
|
+
updateNumber: (existingMetadata?.updateNumber || 0) + 1
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Update workflow with new nodes/edges and generate new metadata
|
|
384
|
+
*/
|
|
385
|
+
static updateWorkflow(workflow, nodes, edges) {
|
|
386
|
+
return {
|
|
387
|
+
...workflow,
|
|
388
|
+
nodes,
|
|
389
|
+
edges,
|
|
390
|
+
metadata: this.generateMetadata(workflow.metadata)
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Clear workflow (remove all nodes and edges)
|
|
395
|
+
*/
|
|
396
|
+
static clearWorkflow(workflow) {
|
|
397
|
+
return {
|
|
398
|
+
...workflow,
|
|
399
|
+
nodes: [],
|
|
400
|
+
edges: [],
|
|
401
|
+
metadata: this.generateMetadata(workflow.metadata)
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Update node configuration
|
|
406
|
+
*/
|
|
407
|
+
static updateNodeConfig(workflow, nodeId, newConfig) {
|
|
408
|
+
return {
|
|
409
|
+
...workflow,
|
|
410
|
+
nodes: workflow.nodes.map((node) => node.id === nodeId
|
|
411
|
+
? {
|
|
412
|
+
...node,
|
|
413
|
+
data: { ...node.data, config: { ...newConfig } }
|
|
414
|
+
}
|
|
415
|
+
: node),
|
|
416
|
+
metadata: this.generateMetadata(workflow.metadata)
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Add a new node to the workflow
|
|
421
|
+
*/
|
|
422
|
+
static addNode(workflow, node) {
|
|
423
|
+
return {
|
|
424
|
+
...workflow,
|
|
425
|
+
nodes: [...workflow.nodes, node],
|
|
426
|
+
metadata: this.generateMetadata(workflow.metadata)
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Save workflow to backend
|
|
431
|
+
*/
|
|
432
|
+
static async saveWorkflow(workflow) {
|
|
433
|
+
if (!workflow) {
|
|
434
|
+
logger.warn('No workflow data available to save');
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
// Determine the workflow ID based on whether we have an existing workflow
|
|
439
|
+
let workflowId;
|
|
440
|
+
if (workflow.id) {
|
|
441
|
+
// Use the existing workflow ID
|
|
442
|
+
workflowId = workflow.id;
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
// Generate a new UUID for a new workflow
|
|
446
|
+
workflowId = uuidv4();
|
|
447
|
+
}
|
|
448
|
+
const workflowToSave = {
|
|
449
|
+
id: workflowId,
|
|
450
|
+
name: workflow.name || 'Untitled Workflow',
|
|
451
|
+
nodes: workflow.nodes || [],
|
|
452
|
+
edges: workflow.edges || [],
|
|
453
|
+
metadata: {
|
|
454
|
+
version: '1.0.0',
|
|
455
|
+
createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
|
|
456
|
+
updatedAt: new Date().toISOString()
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
const savedWorkflow = await workflowApi.saveWorkflow(workflowToSave);
|
|
460
|
+
// Update the workflow ID if it changed (new workflow)
|
|
461
|
+
if (savedWorkflow.id && savedWorkflow.id !== workflowToSave.id) {
|
|
462
|
+
workflowActions.batchUpdate({
|
|
463
|
+
nodes: workflowToSave.nodes,
|
|
464
|
+
edges: workflowToSave.edges,
|
|
465
|
+
name: workflowToSave.name,
|
|
466
|
+
metadata: {
|
|
467
|
+
...workflowToSave.metadata,
|
|
468
|
+
...savedWorkflow.metadata
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
return savedWorkflow;
|
|
473
|
+
}
|
|
474
|
+
catch (error) {
|
|
475
|
+
logger.error('Failed to save workflow:', error);
|
|
476
|
+
throw error;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Export workflow as JSON file
|
|
481
|
+
*/
|
|
482
|
+
static exportWorkflow(workflow) {
|
|
483
|
+
if (!workflow) {
|
|
484
|
+
logger.warn('No workflow data available to export');
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
// Use the same ID logic as saveWorkflow
|
|
488
|
+
const workflowId = workflow.id || uuidv4();
|
|
489
|
+
const workflowToExport = {
|
|
490
|
+
id: workflowId,
|
|
491
|
+
name: workflow.name || 'Untitled Workflow',
|
|
492
|
+
nodes: workflow.nodes || [],
|
|
493
|
+
edges: workflow.edges || [],
|
|
494
|
+
metadata: {
|
|
495
|
+
version: '1.0.0',
|
|
496
|
+
createdAt: workflow.metadata?.createdAt || new Date().toISOString(),
|
|
497
|
+
updatedAt: new Date().toISOString()
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
const dataStr = JSON.stringify(workflowToExport, null, 2);
|
|
501
|
+
const dataBlob = new Blob([dataStr], { type: 'application/json' });
|
|
502
|
+
const url = URL.createObjectURL(dataBlob);
|
|
503
|
+
const link = document.createElement('a');
|
|
504
|
+
link.href = url;
|
|
505
|
+
link.download = `${workflowToExport.name}.json`;
|
|
506
|
+
link.click();
|
|
507
|
+
URL.revokeObjectURL(url);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Export workflow as Agent Spec JSON file.
|
|
511
|
+
*
|
|
512
|
+
* Converts the FlowDrop workflow to Agent Spec format and triggers a download.
|
|
513
|
+
* Validates the workflow for Agent Spec compatibility first.
|
|
514
|
+
*
|
|
515
|
+
* @param workflow - The FlowDrop workflow to export
|
|
516
|
+
* @returns Validation result (check .valid before assuming success)
|
|
517
|
+
*/
|
|
518
|
+
static exportAsAgentSpec(workflow) {
|
|
519
|
+
if (!workflow) {
|
|
520
|
+
return { valid: false, errors: ['No workflow data available to export'], warnings: [] };
|
|
521
|
+
}
|
|
522
|
+
// Convert to StandardWorkflow first
|
|
523
|
+
const workflowAdapter = new WorkflowAdapter();
|
|
524
|
+
const standardWorkflow = workflowAdapter.fromSvelteFlow(workflow);
|
|
525
|
+
// Validate for Agent Spec
|
|
526
|
+
const validation = validateForAgentSpecExport(standardWorkflow);
|
|
527
|
+
if (!validation.valid) {
|
|
528
|
+
return validation;
|
|
529
|
+
}
|
|
530
|
+
// Convert to Agent Spec
|
|
531
|
+
const agentSpecAdapter = new AgentSpecAdapter();
|
|
532
|
+
const agentSpecJson = agentSpecAdapter.exportJSON(standardWorkflow);
|
|
533
|
+
// Trigger download
|
|
534
|
+
const dataBlob = new Blob([agentSpecJson], { type: 'application/json' });
|
|
535
|
+
const url = URL.createObjectURL(dataBlob);
|
|
536
|
+
const link = document.createElement('a');
|
|
537
|
+
link.href = url;
|
|
538
|
+
link.download = `${workflow.name || 'workflow'}-agentspec.json`;
|
|
539
|
+
link.click();
|
|
540
|
+
URL.revokeObjectURL(url);
|
|
541
|
+
return validation;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Import a workflow from an Agent Spec JSON or YAML file.
|
|
545
|
+
*
|
|
546
|
+
* Reads the file, detects format, converts to FlowDrop format,
|
|
547
|
+
* and returns a Workflow ready for the editor.
|
|
548
|
+
*
|
|
549
|
+
* @param file - The file to import (JSON or YAML)
|
|
550
|
+
* @returns Promise resolving to the imported FlowDrop Workflow
|
|
551
|
+
*/
|
|
552
|
+
static async importFromAgentSpec(file) {
|
|
553
|
+
const text = await file.text();
|
|
554
|
+
const agentSpecAdapter = new AgentSpecAdapter();
|
|
555
|
+
const workflowAdapter = new WorkflowAdapter();
|
|
556
|
+
// Parse the Agent Spec data
|
|
557
|
+
const standardWorkflow = agentSpecAdapter.importJSON(text);
|
|
558
|
+
// Convert to SvelteFlow format
|
|
559
|
+
return workflowAdapter.toSvelteFlow(standardWorkflow);
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Check if workflow has invalid cycles (excludes valid loopback cycles)
|
|
563
|
+
* Valid loopback cycles are used for ForEach node iteration and should not
|
|
564
|
+
* trigger a warning.
|
|
565
|
+
*
|
|
566
|
+
* @param nodes - Array of workflow nodes
|
|
567
|
+
* @param edges - Array of workflow edges
|
|
568
|
+
* @returns True if there are invalid (non-loopback) cycles
|
|
569
|
+
*/
|
|
570
|
+
static checkWorkflowCycles(nodes, edges) {
|
|
571
|
+
return hasInvalidCycles(nodes, edges);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Check if workflow has any cycles (including valid loopback cycles)
|
|
575
|
+
* Use this when you need to detect ALL cycles regardless of type.
|
|
576
|
+
*
|
|
577
|
+
* @param nodes - Array of workflow nodes
|
|
578
|
+
* @param edges - Array of workflow edges
|
|
579
|
+
* @returns True if any cycle exists
|
|
580
|
+
*/
|
|
581
|
+
static checkWorkflowHasAnyCycles(nodes, edges) {
|
|
582
|
+
return hasCycles(nodes, edges);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Configuration helper
|
|
587
|
+
*/
|
|
588
|
+
export class ConfigurationHelper {
|
|
589
|
+
/**
|
|
590
|
+
* Configure API endpoints
|
|
591
|
+
*/
|
|
592
|
+
static configureEndpoints(config) {
|
|
593
|
+
setEndpointConfig(config);
|
|
594
|
+
}
|
|
595
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowDrop - Visual Workflow Editor Library
|
|
3
|
+
*
|
|
4
|
+
* A Svelte 5 component library built on @xyflow/svelte for creating node-based workflow editors.
|
|
5
|
+
*
|
|
6
|
+
* ## Module Structure (Tree-Shakable)
|
|
7
|
+
*
|
|
8
|
+
* For optimal bundle size, import from specific sub-modules:
|
|
9
|
+
*
|
|
10
|
+
* - `@flowdrop/flowdrop/core` - Types and utilities only (no heavy deps)
|
|
11
|
+
* - `@flowdrop/flowdrop/editor` - WorkflowEditor with @xyflow/svelte
|
|
12
|
+
* - `@flowdrop/flowdrop/form` - SchemaForm with basic fields
|
|
13
|
+
* - `@flowdrop/flowdrop/form/code` - Code editor support (adds CodeMirror)
|
|
14
|
+
* - `@flowdrop/flowdrop/form/markdown` - Markdown editor support (CodeMirror 6)
|
|
15
|
+
* - `@flowdrop/flowdrop/display` - MarkdownDisplay (adds marked)
|
|
16
|
+
* - `@flowdrop/flowdrop/playground` - Playground for interactive workflow testing
|
|
17
|
+
* - `@flowdrop/flowdrop/styles` - CSS styles
|
|
18
|
+
*
|
|
19
|
+
* ## Legacy Import (Full Bundle)
|
|
20
|
+
*
|
|
21
|
+
* Importing from the main entry point includes everything:
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { WorkflowEditor, SchemaForm } from "@flowdrop/flowdrop";
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Note**: This will bundle ALL dependencies including @xyflow/svelte,
|
|
28
|
+
* CodeMirror and marked. For smaller bundles, use sub-modules.
|
|
29
|
+
*
|
|
30
|
+
* @module flowdrop
|
|
31
|
+
*/
|
|
32
|
+
export * from './core/index.js';
|
|
33
|
+
export * from './form/index.js';
|
|
34
|
+
export * from './display/index.js';
|
|
35
|
+
export * from './playground/index.js';
|
|
36
|
+
export * from './editor/index.js';
|
|
37
|
+
export * from './settings/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowDrop - Visual Workflow Editor Library
|
|
3
|
+
*
|
|
4
|
+
* A Svelte 5 component library built on @xyflow/svelte for creating node-based workflow editors.
|
|
5
|
+
*
|
|
6
|
+
* ## Module Structure (Tree-Shakable)
|
|
7
|
+
*
|
|
8
|
+
* For optimal bundle size, import from specific sub-modules:
|
|
9
|
+
*
|
|
10
|
+
* - `@flowdrop/flowdrop/core` - Types and utilities only (no heavy deps)
|
|
11
|
+
* - `@flowdrop/flowdrop/editor` - WorkflowEditor with @xyflow/svelte
|
|
12
|
+
* - `@flowdrop/flowdrop/form` - SchemaForm with basic fields
|
|
13
|
+
* - `@flowdrop/flowdrop/form/code` - Code editor support (adds CodeMirror)
|
|
14
|
+
* - `@flowdrop/flowdrop/form/markdown` - Markdown editor support (CodeMirror 6)
|
|
15
|
+
* - `@flowdrop/flowdrop/display` - MarkdownDisplay (adds marked)
|
|
16
|
+
* - `@flowdrop/flowdrop/playground` - Playground for interactive workflow testing
|
|
17
|
+
* - `@flowdrop/flowdrop/styles` - CSS styles
|
|
18
|
+
*
|
|
19
|
+
* ## Legacy Import (Full Bundle)
|
|
20
|
+
*
|
|
21
|
+
* Importing from the main entry point includes everything:
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { WorkflowEditor, SchemaForm } from "@flowdrop/flowdrop";
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* **Note**: This will bundle ALL dependencies including @xyflow/svelte,
|
|
28
|
+
* CodeMirror and marked. For smaller bundles, use sub-modules.
|
|
29
|
+
*
|
|
30
|
+
* @module flowdrop
|
|
31
|
+
*/
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// IMPORTANT: This module re-exports from sub-modules for backward compatibility.
|
|
34
|
+
// New code should import directly from sub-modules for better tree-shaking.
|
|
35
|
+
//
|
|
36
|
+
// The wildcard re-exports below are intentional: each sub-module barrel uses
|
|
37
|
+
// explicit named exports, so the public API surface is fully controlled there.
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Core Exports (Types & Utilities - No Heavy Dependencies)
|
|
41
|
+
// ============================================================================
|
|
42
|
+
export * from './core/index.js';
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Form Exports
|
|
45
|
+
// ============================================================================
|
|
46
|
+
export * from './form/index.js';
|
|
47
|
+
// Note: Heavy form fields (code, markdown) are NOT auto-registered.
|
|
48
|
+
// Users must import from form/code or form/markdown and register explicitly.
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Display Exports
|
|
51
|
+
// ============================================================================
|
|
52
|
+
export * from './display/index.js';
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Playground Exports
|
|
55
|
+
// ============================================================================
|
|
56
|
+
export * from './playground/index.js';
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Editor Exports (includes @xyflow/svelte and auto-registers builtin nodes)
|
|
59
|
+
// ============================================================================
|
|
60
|
+
export * from './editor/index.js';
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// Settings Exports (stores, services, components, types)
|
|
63
|
+
// ============================================================================
|
|
64
|
+
export * from './settings/index.js';
|