mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-31 16:49:07 +08:00
refactor(preferences): update memory preference handling
- Replace direct Redux state access for memory preferences with preferenceService calls in multiple components. - Introduce new preference mappings for memory settings, including 'feature.memory.auto_dimensions'. - Remove deprecated preference mappings and update default preferences accordingly. - Regenerate preference schemas to reflect the latest changes in memory configuration.
This commit is contained in:
parent
dd7b76750b
commit
143b4c46c8
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Auto-generated preferences configuration
|
||||
* Generated at: 2025-11-28T15:24:33.354Z
|
||||
* Generated at: 2025-11-28T16:19:17.585Z
|
||||
*
|
||||
* This file is automatically generated from classification.json
|
||||
* To update this file, modify classification.json and run:
|
||||
@ -310,6 +310,8 @@ export interface PreferenceSchemas {
|
||||
'feature.csaas.host': string
|
||||
// redux/settings/apiServer.port
|
||||
'feature.csaas.port': number
|
||||
// redux/memory/memoryConfig.isAutoDimensions
|
||||
'feature.memory.auto_dimensions': boolean
|
||||
// redux/memory/currentUserId
|
||||
'feature.memory.current_user_id': string
|
||||
// redux/memory/memoryConfig.embedderDimensions
|
||||
@ -318,8 +320,6 @@ export interface PreferenceSchemas {
|
||||
'feature.memory.enabled': boolean
|
||||
// redux/memory/memoryConfig.customFactExtractionPrompt
|
||||
'feature.memory.fact_extraction_prompt': string
|
||||
// redux/memory/memoryConfig.isAutoDimensions
|
||||
'feature.memory.is_auto_dimensions': boolean
|
||||
// redux/memory/memoryConfig.customUpdateMemoryPrompt
|
||||
'feature.memory.update_memory_prompt': string
|
||||
// redux/settings/maxKeepAliveMinapps
|
||||
@ -585,11 +585,11 @@ export const DefaultPreferences: PreferenceSchemas = {
|
||||
'feature.csaas.enabled': false,
|
||||
'feature.csaas.host': 'localhost',
|
||||
'feature.csaas.port': 23333,
|
||||
'feature.memory.auto_dimensions': true,
|
||||
'feature.memory.current_user_id': 'default-user',
|
||||
'feature.memory.embedder_dimensions': 1536,
|
||||
'feature.memory.enabled': false,
|
||||
'feature.memory.fact_extraction_prompt': MEMORY_FACT_EXTRACTION_PROMPT,
|
||||
'feature.memory.is_auto_dimensions': true,
|
||||
'feature.memory.update_memory_prompt': MEMORY_UPDATE_SYSTEM_PROMPT,
|
||||
'feature.minapp.max_keep_alive': 3,
|
||||
'feature.minapp.open_link_external': false,
|
||||
|
||||
@ -7,10 +7,11 @@
|
||||
* 3. onRequestEnd: 自动记忆存储
|
||||
*/
|
||||
import { type AiRequestContext, definePlugin } from '@cherrystudio/ai-core'
|
||||
import { preferenceService } from '@data/PreferenceService'
|
||||
import { loggerService } from '@logger'
|
||||
import { getDefaultModel, getProviderByModel } from '@renderer/services/AssistantService'
|
||||
import store from '@renderer/store'
|
||||
import { selectCurrentUserId, selectGlobalMemoryEnabled, selectMemoryConfig } from '@renderer/store/memory'
|
||||
import { selectMemoryConfig } from '@renderer/store/memory'
|
||||
import type { Assistant } from '@renderer/types'
|
||||
import type { ExtractResults } from '@renderer/utils/extract'
|
||||
import { extractInfoFromXML } from '@renderer/utils/extract'
|
||||
@ -176,7 +177,7 @@ async function storeConversationMemory(
|
||||
assistant: Assistant,
|
||||
context: AiRequestContext
|
||||
): Promise<void> {
|
||||
const globalMemoryEnabled = selectGlobalMemoryEnabled(store.getState())
|
||||
const globalMemoryEnabled = await preferenceService.get('feature.memory.enabled')
|
||||
|
||||
if (!globalMemoryEnabled || !assistant.enableMemory) {
|
||||
return
|
||||
@ -199,7 +200,7 @@ async function storeConversationMemory(
|
||||
return
|
||||
}
|
||||
|
||||
const currentUserId = selectCurrentUserId(store.getState())
|
||||
const currentUserId = await preferenceService.get('feature.memory.current_user_id')
|
||||
// const lastUserMessage = messages.findLast((m) => m.role === 'user')
|
||||
|
||||
const processorConfig = MemoryProcessor.getProcessorConfig(
|
||||
@ -267,7 +268,7 @@ export const searchOrchestrationPlugin = (assistant: Assistant, topicId: string)
|
||||
const knowledgeBaseIds = assistant.knowledge_bases?.map((base) => base.id)
|
||||
const hasKnowledgeBase = !isEmpty(knowledgeBaseIds)
|
||||
const knowledgeRecognition = assistant.knowledgeRecognition || 'on'
|
||||
const globalMemoryEnabled = selectGlobalMemoryEnabled(store.getState())
|
||||
const globalMemoryEnabled = await preferenceService.get('feature.memory.enabled')
|
||||
const shouldWebSearch = !!assistant.webSearchProviderId
|
||||
const shouldKnowledgeSearch = hasKnowledgeBase && knowledgeRecognition === 'on'
|
||||
const shouldMemorySearch = globalMemoryEnabled && assistant.enableMemory
|
||||
@ -369,7 +370,7 @@ export const searchOrchestrationPlugin = (assistant: Assistant, topicId: string)
|
||||
}
|
||||
|
||||
// 🧠 记忆搜索工具配置
|
||||
const globalMemoryEnabled = selectGlobalMemoryEnabled(store.getState())
|
||||
const globalMemoryEnabled = await preferenceService.get('feature.memory.enabled')
|
||||
if (globalMemoryEnabled && assistant.enableMemory) {
|
||||
// logger.info('🧠 Adding memory search tool')
|
||||
params.tools['builtin_memory_search'] = memorySearchTool()
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { preferenceService } from '@data/PreferenceService'
|
||||
import store from '@renderer/store'
|
||||
import { selectCurrentUserId, selectGlobalMemoryEnabled, selectMemoryConfig } from '@renderer/store/memory'
|
||||
import { selectMemoryConfig } from '@renderer/store/memory'
|
||||
import { type InferToolInput, type InferToolOutput, tool } from 'ai'
|
||||
import * as z from 'zod'
|
||||
|
||||
@ -18,7 +19,7 @@ export const memorySearchTool = () => {
|
||||
limit: z.number().min(1).max(20).default(5).describe('Maximum number of memories to return')
|
||||
}),
|
||||
execute: async ({ query, limit = 5 }) => {
|
||||
const globalMemoryEnabled = selectGlobalMemoryEnabled(store.getState())
|
||||
const globalMemoryEnabled = await preferenceService.get('feature.memory.enabled')
|
||||
if (!globalMemoryEnabled) {
|
||||
return []
|
||||
}
|
||||
@ -28,7 +29,7 @@ export const memorySearchTool = () => {
|
||||
return []
|
||||
}
|
||||
|
||||
const currentUserId = selectCurrentUserId(store.getState())
|
||||
const currentUserId = await preferenceService.get('feature.memory.current_user_id')
|
||||
const processorConfig = MemoryProcessor.getProcessorConfig(memoryConfig, 'default', currentUserId)
|
||||
|
||||
const memoryProcessor = new MemoryProcessor()
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import { Box, Button, InfoTooltip, Switch, Tooltip } from '@cherrystudio/ui'
|
||||
import { loggerService } from '@logger'
|
||||
import { usePreference } from '@renderer/data/hooks/usePreference'
|
||||
import MemoriesSettingsModal from '@renderer/pages/memory/settings-modal'
|
||||
import MemoryService from '@renderer/services/MemoryService'
|
||||
import { selectGlobalMemoryEnabled, selectMemoryConfig } from '@renderer/store/memory'
|
||||
import { selectMemoryConfig } from '@renderer/store/memory'
|
||||
import type { Assistant, AssistantSettings } from '@renderer/types'
|
||||
import { Alert, Card, Space, Typography } from 'antd'
|
||||
import { useForm } from 'antd/es/form/Form'
|
||||
@ -26,7 +27,7 @@ interface Props {
|
||||
const AssistantMemorySettings: React.FC<Props> = ({ assistant, updateAssistant, onClose }) => {
|
||||
const { t } = useTranslation()
|
||||
const memoryConfig = useSelector(selectMemoryConfig)
|
||||
const globalMemoryEnabled = useSelector(selectGlobalMemoryEnabled)
|
||||
const [globalMemoryEnabled] = usePreference('feature.memory.enabled')
|
||||
const [memoryStats, setMemoryStats] = useState<{ count: number; loading: boolean }>({
|
||||
count: 0,
|
||||
loading: true
|
||||
|
||||
@ -4,6 +4,7 @@ import { Flex } from '@cherrystudio/ui'
|
||||
import { Switch } from '@cherrystudio/ui'
|
||||
import { Button } from '@cherrystudio/ui'
|
||||
import { cacheService } from '@data/CacheService'
|
||||
import { usePreference } from '@data/hooks/usePreference'
|
||||
import { loggerService } from '@logger'
|
||||
import { DeleteIcon, EditIcon, LoadingIcon, RefreshIcon } from '@renderer/components/Icons'
|
||||
import TextBadge from '@renderer/components/TextBadge'
|
||||
@ -11,13 +12,7 @@ import { useTheme } from '@renderer/context/ThemeProvider'
|
||||
import { useModel } from '@renderer/hooks/useModel'
|
||||
import MemoriesSettingsModal from '@renderer/pages/memory/settings-modal'
|
||||
import MemoryService from '@renderer/services/MemoryService'
|
||||
import {
|
||||
selectCurrentUserId,
|
||||
selectGlobalMemoryEnabled,
|
||||
selectMemoryConfig,
|
||||
setCurrentUserId,
|
||||
setGlobalMemoryEnabled
|
||||
} from '@renderer/store/memory'
|
||||
import { selectMemoryConfig } from '@renderer/store/memory'
|
||||
import type { MemoryItem } from '@types'
|
||||
import { Badge, Dropdown, Empty, Form, Input, Modal, Pagination, Space, Spin } from 'antd'
|
||||
import dayjs from 'dayjs'
|
||||
@ -25,7 +20,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { Brain, Calendar, MenuIcon, PlusIcon, Settings2, UserRound, UserRoundMinus, UserRoundPlus } from 'lucide-react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useSelector } from 'react-redux'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import {
|
||||
@ -281,9 +276,8 @@ const AddUserModal: React.FC<AddUserModalProps> = ({ visible, onCancel, onAdd, e
|
||||
|
||||
const MemorySettings = () => {
|
||||
const { t } = useTranslation()
|
||||
const dispatch = useDispatch()
|
||||
const currentUser = useSelector(selectCurrentUserId)
|
||||
const globalMemoryEnabled = useSelector(selectGlobalMemoryEnabled)
|
||||
const [currentUser, setCurrentUserId] = usePreference('feature.memory.current_user_id')
|
||||
const [globalMemoryEnabled, setGlobalMemoryEnabled] = usePreference('feature.memory.enabled')
|
||||
|
||||
const [allMemories, setAllMemories] = useState<MemoryItem[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
@ -436,8 +430,8 @@ const MemorySettings = () => {
|
||||
const handleUserSwitch = async (userId: string) => {
|
||||
logger.verbose(`Switching to user: ${userId}`)
|
||||
|
||||
// First update Redux state
|
||||
dispatch(setCurrentUserId(userId))
|
||||
// First update preference state
|
||||
setCurrentUserId(userId)
|
||||
|
||||
// Clear current memories to show loading state immediately
|
||||
setAllMemories([])
|
||||
@ -483,7 +477,7 @@ const MemorySettings = () => {
|
||||
await memoryService.updateConfig()
|
||||
if (cacheService.get('memory.wait.settings')) {
|
||||
cacheService.delete('memory.wait.settings')
|
||||
dispatch(setGlobalMemoryEnabled(true))
|
||||
setGlobalMemoryEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +554,7 @@ const MemorySettings = () => {
|
||||
return setSettingsModalVisible(true)
|
||||
}
|
||||
|
||||
dispatch(setGlobalMemoryEnabled(enabled))
|
||||
setGlobalMemoryEnabled(enabled)
|
||||
|
||||
if (enabled) {
|
||||
return window.modal.confirm({
|
||||
|
||||
@ -6,9 +6,9 @@ import {
|
||||
FactRetrievalSchema,
|
||||
getFactRetrievalMessages,
|
||||
getUpdateMemoryMessages,
|
||||
MemoryUpdateSchema,
|
||||
updateMemorySystemPrompt
|
||||
MemoryUpdateSchema
|
||||
} from '@renderer/utils/memory-prompts'
|
||||
import { MEMORY_UPDATE_SYSTEM_PROMPT } from '@shared/config/prompts'
|
||||
import type { MemoryConfig, MemoryItem } from '@types'
|
||||
import jaison from 'jaison/lib/index.js'
|
||||
|
||||
@ -122,7 +122,7 @@ export class MemoryProcessor {
|
||||
const updateMemoryUserPrompt = getUpdateMemoryMessages(existingMemories, facts)
|
||||
|
||||
const responseContent = await fetchGenerate({
|
||||
prompt: updateMemorySystemPrompt,
|
||||
prompt: MEMORY_UPDATE_SYSTEM_PROMPT,
|
||||
content: updateMemoryUserPrompt,
|
||||
model: getModel(memoryConfig.llmApiClient.model, memoryConfig.llmApiClient.provider)
|
||||
})
|
||||
|
||||
@ -113,7 +113,9 @@ vi.mock(import('@renderer/config/providers'), async (importOriginal) => {
|
||||
vi.mock('@shared/config/prompts', () => ({
|
||||
WEB_SEARCH_PROMPT_FOR_OPENROUTER: 'mock-prompt',
|
||||
TRANSLATE_PROMPT:
|
||||
'You are a translation expert. Your only task is to translate text enclosed with <translate_input> from input language to {{target_language}}, provide the translation result directly without any explanation, without `TRANSLATE` and keep original format.'
|
||||
'You are a translation expert. Your only task is to translate text enclosed with <translate_input> from input language to {{target_language}}, provide the translation result directly without any explanation, without `TRANSLATE` and keep original format.',
|
||||
MEMORY_FACT_EXTRACTION_PROMPT: 'mock-memory-fact-extraction-prompt',
|
||||
MEMORY_UPDATE_SYSTEM_PROMPT: 'mock-memory-update-system-prompt'
|
||||
}))
|
||||
|
||||
vi.mock('@renderer/config/systemModels', () => ({
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
|
||||
import { factExtractionPrompt, updateMemorySystemPrompt } from '@renderer/utils/memory-prompts'
|
||||
import { MEMORY_FACT_EXTRACTION_PROMPT, MEMORY_UPDATE_SYSTEM_PROMPT } from '@shared/config/prompts'
|
||||
import type { MemoryConfig } from '@types'
|
||||
|
||||
/**
|
||||
@ -19,8 +19,8 @@ export interface MemoryState {
|
||||
const defaultMemoryConfig: MemoryConfig = {
|
||||
embedderDimensions: 1536,
|
||||
isAutoDimensions: true,
|
||||
customFactExtractionPrompt: factExtractionPrompt,
|
||||
customUpdateMemoryPrompt: updateMemorySystemPrompt
|
||||
customFactExtractionPrompt: MEMORY_FACT_EXTRACTION_PROMPT,
|
||||
customUpdateMemoryPrompt: MEMORY_UPDATE_SYSTEM_PROMPT
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user