@@ -19,6 +19,52 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
1919 status . value ?. state === 'Starting' || status . value ?. state === 'Stopping' )
2020
2121 let connection : signalR . HubConnection | null = null
22+ let downloadSyncTimer : ReturnType < typeof setInterval > | null = null
23+ let isSyncingDownloads = false
24+
25+ function replaceDownloads ( items : LocalLlmDownloadProgress [ ] ) {
26+ downloads . value = new Map ( items . map ( item => [ item . catalogId , item ] ) )
27+ }
28+
29+ function stopDownloadSync ( ) {
30+ if ( downloadSyncTimer !== null ) {
31+ clearInterval ( downloadSyncTimer )
32+ downloadSyncTimer = null
33+ }
34+ }
35+
36+ function ensureDownloadSync ( ) {
37+ if ( downloadSyncTimer !== null ) return
38+
39+ downloadSyncTimer = setInterval ( ( ) => {
40+ void syncDownloadState ( )
41+ } , 3000 )
42+ }
43+
44+ async function syncDownloadState ( ) {
45+ if ( isSyncingDownloads ) return
46+ isSyncingDownloads = true
47+
48+ try {
49+ const [ currentSettings , activeDownloads ] = await Promise . all ( [
50+ localLlmApi . getSettings ( ) ,
51+ localLlmApi . getActiveDownloads ( ) ,
52+ ] )
53+
54+ settings . value = currentSettings
55+ replaceDownloads ( activeDownloads )
56+
57+ if ( activeDownloads . length > 0 ) {
58+ ensureDownloadSync ( )
59+ } else {
60+ stopDownloadSync ( )
61+ }
62+ } catch {
63+ // Keep the last known UI state if reconciliation fails temporarily.
64+ } finally {
65+ isSyncingDownloads = false
66+ }
67+ }
2268
2369 async function connect ( ) {
2470 if ( connection && connection . state !== signalR . HubConnectionState . Disconnected ) return
@@ -36,16 +82,15 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
3682 if ( progress . done || progress . error ) {
3783 downloads . value . delete ( progress . catalogId )
3884 downloads . value = new Map ( downloads . value )
39- if ( progress . done && ! progress . error ) {
40- fetchModels ( )
41- }
85+ void syncDownloadState ( )
4286 } else if ( progress . paused ) {
4387 downloads . value . delete ( progress . catalogId )
4488 downloads . value = new Map ( downloads . value )
45- fetchSettings ( )
89+ void syncDownloadState ( )
4690 } else {
4791 downloads . value . set ( progress . catalogId , progress )
4892 downloads . value = new Map ( downloads . value )
93+ ensureDownloadSync ( )
4994 }
5095 } )
5196
@@ -62,10 +107,12 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
62107
63108 connection . onreconnected ( async ( ) => {
64109 try { await connection ?. invoke ( 'JoinLocalLlmGroup' ) } catch { /* ignore */ }
110+ void syncDownloadState ( )
65111 } )
66112
67113 await connection . start ( )
68114 await connection . invoke ( 'JoinLocalLlmGroup' )
115+ await syncDownloadState ( )
69116 }
70117
71118 async function disconnect ( ) {
@@ -74,6 +121,7 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
74121 await connection . stop ( )
75122 connection = null
76123 }
124+ stopDownloadSync ( )
77125 }
78126
79127 async function fetchStatus ( ) {
@@ -117,6 +165,15 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
117165
118166 async function downloadModel ( catalogId : string ) {
119167 await localLlmApi . downloadModel ( catalogId )
168+ downloads . value . set ( catalogId , {
169+ catalogId,
170+ bytesDownloaded : 0 ,
171+ totalBytes : 0 ,
172+ speedBytesPerSec : 0 ,
173+ done : false ,
174+ } )
175+ downloads . value = new Map ( downloads . value )
176+ ensureDownloadSync ( )
120177 }
121178
122179 async function pauseDownload ( catalogId : string ) {
@@ -127,7 +184,7 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
127184 await localLlmApi . cancelDownload ( catalogId )
128185 downloads . value . delete ( catalogId )
129186 downloads . value = new Map ( downloads . value )
130- await fetchSettings ( )
187+ await syncDownloadState ( )
131188 }
132189
133190 async function downloadLlama ( ) {
@@ -148,7 +205,7 @@ export const useLocalLlmStore = defineStore('localLlm', () => {
148205 status, settings, gpus, catalog, downloads, llamaStatus, llamaDownload,
149206 isRunning, isStarting, isBusy,
150207 connect, disconnect,
151- fetchStatus, fetchSettings, fetchGpus, refreshGpus, fetchCatalog, fetchLlamaStatus, fetchModels,
208+ fetchStatus, fetchSettings, fetchGpus, refreshGpus, fetchCatalog, fetchLlamaStatus, fetchModels, syncDownloadState ,
152209 startServer, stopServer, downloadModel, pauseDownload, cancelDownload,
153210 downloadLlama, cancelLlamaDownload, retryLlamaDownload,
154211 }
0 commit comments