bug修改丢失记忆

This commit is contained in:
1600822305 2025-04-13 21:36:23 +08:00
parent 249ab3d59f
commit bbdcd85014
3 changed files with 106 additions and 64 deletions

View File

@ -15,7 +15,8 @@ import {
updateUserInterest, updateUserInterest,
updateMemoryPriorities, updateMemoryPriorities,
accessMemory, accessMemory,
Memory Memory,
saveMemoryData // <-- 添加 saveMemoryData
} from '@renderer/store/memory' } from '@renderer/store/memory'
import { useCallback, useEffect, useRef } from 'react' // Add useRef back import { useCallback, useEffect, useRef } from 'react' // Add useRef back
@ -580,11 +581,12 @@ export const addShortMemoryItem = (
) )
} }
// 分析对话内容并提取重要信息添加到短期记忆
// 分析对话内容并提取重要信息添加到短期记忆 // 分析对话内容并提取重要信息添加到短期记忆
export const analyzeAndAddShortMemories = async (topicId: string) => { export const analyzeAndAddShortMemories = async (topicId: string) => {
if (!topicId) { if (!topicId) {
console.log('[Short Memory Analysis] No topic ID provided') console.log('[Short Memory Analysis] No topic ID provided')
return return false
} }
// 获取当前记忆状态 // 获取当前记忆状态
@ -594,7 +596,7 @@ export const analyzeAndAddShortMemories = async (topicId: string) => {
if (!shortMemoryAnalyzeModel) { if (!shortMemoryAnalyzeModel) {
console.log('[Short Memory Analysis] No short memory analyze model set') console.log('[Short Memory Analysis] No short memory analyze model set')
return return false
} }
// 获取对话内容 // 获取对话内容
@ -612,13 +614,13 @@ export const analyzeAndAddShortMemories = async (topicId: string) => {
} }
} catch (error) { } catch (error) {
console.error(`[Short Memory Analysis] Failed to get messages for topic ${topicId}:`, error) console.error(`[Short Memory Analysis] Failed to get messages for topic ${topicId}:`, error)
return return false
} }
} }
if (!messages || messages.length === 0) { if (!messages || messages.length === 0) {
console.log('[Short Memory Analysis] No messages to analyze.') console.log('[Short Memory Analysis] No messages to analyze.')
return return false
} }
// 获取现有的短期记忆 // 获取现有的短期记忆
@ -638,7 +640,7 @@ export const analyzeAndAddShortMemories = async (topicId: string) => {
if (newMessages.length === 0) { if (newMessages.length === 0) {
console.log('[Short Memory Analysis] No new messages to analyze.') console.log('[Short Memory Analysis] No new messages to analyze.')
return return false
} }
console.log(`[Short Memory Analysis] Found ${newMessages.length} new messages to analyze.`) console.log(`[Short Memory Analysis] Found ${newMessages.length} new messages to analyze.`)
@ -698,7 +700,7 @@ ${newConversation}
if (!model) { if (!model) {
console.error(`[Short Memory Analysis] Model ${shortMemoryAnalyzeModel} not found`) console.error(`[Short Memory Analysis] Model ${shortMemoryAnalyzeModel} not found`)
return return false
} }
// 调用AI生成文本 // 调用AI生成文本
@ -710,37 +712,67 @@ ${newConversation}
}) })
console.log('[Short Memory Analysis] AI.generateText response:', result) console.log('[Short Memory Analysis] AI.generateText response:', result)
if (!result) { if (!result || typeof result !== 'string' || result.trim() === '') {
console.log('[Short Memory Analysis] No result from AI analysis.') console.log('[Short Memory Analysis] No valid result from AI analysis.')
return return false
} }
// 解析结果 // 改进的记忆提取逻辑
const lines = result let extractedLines: string[] = []
.split('\n')
.map((line: string) => line.trim())
.filter((line: string) => {
// 匹配以数字和点开头的行(如"1.", "2.")或者以短横线开头的行(如"-"
return /^\d+\./.test(line) || line.startsWith('-')
})
.map((line: string) => {
// 如果是数字开头,移除数字和点,如果是短横线开头,移除短横线
if (/^\d+\./.test(line)) {
return line.replace(/^\d+\.\s*/, '').trim()
} else if (line.startsWith('-')) {
return line.substring(1).trim()
}
return line
})
.filter(Boolean)
console.log('[Short Memory Analysis] Extracted items:', lines) // 首先尝试匹配带有数字或短横线的列表项
const listItemRegex = /(?:^|\n)(?:\d+\.\s*|\-\s*)(.+?)(?=\n\d+\.\s*|\n\-\s*|\n\n|$)/gs
let match
while ((match = listItemRegex.exec(result)) !== null) {
if (match[1] && match[1].trim()) {
extractedLines.push(match[1].trim())
}
}
// 过滤掉已存在的记忆 // 如果没有找到列表项,则尝试按行分割并过滤
if (extractedLines.length === 0) {
extractedLines = result
.split('\n')
.map(line => line.trim())
.filter(line => {
// 过滤掉空行和非内容行(如标题、分隔符等)
return line &&
!line.startsWith('#') &&
!line.startsWith('---') &&
!line.startsWith('===') &&
!line.includes('没有找到新的重要信息') &&
!line.includes('No new important information')
})
// 清理行首的数字、点和短横线
.map(line => line.replace(/^(\d+\.\s*|\-\s*)/, '').trim())
}
console.log('[Short Memory Analysis] Extracted items:', extractedLines)
if (extractedLines.length === 0) {
console.log('[Short Memory Analysis] No memory items extracted from the analysis result.')
return false
}
// 过滤掉已存在的记忆(使用更严格的比较)
const existingContents = topicShortMemories.map((memory) => memory.content.toLowerCase()) const existingContents = topicShortMemories.map((memory) => memory.content.toLowerCase())
const newMemories = lines.filter((content: string) => !existingContents.includes(content.toLowerCase())) const newMemories = extractedLines.filter((content: string) => {
const normalizedContent = content.toLowerCase()
// 检查是否与现有记忆完全匹配或高度相似
return !existingContents.some(existingContent =>
existingContent === normalizedContent ||
// 简单的相似度检查 - 如果一个字符串包含另一个的80%以上的内容
(existingContent.includes(normalizedContent) && normalizedContent.length > existingContent.length * 0.8) ||
(normalizedContent.includes(existingContent) && existingContent.length > normalizedContent.length * 0.8)
)
})
console.log(`[Short Memory Analysis] Found ${lines.length} items, ${newMemories.length} are new`) console.log(`[Short Memory Analysis] Found ${extractedLines.length} items, ${newMemories.length} are new`)
if (newMemories.length === 0) {
console.log('[Short Memory Analysis] No new memories to add after filtering.')
return false
}
// 收集新分析的消息ID // 收集新分析的消息ID
const newMessageIds = newMessages.map((msg) => msg.id) const newMessageIds = newMessages.map((msg) => msg.id)
@ -749,12 +781,39 @@ ${newConversation}
const lastMessageId = messages[messages.length - 1]?.id const lastMessageId = messages[messages.length - 1]?.id
// 添加新的短期记忆 // 添加新的短期记忆
const addedMemories: string[] = [] // Explicitly type addedMemories
for (const content of newMemories) { for (const content of newMemories) {
addShortMemoryItem(content, topicId, newMessageIds, lastMessageId) try {
console.log(`[Short Memory Analysis] Added new short memory: "${content}" to topic ${topicId}`) store.dispatch(
addShortMemory({
content,
topicId,
analyzedMessageIds: newMessageIds,
lastMessageId: lastMessageId
})
)
addedMemories.push(content)
console.log(`[Short Memory Analysis] Added new short memory: "${content}" to topic ${topicId}`)
} catch (error) {
console.error(`[Short Memory Analysis] Failed to add memory: "${content}"`, error)
}
} }
return newMemories.length > 0 // 显式触发保存操作,确保数据被持久化
try {
const state = store.getState().memory
await store.dispatch(saveMemoryData({
memoryLists: state.memoryLists,
memories: state.memories,
shortMemories: state.shortMemories
})).unwrap() // 使用unwrap()来等待异步操作完成并处理错误
console.log('[Short Memory Analysis] Memory data saved successfully')
} catch (error) {
console.error('[Short Memory Analysis] Failed to save memory data:', error)
// 即使保存失败我们仍然返回true因为记忆已经添加到Redux状态中
}
return addedMemories.length > 0
} catch (error) { } catch (error) {
console.error('[Short Memory Analysis] Failed to analyze and add short memories:', error) console.error('[Short Memory Analysis] Failed to analyze and add short memories:', error)
return false return false

View File

@ -10,7 +10,7 @@ import copilot from './copilot'
import knowledge from './knowledge' import knowledge from './knowledge'
import llm from './llm' import llm from './llm'
import mcp from './mcp' import mcp from './mcp'
import memory, { memoryPersistenceMiddleware } from './memory' import memory from './memory' // Removed import of memoryPersistenceMiddleware
import messagesReducer from './messages' import messagesReducer from './messages'
import migrate from './migrate' import migrate from './migrate'
import minapps from './minapps' import minapps from './minapps'
@ -59,7 +59,7 @@ const store = configureStore({
serializableCheck: { serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER] ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
} }
}).concat(memoryPersistenceMiddleware) }) // Removed concat of memoryPersistenceMiddleware
}, },
devTools: true devTools: true
}) })

View File

@ -755,15 +755,15 @@ export const loadMemoryData = createAsyncThunk(
'memory/loadData', 'memory/loadData',
async () => { async () => {
try { try {
log.info('Loading memory data from file...') // log.info('Loading memory data from file...') // Removed direct log call from renderer
const data = await window.api.memory.loadData() const data = await window.api.memory.loadData()
log.info('Memory data loaded successfully') // log.info('Memory data loaded successfully') // Removed direct log call from renderer
return data return data
} catch (error) { } catch (error) {
log.error('Failed to load memory data:', error) console.error('Failed to load memory data:', error) // Use console.error instead of log.error
return null return null // Ensure the thunk returns null on error
} }
} } // <-- Add missing closing brace for the async function
) )
// 保存记忆数据的异步 thunk // 保存记忆数据的异步 thunk
@ -771,34 +771,17 @@ export const saveMemoryData = createAsyncThunk(
'memory/saveData', 'memory/saveData',
async (data: Partial<MemoryState>) => { async (data: Partial<MemoryState>) => {
try { try {
log.info('Saving memory data to file...') // log.info('Saving memory data to file...') // Removed direct log call from renderer
const result = await window.api.memory.saveData(data) const result = await window.api.memory.saveData(data)
log.info('Memory data saved successfully') // log.info('Memory data saved successfully') // Removed direct log call from renderer
return result return result
} catch (error) { } catch (error) {
log.error('Failed to save memory data:', error) console.error('Failed to save memory data:', error) // Use console.error instead of log.error
return false return false
} }
} }
) )
// 创建一个中间件来自动保存记忆数据的变化 // Middleware removed to prevent duplicate saves triggered by batch additions.
export const memoryPersistenceMiddleware = (store) => (next) => (action) => { // Explicit saves should be handled where needed, e.g., at the end of analysis functions.
const result = next(action)
// 如果是记忆相关的操作,保存数据到文件
if (action.type.startsWith('memory/') &&
!action.type.includes('loadData') &&
!action.type.includes('saveData')) {
const state = store.getState().memory
store.dispatch(saveMemoryData({
memoryLists: state.memoryLists,
memories: state.memories,
shortMemories: state.shortMemories
}))
}
return result
}
export default memorySlice.reducer export default memorySlice.reducer