From ad82eae6a99df8c31475e54a49596a055f84075e Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 24 Sep 2024 00:57:28 +0200 Subject: [PATCH] feat: create new message pair on cmd+shift+enter --- src/lib/components/chat/Chat.svelte | 103 ++++++++++++++---- src/lib/components/chat/MessageInput.svelte | 7 ++ src/lib/components/chat/Messages.svelte | 36 +++--- .../components/chat/Messages/Message.svelte | 2 +- 4 files changed, 110 insertions(+), 38 deletions(-) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 9b490eca8..4f227c090 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/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); }} diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index bb5250def..f474b755b 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/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(); diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index d6d2b881a..aa1cfb433 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/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}
{#key chatId} -
+
+ {#if messages.at(0)?.parentId !== null} + { + console.log('visible'); + if (!messagesLoading) { + loadMoreMessages(); + } + }} + > +
+ +
Loading...
+
+
+ {/if} + {#each messages as message, messageIdx (message.id)} {/each} - - {#if messages.at(-1).parentId !== null} - { - console.log('visible'); - if (!messagesLoading) { - loadMoreMessages(); - } - }} - > -
- -
Loading...
-
-
- {/if}
{#if bottomPadding} diff --git a/src/lib/components/chat/Messages/Message.svelte b/src/lib/components/chat/Messages/Message.svelte index dd5c498a3..3b07ef3db 100644 --- a/src/lib/components/chat/Messages/Message.svelte +++ b/src/lib/components/chat/Messages/Message.svelte @@ -41,7 +41,7 @@ export let readOnly = false; onMount(() => { - console.log('message', idx); + // console.log('message', idx); });