@flowdrop/flowdrop 1.15.0 → 2.0.0-beta.2
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 +508 -0
- package/MIGRATION-2.0.md +629 -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/api/enhanced-client.js +6 -11
- 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 +163 -192
- package/dist/components/App.svelte.d.ts +47 -8
- package/dist/components/ConfigForm.svelte +77 -49
- 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 +22 -68
- package/dist/components/PipelineStatus.svelte.d.ts +3 -0
- package/dist/components/PortCoordinateTracker.svelte +5 -6
- package/dist/components/SchemaForm.stories.svelte +1 -3
- package/dist/components/SchemaForm.svelte +22 -27
- 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 +121 -111
- package/dist/components/WorkflowEditor.svelte.d.ts +21 -10
- package/dist/components/chat/AIChatPanel.svelte +98 -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 +16 -15
- package/dist/components/form/FormField.svelte +4 -2
- package/dist/components/form/FormFieldLight.svelte +34 -3
- package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
- 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/FormUISchemaRenderer.svelte +3 -1
- 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 +25 -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 +17 -5
- 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 +69 -8
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
- package/dist/components/playground/PipelinePanel.svelte +31 -8
- package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
- package/dist/components/playground/PipelineTableView.svelte +188 -44
- package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
- package/dist/components/playground/Playground.svelte +154 -105
- package/dist/components/playground/Playground.svelte.d.ts +5 -0
- package/dist/components/playground/PlaygroundApp.svelte +11 -1
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +6 -0
- package/dist/components/playground/PlaygroundModal.svelte +18 -3
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +6 -0
- package/dist/components/playground/PlaygroundStudio.svelte +40 -32
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +6 -0
- package/dist/components/playground/SessionManager.svelte +9 -12
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +30 -1
- package/dist/components/playground/pipelineViewUtils.svelte.js +40 -3
- package/dist/config/endpoints.d.ts +23 -7
- package/dist/config/endpoints.js +30 -10
- package/dist/core/index.d.ts +5 -6
- package/dist/core/index.js +8 -12
- package/dist/display/index.d.ts +6 -3
- package/dist/display/index.js +7 -5
- package/dist/editor/index.d.ts +20 -21
- package/dist/editor/index.js +26 -36
- 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 +19 -14
- package/dist/form/full.js +26 -28
- package/dist/form/index.d.ts +3 -4
- package/dist/form/index.js +6 -5
- package/dist/form/markdown.d.ts +13 -8
- package/dist/form/markdown.js +22 -23
- package/dist/helpers/proximityConnect.d.ts +3 -2
- package/dist/helpers/proximityConnect.js +2 -5
- package/dist/helpers/workflowEditorHelper.d.ts +14 -5
- package/dist/helpers/workflowEditorHelper.js +28 -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 +3 -3
- package/dist/playground/index.d.ts +4 -5
- package/dist/playground/index.js +4 -32
- package/dist/playground/mount.d.ts +25 -0
- package/dist/playground/mount.js +50 -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/builtinNodeTypes.d.ts +53 -0
- package/dist/registry/builtinNodeTypes.js +67 -0
- package/dist/registry/builtinNodes.d.ts +2 -64
- package/dist/registry/builtinNodes.js +7 -103
- 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 +3 -3
- package/dist/services/agentSpecExecutionService.d.ts +0 -2
- package/dist/services/agentSpecExecutionService.js +0 -3
- package/dist/services/apiVariableService.d.ts +2 -1
- package/dist/services/apiVariableService.js +16 -47
- package/dist/services/autoSaveService.d.ts +7 -0
- package/dist/services/autoSaveService.js +6 -4
- package/dist/services/categoriesApi.js +3 -6
- package/dist/services/chatService.d.ts +9 -4
- package/dist/services/chatService.js +23 -28
- 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 +15 -9
- package/dist/services/interruptService.js +35 -37
- package/dist/services/nodeExecutionService.d.ts +18 -3
- package/dist/services/nodeExecutionService.js +71 -45
- package/dist/services/playgroundService.d.ts +16 -10
- package/dist/services/playgroundService.js +42 -43
- package/dist/services/portConfigApi.js +3 -6
- package/dist/services/settingsService.d.ts +9 -4
- package/dist/services/settingsService.js +23 -12
- 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 +56 -0
- package/dist/stores/apiContext.js +80 -0
- package/dist/stores/categoriesStore.svelte.d.ts +28 -23
- package/dist/stores/categoriesStore.svelte.js +69 -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 -222
- package/dist/stores/playgroundStore.svelte.js +513 -580
- 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 +159 -54
- package/dist/types/auth.d.ts +9 -51
- package/dist/types/auth.js +4 -54
- package/dist/types/events.d.ts +6 -3
- package/dist/types/index.d.ts +37 -5
- package/dist/types/index.js +0 -1
- 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/edgeStyling.js +9 -5
- package/dist/utils/fetchWithAuth.d.ts +36 -15
- package/dist/utils/fetchWithAuth.js +53 -23
- 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 -20
- package/dist/utils/performanceUtils.js +7 -0
- package/package.json +7 -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
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import ControlPanel from './ControlPanel.svelte';
|
|
18
18
|
import type { Workflow } from '../../types/index.js';
|
|
19
19
|
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
20
|
+
import type { AuthProvider } from '../../types/auth.js';
|
|
20
21
|
import type {
|
|
21
22
|
PlaygroundMode,
|
|
22
23
|
PlaygroundConfig,
|
|
@@ -24,21 +25,9 @@
|
|
|
24
25
|
} from '../../types/playground.js';
|
|
25
26
|
import { playgroundService } from '../../services/playgroundService.js';
|
|
26
27
|
import { interruptService } from '../../services/interruptService.js';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
getCurrentSession,
|
|
30
|
-
getSessions,
|
|
31
|
-
getIsExecuting,
|
|
32
|
-
getIsLoading,
|
|
33
|
-
getError,
|
|
34
|
-
playgroundActions,
|
|
35
|
-
applyServerResponse,
|
|
36
|
-
getLatestSequenceNumber,
|
|
37
|
-
getOldestSequenceNumber,
|
|
38
|
-
setHasOlder
|
|
39
|
-
} from '../../stores/playgroundStore.svelte.js';
|
|
28
|
+
import { provideInstance } from '../../stores/getInstance.svelte.js';
|
|
29
|
+
import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
|
|
40
30
|
import type { PlaygroundMessagesApiResponse } from '../../types/playground.js';
|
|
41
|
-
import { interruptActions } from '../../stores/interruptStore.svelte.js';
|
|
42
31
|
import { logger } from '../../utils/logger.js';
|
|
43
32
|
|
|
44
33
|
interface Props {
|
|
@@ -47,11 +36,14 @@
|
|
|
47
36
|
mode?: PlaygroundMode;
|
|
48
37
|
initialSessionId?: string;
|
|
49
38
|
endpointConfig?: EndpointConfig;
|
|
39
|
+
/** Auth provider applied to this instance's API requests. */
|
|
40
|
+
authProvider?: AuthProvider;
|
|
50
41
|
config?: PlaygroundConfig;
|
|
51
42
|
onClose?: () => void;
|
|
52
43
|
onTogglePanel?: () => void;
|
|
53
44
|
isPipelinePanelOpen?: boolean;
|
|
54
45
|
onSessionNavigate?: (sessionId: string) => void;
|
|
46
|
+
instance?: FlowDropInstance;
|
|
55
47
|
}
|
|
56
48
|
|
|
57
49
|
let {
|
|
@@ -60,13 +52,19 @@
|
|
|
60
52
|
mode = 'standalone',
|
|
61
53
|
initialSessionId,
|
|
62
54
|
endpointConfig,
|
|
55
|
+
authProvider,
|
|
63
56
|
config = {},
|
|
64
57
|
onClose,
|
|
65
58
|
onTogglePanel,
|
|
66
59
|
isPipelinePanelOpen = false,
|
|
67
|
-
onSessionNavigate
|
|
60
|
+
onSessionNavigate,
|
|
61
|
+
instance
|
|
68
62
|
}: Props = $props();
|
|
69
63
|
|
|
64
|
+
// Resolve/provide once at init; the instance prop is a fixed mount-time choice.
|
|
65
|
+
// svelte-ignore state_referenced_locally
|
|
66
|
+
const fd = provideInstance(instance);
|
|
67
|
+
|
|
70
68
|
let loadedInitialSessionId = $state<string | undefined>(undefined);
|
|
71
69
|
let autoRunTriggered = $state(false);
|
|
72
70
|
let isRefreshing = $state(false);
|
|
@@ -78,7 +76,7 @@
|
|
|
78
76
|
|
|
79
77
|
// Vertical resizer state for the ExecutionConsole ↔ ControlPanel split.
|
|
80
78
|
let playgroundContentEl = $state<HTMLElement | null>(null);
|
|
81
|
-
let controlPanelHeight = $state(
|
|
79
|
+
let controlPanelHeight = $state(140);
|
|
82
80
|
let isVerticalResizing = $state(false);
|
|
83
81
|
let containerHeight = $state(0);
|
|
84
82
|
let dragContainerBottom = 0;
|
|
@@ -132,18 +130,23 @@
|
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
onMount(() => {
|
|
135
|
-
if (endpointConfig)
|
|
136
|
-
if (workflow)
|
|
133
|
+
if (endpointConfig) fd.api.configure(endpointConfig, authProvider);
|
|
134
|
+
if (workflow) fd.playground.setWorkflow(workflow);
|
|
137
135
|
|
|
138
136
|
const handleVisibility = () => {
|
|
139
137
|
if (document.visibilityState === 'visible' && playgroundService.isPolling()) {
|
|
140
|
-
const sessionId =
|
|
138
|
+
const sessionId = fd.playground.currentSession?.id;
|
|
141
139
|
if (sessionId) {
|
|
142
140
|
void playgroundService
|
|
143
|
-
.getMessages(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
.getMessages(
|
|
142
|
+
fd.api.config,
|
|
143
|
+
sessionId,
|
|
144
|
+
{
|
|
145
|
+
since: playgroundService.getLastSequenceNumber() ?? undefined
|
|
146
|
+
},
|
|
147
|
+
fd.api.authProvider
|
|
148
|
+
)
|
|
149
|
+
.then((response) => fd.playground.applyServerResponse(response, sessionId))
|
|
147
150
|
.catch((err) => logger.error('[Playground] Visibility catchup failed:', err));
|
|
148
151
|
}
|
|
149
152
|
}
|
|
@@ -168,7 +171,7 @@
|
|
|
168
171
|
if (!initialSessionId) return;
|
|
169
172
|
if (loadedInitialSessionId === initialSessionId) return;
|
|
170
173
|
|
|
171
|
-
const sessionList =
|
|
174
|
+
const sessionList = fd.playground.sessions;
|
|
172
175
|
if (sessionList.length === 0) return;
|
|
173
176
|
|
|
174
177
|
void loadInitialSession(initialSessionId);
|
|
@@ -194,7 +197,7 @@
|
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
async function loadInitialSession(sessionId: string): Promise<void> {
|
|
197
|
-
const sessionList =
|
|
200
|
+
const sessionList = fd.playground.sessions;
|
|
198
201
|
const sessionExists = sessionList.some((s) => s.id === sessionId);
|
|
199
202
|
|
|
200
203
|
if (!sessionExists) {
|
|
@@ -217,48 +220,62 @@
|
|
|
217
220
|
onDestroy(() => {
|
|
218
221
|
playgroundService.stopPolling();
|
|
219
222
|
interruptService.stopPolling();
|
|
220
|
-
|
|
221
|
-
|
|
223
|
+
fd.playground.reset();
|
|
224
|
+
fd.interrupts.reset();
|
|
222
225
|
});
|
|
223
226
|
|
|
224
227
|
async function loadSessions(): Promise<void> {
|
|
225
|
-
|
|
226
|
-
|
|
228
|
+
fd.playground.setLoading(true);
|
|
229
|
+
fd.playground.setError(null);
|
|
227
230
|
|
|
228
231
|
try {
|
|
229
|
-
const sessionList = await playgroundService.listSessions(
|
|
230
|
-
|
|
232
|
+
const sessionList = await playgroundService.listSessions(
|
|
233
|
+
fd.api.config,
|
|
234
|
+
workflowId,
|
|
235
|
+
undefined,
|
|
236
|
+
fd.api.authProvider
|
|
237
|
+
);
|
|
238
|
+
fd.playground.setSessions(sessionList);
|
|
231
239
|
} catch (err) {
|
|
232
240
|
const errorMessage = err instanceof Error ? err.message : 'Failed to load sessions';
|
|
233
|
-
|
|
241
|
+
fd.playground.setError(errorMessage);
|
|
234
242
|
logger.error('Failed to load sessions:', err);
|
|
235
243
|
} finally {
|
|
236
|
-
|
|
244
|
+
fd.playground.setLoading(false);
|
|
237
245
|
}
|
|
238
246
|
}
|
|
239
247
|
|
|
240
248
|
async function loadSession(sessionId: string): Promise<void> {
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
fd.playground.setLoading(true);
|
|
250
|
+
fd.playground.setError(null);
|
|
243
251
|
const token = ++loadToken;
|
|
244
252
|
|
|
245
253
|
try {
|
|
246
|
-
const session = await playgroundService.getSession(
|
|
254
|
+
const session = await playgroundService.getSession(
|
|
255
|
+
fd.api.config,
|
|
256
|
+
sessionId,
|
|
257
|
+
fd.api.authProvider
|
|
258
|
+
);
|
|
247
259
|
if (token !== loadToken) return; // a newer session load superseded us
|
|
248
|
-
|
|
260
|
+
fd.playground.setCurrentSession(session);
|
|
249
261
|
|
|
250
262
|
// Load only the most recent page; older messages load on demand when the
|
|
251
263
|
// user scrolls up (loadOlderMessages). Clear right before applying the
|
|
252
264
|
// fresh page — not before the await — so switching sessions doesn't blank
|
|
253
265
|
// the view for the duration of the fetch.
|
|
254
|
-
const response = await playgroundService.getMessages(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
const response = await playgroundService.getMessages(
|
|
267
|
+
fd.api.config,
|
|
268
|
+
sessionId,
|
|
269
|
+
{
|
|
270
|
+
latest: true,
|
|
271
|
+
limit: messagePageSize
|
|
272
|
+
},
|
|
273
|
+
fd.api.authProvider
|
|
274
|
+
);
|
|
258
275
|
if (token !== loadToken) return;
|
|
259
|
-
|
|
260
|
-
applyServerResponse(response, sessionId);
|
|
261
|
-
setHasOlder(deriveHasOlder(response));
|
|
276
|
+
fd.playground.clearMessages();
|
|
277
|
+
fd.playground.applyServerResponse(response, sessionId);
|
|
278
|
+
fd.playground.setHasOlder(deriveHasOlder(response));
|
|
262
279
|
|
|
263
280
|
if (session.status !== 'idle') {
|
|
264
281
|
// Seed polling from the newest loaded message so it tails live updates
|
|
@@ -268,10 +285,10 @@
|
|
|
268
285
|
} catch (err) {
|
|
269
286
|
if (token !== loadToken) return; // don't surface a superseded load's error
|
|
270
287
|
const errorMessage = err instanceof Error ? err.message : 'Failed to load session';
|
|
271
|
-
|
|
288
|
+
fd.playground.setError(errorMessage);
|
|
272
289
|
logger.error('Failed to load session:', err);
|
|
273
290
|
} finally {
|
|
274
|
-
if (token === loadToken)
|
|
291
|
+
if (token === loadToken) fd.playground.setLoading(false);
|
|
275
292
|
}
|
|
276
293
|
}
|
|
277
294
|
|
|
@@ -282,22 +299,27 @@
|
|
|
282
299
|
* historical fetch never disturbs the live polling cursor or pipeline view.
|
|
283
300
|
*/
|
|
284
301
|
async function loadOlderMessages(): Promise<void> {
|
|
285
|
-
const sessionId =
|
|
286
|
-
const before =
|
|
302
|
+
const sessionId = fd.playground.currentSession?.id;
|
|
303
|
+
const before = fd.playground.oldestSequenceNumber;
|
|
287
304
|
if (!sessionId || before === null) return;
|
|
288
305
|
|
|
289
306
|
try {
|
|
290
|
-
const response = await playgroundService.getMessages(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
307
|
+
const response = await playgroundService.getMessages(
|
|
308
|
+
fd.api.config,
|
|
309
|
+
sessionId,
|
|
310
|
+
{
|
|
311
|
+
before,
|
|
312
|
+
limit: messagePageSize
|
|
313
|
+
},
|
|
314
|
+
fd.api.authProvider
|
|
315
|
+
);
|
|
294
316
|
// The session may have changed while the fetch was in flight — don't
|
|
295
317
|
// splice an old session's page into the new session's store.
|
|
296
|
-
if (
|
|
318
|
+
if (fd.playground.currentSession?.id !== sessionId) return;
|
|
297
319
|
if (response.data && response.data.length > 0) {
|
|
298
|
-
|
|
320
|
+
fd.playground.addMessages(response.data);
|
|
299
321
|
}
|
|
300
|
-
setHasOlder(deriveHasOlder(response));
|
|
322
|
+
fd.playground.setHasOlder(deriveHasOlder(response));
|
|
301
323
|
} catch (err) {
|
|
302
324
|
logger.error('[Playground] Failed to load older messages:', err);
|
|
303
325
|
}
|
|
@@ -314,12 +336,18 @@
|
|
|
314
336
|
}
|
|
315
337
|
|
|
316
338
|
async function handleCreateSession(): Promise<void> {
|
|
317
|
-
|
|
318
|
-
|
|
339
|
+
fd.playground.setLoading(true);
|
|
340
|
+
fd.playground.setError(null);
|
|
319
341
|
|
|
320
342
|
try {
|
|
321
|
-
const sessionName = `Session ${
|
|
322
|
-
const session = await playgroundService.createSession(
|
|
343
|
+
const sessionName = `Session ${fd.playground.sessions.length + 1}`;
|
|
344
|
+
const session = await playgroundService.createSession(
|
|
345
|
+
fd.api.config,
|
|
346
|
+
workflowId,
|
|
347
|
+
sessionName,
|
|
348
|
+
undefined,
|
|
349
|
+
fd.api.authProvider
|
|
350
|
+
);
|
|
323
351
|
|
|
324
352
|
// Stop polling the previous (possibly running) session before switching,
|
|
325
353
|
// mirroring handleSelectSession. Otherwise its next poll keeps the old
|
|
@@ -331,60 +359,66 @@
|
|
|
331
359
|
return;
|
|
332
360
|
}
|
|
333
361
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
362
|
+
fd.playground.addSession(session);
|
|
363
|
+
fd.playground.setCurrentSession(session);
|
|
364
|
+
fd.playground.clearMessages();
|
|
337
365
|
} catch (err) {
|
|
338
366
|
const errorMessage = err instanceof Error ? err.message : 'Failed to create session';
|
|
339
|
-
|
|
367
|
+
fd.playground.setError(errorMessage);
|
|
340
368
|
logger.error('Failed to create session:', err);
|
|
341
369
|
} finally {
|
|
342
|
-
|
|
370
|
+
fd.playground.setLoading(false);
|
|
343
371
|
}
|
|
344
372
|
}
|
|
345
373
|
|
|
346
374
|
async function handleSelectSession(sessionId: string): Promise<void> {
|
|
347
|
-
|
|
348
|
-
const currentSessionId =
|
|
375
|
+
fd.playground.pinExecution(null);
|
|
376
|
+
const currentSessionId = fd.playground.currentSession?.id;
|
|
349
377
|
if (currentSessionId === sessionId) return;
|
|
350
378
|
|
|
351
379
|
playgroundService.stopPolling();
|
|
352
|
-
|
|
380
|
+
fd.playground.updateSessionStatus('idle');
|
|
353
381
|
await loadSession(sessionId);
|
|
354
382
|
}
|
|
355
383
|
|
|
356
384
|
async function handleDeleteSession(sessionId: string): Promise<void> {
|
|
357
385
|
try {
|
|
358
|
-
await playgroundService.deleteSession(sessionId);
|
|
359
|
-
|
|
386
|
+
await playgroundService.deleteSession(fd.api.config, sessionId, fd.api.authProvider);
|
|
387
|
+
fd.playground.removeSession(sessionId);
|
|
360
388
|
|
|
361
|
-
if (
|
|
389
|
+
if (fd.playground.currentSession?.id === sessionId) {
|
|
362
390
|
playgroundService.stopPolling();
|
|
363
391
|
}
|
|
364
392
|
} catch (err) {
|
|
365
393
|
const errorMessage = err instanceof Error ? err.message : 'Failed to delete session';
|
|
366
|
-
|
|
394
|
+
fd.playground.setError(errorMessage);
|
|
367
395
|
logger.error('Failed to delete session:', err);
|
|
368
396
|
}
|
|
369
397
|
}
|
|
370
398
|
|
|
371
399
|
async function handleSendMessage(content: string): Promise<void> {
|
|
372
|
-
if (
|
|
400
|
+
if (fd.playground.isExecuting) return;
|
|
373
401
|
|
|
374
|
-
if (!
|
|
402
|
+
if (!fd.playground.currentSession) {
|
|
375
403
|
await handleCreateSession();
|
|
376
|
-
if (!
|
|
404
|
+
if (!fd.playground.currentSession) return;
|
|
377
405
|
}
|
|
378
406
|
|
|
379
|
-
const sessionId =
|
|
407
|
+
const sessionId = fd.playground.currentSession!.id;
|
|
380
408
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
409
|
+
fd.playground.updateSessionStatus('running');
|
|
410
|
+
fd.playground.pinExecution(null);
|
|
411
|
+
fd.playground.setError(null);
|
|
384
412
|
|
|
385
413
|
try {
|
|
386
|
-
const message = await playgroundService.sendMessage(
|
|
387
|
-
|
|
414
|
+
const message = await playgroundService.sendMessage(
|
|
415
|
+
fd.api.config,
|
|
416
|
+
sessionId,
|
|
417
|
+
content,
|
|
418
|
+
{},
|
|
419
|
+
fd.api.authProvider
|
|
420
|
+
);
|
|
421
|
+
fd.playground.addMessage(message);
|
|
388
422
|
// Only start polling if not already active — avoids resetting the cursor
|
|
389
423
|
// mid-session and re-fetching messages that are already in the store.
|
|
390
424
|
// Seed from the newest loaded message so polling tails live updates
|
|
@@ -394,25 +428,25 @@
|
|
|
394
428
|
}
|
|
395
429
|
} catch (err) {
|
|
396
430
|
const errorMessage = err instanceof Error ? err.message : 'Failed to send message';
|
|
397
|
-
|
|
398
|
-
|
|
431
|
+
fd.playground.setError(errorMessage);
|
|
432
|
+
fd.playground.updateSessionStatus('idle');
|
|
399
433
|
logger.error('Failed to send message:', err);
|
|
400
434
|
}
|
|
401
435
|
}
|
|
402
436
|
|
|
403
437
|
async function handleStopExecution(): Promise<void> {
|
|
404
|
-
const sessionId =
|
|
438
|
+
const sessionId = fd.playground.currentSession?.id;
|
|
405
439
|
if (!sessionId) return;
|
|
406
440
|
|
|
407
441
|
try {
|
|
408
|
-
await playgroundService.stopExecution(sessionId);
|
|
442
|
+
await playgroundService.stopExecution(fd.api.config, sessionId, fd.api.authProvider);
|
|
409
443
|
playgroundService.stopPolling();
|
|
410
|
-
|
|
444
|
+
fd.playground.updateSessionStatus('idle');
|
|
411
445
|
} catch (err) {
|
|
412
446
|
const errorMessage = err instanceof Error ? err.message : 'Failed to stop execution';
|
|
413
|
-
|
|
447
|
+
fd.playground.setError(errorMessage);
|
|
414
448
|
playgroundService.stopPolling();
|
|
415
|
-
|
|
449
|
+
fd.playground.updateSessionStatus('idle');
|
|
416
450
|
logger.error('Failed to stop execution:', err);
|
|
417
451
|
}
|
|
418
452
|
}
|
|
@@ -423,26 +457,33 @@
|
|
|
423
457
|
overrideShouldStopPolling?: (status: PlaygroundSessionStatus) => boolean
|
|
424
458
|
): void {
|
|
425
459
|
const pollingInterval = config.pollingInterval ?? 1500;
|
|
426
|
-
const initialSequenceNumber = seedSequence ?
|
|
460
|
+
const initialSequenceNumber = seedSequence ? fd.playground.latestSequenceNumber : null;
|
|
427
461
|
|
|
428
462
|
playgroundService.startPolling(
|
|
463
|
+
fd.api.config,
|
|
429
464
|
sessionId,
|
|
430
|
-
(response) => applyServerResponse(response, sessionId),
|
|
465
|
+
(response) => fd.playground.applyServerResponse(response, sessionId),
|
|
431
466
|
pollingInterval,
|
|
432
467
|
overrideShouldStopPolling ?? config.shouldStopPolling,
|
|
433
|
-
initialSequenceNumber
|
|
468
|
+
initialSequenceNumber,
|
|
469
|
+
fd.api.authProvider
|
|
434
470
|
);
|
|
435
471
|
}
|
|
436
472
|
|
|
437
473
|
async function refreshFromServer(): Promise<void> {
|
|
438
|
-
const sessionId =
|
|
474
|
+
const sessionId = fd.playground.currentSession?.id;
|
|
439
475
|
if (!sessionId || isRefreshing) return;
|
|
440
476
|
isRefreshing = true;
|
|
441
477
|
try {
|
|
442
|
-
const response = await playgroundService.getMessages(
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
478
|
+
const response = await playgroundService.getMessages(
|
|
479
|
+
fd.api.config,
|
|
480
|
+
sessionId,
|
|
481
|
+
{
|
|
482
|
+
since: playgroundService.getLastSequenceNumber() ?? undefined
|
|
483
|
+
},
|
|
484
|
+
fd.api.authProvider
|
|
485
|
+
);
|
|
486
|
+
fd.playground.applyServerResponse(response, sessionId);
|
|
446
487
|
if (response.sessionStatus === 'running' && !playgroundService.isPolling()) {
|
|
447
488
|
startPolling(sessionId, true);
|
|
448
489
|
}
|
|
@@ -454,16 +495,21 @@
|
|
|
454
495
|
}
|
|
455
496
|
|
|
456
497
|
async function handleInterruptResolved(): Promise<void> {
|
|
457
|
-
const sessionId =
|
|
498
|
+
const sessionId = fd.playground.currentSession?.id;
|
|
458
499
|
if (!sessionId) return;
|
|
459
500
|
|
|
460
501
|
try {
|
|
461
502
|
// Catch up immediately rather than waiting for the next poll interval.
|
|
462
503
|
// Use the service's sequence cursor so we only fetch new messages.
|
|
463
|
-
const response = await playgroundService.getMessages(
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
504
|
+
const response = await playgroundService.getMessages(
|
|
505
|
+
fd.api.config,
|
|
506
|
+
sessionId,
|
|
507
|
+
{
|
|
508
|
+
since: playgroundService.getLastSequenceNumber() ?? undefined
|
|
509
|
+
},
|
|
510
|
+
fd.api.authProvider
|
|
511
|
+
);
|
|
512
|
+
fd.playground.applyServerResponse(response, sessionId);
|
|
467
513
|
} catch (err) {
|
|
468
514
|
logger.error('[Playground] Failed to refresh after interrupt:', err);
|
|
469
515
|
}
|
|
@@ -483,14 +529,14 @@
|
|
|
483
529
|
class:playground--modal={mode === 'modal'}
|
|
484
530
|
>
|
|
485
531
|
<main class="playground__main">
|
|
486
|
-
{#if
|
|
532
|
+
{#if fd.playground.error}
|
|
487
533
|
<div class="playground__error">
|
|
488
534
|
<Icon icon="mdi:alert-circle" />
|
|
489
|
-
<span>{
|
|
535
|
+
<span>{fd.playground.error}</span>
|
|
490
536
|
<button
|
|
491
537
|
type="button"
|
|
492
538
|
class="playground__error-dismiss"
|
|
493
|
-
onclick={() =>
|
|
539
|
+
onclick={() => fd.playground.setError(null)}
|
|
494
540
|
>
|
|
495
541
|
<Icon icon="mdi:close" />
|
|
496
542
|
</button>
|
|
@@ -498,7 +544,7 @@
|
|
|
498
544
|
{/if}
|
|
499
545
|
|
|
500
546
|
<div class="playground__content" bind:this={playgroundContentEl}>
|
|
501
|
-
{#if
|
|
547
|
+
{#if fd.playground.isLoading && !fd.playground.currentSession}
|
|
502
548
|
<div class="playground__loading">
|
|
503
549
|
<Icon icon="mdi:loading" class="playground__loading-icon" />
|
|
504
550
|
<span>Loading...</span>
|
|
@@ -509,7 +555,7 @@
|
|
|
509
555
|
autoScroll={config.autoScroll ?? true}
|
|
510
556
|
enableMarkdown={config.enableMarkdown ?? true}
|
|
511
557
|
onInterruptResolved={handleInterruptResolved}
|
|
512
|
-
onCreateSession={
|
|
558
|
+
onCreateSession={fd.playground.sessions.length === 0 ? handleCreateSession : undefined}
|
|
513
559
|
onLoadOlder={loadOlderMessages}
|
|
514
560
|
/>
|
|
515
561
|
|
|
@@ -550,6 +596,9 @@
|
|
|
550
596
|
showChatInput={config.showChatInput ?? true}
|
|
551
597
|
showRunButton={config.showRunButton ?? true}
|
|
552
598
|
predefinedMessage={config.predefinedMessage}
|
|
599
|
+
showSessionHeader={config.showSessionHeader ?? true}
|
|
600
|
+
showNewSessionButton={config.showNewSessionButton ?? true}
|
|
601
|
+
showSessionList={config.showSessionList ?? true}
|
|
553
602
|
/>
|
|
554
603
|
{/if}
|
|
555
604
|
</div>
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import type { Workflow } from '../../types/index.js';
|
|
2
2
|
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
3
|
+
import type { AuthProvider } from '../../types/auth.js';
|
|
3
4
|
import type { PlaygroundMode, PlaygroundConfig } from '../../types/playground.js';
|
|
5
|
+
import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
|
|
4
6
|
interface Props {
|
|
5
7
|
workflowId: string;
|
|
6
8
|
workflow?: Workflow;
|
|
7
9
|
mode?: PlaygroundMode;
|
|
8
10
|
initialSessionId?: string;
|
|
9
11
|
endpointConfig?: EndpointConfig;
|
|
12
|
+
/** Auth provider applied to this instance's API requests. */
|
|
13
|
+
authProvider?: AuthProvider;
|
|
10
14
|
config?: PlaygroundConfig;
|
|
11
15
|
onClose?: () => void;
|
|
12
16
|
onTogglePanel?: () => void;
|
|
13
17
|
isPipelinePanelOpen?: boolean;
|
|
14
18
|
onSessionNavigate?: (sessionId: string) => void;
|
|
19
|
+
instance?: FlowDropInstance;
|
|
15
20
|
}
|
|
16
21
|
declare const Playground: import("svelte").Component<Props, {}, "">;
|
|
17
22
|
type Playground = ReturnType<typeof Playground>;
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
import Navbar from '../Navbar.svelte';
|
|
14
14
|
import PlaygroundStudio from './PlaygroundStudio.svelte';
|
|
15
15
|
import type { Workflow } from '../../types/index.js';
|
|
16
|
+
import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
|
|
16
17
|
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
18
|
+
import type { AuthProvider } from '../../types/auth.js';
|
|
17
19
|
import type { PlaygroundConfig } from '../../types/playground.js';
|
|
18
20
|
import type { SettingsCategory } from '../../types/settings.js';
|
|
19
21
|
import type { NavbarAction } from '../../types/navbar.js';
|
|
@@ -23,6 +25,8 @@
|
|
|
23
25
|
workflow?: Workflow;
|
|
24
26
|
mode?: 'standalone' | 'embedded';
|
|
25
27
|
endpointConfig?: EndpointConfig;
|
|
28
|
+
/** Auth provider applied to this instance's API requests. */
|
|
29
|
+
authProvider?: AuthProvider;
|
|
26
30
|
config?: PlaygroundConfig;
|
|
27
31
|
showNavbar?: boolean;
|
|
28
32
|
navbarTitle?: string;
|
|
@@ -37,6 +41,8 @@
|
|
|
37
41
|
initialPipelineWidth?: number;
|
|
38
42
|
onClose?: () => void;
|
|
39
43
|
onSessionNavigate?: (sessionId: string) => void;
|
|
44
|
+
/** Per-instance state container — forwarded to the inner PlaygroundStudio */
|
|
45
|
+
instance?: FlowDropInstance;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
let {
|
|
@@ -44,6 +50,7 @@
|
|
|
44
50
|
workflow,
|
|
45
51
|
mode = 'standalone',
|
|
46
52
|
endpointConfig,
|
|
53
|
+
authProvider,
|
|
47
54
|
config = {},
|
|
48
55
|
showNavbar = true,
|
|
49
56
|
navbarTitle,
|
|
@@ -57,7 +64,8 @@
|
|
|
57
64
|
minChatWidth,
|
|
58
65
|
initialPipelineWidth,
|
|
59
66
|
onClose,
|
|
60
|
-
onSessionNavigate
|
|
67
|
+
onSessionNavigate,
|
|
68
|
+
instance
|
|
61
69
|
}: Props = $props();
|
|
62
70
|
|
|
63
71
|
const displayTitle = $derived(navbarTitle ?? workflow?.name ?? 'Playground');
|
|
@@ -77,10 +85,12 @@
|
|
|
77
85
|
{/if}
|
|
78
86
|
<div class="fd-playground-app__content">
|
|
79
87
|
<PlaygroundStudio
|
|
88
|
+
{instance}
|
|
80
89
|
{workflowId}
|
|
81
90
|
{workflow}
|
|
82
91
|
{mode}
|
|
83
92
|
{endpointConfig}
|
|
93
|
+
{authProvider}
|
|
84
94
|
{config}
|
|
85
95
|
{initialSessionId}
|
|
86
96
|
{initialPipelineOpen}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { Workflow } from '../../types/index.js';
|
|
2
|
+
import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
|
|
2
3
|
import type { EndpointConfig } from '../../config/endpoints.js';
|
|
4
|
+
import type { AuthProvider } from '../../types/auth.js';
|
|
3
5
|
import type { PlaygroundConfig } from '../../types/playground.js';
|
|
4
6
|
import type { SettingsCategory } from '../../types/settings.js';
|
|
5
7
|
import type { NavbarAction } from '../../types/navbar.js';
|
|
@@ -8,6 +10,8 @@ interface Props {
|
|
|
8
10
|
workflow?: Workflow;
|
|
9
11
|
mode?: 'standalone' | 'embedded';
|
|
10
12
|
endpointConfig?: EndpointConfig;
|
|
13
|
+
/** Auth provider applied to this instance's API requests. */
|
|
14
|
+
authProvider?: AuthProvider;
|
|
11
15
|
config?: PlaygroundConfig;
|
|
12
16
|
showNavbar?: boolean;
|
|
13
17
|
navbarTitle?: string;
|
|
@@ -22,6 +26,8 @@ interface Props {
|
|
|
22
26
|
initialPipelineWidth?: number;
|
|
23
27
|
onClose?: () => void;
|
|
24
28
|
onSessionNavigate?: (sessionId: string) => void;
|
|
29
|
+
/** Per-instance state container — forwarded to the inner PlaygroundStudio */
|
|
30
|
+
instance?: FlowDropInstance;
|
|
25
31
|
}
|
|
26
32
|
declare const PlaygroundApp: import("svelte").Component<Props, {}, "">;
|
|
27
33
|
type PlaygroundApp = ReturnType<typeof PlaygroundApp>;
|