windmill-components 1.532.0 → 1.537.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/package/components/ArgInput.svelte +25 -18
  2. package/package/components/Auth0Setting.svelte +8 -3
  3. package/package/components/Dev.svelte +5 -4
  4. package/package/components/DiffDrawer.svelte +2 -2
  5. package/package/components/DiffEditor.svelte +34 -37
  6. package/package/components/DiffEditor.svelte.d.ts +23 -39
  7. package/package/components/EditableSchemaForm.svelte +42 -51
  8. package/package/components/EditableSchemaForm.svelte.d.ts +2 -3
  9. package/package/components/Editor.svelte +30 -9
  10. package/package/components/Editor.svelte.d.ts +5 -0
  11. package/package/components/FlowBuilder.svelte +7 -4
  12. package/package/components/FlowPreviewContent.svelte +3 -3
  13. package/package/components/FlowStatusViewer.svelte +28 -0
  14. package/package/components/FlowStatusViewerInner.svelte +72 -20
  15. package/package/components/FlowStatusViewerInner.svelte.d.ts +7 -0
  16. package/package/components/ModulePreview.svelte +2 -1
  17. package/package/components/ModulePreview.svelte.d.ts +1 -0
  18. package/package/components/ModulePreviewForm.svelte +72 -65
  19. package/package/components/ModulePreviewResultViewer.svelte +13 -18
  20. package/package/components/ModuleTest.svelte +6 -5
  21. package/package/components/ModuleTest.svelte.d.ts +1 -0
  22. package/package/components/OktaSetting.svelte +8 -3
  23. package/package/components/Portal.svelte +11 -7
  24. package/package/components/Portal.svelte.d.ts +19 -39
  25. package/package/components/RunForm.svelte +2 -2
  26. package/package/components/RunForm.svelte.d.ts +1 -1
  27. package/package/components/RunFormAdvancedPopup.svelte +13 -1
  28. package/package/components/SchemaForm.svelte +1 -2
  29. package/package/components/ScriptBuilder.svelte +1 -1
  30. package/package/components/ScriptEditor.svelte +21 -7
  31. package/package/components/SimpleEditor.svelte +0 -1
  32. package/package/components/apps/components/layout/AppModal.svelte +2 -2
  33. package/package/components/apps/editor/component/ComponentNavigation.svelte +3 -2
  34. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +1 -1
  35. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte +0 -1
  36. package/package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte +3 -1
  37. package/package/components/apps/editor/settingsPanel/GridCondition.svelte +3 -1
  38. package/package/components/apps/editor/settingsPanel/GridNavbar.svelte +3 -1
  39. package/package/components/apps/editor/settingsPanel/GridTab.svelte +3 -1
  40. package/package/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte +55 -53
  41. package/package/components/apps/editor/settingsPanel/TableActions.svelte +3 -1
  42. package/package/components/common/button/model.d.ts +1 -1
  43. package/package/components/common/drawer/Disposable.svelte +51 -30
  44. package/package/components/common/drawer/Disposable.svelte.d.ts +12 -44
  45. package/package/components/common/drawer/Drawer.svelte +15 -11
  46. package/package/components/copilot/MetadataGen.svelte +14 -3
  47. package/package/components/copilot/chat/AIChatInput.svelte +0 -1
  48. package/package/components/copilot/chat/AIChatManager.svelte.js +3 -3
  49. package/package/components/copilot/chat/AvailableContextList.svelte +192 -66
  50. package/package/components/copilot/chat/AvailableContextList.svelte.d.ts +2 -2
  51. package/package/components/copilot/chat/ContextElementBadge.svelte +3 -3
  52. package/package/components/copilot/chat/ContextManager.svelte.js +36 -13
  53. package/package/components/copilot/chat/ContextTextarea.svelte +21 -48
  54. package/package/components/copilot/chat/ToolContentDisplay.svelte +10 -1
  55. package/package/components/copilot/chat/ToolExecutionDisplay.svelte +3 -3
  56. package/package/components/copilot/chat/context.d.ts +7 -2
  57. package/package/components/copilot/chat/flow/FlowAIChat.svelte +110 -8
  58. package/package/components/copilot/chat/flow/core.d.ts +11 -0
  59. package/package/components/copilot/chat/flow/core.js +121 -3
  60. package/package/components/copilot/chat/flow/uiIntents.d.ts +8 -0
  61. package/package/components/copilot/chat/flow/uiIntents.js +5 -0
  62. package/package/components/copilot/chat/flow/useUiIntent.d.ts +5 -0
  63. package/package/components/copilot/chat/flow/useUiIntent.js +12 -0
  64. package/package/components/copilot/chat/monaco-adapter.d.ts +22 -4
  65. package/package/components/copilot/chat/monaco-adapter.js +55 -16
  66. package/package/components/copilot/chat/script/core.js +3 -2
  67. package/package/components/copilot/chat/shared.d.ts +3 -2
  68. package/package/components/copilot/chat/shared.js +24 -12
  69. package/package/components/copilot/lib.js +12 -7
  70. package/package/components/copilot/shared.d.ts +1 -1
  71. package/package/components/copilot/shared.js +16 -10
  72. package/package/components/flows/FlowEditor.svelte +4 -2
  73. package/package/components/flows/FlowEditor.svelte.d.ts +1 -0
  74. package/package/components/flows/FlowModuleIcon.svelte +8 -8
  75. package/package/components/flows/common/FlowCardHeader.svelte +4 -1
  76. package/package/components/flows/content/FlowBranchesAllWrapper.svelte +6 -0
  77. package/package/components/flows/content/FlowBranchesOneWrapper.svelte +6 -0
  78. package/package/components/flows/content/FlowEditorPanel.svelte +2 -1
  79. package/package/components/flows/content/FlowEditorPanel.svelte.d.ts +1 -0
  80. package/package/components/flows/content/FlowInput.svelte +31 -34
  81. package/package/components/flows/content/FlowInput.svelte.d.ts +1 -0
  82. package/package/components/flows/content/FlowLoop.svelte +7 -0
  83. package/package/components/flows/content/FlowModuleComponent.svelte +37 -44
  84. package/package/components/flows/content/FlowModuleScript.svelte +1 -1
  85. package/package/components/flows/content/FlowModuleSuspend.svelte +16 -18
  86. package/package/components/flows/content/FlowWhileLoop.svelte +6 -0
  87. package/package/components/flows/content/ScriptEditorDrawer.svelte +9 -11
  88. package/package/components/flows/dfs.d.ts +1 -1
  89. package/package/components/flows/dfs.js +6 -6
  90. package/package/components/flows/flowInfers.js +7 -7
  91. package/package/components/flows/flowStateUtils.svelte.js +1 -2
  92. package/package/components/flows/map/FlowModuleSchemaItem.svelte +12 -26
  93. package/package/components/flows/map/MapItem.svelte +8 -4
  94. package/package/components/flows/map/VirtualItem.svelte +1 -1
  95. package/package/components/flows/pickers/TopLevelNode.svelte +1 -1
  96. package/package/components/flows/propPicker/InputPickerInner.svelte +5 -5
  97. package/package/components/flows/propPicker/OutputPickerInner.svelte +143 -118
  98. package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +7 -16
  99. package/package/components/flows/{testSteps.svelte.d.ts → stepsInputArgs.svelte.d.ts} +2 -1
  100. package/package/components/flows/{testSteps.svelte.js → stepsInputArgs.svelte.js} +15 -3
  101. package/package/components/flows/types.d.ts +16 -3
  102. package/package/components/flows/utils.js +3 -0
  103. package/package/components/graph/FlowGraphV2.svelte +1 -1
  104. package/package/components/graph/renderers/nodes/AIToolNode.svelte +4 -4
  105. package/package/components/graph/renderers/nodes/NewAIToolNode.svelte +71 -54
  106. package/package/components/propertyPicker/ObjectViewer.svelte +11 -3
  107. package/package/components/raw_apps/RawAppInlineScriptEditor.svelte +1 -1
  108. package/package/components/schema/AddPropertyV2.svelte +2 -7
  109. package/package/components/schema/AddPropertyV2.svelte.d.ts +3 -20
  110. package/package/components/schema/EditableSchemaDrawer.svelte +109 -115
  111. package/package/components/schema/EditableSchemaDrawer.svelte.d.ts +2 -1
  112. package/package/components/schema/EditableSchemaSdkWrapper.svelte +16 -3
  113. package/package/components/schema/EditableSchemaSdkWrapper.svelte.d.ts +4 -1
  114. package/package/components/schema/EditableSchemaWrapper.svelte +3 -10
  115. package/package/components/schema/FlowPropertyEditor.svelte +9 -41
  116. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +1 -1
  117. package/package/components/schema/SchemaFormDND.svelte +11 -10
  118. package/package/components/schema/SchemaFormDND.svelte.d.ts +3 -2
  119. package/package/components/schema/editable_schema_wrapper.d.ts +0 -3
  120. package/package/components/settings/PremiumInfo.svelte +7 -2
  121. package/package/components/triggers/CaptureWrapper.svelte +2 -13
  122. package/package/components/triggers/CaptureWrapper.svelte.d.ts +1 -1
  123. package/package/components/triggers/TriggersWrapper.svelte +1 -0
  124. package/package/components/triggers/http/RouteEditorInner.svelte +1 -1
  125. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +23 -20
  126. package/package/components/triggers/nats/NatsTriggersConfigSection.svelte +15 -27
  127. package/package/components/triggers/nats/NatsTriggersConfigSection.svelte.d.ts +7 -5
  128. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +16 -16
  129. package/package/hubPaths.json +3 -1
  130. package/package/script_helpers.d.ts +2 -2
  131. package/package/script_helpers.js +2 -0
  132. package/package/stores.d.ts +1 -0
  133. package/package/stores.js +8 -1
  134. package/package.json +2 -2
  135. package/package/components/ModulePreviewResultViewer.svelte.d.ts +0 -28
@@ -0,0 +1,12 @@
1
+ import { uiIntentStore } from './uiIntents';
2
+ import { onDestroy } from 'svelte';
3
+ export function useUiIntent(componentId, handlers) {
4
+ const unsub = uiIntentStore.subscribe((intent) => {
5
+ if (!intent || intent.componentId !== componentId)
6
+ return;
7
+ if (intent.kind === 'open_module_tab')
8
+ handlers.openTab?.(intent.tab);
9
+ uiIntentStore.set(null);
10
+ });
11
+ onDestroy(() => unsub());
12
+ }
@@ -15,18 +15,36 @@ export declare class AIChatEditorHandler {
15
15
  changes: VisualChangeWithDiffIndex[];
16
16
  groupIndex: number;
17
17
  }[];
18
+ private reviewState;
18
19
  constructor(editor: meditor.IStandaloneCodeEditor);
19
20
  clear(): void;
20
21
  preventWriting(): void;
21
22
  allowWriting(): void;
22
- finish(): Promise<void>;
23
- acceptAll(): Promise<void>;
24
- rejectAll(): Promise<void>;
23
+ finish(opts?: {
24
+ disableReviewCallback?: boolean;
25
+ }): Promise<void>;
26
+ getReviewMode(): 'apply' | 'revert' | null;
27
+ acceptAll(opts?: {
28
+ disableReviewCallback?: boolean;
29
+ }): Promise<void>;
30
+ rejectAll(opts?: {
31
+ disableReviewCallback?: boolean;
32
+ }): Promise<void>;
33
+ keepAll(opts?: {
34
+ disableReviewCallback?: boolean;
35
+ }): Promise<void>;
36
+ revertAll(opts?: {
37
+ disableReviewCallback?: boolean;
38
+ }): Promise<void>;
25
39
  applyGroup(group: {
26
40
  changes: VisualChangeWithDiffIndex[];
27
41
  groupIndex: number;
28
42
  }): void;
29
43
  private calculateVisualChanges;
30
- reviewAndApply(newCode: string, applyAll?: boolean): Promise<void>;
44
+ reviewChanges(targetCode: string, opts?: {
45
+ applyAll?: boolean;
46
+ mode?: 'apply' | 'revert';
47
+ onFinishedReview?: () => void;
48
+ }): Promise<void>;
31
49
  }
32
50
  export {};
@@ -10,6 +10,8 @@ export class AIChatEditorHandler {
10
10
  readOnlyDisposable = undefined;
11
11
  reviewingChanges = writable(false);
12
12
  groupChanges = [];
13
+ // Track review decisions
14
+ reviewState = null;
13
15
  constructor(editor) {
14
16
  this.editor = editor;
15
17
  }
@@ -48,7 +50,14 @@ export class AIChatEditorHandler {
48
50
  this.readOnlyDisposable.dispose();
49
51
  }
50
52
  }
51
- async finish() {
53
+ async finish(opts) {
54
+ // expose mode getter relies on reviewState
55
+ // Call completion callback if we're tracking review state
56
+ if (this.reviewState?.onFinishedReview && !opts?.disableReviewCallback) {
57
+ this.reviewState.onFinishedReview();
58
+ }
59
+ // Reset review state
60
+ this.reviewState = null;
52
61
  this.clear();
53
62
  this.allowWriting();
54
63
  this.reviewingChanges.set(false);
@@ -56,15 +65,26 @@ export class AIChatEditorHandler {
56
65
  scrollBeyondLastLine: false
57
66
  });
58
67
  }
59
- async acceptAll() {
68
+ getReviewMode() {
69
+ return this.reviewState?.mode ?? null;
70
+ }
71
+ async acceptAll(opts) {
60
72
  this.groupChanges.reverse();
61
73
  for (const group of this.groupChanges) {
62
74
  this.applyGroup(group);
63
75
  }
64
- this.finish();
76
+ this.finish(opts);
77
+ }
78
+ async rejectAll(opts) {
79
+ this.finish(opts);
80
+ }
81
+ // Keep all changes, used in revert mode
82
+ async keepAll(opts) {
83
+ this.finish(opts);
65
84
  }
66
- async rejectAll() {
67
- this.finish();
85
+ // Revert all changes, used in revert mode
86
+ async revertAll(opts) {
87
+ this.acceptAll(opts);
68
88
  }
69
89
  applyGroup(group) {
70
90
  // maximum of 2 changes per group with the deletion first
@@ -147,23 +167,30 @@ export class AIChatEditorHandler {
147
167
  }
148
168
  return changedLines;
149
169
  }
150
- async reviewAndApply(newCode, applyAll = false) {
151
- if (aiChatManager.pendingNewCode === newCode) {
170
+ async reviewChanges(targetCode, opts) {
171
+ if (aiChatManager.pendingNewCode === targetCode && opts?.mode === 'apply') {
152
172
  this.acceptAll();
153
173
  return;
154
174
  }
155
175
  else if (aiChatManager.pendingNewCode) {
156
176
  this.clear();
157
177
  }
158
- aiChatManager.pendingNewCode = newCode;
159
- const changedLines = await this.calculateVisualChanges(newCode);
178
+ aiChatManager.pendingNewCode = targetCode;
179
+ const changedLines = await this.calculateVisualChanges(targetCode);
160
180
  if (changedLines.length === 0)
161
181
  return;
182
+ // Initialize review state for tracking
183
+ this.reviewState = {
184
+ mode: opts?.mode ?? 'apply',
185
+ onFinishedReview: opts?.onFinishedReview
186
+ };
162
187
  let indicesOfRejectedLineChanges = [];
163
188
  for (const [groupIndex, group] of this.groupChanges.entries()) {
164
189
  let collection = undefined;
165
190
  let ids = [];
166
- const acceptFn = () => {
191
+ const isRevert = opts?.mode === 'revert';
192
+ // Apply this group and continue with remaining changes
193
+ const onApply = () => {
167
194
  this.applyGroup(group);
168
195
  this.clear();
169
196
  let newCodeWithRejects = '';
@@ -178,9 +205,11 @@ export class AIChatEditorHandler {
178
205
  newCodeWithRejects += change.value;
179
206
  }
180
207
  }
181
- this.reviewAndApply(newCodeWithRejects);
208
+ this.reviewChanges(newCodeWithRejects, opts);
182
209
  };
183
- const rejectFn = () => {
210
+ // Discard this group and continue with remaining changes
211
+ const onDiscard = () => {
212
+ // This group was not applied (not reverted in revert mode)
184
213
  indicesOfRejectedLineChanges.push(...group.changes.map((c) => c.diffIndex));
185
214
  collection?.clear();
186
215
  this.editor.changeViewZones((acc) => {
@@ -193,25 +222,35 @@ export class AIChatEditorHandler {
193
222
  this.finish();
194
223
  }
195
224
  };
225
+ // In revert mode: Accept = keep current code, Reject = revert to targetCode
226
+ // In apply mode: Accept = apply changes, Reject = discard changes
227
+ const acceptFn = isRevert ? onDiscard : onApply;
228
+ const rejectFn = isRevert ? onApply : onDiscard;
196
229
  const changes = group.changes.map((c, i) => {
197
230
  if (i === group.changes.length - 1) {
198
231
  return {
199
232
  ...c,
200
- options: { ...(c.options ?? {}), review: { acceptFn, rejectFn } }
233
+ options: {
234
+ ...(c.options ?? {}),
235
+ review: {
236
+ acceptFn,
237
+ rejectFn
238
+ }
239
+ }
201
240
  };
202
241
  }
203
242
  else {
204
243
  return c;
205
244
  }
206
245
  });
207
- if (!applyAll) {
246
+ if (!opts?.applyAll) {
208
247
  ;
209
- ({ collection, ids } = await displayVisualChanges('editor-windmill-chat-style', this.editor, changes));
248
+ ({ collection, ids } = await displayVisualChanges('editor-windmill-chat-style', this.editor, changes, isRevert));
210
249
  this.decorationsCollections.push(collection);
211
250
  this.viewZoneIds.push(...ids);
212
251
  }
213
252
  }
214
- if (applyAll) {
253
+ if (opts?.applyAll) {
215
254
  this.acceptAll();
216
255
  }
217
256
  }
@@ -2,7 +2,7 @@ import { ResourceService, JobService } from '../../../../gen/services.gen';
2
2
  import { capitalize, isObject, toCamel } from '../../../../utils';
3
3
  import { get } from 'svelte/store';
4
4
  import { compile, phpCompile, pythonCompile } from '../../utils';
5
- import { copilotSessionModel, dbSchemas } from '../../../../stores';
5
+ import { dbSchemas, getCurrentModel } from '../../../../stores';
6
6
  import { getDbSchemas } from '../../../apps/components/display/dbtable/utils';
7
7
  import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '../../../../script_helpers';
8
8
  import { createSearchHubScriptsTool, executeTestRun, buildTestRunArgs, buildContextString } from '../shared';
@@ -522,7 +522,8 @@ export async function searchExternalIntegrationResources(args) {
522
522
  const result = await fetch(`https://registry.npmjs.org/-/v1/search?text=${args.query}&size=2`);
523
523
  const data = await result.json();
524
524
  const filtered = data.objects.filter((r) => r.searchScore >= SCORE_THRESHOLD);
525
- const modelContextWindow = getModelContextWindow(get(copilotSessionModel)?.model ?? '');
525
+ const model = getCurrentModel();
526
+ const modelContextWindow = getModelContextWindow(model.model);
526
527
  const results = await Promise.all(filtered.map(async (r) => {
527
528
  let documentation = '';
528
529
  let types = '';
@@ -1,5 +1,5 @@
1
1
  import type { ChatCompletionMessageParam, ChatCompletionMessageToolCall, ChatCompletionTool } from 'openai/resources/chat/completions.mjs';
2
- import type { CodePieceElement, ContextElement } from './context';
2
+ import type { ContextElement, FlowModuleCodePieceElement } from './context';
3
3
  import type { ExtendedOpenFlow } from '../../flows/types';
4
4
  import type { FunctionParameters } from 'openai/resources/shared.mjs';
5
5
  import { z } from 'zod';
@@ -12,8 +12,9 @@ export interface ContextStringResult {
12
12
  hasDiff: boolean;
13
13
  hasFlowModule: boolean;
14
14
  }
15
+ export declare const extractAllModules: (modules: FlowModule[]) => FlowModule[];
15
16
  export declare const findModuleById: (modules: FlowModule[], moduleId: string) => FlowModule | undefined;
16
- export declare function applyCodePiecesToFlowModules(codePieces: CodePieceElement[], flowModules: FlowModule[]): string;
17
+ export declare function applyCodePiecesToFlowModules(codePieces: FlowModuleCodePieceElement[], flowModules: FlowModule[]): string;
17
18
  export declare function buildContextString(selectedContext: ContextElement[]): string;
18
19
  type BaseDisplayMessage = {
19
20
  content: string;
@@ -1,10 +1,27 @@
1
1
  import { get } from 'svelte/store';
2
- import { copilotSessionModel, workspaceStore } from '../../../stores';
2
+ import { workspaceStore, getCurrentModel } from '../../../stores';
3
3
  import { zodToJsonSchema } from 'zod-to-json-schema';
4
4
  import { z } from 'zod';
5
5
  import { ScriptService, JobService } from '../../../gen';
6
6
  import { scriptLangToEditorLang } from '../../../scripts';
7
7
  import YAML from 'yaml';
8
+ export const extractAllModules = (modules) => {
9
+ return modules.flatMap((m) => {
10
+ if (m.value.type === 'forloopflow' || m.value.type === 'whileloopflow') {
11
+ return [m, ...extractAllModules(m.value.modules)];
12
+ }
13
+ if (m.value.type === 'branchall') {
14
+ return [m, ...extractAllModules(m.value.branches.flatMap((b) => b.modules))];
15
+ }
16
+ if (m.value.type === 'branchone') {
17
+ return [
18
+ m,
19
+ ...extractAllModules([...m.value.branches.flatMap((b) => b.modules), ...m.value.default])
20
+ ];
21
+ }
22
+ return [m];
23
+ });
24
+ };
8
25
  export const findModuleById = (modules, moduleId) => {
9
26
  for (const module of modules) {
10
27
  if (module.id === moduleId) {
@@ -48,18 +65,13 @@ const applyCodePieceToCodeContext = (codePieces, codeContext) => {
48
65
  return code.join('\n');
49
66
  };
50
67
  export function applyCodePiecesToFlowModules(codePieces, flowModules) {
51
- // Parse code piece titles to extract module IDs
52
- // Format: "[id] L3-L5"
53
68
  const moduleCodePieces = new Map();
54
69
  for (const codePiece of codePieces) {
55
- const match = codePiece.title.match(/\[([^\]]+)\]\s+L\d+-L\d+/);
56
- if (match) {
57
- const moduleId = match[1];
58
- if (!moduleCodePieces.has(moduleId)) {
59
- moduleCodePieces.set(moduleId, []);
60
- }
61
- moduleCodePieces.get(moduleId).push(codePiece);
70
+ const moduleId = codePiece.id;
71
+ if (!moduleCodePieces.has(moduleId)) {
72
+ moduleCodePieces.set(moduleId, []);
62
73
  }
74
+ moduleCodePieces.get(moduleId).push(codePiece);
63
75
  }
64
76
  // Clone modules to avoid mutation
65
77
  const modifiedModules = JSON.parse(JSON.stringify(flowModules));
@@ -296,8 +308,8 @@ export async function buildSchemaForTool(toolDef, schemaBuilder) {
296
308
  }
297
309
  toolDef.function.parameters = { ...schema, additionalProperties: false };
298
310
  // OPEN AI models don't support strict mode well with schema with complex properties, so we disable it
299
- const model = get(copilotSessionModel)?.provider;
300
- if (model === 'openai' || model === 'azure_openai') {
311
+ const model = getCurrentModel();
312
+ if (model.provider === 'openai' || model.provider === 'azure_openai') {
301
313
  toolDef.function.strict = false;
302
314
  }
303
315
  return true;
@@ -1,4 +1,4 @@
1
- import { copilotInfo, copilotSessionModel, workspaceStore } from '../../stores';
1
+ import { getCurrentModel, workspaceStore } from '../../stores';
2
2
  import { buildClientSchema, printSchema } from 'graphql';
3
3
  import { OpenAI } from 'openai';
4
4
  import { get } from 'svelte/store';
@@ -7,7 +7,16 @@ import { EDIT_CONFIG, FIX_CONFIG, GEN_CONFIG } from './prompts';
7
7
  import { formatResourceTypes } from './utils';
8
8
  import { z } from 'zod';
9
9
  export const SUPPORTED_LANGUAGES = new Set(Object.keys(GEN_CONFIG.prompts));
10
- const OPENAI_MODELS = ['gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-4o', 'gpt-4o-mini', 'o4-mini', 'o3', 'o3-mini'];
10
+ const OPENAI_MODELS = [
11
+ 'gpt-5',
12
+ 'gpt-5-mini',
13
+ 'gpt-5-nano',
14
+ 'gpt-4o',
15
+ 'gpt-4o-mini',
16
+ 'o4-mini',
17
+ 'o3',
18
+ 'o3-mini'
19
+ ];
11
20
  // need at least one model for each provider except customai
12
21
  export const AI_DEFAULT_MODELS = {
13
22
  openai: OPENAI_MODELS,
@@ -331,11 +340,7 @@ const PROMPTS_CONFIGS = {
331
340
  gen: GEN_CONFIG
332
341
  };
333
342
  function getProviderAndCompletionConfig({ messages, stream, tools, forceModelProvider }) {
334
- let info = get(copilotInfo);
335
- const modelProvider = forceModelProvider ?? get(copilotSessionModel) ?? info.defaultModel ?? info.aiModels[0];
336
- if (!modelProvider) {
337
- throw new Error('No model selected');
338
- }
343
+ const modelProvider = forceModelProvider ?? getCurrentModel();
339
344
  const providerConfig = PROVIDER_COMPLETION_CONFIG_MAP[modelProvider.provider];
340
345
  const processedMessages = prepareMessages(modelProvider.provider, messages);
341
346
  return {
@@ -41,7 +41,7 @@ export type VisualChange = {
41
41
  };
42
42
  export declare function setGlobalCSS(id: string, cssCode: string): void;
43
43
  export declare let VISUAL_CHANGES_CSS: string;
44
- export declare function displayVisualChanges(cssId: string, editor: meditor.IStandaloneCodeEditor, visualChanges: VisualChange[]): Promise<{
44
+ export declare function displayVisualChanges(cssId: string, editor: meditor.IStandaloneCodeEditor, visualChanges: VisualChange[], revertMode?: boolean): Promise<{
45
45
  collection: meditor.IEditorDecorationsCollection;
46
46
  ids: string[];
47
47
  }>;
@@ -1,6 +1,6 @@
1
1
  import { createLongHash } from '../../editorLangUtils';
2
2
  import {} from 'monaco-editor';
3
- function applyMonacoStyles(targetEl, greenHighlight) {
3
+ function applyMonacoStyles(targetEl, greenHighlight, revertMode) {
4
4
  const computedStyles = window.getComputedStyle(document.querySelector('.monaco-editor .view-lines'));
5
5
  Object.assign(targetEl.style, {
6
6
  fontFamily: computedStyles.fontFamily,
@@ -10,7 +10,9 @@ function applyMonacoStyles(targetEl, greenHighlight) {
10
10
  whiteSpace: 'pre'
11
11
  });
12
12
  if (greenHighlight) {
13
- targetEl.style.backgroundColor = 'var(--vscode-diffEditor-insertedTextBackground)';
13
+ targetEl.style.backgroundColor = revertMode
14
+ ? 'var(--vscode-diffEditor-removedTextBackground)'
15
+ : 'var(--vscode-diffEditor-insertedTextBackground)';
14
16
  }
15
17
  }
16
18
  export function setGlobalCSS(id, cssCode) {
@@ -22,7 +24,7 @@ export function setGlobalCSS(id, cssCode) {
22
24
  }
23
25
  styleTag.textContent = cssCode;
24
26
  }
25
- function addInlineGhostText(change) {
27
+ function addInlineGhostText(change, revertMode) {
26
28
  const cssId = createLongHash();
27
29
  const decoration = {
28
30
  range: {
@@ -32,7 +34,11 @@ function addInlineGhostText(change) {
32
34
  endColumn: change.position.column + change.value.length
33
35
  },
34
36
  options: {
35
- beforeContentClassName: `editor-ghost-text editor-ghost-text-content-${cssId} ${change.options?.greenHighlight ? 'editor-ghost-text-green' : ''}`
37
+ beforeContentClassName: `editor-ghost-text editor-ghost-text-content-${cssId} ${change.options?.greenHighlight
38
+ ? revertMode
39
+ ? 'editor-ghost-text-removed'
40
+ : 'editor-ghost-text-green'
41
+ : ''}`
36
42
  }
37
43
  };
38
44
  const safeContent = change.value.replaceAll('"', '\\"');
@@ -90,14 +96,14 @@ function getReviewButtons(editor, acceptFn, rejectFn) {
90
96
  reviewButtons.append(rejectButton);
91
97
  return reviewButtons;
92
98
  }
93
- async function addMultilineGhostText(editor, text, afterLineNumber, heightInLines, options) {
99
+ async function addMultilineGhostText(editor, text, afterLineNumber, heightInLines, options, revertMode) {
94
100
  const el = document.createElement('div');
95
101
  el.textContent = text;
96
102
  if (options?.review) {
97
103
  const reviewButtons = getReviewButtons(editor, options.review.acceptFn, options.review.rejectFn);
98
104
  el.append(reviewButtons);
99
105
  }
100
- applyMonacoStyles(el, options?.greenHighlight);
106
+ applyMonacoStyles(el, options?.greenHighlight, revertMode);
101
107
  const addZonePromise = new Promise((resolve, reject) => {
102
108
  editor?.changeViewZones((acc) => {
103
109
  const id = acc.addZone({
@@ -112,13 +118,13 @@ async function addMultilineGhostText(editor, text, afterLineNumber, heightInLine
112
118
  return addZonePromise;
113
119
  }
114
120
  export let VISUAL_CHANGES_CSS = `.editor-ghost-text-green { background-color: var(--vscode-diffEditor-insertedTextBackground) !important; }\n.editor-ghost-text-removed { background-color: var(--vscode-diffEditor-removedTextBackground); }\n\n.editor-ghost-text { display: inline-block; background-color: var(--vscode-editor-background); color: gray;}`;
115
- export async function displayVisualChanges(cssId, editor, visualChanges) {
121
+ export async function displayVisualChanges(cssId, editor, visualChanges, revertMode) {
116
122
  let decorations = [];
117
123
  let css = '';
118
124
  let ids = [];
119
125
  for (const change of visualChanges) {
120
126
  if (change.type === 'added_inline') {
121
- const { css: newCss, decoration } = addInlineGhostText(change);
127
+ const { css: newCss, decoration } = addInlineGhostText(change, revertMode);
122
128
  decorations.push(decoration);
123
129
  css += newCss;
124
130
  }
@@ -131,7 +137,7 @@ export async function displayVisualChanges(cssId, editor, visualChanges) {
131
137
  endColumn: change.range.endColumn
132
138
  },
133
139
  options: {
134
- className: 'editor-ghost-text-removed',
140
+ className: revertMode ? 'editor-ghost-text-green' : 'editor-ghost-text-removed',
135
141
  isWholeLine: change.options?.isWholeLine
136
142
  }
137
143
  };
@@ -157,7 +163,7 @@ export async function displayVisualChanges(cssId, editor, visualChanges) {
157
163
  }
158
164
  else if (change.type === 'added_block') {
159
165
  const id = await addMultilineGhostText(editor, change.value, change.position.afterLineNumber, change.value.split('\n').length, // we know it won't end by \n
160
- change.options);
166
+ change.options, revertMode);
161
167
  ids.push(id);
162
168
  }
163
169
  }
@@ -8,8 +8,9 @@ import { writable } from 'svelte/store';
8
8
  import FlowAIChat from '../copilot/chat/flow/FlowAIChat.svelte';
9
9
  import { aiChatManager, AIMode } from '../copilot/chat/AIChatManager.svelte';
10
10
  import { triggerableByAI } from '../../actions/triggerableByAI.svelte';
11
+ import { extractAllModules } from '../copilot/chat/shared';
11
12
  const { flowStore } = getContext('FlowEditorContext');
12
- let { loading, disableStaticInputs = false, disableTutorials = false, disableAi = false, disableSettings = false, disabledFlowInputs = false, smallErrorHandler = false, showJobStatus = false, newFlow = false, savedFlow = undefined, onDeployTrigger = () => { }, onTestUpTo = undefined, onEditInput = undefined, forceTestTab, highlightArg, localModuleStates = {}, testModuleStates = undefined, aiChatOpen, showFlowAiButton, toggleAiChat, isOwner, onTestFlow, isRunning, onCancelTestFlow, onOpenPreview, onHideJobStatus, individualStepTests = false, job, suspendStatus, onDelete, flowHasChanged } = $props();
13
+ let { loading, disableStaticInputs = false, disableTutorials = false, disableAi = false, disableSettings = false, disabledFlowInputs = false, smallErrorHandler = false, showJobStatus = false, newFlow = false, savedFlow = undefined, onDeployTrigger = () => { }, onTestUpTo = undefined, onEditInput = undefined, forceTestTab, highlightArg, localModuleStates = {}, testModuleStates = undefined, aiChatOpen, showFlowAiButton, toggleAiChat, isOwner, onTestFlow, isRunning, onCancelTestFlow, onOpenPreview, onHideJobStatus, individualStepTests = false, job, suspendStatus, onDelete, flowHasChanged, previewOpen } = $props();
13
14
  let flowModuleSchemaMap = $state();
14
15
  export function isNodeVisible(nodeId) {
15
16
  return flowModuleSchemaMap?.isNodeVisible(nodeId) ?? false;
@@ -24,7 +25,7 @@ $effect(() => {
24
25
  lastDeployedFlow: savedFlow,
25
26
  lastSavedFlow: savedFlow?.draft,
26
27
  path: savedFlow?.path,
27
- modules: flowStore.val.value.modules
28
+ modules: extractAllModules(flowStore.val.value.modules)
28
29
  };
29
30
  aiChatManager.flowOptions = options;
30
31
  });
@@ -117,6 +118,7 @@ onDestroy(() => {
117
118
  {isOwner}
118
119
  {suspendStatus}
119
120
  onOpenDetails={onOpenPreview}
121
+ {previewOpen}
120
122
  />
121
123
  {/if}
122
124
  </Pane>
@@ -40,6 +40,7 @@ interface Props {
40
40
  }>>;
41
41
  onDelete?: (id: string) => void;
42
42
  flowHasChanged?: boolean;
43
+ previewOpen: boolean;
43
44
  }
44
45
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
45
46
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
@@ -9,19 +9,19 @@ const iconHeight = height || size;
9
9
  </script>
10
10
 
11
11
  {#if module.value.type === 'aiagent'}
12
- <Bot size={16} />
12
+ <Bot size={16} class="text-violet-800 dark:text-violet-400" />
13
13
  {:else if module.value.type === 'rawscript'}
14
14
  <LanguageIcon lang={module.value.language} width={iconWidth} height={iconHeight} />
15
15
  {:else if module.summary === 'Terminate flow'}
16
- <Square size={size} />
16
+ <Square {size} />
17
17
  {:else if module.value.type === 'identity'}
18
- <ArrowDown size={size} />
18
+ <ArrowDown {size} />
19
19
  {:else if module.value.type === 'flow'}
20
- <BarsStaggered size={size} />
20
+ <BarsStaggered {size} />
21
21
  {:else if module.value.type === 'forloopflow' || module.value.type === 'whileloopflow'}
22
- <Repeat size={size} />
22
+ <Repeat {size} />
23
23
  {:else if module.value.type === 'branchone' || module.value.type === 'branchall'}
24
- <GitBranch size={size} />
24
+ <GitBranch {size} />
25
25
  {:else if module.value.type === 'script'}
26
26
  {#if module.value.path.startsWith('hub/')}
27
27
  <IconedResourceType
@@ -31,9 +31,9 @@ const iconHeight = height || size;
31
31
  silent={true}
32
32
  />
33
33
  {:else}
34
- <Building size={size} />
34
+ <Building {size} />
35
35
  {/if}
36
36
  {:else}
37
37
  <!-- Fallback icon for unknown module types -->
38
- <BarsStaggered size={size} />
38
+ <BarsStaggered {size} />
39
39
  {/if}
@@ -47,7 +47,7 @@ $effect.pre(() => {
47
47
  </script>
48
48
 
49
49
  <div
50
- class="overflow-x-auto scrollbar-hidden flex items-center justify-between px-4 py-1 flex-nowrap"
50
+ class="overflow-x-auto scrollbar-hidden flex items-center justify-between px-4 pt-1 pb-4 flex-nowrap"
51
51
  >
52
52
  {#if flowModuleValue}
53
53
  <span class="text-sm w-full mr-4">
@@ -129,6 +129,9 @@ $effect.pre(() => {
129
129
  {:else if flowModuleValue.type === 'flow'}
130
130
  <Badge color="indigo" capitalize>flow</Badge>
131
131
  <input bind:value={summary} placeholder="Summary" class="w-full grow" />
132
+ {:else if flowModuleValue.type === 'aiagent'}
133
+ <Badge color="indigo">AI Agent</Badge>
134
+ <input bind:value={summary} placeholder="Summary" class="w-full grow" />
132
135
  {/if}
133
136
  </div>
134
137
  </span>
@@ -12,12 +12,18 @@ import FlowModuleDeleteAfterUse from './FlowModuleDeleteAfterUse.svelte';
12
12
  import { enterpriseLicense } from '../../../stores';
13
13
  import FlowModuleSkip from './FlowModuleSkip.svelte';
14
14
  import TabsV2 from '../../common/tabs/TabsV2.svelte';
15
+ import { useUiIntent } from '../../copilot/chat/flow/useUiIntent';
15
16
  let { noEditor, flowModule = $bindable(), previousModule, parentModule } = $props();
16
17
  let value = $state(flowModule.value);
17
18
  $effect(() => {
18
19
  value = flowModule.value;
19
20
  });
20
21
  let selected = $state('early-stop');
22
+ useUiIntent(`branchall-${flowModule.id}`, {
23
+ openTab: (tab) => {
24
+ selected = tab;
25
+ }
26
+ });
21
27
  </script>
22
28
 
23
29
  <div class="h-full flex flex-col w-full" id="flow-editor-branch-all-wrapper">
@@ -12,12 +12,18 @@ import SplitPanesWrapper from '../../splitPanes/SplitPanesWrapper.svelte';
12
12
  import FlowModuleMock from './FlowModuleMock.svelte';
13
13
  import { enterpriseLicense } from '../../../stores';
14
14
  import FlowModuleSkip from './FlowModuleSkip.svelte';
15
+ import { useUiIntent } from '../../copilot/chat/flow/useUiIntent';
15
16
  let { flowModule = $bindable(), previousModule, parentModule, noEditor, enableAi = false } = $props();
16
17
  let value = $state(flowModule.value);
17
18
  $effect(() => {
18
19
  value = flowModule.value;
19
20
  });
20
21
  let selected = $state('early-stop');
22
+ useUiIntent(`branchone-${flowModule.id}`, {
23
+ openTab: (tab) => {
24
+ selected = tab;
25
+ }
26
+ });
21
27
  </script>
22
28
 
23
29
  <div class="h-full" id="flow-editor-branch-one-wrapper">
@@ -10,7 +10,7 @@ import TriggersEditor from '../../triggers/TriggersEditor.svelte';
10
10
  import { handleSelectTriggerFromKind } from '../../triggers/utils';
11
11
  import { computeMissingInputWarnings } from '../missingInputWarnings';
12
12
  import FlowResult from './FlowResult.svelte';
13
- let { noEditor = false, enableAi = false, newFlow = false, disabledFlowInputs = false, savedFlow = undefined, onDeployTrigger = () => { }, forceTestTab, highlightArg, onTestFlow, job, isOwner, suspendStatus, onOpenDetails } = $props();
13
+ let { noEditor = false, enableAi = false, newFlow = false, disabledFlowInputs = false, savedFlow = undefined, onDeployTrigger = () => { }, forceTestTab, highlightArg, onTestFlow, job, isOwner, suspendStatus, onOpenDetails, previewOpen = false } = $props();
14
14
  const { selectedId, flowStore, flowStateStore, flowInputsStore, pathStore, initialPathStore, fakeInitialPath, previewArgs, flowInputEditorState } = getContext('FlowEditorContext');
15
15
  const { showCaptureHint, triggersState, triggersCount } = getContext('TriggerContext');
16
16
  function checkDup(modules) {
@@ -41,6 +41,7 @@ $effect(() => {
41
41
  }}
42
42
  on:applyArgs
43
43
  {onTestFlow}
44
+ {previewOpen}
44
45
  />
45
46
  {:else if $selectedId === 'Result'}
46
47
  <FlowResult {noEditor} {job} {isOwner} {suspendStatus} {onOpenDetails} />
@@ -20,6 +20,7 @@ interface Props {
20
20
  nb: number;
21
21
  }>>;
22
22
  onOpenDetails?: () => void;
23
+ previewOpen?: boolean;
23
24
  }
24
25
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
25
26
  new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {