From 3f0dd80898cb22ec9d230a006dfb6ddbd3eb16b3 Mon Sep 17 00:00:00 2001 From: Miguel Bernadin Date: Fri, 27 Dec 2024 08:14:22 -0800 Subject: [PATCH 1/5] fix: chmod +x update_ollama_models.sh --- update_ollama_models.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 update_ollama_models.sh diff --git a/update_ollama_models.sh b/update_ollama_models.sh old mode 100644 new mode 100755 From 7f8b6ebbd5016f701d7f41c7b3cf56e769f25862 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 27 Dec 2024 12:24:58 -0800 Subject: [PATCH 2/5] refac: styling --- src/lib/components/channel/Messages.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/channel/Messages.svelte b/src/lib/components/channel/Messages.svelte index 3614263a1..deb2d93fb 100644 --- a/src/lib/components/channel/Messages.svelte +++ b/src/lib/components/channel/Messages.svelte @@ -66,7 +66,7 @@ {($settings?.widescreenMode ?? null) ? 'max-w-full' : 'max-w-5xl'} mx-auto" > {#if channel} -
+
{channel.name}
From 7b3a86475d7b28ecc682d4bbfaaf1c6e3eedf043 Mon Sep 17 00:00:00 2001 From: cvaz1306 Date: Fri, 27 Dec 2024 17:06:15 -0800 Subject: [PATCH 3/5] Add reset panzoom button to SVGPanZoom and cleanup --- src/lib/components/common/SVGPanZoom.svelte | 24 +++++++++++++++++++-- src/lib/components/icons/Reset.svelte | 8 +++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/lib/components/icons/Reset.svelte diff --git a/src/lib/components/common/SVGPanZoom.svelte b/src/lib/components/common/SVGPanZoom.svelte index e576ffb06..dc7f81afd 100644 --- a/src/lib/components/common/SVGPanZoom.svelte +++ b/src/lib/components/common/SVGPanZoom.svelte @@ -2,7 +2,7 @@ import { onMount, getContext } from 'svelte'; const i18n = getContext('i18n'); - import panzoom from 'panzoom'; + import panzoom, { type PanZoom } from 'panzoom'; import DOMPurify from 'dompurify'; import DocumentDuplicate from '../icons/DocumentDuplicate.svelte'; @@ -10,12 +10,13 @@ import { toast } from 'svelte-sonner'; import Tooltip from './Tooltip.svelte'; import Clipboard from '../icons/Clipboard.svelte'; + import Reset from '../icons/Reset.svelte'; export let className = ''; export let svg = ''; export let content = ''; - let instance; + let instance: PanZoom; let sceneParentElement: HTMLElement; let sceneElement: HTMLElement; @@ -28,6 +29,12 @@ zoomSpeed: 0.065 }); } + function resetPanZoomViewport() { + console.log('Reset View') + instance.moveTo(0, 0); + instance.zoomAbs(0,0,1); + console.log(instance.getTransform()); + }
@@ -49,5 +56,18 @@
+
+ + + +
{/if}
diff --git a/src/lib/components/icons/Reset.svelte b/src/lib/components/icons/Reset.svelte new file mode 100644 index 000000000..c8a16ee34 --- /dev/null +++ b/src/lib/components/icons/Reset.svelte @@ -0,0 +1,8 @@ + + + + \ No newline at end of file From d55884b50ec06d3c40540deb47ae6d821b27ab04 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 27 Dec 2024 22:36:14 -0800 Subject: [PATCH 4/5] enh: ENABLE_REALTIME_CHAT_SAVE --- backend/open_webui/env.py | 5 ++++ backend/open_webui/utils/middleware.py | 31 +++++++++++++++++------ src/lib/components/chat/Chat.svelte | 34 +++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index a5f848b62..19e949e88 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -311,6 +311,11 @@ RESET_CONFIG_ON_START = ( os.environ.get("RESET_CONFIG_ON_START", "False").lower() == "true" ) + +ENABLE_REALTIME_CHAT_SAVE = ( + os.environ.get("ENABLE_REALTIME_CHAT_SAVE", "True").lower() == "true" +) + #################################### # REDIS #################################### diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 7d79e1d0b..a289b2c59 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -65,6 +65,7 @@ from open_webui.env import ( SRC_LOG_LEVELS, GLOBAL_LOG_LEVEL, BYPASS_MODEL_ACCESS_CONTROL, + ENABLE_REALTIME_CHAT_SAVE, ) from open_webui.constants import TASKS @@ -977,7 +978,6 @@ async def process_chat_response( ) else: - value = ( data.get("choices", [])[0] .get("delta", {}) @@ -987,6 +987,28 @@ async def process_chat_response( if value: content = f"{content}{value}" + if ENABLE_REALTIME_CHAT_SAVE: + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": content, + }, + ) + else: + data = { + "content": content, + } + + except Exception as e: + done = "data: [DONE]" in line + title = Chats.get_chat_title_by_id(metadata["chat_id"]) + + if done: + data = {"done": True, "content": content, "title": title} + + if not ENABLE_REALTIME_CHAT_SAVE: # Save message in the database Chats.upsert_message_to_chat_by_id_and_message_id( metadata["chat_id"], @@ -996,13 +1018,6 @@ async def process_chat_response( }, ) - except Exception as e: - done = "data: [DONE]" in line - title = Chats.get_chat_title_by_id(metadata["chat_id"]) - - if done: - data = {"done": True, "content": content, "title": title} - # Send a webhook notification if the user is not active if ( get_user_id_from_session_pool(metadata["session_id"]) diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index 9bec3934d..6c3d610ad 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -1053,7 +1053,7 @@ }; const chatCompletionEventHandler = async (data, message, chatId) => { - const { id, done, choices, sources, selected_model_id, error, usage } = data; + const { id, done, choices, content, sources, selected_model_id, error, usage } = data; if (error) { await handleOpenAIError(error, message); @@ -1105,6 +1105,38 @@ } } + if (content) { + // REALTIME_CHAT_SAVE is disabled + message.content = content; + + if (navigator.vibrate && ($settings?.hapticFeedback ?? false)) { + navigator.vibrate(5); + } + + // Emit chat event for TTS + const messageContentParts = getMessageContentParts( + message.content, + $config?.audio?.tts?.split_on ?? 'punctuation' + ); + messageContentParts.pop(); + + // dispatch only last sentence and make sure it hasn't been dispatched before + if ( + messageContentParts.length > 0 && + messageContentParts[messageContentParts.length - 1] !== message.lastSentence + ) { + message.lastSentence = messageContentParts[messageContentParts.length - 1]; + eventTarget.dispatchEvent( + new CustomEvent('chat', { + detail: { + id: message.id, + content: messageContentParts[messageContentParts.length - 1] + } + }) + ); + } + } + if (selected_model_id) { message.selectedModelId = selected_model_id; message.arena = true; From 5a720a4a31058ed88a58930052128bc6a0ad062e Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 27 Dec 2024 22:46:50 -0800 Subject: [PATCH 5/5] refac --- backend/open_webui/utils/middleware.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index a289b2c59..bb6c56a3b 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -929,6 +929,10 @@ async def process_chat_response( # Handle as a background task async def post_response_handler(response, events): + + assistant_message = get_last_assistant_message(form_data["messages"]) + content = assistant_message if assistant_message else "" + try: for event in events: await event_emitter( @@ -947,9 +951,6 @@ async def process_chat_response( }, ) - assistant_message = get_last_assistant_message(form_data["messages"]) - content = assistant_message if assistant_message else "" - async for line in response.body_iterator: line = line.decode("utf-8") if isinstance(line, bytes) else line data = line @@ -1051,6 +1052,16 @@ async def process_chat_response( print("Task was cancelled!") await event_emitter({"type": "task-cancelled"}) + if not ENABLE_REALTIME_CHAT_SAVE: + # Save message in the database + Chats.upsert_message_to_chat_by_id_and_message_id( + metadata["chat_id"], + metadata["message_id"], + { + "content": content, + }, + ) + if response.background is not None: await response.background()