Add the beta function switch Settings

pull/20352/head
dongfubao 12 months ago
parent 34ae11cb05
commit 22ee1a6e04

@ -48,6 +48,7 @@ tenant_fields = {
"in_trial": fields.Boolean, "in_trial": fields.Boolean,
"trial_end_reason": fields.String, "trial_end_reason": fields.String,
"custom_config": fields.Raw(attribute="custom_config"), "custom_config": fields.Raw(attribute="custom_config"),
"beta_config": fields.Raw(attribute="beta_config"),
} }
tenants_fields = { tenants_fields = {
@ -177,6 +178,31 @@ class CustomConfigWorkspaceApi(Resource):
return {"result": "success", "tenant": marshal(WorkspaceService.get_tenant_info(tenant), tenant_fields)} return {"result": "success", "tenant": marshal(WorkspaceService.get_tenant_info(tenant), tenant_fields)}
class BetaConfigWorkspaceApi(Resource):
@setup_required
@login_required
@account_initialization_required
def post(self):
parser = reqparse.RequestParser()
parser.add_argument("beta_config", type=dict, location="json")
args = parser.parse_args()
tenant = db.get_or_404(Tenant, current_user.current_tenant_id)
db_config = tenant.beta_config_dict
param_config = args["beta_config"] or {}
if not db_config:
tenant.beta_config_dict = param_config
else:
merged_config = {**db_config, **param_config}
tenant.beta_config_dict = merged_config
db.session.commit()
return {"result": "success", "tenant": marshal(WorkspaceService.get_tenant_info(tenant), tenant_fields)}
class WebappLogoWorkspaceApi(Resource): class WebappLogoWorkspaceApi(Resource):
@setup_required @setup_required
@login_required @login_required
@ -239,5 +265,6 @@ api.add_resource(TenantApi, "/workspaces/current", endpoint="workspaces_current"
api.add_resource(TenantApi, "/info", endpoint="info") # Deprecated api.add_resource(TenantApi, "/info", endpoint="info") # Deprecated
api.add_resource(SwitchWorkspaceApi, "/workspaces/switch") # POST for switching tenant api.add_resource(SwitchWorkspaceApi, "/workspaces/switch") # POST for switching tenant
api.add_resource(CustomConfigWorkspaceApi, "/workspaces/custom-config") api.add_resource(CustomConfigWorkspaceApi, "/workspaces/custom-config")
api.add_resource(BetaConfigWorkspaceApi, "/workspaces/beta-config")
api.add_resource(WebappLogoWorkspaceApi, "/workspaces/custom-config/webapp-logo/upload") api.add_resource(WebappLogoWorkspaceApi, "/workspaces/custom-config/webapp-logo/upload")
api.add_resource(WorkspaceInfoApi, "/workspaces/info") # POST for changing workspace info api.add_resource(WorkspaceInfoApi, "/workspaces/info") # POST for changing workspace info

@ -199,6 +199,7 @@ class Tenant(Base):
plan = db.Column(db.String(255), nullable=False, server_default=db.text("'basic'::character varying")) plan = db.Column(db.String(255), nullable=False, server_default=db.text("'basic'::character varying"))
status = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying")) status = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying"))
custom_config = db.Column(db.Text) custom_config = db.Column(db.Text)
beta_config = db.Column(db.Text)
created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp())
@ -217,6 +218,14 @@ class Tenant(Base):
def custom_config_dict(self, value: dict): def custom_config_dict(self, value: dict):
self.custom_config = json.dumps(value) self.custom_config = json.dumps(value)
@property
def beta_config_dict(self) -> dict:
return json.loads(self.beta_config) if self.beta_config else {}
@beta_config_dict.setter
def beta_config_dict(self, value: dict):
self.beta_config = json.dumps(value)
class TenantAccountJoin(Base): class TenantAccountJoin(Base):
__tablename__ = "tenant_account_joins" __tablename__ = "tenant_account_joins"

@ -20,6 +20,7 @@ class WorkspaceService:
"created_at": tenant.created_at, "created_at": tenant.created_at,
"trial_end_reason": None, "trial_end_reason": None,
"role": "normal", "role": "normal",
"beta_config": tenant.beta_config_dict,
} }
# Get role of user # Get role of user

@ -0,0 +1,45 @@
import { useTranslation } from 'react-i18next'
import Switch from '@/app/components/base/switch'
import {
updateCurrentWorkspace,
} from '@/service/common'
import { useAppContext } from '@/context/app-context'
const BetaPage = () => {
const { t } = useTranslation()
const {
currentWorkspace,
mutateCurrentWorkspace,
} = useAppContext()
const workflowVarCheck = currentWorkspace.beta_config?.workflow_var_check
const handleSwitch = async (checked: boolean) => {
await updateCurrentWorkspace({
url: '/workspaces/beta-config',
body: {
beta_config: {
workflow_var_check: checked,
},
},
})
mutateCurrentWorkspace()
}
return (
<div className='py-4'>
<div className='system-md-medium mb-2 flex items-center justify-between rounded-xl bg-background-section-burn p-4 text-text-primary'>
<div>
<div className='system-md-medium text-text-primary'>{t('common.beta.workflowVarCheck')}</div>
<div className='system-xs-regular text-text-tertiary'>{t('common.beta.workflowVarCheckTip')}</div>
</div>
<Switch
size='l'
defaultValue={workflowVarCheck}
onChange={handleSwitch}
/>
</div>
</div>
)
}
export default BetaPage

@ -15,6 +15,8 @@ import {
RiMoneyDollarCircleLine, RiMoneyDollarCircleLine,
RiPuzzle2Fill, RiPuzzle2Fill,
RiPuzzle2Line, RiPuzzle2Line,
RiTestTubeFill,
RiTestTubeLine,
RiTranslate2, RiTranslate2,
} from '@remixicon/react' } from '@remixicon/react'
import Button from '../../base/button' import Button from '../../base/button'
@ -31,6 +33,7 @@ import { useProviderContext } from '@/context/provider-context'
import { useAppContext } from '@/context/app-context' import { useAppContext } from '@/context/app-context'
import MenuDialog from '@/app/components/header/account-setting/menu-dialog' import MenuDialog from '@/app/components/header/account-setting/menu-dialog'
import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import BatePage from './beta-page'
const iconClassName = ` const iconClassName = `
w-5 h-5 mr-2 w-5 h-5 mr-2
@ -56,8 +59,7 @@ export default function AccountSetting({
const [activeMenu, setActiveMenu] = useState(activeTab) const [activeMenu, setActiveMenu] = useState(activeTab)
const { t } = useTranslation() const { t } = useTranslation()
const { enableBilling, enableReplaceWebAppLogo } = useProviderContext() const { enableBilling, enableReplaceWebAppLogo } = useProviderContext()
const { isCurrentWorkspaceDatasetOperator } = useAppContext() const { isCurrentWorkspaceDatasetOperator, currentWorkspace } = useAppContext()
const workplaceGroupItems = (() => { const workplaceGroupItems = (() => {
if (isCurrentWorkspaceDatasetOperator) if (isCurrentWorkspaceDatasetOperator)
return [] return []
@ -100,6 +102,12 @@ export default function AccountSetting({
icon: <RiColorFilterLine className={iconClassName} />, icon: <RiColorFilterLine className={iconClassName} />,
activeIcon: <RiColorFilterFill className={iconClassName} />, activeIcon: <RiColorFilterFill className={iconClassName} />,
}, },
{
key: currentWorkspace.role === 'owner' ? 'beta' : false,
name: t('common.beta.beta'),
icon: <RiTestTubeLine className={iconClassName} />,
activeIcon: <RiTestTubeFill className={iconClassName} />,
},
].filter(item => !!item.key) as GroupItem[] ].filter(item => !!item.key) as GroupItem[]
})() })()
@ -220,6 +228,7 @@ export default function AccountSetting({
{activeMenu === 'api-based-extension' && <ApiBasedExtensionPage />} {activeMenu === 'api-based-extension' && <ApiBasedExtensionPage />}
{activeMenu === 'custom' && <CustomPage />} {activeMenu === 'custom' && <CustomPage />}
{activeMenu === 'language' && <LanguagePage />} {activeMenu === 'language' && <LanguagePage />}
{activeMenu === 'beta' && <BatePage />}
</div> </div>
</div> </div>
</div> </div>

@ -34,6 +34,7 @@ import { useDatasetsDetailStore } from '../datasets-detail-store/store'
import type { KnowledgeRetrievalNodeType } from '../nodes/knowledge-retrieval/types' import type { KnowledgeRetrievalNodeType } from '../nodes/knowledge-retrieval/types'
import type { DataSet } from '@/models/datasets' import type { DataSet } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets' import { fetchDatasets } from '@/service/datasets'
import { useAppContext } from '@/context/app-context'
export const useChecklist = (nodes: Node[], edges: Edge[]) => { export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const { t } = useTranslation() const { t } = useTranslation()
@ -45,6 +46,9 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const workflowTools = useStore(s => s.workflowTools) const workflowTools = useStore(s => s.workflowTools)
const { data: strategyProviders } = useStrategyProviders() const { data: strategyProviders } = useStrategyProviders()
const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail) const datasetsDetail = useDatasetsDetailStore(s => s.datasetsDetail)
const {
currentWorkspace,
} = useAppContext()
const chatVarList = useStore(s => s.conversationVariables) const chatVarList = useStore(s => s.conversationVariables)
const environmentVariables = useStore(s => s.environmentVariables) const environmentVariables = useStore(s => s.environmentVariables)
@ -72,6 +76,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
const allVariablesMap = transformStartNodeVariables(chatVarList, environmentVariables) const allVariablesMap = transformStartNodeVariables(chatVarList, environmentVariables)
const errMessageMap = new Map() const errMessageMap = new Map()
const workflowVarCheck = currentWorkspace.beta_config?.workflow_var_check
for (let i = 0; i < nodes.length; i++) { for (let i = 0; i < nodes.length; i++) {
const node = nodes[i] const node = nodes[i]
@ -120,7 +125,7 @@ export const useChecklist = (nodes: Node[], edges: Edge[]) => {
varErrorMessage: [], varErrorMessage: [],
}) })
} }
if (nodesExtraData[node.data.type as BlockEnum].checkVarValid) { if (workflowVarCheck && nodesExtraData[node.data.type as BlockEnum].checkVarValid) {
const { errorMessage: varErrorMessages } = nodesExtraData[node.data.type as BlockEnum].checkVarValid(node.data, { ...allVariablesMap, ...node._parentOutputVarMap }, t) const { errorMessage: varErrorMessages } = nodesExtraData[node.data.type as BlockEnum].checkVarValid(node.data, { ...allVariablesMap, ...node._parentOutputVarMap }, t)
if (varErrorMessages?.length) { if (varErrorMessages?.length) {

@ -7,6 +7,7 @@ import {
ALL_CHAT_AVAILABLE_BLOCKS, ALL_CHAT_AVAILABLE_BLOCKS,
ALL_COMPLETION_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS,
} from '@/app/components/workflow/blocks' } from '@/app/components/workflow/blocks'
import { transformToBodyPayload } from './utils'
const nodeDefault: NodeDefault<HttpNodeType> = { const nodeDefault: NodeDefault<HttpNodeType> = {
defaultValue: { defaultValue: {
@ -78,7 +79,9 @@ const nodeDefault: NodeDefault<HttpNodeType> = {
const body_warnings: string[] = [] const body_warnings: string[] = []
if ([BodyType.binary].includes(payload.body.type)) { if ([BodyType.binary].includes(payload.body.type)) {
const body_data = payload.body.data as BodyPayload let body_data = payload.body.data
if (typeof body_data === 'string')
body_data = transformToBodyPayload(body_data, false)
body_data.forEach((item) => { body_data.forEach((item) => {
const key_warnings = getNotExistVariablesByText(item.key || '', varMap) const key_warnings = getNotExistVariablesByText(item.key || '', varMap)
if (key_warnings.length) if (key_warnings.length)
@ -89,7 +92,9 @@ const nodeDefault: NodeDefault<HttpNodeType> = {
}) })
} }
else { else {
const body_data = payload.body.data as BodyPayload let body_data = payload.body.data
if (typeof body_data === 'string')
body_data = transformToBodyPayload(body_data, [BodyType.formData, BodyType.xWwwFormUrlencoded].includes(payload.body.type))
body_data.forEach((item) => { body_data.forEach((item) => {
const key_warnings = getNotExistVariablesByText(item.key || '', varMap) const key_warnings = getNotExistVariablesByText(item.key || '', varMap)
if (key_warnings.length) if (key_warnings.length)

@ -273,6 +273,11 @@ const translation = {
setBuilder: 'Set as builder (设置为构建器)', setBuilder: 'Set as builder (设置为构建器)',
builder: '构建器', builder: '构建器',
}, },
beta: {
beta: 'Beta 功能',
workflowVarCheck: '严格模式-变量可用性检查',
workflowVarCheckTip: '启用后cahflow/workflow 将会检查节点中变量是否可用。',
},
integrations: { integrations: {
connected: '登录方式', connected: '登录方式',
google: 'Google', google: 'Google',

@ -134,6 +134,9 @@ export type ICurrentWorkspace = Omit<IWorkspace, 'current'> & {
custom_config?: { custom_config?: {
remove_webapp_brand?: boolean remove_webapp_brand?: boolean
replace_webapp_logo?: string replace_webapp_logo?: string
},
beta_config?: {
workflow_var_check?: boolean
} }
} }

Loading…
Cancel
Save