From bd312f0979c756094046913d88909442ffe5ae01 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Thu, 1 Jan 2026 12:14:24 -0500 Subject: [PATCH] Echo system prompt as final assistant message for attention reinforcement - Add system prompt as last assistant message in chat history - Support UNCLOSEAI_SYSTEM_PROMPT_REPLACE flag for custom prompts - Use configured voice preference in page-reader TTS - Disable code execution button (sandbox not running) --- public/src/config.js | 21 +++++++++- public/src/page-reader.js | 20 +++++++++- public/src/storage.js | 14 +++---- public/src/uncloseai-embed-modal.js | 59 ++++++----------------------- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/public/src/config.js b/public/src/config.js index 0a77651..6d3e321 100644 --- a/public/src/config.js +++ b/public/src/config.js @@ -22,6 +22,9 @@ export function setSystemMessageAppend(appendText) { // Function to get the complete system message with language preference export async function getSystemMessage() { + const hasCustomPrompt = typeof window !== "undefined" && window.UNCLOSEAI_SYSTEM_PROMPT; + const shouldReplace = typeof window !== "undefined" && window.UNCLOSEAI_SYSTEM_PROMPT_REPLACE === true; + // Get user's language preference from localStorage let userLang = "en"; try { @@ -59,8 +62,22 @@ export async function getSystemMessage() { languageInstruction = `\n\nIMPORTANT: The user has set their language preference to ${langName}. Please respond in ${langName} unless the user explicitly asks for another language. Maintain natural, fluent communication in ${langName}.`; } - const baseMessage = SYSTEM_MESSAGE_APPEND - ? `${SYSTEM_MESSAGE_BASE}\n\n${SYSTEM_MESSAGE_APPEND}` + // If REPLACE flag is set with a custom prompt, use only the custom prompt + if (hasCustomPrompt && shouldReplace) { + console.log("uncloseai.js: Replacing system prompt with custom prompt from parent site"); + return window.UNCLOSEAI_SYSTEM_PROMPT + languageInstruction; + } + + // Combine all append sources: internal SYSTEM_MESSAGE_APPEND + parent's custom prompt + const parentPrompt = hasCustomPrompt ? window.UNCLOSEAI_SYSTEM_PROMPT : ""; + const combinedAppend = [SYSTEM_MESSAGE_APPEND, parentPrompt].filter(Boolean).join("\n\n"); + + if (combinedAppend) { + console.log("uncloseai.js: Appending custom prompt to default system prompt"); + } + + const baseMessage = combinedAppend + ? `${SYSTEM_MESSAGE_BASE}\n\n${combinedAppend}` : SYSTEM_MESSAGE_BASE; return baseMessage + languageInstruction; diff --git a/public/src/page-reader.js b/public/src/page-reader.js index 1b5bdfe..d83b1cb 100644 --- a/public/src/page-reader.js +++ b/public/src/page-reader.js @@ -14,8 +14,24 @@ export async function readPageWithHermes(button = null) { const processedContent = await processContentWithHermes(content); - // Generate TTS with default voice and 90% speed immediately - const { audio, blob } = await speakText(processedContent, "alloy", 0.9); + // Get voice preference from settings (format: "model:voice", e.g., "tts-1:onyx") + let voice = "alloy"; + let model = "tts-1"; + try { + const savedVoice = localStorage.getItem("uncloseai_selected_voice"); + if (savedVoice && savedVoice.includes(":")) { + const parts = savedVoice.split(":"); + model = parts[0]; + voice = parts[1]; + } else if (savedVoice) { + voice = savedVoice; + } + } catch (error) { + console.warn("Failed to read voice preference:", error); + } + + // Generate TTS with configured voice and 90% speed immediately + const { audio, blob } = await speakText(processedContent, voice, 0.9, model); if (button) { button.title = getUIText("readingPageClickToPause"); diff --git a/public/src/storage.js b/public/src/storage.js index 3d37c93..292741a 100644 --- a/public/src/storage.js +++ b/public/src/storage.js @@ -36,21 +36,19 @@ export function loadConversationHistory() { export async function clearConversationHistory() { localStorage.removeItem(getPageSpecificKey("hermes-conversation-history")); + const systemContent = await getSystemMessage(); return [ - { - role: "system", - content: await getSystemMessage(), - }, + { role: "system", content: systemContent }, + { role: "assistant", content: systemContent }, ]; } // Initialize chat history export async function initializeChatHistory() { + const systemContent = await getSystemMessage(); return [ - { - role: "system", - content: await getSystemMessage(), - }, + { role: "system", content: systemContent }, ...loadConversationHistory(), + { role: "assistant", content: systemContent }, ]; } diff --git a/public/src/uncloseai-embed-modal.js b/public/src/uncloseai-embed-modal.js index 909f2e9..5cf9f36 100644 --- a/public/src/uncloseai-embed-modal.js +++ b/public/src/uncloseai-embed-modal.js @@ -136,50 +136,9 @@ function addCodeBlockCopyButtons(element) { buttonContainer.appendChild(copyBtn); - // Add code execution button - const runBtn = document.createElement("button"); - runBtn.className = "uncloseai-code-copy-btn"; // Reuse same styling - runBtn.textContent = "▶"; - runBtn.title = "Run code in sandbox"; + // Code execution button disabled - sandbox service not running + // To re-enable, uncomment the runBtn code below - // Detect language from code block class - let language = 'python'; // Default - const classes = codeBlock.className.split(' '); - for (const cls of classes) { - if (cls.startsWith('language-')) { - language = cls.replace('language-', ''); - break; - } - } - - runBtn.onclick = async () => { - // Create results container if it doesn't exist - let resultsContainer = pre.nextElementSibling; - if (!resultsContainer || !resultsContainer.classList.contains('uncloseai-code-execution-results')) { - resultsContainer = document.createElement('div'); - resultsContainer.className = 'uncloseai-code-execution-results'; - resultsContainer.style.marginTop = '10px'; - resultsContainer.style.padding = '10px'; - - // Match the code block's background color - const preStyles = window.getComputedStyle(pre); - resultsContainer.style.backgroundColor = preStyles.backgroundColor; - - resultsContainer.style.borderRadius = '5px'; - resultsContainer.style.fontFamily = 'monospace'; - resultsContainer.style.fontSize = '14px'; - resultsContainer.style.whiteSpace = 'pre-wrap'; - resultsContainer.style.wordWrap = 'break-word'; - resultsContainer.style.border = '1px solid var(--uncloseai-border-color)'; - pre.parentElement.insertBefore(resultsContainer, pre.nextSibling); - } - - // Execute the code - const { executeCode } = await import("./code-execution.js"); - await executeCode(codeBlock.textContent, language, resultsContainer, runBtn); - }; - - buttonContainer.appendChild(runBtn); pre.appendChild(buttonContainer); } }); @@ -1539,9 +1498,11 @@ You have complete knowledge of this page content and can reference any details, const { getSystemMessage } = await import("./config.js"); // Create new history with updated system message and loaded conversation + const systemContent = await getSystemMessage(); const newHistory = [ - { role: "system", content: await getSystemMessage() }, + { role: "system", content: systemContent }, ...history, + { role: "assistant", content: systemContent }, ]; // Update the chat.js module's history @@ -1686,9 +1647,11 @@ You have complete knowledge of this page content and can reference any details, // Update the chat.js module history to match localStorage const { updateChatHistory } = await import("./chat.js"); const { getSystemMessage } = await import("./config.js"); + const systemContent = await getSystemMessage(); const newHistory = [ - { role: "system", content: await getSystemMessage() }, + { role: "system", content: systemContent }, ...currentHistory, + { role: "assistant", content: systemContent }, ]; await updateChatHistory(newHistory); } @@ -2002,10 +1965,12 @@ You have complete knowledge of this page content and can reference any details, const { updateChatHistory, getChatHistory } = await import("./chat.js"); const { getSystemMessage } = await import("./config.js"); - // Create new history with system message and intro + // Create new history with system message, intro, and echo for attention + const systemContent = await getSystemMessage(); const newHistory = [ - { role: "system", content: await getSystemMessage() }, + { role: "system", content: systemContent }, { role: "assistant", content: response }, + { role: "assistant", content: systemContent }, ]; // Update the chat.js module's history