var conversation_id = false; var conversations = []; var assistant_key = false; var assistants = []; var tov_key = false; const tone_of_voices = [ { key: "standard", name: "Barclays" }, { key: "pep", name: "Barclaycard" } ]; var sending_message = false; var md_converter = new showdown.Converter(); function maskUKBankDetails(text) { // Enhanced regular expression for UK Sort Code to match various formats: XX-XX-XX, XX XX XX, XXXXXX, or XX*XX*XX const sortCodeRegex = /\b(\d{2}[-\s*]\d{2}[-\s*]\d{2}|\d{6})\b/g; // specific expression for XX XX XX const sortCodeSpacesRegex = /\b\d{2}\s\d{2}\s\d{2}\b/g; // Regular expression for UK Bank Account Number: 8 digits const accountNumberRegex = /\b\d{8}\b/g; // Regular expression for UK Bank Account Number: 7 digits const accountNumberSevenRegex = /\b\d{7}\b/g; // Regular expression for email addresses const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g; // Regular expression for 16-digit card numbers, split or unsplit by any non-digit character const cardNumberRegex = /\b(?:\d{4}[-\s*]){3}\d{4}\b|\b\d{16}\b/g; // Regular expression for specific cybersecurity-related terms const cybersecurityTermsRegex = /\b\w*?(malware|malicious|hack|injection|attack|password|phishing|exploit)\w*?\b/gi; const tabRegex = /\t/g; const accountNumSeparateRegex = /\b\d{4}[-\s]\d{4}\b/g; // Replace matched patterns with '######' or appropriate replacement return text .replace(sortCodeRegex, '######') .replace(accountNumberRegex, '######') .replace(cardNumberRegex, '############') .replace(sortCodeSpacesRegex, '############') .replace(accountNumberSevenRegex, '############') .replace(emailRegex, '############') .replace(tabRegex, '-') .replace(cybersecurityTermsRegex, '#######') .replace(accountNumSeparateRegex, '#########'); } // Function to remove citation markers from text function removeCitations(text) { // Improved regex to handle all variations of citation markers including any preceding/trailing whitespace return text ? text.replace(/\s*【\d+:\d+†[^】]+】\s*/g, '') : text; } const toggleSidebar = (e) => { e.stopPropagation(); if (Array.from(document.getElementById("body").classList).includes("sidebar-hidden")) { document.getElementById("body").classList.remove("sidebar-hidden"); } else { document.getElementById("body").classList.add("sidebar-hidden"); } }; const getConversations = () => { // Function to fetch conversations with retry capability const fetchConversations = (retryCount = 0) => { return gcp_fetch(make_url + "?GetConversations=True") .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then((res) => { if (!res?.conversations) return false; conversations = res.conversations; document.getElementById("conversations-list").innerHTML = res?.conversations ?.map((conversation) => { return conversations_list_item ?.replaceAll("{CONVERSATION_ID}", conversation?.id) ?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title)); }) ?.join(""); }) .catch((error) => { console.error(`Error fetching conversations (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying conversations fetch..."); return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => fetchConversations(retryCount + 1)); } // If we've already retried, show the error document.getElementById("conversations-list").innerHTML = `
`; }); }; // Start the API call with retry functionality fetchConversations(); }; const processConversationTitle = (input_title) => { let new_title = JSON.parse(JSON.stringify(input_title)); new_title = new_title.trim(); if (new_title.startsWith("'") || new_title.startsWith('"')) { new_title = new_title.substring(1); } if (new_title.endsWith("'") || new_title.endsWith('"')) { new_title = new_title.substring(0, new_title.length - 1); } return new_title; }; const getAssistants = () => { // Function to fetch assistants with retry capability const fetchAssistants = (retryCount = 0) => { return gcp_fetch(make_url + "?GetAssistants=True") .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then((res) => { if (!res?.assistants) return false; assistants = res.assistants; document.getElementById("assistants-list").innerHTML = res?.assistants ?.map((assistant) => { return assistant_list_item?.replaceAll("{ASSISTANT_KEY}", assistant?.key)?.replaceAll("{ASSISTANT_NAME}", assistant?.name); }) ?.join(""); }) .catch((error) => { console.error(`Error fetching assistants (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying assistants fetch..."); return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => fetchAssistants(retryCount + 1)); } // If we've already retried, show the error document.getElementById("assistants-list").innerHTML = ``; }); }; // Start the API call with retry functionality fetchAssistants(); }; const getTOVs = () => { document.getElementById("tov-list").innerHTML = tone_of_voices ?.map((tov) => { return tov_list_item?.replaceAll("{TOV_ID}", tov?.key)?.replaceAll("{TOV_NAME}", tov?.name); }) ?.join(""); setDefaultToneOfVoice(); }; const setDefaultToneOfVoice = () => { tov_key = tone_of_voices[0]?.key; document.getElementById("tov-name").innerHTML = tone_of_voices[0]?.name; document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-list").classList.add("tov-list-hidden"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); }; const goToConversation = (e, new_conversation_id) => { e.stopPropagation(); //console.log("after e.stopPropagation"); conversation_id = new_conversation_id; const conversation = conversations?.find((e) => e.id === new_conversation_id); const assistant = assistants?.find((e) => e.key === conversation?.assistant_key); //console.log("assistants: ", assistant, "conversation: ", conversation); if (!assistant) return false; Array.from(document.getElementsByClassName("conversations-list-btn-active"))?.map((el) => el.classList.remove("conversations-list-btn-active")); document.getElementById("conversations-list-item-" + new_conversation_id)?.classList.add("conversations-list-btn-active"); document.getElementById("chat").innerHTML = loading_circle; // Ensure the send button is enabled const sendButton = document.getElementById("send-button"); if (sendButton) { sendButton.disabled = false; } assistant_key = conversation?.assistant_key; document.getElementById("assistant-name").innerHTML = assistants.find((e) => e.key === conversation?.assistant_key)?.name; document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); document.getElementById("assistant-name").classList.remove("assistant-name-placeholder"); document.getElementById("tov-name").innerHTML = tone_of_voices.find((e) => e.key === conversation?.tov_key)?.name; document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-list").classList.add("tov-list-hidden"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); //console.log("before gcp_fetch"); // Function to make the API call (so we can retry it) const loadConversation = (retryCount = 0) => { return gcp_fetch(make_url + `?GetMessages=True&ConversationID=${encodeURI(conversation_id)}`) .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then((res) => { if (res?.conversation_id === conversation_id) { document.getElementById("chat").innerHTML = chat_message_assistant.replaceAll("{CONTENT}", assistant?.initial_message); document.getElementById("chat").innerHTML += res?.messages ?.map((message) => { if (message?.role === "assistant") return chat_message_assistant.replaceAll("{CONTENT}", md_converter?.makeHtml(removeCitations(message?.content))); if (message?.role === "user") return chat_message_user.replaceAll("{CONTENT}", md_converter?.makeHtml(message?.content)); return ""; }) ?.join(""); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; } }) .catch((error) => { console.error(`Error loading conversation (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying conversation load..."); // Keep loading indicator document.getElementById("chat").innerHTML = loading_circle; // Wait a moment before retrying return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => loadConversation(retryCount + 1)); } // If we've already retried or max retries reached, show the error // Re-enable the send button if it was disabled const sendButton = document.getElementById("send-button"); if (sendButton) { sendButton.disabled = false; } // Show error message in chat document.getElementById("chat").innerHTML = chat_message_assistant.replaceAll( "{CONTENT}", `` ); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }); }; // Start the API call with retry functionality loadConversation(); }; const goToCreateNewConversationsPage = () => { conversation_id = false; assistant_key = false; sending_message = false; document.getElementById("page-content").innerHTML = chat_new_conversation_html; Array.from(document.getElementsByClassName("conversations-list-btn-active"))?.map((el) => el.classList.remove("conversations-list-btn-active")); document.getElementById("message-input").addEventListener("input", () => { document.getElementById("message-input").style.height = "auto"; document.getElementById("message-input").style.height = document.getElementById("message-input").scrollHeight + 6 + "px"; }); document.getElementById("message-input").addEventListener("keydown", (e) => { if (e.code === "Enter" && !e?.shiftKey) { e.preventDefault(); sendMessage(); } }); document.getElementById("assistants-list").innerHTML = assistants ?.map((assistant) => { return assistant_list_item?.replaceAll("{ASSISTANT_KEY}", assistant?.key)?.replaceAll("{ASSISTANT_NAME}", assistant?.name); }) ?.join(""); document.getElementById("tov-list").innerHTML = tone_of_voices ?.map((tov) => { return tov_list_item?.replaceAll("{TOV_ID}", tov?.key)?.replaceAll("{TOV_NAME}", tov?.name); }) ?.join(""); setDefaultToneOfVoice(); // Ensure the send button is enabled by default const sendButton = document.getElementById("send-button"); if (sendButton) { sendButton.disabled = false; } }; const startDeletingConversation = (e, conversation_id) => { e.stopPropagation(); document.getElementById("conversations-list-item-manage-container-" + conversation_id).innerHTML = conversations_list_item_manage_delete_options_html?.replaceAll("{CONVERSATION_ID}", conversation_id); }; const stopDeletingConversation = (e, conversation_id) => { e.stopPropagation(); document.getElementById("conversations-list-item-manage-container-" + conversation_id).innerHTML = conversations_list_item_manage_options_html?.replaceAll("{CONVERSATION_ID}", conversation_id); }; const deleteConversation = (e, conversation_id) => { e.stopPropagation(); const conversation = conversations?.find((e) => e?.id === conversation_id); if (!conversation) return false; goToCreateNewConversationsPage(); // Function to delete conversation with retry capability const performDelete = (retryCount = 0) => { return gcp_fetch(make_url + `?DeleteConversation=True&ConversationID=${encodeURI(conversation_id)}`) .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then(() => { const conversation_index = conversations?.findIndex((e) => e?.id === conversation_id); if (conversation_index === -1) return false; conversations.splice(conversation_index, 1); document.getElementById(`conversations-list-item-${conversation_id}`)?.remove(); }) .catch((error) => { console.error(`Error deleting conversation (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying conversation delete..."); return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => performDelete(retryCount + 1)); } // If we've already retried, show the error console.error("Error deleting conversation after retry:", error); // Show error message in chat document.getElementById("chat").innerHTML = chat_message_assistant.replaceAll( "{CONTENT}", `` ); // Refresh conversations list getConversations(); }); }; // Start the API call with retry functionality performDelete(); }; const sendMessage = () => { if (!assistant_key) { alert("Please Select an Assistant"); return false; } if (!tov_key) { alert("Please Select a Tone of Voice"); return false; } // Create copies of keys needed throughout the function, before any early returns const new_assistant_key = JSON.parse(JSON.stringify(assistant_key)); const new_tov_key = JSON.parse(JSON.stringify(tov_key)); // Check if the message is empty or only contains whitespace const rawMessage = document.getElementById("message-input")?.value; if (!rawMessage || rawMessage.trim() === "") { // Add a warning message to the chat document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll( "{CONTENT}", "You've tried to submit a blank message. Please enter a message and try again." ); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; return false; } // Return early if already sending a message if (sending_message) return false; sending_message = true; // Disable the send button while waiting for response document.getElementById("send-button").disabled = true; //const message = document.getElementById("message-input")?.value; const message = maskUKBankDetails(rawMessage); document.getElementById("message-input").value = ""; document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistant-name").classList.remove("assistant-name-placeholder"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); document.getElementById("tov-list").classList.add("tov-list-hidden"); Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); document.getElementById("chat").innerHTML += chat_message_user_new.replaceAll("{CONTENT}", md_converter?.makeHtml(message)); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; setTimeout(() => { Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); document.getElementById("chat").innerHTML += chat_message_assistant_loading_dots; setTimeout(() => { // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }, 5); }, 2000); //console.log("URI encoded message: " + encodeURI(message)); const utf8Bytes = new TextEncoder().encode(message); let binary = ''; for (let i = 0; i < utf8Bytes.length; i++) { binary += String.fromCharCode(utf8Bytes[i]); } const encodedMessage = btoa(binary); // Function to make the API call (so we can retry it) const makeAPICall = (retryCount = 0) => { return gcp_fetch( make_url + `?ConversationID=${encodeURI(conversation_id)}&AssistantKey=${encodeURI(new_assistant_key)}&TOV_Key=${encodeURI( new_tov_key )}&Message=${encodeURIComponent(encodedMessage)}` ) .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then((res) => { if (sending_message && res?.conversation_id) { conversation_id = res?.conversation_id; if (conversations.findIndex((e) => e.id === res?.conversation_id) === -1 && res?.conversation_title) { conversations = [ { id: res?.conversation_id, title: res?.conversation_title, assistant_key: new_assistant_key, tov_key: new_tov_key }, ].concat(conversations); document.getElementById("conversations-list").innerHTML = conversations ?.map((conversation) => { if (conversation?.id === res?.conversation_id) return conversations_list_item_active ?.replaceAll("{CONVERSATION_ID}", conversation?.id) ?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title)); return conversations_list_item ?.replaceAll("{CONVERSATION_ID}", conversation?.id) ?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title)); }) ?.join(""); } } // Re-enable the send button document.getElementById("send-button").disabled = false; sending_message = false; Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove()); // Check if we have a message, otherwise show error if (res?.message) { document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", md_converter?.makeHtml(removeCitations(res.message))); } else { document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", "Sorry, there was an issue processing your request. The response was incomplete."); } // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }) .catch((error) => { console.error(`Error in API call (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying request..."); // Keep loading indicator // Don't remove the loading dots yet // Wait a moment before retrying (e.g., 1 second) return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => makeAPICall(retryCount + 1)); } // If we've already retried or max retries reached, show the error // Re-enable the send button document.getElementById("send-button").disabled = false; sending_message = false; Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove()); // Show error message in chat document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll( "{CONTENT}", `` ); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }); }; // Start the API call with retry functionality makeAPICall(); }; const toggleAssistantsDropdown = () => { if (conversation_id !== false || sending_message) return false; if (Array.from(document.getElementById("assistants-list").classList).includes("assistants-list-hidden")) { document.getElementById("assistant-name-container").classList.add("assistant-name-container-active"); document.getElementById("assistants-list").classList.remove("assistants-list-hidden"); } else { document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); } }; const selectAssistant = (new_assistant_key) => { if (conversation_id !== false || sending_message) return false; const assistant = assistants?.find((e) => e.key === new_assistant_key); if (!assistant) return false; assistant_key = new_assistant_key; document.getElementById("assistant-name").innerHTML = assistants.find((e) => e.key === new_assistant_key)?.name; document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistant-name").classList.remove("assistant-name-placeholder"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); document.getElementById("chat").innerHTML = ``; setTimeout(() => { if (JSON.stringify(assistant_key) === JSON.stringify(new_assistant_key)) { document.getElementById("chat").innerHTML = chat_message_assistant_new.replaceAll("{CONTENT}", assistant?.initial_message); } }, 500); }; const toggleTOVsDropdown = () => { if (conversation_id !== false || sending_message) return false; if (Array.from(document.getElementById("tov-list").classList).includes("tov-list-hidden")) { document.getElementById("tov-name-container").classList.add("tov-name-container-active"); document.getElementById("tov-list").classList.remove("tov-list-hidden"); } else { document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-list").classList.add("tov-list-hidden"); } }; const selectTOV = (new_tov_key) => { if (conversation_id !== false || sending_message) return false; const tov = tone_of_voices?.find((e) => e.key === new_tov_key); if (!tov) return false; tov_key = new_tov_key; document.getElementById("tov-name").innerHTML = tone_of_voices.find((e) => e.key === new_tov_key)?.name; document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); document.getElementById("tov-list").classList.add("tov-list-hidden"); }; const onAuthenticated = () => { goToCreateNewConversationsPage(); getConversations(); getAssistants(); getTOVs(); // Ensure the send button is enabled by default document.getElementById("message-input").value = ""; document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistant-name").classList.remove("assistant-name-placeholder"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); document.getElementById("tov-list").classList.add("tov-list-hidden"); Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); document.getElementById("chat").innerHTML += chat_message_user_new.replaceAll("{CONTENT}", md_converter?.makeHtml(message)); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; setTimeout(() => { Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); document.getElementById("chat").innerHTML += chat_message_assistant_loading_dots; setTimeout(() => { // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }, 5); }, 2000); //console.log("URI encoded message: " + encodeURI(message)); const utf8Bytes = new TextEncoder().encode(message); let binary = ''; for (let i = 0; i < utf8Bytes.length; i++) { binary += String.fromCharCode(utf8Bytes[i]); } const encodedMessage = btoa(binary); // Function to make the API call (so we can retry it) const makeAPICall = (retryCount = 0) => { return gcp_fetch( make_url + `?ConversationID=${encodeURI(conversation_id)}&AssistantKey=${encodeURI(new_assistant_key)}&TOV_Key=${encodeURI( new_tov_key )}&Message=${encodeURIComponent(encodedMessage)}` ) .then((res) => { if (!res.ok) { throw new Error(`Server responded with status: ${res.status} ${res.statusText}`); } return res.json(); }) .then((res) => { if (sending_message && res?.conversation_id) { conversation_id = res?.conversation_id; if (conversations.findIndex((e) => e.id === res?.conversation_id) === -1 && res?.conversation_title) { conversations = [ { id: res?.conversation_id, title: res?.conversation_title, assistant_key: new_assistant_key, tov_key: new_tov_key }, ].concat(conversations); document.getElementById("conversations-list").innerHTML = conversations ?.map((conversation) => { if (conversation?.id === res?.conversation_id) return conversations_list_item_active ?.replaceAll("{CONVERSATION_ID}", conversation?.id) ?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title)); return conversations_list_item ?.replaceAll("{CONVERSATION_ID}", conversation?.id) ?.replaceAll("{CONVERSATION_TITLE}", processConversationTitle(conversation?.title)); }) ?.join(""); } } // Re-enable the send button document.getElementById("send-button").disabled = false; sending_message = false; Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove()); // Check if we have a message, otherwise show error if (res?.message) { document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", md_converter?.makeHtml(removeCitations(res.message))); } else { document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll("{CONTENT}", "Sorry, there was an issue processing your request. The response was incomplete."); } // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }) .catch((error) => { console.error(`Error in API call (attempt ${retryCount + 1}):`, error); // If this is the first failure, retry once if (retryCount === 0) { console.log("Retrying request..."); // Keep loading indicator // Don't remove the loading dots yet // Wait a moment before retrying (e.g., 1 second) return new Promise(resolve => setTimeout(resolve, 1000)) .then(() => makeAPICall(retryCount + 1)); } // If we've already retried or max retries reached, show the error // Re-enable the send button document.getElementById("send-button").disabled = false; sending_message = false; Array.from(document.getElementsByClassName("chat-message-appear"))?.map((el) => el.classList.remove("chat-message-appear")); Array.from(document.getElementsByClassName("chat-message-loading-dots"))?.map((el) => el.remove()); // Show error message in chat document.getElementById("chat").innerHTML += chat_message_assistant_new.replaceAll( "{CONTENT}", `` ); // Scroll to Last Message document.getElementById("chat").scrollTop = document.getElementById("chat").scrollHeight; }); }; // Start the API call with retry functionality makeAPICall(); }; const toggleAssistantsDropdown = () => { if (conversation_id !== false || sending_message) return false; if (Array.from(document.getElementById("assistants-list").classList).includes("assistants-list-hidden")) { document.getElementById("assistant-name-container").classList.add("assistant-name-container-active"); document.getElementById("assistants-list").classList.remove("assistants-list-hidden"); } else { document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); } }; const selectAssistant = (new_assistant_key) => { if (conversation_id !== false || sending_message) return false; const assistant = assistants?.find((e) => e.key === new_assistant_key); if (!assistant) return false; assistant_key = new_assistant_key; document.getElementById("assistant-name").innerHTML = assistants.find((e) => e.key === new_assistant_key)?.name; document.getElementById("assistant-name-container").classList.remove("assistant-name-container-active"); document.getElementById("assistant-name").classList.remove("assistant-name-placeholder"); document.getElementById("assistants-list").classList.add("assistants-list-hidden"); document.getElementById("chat").innerHTML = ``; setTimeout(() => { if (JSON.stringify(assistant_key) === JSON.stringify(new_assistant_key)) { document.getElementById("chat").innerHTML = chat_message_assistant_new.replaceAll("{CONTENT}", assistant?.initial_message); } }, 500); }; const toggleTOVsDropdown = () => { if (conversation_id !== false || sending_message) return false; if (Array.from(document.getElementById("tov-list").classList).includes("tov-list-hidden")) { document.getElementById("tov-name-container").classList.add("tov-name-container-active"); document.getElementById("tov-list").classList.remove("tov-list-hidden"); } else { document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-list").classList.add("tov-list-hidden"); } }; const selectTOV = (new_tov_key) => { if (conversation_id !== false || sending_message) return false; const tov = tone_of_voices?.find((e) => e.key === new_tov_key); if (!tov) return false; tov_key = new_tov_key; document.getElementById("tov-name").innerHTML = tone_of_voices.find((e) => e.key === new_tov_key)?.name; document.getElementById("tov-name-container").classList.remove("tov-name-container-active"); document.getElementById("tov-name").classList.remove("tov-name-placeholder"); document.getElementById("tov-list").classList.add("tov-list-hidden"); }; const onAuthenticated = () => { goToCreateNewConversationsPage(); getConversations(); getAssistants(); getTOVs(); // Ensure the send button is enabled by default setTimeout(() => { const sendButton = document.getElementById("send-button"); if (sendButton) { sendButton.disabled = false; } }, 500); // Small delay to ensure DOM is ready }; // Help Modal Functionality document.addEventListener('DOMContentLoaded', () => { const modal = document.getElementById("help-modal"); const btn = document.getElementById("help-btn"); const span = document.getElementsByClassName("close-btn")[0]; if (btn) { btn.onclick = function() { modal.style.display = "flex"; } } if (span) { span.onclick = function() { modal.style.display = "none"; } } window.onclick = function(event) { if (event.target == modal) { modal.style.display = "none"; } } });