Files
KrisHD_AI/public/app/reasoning.js
T

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";
}