mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-21 07:26:50 +00:00
feat: support manual add and edit for memory facts (#1538)
* feat: support manual add and edit for memory facts * fix: restore memory updater save helper * fix: address memory fact review feedback * fix: remove duplicate memory fact edit action * docs: simplify memory fact review setup * docs: relax memory review startup instructions * fix: clear rebase marker in memory settings page * fix: address memory fact review and format issues * fix: address memory fact review feedback * refactor: make memory fact updates explicit patch semantics --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
@@ -22,6 +22,7 @@ export const enUS: Translations = {
|
||||
home: "Home",
|
||||
settings: "Settings",
|
||||
delete: "Delete",
|
||||
edit: "Edit",
|
||||
rename: "Rename",
|
||||
share: "Share",
|
||||
openInNewWindow: "Open in new window",
|
||||
@@ -312,6 +313,11 @@ export const enUS: Translations = {
|
||||
"DeerFlow automatically learns from your conversations in the background. These memories help DeerFlow understand you better and deliver a more personalized experience.",
|
||||
empty: "No memory data to display.",
|
||||
rawJson: "Raw JSON",
|
||||
addFact: "Add fact",
|
||||
addFactTitle: "Add memory fact",
|
||||
editFactTitle: "Edit memory fact",
|
||||
addFactSuccess: "Fact created",
|
||||
editFactSuccess: "Fact updated",
|
||||
clearAll: "Clear all memory",
|
||||
clearAllConfirmTitle: "Clear all memory?",
|
||||
clearAllConfirmDescription:
|
||||
@@ -321,9 +327,19 @@ export const enUS: Translations = {
|
||||
factDeleteConfirmDescription:
|
||||
"This fact will be removed from memory immediately. This action cannot be undone.",
|
||||
factDeleteSuccess: "Fact deleted",
|
||||
factContentLabel: "Content",
|
||||
factCategoryLabel: "Category",
|
||||
factConfidenceLabel: "Confidence",
|
||||
factContentPlaceholder: "Describe the memory fact you want to save",
|
||||
factCategoryPlaceholder: "context",
|
||||
factConfidenceHint: "Use a number between 0 and 1.",
|
||||
factSave: "Save fact",
|
||||
factValidationContent: "Fact content cannot be empty.",
|
||||
factValidationConfidence: "Confidence must be a number between 0 and 1.",
|
||||
manualFactSource: "Manual",
|
||||
noFacts: "No saved facts yet.",
|
||||
summaryReadOnly:
|
||||
"Summary sections are read-only for now. You can currently clear all memory or delete individual facts.",
|
||||
"Summary sections are read-only for now. You can currently add, edit, or delete individual facts, or clear all memory.",
|
||||
memoryFullyEmpty: "No memory saved yet.",
|
||||
factPreviewLabel: "Fact to delete",
|
||||
searchPlaceholder: "Search memory",
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface Translations {
|
||||
home: string;
|
||||
settings: string;
|
||||
delete: string;
|
||||
edit: string;
|
||||
rename: string;
|
||||
share: string;
|
||||
openInNewWindow: string;
|
||||
@@ -247,6 +248,11 @@ export interface Translations {
|
||||
description: string;
|
||||
empty: string;
|
||||
rawJson: string;
|
||||
addFact: string;
|
||||
addFactTitle: string;
|
||||
editFactTitle: string;
|
||||
addFactSuccess: string;
|
||||
editFactSuccess: string;
|
||||
clearAll: string;
|
||||
clearAllConfirmTitle: string;
|
||||
clearAllConfirmDescription: string;
|
||||
@@ -254,6 +260,16 @@ export interface Translations {
|
||||
factDeleteConfirmTitle: string;
|
||||
factDeleteConfirmDescription: string;
|
||||
factDeleteSuccess: string;
|
||||
factContentLabel: string;
|
||||
factCategoryLabel: string;
|
||||
factConfidenceLabel: string;
|
||||
factContentPlaceholder: string;
|
||||
factCategoryPlaceholder: string;
|
||||
factConfidenceHint: string;
|
||||
factSave: string;
|
||||
factValidationContent: string;
|
||||
factValidationConfidence: string;
|
||||
manualFactSource: string;
|
||||
noFacts: string;
|
||||
summaryReadOnly: string;
|
||||
memoryFullyEmpty: string;
|
||||
|
||||
@@ -22,6 +22,7 @@ export const zhCN: Translations = {
|
||||
home: "首页",
|
||||
settings: "设置",
|
||||
delete: "删除",
|
||||
edit: "编辑",
|
||||
rename: "重命名",
|
||||
share: "分享",
|
||||
openInNewWindow: "在新窗口打开",
|
||||
@@ -298,6 +299,11 @@ export const zhCN: Translations = {
|
||||
"DeerFlow 会在后台不断从你的对话中自动学习。这些记忆能帮助 DeerFlow 更好地理解你,并提供更个性化的体验。",
|
||||
empty: "暂无可展示的记忆数据。",
|
||||
rawJson: "原始 JSON",
|
||||
addFact: "添加事实",
|
||||
addFactTitle: "添加记忆事实",
|
||||
editFactTitle: "编辑记忆事实",
|
||||
addFactSuccess: "事实已创建",
|
||||
editFactSuccess: "事实已更新",
|
||||
clearAll: "清空全部记忆",
|
||||
clearAllConfirmTitle: "要清空全部记忆吗?",
|
||||
clearAllConfirmDescription:
|
||||
@@ -307,9 +313,19 @@ export const zhCN: Translations = {
|
||||
factDeleteConfirmDescription:
|
||||
"这条事实会立即从记忆中删除。此操作无法撤销。",
|
||||
factDeleteSuccess: "事实已删除",
|
||||
factContentLabel: "内容",
|
||||
factCategoryLabel: "类别",
|
||||
factConfidenceLabel: "置信度",
|
||||
factContentPlaceholder: "描述你想保存的记忆事实",
|
||||
factCategoryPlaceholder: "context",
|
||||
factConfidenceHint: "请输入 0 到 1 之间的数字。",
|
||||
factSave: "保存事实",
|
||||
factValidationContent: "事实内容不能为空。",
|
||||
factValidationConfidence: "置信度必须是 0 到 1 之间的数字。",
|
||||
manualFactSource: "手动添加",
|
||||
noFacts: "还没有保存的事实。",
|
||||
summaryReadOnly:
|
||||
"摘要分区当前仍为只读。现在你可以清空全部记忆或删除单条事实。",
|
||||
"摘要分区当前仍为只读。你可以在下方添加、编辑或删除事实,或清空全部记忆。",
|
||||
memoryFullyEmpty: "还没有保存任何记忆。",
|
||||
factPreviewLabel: "即将删除的事实",
|
||||
searchPlaceholder: "搜索记忆",
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { getBackendBaseURL } from "../config";
|
||||
|
||||
import type { UserMemory } from "./types";
|
||||
import type {
|
||||
MemoryFactInput,
|
||||
MemoryFactPatchInput,
|
||||
UserMemory,
|
||||
} from "./types";
|
||||
|
||||
async function readMemoryResponse(
|
||||
response: Response,
|
||||
@@ -39,3 +43,33 @@ export async function deleteMemoryFact(factId: string): Promise<UserMemory> {
|
||||
);
|
||||
return readMemoryResponse(response, "Failed to delete memory fact");
|
||||
}
|
||||
|
||||
export async function createMemoryFact(
|
||||
input: MemoryFactInput,
|
||||
): Promise<UserMemory> {
|
||||
const response = await fetch(`${getBackendBaseURL()}/api/memory/facts`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(input),
|
||||
});
|
||||
return readMemoryResponse(response, "Failed to create memory fact");
|
||||
}
|
||||
|
||||
export async function updateMemoryFact(
|
||||
factId: string,
|
||||
input: MemoryFactPatchInput,
|
||||
): Promise<UserMemory> {
|
||||
const response = await fetch(
|
||||
`${getBackendBaseURL()}/api/memory/facts/${encodeURIComponent(factId)}`,
|
||||
{
|
||||
method: "PATCH",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(input),
|
||||
},
|
||||
);
|
||||
return readMemoryResponse(response, "Failed to update memory fact");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { clearMemory, deleteMemoryFact, loadMemory } from "./api";
|
||||
import type { UserMemory } from "./types";
|
||||
import {
|
||||
clearMemory,
|
||||
createMemoryFact,
|
||||
deleteMemoryFact,
|
||||
loadMemory,
|
||||
updateMemoryFact,
|
||||
} from "./api";
|
||||
import type {
|
||||
MemoryFactInput,
|
||||
MemoryFactPatchInput,
|
||||
UserMemory,
|
||||
} from "./types";
|
||||
|
||||
export function useMemory() {
|
||||
const { data, isLoading, error } = useQuery({
|
||||
@@ -32,3 +42,31 @@ export function useDeleteMemoryFact() {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateMemoryFact() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (input: MemoryFactInput) => createMemoryFact(input),
|
||||
onSuccess: (memory) => {
|
||||
queryClient.setQueryData<UserMemory>(["memory"], memory);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateMemoryFact() {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({
|
||||
factId,
|
||||
input,
|
||||
}: {
|
||||
factId: string;
|
||||
input: MemoryFactPatchInput;
|
||||
}) => updateMemoryFact(factId, input),
|
||||
onSuccess: (memory) => {
|
||||
queryClient.setQueryData<UserMemory>(["memory"], memory);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
export interface MemoryFact {
|
||||
id: string;
|
||||
content: string;
|
||||
category: string;
|
||||
confidence: number;
|
||||
createdAt: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
export interface MemoryFactInput {
|
||||
content: string;
|
||||
category: string;
|
||||
confidence: number;
|
||||
}
|
||||
|
||||
export interface MemoryFactPatchInput {
|
||||
content?: string;
|
||||
category?: string;
|
||||
confidence?: number;
|
||||
}
|
||||
|
||||
export interface UserMemory {
|
||||
version: string;
|
||||
lastUpdated: string;
|
||||
@@ -29,12 +50,5 @@ export interface UserMemory {
|
||||
updatedAt: string;
|
||||
};
|
||||
};
|
||||
facts: {
|
||||
id: string;
|
||||
content: string;
|
||||
category: string;
|
||||
confidence: number;
|
||||
createdAt: string;
|
||||
source: string;
|
||||
}[];
|
||||
facts: MemoryFact[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user