diff --git a/public/script.js b/public/script.js index 369aa2758..72813e30b 100644 --- a/public/script.js +++ b/public/script.js @@ -40,6 +40,7 @@ import { regenerateGroup, group_generation_id, getGroupChat, + renameGroupMember, } from "./scripts/group-chats.js"; import { @@ -101,7 +102,6 @@ import { tags, loadTagsSettings, printTags, - isElementTagged, getTagsList, appendTagToList, createTagMapFromList, @@ -196,7 +196,7 @@ let safetychat = [ is_user: false, is_name: true, create_date: 0, - mes: "\nYou deleted a character/chat and arrived back here for safety reasons! Pick another character!\n\n", + mes: "You deleted a character/chat and arrived back here for safety reasons! Pick another character!", }, ]; let chat_create_date = 0; @@ -493,7 +493,7 @@ var colab_ini_step = 1; let token; -function getRequestHeaders() { +export function getRequestHeaders() { return { "Content-Type": "application/json", "X-CSRF-Token": token, @@ -2538,6 +2538,8 @@ async function renameCharacter() { throw new Error('New character not selected'); } + // Also rename as a group member + await renameGroupMember(oldAvatar, newAvatar, newValue); callPopup('

Character renamed!

Sprites folder (if any) should be renamed manually.', 'text'); } else { diff --git a/public/scripts/bookmarks.js b/public/scripts/bookmarks.js index c90aa1fc6..102dbc8e4 100644 --- a/public/scripts/bookmarks.js +++ b/public/scripts/bookmarks.js @@ -2,13 +2,13 @@ import { characters, saveChat, sendSystemMessage, - token, system_messages, system_message_types, this_chid, openCharacterChat, chat_metadata, callPopup, + getRequestHeaders, } from "../script.js"; import { selected_group } from "./group-chats.js"; @@ -25,10 +25,7 @@ const bookmarkNameToken = 'Bookmark #'; async function getExistingChatNames() { const response = await fetch("/getallchatsofcharacter", { method: 'POST', - headers: { - 'Content-Type': 'application/json', - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ avatar_url: characters[this_chid].avatar }) }); diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index d0205664d..a049c9319 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -1,4 +1,4 @@ -import { callPopup, saveSettings, saveSettingsDebounced, token } from "../script.js"; +import { callPopup, saveSettings, saveSettingsDebounced } from "../script.js"; import { isSubsetOf } from "./utils.js"; export { getContext, @@ -37,7 +37,7 @@ let connectedToApi = false; async function discoverExtensions() { try { - const response = await fetch('/discover_extensions', { headers: { 'X-CSRF-Token': token } }); + const response = await fetch('/discover_extensions'); if (response.ok) { const extensions = await response.json(); diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index 6c01e0624..9c21fffe3 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -1,4 +1,4 @@ -import { saveSettingsDebounced, token } from "../../../script.js"; +import { saveSettingsDebounced } from "../../../script.js"; import { getContext, getApiUrl, modules, extension_settings } from "../../extensions.js"; export { MODULE_NAME }; @@ -250,11 +250,7 @@ async function getSpritesList(name) { console.log('getting sprites list'); try { - const result = await fetch(`/get_sprites?name=${encodeURIComponent(name)}`, { - headers: { - 'X-CSRF-Token': token, - } - }); + const result = await fetch(`/get_sprites?name=${encodeURIComponent(name)}`); let sprites = result.ok ? (await result.json()) : []; return sprites; diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index 3fe1b1ba0..f3e6fea7d 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -14,7 +14,6 @@ import { substituteParams, characters, default_avatar, - token, addOneMessage, callPopup, clearChat, @@ -42,6 +41,7 @@ import { isStreamingEnabled, getThumbnailUrl, streamingProcessor, + getRequestHeaders, } from "../script.js"; import { appendTagToList, createTagMapFromList, getTagsList } from './tags.js'; @@ -82,10 +82,7 @@ const saveGroupDebounced = debounce(async (group) => await _save(group), 500); async function _save(group) { await fetch("/editgroup", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify(group), }); await getCharacters(); @@ -120,10 +117,7 @@ export async function getGroupChat(groupId) { const chat_id = group.chat_id; const response = await fetch("/getgroupchat", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ id: chat_id }), }); @@ -139,7 +133,7 @@ export async function getGroupChat(groupId) { sendSystemMessage(system_message_types.GROUP); if (group && Array.isArray(group.members)) { for (let member of group.members) { - const character = characters.find(x => x.avatar === member || x.name === member); + const character = characters.find(x => x.avatar === member || x.name === member); if (!character) { continue; @@ -188,10 +182,7 @@ async function saveGroupChat(groupId, shouldSaveGroup) { const chat_id = group.chat_id; const response = await fetch("/savegroupchat", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ id: chat_id, chat: [...chat] }), }); @@ -200,13 +191,81 @@ async function saveGroupChat(groupId, shouldSaveGroup) { } } +export async function renameGroupMember(oldAvatar, newAvatar, newName) { + // Scan every group for our renamed character + for (const group of groups) { + try { + + // Try finding the member by old avatar link + const memberIndex = group.members.findIndex(x => x == oldAvatar); + + // Character was not present in the group... + if (memberIndex == -1) { + continue; + } + + // Replace group member avatar id and save the changes + group.members[memberIndex] = newAvatar; + await editGroup(group.id, true); + console.log(`Renamed character ${newName} in group: ${group.name}`) + + // Load all chats from this group + for (const chatId of group.chats) { + const getChatResponse = await fetch("/getgroupchat", { + method: "POST", + headers: getRequestHeaders(), + body: JSON.stringify({ id: chatId }), + }); + + if (getChatResponse.ok) { + // Only save the chat if there were any changes to the chat content + let hadChanges = false; + const messages = await getChatResponse.json(); + // Chat shouldn't be empty + if (Array.isArray(messages) && messages.length) { + // Iterate over every chat message + for (const message of messages) { + // Only look at character messages + if (message.is_user || message.is_system) { + continue; + } + + // Message belonged to the old-named character: + // Update name, avatar thumbnail URL and original avatar link + if (message.force_avatar && message.force_avatar.indexOf(encodeURIComponent(oldAvatar)) !== -1) { + message.name = newName; + message.force_avatar = message.force_avatar.replace(encodeURIComponent(oldAvatar), encodeURIComponent(newAvatar)); + message.original_avatar = newAvatar; + hadChanges = true; + } + } + } + + if (hadChanges) { + const saveChatResponse = await fetch("/savegroupchat", { + method: "POST", + headers: getRequestHeaders(), + body: JSON.stringify({ id: chatId, chat: [...messages] }), + }); + + if (saveChatResponse.ok) { + console.log(`Renamed character ${newName} in group chat: ${chatId}`); + } + } + } + } + } + catch (error) { + console.log(`An error during renaming the character ${newName} in group: ${group.name}`); + console.error(error); + } + } +} + async function getGroups() { const response = await fetch("/getgroups", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders() }); if (response.ok) { @@ -219,9 +278,9 @@ async function getGroups() { group.chat_id = group.id; group.chats = [group.id]; group.members = group.members - .map(x => characters.find(y => y.name == x)?.avatar) - .filter(x => x) - .filter(onlyUnique) + .map(x => characters.find(y => y.name == x)?.avatar) + .filter(x => x) + .filter(onlyUnique) } } } @@ -491,7 +550,7 @@ function activateSwipe(members) { let activatedNames = []; // pre-update group chat swipe - if (!chat[chat.length -1].original_avatar) { + if (!chat[chat.length - 1].original_avatar) { const matches = characters.filter(x => x.name == chat[chat.length - 1].name); for (const match of matches) { @@ -502,7 +561,7 @@ function activateSwipe(members) { } } else { - activatedNames.push(chat[chat.length -1].original_avatar); + activatedNames.push(chat[chat.length - 1].original_avatar); } const memberIds = activatedNames @@ -609,10 +668,7 @@ function extractAllWords(value) { async function deleteGroup(id) { const response = await fetch("/deletegroup", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ id: id }), }); @@ -930,7 +986,7 @@ $(document).ready(() => { .toArray(); const memberNames = characters.filter(x => members.includes(x.avatar)).map(x => x.name).join(", "); - + if (!name) { name = `Chat with ${memberNames}`; } @@ -943,10 +999,7 @@ $(document).ready(() => { const createGroupResponse = await fetch("/creategroup", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ name: name, members: members, diff --git a/public/scripts/openai.js b/public/scripts/openai.js index 8f7249341..efb9742a7 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -10,13 +10,13 @@ import { checkOnlineStatus, setOnlineStatus, getExtensionPrompt, - token, name1, name2, extension_prompt_types, characters, this_chid, callPopup, + getRequestHeaders, } from "../script.js"; import { groups, selected_group } from "./group-chats.js"; @@ -509,10 +509,7 @@ async function sendOpenAIRequest(openai_msgs_tosend, signal) { const response = await fetch(generate_url, { method: 'POST', body: JSON.stringify(generate_data), - headers: { - 'Content-Type': 'application/json', - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), signal: signal, }); @@ -567,10 +564,7 @@ async function calculateLogitBias() { try { const reply = await fetch(`/openai_bias?model=${oai_settings.openai_model}`, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': token, - }, + headers: getRequestHeaders(), body, }); @@ -802,10 +796,7 @@ async function saveOpenAIPreset(name, settings) { const savePresetSettings = await fetch(`/savepreset_openai?name=${name}`, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': token, - }, + headers: getRequestHeaders(), body: JSON.stringify(presetBody), }); @@ -837,7 +828,7 @@ async function showApiKeyUsage() { try { const response = await fetch('/openai_usage', { method: 'POST', - headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': token }, + headers: getRequestHeaders(), body: body, }); diff --git a/public/scripts/poe.js b/public/scripts/poe.js index ce35a54e6..e676e06b2 100644 --- a/public/scripts/poe.js +++ b/public/scripts/poe.js @@ -1,11 +1,11 @@ import { - token as csrf_token, saveSettingsDebounced, setOnlineStatus, checkOnlineStatus, substituteParams, max_context, getTokenCount, + getRequestHeaders, } from "../script.js"; export { @@ -149,10 +149,7 @@ async function purgeConversation(count = -1) { }); const response = await fetch('/purge_poe', { - headers: { - 'X-CSRF-Token': csrf_token, - 'Content-Type': 'application/json', - }, + headers: getRequestHeaders(), body: body, method: 'POST', }); @@ -173,10 +170,7 @@ async function sendMessage(prompt, withStreaming, signal) { }); const response = await fetch('/generate_poe', { - headers: { - 'X-CSRF-Token': csrf_token, - 'Content-Type': 'application/json', - }, + headers: getRequestHeaders(), body: body, method: 'POST', signal: signal, @@ -241,10 +235,7 @@ function setButtonState(value) { async function checkStatusPoe() { const body = JSON.stringify({ token: poe_settings.token }); const response = await fetch('/status_poe', { - headers: { - 'X-CSRF-Token': csrf_token, - 'Content-Type': 'application/json', - }, + headers: getRequestHeaders(), body: body, method: 'POST', }); diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js index f7a33f42b..5402a058b 100644 --- a/public/scripts/power-user.js +++ b/public/scripts/power-user.js @@ -3,10 +3,10 @@ import { scrollChatToBottom, characters, callPopup, - token, getStatus, reloadMarkdownProcessor, reloadCurrentChat, + getRequestHeaders, } from "../script.js"; export { @@ -449,10 +449,8 @@ async function saveTheme() { }; const response = await fetch('/savetheme', { - method: 'POST', headers: { - 'X-CSRF-Token': token, - 'Content-Type': 'application/json', - }, + method: 'POST', + headers: getRequestHeaders(), body: JSON.stringify(theme) }); diff --git a/public/scripts/textgen-settings.js b/public/scripts/textgen-settings.js index 6ab0107fd..474bf97da 100644 --- a/public/scripts/textgen-settings.js +++ b/public/scripts/textgen-settings.js @@ -1,6 +1,6 @@ import { + getRequestHeaders, saveSettingsDebounced, - token, } from "../script.js"; export { @@ -160,8 +160,7 @@ function setSettingByName(i, value, trigger) { async function generateTextGenWithStreaming(generate_data, signal) { const response = await fetch('/generate_textgenerationwebui', { headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': token, + ...getRequestHeaders(), 'X-Response-Streaming': true, 'X-Streaming-URL': textgenerationwebui_settings.streaming_url, }, diff --git a/public/scripts/world-info.js b/public/scripts/world-info.js index ccfaf9169..34b49cbe8 100644 --- a/public/scripts/world-info.js +++ b/public/scripts/world-info.js @@ -1,4 +1,4 @@ -import { saveSettings, callPopup, token, substituteParams, getTokenCount } from "../script.js"; +import { saveSettings, callPopup, substituteParams, getTokenCount, getRequestHeaders } from "../script.js"; import { download, debounce } from "./utils.js"; export { @@ -92,10 +92,7 @@ async function loadWorldInfoData() { const response = await fetch("/getworldinfo", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ name: world_info }), }); @@ -107,10 +104,7 @@ async function loadWorldInfoData() { async function updateWorldInfoList(importedWorldName) { var result = await fetch("/getsettings", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({}), }); @@ -343,10 +337,7 @@ function createWorldInfoEntry() { async function _save() { const response = await fetch("/editworldinfo", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ name: world_info, data: world_info_data }), }); } @@ -384,10 +375,7 @@ async function deleteWorldInfo(worldInfoName, selectWorldName) { const response = await fetch("/deleteworldinfo", { method: "POST", - headers: { - "Content-Type": "application/json", - "X-CSRF-Token": token, - }, + headers: getRequestHeaders(), body: JSON.stringify({ name: worldInfoName }), });