843 lines
No EOL
33 KiB
JavaScript
Executable file
843 lines
No EOL
33 KiB
JavaScript
Executable file
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 =
|
|
`<div class="error-message">Error loading conversations: ${error.message}</div>`;
|
|
});
|
|
};
|
|
|
|
// 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 =
|
|
`<div class="error-message">Error loading assistants: ${error.message}</div>`;
|
|
});
|
|
};
|
|
|
|
// 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}",
|
|
`<div class="error-message">Sorry, there was an error loading this conversation: ${error.message}</div>`
|
|
);
|
|
|
|
// 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}",
|
|
`<div class="error-message">Error deleting conversation: ${error.message}</div>`
|
|
);
|
|
|
|
// 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}",
|
|
`<div class="error-message">Sorry, an error occurred: ${error.message}</div>`
|
|
);
|
|
|
|
// 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}",
|
|
`<div class="error-message">Sorry, an error occurred: ${error.message}</div>`
|
|
);
|
|
|
|
// 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";
|
|
}
|
|
}
|
|
}); |