windmill-components 1.677.1 → 1.695.0

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 (552) hide show
  1. package/package/components/AppConnectInner.svelte +6 -0
  2. package/package/components/ArgInput.svelte +2 -0
  3. package/package/components/AutoscalingConfigEditor.svelte +18 -4
  4. package/package/components/CiTestResults.svelte +64 -0
  5. package/package/components/CiTestResults.svelte.d.ts +7 -0
  6. package/package/components/CompareWorkspaces.svelte +741 -484
  7. package/package/components/DBManager.svelte +35 -4
  8. package/package/components/DBManager.svelte.d.ts +2 -0
  9. package/package/components/DBManagerContent.svelte +3 -1
  10. package/package/components/DBManagerContent.svelte.d.ts +3 -0
  11. package/package/components/DBManagerDrawer.svelte +145 -3
  12. package/package/components/DBTableEditor.svelte +14 -4
  13. package/package/components/DatatablePicker.svelte +2 -5
  14. package/package/components/DatatableSchemaDiff.svelte +531 -0
  15. package/package/components/DatatableSchemaDiff.svelte.d.ts +29 -0
  16. package/package/components/DedicatedWorkersSelector.svelte +4 -2
  17. package/package/components/DefaultTagsInner.svelte +42 -2
  18. package/package/components/DeployWorkspaceDrawer.svelte +1 -1
  19. package/package/components/Dev.svelte +407 -74
  20. package/package/components/EditableSchemaForm.svelte +4 -0
  21. package/package/components/Editor.svelte +1 -1
  22. package/package/components/EditorBar.svelte +1 -1
  23. package/package/components/EditorBar.svelte.d.ts +1 -1
  24. package/package/components/ErrorOrRecoveryHandler.svelte +2 -2
  25. package/package/components/FlowPreviewContent.svelte +32 -30
  26. package/package/components/FlowRestartButton.svelte +143 -61
  27. package/package/components/FlowRestartButton.svelte.d.ts +37 -0
  28. package/package/components/FlowStatusViewer.svelte +15 -1
  29. package/package/components/FlowStatusViewer.svelte.d.ts +10 -2
  30. package/package/components/FlowStatusViewerInner.svelte +270 -222
  31. package/package/components/FlowStatusViewerInner.svelte.d.ts +6 -2
  32. package/package/components/FlowTimeline.svelte +1 -1
  33. package/package/components/FolderEditor.svelte +189 -4
  34. package/package/components/ForkConflictModal.svelte +57 -0
  35. package/package/components/ForkConflictModal.svelte.d.ts +3 -0
  36. package/package/components/ForkWorkspaceBanner.svelte +82 -11
  37. package/package/components/GitRepoViewer.svelte +251 -97
  38. package/package/components/GlobalUserOffboardingModal.svelte +293 -0
  39. package/package/components/GlobalUserOffboardingModal.svelte.d.ts +10 -0
  40. package/package/components/InputTransformSchemaForm.svelte +1 -1
  41. package/package/components/InstanceSettings.svelte +58 -19
  42. package/package/components/Login.svelte +133 -36
  43. package/package/components/Login.svelte.d.ts +1 -0
  44. package/package/components/ModuleTest.svelte +2 -1
  45. package/package/components/NoMainFuncBadge.svelte +1 -1
  46. package/package/components/OffboardItemsBox.svelte +56 -0
  47. package/package/components/OffboardItemsBox.svelte.d.ts +12 -0
  48. package/package/components/OffboardReassignControls.svelte +47 -0
  49. package/package/components/OffboardReassignControls.svelte.d.ts +20 -0
  50. package/package/components/OffboardWorkspaceSection.svelte +110 -0
  51. package/package/components/OffboardWorkspaceSection.svelte.d.ts +24 -0
  52. package/package/components/OnBehalfOfSelector.svelte +21 -3
  53. package/package/components/OnBehalfOfSelector.svelte.d.ts +7 -0
  54. package/package/components/Path.svelte +7 -1
  55. package/package/components/Path.svelte.d.ts +1 -1
  56. package/package/components/QueueAlerts.svelte +10 -10
  57. package/package/components/ResourcePicker.svelte +2 -2
  58. package/package/components/RunsPage.svelte +2 -1
  59. package/package/components/S3FilePickerInner.svelte +89 -89
  60. package/package/components/ScriptBuilder.svelte +52 -11
  61. package/package/components/ScriptEditor.svelte +19 -8
  62. package/package/components/ScriptEditor.svelte.d.ts +1 -1
  63. package/package/components/ShareModal.svelte +236 -98
  64. package/package/components/ShareModal.svelte.d.ts +1 -1
  65. package/package/components/SuperadminSettingsInner.svelte +362 -315
  66. package/package/components/UserOffboardingModal.svelte +238 -0
  67. package/package/components/UserOffboardingModal.svelte.d.ts +10 -0
  68. package/package/components/WorkspaceDeployLayout.svelte +3 -3
  69. package/package/components/WorkspaceDeployLayout.svelte.d.ts +1 -0
  70. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +3 -0
  71. package/package/components/apps/components/helpers/executeRunnable.js +2 -1
  72. package/package/components/apps/editor/AppReportsDrawerInner.svelte +1 -1
  73. package/package/components/apps/editor/appPolicy.js +2 -1
  74. package/package/components/apps/editor/commonAppUtils.d.ts +3 -0
  75. package/package/components/apps/editor/inlineScriptsPanel/CacheTtlPopup.svelte +1 -1
  76. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +7 -0
  77. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +4 -2
  78. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte +49 -0
  79. package/package/components/apps/editor/inlineScriptsPanel/TagPopup.svelte.d.ts +9 -0
  80. package/package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +12 -0
  81. package/package/components/apps/inputType.d.ts +1 -0
  82. package/package/components/apps/sharedTypes.d.ts +1 -0
  83. package/package/components/assets/AssetsDropdownButton.svelte +1 -1
  84. package/package/components/auditLogs/AuditLogsFilters.svelte +8 -3
  85. package/package/components/common/confirmationModal/ConfirmationModal.svelte +1 -1
  86. package/package/components/common/fileUpload/S3ArgInput.svelte +12 -10
  87. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +2 -0
  88. package/package/components/common/table/AppRow.svelte +3 -3
  89. package/package/components/common/table/FlowRow.svelte +3 -3
  90. package/package/components/common/table/RawAppRow.svelte +4 -4
  91. package/package/components/common/table/Row.svelte +6 -2
  92. package/package/components/common/table/ScriptRow.svelte +11 -3
  93. package/package/components/copilot/chat/AIChatDisplay.svelte +5 -36
  94. package/package/components/copilot/chat/AIChatInput.svelte +56 -47
  95. package/package/components/copilot/chat/AIChatManager.svelte.js +50 -48
  96. package/package/components/copilot/chat/ContextElementBadge.svelte +6 -4
  97. package/package/components/copilot/chat/anthropic.d.ts +7 -1
  98. package/package/components/copilot/chat/anthropic.js +5 -2
  99. package/package/components/copilot/chat/app/core.d.ts +12 -20
  100. package/package/components/copilot/chat/app/core.js +230 -159
  101. package/package/components/copilot/chat/app/core.test.js +417 -0
  102. package/package/components/copilot/chat/chatLoop.d.ts +3 -0
  103. package/package/components/copilot/chat/chatLoop.js +13 -5
  104. package/package/components/copilot/chat/context.js +44 -0
  105. package/package/components/copilot/chat/flow/FlowAIChat.svelte +57 -76
  106. package/package/components/copilot/chat/flow/core.d.ts +14 -3
  107. package/package/components/copilot/chat/flow/core.js +494 -116
  108. package/package/components/copilot/chat/flow/helperUtils.d.ts +22 -0
  109. package/package/components/copilot/chat/flow/helperUtils.js +100 -0
  110. package/package/components/copilot/chat/flow/helperUtils.test.js +231 -0
  111. package/package/components/copilot/chat/flow/inlineScriptsUtils.d.ts +5 -24
  112. package/package/components/copilot/chat/flow/inlineScriptsUtils.js +30 -55
  113. package/package/components/copilot/chat/flow/openFlow.json +1 -1
  114. package/package/components/copilot/chat/flow/openFlowZod.gen.js +24 -0
  115. package/package/components/copilot/chat/flow/utils.test.js +59 -0
  116. package/package/components/copilot/chat/openai-responses.d.ts +7 -1
  117. package/package/components/copilot/chat/openai-responses.js +5 -2
  118. package/package/components/copilot/chat/script/core.js +3 -0
  119. package/package/components/copilot/chat/shared.d.ts +7 -2
  120. package/package/components/copilot/chat/shared.js +116 -53
  121. package/package/components/copilot/chat/shared.test.d.ts +1 -0
  122. package/package/components/copilot/chat/shared.test.js +412 -0
  123. package/package/components/copilot/chat/tokenUsage.d.ts +23 -0
  124. package/package/components/copilot/chat/tokenUsage.js +42 -0
  125. package/package/components/copilot/chat/workspaceTools.d.ts +7 -0
  126. package/package/components/copilot/chat/workspaceTools.js +239 -0
  127. package/package/components/copilot/chat/workspaceToolsZod.gen.d.ts +1295 -0
  128. package/package/components/copilot/chat/workspaceToolsZod.gen.js +424 -0
  129. package/package/components/copilot/lib.d.ts +5 -1
  130. package/package/components/copilot/lib.js +24 -6
  131. package/package/components/copilot/lib.test.d.ts +1 -0
  132. package/package/components/copilot/lib.test.js +19 -0
  133. package/package/components/copilot/modelConfig.d.ts +3 -0
  134. package/package/components/copilot/modelConfig.js +10 -0
  135. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte +337 -0
  136. package/package/components/deploymentRequest/DeploymentRequestPanel.svelte.d.ts +15 -0
  137. package/package/components/details/CopyableCodeBlock.svelte +18 -8
  138. package/package/components/details/CopyableCodeBlock.svelte.d.ts +1 -0
  139. package/package/components/flows/FlowAssetsHandler.svelte +19 -21
  140. package/package/components/flows/FlowProgressBar.svelte +5 -2
  141. package/package/components/flows/agentToolTree.d.ts +17 -0
  142. package/package/components/flows/agentToolTree.js +114 -0
  143. package/package/components/flows/agentToolTree.test.d.ts +1 -0
  144. package/package/components/flows/agentToolTree.test.js +86 -0
  145. package/package/components/flows/agentToolUtils.d.ts +0 -5
  146. package/package/components/flows/agentToolUtils.js +0 -49
  147. package/package/components/flows/content/FlowLoop.svelte +7 -4
  148. package/package/components/flows/content/FlowModuleComponent.svelte +636 -599
  149. package/package/components/flows/content/FlowModuleDeleteAfterUse.svelte +15 -7
  150. package/package/components/flows/content/FlowSettings.svelte +29 -0
  151. package/package/components/flows/conversations/FlowChatManager.svelte.js +21 -10
  152. package/package/components/flows/dfs.d.ts +6 -2
  153. package/package/components/flows/dfs.js +19 -11
  154. package/package/components/flows/flowDeleteController.d.ts +32 -0
  155. package/package/components/flows/flowDeleteController.js +54 -0
  156. package/package/components/flows/flowDeleteController.test.d.ts +1 -0
  157. package/package/components/flows/flowDeleteController.test.js +121 -0
  158. package/package/components/flows/flowDeleteUtils.d.ts +48 -0
  159. package/package/components/flows/flowDeleteUtils.js +150 -0
  160. package/package/components/flows/flowDeleteUtils.test.d.ts +1 -0
  161. package/package/components/flows/flowDeleteUtils.test.js +131 -0
  162. package/package/components/flows/flowDiff.d.ts +2 -47
  163. package/package/components/flows/flowDiff.js +16 -293
  164. package/package/components/flows/flowDiff.testUtils.d.ts +8 -0
  165. package/package/components/flows/flowDiff.testUtils.js +26 -0
  166. package/package/components/flows/flowDiffManager.svelte.js +20 -75
  167. package/package/components/flows/flowDiffManager.svelte.test.js +103 -2
  168. package/package/components/flows/flowExplorer.d.ts +4 -0
  169. package/package/components/flows/flowExplorer.js +7 -30
  170. package/package/components/flows/flowState.d.ts +1 -0
  171. package/package/components/flows/flowStateUtils.svelte.js +11 -2
  172. package/package/components/flows/flowTree.d.ts +91 -0
  173. package/package/components/flows/flowTree.js +326 -0
  174. package/package/components/flows/flowTree.test.d.ts +1 -0
  175. package/package/components/flows/flowTree.test.js +236 -0
  176. package/package/components/flows/map/FlowJobsMenu.svelte +36 -30
  177. package/package/components/flows/map/FlowModuleSchemaItem.svelte +1 -1
  178. package/package/components/flows/map/FlowModuleSchemaMap.svelte +73 -229
  179. package/package/components/flows/map/FlowModuleSchemaMap.svelte.d.ts +1 -2
  180. package/package/components/flows/pickers/PickHubScriptQuick.svelte +2 -2
  181. package/package/components/flows/previousResults.js +13 -41
  182. package/package/components/flows/previousResults.test.d.ts +1 -0
  183. package/package/components/flows/previousResults.test.js +65 -0
  184. package/package/components/flows/propPicker/OutputPicker.svelte +2 -1
  185. package/package/components/flows/propPicker/OutputPickerInner.svelte +41 -4
  186. package/package/components/flows/propPicker/StepHistory.svelte +9 -1
  187. package/package/components/git_sync/GitSyncContext.svelte.js +11 -7
  188. package/package/components/git_sync/GitSyncRepositoryCard.svelte +2 -29
  189. package/package/components/git_sync/PullWorkspaceModal.svelte +6 -7
  190. package/package/components/graph/FlowGraphV2.svelte +8 -4
  191. package/package/components/graph/FlowGraphV2.svelte.d.ts +2 -0
  192. package/package/components/graph/groupedModulesProxy.svelte.d.ts +10 -0
  193. package/package/components/graph/groupedModulesProxy.svelte.js +17 -1
  194. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +8 -2
  195. package/package/components/home/HomeConnectDrawer.svelte +125 -0
  196. package/package/components/home/HomeConnectDrawer.svelte.d.ts +5 -0
  197. package/package/components/home/deploy_ui.js +1 -1
  198. package/package/components/icons/AzureIcon.svelte +12 -25
  199. package/package/components/icons/AzureIcon.svelte.d.ts +3 -2
  200. package/package/components/icons/GithubIcon.svelte +4 -4
  201. package/package/components/icons/GithubIcon.svelte.d.ts +5 -2
  202. package/package/components/instanceSettings/ExternalJwtTokens.svelte +85 -0
  203. package/package/components/instanceSettings/ExternalJwtTokens.svelte.d.ts +12 -0
  204. package/package/components/instanceSettings/GhesAppSettings.svelte +17 -0
  205. package/package/components/instanceSettings/IndexerMemorySettings.svelte +56 -29
  206. package/package/components/instanceSettings/SecretBackendConfig.svelte +9 -2
  207. package/package/components/instanceSettings.d.ts +1 -0
  208. package/package/components/instanceSettings.js +66 -8
  209. package/package/components/mcp/McpScopeSelector.svelte +119 -9
  210. package/package/components/mcp/McpScopeSelector.svelte.d.ts +1 -0
  211. package/package/components/offboarding-utils.d.ts +11 -0
  212. package/package/components/offboarding-utils.js +102 -0
  213. package/package/components/progressBar/ProgressBar.svelte +9 -5
  214. package/package/components/progressBar/ProgressBar.svelte.d.ts +1 -0
  215. package/package/components/raw_apps/DeleteAfterUsePopup.svelte +52 -0
  216. package/package/components/raw_apps/DeleteAfterUsePopup.svelte.d.ts +9 -0
  217. package/package/components/raw_apps/RawAppBackgroundRunner.svelte +5 -1
  218. package/package/components/raw_apps/RawAppDataTableDrawer.svelte +1 -1
  219. package/package/components/raw_apps/RawAppEditor.svelte +186 -102
  220. package/package/components/raw_apps/RawAppEditorHeader.svelte +6 -1
  221. package/package/components/raw_apps/RawAppEditorHeader.svelte.d.ts +1 -0
  222. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +9 -3
  223. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte.d.ts +2 -1
  224. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +1 -0
  225. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte.d.ts +1 -0
  226. package/package/components/raw_apps/RawAppInputsSpecEditor.svelte +48 -5
  227. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte +129 -0
  228. package/package/components/raw_apps/RawAppSharedUiDrawer.svelte.d.ts +5 -0
  229. package/package/components/raw_apps/RawAppSidebar.svelte +12 -0
  230. package/package/components/raw_apps/RawAppYamlEditor.svelte +81 -0
  231. package/package/components/raw_apps/RawAppYamlEditor.svelte.d.ts +20 -0
  232. package/package/components/raw_apps/dataTableRefUtils.d.ts +7 -0
  233. package/package/components/raw_apps/dataTableRefUtils.js +34 -0
  234. package/package/components/raw_apps/dataTableRefUtils.test.d.ts +1 -0
  235. package/package/components/raw_apps/dataTableRefUtils.test.js +29 -0
  236. package/package/components/raw_apps/datatableUtils.svelte.js +1 -1
  237. package/package/components/raw_apps/rawAppPolicy.d.ts +1 -0
  238. package/package/components/raw_apps/rawAppPolicy.js +17 -2
  239. package/package/components/resources/resourceTypesFilter.d.ts +19 -0
  240. package/package/components/resources/resourceTypesFilter.js +21 -0
  241. package/package/components/restartFromStepPath.d.ts +39 -0
  242. package/package/components/restartFromStepPath.js +89 -0
  243. package/package/components/runs/JobDetailFieldConfig.d.ts +1 -0
  244. package/package/components/runs/JobDetailFieldConfig.js +57 -10
  245. package/package/components/runs/JobDetailHeader.svelte +24 -3
  246. package/package/components/runs/runsFilter.d.ts +1 -1
  247. package/package/components/schema/FlowPropertyEditor.svelte +30 -1
  248. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +5 -2
  249. package/package/components/script_builder.d.ts +1 -1
  250. package/package/components/search/GlobalSearchModal.svelte +8 -1
  251. package/package/components/select/Select.svelte +3 -2
  252. package/package/components/select/Select.svelte.d.ts +1 -0
  253. package/package/components/settings/CreateToken.svelte +91 -71
  254. package/package/components/settings/CreateToken.svelte.d.ts +3 -0
  255. package/package/components/settings/EditTokenScopesModal.svelte +57 -0
  256. package/package/components/settings/EditTokenScopesModal.svelte.d.ts +10 -0
  257. package/package/components/settings/ScopesPicker.svelte +43 -0
  258. package/package/components/settings/ScopesPicker.svelte.d.ts +11 -0
  259. package/package/components/settings/TokensTable.svelte +51 -15
  260. package/package/components/settings/WorkspaceUserSettings.svelte +34 -28
  261. package/package/components/sidebar/OperatorMenu.svelte +6 -0
  262. package/package/components/sidebar/SidebarContent.svelte +68 -2
  263. package/package/components/sidebar/WorkspaceMenu.svelte +8 -4
  264. package/package/components/triggers/AddTriggersButton.svelte +17 -0
  265. package/package/components/triggers/CaptureWrapper.svelte +19 -1
  266. package/package/components/triggers/PermissionedAsLine.svelte +37 -3
  267. package/package/components/triggers/PermissionedAsLine.svelte.d.ts +6 -0
  268. package/package/components/triggers/TriggerEditorToolbar.svelte.d.ts +1 -1
  269. package/package/components/triggers/TriggerModeToggle.svelte +36 -7
  270. package/package/components/triggers/TriggerModeToggle.svelte.d.ts +1 -1
  271. package/package/components/triggers/TriggerSuspendedJobsModal.svelte.d.ts +1 -1
  272. package/package/components/triggers/TriggersEditor.svelte +10 -2
  273. package/package/components/triggers/TriggersWrapper.svelte +20 -0
  274. package/package/components/triggers/azure/AzureCapture.svelte +41 -0
  275. package/package/components/triggers/azure/AzureCapture.svelte.d.ts +44 -0
  276. package/package/components/triggers/azure/AzureTriggerEditor.svelte +20 -0
  277. package/package/components/triggers/azure/AzureTriggerEditor.svelte.d.ts +9 -0
  278. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte +301 -0
  279. package/package/components/triggers/azure/AzureTriggerEditorConfigSection.svelte.d.ts +16 -0
  280. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte +422 -0
  281. package/package/components/triggers/azure/AzureTriggerEditorInner.svelte.d.ts +25 -0
  282. package/package/components/triggers/azure/AzureTriggerPanel.svelte +55 -0
  283. package/package/components/triggers/azure/AzureTriggerPanel.svelte.d.ts +10 -0
  284. package/{dist/sharedUtils/components/triggers/kafka → package/components/triggers/azure}/utils.d.ts +1 -1
  285. package/package/components/triggers/azure/utils.js +56 -0
  286. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +15 -11
  287. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +22 -14
  288. package/package/components/triggers/http/RouteEditorConfigSection.svelte +15 -7
  289. package/package/components/triggers/http/RouteEditorInner.svelte +16 -14
  290. package/package/components/triggers/http/RoutesGenerator.svelte +6 -1
  291. package/package/components/triggers/http/RoutesPanel.svelte +1 -1
  292. package/package/components/triggers/http/utils.d.ts +1 -1
  293. package/package/components/triggers/http/utils.js +2 -2
  294. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +22 -14
  295. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +22 -14
  296. package/package/components/triggers/native/NativeTriggerEditor.svelte +3 -0
  297. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte +118 -0
  298. package/package/components/triggers/native/services/github/GitHubTriggerForm.svelte.d.ts +17 -0
  299. package/package/components/triggers/native/utils.js +14 -0
  300. package/package/components/triggers/nats/NatsTriggerEditor.svelte.d.ts +4 -3
  301. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +22 -14
  302. package/package/components/triggers/postgres/PostgresTriggerEditor.svelte.d.ts +4 -3
  303. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +22 -14
  304. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +22 -14
  305. package/package/components/triggers/sqs/SqsTriggerEditor.svelte.d.ts +4 -3
  306. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +22 -14
  307. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  308. package/package/components/triggers/triggers.svelte.js +24 -1
  309. package/package/components/triggers/utils.js +47 -6
  310. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +22 -14
  311. package/package/components/triggers.d.ts +1 -1
  312. package/package/components/useFolderDefaultPermissionedAs.svelte.d.ts +13 -0
  313. package/package/components/useFolderDefaultPermissionedAs.svelte.js +63 -0
  314. package/package/components/useNestedRestartState.svelte.d.ts +56 -0
  315. package/package/components/useNestedRestartState.svelte.js +320 -0
  316. package/package/components/workspaceSettings/CreateWorkspace.svelte +16 -677
  317. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte +604 -0
  318. package/package/components/workspaceSettings/CreateWorkspaceInner.svelte.d.ts +7 -0
  319. package/package/components/workspaceSettings/CustomInstanceDbSelect.svelte +27 -25
  320. package/package/components/workspaceSettings/CustomInstanceDbWizardModal.svelte +46 -8
  321. package/package/components/workspaceSettings/DataTableSettings.svelte +27 -22
  322. package/package/components/workspaceSettings/DucklakeSettings.svelte +1 -1
  323. package/package/components/workspaceSettings/ForkDatatableSection.svelte +228 -0
  324. package/package/components/workspaceSettings/ForkDatatableSection.svelte.d.ts +28 -0
  325. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +8 -2
  326. package/package/components/workspaceSettings/RulesetEditor.svelte +27 -2
  327. package/package/components/workspaceSettings/SharedUiSettings.svelte +175 -0
  328. package/package/components/workspaceSettings/SharedUiSettings.svelte.d.ts +3 -0
  329. package/package/components/workspaceSettings/VolumeStorageSettings.svelte +1 -1
  330. package/package/components/workspaceSettings/WorkspaceIntegrations.svelte +17 -1
  331. package/package/consts.d.ts +3 -0
  332. package/package/consts.js +10 -0
  333. package/package/gen/core/OpenAPI.js +1 -1
  334. package/package/gen/schemas.gen.d.ts +795 -59
  335. package/package/gen/schemas.gen.js +801 -60
  336. package/package/gen/services.gen.d.ts +475 -5
  337. package/package/gen/services.gen.js +976 -23
  338. package/package/gen/types.gen.d.ts +1865 -75
  339. package/package/githubApp.js +5 -1
  340. package/package/hubPaths.json +2 -8
  341. package/package/infer.d.ts +1 -1
  342. package/package/infer.js +50 -52
  343. package/package/infer.svelte.js +10 -1
  344. package/package/mcpEndpointTools.js +60 -4
  345. package/package/monaco_workers/sqlTypePlugin.worker.d.ts +10 -0
  346. package/package/monaco_workers/sqlTypePlugin.worker.js +39 -0
  347. package/package/script_helpers.d.ts +8 -2
  348. package/package/script_helpers.js +31 -0
  349. package/package/stores.d.ts +11 -0
  350. package/package/stores.js +6 -0
  351. package/package/system_prompts/index.d.ts +1 -0
  352. package/package/system_prompts/index.js +8 -0
  353. package/package/system_prompts/prompts.d.ts +17 -13
  354. package/package/system_prompts/prompts.js +921 -61
  355. package/package/templates/ci_test_bun.ts.template +27 -0
  356. package/package/templates/ci_test_python.py.template +26 -0
  357. package/package/utils/forkConflict.d.ts +26 -0
  358. package/package/utils/forkConflict.js +56 -0
  359. package/package/utils_deployable.d.ts +164 -121
  360. package/package/utils_deployable.js +61 -11
  361. package/package/utils_workspace_deploy.d.ts +8 -8
  362. package/package/utils_workspace_deploy.js +89 -421
  363. package/package.json +30 -6
  364. package/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +0 -2
  365. package/dist/sharedUtils/base.d.ts +0 -1
  366. package/dist/sharedUtils/cloud.d.ts +0 -1
  367. package/dist/sharedUtils/common.d.ts +0 -111
  368. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +0 -5
  369. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +0 -5
  370. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +0 -5
  371. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +0 -13
  372. package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +0 -11
  373. package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +0 -95
  374. package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +0 -6
  375. package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +0 -7
  376. package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +0 -33
  377. package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +0 -10
  378. package/dist/sharedUtils/components/apps/editor/component/components.d.ts +0 -5371
  379. package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +0 -3
  380. package/dist/sharedUtils/components/apps/editor/component/index.d.ts +0 -3
  381. package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +0 -7
  382. package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +0 -3
  383. package/dist/sharedUtils/components/apps/gridUtils.d.ts +0 -14
  384. package/dist/sharedUtils/components/apps/inputType.d.ts +0 -178
  385. package/dist/sharedUtils/components/apps/rx.d.ts +0 -29
  386. package/dist/sharedUtils/components/apps/sharedTypes.d.ts +0 -21
  387. package/dist/sharedUtils/components/apps/types.d.ts +0 -274
  388. package/dist/sharedUtils/components/assets/lib.d.ts +0 -25
  389. package/dist/sharedUtils/components/common/alert/model.d.ts +0 -2
  390. package/dist/sharedUtils/components/common/badge/model.d.ts +0 -8
  391. package/dist/sharedUtils/components/common/button/model.d.ts +0 -45
  392. package/dist/sharedUtils/components/common/fileInput/model.d.ts +0 -1
  393. package/dist/sharedUtils/components/common/index.d.ts +0 -24
  394. package/dist/sharedUtils/components/common/skeleton/model.d.ts +0 -21
  395. package/dist/sharedUtils/components/dbTypes.d.ts +0 -14
  396. package/dist/sharedUtils/components/diff_drawer.d.ts +0 -26
  397. package/dist/sharedUtils/components/ducklake.d.ts +0 -1
  398. package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +0 -7
  399. package/dist/sharedUtils/components/icons/index.d.ts +0 -101
  400. package/dist/sharedUtils/components/random_positive_adjetive.d.ts +0 -1
  401. package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +0 -10
  402. package/dist/sharedUtils/components/raw_apps/utils.d.ts +0 -15
  403. package/dist/sharedUtils/components/triggers/email/utils.d.ts +0 -4
  404. package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +0 -2
  405. package/dist/sharedUtils/components/triggers/http/utils.d.ts +0 -11
  406. package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +0 -2
  407. package/dist/sharedUtils/components/triggers/nats/utils.d.ts +0 -2
  408. package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +0 -8
  409. package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +0 -2
  410. package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +0 -32
  411. package/dist/sharedUtils/components/triggers/utils.d.ts +0 -80
  412. package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +0 -2
  413. package/dist/sharedUtils/components/triggers.d.ts +0 -20
  414. package/dist/sharedUtils/gen/core/ApiError.d.ts +0 -10
  415. package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +0 -13
  416. package/dist/sharedUtils/gen/core/ApiResult.d.ts +0 -7
  417. package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +0 -26
  418. package/dist/sharedUtils/gen/core/OpenAPI.d.ts +0 -27
  419. package/dist/sharedUtils/gen/core/request.d.ts +0 -29
  420. package/dist/sharedUtils/gen/index.d.ts +0 -6
  421. package/dist/sharedUtils/gen/schemas.gen.d.ts +0 -7036
  422. package/dist/sharedUtils/gen/services.gen.d.ts +0 -6047
  423. package/dist/sharedUtils/gen/types.gen.d.ts +0 -21881
  424. package/dist/sharedUtils/history.svelte.d.ts +0 -9
  425. package/dist/sharedUtils/hub.d.ts +0 -49
  426. package/dist/sharedUtils/jsr.json +0 -6
  427. package/dist/sharedUtils/lib.d.ts +0 -5
  428. package/dist/sharedUtils/lib.es.js +0 -1588
  429. package/dist/sharedUtils/package.json +0 -12
  430. package/dist/sharedUtils/schema.d.ts +0 -3
  431. package/dist/sharedUtils/stores.d.ts +0 -97
  432. package/dist/sharedUtils/svelte5Utils.svelte.d.ts +0 -80
  433. package/dist/sharedUtils/toast.d.ts +0 -8
  434. package/dist/sharedUtils/utils.d.ts +0 -265
  435. package/package/components/copilot/chat/__tests__/app/appChat.eval.test.js +0 -153
  436. package/package/components/copilot/chat/__tests__/app/appEvalComparison.d.ts +0 -21
  437. package/package/components/copilot/chat/__tests__/app/appEvalComparison.js +0 -136
  438. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.d.ts +0 -15
  439. package/package/components/copilot/chat/__tests__/app/appEvalHelpers.js +0 -107
  440. package/package/components/copilot/chat/__tests__/app/appEvalRunner.d.ts +0 -50
  441. package/package/components/copilot/chat/__tests__/app/appEvalRunner.js +0 -93
  442. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.d.ts +0 -29
  443. package/package/components/copilot/chat/__tests__/app/appFixtureLoader.js +0 -134
  444. package/package/components/copilot/chat/__tests__/app/appResultsWriter.d.ts +0 -30
  445. package/package/components/copilot/chat/__tests__/app/appResultsWriter.js +0 -197
  446. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.d.ts +0 -10
  447. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/main.js +0 -9
  448. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/createFolder/meta.json +0 -4
  449. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.d.ts +0 -6
  450. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/main.js +0 -5
  451. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/deleteItem/meta.json +0 -4
  452. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.d.ts +0 -12
  453. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/main.js +0 -14
  454. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFiles/meta.json +0 -4
  455. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.d.ts +0 -8
  456. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/main.js +0 -25
  457. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/listFolders/meta.json +0 -4
  458. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.d.ts +0 -7
  459. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/main.js +0 -5
  460. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/moveItem/meta.json +0 -4
  461. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.d.ts +0 -8
  462. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/main.js +0 -5
  463. package/package/components/copilot/chat/__tests__/app/initial/file_manager/backend/renameItem/meta.json +0 -4
  464. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.d.ts +0 -10
  465. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Breadcrumb.tsx +0 -26
  466. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.d.ts +0 -10
  467. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileItem.tsx +0 -79
  468. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.d.ts +0 -10
  469. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FileList.tsx +0 -46
  470. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.d.ts +0 -10
  471. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/FolderTree.tsx +0 -56
  472. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.d.ts +0 -6
  473. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/components/Toolbar.tsx +0 -59
  474. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.d.ts +0 -16
  475. package/package/components/copilot/chat/__tests__/app/initial/file_manager/frontend/index.tsx +0 -119
  476. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.d.ts +0 -15
  477. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/main.js +0 -14
  478. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/addToCart/meta.json +0 -4
  479. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.d.ts +0 -14
  480. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/main.js +0 -5
  481. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/calculateTotal/meta.json +0 -4
  482. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.d.ts +0 -6
  483. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/main.js +0 -41
  484. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/getProducts/meta.json +0 -4
  485. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.d.ts +0 -15
  486. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/main.js +0 -3
  487. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/backend/removeFromCart/meta.json +0 -4
  488. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.d.ts +0 -9
  489. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/Cart.tsx +0 -51
  490. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.d.ts +0 -8
  491. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductCard.tsx +0 -27
  492. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.d.ts +0 -8
  493. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/components/ProductList.tsx +0 -18
  494. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.d.ts +0 -12
  495. package/package/components/copilot/chat/__tests__/app/initial/shopping_cart/frontend/index.tsx +0 -81
  496. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.d.ts +0 -3
  497. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/main.js +0 -3
  498. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/decrementCounter/meta.json +0 -4
  499. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.d.ts +0 -3
  500. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/main.js +0 -3
  501. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/backend/incrementCounter/meta.json +0 -4
  502. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.d.ts +0 -2
  503. package/package/components/copilot/chat/__tests__/app/initial/test1_counter_app/frontend/index.tsx +0 -38
  504. package/package/components/copilot/chat/__tests__/app/variants/baseline.d.ts +0 -6
  505. package/package/components/copilot/chat/__tests__/app/variants/baseline.js +0 -10
  506. package/package/components/copilot/chat/__tests__/app/variants/index.d.ts +0 -3
  507. package/package/components/copilot/chat/__tests__/app/variants/index.js +0 -3
  508. package/package/components/copilot/chat/__tests__/app/variants/streamlined.d.ts +0 -6
  509. package/package/components/copilot/chat/__tests__/app/variants/streamlined.js +0 -137
  510. package/package/components/copilot/chat/__tests__/flow/expected/test1.json +0 -134
  511. package/package/components/copilot/chat/__tests__/flow/expected/test2.json +0 -183
  512. package/package/components/copilot/chat/__tests__/flow/expected/test3.json +0 -204
  513. package/package/components/copilot/chat/__tests__/flow/expected/test4.json +0 -175
  514. package/package/components/copilot/chat/__tests__/flow/expected/test5_modify_simple.json +0 -68
  515. package/package/components/copilot/chat/__tests__/flow/expected/test6_modify_medium.json +0 -142
  516. package/package/components/copilot/chat/__tests__/flow/expected/test7_modify_complex.json +0 -136
  517. package/package/components/copilot/chat/__tests__/flow/flowChat.eval.test.js +0 -294
  518. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.d.ts +0 -17
  519. package/package/components/copilot/chat/__tests__/flow/flowEvalComparison.js +0 -49
  520. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.d.ts +0 -12
  521. package/package/components/copilot/chat/__tests__/flow/flowEvalHelpers.js +0 -79
  522. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.d.ts +0 -50
  523. package/package/components/copilot/chat/__tests__/flow/flowEvalRunner.js +0 -102
  524. package/package/components/copilot/chat/__tests__/flow/initial/test5_initial.json +0 -53
  525. package/package/components/copilot/chat/__tests__/flow/initial/test6_initial.json +0 -68
  526. package/package/components/copilot/chat/__tests__/flow/initial/test7_initial.json +0 -120
  527. package/package/components/copilot/chat/__tests__/flow/variants/baseline.d.ts +0 -6
  528. package/package/components/copilot/chat/__tests__/flow/variants/baseline.js +0 -10
  529. package/package/components/copilot/chat/__tests__/flow/variants/index.d.ts +0 -3
  530. package/package/components/copilot/chat/__tests__/flow/variants/index.js +0 -3
  531. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.d.ts +0 -15
  532. package/package/components/copilot/chat/__tests__/flow/variants/minimal-single-tool.js +0 -388
  533. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.d.ts +0 -45
  534. package/package/components/copilot/chat/__tests__/shared/baseEvalRunner.js +0 -121
  535. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.d.ts +0 -28
  536. package/package/components/copilot/chat/__tests__/shared/baseLLMEvaluator.js +0 -96
  537. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.d.ts +0 -32
  538. package/package/components/copilot/chat/__tests__/shared/baseResultsWriter.js +0 -130
  539. package/package/components/copilot/chat/__tests__/shared/baseVariants.d.ts +0 -45
  540. package/package/components/copilot/chat/__tests__/shared/baseVariants.js +0 -57
  541. package/package/components/copilot/chat/__tests__/shared/index.d.ts +0 -10
  542. package/package/components/copilot/chat/__tests__/shared/index.js +0 -5
  543. package/package/components/copilot/chat/__tests__/shared/types.d.ts +0 -105
  544. package/package/components/copilot/chat/__tests__/shared/types.js +0 -9
  545. package/package/components/copilot/chat/flow/openFlowZod.js +0 -24
  546. package/package/components/copilot/chat/flow/utils.d.ts +0 -14
  547. package/package/components/copilot/chat/flow/utils.js +0 -108
  548. package/package/components/flows/agentToolUtils.test.js +0 -55
  549. /package/package/components/copilot/chat/{__tests__/app/appChat.eval.test.d.ts → app/core.test.d.ts} +0 -0
  550. /package/package/components/copilot/chat/{__tests__/flow/flowChat.eval.test.d.ts → flow/helperUtils.test.d.ts} +0 -0
  551. /package/package/components/copilot/chat/flow/{openFlowZod.d.ts → openFlowZod.gen.d.ts} +0 -0
  552. /package/package/components/{flows/agentToolUtils.test.d.ts → copilot/chat/flow/utils.test.d.ts} +0 -0
@@ -29,16 +29,6 @@ The preprocessor receives a single parameter called \`event\`.
29
29
  `;
30
30
  export const FLOW_BASE = `# Windmill Flow Building Guide
31
31
 
32
- ## CLI Commands
33
-
34
- Create a folder ending with \`__flow\` and add a \`flow.yaml\` file with the flow definition.
35
- For rawscript modules, use \`!inline path/to/script.ts\` for the content key. Inline script files should NOT include \`.inline_script.\` in their names (e.g. use \`a.ts\`, not \`a.inline_script.ts\`).
36
- After writing, tell the user they can run:
37
- - \`wmill generate-metadata\` - Generate lock files for the flow you modified
38
- - \`wmill sync push\` - Deploy to Windmill
39
-
40
- Do NOT run these commands yourself. Instead, inform the user that they should run them.
41
-
42
32
  ## OpenFlow Schema
43
33
 
44
34
  The OpenFlow schema (openflow.openapi.yaml) is the source of truth for flow structure. Refer to OPENFLOW_SCHEMA for the complete type definitions.
@@ -49,6 +39,53 @@ The OpenFlow schema (openflow.openapi.yaml) is the source of truth for flow stru
49
39
  - \`preprocessor\` - Reserved for preprocessor module
50
40
  - \`Input\` - Reserved for flow input reference
51
41
 
42
+ ## Hard Structural Rules
43
+
44
+ These are strict Windmill schema rules. Follow them exactly.
45
+
46
+ - \`value.modules\` is only for normal sequential steps
47
+ - \`value.preprocessor_module\` and \`value.failure_module\` are special top-level fields inside \`value\`, not entries in \`value.modules\`
48
+ - If a flow needs a preprocessor, create \`value.preprocessor_module\` with \`id: preprocessor\`
49
+ - If a flow needs a failure handler, create \`value.failure_module\` with \`id: failure\`
50
+ - Do NOT create regular modules inside \`value.modules\` named \`preprocessor\` or \`failure\`
51
+ - \`preprocessor_module\` and \`failure_module\` only support \`script\` or \`rawscript\`
52
+ - \`preprocessor_module\` runs before normal modules and cannot reference \`results.*\`
53
+ - \`failure_module\` can use the \`error\` object with \`error.message\`, \`error.step_id\`, \`error.name\`, and \`error.stack\`
54
+
55
+ Correct shape:
56
+
57
+ \`\`\`yaml
58
+ value:
59
+ preprocessor_module:
60
+ id: preprocessor
61
+ value:
62
+ type: rawscript
63
+ ...
64
+ failure_module:
65
+ id: failure
66
+ value:
67
+ type: rawscript
68
+ ...
69
+ modules:
70
+ - id: process_event
71
+ value:
72
+ type: rawscript
73
+ ...
74
+ \`\`\`
75
+
76
+ Incorrect shape:
77
+
78
+ \`\`\`yaml
79
+ value:
80
+ modules:
81
+ - id: preprocessor
82
+ ...
83
+ - id: process_event
84
+ ...
85
+ - id: failure
86
+ ...
87
+ \`\`\`
88
+
52
89
  ## Module ID Rules
53
90
 
54
91
  - Must be unique across the entire flow
@@ -64,10 +101,148 @@ The OpenFlow schema (openflow.openapi.yaml) is the source of truth for flow stru
64
101
  ## Data Flow Between Steps
65
102
 
66
103
  - \`flow_input.property\` - Access flow input parameters
67
- - \`results.step_id\` - Access output from a previous step
68
- - \`results.step_id.property\` - Access specific property from previous step output
69
- - \`flow_input.iter.value\` - Current item when inside a for-loop
70
- - \`flow_input.iter.index\` - Current index when inside a for-loop
104
+ - \`results.step_id\` - Access output from a previous step only when that step result is in scope
105
+ - \`results.step_id.property\` - Access specific property from a previous step output only when that step result is in scope
106
+ - \`flow_input.iter.value\` - Current iteration value when inside a loop (\`forloopflow\` or \`whileloopflow\`)
107
+ - \`flow_input.iter.index\` - Current loop index when inside a loop (\`forloopflow\` or \`whileloopflow\`)
108
+
109
+ ## Loop Structure Rules
110
+
111
+ - For \`whileloopflow\`, use module-level \`stop_after_if\` on the loop module itself when the loop should stop after an iteration result
112
+ - Do NOT put \`stop_after_if\` inside \`value\` of a \`whileloopflow\`
113
+ - \`stop_after_all_iters_if\` is for checks after the whole loop finishes, not the normal per-iteration break condition
114
+ - When a \`whileloopflow\` carries state forward between iterations, use \`flow_input.iter.value\` as the current loop value and provide an explicit first-iteration fallback when needed
115
+ - Use \`flow_input.iter.index\` only when the loop logic is truly based on the iteration index, not as a replacement for the current loop value
116
+ - If the user asks for a final scalar/object after a loop, add a normal step after the loop that extracts the final value from the loop result instead of returning the whole loop result array
117
+
118
+ Correct \`whileloopflow\` shape:
119
+
120
+ \`\`\`yaml
121
+ - id: loop_until_done
122
+ stop_after_if:
123
+ expr: result.done === true
124
+ skip_if_stopped: false
125
+ value:
126
+ type: whileloopflow
127
+ skip_failures: false
128
+ modules:
129
+ - id: advance_state
130
+ value:
131
+ type: rawscript
132
+ input_transforms:
133
+ state:
134
+ type: javascript
135
+ expr: flow_input.iter && flow_input.iter.value !== undefined ? flow_input.iter.value : flow_input.initial_state
136
+ - id: return_final_state
137
+ value:
138
+ type: rawscript
139
+ input_transforms:
140
+ final_state:
141
+ type: javascript
142
+ expr: results.loop_until_done[results.loop_until_done.length - 1]
143
+ \`\`\`
144
+
145
+ Incorrect \`whileloopflow\` patterns:
146
+
147
+ \`\`\`yaml
148
+ - id: loop_until_done
149
+ value:
150
+ type: whileloopflow
151
+ stop_after_if:
152
+ expr: result.done === true
153
+ \`\`\`
154
+
155
+ \`\`\`yaml
156
+ input_transforms:
157
+ state:
158
+ type: javascript
159
+ expr: flow_input.iter.index
160
+ \`\`\`
161
+
162
+ \`\`\`yaml
163
+ input_transforms:
164
+ final_state:
165
+ type: javascript
166
+ expr: results.loop_until_done
167
+ \`\`\`
168
+
169
+ ## Approval / Suspend Structure
170
+
171
+ - \`suspend\` belongs on the flow module object itself, as a sibling of \`id\` and \`value\`
172
+ - Never put \`suspend\` inside \`value\`
173
+
174
+ Correct shape:
175
+
176
+ \`\`\`yaml
177
+ - id: request_approval
178
+ suspend:
179
+ required_events: 1
180
+ resume_form:
181
+ schema:
182
+ type: object
183
+ properties:
184
+ comment:
185
+ type: string
186
+ required: [comment]
187
+ value:
188
+ type: identity
189
+ \`\`\`
190
+
191
+ Incorrect shape:
192
+
193
+ \`\`\`yaml
194
+ - id: request_approval
195
+ value:
196
+ type: rawscript
197
+ suspend:
198
+ required_events: 1
199
+ \`\`\`
200
+
201
+ ## Branch Result Scope Rules
202
+
203
+ - Inside a branch, you may reference earlier outer steps and earlier steps in the same branch
204
+ - Outside a \`branchone\`, do NOT reference ids of steps that only exist inside its branches or default branch. Use \`results.<branchone_module_id>\` instead
205
+ - Outside a \`branchall\`, do NOT reference ids of steps inside its branches. Use \`results.<branchall_module_id>\` instead
206
+ - If downstream steps need a stable shape after a branch, make each branch return the same fields
207
+ - When needed, add a normalization step immediately after the branch and consume \`results.<branch_module_id>\` there
208
+
209
+ Correct after \`branchone\`:
210
+
211
+ \`\`\`yaml
212
+ - id: route_order
213
+ value:
214
+ type: branchone
215
+ ...
216
+ - id: send_confirmation
217
+ value:
218
+ input_transforms:
219
+ routed:
220
+ type: javascript
221
+ expr: results.route_order
222
+ \`\`\`
223
+
224
+ Incorrect after \`branchone\`:
225
+
226
+ \`\`\`yaml
227
+ expr: results.create_shipment
228
+ expr: results.create_backorder
229
+ \`\`\`
230
+
231
+ Correct after \`branchall\`:
232
+
233
+ \`\`\`yaml
234
+ - id: enrich_parallel
235
+ value:
236
+ type: branchall
237
+ parallel: true
238
+ ...
239
+ - id: combine_data
240
+ value:
241
+ input_transforms:
242
+ enrichments:
243
+ type: javascript
244
+ expr: results.enrich_parallel
245
+ \`\`\`
71
246
 
72
247
  ## Input Transforms
73
248
 
@@ -84,14 +259,14 @@ JavaScript transform (dynamic expression):
84
259
  - For flow inputs: Use type \`"object"\` with format \`"resource-{type}"\` (e.g., \`"resource-postgresql"\`)
85
260
  - For step inputs: Use static value \`"$res:path/to/resource"\`
86
261
 
87
- ## Failure Handler
262
+ ## Final Structural Self-Check
88
263
 
89
- Executes when any step fails. Has access to error details:
264
+ Before finalizing a flow, verify:
90
265
 
91
- - \`error.message\` - Error message
92
- - \`error.step_id\` - ID of failed step
93
- - \`error.name\` - Error name
94
- - \`error.stack\` - Stack trace
266
+ - any preprocessor is in \`value.preprocessor_module\`
267
+ - any failure handler is in \`value.failure_module\`
268
+ - any approval step has module-level \`suspend\`
269
+ - no downstream step references inner branch step ids from outside the branch
95
270
 
96
271
  ## S3 Object Operations
97
272
 
@@ -146,6 +321,224 @@ Reference a specific resource using \`$res:\` prefix:
146
321
  }
147
322
  \`\`\`
148
323
  `;
324
+ export const WORKFLOW_AS_CODE_BASE = `# Windmill Workflow-as-Code Writing Guide
325
+
326
+ ## Scope
327
+
328
+ Use this guide when writing or modifying Windmill Workflow-as-Code (WAC) scripts.
329
+ WAC is authored as a Windmill script and deployed with the normal script workflow. It is not an OpenFlow YAML flow.
330
+
331
+ Supported WAC authoring targets:
332
+ - TypeScript scripts that import from \`windmill-client\`
333
+ - Python 3 scripts that import from \`wmill\`
334
+
335
+ ## File Shape
336
+
337
+ TypeScript:
338
+
339
+ \`\`\`typescript
340
+ import {
341
+ task,
342
+ taskScript,
343
+ taskFlow,
344
+ step,
345
+ sleep,
346
+ waitForApproval,
347
+ getResumeUrls,
348
+ parallel,
349
+ workflow,
350
+ } from "windmill-client";
351
+
352
+ const process = task(async (x: string): Promise<string> => {
353
+ return \`processed: \${x}\`;
354
+ });
355
+
356
+ export const main = workflow(async (x: string) => {
357
+ const result = await process(x);
358
+ return { result };
359
+ });
360
+ \`\`\`
361
+
362
+ Python:
363
+
364
+ \`\`\`python
365
+ from wmill import task, task_script, task_flow, step, sleep, wait_for_approval, get_resume_urls, parallel, workflow
366
+
367
+ @task()
368
+ async def process(x: str) -> str:
369
+ return f"processed: {x}"
370
+
371
+ @workflow
372
+ async def main(x: str):
373
+ result = await process(x)
374
+ return {"result": result}
375
+ \`\`\`
376
+
377
+ Rules:
378
+ - Do not call \`main\`.
379
+ - TypeScript should export the workflow entrypoint, preferably \`export const main = workflow(async (...) => { ... })\`.
380
+ - Python must use \`@workflow\` on an async top-level function, usually \`main\`.
381
+ - Define task functions and \`taskScript\`/\`task_script\` or \`taskFlow\`/\`task_flow\` assignments at module top level with stable names.
382
+ - Use the exact SDK names. Do not alias \`workflow\`, \`task\`, \`taskScript\`, \`taskFlow\`, \`step\`, \`sleep\`, \`waitForApproval\`, \`task_script\`, \`task_flow\`, or \`wait_for_approval\`; the WAC parser recognizes these names directly.
383
+
384
+ ## Checkpoint And Replay Model
385
+
386
+ The parent workflow may rerun from the top after any suspension, retry, approval, or child task completion. Completed durable steps are replayed from the checkpoint.
387
+
388
+ Put every side effect or non-deterministic value behind a durable WAC boundary:
389
+ - Use \`task()\` / \`@task()\` for substantial work that should run as its own child job.
390
+ - Use \`taskScript()\` / \`task_script()\` for an existing script or a relative module file.
391
+ - Use \`taskFlow()\` / \`task_flow()\` for an existing Windmill flow.
392
+ - Use \`step(name, fn)\` for lightweight inline work whose result must be checkpointed.
393
+ - Use \`sleep(seconds)\` for server-side sleeps that do not hold a worker.
394
+ - Use \`waitForApproval()\` / \`wait_for_approval()\` for external approval suspension.
395
+
396
+ Never put API calls, database writes, notifications, random values, timestamps, or irreversible changes directly in the top-level workflow body. The workflow body can be rerun. Put those operations in a task or in \`step()\`.
397
+
398
+ Branching on task or step results is safe because those results are checkpointed. Branching on current time, random data, environment reads, or external state is unsafe unless the value is first captured with \`step()\`.
399
+
400
+ ## Tasks
401
+
402
+ Use \`task()\` / \`@task()\` for inline functions that become workflow steps:
403
+
404
+ \`\`\`typescript
405
+ const enrich = task(async (customerId: string) => {
406
+ return await fetchCustomer(customerId);
407
+ });
408
+ \`\`\`
409
+
410
+ \`\`\`python
411
+ @task(timeout=600, tag="etl")
412
+ async def enrich(customer_id: str):
413
+ return await fetch_customer(customer_id)
414
+ \`\`\`
415
+
416
+ In TypeScript, prefer assigning each task to a named top-level const. In Python, prefer top-level async functions decorated with \`@task()\` or \`@task\`.
417
+
418
+ For existing scripts:
419
+
420
+ \`\`\`typescript
421
+ const helper = taskScript("./helper.ts");
422
+ const existing = taskScript("f/data/extract", { timeout: 600 });
423
+ const value = await helper({ input: x });
424
+ \`\`\`
425
+
426
+ \`\`\`python
427
+ helper = task_script("./helper.py")
428
+ existing = task_script("f/data/extract", timeout=600)
429
+ value = await helper(input=x)
430
+ \`\`\`
431
+
432
+ For existing flows:
433
+
434
+ \`\`\`typescript
435
+ const pipeline = taskFlow("f/etl/pipeline");
436
+ const output = await pipeline({ input: data });
437
+ \`\`\`
438
+
439
+ \`\`\`python
440
+ pipeline = task_flow("f/etl/pipeline")
441
+ output = await pipeline(input=data)
442
+ \`\`\`
443
+
444
+ ## Inline Steps
445
+
446
+ Use \`step()\` for lightweight inline values that must not change during replay:
447
+
448
+ \`\`\`typescript
449
+ const urls = await step("get_urls", () => getResumeUrls());
450
+ const startedAt = await step("started_at", () => new Date().toISOString());
451
+ \`\`\`
452
+
453
+ \`\`\`python
454
+ urls = await step("get_urls", lambda: get_resume_urls())
455
+ \`\`\`
456
+
457
+ Use stable, descriptive step names. Do not generate step names dynamically.
458
+
459
+ ## Parallelism
460
+
461
+ To run independent work in parallel, start task promises/coroutines before awaiting them together:
462
+
463
+ \`\`\`typescript
464
+ const [a, b] = await Promise.all([process("a"), process("b")]);
465
+ const many = await parallel(items, process, { concurrency: 5 });
466
+ \`\`\`
467
+
468
+ \`\`\`python
469
+ import asyncio
470
+
471
+ a, b = await asyncio.gather(process("a"), process("b"))
472
+ many = await parallel(items, process, concurrency=5)
473
+ \`\`\`
474
+
475
+ Only parallelize independent steps. Do not read the result of a task before it is awaited.
476
+
477
+ ## Approvals
478
+
479
+ Generate resume URLs inside \`step()\` before sending them:
480
+
481
+ \`\`\`typescript
482
+ const urls = await step("get_urls", () => getResumeUrls());
483
+ await step("notify", () => sendApprovalEmail(urls.approvalPage));
484
+ const approval = await waitForApproval({ timeout: 3600 });
485
+ \`\`\`
486
+
487
+ \`\`\`python
488
+ urls = await step("get_urls", lambda: get_resume_urls())
489
+ await step("notify", lambda: send_approval_email(urls["approvalPage"]))
490
+ approval = await wait_for_approval(timeout=3600)
491
+ \`\`\`
492
+
493
+ \`selfApproval: false\` and \`self_approval=False\` are Enterprise-only approval behavior. Do not use them unless the user asks for that behavior.
494
+
495
+ ## Error Handling
496
+
497
+ Let task errors fail the workflow unless the user asks for recovery logic.
498
+
499
+ Python: \`except Exception\` is safe around WAC calls because internal suspension inherits from \`BaseException\`. Avoid bare \`except:\` in workflow code. If the user asks for recovery logic around failed child work, catch \`TaskError\` from \`wmill\` for task failures.
500
+
501
+ TypeScript: avoid broad \`try/catch\` around WAC SDK calls. The SDK uses an internal suspension error during initial dispatch; catching it can break workflow suspension. If a broad catch is unavoidable, rethrow internal suspension errors before handling business errors.
502
+ `;
503
+ export const FLOW_CHAT_SPECIAL_MODULES = `## Special Modules
504
+
505
+ - Use \`set_preprocessor_module\` to add, replace, or remove the top-level \`value.preprocessor_module\`
506
+ - Use \`set_failure_module\` to add, replace, or remove the top-level \`value.failure_module\`
507
+ - Use \`set_flow_json\` only when you are replacing the whole flow, including normal modules and optional special modules
508
+
509
+ **Example - Update only the special modules:**
510
+ \`\`\`javascript
511
+ set_preprocessor_module({
512
+ module: JSON.stringify({
513
+ id: "preprocessor",
514
+ value: {
515
+ type: "rawscript",
516
+ language: "bun",
517
+ content: "export async function preprocessor(payload: string) { const trimmed = payload.trim(); if (!trimmed) { throw new Error('payload must not be empty'); } return { payload: trimmed }; }",
518
+ input_transforms: {
519
+ payload: { type: "javascript", expr: "flow_input.payload" }
520
+ }
521
+ }
522
+ })
523
+ })
524
+
525
+ set_failure_module({
526
+ module: JSON.stringify({
527
+ id: "failure",
528
+ value: {
529
+ type: "rawscript",
530
+ language: "bun",
531
+ content: "export async function main(message: string, name: string, step_id: string) { return { message, name, step_id }; }",
532
+ input_transforms: {
533
+ message: { type: "javascript", expr: "error.message" },
534
+ name: { type: "javascript", expr: "error.name" },
535
+ step_id: { type: "javascript", expr: "error.step_id" }
536
+ }
537
+ }
538
+ })
539
+ })
540
+ \`\`\`
541
+ `;
149
542
  export const SDK_TYPESCRIPT = `# TypeScript SDK (windmill-client)
150
543
 
151
544
  Import: import * as wmill from 'windmill-client'
@@ -1374,6 +1767,223 @@ async def parallel(items, fn, concurrency: Optional[int] = None)
1374
1767
  # offset: Message offset to commit (from event['offset'])
1375
1768
  def commit_kafka_offsets(trigger_path: str, topic: str, partition: int, offset: int) -> None
1376
1769
 
1770
+ `;
1771
+ export const WAC_SDK_TYPESCRIPT = `## TypeScript Workflow-as-Code API (windmill-client)
1772
+
1773
+ Import: \`import { workflow, task, taskScript, taskFlow, step, sleep, waitForApproval, getResumeUrls, parallel } from "windmill-client"\`
1774
+
1775
+ \`\`\`typescript
1776
+ export interface TaskOptions {
1777
+ timeout?: number;
1778
+ tag?: string;
1779
+ cache_ttl?: number;
1780
+ priority?: number;
1781
+ concurrency_limit?: number;
1782
+ concurrency_key?: string;
1783
+ concurrency_time_window_s?: number;
1784
+ }
1785
+
1786
+ /**
1787
+ * Get URLs needed for resuming a flow after this step
1788
+ * @param approver approver name
1789
+ * @param flowLevel if true, generate resume URLs for the parent flow instead of the specific step.
1790
+ * This allows pre-approvals that can be consumed by any later suspend step in the same flow.
1791
+ * @returns approval page UI URL, resume and cancel API URLs for resuming the flow
1792
+ */
1793
+ export async function getResumeUrls(approver?: string, flowLevel?: boolean): Promise<{ approvalPage: string; resume: string; cancel: string; }>
1794
+
1795
+ /**
1796
+ * Wrap an async function as a workflow task.
1797
+ *
1798
+ * @example
1799
+ * const extract_data = task(async (url: string) => { ... });
1800
+ * const run_external = task("f/external_script", async (x: number) => { ... });
1801
+ *
1802
+ * Inside a \`workflow()\`, calling a task dispatches it as a step.
1803
+ * Outside a workflow, the function body executes directly.
1804
+ */
1805
+ export function task<T extends (...args: any[]) => Promise<any>>(fnOrPath: T | string, maybeFnOrOptions?: T | TaskOptions, maybeOptions?: TaskOptions,): T
1806
+
1807
+ /**
1808
+ * Create a task that dispatches to a separate Windmill script.
1809
+ *
1810
+ * @example
1811
+ * const extract = taskScript("f/data/extract");
1812
+ * // inside workflow: await extract({ url: "https://..." })
1813
+ */
1814
+ export function taskScript(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
1815
+
1816
+ /**
1817
+ * Create a task that dispatches to a separate Windmill flow.
1818
+ *
1819
+ * @example
1820
+ * const pipeline = taskFlow("f/etl/pipeline");
1821
+ * // inside workflow: await pipeline({ input: data })
1822
+ */
1823
+ export function taskFlow(path: string, options?: TaskOptions): (...args: any[]) => PromiseLike<any>
1824
+
1825
+ /**
1826
+ * Mark an async function as a workflow-as-code entry point.
1827
+ *
1828
+ * The function must be **deterministic**: given the same inputs it must call
1829
+ * tasks in the same order on every replay. Branching on task results is fine
1830
+ * (results are replayed from checkpoint), but branching on external state
1831
+ * (current time, random values, external API calls) must use \`step()\` to
1832
+ * checkpoint the value so replays see the same result.
1833
+ */
1834
+ export function workflow<T>(fn: (...args: any[]) => Promise<T>)
1835
+
1836
+ export async function step<T>(name: string, fn: () => T | Promise<T>): Promise<T>
1837
+
1838
+ export async function sleep(seconds: number): Promise<void>
1839
+
1840
+ /**
1841
+ * Suspend the workflow and wait for an external approval.
1842
+ *
1843
+ * Use \`getResumeUrls()\` (wrapped in \`step()\`) to obtain resume/cancel/approvalPage
1844
+ * URLs before calling this function.
1845
+ *
1846
+ * @example
1847
+ * const urls = await step("urls", () => getResumeUrls());
1848
+ * await step("notify", () => sendEmail(urls.approvalPage));
1849
+ * const { value, approver } = await waitForApproval({ timeout: 3600 });
1850
+ */
1851
+ export function waitForApproval(options?: { timeout?: number; form?: object; selfApproval?: boolean; }): PromiseLike<{ value: any; approver: string; approved: boolean }>
1852
+
1853
+ /**
1854
+ * Process items in parallel with optional concurrency control.
1855
+ *
1856
+ * Each item is processed by calling \`fn(item)\`, which should be a task().
1857
+ * Items are dispatched in batches of \`concurrency\` (default: all at once).
1858
+ *
1859
+ * @example
1860
+ * const process = task(async (item: string) => { ... });
1861
+ * const results = await parallel(items, process, { concurrency: 5 });
1862
+ */
1863
+ export async function parallel<T, R>(items: T[], fn: (item: T) => PromiseLike<R> | R, options?: { concurrency?: number },): Promise<R[]>
1864
+ \`\`\`
1865
+ `;
1866
+ export const WAC_SDK_PYTHON = `## Python Workflow-as-Code API (wmill)
1867
+
1868
+ Import: \`from wmill import workflow, task, task_script, task_flow, step, sleep, wait_for_approval, get_resume_urls, parallel, TaskError\`
1869
+
1870
+ \`\`\`python
1871
+ # Raised when a WAC task step failed.
1872
+ #
1873
+ # Attributes:
1874
+ # step_key: The checkpoint key of the failed step.
1875
+ # child_job_id: The UUID of the failed child job.
1876
+ # result: The error result from the child job.
1877
+ class TaskError(Exception):
1878
+ def __init__(self, message: str, *, step_key: str = '', child_job_id: str = '', result = None)
1879
+
1880
+ # Get URLs needed for resuming a flow after suspension.
1881
+ #
1882
+ # Args:
1883
+ # approver: Optional approver name
1884
+ # flow_level: If True, generate resume URLs for the parent flow instead of the
1885
+ # specific step. This allows pre-approvals that can be consumed by any later
1886
+ # suspend step in the same flow.
1887
+ #
1888
+ # Returns:
1889
+ # Dictionary with approvalPage, resume, and cancel URLs
1890
+ def get_resume_urls(approver: str = None, flow_level: bool = None) -> dict
1891
+
1892
+ # Decorator that marks a function as a workflow task.
1893
+ #
1894
+ # Works in both WAC v1 (sync, HTTP-based dispatch) and WAC v2
1895
+ # (async, checkpoint/replay) modes:
1896
+ #
1897
+ # - **v2 (inside @workflow)**: dispatches as a checkpoint step.
1898
+ # - **v1 (WM_JOB_ID set, no @workflow)**: dispatches via HTTP API.
1899
+ # - **Standalone**: executes the function body directly.
1900
+ #
1901
+ # Usage::
1902
+ #
1903
+ # @task
1904
+ # async def extract_data(url: str): ...
1905
+ #
1906
+ # @task(path="f/external_script", timeout=600, tag="gpu")
1907
+ # async def run_external(x: int): ...
1908
+ def task(_func = None, *, path: Optional[str] = None, tag: Optional[str] = None, timeout: Optional[int] = None, cache_ttl: Optional[int] = None, priority: Optional[int] = None, concurrency_limit: Optional[int] = None, concurrency_key: Optional[str] = None, concurrency_time_window_s: Optional[int] = None)
1909
+
1910
+ # Create a task that dispatches to a separate Windmill script.
1911
+ #
1912
+ # Usage::
1913
+ #
1914
+ # extract = task_script("f/data/extract", timeout=600)
1915
+ #
1916
+ # @workflow
1917
+ # async def main():
1918
+ # data = await extract(url="https://...")
1919
+ def task_script(path: str, *, timeout: Optional[int] = None, tag: Optional[str] = None, cache_ttl: Optional[int] = None, priority: Optional[int] = None, concurrency_limit: Optional[int] = None, concurrency_key: Optional[str] = None, concurrency_time_window_s: Optional[int] = None)
1920
+
1921
+ # Create a task that dispatches to a separate Windmill flow.
1922
+ #
1923
+ # Usage::
1924
+ #
1925
+ # pipeline = task_flow("f/etl/pipeline", priority=10)
1926
+ #
1927
+ # @workflow
1928
+ # async def main():
1929
+ # result = await pipeline(input=data)
1930
+ def task_flow(path: str, *, timeout: Optional[int] = None, tag: Optional[str] = None, cache_ttl: Optional[int] = None, priority: Optional[int] = None, concurrency_limit: Optional[int] = None, concurrency_key: Optional[str] = None, concurrency_time_window_s: Optional[int] = None)
1931
+
1932
+ # Decorator marking an async function as a workflow-as-code entry point.
1933
+ #
1934
+ # The function must be **deterministic**: given the same inputs it must call
1935
+ # tasks in the same order on every replay. Branching on task results is fine
1936
+ # (results are replayed from checkpoint), but branching on external state
1937
+ # (current time, random values, external API calls) must use \`\`step()\`\` to
1938
+ # checkpoint the value so replays see the same result.
1939
+ def workflow(func)
1940
+
1941
+ # Execute \`\`fn\`\` inline and checkpoint the result.
1942
+ #
1943
+ # On replay the cached value is returned without re-executing \`\`fn\`\`.
1944
+ # Use for lightweight deterministic operations (timestamps, random IDs,
1945
+ # config reads) that should not incur the overhead of a child job.
1946
+ async def step(name: str, fn)
1947
+
1948
+ # Server-side sleep — suspend the workflow for the given duration without holding a worker.
1949
+ #
1950
+ # Inside a @workflow, the parent job suspends and auto-resumes after \`\`seconds\`\`.
1951
+ # Outside a workflow, falls back to \`\`asyncio.sleep\`\`.
1952
+ async def sleep(seconds: int)
1953
+
1954
+ # Suspend the workflow and wait for an external approval.
1955
+ #
1956
+ # Use \`\`get_resume_urls()\`\` (wrapped in \`\`step()\`\`) to obtain
1957
+ # resume/cancel/approval URLs before calling this function.
1958
+ #
1959
+ # Returns a dict with \`\`value\`\` (form data), \`\`approver\`\`, and \`\`approved\`\`.
1960
+ #
1961
+ # Args:
1962
+ # timeout: Approval timeout in seconds (default 1800).
1963
+ # form: Optional form schema for the approval page.
1964
+ # self_approval: Whether the user who triggered the flow can approve it (default True).
1965
+ #
1966
+ # Example::
1967
+ #
1968
+ # urls = await step("urls", lambda: get_resume_urls())
1969
+ # await step("notify", lambda: send_email(urls["approvalPage"]))
1970
+ # result = await wait_for_approval(timeout=3600)
1971
+ async def wait_for_approval(timeout: int = 1800, form: dict | None = None, self_approval: bool = True) -> dict
1972
+
1973
+ # Process items in parallel with optional concurrency control.
1974
+ #
1975
+ # Each item is processed by calling \`\`fn(item)\`\`, which should be a @task.
1976
+ # Items are dispatched in batches of \`\`concurrency\`\` (default: all at once).
1977
+ #
1978
+ # Example::
1979
+ #
1980
+ # @task
1981
+ # async def process(item: str):
1982
+ # ...
1983
+ #
1984
+ # results = await parallel(items, process, concurrency=5)
1985
+ async def parallel(items, fn, *, concurrency: Optional[int] = None)
1986
+ \`\`\`
1377
1987
  `;
1378
1988
  export const DATATABLE_SDK_TYPESCRIPT = `## TypeScript Datatable API (windmill-client)
1379
1989
 
@@ -1523,7 +2133,7 @@ class SqlQuery:
1523
2133
  `;
1524
2134
  export const OPENFLOW_SCHEMA = `## OpenFlow Schema
1525
2135
 
1526
- {"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_use":{"type":"boolean","description":"If true, this step's result is deleted after use to save memory"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`;
2136
+ {"OpenFlow":{"type":"object","description":"Top-level flow definition containing metadata, configuration, and the flow structure","properties":{"summary":{"type":"string","description":"Short description of what this flow does"},"description":{"type":"string","description":"Detailed documentation for this flow"},"value":{"$ref":"#/components/schemas/FlowValue"},"schema":{"type":"object","description":"JSON Schema for flow inputs. Use this to define input parameters, their types, defaults, and validation. For resource inputs, set type to 'object' and format to 'resource-<type>' (e.g., 'resource-stripe')"},"on_behalf_of_email":{"type":"string","description":"The flow will be run with the permissions of the user with this email."}},"required":["summary","value"]},"FlowValue":{"type":"object","description":"The flow structure containing modules and optional preprocessor/failure handlers","properties":{"modules":{"type":"array","description":"Array of steps that execute in sequence. Each step can be a script, subflow, loop, or branch","items":{"$ref":"#/components/schemas/FlowModule"}},"failure_module":{"description":"Special module that executes when the flow fails. Receives error object with message, name, stack, and step_id. Must have id 'failure'. Only supports script/rawscript types","$ref":"#/components/schemas/FlowModule"},"preprocessor_module":{"description":"Special module that runs before the first step on external triggers. Must have id 'preprocessor'. Only supports script/rawscript types. Cannot reference other step results","$ref":"#/components/schemas/FlowModule"},"same_worker":{"type":"boolean","description":"If true, all steps run on the same worker for better performance"},"concurrent_limit":{"type":"number","description":"Maximum number of concurrent executions of this flow"},"concurrency_key":{"type":"string","description":"Expression to group concurrent executions (e.g., by user ID)"},"concurrency_time_window_s":{"type":"number","description":"Time window in seconds for concurrent_limit"},"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce flow executions"},"debounce_key":{"type":"string","description":"Expression to group debounced executions"},"debounce_args_to_accumulate":{"type":"array","description":"Arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds that a job can be debounced"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of times a job can be debounced"},"skip_expr":{"type":"string","description":"JavaScript expression to conditionally skip the entire flow"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for flow results"},"cache_ignore_s3_path":{"type":"boolean"},"delete_after_secs":{"type":"integer","description":"If set, delete the flow job's args, result and logs after this many seconds following job completion"},"flow_env":{"type":"object","description":"Environment variables available to all steps. Values can be strings, JSON values, or special references: '$var:path' (workspace variable) or '$res:path' (resource).","additionalProperties":{}},"priority":{"type":"number","description":"Execution priority (higher numbers run first)"},"early_return":{"type":"string","description":"JavaScript expression to return early from the flow"},"chat_input_enabled":{"type":"boolean","description":"Whether this flow accepts chat-style input"},"notes":{"type":"array","description":"Sticky notes attached to the flow","items":{"$ref":"#/components/schemas/FlowNote"}},"groups":{"type":"array","description":"Semantic groups of modules for organizational purposes","items":{"$ref":"#/components/schemas/FlowGroup"}}},"required":["modules"]},"Retry":{"type":"object","description":"Retry configuration for failed module executions","properties":{"constant":{"type":"object","description":"Retry with constant delay between attempts","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"seconds":{"type":"integer","description":"Seconds to wait between retries"}}},"exponential":{"type":"object","description":"Retry with exponential backoff (delay doubles each time)","properties":{"attempts":{"type":"integer","description":"Number of retry attempts"},"multiplier":{"type":"integer","description":"Multiplier for exponential backoff"},"seconds":{"type":"integer","minimum":1,"description":"Initial delay in seconds"},"random_factor":{"type":"integer","minimum":0,"maximum":100,"description":"Random jitter percentage (0-100) to avoid thundering herd"}}},"retry_if":{"$ref":"#/components/schemas/RetryIf"}}},"FlowNote":{"type":"object","description":"A sticky note attached to a flow for documentation and annotation","properties":{"id":{"type":"string","description":"Unique identifier for the note"},"text":{"type":"string","description":"Content of the note"},"position":{"type":"object","description":"Position of the note in the flow editor","properties":{"x":{"type":"number","description":"X coordinate"},"y":{"type":"number","description":"Y coordinate"}},"required":["x","y"]},"size":{"type":"object","description":"Size of the note in the flow editor","properties":{"width":{"type":"number","description":"Width in pixels"},"height":{"type":"number","description":"Height in pixels"}},"required":["width","height"]},"color":{"type":"string","description":"Color of the note (e.g., \\"yellow\\", \\"#ffff00\\")"},"type":{"type":"string","enum":["free","group"],"description":"Type of note - 'free' for standalone notes, 'group' for notes that group other nodes"},"locked":{"type":"boolean","default":false,"description":"Whether the note is locked and cannot be edited or moved"},"contained_node_ids":{"type":"array","items":{"type":"string"},"description":"For group notes, the IDs of nodes contained within this group"}},"required":["id","text","color","type"]},"FlowGroup":{"type":"object","description":"A semantic group of flow modules for organizational purposes. Does not affect execution \\u2014 modules remain in their original position in the flow. Groups provide naming and collapsibility in the editor. Members are computed dynamically from all nodes on paths between start_id and end_id.","properties":{"summary":{"type":"string","description":"Display name for this group"},"note":{"type":"string","description":"Markdown note shown below the group header"},"autocollapse":{"type":"boolean","default":false,"description":"If true, this group is collapsed by default in the flow editor. UI hint only."},"start_id":{"type":"string","description":"ID of the first flow module in this group (topological entry point)"},"end_id":{"type":"string","description":"ID of the last flow module in this group (topological exit point)"},"color":{"type":"string","description":"Color for the group in the flow editor"}},"required":["start_id","end_id"]},"RetryIf":{"type":"object","description":"Conditional retry based on error or result","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to retry. Has access to 'result' and 'error' variables"}},"required":["expr"]},"StopAfterIf":{"type":"object","description":"Early termination condition for a module","properties":{"skip_if_stopped":{"type":"boolean","description":"If true, following steps are skipped when this condition triggers"},"expr":{"type":"string","description":"JavaScript expression evaluated after the module runs. Can use 'result' (step's result) or 'flow_input'. Return true to stop"},"error_message":{"type":"string","nullable":true,"description":"Custom error message when stopping with an error. Mutually exclusive with skip_if_stopped. If set to a non-empty string, the flow stops with this error. If empty string, a default error message is used. If null or omitted, no error is raised."}},"required":["expr"]},"FlowModule":{"type":"object","description":"A single step in a flow. Can be a script, subflow, loop, or branch","properties":{"id":{"type":"string","description":"Unique identifier for this step. Used to reference results via 'results.step_id'. Must be a valid identifier (alphanumeric, underscore, hyphen)"},"value":{"$ref":"#/components/schemas/FlowModuleValue"},"stop_after_if":{"description":"Early termination condition evaluated after this step completes","$ref":"#/components/schemas/StopAfterIf"},"stop_after_all_iters_if":{"description":"For loops only - early termination condition evaluated after all iterations complete","$ref":"#/components/schemas/StopAfterIf"},"skip_if":{"type":"object","description":"Conditionally skip this step based on previous results or flow inputs","properties":{"expr":{"type":"string","description":"JavaScript expression that returns true to skip. Can use 'flow_input' or 'results.<step_id>'"}},"required":["expr"]},"sleep":{"description":"Delay before executing this step (in seconds or as expression)","$ref":"#/components/schemas/InputTransform"},"cache_ttl":{"type":"number","description":"Cache duration in seconds for this step's results"},"cache_ignore_s3_path":{"type":"boolean"},"timeout":{"description":"Maximum execution time in seconds (static value or expression)","$ref":"#/components/schemas/InputTransform"},"delete_after_secs":{"type":"integer","description":"If set, delete the step's args, result and logs after this many seconds following job completion"},"summary":{"type":"string","description":"Short description of what this step does"},"mock":{"type":"object","description":"Mock configuration for testing without executing the actual step","properties":{"enabled":{"type":"boolean","description":"If true, return mock value instead of executing"},"return_value":{"description":"Value to return when mocked"}}},"suspend":{"type":"object","description":"Configuration for approval/resume steps that wait for user input","properties":{"required_events":{"type":"integer","description":"Number of approvals required before continuing"},"timeout":{"type":"integer","description":"Timeout in seconds before auto-continuing or canceling"},"resume_form":{"type":"object","description":"Form schema for collecting input when resuming","properties":{"schema":{"type":"object","description":"JSON Schema for the resume form"}}},"user_auth_required":{"type":"boolean","description":"If true, only authenticated users can approve"},"user_groups_required":{"description":"Expression or list of groups that can approve","$ref":"#/components/schemas/InputTransform"},"self_approval_disabled":{"type":"boolean","description":"If true, the user who started the flow cannot approve"},"hide_cancel":{"type":"boolean","description":"If true, hide the cancel button on the approval form"},"continue_on_disapprove_timeout":{"type":"boolean","description":"If true, continue flow on timeout instead of canceling"}}},"priority":{"type":"number","description":"Execution priority for this step (higher numbers run first)"},"continue_on_error":{"type":"boolean","description":"If true, flow continues even if this step fails"},"retry":{"description":"Retry configuration if this step fails","$ref":"#/components/schemas/Retry"},"debouncing":{"description":"Debounce configuration for this step (EE only)","type":"object","properties":{"debounce_delay_s":{"type":"integer","description":"Delay in seconds to debounce this step's executions across flow runs"},"debounce_key":{"type":"string","description":"Expression to group debounced executions. Supports $workspace and $args[name]. Default: $workspace/flow/<flow_path>-<step_id>"},"debounce_args_to_accumulate":{"type":"array","description":"Array-type arguments to accumulate across debounced executions","items":{"type":"string"}},"max_total_debouncing_time":{"type":"integer","description":"Maximum total time in seconds before forced execution"},"max_total_debounces_amount":{"type":"integer","description":"Maximum number of debounces before forced execution"}}}},"required":["value","id"]},"InputTransform":{"description":"Maps input parameters for a step. Can be a static value or a JavaScript expression that references previous results or flow inputs","oneOf":[{"$ref":"#/components/schemas/StaticTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"StaticTransform":{"type":"object","description":"Static value passed directly to the step. Use for hardcoded values or resource references like '$res:path/to/resource'","properties":{"value":{"description":"The static value. For resources, use format '$res:path/to/resource'"},"type":{"type":"string","enum":["static"]}},"required":["type"]},"JavascriptTransform":{"type":"object","description":"JavaScript expression evaluated at runtime. Can reference previous step results via 'results.step_id' or flow inputs via 'flow_input.property'. Inside loops, use 'flow_input.iter.value' for the current iteration value","properties":{"expr":{"type":"string","description":"JavaScript expression returning the value. Available variables - results (object with all previous step results), flow_input (flow inputs), flow_input.iter (in loops)"},"type":{"type":"string","enum":["javascript"]}},"required":["expr","type"]},"AiTransform":{"type":"object","description":"Value resolved by the AI runtime for this input. The AI engine decides how to satisfy the parameter.","properties":{"type":{"type":"string","enum":["ai"]}},"required":["type"]},"AIProviderKind":{"type":"string","description":"Supported AI provider types","enum":["openai","azure_openai","anthropic","mistral","deepseek","googleai","groq","openrouter","togetherai","customai","aws_bedrock"]},"ProviderConfig":{"type":"object","description":"Complete AI provider configuration with resource reference and model selection","properties":{"kind":{"$ref":"#/components/schemas/AIProviderKind"},"resource":{"type":"string","description":"Resource reference in format '$res:{resource_path}' pointing to provider credentials"},"model":{"type":"string","description":"Model identifier (e.g., 'gpt-4', 'claude-3-opus-20240229', 'gemini-pro')"}},"required":["kind","resource","model"]},"StaticProviderTransform":{"type":"object","description":"Static provider configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/ProviderConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"ProviderTransform":{"description":"Provider configuration - can be static (ProviderConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticProviderTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticProviderTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"MemoryOff":{"type":"object","description":"No conversation memory/context","properties":{"kind":{"type":"string","enum":["off"]}},"required":["kind"]},"MemoryAuto":{"type":"object","description":"Automatic context management","properties":{"kind":{"type":"string","enum":["auto"]},"context_length":{"type":"integer","description":"Maximum number of messages to retain in context"},"memory_id":{"type":"string","description":"Identifier for persistent memory across agent invocations"}},"required":["kind"]},"MemoryMessage":{"type":"object","description":"A single message in conversation history","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"MemoryManual":{"type":"object","description":"Explicit message history","properties":{"kind":{"type":"string","enum":["manual"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/MemoryMessage"}}},"required":["kind","messages"]},"MemoryConfig":{"description":"Conversation memory configuration","oneOf":[{"$ref":"#/components/schemas/MemoryOff"},{"$ref":"#/components/schemas/MemoryAuto"},{"$ref":"#/components/schemas/MemoryManual"}],"discriminator":{"propertyName":"kind","mapping":{"off":"#/components/schemas/MemoryOff","auto":"#/components/schemas/MemoryAuto","manual":"#/components/schemas/MemoryManual"}}},"StaticMemoryTransform":{"type":"object","description":"Static memory configuration passed directly to the AI agent","properties":{"value":{"$ref":"#/components/schemas/MemoryConfig"},"type":{"type":"string","enum":["static"]}},"required":["type","value"]},"MemoryTransform":{"description":"Memory configuration - can be static (MemoryConfig), JavaScript expression, or AI-determined","oneOf":[{"$ref":"#/components/schemas/StaticMemoryTransform"},{"$ref":"#/components/schemas/JavascriptTransform"},{"$ref":"#/components/schemas/AiTransform"}],"discriminator":{"propertyName":"type","mapping":{"static":"#/components/schemas/StaticMemoryTransform","javascript":"#/components/schemas/JavascriptTransform","ai":"#/components/schemas/AiTransform"}}},"FlowModuleValue":{"description":"The actual implementation of a flow step. Can be a script (inline or referenced), subflow, loop, branch, or special module type","oneOf":[{"$ref":"#/components/schemas/RawScript"},{"$ref":"#/components/schemas/PathScript"},{"$ref":"#/components/schemas/PathFlow"},{"$ref":"#/components/schemas/ForloopFlow"},{"$ref":"#/components/schemas/WhileloopFlow"},{"$ref":"#/components/schemas/BranchOne"},{"$ref":"#/components/schemas/BranchAll"},{"$ref":"#/components/schemas/Identity"},{"$ref":"#/components/schemas/AiAgent"}],"discriminator":{"propertyName":"type","mapping":{"rawscript":"#/components/schemas/RawScript","script":"#/components/schemas/PathScript","flow":"#/components/schemas/PathFlow","forloopflow":"#/components/schemas/ForloopFlow","whileloopflow":"#/components/schemas/WhileloopFlow","branchone":"#/components/schemas/BranchOne","branchall":"#/components/schemas/BranchAll","identity":"#/components/schemas/Identity","aiagent":"#/components/schemas/AiAgent"}}},"RawScript":{"type":"object","description":"Inline script with code defined directly in the flow. Use 'bun' as default language if unspecified. The script receives arguments from input_transforms","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"content":{"type":"string","description":"The script source code. Should export a 'main' function"},"language":{"type":"string","description":"Programming language for this script","enum":["deno","bun","python3","go","bash","powershell","postgresql","mysql","bigquery","snowflake","mssql","oracledb","graphql","nativets","php","rust","ansible","csharp","nu","java","ruby","rlang","duckdb"]},"path":{"type":"string","description":"Optional path for saving this script"},"lock":{"type":"string","description":"Lock file content for dependencies"},"type":{"type":"string","enum":["rawscript"]},"tag":{"type":"string","description":"Worker group tag for execution routing"},"concurrent_limit":{"type":"number","description":"Maximum concurrent executions of this script"},"concurrency_time_window_s":{"type":"number","description":"Time window for concurrent_limit"},"custom_concurrency_key":{"type":"string","description":"Custom key for grouping concurrent executions"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"},"assets":{"type":"array","description":"External resources this script accesses (S3 objects, resources, etc.)","items":{"type":"object","required":["path","kind"],"properties":{"path":{"type":"string","description":"Path to the asset"},"kind":{"type":"string","description":"Type of asset","enum":["s3object","resource","ducklake","datatable","volume"]},"access_type":{"type":"string","nullable":true,"description":"Access level for this asset","enum":["r","w","rw"]},"alt_access_type":{"type":"string","nullable":true,"description":"Alternative access level","enum":["r","w","rw"]}}}}},"required":["type","content","language","input_transforms"]},"PathScript":{"type":"object","description":"Reference to an existing script by path. Use this when calling a previously saved script instead of writing inline code","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the script's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the script in the workspace (e.g., 'f/scripts/send_email')"},"hash":{"type":"string","description":"Optional specific version hash of the script to use"},"type":{"type":"string","enum":["script"]},"tag_override":{"type":"string","description":"Override the script's default worker group tag"},"is_trigger":{"type":"boolean","description":"If true, this script is a trigger that can start the flow"}},"required":["type","path","input_transforms"]},"PathFlow":{"type":"object","description":"Reference to an existing flow by path. Use this to call another flow as a subflow","properties":{"input_transforms":{"type":"object","description":"Map of parameter names to their values (static or JavaScript expressions). These become the subflow's input arguments","additionalProperties":{"$ref":"#/components/schemas/InputTransform"}},"path":{"type":"string","description":"Path to the flow in the workspace (e.g., 'f/flows/process_user')"},"type":{"type":"string","enum":["flow"]}},"required":["type","path","input_transforms"]},"ForloopFlow":{"type":"object","description":"Executes nested modules in a loop over an iterator. Inside the loop, use 'flow_input.iter.value' to access the current iteration value, and 'flow_input.iter.index' for the index. Supports parallel execution for better performance on I/O-bound operations","properties":{"modules":{"type":"array","description":"Steps to execute for each iteration. These can reference the iteration value via 'flow_input.iter.value'","items":{"$ref":"#/components/schemas/FlowModule"}},"iterator":{"description":"JavaScript expression that returns an array to iterate over. Can reference 'results.step_id' or 'flow_input'","$ref":"#/components/schemas/InputTransform"},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["forloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (faster for I/O-bound operations). Use with parallelism to control concurrency"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true. Limits resource usage. Can be static number or expression","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","iterator","skip_failures","type"]},"WhileloopFlow":{"type":"object","description":"Executes nested modules repeatedly while a condition is true. The loop checks the condition after each iteration. Use stop_after_if on modules to control loop termination","properties":{"modules":{"type":"array","description":"Steps to execute in each iteration. Use stop_after_if to control when the loop ends","items":{"$ref":"#/components/schemas/FlowModule"}},"skip_failures":{"type":"boolean","description":"If true, iteration failures don't stop the loop. Failed iterations return null"},"type":{"type":"string","enum":["whileloopflow"]},"parallel":{"type":"boolean","description":"If true, iterations run concurrently (use with caution in while loops)"},"parallelism":{"description":"Maximum number of concurrent iterations when parallel=true","$ref":"#/components/schemas/InputTransform"},"squash":{"type":"boolean"}},"required":["modules","skip_failures","type"]},"BranchOne":{"type":"object","description":"Conditional branching where only the first matching branch executes. Branches are evaluated in order, and the first one with a true expression runs. If no branches match, the default branch executes","properties":{"branches":{"type":"array","description":"Array of branches to evaluate in order. The first branch with expr evaluating to true executes","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch condition"},"expr":{"type":"string","description":"JavaScript expression that returns boolean. Can use 'results.step_id' or 'flow_input'. First true expr wins"},"modules":{"type":"array","description":"Steps to execute if this branch's expr is true","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules","expr"]}},"default":{"type":"array","description":"Steps to execute if no branch expressions match","items":{"$ref":"#/components/schemas/FlowModule"}},"type":{"type":"string","enum":["branchone"]}},"required":["branches","default","type"]},"BranchAll":{"type":"object","description":"Parallel branching where all branches execute simultaneously. Unlike BranchOne, all branches run regardless of conditions. Useful for executing independent tasks concurrently","properties":{"branches":{"type":"array","description":"Array of branches that all execute (either in parallel or sequentially)","items":{"type":"object","properties":{"summary":{"type":"string","description":"Short description of this branch's purpose"},"skip_failure":{"type":"boolean","description":"If true, failure in this branch doesn't fail the entire flow"},"modules":{"type":"array","description":"Steps to execute in this branch","items":{"$ref":"#/components/schemas/FlowModule"}}},"required":["modules"]}},"type":{"type":"string","enum":["branchall"]},"parallel":{"type":"boolean","description":"If true, all branches execute concurrently. If false, they execute sequentially"}},"required":["branches","type"]},"AgentTool":{"type":"object","description":"A tool available to an AI agent. Can be a flow module or an external MCP (Model Context Protocol) tool","properties":{"id":{"type":"string","description":"Unique identifier for this tool. Cannot contain spaces - use underscores instead (e.g., 'get_user_data' not 'get user data')"},"summary":{"type":"string","description":"Short description of what this tool does (shown to the AI)"},"value":{"$ref":"#/components/schemas/ToolValue"}},"required":["id","value"]},"ToolValue":{"description":"The implementation of a tool. Can be a flow module (script/flow) or an MCP tool reference","oneOf":[{"$ref":"#/components/schemas/FlowModuleTool"},{"$ref":"#/components/schemas/McpToolValue"},{"$ref":"#/components/schemas/WebsearchToolValue"}],"discriminator":{"propertyName":"tool_type","mapping":{"flowmodule":"#/components/schemas/FlowModuleTool","mcp":"#/components/schemas/McpToolValue","websearch":"#/components/schemas/WebsearchToolValue"}}},"FlowModuleTool":{"description":"A tool implemented as a flow module (script, flow, etc.). The AI can call this like any other flow module","allOf":[{"type":"object","properties":{"tool_type":{"type":"string","enum":["flowmodule"]}},"required":["tool_type"]},{"$ref":"#/components/schemas/FlowModuleValue"}]},"WebsearchToolValue":{"type":"object","description":"A tool implemented as a websearch tool. The AI can call this like any other websearch tool","properties":{"tool_type":{"type":"string","enum":["websearch"]}},"required":["tool_type"]},"McpToolValue":{"type":"object","description":"Reference to an external MCP (Model Context Protocol) tool. The AI can call tools from MCP servers","properties":{"tool_type":{"type":"string","enum":["mcp"]},"resource_path":{"type":"string","description":"Path to the MCP resource/server configuration"},"include_tools":{"type":"array","description":"Whitelist of specific tools to include from this MCP server","items":{"type":"string"}},"exclude_tools":{"type":"array","description":"Blacklist of tools to exclude from this MCP server","items":{"type":"string"}}},"required":["tool_type","resource_path"]},"AiAgent":{"type":"object","description":"AI agent step that can use tools to accomplish tasks. The agent receives inputs and can call any of its configured tools to complete the task","properties":{"input_transforms":{"type":"object","description":"Input parameters for the AI agent mapped to their values","properties":{"provider":{"$ref":"#/components/schemas/ProviderTransform"},"output_type":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Output format type.\\nValid values: 'text' (default) - plain text response, 'image' - image generation\\n"},"user_message":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"The user's prompt/message to the AI agent. Supports variable interpolation with flow.input syntax."},"system_prompt":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"System instructions that guide the AI's behavior, persona, and response style. Optional."},"streaming":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Boolean. If true, stream the AI response incrementally.\\nStreaming events include: token_delta, tool_call, tool_call_arguments, tool_execution, tool_result\\n"},"memory":{"$ref":"#/components/schemas/MemoryTransform"},"output_schema":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"JSON Schema object defining structured output format. Used when you need the AI to return data in a specific shape.\\nSupports standard JSON Schema properties: type, properties, required, items, enum, pattern, minLength, maxLength, minimum, maximum, etc.\\nExample: { type: 'object', properties: { name: { type: 'string' }, age: { type: 'integer' } }, required: ['name'] }\\n"},"user_attachments":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Array of file references (images or PDFs) for the AI agent.\\nFormat: Array<{ bucket: string, key: string }> - S3 object references\\nExample: [{ bucket: 'my-bucket', key: 'documents/report.pdf' }]\\n"},"max_completion_tokens":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Integer. Maximum number of tokens the AI will generate in its response.\\nRange: 1 to 4,294,967,295. Typical values: 256-4096 for most use cases.\\n"},"temperature":{"allOf":[{"$ref":"#/components/schemas/InputTransform"}],"description":"Float. Controls randomness/creativity of responses.\\nRange: 0.0 to 2.0 (provider-dependent)\\n- 0.0 = deterministic, focused responses\\n- 0.7 = balanced (common default)\\n- 1.0+ = more creative/random\\n"}},"required":["provider","user_message","output_type"]},"tools":{"type":"array","description":"Array of tools the agent can use. The agent decides which tools to call based on the task","items":{"$ref":"#/components/schemas/AgentTool"}},"type":{"type":"string","enum":["aiagent"]},"omit_output_from_conversation":{"type":"boolean","default":false,"description":"If true, this AI agent step does not persist its assistant or tool messages to the flow conversation when chat mode is enabled."},"parallel":{"type":"boolean","description":"If true, the agent can execute multiple tool calls in parallel"}},"required":["tools","type","input_transforms"]},"Identity":{"type":"object","description":"Pass-through module that returns its input unchanged. Useful for flow structure or as a placeholder","properties":{"type":{"type":"string","enum":["identity"]},"flow":{"type":"boolean","description":"If true, marks this as a flow identity (special handling)"}},"required":["type"]},"FlowStatus":{"type":"object","properties":{"step":{"type":"integer"},"modules":{"type":"array","items":{"$ref":"#/components/schemas/FlowStatusModule"}},"user_states":{"additionalProperties":true},"preprocessor_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"}]},"failure_module":{"allOf":[{"$ref":"#/components/schemas/FlowStatusModule"},{"type":"object","properties":{"parent_module":{"type":"string"}}}]},"retry":{"type":"object","properties":{"fail_count":{"type":"integer"},"failed_jobs":{"type":"array","items":{"type":"string","format":"uuid"}}}}},"required":["step","modules","failure_module"]},"FlowStatusModule":{"type":"object","properties":{"type":{"type":"string","enum":["WaitingForPriorSteps","WaitingForEvents","WaitingForExecutor","InProgress","Success","Failure"]},"id":{"type":"string"},"job":{"type":"string","format":"uuid"},"count":{"type":"integer"},"progress":{"type":"integer"},"iterator":{"type":"object","properties":{"index":{"type":"integer"},"itered":{"type":"array","items":{}},"itered_len":{"type":"integer"},"args":{}}},"flow_jobs":{"type":"array","items":{"type":"string"}},"flow_jobs_success":{"type":"array","items":{"type":"boolean"}},"flow_jobs_duration":{"type":"object","properties":{"started_at":{"type":"array","items":{"type":"string"}},"duration_ms":{"type":"array","items":{"type":"integer"}}}},"branch_chosen":{"type":"object","properties":{"type":{"type":"string","enum":["branch","default"]},"branch":{"type":"integer"}},"required":["type"]},"branchall":{"type":"object","properties":{"branch":{"type":"integer"},"len":{"type":"integer"}},"required":["branch","len"]},"approvers":{"type":"array","items":{"type":"object","properties":{"resume_id":{"type":"integer"},"approver":{"type":"string"}},"required":["resume_id","approver"]}},"failed_retries":{"type":"array","items":{"type":"string","format":"uuid"}},"skipped":{"type":"boolean"},"agent_actions":{"type":"array","items":{"type":"object","oneOf":[{"type":"object","properties":{"job_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"type":{"type":"string","enum":["tool_call"]},"module_id":{"type":"string"}},"required":["job_id","function_name","type","module_id"]},{"type":"object","properties":{"call_id":{"type":"string","format":"uuid"},"function_name":{"type":"string"},"resource_path":{"type":"string"},"type":{"type":"string","enum":["mcp_tool_call"]},"arguments":{"type":"object"}},"required":["call_id","function_name","resource_path","type"]},{"type":"object","properties":{"type":{"type":"string","enum":["web_search"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["message"]}},"required":["content","type"]}]}},"agent_actions_success":{"type":"array","items":{"type":"boolean"}}},"required":["type"]}}`;
1527
2137
  export const CLI_COMMANDS = `# Windmill CLI Commands
1528
2138
 
1529
2139
  The Windmill CLI (\`wmill\`) provides commands for managing scripts, flows, apps, and other resources.
@@ -1561,7 +2171,15 @@ app related commands
1561
2171
  - \`app lint [app_folder:string]\` - Lint a raw app folder to validate structure and buildability
1562
2172
  - \`--fix\` - Attempt to fix common issues (not implemented yet)
1563
2173
  - \`app new\` - create a new raw app from a template
2174
+ - \`--summary <summary:string>\` - App summary (short description). Skips the prompt when provided. Triggers non-interactive mode.
2175
+ - \`--path <path:string>\` - App path (e.g., f/folder/my_app or u/username/my_app). Skips the prompt when provided. Triggers non-interactive mode.
2176
+ - \`--framework <framework:string>\` - Framework template: react19 | react18 | svelte5 | vue. Skips the prompt when provided. Triggers non-interactive mode.
2177
+ - \`--datatable <datatable:string>\` - Datatable to wire up. Without this flag in non-interactive mode, no datatable is configured.
2178
+ - \`--schema <schema:string>\` - Schema to use with --datatable. Created (CREATE SCHEMA IF NOT EXISTS) if it doesn't already exist.
2179
+ - \`--overwrite\` - Overwrite the target directory if it already exists, without prompting.
2180
+ - \`--no-open-in-desktop\` - Do not prompt to open the new app in Claude Desktop.
1564
2181
  - \`app generate-agents [app_folder:string]\` - regenerate AGENTS.md and DATATABLES.md from remote workspace
2182
+ - \`app set-permissioned-as <path:string> <email:string>\` - Set the on_behalf_of_email for an app (requires admin or wm_deployers group)
1565
2183
 
1566
2184
  ### audit
1567
2185
 
@@ -1580,6 +2198,10 @@ Show all available wmill.yaml configuration options
1580
2198
  **Options:**
1581
2199
  - \`--json\` - Output as JSON for programmatic consumption
1582
2200
 
2201
+ **Subcommands:**
2202
+
2203
+ - \`config migrate\` - Migrate wmill.yaml from gitBranches/environments to workspaces format
2204
+
1583
2205
  ### dependencies
1584
2206
 
1585
2207
  workspace dependencies related commands
@@ -1592,10 +2214,13 @@ workspace dependencies related commands
1592
2214
 
1593
2215
  ### dev
1594
2216
 
1595
- Launch a dev server that watches for local file changes and auto-pushes them to the remote workspace. Provides live reload for scripts and flows during development.
2217
+ Watch local file changes and live-reload the dev page for preview. Does NOT deploy to the remote workspace use wmill sync push for that.
1596
2218
 
1597
2219
  **Options:**
1598
- - \`--includes <pattern...:string>\` - Filter paths givena glob pattern or path
2220
+ - \`--includes <pattern...:string>\` - Filter paths given a glob pattern or path
2221
+ - \`--proxy-port <port:number>\` - Port for a localhost reverse proxy to the remote Windmill server
2222
+ - \`--path <path:string>\` - Watch a specific windmill path (e.g., u/admin/my_script or f/my_flow)
2223
+ - \`--no-open\` - Do not open the browser automatically
1599
2224
 
1600
2225
  ### docs
1601
2226
 
@@ -1640,6 +2265,7 @@ flow related commands
1640
2265
  - \`--json\` - Output as JSON (for piping to jq)
1641
2266
  - \`flow show-version <path:string> <version:string>\` - Show a specific version of a flow
1642
2267
  - \`--json\` - Output as JSON (for piping to jq)
2268
+ - \`flow set-permissioned-as <path:string> <email:string>\` - Set the on_behalf_of_email for a flow (requires admin or wm_deployers group)
1643
2269
 
1644
2270
  ### folder
1645
2271
 
@@ -1659,6 +2285,9 @@ folder related commands
1659
2285
  - \`folder push <name:string>\` - push a local folder to the remote by name. This overrides any remote versions.
1660
2286
  - \`folder add-missing\` - create default folder.meta.yaml for all subdirectories of f/ that are missing one
1661
2287
  - \`-y, --yes\` - skip confirmation prompt
2288
+ - \`folder show-rules <name:string>\` - Show default_permissioned_as rules for a folder. Use --test-path to see which rule matches a given item path.
2289
+ - \`--test-path <path:string>\` - Test which rule matches this item path (e.g. f/prod/jobs/my_script)
2290
+ - \`--json\` - Output as JSON
1662
2291
 
1663
2292
  ### generate-metadata
1664
2293
 
@@ -1678,6 +2307,15 @@ Generate metadata (locks, schemas) for all scripts, flows, and apps
1678
2307
  - \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
1679
2308
  - \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
1680
2309
 
2310
+ **Subcommands:**
2311
+
2312
+ - \`generate-metadata rehash [folder:string]\`
2313
+ - \`--skip-scripts\` - Skip processing scripts
2314
+ - \`--skip-flows\` - Skip processing flows
2315
+ - \`--skip-apps\` - Skip processing apps
2316
+ - \`-i --includes <patterns:file[]>\` - Comma separated patterns to specify which files to include
2317
+ - \`-e --excludes <patterns:file[]>\` - Comma separated patterns to specify which files to exclude
2318
+
1681
2319
  ### gitsync-settings
1682
2320
 
1683
2321
  Manage git-sync settings between local wmill.yaml and Windmill backend
@@ -1754,7 +2392,7 @@ sync local with a remote instance or the opposite (push or pull)
1754
2392
  - \`--dry-run\` - Perform a dry run without making changes
1755
2393
  - \`--skip-users\` - Skip pulling users
1756
2394
  - \`--skip-settings\` - Skip pulling settings
1757
- - \`--skip-configs\` - Skip pulling configs (worker groups and SMTP)
2395
+ - \`--skip-configs\` - Skip pulling configs (worker groups)
1758
2396
  - \`--skip-groups\` - Skip pulling instance groups
1759
2397
  - \`--include-workspaces\` - Also pull workspaces
1760
2398
  - \`--folder-per-instance\` - Create a folder per instance
@@ -1766,7 +2404,7 @@ sync local with a remote instance or the opposite (push or pull)
1766
2404
  - \`--dry-run\` - Perform a dry run without making changes
1767
2405
  - \`--skip-users\` - Skip pushing users
1768
2406
  - \`--skip-settings\` - Skip pushing settings
1769
- - \`--skip-configs\` - Skip pushing configs (worker groups and SMTP)
2407
+ - \`--skip-configs\` - Skip pushing configs (worker groups)
1770
2408
  - \`--skip-groups\` - Skip pushing instance groups
1771
2409
  - \`--include-workspaces\` - Also push workspaces
1772
2410
  - \`--folder-per-instance\` - Create a folder per instance
@@ -1778,6 +2416,11 @@ sync local with a remote instance or the opposite (push or pull)
1778
2416
  - \`-o, --output-file <file:string>\` - Write YAML to a file instead of stdout
1779
2417
  - \`--show-secrets\` - Include sensitive fields (license key, JWT secret) without prompting
1780
2418
  - \`--instance <instance:string>\` - Name of the instance, override the active instance
2419
+ - \`instance connect-slack\`
2420
+ - \`--bot-token <bot_token:string>\` - Slack bot token (xoxb-...)
2421
+ - \`--team-id <team_id:string>\` - Slack team id
2422
+ - \`--team-name <team_name:string>\` - Slack team name
2423
+ - \`--instance <instance:string>\` - Instance profile to connect against (defaults to the active instance)
1781
2424
 
1782
2425
  ### job
1783
2426
 
@@ -1881,7 +2524,9 @@ schedule related commands
1881
2524
  - \`schedule new <path:string>\` - create a new schedule locally
1882
2525
  - \`schedule push <file_path:string> <remote_path:string>\` - push a local schedule spec. This overrides any remote versions.
1883
2526
  - \`schedule enable <path:string>\` - Enable a schedule
2527
+ - \`--force\` - Bypass the fork-conflict warning when the parent workspace has the same schedule (acknowledges that both crons will fire)
1884
2528
  - \`schedule disable <path:string>\` - Disable a schedule
2529
+ - \`schedule set-permissioned-as <path:string> <email:string>\` - Set the email (run-as user) for a schedule (requires admin or wm_deployers group)
1885
2530
 
1886
2531
  ### script
1887
2532
 
@@ -1913,6 +2558,7 @@ script related commands
1913
2558
  - \`script bootstrap <path:file> <language:string>\` - create a new script (alias for new)
1914
2559
  - \`--summary <summary:string>\` - script summary
1915
2560
  - \`--description <description:string>\` - script description
2561
+ - \`script set-permissioned-as <path:string> <email:string>\` - Set the on_behalf_of_email for a script (requires admin or wm_deployers group)
1916
2562
  - \`script history <path:string>\` - show version history for a script
1917
2563
  - \`--json\` - Output as JSON (for piping to jq)
1918
2564
 
@@ -1951,7 +2597,7 @@ sync local with a remote workspaces or the opposite (push or pull)
1951
2597
  - \`--extra-includes <patterns:file[]>\` - Comma separated patterns to specify which file to take into account (among files that are compatible with windmill). Patterns can include * (any string until '/') and ** (any string). Useful to still take wmill.yaml into account and act as a second pattern to satisfy
1952
2598
  - \`--repository <repo:string>\` - Specify repository path (e.g., u/user/repo) when multiple repositories exist
1953
2599
  - \`--promotion <branch:string>\` - Use promotionOverrides from the specified branch instead of regular overrides
1954
- - \`--branch, --env <branch:string>\` - Override the current git branch/environment (works even outside a git repository)
2600
+ - \`--branch, --env <branch:string>\` - [Deprecated: use --workspace] Override the current git branch/environment
1955
2601
  - \`sync push\` - Push any local changes and apply them remotely.
1956
2602
  - \`--yes\` - Push without needing confirmation
1957
2603
  - \`--dry-run\` - Show changes that would be pushed without actually pushing
@@ -1982,10 +2628,11 @@ sync local with a remote workspaces or the opposite (push or pull)
1982
2628
  - \`--message <message:string>\` - Include a message that will be added to all scripts/flows/apps updated during this push
1983
2629
  - \`--parallel <number>\` - Number of changes to process in parallel
1984
2630
  - \`--repository <repo:string>\` - Specify repository path (e.g., u/user/repo) when multiple repositories exist
1985
- - \`--branch, --env <branch:string>\` - Override the current git branch/environment (works even outside a git repository)
2631
+ - \`--branch, --env <branch:string>\` - [Deprecated: use --workspace] Override the current git branch/environment
1986
2632
  - \`--lint\` - Run lint validation before pushing
1987
2633
  - \`--locks-required\` - Fail if scripts or flow inline scripts that need locks have no locks
1988
2634
  - \`--auto-metadata\` - Automatically regenerate stale metadata (locks and schemas) before pushing
2635
+ - \`--accept-overriding-permissioned-as-with-self\` - Accept that items with a different permissioned_as will be updated with your own user
1989
2636
 
1990
2637
  ### token
1991
2638
 
@@ -2016,10 +2663,12 @@ trigger related commands
2016
2663
  - \`--json\` - Output as JSON (for piping to jq)
2017
2664
  - \`trigger get <path:string>\` - get a trigger's details
2018
2665
  - \`--json\` - Output as JSON (for piping to jq)
2019
- - \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email). Recommended for faster lookup
2666
+ - \`--kind <kind:string>\` - Trigger kind (http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email). Recommended for faster lookup
2020
2667
  - \`trigger new <path:string>\` - create a new trigger locally
2021
- - \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, email)
2668
+ - \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)
2022
2669
  - \`trigger push <file_path:string> <remote_path:string>\` - push a local trigger spec. This overrides any remote versions.
2670
+ - \`trigger set-permissioned-as <path:string> <email:string>\` - Set the email (run-as user) for a trigger (requires admin or wm_deployers group)
2671
+ - \`--kind <kind:string>\` - Trigger kind (required: http, websocket, kafka, nats, postgres, mqtt, sqs, gcp, azure, email)
2023
2672
 
2024
2673
  ### user
2025
2674
 
@@ -2070,7 +2719,7 @@ display worker groups, pull and push worker groups configs
2070
2719
  - \`--instance\` - Name of the instance to push to, override the active instance
2071
2720
  - \`--base-url\` - Base url to be passed to the instance settings instead of the local one
2072
2721
  - \`--yes\` - Pull without needing confirmation
2073
- - \`worker-groups push\` - Push instance settings, users, configs, group and overwrite remote
2722
+ - \`worker-groups push\` - Push worker groups (similar to \`wmill instance push --skip-users --skip-settings --skip-groups\`)
2074
2723
  - \`--instance [instance]\` - Name of the instance to push to, override the active instance
2075
2724
  - \`--base-url [baseUrl]\` - If used with --token, will be used as the base url for the instance
2076
2725
  - \`--yes\` - Push without needing confirmation
@@ -2101,14 +2750,31 @@ workspace related commands
2101
2750
  - \`workspace list\` - List local workspace profiles
2102
2751
  - \`workspace list-remote\` - List workspaces on the remote server that you have access to
2103
2752
  - \`workspace list-forks\` - List forked workspaces on the remote server
2104
- - \`workspace bind\` - Bind the current Git branch to the active workspace. This adds the branch to gitBranches in wmill.yaml so sync operations use the correct workspace for each branch.
2105
- - \`--branch, --env <branch:string>\` - Specify branch/environment (defaults to current)
2106
- - \`workspace unbind\` - Remove workspace binding from the current Git branch
2107
- - \`--branch, --env <branch:string>\` - Specify branch/environment (defaults to current)
2753
+ - \`workspace bind\` - Create or update a workspace entry in wmill.yaml from the active profile
2754
+ - \`--workspace <name:string>\` - Workspace name (default: current branch or workspaceId)
2755
+ - \`--branch <branch:string>\` - Git branch to associate (default: workspace name)
2756
+ - \`workspace unbind\` - Remove baseUrl and workspaceId from a workspace entry
2757
+ - \`--workspace <name:string>\` - Workspace to unbind
2108
2758
  - \`workspace fork [workspace_name:string] [workspace_id:string]\` - Create a forked workspace
2109
2759
  - \`--create-workspace-name <workspace_name:string>\` - Specify the workspace name. Ignored if --create is not specified or the workspace already exists. Will default to the workspace id.
2760
+ - \`--color <color:string>\` - Workspace color (hex code, e.g. #ff0000)
2761
+ - \`--datatable-behavior <behavior:string>\` - How to handle datatables: skip, schema_only, or schema_and_data (default: interactive prompt)
2762
+ - \`-y --yes\` - Skip interactive prompts (defaults datatable behavior to 'skip')
2110
2763
  - \`workspace delete-fork <fork_name:string>\` - Delete a forked workspace and git branch
2111
2764
  - \`-y --yes\` - Skip confirmation prompt
2765
+ - \`workspace merge\` - Compare and deploy changes between a fork and its parent workspace
2766
+ - \`--direction <direction:string>\` - Deploy direction: to-parent or to-fork
2767
+ - \`--all\` - Deploy all changed items including conflicts
2768
+ - \`--skip-conflicts\` - Skip items modified in both workspaces
2769
+ - \`--include <items:string>\` - Comma-separated kind:path items to include (e.g. script:f/test/main,flow:f/my/flow)
2770
+ - \`--exclude <items:string>\` - Comma-separated kind:path items to exclude
2771
+ - \`--preserve-on-behalf-of\` - Preserve original on_behalf_of/permissioned_as values
2772
+ - \`-y --yes\` - Non-interactive mode (deploy without prompts)
2773
+ - \`workspace connect-slack\` - Non-interactively connect Slack to the active workspace using a pre-minted bot token (xoxb-...). Produces the same artifacts as the UI OAuth flow: workspace_settings fields, g/slack group, f/slack_bot folder, and the encrypted bot token variable + resource at f/slack_bot/bot_token.
2774
+ - \`--bot-token <bot_token:string>\` - Slack bot token (xoxb-...)
2775
+ - \`--team-id <team_id:string>\` - Slack team id
2776
+ - \`--team-name <team_name:string>\` - Slack team name
2777
+ - \`workspace disconnect-slack\`
2112
2778
 
2113
2779
  `;
2114
2780
  export const LANG_BASH = `# Bash
@@ -2172,6 +2838,37 @@ Name the parameters by adding comments before the statement:
2172
2838
  -- @name2 (int64) = 0
2173
2839
  SELECT * FROM users WHERE name = @name1 AND age > @name2;
2174
2840
  \`\`\`
2841
+
2842
+ ## Receiving an S3Object as a script parameter
2843
+
2844
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for
2845
+ it, downloads the file, and binds it as a \`STRING\` JSON parameter — Parquet/CSV
2846
+ files are decoded server-side into a JSON array of records, JSON/JSONL pass
2847
+ through. Consume with \`JSON_EXTRACT_ARRAY\` / \`JSON_VALUE\`:
2848
+
2849
+ \`\`\`sql
2850
+ -- @file (s3object)
2851
+ SELECT
2852
+ CAST(JSON_VALUE(row, '$.id') AS INT64) AS id,
2853
+ JSON_VALUE(row, '$.name') AS name
2854
+ FROM UNNEST(JSON_EXTRACT_ARRAY(@file)) AS row;
2855
+ \`\`\`
2856
+
2857
+ ## Streaming query results to S3
2858
+
2859
+ Add a \`-- s3\` directive at the top of the script to stream the result set to S3
2860
+ instead of returning rows. Windmill writes the file and returns its \`S3Object\`
2861
+ as the script result.
2862
+
2863
+ \`\`\`sql
2864
+ -- s3 prefix=exports/users format=parquet
2865
+ SELECT id, name FROM users;
2866
+ \`\`\`
2867
+
2868
+ All keys are optional: \`prefix\` (object key prefix), \`storage\` (named storage —
2869
+ omit to use the workspace default), \`format\` (\`json\` (default), \`parquet\`, or
2870
+ \`csv\`). Use this for large result sets — rows stream directly to S3 instead of
2871
+ being buffered, bypassing the 10000-row return cap.
2175
2872
  `;
2176
2873
  export const LANG_BUN = `# TypeScript (Bun)
2177
2874
 
@@ -2255,19 +2952,20 @@ export async function preprocessor(event: Event) {
2255
2952
 
2256
2953
  ## S3 Object Operations
2257
2954
 
2258
- Windmill provides built-in support for S3-compatible storage operations.
2955
+ Windmill provides built-in support for S3-compatible storage operations. The \`wmill.S3Object\` type covers both the \`s3://storage/key\` URI form (\`s3:///key\` for the workspace default storage) and the \`{ s3, storage? }\` record form — always use it instead of redefining your own.
2259
2956
 
2260
- ### S3Object Type
2261
-
2262
- The S3Object type represents a file in S3 storage:
2957
+ ### Receiving an S3Object as a script parameter
2263
2958
 
2264
2959
  \`\`\`typescript
2265
- type S3Object = {
2266
- s3: string; // Path within the bucket
2267
- };
2960
+ import * as wmill from "windmill-client";
2961
+
2962
+ export async function main(file: wmill.S3Object) {
2963
+ const content = await wmill.loadS3File(file);
2964
+ // ...
2965
+ }
2268
2966
  \`\`\`
2269
2967
 
2270
- ## TypeScript Operations
2968
+ ### S3 operations
2271
2969
 
2272
2970
  \`\`\`typescript
2273
2971
  import * as wmill from "windmill-client";
@@ -2279,7 +2977,7 @@ const content: Uint8Array = await wmill.loadS3File(s3object);
2279
2977
  const blob: Blob = await wmill.loadS3FileStream(s3object);
2280
2978
 
2281
2979
  // Write file to S3
2282
- const result: S3Object = await wmill.writeS3File(
2980
+ const result: wmill.S3Object = await wmill.writeS3File(
2283
2981
  s3object, // Target path (or undefined to auto-generate)
2284
2982
  fileContent, // string or Blob
2285
2983
  s3ResourcePath // Optional: specific S3 resource to use
@@ -2366,19 +3064,20 @@ export async function preprocessor(event: Event) {
2366
3064
 
2367
3065
  ## S3 Object Operations
2368
3066
 
2369
- Windmill provides built-in support for S3-compatible storage operations.
2370
-
2371
- ### S3Object Type
3067
+ Windmill provides built-in support for S3-compatible storage operations. The \`wmill.S3Object\` type covers both the \`s3://storage/key\` URI form (\`s3:///key\` for the workspace default storage) and the \`{ s3, storage? }\` record form — always use it instead of redefining your own.
2372
3068
 
2373
- The S3Object type represents a file in S3 storage:
3069
+ ### Receiving an S3Object as a script parameter
2374
3070
 
2375
3071
  \`\`\`typescript
2376
- type S3Object = {
2377
- s3: string; // Path within the bucket
2378
- };
3072
+ import * as wmill from "windmill-client";
3073
+
3074
+ export async function main(file: wmill.S3Object) {
3075
+ const content = await wmill.loadS3File(file);
3076
+ // ...
3077
+ }
2379
3078
  \`\`\`
2380
3079
 
2381
- ## TypeScript Operations
3080
+ ### S3 operations
2382
3081
 
2383
3082
  \`\`\`typescript
2384
3083
  import * as wmill from "windmill-client";
@@ -2390,7 +3089,7 @@ const content: Uint8Array = await wmill.loadS3File(s3object);
2390
3089
  const blob: Blob = await wmill.loadS3FileStream(s3object);
2391
3090
 
2392
3091
  // Write file to S3
2393
- const result: S3Object = await wmill.writeS3File(
3092
+ const result: wmill.S3Object = await wmill.writeS3File(
2394
3093
  s3object, // Target path (or undefined to auto-generate)
2395
3094
  fileContent, // string or Blob
2396
3095
  s3ResourcePath // Optional: specific S3 resource to use
@@ -2525,19 +3224,20 @@ export async function preprocessor(event: Event) {
2525
3224
 
2526
3225
  ## S3 Object Operations
2527
3226
 
2528
- Windmill provides built-in support for S3-compatible storage operations.
2529
-
2530
- ### S3Object Type
3227
+ Windmill provides built-in support for S3-compatible storage operations. The \`wmill.S3Object\` type covers both the \`s3://storage/key\` URI form (\`s3:///key\` for the workspace default storage) and the \`{ s3, storage? }\` record form — always use it instead of redefining your own.
2531
3228
 
2532
- The S3Object type represents a file in S3 storage:
3229
+ ### Receiving an S3Object as a script parameter
2533
3230
 
2534
3231
  \`\`\`typescript
2535
- type S3Object = {
2536
- s3: string; // Path within the bucket
2537
- };
3232
+ import * as wmill from "windmill-client";
3233
+
3234
+ export async function main(file: wmill.S3Object) {
3235
+ const content = await wmill.loadS3File(file);
3236
+ // ...
3237
+ }
2538
3238
  \`\`\`
2539
3239
 
2540
- ## TypeScript Operations
3240
+ ### S3 operations
2541
3241
 
2542
3242
  \`\`\`typescript
2543
3243
  import * as wmill from "windmill-client";
@@ -2549,7 +3249,7 @@ const content: Uint8Array = await wmill.loadS3File(s3object);
2549
3249
  const blob: Blob = await wmill.loadS3FileStream(s3object);
2550
3250
 
2551
3251
  // Write file to S3
2552
- const result: S3Object = await wmill.writeS3File(
3252
+ const result: wmill.S3Object = await wmill.writeS3File(
2553
3253
  s3object, // Target path (or undefined to auto-generate)
2554
3254
  fileContent, // string or Blob
2555
3255
  s3ResourcePath // Optional: specific S3 resource to use
@@ -2607,6 +3307,30 @@ SELECT * FROM read_parquet('s3:///path/to/file.parquet');
2607
3307
  -- JSON files
2608
3308
  SELECT * FROM read_json('s3:///path/to/file.json');
2609
3309
  \`\`\`
3310
+
3311
+ ### Receiving an S3Object as a script parameter
3312
+
3313
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for it
3314
+ and binds the arg as the bare \`s3://storage/key\` URI, which DuckDB's reader
3315
+ functions consume directly:
3316
+
3317
+ \`\`\`sql
3318
+ -- $file (s3object)
3319
+ SELECT * FROM read_parquet($file);
3320
+ \`\`\`
3321
+
3322
+ Works with any DuckDB reader: \`read_csv($file)\`, \`read_json($file)\`, etc.
3323
+
3324
+ ### Writing query results to S3
3325
+
3326
+ DuckDB writes to S3 natively via \`COPY ... TO\`:
3327
+
3328
+ \`\`\`sql
3329
+ COPY (SELECT * FROM users) TO 's3:///exports/users.parquet' (FORMAT PARQUET);
3330
+ \`\`\`
3331
+
3332
+ Use this instead of the \`-- s3\` streaming directive supported by the other SQL
3333
+ dialects — that directive is not available in DuckDB.
2610
3334
  `;
2611
3335
  export const LANG_GO = `# Go
2612
3336
 
@@ -2763,6 +3487,36 @@ Name the parameters by adding comments before the statement:
2763
3487
  -- @P2 name2 (int) = 0
2764
3488
  SELECT * FROM users WHERE name = @P1 AND age > @P2;
2765
3489
  \`\`\`
3490
+
3491
+ ## Receiving an S3Object as a script parameter
3492
+
3493
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for
3494
+ it, downloads the file, and binds it as \`nvarchar(max)\` JSON text — Parquet/CSV
3495
+ files are decoded server-side into a JSON array of records, JSON/JSONL pass
3496
+ through. Consume with \`OPENJSON\`:
3497
+
3498
+ \`\`\`sql
3499
+ -- @P1 file (s3object)
3500
+ SELECT id, name
3501
+ FROM OPENJSON(@P1)
3502
+ WITH (id INT, name NVARCHAR(200));
3503
+ \`\`\`
3504
+
3505
+ ## Streaming query results to S3
3506
+
3507
+ Add a \`-- s3\` directive at the top of the script to stream the result set to S3
3508
+ instead of returning rows. Windmill writes the file and returns its \`S3Object\`
3509
+ as the script result.
3510
+
3511
+ \`\`\`sql
3512
+ -- s3 prefix=exports/users format=parquet
3513
+ SELECT id, name FROM users;
3514
+ \`\`\`
3515
+
3516
+ All keys are optional: \`prefix\` (object key prefix), \`storage\` (named storage —
3517
+ omit to use the workspace default), \`format\` (\`json\` (default), \`parquet\`, or
3518
+ \`csv\`). Use this for large result sets — rows stream directly to S3 instead of
3519
+ being buffered as the script return value.
2766
3520
  `;
2767
3521
  export const LANG_MYSQL = `# MySQL
2768
3522
 
@@ -2775,6 +3529,37 @@ Name the parameters by adding comments before the statement:
2775
3529
  -- ? name2 (int) = 0
2776
3530
  SELECT * FROM users WHERE name = ? AND age > ?;
2777
3531
  \`\`\`
3532
+
3533
+ ## Receiving an S3Object as a script parameter
3534
+
3535
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for
3536
+ it, downloads the file, and binds it as JSON text — Parquet/CSV files are
3537
+ decoded server-side into a JSON array of records, JSON/JSONL pass through.
3538
+ Consume with \`JSON_TABLE\`:
3539
+
3540
+ \`\`\`sql
3541
+ -- ? file (s3object)
3542
+ SELECT id, name
3543
+ FROM JSON_TABLE(?, '$[*]'
3544
+ COLUMNS (id INT PATH '$.id', name VARCHAR(200) PATH '$.name')
3545
+ ) AS r;
3546
+ \`\`\`
3547
+
3548
+ ## Streaming query results to S3
3549
+
3550
+ Add a \`-- s3\` directive at the top of the script to stream the result set to S3
3551
+ instead of returning rows. Windmill writes the file and returns its \`S3Object\`
3552
+ as the script result.
3553
+
3554
+ \`\`\`sql
3555
+ -- s3 prefix=exports/users format=parquet
3556
+ SELECT id, name FROM users;
3557
+ \`\`\`
3558
+
3559
+ All keys are optional: \`prefix\` (object key prefix), \`storage\` (named storage —
3560
+ omit to use the workspace default), \`format\` (\`json\` (default), \`parquet\`, or
3561
+ \`csv\`). Use this for large result sets — rows stream directly to S3 instead of
3562
+ being buffered as the script return value.
2778
3563
  `;
2779
3564
  export const LANG_NATIVETS = `# TypeScript (Native)
2780
3565
 
@@ -2923,6 +3708,35 @@ Name the parameters by adding comments at the beginning of the script (without s
2923
3708
  -- $2 name2 = default_value
2924
3709
  SELECT * FROM users WHERE name = $1::TEXT AND age > $2::INT;
2925
3710
  \`\`\`
3711
+
3712
+ ## Receiving an S3Object as a script parameter
3713
+
3714
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for
3715
+ it, downloads the file, and binds it as a \`jsonb\` parameter — Parquet/CSV files
3716
+ are decoded server-side into a JSON array of records, JSON/JSONL pass through.
3717
+ Consume with \`jsonb_to_recordset\` (or any \`jsonb\` API):
3718
+
3719
+ \`\`\`sql
3720
+ -- $1 file (s3object)
3721
+ SELECT *
3722
+ FROM jsonb_to_recordset($1::jsonb) AS r(id INT, name TEXT);
3723
+ \`\`\`
3724
+
3725
+ ## Streaming query results to S3
3726
+
3727
+ Add a \`-- s3\` directive at the top of the script to stream the result set to S3
3728
+ instead of returning rows. Windmill writes the file and returns its \`S3Object\`
3729
+ as the script result.
3730
+
3731
+ \`\`\`sql
3732
+ -- s3 prefix=exports/users format=parquet
3733
+ SELECT id, name FROM users;
3734
+ \`\`\`
3735
+
3736
+ All keys are optional: \`prefix\` (object key prefix), \`storage\` (named storage —
3737
+ omit to use the workspace default), \`format\` (\`json\` (default), \`parquet\`, or
3738
+ \`csv\`). Use this for large result sets — rows stream directly to S3 instead of
3739
+ being buffered as the script return value.
2926
3740
  `;
2927
3741
  export const LANG_POWERSHELL = `# PowerShell
2928
3742
 
@@ -3080,6 +3894,21 @@ def preprocessor(event: Event):
3080
3894
 
3081
3895
  Windmill provides built-in support for S3-compatible storage operations.
3082
3896
 
3897
+ ### Receiving an S3Object as a script parameter
3898
+
3899
+ To accept a file from S3 as input to a script, type the parameter with \`S3Object\` (imported from \`wmill\`):
3900
+
3901
+ \`\`\`python
3902
+ import wmill
3903
+ from wmill import S3Object
3904
+
3905
+ def main(file: S3Object):
3906
+ content = wmill.load_s3_file(file)
3907
+ # ...
3908
+ \`\`\`
3909
+
3910
+ ### S3 operations
3911
+
3083
3912
  \`\`\`python
3084
3913
  import wmill
3085
3914
 
@@ -3272,4 +4101,35 @@ Name the parameters by adding comments before the statement:
3272
4101
  -- ? name2 (number) = 0
3273
4102
  SELECT * FROM users WHERE name = ? AND age > ?;
3274
4103
  \`\`\`
4104
+
4105
+ ## Receiving an S3Object as a script parameter
4106
+
4107
+ Declare the arg with type \`(s3object)\`. Windmill renders an S3 file picker for
4108
+ it, downloads the file, and binds it as JSON text — Parquet/CSV files are
4109
+ decoded server-side into a JSON array of records, JSON/JSONL pass through.
4110
+ Wrap the bind with \`PARSE_JSON(?)\` and walk it with \`LATERAL FLATTEN\`:
4111
+
4112
+ \`\`\`sql
4113
+ -- ? file (s3object)
4114
+ SELECT
4115
+ v.value:id::NUMBER AS id,
4116
+ v.value:name::STRING AS name
4117
+ FROM LATERAL FLATTEN(input => PARSE_JSON(?)) v;
4118
+ \`\`\`
4119
+
4120
+ ## Streaming query results to S3
4121
+
4122
+ Add a \`-- s3\` directive at the top of the script to stream the result set to S3
4123
+ instead of returning rows. Windmill writes the file and returns its \`S3Object\`
4124
+ as the script result.
4125
+
4126
+ \`\`\`sql
4127
+ -- s3 prefix=exports/users format=parquet
4128
+ SELECT id, name FROM users;
4129
+ \`\`\`
4130
+
4131
+ All keys are optional: \`prefix\` (object key prefix), \`storage\` (named storage —
4132
+ omit to use the workspace default), \`format\` (\`json\` (default), \`parquet\`, or
4133
+ \`csv\`). Use this for large result sets — rows stream directly to S3 instead of
4134
+ being buffered, bypassing the 10000-row return cap.
3275
4135
  `;