';
return html;
}
updateLastQuery(query, topMatches) {
const queryEl = this.panel.querySelector('#last-query');
queryEl.textContent = query;
this.lastQueryData = {
query,
topMatches,
timestamp: new Date()
};
}
clearChatSession() {
// Determine the active bot ID from MxChatInstances
let botId = 'default';
if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getAllBotIds === 'function') {
const botIds = MxChatInstances.getAllBotIds();
if (botIds.length > 0) {
botId = botIds[0];
}
}
// Get current session ID using the correct bot-suffixed cookie name
const cookieName = 'mxchat_session_id_' + botId;
const sessionId = this.getCookie(cookieName) || this.getCookie('mxchat_session_id') || this.getCurrentSessionId();
if (!sessionId) {
this.log('No active session found');
return;
}
this.log('Current session ID: ' + sessionId);
this.log('Starting fresh session...');
// Use MxChatInstances.resetChatSession to properly reset in-memory state + cookie
if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.resetChatSession === 'function') {
MxChatInstances.resetChatSession(botId);
}
// Get the new session ID that was just set by resetChatSession
let newSessionId = '';
if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getChatSession === 'function') {
newSessionId = MxChatInstances.getChatSession(botId);
}
// Fallback if MxChatInstances wasn't available
if (!newSessionId) {
newSessionId = 'mxchat_chat_' + Math.random().toString(36).substr(2, 9);
this.clearMxChatCookie(botId);
this.setChatSession(newSessionId, botId);
}
this.log('New session ID: ' + newSessionId);
// Call backend to clear old session data
fetch(mxchatTestData.ajaxUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'mxchat_start_fresh_session',
nonce: mxchatTestData.nonce,
old_session_id: sessionId,
new_session_id: newSessionId
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
this.log('Backend session cleared: ' + data.data.message);
// Update the session ID everywhere in the DOM
this.updateSessionIdEverywhere(newSessionId);
// Clear the chat UI
this.clearChatUI();
// Show popular questions again
const popularQuestions = document.querySelector('#mxchat-popular-questions');
if (popularQuestions) {
popularQuestions.style.display = 'block';
}
// Clear testing data displays
this.updateLastQuery('New session started', []);
this.updateTopMatches([], 0);
this.updateApprovedUrls([]);
this.log('Fresh session started successfully');
} else {
this.log('Error clearing session: ' + (data.data?.message || 'Unknown error'));
}
})
.catch(error => {
console.error('Error clearing chat session:', error);
this.log('Connection error when clearing session');
});
}
// Helper function to get cookie (same as your existing one)
getCookie(name) {
let value = "; " + document.cookie;
let parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
// Helper function to set session cookie (matches chat-script.js format)
setChatSession(sessionId, botId) {
botId = botId || 'default';
document.cookie = 'mxchat_session_id_' + botId + '=' + sessionId + '; path=/; max-age=86400; SameSite=Lax';
}
// Helper function to clear the MxChat session cookie
clearMxChatCookie(botId) {
botId = botId || 'default';
// Clear both bot-suffixed and legacy cookie formats
document.cookie = 'mxchat_session_id_' + botId + '=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
document.cookie = 'mxchat_session_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Lax';
this.log('Session cookie cleared');
}
updateSessionIdEverywhere(newSessionId) {
// Update global session ID variable if it exists
if (window.mxchatSessionId) {
window.mxchatSessionId = newSessionId;
}
// Update session ID in chat input data attribute
const chatInput = document.querySelector('#chat-input');
if (chatInput) {
chatInput.dataset.sessionId = newSessionId;
}
// Update any hidden session ID fields
const sessionInputs = document.querySelectorAll('input[name="session_id"]');
sessionInputs.forEach(input => {
input.value = newSessionId;
});
// Update any data attributes that store session ID
const elementsWithSessionId = document.querySelectorAll('[data-session-id]');
elementsWithSessionId.forEach(element => {
element.dataset.sessionId = newSessionId;
});
// Update URL parameter if it exists
if (window.location.search.includes('session_id=')) {
const url = new URL(window.location);
url.searchParams.set('session_id', newSessionId);
window.history.replaceState({}, '', url);
}
this.log('๐ Session ID updated everywhere in DOM');
}
clearChatUI() {
const chatBox = document.querySelector('#chat-box');
if (chatBox) {
// Remove all messages (both user and bot)
const allMessages = chatBox.querySelectorAll('.bot-message, .user-message');
allMessages.forEach(msg => {
// Keep the first bot message if it's a welcome message
if (msg === chatBox.querySelector('.bot-message') &&
msg.textContent.toLowerCase().includes('welcome')) {
return; // Keep welcome message
}
msg.remove();
});
this.log('๐งน Chat UI cleared');
}
// Clear chat input
const chatInput = document.querySelector('#chat-input');
if (chatInput) {
chatInput.value = '';
}
}
getCurrentSessionId() {
// Try MxChatInstances first (most reliable โ matches chat-script.js)
if (typeof MxChatInstances !== 'undefined' && typeof MxChatInstances.getChatSession === 'function') {
const botIds = typeof MxChatInstances.getAllBotIds === 'function' ? MxChatInstances.getAllBotIds() : ['default'];
const botId = botIds.length > 0 ? botIds[0] : 'default';
const instanceSession = MxChatInstances.getChatSession(botId);
if (instanceSession) {
return instanceSession;
}
}
// Try bot-suffixed cookie, then legacy cookie
const botCookieId = this.getCookie('mxchat_session_id_default');
if (botCookieId) {
return botCookieId;
}
const cookieSessionId = this.getCookie('mxchat_session_id');
if (cookieSessionId) {
return cookieSessionId;
}
// Try to get session ID from various DOM sources
const chatInput = document.querySelector('#chat-input');
if (chatInput && chatInput.dataset.sessionId) {
return chatInput.dataset.sessionId;
}
// Try to get from URL parameters
const urlParams = new URLSearchParams(window.location.search);
const sessionFromUrl = urlParams.get('session_id');
if (sessionFromUrl) {
return sessionFromUrl;
}
// Try to get from global variables
if (window.chatSessionId) {
return window.chatSessionId;
}
// Generate a temporary session ID if none found
return 'mxchat_chat_' + Math.random().toString(36).substr(2, 9);
}
loadSystemInfo() {
// Load system information from backend
this.updateSimilarityThreshold();
this.updateSystemPrompt();
this.updateKnowledgeBaseStatus();
}
updateSimilarityThreshold() {
fetch(mxchatTestData.ajaxUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'mxchat_get_similarity_threshold',
nonce: mxchatTestData.nonce
})
})
.then(response => response.json())
.then(data => {
const thresholdEl = this.panel.querySelector('#similarity-threshold');
if (data.success) {
thresholdEl.innerHTML = `${data.data.threshold_percentage}`;
} else {
thresholdEl.innerHTML = 'Error loading threshold';
}
})
.catch(error => {
console.error('Error fetching similarity threshold:', error);
const thresholdEl = this.panel.querySelector('#similarity-threshold');
thresholdEl.innerHTML = 'Connection error';
});
}
updateSystemPrompt() {
const promptEl = this.panel.querySelector('#system-prompt');
promptEl.textContent = 'Loading system prompt...';
fetch(mxchatTestData.ajaxUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'mxchat_get_system_info',
nonce: mxchatTestData.nonce
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
promptEl.textContent = data.data.system_prompt || 'No system prompt configured';
// Enhanced model display with OpenRouter support
if (data.data.is_openrouter) {
this.log(`๐ค Model: OpenRouter`);
this.log(` โโ Using: ${data.data.openrouter_model}`);
} else {
this.log(`๐ค Model: ${data.data.selected_model}`);
}
// Enhanced API status with OpenRouter
const apiStatus = data.data.api_status;
const configuredApis = Object.keys(apiStatus).filter(key => apiStatus[key]);
if (configuredApis.length > 0) {
this.log(`๐ Configured APIs: ${configuredApis.map(api => {
// Capitalize and format API names
if (api === 'openai') return 'OpenAI';
if (api === 'xai') return 'X.AI';
if (api === 'openrouter') return 'OpenRouter';
return api.charAt(0).toUpperCase() + api.slice(1);
}).join(', ')}`);
} else {
this.log(`โ ๏ธ No API keys configured`);
}
// Specific warning for OpenRouter if selected but no key
if (data.data.is_openrouter && !apiStatus.openrouter) {
this.log(`โ WARNING: OpenRouter selected but no API key configured!`);
}
} else {
promptEl.textContent = 'Error loading system prompt';
}
})
.catch(error => {
console.error('Error fetching system info:', error);
promptEl.textContent = 'Connection error';
});
}
updateKnowledgeBaseStatus() {
const statusEl = this.panel.querySelector('#kb-status');
statusEl.innerHTML = 'Checking...';
fetch(mxchatTestData.ajaxUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
action: 'mxchat_get_kb_status',
nonce: mxchatTestData.nonce
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
const kbData = data.data;
statusEl.innerHTML = `โ ${kbData.status} (${kbData.type} - ${kbData.documents})`;
} else {
statusEl.innerHTML = 'Error loading KB status';
}
})
.catch(error => {
console.error('Error fetching KB status:', error);
statusEl.innerHTML = 'Connection error';
});
}
clearDebugConsole() {
const console = this.panel.querySelector('#debug-console');
console.innerHTML = '
Debug console cleared...
';
}
log(message) {
const console = this.panel.querySelector('#debug-console');
const timestamp = new Date().toLocaleTimeString();
const logEntry = document.createElement('div');
logEntry.className = 'debug-entry';
logEntry.innerHTML = `[${timestamp}] ${message}`;
console.appendChild(logEntry);
console.scrollTop = console.scrollHeight;
// Keep only last 50 entries to prevent memory issues
const entries = console.querySelectorAll('.debug-entry');
if (entries.length > 50) {
entries[0].remove();
}
}
}
// Initialize the test panel when the script loads
document.addEventListener('DOMContentLoaded', function() {
// Only initialize if user is admin and testing is enabled
if (window.mxchatTestingEnabled) {
window.mxchatTestPanel = new MxChatTestPanel();
}
});
// Global function to enable testing mode programmatically
window.enableMxChatTesting = function() {
if (!window.mxchatTestPanel) {
window.mxchatTestPanel = new MxChatTestPanel();
}
};