58 lines
2.4 KiB
JavaScript
58 lines
2.4 KiB
JavaScript
import {supportsReasoning} from "./modelCapabilities.js?v=20260921-reasoning-capability";
|
|
|
|
export function createReasoningToggle(button) {
|
|
let reasoningEnabled = false;
|
|
let supported = false;
|
|
let busy = false;
|
|
const render = () => {
|
|
button.disabled = !supported || busy;
|
|
button.setAttribute("aria-pressed", String(reasoningEnabled));
|
|
button.title = !supported ? "This model does not support reasoning"
|
|
: reasoningEnabled ? "Reasoning enabled" : "Enable reasoning";
|
|
button.setAttribute("aria-label", button.title);
|
|
};
|
|
button.addEventListener("click", () => {
|
|
if (!supported || busy) return;
|
|
reasoningEnabled = !reasoningEnabled;
|
|
render();
|
|
});
|
|
render();
|
|
return {
|
|
get enabled() { return reasoningEnabled; },
|
|
reset() { reasoningEnabled = false; render(); },
|
|
setModel(model) { supported = supportsReasoning(model); if (!supported) reasoningEnabled = false; render(); },
|
|
setBusy(value) { busy = value; render(); }
|
|
};
|
|
}
|
|
|
|
export function updateReasoning(messageElement, thinking, streaming = false) {
|
|
let details = messageElement.querySelector(".msg-reasoning");
|
|
if (!thinking) {
|
|
details?.remove();
|
|
return;
|
|
}
|
|
if (!details) {
|
|
details = document.createElement("details");
|
|
details.className = "msg-reasoning";
|
|
details.open = streaming;
|
|
const summary = document.createElement("summary");
|
|
const content = document.createElement("div");
|
|
content.className = "msg-reasoning-content";
|
|
details.append(summary, content);
|
|
messageElement.insertBefore(details, messageElement.querySelector(".msg-content"));
|
|
}
|
|
details.querySelector("summary").textContent = streaming ? "Reasoning · Thinking…" : "Reasoning";
|
|
const content = details.querySelector(".msg-reasoning-content");
|
|
const follow = content.scrollHeight - content.scrollTop - content.clientHeight < 40;
|
|
content.textContent = thinking;
|
|
if (streaming && follow) content.scrollTop = content.scrollHeight;
|
|
}
|
|
|
|
export function finishReasoning(messageElement) {
|
|
const details = messageElement.querySelector(".msg-reasoning");
|
|
if (!details || details.dataset.complete) return;
|
|
details.dataset.complete = "true";
|
|
details.open = false;
|
|
details.querySelector("summary").textContent = "Reasoning · Completed";
|
|
}
|