@flowdrop/flowdrop 1.14.0 → 2.0.0-beta.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/CHANGELOG.md +475 -0
- package/MIGRATION-2.0.md +472 -0
- package/README.md +23 -23
- package/dist/adapters/WorkflowAdapter.d.ts +1 -1
- package/dist/adapters/WorkflowAdapter.js +14 -8
- package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
- package/dist/chat/batchFeedback.d.ts +39 -0
- package/dist/chat/batchFeedback.js +51 -0
- package/dist/commands/executor.js +15 -1
- package/dist/commands/storeIntegration.svelte.d.ts +4 -1
- package/dist/commands/storeIntegration.svelte.js +26 -21
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/App.svelte +162 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +110 -66
- package/dist/components/ConfigModal.svelte +7 -2
- package/dist/components/ConnectionLine.svelte +4 -2
- package/dist/components/Navbar.svelte +61 -1
- package/dist/components/NodeSidebar.svelte +27 -45
- package/dist/components/NodeStatusOverlay.svelte +94 -6
- package/dist/components/NodeSwapPicker.svelte +10 -8
- package/dist/components/PipelineStatus.svelte +16 -67
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +45 -40
- package/dist/components/SchemaForm.svelte.d.ts +0 -8
- package/dist/components/SettingsModal.svelte +8 -3
- package/dist/components/SettingsPanel.svelte +20 -4
- package/dist/components/SwapMappingEditor.svelte +67 -49
- package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
- package/dist/components/UniversalNode.svelte +9 -7
- package/dist/components/WorkflowEditor.svelte +118 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +18 -10
- package/dist/components/chat/AIChatPanel.svelte +93 -89
- package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
- package/dist/components/chat/CommandPreview.svelte +2 -1
- package/dist/components/console/CommandConsole.svelte +7 -5
- package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
- package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
- package/dist/components/console/ConsoleInput.svelte +15 -6
- package/dist/components/console/ConsoleOutput.svelte +2 -1
- package/dist/components/form/FormArray.svelte +5 -9
- package/dist/components/form/FormArray.svelte.d.ts +2 -1
- package/dist/components/form/FormAutocomplete.svelte +29 -13
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +4 -2
- package/dist/components/form/FormMarkdownEditor.svelte +9 -4
- package/dist/components/form/FormRangeField.svelte +1 -0
- package/dist/components/form/FormTemplateEditor.svelte +11 -3
- package/dist/components/form/FormToggle.svelte +5 -12
- package/dist/components/form/FormToggle.svelte.d.ts +4 -2
- package/dist/components/form/templateAutocomplete.js +1 -5
- package/dist/components/form/types.d.ts +1 -14
- package/dist/components/interrupt/FormPrompt.svelte +3 -2
- package/dist/components/interrupt/InterruptBubble.svelte +16 -17
- package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
- package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
- package/dist/components/layouts/MainLayout.svelte +20 -13
- package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
- package/dist/components/nodes/AtomNode.svelte +292 -0
- package/dist/components/nodes/AtomNode.svelte.d.ts +26 -0
- package/dist/components/nodes/GatewayNode.svelte +19 -10
- package/dist/components/nodes/IdeaNode.svelte +7 -0
- package/dist/components/nodes/SimpleNode.svelte +11 -6
- package/dist/components/nodes/SquareNode.svelte +15 -8
- package/dist/components/nodes/TerminalNode.svelte +9 -4
- package/dist/components/nodes/ToolNode.svelte +7 -1
- package/dist/components/nodes/WorkflowNode.svelte +16 -7
- package/dist/components/playground/ChatInput.svelte +11 -14
- package/dist/components/playground/ChatPanel.svelte +6 -49
- package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
- package/dist/components/playground/ControlPanel.svelte +134 -123
- package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
- package/dist/components/playground/ExecutionLogs.svelte +11 -9
- package/dist/components/playground/InputCollector.svelte +11 -9
- package/dist/components/playground/MessageStream.svelte +17 -23
- package/dist/components/playground/PipelineKanbanView.svelte +65 -6
- package/dist/components/playground/PipelinePanel.svelte +11 -5
- package/dist/components/playground/PipelineTableView.svelte +186 -44
- package/dist/components/playground/Playground.svelte +95 -92
- package/dist/components/playground/Playground.svelte.d.ts +2 -0
- package/dist/components/playground/PlaygroundApp.svelte +6 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +13 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +34 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +28 -0
- package/dist/components/playground/pipelineViewUtils.svelte.js +38 -1
- package/dist/config/endpoints.d.ts +0 -7
- package/dist/config/endpoints.js +2 -10
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +6 -6
- package/dist/display/index.d.ts +0 -2
- package/dist/display/index.js +0 -6
- package/dist/editor/index.d.ts +19 -20
- package/dist/editor/index.js +25 -35
- package/dist/form/code.d.ts +25 -15
- package/dist/form/code.js +44 -41
- package/dist/form/fieldRegistry.d.ts +17 -13
- package/dist/form/fieldRegistry.js +32 -12
- package/dist/form/full.d.ts +17 -13
- package/dist/form/full.js +22 -27
- package/dist/form/index.d.ts +3 -3
- package/dist/form/index.js +3 -3
- package/dist/form/markdown.d.ts +13 -8
- package/dist/form/markdown.js +22 -23
- package/dist/helpers/proximityConnect.d.ts +7 -3
- package/dist/helpers/proximityConnect.js +19 -6
- package/dist/helpers/workflowEditorHelper.d.ts +12 -5
- package/dist/helpers/workflowEditorHelper.js +27 -25
- package/dist/index.d.ts +28 -24
- package/dist/index.js +27 -50
- package/dist/messages/defaults.d.ts +2 -5
- package/dist/messages/defaults.js +3 -6
- package/dist/messages/index.d.ts +0 -1
- package/dist/messages/index.js +0 -1
- package/dist/mocks/app-forms.d.ts +6 -2
- package/dist/mocks/app-forms.js +11 -4
- package/dist/openapi/v1/openapi.yaml +227 -164
- package/dist/playground/index.d.ts +2 -3
- package/dist/playground/index.js +2 -30
- package/dist/playground/mount.d.ts +15 -0
- package/dist/playground/mount.js +46 -20
- package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
- package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
- package/dist/registry/builtinFormats.d.ts +9 -18
- package/dist/registry/builtinFormats.js +9 -39
- package/dist/registry/builtinNodes.d.ts +1 -26
- package/dist/registry/builtinNodes.js +14 -50
- package/dist/registry/index.d.ts +3 -4
- package/dist/registry/index.js +4 -6
- package/dist/registry/nodeComponentRegistry.d.ts +182 -15
- package/dist/registry/nodeComponentRegistry.js +235 -17
- package/dist/registry/workflowFormatRegistry.d.ts +14 -9
- package/dist/registry/workflowFormatRegistry.js +24 -8
- package/dist/{schema → schemas}/index.d.ts +2 -2
- package/dist/{schema → schemas}/index.js +2 -2
- package/dist/schemas/v1/workflow.schema.json +53 -6
- package/dist/services/agentSpecExecutionService.js +0 -1
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +5 -22
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/chatService.d.ts +8 -4
- package/dist/services/chatService.js +15 -15
- package/dist/services/draftStorage.d.ts +129 -13
- package/dist/services/draftStorage.js +185 -37
- package/dist/services/dynamicSchemaService.d.ts +2 -1
- package/dist/services/dynamicSchemaService.js +5 -22
- package/dist/services/globalSave.d.ts +13 -12
- package/dist/services/globalSave.js +29 -51
- package/dist/services/historyService.d.ts +9 -3
- package/dist/services/historyService.js +9 -3
- package/dist/services/interruptService.d.ts +14 -9
- package/dist/services/interruptService.js +27 -27
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +14 -9
- package/dist/services/playgroundService.js +31 -30
- package/dist/services/variableService.d.ts +2 -1
- package/dist/services/variableService.js +2 -2
- package/dist/services/workflowStorage.js +6 -6
- package/dist/stores/apiContext.d.ts +45 -0
- package/dist/stores/apiContext.js +65 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +70 -64
- package/dist/stores/getInstance.svelte.d.ts +39 -0
- package/dist/stores/getInstance.svelte.js +65 -0
- package/dist/stores/historyStore.svelte.d.ts +77 -93
- package/dist/stores/historyStore.svelte.js +134 -160
- package/dist/stores/instanceContainer.svelte.d.ts +111 -0
- package/dist/stores/instanceContainer.svelte.js +114 -0
- package/dist/stores/interruptStore.svelte.d.ts +112 -82
- package/dist/stores/interruptStore.svelte.js +253 -226
- package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
- package/dist/stores/pipelinePanelStore.svelte.js +61 -14
- package/dist/stores/playgroundStore.svelte.d.ts +169 -216
- package/dist/stores/playgroundStore.svelte.js +515 -572
- package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
- package/dist/stores/portCoordinateStore.svelte.js +109 -98
- package/dist/stores/settingsStore.svelte.d.ts +4 -1
- package/dist/stores/settingsStore.svelte.js +47 -12
- package/dist/stores/workflowStore.svelte.d.ts +178 -213
- package/dist/stores/workflowStore.svelte.js +449 -501
- package/dist/stories/EdgeDecorator.svelte +5 -2
- package/dist/stories/NodeDecorator.svelte +5 -3
- package/dist/svelte-app.d.ts +60 -10
- package/dist/svelte-app.js +157 -53
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +71 -6
- package/dist/types/navbar.d.ts +7 -0
- package/dist/types/playground.d.ts +18 -3
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.js +1 -0
- package/dist/utils/colors.d.ts +47 -21
- package/dist/utils/colors.js +69 -68
- package/dist/utils/connections.d.ts +9 -15
- package/dist/utils/connections.js +13 -32
- package/dist/utils/duration.d.ts +13 -0
- package/dist/utils/duration.js +45 -0
- package/dist/utils/formMerge.d.ts +36 -0
- package/dist/utils/formMerge.js +70 -0
- package/dist/utils/icons.d.ts +5 -2
- package/dist/utils/icons.js +6 -5
- package/dist/utils/nodeSwap.d.ts +6 -2
- package/dist/utils/nodeSwap.js +62 -126
- package/dist/utils/nodeTypes.d.ts +17 -8
- package/dist/utils/nodeTypes.js +27 -19
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +6 -5
- package/dist/messages/deprecation.d.ts +0 -20
- package/dist/messages/deprecation.js +0 -33
- package/dist/registry/plugin.d.ts +0 -215
- package/dist/registry/plugin.js +0 -249
- package/dist/services/api.d.ts +0 -129
- package/dist/services/api.js +0 -217
|
@@ -11,15 +11,17 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Extends BaseRegistry for shared mechanics (subscribe, onClear, etc.).
|
|
13
13
|
*/
|
|
14
|
-
import { BaseRegistry } from './BaseRegistry.js';
|
|
14
|
+
import { BaseRegistry } from './BaseRegistry.svelte.js';
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Per-instance registry for workflow format adapters.
|
|
17
|
+
* Extends BaseRegistry for shared mechanics; seeded with the built-in
|
|
18
|
+
* adapters at construction (see `createFlowDropInstance`). Reach it via
|
|
19
|
+
* `fd.formats`, or supply adapters through the `formatAdapters` mount option.
|
|
18
20
|
*
|
|
19
21
|
* @example
|
|
20
22
|
* ```typescript
|
|
21
23
|
* // Register a custom format
|
|
22
|
-
*
|
|
24
|
+
* fd.formats.register({
|
|
23
25
|
* id: 'n8n',
|
|
24
26
|
* name: 'n8n Workflow',
|
|
25
27
|
* export: (workflow) => JSON.stringify(convertToN8n(workflow)),
|
|
@@ -27,10 +29,23 @@ import { BaseRegistry } from './BaseRegistry.js';
|
|
|
27
29
|
* });
|
|
28
30
|
*
|
|
29
31
|
* // Get an adapter
|
|
30
|
-
* const adapter =
|
|
32
|
+
* const adapter = fd.formats.get('n8n');
|
|
31
33
|
* ```
|
|
32
34
|
*/
|
|
33
|
-
class WorkflowFormatRegistry extends BaseRegistry {
|
|
35
|
+
export class WorkflowFormatRegistry extends BaseRegistry {
|
|
36
|
+
/**
|
|
37
|
+
* @param seed - Optional initial format adapters. When omitted the registry
|
|
38
|
+
* starts empty; instances created via `createFlowDropInstance` pass the
|
|
39
|
+
* built-in flowdrop + agentspec adapters (see `builtinFormats.ts`).
|
|
40
|
+
*/
|
|
41
|
+
constructor(seed) {
|
|
42
|
+
super();
|
|
43
|
+
if (seed) {
|
|
44
|
+
for (const adapter of seed) {
|
|
45
|
+
this.register(adapter, true);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
34
49
|
/**
|
|
35
50
|
* Register a workflow format adapter.
|
|
36
51
|
*
|
|
@@ -44,6 +59,7 @@ class WorkflowFormatRegistry extends BaseRegistry {
|
|
|
44
59
|
`Use overwrite: true to replace it.`);
|
|
45
60
|
}
|
|
46
61
|
this.items.set(adapter.id, adapter);
|
|
62
|
+
this.touch();
|
|
47
63
|
this.notifyListeners();
|
|
48
64
|
}
|
|
49
65
|
/**
|
|
@@ -61,6 +77,7 @@ class WorkflowFormatRegistry extends BaseRegistry {
|
|
|
61
77
|
* @returns Array of NodeMetadata from all format adapters
|
|
62
78
|
*/
|
|
63
79
|
getAllFormatNodes() {
|
|
80
|
+
this.trackVersion(); // reactive dependency (reads items directly)
|
|
64
81
|
const allNodes = [];
|
|
65
82
|
for (const adapter of this.items.values()) {
|
|
66
83
|
if (adapter.nodes && adapter.nodes.length > 0) {
|
|
@@ -76,6 +93,7 @@ class WorkflowFormatRegistry extends BaseRegistry {
|
|
|
76
93
|
* @returns Array of NodeMetadata for the format, or empty array
|
|
77
94
|
*/
|
|
78
95
|
getFormatNodes(formatId) {
|
|
96
|
+
this.trackVersion(); // reactive dependency (reads items directly)
|
|
79
97
|
const adapter = this.items.get(formatId);
|
|
80
98
|
return adapter?.nodes ?? [];
|
|
81
99
|
}
|
|
@@ -92,5 +110,3 @@ class WorkflowFormatRegistry extends BaseRegistry {
|
|
|
92
110
|
}));
|
|
93
111
|
}
|
|
94
112
|
}
|
|
95
|
-
/** Singleton instance of the workflow format registry */
|
|
96
|
-
export const workflowFormatRegistry = new WorkflowFormatRegistry();
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* const valid = validate(myWorkflow);
|
|
16
16
|
* ```
|
|
17
17
|
*
|
|
18
|
-
* @module
|
|
18
|
+
* @module schemas
|
|
19
19
|
*/
|
|
20
|
-
import workflowSchema from '
|
|
20
|
+
import workflowSchema from './v1/workflow.schema.json';
|
|
21
21
|
/** Current workflow schema format version */
|
|
22
22
|
export declare const WORKFLOW_SCHEMA_VERSION = "1.0.0";
|
|
23
23
|
export { workflowSchema };
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* const valid = validate(myWorkflow);
|
|
16
16
|
* ```
|
|
17
17
|
*
|
|
18
|
-
* @module
|
|
18
|
+
* @module schemas
|
|
19
19
|
*/
|
|
20
|
-
import workflowSchema from '
|
|
20
|
+
import workflowSchema from './v1/workflow.schema.json';
|
|
21
21
|
/** Current workflow schema format version */
|
|
22
22
|
export const WORKFLOW_SCHEMA_VERSION = '1.0.0';
|
|
23
23
|
export { workflowSchema };
|
|
@@ -51,6 +51,46 @@
|
|
|
51
51
|
"metadata"
|
|
52
52
|
],
|
|
53
53
|
"$defs": {
|
|
54
|
+
"AtomUIConfig": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"description": "Display/behaviour settings for minimalist `atom` nodes (e.g. Constant, Cast).\nLives under `extensions.ui.atom`. The atom renderer reads these to decide what\nto show, and `valueTypeKey` drives the bound output port's `dataType` from\nconfig so connection validation matches the type the user picked.\n\nAll fields are optional — an empty object renders a label-only pill using the\nnode's `label`.\n",
|
|
57
|
+
"properties": {
|
|
58
|
+
"valueKey": {
|
|
59
|
+
"type": "string",
|
|
60
|
+
"description": "Config key whose value becomes the node body text.\nFalls back to the node `label` when unset or empty.\n"
|
|
61
|
+
},
|
|
62
|
+
"valueTypeKey": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Config key holding the selected value's type (a port dataType id).\nThe bound output port adopts this dataType.\n"
|
|
65
|
+
},
|
|
66
|
+
"outputPortId": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Output port id driven by `valueTypeKey`.\nDefaults to the first output port when unset.\n"
|
|
69
|
+
},
|
|
70
|
+
"shape": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"enum": [
|
|
73
|
+
"pill",
|
|
74
|
+
"rectangle"
|
|
75
|
+
],
|
|
76
|
+
"default": "pill",
|
|
77
|
+
"description": "Body shape. `pill` (default) is fully rounded; `rectangle` is lightly rounded.\n"
|
|
78
|
+
},
|
|
79
|
+
"prefix": {
|
|
80
|
+
"type": "string",
|
|
81
|
+
"description": "Dimmed affordance rendered before the body (e.g. `\"→ \"` to mark a transform).\nStays visible while the body value ellipsizes. Hidden in the empty state.\n"
|
|
82
|
+
},
|
|
83
|
+
"placeholder": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Text shown (dimmed) when the resolved body value is empty/unset."
|
|
86
|
+
},
|
|
87
|
+
"maxWidth": {
|
|
88
|
+
"type": "integer",
|
|
89
|
+
"description": "Max body width in px before the label ellipsizes."
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"additionalProperties": false
|
|
93
|
+
},
|
|
54
94
|
"AutocompleteConfig": {
|
|
55
95
|
"type": "object",
|
|
56
96
|
"description": "Configuration for autocomplete fields that fetch suggestions from a callback URL.\nUsed when format is \"autocomplete\".\n",
|
|
@@ -414,15 +454,17 @@
|
|
|
414
454
|
},
|
|
415
455
|
"nodeType": {
|
|
416
456
|
"type": "string",
|
|
417
|
-
"description": "Changes how the node is visually rendered. This allows a single node definition\nto support multiple visual representations.\n\nAvailable built-in types:\n- `default`: Standard workflow node with full details\n- `simple`: Compact layout with minimal chrome\n- `square`: Geometric square layout (icon-only)\n- `tool`: Specialized style for agent tools\n- `gateway`: Branching control flow visualization\n- `terminal`: Start/end/exit node styling\n- `note`: Sticky note style for annotations\n\nThe node's `metadata.supportedTypes` defines which types are allowed.\nIf invalid or missing, falls back to `metadata.type` or \"default\".\n",
|
|
457
|
+
"description": "Changes how the node is visually rendered. This allows a single node definition\nto support multiple visual representations.\n\nAvailable built-in types:\n- `default`: Standard workflow node with full details\n- `simple`: Compact layout with minimal chrome\n- `square`: Geometric square layout (icon-only)\n- `atom`: Minimal label-only pill/rectangle (uses extensions.ui.atom)\n- `tool`: Specialized style for agent tools\n- `gateway`: Branching control flow visualization\n- `terminal`: Start/end/exit node styling\n- `note`: Sticky note style for annotations\n- `idea`: Conceptual idea node for BPMN-like flow diagrams\n\nThe node's `metadata.supportedTypes` defines which types are allowed.\nIf invalid or missing, falls back to `metadata.type` or \"default\".\n",
|
|
418
458
|
"enum": [
|
|
419
459
|
"default",
|
|
420
460
|
"simple",
|
|
421
461
|
"square",
|
|
462
|
+
"atom",
|
|
422
463
|
"tool",
|
|
423
464
|
"gateway",
|
|
424
465
|
"terminal",
|
|
425
|
-
"note"
|
|
466
|
+
"note",
|
|
467
|
+
"idea"
|
|
426
468
|
]
|
|
427
469
|
},
|
|
428
470
|
"dynamicInputs": {
|
|
@@ -677,12 +719,14 @@
|
|
|
677
719
|
"note",
|
|
678
720
|
"simple",
|
|
679
721
|
"square",
|
|
722
|
+
"atom",
|
|
680
723
|
"tool",
|
|
681
724
|
"gateway",
|
|
682
725
|
"terminal",
|
|
726
|
+
"idea",
|
|
683
727
|
"default"
|
|
684
728
|
],
|
|
685
|
-
"description": "Visual rendering type for the node.\n\nBuilt-in types:\n- `note` - Sticky note with markdown support\n- `simple` - Compact layout with header and description\n- `square` - Minimal square node with centered icon\n- `tool` - Specialized node for agent tools\n- `gateway` - Branching control flow with dynamic branches (uses config.branches)\n- `terminal` - Circular node for workflow start/end/exit points\n- `default` - Full-featured workflow node with dynamic port support\n\n## Dynamic Port Support\n\nThe `default` and `gateway` node types support dynamic ports:\n\n- **default**: Supports `config.dynamicInputs` and `config.dynamicOutputs`\n for user-defined input/output handles\n- **gateway**: Supports `config.branches` for conditional branching paths\n\n## UI Extensions\n\nAll node types support `extensions.ui.hideUnconnectedHandles` to control\nvisibility of unconnected ports.\n"
|
|
729
|
+
"description": "Visual rendering type for the node.\n\nBuilt-in types:\n- `note` - Sticky note with markdown support\n- `simple` - Compact layout with header and description\n- `square` - Minimal square node with centered icon\n- `atom` - Minimal label-only pill/rectangle for value/transform nodes (uses extensions.ui.atom)\n- `tool` - Specialized node for agent tools\n- `gateway` - Branching control flow with dynamic branches (uses config.branches)\n- `terminal` - Circular node for workflow start/end/exit points\n- `idea` - Conceptual idea node for BPMN-like flow diagrams\n- `default` - Full-featured workflow node with dynamic port support\n\n## Dynamic Port Support\n\nThe `default` and `gateway` node types support dynamic ports:\n\n- **default**: Supports `config.dynamicInputs` and `config.dynamicOutputs`\n for user-defined input/output handles\n- **gateway**: Supports `config.branches` for conditional branching paths\n\n## UI Extensions\n\nAll node types support `extensions.ui.hideUnconnectedHandles` to control\nvisibility of unconnected ports.\n"
|
|
686
730
|
},
|
|
687
731
|
"NodeUIExtensions": {
|
|
688
732
|
"type": "object",
|
|
@@ -692,6 +736,9 @@
|
|
|
692
736
|
"type": "boolean",
|
|
693
737
|
"description": "Show/hide unconnected handles (ports) to reduce visual noise.\nWhen true, only ports with active connections are displayed.\nUseful for nodes with many optional ports.\n"
|
|
694
738
|
},
|
|
739
|
+
"atom": {
|
|
740
|
+
"$ref": "#/$defs/AtomUIConfig"
|
|
741
|
+
},
|
|
695
742
|
"style": {
|
|
696
743
|
"type": "object",
|
|
697
744
|
"additionalProperties": true,
|
|
@@ -1006,9 +1053,9 @@
|
|
|
1006
1053
|
"WorkflowMetadata": {
|
|
1007
1054
|
"type": "object",
|
|
1008
1055
|
"properties": {
|
|
1009
|
-
"
|
|
1056
|
+
"schemaVersion": {
|
|
1010
1057
|
"type": "string",
|
|
1011
|
-
"description": "Workflow version"
|
|
1058
|
+
"description": "Workflow schema format version — identifies the document format, not the workflow's own revision."
|
|
1012
1059
|
},
|
|
1013
1060
|
"createdAt": {
|
|
1014
1061
|
"type": "string",
|
|
@@ -1046,7 +1093,7 @@
|
|
|
1046
1093
|
}
|
|
1047
1094
|
},
|
|
1048
1095
|
"required": [
|
|
1049
|
-
"
|
|
1096
|
+
"schemaVersion",
|
|
1050
1097
|
"createdAt",
|
|
1051
1098
|
"updatedAt"
|
|
1052
1099
|
]
|
|
@@ -227,7 +227,6 @@ export class AgentSpecExecutionService {
|
|
|
227
227
|
/** Get the config, throwing if not configured */
|
|
228
228
|
getConfig() {
|
|
229
229
|
this.ensureConfigured();
|
|
230
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
231
230
|
return this.config;
|
|
232
231
|
}
|
|
233
232
|
startPolling(executionId, nameToNodeId, onNodeUpdate, onComplete, onError, intervalMs = 2000) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* @module services/apiVariableService
|
|
7
7
|
*/
|
|
8
8
|
import type { VariableSchema, ApiVariablesConfig, AuthProvider } from '../types/index.js';
|
|
9
|
+
import type { EndpointConfig } from '../config/endpoints.js';
|
|
9
10
|
/**
|
|
10
11
|
* Context for variable API requests
|
|
11
12
|
*/
|
|
@@ -71,7 +72,7 @@ export declare function resolveEndpointUrl(template: string, context: VariableCo
|
|
|
71
72
|
* }
|
|
72
73
|
* ```
|
|
73
74
|
*/
|
|
74
|
-
export declare function fetchVariableSchema(workflowId: string | undefined, nodeId: string, config: ApiVariablesConfig, authProvider?: AuthProvider): Promise<ApiVariableResult>;
|
|
75
|
+
export declare function fetchVariableSchema(endpointConfig: EndpointConfig | null, workflowId: string | undefined, nodeId: string, config: ApiVariablesConfig, authProvider?: AuthProvider): Promise<ApiVariableResult>;
|
|
75
76
|
/**
|
|
76
77
|
* Clears the variable schema cache.
|
|
77
78
|
* Can optionally clear only entries matching a specific pattern.
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module services/apiVariableService
|
|
7
7
|
*/
|
|
8
|
-
import { getEndpointConfig } from './api.js';
|
|
9
8
|
import { logger } from '../utils/logger.js';
|
|
10
9
|
import { DEFAULT_CACHE_TTL_MS } from '../config/constants.js';
|
|
11
10
|
/**
|
|
@@ -116,7 +115,7 @@ function resolveBodyTemplates(body, context) {
|
|
|
116
115
|
* }
|
|
117
116
|
* ```
|
|
118
117
|
*/
|
|
119
|
-
export async function fetchVariableSchema(workflowId, nodeId, config, authProvider) {
|
|
118
|
+
export async function fetchVariableSchema(endpointConfig, workflowId, nodeId, config, authProvider) {
|
|
120
119
|
const endpoint = config.endpoint;
|
|
121
120
|
const context = { workflowId, nodeId };
|
|
122
121
|
// Generate cache key
|
|
@@ -136,12 +135,9 @@ export async function fetchVariableSchema(workflowId, nodeId, config, authProvid
|
|
|
136
135
|
// Resolve the URL with template variables
|
|
137
136
|
let url = resolveEndpointUrl(endpoint.url, context);
|
|
138
137
|
// If URL is relative, prepend base URL from endpoint config
|
|
139
|
-
if (url.startsWith('/')) {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
const baseUrl = currentConfig.baseUrl.replace(/\/$/, '');
|
|
143
|
-
url = `${baseUrl}${url}`;
|
|
144
|
-
}
|
|
138
|
+
if (url.startsWith('/') && endpointConfig?.baseUrl) {
|
|
139
|
+
const baseUrl = endpointConfig.baseUrl.replace(/\/$/, '');
|
|
140
|
+
url = `${baseUrl}${url}`;
|
|
145
141
|
}
|
|
146
142
|
// Prepare request options
|
|
147
143
|
const method = endpoint.method ?? 'GET';
|
|
@@ -161,19 +157,6 @@ export async function fetchVariableSchema(workflowId, nodeId, config, authProvid
|
|
|
161
157
|
logger.warn('Failed to get auth headers:', error);
|
|
162
158
|
}
|
|
163
159
|
}
|
|
164
|
-
// Add auth headers from endpoint config as fallback
|
|
165
|
-
const currentConfig = getEndpointConfig();
|
|
166
|
-
if (currentConfig?.auth) {
|
|
167
|
-
if (currentConfig.auth.type === 'bearer' && currentConfig.auth.token) {
|
|
168
|
-
headers['Authorization'] = headers['Authorization'] ?? `Bearer ${currentConfig.auth.token}`;
|
|
169
|
-
}
|
|
170
|
-
else if (currentConfig.auth.type === 'api_key' && currentConfig.auth.apiKey) {
|
|
171
|
-
headers['X-API-Key'] = headers['X-API-Key'] ?? currentConfig.auth.apiKey;
|
|
172
|
-
}
|
|
173
|
-
else if (currentConfig.auth.type === 'custom' && currentConfig.auth.headers) {
|
|
174
|
-
Object.assign(headers, currentConfig.auth.headers);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
160
|
// Prepare fetch options
|
|
178
161
|
const fetchOptions = {
|
|
179
162
|
method,
|
|
@@ -202,7 +185,7 @@ export async function fetchVariableSchema(workflowId, nodeId, config, authProvid
|
|
|
202
185
|
const refreshed = await authProvider.onUnauthorized();
|
|
203
186
|
if (refreshed) {
|
|
204
187
|
// Retry with refreshed auth
|
|
205
|
-
return fetchVariableSchema(workflowId, nodeId, config, authProvider);
|
|
188
|
+
return fetchVariableSchema(endpointConfig, workflowId, nodeId, config, authProvider);
|
|
206
189
|
}
|
|
207
190
|
}
|
|
208
191
|
return {
|
|
@@ -23,6 +23,12 @@ interface AutoSaveOptions {
|
|
|
23
23
|
* Optional callback for successful saves
|
|
24
24
|
*/
|
|
25
25
|
onSuccess?: () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Dirty-state probe for the owning FlowDrop instance, e.g.
|
|
28
|
+
* `() => fd.workflow.isDirty`. Defaults to the page-default
|
|
29
|
+
* instance's dirty state when omitted.
|
|
30
|
+
*/
|
|
31
|
+
isDirty?: () => boolean;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Initialize auto-save functionality based on user settings
|
|
@@ -68,6 +74,7 @@ export declare class AutoSaveManager {
|
|
|
68
74
|
private onSave;
|
|
69
75
|
private onError?;
|
|
70
76
|
private onSuccess?;
|
|
77
|
+
private isDirtyProbe;
|
|
71
78
|
/**
|
|
72
79
|
* Create a new AutoSaveManager
|
|
73
80
|
*
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module services/autoSaveService
|
|
8
8
|
*/
|
|
9
9
|
import { getBehaviorSettings, onSettingsChange } from '../stores/settingsStore.svelte.js';
|
|
10
|
-
import {
|
|
10
|
+
import { getDefaultInstance } from '../stores/instanceContainer.svelte.js';
|
|
11
11
|
import { logger } from '../utils/logger.js';
|
|
12
12
|
/**
|
|
13
13
|
* Initialize auto-save functionality based on user settings
|
|
@@ -40,7 +40,7 @@ import { logger } from '../utils/logger.js';
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
export function initAutoSave(options) {
|
|
43
|
-
const { onSave, onError, onSuccess } = options;
|
|
43
|
+
const { onSave, onError, onSuccess, isDirty: isDirtyProbe = () => getDefaultInstance().workflow.isDirty } = options;
|
|
44
44
|
const state = {
|
|
45
45
|
intervalId: null,
|
|
46
46
|
isSaving: false,
|
|
@@ -52,7 +52,7 @@ export function initAutoSave(options) {
|
|
|
52
52
|
*/
|
|
53
53
|
async function performAutoSave() {
|
|
54
54
|
// Skip if already saving or not dirty
|
|
55
|
-
if (state.isSaving || !
|
|
55
|
+
if (state.isSaving || !isDirtyProbe()) {
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
state.isSaving = true;
|
|
@@ -127,6 +127,7 @@ export class AutoSaveManager {
|
|
|
127
127
|
onSave;
|
|
128
128
|
onError;
|
|
129
129
|
onSuccess;
|
|
130
|
+
isDirtyProbe;
|
|
130
131
|
/**
|
|
131
132
|
* Create a new AutoSaveManager
|
|
132
133
|
*
|
|
@@ -136,6 +137,7 @@ export class AutoSaveManager {
|
|
|
136
137
|
this.onSave = options.onSave;
|
|
137
138
|
this.onError = options.onError;
|
|
138
139
|
this.onSuccess = options.onSuccess;
|
|
140
|
+
this.isDirtyProbe = options.isDirty ?? (() => getDefaultInstance().workflow.isDirty);
|
|
139
141
|
}
|
|
140
142
|
/**
|
|
141
143
|
* Start the auto-save manager
|
|
@@ -207,7 +209,7 @@ export class AutoSaveManager {
|
|
|
207
209
|
* Perform the save operation
|
|
208
210
|
*/
|
|
209
211
|
async performSave() {
|
|
210
|
-
if (this.isSaving || !
|
|
212
|
+
if (this.isSaving || !this.isDirtyProbe()) {
|
|
211
213
|
return;
|
|
212
214
|
}
|
|
213
215
|
this.isSaving = true;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @module services/chatService
|
|
8
8
|
*/
|
|
9
9
|
import type { ChatRequest, ChatResponse, ChatHistoryMessage } from '../types/chat.js';
|
|
10
|
+
import type { EndpointConfig } from '../config/endpoints.js';
|
|
10
11
|
/**
|
|
11
12
|
* Chat Service class
|
|
12
13
|
*
|
|
@@ -23,7 +24,9 @@ export declare class ChatService {
|
|
|
23
24
|
*/
|
|
24
25
|
static getInstance(): ChatService;
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
+
* Validate and return the caller-supplied endpoint configuration.
|
|
28
|
+
*
|
|
29
|
+
* Callers thread the config from `getInstance().api.config`.
|
|
27
30
|
*
|
|
28
31
|
* @throws Error if endpoint configuration is not set
|
|
29
32
|
* @returns The endpoint configuration
|
|
@@ -32,6 +35,7 @@ export declare class ChatService {
|
|
|
32
35
|
/**
|
|
33
36
|
* Generic API request helper
|
|
34
37
|
*
|
|
38
|
+
* @param config - The endpoint configuration
|
|
35
39
|
* @param url - The URL to fetch
|
|
36
40
|
* @param options - Fetch options
|
|
37
41
|
* @returns The parsed JSON response
|
|
@@ -44,20 +48,20 @@ export declare class ChatService {
|
|
|
44
48
|
* @param request - The chat request payload
|
|
45
49
|
* @returns The chat response from the LLM
|
|
46
50
|
*/
|
|
47
|
-
sendMessage(workflowId: string, request: ChatRequest): Promise<ChatResponse>;
|
|
51
|
+
sendMessage(endpointConfig: EndpointConfig | null, workflowId: string, request: ChatRequest): Promise<ChatResponse>;
|
|
48
52
|
/**
|
|
49
53
|
* Get conversation history for a workflow
|
|
50
54
|
*
|
|
51
55
|
* @param workflowId - The workflow ID
|
|
52
56
|
* @returns Array of chat history messages
|
|
53
57
|
*/
|
|
54
|
-
getHistory(workflowId: string): Promise<ChatHistoryMessage[]>;
|
|
58
|
+
getHistory(endpointConfig: EndpointConfig | null, workflowId: string): Promise<ChatHistoryMessage[]>;
|
|
55
59
|
/**
|
|
56
60
|
* Clear conversation history for a workflow
|
|
57
61
|
*
|
|
58
62
|
* @param workflowId - The workflow ID
|
|
59
63
|
*/
|
|
60
|
-
clearHistory(workflowId: string): Promise<void>;
|
|
64
|
+
clearHistory(endpointConfig: EndpointConfig | null, workflowId: string): Promise<void>;
|
|
61
65
|
}
|
|
62
66
|
/**
|
|
63
67
|
* Pre-instantiated ChatService singleton
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* @module services/chatService
|
|
8
8
|
*/
|
|
9
9
|
import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
|
|
10
|
-
import { getEndpointConfig } from './api.js';
|
|
11
10
|
import { logger } from '../utils/logger.js';
|
|
12
11
|
/**
|
|
13
12
|
* Chat Service class
|
|
@@ -30,27 +29,28 @@ export class ChatService {
|
|
|
30
29
|
return ChatService.instance;
|
|
31
30
|
}
|
|
32
31
|
/**
|
|
33
|
-
*
|
|
32
|
+
* Validate and return the caller-supplied endpoint configuration.
|
|
33
|
+
*
|
|
34
|
+
* Callers thread the config from `getInstance().api.config`.
|
|
34
35
|
*
|
|
35
36
|
* @throws Error if endpoint configuration is not set
|
|
36
37
|
* @returns The endpoint configuration
|
|
37
38
|
*/
|
|
38
|
-
getConfig() {
|
|
39
|
-
const config = getEndpointConfig();
|
|
39
|
+
getConfig(config) {
|
|
40
40
|
if (!config) {
|
|
41
|
-
throw new Error('Endpoint configuration not set.
|
|
41
|
+
throw new Error('Endpoint configuration not set. Configure the instance via fd.api.configure().');
|
|
42
42
|
}
|
|
43
43
|
return config;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Generic API request helper
|
|
47
47
|
*
|
|
48
|
+
* @param config - The endpoint configuration
|
|
48
49
|
* @param url - The URL to fetch
|
|
49
50
|
* @param options - Fetch options
|
|
50
51
|
* @returns The parsed JSON response
|
|
51
52
|
*/
|
|
52
|
-
async request(url, options = {}) {
|
|
53
|
-
const config = this.getConfig();
|
|
53
|
+
async request(config, url, options = {}) {
|
|
54
54
|
const headers = getEndpointHeaders(config, 'chat');
|
|
55
55
|
const response = await fetch(url, {
|
|
56
56
|
...options,
|
|
@@ -83,13 +83,13 @@ export class ChatService {
|
|
|
83
83
|
* @param request - The chat request payload
|
|
84
84
|
* @returns The chat response from the LLM
|
|
85
85
|
*/
|
|
86
|
-
async sendMessage(workflowId, request) {
|
|
87
|
-
const config = this.getConfig();
|
|
86
|
+
async sendMessage(endpointConfig, workflowId, request) {
|
|
87
|
+
const config = this.getConfig(endpointConfig);
|
|
88
88
|
const url = buildEndpointUrl(config, config.endpoints.chat.sendMessage, {
|
|
89
89
|
id: workflowId
|
|
90
90
|
});
|
|
91
91
|
logger.debug('[ChatService] Sending message to', url);
|
|
92
|
-
return this.request(url, {
|
|
92
|
+
return this.request(config, url, {
|
|
93
93
|
method: 'POST',
|
|
94
94
|
body: JSON.stringify(request)
|
|
95
95
|
});
|
|
@@ -100,21 +100,21 @@ export class ChatService {
|
|
|
100
100
|
* @param workflowId - The workflow ID
|
|
101
101
|
* @returns Array of chat history messages
|
|
102
102
|
*/
|
|
103
|
-
async getHistory(workflowId) {
|
|
104
|
-
const config = this.getConfig();
|
|
103
|
+
async getHistory(endpointConfig, workflowId) {
|
|
104
|
+
const config = this.getConfig(endpointConfig);
|
|
105
105
|
const url = buildEndpointUrl(config, config.endpoints.chat.getHistory, {
|
|
106
106
|
id: workflowId
|
|
107
107
|
});
|
|
108
108
|
logger.debug('[ChatService] Getting history from', url);
|
|
109
|
-
return this.request(url);
|
|
109
|
+
return this.request(config, url);
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Clear conversation history for a workflow
|
|
113
113
|
*
|
|
114
114
|
* @param workflowId - The workflow ID
|
|
115
115
|
*/
|
|
116
|
-
async clearHistory(workflowId) {
|
|
117
|
-
const config = this.getConfig();
|
|
116
|
+
async clearHistory(endpointConfig, workflowId) {
|
|
117
|
+
const config = this.getConfig(endpointConfig);
|
|
118
118
|
const url = buildEndpointUrl(config, config.endpoints.chat.clearHistory, {
|
|
119
119
|
id: workflowId
|
|
120
120
|
});
|