|
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' |
|
type Tab = 'documents' | 'knowledge-graph' | 'retrieval' | 'api' |
|
|
|
interface SettingsState { |
|
|
|
showFileName: boolean |
|
setShowFileName: (show: boolean) => 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 |
|
} |
|
|
|
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, |
|
|
|
retrievalHistory: [], |
|
|
|
querySettings: { |
|
mode: 'global', |
|
response_type: 'Multiple Paragraphs', |
|
top_k: 40, |
|
chunk_top_k: 10, |
|
max_entity_tokens: 10000, |
|
max_relation_tokens: 10000, |
|
max_total_tokens: 32000, |
|
only_need_context: false, |
|
only_need_prompt: false, |
|
stream: true, |
|
history_turns: 3, |
|
user_prompt: '', |
|
enable_rerank: true |
|
}, |
|
|
|
setTheme: (theme: Theme) => set({ theme }), |
|
|
|
setLanguage: (language: Language) => { |
|
set({ language }) |
|
|
|
import('i18next').then(({ default: i18n }) => { |
|
if (i18n.language !== language) { |
|
i18n.changeLanguage(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>) => |
|
set((state) => ({ |
|
querySettings: { ...state.querySettings, ...settings } |
|
})), |
|
|
|
setShowFileName: (show: boolean) => set({ showFileName: show }), |
|
setShowLegend: (show: boolean) => set({ showLegend: show }) |
|
}), |
|
{ |
|
name: 'settings-storage', |
|
storage: createJSONStorage(() => localStorage), |
|
version: 15, |
|
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: 3, |
|
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, |
|
} |
|
} |
|
return state |
|
} |
|
} |
|
) |
|
) |
|
|
|
const useSettingsStore = createSelectors(useSettingsStoreBase) |
|
|
|
export { useSettingsStore, type Theme } |
|
|