diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 95be5849..2e2a24c8 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -1553,6 +1553,7 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re 'parameter-extractor': 'Parameter Extraction', flowControl: 'Flow Control', 'if-else': 'Conditional Branch', + 'question-classifier': 'Question Classifier', iteration: 'Iteration', loop: 'Loop', parallel: 'Parallel Execution', @@ -1664,7 +1665,18 @@ Memory Bear: After the rebellion, regional warlordism intensified for several re "gt": '>', "ge": '>=', else_desc: 'Used to define the logic that should be executed when the if condition is not met.' - } + }, + 'question-classifier': { + model_id: 'Model', + input_variable: 'Input Variable', + categories: 'Categories', + user_supplement_prompt: 'Instruction', + class_name: 'Category', + addClassName: 'Add Category' + }, + name: 'Key', + type: 'Type', + value: 'Value', }, clear: 'Clear', diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index e00fe134..f52d7328 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -1654,6 +1654,7 @@ export const zh = { 'parameter-extractor': '参数提取', flowControl: '流程控制', 'if-else': '条件分支', + 'question-classifier': '问题分类器', iteration: '迭代 (Iteration)', loop: '循环 (Loop)', parallel: '并行执行', @@ -1793,6 +1794,14 @@ export const zh = { template: '代码', mapping: '输入变量' }, + 'question-classifier': { + model_id: '模型', + input_variable: '输入变量', + categories: '分类', + user_supplement_prompt: '指令', + class_name: '分类', + addClassName: '添加分类' + }, name: '键', type: '类型', value: '值', diff --git a/web/src/views/Workflow/components/Properties/CategoryList/index.tsx b/web/src/views/Workflow/components/Properties/CategoryList/index.tsx new file mode 100644 index 00000000..db1cd658 --- /dev/null +++ b/web/src/views/Workflow/components/Properties/CategoryList/index.tsx @@ -0,0 +1,64 @@ +import { type FC } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Input, Button, Form, Space } from 'antd'; +import { PlusOutlined, CopyOutlined, DeleteOutlined, ExpandOutlined } from '@ant-design/icons'; + +interface CategoryListProps { + parentName: string; +} + +const CategoryList: FC = ({ parentName }) => { + const { t } = useTranslation(); + const form = Form.useFormInstance(); + const formValues = Form.useWatch([parentName], form); + + console.log('formValues', formValues) + return ( + + {(fields, { add, remove }) => ( + + {fields.map(({ key, name, ...restField }, index) => { + const currentItem = formValues?.[key] || {}; + const contentLength = (currentItem.class_name || '').length; + + return ( +
+
+
{t('workflow.config.question-classifier.class_name')} {index + 1}
+
+ {contentLength} +
+
+ + + +
+ )})} + + +
+ )} +
+ ); +}; + +export default CategoryList; \ No newline at end of file diff --git a/web/src/views/Workflow/components/Properties/index.tsx b/web/src/views/Workflow/components/Properties/index.tsx index 2b08a04c..f32b3bf2 100644 --- a/web/src/views/Workflow/components/Properties/index.tsx +++ b/web/src/views/Workflow/components/Properties/index.tsx @@ -17,6 +17,7 @@ import GroupVariableList from './GroupVariableList' import CaseList from './CaseList' import HttpRequest from './HttpRequest'; import MappingList from './MappingList' +import CategoryList from './CategoryList' interface PropertiesProps { selectedNode?: Node | null; @@ -472,10 +473,15 @@ const Properties: FC = ({ : config.type === 'variableList' ? ({ + ...vo, + value: `{{${vo.value}}}` + }))} /> : config.type === 'switch' ? + : config.type === 'categoryList' + ? : null } diff --git a/web/src/views/Workflow/constant.ts b/web/src/views/Workflow/constant.ts index af444d70..d27b9cc6 100644 --- a/web/src/views/Workflow/constant.ts +++ b/web/src/views/Workflow/constant.ts @@ -37,6 +37,7 @@ import sensitiveDetectionIcon from '@/assets/images/workflow/sensitive_detection import outputAuditIcon from '@/assets/images/workflow/output_audit.png'; import selfOptimizationIcon from '@/assets/images/workflow/self_optimization.png'; import processEvolutionIcon from '@/assets/images/workflow/process_evolution.png'; +import questionClassifierIcon from '@/assets/images/workflow/question-classifier.png' import { getModelListUrl } from '@/api/models' import type { NodeLibrary } from './types' @@ -201,6 +202,28 @@ export const nodeLibrary: NodeLibrary[] = [ } } }, + { + type: "question-classifier", icon: questionClassifierIcon, + config: { + model_id: { + type: 'customSelect', + url: getModelListUrl, + params: { type: 'llm,chat' }, // llm/chat + valueKey: 'id', + labelKey: 'name', + }, + input_variable: { + type: 'variableList', + }, + categories: { + type: 'categoryList' + }, + user_supplement_prompt: { + type: 'messageEditor', + isArray: false + } + } + }, // { type: "iteration", icon: iterationIcon }, // { type: "loop", icon: loopIcon }, // { type: "parallel", icon: parallelIcon }, diff --git a/web/src/views/Workflow/hooks/useWorkflowGraph.ts b/web/src/views/Workflow/hooks/useWorkflowGraph.ts index c7480f51..0d524c5b 100644 --- a/web/src/views/Workflow/hooks/useWorkflowGraph.ts +++ b/web/src/views/Workflow/hooks/useWorkflowGraph.ts @@ -771,7 +771,7 @@ export const useWorkflowGraph = ({ itemConfig = { ...itemConfig, ...data.config[key].defaultValue, - knowledge_bases: knowledge_bases.map((vo: any) => ({ kb_id: vo.id, ...vo.config })) + knowledge_bases: knowledge_bases?.map((vo: any) => ({ kb_id: vo.id, ...vo.config })) } } })