mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-02 22:02:13 +08:00
@@ -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",
|
||||
|
||||
3
frontend/pnpm-lock.yaml
generated
3
frontend/pnpm-lock.yaml
generated
@@ -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
|
||||
|
||||
@@ -31,6 +31,26 @@ function confidenceToLevelKey(confidence: unknown): {
|
||||
return { key: "normal", value };
|
||||
}
|
||||
|
||||
function formatMemorySection(
|
||||
title: string,
|
||||
summary: string,
|
||||
updatedAt: string | undefined,
|
||||
t: ReturnType<typeof useI18n>["t"],
|
||||
): string {
|
||||
const content =
|
||||
summary.trim() ||
|
||||
`<span class="text-muted-foreground">${t.settings.memory.markdown.empty}</span>`;
|
||||
return [
|
||||
`### ${title}`,
|
||||
content,
|
||||
"",
|
||||
updatedAt &&
|
||||
`> ${t.settings.memory.markdown.updatedAt}: \`${formatTimeAgo(updatedAt)}\``,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
function memoryToMarkdown(
|
||||
memory: UserMemory,
|
||||
t: ReturnType<typeof useI18n>["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(
|
||||
`<span class="text-muted-foreground">${t.settings.memory.markdown.empty}</span>`,
|
||||
);
|
||||
} else {
|
||||
parts.push(
|
||||
[
|
||||
|
||||
@@ -115,20 +115,20 @@ function SkillSettingsList({
|
||||
}
|
||||
|
||||
function EmptySkill({ onCreateSkill }: { onCreateSkill: () => void }) {
|
||||
const { t } = useI18n();
|
||||
return (
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia variant="icon">
|
||||
<SparklesIcon />
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>No agent skill yet</EmptyTitle>
|
||||
<EmptyTitle>{t.settings.skills.emptyTitle}</EmptyTitle>
|
||||
<EmptyDescription>
|
||||
Put your agent skill folders under the `/skills/custom` folder under
|
||||
the root folder of DeerFlow.
|
||||
{t.settings.skills.emptyDescription}
|
||||
</EmptyDescription>
|
||||
</EmptyHeader>
|
||||
<EmptyContent>
|
||||
<Button onClick={onCreateSkill}>Create Your First Skill</Button>
|
||||
<Button onClick={onCreateSkill}>{t.settings.skills.emptyButton}</Button>
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -225,6 +225,9 @@ export interface Translations {
|
||||
title: string;
|
||||
description: string;
|
||||
createSkill: string;
|
||||
emptyTitle: string;
|
||||
emptyDescription: string;
|
||||
emptyButton: string;
|
||||
};
|
||||
notification: {
|
||||
title: string;
|
||||
|
||||
@@ -275,6 +275,10 @@ export const zhCN: Translations = {
|
||||
title: "技能",
|
||||
description: "管理 Agent Skill 配置和启用状态。",
|
||||
createSkill: "新建技能",
|
||||
emptyTitle: "还没有技能",
|
||||
emptyDescription:
|
||||
"将你的 Agent Skill 文件夹放在 DeerFlow 根目录下的 `/skills/custom` 文件夹中。",
|
||||
emptyButton: "创建你的第一个技能",
|
||||
},
|
||||
notification: {
|
||||
title: "通知",
|
||||
|
||||
@@ -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"],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user