From 0319e63999bf795c24cbd6a53c66da28ec7dba3f Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sat, 5 Oct 2024 03:07:56 -0700 Subject: [PATCH] enh: new landing page --- src/lib/components/chat/Chat.svelte | 107 +++++--- src/lib/components/chat/MessageInput.svelte | 52 ++-- .../chat/MessageInput/Suggestions.svelte | 120 ++------- src/lib/components/chat/Messages.svelte | 38 +-- .../chat/Messages/OldPlaceholder.svelte | 135 ++++++++++ .../chat/Messages/Placeholder.svelte | 254 ++++++++++++------ 6 files changed, 421 insertions(+), 285 deletions(-) create mode 100644 src/lib/components/chat/Messages/OldPlaceholder.svelte diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 81416e77f..fd28d417a 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -70,6 +70,7 @@ import Navbar from '$lib/components/layout/Navbar.svelte'; import ChatControls from './ChatControls.svelte'; import EventConfirmDialog from '../common/ConfirmDialog.svelte'; + import Placeholder from './Messages/Placeholder.svelte'; export let chatIdProp = ''; @@ -689,7 +690,6 @@ ); files = []; - prompt = ''; // Create user message @@ -1954,49 +1954,85 @@ {/if}
- -
- + {$i18n.t('LLMs can make mistakes. Verify important information.')} +
+
+ {:else} + { const model = $models.find((m) => m.id === e); if (model?.info?.meta?.toolIds ?? false) { @@ -2005,14 +2041,17 @@ return a; }, [])} transparentBackground={$settings?.backgroundImageUrl ?? false} - {submitPrompt} {stopResponse} {createMessagePair} - on:call={async () => { - await showControls.set(true); + on:submit={async (e) => { + if (e.detail) { + prompt = ''; + await tick(); + submitPrompt(e.detail); + } }} /> - + {/if} diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index d3e17ba00..4d10a2e7a 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -12,21 +12,14 @@ config, showCallOverlay, tools, - user as _user + user as _user, + showControls } from '$lib/stores'; import { blobToFile, findWordIndices } from '$lib/utils'; - import { transcribeAudio } from '$lib/apis/audio'; - - import { processFile } from '$lib/apis/retrieval'; import { uploadFile } from '$lib/apis/files'; - import { - SUPPORTED_FILE_TYPE, - SUPPORTED_FILE_EXTENSIONS, - WEBUI_BASE_URL, - WEBUI_API_BASE_URL - } from '$lib/constants'; + import { WEBUI_BASE_URL, WEBUI_API_BASE_URL } from '$lib/constants'; import Tooltip from '../common/Tooltip.svelte'; import InputMenu from './MessageInput/InputMenu.svelte'; @@ -41,7 +34,6 @@ export let transparentBackground = false; - export let submitPrompt: Function; export let createMessagePair: Function; export let stopResponse: Function; @@ -50,6 +42,14 @@ export let atSelectedModel: Model | undefined; export let selectedModels: ['']; + export let history; + + export let prompt = ''; + export let files = []; + export let availableToolIds = []; + export let selectedToolIds = []; + export let webSearchEnabled = false; + let recording = false; let chatTextAreaElement: HTMLTextAreaElement; @@ -61,15 +61,7 @@ let dragged = false; let user = null; - let chatInputPlaceholder = ''; - - export let history; - - export let prompt = ''; - export let files = []; - export let availableToolIds = []; - export let selectedToolIds = []; - export let webSearchEnabled = false; + export let placeholder = ''; let visionCapableModels = []; $: visionCapableModels = [...(atSelectedModel ? [atSelectedModel] : selectedModels)].filter( @@ -241,7 +233,7 @@
-
+
{#if autoScroll === false && history?.currentId}
-
+
@@ -371,7 +363,7 @@ class="w-full flex gap-1.5" on:submit|preventDefault={() => { // check if selectedModels support image input - submitPrompt(prompt); + dispatch('submit', prompt); }} >
{ if ( @@ -523,7 +513,7 @@ // Submit the prompt when Enter key is pressed if (prompt !== '' && e.key === 'Enter' && !e.shiftKey) { - submitPrompt(prompt); + dispatch('submit', prompt); } } }} @@ -760,7 +750,7 @@ stream = null; showCallOverlay.set(true); - dispatch('call'); + showControls.set(true); } catch (err) { // If the user denies the permission or an error occurs, show an error message toast.error($i18n.t('Permission denied when accessing media devices')); @@ -825,10 +815,6 @@
{/if} - -
- {$i18n.t('LLMs can make mistakes. Verify important information.')} -
diff --git a/src/lib/components/chat/MessageInput/Suggestions.svelte b/src/lib/components/chat/MessageInput/Suggestions.svelte index 8c549b67b..e931ca600 100644 --- a/src/lib/components/chat/MessageInput/Suggestions.svelte +++ b/src/lib/components/chat/MessageInput/Suggestions.svelte @@ -1,10 +1,10 @@ {#if prompts.length > 0} @@ -39,80 +21,32 @@
{/if} -
-
- {#each prompts as prompt, promptIdx} -
- +
Prompt
+ {/if}
- {/each} - - -
+ + {/each}
- - diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index a75046277..b0c322a66 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -310,43 +310,7 @@
{#if Object.keys(history?.messages ?? {}).length == 0} - { - let text = p; - - if (p.includes('{{CLIPBOARD}}')) { - const clipboardText = await navigator.clipboard.readText().catch((err) => { - toast.error($i18n.t('Failed to read clipboard contents')); - return '{{CLIPBOARD}}'; - }); - - text = p.replaceAll('{{CLIPBOARD}}', clipboardText); - } - - prompt = text; - - await tick(); - - const chatInputElement = document.getElementById('chat-textarea'); - if (chatInputElement) { - prompt = p; - - chatInputElement.style.height = ''; - chatInputElement.style.height = Math.min(chatInputElement.scrollHeight, 200) + 'px'; - chatInputElement.focus(); - - const words = findWordIndices(prompt); - - if (words.length > 0) { - const word = words.at(0); - chatInputElement.setSelectionRange(word?.startIndex, word.endIndex + 1); - } - } - - await tick(); - }} - /> + {:else}
{#key chatId} diff --git a/src/lib/components/chat/Messages/OldPlaceholder.svelte b/src/lib/components/chat/Messages/OldPlaceholder.svelte new file mode 100644 index 000000000..51cc7c9eb --- /dev/null +++ b/src/lib/components/chat/Messages/OldPlaceholder.svelte @@ -0,0 +1,135 @@ + + +{#key mounted} +
+
+
+ {#each models as model, modelIdx} + + {/each} +
+
+ + {#if $temporaryChatEnabled} + +
+ Temporary Chat +
+
+ {/if} + +
+
+
+ {#if models[selectedModelIdx]?.info} + {models[selectedModelIdx]?.info?.name} + {:else} + {$i18n.t('Hello, {{name}}', { name: $user.name })} + {/if} +
+ +
+ {#if models[selectedModelIdx]?.info?.meta?.description ?? null} +
+ {@html marked.parse( + sanitizeResponseContent(models[selectedModelIdx]?.info?.meta?.description) + )} +
+ {#if models[selectedModelIdx]?.info?.meta?.user} +
+ By + {#if models[selectedModelIdx]?.info?.meta?.user.community} + {models[selectedModelIdx]?.info?.meta?.user.name + ? models[selectedModelIdx]?.info?.meta?.user.name + : `@${models[selectedModelIdx]?.info?.meta?.user.username}`} + {:else} + {models[selectedModelIdx]?.info?.meta?.user.name} + {/if} +
+ {/if} + {:else} +
+ {$i18n.t('How can I help you today?')} +
+ {/if} +
+
+
+ +
+ +
+
+{/key} diff --git a/src/lib/components/chat/Messages/Placeholder.svelte b/src/lib/components/chat/Messages/Placeholder.svelte index 51cc7c9eb..b54c15572 100644 --- a/src/lib/components/chat/Messages/Placeholder.svelte +++ b/src/lib/components/chat/Messages/Placeholder.svelte @@ -1,32 +1,87 @@ {#key mounted} -
-
-
- {#each models as model, modelIdx} - - {/each} -
-
- +
{#if $temporaryChatEnabled}
@@ -78,58 +103,111 @@ {/if}
-
-
- {#if models[selectedModelIdx]?.info} - {models[selectedModelIdx]?.info?.name} - {:else} - {$i18n.t('Hello, {{name}}', { name: $user.name })} - {/if} +
+ +
+
+ {#each models as model, modelIdx} + + {/each} +
+
+ +
+ {#if models[selectedModelIdx]?.info} + {models[selectedModelIdx]?.info?.name} + {:else} + {$i18n.t('Hello, {{name}}', { name: $user.name })} + {/if} +
+
+ +
+
+ {#if models[selectedModelIdx]?.info?.meta?.description ?? null} +
+ {@html marked.parse( + sanitizeResponseContent(models[selectedModelIdx]?.info?.meta?.description) + )} +
+ {#if models[selectedModelIdx]?.info?.meta?.user} +
+ By + {#if models[selectedModelIdx]?.info?.meta?.user.community} + {models[selectedModelIdx]?.info?.meta?.user.name + ? models[selectedModelIdx]?.info?.meta?.user.name + : `@${models[selectedModelIdx]?.info?.meta?.user.username}`} + {:else} + {models[selectedModelIdx]?.info?.meta?.user.name} + {/if} +
+ {/if} + {/if} +
-
- {#if models[selectedModelIdx]?.info?.meta?.description ?? null} -
- {@html marked.parse( - sanitizeResponseContent(models[selectedModelIdx]?.info?.meta?.description) - )} -
- {#if models[selectedModelIdx]?.info?.meta?.user} -
- By - {#if models[selectedModelIdx]?.info?.meta?.user.community} - {models[selectedModelIdx]?.info?.meta?.user.name - ? models[selectedModelIdx]?.info?.meta?.user.name - : `@${models[selectedModelIdx]?.info?.meta?.user.username}`} - {:else} - {models[selectedModelIdx]?.info?.meta?.user.name} - {/if} -
- {/if} - {:else} -
- {$i18n.t('How can I help you today?')} -
- {/if} +
+ { + dispatch('submit', e.detail); + }} + />
- -
- +
+
+ { + selectSuggestionPrompt(e.detail); + }} + /> +
{/key}