@flowdrop/flowdrop 2.0.0-beta.1 → 2.0.0-beta.3

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 (149) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/MIGRATION-2.0.md +173 -3
  3. package/dist/api/enhanced-client.js +6 -11
  4. package/dist/components/App.svelte +22 -45
  5. package/dist/components/App.svelte.d.ts +2 -7
  6. package/dist/components/CanvasIconButton.svelte +76 -0
  7. package/dist/components/CanvasIconButton.svelte.d.ts +18 -0
  8. package/dist/components/ConfigForm.svelte +6 -21
  9. package/dist/components/ConfigPanel.svelte +4 -3
  10. package/dist/components/LogoWordmark.svelte +113 -0
  11. package/dist/components/LogoWordmark.svelte.d.ts +26 -0
  12. package/dist/components/Navbar.svelte +8 -59
  13. package/dist/components/NodeSidebar.svelte +4 -11
  14. package/dist/components/NodeSwapPicker.svelte +0 -2
  15. package/dist/components/PipelineStatus.svelte +6 -1
  16. package/dist/components/PipelineStatus.svelte.d.ts +3 -0
  17. package/dist/components/PortMappingRow.svelte +0 -2
  18. package/dist/components/SchemaForm.svelte +4 -14
  19. package/dist/components/SettingsModal.svelte +0 -5
  20. package/dist/components/SettingsPanel.svelte +2 -6
  21. package/dist/components/ThemeToggle.svelte +0 -5
  22. package/dist/components/UniversalNode.svelte +32 -1
  23. package/dist/components/WorkflowEditor.svelte +66 -52
  24. package/dist/components/WorkflowEditor.svelte.d.ts +21 -0
  25. package/dist/components/chat/AIChatPanel.svelte +7 -2
  26. package/dist/components/console/ConsoleAutocomplete.svelte +1 -1
  27. package/dist/components/console/ConsoleOutput.svelte +2 -2
  28. package/dist/components/form/FormArray.svelte +0 -16
  29. package/dist/components/form/FormAutocomplete.svelte +18 -15
  30. package/dist/components/form/FormCheckboxGroup.svelte +0 -4
  31. package/dist/components/form/FormCodeEditor.svelte +9 -7
  32. package/dist/components/form/FormFieldLight.svelte +33 -4
  33. package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
  34. package/dist/components/form/FormMarkdownEditor.svelte +8 -5
  35. package/dist/components/form/FormNumberField.svelte +0 -4
  36. package/dist/components/form/FormRangeField.svelte +1 -20
  37. package/dist/components/form/FormSelect.svelte +10 -6
  38. package/dist/components/form/FormTemplateEditor.svelte +6 -4
  39. package/dist/components/form/FormTextField.svelte +10 -6
  40. package/dist/components/form/FormTextarea.svelte +10 -6
  41. package/dist/components/form/FormToggle.svelte +0 -4
  42. package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
  43. package/dist/components/icons/CommandLineIcon.svelte +15 -0
  44. package/dist/components/icons/CommandLineIcon.svelte.d.ts +26 -0
  45. package/dist/components/icons/MenuIcon.svelte +4 -0
  46. package/dist/components/icons/MenuIcon.svelte.d.ts +26 -0
  47. package/dist/components/icons/MenuOpenIcon.svelte +6 -0
  48. package/dist/components/icons/MenuOpenIcon.svelte.d.ts +26 -0
  49. package/dist/components/interrupt/ChoicePrompt.svelte +0 -10
  50. package/dist/components/interrupt/ConfirmationPrompt.svelte +0 -5
  51. package/dist/components/interrupt/InterruptBubble.svelte +11 -12
  52. package/dist/components/interrupt/ReviewPrompt.svelte +0 -20
  53. package/dist/components/interrupt/TextInputPrompt.svelte +0 -6
  54. package/dist/components/layouts/MainLayout.svelte +4 -5
  55. package/dist/components/nodes/AtomNode.svelte +46 -34
  56. package/dist/components/nodes/GatewayNode.svelte +91 -99
  57. package/dist/components/nodes/IdeaNode.svelte +62 -90
  58. package/dist/components/nodes/NodeConfigButton.svelte +86 -0
  59. package/dist/components/nodes/NodeConfigButton.svelte.d.ts +15 -0
  60. package/dist/components/nodes/NotesNode.svelte +70 -81
  61. package/dist/components/nodes/SimpleNode.svelte +28 -78
  62. package/dist/components/nodes/SquareNode.svelte +79 -109
  63. package/dist/components/nodes/TerminalNode.svelte +28 -86
  64. package/dist/components/nodes/ToolNode.svelte +82 -95
  65. package/dist/components/nodes/WorkflowNode.svelte +91 -100
  66. package/dist/components/playground/ChatInput.svelte +0 -1
  67. package/dist/components/playground/InputCollector.svelte +0 -2
  68. package/dist/components/playground/PipelineKanbanView.svelte +4 -2
  69. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
  70. package/dist/components/playground/PipelinePanel.svelte +20 -3
  71. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
  72. package/dist/components/playground/PipelineTableView.svelte +4 -2
  73. package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
  74. package/dist/components/playground/Playground.svelte +76 -25
  75. package/dist/components/playground/Playground.svelte.d.ts +3 -0
  76. package/dist/components/playground/PlaygroundApp.svelte +6 -1
  77. package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
  78. package/dist/components/playground/PlaygroundModal.svelte +5 -0
  79. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
  80. package/dist/components/playground/PlaygroundStudio.svelte +7 -6
  81. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
  82. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +2 -1
  83. package/dist/components/playground/pipelineViewUtils.svelte.js +2 -2
  84. package/dist/config/endpoints.d.ts +23 -0
  85. package/dist/config/endpoints.js +28 -0
  86. package/dist/core/index.d.ts +1 -2
  87. package/dist/core/index.js +2 -6
  88. package/dist/display/index.d.ts +6 -1
  89. package/dist/display/index.js +9 -1
  90. package/dist/editor/index.d.ts +1 -1
  91. package/dist/editor/index.js +1 -1
  92. package/dist/form/full.d.ts +2 -1
  93. package/dist/form/full.js +4 -1
  94. package/dist/form/index.d.ts +0 -1
  95. package/dist/form/index.js +3 -2
  96. package/dist/helpers/workflowEditorHelper.d.ts +4 -2
  97. package/dist/helpers/workflowEditorHelper.js +4 -3
  98. package/dist/playground/index.d.ts +2 -2
  99. package/dist/playground/index.js +2 -2
  100. package/dist/playground/mount.d.ts +19 -5
  101. package/dist/playground/mount.js +16 -8
  102. package/dist/registry/builtinNodeTypes.d.ts +53 -0
  103. package/dist/registry/builtinNodeTypes.js +67 -0
  104. package/dist/registry/builtinNodes.d.ts +2 -39
  105. package/dist/registry/builtinNodes.js +6 -53
  106. package/dist/services/agentSpecExecutionService.d.ts +0 -2
  107. package/dist/services/agentSpecExecutionService.js +0 -2
  108. package/dist/services/apiVariableService.js +12 -26
  109. package/dist/services/categoriesApi.js +3 -6
  110. package/dist/services/chatService.d.ts +4 -3
  111. package/dist/services/chatService.js +13 -18
  112. package/dist/services/interruptService.d.ts +7 -6
  113. package/dist/services/interruptService.js +19 -21
  114. package/dist/services/playgroundService.d.ts +9 -8
  115. package/dist/services/playgroundService.js +23 -25
  116. package/dist/services/portConfigApi.js +3 -6
  117. package/dist/services/settingsService.d.ts +9 -4
  118. package/dist/services/settingsService.js +23 -12
  119. package/dist/skins/drafter.d.ts +30 -0
  120. package/dist/skins/drafter.js +185 -0
  121. package/dist/skins/index.d.ts +2 -1
  122. package/dist/skins/index.js +4 -2
  123. package/dist/stores/apiContext.d.ts +11 -0
  124. package/dist/stores/apiContext.js +15 -0
  125. package/dist/stores/categoriesStore.svelte.js +0 -1
  126. package/dist/stores/playgroundStore.svelte.js +0 -2
  127. package/dist/styles/base.css +38 -9
  128. package/dist/styles/tokens.css +54 -2
  129. package/dist/svelte-app.d.ts +6 -0
  130. package/dist/svelte-app.js +4 -2
  131. package/dist/themes/drafter.d.ts +2 -0
  132. package/dist/themes/drafter.js +15 -0
  133. package/dist/themes/index.d.ts +2 -1
  134. package/dist/themes/index.js +8 -2
  135. package/dist/types/auth.d.ts +9 -51
  136. package/dist/types/auth.js +4 -54
  137. package/dist/types/events.d.ts +18 -0
  138. package/dist/types/events.js +2 -1
  139. package/dist/types/index.d.ts +4 -2
  140. package/dist/types/index.js +0 -1
  141. package/dist/types/settings.d.ts +1 -1
  142. package/dist/types/settings.js +1 -1
  143. package/dist/types/skin.d.ts +1 -1
  144. package/dist/types/theme.d.ts +16 -2
  145. package/dist/utils/edgeStyling.js +9 -5
  146. package/dist/utils/fetchWithAuth.d.ts +36 -15
  147. package/dist/utils/fetchWithAuth.js +53 -23
  148. package/dist/utils/nodeTypes.js +1 -1
  149. package/package.json +2 -1
@@ -232,7 +232,6 @@
232
232
 
233
233
  .chat-input__wrapper:focus-within {
234
234
  border-color: var(--fd-primary);
235
- box-shadow: 0 0 0 3px var(--fd-primary-muted);
236
235
  }
237
236
 
238
237
  .chat-input__textarea {
@@ -369,9 +369,7 @@
369
369
  .input-collector__input:focus,
370
370
  .input-collector__select:focus,
371
371
  .input-collector__textarea:focus {
372
- outline: none;
373
372
  border-color: var(--fd-primary);
374
- box-shadow: 0 0 0 3px var(--fd-primary-muted);
375
373
  }
376
374
 
377
375
  .input-collector__input::placeholder,
@@ -46,19 +46,21 @@
46
46
  import type { NodeStatus } from './pipelineViewUtils.svelte.js';
47
47
  import type { Workflow, WorkflowNode } from '../../types/index.js';
48
48
  import type { EndpointConfig } from '../../config/endpoints.js';
49
+ import type { AuthProvider } from '../../types/auth.js';
49
50
 
50
51
  interface Props {
51
52
  pipelineId: string;
52
53
  workflow: Workflow;
53
54
  endpointConfig: EndpointConfig;
55
+ authProvider?: AuthProvider;
54
56
  refreshTrigger?: number;
55
57
  }
56
58
 
57
- let { pipelineId, workflow, endpointConfig, refreshTrigger = 0 }: Props = $props();
59
+ let { pipelineId, workflow, endpointConfig, authProvider, refreshTrigger = 0 }: Props = $props();
58
60
 
59
61
  // endpointConfig is consumed once to build the API client; it must be stable
60
62
  // svelte-ignore state_referenced_locally
61
- const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig);
63
+ const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig, authProvider);
62
64
 
63
65
  $effect(() => {
64
66
  if (refreshTrigger <= 0) return;
@@ -1,9 +1,11 @@
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
  interface Props {
4
5
  pipelineId: string;
5
6
  workflow: Workflow;
6
7
  endpointConfig: EndpointConfig;
8
+ authProvider?: AuthProvider;
7
9
  refreshTrigger?: number;
8
10
  }
9
11
  declare const PipelineKanbanView: import("svelte").Component<Props, {}, "">;
@@ -16,12 +16,14 @@
16
16
  import { logger } from '../../utils/logger.js';
17
17
  import type { Workflow, PipelineViewDef } from '../../types/index.js';
18
18
  import type { EndpointConfig } from '../../config/endpoints.js';
19
+ import type { AuthProvider } from '../../types/auth.js';
19
20
  import type { PlaygroundExecution } from '../../types/playground.js';
20
21
 
21
22
  interface Props {
22
23
  pipelineId: string | null;
23
24
  workflow: Workflow;
24
25
  endpointConfig: EndpointConfig;
26
+ authProvider?: AuthProvider;
25
27
  isPinned: boolean;
26
28
  /** All executions for the current session, oldest-first */
27
29
  executions?: PlaygroundExecution[];
@@ -39,6 +41,7 @@
39
41
  pipelineId,
40
42
  workflow,
41
43
  endpointConfig,
44
+ authProvider,
42
45
  isPinned,
43
46
  executions = [],
44
47
  latestExecutionId = null,
@@ -248,14 +251,27 @@
248
251
  {#if pipelineId}
249
252
  {#key pipelineId}
250
253
  {#if viewMode === 'kanban'}
251
- <PipelineKanbanView {pipelineId} {workflow} {endpointConfig} {refreshTrigger} />
254
+ <PipelineKanbanView
255
+ {pipelineId}
256
+ {workflow}
257
+ {endpointConfig}
258
+ {authProvider}
259
+ {refreshTrigger}
260
+ />
252
261
  {:else if viewMode === 'table'}
253
- <PipelineTableView {pipelineId} {workflow} {endpointConfig} {refreshTrigger} />
262
+ <PipelineTableView
263
+ {pipelineId}
264
+ {workflow}
265
+ {endpointConfig}
266
+ {authProvider}
267
+ {refreshTrigger}
268
+ />
254
269
  {:else if viewMode === 'graph'}
255
270
  <PipelineStatus
256
271
  {pipelineId}
257
272
  {workflow}
258
273
  {endpointConfig}
274
+ {authProvider}
259
275
  runLabel={pipelineId}
260
276
  {refreshTrigger}
261
277
  isEmbedded={true}
@@ -264,7 +280,7 @@
264
280
  {@const activeView = extraViews.find((v) => v.key === viewMode)}
265
281
  {#if activeView}
266
282
  {@const View = activeView.component}
267
- <View {pipelineId} {workflow} {endpointConfig} {refreshTrigger} />
283
+ <View {pipelineId} {workflow} {endpointConfig} {authProvider} {refreshTrigger} />
268
284
  {/if}
269
285
  {/if}
270
286
  {/key}
@@ -277,6 +293,7 @@
277
293
  disableSidebar={true}
278
294
  mode="locked"
279
295
  {endpointConfig}
296
+ {authProvider}
280
297
  />
281
298
  {/if}
282
299
  </div>
@@ -1,10 +1,12 @@
1
1
  import type { Workflow, PipelineViewDef } 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 { PlaygroundExecution } from '../../types/playground.js';
4
5
  interface Props {
5
6
  pipelineId: string | null;
6
7
  workflow: Workflow;
7
8
  endpointConfig: EndpointConfig;
9
+ authProvider?: AuthProvider;
8
10
  isPinned: boolean;
9
11
  /** All executions for the current session, oldest-first */
10
12
  executions?: PlaygroundExecution[];
@@ -55,15 +55,17 @@
55
55
  import { formatMicroseconds } from '../../utils/duration.js';
56
56
  import type { Workflow, WorkflowNode } from '../../types/index.js';
57
57
  import type { EndpointConfig } from '../../config/endpoints.js';
58
+ import type { AuthProvider } from '../../types/auth.js';
58
59
 
59
60
  interface Props {
60
61
  pipelineId: string;
61
62
  workflow: Workflow;
62
63
  endpointConfig: EndpointConfig;
64
+ authProvider?: AuthProvider;
63
65
  refreshTrigger?: number;
64
66
  }
65
67
 
66
- let { pipelineId, workflow, endpointConfig, refreshTrigger = 0 }: Props = $props();
68
+ let { pipelineId, workflow, endpointConfig, authProvider, refreshTrigger = 0 }: Props = $props();
67
69
 
68
70
  interface JobRow {
69
71
  /** Stable key: job id, or node id for nodes without a job yet */
@@ -85,7 +87,7 @@
85
87
 
86
88
  // endpointConfig is consumed once to build the API client; it must be stable
87
89
  // svelte-ignore state_referenced_locally
88
- const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig);
90
+ const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig, authProvider);
89
91
 
90
92
  $effect(() => {
91
93
  if (refreshTrigger <= 0) return;
@@ -1,9 +1,11 @@
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
  interface Props {
4
5
  pipelineId: string;
5
6
  workflow: Workflow;
6
7
  endpointConfig: EndpointConfig;
8
+ authProvider?: AuthProvider;
7
9
  refreshTrigger?: number;
8
10
  }
9
11
  declare const PipelineTableView: import("svelte").Component<Props, {}, "">;
@@ -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,
@@ -35,6 +36,8 @@
35
36
  mode?: PlaygroundMode;
36
37
  initialSessionId?: string;
37
38
  endpointConfig?: EndpointConfig;
39
+ /** Auth provider applied to this instance's API requests. */
40
+ authProvider?: AuthProvider;
38
41
  config?: PlaygroundConfig;
39
42
  onClose?: () => void;
40
43
  onTogglePanel?: () => void;
@@ -49,6 +52,7 @@
49
52
  mode = 'standalone',
50
53
  initialSessionId,
51
54
  endpointConfig,
55
+ authProvider,
52
56
  config = {},
53
57
  onClose,
54
58
  onTogglePanel,
@@ -126,7 +130,7 @@
126
130
  }
127
131
 
128
132
  onMount(() => {
129
- if (endpointConfig) fd.api.configure(endpointConfig);
133
+ if (endpointConfig) fd.api.configure(endpointConfig, authProvider);
130
134
  if (workflow) fd.playground.setWorkflow(workflow);
131
135
 
132
136
  const handleVisibility = () => {
@@ -134,9 +138,14 @@
134
138
  const sessionId = fd.playground.currentSession?.id;
135
139
  if (sessionId) {
136
140
  void playgroundService
137
- .getMessages(fd.api.config, sessionId, {
138
- since: playgroundService.getLastSequenceNumber() ?? undefined
139
- })
141
+ .getMessages(
142
+ fd.api.config,
143
+ sessionId,
144
+ {
145
+ since: playgroundService.getLastSequenceNumber() ?? undefined
146
+ },
147
+ fd.api.authProvider
148
+ )
140
149
  .then((response) => fd.playground.applyServerResponse(response, sessionId))
141
150
  .catch((err) => logger.error('[Playground] Visibility catchup failed:', err));
142
151
  }
@@ -220,7 +229,12 @@
220
229
  fd.playground.setError(null);
221
230
 
222
231
  try {
223
- const sessionList = await playgroundService.listSessions(fd.api.config, workflowId);
232
+ const sessionList = await playgroundService.listSessions(
233
+ fd.api.config,
234
+ workflowId,
235
+ undefined,
236
+ fd.api.authProvider
237
+ );
224
238
  fd.playground.setSessions(sessionList);
225
239
  } catch (err) {
226
240
  const errorMessage = err instanceof Error ? err.message : 'Failed to load sessions';
@@ -237,7 +251,11 @@
237
251
  const token = ++loadToken;
238
252
 
239
253
  try {
240
- const session = await playgroundService.getSession(fd.api.config, sessionId);
254
+ const session = await playgroundService.getSession(
255
+ fd.api.config,
256
+ sessionId,
257
+ fd.api.authProvider
258
+ );
241
259
  if (token !== loadToken) return; // a newer session load superseded us
242
260
  fd.playground.setCurrentSession(session);
243
261
 
@@ -245,10 +263,15 @@
245
263
  // user scrolls up (loadOlderMessages). Clear right before applying the
246
264
  // fresh page — not before the await — so switching sessions doesn't blank
247
265
  // the view for the duration of the fetch.
248
- const response = await playgroundService.getMessages(fd.api.config, sessionId, {
249
- latest: true,
250
- limit: messagePageSize
251
- });
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
+ );
252
275
  if (token !== loadToken) return;
253
276
  fd.playground.clearMessages();
254
277
  fd.playground.applyServerResponse(response, sessionId);
@@ -281,10 +304,15 @@
281
304
  if (!sessionId || before === null) return;
282
305
 
283
306
  try {
284
- const response = await playgroundService.getMessages(fd.api.config, sessionId, {
285
- before,
286
- limit: messagePageSize
287
- });
307
+ const response = await playgroundService.getMessages(
308
+ fd.api.config,
309
+ sessionId,
310
+ {
311
+ before,
312
+ limit: messagePageSize
313
+ },
314
+ fd.api.authProvider
315
+ );
288
316
  // The session may have changed while the fetch was in flight — don't
289
317
  // splice an old session's page into the new session's store.
290
318
  if (fd.playground.currentSession?.id !== sessionId) return;
@@ -313,7 +341,13 @@
313
341
 
314
342
  try {
315
343
  const sessionName = `Session ${fd.playground.sessions.length + 1}`;
316
- const session = await playgroundService.createSession(fd.api.config, workflowId, sessionName);
344
+ const session = await playgroundService.createSession(
345
+ fd.api.config,
346
+ workflowId,
347
+ sessionName,
348
+ undefined,
349
+ fd.api.authProvider
350
+ );
317
351
 
318
352
  // Stop polling the previous (possibly running) session before switching,
319
353
  // mirroring handleSelectSession. Otherwise its next poll keeps the old
@@ -349,7 +383,7 @@
349
383
 
350
384
  async function handleDeleteSession(sessionId: string): Promise<void> {
351
385
  try {
352
- await playgroundService.deleteSession(fd.api.config, sessionId);
386
+ await playgroundService.deleteSession(fd.api.config, sessionId, fd.api.authProvider);
353
387
  fd.playground.removeSession(sessionId);
354
388
 
355
389
  if (fd.playground.currentSession?.id === sessionId) {
@@ -377,7 +411,13 @@
377
411
  fd.playground.setError(null);
378
412
 
379
413
  try {
380
- const message = await playgroundService.sendMessage(fd.api.config, sessionId, content, {});
414
+ const message = await playgroundService.sendMessage(
415
+ fd.api.config,
416
+ sessionId,
417
+ content,
418
+ {},
419
+ fd.api.authProvider
420
+ );
381
421
  fd.playground.addMessage(message);
382
422
  // Only start polling if not already active — avoids resetting the cursor
383
423
  // mid-session and re-fetching messages that are already in the store.
@@ -399,7 +439,7 @@
399
439
  if (!sessionId) return;
400
440
 
401
441
  try {
402
- await playgroundService.stopExecution(fd.api.config, sessionId);
442
+ await playgroundService.stopExecution(fd.api.config, sessionId, fd.api.authProvider);
403
443
  playgroundService.stopPolling();
404
444
  fd.playground.updateSessionStatus('idle');
405
445
  } catch (err) {
@@ -425,7 +465,8 @@
425
465
  (response) => fd.playground.applyServerResponse(response, sessionId),
426
466
  pollingInterval,
427
467
  overrideShouldStopPolling ?? config.shouldStopPolling,
428
- initialSequenceNumber
468
+ initialSequenceNumber,
469
+ fd.api.authProvider
429
470
  );
430
471
  }
431
472
 
@@ -434,9 +475,14 @@
434
475
  if (!sessionId || isRefreshing) return;
435
476
  isRefreshing = true;
436
477
  try {
437
- const response = await playgroundService.getMessages(fd.api.config, sessionId, {
438
- since: playgroundService.getLastSequenceNumber() ?? undefined
439
- });
478
+ const response = await playgroundService.getMessages(
479
+ fd.api.config,
480
+ sessionId,
481
+ {
482
+ since: playgroundService.getLastSequenceNumber() ?? undefined
483
+ },
484
+ fd.api.authProvider
485
+ );
440
486
  fd.playground.applyServerResponse(response, sessionId);
441
487
  if (response.sessionStatus === 'running' && !playgroundService.isPolling()) {
442
488
  startPolling(sessionId, true);
@@ -455,9 +501,14 @@
455
501
  try {
456
502
  // Catch up immediately rather than waiting for the next poll interval.
457
503
  // Use the service's sequence cursor so we only fetch new messages.
458
- const response = await playgroundService.getMessages(fd.api.config, sessionId, {
459
- since: playgroundService.getLastSequenceNumber() ?? undefined
460
- });
504
+ const response = await playgroundService.getMessages(
505
+ fd.api.config,
506
+ sessionId,
507
+ {
508
+ since: playgroundService.getLastSequenceNumber() ?? undefined
509
+ },
510
+ fd.api.authProvider
511
+ );
461
512
  fd.playground.applyServerResponse(response, sessionId);
462
513
  } catch (err) {
463
514
  logger.error('[Playground] Failed to refresh after interrupt:', err);
@@ -1,5 +1,6 @@
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';
4
5
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
5
6
  interface Props {
@@ -8,6 +9,8 @@ interface Props {
8
9
  mode?: PlaygroundMode;
9
10
  initialSessionId?: string;
10
11
  endpointConfig?: EndpointConfig;
12
+ /** Auth provider applied to this instance's API requests. */
13
+ authProvider?: AuthProvider;
11
14
  config?: PlaygroundConfig;
12
15
  onClose?: () => void;
13
16
  onTogglePanel?: () => void;
@@ -15,6 +15,7 @@
15
15
  import type { Workflow } from '../../types/index.js';
16
16
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
17
17
  import type { EndpointConfig } from '../../config/endpoints.js';
18
+ import type { AuthProvider } from '../../types/auth.js';
18
19
  import type { PlaygroundConfig } from '../../types/playground.js';
19
20
  import type { SettingsCategory } from '../../types/settings.js';
20
21
  import type { NavbarAction } from '../../types/navbar.js';
@@ -24,6 +25,8 @@
24
25
  workflow?: Workflow;
25
26
  mode?: 'standalone' | 'embedded';
26
27
  endpointConfig?: EndpointConfig;
28
+ /** Auth provider applied to this instance's API requests. */
29
+ authProvider?: AuthProvider;
27
30
  config?: PlaygroundConfig;
28
31
  showNavbar?: boolean;
29
32
  navbarTitle?: string;
@@ -47,8 +50,9 @@
47
50
  workflow,
48
51
  mode = 'standalone',
49
52
  endpointConfig,
53
+ authProvider,
50
54
  config = {},
51
- showNavbar = true,
55
+ showNavbar = false,
52
56
  navbarTitle,
53
57
  primaryActions = [],
54
58
  showSettings = true,
@@ -86,6 +90,7 @@
86
90
  {workflow}
87
91
  {mode}
88
92
  {endpointConfig}
93
+ {authProvider}
89
94
  {config}
90
95
  {initialSessionId}
91
96
  {initialPipelineOpen}
@@ -1,6 +1,7 @@
1
1
  import type { Workflow } from '../../types/index.js';
2
2
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
3
3
  import type { EndpointConfig } from '../../config/endpoints.js';
4
+ import type { AuthProvider } from '../../types/auth.js';
4
5
  import type { PlaygroundConfig } from '../../types/playground.js';
5
6
  import type { SettingsCategory } from '../../types/settings.js';
6
7
  import type { NavbarAction } from '../../types/navbar.js';
@@ -9,6 +10,8 @@ interface Props {
9
10
  workflow?: Workflow;
10
11
  mode?: 'standalone' | 'embedded';
11
12
  endpointConfig?: EndpointConfig;
13
+ /** Auth provider applied to this instance's API requests. */
14
+ authProvider?: AuthProvider;
12
15
  config?: PlaygroundConfig;
13
16
  showNavbar?: boolean;
14
17
  navbarTitle?: string;
@@ -12,6 +12,7 @@
12
12
  import type { Workflow } from '../../types/index.js';
13
13
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
14
14
  import type { EndpointConfig } from '../../config/endpoints.js';
15
+ import type { AuthProvider } from '../../types/auth.js';
15
16
  import type { PlaygroundConfig } from '../../types/playground.js';
16
17
  import { m } from '../../messages/index.js';
17
18
 
@@ -29,6 +30,8 @@
29
30
  initialSessionId?: string;
30
31
  /** API endpoint configuration */
31
32
  endpointConfig?: EndpointConfig;
33
+ /** Auth provider applied to this instance's API requests. */
34
+ authProvider?: AuthProvider;
32
35
  /** Playground configuration options */
33
36
  config?: PlaygroundConfig;
34
37
  /** Per-instance state container — forwarded to the inner Playground */
@@ -43,6 +46,7 @@
43
46
  workflow,
44
47
  initialSessionId,
45
48
  endpointConfig,
49
+ authProvider,
46
50
  config = {},
47
51
  instance,
48
52
  onClose
@@ -111,6 +115,7 @@
111
115
  mode="modal"
112
116
  {initialSessionId}
113
117
  {endpointConfig}
118
+ {authProvider}
114
119
  {config}
115
120
  {onClose}
116
121
  />
@@ -1,6 +1,7 @@
1
1
  import type { Workflow } from '../../types/index.js';
2
2
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
3
3
  import type { EndpointConfig } from '../../config/endpoints.js';
4
+ import type { AuthProvider } from '../../types/auth.js';
4
5
  import type { PlaygroundConfig } from '../../types/playground.js';
5
6
  /**
6
7
  * Component props
@@ -16,6 +17,8 @@ interface Props {
16
17
  initialSessionId?: string;
17
18
  /** API endpoint configuration */
18
19
  endpointConfig?: EndpointConfig;
20
+ /** Auth provider applied to this instance's API requests. */
21
+ authProvider?: AuthProvider;
19
22
  /** Playground configuration options */
20
23
  config?: PlaygroundConfig;
21
24
  /** Per-instance state container — forwarded to the inner Playground */
@@ -8,6 +8,7 @@
8
8
  import { logger } from '../../utils/logger.js';
9
9
  import type { Workflow, PipelineViewDef } from '../../types/index.js';
10
10
  import type { EndpointConfig } from '../../config/endpoints.js';
11
+ import type { AuthProvider } from '../../types/auth.js';
11
12
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
12
13
 
13
14
  interface Props {
@@ -17,6 +18,8 @@
17
18
  workflow?: Workflow;
18
19
  /** API endpoint configuration */
19
20
  endpointConfig?: EndpointConfig;
21
+ /** Auth provider applied to this instance's API requests. */
22
+ authProvider?: AuthProvider;
20
23
  /** Display mode (default: standalone) */
21
24
  mode?: PlaygroundMode;
22
25
  /** Session ID to activate on mount. Changing this prop remounts the Playground. */
@@ -43,6 +46,7 @@
43
46
  workflowId,
44
47
  workflow: workflowProp,
45
48
  endpointConfig,
49
+ authProvider,
46
50
  mode = 'standalone',
47
51
  initialSessionId,
48
52
  config = {},
@@ -99,7 +103,7 @@
99
103
  fd.pipelinePanel.setOpen(initialPipelineOpen);
100
104
  }
101
105
  if (endpointConfig) {
102
- fd.api.configure(endpointConfig);
106
+ fd.api.configure(endpointConfig, authProvider);
103
107
  }
104
108
  if (!workflowProp) {
105
109
  void loadWorkflow();
@@ -182,6 +186,7 @@
182
186
  pipelineId={activeId}
183
187
  workflow={resolvedWorkflow}
184
188
  {endpointConfig}
189
+ {authProvider}
185
190
  isPinned={fd.playground.pinnedExecutionId !== null}
186
191
  {executions}
187
192
  latestExecutionId={fd.playground.latestExecutionId}
@@ -238,6 +243,7 @@
238
243
  {workflowId}
239
244
  workflow={resolvedWorkflow}
240
245
  {endpointConfig}
246
+ {authProvider}
241
247
  {mode}
242
248
  {initialSessionId}
243
249
  {config}
@@ -457,11 +463,6 @@
457
463
  .playground-studio__back-to-chat:hover {
458
464
  background-color: var(--fd-muted);
459
465
  }
460
-
461
- .playground-studio__back-to-chat:focus-visible {
462
- outline: 2px solid var(--fd-ring);
463
- outline-offset: 2px;
464
- }
465
466
  }
466
467
 
467
468
  @media (prefers-reduced-motion: reduce) {
@@ -1,6 +1,7 @@
1
1
  import type { FlowDropInstance } from '../../stores/instanceContainer.svelte.js';
2
2
  import type { Workflow, PipelineViewDef } from '../../types/index.js';
3
3
  import type { EndpointConfig } from '../../config/endpoints.js';
4
+ import type { AuthProvider } from '../../types/auth.js';
4
5
  import type { PlaygroundConfig, PlaygroundMode } from '../../types/playground.js';
5
6
  interface Props {
6
7
  /** Target workflow ID */
@@ -9,6 +10,8 @@ interface Props {
9
10
  workflow?: Workflow;
10
11
  /** API endpoint configuration */
11
12
  endpointConfig?: EndpointConfig;
13
+ /** Auth provider applied to this instance's API requests. */
14
+ authProvider?: AuthProvider;
12
15
  /** Display mode (default: standalone) */
13
16
  mode?: PlaygroundMode;
14
17
  /** Session ID to activate on mount. Changing this prop remounts the Playground. */
@@ -1,4 +1,5 @@
1
1
  import type { EndpointConfig } from '../../config/endpoints.js';
2
+ import type { AuthProvider } from '../../types/auth.js';
2
3
  import type { NodeExecutionStatus, KanbanColumnDef } from '../../types/index.js';
3
4
  export type NodeStatus = NodeExecutionStatus;
4
5
  export interface NodeStatusData {
@@ -40,7 +41,7 @@ export declare function resolveStatus(raw: NodeStatusData | undefined): NodeStat
40
41
  * `endpointConfig` is used once to construct the API client — it must be stable.
41
42
  * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
42
43
  */
43
- export declare function createPipelineDataFetcher(getPipelineId: () => string, endpointConfig: EndpointConfig): {
44
+ export declare function createPipelineDataFetcher(getPipelineId: () => string, endpointConfig: EndpointConfig, authProvider?: AuthProvider): {
44
45
  readonly nodeStatusMap: Record<string, NodeStatusData>;
45
46
  readonly jobs: PipelineJobItem[];
46
47
  readonly kanbanConfig: KanbanColumnDef[] | null;
@@ -55,8 +55,8 @@ export function resolveStatus(raw) {
55
55
  * `endpointConfig` is used once to construct the API client — it must be stable.
56
56
  * `getPipelineId` is called on every fetch so pipeline ID changes are picked up.
57
57
  */
58
- export function createPipelineDataFetcher(getPipelineId, endpointConfig) {
59
- const client = new EnhancedFlowDropApiClient(endpointConfig);
58
+ export function createPipelineDataFetcher(getPipelineId, endpointConfig, authProvider) {
59
+ const client = new EnhancedFlowDropApiClient(endpointConfig, authProvider);
60
60
  let nodeStatusMap = $state({});
61
61
  let jobs = $state([]);
62
62
  let kanbanConfig = $state(null);
@@ -3,6 +3,7 @@
3
3
  * Provides configurable endpoints for all API actions
4
4
  */
5
5
  import type { AgentSpecEndpointConfig } from './agentSpecEndpoints.js';
6
+ import type { AuthProvider } from '../types/auth.js';
6
7
  export interface EndpointConfig {
7
8
  /** Base URL for all endpoints */
8
9
  baseUrl: string;
@@ -159,3 +160,25 @@ export declare function getEndpointMethod(config: EndpointConfig, endpointKey: s
159
160
  * Get custom headers for an endpoint
160
161
  */
161
162
  export declare function getEndpointHeaders(config: EndpointConfig, endpointKey: string): Record<string, string>;
163
+ /**
164
+ * Build request headers for an endpoint, layering the auth provider's headers
165
+ * over the static endpoint headers.
166
+ *
167
+ * This is the single header-building path shared by the per-instance services
168
+ * (playground, chat, interrupt, settings, port config, categories). Routing all
169
+ * of them through this helper guarantees a configured {@link AuthProvider}
170
+ * authenticates every request consistently — matching the behaviour of
171
+ * {@link EnhancedFlowDropApiClient}, which owns the equivalent merge for the
172
+ * typed workflow/node API.
173
+ *
174
+ * `getAuthHeaders()` is awaited per call so providers can return freshly
175
+ * refreshed tokens. When no provider is supplied the result is identical to
176
+ * {@link getEndpointHeaders} (no auth) — keeping unauthenticated callers
177
+ * working unchanged.
178
+ *
179
+ * @param config - The endpoint configuration
180
+ * @param endpointKey - Key identifying the endpoint (for static header lookup)
181
+ * @param authProvider - Optional auth provider supplying `Authorization` etc.
182
+ * @returns Merged headers: static endpoint headers < auth headers
183
+ */
184
+ export declare function getRequestHeaders(config: EndpointConfig, endpointKey: string, authProvider?: AuthProvider): Promise<Record<string, string>>;