import { humanizedDateTime } from "./scripts/RossAscends-mods.js";
import { encode, decode } from "../scripts/gpt-2-3-tokenizer/mod.js";
//RossAscends: exporting functions and vars for RA mods.
export {
Generate,
getSettings,
saveSettings,
printMessages,
clearChat,
getChat,
this_chid,
settings,
characters,
online_status,
main_api,
api_server,
api_key_novel,
getCharacters,
is_send_press,
world_info,
};
// API OBJECT FOR EXTERNAL WIRING
window["TavernAI"] = {};
const VERSION = "1.2.8";
var converter = new showdown.Converter({ emoji: "true" });
var bg_menu_toggle = false;
const systemUserName = "TavernAI";
const systemCharName = "Chloe";
var default_user_name = "You";
var name1 = default_user_name;
var name2 = "Chloe";
// might want to migrate this to 'system message' code
var chat = [
{
name: "Chloe",
is_user: false,
is_name: true,
create_date: 0,
mes:
"\n*You went inside. The air smelled of fried meat, tobacco and a hint of wine. A dim light was cast by candles, and a fire crackled in the fireplace. It seems to be a very pleasant place. Behind the wooden bar is an elf waitress, she is smiling. Her ears are very pointy, and there is a twinkle in her eye. She wears glasses and a white apron. As soon as she noticed you, she immediately came right up close to you.*\n\n" +
' "Hello there! How is your evening going?"
\n' +
'\n',
},
];
var safetychat = [
{
name: "Chloe",
is_user: false,
is_name: true,
create_date: 0,
mes: "\n*You deleted a character/chat and arrived back here for safety reasons! Pick another character!*\n\n",
},
];
var chat_create_date = 0;
let prev_selected_char = null;
var default_ch_mes = "Hello";
var count_view_mes = 0;
var mesStr = "";
var generatedPromtCache = "";
var characters = [];
let groups = [];
let selected_group = null;
let is_group_automode_enabled = false;
var this_chid;
var active_character;
var backgrounds = [];
var default_avatar = "img/fluffy.png";
var is_colab = false;
var is_checked_colab = false;
var is_mes_reload_avatar = false;
let collapse_newlines = false;
const system_message_types = {
HELP: "help",
WELCOME: "welcome",
GROUP: "group",
EMPTY: "empty",
GENERIC: "generic",
};
const system_messages = {
help: {
name: systemUserName,
force_avatar: "img/five.png",
is_user: false,
is_system: true,
is_name: true,
mes: 'Hi there! The following chat formatting commands are supported:
*text* – format the actions that your character does
{*text*} – set the behavioral bias for your character
',
},
group: {
name: systemUserName,
force_avatar: "img/five.png",
is_user: false,
is_system: true,
is_name: true,
mes: "Group chat created. Say 'Hi' to lovely people!",
},
empty: {
name: systemUserName,
force_avatar: "img/five.png",
is_user: false,
is_system: true,
is_name: true,
mes: "No one hears you. **Hint:** add more members to the group!",
},
generic: {
name: systemUserName,
force_avatar: "img/five.png",
is_user: false,
is_system: true,
is_name: true,
mes: "Generic system message. User `text` parameter to override the contents",
},
};
const world_info_position = {
before: 0,
after: 1,
};
const talkativeness_default = 0.5;
const storage_keys = {
collapse_newlines: "TavernAI_collapse_newlines",
};
var is_advanced_char_open = false;
var is_world_edit_open = false;
var menu_type = ""; //what is selected in the menu
var selected_button = ""; //which button pressed
//create pole save
var create_save_name = "";
var create_save_description = "";
var create_save_personality = "";
var create_save_first_message = "";
var create_save_avatar = "";
var create_save_scenario = "";
var create_save_mes_example = "";
var create_save_talkativeness = talkativeness_default;
var timerSaveEdit;
var timerWorldSave;
var timerGroupSave;
var durationSaveEdit = 200;
//animation right menu
var animation_rm_duration = 200;
var animation_rm_easing = "";
var popup_type = "";
var bg_file_for_del = "";
var online_status = "no_connection";
var api_server = "";
var api_server_textgenerationwebui = "";
//var interval_timer = setInterval(getStatus, 2000);
var interval_timer_novel = setInterval(getStatusNovel, 3000);
const groupAutoModeInterval = setInterval(groupChatAutoModeWorker, 5000);
var is_get_status = false;
var is_get_status_novel = false;
var is_api_button_press = false;
var is_api_button_press_novel = false;
var is_send_press = false; //Send generation
let is_group_generating = false; // Group generation flag
var add_mes_without_animation = false;
var this_del_mes = 0;
var this_edit_mes_text = "";
var this_edit_mes_chname = "";
var this_edit_mes_id;
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
//settings
var settings;
var koboldai_settings;
var koboldai_setting_names;
var preset_settings = "gui";
var user_avatar = "you.png";
var temp = 0.5;
var world_info = null;
var world_names;
var world_info_data = null;
var world_info_depth = 2;
var world_info_budget = 128;
var imported_world_name = "";
var amount_gen = 80; //default max length of AI generated responses
var max_context = 2048;
var rep_pen = 1;
var rep_pen_size = 100;
var textgenerationwebui_settings = {
temp: 0.5,
top_p: 0.9,
top_k: 0,
typical_p: 1,
rep_pen: 1.1,
rep_pen_size: 0,
penalty_alpha: 0,
};
var is_pygmalion = false;
var tokens_already_generated = 0;
var message_already_generated = "";
var if_typing_text = false;
const tokens_cycle_count = 30;
var cycle_count_generation = 0;
var anchor_order = 0;
var style_anchor = true;
var character_anchor = true;
let extension_prompts = {};
var auto_connect = false;
var auto_load_chat = false;
var main_api = "kobold";
//novel settings
var temp_novel = 0.5;
var rep_pen_novel = 1;
var rep_pen_size_novel = 100;
var api_key_novel = "";
var novel_tier;
var model_novel = "euterpe-v2";
var novelai_settings;
var novelai_setting_names;
var preset_settings_novel = "Classic-Krake";
//css
var bg1_toggle = true; // inits the BG as BG1
var css_mes_bg = $('').css("background");
var css_send_form_display = $("").css("display");
var colab_ini_step = 1;
var token;
setInterval(function () {
switch (colab_ini_step) {
case 0:
$("#colab_popup_text").html("
Initialization
");
colab_ini_step = 1;
break;
case 1:
$("#colab_popup_text").html("
Initialization.
");
colab_ini_step = 2;
break;
case 2:
$("#colab_popup_text").html("
Initialization..
");
colab_ini_step = 3;
break;
case 3:
$("#colab_popup_text").html("
Initialization...
");
colab_ini_step = 0;
break;
}
}, 500);
/////////////
$.ajaxPrefilter((options, originalOptions, xhr) => {
xhr.setRequestHeader("X-CSRF-Token", token);
});
$.get("/csrf-token").then((data) => {
token = data.token;
getCharacters();
getSettings("def");
getLastVersion();
//getCharacters();
printMessages();
getBackgrounds();
getUserAvatars();
});
function flushSettings() {
$("#settings_perset").empty();
$("#settings_perset_novel").empty();
$("#world_info").empty();
$("#settings_perset").append(
''
);
$("#world_info").append('');
}
function checkOnlineStatus() {
//console.log(online_status);
if (online_status == "no_connection") {
$("#send_textarea").attr("placeholder", "Not connected to API!"); //Input bar placeholder tells users they are not connected
$("#send_form").css("background-color", "rgba(100,0,0,0.7)"); //entire input form area is red when not connected
$("#send_but").css("display", "none"); //send button is hidden when not connected
$("#online_status_indicator2").css("background-color", "red");
$("#online_status_text2").html("No connection...");
$("#online_status_indicator3").css("background-color", "red");
$("#online_status_text3").html("No connection...");
is_get_status = false;
is_get_status_novel = false;
} else {
$("#send_textarea").attr("placeholder", "Type a message..."); //on connect, placeholder tells user to type message
$("#send_form").css("background-color", "rgba(0,0,0,0.7)"); //on connect, form BG changes to transprent black
$("#send_but").css("display", "inline"); //on connect, send button shows up
$("#online_status_indicator2").css("background-color", "green");
$("#online_status_text2").html(online_status);
$("#online_status_indicator3").css("background-color", "green");
$("#online_status_text3").html(online_status);
$("#online_status_indicator4").css("background-color", "green");
$("#online_status_text4").html(online_status);
}
}
async function getLastVersion() {
jQuery.ajax({
type: "POST", //
url: "/getlastversion", //
data: JSON.stringify({
"": "",
}),
beforeSend: function () { },
cache: false,
dataType: "json",
contentType: "application/json",
//processData: false,
success: function (data) {
var getVersion = data.version;
if (getVersion !== "error" && getVersion != undefined) {
if (compareVersions(getVersion, VERSION) === 1) {
$("#verson").append(" (v." + getVersion + ")");
}
}
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
}
async function getStatus() {
if (is_get_status) {
jQuery.ajax({
type: "POST", //
url: "/getstatus", //
data: JSON.stringify({
api_server:
main_api == "kobold" ? api_server : api_server_textgenerationwebui,
main_api: main_api,
}),
beforeSend: function () {
if (is_api_button_press) {
//$("#api_loading").css("display", 'inline-block');
//$("#api_button").css("display", 'none');
}
//$('#create_button').attr('value','Creating...'); //
},
cache: false,
dataType: "json",
crossDomain: true,
contentType: "application/json",
//processData: false,
success: function (data) {
online_status = data.result;
if (online_status == undefined) {
online_status = "no_connection";
}
if (online_status.toLowerCase().indexOf("pygmalion") != -1) {
is_pygmalion = true;
online_status += " (Pyg. formatting on)";
} else {
is_pygmalion = false;
}
//console.log(online_status);
resultCheckStatus();
if (online_status !== "no_connection") {
var checkStatusNow = setTimeout(getStatus, 3000); //getStatus();
}
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
online_status = "no_connection";
resultCheckStatus();
},
});
} else {
if (is_get_status_novel != true) {
online_status = "no_connection";
}
}
}
function resultCheckStatus() {
is_api_button_press = false;
checkOnlineStatus();
$("#api_loading").css("display", "none");
$("#api_button").css("display", "inline-block");
$("#api_loading_textgenerationwebui").css("display", "none");
$("#api_button_textgenerationwebui").css("display", "inline-block");
}
async function getSoftPromptsList() {
if (!api_server) {
return;
}
const response = await fetch("/getsoftprompts", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({ api_server: api_server }),
});
if (response.ok) {
const data = await response.json();
updateSoftPromptsList(data.soft_prompts);
}
}
function clearSoftPromptsList() {
$('#softprompt option[value!=""]').each(function () {
$(this).remove();
});
}
function updateSoftPromptsList(soft_prompts) {
// Delete SPs removed from Kobold
$("#softprompt option").each(function () {
const value = $(this).attr("value");
if (value == "") {
return;
}
const prompt = soft_prompts.find((x) => x.name === value);
if (!prompt) {
$(this).remove();
}
});
// Add SPs added to Kobold
soft_prompts.forEach((prompt) => {
if ($(`#softprompt option[value="${prompt.name}"]`).length === 0) {
$("#softprompt").append(
``
);
if (prompt.selected) {
$("#softprompt").val(prompt.name);
}
}
});
// No SP selected or no SPs
if (soft_prompts.length === 0 || !soft_prompts.some((x) => x.selected)) {
$("#softprompt").val("");
}
}
function printCharacters() {
//console.log('printCharacters() entered');
$("#rm_print_characters_block").empty();
//console.log('printCharacters() -- sees '+characters.length+' characters.');
characters.forEach(function (item, i, arr) {
var this_avatar = default_avatar;
if (item.avatar != "none") {
this_avatar = "characters/" + item.avatar + "?" + Date.now();
} //RossAscends: changed 'prepend' to 'append' to make alphabetical sorting display correctly.
$("#rm_print_characters_block").append(
"
' +
item.name +
"
"
);
//console.log('printcharacters() -- printing -- ChID '+i+' ('+item.name+')');
});
printGroups();
}
function printGroups() {
for (let group of groups) {
const template = $("#group_list_template .group_select").clone();
template.data("id", group.id);
template.find(".ch_name").html(group.name);
$("#rm_print_characters_block").prepend(template);
updateGroupAvatar(group);
}
}
function updateGroupAvatar(group) {
$("#rm_print_characters_block .group_select").each(function () {
if ($(this).data("id") == group.id) {
const avatar = getGroupAvatar(group);
if (avatar) {
$(this).find(".avatar").replaceWith(avatar);
}
}
});
}
function getGroupAvatar(group) {
const memberAvatars = [];
if (group && Array.isArray(group.members) && group.members.length) {
for (const member of group.members) {
const charIndex = characters.findIndex((x) => x.name === member);
if (charIndex !== -1 && characters[charIndex].avatar !== "none") {
const this_avatar = `characters/${characters[charIndex].avatar
}#${Date.now()}`;
memberAvatars.push(this_avatar);
}
if (memberAvatars.length === 4) {
break;
}
}
}
// Cohee: there's probably a smarter way to do this..
if (memberAvatars.length === 1) {
const groupAvatar = $("#group_avatars_template .collage_1").clone();
groupAvatar.find(".img_1").attr("src", memberAvatars[0]);
return groupAvatar;
}
if (memberAvatars.length === 2) {
const groupAvatar = $("#group_avatars_template .collage_2").clone();
groupAvatar.find(".img_1").attr("src", memberAvatars[0]);
groupAvatar.find(".img_2").attr("src", memberAvatars[1]);
return groupAvatar;
}
if (memberAvatars.length === 3) {
const groupAvatar = $("#group_avatars_template .collage_3").clone();
groupAvatar.find(".img_1").attr("src", memberAvatars[0]);
groupAvatar.find(".img_2").attr("src", memberAvatars[1]);
groupAvatar.find(".img_3").attr("src", memberAvatars[2]);
return groupAvatar;
}
if (memberAvatars.length === 4) {
const groupAvatar = $("#group_avatars_template .collage_4").clone();
groupAvatar.find(".img_1").attr("src", memberAvatars[0]);
groupAvatar.find(".img_2").attr("src", memberAvatars[1]);
groupAvatar.find(".img_3").attr("src", memberAvatars[2]);
groupAvatar.find(".img_4").attr("src", memberAvatars[3]);
return groupAvatar;
}
// default avatar
const groupAvatar = $("#group_avatars_template .collage_1").clone();
groupAvatar.find(".img_1").attr("src", group.avatar_url);
return groupAvatar;
}
async function getCharacters() {
await getGroups();
//console.log('getCharacters() -- entered');
//console.log(characters);
var response = await fetch("/getcharacters", {
//RossAscends: changed from const
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({
"": "",
}),
});
if (response.ok === true) {
var getData = ""; //RossAscends: reset to force array to update to account for deleted character.
var getData = await response.json(); //RossAscends: changed from const
//console.log(getData);
//var aa = JSON.parse(getData[0]);
var load_ch_count = Object.getOwnPropertyNames(getData); //RossAscends: change from const to create dynamic character load amounts.
var charCount = load_ch_count.length;
//console.log('/getcharacters -- expecting to load '+charCount+' characters.')
for (var i = 0; i < load_ch_count.length; i++) {
characters[i] = [];
characters[i] = getData[i];
//console.log('/getcharacters -- loaded character #'+(i+1)+' ('+characters[i].name+')');
}
//RossAscends: updated character sorting to be alphabetical
characters.sort(function (a, b) {
//console.log('sorting characters: '+a.name+' vs '+b.name);
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
});
//console.log(characters);
//characters.reverse();
//console.log('/getcharacters -- this_chid -- '+this_chid);
if (this_chid != undefined && this_chid != "invalid-safety-id") {
$("#avatar_url_pole").val(characters[this_chid].avatar);
}
//console.log('/getcharacters -- sending '+i+' characters to /printcharacters');
printCharacters();
//console.log(propOwn.length);
//return JSON.parse(getData[0]);
//const getData = await response.json();
//var getMessage = getData.results[0].text;
}
}
async function getBackgrounds() {
const response = await fetch("/getbackgrounds", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({
"": "",
}),
});
if (response.ok === true) {
const getData = await response.json();
//background = getData;
//console.log(getData.length);
for (var i = 0; i < getData.length; i++) {
//console.log(1);
$("#bg_menu_content").append(
"
");
$("#rm_button_characters").css("class", "deselected-right-tab");
$("#rm_button_settings").css("class", "deselected-right-tab");
$("#rm_button_selected_ch").css("class", "deselected-right-tab");
prev_selected_char = charId;
}
function select_selected_character(chid) {
//character select
//console.log('select_selected_character() -- starting with input of -- '+chid+' (name:'+characters[chid].name+')');
select_rm_create();
menu_type = "character_edit";
$("#delete_button").css("display", "block");
$("#export_button").css("display", "block");
$("#rm_button_selected_ch").css("class", "selected-right-tab");
var display_name = characters[chid].name;
$("#rm_button_selected_ch").children("h2").text(display_name);
//create text poles
$("#rm_button_back").css("display", "none");
//$("#character_import_button").css("display", "none");
$("#create_button").attr("value", "Save");
$("#create_button").css("display", "none");
var i = 0;
while ($("#rm_button_selected_ch").width() > 170 && i < 100) {
display_name = display_name.slice(0, display_name.length - 2);
//console.log(display_name);
$("#rm_button_selected_ch")
.children("h2")
.text($.trim(display_name) + "...");
i++;
}
$("#add_avatar_button").val("");
$("#character_popup_text_h3").text(characters[chid].name);
$("#character_name_pole").val(characters[chid].name);
$("#description_textarea").val(characters[chid].description);
$("#personality_textarea").val(characters[chid].personality);
$("#firstmessage_textarea").val(characters[chid].first_mes);
$("#scenario_pole").val(characters[chid].scenario);
$("#talkativeness_slider").val(
characters[chid].talkativeness ?? talkativeness_default
);
$("#mes_example_textarea").val(characters[chid].mes_example);
$("#selected_chat_pole").val(characters[chid].chat);
$("#create_date_pole").val(characters[chid].create_date);
$("#avatar_url_pole").val(characters[chid].avatar);
$("#chat_import_avatar_url").val(characters[chid].avatar);
$("#chat_import_character_name").val(characters[chid].name);
//$("#avatar_div").css("display", "none");
var this_avatar = default_avatar;
if (characters[chid].avatar != "none") {
this_avatar = "characters/" + characters[chid].avatar;
}
$("#avatar_load_preview").attr("src", this_avatar + "?" + Date.now());
$("#name_div").css("display", "none");
$("#form_create").attr("actiontype", "editcharacter");
active_character = chid;
//console.log('select_selected_character() -- active_character -- '+chid+'(ChID of '+display_name+')');
saveSettings();
//console.log('select_selected_character() -- called saveSettings() to save -- active_character -- '+active_character+'(ChID of '+display_name+')');
}
function select_rm_create() {
menu_type = "create";
//console.log('select_rm_Create() -- selected button: '+selected_button);
if (selected_button == "create") {
if (create_save_avatar != "") {
$("#add_avatar_button").get(0).files = create_save_avatar;
read_avatar_load($("#add_avatar_button").get(0));
}
}
$("#rm_characters_block").css("display", "none");
$("#rm_api_block").css("display", "none");
$("#rm_ch_create_block").css("display", "block");
$("#rm_group_chats_block").css("display", "none");
$("#rm_ch_create_block").css("opacity", 0.0);
$("#rm_ch_create_block").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
complete: function () { },
});
$("#rm_info_block").css("display", "none");
$("#delete_button_div").css("display", "none");
$("#delete_button").css("display", "none");
$("#export_button").css("display", "none");
$("#create_button").css("display", "block");
$("#create_button").attr("value", "Create");
//RossAscends: commented this out as part of the auto-loading token counter
//$('#result_info').html(' ');
$("#rm_button_characters").css("class", "deselected-right-tab");
$("#rm_button_settings").css("class", "deselected-right-tab");
$("#rm_button_selected_ch").css("class", "deselected-right-tab");
//create text poles
$("#rm_button_back").css("display", "inline-block");
$("#character_import_button").css("display", "inline-block");
$("#character_popup_text_h3").text("Create character");
$("#character_name_pole").val(create_save_name);
$("#description_textarea").val(create_save_description);
$("#personality_textarea").val(create_save_personality);
$("#firstmessage_textarea").val(create_save_first_message);
$("#talkativeness_slider").val(create_save_talkativeness);
$("#scenario_pole").val(create_save_scenario);
if ($.trim(create_save_mes_example).length == 0) {
$("#mes_example_textarea").val("");
} else {
$("#mes_example_textarea").val(create_save_mes_example);
}
$("#avatar_div").css("display", "grid");
$("#avatar_load_preview").attr("src", default_avatar);
$("#name_div").css("display", "block");
$("#form_create").attr("actiontype", "createcharacter");
}
function select_rm_characters() {
/* QuickRefresh(true); */
if (prev_selected_char) {
let newChId = characters.findIndex((x) => x.name == prev_selected_char);
$(`.character_select[chid="${newChId}"]`).trigger("click");
prev_selected_char = null;
}
menu_type = "characters";
$("#rm_characters_block").css("display", "block");
$("#rm_characters_block").css("opacity", 0.0);
$("#rm_characters_block").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
complete: function () { },
});
$("#rm_api_block").css("display", "none");
$("#rm_ch_create_block").css("display", "none");
$("#rm_info_block").css("display", "none");
$("#rm_group_chats_block").css("display", "none");
$("#rm_button_characters").css("class", "selected-right-tab");
$("#rm_button_settings").css("class", "deselected-right-tab");
$("#rm_button_selected_ch").css("class", "deselected-right-tab");
}
/// UTILS
function onlyUnique(value, index, array) {
return array.indexOf(value) === index;
}
function shuffle(array) {
let currentIndex = array.length,
randomIndex;
while (currentIndex != 0) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
];
}
return array;
}
function setExtensionPrompt(key, value) {
extension_prompts[key] = value;
}
async function updateWorldInfoList(importedWorldName) {
var result = await fetch("/getsettings", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({}),
});
if (result.ok) {
var data = await result.json();
world_names = data.world_names?.length ? data.world_names : [];
$("#world_info").find('option[value!="None"]').remove();
world_names.forEach((item, i) => {
$("#world_info").append(``);
});
if (importedWorldName) {
const indexOf = world_names.indexOf(world_info);
$("#world_info").val(indexOf);
popup_type = "world_imported";
callPopup("
World imported successfully! Select it now?
");
}
}
}
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], { type: contentType });
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
// World Info Editor
async function showWorldEditor() {
if (!world_info) {
popup_type = "default";
callPopup("
Select a world info first!
");
return;
}
is_world_edit_open = true;
$("#world_popup_name").val(world_info);
$("#world_popup").css("display", "flex");
await loadWorldInfoData();
displayWorldEntries(world_info_data);
}
async function loadWorldInfoData() {
if (!world_info) {
return;
}
const response = await fetch("/getworldinfo", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({ name: world_info }),
});
if (response.ok) {
world_info_data = await response.json();
}
}
function hideWorldEditor() {
is_world_edit_open = false;
$("#world_popup").css("display", "none");
}
function displayWorldEntries(data) {
$("#world_popup_entries_list").empty();
if (!data || !("entries" in data)) {
return;
}
for (const entryUid in data.entries) {
const entry = data.entries[entryUid];
appendWorldEntry(entry);
}
}
function appendWorldEntry(entry) {
const template = $("#entry_edit_template .world_entry").clone();
template.data("uid", entry.uid);
// key
const keyInput = template.find('textarea[name="key"]');
keyInput.data("uid", entry.uid);
keyInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).val();
$(this).css("height", ""); //reset the height
$(this).css("height", $(this).prop("scrollHeight") + "px");
world_info_data.entries[uid].key = value
.split(",")
.map((x) => x.trim())
.filter((x) => x);
saveWorldInfo();
});
keyInput.val(entry.key.join(",")).trigger("input");
keyInput.css("height", ""); //reset the height
keyInput.css("height", $(this).prop("scrollHeight") + "px");
// keysecondary
const keySecondaryInput = template.find('textarea[name="keysecondary"]');
keySecondaryInput.data("uid", entry.uid);
keySecondaryInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).val();
$(this).css("height", ""); //reset the height
$(this).css("height", $(this).prop("scrollHeight") + "px");
world_info_data.entries[uid].keysecondary = value
.split(",")
.map((x) => x.trim())
.filter((x) => x);
saveWorldInfo();
});
keySecondaryInput.val(entry.keysecondary.join(",")).trigger("input");
keySecondaryInput.css("height", ""); //reset the height
keySecondaryInput.css("height", $(this).prop("scrollHeight") + "px");
// comment
const commentInput = template.find('textarea[name="comment"]');
commentInput.data("uid", entry.uid);
commentInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).val();
$(this).css("height", ""); //reset the height
$(this).css("height", $(this).prop("scrollHeight") + "px");
world_info_data.entries[uid].comment = value;
saveWorldInfo();
});
commentInput.val(entry.comment).trigger("input");
commentInput.css("height", ""); //reset the height
commentInput.css("height", $(this).prop("scrollHeight") + "px");
// content
const contentInput = template.find('textarea[name="content"]');
contentInput.data("uid", entry.uid);
contentInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).val();
world_info_data.entries[uid].content = value;
$(this).css("height", ""); //reset the height
$(this).css("height", $(this).prop("scrollHeight") + "px");
saveWorldInfo();
// count tokens
const numberOfTokens = encode(value).length;
$(this)
.closest(".world_entry")
.find(".world_entry_form_token_counter")
.html(numberOfTokens);
});
contentInput.val(entry.content).trigger("input");
contentInput.css("height", ""); //reset the height
contentInput.css("height", $(this).prop("scrollHeight") + "px");
// selective
const selectiveInput = template.find('input[name="selective"]');
selectiveInput.data("uid", entry.uid);
selectiveInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).prop("checked");
world_info_data.entries[uid].selective = value;
saveWorldInfo();
const keysecondary = $(this)
.closest(".world_entry")
.find(".keysecondary");
value ? keysecondary.show() : keysecondary.hide();
});
selectiveInput.prop("checked", entry.selective).trigger("input");
selectiveInput.siblings(".checkbox_fancy").click(function () {
$(this).siblings("input").click();
});
// constant
const constantInput = template.find('input[name="constant"]');
constantInput.data("uid", entry.uid);
constantInput.on("input", function () {
const uid = $(this).data("uid");
const value = $(this).prop("checked");
world_info_data.entries[uid].constant = value;
saveWorldInfo();
});
constantInput.prop("checked", entry.constant).trigger("input");
constantInput.siblings(".checkbox_fancy").click(function () {
$(this).siblings("input").click();
});
// order
const orderInput = template.find('input[name="order"]');
orderInput.data("uid", entry.uid);
orderInput.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
world_info_data.entries[uid].order = !isNaN(value) ? value : 0;
saveWorldInfo();
});
orderInput.val(entry.order).trigger("input");
// position
if (entry.position === undefined) {
entry.position = 0;
}
const positionInput = template.find('input[name="position"]');
positionInput.data("uid", entry.uid);
positionInput.on("input", function () {
const uid = $(this).data("uid");
const value = Number($(this).val());
world_info_data.entries[uid].position = !isNaN(value) ? value : 0;
saveWorldInfo();
});
template
.find(`input[name="position"][value=${entry.position}]`)
.prop("checked", true)
.trigger("input");
// display uid
template.find(".world_entry_form_uid_value").html(entry.uid);
// delete button
const deleteButton = template.find("input.delete_entry_button");
deleteButton.data("uid", entry.uid);
deleteButton.on("click", function () {
const uid = $(this).data("uid");
deleteWorldInfoEntry(uid);
$(this).closest(".world_entry").remove();
saveWorldInfo();
});
template.appendTo("#world_popup_entries_list");
return template;
}
async function deleteWorldInfoEntry(uid) {
if (!world_info_data || !("entries" in world_info_data)) {
return;
}
delete world_info_data.entries[uid];
}
function createWorldInfoEntry() {
const newEntryTemplate = {
key: [],
keysecondary: [],
comment: "",
content: "",
constant: false,
selective: false,
order: 100,
position: 0,
};
const newUid = getFreeWorldEntryUid();
if (!Number.isInteger(newUid)) {
console.error("Couldn't assign UID to a new entry");
return;
}
const newEntry = { uid: newUid, ...newEntryTemplate };
world_info_data.entries[newUid] = newEntry;
const entryTemplate = appendWorldEntry(newEntry);
entryTemplate.get(0).scrollIntoView({ behavior: "smooth" });
}
async function saveWorldInfo(immediately) {
if (!world_info || !world_info_data) {
return;
}
async function _save() {
const response = await fetch("/editworldinfo", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({ name: world_info, data: world_info_data }),
});
}
if (immediately) {
return await _save();
}
clearTimeout(timerWorldSave);
timerWorldSave = setTimeout(async () => await _save(), durationSaveEdit);
}
async function renameWorldInfo() {
const oldName = world_info;
const newName = $("#world_popup_name").val();
if (oldName === newName) {
return;
}
world_info = newName;
await saveWorldInfo(true);
await deleteWorldInfo(oldName, newName);
}
async function deleteWorldInfo(worldInfoName, selectWorldName) {
if (!world_names.includes(worldInfoName)) {
return;
}
const response = await fetch("/deleteworldinfo", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({ name: worldInfoName }),
});
if (response.ok) {
await updateWorldInfoList();
const selectedIndex = world_names.indexOf(selectWorldName);
if (selectedIndex !== -1) {
$("#world_info").val(selectedIndex).change();
} else {
$("#world_info").val("None").change();
}
hideWorldEditor();
}
}
function getFreeWorldEntryUid() {
if (!world_info_data || !("entries" in world_info_data)) {
return null;
}
const MAX_UID = 1_000_000; // <- should be safe enough :)
for (let uid = 0; uid < MAX_UID; uid++) {
if (uid in world_info_data.entries) {
continue;
}
return uid;
}
return null;
}
function getFreeWorldName() {
const MAX_FREE_NAME = 100_000;
for (let index = 1; index < MAX_FREE_NAME; index++) {
const newName = `New World (${index})`;
if (world_names.includes(newName)) {
continue;
}
return newName;
}
return undefined;
}
async function createNewWorldInfo() {
const worldInfoTemplate = { entries: {} };
const worldInfoName = getFreeWorldName();
if (!worldInfoName) {
return;
}
world_info = worldInfoName;
world_info_data = { ...worldInfoTemplate };
await saveWorldInfo(true);
await updateWorldInfoList();
const selectedIndex = world_names.indexOf(worldInfoName);
if (selectedIndex !== -1) {
$("#world_info").val(selectedIndex).change();
} else {
$("#world_info").val("None").change();
}
}
window["TavernAI"].getContext = function () {
return {
chat: chat,
characters: characters,
groups: groups,
worldInfo: world_info_data,
name1: name1,
name2: name2,
characterId: this_chid,
groupId: selected_group,
chatId: this_chid && characters[this_chid] && characters[this_chid].chat,
onlineStatus: online_status,
addOneMessage: addOneMessage,
generate: Generate,
encode: encode,
extensionPrompts: extension_prompts,
setExtensionPrompt: setExtensionPrompt,
saveChat: saveChat,
sendSystemMessage: sendSystemMessage,
};
};
$(document).ready(function () {
$("#character_search_bar").on("input", function () {
const searchValue = $(this).val().trim().toLowerCase();
if (!searchValue) {
$("#rm_print_characters_block .character_select").show();
} else {
$("#rm_print_characters_block .character_select").each(function () {
$(this).children(".ch_name").text().toLowerCase().includes(searchValue)
? $(this).show()
: $(this).hide();
});
}
});
$("#characloud_url").click(function () {
window.open("https://boosty.to/tavernai", "_blank");
});
$("#send_but").click(function () {
//$( "#send_but" ).css({"background": "url('img/load.gif')","background-size": "100%, 100%", "background-position": "center center"});
if (is_send_press == false) {
is_send_press = true;
Generate();
}
});
//hotkey to send input with enter (shift+enter generates a new line in the chat input box)
//this is not ideal for touch device users with virtual keyboards.
//ideally we would detect if the user is using a virtual keyboard, and disable this shortcut for them.
//because mobile users' hands are always near the screen, tapping the send button is better for them, and enter should always make a new line.
//note: CAI seems to have this handled. PC: shift+enter = new line, enter = send. iOS: shift+enter AND enter both make new lines, and only the send button sends.
//maybe a way to simulate this would be to disable the eventListener for people iOS.
$("#send_textarea").keydown(function (e) {
if (
!e.shiftKey &&
!e.ctrlKey &&
e.key == "Enter" &&
is_send_press == false
) {
is_send_press = true;
e.preventDefault();
Generate();
}
});
/* //RossAscends: Additional hotkeys
document.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.key == "Enter") { // Ctrl+Enter for Regeneration Last Response
if (is_send_press == false) {
is_send_press = true;
Generate('regenerate');
}
} else if (event.ctrlKey && event.key == "ArrowUp") { //Ctrl+UpArrow for Connect to last server
document.getElementById('api_button').click();
}
}); */
//menu buttons setup
var selected_button_style = {};
var deselected_button_style = {};
$("#rm_button_create").css("class", "deselected-right-tab");
$("#rm_button_characters").css("class", "deselected-right-tab");
$("#rm_button_settings").click(function () {
selected_button = "settings";
menu_type = "settings";
$("#rm_characters_block").css("display", "none");
$("#rm_api_block").css("display", "grid");
$("#rm_api_block").css("opacity", 0.0);
$("#rm_api_block").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
complete: function () { },
});
$("#rm_ch_create_block").css("display", "none");
$("#rm_info_block").css("display", "none");
$("#rm_group_chats_block").css("display", "none");
$("#rm_button_characters").css("class", "deselected-right-tab");
$("#rm_button_settings").css("class", "selected-right-tab");
$("#rm_button_selected_ch").css("class", "deselected-right-tab");
});
$("#rm_button_characters").click(function () {
selected_button = "characters";
select_rm_characters();
});
$("#rm_button_back").click(function () {
selected_button = "characters";
select_rm_characters();
});
$("#rm_button_create").click(function () {
selected_button = "create";
select_rm_create();
});
$("#rm_button_selected_ch").click(function () {
selected_button = "character_edit";
select_selected_character(this_chid);
});
$(document).on("click", ".group_select", async function () {
const id = $(this).data("id");
selected_button = "group_chats";
if (!is_send_press && !is_group_generating) {
if (selected_group !== id) {
selected_group = id;
this_chid = undefined;
this_edit_mes_id = undefined;
clearChat();
chat.length = 0;
await getGroupChat(id);
}
select_group_chats(id);
}
});
$("#rm_button_group_chats").click(function () {
selected_button = "group_chats";
select_group_chats();
});
$("#rm_button_back_from_group").click(function () {
selected_button = "characters";
select_rm_characters();
});
$("#rm_group_filter").on("input", function () {
const searchValue = $(this).val().trim().toLowerCase();
if (!searchValue) {
$("#rm_group_add_members .group_member").show();
} else {
$("#rm_group_add_members .group_member").each(function () {
$(this).children(".ch_name").text().toLowerCase().includes(searchValue)
? $(this).show()
: $(this).hide();
});
}
});
$("#rm_group_submit").click(async function () {
let name = $("#rm_group_chat_name").val();
const members = $("#rm_group_members .group_member")
.map((_, x) => $(x).data("id"))
.toArray();
if (!name) {
name = `Chat with ${members.join(", ")}`;
}
// placeholder
const avatar_url = "/img/five.png";
const createGroupResponse = await fetch("/creategroup", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
body: JSON.stringify({
name: name,
members: members,
avatar_url: avatar_url,
}),
});
if (createGroupResponse.ok) {
const createGroupData = await createGroupResponse.json();
const id = createGroupData.id;
await getCharacters();
$("#rm_info_avatar").html("");
var avatar = $("#avatar_div_div").clone();
avatar.find("img").attr("src", avatar_url);
$("#rm_info_avatar").append(avatar);
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
select_rm_info("Group chat created");
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
}
});
$("#rm_group_automode").on("input", function () {
const value = $(this).prop("checked");
is_group_automode_enabled = value;
});
$(document).on("click", ".character_select", function () {
if (this_chid !== $(this).attr("chid")) {
//if clicked on a different character from what was currently selected
if (!is_send_press) {
selected_group = null;
is_group_generating = false;
this_edit_mes_id = undefined;
selected_button = "character_edit";
this_chid = $(this).attr("chid");
active_character = this_chid;
clearChat();
chat.length = 0;
getChat();
//console.log('Clicked on '+characters[this_chid].name+' Active_Character set to: '+active_character+' (ChID:'+this_chid+')');
}
} else {
//if clicked on character that was already selected
selected_button = "character_edit";
select_selected_character(this_chid);
}
$("#character_search_bar").val("").trigger("input");
});
var scroll_holder = 0;
var is_use_scroll_holder = false;
$(document).on("input", ".edit_textarea", function () {
scroll_holder = $("#chat").scrollTop();
$(this).height(0).height(this.scrollHeight);
is_use_scroll_holder = true;
});
$("#chat").on("scroll", function () {
if (is_use_scroll_holder) {
$("#chat").scrollTop(scroll_holder);
is_use_scroll_holder = false;
}
});
$(document).on("click", ".del_checkbox", function () {
//when a 'delete message' checkbox is clicked
$(".del_checkbox").each(function () {
$(this).prop("checked", false);
$(this).parent().css("background", css_mes_bg);
});
$(this).parent().css("background", "#600"); //sets the bg of the mes selected for deletion
var i = $(this).parent().attr("mesid"); //checks the message ID in the chat
this_del_mes = i;
while (i < chat.length) {
//as long as the current message ID is less than the total chat length
$(".mes[mesid='" + i + "']").css("background", "#600"); //sets the bg of the all msgs BELOW the selected .mes
$(".mes[mesid='" + i + "']")
.children(".del_checkbox")
.prop("checked", true);
i++;
//console.log(i);
}
});
$(document).on("click", "#user_avatar_block .avatar", function () {
user_avatar = $(this).attr("imgfile");
$(".mes").each(function () {
if ($(this).attr("ch_name") == name1) {
$(this)
.children(".avatar")
.children("img")
.attr("src", "User Avatars/" + user_avatar);
}
});
saveSettings();
highlightSelectedAvatar();
});
$(document).on("click", "#user_avatar_block .avatar_upload", function () {
$("#avatar_upload_file").click();
});
$("#avatar_upload_file").on("change", function (e) {
const file = e.target.files[0];
if (!file) {
return;
}
const formData = new FormData($("#form_upload_avatar").get(0));
jQuery.ajax({
type: "POST",
url: "/uploaduseravatar",
data: formData,
beforeSend: () => { },
cache: false,
contentType: false,
processData: false,
success: function (data) {
if (data.path) {
appendUserAvatar(data.path);
}
},
error: (jqXHR, exception) => { },
});
// Will allow to select the same file twice in a row
$("#form_upload_avatar").trigger("reset");
});
$("#logo_block").click(function (event) {
if (!bg_menu_toggle) {
$("#bg_menu_button").transition({
perspective: "100px",
rotate3d: "1,1,0,180deg",
});
$("#bg_menu_content").transition({
opacity: 1.0,
height: "90vh",
duration: 340,
easing: "in",
complete: function () {
bg_menu_toggle = true;
$("#bg_menu_content").css("overflow-y", "auto");
},
});
} else {
$("#bg_menu_button").transition({
perspective: "100px",
rotate3d: "1,1,0,360deg",
});
$("#bg_menu_content").css("overflow-y", "hidden");
$("#bg_menu_content").transition({
opacity: 0.0,
height: "0px",
duration: 340,
easing: "in",
complete: function () {
bg_menu_toggle = false;
},
});
}
});
$(document).on("click", ".bg_example_img", function () {
//when user clicks on a BG thumbnail...
var this_bgfile = $(this).attr("bgfile"); // this_bgfile = whatever they clicked
if (bg1_toggle == true) {
//if bg1 is toggled true (initially set as true in first JS vars)
bg1_toggle = false; // then toggle it false
var number_bg = 2; // sets a variable for bg2
var target_opacity = 1.0; // target opacity is 100%
} else {
//if bg1 is FALSE
bg1_toggle = true; // make it true
var number_bg = 1; // set variable to bg1..
var target_opacity = 0.0; // set target opacity to 0
}
$("#bg2").stop(); // first, stop whatever BG transition was happening before
$("#bg2").transition({
// start a new BG transition routine
opacity: target_opacity, // set opacity to previously set variable
duration: 1300, //animation_rm_duration,
easing: "linear",
complete: function () {
// why does the BG transition completion make the #options (right nav) invisible?
$("#options").css("display", "none");
},
});
$("#bg" + number_bg).css(
"background-image",
'url("backgrounds/' + this_bgfile + '")'
);
setBackground(this_bgfile);
});
$(document).on("click", ".bg_example_cross", function () {
bg_file_for_del = $(this);
//$(this).parent().remove();
//delBackground(this_bgfile);
popup_type = "del_bg";
callPopup("
Delete the background?
");
});
$("#advanced_div").click(function () {
if (!is_advanced_char_open) {
is_advanced_char_open = true;
$("#character_popup").css("display", "grid");
$("#character_popup").css("opacity", 0.0);
$("#character_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
} else {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
}
});
$("#character_cross").click(function () {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
});
$("#character_popup_ok").click(function () {
is_advanced_char_open = false;
$("#character_popup").css("display", "none");
});
$("#dialogue_popup_ok").click(function () {
$("#shadow_popup").css("display", "none");
$("#shadow_popup").css("opacity:", 0.0);
if (popup_type == "del_bg") {
delBackground(bg_file_for_del.attr("bgfile"));
bg_file_for_del.parent().remove();
}
if (popup_type == "del_ch") {
console.log(
"Deleting character -- ChID: " +
this_chid +
" -- Name: " +
characters[this_chid].name
);
var msg = jQuery("#form_create").serialize(); // ID form
jQuery.ajax({
method: "POST",
url: "/deletecharacter",
beforeSend: function () {
select_rm_info("Character deleted");
//$('#create_button').attr('value','Deleting...');
},
data: msg,
cache: false,
success: function (html) {
//RossAscends: New handling of character deletion that avoids page refreshes and should have fixed char corruption due to cache problems.
//due to how it is handled with 'popup_type', i couldn't find a way to make my method completely modular, so keeping it in TAI-main.js as a new default.
//this allows for dynamic refresh of character list after deleting a character.
$("#character_cross").click(); // closes advanced editing popup
this_chid = "invalid-safety-id"; // unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays)
//avatar = "..img/Chloe.jpg";
characters.length = 0; // resets the characters array, forcing getcharacters to reset
name2 = "Chloe"; // replaces deleted charcter name with Chloe, since she will be displayed next.
chat = [...safetychat]; // sets up chloe to tell user about having deleted a character
$(document.getElementById("rm_button_selected_ch")).css(
"class",
"deselected-right-tab"
); // 'deselects' character's tab panel
$(document.getElementById("rm_button_selected_ch"))
.children("h2")
.text(""); // removes character name from nav tabs
clearChat(); // removes deleted char's chat
this_chid = undefined; // prevents getCharacters from trying to load an invalid char.
getCharacters(); // gets the new list of characters (that doesn't include the deleted one)
printMessages(); // prints out Chloe's 'deleted character' message
//console.log("#dialogue_popup_ok(del-char) >>>> saving");
saveSettings(); // saving settings to keep changes to variables
//getCharacters();
//$('#create_button_div').html(html);
},
});
}
if (popup_type === "world_imported" && imported_world_name) {
world_names.forEach((item, i) => {
if (item === imported_world_name) {
$("#world_info").val(i).change();
}
});
imported_world_name = "";
}
if (popup_type === "del_world" && world_info) {
deleteWorldInfo(world_info);
}
if (popup_type === "del_group") {
const groupId = $("#dialogue_popup").data("group_id");
if (groupId) {
deleteGroup(groupId);
}
}
//Make a new chat for selected character
if (
popup_type == "new_chat" &&
this_chid != undefined &&
menu_type != "create"
) {
//Fix it; New chat doesn't create while open create character menu
clearChat();
chat.length = 0;
characters[this_chid].chat = name2 + " - " + humanizedDateTime(); //RossAscends: added character name to new chat filenames and replaced Date.now() with humanizedDateTime;
$("#selected_chat_pole").val(characters[this_chid].chat);
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
getChat();
}
});
$("#dialogue_popup_cancel").click(function () {
$("#shadow_popup").css("display", "none");
$("#shadow_popup").css("opacity:", 0.0);
popup_type = "";
});
function callPopup(text) {
$("#dialogue_popup_cancel").css("display", "inline-block");
switch (popup_type) {
case "text":
case "char_not_selected":
$("#dialogue_popup_ok").text("Ok");
$("#dialogue_popup_cancel").css("display", "none");
break;
case "world_imported":
case "new_chat":
$("#dialogue_popup_ok").text("Yes");
break;
case "del_world":
case "del_group":
default:
$("#dialogue_popup_ok").text("Delete");
}
$("#dialogue_popup_text").html(text);
$("#shadow_popup").css("display", "block");
$("#shadow_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
}
function read_bg_load(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#bg_load_preview")
.attr("src", e.target.result)
.width(103)
.height(83);
var formData = new FormData($("#form_bg_download").get(0));
//console.log(formData);
jQuery.ajax({
type: "POST",
url: "/downloadbackground",
data: formData,
beforeSend: function () {
//$('#create_button').attr('value','Creating...');
},
cache: false,
contentType: false,
processData: false,
success: function (html) {
setBackground(html);
if (bg1_toggle == true) {
// this is a repeat of the background setting function for when user uploads a new BG image
bg1_toggle = false; // should make the Bg setting a modular function to be called in both cases
var number_bg = 2;
var target_opacity = 1.0;
} else {
bg1_toggle = true;
var number_bg = 1;
var target_opacity = 0.0;
}
$("#bg2").transition({
opacity: target_opacity,
duration: 1300, //animation_rm_duration,
easing: "linear",
complete: function () {
$("#options").css("display", "none");
},
});
$("#bg" + number_bg).css(
"background-image",
"url(" + e.target.result + ")"
);
$("#form_bg_download").after(
"
"
);
},
error: function (jqXHR, exception) {
console.log(exception);
console.log(jqXHR);
},
});
};
reader.readAsDataURL(input.files[0]);
}
}
$("#add_bg_button").change(function () {
read_bg_load(this);
});
function read_avatar_load(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
if (selected_button == "create") {
create_save_avatar = input.files;
}
reader.onload = function (e) {
if (selected_button == "character_edit") {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
$("#avatar_load_preview").attr("src", e.target.result);
//.width(103)
//.height(83);
//console.log(e.target.result.name);
};
reader.readAsDataURL(input.files[0]);
}
}
$("#add_avatar_button").change(function () {
is_mes_reload_avatar = Date.now();
read_avatar_load(this);
});
$("#form_create").submit(function (e) {
$("#rm_info_avatar").html("");
var formData = new FormData($("#form_create").get(0));
if ($("#form_create").attr("actiontype") == "createcharacter") {
if ($("#character_name_pole").val().length > 0) {
//if the character name text area isn't empty (only posible when creating a new character)
//console.log('/createcharacter entered');
jQuery.ajax({
type: "POST",
url: "/createcharacter",
data: formData,
beforeSend: function () {
$("#create_button").attr("disabled", true);
$("#create_button").attr("value", "Creating...");
},
cache: false,
contentType: false,
processData: false,
success: async function (html) {
$("#character_cross").click(); //closes the advanced character editing popup
$("#character_name_pole").val("");
create_save_name = "";
$("#description_textarea").val("");
create_save_description = "";
$("#personality_textarea").val("");
create_save_personality = "";
$("#firstmessage_textarea").val("");
create_save_first_message = "";
$("#talkativeness_slider").val(talkativeness_default);
create_save_talkativeness = talkativeness_default;
$("#character_popup_text_h3").text("Create character");
$("#scenario_pole").val("");
create_save_scenario = "";
$("#mes_example_textarea").val("");
create_save_mes_example = "";
create_save_avatar = "";
$("#create_button").removeAttr("disabled");
$("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true)
);
$("#create_button").attr("value", "Create");
if (true) {
let oldSelectedChar = null;
if (this_chid != undefined && this_chid != "invalid-safety-id") {
oldSelectedChar = characters[this_chid].name;
}
await getCharacters();
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
var $prev_img = $("#avatar_div_div").clone();
$("#rm_info_avatar").append($prev_img);
select_rm_info("Character created", oldSelectedChar);
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
} else {
$("#result_info").html(html);
}
},
error: function (jqXHR, exception) {
//alert('ERROR: '+xhr.status+ ' Status Text: '+xhr.statusText+' '+xhr.responseText);
$("#create_button").removeAttr("disabled");
},
});
} else {
$("#result_info").html("Name not entered");
}
} else {
//console.log('/editcharacter -- entered.');
//console.log('Avatar Button Value:'+$("#add_avatar_button").val());
jQuery.ajax({
type: "POST",
url: "/editcharacter",
data: formData,
beforeSend: function () {
$("#create_button").attr("disabled", true);
$("#create_button").attr("value", "Save");
},
cache: false,
contentType: false,
processData: false,
success: function (html) {
$(".mes").each(function () {
if ($(this).attr("ch_name") != name1) {
$(this)
.children(".avatar")
.children("img")
.attr("src", $("#avatar_load_preview").attr("src"));
}
});
if (chat.length === 1) {
var this_ch_mes = default_ch_mes;
if ($("#firstmessage_textarea").val() != "") {
this_ch_mes = $("#firstmessage_textarea").val();
}
if (
this_ch_mes !=
$.trim(
$("#chat")
.children(".mes")
.children(".mes_block")
.children(".mes_text")
.text()
)
) {
clearChat();
chat.length = 0;
chat[0] = {};
chat[0]["name"] = name2;
chat[0]["is_user"] = false;
chat[0]["is_name"] = true;
chat[0]["mes"] = this_ch_mes;
add_mes_without_animation = true;
addOneMessage(chat[0]);
}
}
$("#create_button").removeAttr("disabled");
getCharacters();
$("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true)
);
$("#create_button").attr("value", "Save");
//console.log('/editcharacters -- this_chid -- '+this_chid);
/* if (this_chid != undefined && this_chid != 'invalid-safety-id') { //added check to avoid trying to load tokens in case of character deletion
CountCharTokens();
} */
},
error: function (jqXHR, exception) {
$("#create_button").removeAttr("disabled");
$("#result_info").html("Error: no connection");
},
});
}
});
$("#delete_button").click(function () {
popup_type = "del_ch";
callPopup(
"
Delete the character?
Page will reload and you will be returned to Chloe."
);
});
$("#rm_info_button").click(function () {
$("#rm_info_avatar").html("");
select_rm_characters();
});
//@@@@@@@@@@@@@@@@@@@@@@@@
//character text poles creating and editing save
$("#character_name_pole").on("change keyup paste", function () {
if (menu_type == "create") {
create_save_name = $("#character_name_pole").val();
}
});
$("#description_textarea").on("keyup paste cut", function () {
//change keyup paste cut
if (menu_type == "create") {
create_save_description = $("#description_textarea").val();
CountCharTokens();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#personality_textarea").on("keyup paste cut", function () {
if (menu_type == "create") {
create_save_personality = $("#personality_textarea").val();
CountCharTokens();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#scenario_pole").on("keyup paste cut", function () {
if (menu_type == "create") {
create_save_scenario = $("#scenario_pole").val();
CountCharTokens();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#mes_example_textarea").on("keyup paste cut", function () {
if (menu_type == "create") {
create_save_mes_example = $("#mes_example_textarea").val();
CountCharTokens();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#firstmessage_textarea").on("keyup paste cut", function () {
if (menu_type == "create") {
create_save_first_message = $("#firstmessage_textarea").val();
CountCharTokens();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#talkativeness_slider").on("input", function () {
if (menu_type == "create") {
create_save_talkativeness = $("#talkativeness_slider").val();
} else {
timerSaveEdit = setTimeout(() => {
$("#create_button").click();
}, durationSaveEdit);
}
});
$("#api_button").click(function () {
if ($("#api_url_text").val() != "") {
$("#api_loading").css("display", "inline-block");
$("#api_button").css("display", "none");
api_server = $("#api_url_text").val();
api_server = $.trim(api_server);
//console.log("1: "+api_server);
if (api_server.substr(api_server.length - 1, 1) == "/") {
api_server = api_server.substr(0, api_server.length - 1);
}
if (
!(
api_server.substr(api_server.length - 3, 3) == "api" ||
api_server.substr(api_server.length - 4, 4) == "api/"
)
) {
api_server = api_server + "/api";
}
//console.log("2: "+api_server);
main_api = "kobold";
saveSettings();
is_get_status = true;
is_api_button_press = true;
getStatus();
clearSoftPromptsList();
getSoftPromptsList();
}
});
$("#api_button_textgenerationwebui").click(function () {
if ($("#textgenerationwebui_api_url_text").val() != "") {
$("#api_loading_textgenerationwebui").css("display", "inline-block");
$("#api_button_textgenerationwebui").css("display", "none");
api_server_textgenerationwebui = $(
"#textgenerationwebui_api_url_text"
).val();
api_server_textgenerationwebui = $.trim(api_server_textgenerationwebui);
if (
api_server_textgenerationwebui.substr(
api_server_textgenerationwebui.length - 1,
1
) == "/"
) {
api_server_textgenerationwebui = api_server_textgenerationwebui.substr(
0,
api_server_textgenerationwebui.length - 1
);
}
//console.log("2: "+api_server_textgenerationwebui);
main_api = "textgenerationwebui";
saveSettings();
is_get_status = true;
is_api_button_press = true;
getStatus();
}
});
$("body").click(function () {
if ($("#options").css("opacity") == 1.0) {
$("#options").transition({
opacity: 0.0,
duration: 100, //animation_rm_duration,
easing: animation_rm_easing,
complete: function () {
$("#options").css("display", "none");
},
});
}
});
$("#options_button").click(function () {
// this is the options button click function, shows the options menu if closed
if (
$("#options").css("display") === "none" &&
$("#options").css("opacity") == 0.0
) {
$("#options").css("display", "block");
$("#options").transition({
opacity: 1.0, // the manual setting of CSS via JS is what allows the click-away feature to work
duration: 100,
easing: animation_rm_easing,
complete: function () { },
});
}
});
$("#option_select_chat").click(function () {
if (selected_group) {
// will open a chat selection screen
openNavToggle();
$("#rm_button_characters").trigger("click");
return;
}
if (this_chid != undefined && !is_send_press) {
getAllCharaChats();
$("#shadow_select_chat_popup").css("display", "block");
$("#shadow_select_chat_popup").css("opacity", 0.0);
$("#shadow_select_chat_popup").transition({
opacity: 1.0,
duration: animation_rm_duration,
easing: animation_rm_easing,
});
}
});
$("#option_start_new_chat").click(function () {
if (selected_group) {
// will open a group creation screen
openNavToggle();
$("#rm_button_group_chats").trigger("click");
return;
}
if (this_chid != undefined && !is_send_press) {
popup_type = "new_chat";
callPopup("