Skip to content

Commit d784eb1

Browse files
committed
refac
1 parent 6a00420 commit d784eb1

2 files changed

Lines changed: 63 additions & 57 deletions

File tree

src/lib/components/chat/Chat.svelte

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
showEmbeds,
4646
selectedTerminalId,
4747
showFileNavPath,
48-
showFileNavDir
48+
showFileNavDir,
49+
chatRequestQueues
4950
} from '$lib/stores';
5051
5152
import { WEBUI_API_BASE_URL } from '$lib/constants';
@@ -170,8 +171,7 @@
170171
let files = [];
171172
let params = {};
172173
173-
// Message queue for storing messages while generating
174-
let messageQueue: { id: string; prompt: string; files: any[] }[] = [];
174+
175175
176176
$: if (chatIdProp) {
177177
navigateHandler();
@@ -180,16 +180,10 @@
180180
const navigateHandler = async () => {
181181
loading = true;
182182
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-
188183
prompt = '';
189184
messageInput?.setText('');
190185
191186
files = [];
192-
messageQueue = [];
193187
selectedToolIds = [];
194188
selectedFilterIds = [];
195189
webSearchEnabled = false;
@@ -206,28 +200,11 @@
206200
207201
await tick();
208202
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);
231208
}
232209
233210
if (storageChatInput) {
@@ -444,6 +421,7 @@
444421
for (const messageId of history.messages[message.parentId].childrenIds) {
445422
history.messages[messageId].done = true;
446423
}
424+
await processNextInQueue($chatId);
447425
} else {
448426
message.done = true;
449427
}
@@ -562,6 +540,9 @@
562540
563541
history.messages[event.message_id] = message;
564542
}
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.
565546
}
566547
};
567548
@@ -1155,7 +1136,6 @@
11551136
chatFiles = [];
11561137
params = {};
11571138
taskIds = null;
1158-
messageQueue = [];
11591139
11601140
if ($page.url.searchParams.get('youtube')) {
11611141
await uploadWeb(`https://www.youtube.com/watch?v=${$page.url.searchParams.get('youtube')}`);
@@ -1307,6 +1287,24 @@
13071287
});
13081288
}
13091289
};
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+
13101308
const chatCompletedHandler = async (_chatId, modelId, responseMessageId, messages) => {
13111309
const res = await chatCompleted(localStorage.token, {
13121310
model: modelId,
@@ -1716,16 +1714,8 @@
17161714
createMessagesList(history, message.id)
17171715
);
17181716
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);
17291719
}
17301720
17311721
console.log(data);
@@ -1789,16 +1779,15 @@
17891779
17901780
if (isGenerating) {
17911781
if ($settings?.enableMessageQueue ?? true) {
1792-
// Queue the message
1782+
// Enqueue the request
17931783
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+
}));
18021791
// Clear input
18031792
messageInput?.setText('');
18041793
prompt = '';
@@ -2392,6 +2381,8 @@
23922381
generationController?.abort();
23932382
generationController = null;
23942383
}
2384+
2385+
await processNextInQueue($chatId);
23952386
};
23962387
23972388
const submitMessage = async (parentId, prompt) => {
@@ -2845,12 +2836,16 @@
28452836
{stopResponse}
28462837
{createMessagePair}
28472838
{onUpload}
2848-
{messageQueue}
2839+
messageQueue={$chatRequestQueues[$chatId] ?? []}
28492840
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);
28512843
if (item) {
28522844
// 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+
}));
28542849
// Stop current generation first
28552850
await stopResponse();
28562851
await tick();
@@ -2861,17 +2856,25 @@
28612856
}
28622857
}}
28632858
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);
28652861
if (item) {
28662862
// 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+
}));
28682867
// Set files and restore prompt to input
28692868
files = item.files;
28702869
messageInput?.setText(item.prompt);
28712870
}
28722871
}}
28732872
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+
}));
28752878
}}
28762879
onChange={(data) => {
28772880
if (!$temporaryChatEnabled) {

src/lib/stores/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ export const banners: Writable<Banner[]> = writable([]);
8080
export const settings: Writable<Settings> = writable({});
8181

8282
export const audioQueue = writable<AudioQueue | null>(null);
83+
export const chatRequestQueues: Writable<
84+
Record<string, { id: string; prompt: string; files: any[] }[]>
85+
> = writable({});
8386

8487
export const sidebarWidth = writable(260);
8588

0 commit comments

Comments
 (0)