|
45 | 45 | showEmbeds, |
46 | 46 | selectedTerminalId, |
47 | 47 | showFileNavPath, |
48 | | - showFileNavDir |
| 48 | + showFileNavDir, |
| 49 | + chatRequestQueues |
49 | 50 | } from '$lib/stores'; |
50 | 51 |
|
51 | 52 | import { WEBUI_API_BASE_URL } from '$lib/constants'; |
|
170 | 171 | let files = []; |
171 | 172 | let params = {}; |
172 | 173 |
|
173 | | - // Message queue for storing messages while generating |
174 | | - let messageQueue: { id: string; prompt: string; files: any[] }[] = []; |
| 174 | +
|
175 | 175 |
|
176 | 176 | $: if (chatIdProp) { |
177 | 177 | navigateHandler(); |
|
180 | 180 | const navigateHandler = async () => { |
181 | 181 | loading = true; |
182 | 182 |
|
183 | | - // Save current queue to sessionStorage before navigating away |
184 | | - if (messageQueue.length > 0 && $chatId) { |
185 | | - sessionStorage.setItem(`chat-queue-${$chatId}`, JSON.stringify(messageQueue)); |
186 | | - } |
187 | | -
|
188 | 183 | prompt = ''; |
189 | 184 | messageInput?.setText(''); |
190 | 185 |
|
191 | 186 | files = []; |
192 | | - messageQueue = []; |
193 | 187 | selectedToolIds = []; |
194 | 188 | selectedFilterIds = []; |
195 | 189 | webSearchEnabled = false; |
|
206 | 200 |
|
207 | 201 | await tick(); |
208 | 202 |
|
209 | | - // Restore queue from sessionStorage |
210 | | - const storedQueueData = sessionStorage.getItem(`chat-queue-${chatIdProp}`); |
211 | | - if (storedQueueData) { |
212 | | - try { |
213 | | - const restoredQueue = JSON.parse(storedQueueData); |
214 | | -
|
215 | | - if (restoredQueue.length > 0) { |
216 | | - sessionStorage.removeItem(`chat-queue-${chatIdProp}`); |
217 | | - // Check if there are pending tasks (still generating) |
218 | | - const hasPendingTask = taskIds !== null && taskIds.length > 0; |
219 | | - if (!hasPendingTask) { |
220 | | - // No pending tasks - process the queue |
221 | | - files = restoredQueue.flatMap((m) => m.files); |
222 | | - await tick(); |
223 | | - const combinedPrompt = restoredQueue.map((m) => m.prompt).join('\n\n'); |
224 | | - await submitPrompt(combinedPrompt); |
225 | | - } else { |
226 | | - // Has pending tasks - show as queued (chatCompletedHandler will process) |
227 | | - messageQueue = restoredQueue; |
228 | | - } |
229 | | - } |
230 | | - } catch (e) {} |
| 203 | + // Process any queued requests if the chat is idle |
| 204 | + const lastMessage = history.currentId ? history.messages[history.currentId] : null; |
| 205 | + const isIdle = !lastMessage || lastMessage.role !== 'assistant' || lastMessage.done; |
| 206 | + if (isIdle) { |
| 207 | + await processNextInQueue(chatIdProp); |
231 | 208 | } |
232 | 209 |
|
233 | 210 | if (storageChatInput) { |
|
444 | 421 | for (const messageId of history.messages[message.parentId].childrenIds) { |
445 | 422 | history.messages[messageId].done = true; |
446 | 423 | } |
| 424 | + await processNextInQueue($chatId); |
447 | 425 | } else { |
448 | 426 | message.done = true; |
449 | 427 | } |
|
562 | 540 |
|
563 | 541 | history.messages[event.message_id] = message; |
564 | 542 | } |
| 543 | + } else { |
| 544 | + // Non-active chat completion: queue stays in the global store. |
| 545 | + // navigateHandler will process it when the user returns to that chat. |
565 | 546 | } |
566 | 547 | }; |
567 | 548 |
|
|
1155 | 1136 | chatFiles = []; |
1156 | 1137 | params = {}; |
1157 | 1138 | taskIds = null; |
1158 | | - messageQueue = []; |
1159 | 1139 |
|
1160 | 1140 | if ($page.url.searchParams.get('youtube')) { |
1161 | 1141 | await uploadWeb(`https://www.youtube.com/watch?v=${$page.url.searchParams.get('youtube')}`); |
|
1307 | 1287 | }); |
1308 | 1288 | } |
1309 | 1289 | }; |
| 1290 | +
|
| 1291 | + const processNextInQueue = async (targetChatId: string) => { |
| 1292 | + const queue = $chatRequestQueues[targetChatId]; |
| 1293 | + if (!queue || queue.length === 0) return; |
| 1294 | +
|
| 1295 | + const combinedPrompt = queue.map((m) => m.prompt).join('\n\n'); |
| 1296 | + const combinedFiles = queue.flatMap((m) => m.files); |
| 1297 | +
|
| 1298 | + chatRequestQueues.update((q) => { |
| 1299 | + const { [targetChatId]: _, ...rest } = q; |
| 1300 | + return rest; |
| 1301 | + }); |
| 1302 | +
|
| 1303 | + files = combinedFiles; |
| 1304 | + await tick(); |
| 1305 | + await submitPrompt(combinedPrompt); |
| 1306 | + }; |
| 1307 | +
|
1310 | 1308 | const chatCompletedHandler = async (_chatId, modelId, responseMessageId, messages) => { |
1311 | 1309 | const res = await chatCompleted(localStorage.token, { |
1312 | 1310 | model: modelId, |
|
1716 | 1714 | createMessagesList(history, message.id) |
1717 | 1715 | ); |
1718 | 1716 |
|
1719 | | - // Process message queue immediately after main response finishes |
1720 | | - if (messageQueue.length > 0) { |
1721 | | - const combinedPrompt = messageQueue.map((m) => m.prompt).join('\n\n'); |
1722 | | - const combinedFiles = messageQueue.flatMap((m) => m.files); |
1723 | | - messageQueue = []; |
1724 | | -
|
1725 | | - files = combinedFiles; |
1726 | | - await tick(); |
1727 | | - await submitPrompt(combinedPrompt); |
1728 | | - } |
| 1717 | + // Process next queued request if any |
| 1718 | + await processNextInQueue(chatId); |
1729 | 1719 | } |
1730 | 1720 |
|
1731 | 1721 | console.log(data); |
|
1789 | 1779 |
|
1790 | 1780 | if (isGenerating) { |
1791 | 1781 | if ($settings?.enableMessageQueue ?? true) { |
1792 | | - // Queue the message |
| 1782 | + // Enqueue the request |
1793 | 1783 | const _files = structuredClone(files); |
1794 | | - messageQueue = [ |
1795 | | - ...messageQueue, |
1796 | | - { |
1797 | | - id: uuidv4(), |
1798 | | - prompt: userPrompt, |
1799 | | - files: _files |
1800 | | - } |
1801 | | - ]; |
| 1784 | + chatRequestQueues.update((q) => ({ |
| 1785 | + ...q, |
| 1786 | + [$chatId]: [ |
| 1787 | + ...(q[$chatId] ?? []), |
| 1788 | + { id: uuidv4(), prompt: userPrompt, files: _files } |
| 1789 | + ] |
| 1790 | + })); |
1802 | 1791 | // Clear input |
1803 | 1792 | messageInput?.setText(''); |
1804 | 1793 | prompt = ''; |
|
2392 | 2381 | generationController?.abort(); |
2393 | 2382 | generationController = null; |
2394 | 2383 | } |
| 2384 | +
|
| 2385 | + await processNextInQueue($chatId); |
2395 | 2386 | }; |
2396 | 2387 |
|
2397 | 2388 | const submitMessage = async (parentId, prompt) => { |
|
2845 | 2836 | {stopResponse} |
2846 | 2837 | {createMessagePair} |
2847 | 2838 | {onUpload} |
2848 | | - {messageQueue} |
| 2839 | + messageQueue={$chatRequestQueues[$chatId] ?? []} |
2849 | 2840 | onQueueSendNow={async (id) => { |
2850 | | - const item = messageQueue.find((m) => m.id === id); |
| 2841 | + const queue = $chatRequestQueues[$chatId] ?? []; |
| 2842 | + const item = queue.find((m) => m.id === id); |
2851 | 2843 | if (item) { |
2852 | 2844 | // Remove from queue |
2853 | | - messageQueue = messageQueue.filter((m) => m.id !== id); |
| 2845 | + chatRequestQueues.update((q) => ({ |
| 2846 | + ...q, |
| 2847 | + [$chatId]: queue.filter((m) => m.id !== id) |
| 2848 | + })); |
2854 | 2849 | // Stop current generation first |
2855 | 2850 | await stopResponse(); |
2856 | 2851 | await tick(); |
|
2861 | 2856 | } |
2862 | 2857 | }} |
2863 | 2858 | onQueueEdit={(id) => { |
2864 | | - const item = messageQueue.find((m) => m.id === id); |
| 2859 | + const queue = $chatRequestQueues[$chatId] ?? []; |
| 2860 | + const item = queue.find((m) => m.id === id); |
2865 | 2861 | if (item) { |
2866 | 2862 | // Remove from queue |
2867 | | - messageQueue = messageQueue.filter((m) => m.id !== id); |
| 2863 | + chatRequestQueues.update((q) => ({ |
| 2864 | + ...q, |
| 2865 | + [$chatId]: queue.filter((m) => m.id !== id) |
| 2866 | + })); |
2868 | 2867 | // Set files and restore prompt to input |
2869 | 2868 | files = item.files; |
2870 | 2869 | messageInput?.setText(item.prompt); |
2871 | 2870 | } |
2872 | 2871 | }} |
2873 | 2872 | onQueueDelete={(id) => { |
2874 | | - messageQueue = messageQueue.filter((m) => m.id !== id); |
| 2873 | + const queue = $chatRequestQueues[$chatId] ?? []; |
| 2874 | + chatRequestQueues.update((q) => ({ |
| 2875 | + ...q, |
| 2876 | + [$chatId]: queue.filter((m) => m.id !== id) |
| 2877 | + })); |
2875 | 2878 | }} |
2876 | 2879 | onChange={(data) => { |
2877 | 2880 | if (!$temporaryChatEnabled) { |
|
0 commit comments