From 40a7ac9caac1e38c04d48f30a13704e1d11dbad1 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sun, 18 Feb 2024 14:56:31 -0800 Subject: [PATCH 01/25] feat: delete message scaffolding --- .../chat/Messages/UserMessage.svelte | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index 998fe4e43..78eadb68a 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -281,6 +281,30 @@ /> + + {/if} From c3ed6fe974c5debcd1d4281c2b331c9199db5c42 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Sun, 18 Feb 2024 14:58:26 -0800 Subject: [PATCH 02/25] Update UserMessage.svelte --- src/lib/components/chat/Messages/UserMessage.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index 78eadb68a..196e5972c 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -295,7 +295,7 @@ viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" - class="w-6 h-6" + class="w-4 h-4" > Date: Sun, 18 Feb 2024 17:03:40 -0800 Subject: [PATCH 03/25] add isFirstMessage prop to UserMessage component --- src/lib/components/chat/Messages.svelte | 1 + src/lib/components/chat/Messages/UserMessage.svelte | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index b02ba1166..082b65fc2 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -239,6 +239,7 @@ - + {/if} {/if} From 60c99a44f8cacd687ae0e3cea123365a1506c567 Mon Sep 17 00:00:00 2001 From: Danny Liu Date: Tue, 20 Feb 2024 13:24:22 -0800 Subject: [PATCH 04/25] remove user message and response from DOM as pair --- src/lib/components/chat/Messages.svelte | 166 ++++++++++-------- .../chat/Messages/UserMessage.svelte | 8 +- 2 files changed, 93 insertions(+), 81 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 082b65fc2..53292027d 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -221,6 +221,15 @@ scrollToBottom(); }, 100); }; + + const deleteMessage = async (messageId) => { + history.messages[messageId].deleted = true; + history.messages[history.messages[messageId].childrenIds[0]].deleted = true; + updateChatById(localStorage.token, chatId, { + messages: messages, + history: history + }); + }; {#if messages.length == 0} @@ -229,90 +238,93 @@
{#key chatId} {#each messages as message, messageIdx} -
-
- {#if message.role === 'user'} - message.parentId === null) - .map((message) => message.id) ?? []} - {confirmEditMessage} - {showPreviousMessage} - {showNextMessage} - {copyToClipboard} - /> + {#if !message.deleted} +
+
+ {#if message.role === 'user'} + deleteMessage(message.id)} + user={$user} + {message} + isFirstMessage={messageIdx === 0} + siblings={message.parentId !== null + ? history.messages[message.parentId]?.childrenIds ?? [] + : Object.values(history.messages) + .filter((message) => message.parentId === null) + .map((message) => message.id) ?? []} + {confirmEditMessage} + {showPreviousMessage} + {showNextMessage} + {copyToClipboard} + /> - {#if messages.length - 1 === messageIdx && processing !== ''} -
-
-
+
+ + @keyframes spinner_8HQG { + 0%, + 57.14% { + animation-timing-function: cubic-bezier(0.33, 0.66, 0.66, 1); + transform: translate(0); + } + 28.57% { + animation-timing-function: cubic-bezier(0.33, 0, 0.66, 0.33); + transform: translateY(-6px); + } + 100% { + transform: translate(0); + } + } + +
+
+ {processing} +
-
- {processing} -
-
+ {/if} + {:else} + {/if} - {:else} - - {/if} +
-
+ {/if} {/each} {#if bottomPadding} diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index f64b98df8..7dfca9e36 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -1,11 +1,13 @@ @@ -247,7 +246,7 @@ > {#if message.role === 'user'} deleteMessage(message.id)} + on:delete={() => deleteMessagePair(message.id)} user={$user} {message} isFirstMessage={messageIdx === 0} diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index 7dfca9e36..ca1cff59d 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -45,6 +45,10 @@ edit = false; editedContent = ''; }; + + const deleteMessageHandler = async () => { + dispatch('delete', message.id); + };
@@ -288,7 +292,9 @@ {#if !isFirstMessage}
diff --git a/src/routes/(app)/c/[id]/+page.svelte b/src/routes/(app)/c/[id]/+page.svelte index be84467da..737a13e0e 100644 --- a/src/routes/(app)/c/[id]/+page.svelte +++ b/src/routes/(app)/c/[id]/+page.svelte @@ -858,6 +858,7 @@ {sendPrompt} {continueGeneration} {regenerateResponse} + {stopResponse} />
From 95b8edf6b3e1ac53749bddf70488836a931860a1 Mon Sep 17 00:00:00 2001 From: Danny Liu Date: Tue, 20 Feb 2024 16:00:57 -0800 Subject: [PATCH 09/25] use cancelChatCompletion API call instead of stopResponse function --- src/lib/components/chat/Messages.svelte | 4 ++-- src/routes/(app)/+page.svelte | 1 - src/routes/(app)/c/[id]/+page.svelte | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 9efab1e52..e8b9a80fe 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -11,12 +11,12 @@ import ResponseMessage from './Messages/ResponseMessage.svelte'; import Placeholder from './Messages/Placeholder.svelte'; import Spinner from '../common/Spinner.svelte'; + import { cancelChatCompletion } from '$lib/apis/ollama'; export let chatId = ''; export let sendPrompt: Function; export let continueGeneration: Function; export let regenerateResponse: Function; - export let stopResponse: Function; export let processing = ''; export let bottomPadding = false; @@ -229,7 +229,7 @@ await updateChatById(localStorage.token, chatId, { history }); await chats.set(await getChatList(localStorage.token)); - stopResponse(); + await cancelChatCompletion(localStorage.token, chatId); }; diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index b93dc860a..33409ec32 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -828,7 +828,6 @@ {sendPrompt} {continueGeneration} {regenerateResponse} - {stopResponse} /> diff --git a/src/routes/(app)/c/[id]/+page.svelte b/src/routes/(app)/c/[id]/+page.svelte index 737a13e0e..be84467da 100644 --- a/src/routes/(app)/c/[id]/+page.svelte +++ b/src/routes/(app)/c/[id]/+page.svelte @@ -858,7 +858,6 @@ {sendPrompt} {continueGeneration} {regenerateResponse} - {stopResponse} /> From a655ccdd06aa9b0ebcb270b789589eba920c7098 Mon Sep 17 00:00:00 2001 From: Danny Liu Date: Tue, 20 Feb 2024 16:35:44 -0800 Subject: [PATCH 10/25] only cancel chat completion if the deleted message is the most recently sent --- src/lib/components/chat/Messages.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index e8b9a80fe..6bb840693 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -227,9 +227,13 @@ history.messages[messageId].deleted = true; history.messages[history.messages[messageId].childrenIds[0]].deleted = true; + const responseId = history.messages[messageId].childrenIds[0]; + if (history.messages[responseId].childrenIds.length === 0) { + await cancelChatCompletion(localStorage.token, chatId); + } + await updateChatById(localStorage.token, chatId, { history }); await chats.set(await getChatList(localStorage.token)); - await cancelChatCompletion(localStorage.token, chatId); }; From 7c4d818f2dfad5604451d605edd318655d21070c Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Tue, 20 Feb 2024 18:03:23 -0800 Subject: [PATCH 11/25] refac: styling --- .../chat/Messages/UserMessage.svelte | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index ca1cff59d..6f41c5dfb 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -196,11 +196,11 @@
{message.content}
-
+
{#if siblings.length > 1}
-
+
{siblings.indexOf(message.id) + 1} / {siblings.length}
{#if !isFirstMessage} - - {/if} + + + + + {/if}
{/if} From c42ac39dc4354c409481901a0c45d7b0daac8417 Mon Sep 17 00:00:00 2001 From: Danny Liu Date: Tue, 20 Feb 2024 19:47:30 -0800 Subject: [PATCH 12/25] Recursively set delete=true flag for all children messages --- src/lib/components/chat/Messages.svelte | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 6bb840693..7766b348d 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -223,15 +223,18 @@ }, 100); }; - const deleteMessagePair = async (messageId) => { - history.messages[messageId].deleted = true; - history.messages[history.messages[messageId].childrenIds[0]].deleted = true; + const deleteMessageAndDescendants = async (messageId: string) => { + if (history.messages[messageId]) { + history.messages[messageId].deleted = true; - const responseId = history.messages[messageId].childrenIds[0]; - if (history.messages[responseId].childrenIds.length === 0) { - await cancelChatCompletion(localStorage.token, chatId); + for (const childId of history.messages[messageId].childrenIds) { + await deleteMessageAndDescendants(childId); + } } + }; + const triggerDeleteMessageRecursive = async (messageId: string) => { + await deleteMessageAndDescendants(messageId); await updateChatById(localStorage.token, chatId, { history }); await chats.set(await getChatList(localStorage.token)); }; @@ -252,7 +255,7 @@ > {#if message.role === 'user'} deleteMessagePair(message.id)} + on:delete={() => triggerDeleteMessageRecursive(message.id)} user={$user} {message} isFirstMessage={messageIdx === 0} From c89c27d35105ee380f4aaaa4a9fd9f4f4bf1da75 Mon Sep 17 00:00:00 2001 From: Loan J Date: Wed, 21 Feb 2024 18:46:33 -0500 Subject: [PATCH 13/25] Add release creation workflow --- .github/workflows/build-release.yml | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/build-release.yml diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml new file mode 100644 index 000000000..f4baf8944 --- /dev/null +++ b/.github/workflows/build-release.yml @@ -0,0 +1,42 @@ +name: Release + +on: + push: + branches: + - main # or whatever branch you want to use + +jobs: + release: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Get commit hash + id: get_hash + run: | + HASH=$(git rev-parse --short "$GITHUB_SHA") + echo "::set-output name=hash::$HASH" + + - name: Create GitHub release + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const release = await github.rest.repos.createRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + tag_name: `v${{ steps.get_hash.outputs.hash }}`, + name: `v${{ steps.get_hash.outputs.hash }}`, + body: 'Automatically created new release', + }) + console.log(`Created release ${release.data.html_url}`) + + - name: Upload package to GitHub release + uses: actions/upload-artifact@v3 + with: + name: package + path: . + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 7b27a96e14087db6c07bc3cd3a29762c4fea9a16 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 02:03:24 -0800 Subject: [PATCH 14/25] Update About.svelte --- src/lib/components/chat/Settings/About.svelte | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/components/chat/Settings/About.svelte b/src/lib/components/chat/Settings/About.svelte index b05ad86cd..c10a23be7 100644 --- a/src/lib/components/chat/Settings/About.svelte +++ b/src/lib/components/chat/Settings/About.svelte @@ -44,6 +44,13 @@ /> + + X (formerly Twitter) Follow + + Github Repo Date: Thu, 22 Feb 2024 12:06:20 -0500 Subject: [PATCH 15/25] Update build-release.yml --- .github/workflows/build-release.yml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index f4baf8944..fa3fa296d 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -13,11 +13,18 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 - - name: Get commit hash - id: get_hash + - name: Check for changes in package.json run: | - HASH=$(git rev-parse --short "$GITHUB_SHA") - echo "::set-output name=hash::$HASH" + git diff --cached --diff-filter=d package.json || { + echo "No changes to package.json" + exit 1 + } + + - name: Get version number from package.json + id: get_version + run: | + VERSION=$(jq -r '.version' package.json) + echo "::set-output name=version::$VERSION" - name: Create GitHub release uses: actions/github-script@v5 @@ -27,8 +34,8 @@ jobs: const release = await github.rest.repos.createRelease({ owner: context.repo.owner, repo: context.repo.repo, - tag_name: `v${{ steps.get_hash.outputs.hash }}`, - name: `v${{ steps.get_hash.outputs.hash }}`, + tag_name: `v${{ steps.get_version.outputs.version }}`, + name: `v${{ steps.get_version.outputs.version }}`, body: 'Automatically created new release', }) console.log(`Created release ${release.data.html_url}`) From 97d9ecadcfb74592aa76e9192c6174178ae7ed66 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 13:36:44 -0800 Subject: [PATCH 16/25] fix: version --- package.json | 2 +- src/lib/components/chat/Settings/About.svelte | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index edc4762fc..6a93f04a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "v1.0.0-alpha.101", + "version": "1.0.0-alpha.101", "private": true, "scripts": { "dev": "vite dev --host", diff --git a/src/lib/components/chat/Settings/About.svelte b/src/lib/components/chat/Settings/About.svelte index c10a23be7..e9f7e8d60 100644 --- a/src/lib/components/chat/Settings/About.svelte +++ b/src/lib/components/chat/Settings/About.svelte @@ -18,7 +18,7 @@
{WEBUI_NAME} Version
- {WEB_UI_VERSION} + v{WEB_UI_VERSION}
From 50355fd02baddedf7bf3b3df38d5d2c6411f2f55 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 14:07:01 -0800 Subject: [PATCH 17/25] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 421a9bd2f..c5cc439b5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![Discord](https://img.shields.io/badge/Discord-Open_WebUI-blue?logo=discord&logoColor=white)](https://discord.gg/5rJgQTnV4s) [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/tjbck) -ChatGPT-Style Web Interface for Ollama 🦙 +User-friendly WebUI for LLMs, Inspired by ChatGPT ![Open WebUI Demo](./demo.gif) From e1dc6d3f8112d02bbd0f736a592f613431cfd79c Mon Sep 17 00:00:00 2001 From: Loan J Date: Thu, 22 Feb 2024 19:09:22 -0500 Subject: [PATCH 18/25] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6a93f04a0..352130769 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "1.0.0-alpha.101", + "version": "0.1.0-101", "private": true, "scripts": { "dev": "vite dev --host", @@ -52,4 +52,4 @@ "tippy.js": "^6.3.7", "uuid": "^9.0.1" } -} \ No newline at end of file +} From eaa685043164f92c11b040c02ee5ba7de8e50e94 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 17:53:58 -0800 Subject: [PATCH 19/25] Update Messages.svelte --- src/lib/components/chat/Messages.svelte | 28 ++++++++++++++++++------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 7766b348d..20a6fccad 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -223,20 +223,32 @@ }, 100); }; - const deleteMessageAndDescendants = async (messageId: string) => { + // TODO: change delete behaviour + // const deleteMessageAndDescendants = async (messageId: string) => { + // if (history.messages[messageId]) { + // history.messages[messageId].deleted = true; + + // for (const childId of history.messages[messageId].childrenIds) { + // await deleteMessageAndDescendants(childId); + // } + // } + // }; + + // const triggerDeleteMessageRecursive = async (messageId: string) => { + // await deleteMessageAndDescendants(messageId); + // await updateChatById(localStorage.token, chatId, { history }); + // await chats.set(await getChatList(localStorage.token)); + // }; + + const messageDeleteHandler = async (messageId) => { if (history.messages[messageId]) { history.messages[messageId].deleted = true; for (const childId of history.messages[messageId].childrenIds) { - await deleteMessageAndDescendants(childId); + history.messages[childId].deleted = true; } } - }; - - const triggerDeleteMessageRecursive = async (messageId: string) => { - await deleteMessageAndDescendants(messageId); await updateChatById(localStorage.token, chatId, { history }); - await chats.set(await getChatList(localStorage.token)); }; @@ -255,7 +267,7 @@ > {#if message.role === 'user'} triggerDeleteMessageRecursive(message.id)} + on:delete={() => messageDeleteHandler(message.id)} user={$user} {message} isFirstMessage={messageIdx === 0} From a3a0e18307369214ae58b70aa3b3d4e09cc00718 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 17:54:22 -0800 Subject: [PATCH 20/25] Update Messages.svelte --- src/lib/components/chat/Messages.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index 20a6fccad..ce5a37479 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -11,7 +11,6 @@ import ResponseMessage from './Messages/ResponseMessage.svelte'; import Placeholder from './Messages/Placeholder.svelte'; import Spinner from '../common/Spinner.svelte'; - import { cancelChatCompletion } from '$lib/apis/ollama'; export let chatId = ''; export let sendPrompt: Function; From a2e2dd89a5596269f836b3e711c6df1def1d5934 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 17:58:18 -0800 Subject: [PATCH 21/25] Update Messages.svelte --- src/lib/components/chat/Messages.svelte | 42 ++++++++++++------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index b22873eda..c9e516abb 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -329,28 +329,28 @@ {/if} {:else} { - console.log('save', e); + {message} + modelfiles={selectedModelfiles} + siblings={history.messages[message.parentId]?.childrenIds ?? []} + isLastMessage={messageIdx + 1 === messages.length} + {confirmEditResponseMessage} + {showPreviousMessage} + {showNextMessage} + {rateMessage} + {copyToClipboard} + {continueGeneration} + {regenerateResponse} + on:save={async (e) => { + console.log('save', e); - const message = e.detail; - history.messages[message.id] = message; - await updateChatById(localStorage.token, chatId, { - messages: messages, - history: history - }); - }} - /> + const message = e.detail; + history.messages[message.id] = message; + await updateChatById(localStorage.token, chatId, { + messages: messages, + history: history + }); + }} + /> {/if}
From 79615f26da1b20d90e20036a32ff3d9322b2efe2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 18:49:34 -0800 Subject: [PATCH 22/25] feat: image preview --- .../chat/Messages/ResponseMessage.svelte | 4 +- src/lib/components/common/Image.svelte | 18 ++++++ src/lib/components/common/ImagePreview.svelte | 62 +++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/lib/components/common/Image.svelte create mode 100644 src/lib/components/common/ImagePreview.svelte diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index e9dedc12f..5af3a47e7 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -20,6 +20,7 @@ import ProfileImage from './ProfileImage.svelte'; import Skeleton from './Skeleton.svelte'; import CodeBlock from './CodeBlock.svelte'; + import Image from '$lib/components/common/Image.svelte'; export let modelfiles = []; export let message; @@ -46,7 +47,6 @@ let speakingIdx = null; let loadingSpeech = false; - let generatingImage = false; $: tokens = marked.lexer(message.content); @@ -323,7 +323,7 @@ {#each message.files as file}
{#if file.type === 'image'} - input + {/if}
{/each} diff --git a/src/lib/components/common/Image.svelte b/src/lib/components/common/Image.svelte new file mode 100644 index 000000000..566ebb5b1 --- /dev/null +++ b/src/lib/components/common/Image.svelte @@ -0,0 +1,18 @@ + + + + diff --git a/src/lib/components/common/ImagePreview.svelte b/src/lib/components/common/ImagePreview.svelte new file mode 100644 index 000000000..cf69327fa --- /dev/null +++ b/src/lib/components/common/ImagePreview.svelte @@ -0,0 +1,62 @@ + + +{#if show} + + +
+
+
+ +
+ +
+ +
+
+ +
+{/if} From 7ec4c07bf9c3607397ddbc5a53832adf255def5d Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 19:32:36 -0800 Subject: [PATCH 23/25] feat: image size param --- backend/apps/images/main.py | 32 ++++++++- backend/constants.py | 3 + src/lib/apis/images/index.ts | 67 +++++++++++++++++++ .../components/chat/Settings/Images.svelte | 29 ++++++-- 4 files changed, 125 insertions(+), 6 deletions(-) diff --git a/backend/apps/images/main.py b/backend/apps/images/main.py index 998af3ddb..39d3f96aa 100644 --- a/backend/apps/images/main.py +++ b/backend/apps/images/main.py @@ -1,4 +1,4 @@ -import os +import re import requests from fastapi import ( FastAPI, @@ -34,6 +34,7 @@ app.add_middleware( app.state.AUTOMATIC1111_BASE_URL = AUTOMATIC1111_BASE_URL app.state.ENABLED = app.state.AUTOMATIC1111_BASE_URL != "" +app.state.IMAGE_SIZE = "512x512" @app.get("/enabled", response_model=bool) @@ -74,6 +75,33 @@ async def update_openai_url(form_data: UrlUpdateForm, user=Depends(get_admin_use } +class ImageSizeUpdateForm(BaseModel): + size: str + + +@app.get("/size") +async def get_image_size(user=Depends(get_admin_user)): + return {"IMAGE_SIZE": app.state.IMAGE_SIZE} + + +@app.post("/size/update") +async def update_image_size( + form_data: ImageSizeUpdateForm, user=Depends(get_admin_user) +): + pattern = r"^\d+x\d+$" # Regular expression pattern + if re.match(pattern, form_data.size): + app.state.IMAGE_SIZE = form_data.size + return { + "IMAGE_SIZE": app.state.IMAGE_SIZE, + "status": True, + } + else: + raise HTTPException( + status_code=400, + detail=ERROR_MESSAGES.INCORRECT_FORMAT(" (e.g., 512x512)."), + ) + + @app.get("/models") def get_models(user=Depends(get_current_user)): try: @@ -140,7 +168,7 @@ def generate_image( if form_data.model: set_model_handler(form_data.model) - width, height = tuple(map(int, form_data.size.split("x"))) + width, height = tuple(map(int, app.state.IMAGE_SIZE.split("x"))) data = { "prompt": form_data.prompt, diff --git a/backend/constants.py b/backend/constants.py index 580db9c5f..cb802c7f4 100644 --- a/backend/constants.py +++ b/backend/constants.py @@ -44,3 +44,6 @@ class ERROR_MESSAGES(str, Enum): MALICIOUS = "Unusual activities detected, please try again in a few minutes." PANDOC_NOT_INSTALLED = "Pandoc is not installed on the server. Please contact your administrator for assistance." + INCORRECT_FORMAT = ( + lambda err="": f"Invalid format. Please use the correct format{err if err else ''}" + ) diff --git a/src/lib/apis/images/index.ts b/src/lib/apis/images/index.ts index b25499d64..205ee90ac 100644 --- a/src/lib/apis/images/index.ts +++ b/src/lib/apis/images/index.ts @@ -131,6 +131,73 @@ export const updateAUTOMATIC1111Url = async (token: string = '', url: string) => return res.AUTOMATIC1111_BASE_URL; }; +export const getImageSize = async (token: string = '') => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/size`, { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + } + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.IMAGE_SIZE; +}; + +export const updateImageSize = async (token: string = '', size: string) => { + let error = null; + + const res = await fetch(`${IMAGES_API_BASE_URL}/size/update`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...(token && { authorization: `Bearer ${token}` }) + }, + body: JSON.stringify({ + size: size + }) + }) + .then(async (res) => { + if (!res.ok) throw await res.json(); + return res.json(); + }) + .catch((err) => { + console.log(err); + if ('detail' in err) { + error = err.detail; + } else { + error = 'Server connection failed'; + } + return null; + }); + + if (error) { + throw error; + } + + return res.IMAGE_SIZE; +}; + export const getDiffusionModels = async (token: string = '') => { let error = null; diff --git a/src/lib/components/chat/Settings/Images.svelte b/src/lib/components/chat/Settings/Images.svelte index 9b4b60cdd..e6809c767 100644 --- a/src/lib/components/chat/Settings/Images.svelte +++ b/src/lib/components/chat/Settings/Images.svelte @@ -8,9 +8,11 @@ getDefaultDiffusionModel, getDiffusionModels, getImageGenerationEnabledStatus, + getImageSize, toggleImageGenerationEnabledStatus, updateAUTOMATIC1111Url, - updateDefaultDiffusionModel + updateDefaultDiffusionModel, + updateImageSize } from '$lib/apis/images'; import { getBackendConfig } from '$lib/apis'; const dispatch = createEventDispatcher(); @@ -25,6 +27,8 @@ let selectedModel = ''; let models = []; + let imageSize = ''; + const getModels = async () => { models = await getDiffusionModels(localStorage.token).catch((error) => { toast.error(error); @@ -53,7 +57,6 @@ AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); } }; - const toggleImageGeneration = async () => { if (AUTOMATIC1111_BASE_URL) { enableImageGeneration = await toggleImageGenerationEnabledStatus(localStorage.token).catch( @@ -79,6 +82,7 @@ AUTOMATIC1111_BASE_URL = await getAUTOMATIC1111Url(localStorage.token); if (enableImageGeneration && AUTOMATIC1111_BASE_URL) { + imageSize = await getImageSize(localStorage.token); getModels(); } } @@ -89,13 +93,17 @@ class="flex flex-col h-full justify-between space-y-3 text-sm" on:submit|preventDefault={async () => { loading = true; - const res = await updateDefaultDiffusionModel(localStorage.token, selectedModel); + await updateDefaultDiffusionModel(localStorage.token, selectedModel); + await updateImageSize(localStorage.token, imageSize).catch((error) => { + toast.error(error); + return null; + }); dispatch('save'); loading = false; }} > -
+
Image Settings
@@ -168,6 +176,19 @@ {#if enableImageGeneration}
+
+
Set Image Size
+
+
+ +
+
+
+
Set default model
From e612feec9925898aa94649e820e8c872939cf759 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 19:33:36 -0800 Subject: [PATCH 24/25] Update package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 352130769..332362747 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.1.0-101", + "version": "0.1.102", "private": true, "scripts": { "dev": "vite dev --host", @@ -52,4 +52,4 @@ "tippy.js": "^6.3.7", "uuid": "^9.0.1" } -} +} \ No newline at end of file From 2e7efde4b717cde4766116a4562a5c5f0f7828c2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 22 Feb 2024 19:40:51 -0800 Subject: [PATCH 25/25] Update Images.svelte --- .../components/chat/Settings/Images.svelte | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/lib/components/chat/Settings/Images.svelte b/src/lib/components/chat/Settings/Images.svelte index e6809c767..94cb3213b 100644 --- a/src/lib/components/chat/Settings/Images.svelte +++ b/src/lib/components/chat/Settings/Images.svelte @@ -177,20 +177,7 @@
-
Set Image Size
-
-
- -
-
-
- -
-
Set default model
+
Set Default Model
+
+
+
{/if}