@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
@@ -2,7 +2,6 @@
2
2
  * Node Execution Service
3
3
  * Handles fetching and managing node execution information from the backend
4
4
  */
5
- import { getEndpointConfig } from './api.js';
6
5
  import { buildEndpointUrl } from '../config/endpoints.js';
7
6
  import { NODE_EXECUTION_CACHE_TIMEOUT_MS, PIPELINE_API_UNAVAILABLE_DURATION_MS } from '../config/constants.js';
8
7
  import { logger } from '../utils/logger.js';
@@ -26,12 +25,11 @@ export class NodeExecutionService {
26
25
  /**
27
26
  * Get execution information for a specific node from pipeline data
28
27
  */
29
- async getNodeExecutionInfo(nodeId, pipelineId) {
28
+ async getNodeExecutionInfo(endpointConfig, nodeId, pipelineId) {
30
29
  if (!pipelineId) {
31
30
  return null;
32
31
  }
33
32
  try {
34
- const endpointConfig = getEndpointConfig();
35
33
  if (!endpointConfig)
36
34
  throw new Error('Endpoint config not available');
37
35
  const url = buildEndpointUrl(endpointConfig, endpointConfig.endpoints.pipelines.get, {
@@ -45,24 +43,7 @@ export class NodeExecutionService {
45
43
  const pipelineData = raw.data ?? raw;
46
44
  const jobs = pipelineData.jobs || [];
47
45
  const nodeStatuses = pipelineData.node_statuses || {};
48
- // Find the job for this node
49
- const nodeJob = jobs.find((job) => job.node_id === nodeId);
50
- const nodeStatus = nodeStatuses[nodeId];
51
- if (!nodeJob && !nodeStatus) {
52
- return {
53
- status: 'idle',
54
- executionCount: 0,
55
- isExecuting: false
56
- };
57
- }
58
- const executionInfo = {
59
- status: this.mapJobStatusToExecutionStatus(nodeStatus?.status || nodeJob?.status || 'idle'),
60
- executionCount: nodeJob?.execution_count || 0,
61
- isExecuting: nodeStatus?.status === 'running' || nodeJob?.status === 'running',
62
- lastExecuted: nodeJob?.last_executed || nodeStatus?.last_executed,
63
- lastExecutionDuration: nodeJob?.execution_time || nodeStatus?.execution_time,
64
- lastError: nodeJob?.error || nodeStatus?.error
65
- };
46
+ const executionInfo = this.buildNodeExecutionInfo(nodeId, nodeStatuses[nodeId], jobs);
66
47
  this.cache.set(nodeId, executionInfo);
67
48
  return executionInfo;
68
49
  }
@@ -74,7 +55,7 @@ export class NodeExecutionService {
74
55
  /**
75
56
  * Get execution information for multiple nodes from pipeline data
76
57
  */
77
- async getMultipleNodeExecutionInfo(nodeIds, pipelineId) {
58
+ async getMultipleNodeExecutionInfo(endpointConfig, nodeIds, pipelineId) {
78
59
  if (!pipelineId) {
79
60
  return {};
80
61
  }
@@ -91,7 +72,6 @@ export class NodeExecutionService {
91
72
  return defaultExecutionInfo;
92
73
  }
93
74
  try {
94
- const endpointConfig = getEndpointConfig();
95
75
  if (!endpointConfig)
96
76
  throw new Error('Endpoint config not available');
97
77
  const url = buildEndpointUrl(endpointConfig, endpointConfig.endpoints.pipelines.get, {
@@ -120,28 +100,11 @@ export class NodeExecutionService {
120
100
  const raw = await response.json();
121
101
  const result = raw.data ?? raw;
122
102
  const jobs = result.jobs || [];
103
+ const nodeStatuses = result.node_statuses || {};
123
104
  const executionInfoMap = {};
124
- // Initialize all nodes with default values
125
105
  nodeIds.forEach((nodeId) => {
126
- executionInfoMap[nodeId] = {
127
- status: 'idle',
128
- executionCount: 0,
129
- isExecuting: false
130
- };
131
- });
132
- // Update with actual job data
133
- jobs.forEach((job) => {
134
- const nodeId = job.node_id;
135
- if (nodeIds.includes(nodeId)) {
136
- executionInfoMap[nodeId] = {
137
- status: this.mapJobStatusToExecutionStatus(job.status),
138
- executionCount: job.execution_count || 0,
139
- isExecuting: job.status === 'running',
140
- lastExecuted: job.completed || job.started,
141
- lastExecutionDuration: job.execution_time,
142
- lastError: job.error_message
143
- };
144
- // Update cache
106
+ executionInfoMap[nodeId] = this.buildNodeExecutionInfo(nodeId, nodeStatuses[nodeId], jobs);
107
+ if (executionInfoMap[nodeId].status !== 'idle' || executionInfoMap[nodeId].jobs) {
145
108
  this.cache.set(nodeId, executionInfoMap[nodeId]);
146
109
  }
147
110
  });
@@ -164,9 +127,8 @@ export class NodeExecutionService {
164
127
  /**
165
128
  * Get all node execution counts
166
129
  */
167
- async getAllNodeExecutionCounts() {
130
+ async getAllNodeExecutionCounts(endpointConfig) {
168
131
  try {
169
- const endpointConfig = getEndpointConfig();
170
132
  if (!endpointConfig)
171
133
  throw new Error('Endpoint config not available');
172
134
  const url = buildEndpointUrl(endpointConfig, '/node-execution-counts');
@@ -227,6 +189,66 @@ export class NodeExecutionService {
227
189
  });
228
190
  }
229
191
  }
192
+ /**
193
+ * Build execution info for one node from the pipeline payload.
194
+ *
195
+ * The `node_statuses` entry is the backend-resolved summary (latest job's
196
+ * status, timing from the most recent run, `executions` count); the per-job
197
+ * history is attached from the `jobs` array so loop iterations stay
198
+ * inspectable. Falls back to the node's jobs when no entry exists (older
199
+ * backends).
200
+ */
201
+ buildNodeExecutionInfo(nodeId, entry, jobs) {
202
+ const nodeJobs = jobs.filter((job) => job.node_id === nodeId);
203
+ if (!entry && nodeJobs.length === 0) {
204
+ return {
205
+ status: 'idle',
206
+ executionCount: 0,
207
+ isExecuting: false
208
+ };
209
+ }
210
+ // Fallback for payloads without a node_statuses entry: the last job in
211
+ // pipeline order mirrors the backend's latest-wins resolution.
212
+ const lastJob = nodeJobs[nodeJobs.length - 1];
213
+ const status = entry?.status ?? lastJob?.status ?? 'idle';
214
+ const startedCount = nodeJobs.filter((job) => job.started).length;
215
+ const executionInfo = {
216
+ status: this.mapJobStatusToExecutionStatus(status),
217
+ executionCount: entry?.executions ?? startedCount,
218
+ isExecuting: status === 'running' || nodeJobs.some((job) => job.status === 'running'),
219
+ lastExecuted: entry?.last_executed ?? lastJob?.completed ?? lastJob?.started ?? undefined,
220
+ lastExecutionDuration: entry?.execution_time ?? lastJob?.execution_time ?? undefined,
221
+ lastExecutionDurationUs: entry?.execution_time_us ?? lastJob?.execution_time_us ?? undefined,
222
+ lastError: entry?.error ?? lastJob?.error_message ?? undefined
223
+ };
224
+ if (nodeJobs.length > 0) {
225
+ executionInfo.jobs = nodeJobs.map((job) => this.mapJobToNodeJobExecution(job));
226
+ }
227
+ return executionInfo;
228
+ }
229
+ /**
230
+ * Map a pipeline job payload entry to a NodeJobExecution history item.
231
+ */
232
+ mapJobToNodeJobExecution(job) {
233
+ let executionTime = job.execution_time;
234
+ if (executionTime == null && job.started && job.completed) {
235
+ const started = Date.parse(job.started);
236
+ const completed = Date.parse(job.completed);
237
+ if (!Number.isNaN(started) && !Number.isNaN(completed)) {
238
+ executionTime = completed - started;
239
+ }
240
+ }
241
+ return {
242
+ id: job.id,
243
+ label: job.label,
244
+ status: this.mapJobStatusToExecutionStatus(job.status),
245
+ started: job.started,
246
+ completed: job.completed,
247
+ executionTime,
248
+ executionTimeUs: job.execution_time_us ?? (executionTime != null ? executionTime * 1000 : undefined),
249
+ error: job.error_message ?? job.error
250
+ };
251
+ }
230
252
  /**
231
253
  * Map job status to execution status
232
254
  */
@@ -244,6 +266,10 @@ export class NodeExecutionService {
244
266
  return 'cancelled';
245
267
  case 'skipped':
246
268
  return 'skipped';
269
+ case 'paused':
270
+ return 'paused';
271
+ case 'interrupted':
272
+ return 'interrupted';
247
273
  default:
248
274
  return 'idle';
249
275
  }
@@ -7,6 +7,8 @@
7
7
  * @module services/playgroundService
8
8
  */
9
9
  import type { PlaygroundSession, PlaygroundMessage, PlaygroundMessagesApiResponse, PlaygroundSessionStatus } from '../types/playground.js';
10
+ import type { EndpointConfig } from '../config/endpoints.js';
11
+ import type { AuthProvider } from '../types/auth.js';
10
12
  /**
11
13
  * Pagination options for {@link PlaygroundService.getMessages}.
12
14
  * `since`, `before`, and `latest` are mutually exclusive.
@@ -41,7 +43,10 @@ export declare class PlaygroundService {
41
43
  */
42
44
  static getInstance(): PlaygroundService;
43
45
  /**
44
- * Get the endpoint configuration
46
+ * Validate and return the endpoint configuration passed by the caller.
47
+ *
48
+ * Callers thread the config from `getInstance().api.config`; this enforces
49
+ * the legacy "throws if not configured" contract.
45
50
  *
46
51
  * @throws Error if endpoint configuration is not set
47
52
  * @returns The endpoint configuration
@@ -50,6 +55,7 @@ export declare class PlaygroundService {
50
55
  /**
51
56
  * Generic API request helper
52
57
  *
58
+ * @param config - The endpoint configuration
53
59
  * @param url - The URL to fetch
54
60
  * @param options - Fetch options
55
61
  * @returns The parsed JSON response
@@ -62,10 +68,10 @@ export declare class PlaygroundService {
62
68
  * @param options - Optional pagination parameters
63
69
  * @returns Array of playground sessions
64
70
  */
65
- listSessions(workflowId: string, options?: {
71
+ listSessions(endpointConfig: EndpointConfig | null, workflowId: string, options?: {
66
72
  limit?: number;
67
73
  offset?: number;
68
- }): Promise<PlaygroundSession[]>;
74
+ }, authProvider?: AuthProvider): Promise<PlaygroundSession[]>;
69
75
  /**
70
76
  * Create a new playground session
71
77
  *
@@ -74,20 +80,20 @@ export declare class PlaygroundService {
74
80
  * @param metadata - Optional session metadata
75
81
  * @returns The created session
76
82
  */
77
- createSession(workflowId: string, name?: string, metadata?: Record<string, unknown>): Promise<PlaygroundSession>;
83
+ createSession(endpointConfig: EndpointConfig | null, workflowId: string, name?: string, metadata?: Record<string, unknown>, authProvider?: AuthProvider): Promise<PlaygroundSession>;
78
84
  /**
79
85
  * Get a playground session by ID
80
86
  *
81
87
  * @param sessionId - The session UUID
82
88
  * @returns The session details
83
89
  */
84
- getSession(sessionId: string): Promise<PlaygroundSession>;
90
+ getSession(endpointConfig: EndpointConfig | null, sessionId: string, authProvider?: AuthProvider): Promise<PlaygroundSession>;
85
91
  /**
86
92
  * Delete a playground session
87
93
  *
88
94
  * @param sessionId - The session UUID
89
95
  */
90
- deleteSession(sessionId: string): Promise<void>;
96
+ deleteSession(endpointConfig: EndpointConfig | null, sessionId: string, authProvider?: AuthProvider): Promise<void>;
91
97
  /**
92
98
  * Get messages from a playground session.
93
99
  *
@@ -101,7 +107,7 @@ export declare class PlaygroundService {
101
107
  * @param options - Pagination options
102
108
  * @returns Messages and session status
103
109
  */
104
- getMessages(sessionId: string, options?: GetMessagesOptions): Promise<PlaygroundMessagesApiResponse>;
110
+ getMessages(endpointConfig: EndpointConfig | null, sessionId: string, options?: GetMessagesOptions, authProvider?: AuthProvider): Promise<PlaygroundMessagesApiResponse>;
105
111
  /**
106
112
  * Send a message to a playground session
107
113
  *
@@ -110,13 +116,13 @@ export declare class PlaygroundService {
110
116
  * @param inputs - Optional additional inputs for workflow nodes
111
117
  * @returns The created message
112
118
  */
113
- sendMessage(sessionId: string, content: string, inputs?: Record<string, unknown>): Promise<PlaygroundMessage>;
119
+ sendMessage(endpointConfig: EndpointConfig | null, sessionId: string, content: string, inputs?: Record<string, unknown>, authProvider?: AuthProvider): Promise<PlaygroundMessage>;
114
120
  /**
115
121
  * Stop execution in a playground session
116
122
  *
117
123
  * @param sessionId - The session UUID
118
124
  */
119
- stopExecution(sessionId: string): Promise<void>;
125
+ stopExecution(endpointConfig: EndpointConfig | null, sessionId: string, authProvider?: AuthProvider): Promise<void>;
120
126
  /**
121
127
  * Start polling for new messages
122
128
  *
@@ -126,7 +132,7 @@ export declare class PlaygroundService {
126
132
  * @param shouldStopPolling - Optional override for stop conditions (default: defaultShouldStopPolling)
127
133
  * @param initialSequenceNumber - Optional sequence number to seed polling from (avoids re-fetching already loaded messages)
128
134
  */
129
- startPolling(sessionId: string, callback: (response: PlaygroundMessagesApiResponse) => void, interval?: number, shouldStopPolling?: (status: PlaygroundSessionStatus) => boolean, initialSequenceNumber?: number | null): void;
135
+ startPolling(endpointConfig: EndpointConfig | null, sessionId: string, callback: (response: PlaygroundMessagesApiResponse) => void, interval?: number, shouldStopPolling?: (status: PlaygroundSessionStatus) => boolean, initialSequenceNumber?: number | null, authProvider?: AuthProvider): void;
130
136
  /**
131
137
  * Stop polling for messages
132
138
  */
@@ -7,8 +7,8 @@
7
7
  * @module services/playgroundService
8
8
  */
9
9
  import { defaultShouldStopPolling } from '../types/playground.js';
10
- import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
11
- import { getEndpointConfig } from './api.js';
10
+ import { buildEndpointUrl } from '../config/endpoints.js';
11
+ import { authenticatedFetch } from '../utils/fetchWithAuth.js';
12
12
  import { logger } from '../utils/logger.js';
13
13
  /**
14
14
  * Default polling interval in milliseconds
@@ -43,34 +43,33 @@ export class PlaygroundService {
43
43
  return PlaygroundService.instance;
44
44
  }
45
45
  /**
46
- * Get the endpoint configuration
46
+ * Validate and return the endpoint configuration passed by the caller.
47
+ *
48
+ * Callers thread the config from `getInstance().api.config`; this enforces
49
+ * the legacy "throws if not configured" contract.
47
50
  *
48
51
  * @throws Error if endpoint configuration is not set
49
52
  * @returns The endpoint configuration
50
53
  */
51
- getConfig() {
52
- const config = getEndpointConfig();
54
+ getConfig(config) {
53
55
  if (!config) {
54
- throw new Error('Endpoint configuration not set. Call setEndpointConfig() first.');
56
+ throw new Error('Endpoint configuration not set. Configure the instance via fd.api.configure().');
55
57
  }
56
58
  return config;
57
59
  }
58
60
  /**
59
61
  * Generic API request helper
60
62
  *
63
+ * @param config - The endpoint configuration
61
64
  * @param url - The URL to fetch
62
65
  * @param options - Fetch options
63
66
  * @returns The parsed JSON response
64
67
  */
65
- async request(url, options = {}) {
66
- const config = this.getConfig();
67
- const headers = getEndpointHeaders(config, 'playground');
68
- const response = await fetch(url, {
69
- ...options,
70
- headers: {
71
- ...headers,
72
- ...options.headers
73
- }
68
+ async request(config, url, options = {}, authProvider) {
69
+ const response = await authenticatedFetch(url, options, {
70
+ config,
71
+ endpointKey: 'playground',
72
+ authProvider
74
73
  });
75
74
  if (!response.ok) {
76
75
  const errorData = await response.json().catch(() => ({}));
@@ -91,8 +90,8 @@ export class PlaygroundService {
91
90
  * @param options - Optional pagination parameters
92
91
  * @returns Array of playground sessions
93
92
  */
94
- async listSessions(workflowId, options) {
95
- const config = this.getConfig();
93
+ async listSessions(endpointConfig, workflowId, options, authProvider) {
94
+ const config = this.getConfig(endpointConfig);
96
95
  let url = buildEndpointUrl(config, config.endpoints.playground.listSessions, {
97
96
  id: workflowId
98
97
  });
@@ -108,7 +107,7 @@ export class PlaygroundService {
108
107
  if (queryString) {
109
108
  url = `${url}?${queryString}`;
110
109
  }
111
- const response = await this.request(url);
110
+ const response = await this.request(config, url, {}, authProvider);
112
111
  return response.data ?? [];
113
112
  }
114
113
  /**
@@ -119,15 +118,15 @@ export class PlaygroundService {
119
118
  * @param metadata - Optional session metadata
120
119
  * @returns The created session
121
120
  */
122
- async createSession(workflowId, name, metadata) {
123
- const config = this.getConfig();
121
+ async createSession(endpointConfig, workflowId, name, metadata, authProvider) {
122
+ const config = this.getConfig(endpointConfig);
124
123
  const url = buildEndpointUrl(config, config.endpoints.playground.createSession, {
125
124
  id: workflowId
126
125
  });
127
- const response = await this.request(url, {
126
+ const response = await this.request(config, url, {
128
127
  method: 'POST',
129
128
  body: JSON.stringify({ name, metadata })
130
- });
129
+ }, authProvider);
131
130
  if (!response.data) {
132
131
  throw new Error('Failed to create session: No data returned');
133
132
  }
@@ -139,12 +138,12 @@ export class PlaygroundService {
139
138
  * @param sessionId - The session UUID
140
139
  * @returns The session details
141
140
  */
142
- async getSession(sessionId) {
143
- const config = this.getConfig();
141
+ async getSession(endpointConfig, sessionId, authProvider) {
142
+ const config = this.getConfig(endpointConfig);
144
143
  const url = buildEndpointUrl(config, config.endpoints.playground.getSession, {
145
144
  sessionId
146
145
  });
147
- const response = await this.request(url);
146
+ const response = await this.request(config, url, {}, authProvider);
148
147
  if (!response.data) {
149
148
  throw new Error('Session not found');
150
149
  }
@@ -155,14 +154,14 @@ export class PlaygroundService {
155
154
  *
156
155
  * @param sessionId - The session UUID
157
156
  */
158
- async deleteSession(sessionId) {
159
- const config = this.getConfig();
157
+ async deleteSession(endpointConfig, sessionId, authProvider) {
158
+ const config = this.getConfig(endpointConfig);
160
159
  const url = buildEndpointUrl(config, config.endpoints.playground.deleteSession, {
161
160
  sessionId
162
161
  });
163
- await this.request(url, {
162
+ await this.request(config, url, {
164
163
  method: 'DELETE'
165
- });
164
+ }, authProvider);
166
165
  }
167
166
  // =========================================================================
168
167
  // Message Handling
@@ -180,8 +179,8 @@ export class PlaygroundService {
180
179
  * @param options - Pagination options
181
180
  * @returns Messages and session status
182
181
  */
183
- async getMessages(sessionId, options = {}) {
184
- const config = this.getConfig();
182
+ async getMessages(endpointConfig, sessionId, options = {}, authProvider) {
183
+ const config = this.getConfig(endpointConfig);
185
184
  let url = buildEndpointUrl(config, config.endpoints.playground.getMessages, {
186
185
  sessionId
187
186
  });
@@ -202,7 +201,7 @@ export class PlaygroundService {
202
201
  if (queryString) {
203
202
  url = `${url}?${queryString}`;
204
203
  }
205
- return this.request(url);
204
+ return this.request(config, url, {}, authProvider);
206
205
  }
207
206
  /**
208
207
  * Send a message to a playground session
@@ -212,8 +211,8 @@ export class PlaygroundService {
212
211
  * @param inputs - Optional additional inputs for workflow nodes
213
212
  * @returns The created message
214
213
  */
215
- async sendMessage(sessionId, content, inputs) {
216
- const config = this.getConfig();
214
+ async sendMessage(endpointConfig, sessionId, content, inputs, authProvider) {
215
+ const config = this.getConfig(endpointConfig);
217
216
  const url = buildEndpointUrl(config, config.endpoints.playground.sendMessage, {
218
217
  sessionId
219
218
  });
@@ -221,10 +220,10 @@ export class PlaygroundService {
221
220
  if (inputs) {
222
221
  requestBody.inputs = inputs;
223
222
  }
224
- const response = await this.request(url, {
223
+ const response = await this.request(config, url, {
225
224
  method: 'POST',
226
225
  body: JSON.stringify(requestBody)
227
- });
226
+ }, authProvider);
228
227
  if (!response.data) {
229
228
  throw new Error('Failed to send message: No data returned');
230
229
  }
@@ -235,14 +234,14 @@ export class PlaygroundService {
235
234
  *
236
235
  * @param sessionId - The session UUID
237
236
  */
238
- async stopExecution(sessionId) {
239
- const config = this.getConfig();
237
+ async stopExecution(endpointConfig, sessionId, authProvider) {
238
+ const config = this.getConfig(endpointConfig);
240
239
  const url = buildEndpointUrl(config, config.endpoints.playground.stopExecution, {
241
240
  sessionId
242
241
  });
243
- await this.request(url, {
242
+ await this.request(config, url, {
244
243
  method: 'POST'
245
- });
244
+ }, authProvider);
246
245
  }
247
246
  // =========================================================================
248
247
  // Polling
@@ -256,7 +255,7 @@ export class PlaygroundService {
256
255
  * @param shouldStopPolling - Optional override for stop conditions (default: defaultShouldStopPolling)
257
256
  * @param initialSequenceNumber - Optional sequence number to seed polling from (avoids re-fetching already loaded messages)
258
257
  */
259
- startPolling(sessionId, callback, interval = DEFAULT_POLLING_INTERVAL, shouldStopPolling, initialSequenceNumber) {
258
+ startPolling(endpointConfig, sessionId, callback, interval = DEFAULT_POLLING_INTERVAL, shouldStopPolling, initialSequenceNumber, authProvider) {
260
259
  // Stop any existing polling
261
260
  this.stopPolling();
262
261
  this.pollingSessionId = sessionId;
@@ -268,9 +267,9 @@ export class PlaygroundService {
268
267
  return;
269
268
  }
270
269
  try {
271
- const response = await this.getMessages(sessionId, {
270
+ const response = await this.getMessages(endpointConfig, sessionId, {
272
271
  since: this.lastSequenceNumber ?? undefined
273
- });
272
+ }, authProvider);
274
273
  // Update last sequence number cursor
275
274
  if (response.data && response.data.length > 0) {
276
275
  const lastMessage = response.data[response.data.length - 1];
@@ -2,7 +2,8 @@
2
2
  * Port Configuration API Service
3
3
  * Handles fetching port configuration from the backend
4
4
  */
5
- import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
5
+ import { buildEndpointUrl } from '../config/endpoints.js';
6
+ import { authenticatedFetch } from '../utils/fetchWithAuth.js';
6
7
  import { DEFAULT_PORT_CONFIG } from '../config/defaultPortConfig.js';
7
8
  import { logger } from '../utils/logger.js';
8
9
  /**
@@ -11,11 +12,7 @@ import { logger } from '../utils/logger.js';
11
12
  export async function fetchPortConfig(endpointConfig, authProvider) {
12
13
  try {
13
14
  const url = buildEndpointUrl(endpointConfig, endpointConfig.endpoints.portConfig);
14
- const configHeaders = getEndpointHeaders(endpointConfig, 'portConfig');
15
- const authHeaders = authProvider ? await authProvider.getAuthHeaders() : {};
16
- const response = await fetch(url, {
17
- headers: { ...configHeaders, ...authHeaders }
18
- });
15
+ const response = await authenticatedFetch(url, {}, { config: endpointConfig, endpointKey: 'portConfig', authProvider });
19
16
  if (!response.ok) {
20
17
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
21
18
  }
@@ -9,12 +9,15 @@
9
9
  */
10
10
  import type { FlowDropSettings, PartialSettings } from '../types/settings.js';
11
11
  import type { EndpointConfig } from '../config/endpoints.js';
12
+ import type { AuthProvider } from '../types/auth.js';
12
13
  /**
13
- * Set the endpoint configuration for settings API calls
14
+ * Set the endpoint configuration (and optional auth provider) for settings API
15
+ * calls.
14
16
  *
15
17
  * @param config - Endpoint configuration
18
+ * @param provider - Optional auth provider supplying request auth headers
16
19
  */
17
- export declare function setSettingsEndpointConfig(config: EndpointConfig): void;
20
+ export declare function setSettingsEndpointConfig(config: EndpointConfig, provider?: AuthProvider): void;
18
21
  /**
19
22
  * Get the current endpoint configuration
20
23
  *
@@ -62,8 +65,9 @@ export declare class SettingsService {
62
65
  * Create a new settings service instance
63
66
  *
64
67
  * @param config - Endpoint configuration
68
+ * @param authProvider - Optional auth provider applied to settings requests
65
69
  */
66
- constructor(config: EndpointConfig);
70
+ constructor(config: EndpointConfig, authProvider?: AuthProvider);
67
71
  /**
68
72
  * Get user preferences from the backend
69
73
  *
@@ -87,6 +91,7 @@ export declare class SettingsService {
87
91
  * Create a settings service instance
88
92
  *
89
93
  * @param config - Endpoint configuration
94
+ * @param authProvider - Optional auth provider applied to settings requests
90
95
  * @returns SettingsService instance
91
96
  */
92
- export declare function createSettingsService(config: EndpointConfig): SettingsService;
97
+ export declare function createSettingsService(config: EndpointConfig, authProvider?: AuthProvider): SettingsService;
@@ -7,7 +7,8 @@
7
7
  *
8
8
  * @module services/settingsService
9
9
  */
10
- import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
10
+ import { buildEndpointUrl } from '../config/endpoints.js';
11
+ import { authenticatedFetch } from '../utils/fetchWithAuth.js';
11
12
  // =========================================================================
12
13
  // Configuration
13
14
  // =========================================================================
@@ -16,12 +17,20 @@ import { buildEndpointUrl, getEndpointHeaders } from '../config/endpoints.js';
16
17
  */
17
18
  let endpointConfig = null;
18
19
  /**
19
- * Set the endpoint configuration for settings API calls
20
+ * Auth provider reference, applied to every settings request so the backend
21
+ * sync path authenticates consistently with the rest of the library.
22
+ */
23
+ let authProvider;
24
+ /**
25
+ * Set the endpoint configuration (and optional auth provider) for settings API
26
+ * calls.
20
27
  *
21
28
  * @param config - Endpoint configuration
29
+ * @param provider - Optional auth provider supplying request auth headers
22
30
  */
23
- export function setSettingsEndpointConfig(config) {
31
+ export function setSettingsEndpointConfig(config, provider) {
24
32
  endpointConfig = config;
33
+ authProvider = provider;
25
34
  }
26
35
  /**
27
36
  * Get the current endpoint configuration
@@ -47,10 +56,10 @@ async function settingsRequest(endpointKey, endpointPath, options = {}) {
47
56
  throw new Error('Endpoint configuration not set. Call setSettingsEndpointConfig() first.');
48
57
  }
49
58
  const url = buildEndpointUrl(endpointConfig, endpointPath);
50
- const headers = getEndpointHeaders(endpointConfig, endpointKey);
51
- const response = await fetch(url, {
52
- headers,
53
- ...options
59
+ const response = await authenticatedFetch(url, options, {
60
+ config: endpointConfig,
61
+ endpointKey,
62
+ authProvider
54
63
  });
55
64
  // Check if response is JSON
56
65
  const contentType = response.headers.get('content-type');
@@ -151,11 +160,12 @@ export class SettingsService {
151
160
  * Create a new settings service instance
152
161
  *
153
162
  * @param config - Endpoint configuration
163
+ * @param authProvider - Optional auth provider applied to settings requests
154
164
  */
155
- constructor(config) {
165
+ constructor(config, authProvider) {
156
166
  this.config = config;
157
- // Also set the module-level config
158
- setSettingsEndpointConfig(config);
167
+ // Also set the module-level config + auth provider
168
+ setSettingsEndpointConfig(config, authProvider);
159
169
  }
160
170
  /**
161
171
  * Get user preferences from the backend
@@ -189,8 +199,9 @@ export class SettingsService {
189
199
  * Create a settings service instance
190
200
  *
191
201
  * @param config - Endpoint configuration
202
+ * @param authProvider - Optional auth provider applied to settings requests
192
203
  * @returns SettingsService instance
193
204
  */
194
- export function createSettingsService(config) {
195
- return new SettingsService(config);
205
+ export function createSettingsService(config, authProvider) {
206
+ return new SettingsService(config, authProvider);
196
207
  }
@@ -6,6 +6,7 @@
6
6
  * @module services/variableService
7
7
  */
8
8
  import type { WorkflowNode, WorkflowEdge, VariableSchema, TemplateVariable, TemplateVariablesConfig, AuthProvider } from '../types/index.js';
9
+ import type { EndpointConfig } from '../config/endpoints.js';
9
10
  /**
10
11
  * Options for deriving available variables.
11
12
  */
@@ -138,4 +139,4 @@ export declare function mergeVariableSchemas(primary: VariableSchema, secondary:
138
139
  * const schema = await getVariableSchema(node, nodes, edges, config, workflowId, authProvider);
139
140
  * ```
140
141
  */
141
- export declare function getVariableSchema(node: WorkflowNode, nodes: WorkflowNode[], edges: WorkflowEdge[], config: TemplateVariablesConfig, workflowId?: string, authProvider?: AuthProvider): Promise<VariableSchema>;
142
+ export declare function getVariableSchema(endpointConfig: EndpointConfig | null, node: WorkflowNode, nodes: WorkflowNode[], edges: WorkflowEdge[], config: TemplateVariablesConfig, workflowId?: string, authProvider?: AuthProvider): Promise<VariableSchema>;
@@ -405,14 +405,14 @@ export function mergeVariableSchemas(primary, secondary) {
405
405
  * const schema = await getVariableSchema(node, nodes, edges, config, workflowId, authProvider);
406
406
  * ```
407
407
  */
408
- export async function getVariableSchema(node, nodes, edges, config, workflowId, authProvider) {
408
+ export async function getVariableSchema(endpointConfig, node, nodes, edges, config, workflowId, authProvider) {
409
409
  let resultSchema = { variables: {} };
410
410
  // Try API mode first (if configured)
411
411
  if (config.api) {
412
412
  try {
413
413
  // Import API variable service dynamically to avoid circular dependencies
414
414
  const { fetchVariableSchema } = await import('./apiVariableService.js');
415
- const apiResult = await fetchVariableSchema(workflowId, node.id, config.api, authProvider);
415
+ const apiResult = await fetchVariableSchema(endpointConfig, workflowId, node.id, config.api, authProvider);
416
416
  if (apiResult.success && apiResult.schema) {
417
417
  resultSchema = apiResult.schema;
418
418
  // Merge with static schema if configured