BB AI QA testing fixes

This commit is contained in:
Martin McKeaveney 2024-10-22 18:24:10 +01:00
parent 2795eca672
commit 807ecf6039
4 changed files with 49 additions and 30 deletions

View File

@ -32,9 +32,7 @@
async function fetchAIConfig() { async function fetchAIConfig() {
try { try {
const aiDoc = await API.getConfig(ConfigTypes.AI) const aiDoc = await API.getConfig(ConfigTypes.AI)
if (aiDoc._id) { fullAIConfig = aiDoc
fullAIConfig = aiDoc
}
} catch (error) { } catch (error) {
notifications.error("Error fetching AI config") notifications.error("Error fetching AI config")
} }
@ -66,6 +64,7 @@
} }
// Add new or update existing custom AI Config // Add new or update existing custom AI Config
fullAIConfig.config[id] = editingAIConfig fullAIConfig.config[id] = editingAIConfig
fullAIConfig.type = ConfigTypes.AI
} }
try { try {

@ -1 +1 @@
Subproject commit 297fdc937e9c650b4964fc1a942b60022b195865 Subproject commit 7bd0350ed3f55da30d07a7c67fd746727ce93a9a

View File

@ -18,6 +18,7 @@ import * as loop from "./steps/loop"
import * as collect from "./steps/collect" import * as collect from "./steps/collect"
import * as branch from "./steps/branch" import * as branch from "./steps/branch"
import * as triggerAutomationRun from "./steps/triggerAutomationRun" import * as triggerAutomationRun from "./steps/triggerAutomationRun"
import * as openai from "./steps/openai"
import env from "../environment" import env from "../environment"
import { import {
PluginType, PluginType,
@ -89,21 +90,27 @@ export const BUILTIN_ACTION_DEFINITIONS: Record<
// ran at all // ran at all
if (env.SELF_HOSTED) { if (env.SELF_HOSTED) {
const bash = require("./steps/bash") const bash = require("./steps/bash")
const openai = require("./steps/openai")
// @ts-ignore // @ts-ignore
ACTION_IMPLS["EXECUTE_BASH"] = bash.run ACTION_IMPLS["EXECUTE_BASH"] = bash.run
// @ts-ignore // @ts-ignore
BUILTIN_ACTION_DEFINITIONS["EXECUTE_BASH"] = bash.definition BUILTIN_ACTION_DEFINITIONS["EXECUTE_BASH"] = bash.definition
// @ts-ignore
ACTION_IMPLS.OPENAI = openai.run
BUILTIN_ACTION_DEFINITIONS.OPENAI = openai.definition
} }
export async function getActionDefinitions() { export async function getActionDefinitions() {
if (await features.flags.isEnabled(FeatureFlag.AUTOMATION_BRANCHING)) { if (await features.flags.isEnabled(FeatureFlag.AUTOMATION_BRANCHING)) {
BUILTIN_ACTION_DEFINITIONS["BRANCH"] = branch.definition BUILTIN_ACTION_DEFINITIONS["BRANCH"] = branch.definition
} }
if (
env.SELF_HOSTED ||
(await features.flags.isEnabled(FeatureFlag.BUDIBASE_AI)) ||
(await features.flags.isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS))
) {
BUILTIN_ACTION_DEFINITIONS["OPENAI"] = openai.definition
// @ts-ignore
ACTION_IMPLS["OPENAI"] = openai.run
}
const actionDefinitions = BUILTIN_ACTION_DEFINITIONS const actionDefinitions = BUILTIN_ACTION_DEFINITIONS
if (env.SELF_HOSTED) { if (env.SELF_HOSTED) {
const plugins = await sdk.plugins.fetch(PluginType.AUTOMATION) const plugins = await sdk.plugins.fetch(PluginType.AUTOMATION)

View File

@ -35,6 +35,7 @@ import {
AIInnerConfig, AIInnerConfig,
} from "@budibase/types" } from "@budibase/types"
import * as pro from "@budibase/pro" import * as pro from "@budibase/pro"
import { generateConfigID } from "@budibase/backend-core/src/configs"
const getEventFns = async (config: Config, existing?: Config) => { const getEventFns = async (config: Config, existing?: Config) => {
const fns = [] const fns = []
@ -44,9 +45,7 @@ const getEventFns = async (config: Config, existing?: Config) => {
fns.push(events.email.SMTPCreated) fns.push(events.email.SMTPCreated)
} else if (isAIConfig(config)) { } else if (isAIConfig(config)) {
fns.push(() => events.ai.AIConfigCreated) fns.push(() => events.ai.AIConfigCreated)
fns.push(() => fns.push(() => pro.quotas.addCustomAIConfig)
pro.quotas.updateCustomAIConfigCount(Object.keys(config.config).length)
)
} else if (isGoogleConfig(config)) { } else if (isGoogleConfig(config)) {
fns.push(() => events.auth.SSOCreated(ConfigType.GOOGLE)) fns.push(() => events.auth.SSOCreated(ConfigType.GOOGLE))
if (config.config.activated) { if (config.config.activated) {
@ -85,9 +84,6 @@ const getEventFns = async (config: Config, existing?: Config) => {
fns.push(events.email.SMTPUpdated) fns.push(events.email.SMTPUpdated)
} else if (isAIConfig(config)) { } else if (isAIConfig(config)) {
fns.push(() => events.ai.AIConfigUpdated) fns.push(() => events.ai.AIConfigUpdated)
fns.push(() =>
pro.quotas.updateCustomAIConfigCount(Object.keys(config.config).length)
)
} else if (isGoogleConfig(config)) { } else if (isGoogleConfig(config)) {
fns.push(() => events.auth.SSOUpdated(ConfigType.GOOGLE)) fns.push(() => events.auth.SSOUpdated(ConfigType.GOOGLE))
if (!existing.config.activated && config.config.activated) { if (!existing.config.activated && config.config.activated) {
@ -253,7 +249,7 @@ export async function save(ctx: UserCtx<Config>) {
if (existingConfig) { if (existingConfig) {
await verifyAIConfig(config, existingConfig) await verifyAIConfig(config, existingConfig)
} }
await pro.quotas.updateCustomAIConfigCount(Object.keys(config).length) await pro.quotas.addCustomAIConfig()
break break
} }
} catch (err: any) { } catch (err: any) {
@ -342,29 +338,43 @@ export async function find(ctx: UserCtx) {
let scopedConfig = await configs.getConfig(type) let scopedConfig = await configs.getConfig(type)
if (scopedConfig) { if (scopedConfig) {
if (type === ConfigType.OIDC_LOGOS) { await handleConfigType(type, scopedConfig)
enrichOIDCLogos(scopedConfig) } else if (type === ConfigType.AI) {
} scopedConfig = { config: {} } as AIConfig
await handleAIConfig(scopedConfig)
if (type === ConfigType.AI) {
await pro.sdk.ai.enrichAIConfig(scopedConfig)
// Strip out the API Keys from the response so they don't show in the UI
for (const key in scopedConfig.config) {
if (scopedConfig.config[key].apiKey) {
scopedConfig.config[key].apiKey = PASSWORD_REPLACEMENT
}
}
}
ctx.body = scopedConfig
} else { } else {
// don't throw an error, there simply is nothing to return // If no config found and not AI type, just return an empty body
ctx.body = {} ctx.body = {}
return
} }
ctx.body = scopedConfig
} catch (err: any) { } catch (err: any) {
ctx.throw(err?.status || 400, err) ctx.throw(err?.status || 400, err)
} }
} }
async function handleConfigType(type: ConfigType, config: Config) {
if (type === ConfigType.OIDC_LOGOS) {
enrichOIDCLogos(config)
} else if (type === ConfigType.AI) {
await handleAIConfig(config)
}
}
async function handleAIConfig(config: AIConfig) {
await pro.sdk.ai.enrichAIConfig(config)
stripApiKeys(config)
}
function stripApiKeys(config: AIConfig) {
for (const key in config?.config) {
if (config.config[key].apiKey) {
config.config[key].apiKey = PASSWORD_REPLACEMENT
}
}
}
export async function publicOidc(ctx: Ctx<void, GetPublicOIDCConfigResponse>) { export async function publicOidc(ctx: Ctx<void, GetPublicOIDCConfigResponse>) {
try { try {
// Find the config with the most granular scope based on context // Find the config with the most granular scope based on context
@ -508,6 +518,9 @@ export async function destroy(ctx: UserCtx) {
try { try {
await db.remove(id, rev) await db.remove(id, rev)
await cache.destroy(cache.CacheKey.CHECKLIST) await cache.destroy(cache.CacheKey.CHECKLIST)
if (id === generateConfigID(ConfigType.AI)) {
await pro.quotas.removeCustomAIConfig()
}
ctx.body = { message: "Config deleted successfully" } ctx.body = { message: "Config deleted successfully" }
} catch (err: any) { } catch (err: any) {
ctx.throw(err.status, err) ctx.throw(err.status, err)