mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-29 23:12:38 +08:00
bug修改丢失记忆
This commit is contained in:
parent
249ab3d59f
commit
bbdcd85014
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
})
|
})
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user