windmill-components 1.537.1 → 1.542.5

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 (275) hide show
  1. package/package/components/AIProviderPicker.svelte +181 -0
  2. package/package/components/AIProviderPicker.svelte.d.ts +15 -0
  3. package/package/components/ArgInfo.svelte +2 -2
  4. package/package/components/ArgInput.svelte +35 -9
  5. package/package/components/ArgInput.svelte.d.ts +3 -3
  6. package/package/components/AssignableTagsInner.svelte +89 -3
  7. package/package/components/ConcurrentJobsChart.svelte +36 -48
  8. package/package/components/ConcurrentJobsChart.svelte.d.ts +8 -20
  9. package/package/components/CustomPopover.svelte.d.ts +1 -1
  10. package/package/components/DropdownSelect.svelte +26 -0
  11. package/package/components/DropdownSelect.svelte.d.ts +11 -0
  12. package/package/components/DropdownV2Inner.svelte +1 -1
  13. package/package/components/{DynSelect.svelte → DynamicInput.svelte} +47 -15
  14. package/package/components/DynamicInput.svelte.d.ts +11 -0
  15. package/package/components/EditableSchemaForm.svelte +119 -95
  16. package/package/components/EditableSchemaForm.svelte.d.ts +4 -4
  17. package/package/components/Editor.svelte +86 -93
  18. package/package/components/Editor.svelte.d.ts +4 -3
  19. package/package/components/EditorBar.svelte +2 -5
  20. package/package/components/EditorSettings.svelte +11 -9
  21. package/package/components/FlowBuilder.svelte +3 -3
  22. package/package/components/FlowLogRow.svelte +64 -0
  23. package/package/components/FlowLogRow.svelte.d.ts +15 -0
  24. package/package/components/FlowLogViewer.svelte +406 -373
  25. package/package/components/FlowLogViewer.svelte.d.ts +5 -1
  26. package/package/components/FlowLogViewerWrapper.svelte +44 -1
  27. package/package/components/FlowLoopIterationPreview.svelte.d.ts +1 -1
  28. package/package/components/FlowPreviewContent.svelte.d.ts +1 -1
  29. package/package/components/FlowStatusViewerInner.svelte +34 -3
  30. package/package/components/FolderPicker.svelte +1 -1
  31. package/package/components/InputTransformForm.svelte +20 -10
  32. package/package/components/JobArgs.svelte +1 -1
  33. package/package/components/JobLoader.svelte.d.ts +1 -1
  34. package/package/components/JobStatus.svelte +2 -0
  35. package/package/components/LogSnippetViewer.svelte +3 -3
  36. package/package/components/LogSnippetViewer.svelte.d.ts +1 -1
  37. package/package/components/LogViewer.svelte +87 -71
  38. package/package/components/LogViewer.svelte.d.ts +1 -0
  39. package/package/components/Path.svelte +7 -1
  40. package/package/components/Path.svelte.d.ts +1 -1
  41. package/package/components/PrefixedInput.svelte +120 -0
  42. package/package/components/PrefixedInput.svelte.d.ts +8 -0
  43. package/package/components/QueuePosition.svelte +81 -0
  44. package/package/components/QueuePosition.svelte.d.ts +8 -0
  45. package/package/components/ResourceNarrowing.svelte +13 -0
  46. package/package/components/ResourceNarrowing.svelte.d.ts +6 -0
  47. package/package/components/ResourceTypePicker.svelte +49 -74
  48. package/package/components/RunChart.svelte +74 -89
  49. package/package/components/RunChart.svelte.d.ts +10 -22
  50. package/package/components/S3FilePicker.svelte +1 -1
  51. package/package/components/SchemaForm.svelte.d.ts +2 -2
  52. package/package/components/ScriptBuilder.svelte +2 -1
  53. package/package/components/ScriptEditor.svelte +4 -3
  54. package/package/components/ScriptEditor.svelte.d.ts +2 -1
  55. package/package/components/ServiceLogsInner.svelte +1 -1
  56. package/package/components/ShareModal.svelte.d.ts +1 -1
  57. package/package/components/SimpleEditor.svelte +4 -67
  58. package/package/components/StringTypeNarrowing.svelte +5 -10
  59. package/package/components/TemplateEditor.svelte +2 -16
  60. package/package/components/TimeAgo.svelte +1 -1
  61. package/package/components/TimeAgo.svelte.d.ts +1 -0
  62. package/package/components/Toggle.svelte +2 -1
  63. package/package/components/Toggle.svelte.d.ts +2 -1
  64. package/package/components/WorkerRepl.svelte +1 -1
  65. package/package/components/apps/components/display/AppNavbarItem.svelte +2 -1
  66. package/package/components/apps/components/display/table/AppAggridTable.svelte +44 -48
  67. package/package/components/apps/components/display/table/SyncColumnDefs.svelte +101 -19
  68. package/package/components/apps/components/display/table/SyncColumnDefs.svelte.d.ts +5 -2
  69. package/package/components/apps/components/display/table/utils.js +36 -5
  70. package/package/components/apps/components/inputs/currency/CurrencyInput.svelte +10 -5
  71. package/package/components/apps/editor/AppEditor.svelte +4 -3
  72. package/package/components/apps/editor/AppEditorHeader.svelte +0 -1
  73. package/package/components/apps/editor/GridViewer.svelte.d.ts +11 -4
  74. package/package/components/apps/editor/SettingsPanel.svelte +2 -2
  75. package/package/components/apps/editor/componentsPanel/ListItem.svelte +2 -2
  76. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte.d.ts +1 -1
  77. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorDrawer.svelte.d.ts +1 -1
  78. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte.d.ts +1 -1
  79. package/package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte +26 -3
  80. package/package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +1 -1
  81. package/package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +13 -5
  82. package/package/components/apps/svelte-grid/Grid.svelte.d.ts +30 -11
  83. package/package/components/assets/JobAssetsViewer.svelte +28 -24
  84. package/package/components/auditLogs/AuditLogsTable.svelte +2 -6
  85. package/package/components/chartjs-wrappers/Chart.svelte.d.ts +14 -7
  86. package/package/components/common/OnChange.svelte.d.ts +11 -4
  87. package/package/components/common/badge/Badge.svelte +9 -2
  88. package/package/components/common/badge/Badge.svelte.d.ts +2 -1
  89. package/package/components/common/calendarPicker/CalendarPicker.svelte +5 -1
  90. package/package/components/common/calendarPicker/CalendarPicker.svelte.d.ts +5 -4
  91. package/package/components/common/drawer/Disposable.svelte +9 -11
  92. package/package/components/common/drawer/Drawer.svelte +3 -4
  93. package/package/components/common/drawer/Drawer.svelte.d.ts +1 -0
  94. package/package/components/common/menu/MenuItem.svelte.d.ts +2 -2
  95. package/package/components/common/modal/Modal.svelte.d.ts +1 -1
  96. package/package/components/common/tabs/TabContent.svelte +2 -7
  97. package/package/components/common/tabs/TabContent.svelte.d.ts +5 -27
  98. package/package/components/common/toggleButton-v2/ToggleButtonGroup.svelte +9 -3
  99. package/package/components/common/toggleButton-v2/ToggleButtonGroup.svelte.d.ts +1 -0
  100. package/package/components/common/toggleButton-v2/ToggleButtonMore.svelte +8 -4
  101. package/package/components/common/toggleButton-v2/ToggleButtonMore.svelte.d.ts +1 -0
  102. package/package/components/copilot/MetadataGen.svelte +1 -1
  103. package/package/components/copilot/chat/AIChatManager.svelte.js +24 -102
  104. package/package/components/copilot/chat/AssistantMessage.svelte +0 -4
  105. package/package/components/copilot/chat/anthropic.d.ts +15 -0
  106. package/package/components/copilot/chat/anthropic.js +208 -0
  107. package/package/components/copilot/chat/api/apiTools.d.ts +2 -2
  108. package/package/components/copilot/chat/api/apiTools.js +10 -7
  109. package/package/components/copilot/chat/api/core.d.ts +1 -1
  110. package/package/components/copilot/chat/api/core.js +7 -2
  111. package/package/components/copilot/chat/ask/core.d.ts +1 -1
  112. package/package/components/copilot/chat/ask/core.js +7 -2
  113. package/package/components/copilot/chat/flow/core.d.ts +1 -1
  114. package/package/components/copilot/chat/flow/core.js +14 -4
  115. package/package/components/copilot/chat/monaco-adapter.d.ts +6 -5
  116. package/package/components/copilot/chat/navigator/core.d.ts +1 -1
  117. package/package/components/copilot/chat/navigator/core.js +7 -2
  118. package/package/components/copilot/chat/script/CodeDisplay.svelte +10 -111
  119. package/package/components/copilot/chat/script/core.d.ts +5 -4
  120. package/package/components/copilot/chat/script/core.js +131 -19
  121. package/package/components/copilot/chat/shared.d.ts +7 -7
  122. package/package/components/copilot/lib.d.ts +29 -8
  123. package/package/components/copilot/lib.js +199 -24
  124. package/package/components/custom_ui.d.ts +1 -0
  125. package/package/components/flows/content/FlowInput.svelte +5 -5
  126. package/package/components/flows/content/FlowModuleComponent.svelte +5 -2
  127. package/package/components/flows/content/FlowModuleEarlyStop.svelte +47 -17
  128. package/package/components/flows/content/FlowModuleSleep.svelte +4 -1
  129. package/package/components/flows/content/FlowModuleSuspend.svelte +0 -1
  130. package/package/components/flows/content/FlowModuleTimeout.svelte +50 -10
  131. package/package/components/flows/content/FlowModuleTimeout.svelte.d.ts +1 -0
  132. package/package/components/flows/content/FlowRetries.svelte +108 -3
  133. package/package/components/flows/content/FlowRetries.svelte.d.ts +3 -2
  134. package/package/components/flows/flowInfers.js +8 -35
  135. package/package/components/flows/flowStore.d.ts +45 -1
  136. package/package/components/flows/flowStore.js +1 -1
  137. package/package/components/flows/map/FlowJobsMenu.svelte +3 -3
  138. package/package/components/flows/map/FlowModuleSchemaItem.svelte +61 -54
  139. package/package/components/flows/map/FlowModuleSchemaItem.svelte.d.ts +1 -1
  140. package/package/components/flows/map/FlowModuleSchemaItemViewer.svelte +1 -1
  141. package/package/components/flows/map/InsertModuleButton.svelte +1 -0
  142. package/package/components/flows/map/InsertModuleInner.svelte +12 -15
  143. package/package/components/flows/map/InsertModuleInner.svelte.d.ts +10 -9
  144. package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +1 -1
  145. package/package/components/git_sync/DetectionFlow.svelte +15 -17
  146. package/package/components/git_sync/GitSyncContext.svelte.js +1 -1
  147. package/package/components/git_sync/GitSyncRepositoryCard.svelte +0 -1
  148. package/package/components/graph/graphBuilder.svelte.d.ts +5 -1
  149. package/package/components/graph/renderers/edges/BaseEdge.svelte +9 -1
  150. package/package/components/graph/renderers/edges/BaseEdge.svelte.d.ts +4 -1
  151. package/package/components/graph/renderers/nodes/BranchAllStart.svelte +2 -3
  152. package/package/components/graph/renderers/nodes/BranchOneStart.svelte +2 -3
  153. package/package/components/graph/renderers/triggers/TriggerButton.svelte.d.ts +1 -1
  154. package/package/components/graph/renderers/triggers/TriggersBadge.svelte +3 -1
  155. package/package/components/graph/renderers/triggers/TriggersWrapper.svelte +34 -24
  156. package/package/components/graph/renderers/triggers/TriggersWrapper.svelte.d.ts +1 -2
  157. package/package/components/home/ItemsList.svelte +17 -13
  158. package/package/components/home/TreeView.svelte +21 -27
  159. package/package/components/home/TreeView.svelte.d.ts +2 -29
  160. package/package/components/home/TreeViewRoot.svelte +11 -23
  161. package/package/components/home/TreeViewRoot.svelte.d.ts +15 -13
  162. package/package/components/icons/GitIcon.svelte +10 -2
  163. package/package/components/icons/GitIcon.svelte.d.ts +1 -0
  164. package/package/components/meltComponents/MeltButton.svelte.d.ts +1 -1
  165. package/package/components/meltComponents/Popover.svelte +23 -3
  166. package/package/components/meltComponents/Popover.svelte.d.ts +2 -1
  167. package/package/components/monacoLanguagesOptions.d.ts +3 -0
  168. package/package/components/monacoLanguagesOptions.js +109 -0
  169. package/package/components/propertyPicker/ObjectViewer.svelte +7 -2
  170. package/package/components/propertyPicker/PropPicker.svelte +1 -1
  171. package/package/components/propertyPicker/utils.js +14 -7
  172. package/package/components/runs/JobRunsPreview.svelte +212 -177
  173. package/package/components/runs/JobsLoader.svelte +2 -2
  174. package/package/components/runs/JobsLoader.svelte.d.ts +1 -1
  175. package/package/components/runs/NoWorkerWithTagWarning.svelte +18 -5
  176. package/package/components/runs/RunBadges.svelte +100 -0
  177. package/package/components/runs/RunBadges.svelte.d.ts +12 -0
  178. package/package/components/runs/RunLabels.svelte +86 -0
  179. package/package/components/runs/RunLabels.svelte.d.ts +10 -0
  180. package/package/components/runs/RunOption.svelte +20 -0
  181. package/package/components/runs/RunOption.svelte.d.ts +10 -0
  182. package/package/components/runs/RunRow.svelte +239 -151
  183. package/package/components/runs/RunRow.svelte.d.ts +12 -9
  184. package/package/components/runs/RunsBatchActionsDropdown.svelte +13 -17
  185. package/package/components/runs/RunsBatchActionsDropdown.svelte.d.ts +5 -18
  186. package/package/components/runs/RunsFilter.svelte +369 -243
  187. package/package/components/runs/RunsFilter.svelte.d.ts +2 -0
  188. package/package/components/runs/RunsQueue.svelte +96 -25
  189. package/package/components/runs/RunsQueue.svelte.d.ts +7 -21
  190. package/package/components/runs/RunsTable.svelte +62 -71
  191. package/package/components/runs/RunsTable.svelte.d.ts +2 -1
  192. package/package/components/runs/runs-grid.css +95 -0
  193. package/package/components/schema/EditableSchemaDrawer.svelte +12 -12
  194. package/package/components/schema/FlowPropertyEditor.svelte +197 -206
  195. package/package/components/schema/PropertyEditor.svelte +33 -35
  196. package/package/components/schema/SchemaFormDND.svelte.d.ts +2 -2
  197. package/package/components/search/GlobalSearchModal.svelte +8 -1
  198. package/package/components/select/DraggableTags.svelte.d.ts +17 -7
  199. package/package/components/select/MultiSelect.svelte.d.ts +21 -11
  200. package/package/components/select/Select.svelte +2 -1
  201. package/package/components/select/Select.svelte.d.ts +25 -13
  202. package/package/components/select/SelectDropdown.svelte.d.ts +14 -7
  203. package/package/components/settings/TokenDisplay.svelte +1 -1
  204. package/package/components/sidebar/OperatorMenu.svelte +5 -0
  205. package/package/components/sidebar/SidebarContent.svelte +48 -2
  206. package/package/components/sidebar/WorkspaceMenu.svelte +116 -17
  207. package/package/components/toast.js +6 -3
  208. package/package/components/triggers/AddTriggersButton.svelte +7 -6
  209. package/package/components/triggers/CaptureWrapper.svelte +19 -3
  210. package/package/components/triggers/TriggerLabel.svelte +8 -0
  211. package/package/components/triggers/TriggerTokens.svelte +1 -1
  212. package/package/components/triggers/TriggersEditor.svelte +9 -5
  213. package/package/components/triggers/TriggersTable.svelte +2 -2
  214. package/package/components/triggers/TriggersWrapper.svelte +16 -5
  215. package/package/components/triggers/TriggersWrapper.svelte.d.ts +3 -19
  216. package/package/components/{details/EmailTriggerCaptures.svelte → triggers/email/DefaultEmailCapture.svelte} +5 -5
  217. package/package/components/{details/EmailTriggerCaptures.svelte.d.ts → triggers/email/DefaultEmailCapture.svelte.d.ts} +4 -4
  218. package/package/components/{details/EmailTriggerConfigSection.svelte → triggers/email/DefaultEmailConfigSection.svelte} +24 -14
  219. package/package/components/triggers/email/DefaultEmailConfigSection.svelte.d.ts +13 -0
  220. package/package/components/triggers/email/DefaultEmailPanel.svelte +71 -0
  221. package/package/components/triggers/email/DefaultEmailPanel.svelte.d.ts +11 -0
  222. package/package/components/triggers/email/EmailCapture.svelte +39 -0
  223. package/package/components/triggers/email/EmailCapture.svelte.d.ts +43 -0
  224. package/package/components/triggers/email/EmailTriggerEditor.svelte +20 -0
  225. package/package/components/triggers/email/EmailTriggerEditor.svelte.d.ts +11 -0
  226. package/package/components/triggers/email/EmailTriggerEditorConfigSection.svelte +133 -0
  227. package/package/components/triggers/email/EmailTriggerEditorConfigSection.svelte.d.ts +14 -0
  228. package/package/components/triggers/email/EmailTriggerEditorInner.svelte +335 -0
  229. package/package/components/triggers/email/EmailTriggerEditorInner.svelte.d.ts +22 -0
  230. package/package/components/triggers/email/EmailTriggerPanel.svelte +61 -0
  231. package/package/components/triggers/email/EmailTriggerPanel.svelte.d.ts +14 -0
  232. package/package/components/triggers/email/utils.d.ts +4 -0
  233. package/package/components/triggers/email/utils.js +52 -0
  234. package/package/components/triggers/http/RouteEditorConfigSection.svelte +1 -1
  235. package/package/components/triggers/http/utils.js +1 -1
  236. package/package/components/triggers/triggers.svelte.d.ts +1 -0
  237. package/package/components/triggers/triggers.svelte.js +24 -2
  238. package/package/components/triggers/utils.js +19 -5
  239. package/package/components/triggers.d.ts +1 -1
  240. package/package/components/triggers.js +2 -0
  241. package/package/components/wizards/AgGridWizard.svelte +85 -80
  242. package/package/components/workspaceSettings/AISettings.svelte +74 -22
  243. package/package/components/workspaceSettings/AISettings.svelte.d.ts +2 -1
  244. package/package/components/workspaceSettings/CreateWorkspace.svelte +395 -0
  245. package/package/components/workspaceSettings/CreateWorkspace.svelte.d.ts +6 -0
  246. package/package/components/workspaceSettings/DucklakeSettings.svelte +3 -1
  247. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +1 -1
  248. package/package/components/workspaceSettings/StorageSettings.svelte +69 -48
  249. package/package/gen/core/OpenAPI.js +1 -1
  250. package/package/gen/schemas.gen.d.ts +142 -3
  251. package/package/gen/schemas.gen.js +144 -3
  252. package/package/gen/services.gen.d.ts +129 -1
  253. package/package/gen/services.gen.js +267 -1
  254. package/package/gen/types.gen.d.ts +434 -8
  255. package/package/hubPaths.json +4 -2
  256. package/package/infer.js +1 -1
  257. package/package/keyboardChain.d.ts +5 -0
  258. package/package/keyboardChain.js +40 -0
  259. package/package/services/JobManager.js +2 -2
  260. package/package/stores.d.ts +3 -1
  261. package/package/stores.js +8 -5
  262. package/package/utils/workspaceHierarchy.d.ts +27 -0
  263. package/package/utils/workspaceHierarchy.js +101 -0
  264. package/package/utils.d.ts +6 -3
  265. package/package/utils.js +30 -15
  266. package/package/workspace_settings.js +2 -3
  267. package/package.json +9 -11
  268. package/package/components/DynSelect.svelte.d.ts +0 -11
  269. package/package/components/ObjectTypeNarrowing.svelte +0 -18
  270. package/package/components/ObjectTypeNarrowing.svelte.d.ts +0 -22
  271. package/package/components/details/DetailPageTriggerPanel.svelte +0 -121
  272. package/package/components/details/DetailPageTriggerPanel.svelte.d.ts +0 -20
  273. package/package/components/details/EmailTriggerConfigSection.svelte.d.ts +0 -12
  274. package/package/components/details/EmailTriggerPanel.svelte +0 -76
  275. package/package/components/details/EmailTriggerPanel.svelte.d.ts +0 -26
@@ -1,11 +1,14 @@
1
1
  import { getCurrentModel, workspaceStore } from '../../stores';
2
2
  import { buildClientSchema, printSchema } from 'graphql';
3
- import { OpenAI } from 'openai';
3
+ import OpenAI from 'openai';
4
+ import Anthropic from '@anthropic-ai/sdk';
4
5
  import { get } from 'svelte/store';
5
6
  import { OpenAPI, ResourceService } from '../../gen';
6
7
  import { EDIT_CONFIG, FIX_CONFIG, GEN_CONFIG } from './prompts';
7
8
  import { formatResourceTypes } from './utils';
8
9
  import { z } from 'zod';
10
+ import { processToolCall } from './chat/shared';
11
+ import { generateRandomString } from '../../utils';
9
12
  export const SUPPORTED_LANGUAGES = new Set(Object.keys(GEN_CONFIG.prompts));
10
13
  const OPENAI_MODELS = [
11
14
  'gpt-5',
@@ -17,21 +20,51 @@ const OPENAI_MODELS = [
17
20
  'o3',
18
21
  'o3-mini'
19
22
  ];
20
- // need at least one model for each provider except customai
21
- export const AI_DEFAULT_MODELS = {
22
- openai: OPENAI_MODELS,
23
- azure_openai: OPENAI_MODELS,
24
- anthropic: ['claude-sonnet-4-0', 'claude-sonnet-4-0/thinking', 'claude-3-5-haiku-latest'],
25
- mistral: ['codestral-latest'],
26
- deepseek: ['deepseek-chat', 'deepseek-reasoner'],
27
- googleai: ['gemini-2.0-flash', 'gemini-1.5-flash', 'gemini-1.5-pro'],
28
- groq: ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant'],
29
- openrouter: ['meta-llama/llama-3.2-3b-instruct:free'],
30
- togetherai: ['meta-llama/Llama-3.3-70B-Instruct-Turbo'],
31
- customai: []
23
+ export const AI_PROVIDERS = {
24
+ openai: {
25
+ label: 'OpenAI',
26
+ defaultModels: OPENAI_MODELS
27
+ },
28
+ azure_openai: {
29
+ label: 'Azure OpenAI',
30
+ defaultModels: OPENAI_MODELS
31
+ },
32
+ anthropic: {
33
+ label: 'Anthropic',
34
+ defaultModels: ['claude-sonnet-4-0', 'claude-sonnet-4-0/thinking', 'claude-3-5-haiku-latest']
35
+ },
36
+ mistral: {
37
+ label: 'Mistral',
38
+ defaultModels: ['codestral-latest']
39
+ },
40
+ deepseek: {
41
+ label: 'DeepSeek',
42
+ defaultModels: ['deepseek-chat', 'deepseek-reasoner']
43
+ },
44
+ googleai: {
45
+ label: 'Google AI',
46
+ defaultModels: ['gemini-2.0-flash', 'gemini-1.5-flash', 'gemini-1.5-pro']
47
+ },
48
+ groq: {
49
+ label: 'Groq',
50
+ defaultModels: ['llama-3.3-70b-versatile', 'llama-3.1-8b-instant']
51
+ },
52
+ openrouter: {
53
+ label: 'OpenRouter',
54
+ defaultModels: ['meta-llama/llama-3.2-3b-instruct:free']
55
+ },
56
+ togetherai: {
57
+ label: 'Together AI',
58
+ defaultModels: ['meta-llama/Llama-3.3-70B-Instruct-Turbo']
59
+ },
60
+ customai: {
61
+ label: 'Custom AI',
62
+ defaultModels: []
63
+ }
32
64
  };
33
- export async function fetchAvailableModels(resourcePath, workspace, provider) {
65
+ export async function fetchAvailableModels(resourcePath, workspace, provider, signal) {
34
66
  const models = await fetch(`${location.origin}${OpenAPI.BASE}/w/${workspace}/ai/proxy/models`, {
67
+ signal,
35
68
  headers: {
36
69
  'X-Resource-Path': resourcePath,
37
70
  'X-Provider': provider,
@@ -44,21 +77,34 @@ export async function fetchAvailableModels(resourcePath, workspace, provider) {
44
77
  }
45
78
  const data = (await models.json());
46
79
  if (data.data.length > 0) {
80
+ const sortFunc = (provider) => (a, b) => {
81
+ // First prioritize models in defaultModels array
82
+ const defaultModels = AI_PROVIDERS[provider]?.defaultModels || [];
83
+ const aInDefault = defaultModels.includes(a);
84
+ const bInDefault = defaultModels.includes(b);
85
+ if (aInDefault && !bInDefault)
86
+ return -1;
87
+ if (!aInDefault && bInDefault)
88
+ return 1;
89
+ return 0;
90
+ };
47
91
  switch (provider) {
48
92
  case 'openai':
49
93
  return data.data
50
94
  .filter((m) => m.id.startsWith('gpt-') || m.id.startsWith('o') || m.id.startsWith('codex'))
51
- .map((m) => m.id);
95
+ .map((m) => m.id)
96
+ .sort(sortFunc(provider));
52
97
  case 'azure_openai':
53
98
  return data.data
54
99
  .filter((m) => (m.id.startsWith('gpt-') || m.id.startsWith('o') || m.id.startsWith('codex')) &&
55
100
  m.lifecycle_status !== 'deprecated' &&
56
101
  (m.capabilities.completion || m.capabilities.chat_completion))
57
- .map((m) => m.id);
102
+ .map((m) => m.id)
103
+ .sort(sortFunc(provider));
58
104
  case 'googleai':
59
- return data.data.map((m) => m.id.split('/')[1]);
105
+ return data.data.map((m) => m.id.split('/')[1]).sort(sortFunc(provider));
60
106
  default:
61
- return data.data.map((m) => m.id);
107
+ return data.data.map((m) => m.id).sort(sortFunc(provider));
62
108
  }
63
109
  }
64
110
  return data?.data.map((m) => m.id) ?? [];
@@ -70,9 +116,15 @@ function getModelMaxTokens(provider, model) {
70
116
  else if ((provider === 'azure_openai' || provider === 'openai') && model.startsWith('o')) {
71
117
  return 100000;
72
118
  }
119
+ else if (model.startsWith('claude-sonnet') || model.startsWith('gemini-2.5')) {
120
+ return 64000;
121
+ }
73
122
  else if (model.startsWith('gpt-4.1')) {
74
123
  return 32768;
75
124
  }
125
+ else if (model.startsWith('claude-opus')) {
126
+ return 32000;
127
+ }
76
128
  else if (model.startsWith('gpt-4o') || model.startsWith('codestral')) {
77
129
  return 16384;
78
130
  }
@@ -102,12 +154,13 @@ export function getModelContextWindow(model) {
102
154
  }
103
155
  }
104
156
  function getModelSpecificConfig(modelProvider, tools) {
157
+ const maxTokens = getModelMaxTokens(modelProvider.provider, modelProvider.model);
105
158
  if ((modelProvider.provider === 'openai' || modelProvider.provider === 'azure_openai') &&
106
159
  (modelProvider.model.startsWith('o') || modelProvider.model.startsWith('gpt-5'))) {
107
160
  return {
108
161
  model: modelProvider.model,
109
162
  ...(tools && tools.length > 0 ? { tools } : {}),
110
- max_completion_tokens: getModelMaxTokens(modelProvider.provider, modelProvider.model)
163
+ max_completion_tokens: maxTokens
111
164
  };
112
165
  }
113
166
  else {
@@ -125,7 +178,7 @@ function getModelSpecificConfig(modelProvider, tools) {
125
178
  temperature: 0
126
179
  }),
127
180
  ...(tools && tools.length > 0 ? { tools } : {}),
128
- max_tokens: getModelMaxTokens(modelProvider.provider, modelProvider.model)
181
+ max_tokens: maxTokens
129
182
  };
130
183
  }
131
184
  }
@@ -178,8 +231,10 @@ export const PROVIDER_COMPLETION_CONFIG_MAP = {
178
231
  };
179
232
  class WorkspacedAIClients {
180
233
  openaiClient;
234
+ anthropicClient;
181
235
  init(workspace) {
182
236
  this.initOpenai(workspace);
237
+ this.initAnthropic(workspace);
183
238
  }
184
239
  getBaseURL(workspace) {
185
240
  return `${location.origin}${OpenAPI.BASE}/w/${workspace}/ai/proxy`;
@@ -195,19 +250,33 @@ class WorkspacedAIClients {
195
250
  dangerouslyAllowBrowser: true
196
251
  });
197
252
  }
253
+ initAnthropic(workspace) {
254
+ const baseURL = this.getBaseURL(workspace);
255
+ this.anthropicClient = new Anthropic({
256
+ baseURL,
257
+ apiKey: 'fake-key',
258
+ dangerouslyAllowBrowser: true
259
+ });
260
+ }
198
261
  getOpenaiClient() {
199
262
  if (!this.openaiClient) {
200
263
  throw new Error('OpenAI not initialized');
201
264
  }
202
265
  return this.openaiClient;
203
266
  }
267
+ getAnthropicClient() {
268
+ if (!this.anthropicClient) {
269
+ throw new Error('Anthropic not initialized');
270
+ }
271
+ return this.anthropicClient;
272
+ }
204
273
  }
205
274
  export const workspaceAIClients = new WorkspacedAIClients();
206
275
  export async function testKey({ apiKey, resourcePath, model, abortController, messages, aiProvider }) {
207
276
  if (!apiKey && !resourcePath) {
208
277
  throw new Error('API key or resource path is required');
209
278
  }
210
- const modelToTest = model ?? AI_DEFAULT_MODELS[aiProvider][0];
279
+ const modelToTest = model ?? AI_PROVIDERS[aiProvider].defaultModels[0];
211
280
  if (!modelToTest) {
212
281
  throw new Error('Missing a model to test');
213
282
  }
@@ -339,7 +408,7 @@ const PROMPTS_CONFIGS = {
339
408
  edit: EDIT_CONFIG,
340
409
  gen: GEN_CONFIG
341
410
  };
342
- function getProviderAndCompletionConfig({ messages, stream, tools, forceModelProvider }) {
411
+ export function getProviderAndCompletionConfig({ messages, stream, tools, forceModelProvider }) {
343
412
  const modelProvider = forceModelProvider ?? getCurrentModel();
344
413
  const providerConfig = PROVIDER_COMPLETION_CONFIG_MAP[modelProvider.provider];
345
414
  const processedMessages = prepareMessages(modelProvider.provider, messages);
@@ -449,7 +518,7 @@ export async function getFimCompletion(prompt, suffix, providerModel, abortContr
449
518
  export async function getCompletion(messages, abortController, tools) {
450
519
  const { provider, config } = getProviderAndCompletionConfig({ messages, stream: true, tools });
451
520
  const openaiClient = workspaceAIClients.getOpenaiClient();
452
- const completion = await openaiClient.chat.completions.create(config, {
521
+ const completion = openaiClient.chat.completions.create(config, {
453
522
  signal: abortController.signal,
454
523
  headers: {
455
524
  'X-Provider': provider
@@ -457,6 +526,112 @@ export async function getCompletion(messages, abortController, tools) {
457
526
  });
458
527
  return completion;
459
528
  }
529
+ function extractFirstJSON(str) {
530
+ let depth = 0, i = 0;
531
+ for (; i < str.length; i++) {
532
+ if (str[i] === '{')
533
+ depth++;
534
+ else if (str[i] === '}' && --depth === 0)
535
+ break;
536
+ }
537
+ return str.slice(0, i + 1);
538
+ }
539
+ export async function parseOpenAICompletion(completion, callbacks, messages, addedMessages, tools, helpers) {
540
+ const finalToolCalls = {};
541
+ let answer = '';
542
+ for await (const chunk of completion) {
543
+ if (!('choices' in chunk && chunk.choices.length > 0 && 'delta' in chunk.choices[0])) {
544
+ continue;
545
+ }
546
+ const c = chunk;
547
+ const delta = c.choices[0].delta.content;
548
+ if (delta) {
549
+ answer += delta;
550
+ callbacks.onNewToken(delta);
551
+ }
552
+ const toolCalls = c.choices[0].delta.tool_calls || [];
553
+ if (toolCalls.length > 0 && answer) {
554
+ // if tool calls are present but we have some textual content already, we need to display it to the user first
555
+ callbacks.onMessageEnd();
556
+ answer = '';
557
+ }
558
+ for (let i = 0; i < toolCalls.length; i++) {
559
+ const toolCall = toolCalls[i];
560
+ // Gemini models are missing the index field
561
+ if (toolCall.index === undefined ||
562
+ (typeof toolCall.index === 'string' && toolCall.index === '')) {
563
+ toolCall.index = i;
564
+ }
565
+ // Gemini models are missing the id field
566
+ if (toolCall.id === undefined || (typeof toolCall.id === 'string' && toolCall.id === '')) {
567
+ toolCall.id = generateRandomString();
568
+ }
569
+ const { index } = toolCall;
570
+ let finalToolCall = finalToolCalls[index];
571
+ if (!finalToolCall) {
572
+ finalToolCalls[index] = toolCall;
573
+ }
574
+ else {
575
+ if (toolCall.function?.arguments) {
576
+ if (!finalToolCall.function) {
577
+ finalToolCall.function = toolCall.function;
578
+ }
579
+ else {
580
+ finalToolCall.function.arguments =
581
+ (finalToolCall.function.arguments ?? '') + toolCall.function.arguments;
582
+ // Make sure we only have one JSON object, else for Gemini models it sometimes results in two JSON objects
583
+ finalToolCall.function.arguments = extractFirstJSON(finalToolCall.function.arguments || '{}');
584
+ }
585
+ }
586
+ }
587
+ finalToolCall = finalToolCalls[index];
588
+ if (finalToolCall?.function) {
589
+ const { function: { name: funcName }, id: toolCallId } = finalToolCall;
590
+ if (funcName && toolCallId) {
591
+ const tool = tools.find((t) => t.def.function.name === funcName);
592
+ if (tool && tool.preAction) {
593
+ tool.preAction({ toolCallbacks: callbacks, toolId: toolCallId });
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+ if (answer) {
600
+ const toAdd = { role: 'assistant', content: answer };
601
+ addedMessages.push(toAdd);
602
+ messages.push(toAdd);
603
+ }
604
+ callbacks.onMessageEnd();
605
+ const toolCalls = Object.values(finalToolCalls).filter((toolCall) => toolCall.id !== undefined && toolCall.function?.arguments !== undefined);
606
+ if (toolCalls.length > 0) {
607
+ const toAdd = {
608
+ role: 'assistant',
609
+ tool_calls: toolCalls.map((t) => ({
610
+ ...t,
611
+ function: {
612
+ ...t.function,
613
+ arguments: t.function.arguments || '{}'
614
+ }
615
+ }))
616
+ };
617
+ messages.push(toAdd);
618
+ addedMessages.push(toAdd);
619
+ for (const toolCall of toolCalls) {
620
+ const messageToAdd = await processToolCall({
621
+ tools,
622
+ toolCall,
623
+ helpers,
624
+ toolCallbacks: callbacks
625
+ });
626
+ messages.push(messageToAdd);
627
+ addedMessages.push(messageToAdd);
628
+ }
629
+ }
630
+ else {
631
+ return false;
632
+ }
633
+ return true;
634
+ }
460
635
  export function getResponseFromEvent(part) {
461
636
  return part.choices?.[0]?.delta?.content || '';
462
637
  }
@@ -544,7 +719,7 @@ export async function deltaCodeCompletion(messages, generatedCodeDelta, abortCon
544
719
  continue;
545
720
  }
546
721
  if (!match[1].endsWith('`')) {
547
- // skip udpating if possible that part of three ticks (end of code block)s
722
+ // skip updating if possible that part of three ticks (end of code block)s
548
723
  delta = getStringEndDelta(code, match[1]);
549
724
  generatedCodeDelta.set(delta);
550
725
  code = match[1];
@@ -65,6 +65,7 @@ export type EditorBarUi = {
65
65
  assistants?: boolean;
66
66
  multiplayer?: boolean;
67
67
  autoformatting?: boolean;
68
+ editorSettings?: boolean;
68
69
  vimMode?: boolean;
69
70
  relativeLineNumbers?: boolean;
70
71
  aiGen?: boolean;
@@ -35,8 +35,8 @@ let runDisabled = $state(false);
35
35
  let editableSchemaForm = $state(undefined);
36
36
  let savedPreviewArgs = $state(undefined);
37
37
  let isValid = $state(true);
38
- let dynSelectCode = $state(undefined);
39
- let dynSelectLang = $state(undefined);
38
+ let dynCode = $state(undefined);
39
+ let dynLang = $state(undefined);
40
40
  function updateEditPanelSize(size) {
41
41
  if (!$flowInputEditorState)
42
42
  return;
@@ -306,7 +306,7 @@ function resetSelected() {
306
306
  on:delete={(e) => {
307
307
  addPropertyV2?.handleDeleteArgument([e.detail])
308
308
  }}
309
- showDynSelectOpt
309
+ showDynOpt
310
310
  displayWebhookWarning
311
311
  editTab={$flowInputEditorState?.selectedTab}
312
312
  {previewSchema}
@@ -345,8 +345,8 @@ function resetSelected() {
345
345
  }
346
346
  }}
347
347
  bind:isValid
348
- bind:dynSelectCode
349
- bind:dynSelectLang
348
+ bind:dynCode
349
+ bind:dynLang
350
350
  >
351
351
  {#snippet openEditTab()}
352
352
  <div class={twMerge('flex flex-row divide-x', ButtonType.ColorVariants.blue.divider)}>
@@ -564,7 +564,7 @@ function onJobDone() {
564
564
  </Tooltip>
565
565
  </div>
566
566
  <div class="my-8"></div>
567
- <FlowRetries bind:flowModuleRetry={flowModule.retry} />
567
+ <FlowRetries bind:flowModuleRetry={flowModule.retry} bind:flowModule />
568
568
  </Section>
569
569
  {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'concurrency'}
570
570
  <Section label="Concurrency limits" class="flex flex-col gap-4" eeOnly>
@@ -626,7 +626,10 @@ function onJobDone() {
626
626
  </Section>
627
627
  {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'timeout'}
628
628
  <div>
629
- <FlowModuleTimeout bind:flowModule />
629
+ <FlowModuleTimeout
630
+ previousModuleId={previousModule?.id}
631
+ bind:flowModule
632
+ />
630
633
  </div>
631
634
  {:else if advancedSelected === 'runtime' && advancedRuntimeSelected === 'priority'}
632
635
  <Section label="Priority" class="flex flex-col gap-4">
@@ -11,40 +11,50 @@ const { flowStateStore, flowStore, previewArgs } = getContext('FlowEditorContext
11
11
  let { flowModule = $bindable() } = $props();
12
12
  let editor = $state(undefined);
13
13
  let stepPropPicker = $derived(getStepPropPicker(flowStateStore.val, undefined, undefined, flowModule.id, flowStore.val, previewArgs.val, false));
14
- function checkIfParentLoop(flowStoreValue) {
14
+ function checkIfBreakableParent(flowStoreValue) {
15
15
  const flow = JSON.parse(JSON.stringify(flowStoreValue));
16
16
  const parents = dfs(flowModule.id, flow, true);
17
17
  for (const parent of parents.slice(1)) {
18
18
  if (parent.value.type === 'forloopflow' || parent.value.type === 'whileloopflow') {
19
- return parent.id;
19
+ return { stepId: parent.id, isParallel: parent.value.parallel ?? false, type: 'loop' };
20
+ }
21
+ else if (parent.value.type === 'branchall' && parent.value.parallel) {
22
+ return { stepId: parent.id, isParallel: true, type: 'branchall' };
20
23
  }
21
24
  }
22
25
  return null;
23
26
  }
24
27
  let raise_error_message_stop_after_all_if = $state(flowModule.stop_after_all_iters_if?.error_message !== undefined);
25
28
  let raise_error_message_stop_after_if = $state(flowModule.stop_after_if?.error_message !== undefined);
26
- let isLoop = $derived(flowModule.value.type === 'forloopflow' || flowModule.value.type === 'whileloopflow');
29
+ let { isLoop, isParallelLoop } = $derived(flowModule.value.type === 'forloopflow' || flowModule.value.type === 'whileloopflow'
30
+ ? { isLoop: true, isParallelLoop: flowModule.value.parallel ?? false }
31
+ : { isLoop: false, isParallelLoop: false });
27
32
  let isBranchAll = $derived(flowModule.value.type === 'branchall');
28
33
  let isStopAfterIfEnabled = $derived(Boolean(flowModule.stop_after_if));
29
34
  let isStopAfterAllIterationsEnabled = $derived(Boolean(flowModule.stop_after_all_iters_if));
30
35
  let result = $derived(flowStateStore.val[flowModule.id]?.previewResult ?? NEVER_TESTED_THIS_FAR);
31
- let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
36
+ let breakableParent = $derived(checkIfBreakableParent(flowStore.val));
32
37
  </script>
33
38
 
34
39
  <div class="flex flex-col items-start space-y-2">
35
- {#if !isBranchAll}
40
+ {#if !isBranchAll && !isParallelLoop}
36
41
  <Section
37
42
  label={(isLoop
38
43
  ? 'Break loop'
39
- : parentLoopId
40
- ? 'Break parent loop module ' + parentLoopId
44
+ : breakableParent
45
+ ? breakableParent.isParallel
46
+ ? breakableParent.type === 'loop'
47
+ ? 'Skip rest of steps in iteration'
48
+ : 'Skip rest of steps in branch'
49
+ : 'Break parent loop module ' + breakableParent.stepId
41
50
  : 'Stop flow early') + (isLoop ? ' (evaluated after each iteration)' : '')}
42
51
  class="w-full"
43
52
  >
44
53
  {#snippet header()}
45
54
  <Tooltip documentationLink="https://www.windmill.dev/docs/flows/early_stop">
46
55
  If defined, at the end of the step, the predicate expression will be evaluated to decide
47
- if the flow should stop early or break if inside a for/while loop.
56
+ if the flow should stop early, skip rest of steps in iteration/branch if inside a parallel
57
+ for loop or branch all, or break if inside a for/while loop or branch all.
48
58
  </Tooltip>
49
59
  {/snippet}
50
60
 
@@ -64,8 +74,12 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
64
74
  options={{
65
75
  right: isLoop
66
76
  ? 'Break loop'
67
- : parentLoopId
68
- ? 'Break parent loop module'
77
+ : breakableParent
78
+ ? breakableParent.isParallel
79
+ ? breakableParent.type === 'loop'
80
+ ? 'Skip rest of steps in iteration'
81
+ : 'Skip rest of steps in branch'
82
+ : 'Break parent loop module'
69
83
  : 'Stop flow if condition met'
70
84
  }}
71
85
  />
@@ -83,7 +97,7 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
83
97
  ? result
84
98
  : undefined
85
99
  : result}
86
- {#if !parentLoopId && !isLoop}
100
+ {#if !breakableParent && !isLoop}
87
101
  <div class="flex flex-col gap-2">
88
102
  <Toggle
89
103
  size="xs"
@@ -140,15 +154,17 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
140
154
  </PropPickerWrapper>
141
155
  </div>
142
156
  {:else}
143
- {#if !parentLoopId && !isLoop}
157
+ {#if !breakableParent && !isLoop}
144
158
  <div class="flex flex-col gap-2">
145
159
  <Toggle
160
+ disabled
146
161
  size="xs"
147
162
  options={{
148
163
  right: 'Label flow as "skipped" if stopped'
149
164
  }}
150
165
  />
151
166
  <Toggle
167
+ disabled
152
168
  size="xs"
153
169
  options={{
154
170
  right: 'Raise an error message if stopped'
@@ -165,7 +181,13 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
165
181
 
166
182
  {#if isLoop || isBranchAll}
167
183
  <Section
168
- label={(parentLoopId ? 'Break parent loop module ' + parentLoopId : 'Stop flow early') +
184
+ label={(breakableParent
185
+ ? breakableParent.isParallel
186
+ ? breakableParent.type === 'loop'
187
+ ? 'Skip rest of steps in iteration'
188
+ : 'Skip rest of steps in branch'
189
+ : 'Break parent loop module ' + breakableParent.stepId
190
+ : 'Stop flow early') +
169
191
  (isBranchAll
170
192
  ? ' (evaluated after all branches have been run)'
171
193
  : ' (evaluated after all iterations)')}
@@ -174,7 +196,8 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
174
196
  {#snippet header()}
175
197
  <Tooltip documentationLink="https://www.windmill.dev/docs/flows/early_stop">
176
198
  If defined, at the end of the step, the predicate expression will be evaluated to decide
177
- if the flow should stop early or break if inside a for/while loop.
199
+ if the flow should stop early, skip rest of steps in iteration/branch if inside a parallel
200
+ for loop or branch all, or break if inside a for/while loop or branch all.
178
201
  </Tooltip>
179
202
  {/snippet}
180
203
 
@@ -192,7 +215,14 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
192
215
  }
193
216
  }}
194
217
  options={{
195
- right: (parentLoopId ? 'Break parent loop module' : 'Stop flow') + ' if condition met'
218
+ right:
219
+ (breakableParent
220
+ ? breakableParent.isParallel
221
+ ? breakableParent.type === 'loop'
222
+ ? 'Skip rest of steps in iteration'
223
+ : 'Skip rest of steps in branch'
224
+ : 'Break parent loop module ' + breakableParent.stepId
225
+ : 'Stop flow') + ' if condition met'
196
226
  }}
197
227
  />
198
228
 
@@ -202,7 +232,7 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
202
232
  : 'bg-surface-secondary'}"
203
233
  >
204
234
  {#if flowModule.stop_after_all_iters_if}
205
- {#if !parentLoopId}
235
+ {#if !breakableParent}
206
236
  <div class="flex flex-col gap-2">
207
237
  <Toggle
208
238
  size="xs"
@@ -258,7 +288,7 @@ let parentLoopId = $derived(checkIfParentLoop(flowStore.val));
258
288
  </PropPickerWrapper>
259
289
  </div>
260
290
  {:else}
261
- {#if !parentLoopId}
291
+ {#if !breakableParent}
262
292
  <div class="flex flex-col gap-2">
263
293
  <Toggle
264
294
  disabled
@@ -7,13 +7,15 @@ import PropPickerWrapper from '../propPicker/PropPickerWrapper.svelte';
7
7
  import { SecondsInput } from '../../common';
8
8
  import Section from '../../Section.svelte';
9
9
  import Label from '../../Label.svelte';
10
+ import { getStepPropPicker } from '../previousResults';
10
11
  let { flowModule = $bindable(), previousModuleId } = $props();
11
- const { selectedId, flowStateStore } = getContext('FlowEditorContext');
12
+ const { selectedId, flowStore, flowStateStore, previewArgs } = getContext('FlowEditorContext');
12
13
  let schema = $state(emptySchema());
13
14
  schema.properties['sleep'] = {
14
15
  type: 'number'
15
16
  };
16
17
  let editor = $state(undefined);
18
+ let stepPropPicker = $derived(getStepPropPicker(flowStateStore.val, undefined, undefined, flowModule.id, flowStore.val, previewArgs.val, false));
17
19
  const result = flowStateStore.val[$selectedId]?.previewResult ?? {};
18
20
  let isSleepEnabled = $derived(Boolean(flowModule.sleep));
19
21
  </script>
@@ -47,6 +49,7 @@ let isSleepEnabled = $derived(Boolean(flowModule.sleep));
47
49
  <div class="border">
48
50
  <PropPickerWrapper
49
51
  noFlowPlugConnect={true}
52
+ flow_input={stepPropPicker.pickableProperties.flow_input}
50
53
  notSelectable
51
54
  {result}
52
55
  displayContext={false}
@@ -53,7 +53,6 @@ $effect(() => {
53
53
  let jsonView = $state(false);
54
54
  </script>
55
55
 
56
- A{JSON.stringify(flowModule.suspend?.resume_form)}B
57
56
  <Section label="Suspend/Approval/Prompt" class="w-full">
58
57
  {#snippet action()}
59
58
  <SuspendDrawer text="Approval/Prompt helpers" />