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: {