From e015455fb89c2443d3685168ff3752e52bea1382 Mon Sep 17 00:00:00 2001 From: zhaoying Date: Thu, 16 Apr 2026 19:00:58 +0800 Subject: [PATCH 1/3] feat(web): model support json --- web/src/components/ModelSelect/index.tsx | 24 +++++++------- web/src/i18n/en.ts | 3 ++ web/src/i18n/zh.ts | 3 ++ .../components/ModelConfigModal.tsx | 22 +++++++------ web/src/views/ApplicationConfig/types.ts | 15 +++++---- .../components/CustomModelModal.tsx | 17 +++++++--- web/src/views/ModelManagement/types.ts | 5 +-- .../Properties/ModelConfig/index.tsx | 32 ++++++++++++++++--- web/src/views/Workflow/constant.ts | 6 +++- 9 files changed, 88 insertions(+), 39 deletions(-) diff --git a/web/src/components/ModelSelect/index.tsx b/web/src/components/ModelSelect/index.tsx index 8f9152fb..0b4f671e 100644 --- a/web/src/components/ModelSelect/index.tsx +++ b/web/src/components/ModelSelect/index.tsx @@ -2,9 +2,9 @@ * @Author: ZhaoYing * @Date: 2026-03-07 16:49:59 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-25 11:21:59 + * @Last Modified time: 2026-04-16 17:46:02 */ -import { useEffect, useState, type FC } from 'react'; +import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'; import { Select, Flex, Space } from 'antd'; import type { SelectProps } from 'antd/es/select'; import { useTranslation } from 'react-i18next'; @@ -14,6 +14,10 @@ import type { Query, Model } from '@/views/ModelManagement/types'; import { getListLogoUrl } from '@/views/ModelManagement/utils'; import Tag from '@/components/Tag'; +export interface ModelSelectRef { + options: Model[]; +} + /** Extends AntD SelectProps; omits filterOption since it's handled internally */ interface ModelSelectProps extends SelectProps { /** Extra query params passed to getModelList */ @@ -24,17 +28,15 @@ interface ModelSelectProps extends SelectProps { initialData?: Model[]; } -const ModelSelect: FC = ({ - params, - placeholder, - fontClassName, - isAutoFetch = true, - initialData = [], - ...props -}) => { +const ModelSelect = forwardRef(( + { params, placeholder, fontClassName, isAutoFetch = true, initialData = [], ...props }, + ref +) => { const { t } = useTranslation(); const [options, setOptions] = useState([]); + useImperativeHandle(ref, () => ({ options }), [options]); + // Fetch active models whenever params change; stringify for stable deep comparison useEffect(() => { if (!isAutoFetch) return @@ -89,6 +91,6 @@ const ModelSelect: FC = ({ {...props} /> ); -}; +}); export default ModelSelect; diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 394606a3..d65e4436 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -629,6 +629,7 @@ export const en = { video: 'Video', thinking: 'Deep Thinking', is_thinking: 'Deep Thinking Support', + json_output: 'Support JSON formatted output', }, knowledgeBase: { home: 'Home', @@ -1524,6 +1525,7 @@ export const en = { }`, uploadCover: 'Import and Overwrite', refresh: 'Refresh Current Page', + json_output: 'Support JSON formatted output', }, userMemory: { userMemory: 'User Memory', @@ -2287,6 +2289,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re messagesPlaceholder: 'Write prompts here, type "{" to insert variables, type "insert" to insert', vision: 'Vision', parameterSettings: 'Parameter Settings', + json_output: 'Support JSON formatted output', }, start: { variables: 'Input Fields', diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 98676ef4..921b3554 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -859,6 +859,7 @@ export const zh = { }`, uploadCover: '导入并覆盖', refresh: '刷新当前页', + json_output: '支持JSON格式化输出', }, table: { totalRecords: '共 {{total}} 条记录' @@ -1307,6 +1308,7 @@ export const zh = { video: '视频', thinking: '深度思考', is_thinking: '支持深度思考', + json_output: '支持JSON格式化输出', }, timezones: { 'Asia/Shanghai': '中国标准时间 (UTC+8)', @@ -2248,6 +2250,7 @@ export const zh = { messagesPlaceholder: '在此处编写提示,输入“{”插入变量,输入“insert”插入', vision: '视觉', parameterSettings: '参数设置', + json_output: '支持JSON格式化输出', }, start: { variables: '输入字段', diff --git a/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx b/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx index 8e3e3257..30af7a8c 100644 --- a/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx +++ b/web/src/views/ApplicationConfig/components/ModelConfigModal.tsx @@ -2,7 +2,7 @@ * @Author: ZhaoYing * @Date: 2026-02-03 16:28:07 * @Last Modified by: ZhaoYing - * @Last Modified time: 2026-03-31 16:56:57 + * @Last Modified time: 2026-04-16 18:51:01 */ /** * Model Configuration Modal @@ -102,14 +102,15 @@ const ModelConfigModal = forwardRef( } /** Handle model selection change */ const handleChange: SelectProps['onChange'] = (_value, option) => { - if (source === 'chat') { - form.setFieldValue('label', (option as Model).name) - } - - form.setFieldsValue({ + const newValues: ModelConfig = { capability: (option as Model).capability, deep_thinking: false, - }) + json_output: false + } + if (source === 'chat') { + newValues.label = (option as Model).name + } + form.setFieldsValue(newValues) } /** Expose methods to parent component */ @@ -119,12 +120,10 @@ const ModelConfigModal = forwardRef( })); useEffect(() => { - const { deep_thinking: _, ...rest } = data?.model_parameters || {} + const { deep_thinking: _, json_output: __, ...rest } = data?.model_parameters || {} form.setFieldsValue(rest) }, [values?.default_model_config_id]) - - console.log('handleChange values', values) return ( ( + {source === 'chat' &&