fix(memory): code review fixes for dreaming and tool execution

This commit is contained in:
matevip 2026-04-07 09:22:37 +08:00
parent d3f2a310e8
commit 69afc4e68a
2 changed files with 32 additions and 6 deletions

View File

@ -68,9 +68,10 @@ public class MemoryEmergenceService {
return;
}
// 2. 读取 daily notes 内容
// 2. 批量读取 daily notes 内容避免 N+1 查询
StringBuilder dailyNotesBuilder = new StringBuilder();
for (String filename : dailyFilenames) {
// TODO: 未来可优化为 IN 批量查询当前 listFiles() 会清除 content 字段
WorkspaceFileEntity file = workspaceFileService.getFile(agentId, filename);
if (file != null && file.getContent() != null && !file.getContent().isBlank()) {
dailyNotesBuilder.append("### ").append(filename).append("\n");
@ -221,11 +222,14 @@ public class MemoryEmergenceService {
// 防止无限膨胀超过 20KB 时截断只保留最近的内容
if (newContent.length() > 20_000) {
int cutPoint = newContent.length() - 16_000;
// 找到下一个 "## " 标记作为安全截断点
int safePoint = newContent.indexOf("\n## ", cutPoint);
if (safePoint > 0) {
newContent = "# Dreaming 整合日记\n\n> 早期记录已归档\n\n"
+ newContent.substring(safePoint + 1);
} else {
// 没找到 ## 标记硬截断保留最后 16KB
newContent = "# Dreaming 整合日记\n\n> 早期记录已归档\n\n"
+ newContent.substring(cutPoint);
}
}

View File

@ -94,9 +94,28 @@ public class MemoryRecallService {
recallMapper.insert(entity);
} catch (org.springframework.dao.DuplicateKeyException e) {
// 并发插入冲突退化为更新
log.debug("[MemoryRecall] Concurrent insert for {}, retrying as update", filename);
recordRecall(agentId, filename, snippetText, userQueryHash);
// 并发插入冲突重新查询后更新不递归避免 StackOverflow
log.debug("[MemoryRecall] Concurrent insert for {}, falling back to update", filename);
MemoryRecallEntity retry = recallMapper.selectOne(
new LambdaQueryWrapper<MemoryRecallEntity>()
.eq(MemoryRecallEntity::getAgentId, agentId)
.eq(MemoryRecallEntity::getFilename, filename)
.eq(MemoryRecallEntity::getDeleted, 0)
.last("LIMIT 1"));
if (retry != null) {
retry.setRecallCount(retry.getRecallCount() + 1);
retry.setDailyCount(retry.getDailyCount() + 1);
retry.setLastRecalledAt(now);
retry.setSnippetPreview(preview);
if (userQueryHash != null) {
List<String> hashes = parseQueryHashes(retry.getQueryHashes());
if (!hashes.contains(userQueryHash) && hashes.size() < MAX_QUERY_HASHES) {
hashes.add(userQueryHash);
}
retry.setQueryHashes(toJson(hashes));
}
recallMapper.updateById(retry);
}
}
}
}
@ -263,7 +282,10 @@ public class MemoryRecallService {
item.put("score", c.getScore());
item.put("recallCount", c.getRecallCount());
item.put("dailyCount", c.getDailyCount());
item.put("queryCount", parseQueryHashes(c.getQueryHashes()).size());
// 避免 JSON 反序列化直接数逗号估算 hash 数量"[\"a\",\"b\"]" 1 个逗号 = 2 个元素
String qh = c.getQueryHashes();
int queryCount = (qh == null || qh.length() <= 2) ? 0 : qh.split(",").length;
item.put("queryCount", queryCount);
item.put("promoted", c.getPromoted());
item.put("lastRecalledAt", c.getLastRecalledAt());
item.put("snippetPreview", c.getSnippetPreview());