fix: Add switcher support to chat page - render switcher chips from BotResponse, auto-activate on switch_context suggestion click, include active_switchers in WS payload (#495)
This commit is contained in:
parent
c34b719515
commit
1bb96f1923
1 changed files with 120 additions and 39 deletions
|
|
@ -22,8 +22,14 @@
|
||||||
<main id="messages"></main>
|
<main id="messages"></main>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<div class="suggestions-container" id="suggestions"></div>
|
<div class="chat-footer-content">
|
||||||
<div class="mention-dropdown" id="mentionDropdown">
|
<div class="suggestions-container" id="suggestions"></div>
|
||||||
|
<div class="switchers-container" id="switchers" style="display:none">
|
||||||
|
<div class="switchers-label">Formato:</div>
|
||||||
|
<div class="switchers-chips" id="switcherChips"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mention-dropdown" id="mentionDropdown">
|
||||||
<div class="mention-header">
|
<div class="mention-header">
|
||||||
<span class="mention-title" data-i18n="chat-mention-title"
|
<span class="mention-title" data-i18n="chat-mention-title"
|
||||||
>Reference Entity</span
|
>Reference Entity</span
|
||||||
|
|
@ -171,10 +177,12 @@
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var ws = null;
|
var ws = null;
|
||||||
var currentSessionId = null;
|
var currentSessionId = null;
|
||||||
var currentUserId = null;
|
var currentUserId = null;
|
||||||
var currentBotId = "default";
|
var currentBotId = "default";
|
||||||
|
var activeSwitchers = new Set();
|
||||||
|
var switcherDefinitions = [];
|
||||||
var currentBotName = "default";
|
var currentBotName = "default";
|
||||||
var isStreaming = false;
|
var isStreaming = false;
|
||||||
var streamingMessageId = null;
|
var streamingMessageId = null;
|
||||||
|
|
@ -192,11 +200,73 @@
|
||||||
results: [],
|
results: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
function escapeHtml(text) {
|
function escapeHtml(text) {
|
||||||
var div = document.createElement("div");
|
var div = document.createElement("div");
|
||||||
div.textContent = text;
|
div.textContent = text;
|
||||||
return div.innerHTML;
|
return div.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var SWITCHER_ICONS = {
|
||||||
|
tables: "\u{1F4CA}", infographic: "\u{1F4CD}", cards: "\u{1F0CF}",
|
||||||
|
list: "\u{1F4CB}", comparison: "\u2696", timeline: "\u{23F0}",
|
||||||
|
markdown: "\u{1F4DD}", chart: "\u{1F4C8}"
|
||||||
|
};
|
||||||
|
|
||||||
|
function renderSwitcherChips() {
|
||||||
|
var container = document.getElementById("switcherChips");
|
||||||
|
if (!container) return;
|
||||||
|
container.innerHTML = switcherDefinitions.map(function(sw) {
|
||||||
|
var isActive = activeSwitchers.has(sw.id);
|
||||||
|
return '<div class="switcher-chip' + (isActive ? ' active' : '') + '" ' +
|
||||||
|
'data-switch-id="' + sw.id + '" ' +
|
||||||
|
'style="--switcher-color: ' + (sw.color || '#666') + '; ' +
|
||||||
|
(isActive ? 'color: white; background: ' + (sw.color || '#666') + '; ' : '') + '">' +
|
||||||
|
'<span class="switcher-chip-icon">' + (sw.icon || '\u{1F500}') + '</span>' +
|
||||||
|
'<span>' + sw.label + '</span></div>';
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSwitcher(switcherId) {
|
||||||
|
if (activeSwitchers.has(switcherId)) {
|
||||||
|
activeSwitchers.delete(switcherId);
|
||||||
|
} else {
|
||||||
|
activeSwitchers.add(switcherId);
|
||||||
|
}
|
||||||
|
renderSwitcherChips();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBotSwitchers(switchers) {
|
||||||
|
if (!switchers || switchers.length === 0) return;
|
||||||
|
var existingIds = {};
|
||||||
|
switcherDefinitions.forEach(function(sw) { existingIds[sw.id] = true; });
|
||||||
|
switchers.forEach(function(sw) {
|
||||||
|
if (!existingIds[sw.id]) {
|
||||||
|
switcherDefinitions.push({
|
||||||
|
id: sw.id,
|
||||||
|
label: sw.label || sw.id,
|
||||||
|
icon: sw.icon || SWITCHER_ICONS[sw.id] || "\u{1F500}",
|
||||||
|
color: sw.color || "#666"
|
||||||
|
});
|
||||||
|
existingIds[sw.id] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
renderSwitcherChips();
|
||||||
|
var container = document.getElementById("switchers");
|
||||||
|
if (container && switcherDefinitions.length > 0) {
|
||||||
|
container.style.display = '';
|
||||||
|
}
|
||||||
|
var chipsContainer = document.getElementById("switcherChips");
|
||||||
|
if (chipsContainer && !chipsContainer.dataset.hasClickHandler) {
|
||||||
|
chipsContainer.addEventListener("click", function(e) {
|
||||||
|
var chip = e.target.closest(".switcher-chip");
|
||||||
|
if (chip) {
|
||||||
|
var switcherId = chip.getAttribute("data-switch-id");
|
||||||
|
if (switcherId) toggleSwitcher(switcherId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
chipsContainer.dataset.hasClickHandler = "true";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Scroll handling
|
// Scroll handling
|
||||||
function scrollToBottom(animate) {
|
function scrollToBottom(animate) {
|
||||||
|
|
@ -829,9 +899,12 @@ function updateStreaming(content) {
|
||||||
addMessage("bot", data.content);
|
addMessage("bot", data.content);
|
||||||
}
|
}
|
||||||
isStreaming = false;
|
isStreaming = false;
|
||||||
if (data.suggestions && Array.isArray(data.suggestions) && data.suggestions.length > 0) {
|
if (data.suggestions && Array.isArray(data.suggestions) && data.suggestions.length > 0) {
|
||||||
renderSuggestions(data.suggestions);
|
renderSuggestions(data.suggestions);
|
||||||
}
|
}
|
||||||
|
if (data.switchers && Array.isArray(data.switchers) && data.switchers.length > 0) {
|
||||||
|
renderBotSwitchers(data.switchers);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isStreaming) {
|
if (!isStreaming) {
|
||||||
isStreaming = true;
|
isStreaming = true;
|
||||||
|
|
@ -892,19 +965,26 @@ function updateStreaming(content) {
|
||||||
|
|
||||||
console.log("Parsed action:", action);
|
console.log("Parsed action:", action);
|
||||||
|
|
||||||
if (action.type === "invoke_tool") {
|
if (action.type === "invoke_tool") {
|
||||||
// Invoke tool directly via WebSocket - invisible to user
|
// Invoke tool directly via WebSocket - invisible to user
|
||||||
ws.send(JSON.stringify({
|
ws.send(JSON.stringify({
|
||||||
bot_id: currentBotId,
|
bot_id: currentBotId,
|
||||||
user_id: currentUserId,
|
user_id: currentUserId,
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
channel: "web",
|
channel: "web",
|
||||||
content: action.tool,
|
content: action.tool,
|
||||||
message_type: 6, // TOOL_EXEC
|
message_type: 6, // TOOL_EXEC
|
||||||
timestamp: new Date().toISOString(),
|
active_switchers: Array.from(activeSwitchers),
|
||||||
}));
|
timestamp: new Date().toISOString(),
|
||||||
return;
|
}));
|
||||||
} else if (action.type === "send_message") {
|
return;
|
||||||
|
} else if (action.type === "switch_context" && action.switcher) {
|
||||||
|
if (!activeSwitchers.has(action.switcher)) {
|
||||||
|
activeSwitchers.add(action.switcher);
|
||||||
|
renderSwitcherChips();
|
||||||
|
}
|
||||||
|
window.sendMessage(sugg.text);
|
||||||
|
} else if (action.type === "send_message") {
|
||||||
window.sendMessage(
|
window.sendMessage(
|
||||||
action.message || sugg.text,
|
action.message || sugg.text,
|
||||||
);
|
);
|
||||||
|
|
@ -962,18 +1042,19 @@ function sendMessage(messageContent) {
|
||||||
|
|
||||||
addMessage("user", content);
|
addMessage("user", content);
|
||||||
|
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
ws.send(
|
ws.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
bot_id: currentBotId,
|
bot_id: currentBotId,
|
||||||
user_id: currentUserId,
|
user_id: currentUserId,
|
||||||
session_id: currentSessionId,
|
session_id: currentSessionId,
|
||||||
channel: "web",
|
channel: "web",
|
||||||
content: content,
|
content: content,
|
||||||
message_type: MessageType.USER,
|
message_type: MessageType.USER,
|
||||||
timestamp: new Date().toISOString(),
|
active_switchers: Array.from(activeSwitchers),
|
||||||
}),
|
timestamp: new Date().toISOString(),
|
||||||
);
|
}),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
notify("Not connected to server. Message not sent.", "warning");
|
notify("Not connected to server. Message not sent.", "warning");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue