feature flag support
This commit is contained in:
parent
b4a4f81308
commit
96fbc8fff0
|
@ -268,4 +268,5 @@ export class FlagSet<V extends Flag<any>, T extends { [key: string]: V }> {
|
|||
export const flags = new FlagSet({
|
||||
DEFAULT_VALUES: Flag.boolean(env.isDev()),
|
||||
SQS: Flag.boolean(env.isDev()),
|
||||
AI_CUSTOM_CONFIGS: Flag.boolean(env.isDev()),
|
||||
})
|
||||
|
|
|
@ -17,6 +17,7 @@ export const usage = (users: number = 0, creators: number = 0): QuotaUsage => {
|
|||
automations: 0,
|
||||
dayPasses: 0,
|
||||
queries: 0,
|
||||
budibaseAICredits: 0,
|
||||
triggers: {},
|
||||
breakdown: {
|
||||
rowQueries: {
|
||||
|
@ -46,12 +47,14 @@ export const usage = (users: number = 0, creators: number = 0): QuotaUsage => {
|
|||
automations: 0,
|
||||
dayPasses: 0,
|
||||
queries: 0,
|
||||
budibaseAICredits: 0,
|
||||
triggers: {},
|
||||
},
|
||||
current: {
|
||||
automations: 0,
|
||||
dayPasses: 0,
|
||||
queries: 0,
|
||||
budibaseAICredits: 0,
|
||||
triggers: {},
|
||||
},
|
||||
},
|
||||
|
@ -62,6 +65,7 @@ export const usage = (users: number = 0, creators: number = 0): QuotaUsage => {
|
|||
creators,
|
||||
userGroups: 0,
|
||||
rows: 0,
|
||||
aiCustomConfigs: 0,
|
||||
triggers: {},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -80,7 +80,9 @@
|
|||
}
|
||||
|
||||
async function deleteConfig(key) {
|
||||
// Delete a configuration
|
||||
// We don't store the default BB AI config in the DB
|
||||
delete fullAIConfig.config.budibase_ai
|
||||
// Delete the configuration
|
||||
delete fullAIConfig.config[key]
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { derived } from "svelte/store"
|
||||
import { admin } from "./admin"
|
||||
import { auth } from "./auth"
|
||||
import { isEnabled } from "helpers/featureFlags"
|
||||
import { sdk } from "@budibase/shared-core"
|
||||
import { FeatureFlag } from "@budibase/types";
|
||||
|
||||
export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
||||
const user = $auth?.user
|
||||
|
@ -45,10 +47,6 @@ export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
|||
title: "Auth",
|
||||
href: "/builder/portal/settings/auth",
|
||||
},
|
||||
{
|
||||
title: "AI",
|
||||
href: "/builder/portal/settings/ai",
|
||||
},
|
||||
{
|
||||
title: "Email",
|
||||
href: "/builder/portal/settings/email",
|
||||
|
@ -66,6 +64,15 @@ export const menu = derived([admin, auth], ([$admin, $auth]) => {
|
|||
href: "/builder/portal/settings/environment",
|
||||
},
|
||||
]
|
||||
if (isEnabled(FeatureFlag.AI_CUSTOM_CONFIGS)) {
|
||||
settingsSubPages.push(
|
||||
{
|
||||
title: "AI",
|
||||
href: "/builder/portal/settings/ai",
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (!cloud) {
|
||||
settingsSubPages.push({
|
||||
title: "Version",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export enum FeatureFlag {
|
||||
PER_CREATOR_PER_USER_PRICE = "PER_CREATOR_PER_USER_PRICE",
|
||||
PER_CREATOR_PER_USER_PRICE_ALERT = "PER_CREATOR_PER_USER_PRICE_ALERT",
|
||||
AI_CUSTOM_CONFIGS = "AI_CUSTOM_CONFIGS",
|
||||
}
|
||||
|
||||
export interface TenantFeatureFlags {
|
||||
|
|
|
@ -135,7 +135,6 @@ const getEventFns = async (config: Config, existing?: Config) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fns
|
||||
}
|
||||
|
||||
|
@ -344,11 +343,12 @@ async function enrichAIConfig(aiConfig: AIConfig) {
|
|||
|
||||
// Return the Budibase AI data source as part of the response if licensing allows
|
||||
const budibaseAIEnabled = await pro.features.isBudibaseAIEnabled()
|
||||
const defaultConfigExists = Object.keys(aiConfig.config).some(key => aiConfig.config[key].isDefault)
|
||||
if (budibaseAIEnabled) {
|
||||
aiConfig.config["budibase_ai"] = {
|
||||
provider: "OpenAI",
|
||||
active: true,
|
||||
isDefault: true,
|
||||
isDefault: !defaultConfigExists,
|
||||
defaultModel: env.BUDIBASE_AI_DEFAULT_MODEL,
|
||||
name: "Budibase AI",
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { expect } from "vitest"
|
||||
import { configs } from "@budibase/backend-core"
|
||||
import { UserCtx } from "@budibase/types"
|
||||
import * as pro from "@budibase/pro"
|
||||
|
@ -81,6 +80,35 @@ describe("Global configs controller", () => {
|
|||
})
|
||||
})
|
||||
|
||||
it("Should not not return the default Budibase AI config when on self host", async () => {
|
||||
pro.features.isBudibaseAIEnabled = jest.fn(() => false)
|
||||
configs.getConfig.mockResolvedValue({
|
||||
config: {
|
||||
ai: {
|
||||
apiKey: "abc123APIKey",
|
||||
baseUrl: "https://api.example.com",
|
||||
},
|
||||
},
|
||||
})
|
||||
const ctx = {
|
||||
params: {
|
||||
type: "ai",
|
||||
},
|
||||
throw: jest.fn(),
|
||||
} as UserCtx
|
||||
|
||||
await find(ctx)
|
||||
|
||||
expect(ctx.body).toEqual({
|
||||
config: {
|
||||
ai: {
|
||||
apiKey: "--secret-value--",
|
||||
baseUrl: "https://api.example.com",
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it("Should not update existing secrets when updating an existing AI Config", async () => {
|
||||
const newConfig = {
|
||||
type: "ai",
|
||||
|
@ -114,4 +142,5 @@ describe("Global configs controller", () => {
|
|||
// should be unchanged
|
||||
expect(newConfig.config.aiconfig.apiKey === "myapikey")
|
||||
})
|
||||
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue