From 8ac7e8c299116fc3abde74dd05f917782648a97a Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Sun, 14 Dec 2025 22:29:11 +0100 Subject: [PATCH] fix(chat-ui): model selection toggle and new chat (#7574) Fixes a minor glitch that happens when switching model in from the chat pane where the header was not getting updated. Besides, it allows to create new chat directly when clicking from the management pane to the model. Signed-off-by: Ettore Di Giacinto --- core/http/static/chat.js | 48 ++++++++++--- core/http/views/chat.html | 139 ++++++++++++++++++++++++++---------- core/http/views/manage.html | 2 +- 3 files changed, 141 insertions(+), 48 deletions(-) diff --git a/core/http/static/chat.js b/core/http/static/chat.js index dc0aef87a..203ac5f2e 100644 --- a/core/http/static/chat.js +++ b/core/http/static/chat.js @@ -2473,23 +2473,53 @@ document.addEventListener('DOMContentLoaded', function() { localStorage.removeItem(SYSTEM_PROMPT_STORAGE_KEY); } } else { - // Existing chats loaded - check URL parameter for MCP mode - const urlParams = new URLSearchParams(window.location.search); - if (urlParams.get('mcp') === 'true') { - const activeChat = chatStore.activeChat(); - if (activeChat) { - activeChat.mcpMode = true; - saveChatsToStorage(); + // Existing chats loaded - check if we need to create a new chat for the model in URL + const urlModel = document.getElementById("chat-model")?.value || ""; + const activeChat = chatStore.activeChat(); + const shouldCreateNewChat = sessionStorage.getItem('localai_create_new_chat') === 'true'; + + // Clear the flag after reading it + if (shouldCreateNewChat) { + sessionStorage.removeItem('localai_create_new_chat'); + } + + // If we should create a new chat (from manage.html) or URL model doesn't match active chat, create new chat + // This handles navigation from manage.html or direct links to /chat/MODEL_NAME + if (urlModel && urlModel.trim() && (shouldCreateNewChat || (activeChat && activeChat.model !== urlModel) || !activeChat)) { + // Create a new chat with the model from URL + const urlParams = new URLSearchParams(window.location.search); + const mcpFromUrl = urlParams.get('mcp') === 'true'; + const newChat = chatStore.createChat(urlModel, "", mcpFromUrl); + + // Update context size from template if available + const contextSizeInput = document.getElementById("chat-model"); + if (contextSizeInput && contextSizeInput.dataset.contextSize) { + const contextSize = parseInt(contextSizeInput.dataset.contextSize); + if (!isNaN(contextSize)) { + newChat.contextSize = contextSize; + } + } + + saveChatsToStorage(); + updateUIForActiveChat(); + } else { + // Check URL parameter for MCP mode (update existing active chat) + const urlParams = new URLSearchParams(window.location.search); + if (urlParams.get('mcp') === 'true') { + if (activeChat) { + activeChat.mcpMode = true; + saveChatsToStorage(); + } } } } - // Update context size from template if available + // Update context size from template if available (for existing active chat) const contextSizeInput = document.getElementById("chat-model"); if (contextSizeInput && contextSizeInput.dataset.contextSize) { const contextSize = parseInt(contextSizeInput.dataset.contextSize); const activeChat = chatStore.activeChat(); - if (activeChat) { + if (activeChat && !activeChat.contextSize) { activeChat.contextSize = contextSize; } } diff --git a/core/http/views/chat.html b/core/http/views/chat.html index 685f006b7..e733ebe10 100644 --- a/core/http/views/chat.html +++ b/core/http/views/chat.html @@ -41,6 +41,16 @@ SOFTWARE. __chatContextSize = {{ .ContextSize }}; {{ end }} + // Store gallery configs for header icon display + window.__galleryConfigs = {}; + {{ $allGalleryConfigs:=.GalleryConfig }} + {{ range $modelName, $galleryConfig := $allGalleryConfigs }} + window.__galleryConfigs["{{$modelName}}"] = {}; + {{ if $galleryConfig.Icon }} + window.__galleryConfigs["{{$modelName}}"].Icon = "{{$galleryConfig.Icon}}"; + {{ end }} + {{ end }} + // Function to initialize store function __initChatStore() { if (!window.Alpine) return; @@ -501,6 +511,21 @@ SOFTWARE. } } + // Update model selector to reflect the change (ensure it stays in sync) + const modelSelector = document.getElementById('modelSelector'); + if (modelSelector) { + // Find and select the option matching the model + const optionValue = 'chat/' + modelName; + for (let i = 0; i < modelSelector.options.length; i++) { + if (modelSelector.options[i].value === optionValue) { + modelSelector.selectedIndex = i; + break; + } + } + // Trigger Alpine reactivity by dispatching change event + modelSelector.dispatchEvent(new Event('change', { bubbles: true })); + } + // Trigger MCP availability check in Alpine component // The MCP toggle component will reactively check the data-has-mcp attribute @@ -513,14 +538,6 @@ SOFTWARE. if (typeof updateUIForActiveChat === 'function') { updateUIForActiveChat(); } - - // Trigger MCP availability check in Alpine component - // Dispatch a custom event that the MCP toggle component can listen to - const modelSelector = document.getElementById('modelSelector'); - if (modelSelector) { - // Trigger Alpine reactivity by dispatching change event - modelSelector.dispatchEvent(new Event('change', { bubbles: true })); - } } @@ -559,29 +576,31 @@ SOFTWARE.
-
- - {{ if $model }} - {{ $galleryConfig:= index $allGalleryConfigs $model}} - {{ if $galleryConfig }} - - {{ end }} - {{ end }} - {{ if $model }} - - - - {{ end }} +
+ +
+ {{ if $model }} + {{ $galleryConfig:= index $allGalleryConfigs $model}} + {{ if $galleryConfig }} + + {{ end }} + {{ end }} + {{ if $model }} + + + + {{ end }} +