From 69a037257e61fb74dfa012a62ad4933dd2dc44e9 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 2 Jan 2024 00:55:28 -0800 Subject: [PATCH] feat: prompt preset support --- .gitignore | 1 - src/lib/components/chat/MessageInput.svelte | 110 ++++++++++++---- .../chat/MessageInput/PromptCommands.svelte | 121 ++++++++++++++++++ src/lib/utils/index.ts | 16 +++ 4 files changed, 220 insertions(+), 28 deletions(-) create mode 100644 src/lib/components/chat/MessageInput/PromptCommands.svelte diff --git a/.gitignore b/.gitignore index 1250aef96..528e1f830 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index d2fe8ca29..b55d41924 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -3,6 +3,8 @@ import toast from 'svelte-french-toast'; import Suggestions from './MessageInput/Suggestions.svelte'; import { onMount } from 'svelte'; + import Prompts from './MessageInput/PromptCommands.svelte'; + import { findWordIndices } from '$lib/utils'; export let submitPrompt: Function; export let stopResponse: Function; @@ -11,6 +13,8 @@ export let autoScroll = true; let filesInputElement; + let promptsElement; + let inputFiles; let dragged = false; @@ -154,36 +158,42 @@
- {#if messages.length == 0 && suggestionPrompts.length !== 0} -
- +
+
+ {#if autoScroll === false && messages.length > 0} +
+ +
+ {/if}
- {/if} - {#if autoScroll === false && messages.length > 0} -
- +
+ {#if prompt.charAt(0) === '/'} + + {:else if messages.length == 0 && suggestionPrompts.length !== 0} + + {/if}
- {/if} +
@@ -315,6 +325,52 @@ userMessageElement.scrollIntoView({ block: 'center' }); editButton?.click(); } + + if (prompt.charAt(0) === '/' && e.key === 'Tab') { + e.preventDefault(); + + const commandOptionButton = [ + ...document.getElementsByClassName('selected-command-option-button') + ]?.at(-1); + + commandOptionButton?.click(); + } + + if (prompt.charAt(0) === '/' && e.key === 'ArrowUp') { + promptsElement.selectUp(); + + const commandOptionButton = [ + ...document.getElementsByClassName('selected-command-option-button') + ]?.at(-1); + commandOptionButton.scrollIntoView({ block: 'center' }); + } + + if (prompt.charAt(0) === '/' && e.key === 'ArrowDown') { + promptsElement.selectDown(); + + const commandOptionButton = [ + ...document.getElementsByClassName('selected-command-option-button') + ]?.at(-1); + commandOptionButton.scrollIntoView({ block: 'center' }); + } + + if (prompt.charAt(0) === '/' && e.key === 'Enter') { + e.preventDefault(); + + const commandOptionButton = [ + ...document.getElementsByClassName('selected-command-option-button') + ]?.at(-1); + + commandOptionButton?.click(); + } + + const words = findWordIndices(prompt); + + if (words.length > 0 && e.key === 'Tab') { + const word = words.at(0); + e.preventDefault(); + e.target.setSelectionRange(word?.startIndex, word.endIndex + 1); + } }} rows="1" on:input={(e) => { diff --git a/src/lib/components/chat/MessageInput/PromptCommands.svelte b/src/lib/components/chat/MessageInput/PromptCommands.svelte new file mode 100644 index 000000000..91e5f1aa4 --- /dev/null +++ b/src/lib/components/chat/MessageInput/PromptCommands.svelte @@ -0,0 +1,121 @@ + + +{#if filteredPromptCommands.length > 0} +
+
+
+
/
+
+
+ {#each filteredPromptCommands as command, commandIdx} + + {/each} +
+
+
+{/if} diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 8f7e711bf..344672da5 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -111,3 +111,19 @@ export const checkVersion = (required, current) => { caseFirst: 'upper' }) < 0; }; + +export const findWordIndices = (text) => { + const regex = /\[([^\]]+)\]/g; + let matches = []; + let match; + + while ((match = regex.exec(text)) !== null) { + matches.push({ + word: match[1], + startIndex: match.index, + endIndex: regex.lastIndex - 1 + }); + } + + return matches; +};