small polishes and cleanups

frdel committed Jan 29, 2026 at 09:19 UTC 68e33c6a75772375612be8791222a3ffd73fe912
2 files changed +42 -125
webui/components/messages/action-buttons/simple-action-buttons.js
+2 -2
@@ -54,7 +54,7 @@ export function showButtonFeedback(button, success, originalIcon) {
54 setTimeout(() => {
55 icon.textContent = originalIcon;
56 button.classList.remove("success", "error");
57 - }, 2000);
57 + }, 1000);
58 }
59
60 /**
@@ -77,7 +77,7 @@ export function createActionButton(icon, text = "", handler = null) {
77 if (typeof handler === "function") {
78 button.addEventListener("click", async (event) => {
79 event.stopPropagation();
80 - const shouldShowFeedback = icon === "copy" || icon === "speak";
80 + const shouldShowFeedback = true; // icon === "copy" || icon === "speak";
81 try {
82 await handler();
83 if (shouldShowFeedback) {
webui/js/messages.js
+40 -123
@@ -61,108 +61,6 @@ export function getMessageHandler(type) {
61 }
62 }
63
64 -/**
65 - * Mark a process group as the active one (via .active class)
66 - */
67 -function setActiveProcessGroup(group) {
68 - // if (!group) return;
69 - // // Already active? Nothing to do
70 - // if (group.classList.contains("active")) return;
71 - // // Clear active + shiny from all other groups
72 - // getChatHistoryEl()
73 - // .querySelectorAll(".process-group.active")
74 - // .forEach((g) => {
75 - // if (g !== group) {
76 - // g.classList.remove("active");
77 - // g.querySelectorAll(".step-title.shiny-text").forEach((el) =>
78 - // el.classList.remove("shiny-text"),
79 - // );
80 - // }
81 - // });
82 - // // Mark this group as active
83 - // group.classList.add("active");
84 -}
85 -
86 -function getChatHistoryEl() {
87 - if (!_chatHistory) _chatHistory = document.getElementById("chat-history");
88 - return _chatHistory;
89 -}
90 -
91 -function getLastMessageGroup() {
92 - return getChatHistoryEl()?.lastElementChild;
93 -}
94 -
95 -// function getLastMessageContainer() {
96 -// const chatHistoryEl = getChatHistoryEl();
97 -// if (!chatHistoryEl) return null;
98 -// const lastGroup = chatHistoryEl.lastElementChild;
99 -// if (!lastGroup) return null;
100 -// return lastGroup.lastElementChild;
101 -// }
102 -
103 -function appendToMessageGroup(
104 - messageContainer,
105 - position,
106 - forceNewGroup = false,
107 -) {
108 - const chatHistoryEl = getChatHistoryEl();
109 - if (!chatHistoryEl) return;
110 -
111 - const lastGroup = chatHistoryEl.lastElementChild;
112 - const lastGroupType = lastGroup?.getAttribute("data-group-type");
113 -
114 - if (!forceNewGroup && lastGroup && lastGroupType === position) {
115 - lastGroup.appendChild(messageContainer);
116 - } else {
117 - const group = document.createElement("div");
118 - group.classList.add("message-group", `message-group-${position}`);
119 - group.setAttribute("data-group-type", position);
120 - group.appendChild(messageContainer);
121 - chatHistoryEl.appendChild(group);
122 - }
123 -}
124 -
125 -// function getStatusCode(type, toolName = null) {
126 -// if (type === "tool" && toolName && TOOL_STATUS_CODES[toolName]) {
127 -// return TOOL_STATUS_CODES[toolName];
128 -// }
129 -// return TYPE_STATUS_CODES[type] || type?.toUpperCase()?.slice(0, 4) || "GEN";
130 -// }
131 -
132 -// function getStatusClass(type, toolName = null) {
133 -// if (type === "tool" && toolName && TOOL_STATUS_CLASSES[toolName]) {
134 -// return TOOL_STATUS_CLASSES[toolName];
135 -// }
136 -// return TYPE_STATUS_CLASSES[type] || "status-gen";
137 -// }
138 -
139 -// /**
140 -// * Resolve tool name from kvps, existing attribute, or previous siblings
141 -// * For 'tool' type steps, inherits from preceding step if not directly available
142 -// */
143 -// function resolveToolName(type, kvps, stepElement) {
144 -// // Direct from kvps
145 -// if (kvps?.tool_name) return kvps.tool_name;
146 -
147 -// // Keep existing if present (for non-tool types during updates)
148 -// if (type !== "tool" && stepElement?.hasAttribute("data-tool-name")) {
149 -// return stepElement.getAttribute("data-tool-name");
150 -// }
151 -
152 -// // // Inherit from previous sibling (for tool steps)
153 -// // if (type === 'tool' && stepElement) {
154 -// // let prev = stepElement.previousElementSibling;
155 -// // while (prev) {
156 -// // if (prev.hasAttribute('data-tool-name')) {
157 -// // return prev.getAttribute('data-tool-name');
158 -// // }
159 -// // prev = prev.previousElementSibling;
160 -// // }
161 -// // }
162 -
163 -// return null;
164 -// }
165 -
64 // entrypoint called from poll/WS communication, this is how all messages are rendered and updated
65 // input is raw log format
66 export function setMessages(messages) {
@@ -233,6 +131,38 @@ function getOrCreateMessageContainer(
131 return container;
132 }
133
134 +
135 +function getChatHistoryEl() {
136 + if (!_chatHistory) _chatHistory = document.getElementById("chat-history");
137 + return _chatHistory;
138 +}
139 +
140 +function getLastMessageGroup() {
141 + return getChatHistoryEl()?.lastElementChild;
142 +}
143 +
144 +function appendToMessageGroup(
145 + messageContainer,
146 + position,
147 + forceNewGroup = false,
148 +) {
149 + const chatHistoryEl = getChatHistoryEl();
150 + if (!chatHistoryEl) return;
151 +
152 + const lastGroup = chatHistoryEl.lastElementChild;
153 + const lastGroupType = lastGroup?.getAttribute("data-group-type");
154 +
155 + if (!forceNewGroup && lastGroup && lastGroupType === position) {
156 + lastGroup.appendChild(messageContainer);
157 + } else {
158 + const group = document.createElement("div");
159 + group.classList.add("message-group", `message-group-${position}`);
160 + group.setAttribute("data-group-type", position);
161 + group.appendChild(messageContainer);
162 + chatHistoryEl.appendChild(group);
163 + }
164 +}
165 +
166 function getLastProcessGroup(allowCompleted = true) {
167 const lastContainer = getLastMessageGroup();
168 if (!lastContainer) return null;
@@ -268,22 +198,13 @@ function getOrCreateProcessGroup(id, allowCompleted = true) {
198 messageContainer.appendChild(group);
199
200 appendToMessageGroup(messageContainer, "left");
271 - setActiveProcessGroup(group);
201 return group;
202 }
203
204 function buildDetailPayload(stepData, extras = {}) {
205 if (!stepData) return null;
206 return {
278 - type: stepData.type,
279 - heading: stepData.heading,
280 - content: stepData.content,
281 - kvps: stepData.kvps,
282 - timestamp: stepData.timestamp,
283 - agentno: stepData.agentno,
284 - toolName: stepData.toolName,
285 - statusCode: stepData.statusCode,
286 - statusClass: stepData.statusClass,
207 + ...stepData,
208 ...extras,
209 };
210 }
@@ -800,8 +721,6 @@ export function drawMessageResponse({
721 // response of subordinate agent - render as process step
722 if (agentno && agentno > 0) {
723 const title = getStepTitle(heading, kvps, type);
803 - const statusCode = getStatusCode(type);
804 - const statusClass = getStatusClass(type);
724 const contentText = String(content ?? "");
725 const actionButtons = contentText.trim()
726 ? [
@@ -812,8 +731,8 @@ export function drawMessageResponse({
731 return drawProcessStep({
732 id,
733 title,
815 - statusClass,
816 - statusCode,
734 + // statusClass,
735 + statusCode: "RSP",
736 kvps,
737 type,
738 heading,
@@ -1097,7 +1016,7 @@ export function drawMessageCodeExe({
1016 let title = "Code Execution";
1017 // show command at the start and end
1018 if (kvps?.code && /done_all|code_execution_tool/.test(heading || "")) {
1100 - const s = kvps.session ?? kvps.Session;
1019 + const s = kvps.session;
1020 title = `${s != null ? `[${s}] ` : ""}${kvps.runtime || "bash"}> ${kvps.code.trim()}`;
1021 } else {
1022 // during execution show the original heading (current step)
@@ -1106,8 +1025,8 @@ export function drawMessageCodeExe({
1025
1026 // KVPS to show
1027 const displayKvps = {};
1109 - if (kvps?.runtime) displayKvps.runtime = kvps.runtime;
1110 - if (kvps?.session) displayKvps.session = kvps.session;
1028 + // if (kvps?.runtime) displayKvps.runtime = kvps.runtime;
1029 + // if (kvps?.session>=0) displayKvps.session = kvps.session;
1030
1031 const headerLabels = [
1032 kvps?.runtime && { label: kvps.runtime, class: "tool-name-badge" },
@@ -1341,8 +1260,6 @@ export function drawMessageHint({
1260 ...additional
1261 }) {
1262 const title = getStepTitle(heading, kvps, type);
1344 - const statusCode = getStatusCode(type);
1345 - const statusClass = getStatusClass(type);
1263 const contentText = String(content ?? "");
1264 const actionButtons = contentText.trim()
1265 ? [
@@ -1354,8 +1271,8 @@ export function drawMessageHint({
1271 return drawStandaloneMessage({
1272 id,
1273 title,
1357 - statusClass,
1358 - statusCode,
1274 + // statusClass,
1275 + statusCode: "HNT",
1276 kvps,
1277 type,
1278 heading,