From ca0d87d9b90ff2dd9b57d2731e81743b520cc43d Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Sun, 2 Aug 2026 00:00:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20skill=20=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E4=B8=8E=E6=8F=90=E5=8F=96=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=20Windows=20=E5=8F=8D=E6=96=9C=E6=9D=A0=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端 /api/skills 返回 Path.resolve() 字符串(Windows 为反斜杠),而 USER_SKILL_LINK_RE(ChatArea 气泡渲染)与 SKILL_MARKDOWN_LINK_RE(shared.ts 发送兜底提取)硬编码正斜杠 /.astrion/skills/,导致 / 菜单插入的 skill 引用在消息发出后 fallback 为原始文本。两处正则路径分隔符改 [\\/],对存量反斜杠消息同样生效(渲染侧修复)。@ 文件引用不受影响(路径段 [^)\\n]+ 本就能匹配反斜杠,已 Playwright 实测确认)。 --- static/src/app/methods/message/shared.ts | 3 ++- static/src/components/chat/ChatArea.vue | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/static/src/app/methods/message/shared.ts b/static/src/app/methods/message/shared.ts index d74a2416..da3044a2 100644 --- a/static/src/app/methods/message/shared.ts +++ b/static/src/app/methods/message/shared.ts @@ -3,7 +3,8 @@ import { debugLog } from '../common'; import { useModelStore } from '../../../stores/model'; -export const SKILL_MARKDOWN_LINK_RE = /\[\$([^\]\n]+)\]\(([^)\n]*\/\.astrion\/skills\/[^)\n]+\/SKILL\.md)\)/g; +// 兼容 Windows 反斜杠路径:skills 目录与 SKILL.md 前的分隔符同时接受 / 和 \ +export const SKILL_MARKDOWN_LINK_RE = /\[\$([^\]\n]+)\]\(([^)\n]*[\\/]\.astrion[\\/]skills[\\/][^)\n]+[\\/]SKILL\.md)\)/g; export function extractSkillRefsFromMessage(message = '') { const refs = []; diff --git a/static/src/components/chat/ChatArea.vue b/static/src/components/chat/ChatArea.vue index f62554b9..2e27e892 100644 --- a/static/src/components/chat/ChatArea.vue +++ b/static/src/components/chat/ChatArea.vue @@ -1053,7 +1053,8 @@ const escapeUserHtml = (value: string): string => .replace(/"/g, '"') .replace(/'/g, '''); -const USER_SKILL_LINK_RE = /\[\$([^\]\n]+)\]\(([^)\n]*\/\.astrion\/skills\/[^)\n]+\/SKILL\.md)\)/g; +// 兼容 Windows 反斜杠路径:skills 目录与 SKILL.md 前的分隔符同时接受 / 和 \ +const USER_SKILL_LINK_RE = /\[\$([^\]\n]+)\]\(([^)\n]*[\\/]\.astrion[\\/]skills[\\/][^)\n]+[\\/]SKILL\.md)\)/g; const USER_FILE_LINK_RE = /\[([^\]\n]+)\]\(file:\/\/([^)\n]+)\)/g; const SUB_AGENT_DONE_LABEL_RE = /^子智能体\d+\s*任务完成$/; const SUB_AGENT_DONE_PREFIX_RE = /^(?:✅\s*)?子智能体\s*#?\s*(\d+)\s*任务摘要[::]/;