From 69a037257e61fb74dfa012a62ad4933dd2dc44e9 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 2 Jan 2024 00:55:28 -0800 Subject: [PATCH 1/3] 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 1250aef9..528e1f83 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 d2fe8ca2..b55d4192 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 00000000..91e5f1aa --- /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 8f7e711b..344672da 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; +}; From e02b06a0bf841035f568f5c0ca922e2ae9484c34 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 2 Jan 2024 01:12:49 -0800 Subject: [PATCH 2/3] feat: more prompt presets added --- src/lib/components/chat/MessageInput.svelte | 43 ++++--- .../chat/MessageInput/PromptCommands.svelte | 108 +++++++++++++++++- 2 files changed, 133 insertions(+), 18 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index b55d4192..89cea47f 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -2,7 +2,7 @@ import { settings } from '$lib/stores'; import toast from 'svelte-french-toast'; import Suggestions from './MessageInput/Suggestions.svelte'; - import { onMount } from 'svelte'; + import { onMount, tick } from 'svelte'; import Prompts from './MessageInput/PromptCommands.svelte'; import { findWordIndices } from '$lib/utils'; @@ -308,7 +308,7 @@ submitPrompt(prompt); } }} - on:keydown={(e) => { + on:keydown={async (e) => { if (prompt === '' && e.key == 'ArrowUp') { e.preventDefault(); @@ -326,16 +326,6 @@ 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(); @@ -364,12 +354,31 @@ commandOptionButton?.click(); } - const words = findWordIndices(prompt); - - if (words.length > 0 && e.key === 'Tab') { - const word = words.at(0); + if (prompt.charAt(0) === '/' && e.key === 'Tab') { e.preventDefault(); - e.target.setSelectionRange(word?.startIndex, word.endIndex + 1); + + const commandOptionButton = [ + ...document.getElementsByClassName('selected-command-option-button') + ]?.at(-1); + + commandOptionButton?.click(); + } else if (e.key === 'Tab') { + const words = findWordIndices(prompt); + + if (words.length > 0) { + const word = words.at(0); + const fullPrompt = prompt; + + prompt = prompt.substring(0, word?.endIndex + 1); + await tick(); + + e.target.scrollTop = e.target.scrollHeight; + prompt = fullPrompt; + await tick(); + + e.preventDefault(); + e.target.setSelectionRange(word?.startIndex, word.endIndex + 1); + } } }} rows="1" diff --git a/src/lib/components/chat/MessageInput/PromptCommands.svelte b/src/lib/components/chat/MessageInput/PromptCommands.svelte index 91e5f1aa..2b41bac0 100644 --- a/src/lib/components/chat/MessageInput/PromptCommands.svelte +++ b/src/lib/components/chat/MessageInput/PromptCommands.svelte @@ -43,12 +43,118 @@ include relevant statistics (add the links of the sources you use) and consider title: 'SEO Content Brief', content: `Create a SEO content brief for [keyword].` + }, + { + command: '/seo-ideas', + + title: 'SEO Keyword Ideas', + content: `Generate a list of 20 keyword ideas on [topic]. + +Cluster this list of keywords according to funnel stages whether they are top of the funnel, middle of the funnel or bottom of the funnel keywords.` + }, + { + command: '/summary', + + title: 'Short Summary', + content: `Write a summary in 50 words that summarizes [topic or keyword].` + }, + { + command: '/email-subject', + + title: 'Email Subject Line', + content: `Develop [5] subject lines for a cold email offering your [product or service] to a potential client.` + }, + { + command: '/facebook-ads', + + title: 'Facebook Ads', + content: `Create 3 variations of effective ad copy to promote [product] for [audience]. + +Make sure they are [persuasive/playful/emotional] and mention these benefits: + +[Benefit 1] + +[Benefit 2] + +[Benefit 3] + +Finish with a call to action saying [CTA]. + +Add 3 emojis to it.` + }, + { + command: '/google-ads', + + title: 'Google Ads', + content: `Create 10 google ads (a headline and a description) for [product description] targeting the keyword [keyword]. + +The headline of the ad needs to be under 30 characters. The description needs to be under 90 characters. Format the output as a table.` + }, + { + command: '/insta-caption', + + title: 'Instagram Caption', + content: `Write 5 variations of Instagram captions for [product]. + +Use friendly, human-like language that appeals to [target audience]. + +Emphasize the unique qualities of [product], + +use ample emojis, and don't sound too promotional.` + }, + { + command: '/linkedin-post', + + title: 'LinkedIn Post', + content: `Create a narrative Linkedin post using immersive writing about [topic]. + +Details: + +[give details in bullet point format] + +Use a mix of short and long sentences. Make it punchy and dramatic.` + }, + { + command: '/youtube-desc', + + title: 'YouTube Video', + content: `Write a 100-word YouTube video description that compels [audience] + +to watch a video on [topic] + +and mentions the following keywords + +[keyword 1] + +[keyword 2] + +[keyword 3].` + }, + { + command: '/seo-meta', + + title: 'SEO Meta', + content: `Suggest a meta description for the content above, make it user-friendly and with a call to action, include the keyword [keyword].` + }, + { + command: '/eli5', + + title: 'ELI5', + content: `You are an expert teacher with the ability to explain complex topics in simpler terms. Explain the concept of [topic] in simple terms, so that my [grade level/subject] class can understand [this concept/specific example]?` + }, + { + command: '/emoji-translate', + + title: 'Emoji Translation', + content: `You are an emoji expert. Using only emojis, translate the following text to emojis. [insert numbered sentences].` } ]; let filteredPromptCommands = []; - $: filteredPromptCommands = promptCommands.filter((p) => p.command.includes(prompt)); + $: filteredPromptCommands = promptCommands + .filter((p) => p.command.includes(prompt)) + .sort((a, b) => a.title.localeCompare(b.title)); $: if (prompt) { selectedCommandIdx = 0; From 96b198b27be9d4e608f096ff59fa9d033154caaa Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 2 Jan 2024 01:18:14 -0800 Subject: [PATCH 3/3] fix: formatting --- src/lib/components/chat/MessageInput.svelte | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index 89cea47f..55683329 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -1,11 +1,12 @@