@budibase/worker 3.31.9 → 3.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/worker",
3
3
  "email": "hi@budibase.com",
4
- "version": "3.31.9",
4
+ "version": "3.32.1",
5
5
  "description": "Budibase background service",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -91,5 +91,5 @@
91
91
  "supertest": "6.3.3",
92
92
  "timekeeper": "2.2.0"
93
93
  },
94
- "gitHead": "fd3896fb9777306c4a0f32479094782ab428081b"
94
+ "gitHead": "6ba2ff716f459a1e39604fb846f71db1bdb56545"
95
95
  }
package/scripts/test.sh CHANGED
@@ -4,10 +4,10 @@ set -e
4
4
  if [[ -n $CI ]]
5
5
  then
6
6
  # Running in ci, where resources are limited
7
- echo "jest --coverage --maxWorkers=2 --forceExit --bail $@"
8
- jest --coverage --maxWorkers=2 --forceExit --bail $@
7
+ echo "jest --maxWorkers=2 --forceExit --bail $@"
8
+ jest --maxWorkers=2 --forceExit --bail $@
9
9
  else
10
10
  # --maxWorkers performs better in development
11
11
  echo "jest --coverage --detectOpenHandles $@"
12
12
  jest --coverage --detectOpenHandles $@
13
- fi
13
+ fi
@@ -15,7 +15,6 @@ import {
15
15
  filterValidTranslationOverrides,
16
16
  } from "@budibase/shared-core"
17
17
  import {
18
- AIInnerConfig,
19
18
  Config,
20
19
  ConfigChecklistResponse,
21
20
  ConfigType,
@@ -27,7 +26,6 @@ import {
27
26
  GetPublicTranslationsResponse,
28
27
  GoogleInnerConfig,
29
28
  TranslationOverrides,
30
- isAIConfig,
31
29
  isGoogleConfig,
32
30
  isOIDCConfig,
33
31
  isRecaptchaConfig,
@@ -62,8 +60,6 @@ const getEventFns = async (config: Config, existing?: Config) => {
62
60
  if (!existing) {
63
61
  if (isSMTPConfig(config)) {
64
62
  fns.push(events.email.SMTPCreated)
65
- } else if (isAIConfig(config)) {
66
- fns.push(() => events.ai.AIConfigCreated)
67
63
  } else if (isGoogleConfig(config)) {
68
64
  fns.push(() => events.auth.SSOCreated(ConfigType.GOOGLE))
69
65
  if (config.config.activated) {
@@ -100,8 +96,6 @@ const getEventFns = async (config: Config, existing?: Config) => {
100
96
  } else {
101
97
  if (isSMTPConfig(config)) {
102
98
  fns.push(events.email.SMTPUpdated)
103
- } else if (isAIConfig(config)) {
104
- fns.push(() => events.ai.AIConfigUpdated)
105
99
  } else if (isGoogleConfig(config)) {
106
100
  fns.push(() => events.auth.SSOUpdated(ConfigType.GOOGLE))
107
101
  if (!existing.config.activated && config.config.activated) {
@@ -266,33 +260,6 @@ async function processOIDCConfig(config: OIDCConfigs, existing?: OIDCConfigs) {
266
260
  }
267
261
  }
268
262
 
269
- export async function processAIConfig(
270
- newConfig: AIInnerConfig,
271
- existingConfig: AIInnerConfig
272
- ) {
273
- for (const key in existingConfig) {
274
- if (newConfig[key]?.apiKey === PASSWORD_REPLACEMENT) {
275
- newConfig[key].apiKey = existingConfig[key].apiKey
276
- }
277
- }
278
-
279
- let numBudibaseAI = 0
280
- for (const config of Object.values(newConfig)) {
281
- if (config.provider === "BudibaseAI") {
282
- numBudibaseAI++
283
- if (numBudibaseAI > 1) {
284
- throw new BadRequestError("Only one Budibase AI provider is allowed")
285
- }
286
- } else {
287
- if (!config.apiKey) {
288
- throw new BadRequestError(
289
- `API key is required for provider ${config.provider}`
290
- )
291
- }
292
- }
293
- }
294
- }
295
-
296
263
  export async function processRecaptchaConfig(
297
264
  config: RecaptchaInnerConfig,
298
265
  existingConfig?: RecaptchaInnerConfig
@@ -407,11 +374,6 @@ export async function save(
407
374
  case ConfigType.OIDC:
408
375
  await processOIDCConfig(config, existingConfig?.config)
409
376
  break
410
- case ConfigType.AI:
411
- if (existingConfig) {
412
- await processAIConfig(config, existingConfig.config)
413
- }
414
- break
415
377
  case ConfigType.RECAPTCHA:
416
378
  await processRecaptchaConfig(config, existingConfig?.config)
417
379
  break
@@ -521,7 +483,7 @@ export async function find(ctx: UserCtx<void, FindConfigResponse>) {
521
483
  }
522
484
 
523
485
  function stripSecrets(config: Config, ctx?: UserCtx) {
524
- if (isAIConfig(config)) {
486
+ if (config.type === ConfigType.AI) {
525
487
  for (const key in config.config) {
526
488
  if (config.config[key].apiKey) {
527
489
  config.config[key].apiKey = PASSWORD_REPLACEMENT
@@ -7,7 +7,7 @@ import {
7
7
  tenancy,
8
8
  utils,
9
9
  } from "@budibase/backend-core"
10
- import { ai, groups } from "@budibase/pro"
10
+ import { groups } from "@budibase/pro"
11
11
  import {
12
12
  DevInfo,
13
13
  FetchAPIKeyResponse,
@@ -116,13 +116,6 @@ export async function getSelf(ctx: UserCtx<void, GetGlobalSelfResponse>) {
116
116
 
117
117
  // add the feature flags for this tenant
118
118
  const flags = await features.flags.fetch()
119
- const llmConfig = await ai.getLLMConfig()
120
- const sanitisedLLMConfig = llmConfig
121
- ? {
122
- provider: llmConfig.provider,
123
- model: llmConfig.model,
124
- }
125
- : undefined
126
119
 
127
120
  const settingsConfig = await configs.getSettingsConfig()
128
121
 
@@ -130,7 +123,6 @@ export async function getSelf(ctx: UserCtx<void, GetGlobalSelfResponse>) {
130
123
  ...enrichedUser,
131
124
  ...sessionAttributes,
132
125
  flags,
133
- llm: sanitisedLLMConfig,
134
126
  lockedBy: settingsConfig?.lockedBy,
135
127
  }
136
128
  }
@@ -64,22 +64,6 @@ function scimValidation() {
64
64
  }).unknown(true)
65
65
  }
66
66
 
67
- function aiValidation() {
68
- // prettier-ignore
69
- return Joi.object().pattern(
70
- Joi.string(),
71
- Joi.object({
72
- provider: Joi.string().required(),
73
- isDefault: Joi.boolean().required(),
74
- name: Joi.string().required(),
75
- active: Joi.boolean().required(),
76
- baseUrl: Joi.string().optional().allow("", null),
77
- apiKey: Joi.string().optional(),
78
- defaultModel: Joi.string().optional(),
79
- }).required()
80
- )
81
- }
82
-
83
67
  function recaptchaValidation() {
84
68
  return Joi.object({
85
69
  siteKey: Joi.string().required(),
@@ -124,7 +108,6 @@ function buildConfigSaveValidation() {
124
108
  { is: ConfigType.GOOGLE, then: googleValidation() },
125
109
  { is: ConfigType.OIDC, then: oidcValidation() },
126
110
  { is: ConfigType.SCIM, then: scimValidation() },
127
- { is: ConfigType.AI, then: aiValidation() },
128
111
  { is: ConfigType.RECAPTCHA, then: recaptchaValidation() },
129
112
  { is: ConfigType.TRANSLATIONS, then: translationsValidation() },
130
113
  ],
@@ -32,10 +32,6 @@ export class ConfigAPI extends TestAPI {
32
32
  .expect("Content-Type", /json/)
33
33
  }
34
34
 
35
- getAIConfig = async () => {
36
- return await this.getConfig(ConfigType.AI)
37
- }
38
-
39
35
  getConfig = async <T extends ConfigType>(type: T) => {
40
36
  const resp = await this.request
41
37
  .get(`/api/global/configs/${type}`)
@@ -1,97 +0,0 @@
1
- import { TestConfiguration } from "../../../../tests"
2
- import { AIConfig, ConfigType } from "@budibase/types"
3
- import { configs, context } from "@budibase/backend-core"
4
-
5
- const BASE_CONFIG: AIConfig = {
6
- type: ConfigType.AI,
7
- config: {
8
- ai: {
9
- provider: "OpenAI",
10
- isDefault: false,
11
- name: "Test",
12
- active: true,
13
- defaultModel: "gpt4",
14
- apiKey: "myapikey",
15
- baseUrl: "https://api.example.com",
16
- },
17
- },
18
- }
19
-
20
- describe("Global configs controller", () => {
21
- const config = new TestConfiguration()
22
-
23
- beforeAll(async () => {
24
- await config.beforeAll()
25
- })
26
-
27
- afterAll(async () => {
28
- await config.afterAll()
29
- })
30
-
31
- it("should strip secrets when pulling AI config", async () => {
32
- await config.api.configs.saveConfig(BASE_CONFIG)
33
- const response = await config.api.configs.getAIConfig()
34
- expect(response.config.ai.apiKey).toEqual("--secret-value--")
35
- })
36
-
37
- it("should not update existing secrets when updating an existing AI Config", async () => {
38
- await config.api.configs.saveConfig(BASE_CONFIG)
39
-
40
- const savedConfig = await config.api.configs.getAIConfig()
41
- delete savedConfig._id
42
- delete savedConfig._rev
43
- delete savedConfig.createdAt
44
- delete savedConfig.updatedAt
45
-
46
- await config.api.configs.saveConfig(savedConfig)
47
-
48
- await context.doInTenant(config.tenantId, async () => {
49
- const aiConfig = await configs.getAIConfig()
50
- expect(aiConfig!.config.ai.apiKey).toEqual(BASE_CONFIG.config.ai.apiKey)
51
- })
52
- })
53
-
54
- it("should allow BudibaseAI to save without an apiKey", async () => {
55
- await config.api.configs.saveConfig({
56
- type: ConfigType.AI,
57
- config: {
58
- ai: {
59
- name: "Budibase AI",
60
- active: true,
61
- provider: "BudibaseAI",
62
- isDefault: true,
63
- },
64
- },
65
- })
66
-
67
- const aiConfig = await config.api.configs.getAIConfig()
68
- expect(aiConfig.config.ai).toEqual({
69
- name: "Budibase AI",
70
- provider: "BudibaseAI",
71
- active: true,
72
- isDefault: true,
73
- })
74
- })
75
-
76
- it("should not allow OpenAI to save without an apiKey", async () => {
77
- await config.api.configs.saveConfig(
78
- {
79
- type: ConfigType.AI,
80
- config: {
81
- ai: {
82
- name: "OpenAI",
83
- active: true,
84
- provider: "OpenAI",
85
- isDefault: true,
86
- },
87
- },
88
- },
89
- {
90
- status: 400,
91
- body: {
92
- message: /API key is required for provider OpenAI/,
93
- },
94
- }
95
- )
96
- })
97
- })