Spaces:
Running
Running
Update public/index.html
Browse files- public/index.html +116 -1
public/index.html
CHANGED
|
@@ -501,4 +501,119 @@
|
|
| 501 |
);
|
| 502 |
buffer = '';
|
| 503 |
progress = true;
|
| 504 |
-
} catch (_) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 501 |
);
|
| 502 |
buffer = '';
|
| 503 |
progress = true;
|
| 504 |
+
} catch (_) {
|
| 505 |
+
buffer = buffer.slice(usageIdx);
|
| 506 |
+
}
|
| 507 |
+
|
| 508 |
+
} else if (thinkIdx !== -1) {
|
| 509 |
+
if (thinkIdx > 0) {
|
| 510 |
+
aiContent += buffer.slice(0, thinkIdx);
|
| 511 |
+
buffer = buffer.slice(thinkIdx);
|
| 512 |
+
}
|
| 513 |
+
const afterMarker = buffer.slice(MARKER_LEN);
|
| 514 |
+
const nextThink = afterMarker.indexOf('__THINK__');
|
| 515 |
+
const nextUsage = afterMarker.indexOf('__USAGE__');
|
| 516 |
+
const candidates = [nextThink, nextUsage].filter(x => x !== -1);
|
| 517 |
+
const nextMarker = candidates.length ? Math.min(...candidates) : -1;
|
| 518 |
+
|
| 519 |
+
if (nextMarker !== -1) {
|
| 520 |
+
aiReasoning += afterMarker.slice(0, nextMarker);
|
| 521 |
+
buffer = afterMarker.slice(nextMarker);
|
| 522 |
+
progress = true;
|
| 523 |
+
} else {
|
| 524 |
+
const safeLen = afterMarker.length - MARKER_LEN;
|
| 525 |
+
if (safeLen > 0) {
|
| 526 |
+
aiReasoning += afterMarker.slice(0, safeLen);
|
| 527 |
+
buffer = '__THINK__' + afterMarker.slice(safeLen);
|
| 528 |
+
}
|
| 529 |
+
}
|
| 530 |
+
|
| 531 |
+
} else {
|
| 532 |
+
if (final) {
|
| 533 |
+
aiContent += buffer;
|
| 534 |
+
buffer = '';
|
| 535 |
+
progress = true;
|
| 536 |
+
} else {
|
| 537 |
+
const safeLen = buffer.length - MARKER_LEN;
|
| 538 |
+
if (safeLen > 0) {
|
| 539 |
+
aiContent += buffer.slice(0, safeLen);
|
| 540 |
+
buffer = buffer.slice(safeLen);
|
| 541 |
+
progress = true;
|
| 542 |
+
}
|
| 543 |
+
}
|
| 544 |
+
}
|
| 545 |
+
}
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
while (true) {
|
| 549 |
+
const { value, done } = await reader.read();
|
| 550 |
+
|
| 551 |
+
if (done) {
|
| 552 |
+
flushBuffer(true);
|
| 553 |
+
break;
|
| 554 |
+
}
|
| 555 |
+
|
| 556 |
+
buffer += decoder.decode(value, { stream: true });
|
| 557 |
+
flushBuffer(false);
|
| 558 |
+
|
| 559 |
+
let tempHtml = '';
|
| 560 |
+
if (aiReasoning) tempHtml += `<div class="reasoning-block"><i>Thinking Process</i><br/>${marked.parse(aiReasoning)}</div>`;
|
| 561 |
+
if (aiContent) tempHtml += DOMPurify.sanitize(marked.parse(aiContent));
|
| 562 |
+
|
| 563 |
+
const tempMsg = document.getElementById('temp-ai-msg');
|
| 564 |
+
if (tempMsg) {
|
| 565 |
+
tempMsg.innerHTML = tempHtml || "<span class='animate-pulse text-gray-400'>Thinking...</span>";
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
if (container.scrollHeight - container.scrollTop - container.clientHeight < 100) {
|
| 569 |
+
scrollToBottom();
|
| 570 |
+
}
|
| 571 |
+
}
|
| 572 |
+
|
| 573 |
+
const tempWrapper = document.getElementById('temp-ai-wrapper');
|
| 574 |
+
if (tempWrapper) {
|
| 575 |
+
let finalHtml = '';
|
| 576 |
+
if (aiReasoning) finalHtml += `<div class="reasoning-block"><i>Thinking Process</i><br/>${marked.parse(aiReasoning)}</div>`;
|
| 577 |
+
if (aiContent) finalHtml += DOMPurify.sanitize(marked.parse(aiContent));
|
| 578 |
+
|
| 579 |
+
tempWrapper.outerHTML = `
|
| 580 |
+
<div class="flex justify-start w-full">
|
| 581 |
+
<div class="max-w-[95%] lg:max-w-[85%] rounded-2xl rounded-bl-sm p-4 bg-gray-850 border border-gray-800 text-gray-200 markdown-body shadow-sm">
|
| 582 |
+
${finalHtml || "<span class='text-gray-500'>No response generated.</span>"}
|
| 583 |
+
</div>
|
| 584 |
+
</div>`;
|
| 585 |
+
attachCopyButtons();
|
| 586 |
+
}
|
| 587 |
+
|
| 588 |
+
// Final sync with API state (strictly last 3)
|
| 589 |
+
const finalRes = await fetch(`/api/chats/${currentChatId}`);
|
| 590 |
+
const finalChat = await finalRes.json();
|
| 591 |
+
renderMessages(finalChat.messages);
|
| 592 |
+
loadSidebar();
|
| 593 |
+
|
| 594 |
+
} catch (error) {
|
| 595 |
+
console.error(error);
|
| 596 |
+
const tempMsg = document.getElementById('temp-ai-msg');
|
| 597 |
+
if (tempMsg) {
|
| 598 |
+
tempMsg.innerHTML = "<span class='text-red-400'>Connection lost or chat busy. Reload to sync.</span>";
|
| 599 |
+
}
|
| 600 |
+
} finally {
|
| 601 |
+
if (pollingInterval === null) toggleInputState(false);
|
| 602 |
+
}
|
| 603 |
+
}
|
| 604 |
+
|
| 605 |
+
// βββ Keyboard shortcut ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 606 |
+
document.getElementById('message-input').addEventListener('keydown', e => {
|
| 607 |
+
if (e.key === 'Enter' && !e.shiftKey) {
|
| 608 |
+
e.preventDefault();
|
| 609 |
+
if (!document.getElementById('send-btn').classList.contains('hidden')) {
|
| 610 |
+
sendMessage();
|
| 611 |
+
}
|
| 612 |
+
}
|
| 613 |
+
});
|
| 614 |
+
|
| 615 |
+
// βββ Boot βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 616 |
+
loadSidebar();
|
| 617 |
+
</script>
|
| 618 |
+
</body>
|
| 619 |
+
</html>
|