Merge branch 'master' into dependabot/npm_and_yarn/babel/runtime-7.26.10

This commit is contained in:
Michael Drury 2025-03-25 10:54:37 +00:00 committed by GitHub
commit e3369803a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 39 additions and 114 deletions

View File

@ -163,6 +163,7 @@ const environment = {
ACCOUNT_PORTAL_URL:
process.env.ACCOUNT_PORTAL_URL || "https://account.budibase.app",
ACCOUNT_PORTAL_API_KEY: process.env.ACCOUNT_PORTAL_API_KEY || "",
BUDICLOUD_URL: process.env.BUDICLOUD_URL || "https://budibase.app",
DISABLE_ACCOUNT_PORTAL: process.env.DISABLE_ACCOUNT_PORTAL,
SELF_HOSTED: selfHosted,
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,

View File

@ -261,9 +261,13 @@ export class UserDB {
}
}
const change = dbUser ? 0 : 1 // no change if there is existing user
let change = 1
let creatorsChange = 0
if (opts.isAccountHolder || dbUser) {
change = 0
creatorsChange = 1
}
if (dbUser) {
const [isDbUserCreator, isUserCreator] = await creatorsInList([
dbUser,

View File

@ -65,7 +65,7 @@
</script>
<DetailPopover bind:this={popover} {title} align={PopoverAlignment.Right}>
<div slot="anchor" class:display-new={!authConfig}>
<div slot="anchor" class:display-new={!authConfig && oauth2Enabled}>
<ActionButton icon="LockClosed" quiet selected>
{#if !authConfig}
Authentication

@ -1 +1 @@
Subproject commit f709bb6a07483785c32ebb6f186709450d735ec3
Subproject commit 761ec71e1543ef04887d6515f99a2c2911999ebf

View File

@ -3,7 +3,7 @@ import { OpenAI } from "openai"
import { OpenAIStepInputs, OpenAIStepOutputs } from "@budibase/types"
import { env } from "@budibase/backend-core"
import * as automationUtils from "../automationUtils"
import * as pro from "@budibase/pro"
import { ai } from "@budibase/pro"
/**
* Maintains backward compatibility with automation steps created before the introduction
@ -41,18 +41,9 @@ export async function run({
try {
let response
const customConfigsEnabled = await pro.features.isAICustomConfigsEnabled()
const budibaseAIEnabled = await pro.features.isBudibaseAIEnabled()
let llmWrapper
if (budibaseAIEnabled || customConfigsEnabled) {
llmWrapper = await pro.ai.LargeLanguageModel.forCurrentTenant(
inputs.model
)
}
response = llmWrapper?.llm
? await llmWrapper.run(inputs.prompt)
const llm = await ai.getLLM(inputs.model)
response = llm
? (await llm.prompt(inputs.prompt)).message
: await legacyOpenAIPrompt(inputs)
return {

View File

@ -1,30 +1,11 @@
import { fixAutoColumnSubType, processAIColumns } from "../utils"
import { fixAutoColumnSubType } from "../utils"
import { AutoFieldDefaultNames } from "../../../constants"
import {
AIOperationEnum,
AutoFieldSubType,
FieldSchema,
FieldType,
INTERNAL_TABLE_SOURCE_ID,
RelationshipType,
Table,
TableSourceType,
} from "@budibase/types"
import { generator } from "@budibase/backend-core/tests"
const buildPromptMock = jest.fn()
jest.mock("@budibase/pro", () => ({
ai: {
LargeLanguageModel: {
forCurrentTenant: async () => ({
llm: {},
run: jest.fn(() => "response from LLM"),
buildPromptFromAIOperation: buildPromptMock,
}),
},
},
}))
describe("rowProcessor utility", () => {
describe("fixAutoColumnSubType", () => {
@ -79,59 +60,4 @@ describe("rowProcessor utility", () => {
expect(fixAutoColumnSubType(schema)).toEqual(schema)
})
})
describe("processAIColumns", () => {
it("ensures that bindable inputs are mapped and passed to to LLM prompt generation", async () => {
const table: Table = {
_id: generator.guid(),
name: "AITestTable",
type: "table",
sourceId: INTERNAL_TABLE_SOURCE_ID,
sourceType: TableSourceType.INTERNAL,
schema: {
product: {
type: FieldType.STRING,
name: "product",
constraints: {
presence: true,
type: "string",
},
},
aicol: {
type: FieldType.AI,
name: "aicol",
operation: AIOperationEnum.PROMPT,
prompt: "Translate '{{ product }}' into German",
},
},
}
const inputRows = [
{
product: "Car Battery",
},
]
const result = await processAIColumns(table, inputRows, {
contextRows: inputRows,
})
expect(buildPromptMock).toHaveBeenCalledWith({
row: {
product: "Car Battery",
},
schema: {
name: "aicol",
operation: "PROMPT",
prompt: "Translate 'Car Battery' into German",
type: "ai",
},
})
expect(result).toEqual([
{
aicol: "response from LLM",
product: "Car Battery",
},
])
})
})
})

View File

@ -15,7 +15,7 @@ import {
import { OperationFields } from "@budibase/shared-core"
import tracer from "dd-trace"
import { context } from "@budibase/backend-core"
import * as pro from "@budibase/pro"
import { ai } from "@budibase/pro"
import { coerce } from "./index"
interface FormulaOpts {
@ -126,10 +126,8 @@ export async function processAIColumns<T extends Row | Row[]>(
const numRows = Array.isArray(inputRows) ? inputRows.length : 1
span?.addTags({ table_id: table._id, numRows })
const rows = Array.isArray(inputRows) ? inputRows : [inputRows]
const llmWrapper = await pro.ai.LargeLanguageModel.forCurrentTenant(
"gpt-4o-mini"
)
if (rows && llmWrapper.llm) {
const llm = await ai.getLLM()
if (rows && llm) {
// Ensure we have snippet context
await context.ensureSnippetContext()
@ -153,17 +151,12 @@ export async function processAIColumns<T extends Row | Row[]>(
}
}
const prompt = llmWrapper.buildPromptFromAIOperation({
schema: aiSchema,
row,
})
return tracer.trace("processAIColumn", {}, async span => {
span?.addTags({ table_id: table._id, column })
const llmResponse = await llmWrapper.run(prompt)
const llmResponse = await llm.operation(aiSchema, row)
return {
...row,
[column]: llmResponse,
[column]: llmResponse.message,
}
})
})

View File

@ -6,6 +6,7 @@ export interface GetLicenseRequest {
// All fields should be optional to cater for
// historical versions of budibase
quotaUsage?: QuotaUsage
tenantId?: string
install: {
id: string
tenantId: string

View File

@ -111,18 +111,26 @@ export interface SCIMInnerConfig {
export interface SCIMConfig extends Config<SCIMInnerConfig> {}
export type AIProvider = "OpenAI" | "Anthropic" | "TogetherAI" | "Custom"
export type AIProvider =
| "OpenAI"
| "Anthropic"
| "AzureOpenAI"
| "TogetherAI"
| "Custom"
export interface ProviderConfig {
provider: AIProvider
isDefault: boolean
isBudibaseAI?: boolean
name: string
active: boolean
baseUrl?: string
apiKey?: string
defaultModel?: string
}
export interface AIInnerConfig {
[key: string]: {
provider: AIProvider
isDefault: boolean
name: string
active: boolean
baseUrl?: string
apiKey?: string
defaultModel?: string
}
[key: string]: ProviderConfig
}
export interface AIConfig extends Config<AIInnerConfig> {}

View File

@ -17,4 +17,5 @@ export interface License {
plan: PurchasedPlan
billing?: Billing
testClockId?: string
tenantId?: string
}