From 81f239849a892d6b2df00e3bd73e2dfbdf19d69a Mon Sep 17 00:00:00 2001 From: Luca Gutzeit Date: Mon, 31 Mar 2025 11:13:55 +0200 Subject: [PATCH] Support for Images in Prompt Suggestions --- backend/open_webui/routers/configs.py | 1 + src/lib/components/chat/Chat.svelte | 1 + src/lib/components/chat/Messages.svelte | 14 +++++++++++--- src/lib/components/chat/Placeholder.svelte | 11 ++++++++--- src/lib/components/chat/Suggestions.svelte | 16 +++++++++++++--- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py index 2a4c651f2..8cdda72a6 100644 --- a/backend/open_webui/routers/configs.py +++ b/backend/open_webui/routers/configs.py @@ -206,6 +206,7 @@ async def set_models_config( class PromptSuggestion(BaseModel): title: list[str] content: str + imageUrl: str = "" class SetDefaultSuggestionsForm(BaseModel): diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index c168d628e..5ddf0151e 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -2015,6 +2015,7 @@ bind:history bind:autoScroll bind:prompt + bind:files {selectedModels} {atSelectedModel} {sendPrompt} diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index b55a27b40..17173d2ee 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -30,6 +30,7 @@ export let user = $_user; export let prompt; + export let files = []; export let history = {}; export let selectedModels; export let atSelectedModel; @@ -394,15 +395,22 @@ modelIds={selectedModels} {atSelectedModel} submitPrompt={async (p) => { - let text = p; + const {content, imageUrl} = p; + let text = content; - if (p.includes('{{CLIPBOARD}}')) { + if (content.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); + text = content.replaceAll('{{CLIPBOARD}}', clipboardText); + + console.log('Clipboard text:', clipboardText, text); + } + + if (imageUrl !== "") { + files = [{ type: 'image', url: imageUrl }] } prompt = text; diff --git a/src/lib/components/chat/Placeholder.svelte b/src/lib/components/chat/Placeholder.svelte index f6cbf47b5..f3883e872 100644 --- a/src/lib/components/chat/Placeholder.svelte +++ b/src/lib/components/chat/Placeholder.svelte @@ -43,18 +43,23 @@ let models = []; const selectSuggestionPrompt = async (p) => { - let text = p; + const {content, imageUrl} = p; + let text = content; - if (p.includes('{{CLIPBOARD}}')) { + if (content.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); + text = content.replaceAll('{{CLIPBOARD}}', clipboardText); console.log('Clipboard text:', clipboardText, text); } + + if (imageUrl !== "") { + files = [{ type: 'image', url: imageUrl }] + } prompt = text; diff --git a/src/lib/components/chat/Suggestions.svelte b/src/lib/components/chat/Suggestions.svelte index 746e13e51..e9139ab6b 100644 --- a/src/lib/components/chat/Suggestions.svelte +++ b/src/lib/components/chat/Suggestions.svelte @@ -5,6 +5,8 @@ import { WEBUI_NAME } from '$lib/stores'; import { WEBUI_VERSION } from '$lib/constants'; + import Image from '../common/Image.svelte'; + const i18n = getContext('i18n'); const dispatch = createEventDispatcher(); @@ -83,11 +85,11 @@ {#if filteredPrompts.length > 0} {#each filteredPrompts as prompt, idx (prompt.id || prompt.content)} {/each} {/if}