diff --git a/ui/suite/partials/chat.html b/ui/suite/partials/chat.html index d57d75b..00fb281 100644 --- a/ui/suite/partials/chat.html +++ b/ui/suite/partials/chat.html @@ -4,48 +4,124 @@
-
- - - + + +
- @@ -294,7 +423,9 @@ if (!messages || !scrollBtn) return; var isNearBottom = - messages.scrollHeight - messages.scrollTop - messages.clientHeight < + messages.scrollHeight - + messages.scrollTop - + messages.clientHeight < 100; if (isNearBottom) { @@ -471,9 +602,9 @@ function fetchEntityDetails(type, name) { return fetch( "/api/search/entity?type=" + - encodeURIComponent(type) + - "&name=" + - encodeURIComponent(name), + encodeURIComponent(type) + + "&name=" + + encodeURIComponent(name), ) .then(function (r) { return r.json(); @@ -559,9 +690,9 @@ function fetchEntitiesOfType(type, searchTerm) { fetch( "/api/search/entities?type=" + - encodeURIComponent(type) + - "&q=" + - encodeURIComponent(searchTerm || ""), + encodeURIComponent(type) + + "&q=" + + encodeURIComponent(searchTerm || ""), ) .then(function (r) { return r.json(); @@ -621,8 +752,8 @@ var subtitle = item.subtitle ? '' + - escapeHtml(item.subtitle) + - "" + escapeHtml(item.subtitle) + + "" : ""; var hint = item.isTypeHint ? 'Type : to search' @@ -843,7 +974,11 @@ isStreaming = false; // Render suggestions when message is complete - if (data.suggestions && Array.isArray(data.suggestions) && data.suggestions.length > 0) { + if ( + data.suggestions && + Array.isArray(data.suggestions) && + data.suggestions.length > 0 + ) { renderSuggestions(data.suggestions); } } else { @@ -888,9 +1023,10 @@ // Check if there's an action to parse if (sugg.action) { try { - var action = typeof sugg.action === "string" - ? JSON.parse(sugg.action) - : sugg.action; + var action = + typeof sugg.action === "string" + ? JSON.parse(sugg.action) + : sugg.action; console.log("Parsed action:", action); @@ -899,14 +1035,20 @@ // The backend will recognize this as a tool request window.sendMessage(sugg.text); } else if (action.type === "send_message") { - window.sendMessage(action.message || sugg.text); + window.sendMessage( + action.message || sugg.text, + ); } else if (action.type === "select_context") { window.sendMessage(action.context); } else { window.sendMessage(sugg.text); } } catch (e) { - console.error("Failed to parse action:", e, "falling back to text"); + console.error( + "Failed to parse action:", + e, + "falling back to text", + ); window.sendMessage(sugg.text); } } else { @@ -968,7 +1110,7 @@ currentBotId: currentBotId, currentUserId: currentUserId, currentSessionId: currentSessionId, - currentBotName: currentBotName + currentBotName: currentBotName, }; }; @@ -1028,11 +1170,20 @@ } // Route agent-type messages to AgentMode handler - if (window.AgentMode && data.type && [ - "thought_process", "terminal_output", "browser_ready", - "step_progress", "step_complete", "todo_update", - "agent_status", "file_created" - ].indexOf(data.type) !== -1) { + if ( + window.AgentMode && + data.type && + [ + "thought_process", + "terminal_output", + "browser_ready", + "step_progress", + "step_complete", + "todo_update", + "agent_status", + "file_created", + ].indexOf(data.type) !== -1 + ) { window.AgentMode.handleMessage(data); } @@ -1069,7 +1220,7 @@ // Apply theme data from WebSocket events function getContrastYIQ(hexcolor) { - if (!hexcolor) return '#ffffff'; + if (!hexcolor) return "#ffffff"; // Handle named colors and variables by letting the browser resolve them var temp = document.createElement("div"); @@ -1080,14 +1231,14 @@ document.body.removeChild(temp); var rgb = style.match(/\d+/g); - if (!rgb || rgb.length < 3) return '#ffffff'; + if (!rgb || rgb.length < 3) return "#ffffff"; var r = parseInt(rgb[0]); var g = parseInt(rgb[1]); var b = parseInt(rgb[2]); - var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; - return (yiq >= 128) ? '#000000' : '#ffffff'; + var yiq = (r * 299 + g * 587 + b * 114) / 1000; + return yiq >= 128 ? "#000000" : "#ffffff"; } function applyThemeData(themeData) { @@ -1096,13 +1247,23 @@ var color1 = themeData.color1 || themeData.data?.color1 || "black"; var color2 = themeData.color2 || themeData.data?.color2 || "white"; var logo = themeData.logo_url || themeData.data?.logo_url || ""; - var title = themeData.title || themeData.data?.title || window.__INITIAL_BOT_NAME__ || "Chat"; + var title = + themeData.title || + themeData.data?.title || + window.__INITIAL_BOT_NAME__ || + "Chat"; // Set CSS variables for colors on document element document.documentElement.style.setProperty("--chat-color1", color1); document.documentElement.style.setProperty("--chat-color2", color2); - document.documentElement.style.setProperty("--suggestion-color", color1); - document.documentElement.style.setProperty("--suggestion-bg", color2); + document.documentElement.style.setProperty( + "--suggestion-color", + color1, + ); + document.documentElement.style.setProperty( + "--suggestion-bg", + color2, + ); // Also set on root for better cascading document.documentElement.style.setProperty("--color1", color1); @@ -1112,10 +1273,21 @@ document.documentElement.style.setProperty("--primary", color1); document.documentElement.style.setProperty("--accent", color1); - document.documentElement.style.setProperty("--chat-fg1", getContrastYIQ(color1)); - document.documentElement.style.setProperty("--chat-fg2", getContrastYIQ(color2)); + document.documentElement.style.setProperty( + "--chat-fg1", + getContrastYIQ(color1), + ); + document.documentElement.style.setProperty( + "--chat-fg2", + getContrastYIQ(color2), + ); - console.log("Theme applied:", { color1: color1, color2: color2, logo: logo, title: title }); + console.log("Theme applied:", { + color1: color1, + color2: color2, + logo: logo, + title: title, + }); } // Load bot config and apply colors/logo @@ -1132,47 +1304,98 @@ // Get the theme manager's theme for this bot to check if user selected a different theme var botId = botName.toLowerCase(); var botThemeKey = "gb-theme-" + botId; - var botTheme = window.ThemeManager ? ( - // Get bot-specific theme from theme manager's mapping - (window.ThemeManager.getAvailableThemes && - window.ThemeManager.getAvailableThemes().find(t => t.id === botId)) || - // Fallback to localStorage - localStorage.getItem(botThemeKey) - ) : localStorage.getItem(botThemeKey); + var botTheme = window.ThemeManager + ? // Get bot-specific theme from theme manager's mapping + (window.ThemeManager.getAvailableThemes && + window.ThemeManager.getAvailableThemes().find( + (t) => t.id === botId, + )) || + // Fallback to localStorage + localStorage.getItem(botThemeKey) + : localStorage.getItem(botThemeKey); // Check if bot config has a theme-base setting - var configThemeBase = config.theme_base || config["theme-base"] || "light"; + var configThemeBase = + config.theme_base || config["theme-base"] || "light"; // Only use bot config colors if: // 1. No theme has been explicitly selected by user (localStorage empty or default) // 2. AND the bot config's theme-base matches the current theme var localStorageTheme = localStorage.getItem(botThemeKey); - var useBotConfigColors = !localStorageTheme || + var useBotConfigColors = + !localStorageTheme || localStorageTheme === "default" || localStorageTheme === configThemeBase; // Apply colors from config (API returns snake_case) - var color1 = config.theme_color1 || config["theme-color1"] || config["Theme Color"] || "#3b82f6"; - var color2 = config.theme_color2 || config["theme-color2"] || "#f5deb3"; - var title = config.theme_title || config["theme-title"] || botName; + var color1 = + config.theme_color1 || + config["theme-color1"] || + config["Theme Color"] || + "#3b82f6"; + var color2 = + config.theme_color2 || + config["theme-color2"] || + "#f5deb3"; + var title = + config.theme_title || config["theme-title"] || botName; var logo = config.theme_logo || config["theme-logo"] || ""; // Only set bot config colors if user hasn't selected a different theme if (useBotConfigColors) { - document.documentElement.setAttribute("data-has-bot-colors", "true"); - document.documentElement.style.setProperty("--chat-color1", color1); - document.documentElement.style.setProperty("--chat-color2", color2); - document.documentElement.style.setProperty("--suggestion-color", color1); - document.documentElement.style.setProperty("--suggestion-bg", color2); - document.documentElement.style.setProperty("--color1", color1); - document.documentElement.style.setProperty("--color2", color2); - document.documentElement.style.setProperty("--primary", color1); - document.documentElement.style.setProperty("--accent", color1); - document.documentElement.style.setProperty("--chat-fg1", getContrastYIQ(color1)); - document.documentElement.style.setProperty("--chat-fg2", getContrastYIQ(color2)); - console.log("Bot config colors applied:", { color1: color1, color2: color2 }); + document.documentElement.setAttribute( + "data-has-bot-colors", + "true", + ); + document.documentElement.style.setProperty( + "--chat-color1", + color1, + ); + document.documentElement.style.setProperty( + "--chat-color2", + color2, + ); + document.documentElement.style.setProperty( + "--suggestion-color", + color1, + ); + document.documentElement.style.setProperty( + "--suggestion-bg", + color2, + ); + document.documentElement.style.setProperty( + "--color1", + color1, + ); + document.documentElement.style.setProperty( + "--color2", + color2, + ); + document.documentElement.style.setProperty( + "--primary", + color1, + ); + document.documentElement.style.setProperty( + "--accent", + color1, + ); + document.documentElement.style.setProperty( + "--chat-fg1", + getContrastYIQ(color1), + ); + document.documentElement.style.setProperty( + "--chat-fg2", + getContrastYIQ(color2), + ); + console.log("Bot config colors applied:", { + color1: color1, + color2: color2, + }); } else { - console.log("Bot config colors skipped - user selected custom theme:", localStorageTheme); + console.log( + "Bot config colors skipped - user selected custom theme:", + localStorageTheme, + ); } // Update logo if provided @@ -1190,7 +1413,12 @@ } } - console.log("Bot config loaded:", { color1: color1, color2: color2, title: title, logo: logo }); + console.log("Bot config loaded:", { + color1: color1, + color2: color2, + title: title, + logo: logo, + }); }) .catch(function (e) { console.log("Could not load bot config:", e); @@ -1305,4 +1533,4 @@ console.log("Chat module initialized with @ mentions support"); })(); - \ No newline at end of file +