@@ -4,7 +4,6 @@ import appPackage from "../../../package.json";
44import { useTheme } from "../../contexts/ThemeContext" ;
55import { useToastContext } from "../../contexts/ToastContext" ;
66import {
7- getResponseQualityThresholds ,
87 type ResponseQualityThresholds ,
98 resetResponseQualityThresholds ,
109 saveResponseQualityThresholds ,
@@ -18,13 +17,6 @@ import { useKb } from "../../hooks/useKb";
1817import { useLlm } from "../../hooks/useLlm" ;
1918import { useSearchApiEmbedding } from "../../hooks/useSearchApiEmbedding" ;
2019import { useSettingsOps } from "../../hooks/useSettingsOps" ;
21- import type { ModelInfo } from "../../types/llm" ;
22- import type {
23- AuditEntry ,
24- DeploymentHealthSummary ,
25- IntegrationConfigRecord ,
26- MemoryKernelPreflightStatus ,
27- } from "../../types/settings" ;
2820import {
2921 formatAuditEvent ,
3022 formatBytes ,
@@ -33,6 +25,7 @@ import {
3325 getSearchApiEmbeddingBadge ,
3426 validateQualityThresholds ,
3527} from "./SettingsTab.helpers" ;
28+ import { useSettingsInit } from "./useSettingsInit" ;
3629import { AdvancedSearchSection } from "./sections/AdvancedSearchSection" ;
3730import { ContextWindowSection } from "./sections/ContextWindowSection" ;
3831import { JiraSection } from "./sections/JiraSection" ;
@@ -131,87 +124,81 @@ export function SettingsTab() {
131124 deleteVariable,
132125 } = useCustomVariables ( ) ;
133126
134- const [ loadedModel , setLoadedModel ] = useState < string | null > ( null ) ;
135- const [ loadedModelInfo , setLoadedModelInfo ] = useState < ModelInfo | null > (
136- null ,
137- ) ;
138- const [ downloadedModels , setDownloadedModels ] = useState < string [ ] > ( [ ] ) ;
139- const [ kbFolder , setKbFolderState ] = useState < string | null > ( null ) ;
140- const [ indexStats , setIndexStats ] = useState < {
141- total_chunks : number ;
142- total_files : number ;
143- } | null > ( null ) ;
144- const [ vectorEnabled , setVectorEnabled ] = useState ( false ) ;
145- const [ jiraConfigured , setJiraConfigured ] = useState ( false ) ;
146- const [ contextWindowSize , setContextWindowSize ] = useState < number | null > (
147- null ,
148- ) ;
149- const [ embeddingDownloaded , setEmbeddingDownloaded ] = useState ( false ) ;
150- const [ allowUnverifiedLocalModels , setAllowUnverifiedLocalModels ] =
151- useState ( false ) ;
127+ const init = useSettingsInit ( {
128+ getLoadedModel,
129+ getModelInfo,
130+ listModels,
131+ getKbFolder,
132+ getIndexStats,
133+ getVectorConsent,
134+ getContextWindow,
135+ checkJiraConfig,
136+ isEmbeddingDownloaded,
137+ getDeploymentHealthSummary,
138+ listIntegrations,
139+ checkEmbeddingStatus,
140+ refreshSearchApiEmbeddingStatus,
141+ onShowError : showError ,
142+ } ) ;
143+
144+ const {
145+ loadedModel,
146+ setLoadedModel,
147+ loadedModelInfo,
148+ setLoadedModelInfo,
149+ downloadedModels,
150+ setDownloadedModels,
151+ kbFolder,
152+ setKbFolder : setKbFolderState ,
153+ indexStats,
154+ setIndexStats,
155+ vectorEnabled,
156+ setVectorEnabled,
157+ jiraConfigured,
158+ setJiraConfigured,
159+ contextWindowSize,
160+ setContextWindowSize,
161+ embeddingDownloaded,
162+ setEmbeddingDownloaded,
163+ allowUnverifiedLocalModels,
164+ setAllowUnverifiedLocalModels,
165+ deploymentHealth,
166+ setDeploymentHealth,
167+ integrations,
168+ setIntegrations,
169+ qualityThresholds,
170+ setQualityThresholds,
171+ memoryKernelPreflight,
172+ memoryKernelLoading,
173+ auditEntries,
174+ auditLoading,
175+ auditPage,
176+ setAuditPage,
177+ loadInitialState,
178+ loadAuditEntries,
179+ refreshMemoryKernelStatus,
180+ } = init ;
181+
152182 const [ generatingEmbeddings , setGeneratingEmbeddings ] = useState ( false ) ;
153183 const [ loading , setLoading ] = useState < string | null > ( null ) ;
154184 const [ error , setError ] = useState < string | null > ( null ) ;
155185 const [ backupLoading , setBackupLoading ] = useState <
156186 "export" | "import" | null
157187 > ( null ) ;
158- const [ auditEntries , setAuditEntries ] = useState < AuditEntry [ ] > ( [ ] ) ;
159- const [ auditLoading , setAuditLoading ] = useState ( false ) ;
160188 const [ auditExporting , setAuditExporting ] = useState ( false ) ;
161189 const [ auditSeverityFilter , setAuditSeverityFilter ] = useState <
162190 "all" | "info" | "warning" | "error" | "critical"
163191 > ( "all" ) ;
164192 const [ auditSearchQuery , setAuditSearchQuery ] = useState ( "" ) ;
165- const [ auditPage , setAuditPage ] = useState ( 1 ) ;
166-
167- const [ deploymentHealth , setDeploymentHealth ] =
168- useState < DeploymentHealthSummary | null > ( null ) ;
169193 const [ deployPreflightChecks , setDeployPreflightChecks ] = useState < string [ ] > (
170194 [ ] ,
171195 ) ;
172196 const [ deployPreflightRunning , setDeployPreflightRunning ] = useState ( false ) ;
173- const [ integrations , setIntegrations ] = useState < IntegrationConfigRecord [ ] > (
174- [ ] ,
175- ) ;
176- const [ qualityThresholds , setQualityThresholds ] =
177- useState < ResponseQualityThresholds > ( ( ) => getResponseQualityThresholds ( ) ) ;
178197 const [ qualityThresholdError , setQualityThresholdError ] = useState <
179198 string | null
180199 > ( null ) ;
181- const [ memoryKernelPreflight , setMemoryKernelPreflight ] =
182- useState < MemoryKernelPreflightStatus | null > ( null ) ;
183- const [ memoryKernelLoading , setMemoryKernelLoading ] = useState ( false ) ;
184200 const revampFlags = useMemo ( ( ) => resolveRevampFlags ( ) , [ ] ) ;
185201
186- const loadAuditEntries = useCallback ( async ( ) => {
187- setAuditLoading ( true ) ;
188- try {
189- const entries = await invoke < AuditEntry [ ] > ( "get_audit_entries" , {
190- limit : 200 ,
191- } ) ;
192- setAuditEntries ( entries ?? [ ] ) ;
193- setAuditPage ( 1 ) ;
194- } catch ( err ) {
195- showError ( `Failed to load audit logs: ${ err } ` ) ;
196- } finally {
197- setAuditLoading ( false ) ;
198- }
199- } , [ showError ] ) ;
200-
201- const refreshMemoryKernelStatus = useCallback ( async ( ) => {
202- setMemoryKernelLoading ( true ) ;
203- try {
204- const status = await invoke < MemoryKernelPreflightStatus > (
205- "get_memory_kernel_preflight_status" ,
206- ) ;
207- setMemoryKernelPreflight ( status ) ;
208- } catch {
209- setMemoryKernelPreflight ( null ) ;
210- } finally {
211- setMemoryKernelLoading ( false ) ;
212- }
213- } , [ ] ) ;
214-
215202 const filteredAuditEntries = useMemo ( ( ) => {
216203 const normalized = auditEntries . slice ( ) . reverse ( ) ;
217204 const query = auditSearchQuery . trim ( ) . toLowerCase ( ) ;
@@ -239,83 +226,18 @@ export function SettingsTab() {
239226
240227 useEffect ( ( ) => {
241228 setAuditPage ( ( prev ) => Math . min ( prev , auditTotalPages ) ) ;
242- } , [ auditTotalPages ] ) ;
243-
244- useEffect ( ( ) => {
245- refreshMemoryKernelStatus ( ) ;
246- } , [ refreshMemoryKernelStatus ] ) ;
229+ } , [ auditTotalPages , setAuditPage ] ) ;
247230
248231 const pagedAuditEntries = useMemo ( ( ) => {
249232 const start = ( auditPage - 1 ) * AUDIT_PAGE_SIZE ;
250233 return filteredAuditEntries . slice ( start , start + AUDIT_PAGE_SIZE ) ;
251234 } , [ filteredAuditEntries , auditPage ] ) ;
252235
253236 useEffect ( ( ) => {
254- Promise . resolve ( loadInitialState ( ) ) . catch ( ( err ) =>
255- console . error ( "Settings init failed:" , err ) ,
256- ) ;
257237 Promise . resolve ( loadVariables ( ) ) . catch ( ( err ) =>
258238 console . error ( "Variables load failed:" , err ) ,
259239 ) ;
260- Promise . resolve ( loadAuditEntries ( ) ) . catch ( ( err ) =>
261- console . error ( "Audit load failed:" , err ) ,
262- ) ;
263- // eslint-disable-next-line react-hooks/exhaustive-deps
264- } , [ loadVariables , loadAuditEntries ] ) ;
265-
266- async function loadInitialState ( ) {
267- try {
268- const [
269- loaded ,
270- modelInfo ,
271- downloaded ,
272- folder ,
273- stats ,
274- consent ,
275- jiraConfigResult ,
276- ctxWindow ,
277- embDownloaded ,
278- allowUnverifiedModels ,
279- deployHealth ,
280- integrationsList ,
281- ] = await Promise . all ( [
282- getLoadedModel ( ) ,
283- getModelInfo ( ) . catch ( ( ) => null ) ,
284- listModels ( ) ,
285- getKbFolder ( ) ,
286- getIndexStats ( ) . catch ( ( ) => null ) ,
287- getVectorConsent ( ) . catch ( ( ) => null ) ,
288- checkJiraConfig ( ) . catch ( ( ) => false ) ,
289- getContextWindow ( ) . catch ( ( ) => null ) ,
290- isEmbeddingDownloaded ( ) . catch ( ( ) => false ) ,
291- invoke < boolean > ( "get_allow_unverified_local_models" ) . catch ( ( ) => false ) ,
292- getDeploymentHealthSummary ( ) . catch ( ( ) => null ) ,
293- listIntegrations ( ) . catch ( ( ) => [ ] ) ,
294- ] ) ;
295- setLoadedModel ( loaded ) ;
296- setLoadedModelInfo ( modelInfo ) ;
297- setDownloadedModels ( downloaded ) ;
298- setKbFolderState ( folder ) ;
299- setIndexStats ( stats ) ;
300- if ( consent ) {
301- setVectorEnabled ( consent . enabled ) ;
302- }
303- setJiraConfigured ( jiraConfigResult ) ;
304- setContextWindowSize ( ctxWindow ) ;
305- setEmbeddingDownloaded ( embDownloaded ) ;
306- setAllowUnverifiedLocalModels ( allowUnverifiedModels ) ;
307- setDeploymentHealth ( deployHealth ) ;
308- setIntegrations ( integrationsList ?? [ ] ) ;
309- setQualityThresholds ( getResponseQualityThresholds ( ) ) ;
310-
311- await Promise . all ( [
312- checkEmbeddingStatus ( ) ,
313- refreshSearchApiEmbeddingStatus ( ) ,
314- ] ) ;
315- } catch ( err ) {
316- console . error ( "Failed to load settings state:" , err ) ;
317- }
318- }
240+ } , [ loadVariables ] ) ;
319241
320242 async function handleVectorToggle ( ) {
321243 const newValue = ! vectorEnabled ;
0 commit comments