From f26db3f539eb7ee0fb6e4e2330b7a2335923bbc8 Mon Sep 17 00:00:00 2001 From: bqj6666 Date: Sat, 14 Nov 2026 09:05:11 +0000 Subject: [PATCH] =?UTF-8?q?fix(assistant):=20=E6=B2=A1=E6=9C=89=20MEMORY.m?= =?UTF-8?q?d=20=E6=97=B6=E4=BA=BA=E6=A0=BC=E6=8F=90=E7=A4=BA=E8=AF=8D?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E8=A2=AB=E9=9D=99=E9=BB=98=E6=8B=92=E7=BB=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit save() 首行的 memoryRevision.isBlank() 在没有记忆文件时恒为真:snapshot() 返回 null, revision 落成空串,于是保存流程连取锁都没走到 —— 既无 toast 也无日志,真机表现就是 「助手编辑页改完提示词点保存,按钮可点但毫无反应,退出重进内容丢失」。 人格提示词存在 index.json,与 MEMORY.md 无关,不该被记忆 revision 锁死: - 门禁只保留 dirty / saving / 记忆超限三条 - 记忆未改动时不触碰记忆存储 - 记忆改动但 revision 为空时走 replaceAll(content) 无并发校验写入 - save 入口 / 成功 / 失败各补一条日志,失败不再静默 --- .../screens/assistants/AssistantEditScreen.kt | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/app/src/main/kotlin/io/github/mangi/eta/ui/screens/assistants/AssistantEditScreen.kt b/app/src/main/kotlin/io/github/mangi/eta/ui/screens/assistants/AssistantEditScreen.kt index cd2da2ef47..e58b275786 100644 --- a/app/src/main/kotlin/io/github/mangi/eta/ui/screens/assistants/AssistantEditScreen.kt +++ b/app/src/main/kotlin/io/github/mangi/eta/ui/screens/assistants/AssistantEditScreen.kt @@ -152,19 +152,35 @@ internal fun AssistantEditScreen( } fun save() { - if (!dirty || saving || memoryOverLimit || memoryRevision.isBlank()) return + // 人格提示词存在 index.json,记忆存在 MEMORY.md,两者互不相干。 + // 原先这里用 memoryRevision.isBlank() 把整条保存链锁死:没有 MEMORY.md 时 + // snapshot() 返回 null、revision 恒为空串,连取锁都走不到,于是「点保存毫无反应」 + // 且没有任何日志。这里只保留真正该拦的条件。 + if (!dirty || saving || memoryOverLimit) return val targetMemory = memoryDraft val baseRevision = memoryRevision val targetProfile = original.copy(name = name, prompt = prompt, avatarFileName = avatarFileName, memoryEnabled = memoryEnabled, enabledSkillIds = enabledSkillIds.toList(), toolGroupSwitches = toolSwitches) val memoryChanged = targetMemory != memorySaved + io.github.mangi.eta.core.AndroidAgentLogger.info( + "assistant-save start id=$assistantId memoryChanged=$memoryChanged " + + "revisionBlank=${baseRevision.isBlank()} promptChars=${targetProfile.prompt.length}" + ) saving = true scope.launch { var savedSnapshot: io.github.mangi.eta.data.repository.AgentMemorySnapshot? = null val result = withContext(Dispatchers.IO) { runCatching { - if (memoryChanged) savedSnapshot = AgentMemoryRepository.replaceAll(targetMemory, assistantId, baseRevision) + // 记忆没改动就不碰记忆存储;改动但 revision 为空(还没有 MEMORY.md) + // 走无并发校验的写入,而不是直接拒绝保存。 + if (memoryChanged) { + savedSnapshot = if (baseRevision.isBlank()) { + AgentMemoryRepository.replaceAll(targetMemory) + } else { + AgentMemoryRepository.replaceAll(targetMemory, baseRevision) + } + } AssistantRepository.update(targetProfile) RuntimeConfigRepository.syncToRemotePreferences(EtaApp.serviceInstance) } @@ -174,8 +190,24 @@ internal fun AssistantEditScreen( memorySaved = snapshot.content } saving = false - if (result.isSuccess) onBack() - else android.widget.Toast.makeText(context, result.exceptionOrNull()?.message ?: context.getString(R.string.aes_save_failed_draft_kept), android.widget.Toast.LENGTH_LONG).show() + result.fold( + onSuccess = { + io.github.mangi.eta.core.AndroidAgentLogger.info( + "assistant-save ok id=$assistantId promptChars=${targetProfile.prompt.length}" + ) + onBack() + }, + onFailure = { error -> + io.github.mangi.eta.core.AndroidAgentLogger.warn( + "assistant-save failed id=$assistantId: ${error::class.java.simpleName}: ${error.message}" + ) + android.widget.Toast.makeText( + context, + error.message ?: context.getString(R.string.aes_save_failed_draft_kept), + android.widget.Toast.LENGTH_LONG, + ).show() + }, + ) } }