diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 7b7900f3..baa57e4d 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -1440,6 +1440,7 @@ export const en = { confirmCopyDesc: 'Are you sure to copy 【{{app}}】 app?', noShareAuth: 'No permission to share apps', appCount: '{{count}} apps shared to this space', + resetFeaturesTip: 'Please reconfigure the [Conversation Features - File Upload] settings', }, userMemory: { userMemory: 'User Memory', diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 06a3bd74..16cfe4e0 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -818,6 +818,7 @@ export const zh = { confirmCopyDesc: '确定复制【{{app}}】应用?', noShareAuth: '无共享应用的权限', appCount: '{{count}}个应用共享到此空间', + resetFeaturesTip: '请重新配置【对话功能-文件上传】功能', }, table: { totalRecords: '共 {{total}} 条记录' diff --git a/web/src/views/ApplicationConfig/Agent.tsx b/web/src/views/ApplicationConfig/Agent.tsx index c0b47498..d9212bef 100644 --- a/web/src/views/ApplicationConfig/Agent.tsx +++ b/web/src/views/ApplicationConfig/Agent.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:29:21 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-20 11:36:49 + * @Last Modified time: 2026-03-24 11:02:34 */ import { useEffect, useRef, useState, forwardRef, useImperativeHandle } from 'react'; import { useTranslation } from 'react-i18next' @@ -132,9 +132,20 @@ const Agent = forwardRef { if (type === 'model') { - const { default_model_config_id, ...rest } = vo + const { default_model_config_id, capability, ...rest } = vo + if (default_model_config_id !== values.default_model_config_id) { + const fileUpload = { ...values.features?.file_upload } + Object.keys(fileUpload).forEach(key => { + if (key.includes('enabled')) { + (fileUpload as Record)[key] = false + } + }) + form.setFieldValue(['features', 'file_upload'], fileUpload) + message.warning(t('application.resetFeaturesTip')) + } form.setFieldsValue({ default_model_config_id, + capability, model_parameters: {...rest} }) if (default_model_config_id === values?.default_model_config_id) { @@ -348,13 +359,14 @@ const Agent = forwardRef - + + void; source?: Application['type']; + capability?: Capability[]; } const max_file_count = 1; /** @@ -31,6 +33,7 @@ const max_file_count = 1; const FeaturesConfigModal = forwardRef(({ refresh, source, + capability, }, ref) => { const { t } = useTranslation(); const [visible, setVisible] = useState(false); @@ -47,7 +50,6 @@ const FeaturesConfigModal = forwardRef { setVisible(true); - console.log('initValue', initValue) form.setFieldsValue(initValue) }; /** Copy application with new name */ @@ -64,6 +66,22 @@ const FeaturesConfigModal = forwardRef { + let options = [{ type: 'document', enabled: fu.document_enabled, maxSize: fu.document_max_size_mb }] + if (!capability) return options + + if (capability.includes('vision')) { + options.push({ type: 'image', enabled: fu.image_enabled, maxSize: fu.image_max_size_mb }) + } + if (capability.includes('audio')) { + options.push({ type: 'audio', enabled: fu.audio_enabled, maxSize: fu.audio_max_size_mb }) + } + if (capability.includes('video')) { + options.push({ type: 'video', enabled: fu.video_enabled, maxSize: fu.video_max_size_mb }) + } + return options.filter(item => item.enabled) + } + /** Expose methods to parent component */ useImperativeHandle(ref, () => ({ handleOpen, @@ -109,22 +127,19 @@ const FeaturesConfigModal = forwardRef {values?.file_upload?.enabled && (() => { const fu = values.file_upload - const types = [ - { type: 'image', enabled: fu.image_enabled, maxSize: fu.image_max_size_mb }, - { type: 'audio', enabled: fu.audio_enabled, maxSize: fu.audio_max_size_mb }, - { type: 'document', enabled: fu.document_enabled, maxSize: fu.document_max_size_mb }, - { type: 'video', enabled: fu.video_enabled, maxSize: fu.video_max_size_mb }, - ].filter(item => item.enabled) - return types.length > 0 ? <> + // 'vision' | 'audio' | 'video' + const filterTypes = formatFileTypeOptions(fu) + console.log('filterTypes', filterTypes) + return filterTypes.length > 0 ? <>
{t(`application.supportedTypes`)}
{t('application.singleMaxSize')}
- {types.map((item, index) => ( + {filterTypes.map((item, index) => (
{t(`application.${item.type}`)}
{item.maxSize} MB
@@ -148,6 +163,7 @@ const FeaturesConfigModal = forwardRef ); diff --git a/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx b/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx index f33b313b..b33f0478 100644 --- a/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx +++ b/web/src/views/ApplicationConfig/components/FeaturesConfig/FileUploadSettingModal.tsx @@ -2,15 +2,16 @@ * @Author: ZhaoYing * @Date: 2026-03-05 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-19 20:19:14 + * @Last Modified time: 2026-03-24 11:00:14 */ -import { forwardRef, useImperativeHandle, useState } from 'react'; +import { forwardRef, useImperativeHandle, useState, useMemo } from 'react'; import { Form, InputNumber, Flex, Switch, Row, Col, Radio } from 'antd'; import { useTranslation } from 'react-i18next'; import clsx from 'clsx'; import RbModal from '@/components/RbModal'; import type { FeaturesConfigForm } from '../../types' +import type { Capability } from '@/views/ModelManagement/types' type FileUpload = Omit @@ -21,51 +22,49 @@ interface FileUploadSettingModalRef { interface FileUploadSettingModalProps { onSave: (values: FileUpload) => void; + capability?: Capability[]; +} +const documentType = { + type: 'document', + icon:
, + formats: [ + "pdf", + "docx", + "doc", + "xlsx", + "xls", + "txt", + "csv", + "json", + "md", + ], +} +const imageType = { + type: 'image', + icon:
, + formats: [ + "png", + "jpg", + "jpeg" + ], +} +const audioType = { + type: 'audio', + icon:
, + formats: [ + "mp3", + "wav", + "m4a", + ], +} +const videoType = { + type: 'video', + icon:
, + formats: [ + "mp4", + "mov", + ], } - -const fileTypeOptions = [ - { - type: 'document', - icon:
, - formats: [ - "pdf", - "docx", - "doc", - "xlsx", - "xls", - "txt", - "csv", - "json", - "md", - ], - }, - { - type: 'image', - icon:
, - formats: [ - "png", - "jpg", - "jpeg" - ], - }, - { - type: 'audio', - icon:
, - formats: [ - "mp3", - "wav", - "m4a", - ], - }, - { - type: 'video', - icon:
, - formats: [ - "mp4", - "mov", - ], - }, -]; const defaultValues: FileUpload = { enabled: false, @@ -108,6 +107,7 @@ const defaultValues: FileUpload = { const FileUploadSettingModal = forwardRef(({ onSave, + capability, }, ref) => { const { t } = useTranslation(); const [visible, setVisible] = useState(false); @@ -148,6 +148,15 @@ const FileUploadSettingModal = forwardRef { + let options = [documentType] + if (!capability) return options + if (capability.includes('vision')) options = [...options, imageType] + if (capability.includes('audio')) options = [...options, audioType] + if (capability.includes('video')) options = [...options, videoType] + return options + }, [capability]) + return ( - {/*
{t('application.maxCount')}
*/} diff --git a/web/src/views/ApplicationConfig/components/FeaturesConfig/index.tsx b/web/src/views/ApplicationConfig/components/FeaturesConfig/index.tsx index bb61b7d5..e3847fd3 100644 --- a/web/src/views/ApplicationConfig/components/FeaturesConfig/index.tsx +++ b/web/src/views/ApplicationConfig/components/FeaturesConfig/index.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-03-13 17:20:21 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-18 15:38:59 + * @Last Modified time: 2026-03-24 11:00:25 */ import { type FC, useRef } from 'react'; import { useTranslation } from 'react-i18next'; @@ -11,6 +11,7 @@ import { Button } from 'antd'; import FeaturesConfigModal from './FeaturesConfigModal' import type { FeaturesConfigModalRef, FeaturesConfigForm } from '../../types' import type { Application } from '@/views/ApplicationManagement/types'; +import type { Capability } from '@/views/ModelManagement/types' /** Props for the FeaturesConfig component */ interface FeaturesConfigProps { @@ -19,12 +20,14 @@ interface FeaturesConfigProps { /** Callback to propagate updated config back to the parent */ refresh: (value: FeaturesConfigForm) => void; source?: Application['type']; + capability?: Capability[]; } const FeaturesConfig: FC = ({ value, refresh, - source + source, + capability }) => { const { t } = useTranslation(); // Ref used to imperatively open the config modal @@ -46,6 +49,7 @@ const FeaturesConfig: FC = ({ ref={funConfigModalRef} refresh={refresh} source={source} + capability={capability} /> ) diff --git a/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx b/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx index 19dca77b..52df6c0f 100644 --- a/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx +++ b/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx @@ -1,8 +1,8 @@ /* * @Author: ZhaoYing * @Date: 2026-02-03 16:28:07 - * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-02-03 16:28:07 + * @Last Modified by: ZhaoYing + * @Last Modified time: 2026-03-24 10:59:20 */ /** * Model Configuration Modal @@ -105,6 +105,8 @@ const ModelConfigModal = forwardRef( const handleChange = (_value: string, option: ModelListItem | ModelListItem[] | undefined) => { if (source === 'chat') { form.setFieldValue('label', (option as ModelListItem).name) + } else { + form.setFieldValue('capability', (option as ModelListItem).capability) } } @@ -137,16 +139,19 @@ const ModelConfigModal = forwardRef( rules={[{ required: source !== 'multi_agent', message: t('common.pleaseSelect') }]} hidden={source === 'multi_agent'} > - {source !== 'multi_agent' && + } + {source === 'model' &&