@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.
Files changed (235) hide show
  1. package/CHANGELOG.md +508 -0
  2. package/MIGRATION-2.0.md +629 -0
  3. package/README.md +23 -23
  4. package/dist/adapters/WorkflowAdapter.d.ts +1 -1
  5. package/dist/adapters/WorkflowAdapter.js +14 -8
  6. package/dist/adapters/agentspec/AgentSpecAdapter.js +7 -7
  7. package/dist/api/enhanced-client.js +6 -11
  8. package/dist/chat/batchFeedback.d.ts +39 -0
  9. package/dist/chat/batchFeedback.js +51 -0
  10. package/dist/commands/executor.js +15 -1
  11. package/dist/commands/storeIntegration.svelte.d.ts +4 -1
  12. package/dist/commands/storeIntegration.svelte.js +26 -21
  13. package/dist/commands/types.d.ts +2 -0
  14. package/dist/components/App.svelte +163 -192
  15. package/dist/components/App.svelte.d.ts +47 -8
  16. package/dist/components/ConfigForm.svelte +77 -49
  17. package/dist/components/ConfigModal.svelte +7 -2
  18. package/dist/components/ConnectionLine.svelte +4 -2
  19. package/dist/components/Navbar.svelte +61 -1
  20. package/dist/components/NodeSidebar.svelte +27 -45
  21. package/dist/components/NodeStatusOverlay.svelte +94 -6
  22. package/dist/components/NodeSwapPicker.svelte +10 -8
  23. package/dist/components/PipelineStatus.svelte +22 -68
  24. package/dist/components/PipelineStatus.svelte.d.ts +3 -0
  25. package/dist/components/PortCoordinateTracker.svelte +5 -6
  26. package/dist/components/SchemaForm.stories.svelte +1 -3
  27. package/dist/components/SchemaForm.svelte +22 -27
  28. package/dist/components/SchemaForm.svelte.d.ts +0 -8
  29. package/dist/components/SettingsModal.svelte +8 -3
  30. package/dist/components/SettingsPanel.svelte +20 -4
  31. package/dist/components/SwapMappingEditor.svelte +67 -49
  32. package/dist/components/SwapMappingEditor.svelte.d.ts +0 -2
  33. package/dist/components/UniversalNode.svelte +9 -7
  34. package/dist/components/WorkflowEditor.svelte +121 -111
  35. package/dist/components/WorkflowEditor.svelte.d.ts +21 -10
  36. package/dist/components/chat/AIChatPanel.svelte +98 -89
  37. package/dist/components/chat/AIChatPanel.svelte.d.ts +0 -4
  38. package/dist/components/chat/CommandPreview.svelte +2 -1
  39. package/dist/components/console/CommandConsole.svelte +7 -5
  40. package/dist/components/console/ConsoleAutocomplete.svelte +10 -11
  41. package/dist/components/console/ConsoleAutocomplete.svelte.d.ts +6 -0
  42. package/dist/components/console/ConsoleInput.svelte +15 -6
  43. package/dist/components/console/ConsoleOutput.svelte +2 -1
  44. package/dist/components/form/FormArray.svelte +5 -9
  45. package/dist/components/form/FormArray.svelte.d.ts +2 -1
  46. package/dist/components/form/FormAutocomplete.svelte +16 -15
  47. package/dist/components/form/FormField.svelte +4 -2
  48. package/dist/components/form/FormFieldLight.svelte +34 -3
  49. package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
  50. package/dist/components/form/FormMarkdownEditor.svelte +9 -4
  51. package/dist/components/form/FormRangeField.svelte +1 -0
  52. package/dist/components/form/FormTemplateEditor.svelte +11 -3
  53. package/dist/components/form/FormToggle.svelte +5 -12
  54. package/dist/components/form/FormToggle.svelte.d.ts +4 -2
  55. package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
  56. package/dist/components/form/templateAutocomplete.js +1 -5
  57. package/dist/components/form/types.d.ts +1 -14
  58. package/dist/components/interrupt/FormPrompt.svelte +3 -2
  59. package/dist/components/interrupt/InterruptBubble.svelte +25 -17
  60. package/dist/components/interrupt/ReviewPrompt.svelte +10 -3
  61. package/dist/components/interrupt/TextInputPrompt.svelte +2 -1
  62. package/dist/components/layouts/MainLayout.svelte +20 -13
  63. package/dist/components/layouts/MainLayout.svelte.d.ts +4 -0
  64. package/dist/components/nodes/AtomNode.svelte +17 -5
  65. package/dist/components/nodes/GatewayNode.svelte +19 -10
  66. package/dist/components/nodes/IdeaNode.svelte +7 -0
  67. package/dist/components/nodes/SimpleNode.svelte +11 -6
  68. package/dist/components/nodes/SquareNode.svelte +15 -8
  69. package/dist/components/nodes/TerminalNode.svelte +9 -4
  70. package/dist/components/nodes/ToolNode.svelte +7 -1
  71. package/dist/components/nodes/WorkflowNode.svelte +16 -7
  72. package/dist/components/playground/ChatInput.svelte +11 -14
  73. package/dist/components/playground/ChatPanel.svelte +6 -49
  74. package/dist/components/playground/ChatPanel.svelte.d.ts +0 -14
  75. package/dist/components/playground/ControlPanel.svelte +134 -123
  76. package/dist/components/playground/ControlPanel.svelte.d.ts +3 -0
  77. package/dist/components/playground/ExecutionLogs.svelte +11 -9
  78. package/dist/components/playground/InputCollector.svelte +11 -9
  79. package/dist/components/playground/MessageStream.svelte +17 -23
  80. package/dist/components/playground/PipelineKanbanView.svelte +69 -8
  81. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
  82. package/dist/components/playground/PipelinePanel.svelte +31 -8
  83. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
  84. package/dist/components/playground/PipelineTableView.svelte +188 -44
  85. package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
  86. package/dist/components/playground/Playground.svelte +154 -105
  87. package/dist/components/playground/Playground.svelte.d.ts +5 -0
  88. package/dist/components/playground/PlaygroundApp.svelte +11 -1
  89. package/dist/components/playground/PlaygroundApp.svelte.d.ts +6 -0
  90. package/dist/components/playground/PlaygroundModal.svelte +18 -3
  91. package/dist/components/playground/PlaygroundModal.svelte.d.ts +6 -0
  92. package/dist/components/playground/PlaygroundStudio.svelte +40 -32
  93. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +6 -0
  94. package/dist/components/playground/SessionManager.svelte +9 -12
  95. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +30 -1
  96. package/dist/components/playground/pipelineViewUtils.svelte.js +40 -3
  97. package/dist/config/endpoints.d.ts +23 -7
  98. package/dist/config/endpoints.js +30 -10
  99. package/dist/core/index.d.ts +5 -6
  100. package/dist/core/index.js +8 -12
  101. package/dist/display/index.d.ts +6 -3
  102. package/dist/display/index.js +7 -5
  103. package/dist/editor/index.d.ts +20 -21
  104. package/dist/editor/index.js +26 -36
  105. package/dist/form/code.d.ts +25 -15
  106. package/dist/form/code.js +44 -41
  107. package/dist/form/fieldRegistry.d.ts +17 -13
  108. package/dist/form/fieldRegistry.js +32 -12
  109. package/dist/form/full.d.ts +19 -14
  110. package/dist/form/full.js +26 -28
  111. package/dist/form/index.d.ts +3 -4
  112. package/dist/form/index.js +6 -5
  113. package/dist/form/markdown.d.ts +13 -8
  114. package/dist/form/markdown.js +22 -23
  115. package/dist/helpers/proximityConnect.d.ts +3 -2
  116. package/dist/helpers/proximityConnect.js +2 -5
  117. package/dist/helpers/workflowEditorHelper.d.ts +14 -5
  118. package/dist/helpers/workflowEditorHelper.js +28 -25
  119. package/dist/index.d.ts +28 -24
  120. package/dist/index.js +27 -50
  121. package/dist/messages/defaults.d.ts +2 -5
  122. package/dist/messages/defaults.js +3 -6
  123. package/dist/messages/index.d.ts +0 -1
  124. package/dist/messages/index.js +0 -1
  125. package/dist/mocks/app-forms.d.ts +6 -2
  126. package/dist/mocks/app-forms.js +11 -4
  127. package/dist/openapi/v1/openapi.yaml +3 -3
  128. package/dist/playground/index.d.ts +4 -5
  129. package/dist/playground/index.js +4 -32
  130. package/dist/playground/mount.d.ts +25 -0
  131. package/dist/playground/mount.js +50 -20
  132. package/dist/registry/{BaseRegistry.d.ts → BaseRegistry.svelte.d.ts} +22 -1
  133. package/dist/registry/{BaseRegistry.js → BaseRegistry.svelte.js} +37 -1
  134. package/dist/registry/builtinFormats.d.ts +9 -18
  135. package/dist/registry/builtinFormats.js +9 -39
  136. package/dist/registry/builtinNodeTypes.d.ts +53 -0
  137. package/dist/registry/builtinNodeTypes.js +67 -0
  138. package/dist/registry/builtinNodes.d.ts +2 -64
  139. package/dist/registry/builtinNodes.js +7 -103
  140. package/dist/registry/index.d.ts +3 -4
  141. package/dist/registry/index.js +4 -6
  142. package/dist/registry/nodeComponentRegistry.d.ts +182 -15
  143. package/dist/registry/nodeComponentRegistry.js +235 -17
  144. package/dist/registry/workflowFormatRegistry.d.ts +14 -9
  145. package/dist/registry/workflowFormatRegistry.js +24 -8
  146. package/dist/{schema → schemas}/index.d.ts +2 -2
  147. package/dist/{schema → schemas}/index.js +2 -2
  148. package/dist/schemas/v1/workflow.schema.json +3 -3
  149. package/dist/services/agentSpecExecutionService.d.ts +0 -2
  150. package/dist/services/agentSpecExecutionService.js +0 -3
  151. package/dist/services/apiVariableService.d.ts +2 -1
  152. package/dist/services/apiVariableService.js +16 -47
  153. package/dist/services/autoSaveService.d.ts +7 -0
  154. package/dist/services/autoSaveService.js +6 -4
  155. package/dist/services/categoriesApi.js +3 -6
  156. package/dist/services/chatService.d.ts +9 -4
  157. package/dist/services/chatService.js +23 -28
  158. package/dist/services/draftStorage.d.ts +129 -13
  159. package/dist/services/draftStorage.js +185 -37
  160. package/dist/services/dynamicSchemaService.d.ts +2 -1
  161. package/dist/services/dynamicSchemaService.js +5 -22
  162. package/dist/services/globalSave.d.ts +13 -12
  163. package/dist/services/globalSave.js +29 -51
  164. package/dist/services/historyService.d.ts +9 -3
  165. package/dist/services/historyService.js +9 -3
  166. package/dist/services/interruptService.d.ts +15 -9
  167. package/dist/services/interruptService.js +35 -37
  168. package/dist/services/nodeExecutionService.d.ts +18 -3
  169. package/dist/services/nodeExecutionService.js +71 -45
  170. package/dist/services/playgroundService.d.ts +16 -10
  171. package/dist/services/playgroundService.js +42 -43
  172. package/dist/services/portConfigApi.js +3 -6
  173. package/dist/services/settingsService.d.ts +9 -4
  174. package/dist/services/settingsService.js +23 -12
  175. package/dist/services/variableService.d.ts +2 -1
  176. package/dist/services/variableService.js +2 -2
  177. package/dist/services/workflowStorage.js +6 -6
  178. package/dist/stores/apiContext.d.ts +56 -0
  179. package/dist/stores/apiContext.js +80 -0
  180. package/dist/stores/categoriesStore.svelte.d.ts +28 -23
  181. package/dist/stores/categoriesStore.svelte.js +69 -64
  182. package/dist/stores/getInstance.svelte.d.ts +39 -0
  183. package/dist/stores/getInstance.svelte.js +65 -0
  184. package/dist/stores/historyStore.svelte.d.ts +77 -93
  185. package/dist/stores/historyStore.svelte.js +134 -160
  186. package/dist/stores/instanceContainer.svelte.d.ts +111 -0
  187. package/dist/stores/instanceContainer.svelte.js +114 -0
  188. package/dist/stores/interruptStore.svelte.d.ts +112 -82
  189. package/dist/stores/interruptStore.svelte.js +253 -226
  190. package/dist/stores/pipelinePanelStore.svelte.d.ts +27 -3
  191. package/dist/stores/pipelinePanelStore.svelte.js +61 -14
  192. package/dist/stores/playgroundStore.svelte.d.ts +169 -222
  193. package/dist/stores/playgroundStore.svelte.js +513 -580
  194. package/dist/stores/portCoordinateStore.svelte.d.ts +57 -51
  195. package/dist/stores/portCoordinateStore.svelte.js +109 -98
  196. package/dist/stores/settingsStore.svelte.d.ts +4 -1
  197. package/dist/stores/settingsStore.svelte.js +47 -12
  198. package/dist/stores/workflowStore.svelte.d.ts +178 -213
  199. package/dist/stores/workflowStore.svelte.js +449 -501
  200. package/dist/stories/EdgeDecorator.svelte +5 -2
  201. package/dist/stories/NodeDecorator.svelte +5 -3
  202. package/dist/svelte-app.d.ts +60 -10
  203. package/dist/svelte-app.js +159 -54
  204. package/dist/types/auth.d.ts +9 -51
  205. package/dist/types/auth.js +4 -54
  206. package/dist/types/events.d.ts +6 -3
  207. package/dist/types/index.d.ts +37 -5
  208. package/dist/types/index.js +0 -1
  209. package/dist/types/navbar.d.ts +7 -0
  210. package/dist/types/playground.d.ts +18 -3
  211. package/dist/types/settings.d.ts +13 -0
  212. package/dist/types/settings.js +1 -0
  213. package/dist/utils/colors.d.ts +47 -21
  214. package/dist/utils/colors.js +69 -68
  215. package/dist/utils/connections.d.ts +9 -15
  216. package/dist/utils/connections.js +13 -32
  217. package/dist/utils/duration.d.ts +13 -0
  218. package/dist/utils/duration.js +45 -0
  219. package/dist/utils/edgeStyling.js +9 -5
  220. package/dist/utils/fetchWithAuth.d.ts +36 -15
  221. package/dist/utils/fetchWithAuth.js +53 -23
  222. package/dist/utils/icons.d.ts +5 -2
  223. package/dist/utils/icons.js +6 -5
  224. package/dist/utils/nodeSwap.d.ts +6 -2
  225. package/dist/utils/nodeSwap.js +62 -126
  226. package/dist/utils/nodeTypes.d.ts +17 -8
  227. package/dist/utils/nodeTypes.js +27 -20
  228. package/dist/utils/performanceUtils.js +7 -0
  229. package/package.json +7 -5
  230. package/dist/messages/deprecation.d.ts +0 -20
  231. package/dist/messages/deprecation.js +0 -33
  232. package/dist/registry/plugin.d.ts +0 -215
  233. package/dist/registry/plugin.js +0 -249
  234. package/dist/services/api.d.ts +0 -129
  235. 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 { setEndpointConfig } from '../../services/api.js';
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(280);
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) setEndpointConfig(endpointConfig);
136
- if (workflow) playgroundActions.setWorkflow(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 = getCurrentSession()?.id;
138
+ const sessionId = fd.playground.currentSession?.id;
141
139
  if (sessionId) {
142
140
  void playgroundService
143
- .getMessages(sessionId, {
144
- since: playgroundService.getLastSequenceNumber() ?? undefined
145
- })
146
- .then((response) => applyServerResponse(response, sessionId))
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 = getSessions();
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 = getSessions();
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
- playgroundActions.reset();
221
- interruptActions.reset();
223
+ fd.playground.reset();
224
+ fd.interrupts.reset();
222
225
  });
223
226
 
224
227
  async function loadSessions(): Promise<void> {
225
- playgroundActions.setLoading(true);
226
- playgroundActions.setError(null);
228
+ fd.playground.setLoading(true);
229
+ fd.playground.setError(null);
227
230
 
228
231
  try {
229
- const sessionList = await playgroundService.listSessions(workflowId);
230
- playgroundActions.setSessions(sessionList);
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
- playgroundActions.setError(errorMessage);
241
+ fd.playground.setError(errorMessage);
234
242
  logger.error('Failed to load sessions:', err);
235
243
  } finally {
236
- playgroundActions.setLoading(false);
244
+ fd.playground.setLoading(false);
237
245
  }
238
246
  }
239
247
 
240
248
  async function loadSession(sessionId: string): Promise<void> {
241
- playgroundActions.setLoading(true);
242
- playgroundActions.setError(null);
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(sessionId);
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
- playgroundActions.setCurrentSession(session);
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(sessionId, {
255
- latest: true,
256
- limit: messagePageSize
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
- playgroundActions.clearMessages();
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
- playgroundActions.setError(errorMessage);
288
+ fd.playground.setError(errorMessage);
272
289
  logger.error('Failed to load session:', err);
273
290
  } finally {
274
- if (token === loadToken) playgroundActions.setLoading(false);
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 = getCurrentSession()?.id;
286
- const before = getOldestSequenceNumber();
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(sessionId, {
291
- before,
292
- limit: messagePageSize
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 (getCurrentSession()?.id !== sessionId) return;
318
+ if (fd.playground.currentSession?.id !== sessionId) return;
297
319
  if (response.data && response.data.length > 0) {
298
- playgroundActions.addMessages(response.data);
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
- playgroundActions.setLoading(true);
318
- playgroundActions.setError(null);
339
+ fd.playground.setLoading(true);
340
+ fd.playground.setError(null);
319
341
 
320
342
  try {
321
- const sessionName = `Session ${getSessions().length + 1}`;
322
- const session = await playgroundService.createSession(workflowId, sessionName);
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
- playgroundActions.addSession(session);
335
- playgroundActions.setCurrentSession(session);
336
- playgroundActions.clearMessages();
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
- playgroundActions.setError(errorMessage);
367
+ fd.playground.setError(errorMessage);
340
368
  logger.error('Failed to create session:', err);
341
369
  } finally {
342
- playgroundActions.setLoading(false);
370
+ fd.playground.setLoading(false);
343
371
  }
344
372
  }
345
373
 
346
374
  async function handleSelectSession(sessionId: string): Promise<void> {
347
- playgroundActions.pinExecution(null);
348
- const currentSessionId = getCurrentSession()?.id;
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
- playgroundActions.updateSessionStatus('idle');
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
- playgroundActions.removeSession(sessionId);
386
+ await playgroundService.deleteSession(fd.api.config, sessionId, fd.api.authProvider);
387
+ fd.playground.removeSession(sessionId);
360
388
 
361
- if (getCurrentSession()?.id === sessionId) {
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
- playgroundActions.setError(errorMessage);
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 (getIsExecuting()) return;
400
+ if (fd.playground.isExecuting) return;
373
401
 
374
- if (!getCurrentSession()) {
402
+ if (!fd.playground.currentSession) {
375
403
  await handleCreateSession();
376
- if (!getCurrentSession()) return;
404
+ if (!fd.playground.currentSession) return;
377
405
  }
378
406
 
379
- const sessionId = getCurrentSession()!.id;
407
+ const sessionId = fd.playground.currentSession!.id;
380
408
 
381
- playgroundActions.updateSessionStatus('running');
382
- playgroundActions.pinExecution(null);
383
- playgroundActions.setError(null);
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(sessionId, content, {});
387
- playgroundActions.addMessage(message);
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
- playgroundActions.setError(errorMessage);
398
- playgroundActions.updateSessionStatus('idle');
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 = getCurrentSession()?.id;
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
- playgroundActions.updateSessionStatus('idle');
444
+ fd.playground.updateSessionStatus('idle');
411
445
  } catch (err) {
412
446
  const errorMessage = err instanceof Error ? err.message : 'Failed to stop execution';
413
- playgroundActions.setError(errorMessage);
447
+ fd.playground.setError(errorMessage);
414
448
  playgroundService.stopPolling();
415
- playgroundActions.updateSessionStatus('idle');
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 ? getLatestSequenceNumber() : null;
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 = getCurrentSession()?.id;
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(sessionId, {
443
- since: playgroundService.getLastSequenceNumber() ?? undefined
444
- });
445
- applyServerResponse(response, sessionId);
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 = getCurrentSession()?.id;
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(sessionId, {
464
- since: playgroundService.getLastSequenceNumber() ?? undefined
465
- });
466
- applyServerResponse(response, sessionId);
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 getError()}
532
+ {#if fd.playground.error}
487
533
  <div class="playground__error">
488
534
  <Icon icon="mdi:alert-circle" />
489
- <span>{getError()}</span>
535
+ <span>{fd.playground.error}</span>
490
536
  <button
491
537
  type="button"
492
538
  class="playground__error-dismiss"
493
- onclick={() => playgroundActions.setError(null)}
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 getIsLoading() && !getCurrentSession()}
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={getSessions().length === 0 ? handleCreateSession : undefined}
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>;