From 5f9acebad17129c4d846a3124c27bb85b31de9c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B4=AB=E5=BD=B1233?= Date: Wed, 24 Jun 2026 15:31:58 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=AE=B0=E5=BF=86=E5=8E=BB=E9=87=8D?= =?UTF-8?q?=E6=97=B6=E6=98=8E=E7=A1=AE=E5=91=8A=E7=9F=A5=20AI=E3=80=8C?= =?UTF-8?q?=E5=B7=B2=E5=AD=98=E5=9C=A8=EF=BC=8C=E4=B8=8D=E8=A6=81=E5=86=8D?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=B7=BB=E5=8A=A0=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前 addEntry 检测到重复后静默返回已有条目(success),AI 误以为又成功保存了 新条目,于是继续循环调用。现在改为抛出 DuplicateEntryError,tool handler 捕获后返回 {success:true, duplicate:true, message:'已跳过...不要再重复添加'}, 明确告诉 AI 任务已完成。 也处理了内存面板的手动添加场景,友好提示用户。 --- src/renderer/components/memory-modal.ts | 8 ++++++-- src/renderer/services/memory-service.ts | 17 ++++++++++++++++- src/renderer/services/tool-registry.ts | 16 ++++++++++++---- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/renderer/components/memory-modal.ts b/src/renderer/components/memory-modal.ts index 4bf8098..ab863fc 100644 --- a/src/renderer/components/memory-modal.ts +++ b/src/renderer/components/memory-modal.ts @@ -3,7 +3,7 @@ * 基于工作空间 MEMORY.md 文件 */ -import { loadAllEntries, addEntry, removeEntry, type MemoryEntry, type MemoryType } from '../services/memory-service.js'; +import { loadAllEntries, addEntry, removeEntry, DuplicateEntryError, type MemoryEntry, type MemoryType } from '../services/memory-service.js'; import { showToast } from './toast.js'; import { showPrompt, showConfirm } from './prompt-modal.js'; import { escapeHtml, formatTime } from '../utils/utils.js'; @@ -170,6 +170,10 @@ async function openAddDialog(): Promise { await renderList(); showToast('记忆已添加', 'success', 1500); } catch (err) { - showToast(`添加失败: ${(err as Error).message}`, 'error'); + if (err instanceof DuplicateEntryError) { + showToast('该记忆已存在,无需重复添加', 'info', 2000); + } else { + showToast(`添加失败: ${(err as Error).message}`, 'error'); + } } } diff --git a/src/renderer/services/memory-service.ts b/src/renderer/services/memory-service.ts index 562ca6e..fbcb435 100644 --- a/src/renderer/services/memory-service.ts +++ b/src/renderer/services/memory-service.ts @@ -21,6 +21,18 @@ import { logInfo, logWarn, logDebug, logMemory } from './log-service.js'; // 类型定义 // ═══════════════════════════════════════════════════════════════ +/** 重复条目错误:记忆已存在时抛出,告诉调用方无需重复添加 */ +export class DuplicateEntryError extends Error { + existingId: string; + existingPreview: string; + constructor(id: string, preview: string) { + super(`重复条目: ${preview}... (ID: ${id})`); + this.name = 'DuplicateEntryError'; + this.existingId = id; + this.existingPreview = preview; + } +} + export type MemoryType = 'fact' | 'preference' | 'rule'; export interface MemoryEntry { @@ -435,7 +447,10 @@ export async function addEntry( if (prefixLen > 20 && content.slice(0, prefixLen) === e.content.slice(0, prefixLen)) return true; return simpleSimilarity(e.content, content) > 0.8; }); - if (existing) return existing; + if (existing) { + logDebug('记忆去重: 已有相同条目', `${type}: ${content.slice(0, 40)}`); + throw new DuplicateEntryError(existing.id, existing.content.slice(0, 60)); + } const entry: MemoryEntry = { id: generateMemoryId(), diff --git a/src/renderer/services/tool-registry.ts b/src/renderer/services/tool-registry.ts index 6acc527..ba66fb4 100644 --- a/src/renderer/services/tool-registry.ts +++ b/src/renderer/services/tool-registry.ts @@ -779,7 +779,7 @@ export async function executeTool(toolName: string, args: Record