windmill-components 1.504.6 → 1.511.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 (233) hide show
  1. package/package/ata/index.js +1 -1
  2. package/package/components/AppConnectInner.svelte +184 -29
  3. package/package/components/ArgInput.svelte +33 -103
  4. package/package/components/AuthSettings.svelte +45 -1
  5. package/package/components/Dev.svelte +31 -24
  6. package/package/components/DisplayResult.svelte +53 -26
  7. package/package/components/DisplayResult.svelte.d.ts +1 -1
  8. package/package/components/DynSelect.svelte +3 -3
  9. package/package/components/Editor.svelte +115 -88
  10. package/package/components/Editor.svelte.d.ts +30 -55
  11. package/package/components/EditorBar.svelte +2 -2
  12. package/package/components/ErrorOrRecoveryHandler.svelte +73 -67
  13. package/package/components/ErrorOrRecoveryHandler.svelte.d.ts +8 -24
  14. package/package/components/FlowBuilder.svelte +11 -2
  15. package/package/components/FlowJobResult.svelte +12 -17
  16. package/package/components/FlowJobResult.svelte.d.ts +5 -18
  17. package/package/components/FlowPreviewContent.svelte +13 -10
  18. package/package/components/FlowPreviewContent.svelte.d.ts +1 -1
  19. package/package/components/FlowPreviewResult.svelte +14 -6
  20. package/package/components/FlowStatusViewer.svelte +11 -24
  21. package/package/components/FlowStatusViewer.svelte.d.ts +19 -18
  22. package/package/components/FlowStatusViewerInner.svelte +110 -131
  23. package/package/components/FlowStatusViewerInner.svelte.d.ts +20 -18
  24. package/package/components/GitDiffPreview.svelte +55 -0
  25. package/package/components/GitDiffPreview.svelte.d.ts +13 -0
  26. package/package/components/HistoricInputs.svelte +2 -2
  27. package/package/components/HttpAgentWorkerDrawer.svelte +1 -1
  28. package/package/components/InitGitRepoPopover.svelte +410 -0
  29. package/package/components/InitGitRepoPopover.svelte.d.ts +13 -0
  30. package/package/components/InstanceSetting.svelte +21 -9
  31. package/package/components/InstanceSettings.svelte +16 -3
  32. package/package/components/JobLoader.svelte +567 -0
  33. package/package/components/JobLoader.svelte.d.ts +53 -0
  34. package/package/components/JobLogs.svelte +6 -4
  35. package/package/components/JobLogs.svelte.d.ts +5 -18
  36. package/package/components/JsonEditor.svelte +11 -11
  37. package/package/components/JsonEditor.svelte.d.ts +14 -56
  38. package/package/components/Label.svelte +6 -11
  39. package/package/components/Label.svelte.d.ts +14 -39
  40. package/package/components/LightweightResourcePicker.svelte +18 -39
  41. package/package/components/LightweightResourcePicker.svelte.d.ts +6 -22
  42. package/package/components/LogViewer.svelte +35 -41
  43. package/package/components/LogViewer.svelte.d.ts +6 -20
  44. package/package/components/ModulePreviewResultViewer.svelte +3 -1
  45. package/package/components/ModulePreviewResultViewer.svelte.d.ts +1 -0
  46. package/package/components/ModuleTest.svelte +16 -11
  47. package/package/components/NumberTypeNarrowing.svelte +13 -16
  48. package/package/components/NumberTypeNarrowing.svelte.d.ts +4 -18
  49. package/package/components/PullGitRepoPopover.svelte +355 -0
  50. package/package/components/PullGitRepoPopover.svelte.d.ts +18 -0
  51. package/package/components/ResourceTypePicker.svelte +20 -17
  52. package/package/components/ResourceTypePicker.svelte.d.ts +7 -6
  53. package/package/components/S3FilePicker.svelte +5 -3
  54. package/package/components/SavedInputs.svelte +2 -2
  55. package/package/components/ScriptBuilder.svelte +4 -3
  56. package/package/components/ScriptEditor.svelte +34 -31
  57. package/package/components/ScriptEditor.svelte.d.ts +3 -3
  58. package/package/components/Section.svelte +7 -20
  59. package/package/components/Section.svelte.d.ts +20 -47
  60. package/package/components/ServiceLogsInner.svelte +2 -1
  61. package/package/components/ServiceLogsInner.svelte.d.ts +1 -0
  62. package/package/components/SimpleEditor.svelte +4 -4
  63. package/package/components/SimpleEditor.svelte.d.ts +1 -0
  64. package/package/components/SqlRepl.svelte +0 -1
  65. package/package/components/Subsection.svelte +10 -12
  66. package/package/components/Subsection.svelte.d.ts +15 -39
  67. package/package/components/UserSettings.svelte +1 -1
  68. package/package/components/WorkerGroup.svelte +260 -165
  69. package/package/components/WorkerGroup.svelte.d.ts +2 -0
  70. package/package/components/WorkerTagPicker.svelte +3 -3
  71. package/package/components/WorkerTagSelect.svelte +33 -4
  72. package/package/components/apps/components/buttons/AppButton.svelte +7 -1
  73. package/package/components/apps/components/buttons/AppButton.svelte.d.ts +1 -0
  74. package/package/components/apps/components/display/AppCustomComponent.svelte +1 -1
  75. package/package/components/apps/components/display/AppDisplayComponentByJobId.svelte +16 -11
  76. package/package/components/apps/components/display/AppJobIdLogComponent.svelte +13 -10
  77. package/package/components/apps/components/display/AppMenu.svelte +5 -0
  78. package/package/components/apps/components/display/dbtable/AppDbExplorer.svelte +3 -3
  79. package/package/components/apps/components/display/dbtable/DeleteRow.svelte +3 -3
  80. package/package/components/apps/components/display/dbtable/InsertRowRunnable.svelte +3 -3
  81. package/package/components/apps/components/display/dbtable/UpdateCell.svelte +3 -3
  82. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +3 -3
  83. package/package/components/apps/components/helpers/RunnableComponent.svelte +65 -54
  84. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +5 -5
  85. package/package/components/apps/components/inputs/AppUserResource.svelte +26 -8
  86. package/package/components/apps/editor/AppEditorHeader.svelte +11 -5
  87. package/package/components/apps/editor/AppJobsDrawer.svelte +5 -5
  88. package/package/components/apps/editor/RunnableJobPanel.svelte +4 -4
  89. package/package/components/apps/editor/component/components.d.ts +12 -0
  90. package/package/components/apps/editor/component/components.js +19 -7
  91. package/package/components/assets/AssetButtons.svelte +38 -0
  92. package/package/components/assets/AssetButtons.svelte.d.ts +15 -0
  93. package/package/components/assets/AssetsDropdownButton.svelte +60 -72
  94. package/package/components/assets/AssetsDropdownButton.svelte.d.ts +3 -4
  95. package/package/components/assets/AssetsUsageDrawer.svelte +10 -10
  96. package/package/components/assets/JobAssetsViewer.svelte +79 -0
  97. package/package/components/assets/JobAssetsViewer.svelte.d.ts +7 -0
  98. package/package/components/assets/README_DEV.md +0 -0
  99. package/package/components/assets/lib.d.ts +9 -1
  100. package/package/components/assets/lib.js +48 -7
  101. package/package/components/common/fileUpload/FileUpload.svelte +126 -84
  102. package/package/components/common/fileUpload/FileUpload.svelte.d.ts +13 -3
  103. package/package/components/common/fileUpload/S3ArgInput.svelte +111 -0
  104. package/package/components/common/fileUpload/S3ArgInput.svelte.d.ts +21 -0
  105. package/package/components/common/table/ScriptRow.svelte +3 -1
  106. package/package/components/copilot/AIFormSettings.svelte +3 -4
  107. package/package/components/copilot/AIFormSettings.svelte.d.ts +5 -19
  108. package/package/components/copilot/autocomplete/Autocompletor.d.ts +3 -1
  109. package/package/components/copilot/autocomplete/Autocompletor.js +269 -35
  110. package/package/components/copilot/autocomplete/request.d.ts +3 -0
  111. package/package/components/copilot/autocomplete/request.js +15 -7
  112. package/package/components/copilot/chat/AIChatDisplay.svelte +8 -0
  113. package/package/components/copilot/chat/AIChatManager.svelte.js +13 -8
  114. package/package/components/copilot/chat/flow/ModuleAcceptReject.svelte +5 -5
  115. package/package/components/copilot/chat/flow/core.d.ts +1 -1
  116. package/package/components/copilot/chat/flow/core.js +2 -38
  117. package/package/components/copilot/chat/navigator/apiTools.d.ts +8 -0
  118. package/package/components/copilot/chat/navigator/apiTools.js +95 -15
  119. package/package/components/copilot/chat/navigator/core.d.ts +1 -1
  120. package/package/components/copilot/chat/navigator/core.js +2 -1
  121. package/package/components/copilot/chat/script/core.d.ts +11 -2
  122. package/package/components/copilot/chat/script/core.js +165 -23
  123. package/package/components/copilot/chat/shared.d.ts +10 -0
  124. package/package/components/copilot/chat/shared.js +56 -0
  125. package/package/components/copilot/lib.d.ts +1 -0
  126. package/package/components/copilot/lib.js +30 -9
  127. package/package/components/custom_ui.d.ts +1 -0
  128. package/package/components/flows/FlowAssetsHandler.svelte +133 -0
  129. package/package/components/flows/FlowAssetsHandler.svelte.d.ts +14 -0
  130. package/package/components/flows/content/FlowModuleCache.svelte +4 -4
  131. package/package/components/flows/content/FlowModuleCache.svelte.d.ts +4 -18
  132. package/package/components/flows/content/FlowModuleComponent.svelte +16 -19
  133. package/package/components/flows/content/FlowModuleDeleteAfterUse.svelte +3 -4
  134. package/package/components/flows/content/FlowModuleDeleteAfterUse.svelte.d.ts +4 -18
  135. package/package/components/flows/content/FlowModuleSleep.svelte +6 -7
  136. package/package/components/flows/content/FlowModuleSleep.svelte.d.ts +4 -18
  137. package/package/components/flows/content/FlowModuleSuspend.svelte +19 -17
  138. package/package/components/flows/content/FlowModuleSuspend.svelte.d.ts +4 -18
  139. package/package/components/flows/content/FlowModuleTimeout.svelte +4 -4
  140. package/package/components/flows/content/FlowModuleTimeout.svelte.d.ts +4 -18
  141. package/package/components/flows/flowStore.d.ts +1 -1
  142. package/package/components/flows/map/FlowModuleSchemaItem.svelte +1 -0
  143. package/package/components/flows/propPicker/OutputPicker.svelte +9 -4
  144. package/package/components/flows/scheduleUtils.js +1 -1
  145. package/package/components/flows/types.d.ts +2 -1
  146. package/package/components/graph/FlowGraphV2.svelte +8 -104
  147. package/package/components/graph/FlowGraphV2.svelte.d.ts +0 -2
  148. package/package/components/graph/graphBuilder.svelte.d.ts +6 -3
  149. package/package/components/graph/graphBuilder.svelte.js +35 -9
  150. package/package/components/graph/renderers/edges/BaseEdge.svelte +2 -5
  151. package/package/components/graph/renderers/edges/BaseEdge.svelte.d.ts +1 -0
  152. package/package/components/graph/renderers/nodes/AssetNode.svelte +23 -20
  153. package/package/components/graph/renderers/nodes/AssetNode.svelte.d.ts +5 -10
  154. package/package/components/graph/renderers/nodes/AssetsOverflowedNode.svelte +1 -1
  155. package/package/components/graph/util.js +1 -1
  156. package/package/components/home/ItemsList.svelte +2 -0
  157. package/package/components/icons/AssetGenericIcon.svelte +0 -3
  158. package/package/components/jobs/JobPreview.svelte +10 -6
  159. package/package/components/raw_apps/RawAppInlineScriptRunnable.svelte +13 -12
  160. package/package/components/runs/BatchReRunOptionsPane.svelte +5 -1
  161. package/package/components/runs/JobPreview.svelte +26 -16
  162. package/package/components/runs/{JobLoader.svelte.d.ts → JobsLoader.svelte.d.ts} +3 -3
  163. package/package/components/runs/NoWorkerWithTagWarning.svelte +2 -2
  164. package/package/components/runs/NoWorkerWithTagWarning.svelte.d.ts +1 -0
  165. package/package/components/runs/RunsFilter.svelte.d.ts +1 -1
  166. package/package/components/scriptEditor/LogPanel.svelte +3 -2
  167. package/package/components/script_builder.d.ts +2 -2
  168. package/package/components/settings/CreateToken.svelte +76 -41
  169. package/package/components/settings/CreateToken.svelte.d.ts +1 -1
  170. package/package/components/settings/ScopeSelector.svelte +613 -0
  171. package/package/components/settings/ScopeSelector.svelte.d.ts +8 -0
  172. package/package/components/settings/TokenDisplay.svelte +103 -0
  173. package/package/components/settings/TokenDisplay.svelte.d.ts +10 -0
  174. package/package/components/settings/TokensTable.svelte +70 -349
  175. package/package/components/sidebar/CriticalAlertModal.svelte +3 -0
  176. package/package/components/triggers/DeleteTriggerButton.svelte +1 -1
  177. package/package/components/triggers/TriggerEditorToolbar.svelte +3 -3
  178. package/package/components/triggers/TriggerRetriesAndErrorHandler.svelte +55 -0
  179. package/package/components/triggers/TriggerRetriesAndErrorHandler.svelte.d.ts +13 -0
  180. package/package/components/triggers/TriggersEditor.svelte +45 -3
  181. package/package/components/triggers/TriggersWrapper.svelte +2 -2
  182. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +47 -6
  183. package/package/components/triggers/gcp/utils.js +9 -1
  184. package/package/components/triggers/http/OpenAPISpecGenerator.svelte +3 -2
  185. package/package/components/triggers/http/RouteEditorConfigSection.svelte +26 -23
  186. package/package/components/triggers/http/RouteEditorConfigSection.svelte.d.ts +5 -19
  187. package/package/components/triggers/http/RouteEditorInner.svelte +219 -175
  188. package/package/components/triggers/http/RouteEditorInner.svelte.d.ts +6 -2
  189. package/package/components/triggers/http/utils.js +9 -3
  190. package/package/components/triggers/kafka/KafkaTriggerEditorInner.svelte +47 -6
  191. package/package/components/triggers/kafka/utils.js +9 -1
  192. package/package/components/triggers/mqtt/MqttEditorConfigSection.svelte +4 -132
  193. package/package/components/triggers/mqtt/MqttEditorConfigSection.svelte.d.ts +2 -5
  194. package/package/components/triggers/mqtt/MqttTriggerEditorInner.svelte +182 -13
  195. package/package/components/triggers/mqtt/utils.js +9 -1
  196. package/package/components/triggers/nats/NatsTriggerEditorInner.svelte +47 -6
  197. package/package/components/triggers/nats/utils.js +9 -1
  198. package/package/components/triggers/postgres/PostgresTriggerEditorInner.svelte +41 -2
  199. package/package/components/triggers/postgres/utils.js +9 -1
  200. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +38 -92
  201. package/package/components/triggers/sqs/SqsTriggerEditorInner.svelte +47 -6
  202. package/package/components/triggers/sqs/utils.js +9 -1
  203. package/package/components/triggers/utils.js +12 -0
  204. package/package/components/triggers/websocket/WebsocketTriggerEditorInner.svelte +47 -6
  205. package/package/components/triggers/websocket/utils.js +11 -1
  206. package/package/components/workspaceSettings/AISettings.svelte +0 -2
  207. package/package/components/workspaceSettings/FilterList.svelte +56 -0
  208. package/package/components/workspaceSettings/FilterList.svelte.d.ts +8 -0
  209. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +785 -0
  210. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte.d.ts +18 -0
  211. package/package/gen/core/OpenAPI.js +1 -1
  212. package/package/gen/schemas.gen.d.ts +305 -23
  213. package/package/gen/schemas.gen.js +305 -23
  214. package/package/gen/services.gen.d.ts +33 -1
  215. package/package/gen/services.gen.js +66 -2
  216. package/package/gen/types.gen.d.ts +216 -11
  217. package/package/history.svelte.js +0 -2
  218. package/package/hub.d.ts +1 -0
  219. package/package/hubPaths.json +5 -2
  220. package/package/infer.js +16 -10
  221. package/package/svelte5Utils.svelte.d.ts +1 -0
  222. package/package/svelte5Utils.svelte.js +25 -18
  223. package/package/toast.js +10 -0
  224. package/package/utils.d.ts +3 -2
  225. package/package/utils.js +20 -5
  226. package/package.json +11 -11
  227. package/package/components/ResultJobLoader.svelte +0 -219
  228. package/package/components/ResultJobLoader.svelte.d.ts +0 -52
  229. package/package/components/TestJobLoader.svelte +0 -274
  230. package/package/components/TestJobLoader.svelte.d.ts +0 -43
  231. package/package/components/icons/AssetVarIcon.svelte +0 -31
  232. package/package/components/icons/AssetVarIcon.svelte.d.ts +0 -9
  233. /package/package/components/runs/{JobLoader.svelte → JobsLoader.svelte} +0 -0
@@ -1,15 +1,30 @@
1
1
  import { sleep } from '../../../utils';
2
- import { Position, languages } from 'monaco-editor';
2
+ import { editor as meditor, Position, languages } from 'monaco-editor';
3
3
  import { LRUCache } from 'lru-cache';
4
4
  import { autocompleteRequest } from './request';
5
- import { FIM_MAX_TOKENS } from '../lib';
6
- function filterCompletion(completion, suffix) {
5
+ import { FIM_MAX_TOKENS, getModelContextWindow } from '../lib';
6
+ import { setGlobalCSS } from '../shared';
7
+ import { get } from 'svelte/store';
8
+ import { copilotInfo } from '../../../stores';
9
+ // max ratio of completions to context window
10
+ const COMPLETIONS_MAX_RATIO = 0.1;
11
+ // hard limit to max number of completions to fetch details for, to avoid performance overhead
12
+ const MAX_COMPLETIONS_DETAILS = 50;
13
+ function filterCompletion(completion, suffix, shouldReturnMultiline) {
7
14
  const trimmedCompletion = completion.replaceAll('\n', '');
8
15
  const trimmedSuffix = suffix.slice(0, FIM_MAX_TOKENS).replaceAll('\n', '');
9
16
  if (trimmedSuffix.startsWith(trimmedCompletion)) {
10
- console.log('suffix starts with completion', suffix, completion);
11
17
  return;
12
18
  }
19
+ if (!shouldReturnMultiline) {
20
+ if (completion.startsWith('\n')) {
21
+ // TODO improve cache for this case so that we can use cache when accepting the first line of a multiline completion which starts with \n
22
+ return completion.split('\n').slice(0, 2).join('\n') + '\n';
23
+ }
24
+ else if (completion.includes('\n')) {
25
+ return completion.split('\n').slice(0, 1).join('\n') + '\n';
26
+ }
27
+ }
13
28
  return completion;
14
29
  }
15
30
  export class Autocompletor {
@@ -21,49 +36,103 @@ export class Autocompletor {
21
36
  #abortController = new AbortController();
22
37
  #completionDisposable;
23
38
  #cursorDisposable;
39
+ #lastCompletions = [];
40
+ #contextWindow = 0;
41
+ #shouldShowDeletionCue = false;
42
+ #languageClient = undefined;
24
43
  constructor(editor, scriptLang) {
44
+ setGlobalCSS('ai-chat-autocomplete', `
45
+ .ai-completion-diff {
46
+ background: var(--vscode-diffEditor-removedTextBackground);
47
+ }
48
+ `);
25
49
  this.#scriptLang = scriptLang;
50
+ const deletionsCues = editor.createDecorationsCollection();
51
+ const completionModel = get(copilotInfo).codeCompletionModel;
52
+ this.#contextWindow = getModelContextWindow(completionModel?.model ?? '');
26
53
  this.#completionDisposable = languages.registerInlineCompletionsProvider({ pattern: '**' }, {
54
+ handleItemDidShow: (items) => {
55
+ const item = items.items[0];
56
+ const model = editor.getModel();
57
+ if (!item || !item.range || !model) {
58
+ return;
59
+ }
60
+ const toEol = {
61
+ ...item.range,
62
+ endColumn: model.getLineMaxColumn(item.range.startLineNumber)
63
+ };
64
+ if (this.#shouldShowDeletionCue) {
65
+ deletionsCues.set([
66
+ {
67
+ range: toEol,
68
+ options: {
69
+ className: 'ai-completion-diff'
70
+ }
71
+ }
72
+ ]);
73
+ this.#shouldShowDeletionCue = false;
74
+ }
75
+ },
27
76
  provideInlineCompletions: async (model, position, context, token) => {
28
77
  if (token.isCancellationRequested ||
29
78
  model.uri.toString() !== editor.getModel()?.uri.toString()) {
30
79
  return { items: [] };
31
80
  }
81
+ this.#shouldShowDeletionCue = false;
82
+ const shouldReturnMultiline = this.#shouldReturnMultiline(model, position);
32
83
  const result = await this.#autocomplete(model, position);
33
- if (result) {
34
- const completion = filterCompletion(result.completion, result.suffix);
35
- if (!completion) {
36
- return { items: [] };
37
- }
38
- let range = {
39
- startLineNumber: position.lineNumber,
40
- startColumn: position.column,
41
- endLineNumber: position.lineNumber,
42
- endColumn: position.column
43
- };
44
- const multiline = completion.indexOf('\n') !== -1;
45
- if (multiline) {
46
- // if multiline the range should span until the end of the line
47
- range.endColumn = model.getLineMaxColumn(position.lineNumber);
48
- }
49
- return {
50
- items: [
51
- {
52
- insertText: completion,
53
- range
54
- }
55
- ]
56
- };
84
+ if (!result) {
85
+ return { items: [] };
57
86
  }
58
- else {
59
- return {
60
- items: []
61
- };
87
+ const range = {
88
+ startLineNumber: position.lineNumber,
89
+ startColumn: position.column,
90
+ endLineNumber: position.lineNumber,
91
+ endColumn: position.column
92
+ };
93
+ const toEol = {
94
+ ...range,
95
+ endColumn: model.getLineMaxColumn(position.lineNumber)
96
+ };
97
+ // if shouldReturnMultiline is false, only keep first line of a multiline completion (keeps final new line)
98
+ let completion = filterCompletion(result.completion, result.suffix, shouldReturnMultiline);
99
+ if (!completion) {
100
+ return { items: [] };
101
+ }
102
+ // if completion ends with new line, we want the suggestion to replace the end of the current line
103
+ const endsWithNewLine = completion.endsWith('\n');
104
+ if (endsWithNewLine) {
105
+ // remove new line
106
+ completion = completion.slice(0, -1);
107
+ // set deletion cue for content that will be replaced by the suggestion
108
+ if (!completion.includes('\n')) {
109
+ this.#shouldShowDeletionCue = true;
110
+ }
62
111
  }
112
+ const multiline = completion.indexOf('\n') !== -1;
113
+ return {
114
+ items: [
115
+ {
116
+ insertText: completion,
117
+ range: !endsWithNewLine && multiline ? toEol : range,
118
+ // if completion ends with new line, after applying the suggestion, delete the rest of the line
119
+ additionalTextEdits: endsWithNewLine && !multiline
120
+ ? [
121
+ {
122
+ range: toEol,
123
+ text: ''
124
+ }
125
+ ]
126
+ : []
127
+ }
128
+ ]
129
+ };
63
130
  },
64
131
  freeInlineCompletions: () => { }
65
132
  });
66
133
  this.#cursorDisposable = editor.onDidChangeCursorPosition(async (e) => {
134
+ deletionsCues.clear();
135
+ this.#shouldShowDeletionCue = false;
67
136
  if (e.source === 'mouse') {
68
137
  const model = editor.getModel();
69
138
  if (model) {
@@ -82,6 +151,160 @@ export class Autocompletor {
82
151
  this.#completionDisposable.dispose();
83
152
  this.#cursorDisposable.dispose();
84
153
  }
154
+ setLanguageClient(client) {
155
+ this.#languageClient = client;
156
+ }
157
+ #shouldReturnMultiline(model, position) {
158
+ if (position.column === model.getLineMaxColumn(position.lineNumber)) {
159
+ const cachedCompletion = this.#cache.get(position.lineNumber);
160
+ if (cachedCompletion) {
161
+ const firstCachedLine = cachedCompletion.linePrefix + cachedCompletion.completion.split('\n')[0];
162
+ const lineContent = model.getLineContent(position.lineNumber);
163
+ return firstCachedLine === lineContent;
164
+ }
165
+ }
166
+ return false;
167
+ }
168
+ #markersAtCursor(pos, all) {
169
+ const padding = 1;
170
+ return all.filter((m) => m.startLineNumber >= pos.lineNumber - padding && m.endLineNumber <= pos.lineNumber + padding);
171
+ }
172
+ #partsToText(parts) {
173
+ return parts.map((p) => p.text).join('');
174
+ }
175
+ #formatCompletionEntry(details) {
176
+ let ret = 'SIGNATURE: ' + this.#partsToText(details.displayParts) + '\n';
177
+ for (const doc of details.documentation) {
178
+ ret += 'DOC: ' + doc.text + '\n';
179
+ }
180
+ ret += 'TAGS: ' + JSON.stringify(details.tags);
181
+ return ret;
182
+ }
183
+ #formatTsHelp(help) {
184
+ const signature = this.#partsToText(help.prefixDisplayParts) +
185
+ help.parameters
186
+ .map((p) => this.#partsToText(p.displayParts))
187
+ .join(this.#partsToText(help.separatorDisplayParts)) +
188
+ this.#partsToText(help.suffixDisplayParts);
189
+ const doc = this.#partsToText(help.documentation);
190
+ let ret = 'SIGNATURE: ' + signature + '\n';
191
+ ret += 'DOC: ' + doc + '\n';
192
+ return ret;
193
+ }
194
+ #formatLanguageClientHelp(help) {
195
+ return help.signatures
196
+ .map((s) => 'SIGNATURE: ' + s.label + '\n' + 'DOC: ' + s.documentation.value)
197
+ .join('\n');
198
+ }
199
+ async #getCompletions(model, position) {
200
+ try {
201
+ const line = model.getLineContent(position.lineNumber);
202
+ const word = line.substring(0, position.column);
203
+ let hasDot = false;
204
+ let afterDot = '';
205
+ for (let i = word.length - 1; i >= 0; i--) {
206
+ if (word[i] === ' ') {
207
+ break;
208
+ }
209
+ if (word[i] === '.') {
210
+ hasDot = true;
211
+ afterDot = word.substring(i + 1).split('(')[0];
212
+ break;
213
+ }
214
+ }
215
+ if (hasDot) {
216
+ if (this.#scriptLang === 'bun') {
217
+ return await this.#getTsCompletions(model, position, afterDot);
218
+ }
219
+ else {
220
+ return await this.#getLanguageClientCompletions(model, position, afterDot);
221
+ }
222
+ }
223
+ return [];
224
+ }
225
+ catch (e) {
226
+ console.error('Error getting completions', e);
227
+ return [];
228
+ }
229
+ }
230
+ async #getTsCompletions(model, position, afterDot) {
231
+ try {
232
+ const offs = model.getOffsetAt(position);
233
+ const workerFactory = await languages.typescript.getTypeScriptWorker();
234
+ const worker = await workerFactory(model.uri);
235
+ const info = await worker.getCompletionsAtPosition(model.uri.toString(), offs);
236
+ let entries = [];
237
+ const filteredEntries = (info?.entries ?? []).filter((e) => afterDot ? e?.name?.startsWith(afterDot) : true);
238
+ const detailedEntries = await Promise.all(filteredEntries
239
+ .slice(0, MAX_COMPLETIONS_DETAILS)
240
+ .map((e) => worker.getCompletionEntryDetails(model.uri.toString(), offs, e.name)));
241
+ entries.push(...detailedEntries.map((e) => this.#formatCompletionEntry(e)));
242
+ // get signature of open parenthesis
243
+ const help = await worker.getSignatureHelpItems(model.uri.toString(), offs, {
244
+ triggerReason: { kind: 'invoked' }
245
+ });
246
+ if (help && help.items?.length > 0) {
247
+ entries.push(this.#formatTsHelp(help.items[0]));
248
+ }
249
+ return entries;
250
+ }
251
+ catch (e) {
252
+ console.error('Error getting ts completions', e);
253
+ return [];
254
+ }
255
+ }
256
+ async #getLanguageClientCompletions(model, position, afterDot) {
257
+ try {
258
+ if (!this.#languageClient) {
259
+ return [];
260
+ }
261
+ let entries = [];
262
+ const completions = await this.#languageClient.sendRequest('textDocument/completion', {
263
+ textDocument: { uri: model.uri.toString() },
264
+ position: {
265
+ line: position.lineNumber - 1,
266
+ character: position.column - 1
267
+ }
268
+ });
269
+ // if we failed to resolve a completion, don't try to resolve any more
270
+ let failedToResolve = false;
271
+ const detailedEntries = await Promise.all(completions.items
272
+ .filter((item) => (afterDot ? item.label.startsWith(afterDot) : true))
273
+ .slice(0, MAX_COMPLETIONS_DETAILS)
274
+ .map(async (item) => {
275
+ try {
276
+ if (failedToResolve) {
277
+ return '';
278
+ }
279
+ const resolvedItem = await this.#languageClient.sendRequest('completionItem/resolve', item);
280
+ return this.#formatLanguageClientHelp({
281
+ signatures: [resolvedItem]
282
+ });
283
+ }
284
+ catch (e) {
285
+ console.error('Failed to resolve completion item:', e);
286
+ failedToResolve = true;
287
+ return '';
288
+ }
289
+ }));
290
+ entries.push(...detailedEntries.filter((e) => e !== ''));
291
+ const help = await this.#languageClient.sendRequest('textDocument/signatureHelp', {
292
+ textDocument: { uri: model.uri.toString() },
293
+ position: {
294
+ line: position.lineNumber - 1, // LSP uses 0-based line numbers
295
+ character: position.column - 1 // LSP uses 0-based character positions
296
+ }
297
+ });
298
+ if (help && help.signatures.length > 0) {
299
+ entries.push(this.#formatLanguageClientHelp(help));
300
+ }
301
+ return entries;
302
+ }
303
+ catch (e) {
304
+ console.error('Error getting language client completions', e);
305
+ return [];
306
+ }
307
+ }
85
308
  async #autocomplete(model, position) {
86
309
  const thisTs = Date.now();
87
310
  this.#lastTs = thisTs;
@@ -104,6 +327,12 @@ export class Autocompletor {
104
327
  endLineNumber: model.getLineCount(),
105
328
  endColumn: model.getLineMaxColumn(model.getLineCount())
106
329
  });
330
+ const completions = await this.#getCompletions(model, position);
331
+ // reset cache for this line if new completions are available
332
+ if (completions.length > 0 && completions.some((c) => !this.#lastCompletions.includes(c))) {
333
+ this.#cache.delete(position.lineNumber);
334
+ }
335
+ this.#lastCompletions = completions;
107
336
  const cachedCompletion = this.#cache.get(position.lineNumber);
108
337
  if (cachedCompletion) {
109
338
  if (position.column > cachedCompletion.column &&
@@ -112,13 +341,11 @@ export class Autocompletor {
112
341
  const newLinePrefix = completeLine.substring(0, position.column - 1);
113
342
  if (newLinePrefix === linePrefix) {
114
343
  const modifiedCompletion = cachedCompletion.completion.slice(position.column - cachedCompletion.column);
115
- console.debug('autocomplete partial cache hit', modifiedCompletion);
116
344
  return { completion: modifiedCompletion, suffix };
117
345
  }
118
346
  }
119
347
  else if (position.column === cachedCompletion.column &&
120
348
  cachedCompletion.linePrefix === linePrefix) {
121
- console.debug('autocomplete exact cache hit', cachedCompletion.completion);
122
349
  return { completion: cachedCompletion.completion, suffix };
123
350
  }
124
351
  }
@@ -130,10 +357,17 @@ export class Autocompletor {
130
357
  endLineNumber: position.lineNumber,
131
358
  endColumn: position.column
132
359
  });
360
+ const markers = meditor.getModelMarkers({ resource: model.uri });
361
+ const markersAtCursor = this.#markersAtCursor(position, markers);
362
+ const librariesCompletions = completions
363
+ .join('\n')
364
+ .slice(0, Math.floor(this.#contextWindow * COMPLETIONS_MAX_RATIO));
133
365
  const completion = await autocompleteRequest({
134
366
  prefix,
135
367
  suffix,
136
- scriptLang: this.#scriptLang
368
+ scriptLang: this.#scriptLang,
369
+ markers: markersAtCursor,
370
+ libraries: librariesCompletions
137
371
  }, this.#abortController);
138
372
  if (!completion) {
139
373
  return;
@@ -1,6 +1,9 @@
1
1
  import { type ScriptLang } from '../../../gen/types.gen';
2
+ import type { editor } from 'monaco-editor';
2
3
  export declare function autocompleteRequest(context: {
3
4
  prefix: string;
4
5
  suffix: string;
5
6
  scriptLang: ScriptLang | 'bunnative' | 'jsx' | 'tsx' | 'json';
7
+ markers: editor.IMarker[];
8
+ libraries: string;
6
9
  }, abortController: AbortController): Promise<string | undefined>;
@@ -4,14 +4,22 @@ import { getFimCompletion } from '../lib';
4
4
  import { getLangContext } from '../chat/script/core';
5
5
  import {} from '../../../gen/types.gen';
6
6
  import { getCommentSymbol } from '../utils';
7
+ function comment(commentSymbol, text) {
8
+ return text
9
+ .split('\n')
10
+ .map((line) => `${commentSymbol} ${line}`)
11
+ .join('\n');
12
+ }
7
13
  export async function autocompleteRequest(context, abortController) {
8
- const langContext = getLangContext(context.scriptLang);
9
- const commentSymbol = getCommentSymbol(context.scriptLang);
10
- if (langContext) {
11
- const contextLines = langContext.split('\n');
12
- const commentedContext = contextLines.map((line) => `${commentSymbol} ${line}`).join('\n');
13
- context.prefix = commentedContext + '\n' + context.prefix;
14
- }
14
+ let commentSymbol = getCommentSymbol(context.scriptLang);
15
+ let contextLines = comment(commentSymbol, 'You are a code completion assistant. You are given three important contexts (<LANGUAGE CONTEXT>, <DIAGNOSTICS>, <LIBRARY METHODS>) to help you complete the code.\n');
16
+ contextLines += comment(commentSymbol, 'LANGUAGE CONTEXT:\n');
17
+ contextLines += comment(commentSymbol, getLangContext(context.scriptLang) + '\n');
18
+ contextLines += comment(commentSymbol, 'DIAGNOSTICS:\n');
19
+ contextLines += comment(commentSymbol, context.markers.map((m) => m.message).join('\n') + '\n');
20
+ contextLines += comment(commentSymbol, 'LIBRARY METHODS:\n');
21
+ contextLines += comment(commentSymbol, context.libraries + '\n');
22
+ context.prefix = contextLines + '\n' + context.prefix;
15
23
  const providerModel = get(copilotInfo).codeCompletionModel;
16
24
  if (!providerModel) {
17
25
  throw new Error('No code completion model selected');
@@ -10,6 +10,7 @@ import ChatMode from './ChatMode.svelte';
10
10
  import Markdown from 'svelte-exmarkdown';
11
11
  import { aiChatManager, AIMode } from './AIChatManager.svelte';
12
12
  import AIChatInput from './AIChatInput.svelte';
13
+ import { getModifierKey } from '../../../utils';
13
14
  let { messages, pastChats, hasDiff, diffMode = false, // todo: remove default
14
15
  selectedContext = $bindable([]), // todo: remove default
15
16
  availableContext = [], // todo: remove default
@@ -120,6 +121,13 @@ $effect(() => {
120
121
  {@render headerRight?.()}
121
122
  </div>
122
123
  </div>
124
+ {#if messages.length === 0}
125
+ <span class="text-2xs text-gray-500 dark:text-gray-400 text-center px-2 my-2"
126
+ >You can use {getModifierKey()}L to open or close this chat, and {getModifierKey()}K in the
127
+ script editor to modify selected lines.</span
128
+ >
129
+ {/if}
130
+
123
131
  {#if messages.length > 0}
124
132
  <div
125
133
  class="h-full overflow-y-scroll pt-2 pb-12"
@@ -59,16 +59,18 @@ class AIChatManager {
59
59
  ask: true
60
60
  });
61
61
  open = $derived(chatState.size > 0);
62
- constructor() {
63
- loadApiTools()
64
- .then((tools) => {
65
- this.apiTools = tools;
66
- })
67
- .catch((err) => {
62
+ loadApiTools = async () => {
63
+ try {
64
+ this.apiTools = await loadApiTools();
65
+ if (this.mode === AIMode.NAVIGATOR) {
66
+ this.tools = [this.changeModeTool, ...navigatorTools, ...this.apiTools];
67
+ }
68
+ }
69
+ catch (err) {
68
70
  console.error('Error loading api tools', err);
69
71
  this.apiTools = [];
70
- });
71
- }
72
+ }
73
+ };
72
74
  setAiChatInput(aiChatInput) {
73
75
  this.aiChatInput = aiChatInput;
74
76
  }
@@ -482,6 +484,9 @@ class AIChatManager {
482
484
  }
483
485
  }
484
486
  };
487
+ if (this.mode === AIMode.NAVIGATOR && this.apiTools.length === 0) {
488
+ await this.loadApiTools();
489
+ }
485
490
  await this.chatRequest({
486
491
  ...params
487
492
  });
@@ -1,8 +1,8 @@
1
- <script module>
2
- export const getAiModuleAction = (id: string | undefined) => {
3
- if (!id) return undefined
4
- return aiChatManager.flowAiChatHelpers?.getModuleAction(id)
5
- }
1
+ <script module lang="ts">export const getAiModuleAction = (id) => {
2
+ if (!id)
3
+ return undefined;
4
+ return aiChatManager.flowAiChatHelpers?.getModuleAction(id);
5
+ };
6
6
  </script>
7
7
 
8
8
  <script lang="ts">import { twMerge } from 'tailwind-merge';
@@ -1,7 +1,7 @@
1
1
  import { type FlowModule } from '../../../../gen';
2
2
  import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/chat/completions.mjs';
3
3
  import { z } from 'zod';
4
- import type { Tool } from '../shared';
4
+ import { type Tool } from '../shared';
5
5
  import type { ExtendedOpenFlow } from '../../../flows/types';
6
6
  export type AIModuleAction = 'added' | 'modified' | 'removed';
7
7
  export interface FlowAIChatHelpers {
@@ -1,17 +1,16 @@
1
1
  import { ScriptService } from '../../../../gen';
2
2
  import YAML from 'yaml';
3
3
  import { z } from 'zod';
4
- import { zodToJsonSchema } from 'zod-to-json-schema';
5
4
  import uFuzzy from '@leeoniya/ufuzzy';
6
5
  import { emptySchema, emptyString } from '../../../../utils';
7
6
  import { getFormattedResourceTypes, getLangContext, SUPPORTED_CHAT_SCRIPT_LANGUAGES } from '../script/core';
7
+ import { createSearchHubScriptsTool, createToolDef } from '../shared';
8
8
  const searchScriptsSchema = z.object({
9
9
  query: z
10
10
  .string()
11
11
  .describe('The query to search for, e.g. send email, list stripe invoices, etc..')
12
12
  });
13
13
  const searchScriptsToolDef = createToolDef(searchScriptsSchema, 'search_scripts', 'Search for scripts in the workspace');
14
- const searchHubScriptsToolDef = createToolDef(searchScriptsSchema, 'search_hub_scripts', 'Search for scripts in the hub');
15
14
  const langSchema = z.enum(SUPPORTED_CHAT_SCRIPT_LANGUAGES);
16
15
  const newStepSchema = z.union([
17
16
  z
@@ -189,6 +188,7 @@ const getInstructionsForCodeGenerationToolSchema = z.object({
189
188
  const getInstructionsForCodeGenerationToolDef = createToolDef(getInstructionsForCodeGenerationToolSchema, 'get_instructions_for_code_generation', 'Get instructions for code generation for a raw script step');
190
189
  const workspaceScriptsSearch = new WorkspaceScriptsSearch();
191
190
  export const flowTools = [
191
+ createSearchHubScriptsTool(false),
192
192
  {
193
193
  def: searchScriptsToolDef,
194
194
  fn: async ({ args, workspace, toolId, toolCallbacks }) => {
@@ -203,22 +203,6 @@ export const flowTools = [
203
203
  return JSON.stringify(scriptResults);
204
204
  }
205
205
  },
206
- {
207
- def: searchHubScriptsToolDef,
208
- fn: async ({ args, toolId, toolCallbacks }) => {
209
- toolCallbacks.setToolStatus(toolId, 'Searching for hub scripts related to "' + args.query + '"...');
210
- const parsedArgs = searchScriptsSchema.parse(args);
211
- const scripts = await ScriptService.queryHubScripts({
212
- text: parsedArgs.query,
213
- kind: 'script'
214
- });
215
- toolCallbacks.setToolStatus(toolId, 'Found ' + scripts.length + ' scripts in the hub related to "' + args.query + '"');
216
- return JSON.stringify(scripts.map((s) => ({
217
- path: `hub/${s.version_id}/${s.app}/${s.summary.toLowerCase().replaceAll(/\s+/g, '_')}`,
218
- summary: s.summary
219
- })));
220
- }
221
- },
222
206
  {
223
207
  def: addStepToolDef,
224
208
  fn: async ({ args, helpers, toolId, toolCallbacks }) => {
@@ -370,26 +354,6 @@ export const flowTools = [
370
354
  }
371
355
  }
372
356
  ];
373
- function createToolDef(zodSchema, name, description) {
374
- const schema = zodToJsonSchema(zodSchema, {
375
- name,
376
- target: 'openAi'
377
- });
378
- let parameters = schema.definitions[name];
379
- parameters = {
380
- ...parameters,
381
- required: parameters.required ?? []
382
- };
383
- return {
384
- type: 'function',
385
- function: {
386
- strict: true,
387
- name,
388
- description,
389
- parameters
390
- }
391
- };
392
- }
393
357
  export function prepareFlowSystemMessage() {
394
358
  const content = `You are a helpful assistant that creates and edits workflows on the Windmill platform. You're provided with a bunch of tools to help you edit the flow.
395
359
  Follow the user instructions carefully.
@@ -46,6 +46,14 @@ interface OpenAPISpec {
46
46
  paths: {
47
47
  [path: string]: OpenAPIPathItem;
48
48
  };
49
+ components?: {
50
+ parameters?: {
51
+ [name: string]: OpenAPIParameter;
52
+ };
53
+ schemas?: {
54
+ [name: string]: any;
55
+ };
56
+ };
49
57
  }
50
58
  export declare function buildToolsFromOpenApi(openApiSpec: OpenAPISpec, options?: {
51
59
  pathFilter?: (path: string) => boolean;