From f87d5678f3bd000e1e4d16e14f52cfe1fbfb1eaa Mon Sep 17 00:00:00 2001 From: LofiSu Date: Tue, 10 Feb 2026 12:15:37 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=94=B9=E8=BF=9B=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=A1=B5=E9=9D=A2UI=E5=92=8C=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96=E6=94=AF=E6=8C=81=20/=20Improve=20settings=20pages=20?= =?UTF-8?q?UI=20and=20i18n=20support?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 rehype-raw 依赖以支持在 markdown 中渲染 HTML Add rehype-raw dependency to support HTML rendering in markdown - 重构 memory-settings-page,提取 formatMemorySection 函数减少重复代码 Refactor memory-settings-page by extracting formatMemorySection function to reduce code duplication - 改进空状态显示,使用 HTML span 标签替代 markdown 斜体,提供更好的样式控制 Improve empty state display by using HTML span tags instead of markdown italics for better style control - 为 skill-settings-page 添加完整的国际化支持,替换硬编码的英文文本 Add complete i18n support for skill-settings-page, replacing hardcoded English text - 更新国际化文件,添加技能设置页面的空状态文本(中英文) Update i18n files with empty state text for skill settings page (both Chinese and English) - 在 streamdown 插件配置中添加 rehypeRaw 以支持 HTML 渲染 Add rehypeRaw to streamdown plugins configuration to support HTML rendering Co-authored-by: Cursor --- frontend/package.json | 1 + frontend/pnpm-lock.yaml | 3 + .../settings/memory-settings-page.tsx | 102 ++++++++++-------- .../settings/skill-settings-page.tsx | 8 +- frontend/src/core/i18n/locales/en-US.ts | 6 +- frontend/src/core/i18n/locales/types.ts | 3 + frontend/src/core/i18n/locales/zh-CN.ts | 6 +- frontend/src/core/streamdown/plugins.ts | 2 + 8 files changed, 82 insertions(+), 49 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index e936c34..46ca46a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -73,6 +73,7 @@ "react-dom": "^19.0.0", "react-resizable-panels": "^4.4.1", "rehype-katex": "^7.0.1", + "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", "shiki": "3.15.0", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 9fc1f0c..cb04b35 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -182,6 +182,9 @@ importers: rehype-katex: specifier: ^7.0.1 version: 7.0.1 + rehype-raw: + specifier: ^7.0.0 + version: 7.0.0 remark-gfm: specifier: ^4.0.1 version: 4.0.1 diff --git a/frontend/src/components/workspace/settings/memory-settings-page.tsx b/frontend/src/components/workspace/settings/memory-settings-page.tsx index a5225e6..831aa38 100644 --- a/frontend/src/components/workspace/settings/memory-settings-page.tsx +++ b/frontend/src/components/workspace/settings/memory-settings-page.tsx @@ -31,6 +31,26 @@ function confidenceToLevelKey(confidence: unknown): { return { key: "normal", value }; } +function formatMemorySection( + title: string, + summary: string, + updatedAt: string | undefined, + t: ReturnType["t"], +): string { + const content = + summary.trim() || + `${t.settings.memory.markdown.empty}`; + return [ + `### ${title}`, + content, + "", + updatedAt && + `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(updatedAt)}\``, + ] + .filter(Boolean) + .join("\n"); +} + function memoryToMarkdown( memory: UserMemory, t: ReturnType["t"], @@ -44,65 +64,61 @@ function memoryToMarkdown( parts.push(`\n## ${t.settings.memory.markdown.userContext}`); parts.push( - [ - `### ${t.settings.memory.markdown.work}`, - memory.user.workContext.summary || "-", - "", - memory.user.workContext.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.user.workContext.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.work, + memory.user.workContext.summary, + memory.user.workContext.updatedAt, + t, + ), ); parts.push( - [ - `### ${t.settings.memory.markdown.personal}`, - memory.user.personalContext.summary || "-", - "", - memory.user.personalContext.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.user.personalContext.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.personal, + memory.user.personalContext.summary, + memory.user.personalContext.updatedAt, + t, + ), ); parts.push( - [ - `### ${t.settings.memory.markdown.topOfMind}`, - memory.user.topOfMind.summary || "-", - "", - memory.user.topOfMind.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.user.topOfMind.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.topOfMind, + memory.user.topOfMind.summary, + memory.user.topOfMind.updatedAt, + t, + ), ); parts.push(`\n## ${t.settings.memory.markdown.historyBackground}`); parts.push( - [ - `### ${t.settings.memory.markdown.recentMonths}`, - memory.history.recentMonths.summary || "-", - "", - memory.history.recentMonths.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.history.recentMonths.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.recentMonths, + memory.history.recentMonths.summary, + memory.history.recentMonths.updatedAt, + t, + ), ); parts.push( - [ - `### ${t.settings.memory.markdown.earlierContext}`, - memory.history.earlierContext.summary || "-", - "", - memory.history.earlierContext.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.history.earlierContext.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.earlierContext, + memory.history.earlierContext.summary, + memory.history.earlierContext.updatedAt, + t, + ), ); parts.push( - [ - `### ${t.settings.memory.markdown.longTermBackground}`, - memory.history.longTermBackground.summary || "-", - "", - memory.history.longTermBackground.updatedAt && - `> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(memory.history.longTermBackground.updatedAt)}\``, - ].join("\n"), + formatMemorySection( + t.settings.memory.markdown.longTermBackground, + memory.history.longTermBackground.summary, + memory.history.longTermBackground.updatedAt, + t, + ), ); parts.push(`\n## ${t.settings.memory.markdown.facts}`); if (memory.facts.length === 0) { - parts.push(`_${t.settings.memory.markdown.empty}_`); + parts.push( + `${t.settings.memory.markdown.empty}`, + ); } else { parts.push( [ diff --git a/frontend/src/components/workspace/settings/skill-settings-page.tsx b/frontend/src/components/workspace/settings/skill-settings-page.tsx index 24398fa..c564256 100644 --- a/frontend/src/components/workspace/settings/skill-settings-page.tsx +++ b/frontend/src/components/workspace/settings/skill-settings-page.tsx @@ -115,20 +115,20 @@ function SkillSettingsList({ } function EmptySkill({ onCreateSkill }: { onCreateSkill: () => void }) { + const { t } = useI18n(); return ( - No agent skill yet + {t.settings.skills.emptyTitle} - Put your agent skill folders under the `/skills/custom` folder under - the root folder of DeerFlow. + {t.settings.skills.emptyDescription} - + ); diff --git a/frontend/src/core/i18n/locales/en-US.ts b/frontend/src/core/i18n/locales/en-US.ts index ac53d66..d60e817 100644 --- a/frontend/src/core/i18n/locales/en-US.ts +++ b/frontend/src/core/i18n/locales/en-US.ts @@ -243,7 +243,7 @@ export const enUS: Translations = { longTermBackground: "Long-term background", updatedAt: "Updated at", facts: "Facts", - empty: "Empty", + empty: "empty", table: { category: "Category", confidence: "Confidence", @@ -282,6 +282,10 @@ export const enUS: Translations = { description: "Manage the configuration and enabled status of the agent skills.", createSkill: "Create skill", + emptyTitle: "No agent skill yet", + emptyDescription: + "Put your agent skill folders under the `/skills/custom` folder under the root folder of DeerFlow.", + emptyButton: "Create Your First Skill", }, notification: { title: "Notification", diff --git a/frontend/src/core/i18n/locales/types.ts b/frontend/src/core/i18n/locales/types.ts index 843f517..7213efa 100644 --- a/frontend/src/core/i18n/locales/types.ts +++ b/frontend/src/core/i18n/locales/types.ts @@ -225,6 +225,9 @@ export interface Translations { title: string; description: string; createSkill: string; + emptyTitle: string; + emptyDescription: string; + emptyButton: string; }; notification: { title: string; diff --git a/frontend/src/core/i18n/locales/zh-CN.ts b/frontend/src/core/i18n/locales/zh-CN.ts index 4f03539..b3b2e1b 100644 --- a/frontend/src/core/i18n/locales/zh-CN.ts +++ b/frontend/src/core/i18n/locales/zh-CN.ts @@ -238,7 +238,7 @@ export const zhCN: Translations = { longTermBackground: "长期背景", updatedAt: "更新于", facts: "事实", - empty: "(空)", + empty: "空", table: { category: "类别", confidence: "置信度", @@ -275,6 +275,10 @@ export const zhCN: Translations = { title: "技能", description: "管理 Agent Skill 配置和启用状态。", createSkill: "新建技能", + emptyTitle: "还没有技能", + emptyDescription: + "将你的 Agent Skill 文件夹放在 DeerFlow 根目录下的 `/skills/custom` 文件夹中。", + emptyButton: "创建你的第一个技能", }, notification: { title: "通知", diff --git a/frontend/src/core/streamdown/plugins.ts b/frontend/src/core/streamdown/plugins.ts index d829a53..e921403 100644 --- a/frontend/src/core/streamdown/plugins.ts +++ b/frontend/src/core/streamdown/plugins.ts @@ -1,4 +1,5 @@ import rehypeKatex from "rehype-katex"; +import rehypeRaw from "rehype-raw"; import remarkGfm from "remark-gfm"; import remarkMath from "remark-math"; import type { StreamdownProps } from "streamdown"; @@ -11,6 +12,7 @@ export const streamdownPlugins = { [remarkMath, { singleDollarTextMath: true }], ] as StreamdownProps["remarkPlugins"], rehypePlugins: [ + rehypeRaw, [rehypeKatex, { output: "html" }], ] as StreamdownProps["rehypePlugins"], }; From cc88823a64d74d063dcf4cbdf3861f4e31e0a255 Mon Sep 17 00:00:00 2001 From: LofiSu Date: Tue, 10 Feb 2026 12:29:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:memory=20=E4=B8=BA=E7=A9=BA=E6=97=B6i18?= =?UTF-8?q?n=E5=AD=97=E4=BD=93=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/core/i18n/locales/en-US.ts | 2 +- frontend/src/core/i18n/locales/zh-CN.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/core/i18n/locales/en-US.ts b/frontend/src/core/i18n/locales/en-US.ts index d60e817..1bc60a9 100644 --- a/frontend/src/core/i18n/locales/en-US.ts +++ b/frontend/src/core/i18n/locales/en-US.ts @@ -243,7 +243,7 @@ export const enUS: Translations = { longTermBackground: "Long-term background", updatedAt: "Updated at", facts: "Facts", - empty: "empty", + empty: "(empty)", table: { category: "Category", confidence: "Confidence", diff --git a/frontend/src/core/i18n/locales/zh-CN.ts b/frontend/src/core/i18n/locales/zh-CN.ts index b3b2e1b..a3d399b 100644 --- a/frontend/src/core/i18n/locales/zh-CN.ts +++ b/frontend/src/core/i18n/locales/zh-CN.ts @@ -238,7 +238,7 @@ export const zhCN: Translations = { longTermBackground: "长期背景", updatedAt: "更新于", facts: "事实", - empty: "空", + empty: "(空)", table: { category: "类别", confidence: "置信度",