فهرست منبع

feat: create new message pair on cmd+shift+enter

Timothy J. Baek 7 ماه پیش
والد
کامیت
ad82eae6a9

+ 84 - 19
src/lib/components/chat/Chat.svelte

@@ -559,6 +559,66 @@
 		}, 1000);
 	};
 
+	const createMessagePair = async (userPrompt) => {
+		prompt = '';
+		if (selectedModels.length === 0) {
+			toast.error($i18n.t('Model not selected'));
+		} else {
+			const modelId = selectedModels[0];
+			const model = $models.filter((m) => m.id === modelId).at(0);
+
+			const messages = createMessagesList(history.currentId);
+			const parentMessage = messages.length !== 0 ? messages.at(-1) : null;
+
+			const userMessageId = uuidv4();
+			const responseMessageId = uuidv4();
+
+			const userMessage = {
+				id: userMessageId,
+				parentId: parentMessage ? parentMessage.id : null,
+				childrenIds: [responseMessageId],
+				role: 'user',
+				content: userPrompt ? userPrompt : `[PROMPT] ${userMessageId}`,
+				timestamp: Math.floor(Date.now() / 1000)
+			};
+
+			const responseMessage = {
+				id: responseMessageId,
+				parentId: userMessageId,
+				childrenIds: [],
+				role: 'assistant',
+				content: `[RESPONSE] ${responseMessageId}`,
+				done: true,
+
+				model: modelId,
+				modelName: model.name ?? model.id,
+				modelIdx: 0,
+				timestamp: Math.floor(Date.now() / 1000)
+			};
+
+			if (parentMessage) {
+				parentMessage.childrenIds.push(userMessageId);
+				history.messages[parentMessage.id] = parentMessage;
+			}
+			history.messages[userMessageId] = userMessage;
+			history.messages[responseMessageId] = responseMessage;
+
+			history.currentId = responseMessageId;
+
+			await tick();
+
+			if (autoScroll) {
+				scrollToBottom();
+			}
+
+			if (messages.length === 0) {
+				await initChatHandler();
+			} else {
+				await saveChatHandler($chatId);
+			}
+		}
+	};
+
 	//////////////////////////
 	// Chat functions
 	//////////////////////////
@@ -666,25 +726,7 @@
 			history.messages[history.currentId].parentId === null &&
 			history.messages[history.currentId].role === 'user'
 		) {
-			if (!$temporaryChatEnabled) {
-				chat = await createNewChat(localStorage.token, {
-					id: $chatId,
-					title: $i18n.t('New Chat'),
-					models: selectedModels,
-					system: $settings.system ?? undefined,
-					params: params,
-					history: history,
-					tags: [],
-					timestamp: Date.now()
-				});
-
-				currentChatPage.set(1);
-				await chats.set(await getChatList(localStorage.token, $currentChatPage));
-				await chatId.set(chat.id);
-			} else {
-				await chatId.set('local');
-			}
-			await tick();
+			await initChatHandler();
 		}
 
 		let _responses: string[] = [];
@@ -1718,6 +1760,28 @@
 		});
 	};
 
+	const initChatHandler = async () => {
+		if (!$temporaryChatEnabled) {
+			chat = await createNewChat(localStorage.token, {
+				id: $chatId,
+				title: $i18n.t('New Chat'),
+				models: selectedModels,
+				system: $settings.system ?? undefined,
+				params: params,
+				history: history,
+				tags: [],
+				timestamp: Date.now()
+			});
+
+			currentChatPage.set(1);
+			await chats.set(await getChatList(localStorage.token, $currentChatPage));
+			await chatId.set(chat.id);
+		} else {
+			await chatId.set('local');
+		}
+		await tick();
+	};
+
 	const saveChatHandler = async (_chatId) => {
 		if ($chatId == _chatId) {
 			if (!$temporaryChatEnabled) {
@@ -1861,6 +1925,7 @@
 							transparentBackground={$settings?.backgroundImageUrl ?? false}
 							{submitPrompt}
 							{stopResponse}
+							{createMessagePair}
 							on:call={async () => {
 								await showControls.set(true);
 							}}

+ 7 - 0
src/lib/components/chat/MessageInput.svelte

@@ -41,6 +41,7 @@
 	export let transparentBackground = false;
 
 	export let submitPrompt: Function;
+	export let createMessagePair: Function;
 	export let stopResponse: Function;
 
 	export let autoScroll = false;
@@ -554,6 +555,12 @@
 										const isCtrlPressed = e.ctrlKey || e.metaKey; // metaKey is for Cmd key on Mac
 										const commandsContainerElement = document.getElementById('commands-container');
 
+										// Command/Ctrl + Shift + Enter to submit a message pair
+										if (isCtrlPressed && e.key === 'Enter' && e.shiftKey) {
+											e.preventDefault();
+											createMessagePair(prompt);
+										}
+
 										// Check if Ctrl + R is pressed
 										if (prompt === '' && isCtrlPressed && e.key.toLowerCase() === 'r') {
 											e.preventDefault();

+ 18 - 18
src/lib/components/chat/Messages.svelte

@@ -49,7 +49,7 @@
 
 		let message = history.messages[history.currentId];
 		while (message && _messages.length <= messagesCount) {
-			_messages.push({ ...message });
+			_messages.unshift({ ...message });
 			message = message.parentId !== null ? history.messages[message.parentId] : null;
 		}
 
@@ -341,7 +341,23 @@
 	{:else}
 		<div class="w-full pt-2">
 			{#key chatId}
-				<div class="w-full flex flex-col-reverse">
+				<div class="w-full">
+					{#if messages.at(0)?.parentId !== null}
+						<Loader
+							on:visible={(e) => {
+								console.log('visible');
+								if (!messagesLoading) {
+									loadMoreMessages();
+								}
+							}}
+						>
+							<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
+								<Spinner className=" size-4" />
+								<div class=" ">Loading...</div>
+							</div>
+						</Loader>
+					{/if}
+
 					{#each messages as message, messageIdx (message.id)}
 						<Message
 							{chatId}
@@ -372,22 +388,6 @@
 							}}
 						/>
 					{/each}
-
-					{#if messages.at(-1).parentId !== null}
-						<Loader
-							on:visible={(e) => {
-								console.log('visible');
-								if (!messagesLoading) {
-									loadMoreMessages();
-								}
-							}}
-						>
-							<div class="w-full flex justify-center py-1 text-xs animate-pulse items-center gap-2">
-								<Spinner className=" size-4" />
-								<div class=" ">Loading...</div>
-							</div>
-						</Loader>
-					{/if}
 				</div>
 				<div class="pb-12" />
 				{#if bottomPadding}

+ 1 - 1
src/lib/components/chat/Messages/Message.svelte

@@ -41,7 +41,7 @@
 	export let readOnly = false;
 
 	onMount(() => {
-		console.log('message', idx);
+		// console.log('message', idx);
 	});
 </script>