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,5 +1,58 @@
1
1
  import { get } from 'svelte/store';
2
- import { workspaceStore } from '../../../../stores';
2
+ import { workspaceStore, enterpriseLicense } from '../../../../stores';
3
+ /**
4
+ * Dereferences parameter $ref references in an OpenAPI spec
5
+ * Only resolves parameter references, not schemas or other components
6
+ */
7
+ function dereferenceParameters(spec) {
8
+ if (!spec.components?.parameters) {
9
+ return spec;
10
+ }
11
+ const resolveParameterRef = (paramRef) => {
12
+ if (paramRef.$ref) {
13
+ // Extract parameter name from $ref (e.g., "#/components/parameters/WorkspaceId" -> "WorkspaceId")
14
+ const refPath = paramRef.$ref.split('/');
15
+ if (refPath.length >= 4 && refPath[1] === 'components' && refPath[2] === 'parameters') {
16
+ const paramName = refPath[3];
17
+ const resolvedParam = spec.components?.parameters?.[paramName];
18
+ if (resolvedParam) {
19
+ return resolvedParam;
20
+ }
21
+ }
22
+ console.warn(`Could not resolve parameter reference: ${paramRef.$ref}`);
23
+ return paramRef;
24
+ }
25
+ return paramRef;
26
+ };
27
+ const processParameters = (parameters) => {
28
+ return parameters.map(resolveParameterRef);
29
+ };
30
+ const dereferencedSpec = {
31
+ ...spec,
32
+ paths: {}
33
+ };
34
+ // Process each path
35
+ for (const [pathKey, pathItem] of Object.entries(spec.paths)) {
36
+ const newPathItem = { ...pathItem };
37
+ // Dereference path-level parameters
38
+ if (pathItem.parameters) {
39
+ newPathItem.parameters = processParameters(pathItem.parameters);
40
+ }
41
+ // Dereference operation-level parameters
42
+ const methods = ['get', 'post', 'put', 'delete', 'patch', 'options'];
43
+ for (const method of methods) {
44
+ const operation = pathItem[method];
45
+ if (operation?.parameters) {
46
+ newPathItem[method] = {
47
+ ...operation,
48
+ parameters: processParameters(operation.parameters)
49
+ };
50
+ }
51
+ }
52
+ dereferencedSpec.paths[pathKey] = newPathItem;
53
+ }
54
+ return dereferencedSpec;
55
+ }
3
56
  const buildApiCallTools = (name, description, parameters) => {
4
57
  return {
5
58
  type: 'function',
@@ -46,6 +99,9 @@ export function buildToolsFromOpenApi(openApiSpec, options = {}) {
46
99
  const queryParams = (op.parameters || []).filter((p) => p.in === 'query');
47
100
  // Add path parameters
48
101
  for (const param of pathParams) {
102
+ if (param.name === 'workspace') {
103
+ continue;
104
+ }
49
105
  parameters.properties[param.name] = {
50
106
  type: param.schema?.type || 'string',
51
107
  description: param.description || `Path parameter: ${param.name}`
@@ -81,9 +137,9 @@ export function buildToolsFromOpenApi(openApiSpec, options = {}) {
81
137
  }
82
138
  }
83
139
  }
84
- const tool = buildApiCallTools('api_' + op.operationId, op.summary || op.description || `${method.toUpperCase()} ${path}`, parameters);
140
+ const tool = buildApiCallTools('api_' + op.operationId.replace(/\s+/g, ''), op.summary || op.description || `${method.toUpperCase()} ${path}`, parameters);
85
141
  // Store the endpoint path in the map
86
- endpointMap['api_' + op.operationId] = `${method.toUpperCase()} ${path}`;
142
+ endpointMap['api_' + op.operationId.replace(/\s+/g, '')] = `${method.toUpperCase()} ${path}`;
87
143
  tools.push(tool);
88
144
  }
89
145
  }
@@ -97,7 +153,6 @@ export function createApiTools(chatTools, endpointMap = {}) {
97
153
  const toolName = chatTool.function.name;
98
154
  let endpoint = endpointMap[toolName] || '';
99
155
  endpoint = endpoint.replace('{workspace}', get(workspaceStore));
100
- toolCallbacks.setToolStatus(toolId, `Calling API endpoint (${endpoint})...`);
101
156
  try {
102
157
  // Extract method and path from endpoint
103
158
  const [method, path] = endpoint.split(' ', 2);
@@ -112,8 +167,8 @@ export function createApiTools(chatTools, endpointMap = {}) {
112
167
  if (key === 'body')
113
168
  continue; // Body is handled separately
114
169
  // Check if this is a path parameter
115
- if (url.includes(`:${key}`)) {
116
- url = url.replace(`:${key}`, encodeURIComponent(String(value)));
170
+ if (url.includes(`{${key}}`)) {
171
+ url = url.replace(`{${key}}`, encodeURIComponent(String(value)));
117
172
  }
118
173
  else {
119
174
  // Assume it's a query parameter
@@ -130,17 +185,32 @@ export function createApiTools(chatTools, endpointMap = {}) {
130
185
  }
131
186
  // Log the constructed URL
132
187
  console.log(`Calling API: ${method} ${url} with args: ${JSON.stringify(args)}`);
188
+ toolCallbacks.setToolStatus(toolId, `Calling API endpoint (${url})...`);
133
189
  const response = await fetch(url, {
134
190
  method: method
135
191
  });
136
- const data = await response.json();
137
- // For now, return a placeholder response
138
- // In a real implementation, we would make the actual API call here
139
- toolCallbacks.setToolStatus(toolId, `API call to ${endpoint} completed`);
140
- return JSON.stringify({
141
- success: true,
142
- data: data
143
- });
192
+ if (response.ok) {
193
+ let result = '';
194
+ if (response.headers.get('content-type')?.includes('application/json')) {
195
+ result = await response.json();
196
+ }
197
+ else {
198
+ result = await response.text();
199
+ }
200
+ toolCallbacks.setToolStatus(toolId, `API call to ${url} completed`);
201
+ return JSON.stringify({
202
+ success: true,
203
+ data: result
204
+ });
205
+ }
206
+ else {
207
+ const text = await response.text();
208
+ toolCallbacks.setToolStatus(toolId, `API call to ${url} failed`);
209
+ return JSON.stringify({
210
+ success: false,
211
+ data: text
212
+ });
213
+ }
144
214
  }
145
215
  catch (error) {
146
216
  toolCallbacks.setToolStatus(toolId, `API call to ${endpoint} failed`);
@@ -154,9 +224,12 @@ export function createApiTools(chatTools, endpointMap = {}) {
154
224
  export async function loadApiTools() {
155
225
  try {
156
226
  const response = await fetch('/api/openapi.json');
157
- const openApiSpec = (await response.json());
227
+ const rawOpenApiSpec = (await response.json());
228
+ // Dereference parameter references
229
+ const openApiSpec = dereferenceParameters(rawOpenApiSpec);
158
230
  const pathsToInclude = [
159
231
  'jobs',
232
+ 'jobs_u',
160
233
  'scripts',
161
234
  'flows',
162
235
  'resources',
@@ -164,6 +237,13 @@ export async function loadApiTools() {
164
237
  'schedules',
165
238
  'workers'
166
239
  ];
240
+ // call srch endpoint to check if it's available
241
+ if (get(enterpriseLicense)) {
242
+ const srchResponse = await fetch(`/api/srch/index/search/enabled`);
243
+ if (srchResponse.ok) {
244
+ pathsToInclude.push('srch/w'); // job search
245
+ }
246
+ }
167
247
  const { tools: apiTools, endpointMap } = buildToolsFromOpenApi(openApiSpec, {
168
248
  pathFilter: (path) => pathsToInclude.some((p) => path.includes(`/${p}/`)),
169
249
  methodFilter: ['get']
@@ -1,6 +1,6 @@
1
1
  import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/index.mjs';
2
2
  import type { Tool } from '../shared';
3
- export declare const CHAT_SYSTEM_PROMPT = "\nYou are Windmill's intelligent assistant, designed to help users navigate the application and answer questions about its functionality. It is your only purpose to help the user in the context of the windmill application.\nWindmill is an open-source developer platform for building internal tools, API integrations, background jobs, workflows, and user interfaces. It offers a unified system where scripts are automatically turned into sharable UIs and can be composed into flows or embedded in custom applications.\n\nYou have access to these tools:\n1. View current buttons and inputs on the page (get_triggerable_components)\n2. Execute buttons and inputs (trigger_component) \n3. Get documentation for user requests (get_documentation)\n4. A list of tools to interact with the backend API\n\nINSTRUCTIONS:\n- When users ask about application features or concepts, first use get_documentation internally to retrieve accurate information about how to fulfill the user's request.\n- Then immediately use the available tools to guide the user through the application. Do not wait for the user's confirmation before taking action.\n- If you detect a confirmation modal that needs user confirmation, stop the navigation and let the user know that the action is pending confirmation.\n- Use get_triggerable_components to understand available options, and then trigger the components using trigger_component. Then wait a moment before rescanning the current page, and then continue with the next step. Do this 5 times max.\n- Make sure you navigated as far as possible before responding to the user. Always use get_triggerable_components one last time to make sure you didn't miss anything.\n- If you are not able to fulfill the user's request after 5 attempts, redirect the user to the documentation.\n- If you are asked to fill a form or act on an input, input the existing json object and change the fields the user asked you to change. Take into account the prompt_for_ai field of the schema to know what and how to do changes. Then tell the user that you have updated the form, and ask him to review the changes before running the script or flow.\n- For form inputs where format starts with \"resource-\" and is not \"resource-obj\", fetch the available resources using get_available_resources, and then use the resource_path prefixed with \"$res:\" to fill the input.\n- If you are not sure about an input, set the ones you are sure about, and then ask the user for the value of the input you are not sure about.\n\nGENERAL PRINCIPLES:\n- Be concise but thorough\n- Focus on taking action and completing the user's goals\n- Maintain a friendly, professional tone\n- If you encounter an error or can't complete a request, explain why and suggest alternatives\n- When asked about a specific script, flow or app, first check components directly related to the mentioned entity, before checking the other components.\n- When you do not find what you are looking for on the current page, go to the home page by looking for the \"Home\" component, then scan the components again.\n\nIMPORTANT CONSIDERATIONS:\n- If you do an API call, make sure you ask the user if he also wants you to navigate the application to fulfill his request.\n- The user might have changed the page in the middle of the conversation, so make sure you rescan the page on each user request instead of just responding that you cannot find what the user is asking for.\n- If you navigate to a script creation page, consider this:\n - The page opens with the settings drawer open. After doing the changes mentioned by the user, close the settings drawer.\n - Then if the user has described what he wanted the script to do, switch to script mode with the change_mode tool, and use the new tools you'll have access to to edit the script.\n- If you navigate to a flow creation page, consider this:\n - If the user has described what he wanted the flow to do, switch to flow mode with the change_mode tool before using the new tools you'll have access to to edit the flow.\n\nAPI_TOOLS_RESTRICTIONS:\n- You can only use the API tools to fetch data from the backend API after you tried to navigate the application to fulfill the user's request and it's not enough to do so. ALWAYS ask the user if he also wants you to navigate the application to fulfill his request.\n- If you use api tools, also fetch the relevant documentation to help the user understand the data you fetched, with a link to the documentation if possible.\n\nRETRIEVE_AVAILABLE_RESOURCES_RESTRICTION:\n- You can only use the get_available_resources tool to fill a form or an input based on the user's request. Do not use it when directly asked to fetch available resources, use the API tools instead.\n\nAlways use the provided tools purposefully and appropriately to achieve the user's goals.\nYour actions only allow you to navigate the application through the provided tools.\nWhen you complete the user's request, do not say \"I created...\" or \"I updated...\" or \"I deleted...\", but rather complete your response with precisions about how it works based on the documentation. Also drop a link to the relevant documentation if possible.\n\nExample of good behavior:\n- User: \"How can I set my AI providers?\"\n- You: <call get_documentation and fetch relevant documentation>\n- You: <call get_triggerable_components to find relevant components>\n- You: <trigger the components>\n- You: \"<precisions about the request based on the documentation>\"\n";
3
+ export declare const CHAT_SYSTEM_PROMPT: string;
4
4
  export declare const getDocumentationTool: Tool<{}>;
5
5
  export declare const navigatorTools: Tool<{}>[];
6
6
  export declare function prepareNavigatorSystemMessage(): ChatCompletionSystemMessageParam;
@@ -1,5 +1,5 @@
1
1
  import { ResourceService } from '../../../../gen';
2
- import { workspaceStore } from '../../../../stores';
2
+ import { enterpriseLicense, workspaceStore } from '../../../../stores';
3
3
  import { get } from 'svelte/store';
4
4
  import { triggerablesByAi } from '../sharedChatState.svelte';
5
5
  export const CHAT_SYSTEM_PROMPT = `
@@ -22,6 +22,7 @@ INSTRUCTIONS:
22
22
  - If you are asked to fill a form or act on an input, input the existing json object and change the fields the user asked you to change. Take into account the prompt_for_ai field of the schema to know what and how to do changes. Then tell the user that you have updated the form, and ask him to review the changes before running the script or flow.
23
23
  - For form inputs where format starts with "resource-" and is not "resource-obj", fetch the available resources using get_available_resources, and then use the resource_path prefixed with "$res:" to fill the input.
24
24
  - If you are not sure about an input, set the ones you are sure about, and then ask the user for the value of the input you are not sure about.
25
+ ${get(enterpriseLicense) ? `- If asked to look through the jobs logs, use the /srch/w/{workspace}/index/search/job endpoint to search for the relevant jobs runs. Then use /w/{workspace}/jobs_u/get to get the logs of each job.` : ''}
25
26
 
26
27
  GENERAL PRINCIPLES:
27
28
  - Be concise but thorough
@@ -1,7 +1,7 @@
1
1
  import type { ResourceType, ScriptLang } from '../../../../gen/types.gen';
2
2
  import type { ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam } from 'openai/resources/index.mjs';
3
3
  import type { ContextElement } from '../context';
4
- import type { Tool } from '../shared';
4
+ import { type Tool } from '../shared';
5
5
  export declare function formatResourceTypes(allResourceTypes: ResourceType[], lang: 'python3' | 'php' | 'bun' | 'deno' | 'nativets' | 'bunnative'): string;
6
6
  export declare const SUPPORTED_CHAT_SCRIPT_LANGUAGES: string[];
7
7
  export declare function getLangContext(lang: ScriptLang | 'bunnative' | 'jsx' | 'tsx' | 'json', { allowResourcesFetch, isPreprocessor }?: {
@@ -10,7 +10,7 @@ export declare function getLangContext(lang: ScriptLang | 'bunnative' | 'jsx' |
10
10
  isFailure?: boolean;
11
11
  }): string;
12
12
  export declare function getFormattedResourceTypes(lang: ScriptLang | 'bunnative', prompt: string, workspace: string): Promise<string>;
13
- export declare const CHAT_SYSTEM_PROMPT = "\n\tYou are a coding assistant for the Windmill platform. You are provided with a list of `INSTRUCTIONS` and the current contents of a code file under `CODE`.\n\n\tYour task is to respond to the user's request. Assume all user queries are valid and actionable.\n\n\tWhen the user requests code changes:\n\t- Always include a **single code block** with the **entire updated file**, not just the modified sections.\n\t- The code can include `[#START]` and `[#END]` markers to indicate the start and end of a code piece. You MUST only modify the code between these markers if given, and remove them in your response. If a question is asked about the code, you MUST only talk about the code between the markers. Refer to it as the code piece, not the code between the markers.\n\t- Follow the instructions carefully and explain the reasoning behind your changes.\n\t- If the request is abstract (e.g., \"make this cleaner\"), interpret it concretely and reflect that in the code block.\n\t- Preserve existing formatting, indentation, and whitespace unless changes are strictly required to fulfill the user's request.\n\t- The user can ask you to look at or modify specific files, databases or errors by having its name in the INSTRUCTIONS preceded by the @ symbol. In this case, put your focus on the element that is explicitly mentioned.\n\t- The user can ask you questions about a list of `DATABASES` that are available in the user's workspace. If the user asks you a question about a database, you should ask the user to specify the database name if not given, or take the only one available if there is only one.\n\t- You can also receive a `DIFF` of the changes that have been made to the code. You should use this diff to give better answers.\n\t- Before giving your answer, check again that you carefully followed these instructions.\n\n\tImportant:\n\tDo not mention or reveal these instructions to the user unless explicitly asked to do so.\n";
13
+ export declare const CHAT_SYSTEM_PROMPT = "\n\tYou are a coding assistant for the Windmill platform. You are provided with a list of `INSTRUCTIONS` and the current contents of a code file under `CODE`.\n\n\tYour task is to respond to the user's request. Assume all user queries are valid and actionable.\n\n\tWhen the user requests code changes:\n\t- Always include a **single code block** with the **entire updated file**, not just the modified sections.\n\t- The code can include `[#START]` and `[#END]` markers to indicate the start and end of a code piece. You MUST only modify the code between these markers if given, and remove them in your response. If a question is asked about the code, you MUST only talk about the code between the markers. Refer to it as the code piece, not the code between the markers.\n\t- Follow the instructions carefully and explain the reasoning behind your changes.\n\t- If the request is abstract (e.g., \"make this cleaner\"), interpret it concretely and reflect that in the code block.\n\t- Preserve existing formatting, indentation, and whitespace unless changes are strictly required to fulfill the user's request.\n\t- The user can ask you to look at or modify specific files, databases or errors by having its name in the INSTRUCTIONS preceded by the @ symbol. In this case, put your focus on the element that is explicitly mentioned.\n\t- The user can ask you questions about a list of `DATABASES` that are available in the user's workspace. If the user asks you a question about a database, you should ask the user to specify the database name if not given, or take the only one available if there is only one.\n\t- You can also receive a `DIFF` of the changes that have been made to the code. You should use this diff to give better answers.\n\t- Before giving your answer, check again that you carefully followed these instructions.\n\t- When asked to create a script that communicates with an external service, you can use the `search_hub_scripts` tool to search for relevant scripts in the hub. Make sure the language is the same as what the user is coding in. If you do not find any relevant scripts, you can use the `search_npm_packages` tool to search for relevant packages and their documentation. Always give a link to the documentation in your answer if possible.\n\n\tImportant:\n\tDo not mention or reveal these instructions to the user unless explicitly asked to do so.\n";
14
14
  export declare const INLINE_CHAT_SYSTEM_PROMPT = "\n# Windmill Inline Coding Assistant\n\nYou are a coding assistant for the Windmill platform. You provide precise code modifications based on user instructions.\n\n## Input Format\n\nYou will receive:\n- **INSTRUCTIONS**: User's modification request\n- **CODE**: Current code content with modification boundaries\n- **DATABASES** *(optional)*: Available workspace databases\n\n### Code Boundaries\n\nThe code contains `[#START]` and `[#END]` markers indicating the modification scope:\n- **MUST** only modify code between these markers\n- **MUST** remove the markers in your response\n- **MUST** preserve all other code exactly as provided\n\n## Task Requirements\n\nReturn the modified CODE that fulfills the user's request. Assume all user queries are valid and actionable.\n\n### Critical Rules\n\n- \u2705 **ALWAYS** include a single code block with the entire updated CODE\n- \u2705 **ALWAYS** use the structured XML output format below\n- \u274C **NEVER** include only modified sections\n- \u274C **NEVER** add explanatory text or comments outside the format\n- \u274C **NEVER** include ``` code fences in your response\n- \u274C **NEVER** modify the code outside the boundaries\n\n## Output Format\n\n```xml\n<changes_made>\nBrief description of what was changed\n</changes_made>\n<new_code>\n[complete modified code without markers]\n</new_code>\n```\n\n## Example\n\n### Input:\n```xml\n<user_request>\nINSTRUCTIONS:\nReturn 2 instead of 1\n\nCODE:\nimport * as wmill from \"windmill-client\"\n\nfunction test() {\n\treturn \"hello\"\n}\n\n[#START]\nexport async function main() {\n\treturn 1;\n}\n[#END]\n</user_request>\n```\n\n### Expected Output:\n```xml\n<changes_made>\nChanged return value from 1 to 2 in main function\n</changes_made>\n<new_code>\nimport * as wmill from \"windmill-client\"\n\nfunction test() {\n\treturn \"hello\"\n}\n\nexport async function main() {\n\treturn 2;\n}\n</new_code>\n```\n";
15
15
  export declare const CHAT_USER_PROMPT = "\nINSTRUCTIONS:\n{instructions}\n\nWINDMILL LANGUAGE CONTEXT:\n{lang_context}\n\n";
16
16
  export declare const CHAT_USER_DB_CONTEXT = "- {title}: SCHEMA: \n{schema}\n";
@@ -25,3 +25,12 @@ export interface ScriptChatHelpers {
25
25
  }
26
26
  export declare const resourceTypeTool: Tool<ScriptChatHelpers>;
27
27
  export declare const dbSchemaTool: Tool<ScriptChatHelpers>;
28
+ export declare function searchExternalIntegrationResources(args: {
29
+ query: string;
30
+ }): Promise<string>;
31
+ export declare const searchNpmPackagesTool: Tool<ScriptChatHelpers>;
32
+ export declare function fetchNpmPackageTypes(packageName: string, version?: string): Promise<{
33
+ success: boolean;
34
+ types: string;
35
+ error?: string;
36
+ }>;
@@ -2,10 +2,19 @@ import { ResourceService } 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 { dbSchemas } from '../../../../stores';
5
+ import { copilotSessionModel, dbSchemas } from '../../../../stores';
6
6
  import { scriptLangToEditorLang } from '../../../../scripts';
7
7
  import { getDbSchemas } from '../../../apps/components/display/dbtable/utils';
8
8
  import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '../../../../script_helpers';
9
+ import { createSearchHubScriptsTool } from '../shared';
10
+ import { setupTypeAcquisition } from '../../../../ata';
11
+ import { getModelContextWindow } from '../../lib';
12
+ // Score threshold for npm packages search filtering
13
+ const SCORE_THRESHOLD = 1000;
14
+ // percentage of the context window for documentation of npm packages
15
+ const DOCS_CONTEXT_PERCENTAGE = 1;
16
+ // percentage of the context window for types of npm packages
17
+ const TYPES_CONTEXT_PERCENTAGE = 1;
9
18
  export function formatResourceTypes(allResourceTypes, lang) {
10
19
  const resourceTypes = allResourceTypes.filter((rt) => isObject(rt.schema) && 'properties' in rt.schema && isObject(rt.schema.properties));
11
20
  if (lang === 'python3') {
@@ -45,8 +54,8 @@ const TS_WINDMILL_CLIENT_CONTEXT = `
45
54
  The windmill client (wmill) can be used to interact with Windmill from the script. Import it with \`import * as wmill from "windmill-client"\`. Key functions include:
46
55
 
47
56
  // Resource operations
48
- wmill.getResource(path?: string): Promise<any> // Get resource value by path
49
- wmill.setResource(value: any, path?: string): Promise<void> // Set resource value
57
+ wmill.getResource(path?: string, undefinedIfEmpty?: boolean): Promise<any> // Get resource value by path
58
+ wmill.setResource(value: any, path?: string, initializeToTypeIfNotExist?: string): Promise<void> // Set resource value
50
59
 
51
60
  // State management (persistent across executions)
52
61
  wmill.getState(): Promise<any> // Get shared state
@@ -54,36 +63,39 @@ wmill.setState(state: any): Promise<void> // Set shared state
54
63
 
55
64
  // Variables
56
65
  wmill.getVariable(path: string): Promise<string> // Get variable value
57
- wmill.setVariable(path: string, value: string): Promise<void> // Set variable value
66
+ wmill.setVariable(path: string, value: string, isSecretIfNotExist?: boolean, descriptionIfNotExist?: string): Promise<void> // Set variable value
58
67
 
59
68
  // Script execution
60
- wmill.runScript(path: string, args?: Record<string, any>): Promise<any> // Run script synchronously
61
- wmill.runScriptAsync(path: string, args?: Record<string, any>): Promise<string> // Run script async, returns job ID
62
- wmill.waitJob(jobId: string): Promise<any> // Wait for job completion and get result
69
+ wmill.runScript(path?: string | null, hash_?: string | null, args?: Record<string, any> | null, verbose?: boolean): Promise<any> // Run script synchronously
70
+ wmill.runScriptAsync(path: string | null, hash_: string | null, args: Record<string, any> | null, scheduledInSeconds?: number | null): Promise<string> // Run script async, returns job ID
71
+ wmill.waitJob(jobId: string, verbose?: boolean): Promise<any> // Wait for job completion and get result
72
+ wmill.getResult(jobId: string): Promise<any> // Get job result by ID
73
+ wmill.getResultMaybe(jobId: string): Promise<any> // Get job result by ID, returns undefined if not found
74
+ wmill.getRootJobId(jobId?: string): Promise<string> // Get root job ID from job ID
63
75
 
64
76
  // S3 file operations (if S3 is configured)
65
- wmill.loadS3File(s3object: S3Object | string): Promise<Uint8Array> // Load file content from S3
66
- wmill.writeS3File(s3object: S3Object | string, content: string | Blob): Promise<S3Object> // Write file to S3
77
+ wmill.loadS3File(s3object: S3Object, s3ResourcePath?: string | undefined): Promise<Uint8Array | undefined> // Load file content from S3
78
+ wmill.loadS3FileStream(s3object: S3Object, s3ResourcePath?: string | undefined): Promise<Blob | undefined> // Load file content from S3 as stream
79
+ wmill.writeS3File(s3object: S3Object | undefined, fileContent: string | Blob, s3ResourcePath?: string | undefined): Promise<S3Object> // Write file to S3
67
80
 
68
81
  // Flow operations
69
- wmill.setFlowUserState(key: string, value: any): Promise<void> // Set flow user state
70
- wmill.getFlowUserState(key: string): Promise<any> // Get flow user state
71
- wmill.getResumeUrls(): Promise<{approvalPage: string, resume: string, cancel: string}> // Get approval URLs
82
+ wmill.setFlowUserState(key: string, value: any, errorIfNotPossible?: boolean): Promise<void> // Set flow user state
83
+ wmill.getFlowUserState(key: string, errorIfNotPossible?: boolean): Promise<any> // Get flow user state
84
+ wmill.getResumeUrls(approver?: string): Promise<{approvalPage: string, resume: string, cancel: string}> // Get approval URLs
72
85
 
73
- // Utilities
74
- wmill.getWorkspace(): string // Get current workspace
75
- wmill.databaseUrlFromResource(path: string): Promise<string> // Get database URL from resource`;
86
+ `;
76
87
  const PYTHON_WINDMILL_CLIENT_CONTEXT = `
77
88
 
78
89
  The windmill client (wmill) can be used to interact with Windmill from the script. Import it with \`import wmill\`. Key functions include:
79
90
 
80
91
  // Resource operations
81
- wmill.get_resource(path: str) -> dict | None // Get resource value by path
92
+ wmill.get_resource(path: str, none_if_undefined: bool = False) -> dict | None // Get resource value by path
82
93
  wmill.set_resource(path: str, value: Any, resource_type: str = "any") -> None // Set resource value
83
94
 
84
95
  // State management (persistent across executions)
85
96
  wmill.get_state() -> Any // Get shared state (deprecated, use flow user state)
86
97
  wmill.set_state(value: Any) -> None // Set shared state
98
+ wmill.get_state_path() -> str // Get state path
87
99
  wmill.get_flow_user_state(key: str) -> Any // Get flow user state
88
100
  wmill.set_flow_user_state(key: str, value: Any) -> None // Set flow user state
89
101
 
@@ -92,22 +104,27 @@ wmill.get_variable(path: str) -> str // Get variable value
92
104
  wmill.set_variable(path: str, value: str, is_secret: bool = False) -> None // Set variable value
93
105
 
94
106
  // Script execution
95
- wmill.run_script(path: str, args: dict = None, timeout = None) -> Any // Run script synchronously
96
- wmill.run_script_async(path: str, args: dict = None, scheduled_in_secs: int = None) -> str // Run script async, returns job ID
97
- wmill.wait_job(job_id: str, timeout = None) -> Any // Wait for job completion and get result
107
+ wmill.run_script(path: str = None, hash_: str = None, args: dict = None, timeout = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = True) -> Any // Run script synchronously
108
+ wmill.run_script_async(path: str = None, hash_: str = None, args: dict = None, scheduled_in_secs: int = None) -> str // Run script async, returns job ID
109
+ wmill.wait_job(job_id: str, timeout = None, verbose: bool = False, cleanup: bool = True, assert_result_is_not_none: bool = False) -> Any // Wait for job completion and get result
110
+ wmill.get_result(job_id: str, assert_result_is_not_none: bool = True) -> Any // Get job result by ID
111
+ wmill.get_root_job_id(job_id: str | None = None) -> str // Get root job ID from job ID
98
112
 
99
113
  // S3 file operations (if S3 is configured)
100
- wmill.load_s3_file(s3object: S3Object | str, s3_resource_path: str = None) -> bytes // Load file content from S3
101
- wmill.write_s3_file(s3object: S3Object | str, file_content: bytes, s3_resource_path: str = None) -> S3Object // Write file to S3
114
+ wmill.load_s3_file(s3object: S3Object | str, s3_resource_path: str | None = None) -> bytes // Load file content from S3
115
+ wmill.load_s3_file_reader(s3object: S3Object | str, s3_resource_path: str | None = None) -> BufferedReader // Load S3 file as stream reader
116
+ wmill.write_s3_file(s3object: S3Object | str | None, file_content: BufferedReader | bytes, s3_resource_path: str | None = None, content_type: str | None = None, content_disposition: str | None = None) -> S3Object // Write file to S3
102
117
 
103
118
  // Flow operations
104
- wmill.run_flow_async(path: str, args: dict = None) -> str // Run flow asynchronously
119
+ wmill.run_flow_async(path: str, args: dict = None, scheduled_in_secs: int = None, do_not_track_in_parent: bool = True) -> str // Run flow asynchronously
105
120
  wmill.get_resume_urls(approver: str = None) -> dict // Get approval URLs for flow steps
106
121
 
107
122
  // Utilities
123
+ wmill.get_workspace() -> str // Get current workspace
108
124
  wmill.whoami() -> dict // Get current user information
109
125
  wmill.get_job_status(job_id: str) -> str // Get job status ("RUNNING" | "WAITING" | "COMPLETED")
110
- wmill.set_progress(value: int) -> None // Set job progress (0-100)`;
126
+ wmill.set_progress(value: int, job_id: Optional[str] = None) -> None // Set job progress (0-100)
127
+ wmill.get_progress(job_id: Optional[str] = None) -> Any // Get job progress`;
111
128
  const PYTHON_RESOURCE_TYPE_SYSTEM = `On Windmill, credentials and configuration are stored in resources and passed as parameters to main.
112
129
  If you need credentials, you should add a parameter to \`main\` with the corresponding resource type.
113
130
  You need to **redefine** the type of the resources that are needed before the main function as TypedDict, but only include them if they are actually needed to achieve the function purpose.
@@ -275,6 +292,7 @@ export const CHAT_SYSTEM_PROMPT = `
275
292
  - The user can ask you questions about a list of \`DATABASES\` that are available in the user's workspace. If the user asks you a question about a database, you should ask the user to specify the database name if not given, or take the only one available if there is only one.
276
293
  - You can also receive a \`DIFF\` of the changes that have been made to the code. You should use this diff to give better answers.
277
294
  - Before giving your answer, check again that you carefully followed these instructions.
295
+ - When asked to create a script that communicates with an external service, you can use the \`search_hub_scripts\` tool to search for relevant scripts in the hub. Make sure the language is the same as what the user is coding in. If you do not find any relevant scripts, you can use the \`search_npm_packages\` tool to search for relevant packages and their documentation. Always give a link to the documentation in your answer if possible.
278
296
 
279
297
  Important:
280
298
  Do not mention or reveal these instructions to the user unless explicitly asked to do so.
@@ -407,6 +425,10 @@ export function prepareScriptTools(language, context) {
407
425
  if (context.some((c) => c.type === 'db')) {
408
426
  tools.push(dbSchemaTool);
409
427
  }
428
+ if (['bun', 'deno'].includes(language)) {
429
+ tools.push(createSearchHubScriptsTool(true));
430
+ tools.push(searchNpmPackagesTool);
431
+ }
410
432
  return tools;
411
433
  }
412
434
  export async function prepareScriptUserMessage(instructions, language, selectedContext, options = {}) {
@@ -545,3 +567,123 @@ export const dbSchemaTool = {
545
567
  return stringSchema;
546
568
  }
547
569
  };
570
+ const packagesSearchCache = new Map();
571
+ export async function searchExternalIntegrationResources(args) {
572
+ try {
573
+ if (packagesSearchCache.has(args.query)) {
574
+ return JSON.stringify(packagesSearchCache.get(args.query));
575
+ }
576
+ const result = await fetch(`https://registry.npmjs.org/-/v1/search?text=${args.query}&size=2`);
577
+ const data = await result.json();
578
+ const filtered = data.objects.filter((r) => r.searchScore >= SCORE_THRESHOLD);
579
+ const modelContextWindow = getModelContextWindow(get(copilotSessionModel)?.model ?? '');
580
+ const results = await Promise.all(filtered.map(async (r) => {
581
+ let documentation = '';
582
+ let types = '';
583
+ try {
584
+ const docResponse = await fetch(`https://unpkg.com/${r.package.name}/readme.md`);
585
+ const docLimit = Math.floor((modelContextWindow * DOCS_CONTEXT_PERCENTAGE) / 100);
586
+ documentation = await docResponse.text();
587
+ documentation = documentation.slice(0, docLimit);
588
+ }
589
+ catch (error) {
590
+ console.error('Error getting documentation for package:', error);
591
+ documentation = '';
592
+ }
593
+ try {
594
+ const typesResponse = await fetchNpmPackageTypes(r.package.name, r.package.version);
595
+ const typesLimit = Math.floor((modelContextWindow * TYPES_CONTEXT_PERCENTAGE) / 100);
596
+ types = typesResponse.types.slice(0, typesLimit);
597
+ }
598
+ catch (error) {
599
+ console.error('Error getting types for package:', error);
600
+ types = '';
601
+ }
602
+ return {
603
+ package: r.package.name,
604
+ documentation: documentation,
605
+ types: types
606
+ };
607
+ }));
608
+ packagesSearchCache.set(args.query, results);
609
+ return JSON.stringify(results);
610
+ }
611
+ catch (error) {
612
+ console.error('Error searching external integration resources:', error);
613
+ return 'Error searching external integration resources';
614
+ }
615
+ }
616
+ const SEARCH_NPM_PACKAGES_TOOL = {
617
+ type: 'function',
618
+ function: {
619
+ name: 'search_npm_packages',
620
+ description: 'Search for npm packages and their documentation',
621
+ parameters: {
622
+ type: 'object',
623
+ properties: {
624
+ query: {
625
+ type: 'string',
626
+ description: 'The query to search for'
627
+ }
628
+ },
629
+ required: ['query']
630
+ }
631
+ }
632
+ };
633
+ export const searchNpmPackagesTool = {
634
+ def: SEARCH_NPM_PACKAGES_TOOL,
635
+ fn: async ({ args, toolId, toolCallbacks }) => {
636
+ toolCallbacks.setToolStatus(toolId, 'Searching for relevant packages...');
637
+ const result = await searchExternalIntegrationResources(args);
638
+ toolCallbacks.setToolStatus(toolId, 'Retrieved relevant packages');
639
+ return result;
640
+ }
641
+ };
642
+ export async function fetchNpmPackageTypes(packageName, version = 'latest') {
643
+ try {
644
+ const typeDefinitions = new Map();
645
+ const ata = setupTypeAcquisition({
646
+ projectName: 'NPM-Package-Types',
647
+ depsParser: () => [],
648
+ root: '',
649
+ delegate: {
650
+ receivedFile: (code, path) => {
651
+ if (path.endsWith('.d.ts')) {
652
+ typeDefinitions.set(path, code);
653
+ }
654
+ },
655
+ localFile: () => { }
656
+ }
657
+ });
658
+ const depsToGet = [
659
+ {
660
+ raw: packageName,
661
+ module: packageName,
662
+ version: version
663
+ }
664
+ ];
665
+ await ata(depsToGet);
666
+ if (typeDefinitions.size === 0) {
667
+ return {
668
+ success: false,
669
+ types: '',
670
+ error: `No type definitions found for ${packageName}`
671
+ };
672
+ }
673
+ const formattedTypes = Array.from(typeDefinitions.entries())
674
+ .map(([path, content]) => `// ${path}\n${content}`)
675
+ .join('\n\n');
676
+ return {
677
+ success: true,
678
+ types: formattedTypes
679
+ };
680
+ }
681
+ catch (error) {
682
+ console.error('Error fetching NPM package types:', error);
683
+ return {
684
+ success: false,
685
+ types: '',
686
+ error: `Error fetching package types: ${error instanceof Error ? error.message : 'Unknown error'}`
687
+ };
688
+ }
689
+ }
@@ -1,6 +1,7 @@
1
1
  import type { ChatCompletionMessageParam, ChatCompletionMessageToolCall, ChatCompletionTool } from 'openai/resources/chat/completions.mjs';
2
2
  import type { ContextElement } from './context';
3
3
  import type { ExtendedOpenFlow } from '../../flows/types';
4
+ import { z } from 'zod';
4
5
  type BaseDisplayMessage = {
5
6
  content: string;
6
7
  contextElements?: ContextElement[];
@@ -44,4 +45,13 @@ export interface Tool<T> {
44
45
  export interface ToolCallbacks {
45
46
  setToolStatus: (id: string, content: string) => void;
46
47
  }
48
+ export declare function createToolDef(zodSchema: z.ZodSchema, name: string, description: string): ChatCompletionTool;
49
+ export declare const createSearchHubScriptsTool: (withContent?: boolean) => {
50
+ def: ChatCompletionTool;
51
+ fn: ({ args, toolId, toolCallbacks }: {
52
+ args: any;
53
+ toolId: any;
54
+ toolCallbacks: any;
55
+ }) => Promise<string>;
56
+ };
47
57
  export {};
@@ -1,5 +1,8 @@
1
1
  import { get } from 'svelte/store';
2
2
  import { workspaceStore } from '../../../stores';
3
+ import { zodToJsonSchema } from 'zod-to-json-schema';
4
+ import { z } from 'zod';
5
+ import { ScriptService } from '../../../gen';
3
6
  async function callTool({ tools, functionName, args, workspace, helpers, toolCallbacks, toolId }) {
4
7
  const tool = tools.find((t) => t.def.function.name === functionName);
5
8
  if (!tool) {
@@ -37,3 +40,56 @@ export async function processToolCall({ tools, toolCall, messages, helpers, tool
37
40
  console.error(err);
38
41
  }
39
42
  }
43
+ export function createToolDef(zodSchema, name, description) {
44
+ const schema = zodToJsonSchema(zodSchema, {
45
+ name,
46
+ target: 'openAi'
47
+ });
48
+ let parameters = schema.definitions[name];
49
+ parameters = {
50
+ ...parameters,
51
+ required: parameters.required ?? []
52
+ };
53
+ return {
54
+ type: 'function',
55
+ function: {
56
+ strict: true,
57
+ name,
58
+ description,
59
+ parameters
60
+ }
61
+ };
62
+ }
63
+ const searchHubScriptsSchema = z.object({
64
+ query: z
65
+ .string()
66
+ .describe('The query to search for, e.g. send email, list stripe invoices, etc..')
67
+ });
68
+ const searchHubScriptsToolDef = createToolDef(searchHubScriptsSchema, 'search_hub_scripts', 'Search for scripts in the hub');
69
+ export const createSearchHubScriptsTool = (withContent = false) => ({
70
+ def: searchHubScriptsToolDef,
71
+ fn: async ({ args, toolId, toolCallbacks }) => {
72
+ toolCallbacks.setToolStatus(toolId, 'Searching for hub scripts related to "' + args.query + '"...');
73
+ const parsedArgs = searchHubScriptsSchema.parse(args);
74
+ const scripts = await ScriptService.queryHubScripts({
75
+ text: parsedArgs.query,
76
+ kind: 'script'
77
+ });
78
+ toolCallbacks.setToolStatus(toolId, 'Found ' + scripts.length + ' scripts in the hub related to "' + args.query + '"');
79
+ // if withContent, fetch scripts with their content, limit to 3 results
80
+ const results = await Promise.all(scripts.slice(0, withContent ? 3 : undefined).map(async (s) => {
81
+ let content = '';
82
+ if (withContent) {
83
+ content = await ScriptService.getHubScriptContentByPath({
84
+ path: `hub/${s.version_id}/${s.app}/${s.summary.toLowerCase().replaceAll(/\s+/g, '_')}`
85
+ });
86
+ }
87
+ return {
88
+ path: `hub/${s.version_id}/${s.app}/${s.summary.toLowerCase().replaceAll(/\s+/g, '_')}`,
89
+ summary: s.summary,
90
+ ...(withContent ? { content } : {})
91
+ };
92
+ }));
93
+ return JSON.stringify(results);
94
+ }
95
+ });
@@ -18,6 +18,7 @@ export interface ModelResponse {
18
18
  };
19
19
  }
20
20
  export declare function fetchAvailableModels(resourcePath: string, workspace: string, provider: AIProvider): Promise<string[]>;
21
+ export declare function getModelContextWindow(model: string): 1000000 | 128000 | 200000 | 32000;
21
22
  export declare const PROVIDER_COMPLETION_CONFIG_MAP: Record<AIProvider, ChatCompletionCreateParams>;
22
23
  declare class WorkspacedAIClients {
23
24
  private openaiClient;