From c9d8645abafcca52f95cad9ca7ff7a9d790ef719 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 01:05:38 -0800 Subject: [PATCH 01/18] feat: share button added --- src/lib/components/layout/Navbar.svelte | 99 +++++++++++++++---------- src/routes/(app)/+page.svelte | 2 +- src/routes/(app)/c/[id]/+page.svelte | 2 +- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/lib/components/layout/Navbar.svelte b/src/lib/components/layout/Navbar.svelte index 9bf15a07..e6154a84 100644 --- a/src/lib/components/layout/Navbar.svelte +++ b/src/lib/components/layout/Navbar.svelte @@ -5,48 +5,71 @@ import { chatId } from '$lib/stores'; export let title: string = 'Ollama Web UI'; + export let shareEnabled: boolean = false; - - + diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index 7c0c87b4..728765c2 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -566,7 +566,7 @@ }} /> - + 0} />
diff --git a/src/routes/(app)/c/[id]/+page.svelte b/src/routes/(app)/c/[id]/+page.svelte index f108ba22..9fef89bf 100644 --- a/src/routes/(app)/c/[id]/+page.svelte +++ b/src/routes/(app)/c/[id]/+page.svelte @@ -579,7 +579,7 @@ /> {#if loaded} - + 0} />
From 425d0223222f228ef34bc508577f1306587ae760 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 13:22:57 -0800 Subject: [PATCH 02/18] feat: image clipboard paste input support --- src/lib/components/chat/MessageInput.svelte | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index bc3a6a9d..cb8a12e6 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -235,6 +235,30 @@ e.target.style.height = ''; e.target.style.height = Math.min(e.target.scrollHeight, 200) + 'px'; }} + on:paste={(e) => { + const clipboardData = e.clipboardData || window.clipboardData; + + if (clipboardData && clipboardData.items) { + for (const item of clipboardData.items) { + if (item.type.indexOf('image') !== -1) { + const blob = item.getAsFile(); + const reader = new FileReader(); + + reader.onload = function (e) { + files = [ + ...files, + { + type: 'image', + url: `${e.target.result}` + } + ]; + }; + + reader.readAsDataURL(blob); + } + } + } + }} />
From e93d465fbc53734005bc6303c3ef1b7462542f33 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 13:31:06 -0800 Subject: [PATCH 03/18] chore: audit fix --- package-lock.json | 23 +++++++++++++++++------ package.json | 3 ++- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7003749c..5201d616 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", + "hint.css": "^3.0.0", "http-server": "^14.1.1", "idb": "^7.1.1", "js-sha256": "^0.10.1", @@ -2300,6 +2301,11 @@ "node": ">=12.0.0" } }, + "node_modules/hint.css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hint.css/-/hint.css-3.0.0.tgz", + "integrity": "sha512-UoJ+yLO2kEcfsm/XMU1suAIR0sxCq4HO22pw4okJQo5TQDlA2BrJ57Eaxh4eT+9PDInIDTRm9TVzzbHHWEqASQ==" + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -4160,9 +4166,9 @@ } }, "node_modules/vite": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", - "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", + "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", @@ -5746,6 +5752,11 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==" }, + "hint.css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hint.css/-/hint.css-3.0.0.tgz", + "integrity": "sha512-UoJ+yLO2kEcfsm/XMU1suAIR0sxCq4HO22pw4okJQo5TQDlA2BrJ57Eaxh4eT+9PDInIDTRm9TVzzbHHWEqASQ==" + }, "html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -6991,9 +7002,9 @@ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==" }, "vite": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz", - "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.1.tgz", + "integrity": "sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==", "requires": { "esbuild": "^0.18.10", "fsevents": "~2.3.2", diff --git a/package.json b/package.json index 5b1a89ec..2764a8ba 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", + "hint.css": "^3.0.0", "http-server": "^14.1.1", "idb": "^7.1.1", "js-sha256": "^0.10.1", @@ -50,4 +51,4 @@ "svelte-french-toast": "^1.2.0", "uuid": "^9.0.1" } -} \ No newline at end of file +} From ffaa1b17c5551729c0a21c786c4e6b7c55184af6 Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 14:24:56 -0800 Subject: [PATCH 04/18] feat: show verbose info --- package-lock.json | 42 ++++++++++++++++------ package.json | 2 +- src/lib/components/chat/Messages.svelte | 46 +++++++++++++++++++++++++ src/routes/(app)/+page.svelte | 3 ++ src/routes/(app)/c/[id]/+page.svelte | 3 ++ src/routes/+layout.svelte | 2 +- 6 files changed, 85 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5201d616..bcfc7253 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", - "hint.css": "^3.0.0", "http-server": "^14.1.1", "idb": "^7.1.1", "js-sha256": "^0.10.1", "katex": "^0.16.9", "marked": "^9.1.0", "svelte-french-toast": "^1.2.0", + "tippy.js": "^6.3.7", "uuid": "^9.0.1" }, "devDependencies": { @@ -585,6 +585,15 @@ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "25.0.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", @@ -2301,11 +2310,6 @@ "node": ">=12.0.0" } }, - "node_modules/hint.css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hint.css/-/hint.css-3.0.0.tgz", - "integrity": "sha512-UoJ+yLO2kEcfsm/XMU1suAIR0sxCq4HO22pw4okJQo5TQDlA2BrJ57Eaxh4eT+9PDInIDTRm9TVzzbHHWEqASQ==" - }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -4000,6 +4004,14 @@ "globrex": "^0.1.2" } }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4576,6 +4588,11 @@ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.23.tgz", "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==" }, + "@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" + }, "@rollup/plugin-commonjs": { "version": "25.0.5", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.5.tgz", @@ -5752,11 +5769,6 @@ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==" }, - "hint.css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hint.css/-/hint.css-3.0.0.tgz", - "integrity": "sha512-UoJ+yLO2kEcfsm/XMU1suAIR0sxCq4HO22pw4okJQo5TQDlA2BrJ57Eaxh4eT+9PDInIDTRm9TVzzbHHWEqASQ==" - }, "html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -6896,6 +6908,14 @@ "globrex": "^0.1.2" } }, + "tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "requires": { + "@popperjs/core": "^2.9.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/package.json b/package.json index 2764a8ba..f90b99ad 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,13 @@ "@sveltejs/adapter-node": "^1.3.1", "file-saver": "^2.0.5", "highlight.js": "^11.9.0", - "hint.css": "^3.0.0", "http-server": "^14.1.1", "idb": "^7.1.1", "js-sha256": "^0.10.1", "katex": "^0.16.9", "marked": "^9.1.0", "svelte-french-toast": "^1.2.0", + "tippy.js": "^6.3.7", "uuid": "^9.0.1" } } diff --git a/src/lib/components/chat/Messages.svelte b/src/lib/components/chat/Messages.svelte index b08f1093..e25b0cda 100644 --- a/src/lib/components/chat/Messages.svelte +++ b/src/lib/components/chat/Messages.svelte @@ -2,6 +2,7 @@ import { marked } from 'marked'; import { v4 as uuidv4 } from 'uuid'; + import tippy from 'tippy.js'; import hljs from 'highlight.js'; import 'highlight.js/styles/github-dark.min.css'; import auto_render from 'katex/dist/contrib/auto-render.mjs'; @@ -29,6 +30,24 @@ renderLatex(); hljs.highlightAll(); createCopyCodeBlockButton(); + + for (const message of messages) { + if (message.info) { + tippy(`#info-${message.id}`, { + content: `total_duration: ${ + message.info.total_duration ?? 'N/A' + }
+ load_duration: ${message.info.load_duration ?? 'N/A'}
+ sample_count: ${message.info.sample_count ?? 'N/A'}
+ sample_duration: ${message.info.sample_duration ?? 'N/A'}
+ prompt_eval_count: ${message.info.prompt_eval_count ?? 'N/A'}
+ prompt_eval_duration: ${message.info.prompt_eval_duration ?? 'N/A'}
+ eval_count: ${message.info.eval_count ?? 'N/A'}
+ eval_duration: ${message.info.eval_duration ?? 'N/A'}
`, + allowHTML: true + }); + } + } })(); } @@ -861,6 +880,33 @@ + {#if message.info} + + {/if} + {#if messageIdx + 1 === messages.length} +
+
+
Response Notification
+ + +
-
-
+
+
+
Title Auto Generation
-
-
-
Voice Input Auto-Send
+ +
+
- +
+
+
Voice Input Auto-Send
+ + +
diff --git a/src/routes/(app)/+page.svelte b/src/routes/(app)/+page.svelte index c82a26a5..5d4291d7 100644 --- a/src/routes/(app)/+page.svelte +++ b/src/routes/(app)/+page.svelte @@ -222,6 +222,21 @@ eval_duration: data.eval_duration }; messages = messages; + + if ($settings.responseNotification && !document.hasFocus()) { + const notification = new Notification( + selectedModelfile + ? `${ + selectedModelfile.title.charAt(0).toUpperCase() + + selectedModelfile.title.slice(1) + }` + : `Ollama - ${model}`, + { + body: responseMessage.content, + icon: selectedModelfile?.imageUrl ?? '/favicon.png' + } + ); + } } } } diff --git a/src/routes/(app)/c/[id]/+page.svelte b/src/routes/(app)/c/[id]/+page.svelte index f156ed99..b164a4b4 100644 --- a/src/routes/(app)/c/[id]/+page.svelte +++ b/src/routes/(app)/c/[id]/+page.svelte @@ -234,6 +234,21 @@ eval_duration: data.eval_duration }; messages = messages; + + if ($settings.responseNotification && !document.hasFocus()) { + const notification = new Notification( + selectedModelfile + ? `${ + selectedModelfile.title.charAt(0).toUpperCase() + + selectedModelfile.title.slice(1) + }` + : `Ollama - ${model}`, + { + body: responseMessage.content, + icon: selectedModelfile?.imageUrl ?? '/favicon.png' + } + ); + } } } } From 4622a8990d473fc55d06420af46ef4a3f70a5fce Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 15:39:46 -0800 Subject: [PATCH 06/18] chore: version update --- backend/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/config.py b/backend/config.py index 14ad30e4..870d204a 100644 --- a/backend/config.py +++ b/backend/config.py @@ -30,7 +30,7 @@ if ENV == "prod": # WEBUI_VERSION #################################### -WEBUI_VERSION = os.environ.get("WEBUI_VERSION", "v1.0.0-alpha.21") +WEBUI_VERSION = os.environ.get("WEBUI_VERSION", "v1.0.0-alpha.33") #################################### # WEBUI_AUTH From c87a80f9a53f5f5b7993a614a02d80adf83650ff Mon Sep 17 00:00:00 2001 From: "Timothy J. Baek" Date: Thu, 14 Dec 2023 16:50:54 -0800 Subject: [PATCH 07/18] feat: chat share --- src/lib/components/layout/Navbar.svelte | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/lib/components/layout/Navbar.svelte b/src/lib/components/layout/Navbar.svelte index e6154a84..70e39eb7 100644 --- a/src/lib/components/layout/Navbar.svelte +++ b/src/lib/components/layout/Navbar.svelte @@ -2,10 +2,31 @@ import { v4 as uuidv4 } from 'uuid'; import { goto } from '$app/navigation'; - import { chatId } from '$lib/stores'; + import { chatId, db } from '$lib/stores'; + import toast from 'svelte-french-toast'; export let title: string = 'Ollama Web UI'; export let shareEnabled: boolean = false; + + const shareChat = async () => { + const chat = await $db.getChatById($chatId); + console.log('share', chat); + toast.success('Redirecting you to OllamaHub'); + + const url = 'https://ollamahub.com'; + + const tab = await window.open(`${url}/chats/upload`, '_blank'); + window.addEventListener( + 'message', + (event) => { + if (event.origin !== url) return; + if (event.data === 'loaded') { + tab.postMessage(JSON.stringify(chat), '*'); + } + }, + false + ); + };