@flowdrop/flowdrop 1.3.0 → 1.5.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/README.md +68 -24
- package/dist/adapters/WorkflowAdapter.js +2 -22
- package/dist/adapters/agentspec/autoLayout.d.ts +51 -5
- package/dist/adapters/agentspec/autoLayout.js +120 -23
- package/dist/chat/commandClassifier.d.ts +19 -0
- package/dist/chat/commandClassifier.js +30 -0
- package/dist/chat/index.d.ts +27 -0
- package/dist/chat/index.js +32 -0
- package/dist/chat/responseParser.d.ts +21 -0
- package/dist/chat/responseParser.js +87 -0
- package/dist/commands/batch.d.ts +18 -0
- package/dist/commands/batch.js +56 -0
- package/dist/commands/executor.d.ts +37 -0
- package/dist/commands/executor.js +1044 -0
- package/dist/commands/index.d.ts +14 -0
- package/dist/commands/index.js +17 -0
- package/dist/commands/parser.d.ts +16 -0
- package/dist/commands/parser.js +278 -0
- package/dist/commands/positioner.d.ts +19 -0
- package/dist/commands/positioner.js +33 -0
- package/dist/commands/storeIntegration.svelte.d.ts +16 -0
- package/dist/commands/storeIntegration.svelte.js +67 -0
- package/dist/commands/types.d.ts +343 -0
- package/dist/commands/types.js +45 -0
- package/dist/components/App.svelte +431 -17
- package/dist/components/App.svelte.d.ts +10 -0
- package/dist/components/CanvasBanner.stories.svelte +6 -2
- package/dist/components/CanvasController.svelte +38 -0
- package/dist/components/CanvasController.svelte.d.ts +32 -0
- package/dist/components/ConfigMappingRow.svelte +130 -0
- package/dist/components/ConfigMappingRow.svelte.d.ts +8 -0
- package/dist/components/ConfigPanel.svelte +56 -7
- package/dist/components/ConfigPanel.svelte.d.ts +2 -0
- package/dist/components/FlowDropEdge.svelte +8 -57
- package/dist/components/Logo.svelte +14 -14
- package/dist/components/LogsSidebar.svelte +5 -5
- package/dist/components/Navbar.svelte +58 -10
- package/dist/components/Navbar.svelte.d.ts +7 -0
- package/dist/components/NodeSidebar.svelte +238 -362
- package/dist/components/NodeSwapPicker.svelte +537 -0
- package/dist/components/NodeSwapPicker.svelte.d.ts +16 -0
- package/dist/components/PortMappingRow.svelte +209 -0
- package/dist/components/PortMappingRow.svelte.d.ts +12 -0
- package/dist/components/SwapMappingEditor.svelte +550 -0
- package/dist/components/SwapMappingEditor.svelte.d.ts +12 -0
- package/dist/components/WorkflowEditor.svelte +99 -4
- package/dist/components/WorkflowEditor.svelte.d.ts +8 -0
- package/dist/components/chat/AIChatPanel.svelte +658 -0
- package/dist/components/chat/AIChatPanel.svelte.d.ts +13 -0
- package/dist/components/chat/CommandPreview.svelte +184 -0
- package/dist/components/chat/CommandPreview.svelte.d.ts +9 -0
- package/dist/components/console/CommandConsole.stories.svelte +93 -0
- package/dist/components/console/CommandConsole.stories.svelte.d.ts +27 -0
- package/dist/components/console/CommandConsole.svelte +259 -0
- package/dist/components/console/CommandConsole.svelte.d.ts +11 -0
- package/dist/components/console/ConsoleAutocomplete.svelte +139 -0
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +21 -0
- package/dist/components/console/ConsoleInput.svelte +712 -0
- package/dist/components/console/ConsoleInput.svelte.d.ts +16 -0
- package/dist/components/console/ConsoleOutput.svelte +121 -0
- package/dist/components/console/ConsoleOutput.svelte.d.ts +11 -0
- package/dist/components/console/formatters.d.ts +26 -0
- package/dist/components/console/formatters.js +118 -0
- package/dist/components/interrupt/index.d.ts +1 -0
- package/dist/components/interrupt/index.js +1 -0
- package/dist/components/nodes/SimpleNode.stories.svelte +64 -0
- package/dist/components/nodes/SimpleNode.svelte +27 -11
- package/dist/components/nodes/SquareNode.stories.svelte +45 -0
- package/dist/components/nodes/SquareNode.svelte +27 -11
- package/dist/components/nodes/WorkflowNode.stories.svelte +63 -0
- package/dist/config/endpoints.d.ts +8 -0
- package/dist/config/endpoints.js +5 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +9 -0
- package/dist/editor/index.d.ts +3 -1
- package/dist/editor/index.js +4 -2
- package/dist/helpers/proximityConnect.js +8 -1
- package/dist/helpers/workflowEditorHelper.d.ts +3 -53
- package/dist/helpers/workflowEditorHelper.js +13 -228
- package/dist/playground/index.d.ts +1 -1
- package/dist/playground/index.js +1 -1
- package/dist/schemas/v1/workflow.schema.json +107 -22
- package/dist/services/chatService.d.ts +65 -0
- package/dist/services/chatService.js +131 -0
- package/dist/services/historyService.d.ts +6 -4
- package/dist/services/historyService.js +21 -6
- package/dist/skins/slate.js +16 -0
- package/dist/stores/interruptStore.svelte.js +6 -1
- package/dist/stores/playgroundStore.svelte.d.ts +1 -1
- package/dist/stores/playgroundStore.svelte.js +11 -2
- package/dist/stores/portCoordinateStore.svelte.d.ts +4 -0
- package/dist/stores/portCoordinateStore.svelte.js +20 -26
- package/dist/stores/workflowStore.svelte.d.ts +31 -2
- package/dist/stores/workflowStore.svelte.js +84 -64
- package/dist/stories/EdgeDecorator.svelte +4 -4
- package/dist/styles/base.css +48 -0
- package/dist/svelte-app.d.ts +7 -1
- package/dist/svelte-app.js +4 -1
- package/dist/types/chat.d.ts +63 -0
- package/dist/types/chat.js +9 -0
- package/dist/types/events.d.ts +28 -2
- package/dist/types/events.js +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/settings.d.ts +6 -0
- package/dist/types/settings.js +3 -0
- package/dist/utils/edgeStyling.d.ts +42 -0
- package/dist/utils/edgeStyling.js +176 -0
- package/dist/utils/nodeIds.d.ts +31 -0
- package/dist/utils/nodeIds.js +42 -0
- package/dist/utils/nodeSwap.d.ts +221 -0
- package/dist/utils/nodeSwap.js +686 -0
- package/package.json +6 -1
- package/dist/helpers/nodeLayoutHelper.d.ts +0 -14
- package/dist/helpers/nodeLayoutHelper.js +0 -19
package/dist/core/index.js
CHANGED
|
@@ -58,6 +58,11 @@ export { resolveScopeToKey, keyToScope, generateDefaultUISchema, collectReferenc
|
|
|
58
58
|
export { DEFAULT_PORT_CONFIG } from "../config/defaultPortConfig.js";
|
|
59
59
|
export { defaultEndpointConfig, createEndpointConfig, } from "../config/endpoints.js";
|
|
60
60
|
// ============================================================================
|
|
61
|
+
// Shared Utilities
|
|
62
|
+
// ============================================================================
|
|
63
|
+
export { generateNodeId, extractConfigDefaults } from "../utils/nodeIds.js";
|
|
64
|
+
export { buildTypeMap, parseCommand, executeCommand, toShortId, toShortTypeId, resolveNode, executeBatch, computeAutoPosition, } from "../commands/index.js";
|
|
65
|
+
// ============================================================================
|
|
61
66
|
// Adapters
|
|
62
67
|
// ============================================================================
|
|
63
68
|
export { WorkflowAdapter } from "../adapters/WorkflowAdapter.js";
|
|
@@ -92,3 +97,7 @@ export { sanitizeHtml } from "../utils/sanitize.js";
|
|
|
92
97
|
// Logger
|
|
93
98
|
// ============================================================================
|
|
94
99
|
export { logger, setLogLevel, getLogLevel } from "../utils/logger.js";
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// Node Swap
|
|
102
|
+
// ============================================================================
|
|
103
|
+
export { computeSwapPreview, computeSwapPreviewWithOptions, executeSwap, mapConfig, getVersionUpgrade, compareSemver, performSwap, validateSwapResult, SwapValidationError, } from "../utils/nodeSwap.js";
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export { default as LogsSidebar } from "../components/LogsSidebar.svelte";
|
|
|
57
57
|
export { default as PipelineStatus } from "../components/PipelineStatus.svelte";
|
|
58
58
|
export { default as Navbar } from "../components/Navbar.svelte";
|
|
59
59
|
export { default as Logo } from "../components/Logo.svelte";
|
|
60
|
+
export { default as CommandConsole } from "../components/console/CommandConsole.svelte";
|
|
60
61
|
export { default as Playground } from "../components/playground/Playground.svelte";
|
|
61
62
|
export { default as PlaygroundModal } from "../components/playground/PlaygroundModal.svelte";
|
|
62
63
|
export { default as ChatPanel } from "../components/playground/ChatPanel.svelte";
|
|
@@ -67,7 +68,7 @@ export { default as MessageBubble } from "../components/playground/MessageBubble
|
|
|
67
68
|
export { mountWorkflowEditor, mountFlowDropApp, unmountFlowDropApp, } from "../svelte-app.js";
|
|
68
69
|
export { nodeComponentRegistry, createNamespacedType, parseNamespacedType, BUILTIN_NODE_COMPONENTS, BUILTIN_NODE_TYPES, FLOWDROP_SOURCE, registerBuiltinNodes, areBuiltinsRegistered, isBuiltinType, getBuiltinTypes, resolveBuiltinAlias, registerFlowDropPlugin, unregisterFlowDropPlugin, registerCustomNode, createPlugin, isValidNamespace, getRegisteredPlugins, getPluginNodeCount, } from "../registry/index.js";
|
|
69
70
|
export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, ConfigurationHelper, } from "../helpers/workflowEditorHelper.js";
|
|
70
|
-
export { getWorkflowStore, workflowActions, getWorkflowId, getWorkflowName, getWorkflowNodes, getWorkflowEdges, getWorkflowMetadata, getWorkflowFormat, getWorkflowChanged, getWorkflowValidation, getWorkflowMetadataChanged, getConnectedHandles, getIsDirty, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange, setHistoryEnabled, isHistoryEnabled, setRestoringFromHistory, } from "../stores/workflowStore.svelte.js";
|
|
71
|
+
export { getWorkflowStore, workflowActions, getWorkflowId, getWorkflowName, getWorkflowNodes, getWorkflowEdges, getWorkflowMetadata, getWorkflowFormat, getWorkflowChanged, getWorkflowValidation, getWorkflowMetadataChanged, getConnectedHandles, getIsDirty, isDirty, markAsSaved, getEditVersion, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange, setHistoryEnabled, isHistoryEnabled, setRestoringFromHistory, } from "../stores/workflowStore.svelte.js";
|
|
71
72
|
export { rebuildAllPortCoordinates, updateNodePortCoordinates, removeNodePortCoordinates, getPortCoordinate, getNodePortCoordinates, getPortCoordinateSnapshot, getPortCoordinates, } from "../stores/portCoordinateStore.svelte.js";
|
|
72
73
|
export { getHistoryState, getCanUndo, getCanRedo, historyActions, setOnRestoreCallback, cleanupHistorySubscription, historyService, HistoryService, } from "../stores/historyStore.svelte.js";
|
|
73
74
|
export type { HistoryEntry, HistoryState, PushOptions, } from "../stores/historyStore.svelte.js";
|
|
@@ -91,5 +92,6 @@ export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, } from
|
|
|
91
92
|
export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig, } from "../types/auth.js";
|
|
92
93
|
export type { FlowDropEventHandlers, FlowDropFeatures, WorkflowChangeType, } from "../types/events.js";
|
|
93
94
|
export type { EndpointConfig } from "../config/endpoints.js";
|
|
95
|
+
export type { UIAction } from "../commands/types.js";
|
|
94
96
|
export type { FlowDropMountOptions, MountedFlowDropApp, NavbarAction, } from "../svelte-app.js";
|
|
95
97
|
export type { NodeComponentProps, NodeComponentRegistration, FlowDropPluginConfig, PluginNodeDefinition, } from "../registry/index.js";
|
package/dist/editor/index.js
CHANGED
|
@@ -71,6 +71,8 @@ export { default as LogsSidebar } from "../components/LogsSidebar.svelte";
|
|
|
71
71
|
export { default as PipelineStatus } from "../components/PipelineStatus.svelte";
|
|
72
72
|
export { default as Navbar } from "../components/Navbar.svelte";
|
|
73
73
|
export { default as Logo } from "../components/Logo.svelte";
|
|
74
|
+
// Console Components
|
|
75
|
+
export { default as CommandConsole } from "../components/console/CommandConsole.svelte";
|
|
74
76
|
// Playground Components
|
|
75
77
|
export { default as Playground } from "../components/playground/Playground.svelte";
|
|
76
78
|
export { default as PlaygroundModal } from "../components/playground/PlaygroundModal.svelte";
|
|
@@ -101,8 +103,8 @@ export { EdgeStylingHelper, NodeOperationsHelper, WorkflowOperationsHelper, Conf
|
|
|
101
103
|
// Stores
|
|
102
104
|
// ============================================================================
|
|
103
105
|
export { getWorkflowStore, workflowActions, getWorkflowId, getWorkflowName, getWorkflowNodes, getWorkflowEdges, getWorkflowMetadata, getWorkflowFormat, getWorkflowChanged, getWorkflowValidation, getWorkflowMetadataChanged, getConnectedHandles,
|
|
104
|
-
// Dirty state tracking
|
|
105
|
-
getIsDirty, isDirty, markAsSaved, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange,
|
|
106
|
+
// Dirty state tracking & version counter
|
|
107
|
+
getIsDirty, isDirty, markAsSaved, getEditVersion, getWorkflow as getWorkflowFromStore, setOnDirtyStateChange, setOnWorkflowChange,
|
|
106
108
|
// History control
|
|
107
109
|
setHistoryEnabled, isHistoryEnabled, setRestoringFromHistory, } from "../stores/workflowStore.svelte.js";
|
|
108
110
|
// Port Coordinate Store (Svelte 5 runes-based)
|
|
@@ -239,9 +239,16 @@ export class ProximityConnectHelper {
|
|
|
239
239
|
bestIsExact = isExact;
|
|
240
240
|
}
|
|
241
241
|
};
|
|
242
|
+
// Cache compatible types per dataType to avoid redundant lookups
|
|
243
|
+
const compatCache = new Map();
|
|
244
|
+
for (const srcPort of draggedOutputs) {
|
|
245
|
+
if (!compatCache.has(srcPort.dataType)) {
|
|
246
|
+
compatCache.set(srcPort.dataType, checker.getCompatibleTypes(srcPort.dataType));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
242
249
|
// Direction A: dragged outputs → other inputs (only compatible types)
|
|
243
250
|
for (const srcPort of draggedOutputs) {
|
|
244
|
-
const compatibleTypes =
|
|
251
|
+
const compatibleTypes = compatCache.get(srcPort.dataType);
|
|
245
252
|
for (const targetType of compatibleTypes) {
|
|
246
253
|
const targets = otherInputsByType.get(targetType);
|
|
247
254
|
if (!targets)
|
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { WorkflowNode as WorkflowNodeType, NodeMetadata, Workflow, WorkflowEdge, NodeExecutionInfo } from "../types/index.js";
|
|
6
6
|
import type { EndpointConfig } from "../config/endpoints.js";
|
|
7
|
-
|
|
8
|
-
* Generate a unique node ID based on node type and existing nodes
|
|
9
|
-
* Format: <node_type>.<number>
|
|
10
|
-
* Example: boolean_gateway.1, calculator.2
|
|
11
|
-
*/
|
|
12
|
-
export declare function generateNodeId(nodeTypeId: string, existingNodes: WorkflowNodeType[]): string;
|
|
7
|
+
export { generateNodeId, extractConfigDefaults } from "../utils/nodeIds.js";
|
|
13
8
|
/**
|
|
14
9
|
* Edge category type for styling purposes
|
|
15
10
|
* - trigger: For control flow connections (dataType: "trigger")
|
|
@@ -19,61 +14,16 @@ export declare function generateNodeId(nodeTypeId: string, existingNodes: Workfl
|
|
|
19
14
|
*/
|
|
20
15
|
export type EdgeCategory = "trigger" | "tool" | "loopback" | "data";
|
|
21
16
|
/**
|
|
22
|
-
* Edge styling configuration based on source port data type
|
|
17
|
+
* Edge styling configuration based on source port data type.
|
|
18
|
+
* Delegates to standalone functions in utils/edgeStyling.ts.
|
|
23
19
|
*/
|
|
24
20
|
export declare class EdgeStylingHelper {
|
|
25
|
-
/**
|
|
26
|
-
* Extract the port ID from a handle ID
|
|
27
|
-
* @param handleId - The handle ID string (e.g., "sample-node.1-output-trigger" or "trigger")
|
|
28
|
-
* @returns The port ID (e.g., "trigger") or the handleId itself for short format
|
|
29
|
-
*/
|
|
30
21
|
static extractPortIdFromHandle(handleId: string | undefined): string | null;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a port ID matches a dynamic branch in a Gateway node
|
|
33
|
-
* Gateway nodes store branches in config.branches array
|
|
34
|
-
* @param node - The workflow node to check
|
|
35
|
-
* @param portId - The port ID to look up
|
|
36
|
-
* @returns true if the portId matches a gateway branch
|
|
37
|
-
*/
|
|
38
22
|
static isGatewayBranch(node: WorkflowNodeType, portId: string): boolean;
|
|
39
|
-
/**
|
|
40
|
-
* Get the data type of a port from a node's metadata
|
|
41
|
-
* Also handles dynamic ports like Gateway branches
|
|
42
|
-
* @param node - The workflow node containing the port
|
|
43
|
-
* @param portId - The port ID to look up
|
|
44
|
-
* @param portType - Whether to look in "inputs" or "outputs"
|
|
45
|
-
* @returns The port's dataType or null if not found
|
|
46
|
-
*/
|
|
47
23
|
static getPortDataType(node: WorkflowNodeType, portId: string, portType: "input" | "output"): string | null;
|
|
48
|
-
/**
|
|
49
|
-
* Determine the edge category based on source port data type
|
|
50
|
-
* Note: This method does not check for loopback edges.
|
|
51
|
-
* Use getEdgeCategoryWithLoopback() for full edge categorization.
|
|
52
|
-
*
|
|
53
|
-
* @param sourcePortDataType - The data type of the source output port
|
|
54
|
-
* @returns The edge category for styling
|
|
55
|
-
*/
|
|
56
24
|
static getEdgeCategory(sourcePortDataType: string | null): EdgeCategory;
|
|
57
|
-
/**
|
|
58
|
-
* Determine the full edge category including loopback detection
|
|
59
|
-
* Loopback edges take precedence over source port data type
|
|
60
|
-
*
|
|
61
|
-
* @param edge - The edge to categorize
|
|
62
|
-
* @param sourcePortDataType - The data type of the source output port
|
|
63
|
-
* @returns The edge category for styling
|
|
64
|
-
*/
|
|
65
25
|
static getEdgeCategoryWithLoopback(edge: WorkflowEdge, sourcePortDataType: string | null): EdgeCategory;
|
|
66
|
-
/**
|
|
67
|
-
* Apply custom styling to connection edges based on edge type:
|
|
68
|
-
* - Loopback: Dashed gray line for loop iteration (targets loop_back port)
|
|
69
|
-
* - Trigger ports: Solid black line with arrow
|
|
70
|
-
* - Tool ports: Dashed amber line with arrow
|
|
71
|
-
* - Data ports: Normal gray line with arrow
|
|
72
|
-
*/
|
|
73
26
|
static applyConnectionStyling(edge: WorkflowEdge, sourceNode: WorkflowNodeType, targetNode: WorkflowNodeType): void;
|
|
74
|
-
/**
|
|
75
|
-
* Update existing edges with custom styling rules
|
|
76
|
-
*/
|
|
77
27
|
static updateEdgeStyles(edges: WorkflowEdge[], nodes: WorkflowNodeType[]): WorkflowEdge[];
|
|
78
28
|
}
|
|
79
29
|
/**
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* Workflow Editor Helper
|
|
3
3
|
* Contains business logic for workflow operations
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { hasCycles, hasInvalidCycles, isLoopbackEdge, } from "../utils/connections.js";
|
|
5
|
+
import { hasCycles, hasInvalidCycles, } from "../utils/connections.js";
|
|
7
6
|
import { workflowApi, nodeApi, setEndpointConfig } from "../services/api.js";
|
|
8
7
|
import { v4 as uuidv4 } from "uuid";
|
|
9
8
|
import { workflowActions } from "../stores/workflowStore.svelte.js";
|
|
@@ -12,231 +11,35 @@ import { WorkflowAdapter } from "../adapters/WorkflowAdapter.js";
|
|
|
12
11
|
import { AgentSpecAdapter } from "../adapters/agentspec/AgentSpecAdapter.js";
|
|
13
12
|
import { validateForAgentSpecExport } from "../adapters/agentspec/validator.js";
|
|
14
13
|
import { extractPortId } from "../utils/handleIds.js";
|
|
15
|
-
import { EDGE_MARKER_SIZES } from "../config/constants.js";
|
|
16
14
|
import { logger } from "../utils/logger.js";
|
|
15
|
+
import { generateNodeId, extractConfigDefaults } from "../utils/nodeIds.js";
|
|
16
|
+
import { applyConnectionStyling as applyConnectionStylingUtil, updateEdgeStyles as updateEdgeStylesUtil, isGatewayBranch as isGatewayBranchUtil, getPortDataType as getPortDataTypeUtil, getEdgeCategory as getEdgeCategoryUtil, getEdgeCategoryWithLoopback as getEdgeCategoryWithLoopbackUtil, } from "../utils/edgeStyling.js";
|
|
17
|
+
export { generateNodeId, extractConfigDefaults } from "../utils/nodeIds.js";
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
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
|
|
19
|
+
* Edge styling configuration based on source port data type.
|
|
20
|
+
* Delegates to standalone functions in utils/edgeStyling.ts.
|
|
40
21
|
*/
|
|
41
22
|
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
23
|
static extractPortIdFromHandle(handleId) {
|
|
48
24
|
return extractPortId(handleId);
|
|
49
25
|
}
|
|
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
26
|
static isGatewayBranch(node, portId) {
|
|
58
|
-
|
|
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);
|
|
27
|
+
return isGatewayBranchUtil(node, portId);
|
|
69
28
|
}
|
|
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
29
|
static getPortDataType(node, portId, portType) {
|
|
79
|
-
|
|
80
|
-
const ports = portType === "output"
|
|
81
|
-
? node.data?.metadata?.outputs
|
|
82
|
-
: node.data?.metadata?.inputs;
|
|
83
|
-
if (ports && Array.isArray(ports)) {
|
|
84
|
-
const port = ports.find((p) => p.id === portId);
|
|
85
|
-
if (port?.dataType) {
|
|
86
|
-
return port.dataType;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Check dynamic ports from config (dynamicInputs/dynamicOutputs)
|
|
90
|
-
const dynamicKey = portType === "output" ? "dynamicOutputs" : "dynamicInputs";
|
|
91
|
-
const dynamicPorts = node.data?.config?.[dynamicKey];
|
|
92
|
-
if (dynamicPorts && Array.isArray(dynamicPorts)) {
|
|
93
|
-
const dynamicPort = dynamicPorts.find((p) => p.name === portId);
|
|
94
|
-
if (dynamicPort?.dataType) {
|
|
95
|
-
return dynamicPort.dataType;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// For output ports, also check dynamic Gateway branches
|
|
99
|
-
// Gateway branches are always trigger type (control flow)
|
|
100
|
-
if (portType === "output" && this.isGatewayBranch(node, portId)) {
|
|
101
|
-
return "trigger";
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
30
|
+
return getPortDataTypeUtil(node, portId, portType);
|
|
104
31
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Determine the edge category based on source port data type
|
|
107
|
-
* Note: This method does not check for loopback edges.
|
|
108
|
-
* Use getEdgeCategoryWithLoopback() for full edge categorization.
|
|
109
|
-
*
|
|
110
|
-
* @param sourcePortDataType - The data type of the source output port
|
|
111
|
-
* @returns The edge category for styling
|
|
112
|
-
*/
|
|
113
32
|
static getEdgeCategory(sourcePortDataType) {
|
|
114
|
-
|
|
115
|
-
return "trigger";
|
|
116
|
-
}
|
|
117
|
-
if (sourcePortDataType === "tool") {
|
|
118
|
-
return "tool";
|
|
119
|
-
}
|
|
120
|
-
// All other data types (string, number, boolean, array, etc.) are "data" edges
|
|
121
|
-
return "data";
|
|
33
|
+
return getEdgeCategoryUtil(sourcePortDataType);
|
|
122
34
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Determine the full edge category including loopback detection
|
|
125
|
-
* Loopback edges take precedence over source port data type
|
|
126
|
-
*
|
|
127
|
-
* @param edge - The edge to categorize
|
|
128
|
-
* @param sourcePortDataType - The data type of the source output port
|
|
129
|
-
* @returns The edge category for styling
|
|
130
|
-
*/
|
|
131
35
|
static getEdgeCategoryWithLoopback(edge, sourcePortDataType) {
|
|
132
|
-
|
|
133
|
-
// Check this first as it takes precedence
|
|
134
|
-
if (isLoopbackEdge(edge)) {
|
|
135
|
-
return "loopback";
|
|
136
|
-
}
|
|
137
|
-
// Fall back to source port data type categorization
|
|
138
|
-
return this.getEdgeCategory(sourcePortDataType);
|
|
36
|
+
return getEdgeCategoryWithLoopbackUtil(edge, sourcePortDataType);
|
|
139
37
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Apply custom styling to connection edges based on edge type:
|
|
142
|
-
* - Loopback: Dashed gray line for loop iteration (targets loop_back port)
|
|
143
|
-
* - Trigger ports: Solid black line with arrow
|
|
144
|
-
* - Tool ports: Dashed amber line with arrow
|
|
145
|
-
* - Data ports: Normal gray line with arrow
|
|
146
|
-
*/
|
|
147
38
|
static applyConnectionStyling(edge, sourceNode, targetNode) {
|
|
148
|
-
|
|
149
|
-
const sourcePortId = this.extractPortIdFromHandle(edge.sourceHandle);
|
|
150
|
-
// Get the source port's data type
|
|
151
|
-
const sourcePortDataType = sourcePortId
|
|
152
|
-
? this.getPortDataType(sourceNode, sourcePortId, "output")
|
|
153
|
-
: null;
|
|
154
|
-
// Determine edge category (loopback takes precedence)
|
|
155
|
-
const edgeCategory = this.getEdgeCategoryWithLoopback(edge, sourcePortDataType);
|
|
156
|
-
// Apply styling based on edge category
|
|
157
|
-
// Marker colors use CSS custom properties so they respond to theme changes automatically
|
|
158
|
-
switch (edgeCategory) {
|
|
159
|
-
case "loopback":
|
|
160
|
-
// Loopback edges: dashed gray line for loop iteration
|
|
161
|
-
edge.style =
|
|
162
|
-
"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);";
|
|
163
|
-
edge.class = "flowdrop--edge--loopback";
|
|
164
|
-
edge.markerEnd = {
|
|
165
|
-
type: MarkerType.ArrowClosed,
|
|
166
|
-
...EDGE_MARKER_SIZES.loopback,
|
|
167
|
-
color: "var(--fd-edge-loopback)",
|
|
168
|
-
};
|
|
169
|
-
break;
|
|
170
|
-
case "trigger":
|
|
171
|
-
// Trigger edges: solid dark line for control flow
|
|
172
|
-
edge.style =
|
|
173
|
-
"stroke: var(--fd-edge-trigger); stroke-width: var(--fd-edge-trigger-width);";
|
|
174
|
-
edge.class = "flowdrop--edge--trigger";
|
|
175
|
-
edge.markerEnd = {
|
|
176
|
-
type: MarkerType.ArrowClosed,
|
|
177
|
-
...EDGE_MARKER_SIZES.trigger,
|
|
178
|
-
color: "var(--fd-edge-trigger)",
|
|
179
|
-
};
|
|
180
|
-
break;
|
|
181
|
-
case "tool":
|
|
182
|
-
// Tool edges: dashed amber line
|
|
183
|
-
edge.style = "stroke: var(--fd-edge-tool); stroke-dasharray: 5 3;";
|
|
184
|
-
edge.class = "flowdrop--edge--tool";
|
|
185
|
-
edge.markerEnd = {
|
|
186
|
-
type: MarkerType.ArrowClosed,
|
|
187
|
-
...EDGE_MARKER_SIZES.tool,
|
|
188
|
-
color: "var(--fd-edge-tool)",
|
|
189
|
-
};
|
|
190
|
-
break;
|
|
191
|
-
case "data":
|
|
192
|
-
default:
|
|
193
|
-
// Data edges: normal gray line
|
|
194
|
-
edge.style = "stroke: var(--fd-edge-data);";
|
|
195
|
-
edge.class = "flowdrop--edge--data";
|
|
196
|
-
edge.markerEnd = {
|
|
197
|
-
type: MarkerType.ArrowClosed,
|
|
198
|
-
...EDGE_MARKER_SIZES.data,
|
|
199
|
-
color: "var(--fd-edge-data)",
|
|
200
|
-
};
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
// Store metadata in edge data for API and persistence
|
|
204
|
-
edge.data = {
|
|
205
|
-
...edge.data,
|
|
206
|
-
metadata: {
|
|
207
|
-
...(edge.data?.metadata || {}),
|
|
208
|
-
edgeType: edgeCategory,
|
|
209
|
-
sourcePortDataType: sourcePortDataType ?? undefined,
|
|
210
|
-
},
|
|
211
|
-
targetNodeType: targetNode.type,
|
|
212
|
-
targetCategory: targetNode.data.metadata.category,
|
|
213
|
-
};
|
|
39
|
+
applyConnectionStylingUtil(edge, sourceNode, targetNode);
|
|
214
40
|
}
|
|
215
|
-
/**
|
|
216
|
-
* Update existing edges with custom styling rules
|
|
217
|
-
*/
|
|
218
41
|
static updateEdgeStyles(edges, nodes) {
|
|
219
|
-
return edges
|
|
220
|
-
// Find source and target nodes
|
|
221
|
-
const sourceNode = nodes.find((node) => node.id === edge.source);
|
|
222
|
-
const targetNode = nodes.find((node) => node.id === edge.target);
|
|
223
|
-
// Create a copy of the edge
|
|
224
|
-
const updatedEdge = { ...edge };
|
|
225
|
-
if (!sourceNode || !targetNode) {
|
|
226
|
-
// Set default edgeType even when nodes are not found
|
|
227
|
-
updatedEdge.data = {
|
|
228
|
-
...updatedEdge.data,
|
|
229
|
-
metadata: {
|
|
230
|
-
...(updatedEdge.data?.metadata || {}),
|
|
231
|
-
edgeType: "data",
|
|
232
|
-
},
|
|
233
|
-
};
|
|
234
|
-
return updatedEdge;
|
|
235
|
-
}
|
|
236
|
-
// Apply full styling when nodes are available
|
|
237
|
-
this.applyConnectionStyling(updatedEdge, sourceNode, targetNode);
|
|
238
|
-
return updatedEdge;
|
|
239
|
-
});
|
|
42
|
+
return updateEdgeStylesUtil(edges, nodes);
|
|
240
43
|
}
|
|
241
44
|
}
|
|
242
45
|
/**
|
|
@@ -323,27 +126,9 @@ export class NodeOperationsHelper {
|
|
|
323
126
|
else {
|
|
324
127
|
// New format (direct NodeMetadata)
|
|
325
128
|
nodeType = parsedData;
|
|
326
|
-
// Extract initial config from configSchema
|
|
327
|
-
let initialConfig = {};
|
|
328
|
-
if (nodeType.configSchema &&
|
|
329
|
-
typeof nodeType.configSchema === "object") {
|
|
330
|
-
// If configSchema is a JSON Schema, extract default values
|
|
331
|
-
if (nodeType.configSchema.properties) {
|
|
332
|
-
// JSON Schema format - extract defaults
|
|
333
|
-
Object.entries(nodeType.configSchema.properties).forEach(([key, prop]) => {
|
|
334
|
-
if (prop && typeof prop === "object" && "default" in prop) {
|
|
335
|
-
initialConfig[key] = prop.default;
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
// Simple object format - use as is
|
|
341
|
-
initialConfig = { ...nodeType.configSchema };
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
129
|
nodeData = {
|
|
345
130
|
label: nodeType.name,
|
|
346
|
-
config:
|
|
131
|
+
config: extractConfigDefaults(nodeType.configSchema),
|
|
347
132
|
metadata: nodeType,
|
|
348
133
|
};
|
|
349
134
|
}
|
|
@@ -117,7 +117,7 @@ export { default as SessionManager } from "../components/playground/SessionManag
|
|
|
117
117
|
export { default as InputCollector } from "../components/playground/InputCollector.svelte";
|
|
118
118
|
export { default as ExecutionLogs } from "../components/playground/ExecutionLogs.svelte";
|
|
119
119
|
export { default as MessageBubble } from "../components/playground/MessageBubble.svelte";
|
|
120
|
-
export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, } from "../components/interrupt/index.js";
|
|
120
|
+
export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, ReviewPrompt, } from "../components/interrupt/index.js";
|
|
121
121
|
export { PlaygroundService, playgroundService, } from "../services/playgroundService.js";
|
|
122
122
|
export { InterruptService, interruptService, } from "../services/interruptService.js";
|
|
123
123
|
export { getCurrentSession, getSessions, getMessages, getIsExecuting, getIsLoading, getError as getPlaygroundError, getCurrentWorkflow, getLastPollTimestamp, getSessionStatus, getMessageCount, getChatMessages, getLogMessages, getLatestMessage, getInputFields, getHasChatInput, getSessionCount, playgroundActions, createPollingCallback, subscribeToSessionStatus, getCurrentSessionId, isSessionSelected, getMessagesSnapshot, getLatestMessageTimestamp, } from "../stores/playgroundStore.svelte.js";
|
package/dist/playground/index.js
CHANGED
|
@@ -123,7 +123,7 @@ export { default as MessageBubble } from "../components/playground/MessageBubble
|
|
|
123
123
|
// ============================================================================
|
|
124
124
|
// Interrupt Components (Human-in-the-Loop)
|
|
125
125
|
// ============================================================================
|
|
126
|
-
export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, } from "../components/interrupt/index.js";
|
|
126
|
+
export { InterruptBubble, ConfirmationPrompt, ChoicePrompt, TextInputPrompt, FormPrompt, ReviewPrompt, } from "../components/interrupt/index.js";
|
|
127
127
|
// ============================================================================
|
|
128
128
|
// Playground Service
|
|
129
129
|
// ============================================================================
|