From ec7a8beba55593d0df79daf546f32edb338f83be Mon Sep 17 00:00:00 2001 From: gaga0714 <140368447+gaga0714@users.noreply.github.com> Date: Fri, 20 Mar 2026 11:25:45 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9Aworkflow=20and=20chat=20bugs=20(#65?= =?UTF-8?q?84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix:修复判断器 arrayAny 类型无判断条件可选 * fix:系统工具集不显示版本 * fix:修复视频音频自定义文件类型流程开始无文件链接变量 * fix:输入框会转义成markdown * docs:新增修复 --- .../workflow-and-chat-bug-fixes-analysis.md | 191 ++++++++++++++++++ .../docs/self-host/upgrading/4-14/4149.mdx | 4 + packages/global/core/workflow/utils.ts | 6 +- .../ChatBox/components/ChatItem.tsx | 6 +- .../chat/HelperBot/components/HumanItem.tsx | 2 +- .../Flow/nodes/NodeIfElse/ListItem.tsx | 1 + .../Flow/nodes/NodeSystemConfig.tsx | 7 +- .../Flow/nodes/render/NodeCard.tsx | 9 +- test/cases/global/core/workflow/utils.test.ts | 35 ++++ 9 files changed, 255 insertions(+), 6 deletions(-) create mode 100644 .claude/issue/workflow-and-chat-bug-fixes-analysis.md diff --git a/.claude/issue/workflow-and-chat-bug-fixes-analysis.md b/.claude/issue/workflow-and-chat-bug-fixes-analysis.md new file mode 100644 index 0000000000..465b434343 --- /dev/null +++ b/.claude/issue/workflow-and-chat-bug-fixes-analysis.md @@ -0,0 +1,191 @@ +# 工作流与聊天预览相关 Bug 修复分析文档 + +## Bug 1: 自定义文件扩展类型下,流程开始节点缺少“文件链接”变量 + +### 漏洞概述 + +系统配置开启文件上传后,如果只勾选“自定义文件扩展类型”,流程开始节点不会暴露“文件链接”变量,后续节点无法引用上传文件链接。 + +### 主要问题 + +开始节点和 workflow 输入 schema 的“可上传文件”判断逻辑仍停留在旧实现,只识别: + +- `canSelectFile` +- `canSelectImg` + +没有将以下配置纳入统一判断: + +- `canSelectVideo` +- `canSelectAudio` +- `canSelectCustomFileExtension` + +### 受影响文件 + +- `projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeSystemConfig.tsx` +- `packages/global/core/workflow/utils.ts` +- `test/cases/global/core/workflow/utils.test.ts` + +### 问题代码 + +```typescript +const canUploadFiles = e.canSelectFile || e.canSelectImg; +``` + +```typescript +...(chatConfig?.fileSelectConfig?.canSelectFile || chatConfig?.fileSelectConfig?.canSelectImg + ? [Input_Template_File_Link] + : []), +``` + +### 修改代码 + +```typescript +const canUploadFiles = + e.canSelectFile || + e.canSelectImg || + e.canSelectVideo || + e.canSelectAudio || + e.canSelectCustomFileExtension; +``` + +```typescript +...(chatConfig?.fileSelectConfig?.canSelectFile || +chatConfig?.fileSelectConfig?.canSelectImg || +chatConfig?.fileSelectConfig?.canSelectVideo || +chatConfig?.fileSelectConfig?.canSelectAudio || +chatConfig?.fileSelectConfig?.canSelectCustomFileExtension + ? [Input_Template_File_Link] + : []), +``` + +--- + +## Bug 2: 判断器选择 array 类型变量后,没有条件可选 + +### 漏洞概述 + +在判断器中选择 array 类型变量时,条件下拉为空,无法配置数组相关判断逻辑。 + +### 主要问题 + +前端条件映射遗漏了 `WorkflowIOValueTypeEnum.arrayAny`,导致泛数组类型没有进入 `arrayConditionList` 分支。 + +### 受影响文件 + +- `projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeIfElse/ListItem.tsx` + +### 问题代码 + +```typescript +if ( + valueType === WorkflowIOValueTypeEnum.chatHistory || + valueType === WorkflowIOValueTypeEnum.datasetQuote || + valueType === WorkflowIOValueTypeEnum.dynamic || + valueType === WorkflowIOValueTypeEnum.selectApp || + valueType === WorkflowIOValueTypeEnum.arrayBoolean || + valueType === WorkflowIOValueTypeEnum.arrayNumber || + valueType === WorkflowIOValueTypeEnum.arrayObject || + valueType === WorkflowIOValueTypeEnum.arrayString +) + return arrayConditionList; +``` + +### 修改代码 + +```typescript +if ( + valueType === WorkflowIOValueTypeEnum.chatHistory || + valueType === WorkflowIOValueTypeEnum.datasetQuote || + valueType === WorkflowIOValueTypeEnum.dynamic || + valueType === WorkflowIOValueTypeEnum.selectApp || + valueType === WorkflowIOValueTypeEnum.arrayAny || + valueType === WorkflowIOValueTypeEnum.arrayBoolean || + valueType === WorkflowIOValueTypeEnum.arrayNumber || + valueType === WorkflowIOValueTypeEnum.arrayObject || + valueType === WorkflowIOValueTypeEnum.arrayString +) + return arrayConditionList; +``` + +--- + +## Bug 3: 系统工具集不应显示版本信息 + +### 漏洞概述 + +系统工具集卡片错误显示“保持最新版本”等版本 UI,但系统工具集本身不应展示版本选择能力。 + +### 主要问题 + +节点卡片的版本显示条件排除了 `mcpToolSet`、`mcpTool`、`httpToolSet`,但漏掉了 `systemToolSet`,导致系统工具集也进入了版本渲染逻辑。 + +### 受影响文件 + +- `projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx` + +### 问题代码 + +```typescript +if ( + isAppNode && + (node.toolConfig?.mcpToolSet || node.toolConfig?.mcpTool || node?.toolConfig?.httpToolSet) +) + return false; +``` + +### 修改代码 + +```typescript +if ( + isAppNode && + ( + node.toolConfig?.mcpToolSet || + node.toolConfig?.mcpTool || + node?.toolConfig?.httpToolSet || + node?.toolConfig?.systemToolSet + ) +) + return false; +``` + +--- + +## Bug 4: 用户输入中的 `*` 被按 Markdown 强调语法渲染 + +### 漏洞概述 + +在运行预览和相关聊天场景中,用户输入 `1*1=1, 2*2=4` 后,消息会被按 Markdown 语法渲染,导致 `*` 不按原样显示。 + +### 主要问题 + +用户消息展示层直接复用了 Markdown 渲染组件: + +- 主聊天容器中的人类消息 +- HelperBot 中的人类消息 + +因此用户输入里的 `*`、`#`、`` ` `` 等字符会被 Markdown 解释。 + +### 受影响文件 + +- `projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ChatItem.tsx` +- `projects/app/src/components/core/chat/HelperBot/components/HumanItem.tsx` + +### 问题代码 + +```typescript +{text && } +``` + +### 修改代码 + +```typescript +{text && ( + + {text} + +)} +``` + +```typescript +{text && {text}} +``` diff --git a/document/content/docs/self-host/upgrading/4-14/4149.mdx b/document/content/docs/self-host/upgrading/4-14/4149.mdx index b688f1907a..c135720ece 100644 --- a/document/content/docs/self-host/upgrading/4-14/4149.mdx +++ b/document/content/docs/self-host/upgrading/4-14/4149.mdx @@ -50,3 +50,7 @@ AGENT_SANDBOX_SEALOS_TOKEN= 8. 修复工作流预览模式下,重新打开预览弹窗,会丢失表单输入内容。 9. 修复订阅套餐自定义字段未生效 10. login接口,存在异步 session 问题,会出现报错日志。 +12. 修复判断器 arrayAny 类型无判断条件可选 +13. 系统工具集不显示版本 +14. 修复视频音频自定义文件类型流程开始无文件链接变量 +15. 用户输入框消息不转义成 markdown 格式 diff --git a/packages/global/core/workflow/utils.ts b/packages/global/core/workflow/utils.ts index 119063b416..0fd5d86b31 100644 --- a/packages/global/core/workflow/utils.ts +++ b/packages/global/core/workflow/utils.ts @@ -284,7 +284,11 @@ export const appData2FlowNodeIO = ({ inputs: [ Input_Template_Stream_MODE, Input_Template_History, - ...(chatConfig?.fileSelectConfig?.canSelectFile || chatConfig?.fileSelectConfig?.canSelectImg + ...(chatConfig?.fileSelectConfig?.canSelectFile || + chatConfig?.fileSelectConfig?.canSelectImg || + chatConfig?.fileSelectConfig?.canSelectVideo || + chatConfig?.fileSelectConfig?.canSelectAudio || + chatConfig?.fileSelectConfig?.canSelectCustomFileExtension ? [Input_Template_File_Link] : []), Input_Template_UserChatInput, diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ChatItem.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ChatItem.tsx index 218c78d58d..ffb8937473 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ChatItem.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/components/ChatItem.tsx @@ -79,7 +79,11 @@ const HumanContentCard = React.memo( return ( {files.length > 0 && } - {text && } + {text && ( + + {text} + + )} ); }, diff --git a/projects/app/src/components/core/chat/HelperBot/components/HumanItem.tsx b/projects/app/src/components/core/chat/HelperBot/components/HumanItem.tsx index a447d6e9e7..8390507b3a 100644 --- a/projects/app/src/components/core/chat/HelperBot/components/HumanItem.tsx +++ b/projects/app/src/components/core/chat/HelperBot/components/HumanItem.tsx @@ -46,7 +46,7 @@ const HumanItem = ({ chat }: { chat: UserChatItemType }) => { > {files.length > 0 && } - {text && } + {text && {text}} diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeIfElse/ListItem.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeIfElse/ListItem.tsx index 71a2b30957..a0cd1101e7 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeIfElse/ListItem.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeIfElse/ListItem.tsx @@ -371,6 +371,7 @@ const ConditionSelect = ({ valueType === WorkflowIOValueTypeEnum.datasetQuote || valueType === WorkflowIOValueTypeEnum.dynamic || valueType === WorkflowIOValueTypeEnum.selectApp || + valueType === WorkflowIOValueTypeEnum.arrayAny || valueType === WorkflowIOValueTypeEnum.arrayBoolean || valueType === WorkflowIOValueTypeEnum.arrayNumber || valueType === WorkflowIOValueTypeEnum.arrayObject || diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeSystemConfig.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeSystemConfig.tsx index 3d4eade9a8..3ddf6e14e7 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeSystemConfig.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeSystemConfig.tsx @@ -266,7 +266,12 @@ function FileSelectConfig({ chatConfig: { fileSelectConfig }, setAppDetail }: Co })); // Dynamic add or delete userFilesInput - const canUploadFiles = e.canSelectFile || e.canSelectImg; + const canUploadFiles = + e.canSelectFile || + e.canSelectImg || + e.canSelectVideo || + e.canSelectAudio || + e.canSelectCustomFileExtension; const repeatKey = workflowStartNode.outputs.find((item) => item.key === userFilesInput.key); if (canUploadFiles) { !repeatKey && diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx index 23fc994225..f5251161de 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/NodeCard.tsx @@ -220,10 +220,15 @@ const NodeCard = (props: Props) => { const isAppNode = node && AppNodeFlowNodeTypeMap[node?.flowNodeType]; const isLoopNode = node?.flowNodeType === FlowNodeTypeEnum.loop; const showVersion = useMemo(() => { - // 1. MCP tool & HTTP tool set do not have version + // 1. MCP tool, HTTP tool set and system tool set do not have version if ( isAppNode && - (node.toolConfig?.mcpToolSet || node.toolConfig?.mcpTool || node?.toolConfig?.httpToolSet) + ( + node.toolConfig?.mcpToolSet || + node.toolConfig?.mcpTool || + node?.toolConfig?.httpToolSet || + node?.toolConfig?.systemToolSet + ) ) return false; // 2. Team app/System commercial plugin diff --git a/test/cases/global/core/workflow/utils.test.ts b/test/cases/global/core/workflow/utils.test.ts index fd60e0305c..67bb84f5a8 100644 --- a/test/cases/global/core/workflow/utils.test.ts +++ b/test/cases/global/core/workflow/utils.test.ts @@ -658,6 +658,41 @@ describe('appData2FlowNodeIO', () => { expect(fileLinkInput).toBeDefined(); }); + it.each([ + { + title: 'video selection', + fileSelectConfig: { + canSelectFile: false, + canSelectImg: false, + canSelectVideo: true + } + }, + { + title: 'audio selection', + fileSelectConfig: { + canSelectFile: false, + canSelectImg: false, + canSelectAudio: true + } + }, + { + title: 'custom file extension selection', + fileSelectConfig: { + canSelectFile: false, + canSelectImg: false, + canSelectCustomFileExtension: true + } + } + ])('should include file link input when fileSelectConfig allows $title', ({ fileSelectConfig }) => { + const result = appData2FlowNodeIO({ + chatConfig: { + fileSelectConfig + } + }); + const fileLinkInput = result.inputs.find((i) => i.key === NodeInputKeyEnum.fileUrlList); + expect(fileLinkInput).toBeDefined(); + }); + it('should not include file link input when fileSelectConfig disallows both', () => { const result = appData2FlowNodeIO({ chatConfig: {