diff --git a/RETRIEX_SSE_FINAL_THINK_CLEANUP_FIX_README.md b/RETRIEX_SSE_FINAL_THINK_CLEANUP_FIX_README.md new file mode 100644 index 0000000..653edc9 --- /dev/null +++ b/RETRIEX_SSE_FINAL_THINK_CLEANUP_FIX_README.md @@ -0,0 +1,16 @@ +# RetrieX SSE final think cleanup fix + +This patch fixes a frontend finalization issue where the SSE stream could receive +`event: done` / `[DONE]`, but the last transient `.think` status such as +"Denke nach..." stayed visible. + +The streaming renderer still keeps the latest `.think` block while the answer is +running. On final `done`, it now removes all transient `.think` blocks and also +removes the loader CSS class. This is a UI-only fix and does not change retrieval, +prompting, shop search, scoring, or SSE job logic. + +Changed files: + +- public/assets/js/base.js + +After applying the patch, clear Symfony/browser asset cache as appropriate. diff --git a/public/assets/js/base.js b/public/assets/js/base.js index 53aba97..6ce80e6 100644 --- a/public/assets/js/base.js +++ b/public/assets/js/base.js @@ -232,11 +232,16 @@ document.addEventListener('DOMContentLoaded', () => { return false; } - function cleanupThinkSpans(container) { + function cleanupThinkSpans(container, final = false) { if (!container) { return; } + if (final) { + removeThinkSpansOnly(container); + return; + } + const thinkSpans = Array.from(container.querySelectorAll('.think')); if (thinkSpans.length === 0) { @@ -254,9 +259,9 @@ document.addEventListener('DOMContentLoaded', () => { removeThinkSpansOnly(container); } - function renderBubbleContent(bubble, raw) { + function renderBubbleContent(bubble, raw, final = false) { bubble.innerHTML = renderMarkdown(raw); - cleanupThinkSpans(bubble); + cleanupThinkSpans(bubble, final); enhanceChatLinks(bubble); scrollChatToBottom(); } @@ -333,7 +338,8 @@ document.addEventListener('DOMContentLoaded', () => { function finalizeStream(bubble, raw) { clearScheduledRender(); - renderBubbleContent(bubble, raw); + bubble.classList.remove('loader'); + renderBubbleContent(bubble, raw, true); } async function releaseStreamResources() { @@ -567,7 +573,7 @@ document.addEventListener('DOMContentLoaded', () => { if (raw.trim() !== '') { const formattedMessage = `${userMessage}`; raw += raw.trim() === '' ? formattedMessage : `\n\n${formattedMessage}`; - renderBubbleContent(bubble, raw); + renderBubbleContent(bubble, raw, true); } else { bubble.innerHTML = `${userMessage}`; enhanceChatLinks(bubble);