From 8563588710ef062f51981ec39f29e9055b6f1e12 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Mon, 17 Nov 2025 16:17:26 +0100 Subject: [PATCH] chore: scroll in thinking mode, better buttons placement Signed-off-by: Ettore Di Giacinto --- core/http/static/chat.js | 32 ++++++++++++++++++++++++++-- core/http/views/chat.html | 13 ++++++++++- core/http/views/index.html | 2 +- core/http/views/partials/navbar.html | 20 ++++++++--------- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/core/http/static/chat.js b/core/http/static/chat.js index 055cc85e96cb..da1011a482fd 100644 --- a/core/http/static/chat.js +++ b/core/http/static/chat.js @@ -90,6 +90,23 @@ function updateTokensPerSecond() { } } +function scrollThinkingBoxToBottom() { + // Find all thinking/reasoning message containers that are expanded + const thinkingBoxes = document.querySelectorAll('[data-thinking-box]'); + thinkingBoxes.forEach(box => { + // Only scroll if the box is visible (expanded) and has overflow + if (box.offsetParent !== null && box.scrollHeight > box.clientHeight) { + box.scrollTo({ + top: box.scrollHeight, + behavior: 'smooth' + }); + } + }); +} + +// Make function available globally +window.scrollThinkingBoxToBottom = scrollThinkingBoxToBottom; + function stopRequest() { if (currentAbortController) { currentAbortController.abort(); @@ -996,6 +1013,7 @@ async function promptGPT(systemPrompt, input) { if (now - lastThinkingScrollTime > THINKING_SCROLL_THROTTLE) { lastThinkingScrollTime = now; setTimeout(() => { + // Scroll main chat container const chatContainer = document.getElementById('chat'); if (chatContainer) { chatContainer.scrollTo({ @@ -1003,6 +1021,8 @@ async function promptGPT(systemPrompt, input) { behavior: 'smooth' }); } + // Scroll thinking box to bottom if it's expanded and scrollable + scrollThinkingBoxToBottom(); }, 100); } } else { @@ -1166,8 +1186,8 @@ document.addEventListener("alpine:init", () => { }, add(role, content, image, audio) { const N = this.history.length - 1; - // For thinking messages, always create a new message - if (role === "thinking") { + // For thinking and reasoning messages, always create a new message + if (role === "thinking" || role === "reasoning") { let c = ""; const lines = content.split("\n"); lines.forEach((line) => { @@ -1209,6 +1229,14 @@ document.addEventListener("alpine:init", () => { behavior: 'smooth' }); } + // Also scroll thinking box if it's a thinking/reasoning message + if (role === "thinking" || role === "reasoning") { + setTimeout(() => { + if (typeof window.scrollThinkingBoxToBottom === 'function') { + window.scrollThinkingBoxToBottom(); + } + }, 100); + } const parser = new DOMParser(); const html = parser.parseFromString( this.history[this.history.length - 1].html, diff --git a/core/http/views/chat.html b/core/http/views/chat.html index dccc0ceca024..cd03436e8f5f 100644 --- a/core/http/views/chat.html +++ b/core/http/views/chat.html @@ -178,6 +178,12 @@ behavior: 'smooth' }); } + // Also scroll thinking box if it's a thinking/reasoning message + if (role === "thinking" || role === "reasoning") { + if (typeof window.scrollThinkingBoxToBottom === 'function') { + window.scrollThinkingBoxToBottom(); + } + } }, 100); const parser = new DOMParser(); const html = parser.parseFromString( @@ -566,7 +572,12 @@

x-transition class="mt-2 pt-2 border-t border-[#38BDF8]/20" > -
+
diff --git a/core/http/views/index.html b/core/http/views/index.html index 3eccba916c90..794bd28c1755 100644 --- a/core/http/views/index.html +++ b/core/http/views/index.html @@ -346,7 +346,7 @@

- System + Installed Models and Backends diff --git a/core/http/views/partials/navbar.html b/core/http/views/partials/navbar.html index cc98d4d3d592..88a141d3f895 100644 --- a/core/http/views/partials/navbar.html +++ b/core/http/views/partials/navbar.html @@ -34,12 +34,15 @@ Talk + + API +
@@ -82,7 +82,7 @@ @@ -104,10 +104,7 @@ Swarm - Management - - - API + System @@ -124,6 +121,9 @@ Talk + + API +