| import { create } from 'zustand' |
| import { persist, createJSONStorage } from 'zustand/middleware' |
| import { createSelectors } from '@/lib/utils' |
| import { defaultQueryLabel } from '@/lib/constants' |
| import { Message, QueryRequest } from '@/api/lightrag' |
|
|
| type Theme = 'dark' | 'light' | 'system' |
| type Language = 'en' | 'zh' | 'fr' | 'ar' | 'zh_TW' | 'ru' | 'ja' | 'de' | 'uk' | 'ko' | 'vi' |
| type Tab = 'documents' | 'knowledge-graph' | 'retrieval' | 'api' |
|
|
| interface SettingsState { |
| |
| showFileName: boolean |
| setShowFileName: (show: boolean) => void |
|
|
| documentsPageSize: number |
| setDocumentsPageSize: (size: number) => void |
|
|
| |
| userPromptHistory: string[] |
| addUserPromptToHistory: (prompt: string) => void |
| setUserPromptHistory: (history: string[]) => void |
|
|
| |
| showPropertyPanel: boolean |
| showNodeSearchBar: boolean |
| showLegend: boolean |
| setShowLegend: (show: boolean) => void |
|
|
| showNodeLabel: boolean |
| enableNodeDrag: boolean |
|
|
| showEdgeLabel: boolean |
| enableHideUnselectedEdges: boolean |
| enableEdgeEvents: boolean |
|
|
| minEdgeSize: number |
| setMinEdgeSize: (size: number) => void |
|
|
| maxEdgeSize: number |
| setMaxEdgeSize: (size: number) => void |
|
|
| graphQueryMaxDepth: number |
| setGraphQueryMaxDepth: (depth: number) => void |
|
|
| graphMaxNodes: number |
| setGraphMaxNodes: (nodes: number, triggerRefresh?: boolean) => void |
|
|
| backendMaxGraphNodes: number | null |
| setBackendMaxGraphNodes: (maxNodes: number | null) => void |
|
|
| graphLayoutMaxIterations: number |
| setGraphLayoutMaxIterations: (iterations: number) => void |
|
|
| |
| queryLabel: string |
| setQueryLabel: (queryLabel: string) => void |
|
|
| retrievalHistory: Message[] |
| setRetrievalHistory: (history: Message[]) => void |
|
|
| querySettings: Omit<QueryRequest, 'query'> |
| updateQuerySettings: (settings: Partial<QueryRequest>) => void |
|
|
| |
| apiKey: string | null |
| setApiKey: (key: string | null) => void |
|
|
| |
| theme: Theme |
| setTheme: (theme: Theme) => void |
|
|
| language: Language |
| setLanguage: (lang: Language) => void |
|
|
| enableHealthCheck: boolean |
| setEnableHealthCheck: (enable: boolean) => void |
|
|
| currentTab: Tab |
| setCurrentTab: (tab: Tab) => void |
|
|
| |
| searchLabelDropdownRefreshTrigger: number |
| triggerSearchLabelDropdownRefresh: () => void |
| } |
|
|
| const useSettingsStoreBase = create<SettingsState>()( |
| persist( |
| (set) => ({ |
| theme: 'system', |
| language: 'en', |
| showPropertyPanel: true, |
| showNodeSearchBar: true, |
| showLegend: false, |
|
|
| showNodeLabel: true, |
| enableNodeDrag: true, |
|
|
| showEdgeLabel: false, |
| enableHideUnselectedEdges: true, |
| enableEdgeEvents: false, |
|
|
| minEdgeSize: 1, |
| maxEdgeSize: 1, |
|
|
| graphQueryMaxDepth: 3, |
| graphMaxNodes: 1000, |
| backendMaxGraphNodes: null, |
| graphLayoutMaxIterations: 15, |
|
|
| queryLabel: defaultQueryLabel, |
|
|
| enableHealthCheck: true, |
|
|
| apiKey: null, |
|
|
| currentTab: 'documents', |
| showFileName: false, |
| documentsPageSize: 10, |
|
|
| retrievalHistory: [], |
| userPromptHistory: [], |
|
|
| querySettings: { |
| mode: 'global', |
| top_k: 40, |
| chunk_top_k: 20, |
| max_entity_tokens: 6000, |
| max_relation_tokens: 8000, |
| max_total_tokens: 30000, |
| only_need_context: false, |
| only_need_prompt: false, |
| stream: true, |
| history_turns: 0, |
| user_prompt: '', |
| enable_rerank: true |
| }, |
|
|
| setTheme: (theme: Theme) => set({ theme }), |
|
|
| setLanguage: (language: Language) => { |
| set({ language }) |
| }, |
|
|
| setGraphLayoutMaxIterations: (iterations: number) => |
| set({ |
| graphLayoutMaxIterations: iterations |
| }), |
|
|
| setQueryLabel: (queryLabel: string) => |
| set({ |
| queryLabel |
| }), |
|
|
| setGraphQueryMaxDepth: (depth: number) => set({ graphQueryMaxDepth: depth }), |
|
|
| setGraphMaxNodes: (nodes: number, triggerRefresh: boolean = false) => { |
| const state = useSettingsStore.getState(); |
| if (state.graphMaxNodes === nodes) { |
| return; |
| } |
|
|
| if (triggerRefresh) { |
| const currentLabel = state.queryLabel; |
| |
| set({ graphMaxNodes: nodes, queryLabel: '' }); |
|
|
| |
| setTimeout(() => { |
| set({ queryLabel: currentLabel }); |
| }, 300); |
| } else { |
| set({ graphMaxNodes: nodes }); |
| } |
| }, |
|
|
| setBackendMaxGraphNodes: (maxNodes: number | null) => set({ backendMaxGraphNodes: maxNodes }), |
|
|
| setMinEdgeSize: (size: number) => set({ minEdgeSize: size }), |
|
|
| setMaxEdgeSize: (size: number) => set({ maxEdgeSize: size }), |
|
|
| setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }), |
|
|
| setApiKey: (apiKey: string | null) => set({ apiKey }), |
|
|
| setCurrentTab: (tab: Tab) => set({ currentTab: tab }), |
|
|
| setRetrievalHistory: (history: Message[]) => set({ retrievalHistory: history }), |
|
|
| updateQuerySettings: (settings: Partial<QueryRequest>) => { |
| |
| const filteredSettings = { ...settings } |
| delete filteredSettings.history_turns |
| set((state) => ({ |
| querySettings: { ...state.querySettings, ...filteredSettings, history_turns: 0 } |
| })) |
| }, |
|
|
| setShowFileName: (show: boolean) => set({ showFileName: show }), |
| setShowLegend: (show: boolean) => set({ showLegend: show }), |
| setDocumentsPageSize: (size: number) => set({ documentsPageSize: size }), |
|
|
| |
| addUserPromptToHistory: (prompt: string) => { |
| if (!prompt.trim()) return |
|
|
| set((state) => { |
| const newHistory = [...state.userPromptHistory] |
|
|
| |
| const existingIndex = newHistory.indexOf(prompt) |
| if (existingIndex !== -1) { |
| newHistory.splice(existingIndex, 1) |
| } |
|
|
| |
| newHistory.unshift(prompt) |
|
|
| |
| if (newHistory.length > 12) { |
| newHistory.splice(12) |
| } |
|
|
| return { userPromptHistory: newHistory } |
| }) |
| }, |
|
|
| setUserPromptHistory: (history: string[]) => set({ userPromptHistory: history }), |
|
|
| |
| searchLabelDropdownRefreshTrigger: 0, |
| triggerSearchLabelDropdownRefresh: () => |
| set((state) => ({ |
| searchLabelDropdownRefreshTrigger: state.searchLabelDropdownRefreshTrigger + 1 |
| })) |
| }), |
| { |
| name: 'settings-storage', |
| storage: createJSONStorage(() => localStorage), |
| version: 19, |
| migrate: (state: any, version: number) => { |
| if (version < 2) { |
| state.showEdgeLabel = false |
| } |
| if (version < 3) { |
| state.queryLabel = defaultQueryLabel |
| } |
| if (version < 4) { |
| state.showPropertyPanel = true |
| state.showNodeSearchBar = true |
| state.showNodeLabel = true |
| state.enableHealthCheck = true |
| state.apiKey = null |
| } |
| if (version < 5) { |
| state.currentTab = 'documents' |
| } |
| if (version < 6) { |
| state.querySettings = { |
| mode: 'global', |
| response_type: 'Multiple Paragraphs', |
| top_k: 10, |
| max_token_for_text_unit: 4000, |
| max_token_for_global_context: 4000, |
| max_token_for_local_context: 4000, |
| only_need_context: false, |
| only_need_prompt: false, |
| stream: true, |
| history_turns: 0, |
| hl_keywords: [], |
| ll_keywords: [] |
| } |
| state.retrievalHistory = [] |
| } |
| if (version < 7) { |
| state.graphQueryMaxDepth = 3 |
| state.graphLayoutMaxIterations = 15 |
| } |
| if (version < 8) { |
| state.graphMinDegree = 0 |
| state.language = 'en' |
| } |
| if (version < 9) { |
| state.showFileName = false |
| } |
| if (version < 10) { |
| delete state.graphMinDegree |
| state.graphMaxNodes = 1000 |
| } |
| if (version < 11) { |
| state.minEdgeSize = 1 |
| state.maxEdgeSize = 1 |
| } |
| if (version < 12) { |
| |
| state.retrievalHistory = [] |
| } |
| if (version < 13) { |
| |
| if (state.querySettings) { |
| state.querySettings.user_prompt = '' |
| } |
| } |
| if (version < 14) { |
| |
| state.backendMaxGraphNodes = null |
| } |
| if (version < 15) { |
| |
| state.querySettings = { |
| ...state.querySettings, |
| mode: 'mix', |
| response_type: 'Multiple Paragraphs', |
| top_k: 40, |
| chunk_top_k: 10, |
| max_entity_tokens: 10000, |
| max_relation_tokens: 10000, |
| max_total_tokens: 32000, |
| enable_rerank: true, |
| history_turns: 0, |
| } |
| } |
| if (version < 16) { |
| |
| state.documentsPageSize = 10 |
| } |
| if (version < 17) { |
| |
| if (state.querySettings) { |
| state.querySettings.history_turns = 0 |
| } |
| } |
| if (version < 18) { |
| |
| state.userPromptHistory = [] |
| } |
| if (version < 19) { |
| |
| if (state.querySettings) { |
| delete state.querySettings.response_type |
| } |
| } |
| return state |
| } |
| } |
| ) |
| ) |
|
|
| const useSettingsStore = createSelectors(useSettingsStoreBase) |
|
|
| export { useSettingsStore, type Theme } |
|
|