windmill-components 1.687.0 → 1.695.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/package/components/ArgInput.svelte +2 -0
  2. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  3. package/package/components/CompareWorkspaces.svelte +206 -157
  4. package/package/components/DatatableSchemaDiff.svelte +2 -2
  5. package/package/components/Dev.svelte +401 -85
  6. package/package/components/EditableSchemaForm.svelte +4 -0
  7. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  8. package/package/components/FlowPreviewContent.svelte +32 -30
  9. package/package/components/FlowRestartButton.svelte +143 -61
  10. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  11. package/package/components/FlowStatusViewer.svelte +15 -1
  12. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  13. package/package/components/FlowStatusViewerInner.svelte +1 -2
  14. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  15. package/package/components/ForkConflictModal.svelte +57 -0
  16. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  17. package/package/components/GitRepoViewer.svelte +251 -97
  18. package/package/components/InputTransformSchemaForm.svelte +1 -1
  19. package/package/components/InstanceSettings.svelte +36 -16
  20. package/package/components/Login.svelte +113 -28
  21. package/package/components/Login.svelte.d.ts +1 -0
  22. package/package/components/Path.svelte +7 -1
  23. package/package/components/Path.svelte.d.ts +1 -1
  24. package/package/components/RunsPage.svelte +2 -1
  25. package/package/components/S3FilePickerInner.svelte +89 -89
  26. package/package/components/ScriptEditor.svelte +18 -5
  27. package/package/components/ShareModal.svelte.d.ts +1 -1
  28. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  29. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  30. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  31. package/package/components/apps/editor/appPolicy.js +2 -1
  32. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  33. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  34. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  35. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  36. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  37. package/package/components/apps/inputType.d.ts +1 -0
  38. package/package/components/apps/sharedTypes.d.ts +1 -0
  39. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  40. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  41. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  42. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  43. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  44. package/package/components/copilot/chat/AIChatManager.svelte.js +48 -46
  45. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  46. package/package/components/copilot/chat/app/core.d.ts +12 -20
  47. package/package/components/copilot/chat/app/core.js +103 -160
  48. package/package/components/copilot/chat/app/core.test.js +234 -9
  49. package/package/components/copilot/chat/context.js +44 -0
  50. package/package/components/copilot/chat/flow/FlowAIChat.svelte +5 -3
  51. package/package/components/copilot/chat/flow/core.d.ts +2 -1
  52. package/package/components/copilot/chat/flow/core.js +48 -21
  53. package/package/components/copilot/chat/flow/helperUtils.d.ts +5 -2
  54. package/package/components/copilot/chat/flow/helperUtils.js +33 -1
  55. package/package/components/copilot/chat/flow/helperUtils.test.js +116 -1
  56. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  57. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  58. package/package/components/copilot/chat/script/core.js +3 -0
  59. package/package/components/copilot/chat/shared.d.ts +6 -0
  60. package/package/components/copilot/chat/shared.js +22 -1
  61. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  62. package/package/components/copilot/chat/shared.test.js +412 -0
  63. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  64. package/package/components/copilot/chat/workspaceTools.js +239 -0
  65. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  66. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  67. package/package/components/copilot/lib.js +3 -1
  68. package/package/components/copilot/lib.test.d.ts +1 -0
  69. package/package/components/copilot/lib.test.js +19 -0
  70. package/package/components/copilot/modelConfig.d.ts +3 -0
  71. package/package/components/copilot/modelConfig.js +10 -0
  72. package/package/components/flows/FlowProgressBar.svelte +5 -2
  73. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  74. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  75. package/package/components/flows/flowStateUtils.svelte.js +5 -1
  76. package/package/components/flows/map/FlowModuleSchemaMap.svelte +3 -2
  77. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -0
  78. package/package/components/git_sync/GitSyncContext.svelte.js +0 -2
  79. package/package/components/graph/FlowGraphV2.svelte +7 -3
  80. package/package/components/graph/FlowGraphV2.svelte.d.ts +1 -0
  81. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -0
  82. package/package/components/home/deploy_ui.js +1 -1
  83. package/package/components/icons/AzureIcon.svelte +12 -25
  84. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  85. package/package/components/instanceSettings.js +24 -0
  86. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  87. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  88. package/package/components/offboarding-utils.js +2 -0
  89. package/package/components/progressBar/ProgressBar.svelte +9 -5
  90. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  91. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  92. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  93. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  94. package/package/components/raw_apps/RawAppEditor.svelte +159 -102
  95. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  96. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  97. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  98. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  99. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  100. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  101. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  102. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  103. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  104. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  105. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  106. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  107. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  108. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  109. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  110. package/package/components/resources/resourceTypesFilter.js +21 -0
  111. package/package/components/restartFromStepPath.d.ts +39 -0
  112. package/package/components/restartFromStepPath.js +89 -0
  113. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  114. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  115. package/package/components/runs/JobDetailHeader.svelte +24 -3
  116. package/package/components/runs/runsFilter.d.ts +1 -1
  117. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  118. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  119. package/package/components/search/GlobalSearchModal.svelte +8 -1
  120. package/package/components/select/Select.svelte +1 -1
  121. package/package/components/settings/CreateToken.svelte +48 -77
  122. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  123. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  124. package/package/components/settings/ScopesPicker.svelte +43 -0
  125. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  126. package/package/components/settings/TokensTable.svelte +51 -15
  127. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  128. package/package/components/sidebar/SidebarContent.svelte +11 -1
  129. package/package/components/triggers/AddTriggersButton.svelte +6 -0
  130. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  131. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  132. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  133. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  134. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  135. package/package/components/triggers/TriggersEditor.svelte +5 -1
  136. package/package/components/triggers/TriggersWrapper.svelte +10 -0
  137. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  138. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  139. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  140. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  141. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  142. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  143. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  144. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  145. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  146. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  147. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  148. package/package/components/triggers/azure/utils.js +56 -0
  149. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +2 -0
  150. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +9 -3
  151. package/package/components/triggers/http/RouteEditorInner.svelte +2 -0
  152. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +9 -3
  153. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +9 -3
  154. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +9 -3
  155. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +9 -3
  156. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +9 -3
  157. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +9 -3
  158. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  159. package/package/components/triggers/triggers.svelte.js +23 -1
  160. package/package/components/triggers/utils.js +20 -0
  161. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +9 -3
  162. package/package/components/triggers.d.ts +1 -1
  163. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  164. package/package/components/useNestedRestartState.svelte.js +320 -0
  165. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  166. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  167. package/package/gen/core/OpenAPI.js +1 -1
  168. package/package/gen/schemas.gen.d.ts +294 -24
  169. package/package/gen/schemas.gen.js +297 -25
  170. package/package/gen/services.gen.d.ts +247 -4
  171. package/package/gen/services.gen.js +498 -7
  172. package/package/gen/types.gen.d.ts +990 -37
  173. package/package/hubPaths.json +2 -5
  174. package/package/infer.d.ts +1 -1
  175. package/package/infer.js +37 -51
  176. package/package/mcpEndpointTools.js +60 -4
  177. package/package/script_helpers.js +17 -0
  178. package/package/stores.d.ts +7 -0
  179. package/package/stores.js +6 -1
  180. package/package/system_prompts/index.d.ts +1 -0
  181. package/package/system_prompts/index.js +8 -0
  182. package/package/system_prompts/prompts.d.ts +16 -13
  183. package/package/system_prompts/prompts.js +653 -43
  184. package/package/templates/ci_test_bun.ts.template +8 -0
  185. package/package/templates/ci_test_python.py.template +8 -0
  186. package/package/utils/forkConflict.d.ts +26 -0
  187. package/package/utils/forkConflict.js +56 -0
  188. package/package/utils_deployable.d.ts +164 -121
  189. package/package/utils_deployable.js +61 -11
  190. package/package/utils_workspace_deploy.js +3 -1
  191. package/package.json +29 -5
  192. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  193. package/dist/sharedUtils/base.d.ts +0 -1
  194. package/dist/sharedUtils/cloud.d.ts +0 -1
  195. package/dist/sharedUtils/common.d.ts +0 -111
  196. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  197. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  198. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  199. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  200. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  201. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  202. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  203. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  204. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  205. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  206. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  207. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  208. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  209. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  210. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  211. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  212. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  213. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  214. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  215. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  216. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  217. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  218. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  219. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  220. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  221. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  222. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  223. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  224. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  225. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  226. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  227. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  228. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  229. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  230. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  231. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  232. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  233. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  234. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  235. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  236. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  237. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  238. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  239. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  240. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  241. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  242. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  243. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  244. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  245. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  246. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  247. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  248. package/dist/sharedUtils/gen/index.d.ts +0 -6
  249. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  250. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  251. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  252. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  253. package/dist/sharedUtils/hub.d.ts +0 -49
  254. package/dist/sharedUtils/jsr.json +0 -6
  255. package/dist/sharedUtils/lib.d.ts +0 -5
  256. package/dist/sharedUtils/lib.es.js +0 -1588
  257. package/dist/sharedUtils/package.json +0 -12
  258. package/dist/sharedUtils/schema.d.ts +0 -3
  259. package/dist/sharedUtils/stores.d.ts +0 -97
  260. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  261. package/dist/sharedUtils/toast.d.ts +0 -8
  262. package/dist/sharedUtils/utils.d.ts +0 -265
  263. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  264. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
@@ -87,6 +87,10 @@ let websocketAlive = $state({
87
87
  shellcheck: false
88
88
  });
89
89
  let selected = $state(untrack(() => preprocessorModule) ? 'test' : 'inputs');
90
+ let canShowChatTab = $derived(!preprocessorModule &&
91
+ Boolean(flowStore.val.value?.chat_input_enabled) &&
92
+ flowModule.value.type === 'aiagent');
93
+ let visibleSelected = $derived(selected === 'chat' && !canShowChatTab ? 'inputs' : selected);
90
94
  let advancedSelected = $state('retries');
91
95
  let advancedRuntimeSelected = $state('concurrency');
92
96
  let s3Kind = $state('s3_client');
@@ -162,6 +166,17 @@ function selectAdvanced(subtab) {
162
166
  selected = 'advanced';
163
167
  advancedSelected = subtab;
164
168
  }
169
+ function setOmitOutputFromConversation(omit) {
170
+ if (flowModule.value.type !== 'aiagent') {
171
+ return;
172
+ }
173
+ if (omit) {
174
+ flowModule.value.omit_output_from_conversation = true;
175
+ }
176
+ else {
177
+ delete flowModule.value.omit_output_from_conversation;
178
+ }
179
+ }
165
180
  let forceReload = $state(0);
166
181
  let editorPanelSize = $state(untrack(() => noEditor) ? 0 : flowModule.value.type == 'script' ? 30 : 50);
167
182
  let editorSettingsPanelSize = $state(100 - untrack(() => editorPanelSize));
@@ -634,7 +649,7 @@ onDestroyHook(() => {
634
649
  const [module, state] = await createScriptFromInlineScript(
635
650
  flowModule,
636
651
  selectedId,
637
- flowStateStore.val[flowModule.id].schema,
652
+ flowStateStore.val[flowModule.id]?.schema,
638
653
  $pathStore
639
654
  )
640
655
  if (flowModule.value.type == 'rawscript') {
@@ -673,109 +688,44 @@ onDestroyHook(() => {
673
688
  {/if}
674
689
 
675
690
  <div class="min-h-0 flex-grow" id="flow-editor-editor">
676
- <Splitpanes horizontal>
677
- {#if flowModule.value.type !== 'aiagent'}
678
- <Pane bind:size={editorPanelSize} minSize={10} class="relative">
679
- {#if flowModule.value.type === 'rawscript'}
680
- {#if !noEditor}
681
- {#key flowModule.id}
682
- <div class="absolute top-2 right-4 z-10 flex flex-row gap-2">
683
- {#if assets?.length}
684
- <AssetsDropdownButton {assets} />
685
- {/if}
686
- {#if isDebuggableScript && customUi?.editorBar?.debug != false}
687
- <Button
688
- variant={debugMode ? 'accent' : 'default'}
689
- size="xs"
690
- onclick={toggleDebugMode}
691
- startIcon={{ icon: Bug }}
692
- btnClasses={debugMode
693
- ? ''
694
- : 'bg-surface hover:bg-surface-hover border border-tertiary/30'}
695
- title="Toggle Debug Mode"
696
- >
697
- {debugMode ? 'Exit Debug' : 'Debug'}
698
- </Button>
699
- {/if}
700
- {#if showDebugPanel && !showDebugConsole}
701
- <Button
702
- variant="default"
703
- size="xs"
704
- onclick={() => (showDebugConsole = true)}
705
- startIcon={{ icon: Terminal }}
706
- btnClasses="bg-surface hover:bg-surface-hover border border-tertiary/30"
707
- title="Show Debug Console"
708
- >
709
- Console
710
- </Button>
711
- {/if}
712
- </div>
713
- {#if debugConsoleVisible}
714
- <Splitpanes horizontal class="h-full">
715
- <Pane bind:size={editorPaneSize} minSize={20}>
716
- <div id="flow-editor-code-section" class="h-full relative">
717
- <Editor
718
- loadAsync
719
- folding
720
- path={$pathStore + '/' + flowModule.id}
721
- bind:websocketAlive
722
- bind:this={editor}
723
- class="h-full relative"
724
- code={flowModule.value.content}
725
- scriptLang={flowModule?.value?.language}
726
- automaticLayout={true}
727
- cmdEnterAction={async () => {
728
- selected = 'test'
729
- if (selectedId == flowModule.id) {
730
- if (flowModule.value.type === 'rawscript' && editor) {
731
- flowModule.value.content = editor.getCode()
732
- }
733
- await reload(flowModule)
734
- modulePreview?.runTestWithStepArgs()
735
- }
736
- }}
737
- on:change={async (event) => {
738
- const content = event.detail
739
- if (flowModule.value.type === 'rawscript') {
740
- if (flowModule.value.content !== content) {
741
- flowModule.value.content = content
742
- }
743
- await reload(flowModule)
744
- if (debugMode && breakpointDecorations.length > 0) {
745
- refreshBreakpointPositions()
746
- }
747
- }
748
- }}
749
- formatAction={() => {
750
- reload(flowModule)
751
- saveDraft()
752
- }}
753
- fixedOverflowWidgets={true}
754
- args={Object.entries(flowModule.value.input_transforms).reduce(
755
- (acc, [key, obj]) => {
756
- acc[key] = obj.type === 'static' ? obj.value : undefined
757
- return acc
758
- },
759
- {}
760
- )}
761
- key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`}
762
- moduleId={flowModule.id}
763
- preparedAssetsSqlQueries={preparedSqlQueries.current}
764
- customTag={flowModule.value.tag}
765
- />
766
- </div>
767
- </Pane>
768
- <Pane bind:size={consolePaneSize} minSize={10}>
769
- <DebugConsole
770
- client={dapClient}
771
- currentFrameId={currentDebugFrameId}
772
- onClose={() => (showDebugConsole = false)}
773
- workspace={$workspaceStore}
774
- jobId={debugSessionJobId ?? undefined}
775
- />
776
- </Pane>
777
- </Splitpanes>
778
- {:else}
691
+ {#snippet topPaneContent()}
692
+ {#if flowModule.value.type === 'rawscript'}
693
+ {#if !noEditor}
694
+ {#key flowModule.id}
695
+ <div class="absolute top-2 right-4 z-10 flex flex-row gap-2">
696
+ {#if assets?.length}
697
+ <AssetsDropdownButton {assets} />
698
+ {/if}
699
+ {#if isDebuggableScript && customUi?.editorBar?.debug != false}
700
+ <Button
701
+ variant={debugMode ? 'accent' : 'default'}
702
+ size="xs"
703
+ onclick={toggleDebugMode}
704
+ startIcon={{ icon: Bug }}
705
+ btnClasses={debugMode
706
+ ? ''
707
+ : 'bg-surface hover:bg-surface-hover border border-tertiary/30'}
708
+ title="Toggle Debug Mode"
709
+ >
710
+ {debugMode ? 'Exit Debug' : 'Debug'}
711
+ </Button>
712
+ {/if}
713
+ {#if showDebugPanel && !showDebugConsole}
714
+ <Button
715
+ variant="default"
716
+ size="xs"
717
+ onclick={() => (showDebugConsole = true)}
718
+ startIcon={{ icon: Terminal }}
719
+ btnClasses="bg-surface hover:bg-surface-hover border border-tertiary/30"
720
+ title="Show Debug Console"
721
+ >
722
+ Console
723
+ </Button>
724
+ {/if}
725
+ </div>
726
+ {#if debugConsoleVisible}
727
+ <Splitpanes horizontal class="h-full">
728
+ <Pane bind:size={editorPaneSize} minSize={20}>
779
729
  <div id="flow-editor-code-section" class="h-full relative">
780
730
  <Editor
781
731
  loadAsync
@@ -827,531 +777,618 @@ onDestroyHook(() => {
827
777
  customTag={flowModule.value.tag}
828
778
  />
829
779
  </div>
830
- {/if}
831
- <DiffEditor
832
- open={false}
833
- bind:this={diffEditor}
834
- modifiedModel={editor?.getModel() as meditor.ITextModel}
835
- automaticLayout
836
- fixedOverflowWidgets
837
- defaultLang={scriptLangToEditorLang(flowModule.value.language)}
838
- className="h-full"
839
- buttons={diffMode ? diffButtons : []}
840
- />
841
- {/key}
842
- {/if}
843
- {:else if flowModule.value.type === 'script'}
844
- {#if !noEditor && (customUi?.hubCode != false || !flowModule?.value?.path?.startsWith('hub/'))}
845
- <div class="border-t">
846
- {#key forceReload}
847
- <FlowModuleScript
848
- bind:tag={workspaceScriptTag}
849
- bind:language={workspaceScriptLang}
850
- showAllCode={false}
851
- path={flowModule.value.path}
852
- hash={flowModule.value.hash}
780
+ </Pane>
781
+ <Pane bind:size={consolePaneSize} minSize={10}>
782
+ <DebugConsole
783
+ client={dapClient}
784
+ currentFrameId={currentDebugFrameId}
785
+ onClose={() => (showDebugConsole = false)}
786
+ workspace={$workspaceStore}
787
+ jobId={debugSessionJobId ?? undefined}
853
788
  />
854
- {/key}
789
+ </Pane>
790
+ </Splitpanes>
791
+ {:else}
792
+ <div id="flow-editor-code-section" class="h-full relative">
793
+ <Editor
794
+ loadAsync
795
+ folding
796
+ path={$pathStore + '/' + flowModule.id}
797
+ bind:websocketAlive
798
+ bind:this={editor}
799
+ class="h-full relative"
800
+ code={flowModule.value.content}
801
+ scriptLang={flowModule?.value?.language}
802
+ automaticLayout={true}
803
+ cmdEnterAction={async () => {
804
+ selected = 'test'
805
+ if (selectedId == flowModule.id) {
806
+ if (flowModule.value.type === 'rawscript' && editor) {
807
+ flowModule.value.content = editor.getCode()
808
+ }
809
+ await reload(flowModule)
810
+ modulePreview?.runTestWithStepArgs()
811
+ }
812
+ }}
813
+ on:change={async (event) => {
814
+ const content = event.detail
815
+ if (flowModule.value.type === 'rawscript') {
816
+ if (flowModule.value.content !== content) {
817
+ flowModule.value.content = content
818
+ }
819
+ await reload(flowModule)
820
+ if (debugMode && breakpointDecorations.length > 0) {
821
+ refreshBreakpointPositions()
822
+ }
823
+ }
824
+ }}
825
+ formatAction={() => {
826
+ reload(flowModule)
827
+ saveDraft()
828
+ }}
829
+ fixedOverflowWidgets={true}
830
+ args={Object.entries(flowModule.value.input_transforms).reduce(
831
+ (acc, [key, obj]) => {
832
+ acc[key] = obj.type === 'static' ? obj.value : undefined
833
+ return acc
834
+ },
835
+ {}
836
+ )}
837
+ key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`}
838
+ moduleId={flowModule.id}
839
+ preparedAssetsSqlQueries={preparedSqlQueries.current}
840
+ customTag={flowModule.value.tag}
841
+ />
855
842
  </div>
856
843
  {/if}
857
- {:else if flowModule.value.type === 'flow'}
844
+ <DiffEditor
845
+ open={false}
846
+ bind:this={diffEditor}
847
+ modifiedModel={editor?.getModel() as meditor.ITextModel}
848
+ automaticLayout
849
+ fixedOverflowWidgets
850
+ defaultLang={scriptLangToEditorLang(flowModule.value.language)}
851
+ className="h-full"
852
+ buttons={diffMode ? diffButtons : []}
853
+ />
854
+ {/key}
855
+ {/if}
856
+ {:else if flowModule.value.type === 'script'}
857
+ {#if !noEditor && (customUi?.hubCode != false || !flowModule?.value?.path?.startsWith('hub/'))}
858
+ <div class="border-t">
858
859
  {#key forceReload}
859
- <FlowPathViewer path={flowModule.value.path} />
860
+ <FlowModuleScript
861
+ bind:tag={workspaceScriptTag}
862
+ bind:language={workspaceScriptLang}
863
+ showAllCode={false}
864
+ path={flowModule.value.path}
865
+ hash={flowModule.value.hash}
866
+ />
860
867
  {/key}
861
- {/if}
862
- </Pane>
868
+ </div>
869
+ {/if}
870
+ {:else if flowModule.value.type === 'flow'}
871
+ {#key forceReload}
872
+ <FlowPathViewer path={flowModule.value.path} />
873
+ {/key}
863
874
  {/if}
864
- <Pane
865
- bind:size={
866
- () => {
867
- if (flowModule.value.type === 'aiagent') {
868
- return 100
869
- }
870
- return editorSettingsPanelSize
871
- },
872
- (v) => {
873
- if (flowModule.value.type !== 'aiagent') {
874
- editorSettingsPanelSize = v
875
- }
876
- }
877
- }
878
- minSize={20}
879
- >
880
- <Splitpanes>
881
- <Pane minSize={36} bind:size={leftPanelSize}>
882
- <div class="flex flex-col relative h-[99.99%]">
883
- <Tabs bind:selected wrapperClass="shrink-0">
884
- {#if !preprocessorModule}
885
- <Tab value="inputs" label="Step Input" />
886
- {/if}
887
- <Tab value="test" label="Test this step" />
888
- {#if !preprocessorModule && !isAgentTool}
889
- <Tab value="advanced" label="Advanced" />
890
- {/if}
891
- </Tabs>
892
- {#if selected === 'inputs' && (flowModule.value.type == 'rawscript' || flowModule.value.type == 'script' || flowModule.value.type == 'flow' || flowModule.value.type == 'aiagent')}
893
- <div class="flex-1 overflow-auto" id="flow-editor-step-input">
894
- <PropPickerWrapper
875
+ {/snippet}
876
+
877
+ {#snippet bottomPaneContent()}
878
+ <Splitpanes>
879
+ <Pane minSize={36} bind:size={leftPanelSize}>
880
+ <div class="flex flex-col relative h-[99.99%]">
881
+ <Tabs
882
+ selected={visibleSelected}
883
+ on:selected={(event) => {
884
+ selected = event.detail
885
+ }}
886
+ wrapperClass="shrink-0"
887
+ >
888
+ {#if !preprocessorModule}
889
+ <Tab value="inputs" label="Step Input" />
890
+ {/if}
891
+ <Tab value="test" label="Test this step" />
892
+ {#if canShowChatTab && flowModule.value.type === 'aiagent'}
893
+ <Tab
894
+ value="chat"
895
+ active={Boolean(flowModule.value.omit_output_from_conversation)}
896
+ label="Chat"
897
+ />
898
+ {/if}
899
+ {#if !preprocessorModule && !isAgentTool}
900
+ <Tab value="advanced" label="Advanced" />
901
+ {/if}
902
+ </Tabs>
903
+ {#if visibleSelected === 'inputs' && (flowModule.value.type == 'rawscript' || flowModule.value.type == 'script' || flowModule.value.type == 'flow' || flowModule.value.type == 'aiagent')}
904
+ <div class="flex-1 overflow-auto" id="flow-editor-step-input">
905
+ <PropPickerWrapper
906
+ pickableProperties={stepPropPicker.pickableProperties}
907
+ error={failureModule}
908
+ noPadding
909
+ >
910
+ {#if reloadError}
911
+ <div
912
+ title={reloadError}
913
+ class="absolute left-2 top-2 rounded-full w-2 h-2 bg-red-300"
914
+ ></div>
915
+ {/if}
916
+ <InputTransformSchemaForm
917
+ class="px-2 xl:px-4 pb-8"
918
+ bind:this={inputTransformSchemaForm}
895
919
  pickableProperties={stepPropPicker.pickableProperties}
896
- error={failureModule}
897
- noPadding
898
- >
899
- {#if reloadError}
900
- <div
901
- title={reloadError}
902
- class="absolute left-2 top-2 rounded-full w-2 h-2 bg-red-300"
903
- ></div>
904
- {/if}
905
- <InputTransformSchemaForm
906
- class="px-2 xl:px-4 pb-8"
907
- bind:this={inputTransformSchemaForm}
908
- pickableProperties={stepPropPicker.pickableProperties}
909
- schema={flowStateStore.val[selectedId]?.schema ?? {}}
910
- previousModuleId={previousModule?.id}
911
- bind:args={
912
- () => {
920
+ schema={flowStateStore.val[selectedId]?.schema ?? {}}
921
+ previousModuleId={previousModule?.id}
922
+ bind:args={
923
+ () => {
924
+ // @ts-ignore
925
+ return flowModule?.value?.input_transforms
926
+ },
927
+ (v) => {
928
+ if (
929
+ typeof flowModule?.value === 'object' &&
930
+ flowModule?.value !== null
931
+ ) {
913
932
  // @ts-ignore
914
- return flowModule?.value?.input_transforms
915
- },
916
- (v) => {
917
- if (
918
- typeof flowModule?.value === 'object' &&
919
- flowModule?.value !== null
920
- ) {
921
- // @ts-ignore
922
- flowModule.value.input_transforms = v
923
- }
933
+ flowModule.value.input_transforms = v
924
934
  }
925
935
  }
926
- extraLib={stepPropPicker.extraLib}
927
- {enableAi}
928
- {isAgentTool}
929
- allowedAiTransforms={isAgentTool && flowModule.value.type === 'aiagent'
930
- ? ['user_message']
931
- : undefined}
932
- helperScript={retrieveDynCodeAndLang(flowModule.value)}
933
- chatInputEnabled={flowStore.val.value?.chat_input_enabled ?? false}
934
- />
935
- </PropPickerWrapper>
936
+ }
937
+ extraLib={stepPropPicker.extraLib}
938
+ {enableAi}
939
+ {isAgentTool}
940
+ allowedAiTransforms={isAgentTool && flowModule.value.type === 'aiagent'
941
+ ? ['user_message']
942
+ : undefined}
943
+ helperScript={retrieveDynCodeAndLang(flowModule.value)}
944
+ chatInputEnabled={flowStore.val.value?.chat_input_enabled ?? false}
945
+ />
946
+ </PropPickerWrapper>
947
+ </div>
948
+ {:else if visibleSelected === 'test'}
949
+ {#if debugMode && isDebuggableScript}
950
+ <div transition:slide={{ duration: 200 }}>
951
+ <DebugToolbar
952
+ connected={$debugState.connected}
953
+ running={$debugState.running}
954
+ stopped={$debugState.stopped}
955
+ breakpointCount={debugBreakpoints.size}
956
+ onStart={startDebugging}
957
+ onStop={stopDebugging}
958
+ onContinue={continueExecution}
959
+ onStepOver={stepOver}
960
+ onStepIn={stepIn}
961
+ onStepOut={stepOut}
962
+ onClearBreakpoints={clearAllBreakpoints}
963
+ onExitDebug={toggleDebugMode}
964
+ />
936
965
  </div>
937
- {:else if selected === 'test'}
938
- {#if debugMode && isDebuggableScript}
939
- <div transition:slide={{ duration: 200 }}>
940
- <DebugToolbar
941
- connected={$debugState.connected}
942
- running={$debugState.running}
943
- stopped={$debugState.stopped}
944
- breakpointCount={debugBreakpoints.size}
945
- onStart={startDebugging}
946
- onStop={stopDebugging}
947
- onContinue={continueExecution}
948
- onStepOver={stepOver}
949
- onStepIn={stepIn}
950
- onStepOut={stepOut}
951
- onClearBreakpoints={clearAllBreakpoints}
952
- onExitDebug={toggleDebugMode}
953
- />
954
- </div>
955
- {/if}
956
- <ModulePreview
957
- class="flex-1"
958
- pickableProperties={stepPropPicker.pickableProperties}
959
- bind:this={modulePreview}
960
- mod={flowModule}
961
- {noEditor}
962
- schema={flowStateStore.val[selectedId]?.schema ?? {}}
963
- bind:testJob
964
- bind:testIsLoading
965
- bind:scriptProgress
966
- focusArg={highlightArg}
967
- {onJobDone}
968
- hideRunButton={debugMode && isDebuggableScript}
966
+ {/if}
967
+ <ModulePreview
968
+ class="flex-1"
969
+ pickableProperties={stepPropPicker.pickableProperties}
970
+ bind:this={modulePreview}
971
+ mod={flowModule}
972
+ {noEditor}
973
+ schema={flowStateStore.val[selectedId]?.schema ?? {}}
974
+ bind:testJob
975
+ bind:testIsLoading
976
+ bind:scriptProgress
977
+ focusArg={highlightArg}
978
+ {onJobDone}
979
+ hideRunButton={debugMode && isDebuggableScript}
980
+ />
981
+ {:else if visibleSelected === 'chat' && canShowChatTab && flowModule.value.type === 'aiagent'}
982
+ <div class="flex-1 overflow-auto p-4">
983
+ <Section label="Conversation output">
984
+ <Toggle
985
+ size="xs"
986
+ checked={Boolean(flowModule.value.omit_output_from_conversation)}
987
+ on:change={(event) => {
988
+ setOmitOutputFromConversation(event.detail)
989
+ }}
990
+ options={{
991
+ right: 'Omit assistant and tool messages from the flow conversation',
992
+ rightTooltip:
993
+ 'When enabled, this AI agent still runs normally, but its assistant response and tool-use messages are not stored in chat-mode conversation history.'
994
+ }}
995
+ />
996
+ </Section>
997
+ </div>
998
+ {:else if visibleSelected === 'advanced'}
999
+ <Tabs bind:selected={advancedSelected} wrapperClass="shrink-0">
1000
+ <Tab
1001
+ value="retries"
1002
+ active={flowModule.retry !== undefined || flowModule.continue_on_error}
1003
+ label="Error handling"
969
1004
  />
970
- {:else if selected === 'advanced'}
971
- <Tabs bind:selected={advancedSelected} wrapperClass="shrink-0">
1005
+ {#if !selectedId.includes('failure')}
1006
+ <Tab value="runtime" label="Runtime" />
1007
+ <Tab value="cache" active={Boolean(flowModule.cache_ttl)} label="Cache" />
972
1008
  <Tab
973
- value="retries"
974
- active={flowModule.retry !== undefined || flowModule.continue_on_error}
975
- label="Error handling"
1009
+ value="early-stop"
1010
+ active={Boolean(
1011
+ flowModule.stop_after_if || flowModule.stop_after_all_iters_if
1012
+ )}
1013
+ label="Early Stop"
976
1014
  />
977
- {#if !selectedId.includes('failure')}
978
- <Tab value="runtime" label="Runtime" />
979
- <Tab value="cache" active={Boolean(flowModule.cache_ttl)} label="Cache" />
980
- <Tab
981
- value="early-stop"
982
- active={Boolean(
983
- flowModule.stop_after_if || flowModule.stop_after_all_iters_if
984
- )}
985
- label="Early Stop"
986
- />
987
- <Tab value="skip" active={Boolean(flowModule.skip_if)} label="Skip" />
988
- <Tab
989
- value="suspend"
990
- active={Boolean(flowModule.suspend)}
991
- label="Suspend"
992
- />
993
- <Tab value="sleep" active={Boolean(flowModule.sleep)} label="Sleep" />
994
- <Tab
995
- value="debounce"
996
- active={Boolean(flowModule.debouncing?.debounce_delay_s)}
997
- label="Debounce"
998
- />
999
- <Tab
1000
- value="mock"
1001
- active={Boolean(flowModule.mock?.enabled)}
1002
- label="Mock"
1003
- />
1004
- <Tab value="same_worker" label="Shared Directory" />
1005
- {#if flowModule.value['language'] === 'python3' || flowModule.value['language'] === 'deno'}
1006
- <Tab value="s3" label="S3" />
1007
- {/if}
1015
+ <Tab value="skip" active={Boolean(flowModule.skip_if)} label="Skip" />
1016
+ <Tab value="suspend" active={Boolean(flowModule.suspend)} label="Suspend" />
1017
+ <Tab value="sleep" active={Boolean(flowModule.sleep)} label="Sleep" />
1018
+ <Tab
1019
+ value="debounce"
1020
+ active={Boolean(flowModule.debouncing?.debounce_delay_s)}
1021
+ label="Debounce"
1022
+ />
1023
+ <Tab value="mock" active={Boolean(flowModule.mock?.enabled)} label="Mock" />
1024
+ <Tab value="same_worker" label="Shared Directory" />
1025
+ {#if flowModule.value['language'] === 'python3' || flowModule.value['language'] === 'deno'}
1026
+ <Tab value="s3" label="S3" />
1008
1027
  {/if}
1009
- </Tabs>
1010
- {#if advancedSelected === 'runtime'}
1011
- <Tabs bind:selected={advancedRuntimeSelected} wrapperClass="shrink-0">
1012
- <Tab value="concurrency" label="Concurrency" />
1013
- <Tab value="timeout" label="Timeout" />
1014
- <Tab value="priority" label="Priority" />
1015
- <Tab value="lifetime" label="Lifetime" />
1016
- </Tabs>
1017
1028
  {/if}
1018
- <div class="flex-1 overflow-auto p-4">
1019
- {#if advancedSelected === 'retries'}
1020
- <Section label="Continue on error">
1021
- {#snippet header()}
1022
- <Tooltip>
1023
- When enabled, the flow will continue to the next step even if this step fails (after exhausting all retries, if any). This enables to process the error in a branch one for instance.
1024
- </Tooltip>
1025
- {/snippet}
1026
- <Toggle
1027
- size="xs"
1028
- bind:checked={flowModule.continue_on_error}
1029
- options={{
1030
- left: 'Stop on error and propagate error up',
1031
- right: "Continue on error with error as step's return"
1032
- }}
1033
- />
1034
- </Section>
1035
- <div class="mt-4"></div>
1036
- <Section label="Retries">
1037
- {#snippet header()}
1038
- <Tooltip
1039
- documentationLink="https://www.windmill.dev/docs/flows/retries"
1040
- >
1041
- If defined, upon error this step will be retried with a delay and a
1042
- maximum number of attempts as defined below.
1043
- </Tooltip>
1044
- {/snippet}
1045
- <FlowRetries bind:flowModuleRetry={flowModule.retry} bind:flowModule />
1046
- </Section>
1047
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'concurrency'}
1048
- <Section label="Concurrency limits" class="flex flex-col gap-4" eeOnly>
1049
- {#snippet header()}
1050
- <Tooltip>Allowed concurrency within a given timeframe</Tooltip>
1051
- {/snippet}
1052
- {#if flowModule.value.type == 'rawscript'}
1053
- <Label label="Max number of executions within the time window">
1054
- <div class="flex flex-row gap-2 max-w-sm whitespace-nowrap">
1055
- <input
1056
- disabled={!$enterpriseLicense}
1057
- bind:value={flowModule.value.concurrent_limit}
1058
- type="number"
1059
- />
1060
- <Button
1061
- size="xs"
1062
- variant="default"
1063
- on:click={() => {
1064
- if (flowModule.value.type == 'rawscript') {
1065
- flowModule.value.concurrent_limit = undefined
1066
- }
1067
- }}
1068
- >
1069
- <div class="flex flex-row gap-2"> Remove Limits </div>
1070
- </Button>
1071
- </div>
1072
- </Label>
1073
- <Label label="Time window in seconds">
1074
- <SecondsInput
1075
- disabled={!$enterpriseLicense}
1076
- bind:seconds={flowModule.value.concurrency_time_window_s}
1077
- clearable
1078
- />
1079
- </Label>
1080
- <Label label="Custom concurrency key (optional)">
1081
- {#snippet header()}
1082
- <Tooltip>
1083
- Concurrency keys are global, you can have them be workspace
1084
- specific using the variable `$workspace`. You can also use an
1085
- argument's value using `$args[name_of_arg]`</Tooltip
1086
- >
1087
- {/snippet}
1088
- <!-- svelte-ignore a11y_autofocus -->
1029
+ </Tabs>
1030
+ {#if advancedSelected === 'runtime'}
1031
+ <Tabs bind:selected={advancedRuntimeSelected} wrapperClass="shrink-0">
1032
+ <Tab value="concurrency" label="Concurrency" />
1033
+ <Tab value="timeout" label="Timeout" />
1034
+ <Tab value="priority" label="Priority" />
1035
+ <Tab value="lifetime" label="Lifetime" />
1036
+ </Tabs>
1037
+ {/if}
1038
+ <div class="flex-1 overflow-auto p-4">
1039
+ {#if advancedSelected === 'retries'}
1040
+ <Section label="Continue on error">
1041
+ {#snippet header()}
1042
+ <Tooltip>
1043
+ When enabled, the flow will continue to the next step even if this
1044
+ step fails (after exhausting all retries, if any). This enables to
1045
+ process the error in a branch one for instance.
1046
+ </Tooltip>
1047
+ {/snippet}
1048
+ <Toggle
1049
+ size="xs"
1050
+ bind:checked={flowModule.continue_on_error}
1051
+ options={{
1052
+ left: 'Stop on error and propagate error up',
1053
+ right: "Continue on error with error as step's return"
1054
+ }}
1055
+ />
1056
+ </Section>
1057
+ <div class="mt-4"></div>
1058
+ <Section label="Retries">
1059
+ {#snippet header()}
1060
+ <Tooltip
1061
+ documentationLink="https://www.windmill.dev/docs/flows/retries"
1062
+ >
1063
+ If defined, upon error this step will be retried with a delay and a
1064
+ maximum number of attempts as defined below.
1065
+ </Tooltip>
1066
+ {/snippet}
1067
+ <FlowRetries bind:flowModuleRetry={flowModule.retry} bind:flowModule />
1068
+ </Section>
1069
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'concurrency'}
1070
+ <Section label="Concurrency limits" class="flex flex-col gap-4" eeOnly>
1071
+ {#snippet header()}
1072
+ <Tooltip>Allowed concurrency within a given timeframe</Tooltip>
1073
+ {/snippet}
1074
+ {#if flowModule.value.type == 'rawscript'}
1075
+ <Label label="Max number of executions within the time window">
1076
+ <div class="flex flex-row gap-2 max-w-sm whitespace-nowrap">
1089
1077
  <input
1090
- type="text"
1091
- autofocus
1092
1078
  disabled={!$enterpriseLicense}
1093
- bind:value={flowModule.value.custom_concurrency_key}
1094
- placeholder={`$workspace/script/${$pathStore}-$args[foo]`}
1079
+ bind:value={flowModule.value.concurrent_limit}
1080
+ type="number"
1095
1081
  />
1096
- </Label>
1097
- {:else}
1098
- <Alert type="warning" title="Limitation" size="xs">
1099
- The concurrency limit of a workspace script is only settable in the
1100
- script metadata itself. For hub scripts, this feature is non
1101
- available yet.
1102
- </Alert>
1103
- {/if}
1104
- </Section>
1105
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'timeout'}
1106
- <div>
1107
- <FlowModuleTimeout
1108
- previousModuleId={previousModule?.id}
1109
- bind:flowModule
1110
- />
1111
- </div>
1112
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'priority'}
1113
- <Section label="Priority" class="flex flex-col gap-4">
1114
- <!-- TODO: Add EE-only badge when we have it -->
1115
- <Toggle
1116
- disabled={!$enterpriseLicense || isCloudHosted()}
1117
- checked={flowModule.priority !== undefined && flowModule.priority > 0}
1118
- on:change={() => {
1119
- if (flowModule.priority) {
1120
- flowModule.priority = undefined
1121
- } else {
1122
- flowModule.priority = 100
1123
- }
1124
- }}
1125
- options={{
1126
- right: 'Enabled high priority flow step',
1127
- rightTooltip: `Jobs scheduled from this step when the flow is executed are labeled as high priority and take precedence over the other jobs in the jobs queue. ${
1128
- !$enterpriseLicense
1129
- ? 'This is a feature only available on enterprise edition.'
1130
- : ''
1131
- }`
1132
- }}
1133
- />
1134
- <Label label="Priority number">
1082
+ <Button
1083
+ size="xs"
1084
+ variant="default"
1085
+ on:click={() => {
1086
+ if (flowModule.value.type == 'rawscript') {
1087
+ flowModule.value.concurrent_limit = undefined
1088
+ }
1089
+ }}
1090
+ >
1091
+ <div class="flex flex-row gap-2"> Remove Limits </div>
1092
+ </Button>
1093
+ </div>
1094
+ </Label>
1095
+ <Label label="Time window in seconds">
1096
+ <SecondsInput
1097
+ disabled={!$enterpriseLicense}
1098
+ bind:seconds={flowModule.value.concurrency_time_window_s}
1099
+ clearable
1100
+ />
1101
+ </Label>
1102
+ <Label label="Custom concurrency key (optional)">
1135
1103
  {#snippet header()}
1136
- <Tooltip>The higher the number, the higher the priority.</Tooltip>
1104
+ <Tooltip>
1105
+ Concurrency keys are global, you can have them be workspace
1106
+ specific using the variable `$workspace`. You can also use an
1107
+ argument's value using `$args[name_of_arg]`</Tooltip
1108
+ >
1137
1109
  {/snippet}
1110
+ <!-- svelte-ignore a11y_autofocus -->
1138
1111
  <input
1139
- type="number"
1140
- class="!w-24"
1141
- disabled={flowModule.priority === undefined}
1142
- bind:value={flowModule.priority}
1143
- onfocus={bubble('focus')}
1144
- onchange={() => {
1145
- if (flowModule.priority && flowModule.priority > 100) {
1146
- flowModule.priority = 100
1147
- } else if (flowModule.priority && flowModule.priority < 0) {
1148
- flowModule.priority = 0
1149
- }
1150
- }}
1112
+ type="text"
1113
+ autofocus
1114
+ disabled={!$enterpriseLicense}
1115
+ bind:value={flowModule.value.custom_concurrency_key}
1116
+ placeholder={`$workspace/script/${$pathStore}-$args[foo]`}
1151
1117
  />
1152
1118
  </Label>
1153
-
1119
+ {:else}
1154
1120
  <Alert type="warning" title="Limitation" size="xs">
1155
- Setting priority is only available for enterprise edition and not
1156
- available on the cloud.
1157
- </Alert>
1158
- </Section>
1159
- {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'lifetime'}
1160
- <div>
1161
- <FlowModuleDeleteAfterUse
1162
- bind:flowModule
1163
- disabled={!$enterpriseLicense}
1164
- />
1165
- </div>
1166
- {:else if advancedSelected === 'cache'}
1167
- <div>
1168
- <FlowModuleCache bind:flowModule />
1169
- </div>
1170
- {:else if advancedSelected === 'early-stop'}
1171
- <FlowModuleEarlyStop bind:flowModule />
1172
- {:else if advancedSelected === 'skip'}
1173
- <FlowModuleSkip bind:flowModule {parentModule} {previousModule} />
1174
- {:else if advancedSelected === 'suspend'}
1175
- <div>
1176
- <FlowModuleSuspend
1177
- previousModuleId={previousModule?.id}
1178
- bind:flowModule
1179
- />
1180
- </div>
1181
- {:else if advancedSelected === 'sleep'}
1182
- <div>
1183
- <FlowModuleSleep
1184
- previousModuleId={previousModule?.id}
1185
- bind:flowModule
1186
- />
1187
- </div>
1188
- {:else if advancedSelected === 'debounce'}
1189
- <div>
1190
- <FlowModuleDebounce bind:flowModule {selectedId} />
1191
- </div>
1192
- {:else if advancedSelected === 'mock'}
1193
- <div>
1194
- <FlowModuleMockTransitionMessage />
1195
- </div>
1196
- {:else if advancedSelected === 'same_worker'}
1197
- <div>
1198
- <Alert type="info" title="Share a directory between steps">
1199
- If shared directory is set, will share a folder that will be mounted
1200
- on `./shared` for each of them to pass data between each other.
1121
+ The concurrency limit of a workspace script is only settable in the
1122
+ script metadata itself. For hub scripts, this feature is non available
1123
+ yet.
1201
1124
  </Alert>
1202
- <Button
1203
- btnClasses="mt-4"
1204
- on:click={() => {
1205
- selectionManager.selectId('settings-same-worker')
1125
+ {/if}
1126
+ </Section>
1127
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'timeout'}
1128
+ <div>
1129
+ <FlowModuleTimeout
1130
+ previousModuleId={previousModule?.id}
1131
+ bind:flowModule
1132
+ />
1133
+ </div>
1134
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'priority'}
1135
+ <Section label="Priority" class="flex flex-col gap-4">
1136
+ <!-- TODO: Add EE-only badge when we have it -->
1137
+ <Toggle
1138
+ disabled={!$enterpriseLicense || isCloudHosted()}
1139
+ checked={flowModule.priority !== undefined && flowModule.priority > 0}
1140
+ on:change={() => {
1141
+ if (flowModule.priority) {
1142
+ flowModule.priority = undefined
1143
+ } else {
1144
+ flowModule.priority = 100
1145
+ }
1146
+ }}
1147
+ options={{
1148
+ right: 'Enabled high priority flow step',
1149
+ rightTooltip: `Jobs scheduled from this step when the flow is executed are labeled as high priority and take precedence over the other jobs in the jobs queue. ${
1150
+ !$enterpriseLicense
1151
+ ? 'This is a feature only available on enterprise edition.'
1152
+ : ''
1153
+ }`
1154
+ }}
1155
+ />
1156
+ <Label label="Priority number">
1157
+ {#snippet header()}
1158
+ <Tooltip>The higher the number, the higher the priority.</Tooltip>
1159
+ {/snippet}
1160
+ <input
1161
+ type="number"
1162
+ class="!w-24"
1163
+ disabled={flowModule.priority === undefined}
1164
+ bind:value={flowModule.priority}
1165
+ onfocus={bubble('focus')}
1166
+ onchange={() => {
1167
+ if (flowModule.priority && flowModule.priority > 100) {
1168
+ flowModule.priority = 100
1169
+ } else if (flowModule.priority && flowModule.priority < 0) {
1170
+ flowModule.priority = 0
1171
+ }
1206
1172
  }}
1207
- >
1208
- Set shared directory in the flow settings
1209
- </Button>
1210
- </div>
1211
- {:else if advancedSelected === 's3'}
1212
- <div>
1213
- <h2 class="pb-4">
1214
- S3 snippets
1215
- <Tooltip>
1216
- Read/Write object from/to S3 and leverage Polars and DuckDB to run
1217
- efficient ETL processes.
1218
- </Tooltip>
1219
- </h2>
1220
- </div>
1221
- <div class="flex gap-2 justify-between mb-4 items-center">
1222
- <div class="flex gap-2">
1223
- <ToggleButtonGroup bind:selected={s3Kind} class="w-auto">
1224
- {#snippet children({ item })}
1225
- {#if flowModule.value['language'] === 'deno'}
1226
- <ToggleButton
1227
- value="s3_client"
1228
- small
1229
- label="S3 lite client"
1230
- {item}
1231
- />
1232
- {:else}
1233
- <ToggleButton value="s3_client" small label="Boto3" {item} />
1234
- <ToggleButton value="polars" small label="Polars" {item} />
1235
- <ToggleButton value="duckdb" small label="DuckDB" {item} />
1236
- {/if}
1237
- {/snippet}
1238
- </ToggleButtonGroup>
1239
- </div>
1173
+ />
1174
+ </Label>
1240
1175
 
1241
- <Button
1242
- size="xs"
1243
- on:click={() =>
1244
- editor?.setCode(s3Scripts[flowModule.value['language']][s3Kind])}
1245
- >
1246
- Apply snippet
1247
- </Button>
1248
- </div>
1249
- <HighlightCode
1250
- language={flowModule.value['language']}
1251
- code={s3Scripts[flowModule.value['language']][s3Kind]}
1176
+ <Alert type="warning" title="Limitation" size="xs">
1177
+ Setting priority is only available for enterprise edition and not
1178
+ available on the cloud.
1179
+ </Alert>
1180
+ </Section>
1181
+ {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'lifetime'}
1182
+ <div>
1183
+ <FlowModuleDeleteAfterUse
1184
+ bind:flowModule
1185
+ disabled={!$enterpriseLicense}
1252
1186
  />
1253
- {/if}
1254
- </div>
1255
- {/if}
1256
- </div>
1257
- </Pane>
1258
- {#if selected === 'test'}
1259
- <Pane minSize={20} class="relative">
1260
- {#if stepHistoryLoader?.stepStates[flowModule.id]?.initial && !flowModule.mock?.enabled}
1261
- <!-- svelte-ignore a11y_no_static_element_interactions -->
1262
- <!-- svelte-ignore a11y_click_events_have_key_events -->
1263
- <div
1264
- onclick={() => {
1265
- stepHistoryLoader?.resetInitial(flowModule.id)
1266
- }}
1267
- class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 bg-gray-500/40 absolute top-0 left-0 w-full z-50"
1268
- >
1269
- <div class="text-center text-primary text-sm py-2 pt-20"
1270
- ><span class="font-bold border p-2 bg-surface-secondary rounded-md"
1271
- >Run loaded from history</span
1272
- ></div
1273
- >
1274
- </div>
1275
- {/if}
1276
- {#if showDebugPanel || hasDebugResult}
1277
- <Splitpanes horizontal class="h-full">
1278
- <Pane size={50} minSize={15}>
1279
- <Splitpanes horizontal class="h-full">
1280
- <Pane size={50} minSize={10}>
1281
- <LogViewer
1282
- small
1283
- content={$debugState.logs}
1284
- isLoading={$debugState.running && !$debugState.stopped}
1285
- tag={undefined}
1286
- />
1287
- </Pane>
1288
- <Pane size={50} minSize={10}>
1289
- {#if hasDebugResult}
1290
- <div class="h-full p-2 overflow-auto">
1291
- <DisplayResult
1292
- result={$debugState.result}
1293
- language={rawScriptLang}
1294
- />
1295
- </div>
1296
- {:else}
1297
- <div
1298
- class="h-full flex items-center justify-center text-sm text-tertiary"
1299
- >
1300
- {#if $debugState.running && !$debugState.stopped}
1301
- Running...
1302
- {:else if $debugState.stopped}
1303
- Paused at breakpoint
1304
- {:else}
1305
- Waiting for debug session
1306
- {/if}
1307
- </div>
1308
- {/if}
1309
- </Pane>
1310
- </Splitpanes>
1311
- </Pane>
1312
- <Pane size={50} minSize={15}>
1313
- <DebugPanel
1314
- stackFrames={$debugState.stackFrames}
1315
- scopes={$debugState.scopes}
1316
- variables={$debugState.variables}
1317
- client={dapClient}
1318
- bind:selectedFrameId={selectedDebugFrameId}
1187
+ </div>
1188
+ {:else if advancedSelected === 'cache'}
1189
+ <div>
1190
+ <FlowModuleCache bind:flowModule />
1191
+ </div>
1192
+ {:else if advancedSelected === 'early-stop'}
1193
+ <FlowModuleEarlyStop bind:flowModule />
1194
+ {:else if advancedSelected === 'skip'}
1195
+ <FlowModuleSkip bind:flowModule {parentModule} {previousModule} />
1196
+ {:else if advancedSelected === 'suspend'}
1197
+ <div>
1198
+ <FlowModuleSuspend
1199
+ previousModuleId={previousModule?.id}
1200
+ bind:flowModule
1319
1201
  />
1320
- </Pane>
1321
- </Splitpanes>
1322
- {:else if debugMode && isDebuggableScript}
1323
- <div class="h-full flex items-center justify-center text-sm text-tertiary">
1324
- Click "Debug" in the toolbar to start debugging
1325
- </div>
1326
- {:else}
1327
- <ModulePreviewResultViewer
1328
- lang={flowModule.value['language'] ?? 'deno'}
1329
- {editor}
1330
- {diffEditor}
1331
- loopStatus={parentLoop
1332
- ? { type: 'inside', flow: parentLoop.type }
1333
- : undefined}
1334
- onUpdateMock={(detail) => {
1335
- flowModule.mock = detail
1336
- flowModule = flowModule
1337
- refreshStateStore(flowStore)
1338
- }}
1339
- {testJob}
1340
- {scriptProgress}
1341
- mod={flowModule}
1342
- {testIsLoading}
1343
- disableMock={preprocessorModule || failureModule}
1344
- disableHistory={failureModule}
1345
- loadingJob={stepHistoryLoader?.stepStates[flowModule.id]?.loadingJobs}
1346
- tagLabel={customUi?.tagLabel}
1347
- bind:this={modulePreviewResultViewer}
1348
- />
1349
- {/if}
1350
- </Pane>
1351
- {/if}
1352
- </Splitpanes>
1353
- </Pane>
1354
- </Splitpanes>
1202
+ </div>
1203
+ {:else if advancedSelected === 'sleep'}
1204
+ <div>
1205
+ <FlowModuleSleep previousModuleId={previousModule?.id} bind:flowModule />
1206
+ </div>
1207
+ {:else if advancedSelected === 'debounce'}
1208
+ <div>
1209
+ <FlowModuleDebounce bind:flowModule {selectedId} />
1210
+ </div>
1211
+ {:else if advancedSelected === 'mock'}
1212
+ <div>
1213
+ <FlowModuleMockTransitionMessage />
1214
+ </div>
1215
+ {:else if advancedSelected === 'same_worker'}
1216
+ <div>
1217
+ <Alert type="info" title="Share a directory between steps">
1218
+ If shared directory is set, will share a folder that will be mounted on
1219
+ `./shared` for each of them to pass data between each other.
1220
+ </Alert>
1221
+ <Button
1222
+ btnClasses="mt-4"
1223
+ on:click={() => {
1224
+ selectionManager.selectId('settings-same-worker')
1225
+ }}
1226
+ >
1227
+ Set shared directory in the flow settings
1228
+ </Button>
1229
+ </div>
1230
+ {:else if advancedSelected === 's3'}
1231
+ <div>
1232
+ <h2 class="pb-4">
1233
+ S3 snippets
1234
+ <Tooltip>
1235
+ Read/Write object from/to S3 and leverage Polars and DuckDB to run
1236
+ efficient ETL processes.
1237
+ </Tooltip>
1238
+ </h2>
1239
+ </div>
1240
+ <div class="flex gap-2 justify-between mb-4 items-center">
1241
+ <div class="flex gap-2">
1242
+ <ToggleButtonGroup bind:selected={s3Kind} class="w-auto">
1243
+ {#snippet children({ item })}
1244
+ {#if flowModule.value['language'] === 'deno'}
1245
+ <ToggleButton
1246
+ value="s3_client"
1247
+ small
1248
+ label="S3 lite client"
1249
+ {item}
1250
+ />
1251
+ {:else}
1252
+ <ToggleButton value="s3_client" small label="Boto3" {item} />
1253
+ <ToggleButton value="polars" small label="Polars" {item} />
1254
+ <ToggleButton value="duckdb" small label="DuckDB" {item} />
1255
+ {/if}
1256
+ {/snippet}
1257
+ </ToggleButtonGroup>
1258
+ </div>
1259
+
1260
+ <Button
1261
+ size="xs"
1262
+ on:click={() =>
1263
+ editor?.setCode(s3Scripts[flowModule.value['language']][s3Kind])}
1264
+ >
1265
+ Apply snippet
1266
+ </Button>
1267
+ </div>
1268
+ <HighlightCode
1269
+ language={flowModule.value['language']}
1270
+ code={s3Scripts[flowModule.value['language']][s3Kind]}
1271
+ />
1272
+ {/if}
1273
+ </div>
1274
+ {/if}
1275
+ </div>
1276
+ </Pane>
1277
+ {#if selected === 'test'}
1278
+ <Pane minSize={20} class="relative">
1279
+ {#if stepHistoryLoader?.stepStates[flowModule.id]?.initial && !flowModule.mock?.enabled}
1280
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
1281
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
1282
+ <div
1283
+ onclick={() => {
1284
+ stepHistoryLoader?.resetInitial(flowModule.id)
1285
+ }}
1286
+ class="cursor-pointer h-full hover:bg-gray-500/20 dark:hover:bg-gray-500/20 dark:bg-gray-500/80 bg-gray-500/40 absolute top-0 left-0 w-full z-50"
1287
+ >
1288
+ <div class="text-center text-primary text-sm py-2 pt-20"
1289
+ ><span class="font-bold border p-2 bg-surface-secondary rounded-md"
1290
+ >Run loaded from history</span
1291
+ ></div
1292
+ >
1293
+ </div>
1294
+ {/if}
1295
+ {#if showDebugPanel || hasDebugResult}
1296
+ <Splitpanes horizontal class="h-full">
1297
+ <Pane size={50} minSize={15}>
1298
+ <Splitpanes horizontal class="h-full">
1299
+ <Pane size={50} minSize={10}>
1300
+ <LogViewer
1301
+ small
1302
+ content={$debugState.logs}
1303
+ isLoading={$debugState.running && !$debugState.stopped}
1304
+ tag={undefined}
1305
+ />
1306
+ </Pane>
1307
+ <Pane size={50} minSize={10}>
1308
+ {#if hasDebugResult}
1309
+ <div class="h-full p-2 overflow-auto">
1310
+ <DisplayResult
1311
+ result={$debugState.result}
1312
+ language={rawScriptLang}
1313
+ />
1314
+ </div>
1315
+ {:else}
1316
+ <div
1317
+ class="h-full flex items-center justify-center text-sm text-tertiary"
1318
+ >
1319
+ {#if $debugState.running && !$debugState.stopped}
1320
+ Running...
1321
+ {:else if $debugState.stopped}
1322
+ Paused at breakpoint
1323
+ {:else}
1324
+ Waiting for debug session
1325
+ {/if}
1326
+ </div>
1327
+ {/if}
1328
+ </Pane>
1329
+ </Splitpanes>
1330
+ </Pane>
1331
+ <Pane size={50} minSize={15}>
1332
+ <DebugPanel
1333
+ stackFrames={$debugState.stackFrames}
1334
+ scopes={$debugState.scopes}
1335
+ variables={$debugState.variables}
1336
+ client={dapClient}
1337
+ bind:selectedFrameId={selectedDebugFrameId}
1338
+ />
1339
+ </Pane>
1340
+ </Splitpanes>
1341
+ {:else if debugMode && isDebuggableScript}
1342
+ <div class="h-full flex items-center justify-center text-sm text-tertiary">
1343
+ Click "Debug" in the toolbar to start debugging
1344
+ </div>
1345
+ {:else}
1346
+ <ModulePreviewResultViewer
1347
+ lang={flowModule.value['language'] ?? 'deno'}
1348
+ {editor}
1349
+ {diffEditor}
1350
+ loopStatus={parentLoop
1351
+ ? { type: 'inside', flow: parentLoop.type }
1352
+ : undefined}
1353
+ onUpdateMock={(detail) => {
1354
+ flowModule.mock = detail
1355
+ flowModule = flowModule
1356
+ refreshStateStore(flowStore)
1357
+ }}
1358
+ {testJob}
1359
+ {scriptProgress}
1360
+ mod={flowModule}
1361
+ {testIsLoading}
1362
+ disableMock={preprocessorModule || failureModule}
1363
+ disableHistory={failureModule}
1364
+ loadingJob={stepHistoryLoader?.stepStates[flowModule.id]?.loadingJobs}
1365
+ tagLabel={customUi?.tagLabel}
1366
+ bind:this={modulePreviewResultViewer}
1367
+ />
1368
+ {/if}
1369
+ </Pane>
1370
+ {/if}
1371
+ </Splitpanes>
1372
+ {/snippet}
1373
+
1374
+ {#if flowModule.value.type === 'aiagent' || (noEditor && flowModule.value.type !== 'flow')}
1375
+ <!-- Top pane has no content to show (aiagent has no editor; rawscript/script
1376
+ gate their content on !noEditor). Skip the Splitpanes wrapper entirely so
1377
+ there's no orphan splitter. type === 'flow' still renders FlowPathViewer
1378
+ even with noEditor, so it falls into the Splitpanes branch below. -->
1379
+ <div class="h-full">
1380
+ {@render bottomPaneContent()}
1381
+ </div>
1382
+ {:else}
1383
+ <Splitpanes horizontal>
1384
+ <Pane bind:size={editorPanelSize} minSize={10} class="relative">
1385
+ {@render topPaneContent()}
1386
+ </Pane>
1387
+ <Pane bind:size={editorSettingsPanelSize} minSize={20}>
1388
+ {@render bottomPaneContent()}
1389
+ </Pane>
1390
+ </Splitpanes>
1391
+ {/if}
1355
1392
  </div>
1356
1393
  </div>
1357
1394
  </FlowCard>